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