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