bpf.c (105598) | bpf.c (106927) |
---|---|
1/* 2 * Copyright (c) 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from the Stanford/CMU enet packet filter, 6 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8 * Berkeley Laboratory. --- 23 unchanged lines hidden (view full) --- 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)bpf.c 8.4 (Berkeley) 1/9/95 39 * | 1/* 2 * Copyright (c) 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from the Stanford/CMU enet packet filter, 6 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8 * Berkeley Laboratory. --- 23 unchanged lines hidden (view full) --- 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)bpf.c 8.4 (Berkeley) 1/9/95 39 * |
40 * $FreeBSD: head/sys/net/bpf.c 105598 2002-10-21 02:51:56Z brooks $ | 40 * $FreeBSD: head/sys/net/bpf.c 106927 2002-11-14 23:24:13Z sam $ |
41 */ 42 43#include "opt_bpf.h" 44#include "opt_mac.h" 45#include "opt_netgraph.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 150 unchanged lines hidden (view full) --- 199 return (EIO); 200 } 201 202 len = uio->uio_resid; 203 *datlen = len - hlen; 204 if ((unsigned)len > MCLBYTES) 205 return (EIO); 206 | 41 */ 42 43#include "opt_bpf.h" 44#include "opt_mac.h" 45#include "opt_netgraph.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 150 unchanged lines hidden (view full) --- 199 return (EIO); 200 } 201 202 len = uio->uio_resid; 203 *datlen = len - hlen; 204 if ((unsigned)len > MCLBYTES) 205 return (EIO); 206 |
207 MGETHDR(m, M_TRYWAIT, MT_DATA); 208 if (m == 0) 209 return (ENOBUFS); | |
210 if (len > MHLEN) { | 207 if (len > MHLEN) { |
211 MCLGET(m, M_TRYWAIT); 212 if ((m->m_flags & M_EXT) == 0) { 213 error = ENOBUFS; 214 goto bad; 215 } | 208 m = m_getcl(M_TRYWAIT, MT_DATA, M_PKTHDR); 209 } else { 210 MGETHDR(m, M_TRYWAIT, MT_DATA); |
216 } | 211 } |
212 if (m == NULL) 213 return (ENOBUFS); |
|
217 m->m_pkthdr.len = m->m_len = len; 218 m->m_pkthdr.rcvif = NULL; 219 *mp = m; | 214 m->m_pkthdr.len = m->m_len = len; 215 m->m_pkthdr.rcvif = NULL; 216 *mp = m; |
217 |
|
220 /* 221 * Make room for link header. 222 */ 223 if (hlen != 0) { 224 m->m_pkthdr.len -= hlen; 225 m->m_len -= hlen; 226#if BSD >= 199103 227 m->m_data += hlen; /* XXX */ 228#else 229 m->m_off += hlen; 230#endif 231 error = uiomove((caddr_t)sockp->sa_data, hlen, uio); 232 if (error) 233 goto bad; 234 } 235 error = uiomove(mtod(m, caddr_t), len - hlen, uio); 236 if (!error) 237 return (0); | 218 /* 219 * Make room for link header. 220 */ 221 if (hlen != 0) { 222 m->m_pkthdr.len -= hlen; 223 m->m_len -= hlen; 224#if BSD >= 199103 225 m->m_data += hlen; /* XXX */ 226#else 227 m->m_off += hlen; 228#endif 229 error = uiomove((caddr_t)sockp->sa_data, hlen, uio); 230 if (error) 231 goto bad; 232 } 233 error = uiomove(mtod(m, caddr_t), len - hlen, uio); 234 if (!error) 235 return (0); |
238 bad: | 236bad: |
239 m_freem(m); 240 return (error); 241} 242 243/* 244 * Attach file to the bpf interface, i.e. make d listen on bp. 245 */ 246static void --- 6 unchanged lines hidden (view full) --- 253 * Finally, point the driver's bpf cookie at the interface so 254 * it will divert packets to bpf. 255 */ 256 BPFIF_LOCK(bp); 257 d->bd_bif = bp; 258 d->bd_next = bp->bif_dlist; 259 bp->bif_dlist = d; 260 | 237 m_freem(m); 238 return (error); 239} 240 241/* 242 * Attach file to the bpf interface, i.e. make d listen on bp. 243 */ 244static void --- 6 unchanged lines hidden (view full) --- 251 * Finally, point the driver's bpf cookie at the interface so 252 * it will divert packets to bpf. 253 */ 254 BPFIF_LOCK(bp); 255 d->bd_bif = bp; 256 d->bd_next = bp->bif_dlist; 257 bp->bif_dlist = d; 258 |
261 bp->bif_ifp->if_bpf = bp; | 259 *bp->bif_driverp = bp; |
262 BPFIF_UNLOCK(bp); 263} 264 265/* 266 * Detach a file from its interface. 267 */ 268static void 269bpf_detachd(d) --- 29 unchanged lines hidden (view full) --- 299 if (*p == 0) 300 panic("bpf_detachd: descriptor not in list"); 301 } 302 *p = (*p)->bd_next; 303 if (bp->bif_dlist == 0) 304 /* 305 * Let the driver know that there are no more listeners. 306 */ | 260 BPFIF_UNLOCK(bp); 261} 262 263/* 264 * Detach a file from its interface. 265 */ 266static void 267bpf_detachd(d) --- 29 unchanged lines hidden (view full) --- 297 if (*p == 0) 298 panic("bpf_detachd: descriptor not in list"); 299 } 300 *p = (*p)->bd_next; 301 if (bp->bif_dlist == 0) 302 /* 303 * Let the driver know that there are no more listeners. 304 */ |
307 d->bd_bif->bif_ifp->if_bpf = 0; | 305 *d->bd_bif->bif_driverp = 0; |
308 BPFIF_UNLOCK(bp); 309 d->bd_bif = 0; 310} 311 312/* 313 * Open ethernet device. Returns ENXIO for illegal minor device number, 314 * EBUSY if file is open by another process. 315 */ --- 648 unchanged lines hidden (view full) --- 964 * Look through attached interfaces for the named one. 965 */ 966 mtx_lock(&bpf_mtx); 967 for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 968 struct ifnet *ifp = bp->bif_ifp; 969 970 if (ifp == 0 || ifp != theywant) 971 continue; | 306 BPFIF_UNLOCK(bp); 307 d->bd_bif = 0; 308} 309 310/* 311 * Open ethernet device. Returns ENXIO for illegal minor device number, 312 * EBUSY if file is open by another process. 313 */ --- 648 unchanged lines hidden (view full) --- 962 * Look through attached interfaces for the named one. 963 */ 964 mtx_lock(&bpf_mtx); 965 for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) { 966 struct ifnet *ifp = bp->bif_ifp; 967 968 if (ifp == 0 || ifp != theywant) 969 continue; |
970 /* skip additional entry */ 971 if (bp->bif_driverp != (struct bpf_if **)&ifp->if_bpf) 972 continue; |
|
972 973 mtx_unlock(&bpf_mtx); 974 /* 975 * We found the requested interface. 976 * If it's not up, return an error. 977 * Allocate the packet buffers if we need to. 978 * If we're already attached to requested interface, 979 * just flush the buffer. --- 73 unchanged lines hidden (view full) --- 1053 1054/* 1055 * Incoming linkage from device drivers. Process the packet pkt, of length 1056 * pktlen, which is stored in a contiguous buffer. The packet is parsed 1057 * by each process' filter, and if accepted, stashed into the corresponding 1058 * buffer. 1059 */ 1060void | 973 974 mtx_unlock(&bpf_mtx); 975 /* 976 * We found the requested interface. 977 * If it's not up, return an error. 978 * Allocate the packet buffers if we need to. 979 * If we're already attached to requested interface, 980 * just flush the buffer. --- 73 unchanged lines hidden (view full) --- 1054 1055/* 1056 * Incoming linkage from device drivers. Process the packet pkt, of length 1057 * pktlen, which is stored in a contiguous buffer. The packet is parsed 1058 * by each process' filter, and if accepted, stashed into the corresponding 1059 * buffer. 1060 */ 1061void |
1061bpf_tap(ifp, pkt, pktlen) 1062 struct ifnet *ifp; | 1062bpf_tap(bp, pkt, pktlen) 1063 struct bpf_if *bp; |
1063 register u_char *pkt; 1064 register u_int pktlen; 1065{ | 1064 register u_char *pkt; 1065 register u_int pktlen; 1066{ |
1066 struct bpf_if *bp; | |
1067 register struct bpf_d *d; 1068 register u_int slen; 1069 | 1067 register struct bpf_d *d; 1068 register u_int slen; 1069 |
1070 bp = ifp->if_bpf; | |
1071 BPFIF_LOCK(bp); 1072 for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1073 BPFD_LOCK(d); 1074 ++d->bd_rcount; 1075 slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 1076 if (slen != 0) { 1077#ifdef MAC | 1070 BPFIF_LOCK(bp); 1071 for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1072 BPFD_LOCK(d); 1073 ++d->bd_rcount; 1074 slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen); 1075 if (slen != 0) { 1076#ifdef MAC |
1078 if (mac_check_bpfdesc_receive(d, ifp) == 0) | 1077 if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) |
1079#endif 1080 catchpacket(d, pkt, pktlen, slen, bcopy); 1081 } 1082 BPFD_UNLOCK(d); 1083 } 1084 BPFIF_UNLOCK(bp); 1085} 1086 --- 23 unchanged lines hidden (view full) --- 1110 len -= count; 1111 } 1112} 1113 1114/* 1115 * Incoming linkage from device drivers, when packet is in an mbuf chain. 1116 */ 1117void | 1078#endif 1079 catchpacket(d, pkt, pktlen, slen, bcopy); 1080 } 1081 BPFD_UNLOCK(d); 1082 } 1083 BPFIF_UNLOCK(bp); 1084} 1085 --- 23 unchanged lines hidden (view full) --- 1109 len -= count; 1110 } 1111} 1112 1113/* 1114 * Incoming linkage from device drivers, when packet is in an mbuf chain. 1115 */ 1116void |
1118bpf_mtap(ifp, m) 1119 struct ifnet *ifp; | 1117bpf_mtap(bp, m) 1118 struct bpf_if *bp; |
1120 struct mbuf *m; 1121{ | 1119 struct mbuf *m; 1120{ |
1122 struct bpf_if *bp = ifp->if_bpf; | |
1123 struct bpf_d *d; 1124 u_int pktlen, slen; 1125 1126 pktlen = m_length(m, NULL); 1127 if (pktlen == m->m_len) { | 1121 struct bpf_d *d; 1122 u_int pktlen, slen; 1123 1124 pktlen = m_length(m, NULL); 1125 if (pktlen == m->m_len) { |
1128 bpf_tap(ifp, mtod(m, u_char *), pktlen); | 1126 bpf_tap(bp, mtod(m, u_char *), pktlen); |
1129 return; 1130 } 1131 1132 BPFIF_LOCK(bp); 1133 for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1134 if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL)) 1135 continue; 1136 BPFD_LOCK(d); 1137 ++d->bd_rcount; 1138 slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 1139 if (slen != 0) 1140#ifdef MAC | 1127 return; 1128 } 1129 1130 BPFIF_LOCK(bp); 1131 for (d = bp->bif_dlist; d != 0; d = d->bd_next) { 1132 if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL)) 1133 continue; 1134 BPFD_LOCK(d); 1135 ++d->bd_rcount; 1136 slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0); 1137 if (slen != 0) 1138#ifdef MAC |
1141 if (mac_check_bpfdesc_receive(d, ifp) == 0) | 1139 if (mac_check_bpfdesc_receive(d, bp->bif_ifp) == 0) |
1142#endif 1143 catchpacket(d, (u_char *)m, pktlen, slen, 1144 bpf_mcopy); 1145 BPFD_UNLOCK(d); 1146 } 1147 BPFIF_UNLOCK(bp); 1148} 1149 --- 111 unchanged lines hidden (view full) --- 1261 free(d->bd_fbuf, M_BPF); 1262 } 1263 if (d->bd_filter) 1264 free((caddr_t)d->bd_filter, M_BPF); 1265 mtx_destroy(&d->bd_mtx); 1266} 1267 1268/* | 1140#endif 1141 catchpacket(d, (u_char *)m, pktlen, slen, 1142 bpf_mcopy); 1143 BPFD_UNLOCK(d); 1144 } 1145 BPFIF_UNLOCK(bp); 1146} 1147 --- 111 unchanged lines hidden (view full) --- 1259 free(d->bd_fbuf, M_BPF); 1260 } 1261 if (d->bd_filter) 1262 free((caddr_t)d->bd_filter, M_BPF); 1263 mtx_destroy(&d->bd_mtx); 1264} 1265 1266/* |
1267 * Attach an interface to bpf. dlt is the link layer type; hdrlen is the 1268 * fixed size of the link header (variable length headers not yet supported). 1269 */ 1270void 1271bpfattach(ifp, dlt, hdrlen) 1272 struct ifnet *ifp; 1273 u_int dlt, hdrlen; 1274{ 1275 1276 bpfattach2(ifp, dlt, hdrlen, &ifp->if_bpf); 1277} 1278 1279/* |
|
1269 * Attach an interface to bpf. ifp is a pointer to the structure 1270 * defining the interface to be attached, dlt is the link layer type, 1271 * and hdrlen is the fixed size of the link header (variable length 1272 * headers are not yet supporrted). 1273 */ 1274void | 1280 * Attach an interface to bpf. ifp is a pointer to the structure 1281 * defining the interface to be attached, dlt is the link layer type, 1282 * and hdrlen is the fixed size of the link header (variable length 1283 * headers are not yet supporrted). 1284 */ 1285void |
1275bpfattach(ifp, dlt, hdrlen) | 1286bpfattach2(ifp, dlt, hdrlen, driverp) |
1276 struct ifnet *ifp; 1277 u_int dlt, hdrlen; | 1287 struct ifnet *ifp; 1288 u_int dlt, hdrlen; |
1289 struct bpf_if **driverp; |
|
1278{ 1279 struct bpf_if *bp; 1280 bp = (struct bpf_if *)malloc(sizeof(*bp), M_BPF, M_NOWAIT | M_ZERO); 1281 if (bp == 0) 1282 panic("bpfattach"); 1283 | 1290{ 1291 struct bpf_if *bp; 1292 bp = (struct bpf_if *)malloc(sizeof(*bp), M_BPF, M_NOWAIT | M_ZERO); 1293 if (bp == 0) 1294 panic("bpfattach"); 1295 |
1296 bp->bif_dlist = 0; 1297 bp->bif_driverp = driverp; |
|
1284 bp->bif_ifp = ifp; 1285 bp->bif_dlt = dlt; 1286 mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF); 1287 1288 mtx_lock(&bpf_mtx); 1289 bp->bif_next = bpf_iflist; 1290 bpf_iflist = bp; 1291 mtx_unlock(&bpf_mtx); 1292 | 1298 bp->bif_ifp = ifp; 1299 bp->bif_dlt = dlt; 1300 mtx_init(&bp->bif_mtx, "bpf interface lock", NULL, MTX_DEF); 1301 1302 mtx_lock(&bpf_mtx); 1303 bp->bif_next = bpf_iflist; 1304 bpf_iflist = bp; 1305 mtx_unlock(&bpf_mtx); 1306 |
1293 bp->bif_ifp->if_bpf = 0; | 1307 *bp->bif_driverp = 0; |
1294 1295 /* 1296 * Compute the length of the bpf header. This is not necessarily 1297 * equal to SIZEOF_BPF_HDR because we want to insert spacing such 1298 * that the network layer header begins on a longword boundary (for 1299 * performance reasons and to alleviate alignment restrictions). 1300 */ 1301 bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 1302 1303 if (bootverbose) | 1308 1309 /* 1310 * Compute the length of the bpf header. This is not necessarily 1311 * equal to SIZEOF_BPF_HDR because we want to insert spacing such 1312 * that the network layer header begins on a longword boundary (for 1313 * performance reasons and to alleviate alignment restrictions). 1314 */ 1315 bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen; 1316 1317 if (bootverbose) |
1304 printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit); | 1318 if_printf(ifp, "bpf attached\n"); |
1305} 1306 1307/* 1308 * Detach bpf from an interface. This involves detaching each descriptor 1309 * associated with the interface, and leaving bd_bif NULL. Notify each 1310 * descriptor as it's detached so that any sleepers wake up and get 1311 * ENXIO. 1312 */ --- 134 unchanged lines hidden --- | 1319} 1320 1321/* 1322 * Detach bpf from an interface. This involves detaching each descriptor 1323 * associated with the interface, and leaving bd_bif NULL. Notify each 1324 * descriptor as it's detached so that any sleepers wake up and get 1325 * ENXIO. 1326 */ --- 134 unchanged lines hidden --- |