]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_tun.c
This commit was generated by cvs2svn to compensate for changes in r95415,
[FreeBSD/FreeBSD.git] / sys / net / if_tun.c
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$
17  */
18
19 #include "opt_inet.h"
20
21 #include <sys/param.h>
22 #include <sys/proc.h>
23 #include <sys/systm.h>
24 #include <sys/mbuf.h>
25 #include <sys/module.h>
26 #include <sys/socket.h>
27 #include <sys/filio.h>
28 #include <sys/sockio.h>
29 #include <sys/ttycom.h>
30 #include <sys/poll.h>
31 #include <sys/signalvar.h>
32 #include <sys/filedesc.h>
33 #include <sys/kernel.h>
34 #include <sys/sysctl.h>
35 #include <sys/conf.h>
36 #include <sys/uio.h>
37 #include <sys/vnode.h>
38 #include <sys/malloc.h>
39 #include <machine/bus.h>        /* XXX Shouldn't really be required ! */
40 #include <sys/rman.h>
41
42 #include <net/if.h>
43 #include <net/if_types.h>
44 #include <net/route.h>
45 #include <net/intrq.h>
46 #ifdef INET
47 #include <netinet/in.h>
48 #endif
49 #include <net/bpf.h>
50 #include <net/if_tunvar.h>
51 #include <net/if_tun.h>
52
53 #define TUNDEBUG        if (tundebug) printf
54 #define TUNNAME         "tun"
55 #define TUN_MAXUNIT     0x7fff  /* ifp->if_unit is only 15 bits */
56
57 static MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface");
58 static int tundebug = 0;
59 static struct tun_softc *tunhead = NULL;
60 static struct rman tununits[1];
61 static udev_t tunbasedev = NOUDEV;
62 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
63
64 static void     tunclone(void *arg, char *name, int namelen, dev_t *dev);
65 static void     tuncreate(dev_t dev);
66 static int      tunifioctl(struct ifnet *, u_long, caddr_t);
67 static int      tuninit(struct ifnet *);
68 static int      tunmodevent(module_t, int, void *);
69 static int      tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
70                     struct rtentry *rt);
71 static void     tunstart(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         /* open */      tunopen,
83         /* close */     tunclose,
84         /* read */      tunread,
85         /* write */     tunwrite,
86         /* ioctl */     tunioctl,
87         /* poll */      tunpoll,
88         /* mmap */      nommap,
89         /* strategy */  nostrategy,
90         /* name */      TUNNAME,
91         /* maj */       CDEV_MAJOR,
92         /* dump */      nodump,
93         /* psize */     nopsize,
94         /* flags */     0,
95 };
96
97 static void
98 tunclone(void *arg, char *name, int namelen, dev_t *dev)
99 {
100         struct resource *r;
101         int err;
102         int u;
103
104         if (*dev != NODEV)
105                 return;
106
107         if (strcmp(name, TUNNAME) == 0) {
108                 r = rman_reserve_resource(tununits, 0, TUN_MAXUNIT, 1,
109                     RF_ALLOCATED | RF_ACTIVE, NULL);
110                 u = rman_get_start(r);
111                 err = rman_release_resource(r);
112                 KASSERT(err == 0, ("Unexpected failure releasing resource"));
113                 *dev = makedev(CDEV_MAJOR, unit2minor(u));
114                 if ((*dev)->si_flags & SI_NAMED)
115                         return; /* Already make_dev()d */
116         } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
117                 return; /* Don't recognise the name */
118
119         *dev = make_dev(&tun_cdevsw, unit2minor(u),
120             UID_ROOT, GID_WHEEL, 0600, "tun%d", u);
121
122         /*
123          * All devices depend on tunbasedev so that we can simply
124          * destroy_dev() this device at module unload time to get
125          * rid of all our make_dev()d resources.
126          */
127         if (tunbasedev == NOUDEV)
128                 tunbasedev = (*dev)->si_udev;
129         else {
130                 (*dev)->si_flags |= SI_CHEAPCLONE;
131                 dev_depends(udev2dev(tunbasedev, 0), *dev);
132         }
133 }
134
135 static int
136 tunmodevent(module_t mod, int type, void *data) 
137 {
138         static eventhandler_tag tag;
139         struct tun_softc *tp;
140         dev_t dev;
141         int err;
142
143         switch (type) { 
144         case MOD_LOAD: 
145                 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
146                 if (tag == NULL)
147                         return (ENOMEM);
148                 if (!devfs_present) {
149                         err = cdevsw_add(&tun_cdevsw);
150                         if (err != 0) {
151                                 EVENTHANDLER_DEREGISTER(dev_clone, tag);
152                                 return (err);
153                         }
154                 }
155                 tununits->rm_type = RMAN_ARRAY;
156                 tununits->rm_descr = "open if_tun units";
157                 err = rman_init(tununits);
158                 if (err != 0) {
159                         cdevsw_remove(&tun_cdevsw);
160                         EVENTHANDLER_DEREGISTER(dev_clone, tag);
161                         return (err);
162                 }
163                 err = rman_manage_region(tununits, 0, TUN_MAXUNIT);
164                 if (err != 0) {
165                         printf("%s: tununits: rman_manage_region: Failed %d\n",
166                             TUNNAME, err);
167                         rman_fini(tununits);
168                         cdevsw_remove(&tun_cdevsw);
169                         EVENTHANDLER_DEREGISTER(dev_clone, tag);
170                         return (err);
171                 }
172                 break; 
173         case MOD_UNLOAD: 
174                 err = rman_fini(tununits);
175                 if (err != 0)
176                         return (err);
177                 EVENTHANDLER_DEREGISTER(dev_clone, tag);
178
179                 while (tunhead != NULL) {
180                         KASSERT((tunhead->tun_flags & TUN_OPEN) == 0,
181                             ("tununits is out of sync - unit %d",
182                             tunhead->tun_if.if_unit));
183                         tp = tunhead;
184                         dev = makedev(tun_cdevsw.d_maj,
185                             unit2minor(tp->tun_if.if_unit));
186                         KASSERT(dev->si_drv1 == tp, ("Bad makedev result"));
187                         tunhead = tp->next;
188                         bpfdetach(&tp->tun_if);
189                         if_detach(&tp->tun_if);
190                         KASSERT(dev->si_flags & SI_NAMED, ("Missing make_dev"));
191                         free(tp, M_TUN);
192                 }
193
194                 /*
195                  * Destroying tunbasedev results in all of our make_dev()s
196                  * conveniently going away.
197                  */
198                 if (tunbasedev != NOUDEV)
199                         destroy_dev(udev2dev(tunbasedev, 0));
200
201                 if (!devfs_present)
202                         cdevsw_remove(&tun_cdevsw);
203                 break;
204         } 
205         return 0; 
206
207
208 static moduledata_t tun_mod = { 
209         "if_tun", 
210         tunmodevent, 
211         0
212 }; 
213
214 DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
215
216 static void
217 tunstart(struct ifnet *ifp)
218 {
219         struct tun_softc *tp = ifp->if_softc;
220
221         if (tp->tun_flags & TUN_RWAIT) {
222                 tp->tun_flags &= ~TUN_RWAIT;
223                 wakeup((caddr_t)tp);
224         }
225         if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
226                 pgsigio(tp->tun_sigio, SIGIO, 0);
227         selwakeup(&tp->tun_rsel);
228 }
229
230 static void
231 tuncreate(dev_t dev)
232 {
233         struct tun_softc *sc;
234         struct ifnet *ifp;
235
236         if (!(dev->si_flags & SI_NAMED))
237                 dev = make_dev(&tun_cdevsw, minor(dev),
238                     UID_UUCP, GID_DIALER, 0600, "tun%d", dev2unit(dev));
239
240         MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
241         sc->tun_flags = TUN_INITED;
242         sc->next = tunhead;
243         tunhead = sc;
244
245         ifp = &sc->tun_if;
246         ifp->if_unit = dev2unit(dev);
247         ifp->if_name = TUNNAME;
248         ifp->if_mtu = TUNMTU;
249         ifp->if_ioctl = tunifioctl;
250         ifp->if_output = tunoutput;
251         ifp->if_start = tunstart;
252         ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
253         ifp->if_type = IFT_PPP;
254         ifp->if_snd.ifq_maxlen = ifqmaxlen;
255         ifp->if_softc = sc;
256         if_attach(ifp);
257         bpfattach(ifp, DLT_NULL, sizeof(u_int));
258         dev->si_drv1 = sc;
259 }
260
261 static int
262 tunopen(dev_t dev, int flag, int mode, struct thread *td)
263 {
264         struct resource *r;
265         struct ifnet    *ifp;
266         struct tun_softc *tp;
267         int unit;
268
269         unit = dev2unit(dev);
270         if (unit > TUN_MAXUNIT)
271                 return (ENXIO);
272
273         r = rman_reserve_resource(tununits, unit, unit, 1,
274             RF_ALLOCATED | RF_ACTIVE, NULL);
275         if (r == NULL)
276                 return (EBUSY);
277
278         dev->si_flags &= ~SI_CHEAPCLONE;
279
280         tp = dev->si_drv1;
281         if (!tp) {
282                 tuncreate(dev);
283                 tp = dev->si_drv1;
284         }
285         KASSERT(!(tp->tun_flags & TUN_OPEN), ("Resource & flags out-of-sync"));
286         tp->r_unit = r;
287         tp->tun_pid = td->td_proc->p_pid;
288         ifp = &tp->tun_if;
289         tp->tun_flags |= TUN_OPEN;
290         TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
291
292         return (0);
293 }
294
295 /*
296  * tunclose - close the device - mark i/f down & delete
297  * routing info
298  */
299 static  int
300 tunclose(dev_t dev, int foo, int bar, struct thread *td)
301 {
302         struct tun_softc *tp;
303         struct ifnet *ifp;
304         int s;
305         int err;
306
307         tp = dev->si_drv1;
308         ifp = &tp->tun_if;
309
310         KASSERT(tp->r_unit, ("Unit %d not marked open", ifp->if_unit));
311         tp->tun_flags &= ~TUN_OPEN;
312         tp->tun_pid = 0;
313
314         /*
315          * junk all pending output
316          */
317         IF_DRAIN(&ifp->if_snd);
318
319         if (ifp->if_flags & IFF_UP) {
320                 s = splimp();
321                 if_down(ifp);
322                 splx(s);
323         }
324
325         if (ifp->if_flags & IFF_RUNNING) {
326                 register struct ifaddr *ifa;
327
328                 s = splimp();
329                 /* find internet addresses and delete routes */
330                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
331                         if (ifa->ifa_addr->sa_family == AF_INET)
332                                 rtinit(ifa, (int)RTM_DELETE,
333                                     tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
334                 ifp->if_flags &= ~IFF_RUNNING;
335                 splx(s);
336         }
337
338         funsetown(tp->tun_sigio);
339         selwakeup(&tp->tun_rsel);
340
341         TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
342         err = rman_release_resource(tp->r_unit);
343         KASSERT(err == 0, ("Unit %d failed to release", ifp->if_unit));
344
345         return (0);
346 }
347
348 static int
349 tuninit(struct ifnet *ifp)
350 {
351         struct tun_softc *tp = ifp->if_softc;
352         register struct ifaddr *ifa;
353         int error = 0;
354
355         TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
356
357         ifp->if_flags |= IFF_UP | IFF_RUNNING;
358         getmicrotime(&ifp->if_lastchange);
359
360         for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 
361              ifa = TAILQ_NEXT(ifa, ifa_link)) {
362                 if (ifa->ifa_addr == NULL)
363                         error = EFAULT;
364                         /* XXX: Should maybe return straight off? */
365                 else {
366 #ifdef INET
367                         if (ifa->ifa_addr->sa_family == AF_INET) {
368                             struct sockaddr_in *si;
369
370                             si = (struct sockaddr_in *)ifa->ifa_addr;
371                             if (si->sin_addr.s_addr)
372                                     tp->tun_flags |= TUN_IASET;
373
374                             si = (struct sockaddr_in *)ifa->ifa_dstaddr;
375                             if (si && si->sin_addr.s_addr)
376                                     tp->tun_flags |= TUN_DSTADDR;
377                         }
378 #endif
379                 }
380         }
381         return (error);
382 }
383
384 /*
385  * Process an ioctl request.
386  */
387 int
388 tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
389 {
390         struct ifreq *ifr = (struct ifreq *)data;
391         struct tun_softc *tp = ifp->if_softc;
392         struct ifstat *ifs;
393         int             error = 0, s;
394
395         s = splimp();
396         switch(cmd) {
397         case SIOCGIFSTATUS:
398                 ifs = (struct ifstat *)data;
399                 if (tp->tun_pid)
400                         sprintf(ifs->ascii + strlen(ifs->ascii),
401                             "\tOpened by PID %d\n", tp->tun_pid);
402                 break;
403         case SIOCSIFADDR:
404                 error = tuninit(ifp);
405                 TUNDEBUG("%s%d: address set, error=%d\n",
406                          ifp->if_name, ifp->if_unit, error);
407                 break;
408         case SIOCSIFDSTADDR:
409                 error = tuninit(ifp);
410                 TUNDEBUG("%s%d: destination address set, error=%d\n",
411                          ifp->if_name, ifp->if_unit, error);
412                 break;
413         case SIOCSIFMTU:
414                 ifp->if_mtu = ifr->ifr_mtu;
415                 TUNDEBUG("%s%d: mtu set\n", ifp->if_name, ifp->if_unit);
416                 break;
417         case SIOCSIFFLAGS:
418         case SIOCADDMULTI:
419         case SIOCDELMULTI:
420                 break;
421         default:
422                 error = EINVAL;
423         }
424         splx(s);
425         return (error);
426 }
427
428 /*
429  * tunoutput - queue packets from higher level ready to put out.
430  */
431 int
432 tunoutput(
433         struct ifnet *ifp,
434         struct mbuf *m0,
435         struct sockaddr *dst,
436         struct rtentry *rt)
437 {
438         struct tun_softc *tp = ifp->if_softc;
439
440         TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
441
442         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
443                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
444                           ifp->if_unit, tp->tun_flags);
445                 m_freem (m0);
446                 return (EHOSTDOWN);
447         }
448
449         /* BPF write needs to be handled specially */
450         if (dst->sa_family == AF_UNSPEC) {
451                 dst->sa_family = *(mtod(m0, int *));
452                 m0->m_len -= sizeof(int);
453                 m0->m_pkthdr.len -= sizeof(int);
454                 m0->m_data += sizeof(int);
455         }
456
457         if (ifp->if_bpf) {
458                 /*
459                  * We need to prepend the address family as
460                  * a four byte field.  Cons up a dummy header
461                  * to pacify bpf.  This is safe because bpf
462                  * will only read from the mbuf (i.e., it won't
463                  * try to free it or keep a pointer to it).
464                  */
465                 struct mbuf m;
466                 uint32_t af = dst->sa_family;
467
468                 m.m_next = m0;
469                 m.m_len = 4;
470                 m.m_data = (char *)&af;
471
472                 bpf_mtap(ifp, &m);
473         }
474
475         /* prepend sockaddr? this may abort if the mbuf allocation fails */
476         if (tp->tun_flags & TUN_LMODE) {
477                 /* allocate space for sockaddr */
478                 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
479
480                 /* if allocation failed drop packet */
481                 if (m0 == NULL) {
482                         ifp->if_iqdrops++;
483                         ifp->if_oerrors++;
484                         return (ENOBUFS);
485                 } else {
486                         bcopy(dst, m0->m_data, dst->sa_len);
487                 }
488         }
489
490         if (tp->tun_flags & TUN_IFHEAD) {
491                 /* Prepend the address family */
492                 M_PREPEND(m0, 4, M_DONTWAIT);
493
494                 /* if allocation failed drop packet */
495                 if (m0 == NULL) {
496                         ifp->if_iqdrops++;
497                         ifp->if_oerrors++;
498                         return (ENOBUFS);
499                 } else
500                         *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
501         } else {
502 #ifdef INET
503                 if (dst->sa_family != AF_INET)
504 #endif
505                 {
506                         m_freem(m0);
507                         return (EAFNOSUPPORT);
508                 }
509         }
510
511         if (! IF_HANDOFF(&ifp->if_snd, m0, ifp)) {
512                 ifp->if_collisions++;
513                 return (ENOBUFS);
514         }
515         ifp->if_opackets++;
516         return (0);
517 }
518
519 /*
520  * the cdevsw interface is now pretty minimal.
521  */
522 static  int
523 tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
524 {
525         int             s;
526         int             error;
527         struct tun_softc *tp = dev->si_drv1;
528         struct tuninfo *tunp;
529
530         switch (cmd) {
531         case TUNSIFINFO:
532                 tunp = (struct tuninfo *)data;
533                 if (tunp->mtu < IF_MINMTU)
534                         return (EINVAL);
535                 if (tp->tun_if.if_mtu != tunp->mtu
536                 && (error = suser(td)) != 0)
537                         return (error);
538                 tp->tun_if.if_mtu = tunp->mtu;
539                 tp->tun_if.if_type = tunp->type;
540                 tp->tun_if.if_baudrate = tunp->baudrate;
541                 break;
542         case TUNGIFINFO:
543                 tunp = (struct tuninfo *)data;
544                 tunp->mtu = tp->tun_if.if_mtu;
545                 tunp->type = tp->tun_if.if_type;
546                 tunp->baudrate = tp->tun_if.if_baudrate;
547                 break;
548         case TUNSDEBUG:
549                 tundebug = *(int *)data;
550                 break;
551         case TUNGDEBUG:
552                 *(int *)data = tundebug;
553                 break;
554         case TUNSLMODE:
555                 if (*(int *)data) {
556                         tp->tun_flags |= TUN_LMODE;
557                         tp->tun_flags &= ~TUN_IFHEAD;
558                 } else
559                         tp->tun_flags &= ~TUN_LMODE;
560                 break;
561         case TUNSIFHEAD:
562                 if (*(int *)data) {
563                         tp->tun_flags |= TUN_IFHEAD;
564                         tp->tun_flags &= ~TUN_LMODE;
565                 } else 
566                         tp->tun_flags &= ~TUN_IFHEAD;
567                 break;
568         case TUNGIFHEAD:
569                 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
570                 break;
571         case TUNSIFMODE:
572                 /* deny this if UP */
573                 if (tp->tun_if.if_flags & IFF_UP)
574                         return(EBUSY);
575
576                 switch (*(int *)data & ~IFF_MULTICAST) {
577                 case IFF_POINTOPOINT:
578                 case IFF_BROADCAST:
579                         tp->tun_if.if_flags &=
580                             ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
581                         tp->tun_if.if_flags |= *(int *)data;
582                         break;
583                 default:
584                         return(EINVAL);
585                 }
586                 break;
587         case TUNSIFPID:
588                 tp->tun_pid = curthread->td_proc->p_pid;
589                 break;
590         case FIONBIO:
591                 break;
592         case FIOASYNC:
593                 if (*(int *)data)
594                         tp->tun_flags |= TUN_ASYNC;
595                 else
596                         tp->tun_flags &= ~TUN_ASYNC;
597                 break;
598         case FIONREAD:
599                 s = splimp();
600                 if (tp->tun_if.if_snd.ifq_head) {
601                         struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
602                         for( *(int *)data = 0; mb != 0; mb = mb->m_next) 
603                                 *(int *)data += mb->m_len;
604                 } else
605                         *(int *)data = 0;
606                 splx(s);
607                 break;
608         case FIOSETOWN:
609                 return (fsetown(*(int *)data, &tp->tun_sigio));
610
611         case FIOGETOWN:
612                 *(int *)data = fgetown(tp->tun_sigio);
613                 return (0);
614
615         /* This is deprecated, FIOSETOWN should be used instead. */
616         case TIOCSPGRP:
617                 return (fsetown(-(*(int *)data), &tp->tun_sigio));
618
619         /* This is deprecated, FIOGETOWN should be used instead. */
620         case TIOCGPGRP:
621                 *(int *)data = -fgetown(tp->tun_sigio);
622                 return (0);
623
624         default:
625                 return (ENOTTY);
626         }
627         return (0);
628 }
629
630 /*
631  * The cdevsw read interface - reads a packet at a time, or at
632  * least as much of a packet as can be read.
633  */
634 static  int
635 tunread(dev_t dev, struct uio *uio, int flag)
636 {
637         struct tun_softc *tp = dev->si_drv1;
638         struct ifnet    *ifp = &tp->tun_if;
639         struct mbuf     *m;
640         int             error=0, len, s;
641
642         TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
643         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
644                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
645                           ifp->if_unit, tp->tun_flags);
646                 return (EHOSTDOWN);
647         }
648
649         tp->tun_flags &= ~TUN_RWAIT;
650
651         s = splimp();
652         do {
653                 IF_DEQUEUE(&ifp->if_snd, m);
654                 if (m == NULL) {
655                         if (flag & IO_NDELAY) {
656                                 splx(s);
657                                 return (EWOULDBLOCK);
658                         }
659                         tp->tun_flags |= TUN_RWAIT;
660                         if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
661                                         "tunread", 0)) != 0) {
662                                 splx(s);
663                                 return (error);
664                         }
665                 }
666         } while (m == NULL);
667         splx(s);
668
669         while (m && uio->uio_resid > 0 && error == 0) {
670                 len = min(uio->uio_resid, m->m_len);
671                 if (len != 0)
672                         error = uiomove(mtod(m, caddr_t), len, uio);
673                 m = m_free(m);
674         }
675
676         if (m) {
677                 TUNDEBUG("%s%d: Dropping mbuf\n", ifp->if_name, ifp->if_unit);
678                 m_freem(m);
679         }
680         return (error);
681 }
682
683 /*
684  * the cdevsw write interface - an atomic write is a packet - or else!
685  */
686 static  int
687 tunwrite(dev_t dev, struct uio *uio, int flag)
688 {
689         struct tun_softc *tp = dev->si_drv1;
690         struct ifnet    *ifp = &tp->tun_if;
691         struct mbuf     *top, **mp, *m;
692         int             error=0, tlen, mlen;
693         uint32_t        family;
694
695         TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
696
697         if (uio->uio_resid == 0)
698                 return (0);
699
700         if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
701                 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
702                     uio->uio_resid);
703                 return (EIO);
704         }
705         tlen = uio->uio_resid;
706
707         /* get a header mbuf */
708         MGETHDR(m, M_DONTWAIT, MT_DATA);
709         if (m == NULL)
710                 return (ENOBUFS);
711         mlen = MHLEN;
712
713         top = 0;
714         mp = &top;
715         while (error == 0 && uio->uio_resid > 0) {
716                 m->m_len = min(mlen, uio->uio_resid);
717                 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
718                 *mp = m;
719                 mp = &m->m_next;
720                 if (uio->uio_resid > 0) {
721                         MGET (m, M_DONTWAIT, MT_DATA);
722                         if (m == 0) {
723                                 error = ENOBUFS;
724                                 break;
725                         }
726                         mlen = MLEN;
727                 }
728         }
729         if (error) {
730                 if (top)
731                         m_freem (top);
732                 ifp->if_ierrors++;
733                 return (error);
734         }
735
736         top->m_pkthdr.len = tlen;
737         top->m_pkthdr.rcvif = ifp;
738
739         if (ifp->if_bpf) {
740                 if (tp->tun_flags & TUN_IFHEAD) {
741                         /*
742                          * Conveniently, we already have a 4-byte address
743                          * family prepended to our packet !
744                          * Inconveniently, it's in the wrong byte order !
745                          */
746                         if ((top = m_pullup(top, sizeof(family))) == NULL)
747                                 return (ENOBUFS);
748                         *mtod(top, u_int32_t *) =
749                             ntohl(*mtod(top, u_int32_t *));
750                         bpf_mtap(ifp, top);
751                         *mtod(top, u_int32_t *) =
752                             htonl(*mtod(top, u_int32_t *));
753                 } else {
754                         /*
755                          * We need to prepend the address family as
756                          * a four byte field.  Cons up a dummy header
757                          * to pacify bpf.  This is safe because bpf
758                          * will only read from the mbuf (i.e., it won't
759                          * try to free it or keep a pointer to it).
760                          */
761                         struct mbuf m;
762                         uint32_t af = AF_INET;
763
764                         m.m_next = top;
765                         m.m_len = 4;
766                         m.m_data = (char *)&af;
767
768                         bpf_mtap(ifp, &m);
769                 }
770         }
771
772         if (tp->tun_flags & TUN_IFHEAD) {
773                 if (top->m_len < sizeof(family) &&
774                     (top = m_pullup(top, sizeof(family))) == NULL)
775                         return (ENOBUFS);
776                 family = ntohl(*mtod(top, u_int32_t *));
777                 m_adj(top, sizeof(family));
778         } else
779                 family = AF_INET;
780
781         ifp->if_ibytes += top->m_pkthdr.len;
782         ifp->if_ipackets++;
783
784         return (family_enqueue(family, top));
785 }
786
787 /*
788  * tunpoll - the poll interface, this is only useful on reads
789  * really. The write detect always returns true, write never blocks
790  * anyway, it either accepts the packet or drops it.
791  */
792 static  int
793 tunpoll(dev_t dev, int events, struct thread *td)
794 {
795         int             s;
796         struct tun_softc *tp = dev->si_drv1;
797         struct ifnet    *ifp = &tp->tun_if;
798         int             revents = 0;
799
800         s = splimp();
801         TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
802
803         if (events & (POLLIN | POLLRDNORM)) {
804                 if (ifp->if_snd.ifq_len > 0) {
805                         TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
806                             ifp->if_unit, ifp->if_snd.ifq_len);
807                         revents |= events & (POLLIN | POLLRDNORM);
808                 } else {
809                         TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
810                             ifp->if_unit);
811                         selrecord(td, &tp->tun_rsel);
812                 }
813         }
814         if (events & (POLLOUT | POLLWRNORM))
815                 revents |= events & (POLLOUT | POLLWRNORM);
816
817         splx(s);
818         return (revents);
819 }