summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ppp/bundle.c65
-rw-r--r--usr.sbin/ppp/bundle.h1
-rw-r--r--usr.sbin/ppp/ip.c14
-rw-r--r--usr.sbin/ppp/tun.h12
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);