xref: /openbsd-src/sys/net/if_enc.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: if_enc.c,v 1.36 2001/06/27 02:00:30 provos Exp $	*/
2 /*
3  * The authors of this code are John Ioannidis (ji@tla.org),
4  * Angelos D. Keromytis (kermit@csd.uch.gr) and
5  * Niels Provos (provos@physnet.uni-hamburg.de).
6  *
7  * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
8  * in November 1995.
9  *
10  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11  * by Angelos D. Keromytis.
12  *
13  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14  * and Niels Provos.
15  *
16  * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
17  * and Niels Provos.
18  * Copyright (c) 2001, Angelos D. Keromytis.
19  *
20  * Permission to use, copy, and modify this software with or without fee
21  * is hereby granted, provided that this entire notice is included in
22  * all copies of any software which is or includes a copy or
23  * modification of this software.
24  * You may use this code under the GNU public license if you so wish. Please
25  * contribute changes back to the authors under this freer than GPL license
26  * so that we may further the use of strong encryption without limitations to
27  * all.
28  *
29  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
30  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
31  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
32  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
33  * PURPOSE.
34  */
35 
36 /*
37  * Encapsulation interface driver.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/mbuf.h>
43 #include <sys/socket.h>
44 #include <sys/ioctl.h>
45 
46 #include <net/if.h>
47 #include <net/if_types.h>
48 #include <net/route.h>
49 #include <net/bpf.h>
50 
51 #include <net/if_enc.h>
52 
53 #ifdef	INET
54 #include <netinet/in.h>
55 #include <netinet/in_var.h>
56 #endif
57 
58 #ifdef INET6
59 #ifndef INET
60 #include <netinet/in.h>
61 #endif
62 #include <netinet6/nd6.h>
63 #endif /* INET6 */
64 
65 #ifdef ISO
66 extern struct ifqueue clnlintrq;
67 #endif
68 
69 #ifdef NS
70 extern struct ifqueue nsintrq;
71 #endif
72 
73 #include "bpfilter.h"
74 #include "enc.h"
75 
76 #ifdef ENCDEBUG
77 #define DPRINTF(x)    do { if (encdebug) printf x ; } while (0)
78 #else
79 #define DPRINTF(x)
80 #endif
81 
82 struct enc_softc encif[NENC];
83 
84 void	encattach __P((int));
85 int	encoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
86 	    	       struct rtentry *));
87 int	encioctl __P((struct ifnet *, u_long, caddr_t));
88 void	encrtrequest __P((int, struct rtentry *, struct sockaddr *));
89 void	encstart __P((struct ifnet *));
90 
91 extern int ifqmaxlen;
92 
93 void
94 encattach(int nenc)
95 {
96     struct ifnet *ifp;
97     int i;
98 
99     bzero(encif, sizeof(encif));
100 
101     for (i = 0; i < NENC; i++)
102     {
103 	ifp = &encif[i].sc_if;
104 	sprintf(ifp->if_xname, "enc%d", i);
105 	ifp->if_softc = &encif[i];
106 	ifp->if_mtu = ENCMTU;
107 	ifp->if_ioctl = encioctl;
108 	ifp->if_output = encoutput;
109 	ifp->if_start = encstart;
110 	ifp->if_type = IFT_ENC;
111 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
112 	ifp->if_hdrlen = ENC_HDRLEN;
113 	if_attach(ifp);
114 
115 #if NBPFILTER > 0
116 	bpfattach(&encif[i].sc_if.if_bpf, ifp, DLT_ENC, ENC_HDRLEN);
117 #endif
118 #ifdef INET6
119 	nd6_ifattach(ifp);
120 #endif
121     }
122 }
123 
124 /*
125  * Start output on the enc interface.
126  */
127 void
128 encstart(ifp)
129 struct ifnet *ifp;
130 {
131     struct mbuf *m;
132     int s;
133 
134     for (;;)
135     {
136         s = splimp();
137 	IF_DROP(&ifp->if_snd);
138         IF_DEQUEUE(&ifp->if_snd, m);
139         splx(s);
140 
141         if (m == NULL)
142           return;
143         else
144           m_freem(m);
145     }
146 }
147 
148 int
149 encoutput(ifp, m, dst, rt)
150 struct ifnet *ifp;
151 register struct mbuf *m;
152 struct sockaddr *dst;
153 register struct rtentry *rt;
154 {
155     m_freem(m);
156     return (0);
157 }
158 
159 /* ARGSUSED */
160 void
161 encrtrequest(cmd, rt, sa)
162 int cmd;
163 struct rtentry *rt;
164 struct sockaddr *sa;
165 {
166     if (rt)
167       rt->rt_rmx.rmx_mtu = ENCMTU;
168 }
169 
170 /* ARGSUSED */
171 int
172 encioctl(ifp, cmd, data)
173 register struct ifnet *ifp;
174 u_long cmd;
175 caddr_t data;
176 {
177     switch (cmd)
178     {
179 	case SIOCSIFADDR:
180 	case SIOCAIFADDR:
181 	case SIOCSIFDSTADDR:
182 	case SIOCSIFFLAGS:
183 	    if (ifp->if_flags & IFF_UP)
184 	      ifp->if_flags |= IFF_RUNNING;
185 	    else
186 	      ifp->if_flags &= ~IFF_RUNNING;
187 	    break;
188 
189 	default:
190 	    return (EINVAL);
191     }
192 
193     return 0;
194 }
195