This source file includes following definitions.
- bpf_m_xword
- bpf_m_xhalf
- bpf_filter
- bpf_validate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/types.h>
42 #include <sys/time.h>
43 #ifndef _KERNEL
44 #include <stdlib.h>
45 #include "pcap.h"
46 #endif
47
48 #include <sys/endian.h>
49 #ifdef __STRICT_ALIGNMENT
50 #define BPF_ALIGN
51 #endif
52
53 #ifndef BPF_ALIGN
54 #define EXTRACT_SHORT(p) ((u_int16_t)ntohs(*(u_int16_t *)p))
55 #define EXTRACT_LONG(p) (ntohl(*(u_int32_t *)p))
56 #else
57 #define EXTRACT_SHORT(p)\
58 ((u_int16_t)\
59 ((u_int16_t)*((u_char *)p+0)<<8|\
60 (u_int16_t)*((u_char *)p+1)<<0))
61 #define EXTRACT_LONG(p)\
62 ((u_int32_t)*((u_char *)p+0)<<24|\
63 (u_int32_t)*((u_char *)p+1)<<16|\
64 (u_int32_t)*((u_char *)p+2)<<8|\
65 (u_int32_t)*((u_char *)p+3)<<0)
66 #endif
67
68 #ifdef _KERNEL
69 #include <sys/mbuf.h>
70 #define MINDEX(len, m, k) \
71 { \
72 len = m->m_len; \
73 while (k >= len) { \
74 k -= len; \
75 m = m->m_next; \
76 if (m == 0) \
77 return 0; \
78 len = m->m_len; \
79 } \
80 }
81
82 extern int bpf_maxbufsize;
83
84 int bpf_m_xword(struct mbuf *, u_int32_t, int *);
85 int bpf_m_xhalf(struct mbuf *, u_int32_t, int *);
86
87 int
88 bpf_m_xword(m, k, err)
89 struct mbuf *m;
90 u_int32_t k;
91 int *err;
92 {
93 int len;
94 u_char *cp, *np;
95 struct mbuf *m0;
96
97 *err = 1;
98 MINDEX(len, m, k);
99 cp = mtod(m, u_char *) + k;
100 if (len >= k + 4) {
101 *err = 0;
102 return EXTRACT_LONG(cp);
103 }
104 m0 = m->m_next;
105 if (m0 == 0 || m0->m_len + len - k < 4)
106 return 0;
107 *err = 0;
108 np = mtod(m0, u_char *);
109 switch (len - k) {
110
111 case 1:
112 return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
113
114 case 2:
115 return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
116
117 default:
118 return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
119 }
120 }
121
122 int
123 bpf_m_xhalf(m, k, err)
124 struct mbuf *m;
125 u_int32_t k;
126 int *err;
127 {
128 int len;
129 u_char *cp;
130 struct mbuf *m0;
131
132 *err = 1;
133 MINDEX(len, m, k);
134 cp = mtod(m, u_char *) + k;
135 if (len >= k + 2) {
136 *err = 0;
137 return EXTRACT_SHORT(cp);
138 }
139 m0 = m->m_next;
140 if (m0 == 0)
141 return 0;
142 *err = 0;
143 return (cp[0] << 8) | mtod(m0, u_char *)[0];
144 }
145 #endif
146
147 #include <net/bpf.h>
148
149
150
151
152
153
154 u_int
155 bpf_filter(pc, p, wirelen, buflen)
156 struct bpf_insn *pc;
157 u_char *p;
158 u_int wirelen;
159 u_int buflen;
160 {
161 u_int32_t A = 0, X = 0;
162 u_int32_t k;
163 int32_t mem[BPF_MEMWORDS];
164
165 if (pc == 0)
166
167
168
169 return (u_int)-1;
170 --pc;
171 while (1) {
172 ++pc;
173 switch (pc->code) {
174
175 default:
176 #ifdef _KERNEL
177 return 0;
178 #else
179 abort();
180 #endif
181 case BPF_RET|BPF_K:
182 return (u_int)pc->k;
183
184 case BPF_RET|BPF_A:
185 return (u_int)A;
186
187 case BPF_LD|BPF_W|BPF_ABS:
188 k = pc->k;
189 if (k + sizeof(int32_t) > buflen) {
190 #ifdef _KERNEL
191 int merr;
192
193 if (buflen != 0)
194 return 0;
195 A = bpf_m_xword((struct mbuf *)p, k, &merr);
196 if (merr != 0)
197 return 0;
198 continue;
199 #else
200 return 0;
201 #endif
202 }
203 A = EXTRACT_LONG(&p[k]);
204 continue;
205
206 case BPF_LD|BPF_H|BPF_ABS:
207 k = pc->k;
208 if (k + sizeof(int16_t) > buflen) {
209 #ifdef _KERNEL
210 int merr;
211
212 if (buflen != 0)
213 return 0;
214 A = bpf_m_xhalf((struct mbuf *)p, k, &merr);
215 if (merr != 0)
216 return 0;
217 continue;
218 #else
219 return 0;
220 #endif
221 }
222 A = EXTRACT_SHORT(&p[k]);
223 continue;
224
225 case BPF_LD|BPF_B|BPF_ABS:
226 k = pc->k;
227 if (k >= buflen) {
228 #ifdef _KERNEL
229 struct mbuf *m;
230 int len;
231
232 if (buflen != 0)
233 return 0;
234 m = (struct mbuf *)p;
235 MINDEX(len, m, k);
236 A = mtod(m, u_char *)[k];
237 continue;
238 #else
239 return 0;
240 #endif
241 }
242 A = p[k];
243 continue;
244
245 case BPF_LD|BPF_W|BPF_LEN:
246 A = wirelen;
247 continue;
248
249 case BPF_LDX|BPF_W|BPF_LEN:
250 X = wirelen;
251 continue;
252
253 case BPF_LD|BPF_W|BPF_IND:
254 k = X + pc->k;
255 if (k + sizeof(int32_t) > buflen) {
256 #ifdef _KERNEL
257 int merr;
258
259 if (buflen != 0)
260 return 0;
261 A = bpf_m_xword((struct mbuf *)p, k, &merr);
262 if (merr != 0)
263 return 0;
264 continue;
265 #else
266 return 0;
267 #endif
268 }
269 A = EXTRACT_LONG(&p[k]);
270 continue;
271
272 case BPF_LD|BPF_H|BPF_IND:
273 k = X + pc->k;
274 if (k + sizeof(int16_t) > buflen) {
275 #ifdef _KERNEL
276 int merr;
277
278 if (buflen != 0)
279 return 0;
280 A = bpf_m_xhalf((struct mbuf *)p, k, &merr);
281 if (merr != 0)
282 return 0;
283 continue;
284 #else
285 return 0;
286 #endif
287 }
288 A = EXTRACT_SHORT(&p[k]);
289 continue;
290
291 case BPF_LD|BPF_B|BPF_IND:
292 k = X + pc->k;
293 if (k >= buflen) {
294 #ifdef _KERNEL
295 struct mbuf *m;
296 int len;
297
298 if (buflen != 0)
299 return 0;
300 m = (struct mbuf *)p;
301 MINDEX(len, m, k);
302 A = mtod(m, u_char *)[k];
303 continue;
304 #else
305 return 0;
306 #endif
307 }
308 A = p[k];
309 continue;
310
311 case BPF_LDX|BPF_MSH|BPF_B:
312 k = pc->k;
313 if (k >= buflen) {
314 #ifdef _KERNEL
315 struct mbuf *m;
316 int len;
317
318 if (buflen != 0)
319 return 0;
320 m = (struct mbuf *)p;
321 MINDEX(len, m, k);
322 X = (mtod(m, u_char *)[k] & 0xf) << 2;
323 continue;
324 #else
325 return 0;
326 #endif
327 }
328 X = (p[pc->k] & 0xf) << 2;
329 continue;
330
331 case BPF_LD|BPF_IMM:
332 A = pc->k;
333 continue;
334
335 case BPF_LDX|BPF_IMM:
336 X = pc->k;
337 continue;
338
339 case BPF_LD|BPF_MEM:
340 A = mem[pc->k];
341 continue;
342
343 case BPF_LDX|BPF_MEM:
344 X = mem[pc->k];
345 continue;
346
347 case BPF_ST:
348 mem[pc->k] = A;
349 continue;
350
351 case BPF_STX:
352 mem[pc->k] = X;
353 continue;
354
355 case BPF_JMP|BPF_JA:
356 pc += pc->k;
357 continue;
358
359 case BPF_JMP|BPF_JGT|BPF_K:
360 pc += (A > pc->k) ? pc->jt : pc->jf;
361 continue;
362
363 case BPF_JMP|BPF_JGE|BPF_K:
364 pc += (A >= pc->k) ? pc->jt : pc->jf;
365 continue;
366
367 case BPF_JMP|BPF_JEQ|BPF_K:
368 pc += (A == pc->k) ? pc->jt : pc->jf;
369 continue;
370
371 case BPF_JMP|BPF_JSET|BPF_K:
372 pc += (A & pc->k) ? pc->jt : pc->jf;
373 continue;
374
375 case BPF_JMP|BPF_JGT|BPF_X:
376 pc += (A > X) ? pc->jt : pc->jf;
377 continue;
378
379 case BPF_JMP|BPF_JGE|BPF_X:
380 pc += (A >= X) ? pc->jt : pc->jf;
381 continue;
382
383 case BPF_JMP|BPF_JEQ|BPF_X:
384 pc += (A == X) ? pc->jt : pc->jf;
385 continue;
386
387 case BPF_JMP|BPF_JSET|BPF_X:
388 pc += (A & X) ? pc->jt : pc->jf;
389 continue;
390
391 case BPF_ALU|BPF_ADD|BPF_X:
392 A += X;
393 continue;
394
395 case BPF_ALU|BPF_SUB|BPF_X:
396 A -= X;
397 continue;
398
399 case BPF_ALU|BPF_MUL|BPF_X:
400 A *= X;
401 continue;
402
403 case BPF_ALU|BPF_DIV|BPF_X:
404 if (X == 0)
405 return 0;
406 A /= X;
407 continue;
408
409 case BPF_ALU|BPF_AND|BPF_X:
410 A &= X;
411 continue;
412
413 case BPF_ALU|BPF_OR|BPF_X:
414 A |= X;
415 continue;
416
417 case BPF_ALU|BPF_LSH|BPF_X:
418 A <<= X;
419 continue;
420
421 case BPF_ALU|BPF_RSH|BPF_X:
422 A >>= X;
423 continue;
424
425 case BPF_ALU|BPF_ADD|BPF_K:
426 A += pc->k;
427 continue;
428
429 case BPF_ALU|BPF_SUB|BPF_K:
430 A -= pc->k;
431 continue;
432
433 case BPF_ALU|BPF_MUL|BPF_K:
434 A *= pc->k;
435 continue;
436
437 case BPF_ALU|BPF_DIV|BPF_K:
438 A /= pc->k;
439 continue;
440
441 case BPF_ALU|BPF_AND|BPF_K:
442 A &= pc->k;
443 continue;
444
445 case BPF_ALU|BPF_OR|BPF_K:
446 A |= pc->k;
447 continue;
448
449 case BPF_ALU|BPF_LSH|BPF_K:
450 A <<= pc->k;
451 continue;
452
453 case BPF_ALU|BPF_RSH|BPF_K:
454 A >>= pc->k;
455 continue;
456
457 case BPF_ALU|BPF_NEG:
458 A = -A;
459 continue;
460
461 case BPF_MISC|BPF_TAX:
462 X = A;
463 continue;
464
465 case BPF_MISC|BPF_TXA:
466 A = X;
467 continue;
468 }
469 }
470 }
471
472 #ifdef _KERNEL
473
474
475
476
477
478
479
480
481
482
483 int
484 bpf_validate(f, len)
485 struct bpf_insn *f;
486 int len;
487 {
488 u_int i, from;
489 struct bpf_insn *p;
490
491 if (len < 1 || len > BPF_MAXINSNS)
492 return 0;
493
494 for (i = 0; i < len; ++i) {
495 p = &f[i];
496 switch (BPF_CLASS(p->code)) {
497
498
499
500 case BPF_LD:
501 case BPF_LDX:
502 switch (BPF_MODE(p->code)) {
503 case BPF_IMM:
504 break;
505 case BPF_ABS:
506 case BPF_IND:
507 case BPF_MSH:
508
509
510
511
512 if (p->k >= bpf_maxbufsize)
513 return 0;
514 break;
515 case BPF_MEM:
516 if (p->k >= BPF_MEMWORDS)
517 return 0;
518 break;
519 case BPF_LEN:
520 break;
521 default:
522 return 0;
523 }
524 break;
525 case BPF_ST:
526 case BPF_STX:
527 if (p->k >= BPF_MEMWORDS)
528 return 0;
529 break;
530 case BPF_ALU:
531 switch (BPF_OP(p->code)) {
532 case BPF_ADD:
533 case BPF_SUB:
534 case BPF_OR:
535 case BPF_AND:
536 case BPF_LSH:
537 case BPF_RSH:
538 case BPF_NEG:
539 break;
540 case BPF_DIV:
541
542
543
544 if (BPF_RVAL(p->code) == BPF_K && p->k == 0)
545 return 0;
546 break;
547 default:
548 return 0;
549 }
550 break;
551 case BPF_JMP:
552
553
554
555
556 from = i + 1;
557 switch (BPF_OP(p->code)) {
558 case BPF_JA:
559 if (from + p->k < from || from + p->k >= len)
560 return 0;
561 break;
562 case BPF_JEQ:
563 case BPF_JGT:
564 case BPF_JGE:
565 case BPF_JSET:
566 if (from + p->jt >= len || from + p->jf >= len)
567 return 0;
568 break;
569 default:
570 return 0;
571 }
572 break;
573 case BPF_RET:
574 break;
575 case BPF_MISC:
576 break;
577 default:
578 return 0;
579 }
580
581 }
582 return BPF_CLASS(f[len - 1].code) == BPF_RET;
583 }
584 #endif