Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/net/if_tun.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/net/if_tun.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.82 retrieving revision 1.82.2.6 diff -u -p -r1.82 -r1.82.2.6 --- src/sys/net/if_tun.c 2006/03/03 19:57:37 1.82 +++ src/sys/net/if_tun.c 2006/09/14 12:31:55 1.82.2.6 @@ -1,4 +1,4 @@ -/* $NetBSD: if_tun.c,v 1.82 2006/03/03 19:57:37 rpaulo Exp $ */ +/* $NetBSD: if_tun.c,v 1.82.2.6 2006/09/14 12:31:55 yamt Exp $ */ /* * Copyright (c) 1988, Julian Onions @@ -15,10 +15,9 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.82 2006/03/03 19:57:37 rpaulo Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.82.2.6 2006/09/14 12:31:55 yamt Exp $"); #include "opt_inet.h" -#include "opt_ns.h" #include #include @@ -35,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1 #include #include #include +#include #include @@ -52,10 +52,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1 #include #endif -#ifdef NS -#include -#include -#endif #include "bpfilter.h" #if NBPFILTER > 0 @@ -102,7 +98,7 @@ static dev_type_kqfilter(tunkqfilter); const struct cdevsw tun_cdevsw = { tunopen, tunclose, tunread, tunwrite, tunioctl, - nostop, notty, tunpoll, nommap, tunkqfilter, + nostop, notty, tunpoll, nommap, tunkqfilter, D_OTHER, }; void @@ -274,12 +270,12 @@ tun_clone_destroy(struct ifnet *ifp) static int tunopen(dev_t dev, int flag, int mode, struct lwp *l) { - struct proc *p = l->l_proc; struct ifnet *ifp; struct tun_softc *tp; int s, error; - if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) + if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, + &l->l_acflag)) != 0) return (error); s = splnet(); @@ -542,7 +538,9 @@ tun_output(struct ifnet *ifp, struct mbu goto out; } bcopy(dst, mtod(m0, char *), dst->sa_len); - } else { + } + + if (tp->tun_flags & TUN_IFHEAD) { /* Prepend the address family */ M_PREPEND(m0, sizeof(*af), M_DONTWAIT); if (m0 == NULL) { @@ -552,6 +550,15 @@ tun_output(struct ifnet *ifp, struct mbu } af = mtod(m0,uint32_t *); *af = htonl(dst->sa_family); + } else { +#ifdef INET + if (dst->sa_family != AF_INET) +#endif + { + m_freem(m0); + error = EAFNOSUPPORT; + goto out; + } } /* FALLTHROUGH */ case AF_UNSPEC: @@ -633,12 +640,25 @@ tunioctl(dev_t dev, u_long cmd, caddr_t break; case TUNSLMODE: - if (*(int *)data) + if (*(int *)data) { tp->tun_flags |= TUN_PREPADDR; - else + tp->tun_flags &= ~TUN_IFHEAD; + } else tp->tun_flags &= ~TUN_PREPADDR; break; + case TUNSIFHEAD: + if (*(int *)data) { + tp->tun_flags |= TUN_IFHEAD; + tp->tun_flags &= ~TUN_PREPADDR; + } else + tp->tun_flags &= ~TUN_IFHEAD; + break; + + case TUNGIFHEAD: + *(int *)data = (tp->tun_flags & TUN_IFHEAD); + break; + case FIONBIO: if (*(int *)data) tp->tun_flags |= TUN_NBIO; @@ -820,13 +840,17 @@ tunwrite(dev_t dev, struct uio *uio, int goto out0; } } - } else { + } else if (tp->tun_flags & TUN_IFHEAD) { if (uio->uio_resid < sizeof(family)){ error = EIO; goto out0; } error = uiomove((caddr_t)&family, sizeof(family), uio); dst.sa_family = ntohl(family); + } else { +#ifdef INET + dst.sa_family = AF_INET; +#endif } if (uio->uio_resid > TUNMTU) { @@ -847,6 +871,7 @@ tunwrite(dev_t dev, struct uio *uio, int case AF_INET6: ifq = &ip6intrq; isr = NETISR_IPV6; + break; #endif default: error = EAFNOSUPPORT;