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 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 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 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 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 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