|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
23:
24: /*
25: * Copyright (c) 1988, Julian Onions <[email protected]>
26: * Nottingham University 1987.
27: *
28: * This source may be freely distributed, however I would be interested
29: * in any changes that are made.
30: *
31: * This driver takes packets off the IP i/f and hands them up to a
32: * user process to have its wicked way with. This driver has it's
33: * roots in a similar driver written by Phil Cockcroft (formerly) at
34: * UCL. This driver is based much more on read/write/poll mode of
35: * operation though.
36: */
37:
38: #include "tun.h"
39: #if NTUN > 0
40:
41: #include "opt_devfs.h"
42: #include "opt_inet.h"
43:
44: #include <sys/param.h>
45: #include <sys/proc.h>
46: #include <sys/systm.h>
47: #include <sys/mbuf.h>
48: #include <sys/socket.h>
49: #include <sys/filio.h>
50: #include <sys/sockio.h>
51: #include <sys/ttycom.h>
52: #include <sys/poll.h>
53: #include <sys/signalvar.h>
54: #include <sys/filedesc.h>
55: #include <sys/kernel.h>
56: #include <sys/sysctl.h>
57: #if DEVFS
58: #include <sys/devfsext.h>
59: #endif /*DEVFS*/
60: #include <sys/conf.h>
61: #include <sys/uio.h>
62: #include <sys/vnode.h>
63:
64: #include <net/if.h>
65: #include <net/netisr.h>
66: #include <net/route.h>
67:
68: #if INET
69: #include <netinet/in.h>
70: #include <netinet/in_var.h>
71: #endif
72:
73: #if NS
74: #include <netns/ns.h>
75: #include <netns/ns_if.h>
76: #endif
77:
78: #include "bpfilter.h"
79: #if NBPFILTER > 0
80: #include <net/bpf.h>
81: #endif
82:
83: #include <net/if_tunvar.h>
84: #include <net/if_tun.h>
85:
86: static void tunattach __P((void *));
87: PSEUDO_SET(tunattach, if_tun);
88:
89: #define TUNDEBUG if (tundebug) printf
90: static int tundebug = 0;
91: SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
92:
93: static struct tun_softc tunctl[NTUN];
94:
95: static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
96: struct rtentry *rt));
97: static int tunifioctl __P((struct ifnet *, u_long, caddr_t));
98: static int tuninit __P((int));
99:
100: static d_open_t tunopen;
101: static d_close_t tunclose;
102: static d_read_t tunread;
103: static d_write_t tunwrite;
104: static d_ioctl_t tunioctl;
105: static d_poll_t tunpoll;
106:
107: #define CDEV_MAJOR 52
108: static struct cdevsw tun_cdevsw = {
109: tunopen, tunclose, tunread, tunwrite,
110: tunioctl, nullstop, noreset, nodevtotty,
111: tunpoll, nommap, nostrategy, "tun", NULL, -1
112: };
113:
114:
115: static int tun_devsw_installed;
116: #if DEVFS
117: static void *tun_devfs_token[NTUN];
118: #endif
119:
120: #define minor_val(n) ((((n) & ~0xff) << 8) | ((n) & 0xff))
121: #define dev_val(n) (((n) >> 8) | ((n) & 0xff))
122:
123: static void
124: tunattach(dummy)
125: void *dummy;
126: {
127: register int i;
128: struct ifnet *ifp;
129: dev_t dev;
130:
131: if ( tun_devsw_installed )
132: return;
133: dev = makedev(CDEV_MAJOR, 0);
134: cdevsw_add(&dev, &tun_cdevsw, NULL);
135: tun_devsw_installed = 1;
136: for ( i = 0; i < NTUN; i++ ) {
137: #if DEVFS
138: tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, minor_val(i),
139: DV_CHR, UID_UUCP,
140: GID_DIALER, 0600,
141: "tun%d", i);
142: #endif
143: tunctl[i].tun_flags = TUN_INITED;
144:
145: ifp = &tunctl[i].tun_if;
146: ifp->if_unit = i;
147: ifp->if_name = "tun";
148: ifp->if_family = APPLE_IF_FAM_TUN;
149: ifp->if_mtu = TUNMTU;
150: ifp->if_ioctl = tunifioctl;
151: ifp->if_output = tunoutput;
152: ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
153: ifp->if_snd.ifq_maxlen = ifqmaxlen;
154: if_attach(ifp);
155: #if NBPFILTER > 0
156: bpfattach(ifp, DLT_NULL, sizeof(u_int));
157: #endif
158: }
159: }
160:
161: /*
162: * tunnel open - must be superuser & the device must be
163: * configured in
164: */
165: static int
166: tunopen(dev, flag, mode, p)
167: dev_t dev;
168: int flag, mode;
169: struct proc *p;
170: {
171: struct ifnet *ifp;
172: struct tun_softc *tp;
173: register int unit, error;
174:
175: error = suser(p->p_ucred, &p->p_acflag);
176: if (error)
177: return (error);
178:
179: if ((unit = dev_val(minor(dev))) >= NTUN)
180: return (ENXIO);
181: tp = &tunctl[unit];
182: if (tp->tun_flags & TUN_OPEN)
183: return EBUSY;
184: ifp = &tp->tun_if;
185: tp->tun_flags |= TUN_OPEN;
186: TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
187: return (0);
188: }
189:
190: /*
191: * tunclose - close the device - mark i/f down & delete
192: * routing info
193: */
194: static int
195: tunclose(dev, foo, bar, p)
196: dev_t dev;
197: int foo;
198: int bar;
199: struct proc *p;
200: {
201: register int unit = dev_val(minor(dev)), s;
202: struct tun_softc *tp = &tunctl[unit];
203: struct ifnet *ifp = &tp->tun_if;
204: struct mbuf *m;
205:
206: tp->tun_flags &= ~TUN_OPEN;
207:
208: /*
209: * junk all pending output
210: */
211: do {
212: s = splimp();
213: IF_DEQUEUE(&ifp->if_snd, m);
214: splx(s);
215: if (m)
216: m_freem(m);
217: } while (m);
218:
219: if (ifp->if_flags & IFF_UP) {
220: s = splimp();
221: if_down(ifp);
222: if (ifp->if_flags & IFF_RUNNING) {
223: /* find internet addresses and delete routes */
224: register struct ifaddr *ifa;
225: for (ifa = ifp->if_addrhead.tqh_first; ifa;
226: ifa = ifa->ifa_link.tqe_next) {
227: if (ifa->ifa_addr->sa_family == AF_INET) {
228: rtinit(ifa, (int)RTM_DELETE,
229: tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
230: }
231: }
232: }
233: splx(s);
234: }
235: funsetown(tp->tun_sigio);
236: selwakeup(&tp->tun_rsel);
237:
238: TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
239: return (0);
240: }
241:
242: static int
243: tuninit(unit)
244: int unit;
245: {
246: struct tun_softc *tp = &tunctl[unit];
247: struct ifnet *ifp = &tp->tun_if;
248: register struct ifaddr *ifa;
249:
250: TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
251:
252: ifp->if_flags |= IFF_UP | IFF_RUNNING;
253: getmicrotime(&ifp->if_lastchange);
254:
255: for (ifa = ifp->if_addrhead.tqh_first; ifa;
256: ifa = ifa->ifa_link.tqe_next) {
257: #if INET
258: if (ifa->ifa_addr->sa_family == AF_INET) {
259: struct sockaddr_in *si;
260:
261: si = (struct sockaddr_in *)ifa->ifa_addr;
262: if (si && si->sin_addr.s_addr)
263: tp->tun_flags |= TUN_IASET;
264:
265: si = (struct sockaddr_in *)ifa->ifa_dstaddr;
266: if (si && si->sin_addr.s_addr)
267: tp->tun_flags |= TUN_DSTADDR;
268: }
269: #endif
270: }
271: return 0;
272: }
273:
274: /*
275: * Process an ioctl request.
276: */
277: int
278: tunifioctl(ifp, cmd, data)
279: struct ifnet *ifp;
280: u_long cmd;
281: caddr_t data;
282: {
283: register struct ifreq *ifr = (struct ifreq *)data;
284: int error = 0, s;
285:
286: s = splimp();
287: switch(cmd) {
288: case SIOCSIFADDR:
289: tuninit(ifp->if_unit);
290: TUNDEBUG("%s%d: address set\n",
291: ifp->if_name, ifp->if_unit);
292: break;
293: case SIOCSIFDSTADDR:
294: tuninit(ifp->if_unit);
295: TUNDEBUG("%s%d: destination address set\n",
296: ifp->if_name, ifp->if_unit);
297: break;
298: case SIOCSIFMTU:
299: ifp->if_mtu = ifr->ifr_mtu;
300: TUNDEBUG("%s%d: mtu set\n",
301: ifp->if_name, ifp->if_unit);
302: break;
303: case SIOCADDMULTI:
304: case SIOCDELMULTI:
305: break;
306:
307:
308: default:
309: error = EINVAL;
310: }
311: splx(s);
312: return (error);
313: }
314:
315: /*
316: * tunoutput - queue packets from higher level ready to put out.
317: */
318: int
319: tunoutput(ifp, m0, dst, rt)
320: struct ifnet *ifp;
321: struct mbuf *m0;
322: struct sockaddr *dst;
323: struct rtentry *rt;
324: {
325: struct tun_softc *tp = &tunctl[ifp->if_unit];
326: int s;
327:
328: TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
329:
330: if ((tp->tun_flags & TUN_READY) != TUN_READY) {
331: TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
332: ifp->if_unit, tp->tun_flags);
333: m_freem (m0);
334: return EHOSTDOWN;
335: }
336:
337: #if NBPFILTER > 0
338: /* BPF write needs to be handled specially */
339: if (dst->sa_family == AF_UNSPEC) {
340: dst->sa_family = *(mtod(m0, int *));
341: m0->m_len -= sizeof(int);
342: m0->m_pkthdr.len -= sizeof(int);
343: m0->m_data += sizeof(int);
344: }
345:
346: if (ifp->if_bpf) {
347: /*
348: * We need to prepend the address family as
349: * a four byte field. Cons up a dummy header
350: * to pacify bpf. This is safe because bpf
351: * will only read from the mbuf (i.e., it won't
352: * try to free it or keep a pointer to it).
353: */
354: struct mbuf m;
355: u_int af = dst->sa_family;
356:
357: m.m_next = m0;
358: m.m_len = 4;
359: m.m_data = (char *)⁡
360:
361: bpf_mtap(ifp, &m);
362: }
363: #endif
364:
365: switch(dst->sa_family) {
366: #if INET
367: case AF_INET:
368: s = splimp();
369: if (IF_QFULL(&ifp->if_snd)) {
370: IF_DROP(&ifp->if_snd);
371: m_freem(m0);
372: splx(s);
373: ifp->if_collisions++;
374: return (ENOBUFS);
375: }
376: ifp->if_obytes += m0->m_pkthdr.len;
377: IF_ENQUEUE(&ifp->if_snd, m0);
378: splx(s);
379: ifp->if_opackets++;
380: break;
381: #endif
382: default:
383: m_freem(m0);
384: return EAFNOSUPPORT;
385: }
386:
387: if (tp->tun_flags & TUN_RWAIT) {
388: tp->tun_flags &= ~TUN_RWAIT;
389: wakeup((caddr_t)tp);
390: }
391: if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
392: pgsigio(tp->tun_sigio, SIGIO, 0);
393: selwakeup(&tp->tun_rsel);
394: return 0;
395: }
396:
397: /*
398: * the cdevsw interface is now pretty minimal.
399: */
400: static int
401: tunioctl(dev, cmd, data, flag, p)
402: dev_t dev;
403: u_long cmd;
404: caddr_t data;
405: int flag;
406: struct proc *p;
407: {
408: int unit = dev_val(minor(dev)), s;
409: struct tun_softc *tp = &tunctl[unit];
410: struct tuninfo *tunp;
411:
412: switch (cmd) {
413: case TUNSIFINFO:
414: tunp = (struct tuninfo *)data;
415: tp->tun_if.if_mtu = tunp->mtu;
416: tp->tun_if.if_type = tunp->type;
417: tp->tun_if.if_baudrate = tunp->baudrate;
418: break;
419: case TUNGIFINFO:
420: tunp = (struct tuninfo *)data;
421: tunp->mtu = tp->tun_if.if_mtu;
422: tunp->type = tp->tun_if.if_type;
423: tunp->baudrate = tp->tun_if.if_baudrate;
424: break;
425: case TUNSDEBUG:
426: tundebug = *(int *)data;
427: break;
428: case TUNGDEBUG:
429: *(int *)data = tundebug;
430: break;
431: case FIONBIO:
432: break;
433: case FIOASYNC:
434: if (*(int *)data)
435: tp->tun_flags |= TUN_ASYNC;
436: else
437: tp->tun_flags &= ~TUN_ASYNC;
438: break;
439: case FIONREAD:
440: s = splimp();
441: if (tp->tun_if.if_snd.ifq_head) {
442: struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
443: for( *(int *)data = 0; mb != 0; mb = mb->m_next)
444: *(int *)data += mb->m_len;
445: } else
446: *(int *)data = 0;
447: splx(s);
448: break;
449: case FIOSETOWN:
450: return (fsetown(*(int *)data, &tp->tun_sigio));
451:
452: case FIOGETOWN:
453: *(int *)data = fgetown(tp->tun_sigio);
454: return (0);
455:
456: /* This is deprecated, FIOSETOWN should be used instead. */
457: case TIOCSPGRP:
458: return (fsetown(-(*(int *)data), &tp->tun_sigio));
459:
460: /* This is deprecated, FIOGETOWN should be used instead. */
461: case TIOCGPGRP:
462: *(int *)data = -fgetown(tp->tun_sigio);
463: return (0);
464:
465: default:
466: return (ENOTTY);
467: }
468: return (0);
469: }
470:
471: /*
472: * The cdevsw read interface - reads a packet at a time, or at
473: * least as much of a packet as can be read.
474: */
475: static int
476: tunread(dev, uio, flag)
477: dev_t dev;
478: struct uio *uio;
479: int flag;
480: {
481: int unit = dev_val(minor(dev));
482: struct tun_softc *tp = &tunctl[unit];
483: struct ifnet *ifp = &tp->tun_if;
484: struct mbuf *m, *m0;
485: int error=0, len, s;
486:
487: TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
488: if ((tp->tun_flags & TUN_READY) != TUN_READY) {
489: TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
490: ifp->if_unit, tp->tun_flags);
491: return EHOSTDOWN;
492: }
493:
494: tp->tun_flags &= ~TUN_RWAIT;
495:
496: s = splimp();
497: do {
498: IF_DEQUEUE(&ifp->if_snd, m0);
499: if (m0 == 0) {
500: if (flag & IO_NDELAY) {
501: splx(s);
502: return EWOULDBLOCK;
503: }
504: tp->tun_flags |= TUN_RWAIT;
505: if( error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
506: "tunread", 0)) {
507: splx(s);
508: return error;
509: }
510: }
511: } while (m0 == 0);
512: splx(s);
513:
514: while (m0 && uio->uio_resid > 0 && error == 0) {
515: len = min(uio->uio_resid, m0->m_len);
516: if (len == 0)
517: break;
518: error = uiomove(mtod(m0, caddr_t), len, uio);
519: MFREE(m0, m);
520: m0 = m;
521: }
522:
523: if (m0) {
524: TUNDEBUG("Dropping mbuf\n");
525: m_freem(m0);
526: }
527: return error;
528: }
529:
530: /*
531: * the cdevsw write interface - an atomic write is a packet - or else!
532: */
533: static int
534: tunwrite(dev, uio, flag)
535: dev_t dev;
536: struct uio *uio;
537: int flag;
538: {
539: int unit = dev_val(minor(dev));
540: struct ifnet *ifp = &tunctl[unit].tun_if;
541: struct mbuf *top, **mp, *m;
542: int error=0, s, tlen, mlen;
543:
544: TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
545:
546: if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
547: TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
548: uio->uio_resid);
549: return EIO;
550: }
551: tlen = uio->uio_resid;
552:
553: /* get a header mbuf */
554: MGETHDR(m, M_DONTWAIT, MT_DATA);
555: if (m == NULL)
556: return ENOBUFS;
557: mlen = MHLEN;
558:
559: top = 0;
560: mp = ⊤
561: while (error == 0 && uio->uio_resid > 0) {
562: m->m_len = min(mlen, uio->uio_resid);
563: error = uiomove(mtod (m, caddr_t), m->m_len, uio);
564: *mp = m;
565: mp = &m->m_next;
566: if (uio->uio_resid > 0) {
567: MGET (m, M_DONTWAIT, MT_DATA);
568: if (m == 0) {
569: error = ENOBUFS;
570: break;
571: }
572: mlen = MLEN;
573: }
574: }
575: if (error) {
576: if (top)
577: m_freem (top);
578: return error;
579: }
580:
581: top->m_pkthdr.len = tlen;
582: top->m_pkthdr.rcvif = ifp;
583:
584: #if NBPFILTER > 0
585: if (ifp->if_bpf) {
586: /*
587: * We need to prepend the address family as
588: * a four byte field. Cons up a dummy header
589: * to pacify bpf. This is safe because bpf
590: * will only read from the mbuf (i.e., it won't
591: * try to free it or keep a pointer to it).
592: */
593: struct mbuf m;
594: u_int af = AF_INET;
595:
596: m.m_next = top;
597: m.m_len = 4;
598: m.m_data = (char *)⁡
599:
600: bpf_mtap(ifp, &m);
601: }
602: #endif
603:
604: #if INET
605: s = splimp();
606: if (IF_QFULL (&ipintrq)) {
607: IF_DROP(&ipintrq);
608: splx(s);
609: ifp->if_collisions++;
610: m_freem(top);
611: return ENOBUFS;
612: }
613: IF_ENQUEUE(&ipintrq, top);
614: splx(s);
615: ifp->if_ibytes += tlen;
616: ifp->if_ipackets++;
617: schednetisr(NETISR_IP);
618: #endif
619: return error;
620: }
621:
622: /*
623: * tunpoll - the poll interface, this is only useful on reads
624: * really. The write detect always returns true, write never blocks
625: * anyway, it either accepts the packet or drops it.
626: */
627: static int
628: tunpoll(dev, events, p)
629: dev_t dev;
630: int events;
631: struct proc *p;
632: {
633: int unit = dev_val(minor(dev)), s;
634: struct tun_softc *tp = &tunctl[unit];
635: struct ifnet *ifp = &tp->tun_if;
636: int revents = 0;
637:
638: s = splimp();
639: TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
640:
641: if (events & (POLLIN | POLLRDNORM))
642: if (ifp->if_snd.ifq_len > 0) {
643: TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
644: ifp->if_unit, ifp->if_snd.ifq_len);
645: revents |= events & (POLLIN | POLLRDNORM);
646: } else {
647: TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
648: ifp->if_unit);
649: selrecord(p, &tp->tun_rsel);
650: }
651:
652: if (events & (POLLOUT | POLLWRNORM))
653: revents |= events & (POLLOUT | POLLWRNORM);
654:
655: splx(s);
656: return (revents);
657: }
658:
659:
660: #endif /* NTUN */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.