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