xref: /dragonfly/sys/net/tun/if_tun.c (revision af79c6e5)
1 /*	$NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5  * Nottingham University 1987.
6  *
7  * This source may be freely distributed, however I would be interested
8  * in any changes that are made.
9  *
10  * This driver takes packets off the IP i/f and hands them up to a
11  * user process to have its wicked way with. This driver has it's
12  * roots in a similar driver written by Phil Cockcroft (formerly) at
13  * UCL. This driver is based much more on read/write/poll mode of
14  * operation though.
15  *
16  * $FreeBSD: src/sys/net/if_tun.c,v 1.74.2.8 2002/02/13 00:43:11 dillon Exp $
17  * $DragonFly: src/sys/net/tun/if_tun.c,v 1.10 2003/09/15 23:38:14 hsu Exp $
18  */
19 
20 #include "opt_atalk.h"
21 #include "opt_inet.h"
22 #include "opt_inet6.h"
23 #include "opt_ipx.h"
24 
25 #include <sys/param.h>
26 #include <sys/proc.h>
27 #include <sys/systm.h>
28 #include <sys/mbuf.h>
29 #include <sys/socket.h>
30 #include <sys/filio.h>
31 #include <sys/sockio.h>
32 #include <sys/ttycom.h>
33 #include <sys/poll.h>
34 #include <sys/signalvar.h>
35 #include <sys/filedesc.h>
36 #include <sys/kernel.h>
37 #include <sys/sysctl.h>
38 #include <sys/conf.h>
39 #include <sys/uio.h>
40 #include <sys/vnode.h>
41 #include <sys/malloc.h>
42 
43 #include <net/if.h>
44 #include <net/if_types.h>
45 #include <net/netisr.h>
46 #include <net/route.h>
47 
48 #ifdef INET
49 #include <netinet/in.h>
50 #endif
51 
52 #include <net/bpf.h>
53 
54 #include "if_tunvar.h"
55 #include "if_tun.h"
56 
57 static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface");
58 
59 static void tunattach (void *);
60 PSEUDO_SET(tunattach, if_tun);
61 
62 static void tuncreate (dev_t dev);
63 
64 #define TUNDEBUG	if (tundebug) printf
65 static int tundebug = 0;
66 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
67 
68 static int tunoutput (struct ifnet *, struct mbuf *, struct sockaddr *,
69 	    struct rtentry *rt);
70 static int tunifioctl (struct ifnet *, u_long, caddr_t);
71 static int tuninit (struct ifnet *);
72 
73 static	d_open_t	tunopen;
74 static	d_close_t	tunclose;
75 static	d_read_t	tunread;
76 static	d_write_t	tunwrite;
77 static	d_ioctl_t	tunioctl;
78 static	d_poll_t	tunpoll;
79 
80 #define CDEV_MAJOR 52
81 static struct cdevsw tun_cdevsw = {
82 	/* name */	"tun",
83 	/* maj */	CDEV_MAJOR,
84 	/* flags */	0,
85 	/* port */	NULL,
86 	/* autoq */	0,
87 
88 	/* open */	tunopen,
89 	/* close */	tunclose,
90 	/* read */	tunread,
91 	/* write */	tunwrite,
92 	/* ioctl */	tunioctl,
93 	/* poll */	tunpoll,
94 	/* mmap */	nommap,
95 	/* strategy */	nostrategy,
96 	/* dump */	nodump,
97 	/* psize */	nopsize
98 };
99 
100 static void
101 tunattach(dummy)
102 	void *dummy;
103 {
104 
105 	cdevsw_add(&tun_cdevsw);
106 }
107 
108 static void
109 tuncreate(dev)
110 	dev_t dev;
111 {
112 	struct tun_softc *sc;
113 	struct ifnet *ifp;
114 
115 	dev = make_dev(&tun_cdevsw, minor(dev),
116 	    UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
117 
118 	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK);
119 	bzero(sc, sizeof *sc);
120 	sc->tun_flags = TUN_INITED;
121 
122 	ifp = &sc->tun_if;
123 	ifp->if_unit = lminor(dev);
124 	ifp->if_name = "tun";
125 	ifp->if_mtu = TUNMTU;
126 	ifp->if_ioctl = tunifioctl;
127 	ifp->if_output = tunoutput;
128 	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
129 	ifp->if_type = IFT_PPP;
130 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
131 	ifp->if_softc = sc;
132 	if_attach(ifp);
133 	bpfattach(ifp, DLT_NULL, sizeof(u_int));
134 	dev->si_drv1 = sc;
135 }
136 
137 /*
138  * tunnel open - must be superuser & the device must be
139  * configured in
140  */
141 static	int
142 tunopen(dev_t dev, int flag, int mode, struct thread *td)
143 {
144 	struct ifnet	*ifp;
145 	struct tun_softc *tp;
146 	int	error;
147 
148 	KKASSERT(td->td_proc);
149 	if ((error = suser(td)) != NULL)
150 		return (error);
151 
152 	tp = dev->si_drv1;
153 	if (!tp) {
154 		tuncreate(dev);
155 		tp = dev->si_drv1;
156 	}
157 	if (tp->tun_flags & TUN_OPEN)
158 		return EBUSY;
159 	tp->tun_pid = td->td_proc->p_pid;
160 	ifp = &tp->tun_if;
161 	tp->tun_flags |= TUN_OPEN;
162 	TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
163 	return (0);
164 }
165 
166 /*
167  * tunclose - close the device - mark i/f down & delete
168  * routing info
169  */
170 static	int
171 tunclose(dev_t dev, int foo, int bar, struct thread *td)
172 {
173 	int	s;
174 	struct tun_softc *tp;
175 	struct ifnet	*ifp;
176 	struct mbuf	*m;
177 
178 	tp = dev->si_drv1;
179 	ifp = &tp->tun_if;
180 
181 	tp->tun_flags &= ~TUN_OPEN;
182 	tp->tun_pid = 0;
183 
184 	/*
185 	 * junk all pending output
186 	 */
187 	do {
188 		s = splimp();
189 		IF_DEQUEUE(&ifp->if_snd, m);
190 		splx(s);
191 		if (m)
192 			m_freem(m);
193 	} while (m);
194 
195 	if (ifp->if_flags & IFF_UP) {
196 		s = splimp();
197 		if_down(ifp);
198 		splx(s);
199 	}
200 
201 	if (ifp->if_flags & IFF_RUNNING) {
202 		struct ifaddr *ifa;
203 
204 		s = splimp();
205 		/* find internet addresses and delete routes */
206 		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
207 			if (ifa->ifa_addr->sa_family == AF_INET)
208 				rtinit(ifa, (int)RTM_DELETE,
209 				    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
210 		ifp->if_flags &= ~IFF_RUNNING;
211 		splx(s);
212 	}
213 
214 	funsetown(tp->tun_sigio);
215 	selwakeup(&tp->tun_rsel);
216 
217 	TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
218 	return (0);
219 }
220 
221 static int
222 tuninit(ifp)
223 	struct ifnet *ifp;
224 {
225 	struct tun_softc *tp = ifp->if_softc;
226 	struct ifaddr *ifa;
227 	int error = 0;
228 
229 	TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
230 
231 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
232 	getmicrotime(&ifp->if_lastchange);
233 
234 	for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
235 	     ifa = TAILQ_NEXT(ifa, ifa_link)) {
236 		if (ifa->ifa_addr == NULL)
237 			error = EFAULT;
238 			/* XXX: Should maybe return straight off? */
239 		else {
240 #ifdef INET
241 			if (ifa->ifa_addr->sa_family == AF_INET) {
242 			    struct sockaddr_in *si;
243 
244 			    si = (struct sockaddr_in *)ifa->ifa_addr;
245 			    if (si->sin_addr.s_addr)
246 				    tp->tun_flags |= TUN_IASET;
247 
248 			    si = (struct sockaddr_in *)ifa->ifa_dstaddr;
249 			    if (si && si->sin_addr.s_addr)
250 				    tp->tun_flags |= TUN_DSTADDR;
251 			}
252 #endif
253 		}
254 	}
255 	return (error);
256 }
257 
258 /*
259  * Process an ioctl request.
260  */
261 int
262 tunifioctl(ifp, cmd, data)
263 	struct ifnet *ifp;
264 	u_long	cmd;
265 	caddr_t	data;
266 {
267 	struct ifreq *ifr = (struct ifreq *)data;
268 	struct tun_softc *tp = ifp->if_softc;
269 	struct ifstat *ifs;
270 	int		error = 0, s;
271 
272 	s = splimp();
273 	switch(cmd) {
274 	case SIOCGIFSTATUS:
275 		ifs = (struct ifstat *)data;
276 		if (tp->tun_pid)
277 			sprintf(ifs->ascii + strlen(ifs->ascii),
278 			    "\tOpened by PID %d\n", tp->tun_pid);
279 		break;
280 	case SIOCSIFADDR:
281 		error = tuninit(ifp);
282 		TUNDEBUG("%s%d: address set, error=%d\n",
283 			 ifp->if_name, ifp->if_unit, error);
284 		break;
285 	case SIOCSIFDSTADDR:
286 		error = tuninit(ifp);
287 		TUNDEBUG("%s%d: destination address set, error=%d\n",
288 			 ifp->if_name, ifp->if_unit, error);
289 		break;
290 	case SIOCSIFMTU:
291 		ifp->if_mtu = ifr->ifr_mtu;
292 		TUNDEBUG("%s%d: mtu set\n",
293 			 ifp->if_name, ifp->if_unit);
294 		break;
295 	case SIOCSIFFLAGS:
296 	case SIOCADDMULTI:
297 	case SIOCDELMULTI:
298 		break;
299 	default:
300 		error = EINVAL;
301 	}
302 	splx(s);
303 	return (error);
304 }
305 
306 /*
307  * tunoutput - queue packets from higher level ready to put out.
308  */
309 int
310 tunoutput(ifp, m0, dst, rt)
311 	struct ifnet   *ifp;
312 	struct mbuf    *m0;
313 	struct sockaddr *dst;
314 	struct rtentry *rt;
315 {
316 	struct tun_softc *tp = ifp->if_softc;
317 	int		s;
318 
319 	TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
320 
321 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
322 		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
323 			  ifp->if_unit, tp->tun_flags);
324 		m_freem (m0);
325 		return EHOSTDOWN;
326 	}
327 
328 	/* BPF write needs to be handled specially */
329 	if (dst->sa_family == AF_UNSPEC) {
330 		dst->sa_family = *(mtod(m0, int *));
331 		m0->m_len -= sizeof(int);
332 		m0->m_pkthdr.len -= sizeof(int);
333 		m0->m_data += sizeof(int);
334 	}
335 
336 	if (ifp->if_bpf) {
337 		/*
338 		 * We need to prepend the address family as
339 		 * a four byte field.  Cons up a dummy header
340 		 * to pacify bpf.  This is safe because bpf
341 		 * will only read from the mbuf (i.e., it won't
342 		 * try to free it or keep a pointer to it).
343 		 */
344 		struct mbuf m;
345 		uint32_t af = dst->sa_family;
346 
347 		m.m_next = m0;
348 		m.m_len = 4;
349 		m.m_data = (char *)&af;
350 
351 		bpf_mtap(ifp, &m);
352 	}
353 
354 	/* prepend sockaddr? this may abort if the mbuf allocation fails */
355 	if (tp->tun_flags & TUN_LMODE) {
356 		/* allocate space for sockaddr */
357 		M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
358 
359 		/* if allocation failed drop packet */
360 		if (m0 == NULL){
361 			s = splimp();	/* spl on queue manipulation */
362 			IF_DROP(&ifp->if_snd);
363 			splx(s);
364 			ifp->if_oerrors++;
365 			return (ENOBUFS);
366 		} else {
367 			bcopy(dst, m0->m_data, dst->sa_len);
368 		}
369 	}
370 
371 	if (tp->tun_flags & TUN_IFHEAD) {
372 		/* Prepend the address family */
373 		M_PREPEND(m0, 4, M_DONTWAIT);
374 
375 		/* if allocation failed drop packet */
376 		if (m0 == NULL){
377 			s = splimp();	/* spl on queue manipulation */
378 			IF_DROP(&ifp->if_snd);
379 			splx(s);
380 			ifp->if_oerrors++;
381 			return ENOBUFS;
382 		} else
383 			*(u_int32_t *)m0->m_data = htonl(dst->sa_family);
384 	} else {
385 #ifdef INET
386 		if (dst->sa_family != AF_INET)
387 #endif
388 		{
389 			m_freem(m0);
390 			return EAFNOSUPPORT;
391 		}
392 	}
393 
394 	s = splimp();
395 	if (IF_QFULL(&ifp->if_snd)) {
396 		IF_DROP(&ifp->if_snd);
397 		m_freem(m0);
398 		splx(s);
399 		ifp->if_collisions++;
400 		return ENOBUFS;
401 	}
402 	ifp->if_obytes += m0->m_pkthdr.len;
403 	IF_ENQUEUE(&ifp->if_snd, m0);
404 	splx(s);
405 	ifp->if_opackets++;
406 
407 	if (tp->tun_flags & TUN_RWAIT) {
408 		tp->tun_flags &= ~TUN_RWAIT;
409 		wakeup((caddr_t)tp);
410 	}
411 	if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
412 		pgsigio(tp->tun_sigio, SIGIO, 0);
413 	selwakeup(&tp->tun_rsel);
414 	return 0;
415 }
416 
417 /*
418  * the cdevsw interface is now pretty minimal.
419  */
420 static	int
421 tunioctl(dev_t	dev, u_long cmd, caddr_t data, int flag, struct thread *td)
422 {
423 	int		s;
424 	struct tun_softc *tp = dev->si_drv1;
425  	struct tuninfo *tunp;
426 
427 	switch (cmd) {
428  	case TUNSIFINFO:
429  		tunp = (struct tuninfo *)data;
430 		if (tunp->mtu < IF_MINMTU)
431 			return (EINVAL);
432  		tp->tun_if.if_mtu = tunp->mtu;
433  		tp->tun_if.if_type = tunp->type;
434  		tp->tun_if.if_baudrate = tunp->baudrate;
435  		break;
436  	case TUNGIFINFO:
437  		tunp = (struct tuninfo *)data;
438  		tunp->mtu = tp->tun_if.if_mtu;
439  		tunp->type = tp->tun_if.if_type;
440  		tunp->baudrate = tp->tun_if.if_baudrate;
441  		break;
442 	case TUNSDEBUG:
443 		tundebug = *(int *)data;
444 		break;
445 	case TUNGDEBUG:
446 		*(int *)data = tundebug;
447 		break;
448 	case TUNSLMODE:
449 		if (*(int *)data) {
450 			tp->tun_flags |= TUN_LMODE;
451 			tp->tun_flags &= ~TUN_IFHEAD;
452 		} else
453 			tp->tun_flags &= ~TUN_LMODE;
454 		break;
455 	case TUNSIFHEAD:
456 		if (*(int *)data) {
457 			tp->tun_flags |= TUN_IFHEAD;
458 			tp->tun_flags &= ~TUN_LMODE;
459 		} else
460 			tp->tun_flags &= ~TUN_IFHEAD;
461 		break;
462 	case TUNGIFHEAD:
463 		*(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
464 		break;
465 	case TUNSIFMODE:
466 		/* deny this if UP */
467 		if (tp->tun_if.if_flags & IFF_UP)
468 			return(EBUSY);
469 
470 		switch (*(int *)data & ~IFF_MULTICAST) {
471 		case IFF_POINTOPOINT:
472 		case IFF_BROADCAST:
473 			tp->tun_if.if_flags &= ~(IFF_BROADCAST|IFF_POINTOPOINT);
474 			tp->tun_if.if_flags |= *(int *)data;
475 			break;
476 		default:
477 			return(EINVAL);
478 		}
479 		break;
480 	case TUNSIFPID:
481 		tp->tun_pid = curproc->p_pid;
482 		break;
483 	case FIONBIO:
484 		break;
485 	case FIOASYNC:
486 		if (*(int *)data)
487 			tp->tun_flags |= TUN_ASYNC;
488 		else
489 			tp->tun_flags &= ~TUN_ASYNC;
490 		break;
491 	case FIONREAD:
492 		s = splimp();
493 		if (tp->tun_if.if_snd.ifq_head) {
494 			struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
495 			for( *(int *)data = 0; mb != 0; mb = mb->m_next)
496 				*(int *)data += mb->m_len;
497 		} else
498 			*(int *)data = 0;
499 		splx(s);
500 		break;
501 	case FIOSETOWN:
502 		return (fsetown(*(int *)data, &tp->tun_sigio));
503 
504 	case FIOGETOWN:
505 		*(int *)data = fgetown(tp->tun_sigio);
506 		return (0);
507 
508 	/* This is deprecated, FIOSETOWN should be used instead. */
509 	case TIOCSPGRP:
510 		return (fsetown(-(*(int *)data), &tp->tun_sigio));
511 
512 	/* This is deprecated, FIOGETOWN should be used instead. */
513 	case TIOCGPGRP:
514 		*(int *)data = -fgetown(tp->tun_sigio);
515 		return (0);
516 
517 	default:
518 		return (ENOTTY);
519 	}
520 	return (0);
521 }
522 
523 /*
524  * The cdevsw read interface - reads a packet at a time, or at
525  * least as much of a packet as can be read.
526  */
527 static	int
528 tunread(dev, uio, flag)
529 	dev_t dev;
530 	struct uio *uio;
531 	int flag;
532 {
533 	struct tun_softc *tp = dev->si_drv1;
534 	struct ifnet	*ifp = &tp->tun_if;
535 	struct mbuf	*m0;
536 	int		error=0, len, s;
537 
538 	TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
539 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
540 		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
541 			  ifp->if_unit, tp->tun_flags);
542 		return EHOSTDOWN;
543 	}
544 
545 	tp->tun_flags &= ~TUN_RWAIT;
546 
547 	s = splimp();
548 	do {
549 		IF_DEQUEUE(&ifp->if_snd, m0);
550 		if (m0 == 0) {
551 			if (flag & IO_NDELAY) {
552 				splx(s);
553 				return EWOULDBLOCK;
554 			}
555 			tp->tun_flags |= TUN_RWAIT;
556 			if((error = tsleep((caddr_t)tp, PCATCH,
557 					"tunread", 0)) != 0) {
558 				splx(s);
559 				return error;
560 			}
561 		}
562 	} while (m0 == 0);
563 	splx(s);
564 
565 	while (m0 && uio->uio_resid > 0 && error == 0) {
566 		len = min(uio->uio_resid, m0->m_len);
567 		if (len != 0)
568 			error = uiomove(mtod(m0, caddr_t), len, uio);
569 		m0 = m_free(m0);
570 	}
571 
572 	if (m0) {
573 		TUNDEBUG("%s%d: Dropping mbuf\n", ifp->if_name, ifp->if_unit);
574 		m_freem(m0);
575 	}
576 	return error;
577 }
578 
579 /*
580  * the cdevsw write interface - an atomic write is a packet - or else!
581  */
582 static	int
583 tunwrite(dev, uio, flag)
584 	dev_t dev;
585 	struct uio *uio;
586 	int flag;
587 {
588 	struct tun_softc *tp = dev->si_drv1;
589 	struct ifnet	*ifp = &tp->tun_if;
590 	struct mbuf	*top, **mp, *m;
591 	int		error=0, tlen, mlen;
592 	uint32_t	family;
593 	int		isr;
594 
595 	TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
596 
597 	if (uio->uio_resid == 0)
598 		return 0;
599 
600 	if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
601 		TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
602 		    uio->uio_resid);
603 		return EIO;
604 	}
605 	tlen = uio->uio_resid;
606 
607 	/* get a header mbuf */
608 	MGETHDR(m, M_DONTWAIT, MT_DATA);
609 	if (m == NULL)
610 		return ENOBUFS;
611 	mlen = MHLEN;
612 
613 	top = 0;
614 	mp = &top;
615 	while (error == 0 && uio->uio_resid > 0) {
616 		m->m_len = min(mlen, uio->uio_resid);
617 		error = uiomove(mtod (m, caddr_t), m->m_len, uio);
618 		*mp = m;
619 		mp = &m->m_next;
620 		if (uio->uio_resid > 0) {
621 			MGET (m, M_DONTWAIT, MT_DATA);
622 			if (m == 0) {
623 				error = ENOBUFS;
624 				break;
625 			}
626 			mlen = MLEN;
627 		}
628 	}
629 	if (error) {
630 		if (top)
631 			m_freem (top);
632 		ifp->if_ierrors++;
633 		return error;
634 	}
635 
636 	top->m_pkthdr.len = tlen;
637 	top->m_pkthdr.rcvif = ifp;
638 
639 	if (ifp->if_bpf) {
640 		if (tp->tun_flags & TUN_IFHEAD) {
641 			/*
642 			 * Conveniently, we already have a 4-byte address
643 			 * family prepended to our packet !
644 			 * Inconveniently, it's in the wrong byte order !
645 			 */
646 			if ((top = m_pullup(top, sizeof(family))) == NULL)
647 				return ENOBUFS;
648 			*mtod(top, u_int32_t *) =
649 			    ntohl(*mtod(top, u_int32_t *));
650 			bpf_mtap(ifp, top);
651 			*mtod(top, u_int32_t *) =
652 			    htonl(*mtod(top, u_int32_t *));
653 		} else {
654 			/*
655 			 * We need to prepend the address family as
656 			 * a four byte field.  Cons up a dummy header
657 			 * to pacify bpf.  This is safe because bpf
658 			 * will only read from the mbuf (i.e., it won't
659 			 * try to free it or keep a pointer to it).
660 			 */
661 			struct mbuf m;
662 			uint32_t af = AF_INET;
663 
664 			m.m_next = top;
665 			m.m_len = 4;
666 			m.m_data = (char *)&af;
667 
668 			bpf_mtap(ifp, &m);
669 		}
670 	}
671 
672 	if (tp->tun_flags & TUN_IFHEAD) {
673 		if (top->m_len < sizeof(family) &&
674 		    (top = m_pullup(top, sizeof(family))) == NULL)
675 				return ENOBUFS;
676 		family = ntohl(*mtod(top, u_int32_t *));
677 		m_adj(top, sizeof(family));
678 	} else
679 		family = AF_INET;
680 
681 	ifp->if_ibytes += top->m_pkthdr.len;
682 	ifp->if_ipackets++;
683 
684 	switch (family) {
685 #ifdef INET
686 	case AF_INET:
687 		isr = NETISR_IP;
688 		break;
689 #endif
690 #ifdef INET6
691 	case AF_INET6:
692 		isr = NETISR_IPV6;
693 		break;
694 #endif
695 #ifdef IPX
696 	case AF_IPX:
697 		isr = NETISR_IPX;
698 		break;
699 #endif
700 #ifdef NETATALK
701 	case AF_APPLETALK:
702 		isr = NETISR_ATALK2;
703 		break;
704 #endif
705 	default:
706 		m_freem(m);
707 		return (EAFNOSUPPORT);
708 	}
709 
710 	netisr_dispatch(isr, top);
711 	return (0);
712 }
713 
714 /*
715  * tunpoll - the poll interface, this is only useful on reads
716  * really. The write detect always returns true, write never blocks
717  * anyway, it either accepts the packet or drops it.
718  */
719 static	int
720 tunpoll(dev_t dev, int events, struct thread *td)
721 {
722 	int		s;
723 	struct tun_softc *tp = dev->si_drv1;
724 	struct ifnet	*ifp = &tp->tun_if;
725 	int		revents = 0;
726 
727 	s = splimp();
728 	TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
729 
730 	if (events & (POLLIN | POLLRDNORM)) {
731 		if (ifp->if_snd.ifq_len > 0) {
732 			TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
733 			    ifp->if_unit, ifp->if_snd.ifq_len);
734 			revents |= events & (POLLIN | POLLRDNORM);
735 		} else {
736 			TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
737 			    ifp->if_unit);
738 			selrecord(td, &tp->tun_rsel);
739 		}
740 	}
741 	if (events & (POLLOUT | POLLWRNORM))
742 		revents |= events & (POLLOUT | POLLWRNORM);
743 
744 	splx(s);
745 	return (revents);
746 }
747