Home | History | Annotate | Line # | Download | only in net
if_tun.c revision 1.11
      1 /*
      2  * Copyright (c) 1988, Julian Onions <jpo (at) cs.nott.ac.uk>
      3  * Nottingham University 1987.
      4  *
      5  * This source may be freely distributed, however I would be interested
      6  * in any changes that are made.
      7  *
      8  * This driver takes packets off the IP i/f and hands them up to a
      9  * user process to have it's wicked way with. This driver has it's
     10  * roots in a similar driver written by Phil Cockcroft (formerly) at
     11  * UCL. This driver is based much more on read/write/select mode of
     12  * operation though.
     13  *
     14  * $Id: if_tun.c,v 1.11 1994/05/03 23:02:07 deraadt Exp $
     15  */
     16 
     17 #include "tun.h"
     18 #if NTUN > 0
     19 
     20 #include <sys/param.h>
     21 #include <sys/proc.h>
     22 #include <sys/systm.h>
     23 #include <sys/mbuf.h>
     24 #include <sys/buf.h>
     25 #include <sys/protosw.h>
     26 #include <sys/socket.h>
     27 #include <sys/ioctl.h>
     28 #include <sys/errno.h>
     29 #include <sys/syslog.h>
     30 #include <sys/select.h>
     31 #include <sys/file.h>
     32 
     33 #include <machine/cpu.h>
     34 
     35 #include <net/if.h>
     36 #include <net/netisr.h>
     37 #include <net/route.h>
     38 
     39 #ifdef INET
     40 #include <netinet/in.h>
     41 #include <netinet/in_systm.h>
     42 #include <netinet/in_var.h>
     43 #include <netinet/ip.h>
     44 #include <netinet/if_ether.h>
     45 #endif
     46 
     47 #ifdef NS
     48 #include <netns/ns.h>
     49 #include <netns/ns_if.h>
     50 #endif
     51 
     52 #include "bpfilter.h"
     53 #if NBPFILTER > 0
     54 #include <sys/time.h>
     55 #include <net/bpf.h>
     56 #endif
     57 
     58 #include <net/if_tun.h>
     59 
     60 #define TUNDEBUG	if (tundebug) printf
     61 int	tundebug = 0;
     62 
     63 struct tun_softc tunctl[NTUN];
     64 extern int ifqmaxlen;
     65 
     66 int	tunopen __P((dev_t, int, int, struct proc *));
     67 int	tunclose __P((dev_t, int));
     68 int	tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *));
     69 int	tunread __P((dev_t, struct uio *));
     70 int	tunwrite __P((dev_t, struct uio *));
     71 int	tuncioctl __P((dev_t, int, caddr_t, int));
     72 int	tunioctl __P((struct ifnet *, int, caddr_t, int));
     73 int	tunselect __P((dev_t, int));
     74 void	tunattach __P((int));
     75 
     76 static int tuninit __P((int));
     77 
     78 void
     79 tunattach(unused)
     80 	int unused;
     81 {
     82 	register int i;
     83 	struct ifnet *ifp;
     84 	struct sockaddr_in *sin;
     85 
     86 	for (i = 0; i < NTUN; i++) {
     87 		tunctl[i].tun_flags = TUN_INITED;
     88 
     89 		ifp = &tunctl[i].tun_if;
     90 		ifp->if_unit = i;
     91 		ifp->if_name = "tun";
     92 		ifp->if_mtu = TUNMTU;
     93 		ifp->if_ioctl = tunioctl;
     94 		ifp->if_output = tunoutput;
     95 		ifp->if_flags = IFF_POINTOPOINT;
     96 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
     97 		ifp->if_collisions = 0;
     98 		ifp->if_ierrors = 0;
     99 		ifp->if_oerrors = 0;
    100 		ifp->if_ipackets = 0;
    101 		ifp->if_opackets = 0;
    102 		if_attach(ifp);
    103 #if NBPFILTER > 0
    104 		bpfattach(&tunctl[i].tun_bpf, ifp, DLT_NULL, sizeof(u_int));
    105 #endif
    106 	}
    107 }
    108 
    109 /*
    110  * tunnel open - must be superuser & the device must be
    111  * configured in
    112  */
    113 int
    114 tunopen(dev, flag, mode, p)
    115 	dev_t	dev;
    116 	int	flag, mode;
    117 	struct proc *p;
    118 {
    119 	struct ifnet	*ifp;
    120 	struct tun_softc *tp;
    121 	register int	unit, error;
    122 
    123 	if (error = suser(p->p_ucred, &p->p_acflag))
    124 		return (error);
    125 
    126 	if ((unit = minor(dev)) >= NTUN)
    127 		return (ENXIO);
    128 	tp = &tunctl[unit];
    129 	if (tp->tun_flags & TUN_OPEN)
    130 		return ENXIO;
    131 	ifp = &tp->tun_if;
    132 	tp->tun_flags |= TUN_OPEN;
    133 	TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
    134 	return (0);
    135 }
    136 
    137 /*
    138  * tunclose - close the device - mark i/f down & delete
    139  * routing info
    140  */
    141 int
    142 tunclose(dev, flag)
    143 	dev_t	dev;
    144 	int	flag;
    145 {
    146 	register int	unit = minor(dev), s;
    147 	struct tun_softc *tp = &tunctl[unit];
    148 	struct ifnet	*ifp = &tp->tun_if;
    149 	struct mbuf	*m;
    150 
    151 	tp->tun_flags &= ~TUN_OPEN;
    152 
    153 	/*
    154 	 * junk all pending output
    155 	 */
    156 	do {
    157 		s = splimp();
    158 		IF_DEQUEUE(&ifp->if_snd, m);
    159 		splx(s);
    160 		if (m)
    161 			m_freem(m);
    162 	} while (m);
    163 
    164 	if (ifp->if_flags & IFF_UP) {
    165 		s = splimp();
    166 		if_down(ifp);
    167 		if (ifp->if_flags & IFF_RUNNING) {
    168 		    /* find internet addresses and delete routes */
    169 		    register struct ifaddr *ifa;
    170 		    for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
    171 			if (ifa->ifa_addr->sa_family == AF_INET) {
    172 			    rtinit(ifa, (int)RTM_DELETE,
    173 				   tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
    174 			}
    175 		    }
    176 		}
    177 		splx(s);
    178 	}
    179 	tp->tun_pgrp = 0;
    180 	selwakeup(&tp->tun_rsel);
    181 
    182 	TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
    183 	return (0);
    184 }
    185 
    186 static int
    187 tuninit(unit)
    188 	int	unit;
    189 {
    190 	struct tun_softc *tp = &tunctl[unit];
    191 	struct ifnet	*ifp = &tp->tun_if;
    192 	register struct ifaddr *ifa;
    193 
    194 	TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
    195 
    196 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
    197 
    198 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
    199 		if (ifa->ifa_addr->sa_family == AF_INET) {
    200 		    struct sockaddr_in *si;
    201 
    202 		    si = (struct sockaddr_in *)ifa->ifa_addr;
    203 		    if (si && si->sin_addr.s_addr)
    204 			    tp->tun_flags |= TUN_IASET;
    205 
    206 		    si = (struct sockaddr_in *)ifa->ifa_dstaddr;
    207 		    if (si && si->sin_addr.s_addr)
    208 			    tp->tun_flags |= TUN_DSTADDR;
    209 		}
    210 
    211 	return 0;
    212 }
    213 
    214 /*
    215  * Process an ioctl request.
    216  */
    217 int
    218 tunioctl(ifp, cmd, data, flag)
    219 	struct ifnet *ifp;
    220 	int	cmd;
    221 	caddr_t	data;
    222 	int	flag;
    223 {
    224 	struct tun_softc *tp = &tunctl[ifp->if_unit];
    225 	int		error = 0, s;
    226 
    227 	s = splimp();
    228 	switch(cmd) {
    229 	case SIOCSIFADDR:
    230 		tuninit(ifp->if_unit);
    231 		TUNDEBUG("%s%d: address set\n",
    232 			 ifp->if_name, ifp->if_unit);
    233 		break;
    234 	case SIOCSIFDSTADDR:
    235 		tuninit(ifp->if_unit);
    236 		TUNDEBUG("%s%d: destination address set\n",
    237 			 ifp->if_name, ifp->if_unit);
    238 		break;
    239 	default:
    240 		error = EINVAL;
    241 	}
    242 	splx(s);
    243 	return (error);
    244 }
    245 
    246 /*
    247  * tunoutput - queue packets from higher level ready to put out.
    248  */
    249 int
    250 tunoutput(ifp, m0, dst)
    251 	struct ifnet   *ifp;
    252 	struct mbuf    *m0;
    253 	struct sockaddr *dst;
    254 {
    255 	struct tun_softc *tp = &tunctl[ifp->if_unit];
    256 	struct proc	*p;
    257 	int		s;
    258 
    259 	TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
    260 
    261 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
    262 		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
    263 			  ifp->if_unit, tp->tun_flags);
    264 		m_freem (m0);
    265 		return EHOSTDOWN;
    266 	}
    267 
    268 #if NBPFILTER > 0
    269 	if (tp->tun_bpf) {
    270 		/*
    271 		 * We need to prepend the address family as
    272 		 * a four byte field.  Cons up a dummy header
    273 		 * to pacify bpf.  This is safe because bpf
    274 		 * will only read from the mbuf (i.e., it won't
    275 		 * try to free it or keep a pointer to it).
    276 		 */
    277 		struct mbuf m;
    278 		u_int af = dst->sa_family;
    279 
    280 		m.m_next = m0;
    281 		m.m_len = 4;
    282 		m.m_data = (char *)&af;
    283 
    284 		bpf_mtap(tp->tun_bpf, &m);
    285 	}
    286 #endif
    287 
    288 	switch(dst->sa_family) {
    289 #ifdef INET
    290 	case AF_INET:
    291 		s = splimp();
    292 		if (IF_QFULL(&ifp->if_snd)) {
    293 			IF_DROP(&ifp->if_snd);
    294 			m_freem(m0);
    295 			splx(s);
    296 			ifp->if_collisions++;
    297 			return (ENOBUFS);
    298 		}
    299 		IF_ENQUEUE(&ifp->if_snd, m0);
    300 		splx(s);
    301 		ifp->if_opackets++;
    302 		break;
    303 #endif
    304 	default:
    305 		m_freem(m0);
    306 		return EAFNOSUPPORT;
    307 	}
    308 
    309 	if (tp->tun_flags & TUN_RWAIT) {
    310 		tp->tun_flags &= ~TUN_RWAIT;
    311 		wakeup((caddr_t)tp);
    312 	}
    313 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
    314 		if (tp->tun_pgrp > 0)
    315 			gsignal(tp->tun_pgrp, SIGIO);
    316 		else if (p = pfind(-tp->tun_pgrp))
    317 			psignal(p, SIGIO);
    318 	}
    319 	selwakeup(&tp->tun_rsel);
    320 	return 0;
    321 }
    322 
    323 /*
    324  * the cdevsw interface is now pretty minimal.
    325  */
    326 int
    327 tuncioctl(dev, cmd, data, flag)
    328 	dev_t		dev;
    329 	int		cmd;
    330 	caddr_t		data;
    331 	int		flag;
    332 {
    333 	int		unit = minor(dev), s;
    334 	struct tun_softc *tp = &tunctl[unit];
    335 
    336 	switch (cmd) {
    337 	case TUNSDEBUG:
    338 		tundebug = *(int *)data;
    339 		break;
    340 	case TUNGDEBUG:
    341 		*(int *)data = tundebug;
    342 		break;
    343 	case FIONBIO:
    344 		if (*(int *)data)
    345 			tp->tun_flags |= TUN_NBIO;
    346 		else
    347 			tp->tun_flags &= ~TUN_NBIO;
    348 		break;
    349 	case FIOASYNC:
    350 		if (*(int *)data)
    351 			tp->tun_flags |= TUN_ASYNC;
    352 		else
    353 			tp->tun_flags &= ~TUN_ASYNC;
    354 		break;
    355 	case FIONREAD:
    356 		s = splimp();
    357 		if (tp->tun_if.if_snd.ifq_head)
    358 			*(int *)data = tp->tun_if.if_snd.ifq_head->m_len;
    359 		else
    360 			*(int *)data = 0;
    361 		splx(s);
    362 		break;
    363 	case TIOCSPGRP:
    364 		tp->tun_pgrp = *(int *)data;
    365 		break;
    366 	case TIOCGPGRP:
    367 		*(int *)data = tp->tun_pgrp;
    368 		break;
    369 	default:
    370 		return (ENOTTY);
    371 	}
    372 	return (0);
    373 }
    374 
    375 /*
    376  * The cdevsw read interface - reads a packet at a time, or at
    377  * least as much of a packet as can be read.
    378  */
    379 int
    380 tunread(dev, uio)
    381 	dev_t		dev;
    382 	struct uio	*uio;
    383 {
    384 	int		unit = minor(dev);
    385 	struct tun_softc *tp = &tunctl[unit];
    386 	struct ifnet	*ifp = &tp->tun_if;
    387 	struct mbuf	*m, *m0;
    388 	int		error=0, len, s;
    389 
    390 	TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
    391 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
    392 		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
    393 			  ifp->if_unit, tp->tun_flags);
    394 		return EHOSTDOWN;
    395 	}
    396 
    397 	tp->tun_flags &= ~TUN_RWAIT;
    398 
    399 	s = splimp();
    400 	do {
    401 		IF_DEQUEUE(&ifp->if_snd, m0);
    402 		if (m0 == 0) {
    403 			if (tp->tun_flags & TUN_NBIO) {
    404 				splx(s);
    405 				return EWOULDBLOCK;
    406 			}
    407 			tp->tun_flags |= TUN_RWAIT;
    408 			tsleep((caddr_t)tp, PZERO + 1, "tunread", 0);
    409 		}
    410 	} while (m0 == 0);
    411 	splx(s);
    412 
    413 	while (m0 && uio->uio_resid > 0 && error == 0) {
    414 		len = MIN(uio->uio_resid, m0->m_len);
    415 		if (len == 0)
    416 			break;
    417 		error = uiomove(mtod(m0, caddr_t), len, uio);
    418 		MFREE(m0, m);
    419 		m0 = m;
    420 	}
    421 
    422 	if (m0) {
    423 		TUNDEBUG("Dropping mbuf\n");
    424 		m_freem(m0);
    425 	}
    426 	return error;
    427 }
    428 
    429 /*
    430  * the cdevsw write interface - an atomic write is a packet - or else!
    431  */
    432 int
    433 tunwrite(dev, uio)
    434 	dev_t		dev;
    435 	struct uio	*uio;
    436 {
    437 	int		unit = minor (dev);
    438 	struct ifnet	*ifp = &tunctl[unit].tun_if;
    439 	struct mbuf	*top, **mp, *m;
    440 	int		error=0, s, tlen, mlen;
    441 
    442 	TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
    443 
    444 	if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) {
    445 		TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
    446 		    uio->uio_resid);
    447 		return EIO;
    448 	}
    449 	tlen = uio->uio_resid;
    450 
    451 	/* get a header mbuf */
    452 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    453 	if (m == NULL)
    454 		return ENOBUFS;
    455 	mlen = MHLEN;
    456 
    457 	top = 0;
    458 	mp = &top;
    459 	while (error == 0 && uio->uio_resid > 0) {
    460 		m->m_len = MIN (mlen, uio->uio_resid);
    461 		error = uiomove(mtod (m, caddr_t), m->m_len, uio);
    462 		*mp = m;
    463 		mp = &m->m_next;
    464 		if (uio->uio_resid > 0) {
    465 			MGET (m, M_DONTWAIT, MT_DATA);
    466 			if (m == 0) {
    467 				error = ENOBUFS;
    468 				break;
    469 			}
    470 			mlen = MLEN;
    471 		}
    472 	}
    473 	if (error) {
    474 		if (top)
    475 			m_freem (top);
    476 		return error;
    477 	}
    478 
    479 	top->m_pkthdr.len = tlen;
    480 	top->m_pkthdr.rcvif = ifp;
    481 
    482 #if NBPFILTER > 0
    483 	if (tunctl[unit].tun_bpf) {
    484 		/*
    485 		 * We need to prepend the address family as
    486 		 * a four byte field.  Cons up a dummy header
    487 		 * to pacify bpf.  This is safe because bpf
    488 		 * will only read from the mbuf (i.e., it won't
    489 		 * try to free it or keep a pointer to it).
    490 		 */
    491 		struct mbuf m;
    492 		u_int af = AF_INET;
    493 
    494 		m.m_next = top;
    495 		m.m_len = 4;
    496 		m.m_data = (char *)&af;
    497 
    498 		bpf_mtap(tunctl[unit].tun_bpf, &m);
    499 	}
    500 #endif
    501 
    502 	s = splimp();
    503 	if (IF_QFULL (&ipintrq)) {
    504 		IF_DROP(&ipintrq);
    505 		splx(s);
    506 		ifp->if_collisions++;
    507 		m_freem(top);
    508 		return ENOBUFS;
    509 	}
    510 	IF_ENQUEUE(&ipintrq, top);
    511 	splx(s);
    512 	ifp->if_ipackets++;
    513 	schednetisr(NETISR_IP);
    514 	return error;
    515 }
    516 
    517 /*
    518  * tunselect - the select interface, this is only useful on reads
    519  * really. The write detect always returns true, write never blocks
    520  * anyway, it either accepts the packet or drops it.
    521  */
    522 int
    523 tunselect(dev, rw)
    524 	dev_t		dev;
    525 	int		rw;
    526 {
    527 	int		unit = minor(dev), s;
    528 	struct tun_softc *tp = &tunctl[unit];
    529 	struct ifnet	*ifp = &tp->tun_if;
    530 
    531 	s = splimp();
    532 	TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit);
    533 
    534 	switch (rw) {
    535 	case FREAD:
    536 		if (ifp->if_snd.ifq_len > 0) {
    537 			splx(s);
    538 			TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name,
    539 			    ifp->if_unit, ifp->if_snd.ifq_len);
    540 			return 1;
    541 		}
    542 		selrecord(curproc, &tp->tun_rsel);
    543 		break;
    544 	case FWRITE:
    545 		splx(s);
    546 		return 1;
    547 	}
    548 	splx(s);
    549 	TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit);
    550 	return 0;
    551 }
    552 
    553 #endif  /* NTUN */
    554