b7815a3ba77cd82a070f95ae015464ca09e26039
2 * Copyright (c) 1999, 2000
3 * Politecnico di Torino. All rights reserved.
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
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.
23 * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
24 * The Regents of the University of California. All rights reserved.
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.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
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.
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
59 @(#)bpf.c 7.5 (Berkeley) 7/15/91
67 #include "valid_insns.h"
69 #define EXTRACT_SHORT(p)\
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)
80 u_int
bpf_filter(pc
, p
, wirelen
, buflen
,mem_ex
,tme
,time_ref
)
81 register struct bpf_insn
*pc
;
84 register u_int buflen
;
87 struct time_conv
*time_ref
;
90 register u_int32 A
, X
;
95 int32 mem
[BPF_MEMWORDS
];
99 * No filter means accept all.
119 case BPF_LD
|BPF_W
|BPF_ABS
:
121 if (k
+ sizeof(int32
) > buflen
) {
124 A
= EXTRACT_LONG(&p
[k
]);
127 case BPF_LD
|BPF_H
|BPF_ABS
:
129 if (k
+ sizeof(short) > buflen
) {
132 A
= EXTRACT_SHORT(&p
[k
]);
135 case BPF_LD
|BPF_B
|BPF_ABS
:
137 if ((int)k
>= (int)buflen
) {
143 case BPF_LD
|BPF_W
|BPF_LEN
:
147 case BPF_LDX
|BPF_W
|BPF_LEN
:
151 case BPF_LD
|BPF_W
|BPF_IND
:
153 if (k
+ sizeof(int32
) > buflen
) {
156 A
= EXTRACT_LONG(&p
[k
]);
159 case BPF_LD
|BPF_H
|BPF_IND
:
161 if (k
+ sizeof(short) > buflen
) {
164 A
= EXTRACT_SHORT(&p
[k
]);
167 case BPF_LD
|BPF_B
|BPF_IND
:
169 if ((int)k
>= (int)buflen
) {
175 case BPF_LDX
|BPF_MSH
|BPF_B
:
177 if ((int)k
>= (int)buflen
) {
180 X
= (p
[pc
->k
] & 0xf) << 2;
187 case BPF_LDX
|BPF_IMM
:
195 case BPF_LDX
|BPF_MEM
:
199 /* LD NO PACKET INSTRUCTIONS */
201 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_B
:
202 A
= mem_ex
->buffer
[pc
->k
];
205 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_B
:
206 X
= mem_ex
->buffer
[pc
->k
];
209 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_H
:
210 A
= EXTRACT_SHORT(&mem_ex
->buffer
[pc
->k
]);
213 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_H
:
214 X
= EXTRACT_SHORT(&mem_ex
->buffer
[pc
->k
]);
217 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_W
:
218 A
= EXTRACT_LONG(&mem_ex
->buffer
[pc
->k
]);
221 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_W
:
222 X
= EXTRACT_LONG(&mem_ex
->buffer
[pc
->k
]);
225 case BPF_LD
|BPF_MEM_EX_IND
|BPF_B
:
227 if ((int32
)k
>= (int32
)mem_ex
->size
) {
230 A
= mem_ex
->buffer
[k
];
233 case BPF_LD
|BPF_MEM_EX_IND
|BPF_H
:
235 if ((int32
)(k
+1)>= (int32
)mem_ex
->size
) {
238 A
=EXTRACT_SHORT((uint32
*)&mem_ex
->buffer
[k
]);
241 case BPF_LD
|BPF_MEM_EX_IND
|BPF_W
:
243 if ((int32
)(k
+3)>= (int32
)mem_ex
->size
) {
246 A
=EXTRACT_LONG((uint32
*)&mem_ex
->buffer
[k
]);
248 /* END LD NO PACKET INSTRUCTIONS */
258 /* STORE INSTRUCTIONS */
259 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_B
:
260 mem_ex
->buffer
[pc
->k
]=(uint8
)A
;
263 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_B
:
264 mem_ex
->buffer
[pc
->k
]=(uint8
)X
;
267 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_W
:
269 *(uint32
*)&(mem_ex
->buffer
[pc
->k
])=EXTRACT_LONG(&tmp
);
272 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_W
:
274 *(uint32
*)&(mem_ex
->buffer
[pc
->k
])=EXTRACT_LONG(&tmp
);
277 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_H
:
279 *(uint16
*)&mem_ex
->buffer
[pc
->k
]=EXTRACT_SHORT(&tmp2
);
282 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_H
:
284 *(uint16
*)&mem_ex
->buffer
[pc
->k
]=EXTRACT_SHORT(&tmp2
);
287 case BPF_ST
|BPF_MEM_EX_IND
|BPF_B
:
288 mem_ex
->buffer
[pc
->k
+X
]=(uint8
)A
;
290 case BPF_ST
|BPF_MEM_EX_IND
|BPF_W
:
292 *(uint32
*)&mem_ex
->buffer
[pc
->k
+X
]=EXTRACT_LONG(&tmp
);
295 case BPF_ST
|BPF_MEM_EX_IND
|BPF_H
:
297 *(uint16
*)&mem_ex
->buffer
[pc
->k
+X
]=EXTRACT_SHORT(&tmp2
);
299 /* END STORE INSTRUCTIONS */
305 case BPF_JMP
|BPF_JGT
|BPF_K
:
306 pc
+= ((int)A
> (int)pc
->k
) ? pc
->jt
: pc
->jf
;
309 case BPF_JMP
|BPF_JGE
|BPF_K
:
310 pc
+= ((int)A
>= (int)pc
->k
) ? pc
->jt
: pc
->jf
;
313 case BPF_JMP
|BPF_JEQ
|BPF_K
:
314 pc
+= ((int)A
== (int)pc
->k
) ? pc
->jt
: pc
->jf
;
317 case BPF_JMP
|BPF_JSET
|BPF_K
:
318 pc
+= (A
& pc
->k
) ? pc
->jt
: pc
->jf
;
321 case BPF_JMP
|BPF_JGT
|BPF_X
:
322 pc
+= (A
> X
) ? pc
->jt
: pc
->jf
;
325 case BPF_JMP
|BPF_JGE
|BPF_X
:
326 pc
+= (A
>= X
) ? pc
->jt
: pc
->jf
;
329 case BPF_JMP
|BPF_JEQ
|BPF_X
:
330 pc
+= (A
== X
) ? pc
->jt
: pc
->jf
;
333 case BPF_JMP
|BPF_JSET
|BPF_X
:
334 pc
+= (A
& X
) ? pc
->jt
: pc
->jf
;
337 case BPF_ALU
|BPF_ADD
|BPF_X
:
341 case BPF_ALU
|BPF_SUB
|BPF_X
:
345 case BPF_ALU
|BPF_MUL
|BPF_X
:
349 case BPF_ALU
|BPF_DIV
|BPF_X
:
355 case BPF_ALU
|BPF_AND
|BPF_X
:
359 case BPF_ALU
|BPF_OR
|BPF_X
:
363 case BPF_ALU
|BPF_LSH
|BPF_X
:
367 case BPF_ALU
|BPF_RSH
|BPF_X
:
371 case BPF_ALU
|BPF_ADD
|BPF_K
:
375 case BPF_ALU
|BPF_SUB
|BPF_K
:
379 case BPF_ALU
|BPF_MUL
|BPF_K
:
383 case BPF_ALU
|BPF_DIV
|BPF_K
:
387 case BPF_ALU
|BPF_AND
|BPF_K
:
391 case BPF_ALU
|BPF_OR
|BPF_K
:
395 case BPF_ALU
|BPF_LSH
|BPF_K
:
399 case BPF_ALU
|BPF_RSH
|BPF_K
:
403 case BPF_ALU
|BPF_NEG
:
404 A
= (u_int32
)(-((int)A
));
407 case BPF_MISC
|BPF_TAX
:
411 case BPF_MISC
|BPF_TXA
:
415 /* TME INSTRUCTIONS */
416 case BPF_MISC
|BPF_TME
|BPF_LOOKUP
:
417 j
=lookup_frontend(mem_ex
,tme
,pc
->k
,time_ref
);
420 pc
+= (j
== TME_TRUE
) ? pc
->jt
: pc
->jf
;
423 case BPF_MISC
|BPF_TME
|BPF_EXECUTE
:
424 if (execute_frontend(mem_ex
,tme
,wirelen
,pc
->k
)==TME_ERROR
)
428 case BPF_MISC
|BPF_TME
|BPF_SET_ACTIVE
:
429 if (set_active_tme_block(tme
,pc
->k
)==TME_ERROR
)
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
)
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
)
443 /* END TME INSTRUCTIONS */
449 //-------------------------------------------------------------------
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
;
455 register int headersize
;
457 register u_int buflen
;
460 struct time_conv
*time_ref
;
462 register u_int32 A
, X
;
464 int32 mem
[BPF_MEMWORDS
];
470 * No filter means accept all.
490 case BPF_LD
|BPF_W
|BPF_ABS
:
492 if (k
+ sizeof(int32
) > buflen
) {
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
);
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);
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);
515 A
= EXTRACT_LONG(&pd
[k
-headersize
]);
519 case BPF_LD
|BPF_H
|BPF_ABS
:
521 if (k
+ sizeof(short) > buflen
) {
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
);
530 A
= EXTRACT_SHORT(&pd
[k
-headersize
]);
534 case BPF_LD
|BPF_B
|BPF_ABS
:
536 if ((int)k
>= (int)buflen
) {
540 if(k
<headersize
) A
= p
[k
];
541 else A
= pd
[k
-headersize
];
545 case BPF_LD
|BPF_W
|BPF_LEN
:
549 case BPF_LDX
|BPF_W
|BPF_LEN
:
553 case BPF_LD
|BPF_W
|BPF_IND
:
555 if (k
+ sizeof(int32
) > buflen
) {
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
);
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);
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);
578 A
= EXTRACT_LONG(&pd
[k
-headersize
]);
582 case BPF_LD
|BPF_H
|BPF_IND
:
584 if (k
+ sizeof(short) > buflen
) {
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
);
593 A
= EXTRACT_SHORT(&pd
[k
-headersize
]);
597 case BPF_LD
|BPF_B
|BPF_IND
:
599 if ((int)k
>= (int)buflen
) {
603 if(k
<headersize
) A
= p
[k
];
604 else A
= pd
[k
-headersize
];
608 case BPF_LDX
|BPF_MSH
|BPF_B
:
610 if ((int)k
>= (int)buflen
) {
614 if((pc
->k
)<headersize
) X
= (p
[pc
->k
] & 0xf) << 2;
615 else X
= (pd
[(pc
->k
)-headersize
] & 0xf) << 2;
623 case BPF_LDX
|BPF_IMM
:
631 case BPF_LDX
|BPF_MEM
:
635 /* LD NO PACKET INSTRUCTIONS */
637 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_B
:
638 A
= mem_ex
->buffer
[pc
->k
];
641 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_B
:
642 X
= mem_ex
->buffer
[pc
->k
];
645 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_H
:
646 A
= EXTRACT_SHORT(&mem_ex
->buffer
[pc
->k
]);
649 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_H
:
650 X
= EXTRACT_SHORT(&mem_ex
->buffer
[pc
->k
]);
653 case BPF_LD
|BPF_MEM_EX_IMM
|BPF_W
:
654 A
= EXTRACT_LONG(&mem_ex
->buffer
[pc
->k
]);
657 case BPF_LDX
|BPF_MEM_EX_IMM
|BPF_W
:
658 X
= EXTRACT_LONG(&mem_ex
->buffer
[pc
->k
]);
661 case BPF_LD
|BPF_MEM_EX_IND
|BPF_B
:
663 if ((int32
)k
>= (int32
)mem_ex
->size
) {
666 A
= mem_ex
->buffer
[k
];
669 case BPF_LD
|BPF_MEM_EX_IND
|BPF_H
:
671 if ((int32
)(k
+1)>= (int32
)mem_ex
->size
) {
674 A
=EXTRACT_SHORT((uint32
*)&mem_ex
->buffer
[k
]);
677 case BPF_LD
|BPF_MEM_EX_IND
|BPF_W
:
679 if ((int32
)(k
+3)>= (int32
)mem_ex
->size
) {
682 A
=EXTRACT_LONG((uint32
*)&mem_ex
->buffer
[k
]);
684 /* END LD NO PACKET INSTRUCTIONS */
695 /* STORE INSTRUCTIONS */
696 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_B
:
697 mem_ex
->buffer
[pc
->k
]=(uint8
)A
;
700 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_B
:
701 mem_ex
->buffer
[pc
->k
]=(uint8
)X
;
704 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_W
:
706 *(uint32
*)&(mem_ex
->buffer
[pc
->k
])=EXTRACT_LONG(&tmp
);
709 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_W
:
711 *(uint32
*)&(mem_ex
->buffer
[pc
->k
])=EXTRACT_LONG(&tmp
);
714 case BPF_ST
|BPF_MEM_EX_IMM
|BPF_H
:
716 *(uint16
*)&mem_ex
->buffer
[pc
->k
]=EXTRACT_SHORT(&tmp2
);
719 case BPF_STX
|BPF_MEM_EX_IMM
|BPF_H
:
721 *(uint16
*)&mem_ex
->buffer
[pc
->k
]=EXTRACT_SHORT(&tmp2
);
724 case BPF_ST
|BPF_MEM_EX_IND
|BPF_B
:
725 mem_ex
->buffer
[pc
->k
+X
]=(uint8
)A
;
727 case BPF_ST
|BPF_MEM_EX_IND
|BPF_W
:
729 *(uint32
*)&mem_ex
->buffer
[pc
->k
+X
]=EXTRACT_LONG(&tmp
);
732 case BPF_ST
|BPF_MEM_EX_IND
|BPF_H
:
734 *(uint16
*)&mem_ex
->buffer
[pc
->k
+X
]=EXTRACT_SHORT(&tmp2
);
736 /* END STORE INSTRUCTIONS */
744 case BPF_JMP
|BPF_JGT
|BPF_K
:
745 pc
+= ((int)A
> (int)pc
->k
) ? pc
->jt
: pc
->jf
;
748 case BPF_JMP
|BPF_JGE
|BPF_K
:
749 pc
+= ((int)A
>= (int)pc
->k
) ? pc
->jt
: pc
->jf
;
752 case BPF_JMP
|BPF_JEQ
|BPF_K
:
753 pc
+= ((int)A
== (int)pc
->k
) ? pc
->jt
: pc
->jf
;
756 case BPF_JMP
|BPF_JSET
|BPF_K
:
757 pc
+= (A
& pc
->k
) ? pc
->jt
: pc
->jf
;
760 case BPF_JMP
|BPF_JGT
|BPF_X
:
761 pc
+= (A
> X
) ? pc
->jt
: pc
->jf
;
764 case BPF_JMP
|BPF_JGE
|BPF_X
:
765 pc
+= (A
>= X
) ? pc
->jt
: pc
->jf
;
768 case BPF_JMP
|BPF_JEQ
|BPF_X
:
769 pc
+= (A
== X
) ? pc
->jt
: pc
->jf
;
772 case BPF_JMP
|BPF_JSET
|BPF_X
:
773 pc
+= (A
& X
) ? pc
->jt
: pc
->jf
;
776 case BPF_ALU
|BPF_ADD
|BPF_X
:
780 case BPF_ALU
|BPF_SUB
|BPF_X
:
784 case BPF_ALU
|BPF_MUL
|BPF_X
:
788 case BPF_ALU
|BPF_DIV
|BPF_X
:
794 case BPF_ALU
|BPF_AND
|BPF_X
:
798 case BPF_ALU
|BPF_OR
|BPF_X
:
802 case BPF_ALU
|BPF_LSH
|BPF_X
:
806 case BPF_ALU
|BPF_RSH
|BPF_X
:
810 case BPF_ALU
|BPF_ADD
|BPF_K
:
814 case BPF_ALU
|BPF_SUB
|BPF_K
:
818 case BPF_ALU
|BPF_MUL
|BPF_K
:
822 case BPF_ALU
|BPF_DIV
|BPF_K
:
826 case BPF_ALU
|BPF_AND
|BPF_K
:
830 case BPF_ALU
|BPF_OR
|BPF_K
:
834 case BPF_ALU
|BPF_LSH
|BPF_K
:
838 case BPF_ALU
|BPF_RSH
|BPF_K
:
842 case BPF_ALU
|BPF_NEG
:
843 A
= (u_int32
)(-((int)A
));
846 case BPF_MISC
|BPF_TAX
:
850 case BPF_MISC
|BPF_TXA
:
854 /* TME INSTRUCTIONS */
855 case BPF_MISC
|BPF_TME
|BPF_LOOKUP
:
856 j
=lookup_frontend(mem_ex
,tme
,pc
->k
,time_ref
);
859 pc
+= (j
== TME_TRUE
) ? pc
->jt
: pc
->jf
;
862 case BPF_MISC
|BPF_TME
|BPF_EXECUTE
:
863 if (execute_frontend(mem_ex
,tme
,wirelen
,pc
->k
)==TME_ERROR
)
867 case BPF_MISC
|BPF_TME
|BPF_SET_ACTIVE
:
868 if (set_active_tme_block(tme
,pc
->k
)==TME_ERROR
)
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
)
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
)
882 /* END TME INSTRUCTIONS */
889 bpf_validate(f
, len
,mem_ex_size
)
895 register struct bpf_insn
*p
;
898 for (i
= 0; i
< len
; ++i
) {
900 * Check that that jumps are forward, and within
906 IF_LOUD(DbgPrint("Validating program");)
909 for(j
=0;j
<(int32
)VALID_INSTRUCTIONS_LEN
;j
++)
910 if (p
->code
==valid_instructions
[j
])
915 IF_LOUD(DbgPrint("Validating program: no unknown instructions");)
917 if (BPF_CLASS(p
->code
) == BPF_JMP
) {
918 register int32 from
= i
+ 1;
920 if (BPF_OP(p
->code
) == BPF_JA
) {
921 if (from
+ p
->k
>= len
)
924 else if (from
+ p
->jt
>= len
|| from
+ p
->jf
>= len
)
928 IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");)
931 * Check that memory operations use valid addresses.
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))
939 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD memory locations");)
942 * Check if key stores use valid addresses
944 if (BPF_CLASS(p
->code
) == BPF_ST
&& (p
->code
&BPF_MEM_EX_IMM
)==BPF_MEM_EX_IMM
)
945 switch (BPF_SIZE(p
->code
))
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;
952 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD mem_ex locations");)
955 * Check for constant division by 0.
957 if (p
->code
== (BPF_ALU
|BPF_DIV
|BPF_K
) && p
->k
== 0)
960 return BPF_CLASS(f
[len
- 1].code
) == BPF_RET
;