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