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