Deleted Added
full compact
if_tun.c (63358) if_tun.c (64880)
1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
2
3/*
4 * Copyright (c) 1988, Julian Onions <jpo@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 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/poll mode of
14 * operation though.
15 *
1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */
2
3/*
4 * Copyright (c) 1988, Julian Onions <jpo@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 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/poll mode of
14 * operation though.
15 *
16 * $FreeBSD: head/sys/net/if_tun.c 63358 2000-07-17 23:21:42Z brian $
16 * $FreeBSD: head/sys/net/if_tun.c 64880 2000-08-20 21:34:39Z phk $
17 */
18
19#include "opt_inet.h"
17 */
18
19#include "opt_inet.h"
20#include "opt_devfs.h"
20
21#include <sys/param.h>
22#include <sys/proc.h>
23#include <sys/systm.h>
24#include <sys/mbuf.h>
25#include <sys/socket.h>
26#include <sys/filio.h>
27#include <sys/sockio.h>
28#include <sys/ttycom.h>
29#include <sys/poll.h>
30#include <sys/signalvar.h>
31#include <sys/filedesc.h>
32#include <sys/kernel.h>
33#include <sys/sysctl.h>
34#include <sys/conf.h>
35#include <sys/uio.h>
36#include <sys/vnode.h>
37#include <sys/malloc.h>
38
39#include <net/if.h>
40#include <net/if_types.h>
41#include <net/route.h>
42#include <net/intrq.h>
43
44#ifdef INET
45#include <netinet/in.h>
46#endif
47
48#include <net/bpf.h>
49
50#include <net/if_tunvar.h>
51#include <net/if_tun.h>
52
21
22#include <sys/param.h>
23#include <sys/proc.h>
24#include <sys/systm.h>
25#include <sys/mbuf.h>
26#include <sys/socket.h>
27#include <sys/filio.h>
28#include <sys/sockio.h>
29#include <sys/ttycom.h>
30#include <sys/poll.h>
31#include <sys/signalvar.h>
32#include <sys/filedesc.h>
33#include <sys/kernel.h>
34#include <sys/sysctl.h>
35#include <sys/conf.h>
36#include <sys/uio.h>
37#include <sys/vnode.h>
38#include <sys/malloc.h>
39
40#include <net/if.h>
41#include <net/if_types.h>
42#include <net/route.h>
43#include <net/intrq.h>
44
45#ifdef INET
46#include <netinet/in.h>
47#endif
48
49#include <net/bpf.h>
50
51#include <net/if_tunvar.h>
52#include <net/if_tun.h>
53
54#ifdef DEVFS
55#include <sys/eventhandler.h>
56#include <fs/devfs/devfs.h>
57#endif
58
53static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface");
54
55static void tunattach __P((void *));
56PSEUDO_SET(tunattach, if_tun);
57
58static void tuncreate __P((dev_t dev));
59
60#define TUNDEBUG if (tundebug) printf
61static int tundebug = 0;
62SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
63
64static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
65 struct rtentry *rt));
66static int tunifioctl __P((struct ifnet *, u_long, caddr_t));
67static int tuninit __P((struct ifnet *));
68
69static d_open_t tunopen;
70static d_close_t tunclose;
71static d_read_t tunread;
72static d_write_t tunwrite;
73static d_ioctl_t tunioctl;
74static d_poll_t tunpoll;
75
76#define CDEV_MAJOR 52
77static struct cdevsw tun_cdevsw = {
78 /* open */ tunopen,
79 /* close */ tunclose,
80 /* read */ tunread,
81 /* write */ tunwrite,
82 /* ioctl */ tunioctl,
83 /* poll */ tunpoll,
84 /* mmap */ nommap,
85 /* strategy */ nostrategy,
86 /* name */ "tun",
87 /* maj */ CDEV_MAJOR,
88 /* dump */ nodump,
89 /* psize */ nopsize,
90 /* flags */ 0,
91 /* bmaj */ -1
92};
93
59static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface");
60
61static void tunattach __P((void *));
62PSEUDO_SET(tunattach, if_tun);
63
64static void tuncreate __P((dev_t dev));
65
66#define TUNDEBUG if (tundebug) printf
67static int tundebug = 0;
68SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
69
70static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
71 struct rtentry *rt));
72static int tunifioctl __P((struct ifnet *, u_long, caddr_t));
73static int tuninit __P((struct ifnet *));
74
75static d_open_t tunopen;
76static d_close_t tunclose;
77static d_read_t tunread;
78static d_write_t tunwrite;
79static d_ioctl_t tunioctl;
80static d_poll_t tunpoll;
81
82#define CDEV_MAJOR 52
83static struct cdevsw tun_cdevsw = {
84 /* open */ tunopen,
85 /* close */ tunclose,
86 /* read */ tunread,
87 /* write */ tunwrite,
88 /* ioctl */ tunioctl,
89 /* poll */ tunpoll,
90 /* mmap */ nommap,
91 /* strategy */ nostrategy,
92 /* name */ "tun",
93 /* maj */ CDEV_MAJOR,
94 /* dump */ nodump,
95 /* psize */ nopsize,
96 /* flags */ 0,
97 /* bmaj */ -1
98};
99
100#ifdef DEVFS
101static void tun_clone __P((void *arg, char *name, int namelen, dev_t *dev));
102
94static void
103static void
104tun_clone(arg, name, namelen, dev)
105 void *arg;
106 char *name;
107 int namelen;
108 dev_t *dev;
109{
110 int u;
111
112 if (*dev != NODEV)
113 return;
114 if (devfs_stdclone(name, NULL, "tun", &u) != 1)
115 return;
116 /* XXX: minor encoding if u > 255 */
117 *dev = make_dev(&tun_cdevsw, u,
118 UID_UUCP, GID_DIALER, 0600, "tun%d", u);
119
120}
121#endif
122
123
124static void
95tunattach(dummy)
96 void *dummy;
97{
98
125tunattach(dummy)
126 void *dummy;
127{
128
129#ifdef DEVFS
130 EVENTHANDLER_REGISTER(devfs_clone, tun_clone, 0, 1000);
131#else
99 cdevsw_add(&tun_cdevsw);
132 cdevsw_add(&tun_cdevsw);
133#endif
100}
101
102static void
103tuncreate(dev)
104 dev_t dev;
105{
106 struct tun_softc *sc;
107 struct ifnet *ifp;
108
109 dev = make_dev(&tun_cdevsw, minor(dev),
110 UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
111
112 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK);
113 bzero(sc, sizeof *sc);
114 sc->tun_flags = TUN_INITED;
115
116 ifp = &sc->tun_if;
117 ifp->if_unit = lminor(dev);
118 ifp->if_name = "tun";
119 ifp->if_mtu = TUNMTU;
120 ifp->if_ioctl = tunifioctl;
121 ifp->if_output = tunoutput;
122 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
123 ifp->if_type = IFT_PPP;
124 ifp->if_snd.ifq_maxlen = ifqmaxlen;
125 ifp->if_softc = sc;
126 if_attach(ifp);
127 bpfattach(ifp, DLT_NULL, sizeof(u_int));
128 dev->si_drv1 = sc;
129}
130
131/*
132 * tunnel open - must be superuser & the device must be
133 * configured in
134 */
135static int
136tunopen(dev, flag, mode, p)
137 dev_t dev;
138 int flag, mode;
139 struct proc *p;
140{
141 struct ifnet *ifp;
142 struct tun_softc *tp;
143 register int error;
144
145 error = suser(p);
146 if (error)
147 return (error);
148
149 tp = dev->si_drv1;
150 if (!tp) {
151 tuncreate(dev);
152 tp = dev->si_drv1;
153 }
154 if (tp->tun_flags & TUN_OPEN)
155 return EBUSY;
156 tp->tun_pid = p->p_pid;
157 ifp = &tp->tun_if;
158 tp->tun_flags |= TUN_OPEN;
159 TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
160 return (0);
161}
162
163/*
164 * tunclose - close the device - mark i/f down & delete
165 * routing info
166 */
167static int
168tunclose(dev, foo, bar, p)
169 dev_t dev;
170 int foo;
171 int bar;
172 struct proc *p;
173{
174 register int s;
175 struct tun_softc *tp;
176 struct ifnet *ifp;
177 struct mbuf *m;
178
179 tp = dev->si_drv1;
180 ifp = &tp->tun_if;
181
182 tp->tun_flags &= ~TUN_OPEN;
183 tp->tun_pid = 0;
184
185 /*
186 * junk all pending output
187 */
188 do {
189 s = splimp();
190 IF_DEQUEUE(&ifp->if_snd, m);
191 splx(s);
192 if (m)
193 m_freem(m);
194 } while (m);
195
196 if (ifp->if_flags & IFF_UP) {
197 s = splimp();
198 if_down(ifp);
199 splx(s);
200 }
201
202 if (ifp->if_flags & IFF_RUNNING) {
203 register struct ifaddr *ifa;
204
205 s = splimp();
206 /* find internet addresses and delete routes */
207 for (ifa = ifp->if_addrhead.tqh_first; ifa;
208 ifa = ifa->ifa_link.tqe_next)
209 if (ifa->ifa_addr->sa_family == AF_INET)
210 rtinit(ifa, (int)RTM_DELETE,
211 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
212 ifp->if_flags &= ~IFF_RUNNING;
213 splx(s);
214 }
215
216 funsetown(tp->tun_sigio);
217 selwakeup(&tp->tun_rsel);
218
219 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
220 return (0);
221}
222
223static int
224tuninit(ifp)
225 struct ifnet *ifp;
226{
227 struct tun_softc *tp = ifp->if_softc;
228 register struct ifaddr *ifa;
229
230 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
231
232 ifp->if_flags |= IFF_UP | IFF_RUNNING;
233 getmicrotime(&ifp->if_lastchange);
234
235 for (ifa = ifp->if_addrhead.tqh_first; ifa;
236 ifa = ifa->ifa_link.tqe_next) {
237#ifdef INET
238 if (ifa->ifa_addr->sa_family == AF_INET) {
239 struct sockaddr_in *si;
240
241 si = (struct sockaddr_in *)ifa->ifa_addr;
242 if (si && si->sin_addr.s_addr)
243 tp->tun_flags |= TUN_IASET;
244
245 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
246 if (si && si->sin_addr.s_addr)
247 tp->tun_flags |= TUN_DSTADDR;
248 }
249#endif
250 }
251 return 0;
252}
253
254/*
255 * Process an ioctl request.
256 */
257int
258tunifioctl(ifp, cmd, data)
259 struct ifnet *ifp;
260 u_long cmd;
261 caddr_t data;
262{
263 struct ifreq *ifr = (struct ifreq *)data;
264 struct tun_softc *tp = ifp->if_softc;
265 struct ifstat *ifs;
266 int error = 0, s;
267
268 s = splimp();
269 switch(cmd) {
270 case SIOCGIFSTATUS:
271 ifs = (struct ifstat *)data;
272 if (tp->tun_pid)
273 sprintf(ifs->ascii + strlen(ifs->ascii),
274 "\tOpened by PID %d\n", tp->tun_pid);
275 return(0);
276 case SIOCSIFADDR:
277 tuninit(ifp);
278 TUNDEBUG("%s%d: address set\n",
279 ifp->if_name, ifp->if_unit);
280 break;
281 case SIOCSIFDSTADDR:
282 tuninit(ifp);
283 TUNDEBUG("%s%d: destination address set\n",
284 ifp->if_name, ifp->if_unit);
285 break;
286 case SIOCSIFMTU:
287 ifp->if_mtu = ifr->ifr_mtu;
288 TUNDEBUG("%s%d: mtu set\n",
289 ifp->if_name, ifp->if_unit);
290 break;
291 case SIOCADDMULTI:
292 case SIOCDELMULTI:
293 break;
294
295
296 default:
297 error = EINVAL;
298 }
299 splx(s);
300 return (error);
301}
302
303/*
304 * tunoutput - queue packets from higher level ready to put out.
305 */
306int
307tunoutput(ifp, m0, dst, rt)
308 struct ifnet *ifp;
309 struct mbuf *m0;
310 struct sockaddr *dst;
311 struct rtentry *rt;
312{
313 struct tun_softc *tp = ifp->if_softc;
314 int s;
315
316 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
317
318 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
319 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
320 ifp->if_unit, tp->tun_flags);
321 m_freem (m0);
322 return EHOSTDOWN;
323 }
324
325 /* BPF write needs to be handled specially */
326 if (dst->sa_family == AF_UNSPEC) {
327 dst->sa_family = *(mtod(m0, int *));
328 m0->m_len -= sizeof(int);
329 m0->m_pkthdr.len -= sizeof(int);
330 m0->m_data += sizeof(int);
331 }
332
333 if (ifp->if_bpf) {
334 /*
335 * We need to prepend the address family as
336 * a four byte field. Cons up a dummy header
337 * to pacify bpf. This is safe because bpf
338 * will only read from the mbuf (i.e., it won't
339 * try to free it or keep a pointer to it).
340 */
341 struct mbuf m;
342 u_int af = dst->sa_family;
343
344 m.m_next = m0;
345 m.m_len = 4;
346 m.m_data = (char *)&af;
347
348 bpf_mtap(ifp, &m);
349 }
350
351 /* prepend sockaddr? this may abort if the mbuf allocation fails */
352 if (tp->tun_flags & TUN_LMODE) {
353 /* allocate space for sockaddr */
354 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
355
356 /* if allocation failed drop packet */
357 if (m0 == NULL){
358 s = splimp(); /* spl on queue manipulation */
359 IF_DROP(&ifp->if_snd);
360 splx(s);
361 ifp->if_oerrors++;
362 return (ENOBUFS);
363 } else {
364 bcopy(dst, m0->m_data, dst->sa_len);
365 }
366 }
367
368 if (tp->tun_flags & TUN_IFHEAD) {
369 /* Prepend the address family */
370 M_PREPEND(m0, 4, M_DONTWAIT);
371
372 /* if allocation failed drop packet */
373 if (m0 == NULL){
374 s = splimp(); /* spl on queue manipulation */
375 IF_DROP(&ifp->if_snd);
376 splx(s);
377 ifp->if_oerrors++;
378 return ENOBUFS;
379 } else
380 *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
381 } else {
382#ifdef INET
383 if (dst->sa_family != AF_INET)
384#endif
385 {
386 m_freem(m0);
387 return EAFNOSUPPORT;
388 }
389 }
390
391 s = splimp();
392 if (IF_QFULL(&ifp->if_snd)) {
393 IF_DROP(&ifp->if_snd);
394 m_freem(m0);
395 splx(s);
396 ifp->if_collisions++;
397 return ENOBUFS;
398 }
399 ifp->if_obytes += m0->m_pkthdr.len;
400 IF_ENQUEUE(&ifp->if_snd, m0);
401 splx(s);
402 ifp->if_opackets++;
403
404 if (tp->tun_flags & TUN_RWAIT) {
405 tp->tun_flags &= ~TUN_RWAIT;
406 wakeup((caddr_t)tp);
407 }
408 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
409 pgsigio(tp->tun_sigio, SIGIO, 0);
410 selwakeup(&tp->tun_rsel);
411 return 0;
412}
413
414/*
415 * the cdevsw interface is now pretty minimal.
416 */
417static int
418tunioctl(dev, cmd, data, flag, p)
419 dev_t dev;
420 u_long cmd;
421 caddr_t data;
422 int flag;
423 struct proc *p;
424{
425 int s;
426 struct tun_softc *tp = dev->si_drv1;
427 struct tuninfo *tunp;
428
429 switch (cmd) {
430 case TUNSIFINFO:
431 tunp = (struct tuninfo *)data;
432 if (tunp->mtu < IF_MINMTU)
433 return (EINVAL);
434 tp->tun_if.if_mtu = tunp->mtu;
435 tp->tun_if.if_type = tunp->type;
436 tp->tun_if.if_baudrate = tunp->baudrate;
437 break;
438 case TUNGIFINFO:
439 tunp = (struct tuninfo *)data;
440 tunp->mtu = tp->tun_if.if_mtu;
441 tunp->type = tp->tun_if.if_type;
442 tunp->baudrate = tp->tun_if.if_baudrate;
443 break;
444 case TUNSDEBUG:
445 tundebug = *(int *)data;
446 break;
447 case TUNGDEBUG:
448 *(int *)data = tundebug;
449 break;
450 case TUNSLMODE:
451 if (*(int *)data) {
452 tp->tun_flags |= TUN_LMODE;
453 tp->tun_flags &= ~TUN_IFHEAD;
454 } else
455 tp->tun_flags &= ~TUN_LMODE;
456 break;
457 case TUNSIFHEAD:
458 if (*(int *)data) {
459 tp->tun_flags |= TUN_IFHEAD;
460 tp->tun_flags &= ~TUN_LMODE;
461 } else
462 tp->tun_flags &= ~TUN_IFHEAD;
463 break;
464 case TUNGIFHEAD:
465 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
466 break;
467 case TUNSIFMODE:
468 /* deny this if UP */
469 if (tp->tun_if.if_flags & IFF_UP)
470 return(EBUSY);
471
472 switch (*(int *)data) {
473 case IFF_POINTOPOINT:
474 tp->tun_if.if_flags |= IFF_POINTOPOINT;
475 tp->tun_if.if_flags &= ~IFF_BROADCAST;
476 break;
477 case IFF_BROADCAST:
478 tp->tun_if.if_flags &= ~IFF_POINTOPOINT;
479 tp->tun_if.if_flags |= IFF_BROADCAST;
480 break;
481 default:
482 return(EINVAL);
483 }
484 break;
485 case TUNSIFPID:
486 tp->tun_pid = curproc->p_pid;
487 break;
488 case FIONBIO:
489 break;
490 case FIOASYNC:
491 if (*(int *)data)
492 tp->tun_flags |= TUN_ASYNC;
493 else
494 tp->tun_flags &= ~TUN_ASYNC;
495 break;
496 case FIONREAD:
497 s = splimp();
498 if (tp->tun_if.if_snd.ifq_head) {
499 struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
500 for( *(int *)data = 0; mb != 0; mb = mb->m_next)
501 *(int *)data += mb->m_len;
502 } else
503 *(int *)data = 0;
504 splx(s);
505 break;
506 case FIOSETOWN:
507 return (fsetown(*(int *)data, &tp->tun_sigio));
508
509 case FIOGETOWN:
510 *(int *)data = fgetown(tp->tun_sigio);
511 return (0);
512
513 /* This is deprecated, FIOSETOWN should be used instead. */
514 case TIOCSPGRP:
515 return (fsetown(-(*(int *)data), &tp->tun_sigio));
516
517 /* This is deprecated, FIOGETOWN should be used instead. */
518 case TIOCGPGRP:
519 *(int *)data = -fgetown(tp->tun_sigio);
520 return (0);
521
522 default:
523 return (ENOTTY);
524 }
525 return (0);
526}
527
528/*
529 * The cdevsw read interface - reads a packet at a time, or at
530 * least as much of a packet as can be read.
531 */
532static int
533tunread(dev, uio, flag)
534 dev_t dev;
535 struct uio *uio;
536 int flag;
537{
538 struct tun_softc *tp = dev->si_drv1;
539 struct ifnet *ifp = &tp->tun_if;
540 struct mbuf *m, *m0;
541 int error=0, len, s;
542
543 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
544 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
545 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
546 ifp->if_unit, tp->tun_flags);
547 return EHOSTDOWN;
548 }
549
550 tp->tun_flags &= ~TUN_RWAIT;
551
552 s = splimp();
553 do {
554 IF_DEQUEUE(&ifp->if_snd, m0);
555 if (m0 == 0) {
556 if (flag & IO_NDELAY) {
557 splx(s);
558 return EWOULDBLOCK;
559 }
560 tp->tun_flags |= TUN_RWAIT;
561 if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
562 "tunread", 0)) != 0) {
563 splx(s);
564 return error;
565 }
566 }
567 } while (m0 == 0);
568 splx(s);
569
570 while (m0 && uio->uio_resid > 0 && error == 0) {
571 len = min(uio->uio_resid, m0->m_len);
572 if (len == 0)
573 break;
574 error = uiomove(mtod(m0, caddr_t), len, uio);
575 MFREE(m0, m);
576 m0 = m;
577 }
578
579 if (m0) {
580 TUNDEBUG("Dropping mbuf\n");
581 m_freem(m0);
582 }
583 return error;
584}
585
586/*
587 * the cdevsw write interface - an atomic write is a packet - or else!
588 */
589static int
590tunwrite(dev, uio, flag)
591 dev_t dev;
592 struct uio *uio;
593 int flag;
594{
595 struct tun_softc *tp = dev->si_drv1;
596 struct ifnet *ifp = &tp->tun_if;
597 struct mbuf *top, **mp, *m;
598 int error=0, tlen, mlen;
599 u_int32_t family;
600
601 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
602
603 if (uio->uio_resid == 0)
604 return 0;
605
606 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
607 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
608 uio->uio_resid);
609 return EIO;
610 }
611 tlen = uio->uio_resid;
612
613 /* get a header mbuf */
614 MGETHDR(m, M_DONTWAIT, MT_DATA);
615 if (m == NULL)
616 return ENOBUFS;
617 mlen = MHLEN;
618
619 top = 0;
620 mp = &top;
621 while (error == 0 && uio->uio_resid > 0) {
622 m->m_len = min(mlen, uio->uio_resid);
623 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
624 *mp = m;
625 mp = &m->m_next;
626 if (uio->uio_resid > 0) {
627 MGET (m, M_DONTWAIT, MT_DATA);
628 if (m == 0) {
629 error = ENOBUFS;
630 break;
631 }
632 mlen = MLEN;
633 }
634 }
635 if (error) {
636 if (top)
637 m_freem (top);
638 ifp->if_ierrors++;
639 return error;
640 }
641
642 top->m_pkthdr.len = tlen;
643 top->m_pkthdr.rcvif = ifp;
644
645 if (ifp->if_bpf) {
646 if (tp->tun_flags & TUN_IFHEAD)
647 /*
648 * Conveniently, we already have a 4-byte address
649 * family prepended to our packet !
650 */
651 bpf_mtap(ifp, top);
652 else {
653 /*
654 * We need to prepend the address family as
655 * a four byte field. Cons up a dummy header
656 * to pacify bpf. This is safe because bpf
657 * will only read from the mbuf (i.e., it won't
658 * try to free it or keep a pointer to it).
659 */
660 struct mbuf m;
661 u_int af = AF_INET;
662
663 m.m_next = top;
664 m.m_len = 4;
665 m.m_data = (char *)&af;
666
667 bpf_mtap(ifp, &m);
668 }
669 }
670
671 if (tp->tun_flags & TUN_IFHEAD) {
672 if (top->m_len < sizeof(family) &&
673 (top = m_pullup(top, sizeof(family))) == NULL)
674 return ENOBUFS;
675 family = ntohl(*mtod(top, u_int32_t *));
676 m_adj(top, sizeof(family));
677 } else
678 family = AF_INET;
679
680 ifp->if_ibytes += top->m_pkthdr.len;
681 ifp->if_ipackets++;
682
683 return family_enqueue(family, top);
684}
685
686/*
687 * tunpoll - the poll interface, this is only useful on reads
688 * really. The write detect always returns true, write never blocks
689 * anyway, it either accepts the packet or drops it.
690 */
691static int
692tunpoll(dev, events, p)
693 dev_t dev;
694 int events;
695 struct proc *p;
696{
697 int s;
698 struct tun_softc *tp = dev->si_drv1;
699 struct ifnet *ifp = &tp->tun_if;
700 int revents = 0;
701
702 s = splimp();
703 TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
704
705 if (events & (POLLIN | POLLRDNORM)) {
706 if (ifp->if_snd.ifq_len > 0) {
707 TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
708 ifp->if_unit, ifp->if_snd.ifq_len);
709 revents |= events & (POLLIN | POLLRDNORM);
710 } else {
711 TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
712 ifp->if_unit);
713 selrecord(p, &tp->tun_rsel);
714 }
715 }
716 if (events & (POLLOUT | POLLWRNORM))
717 revents |= events & (POLLOUT | POLLWRNORM);
718
719 splx(s);
720 return (revents);
721}
134}
135
136static void
137tuncreate(dev)
138 dev_t dev;
139{
140 struct tun_softc *sc;
141 struct ifnet *ifp;
142
143 dev = make_dev(&tun_cdevsw, minor(dev),
144 UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
145
146 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK);
147 bzero(sc, sizeof *sc);
148 sc->tun_flags = TUN_INITED;
149
150 ifp = &sc->tun_if;
151 ifp->if_unit = lminor(dev);
152 ifp->if_name = "tun";
153 ifp->if_mtu = TUNMTU;
154 ifp->if_ioctl = tunifioctl;
155 ifp->if_output = tunoutput;
156 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
157 ifp->if_type = IFT_PPP;
158 ifp->if_snd.ifq_maxlen = ifqmaxlen;
159 ifp->if_softc = sc;
160 if_attach(ifp);
161 bpfattach(ifp, DLT_NULL, sizeof(u_int));
162 dev->si_drv1 = sc;
163}
164
165/*
166 * tunnel open - must be superuser & the device must be
167 * configured in
168 */
169static int
170tunopen(dev, flag, mode, p)
171 dev_t dev;
172 int flag, mode;
173 struct proc *p;
174{
175 struct ifnet *ifp;
176 struct tun_softc *tp;
177 register int error;
178
179 error = suser(p);
180 if (error)
181 return (error);
182
183 tp = dev->si_drv1;
184 if (!tp) {
185 tuncreate(dev);
186 tp = dev->si_drv1;
187 }
188 if (tp->tun_flags & TUN_OPEN)
189 return EBUSY;
190 tp->tun_pid = p->p_pid;
191 ifp = &tp->tun_if;
192 tp->tun_flags |= TUN_OPEN;
193 TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
194 return (0);
195}
196
197/*
198 * tunclose - close the device - mark i/f down & delete
199 * routing info
200 */
201static int
202tunclose(dev, foo, bar, p)
203 dev_t dev;
204 int foo;
205 int bar;
206 struct proc *p;
207{
208 register int s;
209 struct tun_softc *tp;
210 struct ifnet *ifp;
211 struct mbuf *m;
212
213 tp = dev->si_drv1;
214 ifp = &tp->tun_if;
215
216 tp->tun_flags &= ~TUN_OPEN;
217 tp->tun_pid = 0;
218
219 /*
220 * junk all pending output
221 */
222 do {
223 s = splimp();
224 IF_DEQUEUE(&ifp->if_snd, m);
225 splx(s);
226 if (m)
227 m_freem(m);
228 } while (m);
229
230 if (ifp->if_flags & IFF_UP) {
231 s = splimp();
232 if_down(ifp);
233 splx(s);
234 }
235
236 if (ifp->if_flags & IFF_RUNNING) {
237 register struct ifaddr *ifa;
238
239 s = splimp();
240 /* find internet addresses and delete routes */
241 for (ifa = ifp->if_addrhead.tqh_first; ifa;
242 ifa = ifa->ifa_link.tqe_next)
243 if (ifa->ifa_addr->sa_family == AF_INET)
244 rtinit(ifa, (int)RTM_DELETE,
245 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
246 ifp->if_flags &= ~IFF_RUNNING;
247 splx(s);
248 }
249
250 funsetown(tp->tun_sigio);
251 selwakeup(&tp->tun_rsel);
252
253 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
254 return (0);
255}
256
257static int
258tuninit(ifp)
259 struct ifnet *ifp;
260{
261 struct tun_softc *tp = ifp->if_softc;
262 register struct ifaddr *ifa;
263
264 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
265
266 ifp->if_flags |= IFF_UP | IFF_RUNNING;
267 getmicrotime(&ifp->if_lastchange);
268
269 for (ifa = ifp->if_addrhead.tqh_first; ifa;
270 ifa = ifa->ifa_link.tqe_next) {
271#ifdef INET
272 if (ifa->ifa_addr->sa_family == AF_INET) {
273 struct sockaddr_in *si;
274
275 si = (struct sockaddr_in *)ifa->ifa_addr;
276 if (si && si->sin_addr.s_addr)
277 tp->tun_flags |= TUN_IASET;
278
279 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
280 if (si && si->sin_addr.s_addr)
281 tp->tun_flags |= TUN_DSTADDR;
282 }
283#endif
284 }
285 return 0;
286}
287
288/*
289 * Process an ioctl request.
290 */
291int
292tunifioctl(ifp, cmd, data)
293 struct ifnet *ifp;
294 u_long cmd;
295 caddr_t data;
296{
297 struct ifreq *ifr = (struct ifreq *)data;
298 struct tun_softc *tp = ifp->if_softc;
299 struct ifstat *ifs;
300 int error = 0, s;
301
302 s = splimp();
303 switch(cmd) {
304 case SIOCGIFSTATUS:
305 ifs = (struct ifstat *)data;
306 if (tp->tun_pid)
307 sprintf(ifs->ascii + strlen(ifs->ascii),
308 "\tOpened by PID %d\n", tp->tun_pid);
309 return(0);
310 case SIOCSIFADDR:
311 tuninit(ifp);
312 TUNDEBUG("%s%d: address set\n",
313 ifp->if_name, ifp->if_unit);
314 break;
315 case SIOCSIFDSTADDR:
316 tuninit(ifp);
317 TUNDEBUG("%s%d: destination address set\n",
318 ifp->if_name, ifp->if_unit);
319 break;
320 case SIOCSIFMTU:
321 ifp->if_mtu = ifr->ifr_mtu;
322 TUNDEBUG("%s%d: mtu set\n",
323 ifp->if_name, ifp->if_unit);
324 break;
325 case SIOCADDMULTI:
326 case SIOCDELMULTI:
327 break;
328
329
330 default:
331 error = EINVAL;
332 }
333 splx(s);
334 return (error);
335}
336
337/*
338 * tunoutput - queue packets from higher level ready to put out.
339 */
340int
341tunoutput(ifp, m0, dst, rt)
342 struct ifnet *ifp;
343 struct mbuf *m0;
344 struct sockaddr *dst;
345 struct rtentry *rt;
346{
347 struct tun_softc *tp = ifp->if_softc;
348 int s;
349
350 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
351
352 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
353 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
354 ifp->if_unit, tp->tun_flags);
355 m_freem (m0);
356 return EHOSTDOWN;
357 }
358
359 /* BPF write needs to be handled specially */
360 if (dst->sa_family == AF_UNSPEC) {
361 dst->sa_family = *(mtod(m0, int *));
362 m0->m_len -= sizeof(int);
363 m0->m_pkthdr.len -= sizeof(int);
364 m0->m_data += sizeof(int);
365 }
366
367 if (ifp->if_bpf) {
368 /*
369 * We need to prepend the address family as
370 * a four byte field. Cons up a dummy header
371 * to pacify bpf. This is safe because bpf
372 * will only read from the mbuf (i.e., it won't
373 * try to free it or keep a pointer to it).
374 */
375 struct mbuf m;
376 u_int af = dst->sa_family;
377
378 m.m_next = m0;
379 m.m_len = 4;
380 m.m_data = (char *)&af;
381
382 bpf_mtap(ifp, &m);
383 }
384
385 /* prepend sockaddr? this may abort if the mbuf allocation fails */
386 if (tp->tun_flags & TUN_LMODE) {
387 /* allocate space for sockaddr */
388 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
389
390 /* if allocation failed drop packet */
391 if (m0 == NULL){
392 s = splimp(); /* spl on queue manipulation */
393 IF_DROP(&ifp->if_snd);
394 splx(s);
395 ifp->if_oerrors++;
396 return (ENOBUFS);
397 } else {
398 bcopy(dst, m0->m_data, dst->sa_len);
399 }
400 }
401
402 if (tp->tun_flags & TUN_IFHEAD) {
403 /* Prepend the address family */
404 M_PREPEND(m0, 4, M_DONTWAIT);
405
406 /* if allocation failed drop packet */
407 if (m0 == NULL){
408 s = splimp(); /* spl on queue manipulation */
409 IF_DROP(&ifp->if_snd);
410 splx(s);
411 ifp->if_oerrors++;
412 return ENOBUFS;
413 } else
414 *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
415 } else {
416#ifdef INET
417 if (dst->sa_family != AF_INET)
418#endif
419 {
420 m_freem(m0);
421 return EAFNOSUPPORT;
422 }
423 }
424
425 s = splimp();
426 if (IF_QFULL(&ifp->if_snd)) {
427 IF_DROP(&ifp->if_snd);
428 m_freem(m0);
429 splx(s);
430 ifp->if_collisions++;
431 return ENOBUFS;
432 }
433 ifp->if_obytes += m0->m_pkthdr.len;
434 IF_ENQUEUE(&ifp->if_snd, m0);
435 splx(s);
436 ifp->if_opackets++;
437
438 if (tp->tun_flags & TUN_RWAIT) {
439 tp->tun_flags &= ~TUN_RWAIT;
440 wakeup((caddr_t)tp);
441 }
442 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
443 pgsigio(tp->tun_sigio, SIGIO, 0);
444 selwakeup(&tp->tun_rsel);
445 return 0;
446}
447
448/*
449 * the cdevsw interface is now pretty minimal.
450 */
451static int
452tunioctl(dev, cmd, data, flag, p)
453 dev_t dev;
454 u_long cmd;
455 caddr_t data;
456 int flag;
457 struct proc *p;
458{
459 int s;
460 struct tun_softc *tp = dev->si_drv1;
461 struct tuninfo *tunp;
462
463 switch (cmd) {
464 case TUNSIFINFO:
465 tunp = (struct tuninfo *)data;
466 if (tunp->mtu < IF_MINMTU)
467 return (EINVAL);
468 tp->tun_if.if_mtu = tunp->mtu;
469 tp->tun_if.if_type = tunp->type;
470 tp->tun_if.if_baudrate = tunp->baudrate;
471 break;
472 case TUNGIFINFO:
473 tunp = (struct tuninfo *)data;
474 tunp->mtu = tp->tun_if.if_mtu;
475 tunp->type = tp->tun_if.if_type;
476 tunp->baudrate = tp->tun_if.if_baudrate;
477 break;
478 case TUNSDEBUG:
479 tundebug = *(int *)data;
480 break;
481 case TUNGDEBUG:
482 *(int *)data = tundebug;
483 break;
484 case TUNSLMODE:
485 if (*(int *)data) {
486 tp->tun_flags |= TUN_LMODE;
487 tp->tun_flags &= ~TUN_IFHEAD;
488 } else
489 tp->tun_flags &= ~TUN_LMODE;
490 break;
491 case TUNSIFHEAD:
492 if (*(int *)data) {
493 tp->tun_flags |= TUN_IFHEAD;
494 tp->tun_flags &= ~TUN_LMODE;
495 } else
496 tp->tun_flags &= ~TUN_IFHEAD;
497 break;
498 case TUNGIFHEAD:
499 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
500 break;
501 case TUNSIFMODE:
502 /* deny this if UP */
503 if (tp->tun_if.if_flags & IFF_UP)
504 return(EBUSY);
505
506 switch (*(int *)data) {
507 case IFF_POINTOPOINT:
508 tp->tun_if.if_flags |= IFF_POINTOPOINT;
509 tp->tun_if.if_flags &= ~IFF_BROADCAST;
510 break;
511 case IFF_BROADCAST:
512 tp->tun_if.if_flags &= ~IFF_POINTOPOINT;
513 tp->tun_if.if_flags |= IFF_BROADCAST;
514 break;
515 default:
516 return(EINVAL);
517 }
518 break;
519 case TUNSIFPID:
520 tp->tun_pid = curproc->p_pid;
521 break;
522 case FIONBIO:
523 break;
524 case FIOASYNC:
525 if (*(int *)data)
526 tp->tun_flags |= TUN_ASYNC;
527 else
528 tp->tun_flags &= ~TUN_ASYNC;
529 break;
530 case FIONREAD:
531 s = splimp();
532 if (tp->tun_if.if_snd.ifq_head) {
533 struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
534 for( *(int *)data = 0; mb != 0; mb = mb->m_next)
535 *(int *)data += mb->m_len;
536 } else
537 *(int *)data = 0;
538 splx(s);
539 break;
540 case FIOSETOWN:
541 return (fsetown(*(int *)data, &tp->tun_sigio));
542
543 case FIOGETOWN:
544 *(int *)data = fgetown(tp->tun_sigio);
545 return (0);
546
547 /* This is deprecated, FIOSETOWN should be used instead. */
548 case TIOCSPGRP:
549 return (fsetown(-(*(int *)data), &tp->tun_sigio));
550
551 /* This is deprecated, FIOGETOWN should be used instead. */
552 case TIOCGPGRP:
553 *(int *)data = -fgetown(tp->tun_sigio);
554 return (0);
555
556 default:
557 return (ENOTTY);
558 }
559 return (0);
560}
561
562/*
563 * The cdevsw read interface - reads a packet at a time, or at
564 * least as much of a packet as can be read.
565 */
566static int
567tunread(dev, uio, flag)
568 dev_t dev;
569 struct uio *uio;
570 int flag;
571{
572 struct tun_softc *tp = dev->si_drv1;
573 struct ifnet *ifp = &tp->tun_if;
574 struct mbuf *m, *m0;
575 int error=0, len, s;
576
577 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
578 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
579 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
580 ifp->if_unit, tp->tun_flags);
581 return EHOSTDOWN;
582 }
583
584 tp->tun_flags &= ~TUN_RWAIT;
585
586 s = splimp();
587 do {
588 IF_DEQUEUE(&ifp->if_snd, m0);
589 if (m0 == 0) {
590 if (flag & IO_NDELAY) {
591 splx(s);
592 return EWOULDBLOCK;
593 }
594 tp->tun_flags |= TUN_RWAIT;
595 if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
596 "tunread", 0)) != 0) {
597 splx(s);
598 return error;
599 }
600 }
601 } while (m0 == 0);
602 splx(s);
603
604 while (m0 && uio->uio_resid > 0 && error == 0) {
605 len = min(uio->uio_resid, m0->m_len);
606 if (len == 0)
607 break;
608 error = uiomove(mtod(m0, caddr_t), len, uio);
609 MFREE(m0, m);
610 m0 = m;
611 }
612
613 if (m0) {
614 TUNDEBUG("Dropping mbuf\n");
615 m_freem(m0);
616 }
617 return error;
618}
619
620/*
621 * the cdevsw write interface - an atomic write is a packet - or else!
622 */
623static int
624tunwrite(dev, uio, flag)
625 dev_t dev;
626 struct uio *uio;
627 int flag;
628{
629 struct tun_softc *tp = dev->si_drv1;
630 struct ifnet *ifp = &tp->tun_if;
631 struct mbuf *top, **mp, *m;
632 int error=0, tlen, mlen;
633 u_int32_t family;
634
635 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
636
637 if (uio->uio_resid == 0)
638 return 0;
639
640 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
641 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
642 uio->uio_resid);
643 return EIO;
644 }
645 tlen = uio->uio_resid;
646
647 /* get a header mbuf */
648 MGETHDR(m, M_DONTWAIT, MT_DATA);
649 if (m == NULL)
650 return ENOBUFS;
651 mlen = MHLEN;
652
653 top = 0;
654 mp = &top;
655 while (error == 0 && uio->uio_resid > 0) {
656 m->m_len = min(mlen, uio->uio_resid);
657 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
658 *mp = m;
659 mp = &m->m_next;
660 if (uio->uio_resid > 0) {
661 MGET (m, M_DONTWAIT, MT_DATA);
662 if (m == 0) {
663 error = ENOBUFS;
664 break;
665 }
666 mlen = MLEN;
667 }
668 }
669 if (error) {
670 if (top)
671 m_freem (top);
672 ifp->if_ierrors++;
673 return error;
674 }
675
676 top->m_pkthdr.len = tlen;
677 top->m_pkthdr.rcvif = ifp;
678
679 if (ifp->if_bpf) {
680 if (tp->tun_flags & TUN_IFHEAD)
681 /*
682 * Conveniently, we already have a 4-byte address
683 * family prepended to our packet !
684 */
685 bpf_mtap(ifp, top);
686 else {
687 /*
688 * We need to prepend the address family as
689 * a four byte field. Cons up a dummy header
690 * to pacify bpf. This is safe because bpf
691 * will only read from the mbuf (i.e., it won't
692 * try to free it or keep a pointer to it).
693 */
694 struct mbuf m;
695 u_int af = AF_INET;
696
697 m.m_next = top;
698 m.m_len = 4;
699 m.m_data = (char *)&af;
700
701 bpf_mtap(ifp, &m);
702 }
703 }
704
705 if (tp->tun_flags & TUN_IFHEAD) {
706 if (top->m_len < sizeof(family) &&
707 (top = m_pullup(top, sizeof(family))) == NULL)
708 return ENOBUFS;
709 family = ntohl(*mtod(top, u_int32_t *));
710 m_adj(top, sizeof(family));
711 } else
712 family = AF_INET;
713
714 ifp->if_ibytes += top->m_pkthdr.len;
715 ifp->if_ipackets++;
716
717 return family_enqueue(family, top);
718}
719
720/*
721 * tunpoll - the poll interface, this is only useful on reads
722 * really. The write detect always returns true, write never blocks
723 * anyway, it either accepts the packet or drops it.
724 */
725static int
726tunpoll(dev, events, p)
727 dev_t dev;
728 int events;
729 struct proc *p;
730{
731 int s;
732 struct tun_softc *tp = dev->si_drv1;
733 struct ifnet *ifp = &tp->tun_if;
734 int revents = 0;
735
736 s = splimp();
737 TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
738
739 if (events & (POLLIN | POLLRDNORM)) {
740 if (ifp->if_snd.ifq_len > 0) {
741 TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
742 ifp->if_unit, ifp->if_snd.ifq_len);
743 revents |= events & (POLLIN | POLLRDNORM);
744 } else {
745 TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
746 ifp->if_unit);
747 selrecord(p, &tp->tun_rsel);
748 }
749 }
750 if (events & (POLLOUT | POLLWRNORM))
751 revents |= events & (POLLOUT | POLLWRNORM);
752
753 splx(s);
754 return (revents);
755}