add winpcap 4.0.2 from url http://www.winpcap.org/
[natblaster.git] / winpcap / packetNtx / driver / win_bpf_filter_init.c
blobdbf51e9117666ca3dde0e1aaa79268ac25bac033
1 /*
2 * Copyright (c) 2001 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "tme.h"
34 #include "win_bpf.h"
36 #pragma warning(disable : 4131) //old style function declaration
37 #pragma warning(disable : 4127) // conditional expr is constant (used for while(1) loops)
38 #pragma warning(disable : 4213) //cast on l-value
41 * Initialize the filter machine
43 uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref)
45 register uint32 A, X;
46 int32 mem[BPF_MEMWORDS];
47 register int32 k;
48 uint32 *tmp;
49 uint16 *tmp2;
50 uint32 j;
51 if (pc == 0)
53 * No filter means accept all.
55 return (uint32)-1;
57 RtlZeroMemory(mem, sizeof(mem));
59 A = 0;
60 X = 0;
61 --pc;
62 while (1) {
63 ++pc;
64 switch (pc->code) {
66 default:
67 return 0;
69 /* RET INSTRUCTIONS */
70 case BPF_RET|BPF_K:
71 return (uint32)pc->k;
73 case BPF_RET|BPF_A:
74 return (uint32)A;
75 /* END RET INSTRUCTIONS */
77 /* LD NO PACKET INSTRUCTIONS */
78 case BPF_LD|BPF_IMM:
79 A = pc->k;
80 continue;
82 case BPF_LDX|BPF_IMM:
83 X = pc->k;
84 continue;
86 case BPF_LD|BPF_MEM:
87 A = mem[pc->k];
88 continue;
90 case BPF_LDX|BPF_MEM:
91 X = mem[pc->k];
92 continue;
94 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
95 A= mem_ex->buffer[pc->k];
96 continue;
98 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
99 X= mem_ex->buffer[pc->k];
100 continue;
102 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
103 tmp2=(uint16*)&mem_ex->buffer[pc->k];
104 __asm
106 push eax
107 push ebx
108 mov ebx,tmp2
109 xor eax, eax
110 mov ax, [ebx]
111 bswap eax
112 mov A, eax
113 pop ebx
114 pop eax
116 continue;
118 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
119 tmp2=(uint16*)&mem_ex->buffer[pc->k];
120 __asm
122 push eax
123 push ebx
124 mov ebx,tmp2
125 xor eax, eax
126 mov ax, [ebx]
127 bswap eax
128 mov X, eax
129 pop ebx
130 pop eax
132 continue;
134 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
135 tmp=(uint32*)&mem_ex->buffer[pc->k];
136 __asm
138 push eax
139 push ebx
140 mov ebx,tmp
141 mov eax, [ebx]
142 bswap eax
143 mov A, eax
144 pop ebx
145 pop eax
147 continue;
149 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
150 tmp=(uint32*)&mem_ex->buffer[pc->k];
151 __asm
153 push eax
154 push ebx
155 mov ebx,tmp
156 mov eax, [ebx]
157 bswap eax
158 mov X, eax
159 pop ebx
160 pop eax
162 continue;
164 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
165 k = X + pc->k;
166 if ((int32)k>= (int32)mem_ex->size) {
167 return 0;
169 A= mem_ex->buffer[k];
170 continue;
172 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
173 k = X + pc->k;
174 if ((int32)(k+1)>= (int32)mem_ex->size) {
175 return 0;
177 tmp2=(uint16*)&mem_ex->buffer[k];
178 __asm
180 push eax
181 push ebx
182 mov ebx,tmp2
183 xor eax, eax
184 mov ax, [ebx]
185 bswap eax
186 mov A, eax
187 pop ebx
188 pop eax
190 continue;
192 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
193 k = X + pc->k;
194 if ((int32)(k+3)>= (int32)mem_ex->size) {
195 return 0;
197 tmp=(uint32*)&mem_ex->buffer[k];
198 __asm
200 push eax
201 push ebx
202 mov ebx,tmp
203 mov eax, [ebx]
204 bswap eax
205 mov A, eax
206 pop ebx
207 pop eax
209 continue;
210 /* END LD NO PACKET INSTRUCTIONS */
212 /* STORE INSTRUCTIONS */
213 case BPF_ST:
214 mem[pc->k] = A;
215 continue;
217 case BPF_STX:
218 mem[pc->k] = X;
219 continue;
221 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
222 mem_ex->buffer[pc->k]=(uint8)A;
223 continue;
225 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
226 mem_ex->buffer[pc->k]=(uint8)X;
227 continue;
229 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
230 tmp=(uint32*)&mem_ex->buffer[pc->k];
231 __asm
233 push eax
234 push ebx
235 mov ebx, tmp
236 mov eax, A
237 bswap eax
238 mov [ebx], eax
239 pop ebx
240 pop eax
242 continue;
244 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
245 tmp=(uint32*)&mem_ex->buffer[pc->k];
246 __asm
248 push eax
249 push ebx
250 mov ebx, tmp
251 mov eax, X
252 bswap eax
253 mov [ebx], eax
254 pop ebx
255 pop eax
257 continue;
259 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
260 tmp2=(uint16*)&mem_ex->buffer[pc->k];
261 __asm
263 push eax
264 push ebx
265 mov ebx, tmp2
266 mov eax, A
267 xchg ah, al
268 mov [ebx], ax
269 pop ebx
270 pop eax
272 continue;
274 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
275 tmp2=(uint16*)&mem_ex->buffer[pc->k];
276 __asm
278 push eax
279 push ebx
280 mov ebx, tmp2
281 mov eax, X
282 xchg ah, al
283 mov [ebx], ax
284 pop ebx
285 pop eax
287 continue;
289 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
290 mem_ex->buffer[pc->k+X]=(uint8)A;
292 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
293 tmp=(uint32*)&mem_ex->buffer[pc->k+X];
294 __asm
296 push eax
297 push ebx
298 mov ebx, tmp
299 mov eax, A
300 bswap eax
301 mov [ebx], eax
302 pop ebx
303 pop eax
306 continue;
308 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
309 tmp2=(uint16*)&mem_ex->buffer[pc->k+X];
310 __asm
312 push eax
313 push ebx
314 mov ebx, tmp2
315 mov eax, A
316 xchg ah, al
317 mov [ebx], ax
318 pop ebx
319 pop eax
321 continue;
322 /* END STORE INSTRUCTIONS */
324 /* JUMP INSTRUCTIONS */
325 case BPF_JMP|BPF_JA:
326 pc += pc->k;
327 continue;
329 case BPF_JMP|BPF_JGT|BPF_K:
330 pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf;
331 continue;
333 case BPF_JMP|BPF_JGE|BPF_K:
334 pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf;
335 continue;
337 case BPF_JMP|BPF_JEQ|BPF_K:
338 pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf;
339 continue;
341 case BPF_JMP|BPF_JSET|BPF_K:
342 pc += (A & pc->k) ? pc->jt : pc->jf;
343 continue;
345 case BPF_JMP|BPF_JGT|BPF_X:
346 pc += (A > X) ? pc->jt : pc->jf;
347 continue;
349 case BPF_JMP|BPF_JGE|BPF_X:
350 pc += (A >= X) ? pc->jt : pc->jf;
351 continue;
353 case BPF_JMP|BPF_JEQ|BPF_X:
354 pc += (A == X) ? pc->jt : pc->jf;
355 continue;
357 case BPF_JMP|BPF_JSET|BPF_X:
358 pc += (A & X) ? pc->jt : pc->jf;
359 continue;
360 /* END JUMP INSTRUCTIONS */
362 /* ARITHMETIC INSTRUCTIONS */
363 case BPF_ALU|BPF_ADD|BPF_X:
364 A += X;
365 continue;
367 case BPF_ALU|BPF_SUB|BPF_X:
368 A -= X;
369 continue;
371 case BPF_ALU|BPF_MUL|BPF_X:
372 A *= X;
373 continue;
375 case BPF_ALU|BPF_DIV|BPF_X:
376 if (X == 0)
377 return 0;
378 A /= X;
379 continue;
381 case BPF_ALU|BPF_AND|BPF_X:
382 A &= X;
383 continue;
385 case BPF_ALU|BPF_OR|BPF_X:
386 A |= X;
387 continue;
389 case BPF_ALU|BPF_LSH|BPF_X:
390 A <<= X;
391 continue;
393 case BPF_ALU|BPF_RSH|BPF_X:
394 A >>= X;
395 continue;
397 case BPF_ALU|BPF_ADD|BPF_K:
398 A += pc->k;
399 continue;
401 case BPF_ALU|BPF_SUB|BPF_K:
402 A -= pc->k;
403 continue;
405 case BPF_ALU|BPF_MUL|BPF_K:
406 A *= pc->k;
407 continue;
409 case BPF_ALU|BPF_DIV|BPF_K:
410 A /= pc->k;
411 continue;
413 case BPF_ALU|BPF_AND|BPF_K:
414 A &= pc->k;
415 continue;
417 case BPF_ALU|BPF_OR|BPF_K:
418 A |= pc->k;
419 continue;
421 case BPF_ALU|BPF_LSH|BPF_K:
422 A <<= pc->k;
423 continue;
425 case BPF_ALU|BPF_RSH|BPF_K:
426 A >>= pc->k;
427 continue;
429 case BPF_ALU|BPF_NEG:
430 (int32)A = -((int32)A);
431 continue;
432 /* ARITHMETIC INSTRUCTIONS */
434 /* MISC INSTRUCTIONS */
435 case BPF_MISC|BPF_TAX:
436 X = A;
437 continue;
439 case BPF_MISC|BPF_TXA:
440 A = X;
441 continue;
442 /* END MISC INSTRUCTIONS */
444 /* TME INSTRUCTIONS */
445 case BPF_MISC|BPF_TME|BPF_LOOKUP:
446 j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
447 if (j==TME_ERROR)
448 return 0;
449 pc += (j == TME_TRUE) ? pc->jt : pc->jf;
450 continue;
452 case BPF_MISC|BPF_TME|BPF_EXECUTE:
453 if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR)
454 return 0;
455 continue;
457 case BPF_MISC|BPF_TME|BPF_INIT:
458 if (init_tme_block(tme,pc->k)==TME_ERROR)
459 return 0;
460 continue;
462 case BPF_MISC|BPF_TME|BPF_VALIDATE:
463 if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR)
464 return 0;
465 continue;
467 case BPF_MISC|BPF_TME|BPF_SET_MEMORY:
468 if (init_extended_memory(pc->k,mem_ex)==TME_ERROR)
469 return 0;
470 continue;
472 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
473 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
474 return 0;
475 continue;
477 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ:
478 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
479 return 0;
480 continue;
481 case BPF_MISC|BPF_TME|BPF_SET_WORKING:
482 if (pc->k>=MAX_TME_DATA_BLOCKS)
483 return 0;
484 tme->working=pc->k;
485 continue;
489 case BPF_MISC|BPF_TME|BPF_RESET:
490 if (reset_tme(tme)==TME_ERROR)
491 return 0;
492 continue;
494 case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
495 if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
496 return 0;
497 A=j;
498 continue;
500 case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
501 if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR)
502 return 0;
503 continue;
505 case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION:
506 set_autodeletion(&tme->block_data[tme->working],pc->k);
507 continue;
509 /* END TME INSTRUCTIONS */