b7815a3ba77cd82a070f95ae015464ca09e26039
[reactos.git] / reactos / drivers / net / npf / win_bpf_filter.c
1 /*
2 * Copyright (c) 1999, 2000
3 * Politecnico di Torino. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 *
22 *
23 * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
24 * The Regents of the University of California. All rights reserved.
25 *
26 * This code is derived from the Stanford/CMU enet packet filter,
27 * (net/enet.c) distributed as part of 4.3BSD, and code contributed
28 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
29 * Berkeley Laboratory.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * SUCH DAMAGE.
58
59 @(#)bpf.c 7.5 (Berkeley) 7/15/91
60 */
61
62 #include "tme.h"
63 #include "win_bpf.h"
64
65 #include "debug.h"
66
67 #include "valid_insns.h"
68
69 #define EXTRACT_SHORT(p)\
70 ((u_short)\
71 ((u_short)*((u_char *)p+0)<<8|\
72 (u_short)*((u_char *)p+1)<<0))
73 #define EXTRACT_LONG(p)\
74 ((u_int32)*((u_char *)p+0)<<24|\
75 (u_int32)*((u_char *)p+1)<<16|\
76 (u_int32)*((u_char *)p+2)<<8|\
77 (u_int32)*((u_char *)p+3)<<0)
78
79
80 u_int bpf_filter(pc, p, wirelen, buflen,mem_ex,tme,time_ref)
81 register struct bpf_insn *pc;
82 register u_char *p;
83 u_int wirelen;
84 register u_int buflen;
85 PMEM_TYPE mem_ex;
86 PTME_CORE tme;
87 struct time_conv *time_ref;
88
89 {
90 register u_int32 A, X;
91 register int k;
92 u_int32 j,tmp;
93 u_short tmp2;
94
95 int32 mem[BPF_MEMWORDS];
96
97 if (pc == 0)
98 /*
99 * No filter means accept all.
100 */
101 return (u_int)-1;
102 A = 0;
103 X = 0;
104 --pc;
105 while (1) {
106 ++pc;
107 switch (pc->code) {
108
109 default:
110
111 return 0;
112
113 case BPF_RET|BPF_K:
114 return (u_int)pc->k;
115
116 case BPF_RET|BPF_A:
117 return (u_int)A;
118
119 case BPF_LD|BPF_W|BPF_ABS:
120 k = pc->k;
121 if (k + sizeof(int32) > buflen) {
122 return 0;
123 }
124 A = EXTRACT_LONG(&p[k]);
125 continue;
126
127 case BPF_LD|BPF_H|BPF_ABS:
128 k = pc->k;
129 if (k + sizeof(short) > buflen) {
130 return 0;
131 }
132 A = EXTRACT_SHORT(&p[k]);
133 continue;
134
135 case BPF_LD|BPF_B|BPF_ABS:
136 k = pc->k;
137 if ((int)k >= (int)buflen) {
138 return 0;
139 }
140 A = p[k];
141 continue;
142
143 case BPF_LD|BPF_W|BPF_LEN:
144 A = wirelen;
145 continue;
146
147 case BPF_LDX|BPF_W|BPF_LEN:
148 X = wirelen;
149 continue;
150
151 case BPF_LD|BPF_W|BPF_IND:
152 k = X + pc->k;
153 if (k + sizeof(int32) > buflen) {
154 return 0;
155 }
156 A = EXTRACT_LONG(&p[k]);
157 continue;
158
159 case BPF_LD|BPF_H|BPF_IND:
160 k = X + pc->k;
161 if (k + sizeof(short) > buflen) {
162 return 0;
163 }
164 A = EXTRACT_SHORT(&p[k]);
165 continue;
166
167 case BPF_LD|BPF_B|BPF_IND:
168 k = X + pc->k;
169 if ((int)k >= (int)buflen) {
170 return 0;
171 }
172 A = p[k];
173 continue;
174
175 case BPF_LDX|BPF_MSH|BPF_B:
176 k = pc->k;
177 if ((int)k >= (int)buflen) {
178 return 0;
179 }
180 X = (p[pc->k] & 0xf) << 2;
181 continue;
182
183 case BPF_LD|BPF_IMM:
184 A = pc->k;
185 continue;
186
187 case BPF_LDX|BPF_IMM:
188 X = pc->k;
189 continue;
190
191 case BPF_LD|BPF_MEM:
192 A = mem[pc->k];
193 continue;
194
195 case BPF_LDX|BPF_MEM:
196 X = mem[pc->k];
197 continue;
198
199 /* LD NO PACKET INSTRUCTIONS */
200
201 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
202 A= mem_ex->buffer[pc->k];
203 continue;
204
205 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
206 X= mem_ex->buffer[pc->k];
207 continue;
208
209 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
210 A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
211 continue;
212
213 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
214 X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
215 continue;
216
217 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
218 A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
219 continue;
220
221 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
222 X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
223 continue;
224
225 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
226 k = X + pc->k;
227 if ((int32)k>= (int32)mem_ex->size) {
228 return 0;
229 }
230 A= mem_ex->buffer[k];
231 continue;
232
233 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
234 k = X + pc->k;
235 if ((int32)(k+1)>= (int32)mem_ex->size) {
236 return 0;
237 }
238 A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
239 continue;
240
241 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
242 k = X + pc->k;
243 if ((int32)(k+3)>= (int32)mem_ex->size) {
244 return 0;
245 }
246 A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
247 continue;
248 /* END LD NO PACKET INSTRUCTIONS */
249
250 case BPF_ST:
251 mem[pc->k] = A;
252 continue;
253
254 case BPF_STX:
255 mem[pc->k] = X;
256 continue;
257
258 /* STORE INSTRUCTIONS */
259 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
260 mem_ex->buffer[pc->k]=(uint8)A;
261 continue;
262
263 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
264 mem_ex->buffer[pc->k]=(uint8)X;
265 continue;
266
267 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
268 tmp=A;
269 *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
270 continue;
271
272 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
273 tmp=X;
274 *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
275 continue;
276
277 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
278 tmp2=(uint16)A;
279 *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
280 continue;
281
282 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
283 tmp2=(uint16)X;
284 *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
285 continue;
286
287 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
288 mem_ex->buffer[pc->k+X]=(uint8)A;
289
290 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
291 tmp=A;
292 *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
293 continue;
294
295 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
296 tmp2=(uint16)A;
297 *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
298 continue;
299 /* END STORE INSTRUCTIONS */
300
301 case BPF_JMP|BPF_JA:
302 pc += pc->k;
303 continue;
304
305 case BPF_JMP|BPF_JGT|BPF_K:
306 pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
307 continue;
308
309 case BPF_JMP|BPF_JGE|BPF_K:
310 pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
311 continue;
312
313 case BPF_JMP|BPF_JEQ|BPF_K:
314 pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf;
315 continue;
316
317 case BPF_JMP|BPF_JSET|BPF_K:
318 pc += (A & pc->k) ? pc->jt : pc->jf;
319 continue;
320
321 case BPF_JMP|BPF_JGT|BPF_X:
322 pc += (A > X) ? pc->jt : pc->jf;
323 continue;
324
325 case BPF_JMP|BPF_JGE|BPF_X:
326 pc += (A >= X) ? pc->jt : pc->jf;
327 continue;
328
329 case BPF_JMP|BPF_JEQ|BPF_X:
330 pc += (A == X) ? pc->jt : pc->jf;
331 continue;
332
333 case BPF_JMP|BPF_JSET|BPF_X:
334 pc += (A & X) ? pc->jt : pc->jf;
335 continue;
336
337 case BPF_ALU|BPF_ADD|BPF_X:
338 A += X;
339 continue;
340
341 case BPF_ALU|BPF_SUB|BPF_X:
342 A -= X;
343 continue;
344
345 case BPF_ALU|BPF_MUL|BPF_X:
346 A *= X;
347 continue;
348
349 case BPF_ALU|BPF_DIV|BPF_X:
350 if (X == 0)
351 return 0;
352 A /= X;
353 continue;
354
355 case BPF_ALU|BPF_AND|BPF_X:
356 A &= X;
357 continue;
358
359 case BPF_ALU|BPF_OR|BPF_X:
360 A |= X;
361 continue;
362
363 case BPF_ALU|BPF_LSH|BPF_X:
364 A <<= X;
365 continue;
366
367 case BPF_ALU|BPF_RSH|BPF_X:
368 A >>= X;
369 continue;
370
371 case BPF_ALU|BPF_ADD|BPF_K:
372 A += pc->k;
373 continue;
374
375 case BPF_ALU|BPF_SUB|BPF_K:
376 A -= pc->k;
377 continue;
378
379 case BPF_ALU|BPF_MUL|BPF_K:
380 A *= pc->k;
381 continue;
382
383 case BPF_ALU|BPF_DIV|BPF_K:
384 A /= pc->k;
385 continue;
386
387 case BPF_ALU|BPF_AND|BPF_K:
388 A &= pc->k;
389 continue;
390
391 case BPF_ALU|BPF_OR|BPF_K:
392 A |= pc->k;
393 continue;
394
395 case BPF_ALU|BPF_LSH|BPF_K:
396 A <<= pc->k;
397 continue;
398
399 case BPF_ALU|BPF_RSH|BPF_K:
400 A >>= pc->k;
401 continue;
402
403 case BPF_ALU|BPF_NEG:
404 A = (u_int32)(-((int)A));
405 continue;
406
407 case BPF_MISC|BPF_TAX:
408 X = A;
409 continue;
410
411 case BPF_MISC|BPF_TXA:
412 A = X;
413 continue;
414
415 /* TME INSTRUCTIONS */
416 case BPF_MISC|BPF_TME|BPF_LOOKUP:
417 j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
418 if (j==TME_ERROR)
419 return 0;
420 pc += (j == TME_TRUE) ? pc->jt : pc->jf;
421 continue;
422
423 case BPF_MISC|BPF_TME|BPF_EXECUTE:
424 if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR)
425 return 0;
426 continue;
427
428 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
429 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
430 return 0;
431 continue;
432
433 case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
434 if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
435 return 0;
436 A=j;
437 continue;
438
439 case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
440 if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR)
441 return 0;
442 continue;
443 /* END TME INSTRUCTIONS */
444
445 }
446 }
447 }
448
449 //-------------------------------------------------------------------
450
451 u_int bpf_filter_with_2_buffers(pc, p, pd, headersize, wirelen, buflen, mem_ex,tme,time_ref)
452 register struct bpf_insn *pc;
453 register u_char *p;
454 register u_char *pd;
455 register int headersize;
456 u_int wirelen;
457 register u_int buflen;
458 PMEM_TYPE mem_ex;
459 PTME_CORE tme;
460 struct time_conv *time_ref;
461 {
462 register u_int32 A, X;
463 register int k;
464 int32 mem[BPF_MEMWORDS];
465 u_int32 j,tmp;
466 u_short tmp2;
467
468 if (pc == 0)
469 /*
470 * No filter means accept all.
471 */
472 return (u_int)-1;
473 A = 0;
474 X = 0;
475 --pc;
476 while (1) {
477 ++pc;
478 switch (pc->code) {
479
480 default:
481
482 return 0;
483
484 case BPF_RET|BPF_K:
485 return (u_int)pc->k;
486
487 case BPF_RET|BPF_A:
488 return (u_int)A;
489
490 case BPF_LD|BPF_W|BPF_ABS:
491 k = pc->k;
492 if (k + sizeof(int32) > buflen) {
493 return 0;
494 }
495
496 if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]);
497 else if(k + 2 == headersize){
498 A=(u_int32)*((u_char *)p+k)<<24|
499 (u_int32)*((u_char *)p+k+1)<<16|
500 (u_int32)*((u_char *)p+k+2)<<8|
501 (u_int32)*((u_char *)pd+k-headersize);
502 }
503 else if(k == headersize-1){
504 A=(u_int32)*((u_char *)p+k)<<24|
505 (u_int32)*((u_char *)p+k+1)<<16|
506 (u_int32)*((u_char *)pd+k-headersize)<<8|
507 (u_int32)*((u_char *)pd+k-headersize+1);
508 }
509 else if(k == headersize){
510 A=(u_int32)*((u_char *)p+k)<<24|
511 (u_int32)*((u_char *)pd+k-headersize+1)<<16|
512 (u_int32)*((u_char *)pd+k-headersize+2)<<8|
513 (u_int32)*((u_char *)pd+k-headersize+3);
514 }
515 A = EXTRACT_LONG(&pd[k-headersize]);
516
517 continue;
518
519 case BPF_LD|BPF_H|BPF_ABS:
520 k = pc->k;
521 if (k + sizeof(short) > buflen) {
522 return 0;
523 }
524
525 if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]);
526 else if(k == headersize){
527 A=(u_short)*((u_char *)p+k)<<8|
528 (u_short)*((u_char *)pd+k-headersize);
529 }
530 A = EXTRACT_SHORT(&pd[k-headersize]);
531
532 continue;
533
534 case BPF_LD|BPF_B|BPF_ABS:
535 k = pc->k;
536 if ((int)k >= (int)buflen) {
537 return 0;
538 }
539
540 if(k<headersize) A = p[k];
541 else A = pd[k-headersize];
542
543 continue;
544
545 case BPF_LD|BPF_W|BPF_LEN:
546 A = wirelen;
547 continue;
548
549 case BPF_LDX|BPF_W|BPF_LEN:
550 X = wirelen;
551 continue;
552
553 case BPF_LD|BPF_W|BPF_IND:
554 k = X + pc->k;
555 if (k + sizeof(int32) > buflen) {
556 return 0;
557 }
558
559 if(k + (int)sizeof(int32) < headersize) A = EXTRACT_LONG(&p[k]);
560 else if(k + (int)sizeof(int32) == headersize+2){
561 A=(u_int32)*((u_char *)p+k)<<24|
562 (u_int32)*((u_char *)p+k+1)<<16|
563 (u_int32)*((u_char *)p+k+2)<<8|
564 (u_int32)*((u_char *)pd+k-headersize);
565 }
566 else if(k + (int)sizeof(int32) == headersize+3){
567 A=(u_int32)*((u_char *)p+k)<<24|
568 (u_int32)*((u_char *)p+k+1)<<16|
569 (u_int32)*((u_char *)pd+k-headersize)<<8|
570 (u_int32)*((u_char *)pd+k-headersize+1);
571 }
572 else if(k + (int)sizeof(int32) == headersize+4){
573 A=(u_int32)*((u_char *)p+k)<<24|
574 (u_int32)*((u_char *)pd+k-headersize+1)<<16|
575 (u_int32)*((u_char *)pd+k-headersize+2)<<8|
576 (u_int32)*((u_char *)pd+k-headersize+3);
577 }
578 A = EXTRACT_LONG(&pd[k-headersize]);
579
580 continue;
581
582 case BPF_LD|BPF_H|BPF_IND:
583 k = X + pc->k;
584 if (k + sizeof(short) > buflen) {
585 return 0;
586 }
587
588 if(k + (int)sizeof(short) < headersize) A = EXTRACT_SHORT(&p[k]);
589 else if(k == headersize){
590 A=(u_short)*((u_char *)p+k)<<8|
591 (u_short)*((u_char *)pd+k-headersize);
592 }
593 A = EXTRACT_SHORT(&pd[k-headersize]);
594
595 continue;
596
597 case BPF_LD|BPF_B|BPF_IND:
598 k = X + pc->k;
599 if ((int)k >= (int)buflen) {
600 return 0;
601 }
602
603 if(k<headersize) A = p[k];
604 else A = pd[k-headersize];
605
606 continue;
607
608 case BPF_LDX|BPF_MSH|BPF_B:
609 k = pc->k;
610 if ((int)k >= (int)buflen) {
611 return 0;
612 }
613
614 if((pc->k)<headersize) X = (p[pc->k] & 0xf) << 2;
615 else X = (pd[(pc->k)-headersize] & 0xf) << 2;
616
617 continue;
618
619 case BPF_LD|BPF_IMM:
620 A = pc->k;
621 continue;
622
623 case BPF_LDX|BPF_IMM:
624 X = pc->k;
625 continue;
626
627 case BPF_LD|BPF_MEM:
628 A = mem[pc->k];
629 continue;
630
631 case BPF_LDX|BPF_MEM:
632 X = mem[pc->k];
633 continue;
634
635 /* LD NO PACKET INSTRUCTIONS */
636
637 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
638 A= mem_ex->buffer[pc->k];
639 continue;
640
641 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
642 X= mem_ex->buffer[pc->k];
643 continue;
644
645 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
646 A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
647 continue;
648
649 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
650 X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
651 continue;
652
653 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
654 A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
655 continue;
656
657 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
658 X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
659 continue;
660
661 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
662 k = X + pc->k;
663 if ((int32)k>= (int32)mem_ex->size) {
664 return 0;
665 }
666 A= mem_ex->buffer[k];
667 continue;
668
669 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
670 k = X + pc->k;
671 if ((int32)(k+1)>= (int32)mem_ex->size) {
672 return 0;
673 }
674 A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
675 continue;
676
677 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
678 k = X + pc->k;
679 if ((int32)(k+3)>= (int32)mem_ex->size) {
680 return 0;
681 }
682 A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
683 continue;
684 /* END LD NO PACKET INSTRUCTIONS */
685
686 case BPF_ST:
687 mem[pc->k] = A;
688 continue;
689
690 case BPF_STX:
691 mem[pc->k] = X;
692 continue;
693
694
695 /* STORE INSTRUCTIONS */
696 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
697 mem_ex->buffer[pc->k]=(uint8)A;
698 continue;
699
700 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
701 mem_ex->buffer[pc->k]=(uint8)X;
702 continue;
703
704 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
705 tmp=A;
706 *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
707 continue;
708
709 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
710 tmp=X;
711 *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
712 continue;
713
714 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
715 tmp2=(uint16)A;
716 *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
717 continue;
718
719 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
720 tmp2=(uint16)X;
721 *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
722 continue;
723
724 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
725 mem_ex->buffer[pc->k+X]=(uint8)A;
726
727 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
728 tmp=A;
729 *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
730 continue;
731
732 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
733 tmp2=(uint16)A;
734 *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
735 continue;
736 /* END STORE INSTRUCTIONS */
737
738
739
740 case BPF_JMP|BPF_JA:
741 pc += pc->k;
742 continue;
743
744 case BPF_JMP|BPF_JGT|BPF_K:
745 pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
746 continue;
747
748 case BPF_JMP|BPF_JGE|BPF_K:
749 pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
750 continue;
751
752 case BPF_JMP|BPF_JEQ|BPF_K:
753 pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf;
754 continue;
755
756 case BPF_JMP|BPF_JSET|BPF_K:
757 pc += (A & pc->k) ? pc->jt : pc->jf;
758 continue;
759
760 case BPF_JMP|BPF_JGT|BPF_X:
761 pc += (A > X) ? pc->jt : pc->jf;
762 continue;
763
764 case BPF_JMP|BPF_JGE|BPF_X:
765 pc += (A >= X) ? pc->jt : pc->jf;
766 continue;
767
768 case BPF_JMP|BPF_JEQ|BPF_X:
769 pc += (A == X) ? pc->jt : pc->jf;
770 continue;
771
772 case BPF_JMP|BPF_JSET|BPF_X:
773 pc += (A & X) ? pc->jt : pc->jf;
774 continue;
775
776 case BPF_ALU|BPF_ADD|BPF_X:
777 A += X;
778 continue;
779
780 case BPF_ALU|BPF_SUB|BPF_X:
781 A -= X;
782 continue;
783
784 case BPF_ALU|BPF_MUL|BPF_X:
785 A *= X;
786 continue;
787
788 case BPF_ALU|BPF_DIV|BPF_X:
789 if (X == 0)
790 return 0;
791 A /= X;
792 continue;
793
794 case BPF_ALU|BPF_AND|BPF_X:
795 A &= X;
796 continue;
797
798 case BPF_ALU|BPF_OR|BPF_X:
799 A |= X;
800 continue;
801
802 case BPF_ALU|BPF_LSH|BPF_X:
803 A <<= X;
804 continue;
805
806 case BPF_ALU|BPF_RSH|BPF_X:
807 A >>= X;
808 continue;
809
810 case BPF_ALU|BPF_ADD|BPF_K:
811 A += pc->k;
812 continue;
813
814 case BPF_ALU|BPF_SUB|BPF_K:
815 A -= pc->k;
816 continue;
817
818 case BPF_ALU|BPF_MUL|BPF_K:
819 A *= pc->k;
820 continue;
821
822 case BPF_ALU|BPF_DIV|BPF_K:
823 A /= pc->k;
824 continue;
825
826 case BPF_ALU|BPF_AND|BPF_K:
827 A &= pc->k;
828 continue;
829
830 case BPF_ALU|BPF_OR|BPF_K:
831 A |= pc->k;
832 continue;
833
834 case BPF_ALU|BPF_LSH|BPF_K:
835 A <<= pc->k;
836 continue;
837
838 case BPF_ALU|BPF_RSH|BPF_K:
839 A >>= pc->k;
840 continue;
841
842 case BPF_ALU|BPF_NEG:
843 A = (u_int32)(-((int)A));
844 continue;
845
846 case BPF_MISC|BPF_TAX:
847 X = A;
848 continue;
849
850 case BPF_MISC|BPF_TXA:
851 A = X;
852 continue;
853
854 /* TME INSTRUCTIONS */
855 case BPF_MISC|BPF_TME|BPF_LOOKUP:
856 j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
857 if (j==TME_ERROR)
858 return 0;
859 pc += (j == TME_TRUE) ? pc->jt : pc->jf;
860 continue;
861
862 case BPF_MISC|BPF_TME|BPF_EXECUTE:
863 if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR)
864 return 0;
865 continue;
866
867 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
868 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
869 return 0;
870 continue;
871
872 case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
873 if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
874 return 0;
875 A=j;
876 continue;
877
878 case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
879 if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,FALSE)==TME_ERROR)
880 return 0;
881 continue;
882 /* END TME INSTRUCTIONS */
883
884 }
885 }
886 }
887
888 int32
889 bpf_validate(f, len,mem_ex_size)
890 struct bpf_insn *f;
891 int32 len;
892 uint32 mem_ex_size;
893 {
894 register int32 i,j;
895 register struct bpf_insn *p;
896 int32 flag;
897
898 for (i = 0; i < len; ++i) {
899 /*
900 * Check that that jumps are forward, and within
901 * the code block.
902 */
903
904 p = &f[i];
905
906 IF_LOUD(DbgPrint("Validating program");)
907
908 flag=0;
909 for(j=0;j<(int32)VALID_INSTRUCTIONS_LEN;j++)
910 if (p->code==valid_instructions[j])
911 flag=1;
912 if (flag==0)
913 return 0;
914
915 IF_LOUD(DbgPrint("Validating program: no unknown instructions");)
916
917 if (BPF_CLASS(p->code) == BPF_JMP) {
918 register int32 from = i + 1;
919
920 if (BPF_OP(p->code) == BPF_JA) {
921 if (from + p->k >= len)
922 return 0;
923 }
924 else if (from + p->jt >= len || from + p->jf >= len)
925 return 0;
926 }
927
928 IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");)
929
930 /*
931 * Check that memory operations use valid addresses.
932 */
933 if (((BPF_CLASS(p->code) == BPF_ST && ((p->code &BPF_MEM_EX_IMM)!=BPF_MEM_EX_IMM && (p->code &BPF_MEM_EX_IND)!=BPF_MEM_EX_IND)) ||
934 (BPF_CLASS(p->code) == BPF_LD &&
935 (p->code & 0xe0) == BPF_MEM)) &&
936 (p->k >= BPF_MEMWORDS || p->k < 0))
937 return 0;
938
939 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD memory locations");)
940
941 /*
942 * Check if key stores use valid addresses
943 */
944 if (BPF_CLASS(p->code) == BPF_ST && (p->code &BPF_MEM_EX_IMM)==BPF_MEM_EX_IMM)
945 switch (BPF_SIZE(p->code))
946 {
947 case BPF_W: if (p->k<0 || p->k+3>=(int32)mem_ex_size) return 0;
948 case BPF_H: if (p->k<0 || p->k+1>=(int32)mem_ex_size) return 0;
949 case BPF_B: if (p->k<0 || p->k>=(int32)mem_ex_size) return 0;
950 }
951
952 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD mem_ex locations");)
953
954 /*
955 * Check for constant division by 0.
956 */
957 if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
958 return 0;
959 }
960 return BPF_CLASS(f[len - 1].code) == BPF_RET;
961 }
962