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