1 /* $OpenBSD: if_enc.c,v 1.40 2003/05/03 21:15:11 deraadt 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(int);
85 int encoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
86 struct rtentry *);
87 int encioctl(struct ifnet *, u_long, caddr_t);
88 void encrtrequest(int, struct rtentry *, struct sockaddr *);
89 void encstart(struct ifnet *);
90
91 extern int ifqmaxlen;
92
93 void
encattach(int nenc)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 snprintf(ifp->if_xname, sizeof 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 if_alloc_sadl(ifp);
115
116 #if NBPFILTER > 0
117 bpfattach(&encif[i].sc_if.if_bpf, ifp, DLT_ENC, ENC_HDRLEN);
118 #endif
119 }
120 }
121
122 /*
123 * Start output on the enc interface.
124 */
125 void
encstart(ifp)126 encstart(ifp)
127 struct ifnet *ifp;
128 {
129 struct mbuf *m;
130 int s;
131
132 for (;;)
133 {
134 s = splimp();
135 IF_DROP(&ifp->if_snd);
136 IF_DEQUEUE(&ifp->if_snd, m);
137 splx(s);
138
139 if (m == NULL)
140 return;
141 else
142 m_freem(m);
143 }
144 }
145
146 int
encoutput(ifp,m,dst,rt)147 encoutput(ifp, m, dst, rt)
148 struct ifnet *ifp;
149 register struct mbuf *m;
150 struct sockaddr *dst;
151 register struct rtentry *rt;
152 {
153 m_freem(m);
154 return (0);
155 }
156
157 /* ARGSUSED */
158 void
encrtrequest(cmd,rt,sa)159 encrtrequest(cmd, rt, sa)
160 int cmd;
161 struct rtentry *rt;
162 struct sockaddr *sa;
163 {
164 if (rt)
165 rt->rt_rmx.rmx_mtu = ENCMTU;
166 }
167
168 /* ARGSUSED */
169 int
encioctl(ifp,cmd,data)170 encioctl(ifp, cmd, data)
171 register struct ifnet *ifp;
172 u_long cmd;
173 caddr_t data;
174 {
175 switch (cmd)
176 {
177 case SIOCSIFADDR:
178 case SIOCAIFADDR:
179 case SIOCSIFDSTADDR:
180 case SIOCSIFFLAGS:
181 if (ifp->if_flags & IFF_UP)
182 ifp->if_flags |= IFF_RUNNING;
183 else
184 ifp->if_flags &= ~IFF_RUNNING;
185 break;
186
187 default:
188 return (EINVAL);
189 }
190
191 return 0;
192 }
193