update for HEAD-2003021201
[reactos.git] / drivers / net / npf / win_bpf_filter_init.c
1 /*
2  * Copyright (c) 2001
3  *      Politecnico di Torino.  All rights reserved.
4  *
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
16  * written permission.
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.
20  *
21  *
22  *
23  * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
24  *      The Regents of the University of California.  All rights reserved.
25  *
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.
30  *
31  * Redistribution and use in source and binary forms, with or without
32  * modification, are permitted provided that the following conditions
33  * are met:
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.
46  *
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
57  * SUCH DAMAGE.
58  */
59
60 #include "tme.h"
61 #include "win_bpf.h"
62
63 /*
64  * Initialize the filter machine
65  */
66 uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref)
67 {
68         register uint32 A, X;
69         int32 mem[BPF_MEMWORDS];
70         register int32 k;
71         uint32 *tmp;
72         uint16 *tmp2;
73         uint32 j;
74         if (pc == 0)
75                 /*
76                  * No filter means accept all.
77                  */
78                  return (uint32)-1;
79         A = 0;
80         X = 0;
81         --pc;
82         while (1) {
83                 ++pc;
84                 switch (pc->code) {
85
86                 default:
87                         return 0;
88
89 /* RET INSTRUCTIONS */
90                 case BPF_RET|BPF_K:
91                         return (uint32)pc->k;
92
93                 case BPF_RET|BPF_A:
94                         return (uint32)A;
95 /* END RET INSTRUCTIONS */
96
97 /* LD NO PACKET INSTRUCTIONS */
98                 case BPF_LD|BPF_IMM:
99                         A = pc->k;
100                         continue;
101
102                 case BPF_LDX|BPF_IMM:
103                         X = pc->k;
104                         continue;
105
106                 case BPF_LD|BPF_MEM:
107                         A = mem[pc->k];
108                         continue;
109                         
110                 case BPF_LDX|BPF_MEM:
111                         X = mem[pc->k];
112                         continue;
113
114                 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
115                         A= mem_ex->buffer[pc->k];
116                         continue;
117
118                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
119                         X= mem_ex->buffer[pc->k];
120                         continue;
121
122                 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
123                         tmp2=(uint16*)&mem_ex->buffer[pc->k];
124 #ifndef __GNUC__
125                         __asm
126                         {
127                                 push eax
128                                 push ebx
129                                 mov ebx,tmp2
130                                 xor eax, eax
131                                 mov ax, [ebx]
132                                 bswap eax
133                                 mov A, eax
134                                 pop ebx
135                                 pop eax
136                         }
137 #else
138                         asm("push %%eax;"
139                                 "push %%ebx;"
140                                 "mov %1,%%ebx;"
141                                 "xor %%eax, %%eax;"
142                                 "mov (%%ebx), %%ax;"
143                                 "bswap %%eax;"
144                                 "mov %%eax, %0;"
145                                 "pop %%ebx;"
146                                 "pop %%eax;"
147                 :"=a"(A),"=c"(tmp2): );
148 #endif
149                         continue;
150
151                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
152                         tmp2=(uint16*)&mem_ex->buffer[pc->k];
153 #ifndef __GNUC__
154                         __asm
155                         {
156                                 push eax
157                                 push ebx
158                                 mov ebx,tmp2
159                                 xor eax, eax
160                                 mov ax, [ebx]
161                                 bswap eax
162                                 mov X, eax
163                                 pop ebx
164                                 pop eax
165                         }
166 #else
167                         asm("push %%eax;"
168                                 "push %%ebx;"
169                                 "mov %1,%%ebx;"
170                                 "xor %%eax, %%eax;"
171                                 "mov (%%ebx), %%ax;"
172                                 "bswap %%eax;"
173                                 "mov %%eax, %0;"
174                                 "pop %%ebx;"
175                                 "pop %%eax;"
176                 :"=a"(X),"=c"(tmp2): );
177 #endif
178                         continue;
179
180                 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
181                         tmp=(uint32*)&mem_ex->buffer[pc->k];
182 #ifndef __GNUC__
183                         __asm
184                         {
185                                 push eax
186                                 push ebx
187                                 mov ebx,tmp
188                                 mov eax, [ebx]
189                                 bswap eax
190                                 mov A, eax
191                                 pop ebx
192                                 pop eax
193                         }
194 #else
195                         asm("push %%eax;"
196                                 "push %%ebx;"
197                                 "mov %1,%%ebx;"
198                                 "xor %%eax, %%eax;"
199                                 "mov (%%ebx), %%ax;"
200                                 "bswap %%eax;"
201                                 "mov %%eax, %0;"
202                                 "pop %%ebx;"
203                                 "pop %%eax;"
204                 :"=a"(A),"=c"(tmp): );
205 #endif
206                         continue;
207
208                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
209                         tmp=(uint32*)&mem_ex->buffer[pc->k];
210 #ifndef __GNUC__
211                         __asm
212                         {
213                                 push eax
214                                 push ebx
215                                 mov ebx,tmp
216                                 mov eax, [ebx]
217                                 bswap eax
218                                 mov X, eax
219                                 pop ebx
220                                 pop eax
221                         }
222 #else
223                         asm("push %%eax;"
224                                 "push %%ebx;"
225                                 "mov %1,%%ebx;"
226                                 "xor %%eax, %%eax;"
227                                 "mov (%%ebx), %%ax;"
228                                 "bswap %%eax;"
229                                 "mov %%eax, %0;"
230                                 "pop %%ebx;"
231                                 "pop %%eax;"
232                 :"=a"(X),"=c"(tmp): );
233 #endif
234                         continue;
235                         
236                 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
237                         k = X + pc->k;
238                         if ((int32)k>= (int32)mem_ex->size) {
239                                 return 0;
240                         }
241                         A= mem_ex->buffer[k];
242                         continue;
243
244                 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
245                         k = X + pc->k;
246                         if ((int32)(k+1)>= (int32)mem_ex->size) {
247                                 return 0;
248                         }
249                         tmp2=(uint16*)&mem_ex->buffer[k];
250 #ifndef __GNUC__
251                         __asm
252                         {
253                                 push eax
254                                 push ebx
255                                 mov ebx,tmp2
256                                 xor eax, eax
257                                 mov ax, [ebx]
258                                 bswap eax
259                                 mov A, eax
260                                 pop ebx
261                                 pop eax
262                         }
263 #else
264                         asm("push %%eax;"
265                                 "push %%ebx;"
266                                 "mov %1,%%ebx;"
267                                 "xor %%eax, %%eax;"
268                                 "mov (%%ebx), %%ax;"
269                                 "bswap %%eax;"
270                                 "mov %%eax, %0;"
271                                 "pop %%ebx;"
272                                 "pop %%eax;"
273                 :"=a"(A),"=c"(tmp2): );
274 #endif
275                         continue;
276
277                 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
278                         k = X + pc->k;
279                         if ((int32)(k+3)>= (int32)mem_ex->size) {
280                                 return 0;
281                         }
282                         tmp=(uint32*)&mem_ex->buffer[k];
283 #ifndef __GNUC__
284                         __asm
285                         {
286                                 push eax
287                                 push ebx
288                                 mov ebx,tmp
289                                 mov eax, [ebx]
290                                 bswap eax
291                                 mov A, eax
292                                 pop ebx
293                                 pop eax
294                         }
295 #else
296                         asm("push %%eax;"
297                                 "push %%ebx;"
298                                 "mov %1,%%ebx;"
299                                 "xor %%eax, %%eax;"
300                                 "mov (%%ebx), %%ax;"
301                                 "bswap %%eax;"
302                                 "mov %%eax, %0;"
303                                 "pop %%ebx;"
304                                 "pop %%eax;"
305                 :"=a"(A),"=c"(tmp): );
306 #endif
307                         continue;
308 /* END LD NO PACKET INSTRUCTIONS */
309
310 /* STORE INSTRUCTIONS */
311                 case BPF_ST:
312                         mem[pc->k] = A;
313                         continue;
314
315                 case BPF_STX:
316                         mem[pc->k] = X;
317                         continue;
318
319                 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
320                         mem_ex->buffer[pc->k]=(uint8)A;
321                         continue;
322
323                 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
324                         mem_ex->buffer[pc->k]=(uint8)X;
325                         continue;
326
327                 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
328                         tmp=(uint32*)&mem_ex->buffer[pc->k];
329 #ifndef __GNUC__
330                         __asm
331                         {
332                                 push eax
333                                 push ebx
334                                 mov ebx, tmp
335                                 mov eax, A
336                                 bswap eax
337                                 mov [ebx], eax
338                                 pop ebx
339                                 pop eax
340                         }
341 #else
342                         asm("push %%eax;"
343                                 "push %%ebx;"
344                                 "mov %1,%%ebx;"
345                                 "xor %%eax, %%eax;"
346                                 "mov (%%ebx), %%ax;"
347                                 "bswap %%eax;"
348                                 "mov %%eax, %0;"
349                                 "pop %%ebx;"
350                                 "pop %%eax;"
351                 :"=a"(A),"=c"(tmp): );
352 #endif
353                         continue;
354
355                 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
356                         tmp=(uint32*)&mem_ex->buffer[pc->k];
357 #ifndef __GNUC__
358                         __asm
359                         {
360                                 push eax
361                                 push ebx
362                                 mov ebx, tmp
363                                 mov eax, X
364                                 bswap eax
365                                 mov [ebx], eax
366                                 pop ebx
367                                 pop eax
368                         }
369 #else
370                         asm("push %%eax;"
371                                 "push %%ebx;"
372                                 "mov %1,%%ebx;"
373                                 "xor %%eax, %%eax;"
374                                 "mov (%%ebx), %%ax;"
375                                 "bswap %%eax;"
376                                 "mov %%eax, %0;"
377                                 "pop %%ebx;"
378                                 "pop %%eax;"
379                 :"=a"(X),"=c"(tmp): );
380 #endif
381                         continue;
382
383                 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
384                         tmp2=(uint16*)&mem_ex->buffer[pc->k];
385 #ifndef __GNUC__
386                         __asm
387                         {
388                                 push eax
389                                 push ebx
390                                 mov ebx, tmp2
391                                 mov eax, A
392                                 xchg ah, al
393                                 mov [ebx], ax
394                                 pop ebx
395                                 pop eax
396                         }
397 #else
398                         asm("push %%eax;"
399                                 "push %%ebx;"
400                                 "mov %1,%%ebx;"
401                                 "xor %%eax, %%eax;"
402                                 "mov (%%ebx), %%ax;"
403                                 "bswap %%eax;"
404                                 "mov %%eax, %0;"
405                                 "pop %%ebx;"
406                                 "pop %%eax;"
407                 :"=a"(A),"=c"(tmp2): );
408 #endif
409                         continue;
410
411                 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
412                         tmp2=(uint16*)&mem_ex->buffer[pc->k];
413 #ifndef __GNUC__
414                         __asm
415                         {
416                                 push eax
417                                 push ebx
418                                 mov ebx, tmp2
419                                 mov eax, X
420                                 xchg ah, al
421                                 mov [ebx], ax
422                                 pop ebx
423                                 pop eax
424                         }
425 #else
426                         asm("push %%eax;"
427                                 "push %%ebx;"
428                                 "mov %1,%%ebx;"
429                                 "xor %%eax, %%eax;"
430                                 "mov (%%ebx), %%ax;"
431                                 "bswap %%eax;"
432                                 "mov %%eax, %0;"
433                                 "pop %%ebx;"
434                                 "pop %%eax;"
435                 :"=a"(X),"=c"(tmp2): );
436 #endif
437                         continue;
438
439                 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
440                         mem_ex->buffer[pc->k+X]=(uint8)A;
441
442                 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
443                         tmp=(uint32*)&mem_ex->buffer[pc->k+X];
444 #ifndef __GNUC__
445                         __asm
446                         {
447                                 push eax
448                                 push ebx
449                                 mov ebx, tmp
450                                 mov eax, A
451                                 bswap eax
452                                 mov [ebx], eax
453                                 pop ebx
454                                 pop eax
455                         }
456 #else
457                         asm("push %%eax;"
458                                 "push %%ebx;"
459                                 "mov %1,%%ebx;"
460                                 "xor %%eax, %%eax;"
461                                 "mov (%%ebx), %%ax;"
462                                 "bswap %%eax;"
463                                 "mov %%eax, %0;"
464                                 "pop %%ebx;"
465                                 "pop %%eax;"
466                 :"=a"(A),"=c"(tmp): );
467 #endif
468                         continue;
469
470                 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
471                         tmp2=(uint16*)&mem_ex->buffer[pc->k+X];
472 #ifndef __GNUC__
473                         __asm
474                         {
475                                 push eax
476                                 push ebx
477                                 mov ebx, tmp2
478                                 mov eax, A
479                                 xchg ah, al
480                                 mov [ebx], ax
481                                 pop ebx
482                                 pop eax
483                         }
484 #else
485                         asm("push %%eax;"
486                                 "push %%ebx;"
487                                 "mov %1,%%ebx;"
488                                 "xor %%eax, %%eax;"
489                                 "mov (%%ebx), %%ax;"
490                                 "bswap %%eax;"
491                                 "mov %%eax, %0;"
492                                 "pop %%ebx;"
493                                 "pop %%eax;"
494                 :"=a"(A),"=c"(tmp2): );
495 #endif
496                         continue;
497 /* END STORE INSTRUCTIONS */
498
499 /* JUMP INSTRUCTIONS */
500                 case BPF_JMP|BPF_JA:
501                         pc += pc->k;
502                         continue;
503
504                 case BPF_JMP|BPF_JGT|BPF_K:
505                         pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf;
506                         continue;
507
508                 case BPF_JMP|BPF_JGE|BPF_K:
509                         pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf;
510                         continue;
511
512                 case BPF_JMP|BPF_JEQ|BPF_K:
513                         pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf;
514                         continue;
515
516                 case BPF_JMP|BPF_JSET|BPF_K:
517                         pc += (A & pc->k) ? pc->jt : pc->jf;
518                         continue;
519
520                 case BPF_JMP|BPF_JGT|BPF_X:
521                         pc += (A > X) ? pc->jt : pc->jf;
522                         continue;
523
524                 case BPF_JMP|BPF_JGE|BPF_X:
525                         pc += (A >= X) ? pc->jt : pc->jf;
526                         continue;
527
528                 case BPF_JMP|BPF_JEQ|BPF_X:
529                         pc += (A == X) ? pc->jt : pc->jf;
530                         continue;
531
532                 case BPF_JMP|BPF_JSET|BPF_X:
533                         pc += (A & X) ? pc->jt : pc->jf;
534                         continue;
535 /* END JUMP INSTRUCTIONS */
536
537 /* ARITHMETIC INSTRUCTIONS */
538                 case BPF_ALU|BPF_ADD|BPF_X:
539                         A += X;
540                         continue;
541                         
542                 case BPF_ALU|BPF_SUB|BPF_X:
543                         A -= X;
544                         continue;
545                         
546                 case BPF_ALU|BPF_MUL|BPF_X:
547                         A *= X;
548                         continue;
549                         
550                 case BPF_ALU|BPF_DIV|BPF_X:
551                         if (X == 0)
552                                 return 0;
553                         A /= X;
554                         continue;
555                         
556                 case BPF_ALU|BPF_AND|BPF_X:
557                         A &= X;
558                         continue;
559                         
560                 case BPF_ALU|BPF_OR|BPF_X:
561                         A |= X;
562                         continue;
563
564                 case BPF_ALU|BPF_LSH|BPF_X:
565                         A <<= X;
566                         continue;
567
568                 case BPF_ALU|BPF_RSH|BPF_X:
569                         A >>= X;
570                         continue;
571
572                 case BPF_ALU|BPF_ADD|BPF_K:
573                         A += pc->k;
574                         continue;
575                         
576                 case BPF_ALU|BPF_SUB|BPF_K:
577                         A -= pc->k;
578                         continue;
579                         
580                 case BPF_ALU|BPF_MUL|BPF_K:
581                         A *= pc->k;
582                         continue;
583                         
584                 case BPF_ALU|BPF_DIV|BPF_K:
585                         A /= pc->k;
586                         continue;
587                         
588                 case BPF_ALU|BPF_AND|BPF_K:
589                         A &= pc->k;
590                         continue;
591                         
592                 case BPF_ALU|BPF_OR|BPF_K:
593                         A |= pc->k;
594                         continue;
595
596                 case BPF_ALU|BPF_LSH|BPF_K:
597                         A <<= pc->k;
598                         continue;
599
600                 case BPF_ALU|BPF_RSH|BPF_K:
601                         A >>= pc->k;
602                         continue;
603
604                 case BPF_ALU|BPF_NEG:
605                         (int32)A = -((int32)A);
606                         continue;
607 /* ARITHMETIC INSTRUCTIONS */
608
609 /* MISC INSTRUCTIONS */
610                 case BPF_MISC|BPF_TAX:
611                         X = A;
612                         continue;
613
614                 case BPF_MISC|BPF_TXA:
615                         A = X;
616                         continue;
617 /* END MISC INSTRUCTIONS */
618
619 /* TME INSTRUCTIONS */
620                 case BPF_MISC|BPF_TME|BPF_LOOKUP:
621                         j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
622                         if (j==TME_ERROR)
623                                 return 0;       
624                         pc += (j == TME_TRUE) ? pc->jt : pc->jf;
625                         continue;
626
627                 case BPF_MISC|BPF_TME|BPF_EXECUTE:
628                         if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR)
629                                 return 0;
630                         continue;
631
632                 case BPF_MISC|BPF_TME|BPF_INIT:
633                         if (init_tme_block(tme,pc->k)==TME_ERROR)
634                                 return 0;
635                         continue;
636                         
637                 case BPF_MISC|BPF_TME|BPF_VALIDATE:
638                         if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR)
639                                 return 0;
640                         continue;
641
642                 case BPF_MISC|BPF_TME|BPF_SET_MEMORY:
643                         if (init_extended_memory(pc->k,mem_ex)==TME_ERROR)
644                                 return 0;
645                         continue;
646
647                 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
648                         if (set_active_tme_block(tme,pc->k)==TME_ERROR)
649                                 return 0;
650                         continue;
651
652                 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ:
653                         if (set_active_tme_block(tme,pc->k)==TME_ERROR)
654                                 return 0;
655                         continue;
656                 case BPF_MISC|BPF_TME|BPF_SET_WORKING:
657                         if ((pc->k<0)||(pc->k>=MAX_TME_DATA_BLOCKS))
658                                 return 0;
659                         tme->working=pc->k;
660                         continue;
661
662
663
664                 case BPF_MISC|BPF_TME|BPF_RESET:
665                         if (reset_tme(tme)==TME_ERROR)
666                                 return 0;
667                         continue;
668
669                 case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE:
670                         if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR)
671                                 return 0;
672                         A=j;
673                         continue;
674
675                 case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE:
676                         if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR)
677                                 return 0;
678                         continue;
679
680                 case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION:
681                         set_autodeletion(&tme->block_data[tme->working],pc->k);
682                         continue;
683                         
684 /* END TME INSTRUCTIONS */
685
686                 }
687         }
688 }
689