Handle the availability of TUNSIFHEAD. If it's there, use it.

For the moment this is just overhead, but it'll be used for INET6
support later.
This commit is contained in:
Brian Somers 2000-01-23 01:48:19 +00:00
parent f3c2973db7
commit 3a7b6d76a7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56413
4 changed files with 63 additions and 29 deletions

View File

@ -30,7 +30,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_tun.h> /* For TUNSIFMODE, TUNSLMODE & TUNSIFPID*/
#include <net/if_tun.h> /* For TUNS* ioctls */
#include <arpa/inet.h>
#include <net/route.h>
#include <netinet/in_systm.h>
@ -524,20 +524,36 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
if (FD_ISSET(bundle->dev.fd, fdset)) {
struct tun_data tun;
int n, pri;
char *data;
size_t sz;
if (bundle->dev.header) {
data = (char *)&tun;
sz = sizeof tun;
} else {
data = tun.data;
sz = sizeof tun.data;
}
/* something to read from tun */
n = read(bundle->dev.fd, &tun, sizeof tun);
n = read(bundle->dev.fd, data, sz);
if (n < 0) {
log_Printf(LogWARN, "read from %s: %s\n", TUN_NAME, strerror(errno));
log_Printf(LogWARN, "%s: read: %s\n", bundle->dev.Name, strerror(errno));
return;
}
n -= sizeof tun - sizeof tun.data;
if (n <= 0) {
log_Printf(LogERROR, "read from %s: Only %d bytes read ?\n", TUN_NAME, n);
return;
if (bundle->dev.header) {
n -= sz - sizeof tun.data;
if (n <= 0) {
log_Printf(LogERROR, "%s: read: Got only %d bytes of data !\n",
bundle->dev.Name, n);
return;
}
if (ntohl(tun.family) != AF_INET)
/* XXX: Should be maintaining drop/family counts ! */
return;
}
if (!tun_check_header(tun, AF_INET))
return;
if (((struct ip *)tun.data)->ip_dst.s_addr ==
bundle->ncp.ipcp.my_ip.s_addr) {
@ -545,8 +561,8 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
if (Enabled(bundle, OPT_LOOPBACK)) {
pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
if (pri >= 0) {
n += sizeof tun - sizeof tun.data;
write(bundle->dev.fd, &tun, n);
n += sz - sizeof tun.data;
write(bundle->dev.fd, data, n);
log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
}
return;
@ -638,7 +654,7 @@ bundle_Create(const char *prefix, int type, int unit)
#if defined(__FreeBSD__) && !defined(NOKLDLOAD)
int kldtried;
#endif
#if defined(TUNSIFMODE) || defined(TUNSLMODE)
#if defined(TUNSIFMODE) || defined(TUNSLMODE) || defined(TUNSIFHEAD)
int iff;
#endif
@ -722,13 +738,36 @@ bundle_Create(const char *prefix, int type, int unit)
#endif
#ifdef TUNSLMODE
/* Make sure we're POINTOPOINT */
/* Make sure we're not prepending sockaddrs */
iff = 0;
if (ID0ioctl(bundle.dev.fd, TUNSLMODE, &iff) < 0)
log_Printf(LogERROR, "bundle_Create: ioctl(TUNSLMODE): %s\n",
strerror(errno));
#endif
#ifdef TUNSIFHEAD
/* We want the address family please ! */
iff = 1;
if (ID0ioctl(bundle.dev.fd, TUNSIFHEAD, &iff) < 0) {
log_Printf(LogERROR, "bundle_Create: ioctl(TUNSIFHEAD): %s\n",
strerror(errno));
bundle.dev.header = 0;
} else
bundle.dev.header = 1;
#else
#ifdef __OpenBSD__
/* Always present for OpenBSD */
bundle.dev.header = 1;
#else
/*
* If TUNSIFHEAD isn't available and we're not OpenBSD, assume
* everything's AF_INET (hopefully the tun device won't pass us
* anything else !).
*/
bundle.dev.header = 0;
#endif
#endif
if (!iface_SetFlags(bundle.iface, IFF_UP)) {
iface_Destroy(bundle.iface);
bundle.iface = NULL;

View File

@ -67,6 +67,7 @@ struct bundle {
struct {
char Name[20]; /* The /dev/XXXX name */
int fd; /* The /dev/XXXX descriptor */
unsigned header : 1; /* Family header sent & received ? */
} dev;
u_long bandwidth; /* struct tuninfo speed */

View File

@ -24,9 +24,7 @@
* and optionaly record it into log.
*/
#include <sys/param.h>
#if defined(__OpenBSD__) || defined(__NetBSD__)
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@ -492,6 +490,7 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
int nb, nw;
struct tun_data tun;
struct ip *pip;
char *data;
if (bundle->ncp.ipcp.fsm.state != ST_OPENED) {
log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n");
@ -500,7 +499,6 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
}
m_settype(bp, MB_IPIN);
tun_fill_header(tun, AF_INET);
nb = m_length(bp);
if (nb > sizeof tun.data) {
log_Printf(LogWARN, "ip_Input: %s: Packet too large (got %d, max %d)\n",
@ -519,8 +517,14 @@ ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
nb += sizeof tun - sizeof tun.data;
nw = write(bundle->dev.fd, &tun, nb);
if (bundle->dev.header) {
tun.family = htonl(AF_INET);
nb += sizeof tun - sizeof tun.data;
data = (char *)&tun;
} else
data = tun.data;
nw = write(bundle->dev.fd, data, nb);
if (nw != nb) {
if (nw == -1)
log_Printf(LogERROR, "ip_Input: %s: wrote %d, got %s\n",

View File

@ -27,20 +27,10 @@
*/
struct tun_data {
#ifdef __OpenBSD__
u_int32_t head;
#endif
u_int32_t family;
u_char data[MAX_MRU];
};
#ifdef __OpenBSD__
#define tun_fill_header(f,proto) do { (f).head = htonl(proto); } while (0)
#define tun_check_header(f,proto) ((f).head == htonl(proto))
#else
#define tun_fill_header(f,proto) do { } while (0)
#define tun_check_header(f,proto) (1)
#endif
struct bundle;
extern void tun_configure(struct bundle *, int);