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