diff options
-rw-r--r-- | usr.sbin/ppp/bundle.c | 65 | ||||
-rw-r--r-- | usr.sbin/ppp/bundle.h | 1 | ||||
-rw-r--r-- | usr.sbin/ppp/ip.c | 14 | ||||
-rw-r--r-- | usr.sbin/ppp/tun.h | 12 |
4 files changed, 63 insertions, 29 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index a15b63e410af..73582969580e 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -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; diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h index 613924c60e45..46d97c3f9495 100644 --- a/usr.sbin/ppp/bundle.h +++ b/usr.sbin/ppp/bundle.h @@ -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 */ diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c index efd096dd6c4b..f33c3d93af37 100644 --- a/usr.sbin/ppp/ip.c +++ b/usr.sbin/ppp/ip.c @@ -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", diff --git a/usr.sbin/ppp/tun.h b/usr.sbin/ppp/tun.h index 8cbae71f87ea..f8a8289233e8 100644 --- a/usr.sbin/ppp/tun.h +++ b/usr.sbin/ppp/tun.h @@ -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); |