if_enc.c revision 1.33
1/* $OpenBSD: if_enc.c,v 1.33 2001/04/06 04:42:07 csapuntz Exp $ */ 2 3/* 4 * The authors of this code are John Ioannidis (ji@tla.org), 5 * Angelos D. Keromytis (kermit@csd.uch.gr) and 6 * Niels Provos (provos@physnet.uni-hamburg.de). 7 * 8 * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 9 * in November 1995. 10 * 11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12 * by Angelos D. Keromytis. 13 * 14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 15 * and Niels Provos. 16 * 17 * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis 18 * and Niels Provos. 19 * 20 * Permission to use, copy, and modify this software 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/kernel.h> 43#include <sys/mbuf.h> 44#include <sys/socket.h> 45#include <sys/errno.h> 46#include <sys/ioctl.h> 47#include <sys/proc.h> 48 49#include <machine/cpu.h> 50 51#include <net/if.h> 52#include <net/if_types.h> 53#include <net/netisr.h> 54#include <net/route.h> 55#include <net/bpf.h> 56 57#include <netinet/ip_ipsp.h> 58#include <net/if_enc.h> 59 60#ifdef INET 61#include <netinet/in.h> 62#include <netinet/in_systm.h> 63#include <netinet/in_var.h> 64#include <netinet/ip_var.h> 65#include <netinet/ip.h> 66#endif 67 68#ifdef INET6 69#ifndef INET 70#include <netinet/in.h> 71#endif 72#include <netinet/ip6.h> 73#include <netinet6/ip6_var.h> 74#include <netinet6/nd6.h> 75#endif /* INET6 */ 76 77#ifdef ISO 78extern struct ifqueue clnlintrq; 79#endif 80 81#ifdef NS 82extern struct ifqueue nsintrq; 83#endif 84 85#include "bpfilter.h" 86#include "enc.h" 87 88#ifdef ENCDEBUG 89#define DPRINTF(x) do { if (encdebug) printf x ; } while (0) 90#else 91#define DPRINTF(x) 92#endif 93 94struct enc_softc encif[NENC]; 95 96void encattach __P((int)); 97int encoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 98 struct rtentry *)); 99int encioctl __P((struct ifnet *, u_long, caddr_t)); 100void encrtrequest __P((int, struct rtentry *, struct sockaddr *)); 101void encstart __P((struct ifnet *)); 102 103extern int ifqmaxlen; 104 105void 106encattach(int nenc) 107{ 108 struct ifnet *ifp; 109 int i; 110 111 bzero(encif, sizeof(encif)); 112 113 for (i = 0; i < NENC; i++) 114 { 115 ifp = &encif[i].sc_if; 116 sprintf(ifp->if_xname, "enc%d", i); 117 ifp->if_softc = &encif[i]; 118 ifp->if_mtu = ENCMTU; 119 ifp->if_ioctl = encioctl; 120 ifp->if_output = encoutput; 121 ifp->if_start = encstart; 122 ifp->if_type = IFT_ENC; 123 ifp->if_snd.ifq_maxlen = ifqmaxlen; 124 ifp->if_hdrlen = ENC_HDRLEN; 125 if_attach(ifp); 126 127#if NBPFILTER > 0 128 bpfattach(&encif[i].sc_if.if_bpf, ifp, DLT_ENC, ENC_HDRLEN); 129#endif 130#ifdef INET6 131 nd6_ifattach(ifp); 132#endif 133 } 134} 135 136/* 137 * Start output on the enc interface. 138 */ 139void 140encstart(ifp) 141struct ifnet *ifp; 142{ 143 struct mbuf *m; 144 int s; 145 146 for (;;) 147 { 148 s = splimp(); 149 IF_DROP(&ifp->if_snd); 150 IF_DEQUEUE(&ifp->if_snd, m); 151 splx(s); 152 153 if (m == NULL) 154 return; 155 else 156 m_freem(m); 157 } 158} 159 160int 161encoutput(ifp, m, dst, rt) 162struct ifnet *ifp; 163register struct mbuf *m; 164struct sockaddr *dst; 165register struct rtentry *rt; 166{ 167 m_freem(m); 168 return 0; 169} 170 171/* ARGSUSED */ 172void 173encrtrequest(cmd, rt, sa) 174int cmd; 175struct rtentry *rt; 176struct sockaddr *sa; 177{ 178 if (rt) 179 rt->rt_rmx.rmx_mtu = ENCMTU; 180} 181 182/* ARGSUSED */ 183int 184encioctl(ifp, cmd, data) 185register struct ifnet *ifp; 186u_long cmd; 187caddr_t data; 188{ 189 switch (cmd) 190 { 191 case SIOCSIFADDR: 192 case SIOCAIFADDR: 193 case SIOCSIFDSTADDR: 194 case SIOCSIFFLAGS: 195 if (ifp->if_flags & IFF_UP) 196 ifp->if_flags |= IFF_RUNNING; 197 else 198 ifp->if_flags &= ~IFF_RUNNING; 199 break; 200 201 default: 202 return EINVAL; 203 } 204 205 return 0; 206} 207