1 /*
2 * Copyright (c) 2001 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
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 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.
18 *
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.
30 *
31 */
32
33 #include <GlobalConst.h>
34
35 #include "tme.h"
36 #include "win_bpf.h"
37
38 /*
39 * Initialize the filter machine
40 */
bpf_filter_init(register struct bpf_insn * pc,MEM_TYPE * mem_ex,TME_CORE * tme,struct time_conv * time_ref)41 uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref)
42 {
43 register uint32 A, X;
44 int32 mem[BPF_MEMWORDS];
45 register int32 k;
46 uint32 *tmp;
47 uint16 *tmp2;
48 uint32 j;
49 if (pc == 0)
50 /*
51 * No filter means accept all.
52 */
53 return (uint32)-1;
54 A = 0;
55 X = 0;
56 --pc;
57 while (1) {
58 ++pc;
59 switch (pc->code) {
60
61 default:
62 return 0;
63
64 /* RET INSTRUCTIONS */
65 case BPF_RET|BPF_K:
66 return (uint32)pc->k;
67
68 case BPF_RET|BPF_A:
69 return (uint32)A;
70 /* END RET INSTRUCTIONS */
71
72 /* LD NO PACKET INSTRUCTIONS */
73 case BPF_LD|BPF_IMM:
74 A = pc->k;
75 continue;
76
77 case BPF_LDX|BPF_IMM:
78 X = pc->k;
79 continue;
80
81 case BPF_LD|BPF_MEM:
82 A = mem[pc->k];
83 continue;
84
85 case BPF_LDX|BPF_MEM:
86 X = mem[pc->k];
87 continue;
88
89 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
90 A= mem_ex->buffer[pc->k];
91 continue;
92
93 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
94 X= mem_ex->buffer[pc->k];
95 continue;
96
97 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
98 tmp2=(uint16*)&mem_ex->buffer[pc->k];
99 __asm
100 {
101 push eax
102 push ebx
103 mov ebx,tmp2
104 xor eax, eax
105 mov ax, [ebx]
106 bswap eax
107 mov A, eax
108 pop ebx
109 pop eax
110 }
111 continue;
112
113 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
114 tmp2=(uint16*)&mem_ex->buffer[pc->k];
115 __asm
116 {
117 push eax
118 push ebx
119 mov ebx,tmp2
120 xor eax, eax
121 mov ax, [ebx]
122 bswap eax
123 mov X, eax
124 pop ebx
125 pop eax
126 }
127 continue;
128
129 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
130 tmp=(uint32*)&mem_ex->buffer[pc->k];
131 __asm
132 {
133 push eax
134 push ebx
135 mov ebx,tmp
136 mov eax, [ebx]
137 bswap eax
138 mov A, eax
139 pop ebx
140 pop eax
141 }
142 continue;
143
144 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
145 tmp=(uint32*)&mem_ex->buffer[pc->k];
146 __asm
147 {
148 push eax
149 push ebx
150 mov ebx,tmp
151 mov eax, [ebx]
152 bswap eax
153 mov X, eax
154 pop ebx
155 pop eax
156 }
157 continue;
158
159 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
160 k = X + pc->k;
161 if ((int32)k>= (int32)mem_ex->size) {
162 return 0;
163 }
164 A= mem_ex->buffer[k];
165 continue;
166
167 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
168 k = X + pc->k;
169 if ((int32)(k+1)>= (int32)mem_ex->size) {
170 return 0;
171 }
172 tmp2=(uint16*)&mem_ex->buffer[k];
173 __asm
174 {
175 push eax
176 push ebx
177 mov ebx,tmp2
178 xor eax, eax
179 mov ax, [ebx]
180 bswap eax
181 mov A, eax
182 pop ebx
183 pop eax
184 }
185 continue;
186
187 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
188 k = X + pc->k;
189 if ((int32)(k+3)>= (int32)mem_ex->size) {
190 return 0;
191 }
192 tmp=(uint32*)&mem_ex->buffer[k];
193 __asm
194 {
195 push eax
196 push ebx
197 mov ebx,tmp
198 mov eax, [ebx]
199 bswap eax
200 mov A, eax
201 pop ebx
202 pop eax
203 }
204 continue;
205 /* END LD NO PACKET INSTRUCTIONS */
206
207 /* STORE INSTRUCTIONS */
208 case BPF_ST:
209 mem[pc->k] = A;
210 continue;
211
212 case BPF_STX:
213 mem[pc->k] = X;
214 continue;
215
216 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
217 mem_ex->buffer[pc->k]=(uint8)A;
218 continue;
219
220 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
221 mem_ex->buffer[pc->k]=(uint8)X;
222 continue;
223
224 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
225 tmp=(uint32*)&mem_ex->buffer[pc->k];
226 __asm
227 {
228 push eax
229 push ebx
230 mov ebx, tmp
231 mov eax, A
232 bswap eax
233 mov [ebx], eax
234 pop ebx
235 pop eax
236 }
237 continue;
238
239 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
240 tmp=(uint32*)&mem_ex->buffer[pc->k];
241 __asm
242 {
243 push eax
244 push ebx
245 mov ebx, tmp
246 mov eax, X
247 bswap eax
248 mov [ebx], eax
249 pop ebx
250 pop eax
251 }
252 continue;
253
254 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
255 tmp2=(uint16*)&mem_ex->buffer[pc->k];
256 __asm
257 {
258 push eax
259 push ebx
260 mov ebx, tmp2
261 mov eax, A
262 xchg ah, al
263 mov [ebx], ax
264 pop ebx
265 pop eax
266 }
267 continue;
268
269 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
270 tmp2=(uint16*)&mem_ex->buffer[pc->k];
271 __asm
272 {
273 push eax
274 push ebx
275 mov ebx, tmp2
276 mov eax, X
277 xchg ah, al
278 mov [ebx], ax
279 pop ebx
280 pop eax
281 }
282 continue;
283
284 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
285 mem_ex->buffer[pc->k+X]=(uint8)A;
286
287 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
288 tmp=(uint32*)&mem_ex->buffer[pc->k+X];
289 __asm
290 {
291 push eax
292 push ebx
293 mov ebx, tmp
294 mov eax, A
295 bswap eax
296 mov [ebx], eax
297 pop ebx
298 pop eax
299 }
300
301 continue;
302
303 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
304 tmp2=(uint16*)&mem_ex->buffer[pc->k+X];
305 __asm
306 {
307 push eax
308 push ebx
309 mov ebx, tmp2
310 mov eax, A
311 xchg ah, al
312 mov [ebx], ax
313 pop ebx
314 pop eax
315 }
316 continue;
317 /* END STORE INSTRUCTIONS */
318
319 /* JUMP INSTRUCTIONS */
320 case BPF_JMP|BPF_JA:
321 pc += pc->k;
322 continue;
323
324 case BPF_JMP|BPF_JGT|BPF_K:
325 pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf;
326 continue;
327
328 case BPF_JMP|BPF_JGE|BPF_K:
329 pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf;
330 continue;
331
332 case BPF_JMP|BPF_JEQ|BPF_K:
333 pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf;
334 continue;
335
336 case BPF_JMP|BPF_JSET|BPF_K:
337 pc += (A & pc->k) ? pc->jt : pc->jf;
338 continue;
339
340 case BPF_JMP|BPF_JGT|BPF_X:
341 pc += (A > X) ? pc->jt : pc->jf;
342 continue;
343
344 case BPF_JMP|BPF_JGE|BPF_X:
345 pc += (A >= X) ? pc->jt : pc->jf;
346 continue;
347
348 case BPF_JMP|BPF_JEQ|BPF_X:
349 pc += (A == X) ? pc->jt : pc->jf;
350 continue;
351
352 case BPF_JMP|BPF_JSET|BPF_X:
353 pc += (A & X) ? pc->jt : pc->jf;
354 continue;
355 /* END JUMP INSTRUCTIONS */
356
357 /* ARITHMETIC INSTRUCTIONS */
358 case BPF_ALU|BPF_ADD|BPF_X:
359 A += X;
360 continue;
361
362 case BPF_ALU|BPF_SUB|BPF_X:
363 A -= X;
364 continue;
365
366 case BPF_ALU|BPF_MUL|BPF_X:
367 A *= X;
368 continue;
369
370 case BPF_ALU|BPF_DIV|BPF_X:
371 if (X == 0)
372 return 0;
373 A /= X;
374 continue;
375
376 case BPF_ALU|BPF_AND|BPF_X:
377 A &= X;
378 continue;
379
380 case BPF_ALU|BPF_OR|BPF_X:
381 A |= X;
382 continue;
383
384 case BPF_ALU|BPF_LSH|BPF_X:
385 A <<= X;
386 continue;
387
388 case BPF_ALU|BPF_RSH|BPF_X:
389 A >>= X;
390 continue;
391
392 case BPF_ALU|BPF_ADD|BPF_K:
393 A += pc->k;
394 continue;
395
396 case BPF_ALU|BPF_SUB|BPF_K:
397 A -= pc->k;
398 continue;
399
400 case BPF_ALU|BPF_MUL|BPF_K:
401 A *= pc->k;
402 continue;
403
404 case BPF_ALU|BPF_DIV|BPF_K:
405 A /= pc->k;
406 continue;
407
408 case BPF_ALU|BPF_AND|BPF_K:
409 A &= pc->k;
410 continue;
411
412 case BPF_ALU|BPF_OR|BPF_K:
413 A |= pc->k;
414 continue;
415
416 case BPF_ALU|BPF_LSH|BPF_K:
417 A <<= pc->k;
418 continue;
419
420 case BPF_ALU|BPF_RSH|BPF_K:
421 A >>= pc->k;
422 continue;
423
424 case BPF_ALU|BPF_NEG:
425 (int32)A = -((int32)A);
426 continue;
427 /* ARITHMETIC INSTRUCTIONS */
428
429 /* MISC INSTRUCTIONS */
430 case BPF_MISC|BPF_TAX:
431 X = A;
432 continue;
433
434 case BPF_MISC|BPF_TXA:
435 A = X;
436 continue;
437 /* END MISC INSTRUCTIONS */
438
439 /* TME INSTRUCTIONS */
440 case BPF_MISC|BPF_TME|BPF_LOOKUP:
441 j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
442 if (j==TME_ERROR)
443 return 0;
444 pc += (j == TME_TRUE) ? pc->jt : pc->jf;
445 continue;
446
447 case BPF_MISC|BPF_TME|BPF_EXECUTE:
448 if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR)
449 return 0;
450 continue;
451
452 case BPF_MISC|BPF_TME|BPF_INIT:
453 if (init_tme_block(tme,pc->k)==TME_ERROR)
454 return 0;
455 continue;
456
457 case BPF_MISC|BPF_TME|BPF_VALIDATE:
458 if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR)
459 return 0;
460 continue;
461
462 case BPF_MISC|BPF_TME|BPF_SET_MEMORY:
463 if (init_extended_memory(pc->k,mem_ex)==TME_ERROR)
464 return 0;
465 continue;
466
467 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
468 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
469 return 0;
470 continue;
471
472 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ:
473 if (set_active_tme_block(tme,pc->k)==TME_ERROR)
474 return 0;
475 continue;
476 case BPF_MISC|BPF_TME|BPF_SET_WORKING:
477 if (pc->k>=MAX_TME_DATA_BLOCKS)
478 return 0;
479 tme->working=pc->k;
480 continue;
481
482
483
484 case BPF_MISC|BPF_TME|BPF_RESET:
485 if (reset_tme(tme)==TME_ERROR)
486 return 0;
487 continue;
488
489 case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
490 if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
491 return 0;
492 A=j;
493 continue;
494
495 case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
496 if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR)
497 return 0;
498 continue;
499
500 case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION:
501 set_autodeletion(&tme->block_data[tme->working],pc->k);
502 continue;
503
504 /* END TME INSTRUCTIONS */
505
506 }
507 }
508 }
509
510