]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_tun.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[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/socket.h>
26 #include <sys/filio.h>
27 #include <sys/sockio.h>
28 #include <sys/ttycom.h>
29 #include <sys/poll.h>
30 #include <sys/signalvar.h>
31 #include <sys/filedesc.h>
32 #include <sys/kernel.h>
33 #include <sys/sysctl.h>
34 #include <sys/conf.h>
35 #include <sys/uio.h>
36 #include <sys/vnode.h>
37 #include <sys/malloc.h>
38
39 #include <net/if.h>
40 #include <net/route.h>
41 #include <net/intrq.h>
42
43 #ifdef INET
44 #include <netinet/in.h>
45 #endif
46
47 #include <net/bpf.h>
48
49 #include <net/if_tunvar.h>
50 #include <net/if_tun.h>
51
52 static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface");
53
54 static void tunattach __P((void *));
55 PSEUDO_SET(tunattach, if_tun);
56
57 static void tuncreate __P((dev_t dev));
58
59 #define TUNDEBUG        if (tundebug) printf
60 static int tundebug = 0;
61 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
62
63 static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
64             struct rtentry *rt));
65 static int tunifioctl __P((struct ifnet *, u_long, caddr_t));
66 static int tuninit __P((struct ifnet *));
67
68 static  d_open_t        tunopen;
69 static  d_close_t       tunclose;
70 static  d_read_t        tunread;
71 static  d_write_t       tunwrite;
72 static  d_ioctl_t       tunioctl;
73 static  d_poll_t        tunpoll;
74
75 #define CDEV_MAJOR 52
76 static struct cdevsw tun_cdevsw = {
77         /* open */      tunopen,
78         /* close */     tunclose,
79         /* read */      tunread,
80         /* write */     tunwrite,
81         /* ioctl */     tunioctl,
82         /* poll */      tunpoll,
83         /* mmap */      nommap,
84         /* strategy */  nostrategy,
85         /* name */      "tun",
86         /* maj */       CDEV_MAJOR,
87         /* dump */      nodump,
88         /* psize */     nopsize,
89         /* flags */     0,
90         /* bmaj */      -1
91 };
92
93 static void
94 tunattach(dummy)
95         void *dummy;
96 {
97
98         cdevsw_add(&tun_cdevsw);
99 }
100
101 static void
102 tuncreate(dev)
103         dev_t dev;
104 {
105         struct tun_softc *sc;
106         struct ifnet *ifp;
107
108         dev = make_dev(&tun_cdevsw, minor(dev),
109             UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
110
111         MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK);
112         bzero(sc, sizeof *sc);
113         sc->tun_flags = TUN_INITED;
114
115         ifp = &sc->tun_if;
116         ifp->if_unit = lminor(dev);
117         ifp->if_name = "tun";
118         ifp->if_mtu = TUNMTU;
119         ifp->if_ioctl = tunifioctl;
120         ifp->if_output = tunoutput;
121         ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
122         ifp->if_snd.ifq_maxlen = ifqmaxlen;
123         ifp->if_softc = sc;
124         if_attach(ifp);
125         bpfattach(ifp, DLT_NULL, sizeof(u_int));
126         dev->si_drv1 = sc;
127 }
128
129 /*
130  * tunnel open - must be superuser & the device must be
131  * configured in
132  */
133 static  int
134 tunopen(dev, flag, mode, p)
135         dev_t   dev;
136         int     flag, mode;
137         struct proc *p;
138 {
139         struct ifnet    *ifp;
140         struct tun_softc *tp;
141         register int    error;
142
143         error = suser(p);
144         if (error)
145                 return (error);
146
147         tp = dev->si_drv1;
148         if (!tp) {
149                 tuncreate(dev);
150                 tp = dev->si_drv1;
151         }
152         if (tp->tun_flags & TUN_OPEN)
153                 return EBUSY;
154         tp->tun_pid = p->p_pid;
155         ifp = &tp->tun_if;
156         tp->tun_flags |= TUN_OPEN;
157         TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
158         return (0);
159 }
160
161 /*
162  * tunclose - close the device - mark i/f down & delete
163  * routing info
164  */
165 static  int
166 tunclose(dev, foo, bar, p)
167         dev_t dev;
168         int foo;
169         int bar;
170         struct proc *p;
171 {
172         register int    s;
173         struct tun_softc *tp;
174         struct ifnet    *ifp;
175         struct mbuf     *m;
176
177         tp = dev->si_drv1;
178         ifp = &tp->tun_if;
179
180         tp->tun_flags &= ~TUN_OPEN;
181         tp->tun_pid = 0;
182
183         /*
184          * junk all pending output
185          */
186         do {
187                 s = splimp();
188                 IF_DEQUEUE(&ifp->if_snd, m);
189                 splx(s);
190                 if (m)
191                         m_freem(m);
192         } while (m);
193
194         if (ifp->if_flags & IFF_UP) {
195                 s = splimp();
196                 if_down(ifp);
197                 splx(s);
198         }
199
200         if (ifp->if_flags & IFF_RUNNING) {
201                 register struct ifaddr *ifa;
202
203                 s = splimp();
204                 /* find internet addresses and delete routes */
205                 for (ifa = ifp->if_addrhead.tqh_first; ifa;
206                     ifa = ifa->ifa_link.tqe_next)
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         register struct ifaddr *ifa;
227
228         TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
229
230         ifp->if_flags |= IFF_UP | IFF_RUNNING;
231         getmicrotime(&ifp->if_lastchange);
232
233         for (ifa = ifp->if_addrhead.tqh_first; ifa; 
234              ifa = ifa->ifa_link.tqe_next) {
235 #ifdef INET
236                 if (ifa->ifa_addr->sa_family == AF_INET) {
237                     struct sockaddr_in *si;
238
239                     si = (struct sockaddr_in *)ifa->ifa_addr;
240                     if (si && si->sin_addr.s_addr)
241                             tp->tun_flags |= TUN_IASET;
242
243                     si = (struct sockaddr_in *)ifa->ifa_dstaddr;
244                     if (si && si->sin_addr.s_addr)
245                             tp->tun_flags |= TUN_DSTADDR;
246                 }
247 #endif
248         }
249         return 0;
250 }
251
252 /*
253  * Process an ioctl request.
254  */
255 int
256 tunifioctl(ifp, cmd, data)
257         struct ifnet *ifp;
258         u_long  cmd;
259         caddr_t data;
260 {
261         struct ifreq *ifr = (struct ifreq *)data;
262         struct tun_softc *tp = ifp->if_softc;
263         struct ifstat *ifs;
264         int             error = 0, s;
265
266         s = splimp();
267         switch(cmd) {
268         case SIOCGIFSTATUS:
269                 ifs = (struct ifstat *)data;
270                 if (tp->tun_pid)
271                         sprintf(ifs->ascii + strlen(ifs->ascii),
272                             "\tOpened by PID %d\n", tp->tun_pid);
273                 return(0);
274         case SIOCSIFADDR:
275                 tuninit(ifp);
276                 TUNDEBUG("%s%d: address set\n",
277                          ifp->if_name, ifp->if_unit);
278                 break;
279         case SIOCSIFDSTADDR:
280                 tuninit(ifp);
281                 TUNDEBUG("%s%d: destination address set\n",
282                          ifp->if_name, ifp->if_unit);
283                 break;
284         case SIOCSIFMTU:
285                 ifp->if_mtu = ifr->ifr_mtu;
286                 TUNDEBUG("%s%d: mtu set\n",
287                          ifp->if_name, ifp->if_unit);
288                 break;
289         case SIOCADDMULTI:
290         case SIOCDELMULTI:
291                 break;
292
293
294         default:
295                 error = EINVAL;
296         }
297         splx(s);
298         return (error);
299 }
300
301 /*
302  * tunoutput - queue packets from higher level ready to put out.
303  */
304 int
305 tunoutput(ifp, m0, dst, rt)
306         struct ifnet   *ifp;
307         struct mbuf    *m0;
308         struct sockaddr *dst;
309         struct rtentry *rt;
310 {
311         struct tun_softc *tp = ifp->if_softc;
312         int             s;
313
314         TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
315
316         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
317                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
318                           ifp->if_unit, tp->tun_flags);
319                 m_freem (m0);
320                 return EHOSTDOWN;
321         }
322
323         /* BPF write needs to be handled specially */
324         if (dst->sa_family == AF_UNSPEC) {
325                 dst->sa_family = *(mtod(m0, int *));
326                 m0->m_len -= sizeof(int);
327                 m0->m_pkthdr.len -= sizeof(int);
328                 m0->m_data += sizeof(int);
329         }
330
331         if (ifp->if_bpf) {
332                 /*
333                  * We need to prepend the address family as
334                  * a four byte field.  Cons up a dummy header
335                  * to pacify bpf.  This is safe because bpf
336                  * will only read from the mbuf (i.e., it won't
337                  * try to free it or keep a pointer to it).
338                  */
339                 struct mbuf m;
340                 u_int af = dst->sa_family;
341
342                 m.m_next = m0;
343                 m.m_len = 4;
344                 m.m_data = (char *)&af;
345
346                 bpf_mtap(ifp, &m);
347         }
348
349         /* prepend sockaddr? this may abort if the mbuf allocation fails */
350         if (tp->tun_flags & TUN_LMODE) {
351                 /* allocate space for sockaddr */
352                 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
353
354                 /* if allocation failed drop packet */
355                 if (m0 == NULL){
356                         s = splimp();   /* spl on queue manipulation */
357                         IF_DROP(&ifp->if_snd);
358                         splx(s);
359                         ifp->if_oerrors++;
360                         return (ENOBUFS);
361                 } else {
362                         bcopy(dst, m0->m_data, dst->sa_len);
363                 }
364         }
365
366         if (tp->tun_flags & TUN_IFHEAD) {
367                 /* Prepend the address family */
368                 M_PREPEND(m0, 4, M_DONTWAIT);
369
370                 /* if allocation failed drop packet */
371                 if (m0 == NULL){
372                         s = splimp();   /* spl on queue manipulation */
373                         IF_DROP(&ifp->if_snd);
374                         splx(s);
375                         ifp->if_oerrors++;
376                         return ENOBUFS;
377                 } else
378                         *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
379         } else {
380 #ifdef INET
381                 if (dst->sa_family != AF_INET)
382 #endif
383                 {
384                         m_freem(m0);
385                         return EAFNOSUPPORT;
386                 }
387         }
388
389         s = splimp();
390         if (IF_QFULL(&ifp->if_snd)) {
391                 IF_DROP(&ifp->if_snd);
392                 m_freem(m0);
393                 splx(s);
394                 ifp->if_collisions++;
395                 return ENOBUFS;
396         }
397         ifp->if_obytes += m0->m_pkthdr.len;
398         IF_ENQUEUE(&ifp->if_snd, m0);
399         splx(s);
400         ifp->if_opackets++;
401
402         if (tp->tun_flags & TUN_RWAIT) {
403                 tp->tun_flags &= ~TUN_RWAIT;
404                 wakeup((caddr_t)tp);
405         }
406         if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
407                 pgsigio(tp->tun_sigio, SIGIO, 0);
408         selwakeup(&tp->tun_rsel);
409         return 0;
410 }
411
412 /*
413  * the cdevsw interface is now pretty minimal.
414  */
415 static  int
416 tunioctl(dev, cmd, data, flag, p)
417         dev_t           dev;
418         u_long          cmd;
419         caddr_t         data;
420         int             flag;
421         struct proc     *p;
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) {
471                 case IFF_POINTOPOINT:
472                         tp->tun_if.if_flags |= IFF_POINTOPOINT;
473                         tp->tun_if.if_flags &= ~IFF_BROADCAST;
474                         break;
475                 case IFF_BROADCAST:
476                         tp->tun_if.if_flags &= ~IFF_POINTOPOINT;
477                         tp->tun_if.if_flags |= IFF_BROADCAST;
478                         break;
479                 default:
480                         return(EINVAL);
481                 }
482                 break;
483         case TUNSIFPID:
484                 tp->tun_pid = curproc->p_pid;
485                 break;
486         case FIONBIO:
487                 break;
488         case FIOASYNC:
489                 if (*(int *)data)
490                         tp->tun_flags |= TUN_ASYNC;
491                 else
492                         tp->tun_flags &= ~TUN_ASYNC;
493                 break;
494         case FIONREAD:
495                 s = splimp();
496                 if (tp->tun_if.if_snd.ifq_head) {
497                         struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
498                         for( *(int *)data = 0; mb != 0; mb = mb->m_next) 
499                                 *(int *)data += mb->m_len;
500                 } else
501                         *(int *)data = 0;
502                 splx(s);
503                 break;
504         case FIOSETOWN:
505                 return (fsetown(*(int *)data, &tp->tun_sigio));
506
507         case FIOGETOWN:
508                 *(int *)data = fgetown(tp->tun_sigio);
509                 return (0);
510
511         /* This is deprecated, FIOSETOWN should be used instead. */
512         case TIOCSPGRP:
513                 return (fsetown(-(*(int *)data), &tp->tun_sigio));
514
515         /* This is deprecated, FIOGETOWN should be used instead. */
516         case TIOCGPGRP:
517                 *(int *)data = -fgetown(tp->tun_sigio);
518                 return (0);
519
520         default:
521                 return (ENOTTY);
522         }
523         return (0);
524 }
525
526 /*
527  * The cdevsw read interface - reads a packet at a time, or at
528  * least as much of a packet as can be read.
529  */
530 static  int
531 tunread(dev, uio, flag)
532         dev_t dev;
533         struct uio *uio;
534         int flag;
535 {
536         struct tun_softc *tp = dev->si_drv1;
537         struct ifnet    *ifp = &tp->tun_if;
538         struct mbuf     *m, *m0;
539         int             error=0, len, s;
540
541         TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
542         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
543                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
544                           ifp->if_unit, tp->tun_flags);
545                 return EHOSTDOWN;
546         }
547
548         tp->tun_flags &= ~TUN_RWAIT;
549
550         s = splimp();
551         do {
552                 IF_DEQUEUE(&ifp->if_snd, m0);
553                 if (m0 == 0) {
554                         if (flag & IO_NDELAY) {
555                                 splx(s);
556                                 return EWOULDBLOCK;
557                         }
558                         tp->tun_flags |= TUN_RWAIT;
559                         if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
560                                         "tunread", 0)) != 0) {
561                                 splx(s);
562                                 return error;
563                         }
564                 }
565         } while (m0 == 0);
566         splx(s);
567
568         while (m0 && uio->uio_resid > 0 && error == 0) {
569                 len = min(uio->uio_resid, m0->m_len);
570                 if (len == 0)
571                         break;
572                 error = uiomove(mtod(m0, caddr_t), len, uio);
573                 MFREE(m0, m);
574                 m0 = m;
575         }
576
577         if (m0) {
578                 TUNDEBUG("Dropping mbuf\n");
579                 m_freem(m0);
580         }
581         return error;
582 }
583
584 /*
585  * the cdevsw write interface - an atomic write is a packet - or else!
586  */
587 static  int
588 tunwrite(dev, uio, flag)
589         dev_t dev;
590         struct uio *uio;
591         int flag;
592 {
593         struct tun_softc *tp = dev->si_drv1;
594         struct ifnet    *ifp = &tp->tun_if;
595         struct mbuf     *top, **mp, *m;
596         int             error=0, tlen, mlen;
597         u_int32_t       family;
598
599         TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
600
601         if (uio->uio_resid == 0)
602                 return 0;
603
604         if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
605                 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
606                     uio->uio_resid);
607                 return EIO;
608         }
609         tlen = uio->uio_resid;
610
611         /* get a header mbuf */
612         MGETHDR(m, M_DONTWAIT, MT_DATA);
613         if (m == NULL)
614                 return ENOBUFS;
615         mlen = MHLEN;
616
617         top = 0;
618         mp = &top;
619         while (error == 0 && uio->uio_resid > 0) {
620                 m->m_len = min(mlen, uio->uio_resid);
621                 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
622                 *mp = m;
623                 mp = &m->m_next;
624                 if (uio->uio_resid > 0) {
625                         MGET (m, M_DONTWAIT, MT_DATA);
626                         if (m == 0) {
627                                 error = ENOBUFS;
628                                 break;
629                         }
630                         mlen = MLEN;
631                 }
632         }
633         if (error) {
634                 if (top)
635                         m_freem (top);
636                 ifp->if_ierrors++;
637                 return error;
638         }
639
640         top->m_pkthdr.len = tlen;
641         top->m_pkthdr.rcvif = ifp;
642
643         if (ifp->if_bpf) {
644                 if (tp->tun_flags & TUN_IFHEAD)
645                         /*
646                          * Conveniently, we already have a 4-byte address
647                          * family prepended to our packet !
648                          */
649                         bpf_mtap(ifp, top);
650                 else {
651                         /*
652                          * We need to prepend the address family as
653                          * a four byte field.  Cons up a dummy header
654                          * to pacify bpf.  This is safe because bpf
655                          * will only read from the mbuf (i.e., it won't
656                          * try to free it or keep a pointer to it).
657                          */
658                         struct mbuf m;
659                         u_int af = AF_INET;
660
661                         m.m_next = top;
662                         m.m_len = 4;
663                         m.m_data = (char *)&af;
664
665                         bpf_mtap(ifp, &m);
666                 }
667         }
668
669         if (tp->tun_flags & TUN_IFHEAD) {
670                 if (top->m_len < sizeof(family) &&
671                     (top = m_pullup(top, sizeof(family))) == NULL)
672                                 return ENOBUFS;
673                 family = ntohl(*mtod(top, u_int32_t *));
674                 m_adj(top, sizeof(family));
675         } else
676                 family = AF_INET;
677
678         ifp->if_ibytes += top->m_pkthdr.len;
679         ifp->if_ipackets++;
680
681         return family_enqueue(family, top);
682 }
683
684 /*
685  * tunpoll - the poll interface, this is only useful on reads
686  * really. The write detect always returns true, write never blocks
687  * anyway, it either accepts the packet or drops it.
688  */
689 static  int
690 tunpoll(dev, events, p)
691         dev_t dev;
692         int events;
693         struct proc *p;
694 {
695         int             s;
696         struct tun_softc *tp = dev->si_drv1;
697         struct ifnet    *ifp = &tp->tun_if;
698         int             revents = 0;
699
700         s = splimp();
701         TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
702
703         if (events & (POLLIN | POLLRDNORM)) {
704                 if (ifp->if_snd.ifq_len > 0) {
705                         TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
706                             ifp->if_unit, ifp->if_snd.ifq_len);
707                         revents |= events & (POLLIN | POLLRDNORM);
708                 } else {
709                         TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
710                             ifp->if_unit);
711                         selrecord(p, &tp->tun_rsel);
712                 }
713         }
714         if (events & (POLLOUT | POLLWRNORM))
715                 revents |= events & (POLLOUT | POLLWRNORM);
716
717         splx(s);
718         return (revents);
719 }