1 /* $OpenBSD: if_pflog.c,v 1.4 2001/06/27 01:58:03 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, Niels Provos. 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 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/mbuf.h> 39 #include <sys/socket.h> 40 #include <sys/ioctl.h> 41 42 #include <net/if.h> 43 #include <net/if_types.h> 44 #include <net/route.h> 45 #include <net/bpf.h> 46 47 #include <net/if_pflog.h> 48 49 #ifdef INET 50 #include <netinet/in.h> 51 #include <netinet/in_var.h> 52 #endif 53 54 #ifdef INET6 55 #ifndef INET 56 #include <netinet/in.h> 57 #endif 58 #include <netinet6/nd6.h> 59 #endif /* INET6 */ 60 61 #include "bpfilter.h" 62 #include "pflog.h" 63 64 #define PFLOGMTU (32768 + MHLEN + MLEN) 65 66 #ifdef PFLOGDEBUG 67 #define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0) 68 #else 69 #define DPRINTF(x) 70 #endif 71 72 struct pflog_softc pflogif[NPFLOG]; 73 74 void pflogattach(int); 75 int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 76 struct rtentry *); 77 int pflogioctl(struct ifnet *, u_long, caddr_t); 78 void pflogrtrequest(int, struct rtentry *, struct sockaddr *); 79 void pflogstart(struct ifnet *); 80 81 extern int ifqmaxlen; 82 83 void 84 pflogattach(int npflog) 85 { 86 struct ifnet *ifp; 87 int i; 88 89 bzero(pflogif, sizeof(pflogif)); 90 91 for (i = 0; i < NPFLOG; i++) { 92 ifp = &pflogif[i].sc_if; 93 sprintf(ifp->if_xname, "pflog%d", i); 94 ifp->if_softc = &pflogif[i]; 95 ifp->if_mtu = PFLOGMTU; 96 ifp->if_ioctl = pflogioctl; 97 ifp->if_output = pflogoutput; 98 ifp->if_start = pflogstart; 99 ifp->if_type = IFT_PFLOG; 100 ifp->if_snd.ifq_maxlen = ifqmaxlen; 101 ifp->if_hdrlen = PFLOG_HDRLEN; 102 if_attach(ifp); 103 104 #if NBPFILTER > 0 105 bpfattach(&pflogif[i].sc_if.if_bpf, ifp, DLT_PFLOG, 106 PFLOG_HDRLEN); 107 #endif 108 #ifdef INET6 109 nd6_ifattach(ifp); 110 #endif 111 } 112 } 113 114 /* 115 * Start output on the pflog interface. 116 */ 117 void 118 pflogstart(struct ifnet *ifp) 119 { 120 struct mbuf *m; 121 int s; 122 123 for (;;) { 124 s = splimp(); 125 IF_DROP(&ifp->if_snd); 126 IF_DEQUEUE(&ifp->if_snd, m); 127 splx(s); 128 129 if (m == NULL) 130 return; 131 else 132 m_freem(m); 133 } 134 } 135 136 int 137 pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, 138 struct rtentry *rt) 139 { 140 m_freem(m); 141 return (0); 142 } 143 144 /* ARGSUSED */ 145 void 146 pflogrtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa) 147 { 148 if (rt) 149 rt->rt_rmx.rmx_mtu = PFLOGMTU; 150 } 151 152 /* ARGSUSED */ 153 int 154 pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 155 { 156 switch (cmd) { 157 case SIOCSIFADDR: 158 case SIOCAIFADDR: 159 case SIOCSIFDSTADDR: 160 case SIOCSIFFLAGS: 161 if (ifp->if_flags & IFF_UP) 162 ifp->if_flags |= IFF_RUNNING; 163 else 164 ifp->if_flags &= ~IFF_RUNNING; 165 break; 166 default: 167 return (EINVAL); 168 } 169 170 return (0); 171 } 172