1*aca3beaaSApple OSS Distributions /*
2*aca3beaaSApple OSS Distributions * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
3*aca3beaaSApple OSS Distributions *
4*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*aca3beaaSApple OSS Distributions *
6*aca3beaaSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*aca3beaaSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*aca3beaaSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*aca3beaaSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*aca3beaaSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*aca3beaaSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*aca3beaaSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*aca3beaaSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*aca3beaaSApple OSS Distributions *
15*aca3beaaSApple OSS Distributions * Please obtain a copy of the License at
16*aca3beaaSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*aca3beaaSApple OSS Distributions *
18*aca3beaaSApple OSS Distributions * The Original Code and all software distributed under the License are
19*aca3beaaSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*aca3beaaSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*aca3beaaSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*aca3beaaSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*aca3beaaSApple OSS Distributions * Please see the License for the specific language governing rights and
24*aca3beaaSApple OSS Distributions * limitations under the License.
25*aca3beaaSApple OSS Distributions *
26*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*aca3beaaSApple OSS Distributions */
28*aca3beaaSApple OSS Distributions /*
29*aca3beaaSApple OSS Distributions * Copyright (c) 1990, 1991, 1993
30*aca3beaaSApple OSS Distributions * The Regents of the University of California. All rights reserved.
31*aca3beaaSApple OSS Distributions *
32*aca3beaaSApple OSS Distributions * This code is derived from the Stanford/CMU enet packet filter,
33*aca3beaaSApple OSS Distributions * (net/enet.c) distributed as part of 4.3BSD, and code contributed
34*aca3beaaSApple OSS Distributions * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
35*aca3beaaSApple OSS Distributions * Berkeley Laboratory.
36*aca3beaaSApple OSS Distributions *
37*aca3beaaSApple OSS Distributions * Redistribution and use in source and binary forms, with or without
38*aca3beaaSApple OSS Distributions * modification, are permitted provided that the following conditions
39*aca3beaaSApple OSS Distributions * are met:
40*aca3beaaSApple OSS Distributions * 1. Redistributions of source code must retain the above copyright
41*aca3beaaSApple OSS Distributions * notice, this list of conditions and the following disclaimer.
42*aca3beaaSApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright
43*aca3beaaSApple OSS Distributions * notice, this list of conditions and the following disclaimer in the
44*aca3beaaSApple OSS Distributions * documentation and/or other materials provided with the distribution.
45*aca3beaaSApple OSS Distributions * 3. All advertising materials mentioning features or use of this software
46*aca3beaaSApple OSS Distributions * must display the following acknowledgement:
47*aca3beaaSApple OSS Distributions * This product includes software developed by the University of
48*aca3beaaSApple OSS Distributions * California, Berkeley and its contributors.
49*aca3beaaSApple OSS Distributions * 4. Neither the name of the University nor the names of its contributors
50*aca3beaaSApple OSS Distributions * may be used to endorse or promote products derived from this software
51*aca3beaaSApple OSS Distributions * without specific prior written permission.
52*aca3beaaSApple OSS Distributions *
53*aca3beaaSApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54*aca3beaaSApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55*aca3beaaSApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56*aca3beaaSApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57*aca3beaaSApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58*aca3beaaSApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59*aca3beaaSApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60*aca3beaaSApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61*aca3beaaSApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62*aca3beaaSApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63*aca3beaaSApple OSS Distributions * SUCH DAMAGE.
64*aca3beaaSApple OSS Distributions *
65*aca3beaaSApple OSS Distributions * @(#)bpf_filter.c 8.1 (Berkeley) 6/10/93
66*aca3beaaSApple OSS Distributions *
67*aca3beaaSApple OSS Distributions * $FreeBSD: src/sys/net/bpf_filter.c,v 1.17 1999/12/29 04:38:31 peter Exp $
68*aca3beaaSApple OSS Distributions */
69*aca3beaaSApple OSS Distributions
70*aca3beaaSApple OSS Distributions #include <sys/param.h>
71*aca3beaaSApple OSS Distributions #include <string.h>
72*aca3beaaSApple OSS Distributions
73*aca3beaaSApple OSS Distributions #ifdef sun
74*aca3beaaSApple OSS Distributions #include <netinet/in.h>
75*aca3beaaSApple OSS Distributions #endif
76*aca3beaaSApple OSS Distributions
77*aca3beaaSApple OSS Distributions #ifdef KERNEL
78*aca3beaaSApple OSS Distributions #include <sys/mbuf.h>
79*aca3beaaSApple OSS Distributions #endif
80*aca3beaaSApple OSS Distributions #include <net/bpf.h>
81*aca3beaaSApple OSS Distributions #ifdef KERNEL
82*aca3beaaSApple OSS Distributions
83*aca3beaaSApple OSS Distributions extern unsigned int bpf_maxbufsize;
84*aca3beaaSApple OSS Distributions
85*aca3beaaSApple OSS Distributions static inline u_int32_t
get_word_from_buffers(u_char * cp,u_char * np,size_t num_from_cp)86*aca3beaaSApple OSS Distributions get_word_from_buffers(u_char * cp, u_char * np, size_t num_from_cp)
87*aca3beaaSApple OSS Distributions {
88*aca3beaaSApple OSS Distributions u_int32_t val;
89*aca3beaaSApple OSS Distributions
90*aca3beaaSApple OSS Distributions switch (num_from_cp) {
91*aca3beaaSApple OSS Distributions case 1:
92*aca3beaaSApple OSS Distributions val = ((u_int32_t)cp[0] << 24) |
93*aca3beaaSApple OSS Distributions ((u_int32_t)np[0] << 16) |
94*aca3beaaSApple OSS Distributions ((u_int32_t)np[1] << 8) |
95*aca3beaaSApple OSS Distributions (u_int32_t)np[2];
96*aca3beaaSApple OSS Distributions break;
97*aca3beaaSApple OSS Distributions
98*aca3beaaSApple OSS Distributions case 2:
99*aca3beaaSApple OSS Distributions val = ((u_int32_t)cp[0] << 24) |
100*aca3beaaSApple OSS Distributions ((u_int32_t)cp[1] << 16) |
101*aca3beaaSApple OSS Distributions ((u_int32_t)np[0] << 8) |
102*aca3beaaSApple OSS Distributions (u_int32_t)np[1];
103*aca3beaaSApple OSS Distributions break;
104*aca3beaaSApple OSS Distributions default:
105*aca3beaaSApple OSS Distributions val = ((u_int32_t)cp[0] << 24) |
106*aca3beaaSApple OSS Distributions ((u_int32_t)cp[1] << 16) |
107*aca3beaaSApple OSS Distributions ((u_int32_t)cp[2] << 8) |
108*aca3beaaSApple OSS Distributions (u_int32_t)np[0];
109*aca3beaaSApple OSS Distributions break;
110*aca3beaaSApple OSS Distributions }
111*aca3beaaSApple OSS Distributions return val;
112*aca3beaaSApple OSS Distributions }
113*aca3beaaSApple OSS Distributions
114*aca3beaaSApple OSS Distributions static u_char *
m_hdr_offset(struct mbuf ** m_p,void * hdr,size_t hdrlen,bpf_u_int32 * k_p,size_t * len_p)115*aca3beaaSApple OSS Distributions m_hdr_offset(struct mbuf **m_p, void * hdr, size_t hdrlen, bpf_u_int32 * k_p,
116*aca3beaaSApple OSS Distributions size_t * len_p)
117*aca3beaaSApple OSS Distributions {
118*aca3beaaSApple OSS Distributions u_char *cp;
119*aca3beaaSApple OSS Distributions bpf_u_int32 k = *k_p;
120*aca3beaaSApple OSS Distributions size_t len;
121*aca3beaaSApple OSS Distributions
122*aca3beaaSApple OSS Distributions if (k >= hdrlen) {
123*aca3beaaSApple OSS Distributions struct mbuf *m = *m_p;
124*aca3beaaSApple OSS Distributions
125*aca3beaaSApple OSS Distributions /* there's no header or the offset we want is past the header */
126*aca3beaaSApple OSS Distributions k -= hdrlen;
127*aca3beaaSApple OSS Distributions len = m->m_len;
128*aca3beaaSApple OSS Distributions while (k >= len) {
129*aca3beaaSApple OSS Distributions k -= len;
130*aca3beaaSApple OSS Distributions m = m->m_next;
131*aca3beaaSApple OSS Distributions if (m == NULL) {
132*aca3beaaSApple OSS Distributions return NULL;
133*aca3beaaSApple OSS Distributions }
134*aca3beaaSApple OSS Distributions len = m->m_len;
135*aca3beaaSApple OSS Distributions }
136*aca3beaaSApple OSS Distributions cp = mtod(m, u_char *) + k;
137*aca3beaaSApple OSS Distributions
138*aca3beaaSApple OSS Distributions /* return next mbuf, in case it's needed */
139*aca3beaaSApple OSS Distributions *m_p = m->m_next;
140*aca3beaaSApple OSS Distributions
141*aca3beaaSApple OSS Distributions /* update the offset */
142*aca3beaaSApple OSS Distributions *k_p = k;
143*aca3beaaSApple OSS Distributions } else {
144*aca3beaaSApple OSS Distributions len = hdrlen;
145*aca3beaaSApple OSS Distributions cp = (u_char *)hdr + k;
146*aca3beaaSApple OSS Distributions }
147*aca3beaaSApple OSS Distributions *len_p = len;
148*aca3beaaSApple OSS Distributions return cp;
149*aca3beaaSApple OSS Distributions }
150*aca3beaaSApple OSS Distributions
151*aca3beaaSApple OSS Distributions static u_int32_t
m_xword(struct mbuf * m,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)152*aca3beaaSApple OSS Distributions m_xword(struct mbuf *m, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
153*aca3beaaSApple OSS Distributions {
154*aca3beaaSApple OSS Distributions size_t len;
155*aca3beaaSApple OSS Distributions u_char *cp, *np;
156*aca3beaaSApple OSS Distributions
157*aca3beaaSApple OSS Distributions cp = m_hdr_offset(&m, hdr, hdrlen, &k, &len);
158*aca3beaaSApple OSS Distributions if (cp == NULL) {
159*aca3beaaSApple OSS Distributions goto bad;
160*aca3beaaSApple OSS Distributions }
161*aca3beaaSApple OSS Distributions if (len - k >= 4) {
162*aca3beaaSApple OSS Distributions *err = 0;
163*aca3beaaSApple OSS Distributions return EXTRACT_LONG(cp);
164*aca3beaaSApple OSS Distributions }
165*aca3beaaSApple OSS Distributions if (m == 0 || m->m_len + len - k < 4) {
166*aca3beaaSApple OSS Distributions goto bad;
167*aca3beaaSApple OSS Distributions }
168*aca3beaaSApple OSS Distributions *err = 0;
169*aca3beaaSApple OSS Distributions np = mtod(m, u_char *);
170*aca3beaaSApple OSS Distributions return get_word_from_buffers(cp, np, len - k);
171*aca3beaaSApple OSS Distributions
172*aca3beaaSApple OSS Distributions bad:
173*aca3beaaSApple OSS Distributions *err = 1;
174*aca3beaaSApple OSS Distributions return 0;
175*aca3beaaSApple OSS Distributions }
176*aca3beaaSApple OSS Distributions
177*aca3beaaSApple OSS Distributions static uint16_t
m_xhalf(struct mbuf * m,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)178*aca3beaaSApple OSS Distributions m_xhalf(struct mbuf *m, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
179*aca3beaaSApple OSS Distributions {
180*aca3beaaSApple OSS Distributions size_t len;
181*aca3beaaSApple OSS Distributions u_char *cp;
182*aca3beaaSApple OSS Distributions
183*aca3beaaSApple OSS Distributions cp = m_hdr_offset(&m, hdr, hdrlen, &k, &len);
184*aca3beaaSApple OSS Distributions if (cp == NULL) {
185*aca3beaaSApple OSS Distributions goto bad;
186*aca3beaaSApple OSS Distributions }
187*aca3beaaSApple OSS Distributions if (len - k >= 2) {
188*aca3beaaSApple OSS Distributions *err = 0;
189*aca3beaaSApple OSS Distributions return EXTRACT_SHORT(cp);
190*aca3beaaSApple OSS Distributions }
191*aca3beaaSApple OSS Distributions if (m == 0) {
192*aca3beaaSApple OSS Distributions goto bad;
193*aca3beaaSApple OSS Distributions }
194*aca3beaaSApple OSS Distributions *err = 0;
195*aca3beaaSApple OSS Distributions return (uint16_t)((cp[0] << 8) | mtod(m, u_char *)[0]);
196*aca3beaaSApple OSS Distributions bad:
197*aca3beaaSApple OSS Distributions *err = 1;
198*aca3beaaSApple OSS Distributions return 0;
199*aca3beaaSApple OSS Distributions }
200*aca3beaaSApple OSS Distributions
201*aca3beaaSApple OSS Distributions static u_int8_t
m_xbyte(struct mbuf * m,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)202*aca3beaaSApple OSS Distributions m_xbyte(struct mbuf *m, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
203*aca3beaaSApple OSS Distributions {
204*aca3beaaSApple OSS Distributions size_t len;
205*aca3beaaSApple OSS Distributions u_char *cp;
206*aca3beaaSApple OSS Distributions
207*aca3beaaSApple OSS Distributions cp = m_hdr_offset(&m, hdr, hdrlen, &k, &len);
208*aca3beaaSApple OSS Distributions if (cp == NULL) {
209*aca3beaaSApple OSS Distributions goto bad;
210*aca3beaaSApple OSS Distributions }
211*aca3beaaSApple OSS Distributions *err = 0;
212*aca3beaaSApple OSS Distributions return *cp;
213*aca3beaaSApple OSS Distributions bad:
214*aca3beaaSApple OSS Distributions *err = 1;
215*aca3beaaSApple OSS Distributions return 0;
216*aca3beaaSApple OSS Distributions }
217*aca3beaaSApple OSS Distributions
218*aca3beaaSApple OSS Distributions #if SKYWALK
219*aca3beaaSApple OSS Distributions
220*aca3beaaSApple OSS Distributions #include <skywalk/os_skywalk_private.h>
221*aca3beaaSApple OSS Distributions
222*aca3beaaSApple OSS Distributions static void *
buflet_get_address(kern_buflet_t buflet)223*aca3beaaSApple OSS Distributions buflet_get_address(kern_buflet_t buflet)
224*aca3beaaSApple OSS Distributions {
225*aca3beaaSApple OSS Distributions uint8_t *addr;
226*aca3beaaSApple OSS Distributions
227*aca3beaaSApple OSS Distributions addr = kern_buflet_get_data_address(buflet);
228*aca3beaaSApple OSS Distributions if (addr == NULL) {
229*aca3beaaSApple OSS Distributions return NULL;
230*aca3beaaSApple OSS Distributions }
231*aca3beaaSApple OSS Distributions return addr + kern_buflet_get_data_offset(buflet);
232*aca3beaaSApple OSS Distributions }
233*aca3beaaSApple OSS Distributions
234*aca3beaaSApple OSS Distributions static u_char *
p_hdr_offset(kern_packet_t p,void * hdr,size_t hdrlen,bpf_u_int32 * k_p,size_t * len_p,kern_buflet_t * buflet_p)235*aca3beaaSApple OSS Distributions p_hdr_offset(kern_packet_t p, void * hdr, size_t hdrlen, bpf_u_int32 * k_p,
236*aca3beaaSApple OSS Distributions size_t * len_p, kern_buflet_t * buflet_p)
237*aca3beaaSApple OSS Distributions {
238*aca3beaaSApple OSS Distributions u_char *cp = NULL;
239*aca3beaaSApple OSS Distributions bpf_u_int32 k = *k_p;
240*aca3beaaSApple OSS Distributions size_t len;
241*aca3beaaSApple OSS Distributions kern_buflet_t buflet = NULL;
242*aca3beaaSApple OSS Distributions
243*aca3beaaSApple OSS Distributions if (k >= hdrlen) {
244*aca3beaaSApple OSS Distributions k -= hdrlen;
245*aca3beaaSApple OSS Distributions for (;;) {
246*aca3beaaSApple OSS Distributions buflet = kern_packet_get_next_buflet(p, buflet);
247*aca3beaaSApple OSS Distributions if (buflet == NULL) {
248*aca3beaaSApple OSS Distributions break;
249*aca3beaaSApple OSS Distributions }
250*aca3beaaSApple OSS Distributions len = kern_buflet_get_data_length(buflet);
251*aca3beaaSApple OSS Distributions if (k < len) {
252*aca3beaaSApple OSS Distributions break;
253*aca3beaaSApple OSS Distributions }
254*aca3beaaSApple OSS Distributions k -= len;
255*aca3beaaSApple OSS Distributions }
256*aca3beaaSApple OSS Distributions if (buflet == NULL) {
257*aca3beaaSApple OSS Distributions return NULL;
258*aca3beaaSApple OSS Distributions }
259*aca3beaaSApple OSS Distributions cp = (u_char *)buflet_get_address(buflet) + k;
260*aca3beaaSApple OSS Distributions /* update the offset */
261*aca3beaaSApple OSS Distributions *k_p = k;
262*aca3beaaSApple OSS Distributions } else {
263*aca3beaaSApple OSS Distributions len = hdrlen;
264*aca3beaaSApple OSS Distributions cp = (u_char *)hdr + k;
265*aca3beaaSApple OSS Distributions }
266*aca3beaaSApple OSS Distributions *len_p = len;
267*aca3beaaSApple OSS Distributions *buflet_p = buflet;
268*aca3beaaSApple OSS Distributions return cp;
269*aca3beaaSApple OSS Distributions }
270*aca3beaaSApple OSS Distributions
271*aca3beaaSApple OSS Distributions static u_int32_t
p_xword(kern_packet_t p,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)272*aca3beaaSApple OSS Distributions p_xword(kern_packet_t p, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
273*aca3beaaSApple OSS Distributions {
274*aca3beaaSApple OSS Distributions kern_buflet_t buflet = NULL;
275*aca3beaaSApple OSS Distributions u_char *cp;
276*aca3beaaSApple OSS Distributions size_t len = 0;
277*aca3beaaSApple OSS Distributions u_char *np;
278*aca3beaaSApple OSS Distributions
279*aca3beaaSApple OSS Distributions cp = p_hdr_offset(p, hdr, hdrlen, &k, &len, &buflet);
280*aca3beaaSApple OSS Distributions if (cp == NULL) {
281*aca3beaaSApple OSS Distributions goto bad;
282*aca3beaaSApple OSS Distributions }
283*aca3beaaSApple OSS Distributions if ((len - k) >= 4) {
284*aca3beaaSApple OSS Distributions *err = 0;
285*aca3beaaSApple OSS Distributions return EXTRACT_LONG(cp);
286*aca3beaaSApple OSS Distributions }
287*aca3beaaSApple OSS Distributions buflet = kern_packet_get_next_buflet(p, buflet);
288*aca3beaaSApple OSS Distributions if (buflet == NULL ||
289*aca3beaaSApple OSS Distributions (kern_buflet_get_data_length(buflet) + len - k) < 4) {
290*aca3beaaSApple OSS Distributions goto bad;
291*aca3beaaSApple OSS Distributions }
292*aca3beaaSApple OSS Distributions *err = 0;
293*aca3beaaSApple OSS Distributions np = (u_char *)buflet_get_address(buflet);
294*aca3beaaSApple OSS Distributions return get_word_from_buffers(cp, np, len - k);
295*aca3beaaSApple OSS Distributions
296*aca3beaaSApple OSS Distributions bad:
297*aca3beaaSApple OSS Distributions *err = 1;
298*aca3beaaSApple OSS Distributions return 0;
299*aca3beaaSApple OSS Distributions }
300*aca3beaaSApple OSS Distributions
301*aca3beaaSApple OSS Distributions static uint16_t
p_xhalf(kern_packet_t p,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)302*aca3beaaSApple OSS Distributions p_xhalf(kern_packet_t p, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
303*aca3beaaSApple OSS Distributions {
304*aca3beaaSApple OSS Distributions kern_buflet_t buflet = NULL;
305*aca3beaaSApple OSS Distributions u_char *cp;
306*aca3beaaSApple OSS Distributions size_t len = 0;
307*aca3beaaSApple OSS Distributions u_char *np;
308*aca3beaaSApple OSS Distributions
309*aca3beaaSApple OSS Distributions cp = p_hdr_offset(p, hdr, hdrlen, &k, &len, &buflet);
310*aca3beaaSApple OSS Distributions if (cp == NULL) {
311*aca3beaaSApple OSS Distributions goto bad;
312*aca3beaaSApple OSS Distributions }
313*aca3beaaSApple OSS Distributions if ((len - k) >= 2) {
314*aca3beaaSApple OSS Distributions *err = 0;
315*aca3beaaSApple OSS Distributions return EXTRACT_SHORT(cp);
316*aca3beaaSApple OSS Distributions }
317*aca3beaaSApple OSS Distributions buflet = kern_packet_get_next_buflet(p, buflet);
318*aca3beaaSApple OSS Distributions if (buflet == NULL || kern_buflet_get_data_length(buflet) == 0) {
319*aca3beaaSApple OSS Distributions goto bad;
320*aca3beaaSApple OSS Distributions }
321*aca3beaaSApple OSS Distributions np = (u_char *)buflet_get_address(buflet);
322*aca3beaaSApple OSS Distributions *err = 0;
323*aca3beaaSApple OSS Distributions return (uint16_t)((cp[0] << 8) | np[0]);
324*aca3beaaSApple OSS Distributions bad:
325*aca3beaaSApple OSS Distributions *err = 1;
326*aca3beaaSApple OSS Distributions return 0;
327*aca3beaaSApple OSS Distributions }
328*aca3beaaSApple OSS Distributions
329*aca3beaaSApple OSS Distributions static u_int8_t
p_xbyte(kern_packet_t p,void * hdr,size_t hdrlen,bpf_u_int32 k,int * err)330*aca3beaaSApple OSS Distributions p_xbyte(kern_packet_t p, void * hdr, size_t hdrlen, bpf_u_int32 k, int *err)
331*aca3beaaSApple OSS Distributions {
332*aca3beaaSApple OSS Distributions kern_buflet_t buflet = NULL;
333*aca3beaaSApple OSS Distributions u_char *cp;
334*aca3beaaSApple OSS Distributions size_t len = 0;
335*aca3beaaSApple OSS Distributions
336*aca3beaaSApple OSS Distributions cp = p_hdr_offset(p, hdr, hdrlen, &k, &len, &buflet);
337*aca3beaaSApple OSS Distributions if (cp == NULL) {
338*aca3beaaSApple OSS Distributions goto bad;
339*aca3beaaSApple OSS Distributions }
340*aca3beaaSApple OSS Distributions *err = 0;
341*aca3beaaSApple OSS Distributions return *cp;
342*aca3beaaSApple OSS Distributions bad:
343*aca3beaaSApple OSS Distributions *err = 1;
344*aca3beaaSApple OSS Distributions return 0;
345*aca3beaaSApple OSS Distributions }
346*aca3beaaSApple OSS Distributions
347*aca3beaaSApple OSS Distributions #endif /* SKYWALK */
348*aca3beaaSApple OSS Distributions
349*aca3beaaSApple OSS Distributions static u_int32_t
bp_xword(struct bpf_packet * bp,bpf_u_int32 k,int * err)350*aca3beaaSApple OSS Distributions bp_xword(struct bpf_packet *bp, bpf_u_int32 k, int *err)
351*aca3beaaSApple OSS Distributions {
352*aca3beaaSApple OSS Distributions void * hdr = bp->bpfp_header;
353*aca3beaaSApple OSS Distributions size_t hdrlen = bp->bpfp_header_length;
354*aca3beaaSApple OSS Distributions
355*aca3beaaSApple OSS Distributions switch (bp->bpfp_type) {
356*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_MBUF:
357*aca3beaaSApple OSS Distributions return m_xword(bp->bpfp_mbuf, hdr, hdrlen, k, err);
358*aca3beaaSApple OSS Distributions #if SKYWALK
359*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_PKT:
360*aca3beaaSApple OSS Distributions return p_xword(bp->bpfp_pkt, hdr, hdrlen, k, err);
361*aca3beaaSApple OSS Distributions #endif /* SKYWALK */
362*aca3beaaSApple OSS Distributions default:
363*aca3beaaSApple OSS Distributions break;
364*aca3beaaSApple OSS Distributions }
365*aca3beaaSApple OSS Distributions *err = 1;
366*aca3beaaSApple OSS Distributions return 0;
367*aca3beaaSApple OSS Distributions }
368*aca3beaaSApple OSS Distributions
369*aca3beaaSApple OSS Distributions static u_int16_t
bp_xhalf(struct bpf_packet * bp,bpf_u_int32 k,int * err)370*aca3beaaSApple OSS Distributions bp_xhalf(struct bpf_packet *bp, bpf_u_int32 k, int *err)
371*aca3beaaSApple OSS Distributions {
372*aca3beaaSApple OSS Distributions void * hdr = bp->bpfp_header;
373*aca3beaaSApple OSS Distributions size_t hdrlen = bp->bpfp_header_length;
374*aca3beaaSApple OSS Distributions
375*aca3beaaSApple OSS Distributions switch (bp->bpfp_type) {
376*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_MBUF:
377*aca3beaaSApple OSS Distributions return m_xhalf(bp->bpfp_mbuf, hdr, hdrlen, k, err);
378*aca3beaaSApple OSS Distributions #if SKYWALK
379*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_PKT:
380*aca3beaaSApple OSS Distributions return p_xhalf(bp->bpfp_pkt, hdr, hdrlen, k, err);
381*aca3beaaSApple OSS Distributions #endif /* SKYWALK */
382*aca3beaaSApple OSS Distributions default:
383*aca3beaaSApple OSS Distributions break;
384*aca3beaaSApple OSS Distributions }
385*aca3beaaSApple OSS Distributions *err = 1;
386*aca3beaaSApple OSS Distributions return 0;
387*aca3beaaSApple OSS Distributions }
388*aca3beaaSApple OSS Distributions
389*aca3beaaSApple OSS Distributions static u_int8_t
bp_xbyte(struct bpf_packet * bp,bpf_u_int32 k,int * err)390*aca3beaaSApple OSS Distributions bp_xbyte(struct bpf_packet *bp, bpf_u_int32 k, int *err)
391*aca3beaaSApple OSS Distributions {
392*aca3beaaSApple OSS Distributions void * hdr = bp->bpfp_header;
393*aca3beaaSApple OSS Distributions size_t hdrlen = bp->bpfp_header_length;
394*aca3beaaSApple OSS Distributions
395*aca3beaaSApple OSS Distributions switch (bp->bpfp_type) {
396*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_MBUF:
397*aca3beaaSApple OSS Distributions return m_xbyte(bp->bpfp_mbuf, hdr, hdrlen, k, err);
398*aca3beaaSApple OSS Distributions #if SKYWALK
399*aca3beaaSApple OSS Distributions case BPF_PACKET_TYPE_PKT:
400*aca3beaaSApple OSS Distributions return p_xbyte(bp->bpfp_pkt, hdr, hdrlen, k, err);
401*aca3beaaSApple OSS Distributions #endif /* SKYWALK */
402*aca3beaaSApple OSS Distributions default:
403*aca3beaaSApple OSS Distributions break;
404*aca3beaaSApple OSS Distributions }
405*aca3beaaSApple OSS Distributions *err = 1;
406*aca3beaaSApple OSS Distributions return 0;
407*aca3beaaSApple OSS Distributions }
408*aca3beaaSApple OSS Distributions
409*aca3beaaSApple OSS Distributions #endif
410*aca3beaaSApple OSS Distributions
411*aca3beaaSApple OSS Distributions /*
412*aca3beaaSApple OSS Distributions * Execute the filter program starting at pc on the packet p
413*aca3beaaSApple OSS Distributions * wirelen is the length of the original packet
414*aca3beaaSApple OSS Distributions * buflen is the amount of data present
415*aca3beaaSApple OSS Distributions */
416*aca3beaaSApple OSS Distributions u_int
bpf_filter(const struct bpf_insn * pc,u_char * p,u_int wirelen,u_int buflen)417*aca3beaaSApple OSS Distributions bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen)
418*aca3beaaSApple OSS Distributions {
419*aca3beaaSApple OSS Distributions u_int32_t A = 0, X = 0;
420*aca3beaaSApple OSS Distributions bpf_u_int32 k;
421*aca3beaaSApple OSS Distributions int32_t mem[BPF_MEMWORDS];
422*aca3beaaSApple OSS Distributions #ifdef KERNEL
423*aca3beaaSApple OSS Distributions int merr;
424*aca3beaaSApple OSS Distributions struct bpf_packet * bp = (struct bpf_packet *)(void *)p;
425*aca3beaaSApple OSS Distributions #endif /* KERNEL */
426*aca3beaaSApple OSS Distributions
427*aca3beaaSApple OSS Distributions bzero(mem, sizeof(mem));
428*aca3beaaSApple OSS Distributions
429*aca3beaaSApple OSS Distributions if (pc == 0) {
430*aca3beaaSApple OSS Distributions /*
431*aca3beaaSApple OSS Distributions * No filter means accept all.
432*aca3beaaSApple OSS Distributions */
433*aca3beaaSApple OSS Distributions return (u_int) - 1;
434*aca3beaaSApple OSS Distributions }
435*aca3beaaSApple OSS Distributions
436*aca3beaaSApple OSS Distributions --pc;
437*aca3beaaSApple OSS Distributions while (1) {
438*aca3beaaSApple OSS Distributions ++pc;
439*aca3beaaSApple OSS Distributions switch (pc->code) {
440*aca3beaaSApple OSS Distributions default:
441*aca3beaaSApple OSS Distributions #ifdef KERNEL
442*aca3beaaSApple OSS Distributions return 0;
443*aca3beaaSApple OSS Distributions #else /* KERNEL */
444*aca3beaaSApple OSS Distributions abort();
445*aca3beaaSApple OSS Distributions #endif /* KERNEL */
446*aca3beaaSApple OSS Distributions case BPF_RET | BPF_K:
447*aca3beaaSApple OSS Distributions return (u_int)pc->k;
448*aca3beaaSApple OSS Distributions
449*aca3beaaSApple OSS Distributions case BPF_RET | BPF_A:
450*aca3beaaSApple OSS Distributions return (u_int)A;
451*aca3beaaSApple OSS Distributions
452*aca3beaaSApple OSS Distributions case BPF_LD | BPF_W | BPF_ABS:
453*aca3beaaSApple OSS Distributions k = pc->k;
454*aca3beaaSApple OSS Distributions if (k > buflen || sizeof(int32_t) > buflen - k) {
455*aca3beaaSApple OSS Distributions #ifdef KERNEL
456*aca3beaaSApple OSS Distributions if (buflen != 0) {
457*aca3beaaSApple OSS Distributions return 0;
458*aca3beaaSApple OSS Distributions }
459*aca3beaaSApple OSS Distributions A = bp_xword(bp, k, &merr);
460*aca3beaaSApple OSS Distributions if (merr != 0) {
461*aca3beaaSApple OSS Distributions return 0;
462*aca3beaaSApple OSS Distributions }
463*aca3beaaSApple OSS Distributions continue;
464*aca3beaaSApple OSS Distributions #else /* KERNEL */
465*aca3beaaSApple OSS Distributions return 0;
466*aca3beaaSApple OSS Distributions #endif /* KERNEL */
467*aca3beaaSApple OSS Distributions }
468*aca3beaaSApple OSS Distributions #if BPF_ALIGN
469*aca3beaaSApple OSS Distributions if (((intptr_t)(p + k) & 3) != 0) {
470*aca3beaaSApple OSS Distributions A = EXTRACT_LONG(&p[k]);
471*aca3beaaSApple OSS Distributions } else
472*aca3beaaSApple OSS Distributions #endif /* BPF_ALIGN */
473*aca3beaaSApple OSS Distributions A = ntohl(*(int32_t *)(void *)(p + k));
474*aca3beaaSApple OSS Distributions continue;
475*aca3beaaSApple OSS Distributions
476*aca3beaaSApple OSS Distributions case BPF_LD | BPF_H | BPF_ABS:
477*aca3beaaSApple OSS Distributions k = pc->k;
478*aca3beaaSApple OSS Distributions if (k > buflen || sizeof(int16_t) > buflen - k) {
479*aca3beaaSApple OSS Distributions #ifdef KERNEL
480*aca3beaaSApple OSS Distributions if (buflen != 0) {
481*aca3beaaSApple OSS Distributions return 0;
482*aca3beaaSApple OSS Distributions }
483*aca3beaaSApple OSS Distributions A = bp_xhalf(bp, k, &merr);
484*aca3beaaSApple OSS Distributions if (merr != 0) {
485*aca3beaaSApple OSS Distributions return 0;
486*aca3beaaSApple OSS Distributions }
487*aca3beaaSApple OSS Distributions continue;
488*aca3beaaSApple OSS Distributions #else /* KERNEL */
489*aca3beaaSApple OSS Distributions return 0;
490*aca3beaaSApple OSS Distributions #endif /* KERNEL */
491*aca3beaaSApple OSS Distributions }
492*aca3beaaSApple OSS Distributions A = EXTRACT_SHORT(&p[k]);
493*aca3beaaSApple OSS Distributions continue;
494*aca3beaaSApple OSS Distributions
495*aca3beaaSApple OSS Distributions case BPF_LD | BPF_B | BPF_ABS:
496*aca3beaaSApple OSS Distributions k = pc->k;
497*aca3beaaSApple OSS Distributions if (k >= buflen) {
498*aca3beaaSApple OSS Distributions #ifdef KERNEL
499*aca3beaaSApple OSS Distributions if (buflen != 0) {
500*aca3beaaSApple OSS Distributions return 0;
501*aca3beaaSApple OSS Distributions }
502*aca3beaaSApple OSS Distributions A = bp_xbyte(bp, k, &merr);
503*aca3beaaSApple OSS Distributions if (merr != 0) {
504*aca3beaaSApple OSS Distributions return 0;
505*aca3beaaSApple OSS Distributions }
506*aca3beaaSApple OSS Distributions continue;
507*aca3beaaSApple OSS Distributions #else /* KERNEL */
508*aca3beaaSApple OSS Distributions return 0;
509*aca3beaaSApple OSS Distributions #endif /* KERNEL */
510*aca3beaaSApple OSS Distributions }
511*aca3beaaSApple OSS Distributions A = p[k];
512*aca3beaaSApple OSS Distributions continue;
513*aca3beaaSApple OSS Distributions
514*aca3beaaSApple OSS Distributions case BPF_LD | BPF_W | BPF_LEN:
515*aca3beaaSApple OSS Distributions A = wirelen;
516*aca3beaaSApple OSS Distributions continue;
517*aca3beaaSApple OSS Distributions
518*aca3beaaSApple OSS Distributions case BPF_LDX | BPF_W | BPF_LEN:
519*aca3beaaSApple OSS Distributions X = wirelen;
520*aca3beaaSApple OSS Distributions continue;
521*aca3beaaSApple OSS Distributions
522*aca3beaaSApple OSS Distributions case BPF_LD | BPF_W | BPF_IND:
523*aca3beaaSApple OSS Distributions k = X + pc->k;
524*aca3beaaSApple OSS Distributions if (pc->k > buflen || X > buflen - pc->k ||
525*aca3beaaSApple OSS Distributions sizeof(int32_t) > buflen - k) {
526*aca3beaaSApple OSS Distributions #ifdef KERNEL
527*aca3beaaSApple OSS Distributions if (buflen != 0) {
528*aca3beaaSApple OSS Distributions return 0;
529*aca3beaaSApple OSS Distributions }
530*aca3beaaSApple OSS Distributions A = bp_xword(bp, k, &merr);
531*aca3beaaSApple OSS Distributions if (merr != 0) {
532*aca3beaaSApple OSS Distributions return 0;
533*aca3beaaSApple OSS Distributions }
534*aca3beaaSApple OSS Distributions continue;
535*aca3beaaSApple OSS Distributions #else /* KERNEL */
536*aca3beaaSApple OSS Distributions return 0;
537*aca3beaaSApple OSS Distributions #endif /* KERNEL */
538*aca3beaaSApple OSS Distributions }
539*aca3beaaSApple OSS Distributions #if BPF_ALIGN
540*aca3beaaSApple OSS Distributions if (((intptr_t)(p + k) & 3) != 0) {
541*aca3beaaSApple OSS Distributions A = EXTRACT_LONG(&p[k]);
542*aca3beaaSApple OSS Distributions } else
543*aca3beaaSApple OSS Distributions #endif /* BPF_ALIGN */
544*aca3beaaSApple OSS Distributions A = ntohl(*(int32_t *)(void *)(p + k));
545*aca3beaaSApple OSS Distributions continue;
546*aca3beaaSApple OSS Distributions
547*aca3beaaSApple OSS Distributions case BPF_LD | BPF_H | BPF_IND:
548*aca3beaaSApple OSS Distributions k = X + pc->k;
549*aca3beaaSApple OSS Distributions if (X > buflen || pc->k > buflen - X ||
550*aca3beaaSApple OSS Distributions sizeof(int16_t) > buflen - k) {
551*aca3beaaSApple OSS Distributions #ifdef KERNEL
552*aca3beaaSApple OSS Distributions if (buflen != 0) {
553*aca3beaaSApple OSS Distributions return 0;
554*aca3beaaSApple OSS Distributions }
555*aca3beaaSApple OSS Distributions A = bp_xhalf(bp, k, &merr);
556*aca3beaaSApple OSS Distributions if (merr != 0) {
557*aca3beaaSApple OSS Distributions return 0;
558*aca3beaaSApple OSS Distributions }
559*aca3beaaSApple OSS Distributions continue;
560*aca3beaaSApple OSS Distributions #else /* KERNEL */
561*aca3beaaSApple OSS Distributions return 0;
562*aca3beaaSApple OSS Distributions #endif /* KERNEL */
563*aca3beaaSApple OSS Distributions }
564*aca3beaaSApple OSS Distributions A = EXTRACT_SHORT(&p[k]);
565*aca3beaaSApple OSS Distributions continue;
566*aca3beaaSApple OSS Distributions
567*aca3beaaSApple OSS Distributions case BPF_LD | BPF_B | BPF_IND:
568*aca3beaaSApple OSS Distributions k = X + pc->k;
569*aca3beaaSApple OSS Distributions if (pc->k >= buflen || X >= buflen - pc->k) {
570*aca3beaaSApple OSS Distributions #ifdef KERNEL
571*aca3beaaSApple OSS Distributions if (buflen != 0) {
572*aca3beaaSApple OSS Distributions return 0;
573*aca3beaaSApple OSS Distributions }
574*aca3beaaSApple OSS Distributions A = bp_xbyte(bp, k, &merr);
575*aca3beaaSApple OSS Distributions if (merr != 0) {
576*aca3beaaSApple OSS Distributions return 0;
577*aca3beaaSApple OSS Distributions }
578*aca3beaaSApple OSS Distributions continue;
579*aca3beaaSApple OSS Distributions #else /* KERNEL */
580*aca3beaaSApple OSS Distributions return 0;
581*aca3beaaSApple OSS Distributions #endif /* KERNEL */
582*aca3beaaSApple OSS Distributions }
583*aca3beaaSApple OSS Distributions A = p[k];
584*aca3beaaSApple OSS Distributions continue;
585*aca3beaaSApple OSS Distributions
586*aca3beaaSApple OSS Distributions case BPF_LDX | BPF_MSH | BPF_B:
587*aca3beaaSApple OSS Distributions k = pc->k;
588*aca3beaaSApple OSS Distributions if (k >= buflen) {
589*aca3beaaSApple OSS Distributions #ifdef KERNEL
590*aca3beaaSApple OSS Distributions if (buflen != 0) {
591*aca3beaaSApple OSS Distributions return 0;
592*aca3beaaSApple OSS Distributions }
593*aca3beaaSApple OSS Distributions X = bp_xbyte(bp, k, &merr);
594*aca3beaaSApple OSS Distributions if (merr != 0) {
595*aca3beaaSApple OSS Distributions return 0;
596*aca3beaaSApple OSS Distributions }
597*aca3beaaSApple OSS Distributions X = (X & 0xf) << 2;
598*aca3beaaSApple OSS Distributions continue;
599*aca3beaaSApple OSS Distributions #else
600*aca3beaaSApple OSS Distributions return 0;
601*aca3beaaSApple OSS Distributions #endif
602*aca3beaaSApple OSS Distributions }
603*aca3beaaSApple OSS Distributions X = (p[pc->k] & 0xf) << 2;
604*aca3beaaSApple OSS Distributions continue;
605*aca3beaaSApple OSS Distributions
606*aca3beaaSApple OSS Distributions case BPF_LD | BPF_IMM:
607*aca3beaaSApple OSS Distributions A = pc->k;
608*aca3beaaSApple OSS Distributions continue;
609*aca3beaaSApple OSS Distributions
610*aca3beaaSApple OSS Distributions case BPF_LDX | BPF_IMM:
611*aca3beaaSApple OSS Distributions X = pc->k;
612*aca3beaaSApple OSS Distributions continue;
613*aca3beaaSApple OSS Distributions
614*aca3beaaSApple OSS Distributions case BPF_LD | BPF_MEM:
615*aca3beaaSApple OSS Distributions if (pc->k >= BPF_MEMWORDS) {
616*aca3beaaSApple OSS Distributions return 0;
617*aca3beaaSApple OSS Distributions }
618*aca3beaaSApple OSS Distributions A = mem[pc->k];
619*aca3beaaSApple OSS Distributions continue;
620*aca3beaaSApple OSS Distributions
621*aca3beaaSApple OSS Distributions case BPF_LDX | BPF_MEM:
622*aca3beaaSApple OSS Distributions if (pc->k >= BPF_MEMWORDS) {
623*aca3beaaSApple OSS Distributions return 0;
624*aca3beaaSApple OSS Distributions }
625*aca3beaaSApple OSS Distributions X = mem[pc->k];
626*aca3beaaSApple OSS Distributions continue;
627*aca3beaaSApple OSS Distributions
628*aca3beaaSApple OSS Distributions case BPF_ST:
629*aca3beaaSApple OSS Distributions if (pc->k >= BPF_MEMWORDS) {
630*aca3beaaSApple OSS Distributions return 0;
631*aca3beaaSApple OSS Distributions }
632*aca3beaaSApple OSS Distributions mem[pc->k] = A;
633*aca3beaaSApple OSS Distributions continue;
634*aca3beaaSApple OSS Distributions
635*aca3beaaSApple OSS Distributions case BPF_STX:
636*aca3beaaSApple OSS Distributions if (pc->k >= BPF_MEMWORDS) {
637*aca3beaaSApple OSS Distributions return 0;
638*aca3beaaSApple OSS Distributions }
639*aca3beaaSApple OSS Distributions mem[pc->k] = X;
640*aca3beaaSApple OSS Distributions continue;
641*aca3beaaSApple OSS Distributions
642*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JA:
643*aca3beaaSApple OSS Distributions pc += pc->k;
644*aca3beaaSApple OSS Distributions continue;
645*aca3beaaSApple OSS Distributions
646*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JGT | BPF_K:
647*aca3beaaSApple OSS Distributions pc += (A > pc->k) ? pc->jt : pc->jf;
648*aca3beaaSApple OSS Distributions continue;
649*aca3beaaSApple OSS Distributions
650*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JGE | BPF_K:
651*aca3beaaSApple OSS Distributions pc += (A >= pc->k) ? pc->jt : pc->jf;
652*aca3beaaSApple OSS Distributions continue;
653*aca3beaaSApple OSS Distributions
654*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JEQ | BPF_K:
655*aca3beaaSApple OSS Distributions pc += (A == pc->k) ? pc->jt : pc->jf;
656*aca3beaaSApple OSS Distributions continue;
657*aca3beaaSApple OSS Distributions
658*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JSET | BPF_K:
659*aca3beaaSApple OSS Distributions pc += (A & pc->k) ? pc->jt : pc->jf;
660*aca3beaaSApple OSS Distributions continue;
661*aca3beaaSApple OSS Distributions
662*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JGT | BPF_X:
663*aca3beaaSApple OSS Distributions pc += (A > X) ? pc->jt : pc->jf;
664*aca3beaaSApple OSS Distributions continue;
665*aca3beaaSApple OSS Distributions
666*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JGE | BPF_X:
667*aca3beaaSApple OSS Distributions pc += (A >= X) ? pc->jt : pc->jf;
668*aca3beaaSApple OSS Distributions continue;
669*aca3beaaSApple OSS Distributions
670*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JEQ | BPF_X:
671*aca3beaaSApple OSS Distributions pc += (A == X) ? pc->jt : pc->jf;
672*aca3beaaSApple OSS Distributions continue;
673*aca3beaaSApple OSS Distributions
674*aca3beaaSApple OSS Distributions case BPF_JMP | BPF_JSET | BPF_X:
675*aca3beaaSApple OSS Distributions pc += (A & X) ? pc->jt : pc->jf;
676*aca3beaaSApple OSS Distributions continue;
677*aca3beaaSApple OSS Distributions
678*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_ADD | BPF_X:
679*aca3beaaSApple OSS Distributions A += X;
680*aca3beaaSApple OSS Distributions continue;
681*aca3beaaSApple OSS Distributions
682*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_SUB | BPF_X:
683*aca3beaaSApple OSS Distributions A -= X;
684*aca3beaaSApple OSS Distributions continue;
685*aca3beaaSApple OSS Distributions
686*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_MUL | BPF_X:
687*aca3beaaSApple OSS Distributions A *= X;
688*aca3beaaSApple OSS Distributions continue;
689*aca3beaaSApple OSS Distributions
690*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_DIV | BPF_X:
691*aca3beaaSApple OSS Distributions if (X == 0) {
692*aca3beaaSApple OSS Distributions return 0;
693*aca3beaaSApple OSS Distributions }
694*aca3beaaSApple OSS Distributions A /= X;
695*aca3beaaSApple OSS Distributions continue;
696*aca3beaaSApple OSS Distributions
697*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_AND | BPF_X:
698*aca3beaaSApple OSS Distributions A &= X;
699*aca3beaaSApple OSS Distributions continue;
700*aca3beaaSApple OSS Distributions
701*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_OR | BPF_X:
702*aca3beaaSApple OSS Distributions A |= X;
703*aca3beaaSApple OSS Distributions continue;
704*aca3beaaSApple OSS Distributions
705*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_LSH | BPF_X:
706*aca3beaaSApple OSS Distributions A <<= X;
707*aca3beaaSApple OSS Distributions continue;
708*aca3beaaSApple OSS Distributions
709*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_RSH | BPF_X:
710*aca3beaaSApple OSS Distributions A >>= X;
711*aca3beaaSApple OSS Distributions continue;
712*aca3beaaSApple OSS Distributions
713*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_ADD | BPF_K:
714*aca3beaaSApple OSS Distributions A += pc->k;
715*aca3beaaSApple OSS Distributions continue;
716*aca3beaaSApple OSS Distributions
717*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_SUB | BPF_K:
718*aca3beaaSApple OSS Distributions A -= pc->k;
719*aca3beaaSApple OSS Distributions continue;
720*aca3beaaSApple OSS Distributions
721*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_MUL | BPF_K:
722*aca3beaaSApple OSS Distributions A *= pc->k;
723*aca3beaaSApple OSS Distributions continue;
724*aca3beaaSApple OSS Distributions
725*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_DIV | BPF_K:
726*aca3beaaSApple OSS Distributions A /= pc->k;
727*aca3beaaSApple OSS Distributions continue;
728*aca3beaaSApple OSS Distributions
729*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_AND | BPF_K:
730*aca3beaaSApple OSS Distributions A &= pc->k;
731*aca3beaaSApple OSS Distributions continue;
732*aca3beaaSApple OSS Distributions
733*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_OR | BPF_K:
734*aca3beaaSApple OSS Distributions A |= pc->k;
735*aca3beaaSApple OSS Distributions continue;
736*aca3beaaSApple OSS Distributions
737*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_LSH | BPF_K:
738*aca3beaaSApple OSS Distributions A <<= pc->k;
739*aca3beaaSApple OSS Distributions continue;
740*aca3beaaSApple OSS Distributions
741*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_RSH | BPF_K:
742*aca3beaaSApple OSS Distributions A >>= pc->k;
743*aca3beaaSApple OSS Distributions continue;
744*aca3beaaSApple OSS Distributions
745*aca3beaaSApple OSS Distributions case BPF_ALU | BPF_NEG:
746*aca3beaaSApple OSS Distributions A = -A;
747*aca3beaaSApple OSS Distributions continue;
748*aca3beaaSApple OSS Distributions
749*aca3beaaSApple OSS Distributions case BPF_MISC | BPF_TAX:
750*aca3beaaSApple OSS Distributions X = A;
751*aca3beaaSApple OSS Distributions continue;
752*aca3beaaSApple OSS Distributions
753*aca3beaaSApple OSS Distributions case BPF_MISC | BPF_TXA:
754*aca3beaaSApple OSS Distributions A = X;
755*aca3beaaSApple OSS Distributions continue;
756*aca3beaaSApple OSS Distributions }
757*aca3beaaSApple OSS Distributions }
758*aca3beaaSApple OSS Distributions }
759*aca3beaaSApple OSS Distributions
760*aca3beaaSApple OSS Distributions #ifdef KERNEL
761*aca3beaaSApple OSS Distributions /*
762*aca3beaaSApple OSS Distributions * Return true if the 'fcode' is a valid filter program.
763*aca3beaaSApple OSS Distributions * The constraints are that each jump be forward and to a valid
764*aca3beaaSApple OSS Distributions * code, that memory accesses are within valid ranges (to the
765*aca3beaaSApple OSS Distributions * extent that this can be checked statically; loads of packet data
766*aca3beaaSApple OSS Distributions * have to be, and are, also checked at run time), and that
767*aca3beaaSApple OSS Distributions * the code terminates with either an accept or reject.
768*aca3beaaSApple OSS Distributions *
769*aca3beaaSApple OSS Distributions * The kernel needs to be able to verify an application's filter code.
770*aca3beaaSApple OSS Distributions * Otherwise, a bogus program could easily crash the system.
771*aca3beaaSApple OSS Distributions */
772*aca3beaaSApple OSS Distributions int
bpf_validate(const struct bpf_insn * f,int len)773*aca3beaaSApple OSS Distributions bpf_validate(const struct bpf_insn *f, int len)
774*aca3beaaSApple OSS Distributions {
775*aca3beaaSApple OSS Distributions u_int i, from;
776*aca3beaaSApple OSS Distributions const struct bpf_insn *p;
777*aca3beaaSApple OSS Distributions
778*aca3beaaSApple OSS Distributions if (len < 1 || len > BPF_MAXINSNS) {
779*aca3beaaSApple OSS Distributions return 0;
780*aca3beaaSApple OSS Distributions }
781*aca3beaaSApple OSS Distributions
782*aca3beaaSApple OSS Distributions for (i = 0; i < ((u_int)len); ++i) {
783*aca3beaaSApple OSS Distributions p = &f[i];
784*aca3beaaSApple OSS Distributions switch (BPF_CLASS(p->code)) {
785*aca3beaaSApple OSS Distributions /*
786*aca3beaaSApple OSS Distributions * Check that memory operations use valid addresses
787*aca3beaaSApple OSS Distributions */
788*aca3beaaSApple OSS Distributions case BPF_LD:
789*aca3beaaSApple OSS Distributions case BPF_LDX:
790*aca3beaaSApple OSS Distributions switch (BPF_MODE(p->code)) {
791*aca3beaaSApple OSS Distributions case BPF_IMM:
792*aca3beaaSApple OSS Distributions break;
793*aca3beaaSApple OSS Distributions case BPF_ABS:
794*aca3beaaSApple OSS Distributions case BPF_IND:
795*aca3beaaSApple OSS Distributions case BPF_MSH:
796*aca3beaaSApple OSS Distributions /*
797*aca3beaaSApple OSS Distributions * More strict check with actual packet length
798*aca3beaaSApple OSS Distributions * is done runtime.
799*aca3beaaSApple OSS Distributions */
800*aca3beaaSApple OSS Distributions if (p->k >= bpf_maxbufsize) {
801*aca3beaaSApple OSS Distributions return 0;
802*aca3beaaSApple OSS Distributions }
803*aca3beaaSApple OSS Distributions break;
804*aca3beaaSApple OSS Distributions case BPF_MEM:
805*aca3beaaSApple OSS Distributions if (p->k >= BPF_MEMWORDS) {
806*aca3beaaSApple OSS Distributions return 0;
807*aca3beaaSApple OSS Distributions }
808*aca3beaaSApple OSS Distributions break;
809*aca3beaaSApple OSS Distributions case BPF_LEN:
810*aca3beaaSApple OSS Distributions break;
811*aca3beaaSApple OSS Distributions default:
812*aca3beaaSApple OSS Distributions return 0;
813*aca3beaaSApple OSS Distributions }
814*aca3beaaSApple OSS Distributions break;
815*aca3beaaSApple OSS Distributions case BPF_ST:
816*aca3beaaSApple OSS Distributions case BPF_STX:
817*aca3beaaSApple OSS Distributions if (p->k >= BPF_MEMWORDS) {
818*aca3beaaSApple OSS Distributions return 0;
819*aca3beaaSApple OSS Distributions }
820*aca3beaaSApple OSS Distributions break;
821*aca3beaaSApple OSS Distributions case BPF_ALU:
822*aca3beaaSApple OSS Distributions switch (BPF_OP(p->code)) {
823*aca3beaaSApple OSS Distributions case BPF_ADD:
824*aca3beaaSApple OSS Distributions case BPF_SUB:
825*aca3beaaSApple OSS Distributions case BPF_MUL:
826*aca3beaaSApple OSS Distributions case BPF_OR:
827*aca3beaaSApple OSS Distributions case BPF_AND:
828*aca3beaaSApple OSS Distributions case BPF_LSH:
829*aca3beaaSApple OSS Distributions case BPF_RSH:
830*aca3beaaSApple OSS Distributions case BPF_NEG:
831*aca3beaaSApple OSS Distributions break;
832*aca3beaaSApple OSS Distributions case BPF_DIV:
833*aca3beaaSApple OSS Distributions /*
834*aca3beaaSApple OSS Distributions * Check for constant division by 0
835*aca3beaaSApple OSS Distributions */
836*aca3beaaSApple OSS Distributions if (BPF_SRC(p->code) == BPF_K && p->k == 0) {
837*aca3beaaSApple OSS Distributions return 0;
838*aca3beaaSApple OSS Distributions }
839*aca3beaaSApple OSS Distributions break;
840*aca3beaaSApple OSS Distributions default:
841*aca3beaaSApple OSS Distributions return 0;
842*aca3beaaSApple OSS Distributions }
843*aca3beaaSApple OSS Distributions break;
844*aca3beaaSApple OSS Distributions case BPF_JMP:
845*aca3beaaSApple OSS Distributions /*
846*aca3beaaSApple OSS Distributions * Check that jumps are within the code block,
847*aca3beaaSApple OSS Distributions * and that unconditional branches don't go
848*aca3beaaSApple OSS Distributions * backwards as a result of an overflow.
849*aca3beaaSApple OSS Distributions * Unconditional branches have a 32-bit offset,
850*aca3beaaSApple OSS Distributions * so they could overflow; we check to make
851*aca3beaaSApple OSS Distributions * sure they don't. Conditional branches have
852*aca3beaaSApple OSS Distributions * an 8-bit offset, and the from address is
853*aca3beaaSApple OSS Distributions * less than equal to BPF_MAXINSNS, and we assume that
854*aca3beaaSApple OSS Distributions * BPF_MAXINSNS is sufficiently small that adding 255
855*aca3beaaSApple OSS Distributions * to it won't overlflow
856*aca3beaaSApple OSS Distributions *
857*aca3beaaSApple OSS Distributions * We know that len is <= BPF_MAXINSNS, and we
858*aca3beaaSApple OSS Distributions * assume that BPF_MAXINSNS is less than the maximum
859*aca3beaaSApple OSS Distributions * size of a u_int, so that i+1 doesn't overflow
860*aca3beaaSApple OSS Distributions */
861*aca3beaaSApple OSS Distributions from = i + 1;
862*aca3beaaSApple OSS Distributions switch (BPF_OP(p->code)) {
863*aca3beaaSApple OSS Distributions case BPF_JA:
864*aca3beaaSApple OSS Distributions if (from + p->k < from || from + p->k >= ((u_int)len)) {
865*aca3beaaSApple OSS Distributions return 0;
866*aca3beaaSApple OSS Distributions }
867*aca3beaaSApple OSS Distributions break;
868*aca3beaaSApple OSS Distributions case BPF_JEQ:
869*aca3beaaSApple OSS Distributions case BPF_JGT:
870*aca3beaaSApple OSS Distributions case BPF_JGE:
871*aca3beaaSApple OSS Distributions case BPF_JSET:
872*aca3beaaSApple OSS Distributions if (from + p->jt >= ((u_int)len) || from + p->jf >= ((u_int)len)) {
873*aca3beaaSApple OSS Distributions return 0;
874*aca3beaaSApple OSS Distributions }
875*aca3beaaSApple OSS Distributions break;
876*aca3beaaSApple OSS Distributions default:
877*aca3beaaSApple OSS Distributions return 0;
878*aca3beaaSApple OSS Distributions }
879*aca3beaaSApple OSS Distributions break;
880*aca3beaaSApple OSS Distributions case BPF_RET:
881*aca3beaaSApple OSS Distributions break;
882*aca3beaaSApple OSS Distributions case BPF_MISC:
883*aca3beaaSApple OSS Distributions break;
884*aca3beaaSApple OSS Distributions default:
885*aca3beaaSApple OSS Distributions return 0;
886*aca3beaaSApple OSS Distributions }
887*aca3beaaSApple OSS Distributions }
888*aca3beaaSApple OSS Distributions return BPF_CLASS(f[len - 1].code) == BPF_RET;
889*aca3beaaSApple OSS Distributions }
890*aca3beaaSApple OSS Distributions #endif
891