update for HEAD-2003091401
[reactos.git] / drivers / net / npf / win_bpf_filter.c
1 /*
2  * Copyright (c) 1999, 2000
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         @(#)bpf.c       7.5 (Berkeley) 7/15/91
60 */
61
62 #include "tme.h"
63 #include "win_bpf.h"
64
65 #include "debug.h"
66
67 #include "valid_insns.h"
68
69 #define EXTRACT_SHORT(p)\
70         ((u_short)\
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)
78
79
80 u_int bpf_filter(pc, p, wirelen, buflen,mem_ex,tme,time_ref)
81         register struct bpf_insn *pc;
82         register u_char *p;
83         u_int wirelen;
84         register u_int buflen;
85         PMEM_TYPE mem_ex;
86         PTME_CORE tme;
87         struct time_conv *time_ref;
88
89 {
90         register u_int32 A, X;
91         register int k;
92         u_int32 j,tmp;
93         u_short tmp2;
94         
95         int32 mem[BPF_MEMWORDS];
96
97         if (pc == 0)
98                 /*
99                  * No filter means accept all.
100                  */
101                 return (u_int)-1;
102         A = 0;
103         X = 0;
104         --pc;
105         while (1) {
106                 ++pc;
107                 switch (pc->code) {
108
109                 default:
110                 
111                         return 0;
112
113                 case BPF_RET|BPF_K:
114                         return (u_int)pc->k;
115
116                 case BPF_RET|BPF_A:
117                         return (u_int)A;
118
119                 case BPF_LD|BPF_W|BPF_ABS:
120                         k = pc->k;
121                         if (k + sizeof(int32) > buflen) {
122                                 return 0;
123                         }
124                         A = EXTRACT_LONG(&p[k]);
125                         continue;
126
127                 case BPF_LD|BPF_H|BPF_ABS:
128                         k = pc->k;
129                         if (k + sizeof(short) > buflen) {
130                                 return 0;
131                         }
132                         A = EXTRACT_SHORT(&p[k]);
133                         continue;
134
135                 case BPF_LD|BPF_B|BPF_ABS:
136                         k = pc->k;
137                         if ((int)k >= (int)buflen) {
138                                 return 0;
139                         }
140                         A = p[k];
141                         continue;
142
143                 case BPF_LD|BPF_W|BPF_LEN:
144                         A = wirelen;
145                         continue;
146
147                 case BPF_LDX|BPF_W|BPF_LEN:
148                         X = wirelen;
149                         continue;
150
151                 case BPF_LD|BPF_W|BPF_IND:
152                         k = X + pc->k;
153                         if (k + sizeof(int32) > buflen) {
154                                 return 0;
155                         }
156                         A = EXTRACT_LONG(&p[k]);
157                         continue;
158
159                 case BPF_LD|BPF_H|BPF_IND:
160                         k = X + pc->k;
161                         if (k + sizeof(short) > buflen) {
162                                 return 0;
163                         }
164                         A = EXTRACT_SHORT(&p[k]);
165                         continue;
166
167                 case BPF_LD|BPF_B|BPF_IND:
168                         k = X + pc->k;
169                         if ((int)k >= (int)buflen) {
170                                 return 0;
171                         }
172                         A = p[k];
173                         continue;
174
175                 case BPF_LDX|BPF_MSH|BPF_B:
176                         k = pc->k;
177                         if ((int)k >= (int)buflen) {
178                                 return 0;
179                         }
180                         X = (p[pc->k] & 0xf) << 2;
181                         continue;
182
183                 case BPF_LD|BPF_IMM:
184                         A = pc->k;
185                         continue;
186
187                 case BPF_LDX|BPF_IMM:
188                         X = pc->k;
189                         continue;
190
191                 case BPF_LD|BPF_MEM:
192                         A = mem[pc->k];
193                         continue;
194                         
195                 case BPF_LDX|BPF_MEM:
196                         X = mem[pc->k];
197                         continue;
198
199 /* LD NO PACKET INSTRUCTIONS */
200
201                 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
202                         A= mem_ex->buffer[pc->k];
203                         continue;
204
205                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
206                         X= mem_ex->buffer[pc->k];
207                         continue;
208
209                 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
210                         A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
211                         continue;
212
213                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
214                         X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
215                         continue;
216
217                 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
218                         A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
219                         continue;
220
221                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
222                         X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
223                         continue;
224                         
225                 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
226                         k = X + pc->k;
227                         if ((int32)k>= (int32)mem_ex->size) {
228                                 return 0;
229                         }
230                         A= mem_ex->buffer[k];
231                         continue;
232
233                 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
234                         k = X + pc->k;
235                         if ((int32)(k+1)>= (int32)mem_ex->size) {
236                                 return 0;
237                         }
238                         A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
239                         continue;
240
241                 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
242                         k = X + pc->k;
243                         if ((int32)(k+3)>= (int32)mem_ex->size) {
244                                 return 0;
245                         }
246                         A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
247                         continue;
248 /* END LD NO PACKET INSTRUCTIONS */
249
250                 case BPF_ST:
251                         mem[pc->k] = A;
252                         continue;
253
254                 case BPF_STX:
255                         mem[pc->k] = X;
256                         continue;
257
258 /* STORE INSTRUCTIONS */
259                 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
260                         mem_ex->buffer[pc->k]=(uint8)A;
261                         continue;
262
263                 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
264                         mem_ex->buffer[pc->k]=(uint8)X;
265                         continue;
266
267                 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
268                         tmp=A;
269                         *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
270                         continue;
271
272                 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
273                         tmp=X;
274                         *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
275                         continue;
276
277                 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
278                         tmp2=(uint16)A;
279                         *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
280                         continue;
281
282                 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
283                         tmp2=(uint16)X;
284                         *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
285                         continue;
286
287                 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
288                         mem_ex->buffer[pc->k+X]=(uint8)A;
289
290                 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
291                         tmp=A;
292                         *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
293                         continue;
294
295                 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
296                         tmp2=(uint16)A;
297                         *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
298                         continue;
299 /* END STORE INSTRUCTIONS */
300
301                 case BPF_JMP|BPF_JA:
302                         pc += pc->k;
303                         continue;
304
305                 case BPF_JMP|BPF_JGT|BPF_K:
306                         pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
307                         continue;
308
309                 case BPF_JMP|BPF_JGE|BPF_K:
310                         pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
311                         continue;
312
313                 case BPF_JMP|BPF_JEQ|BPF_K:
314                         pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf;
315                         continue;
316
317                 case BPF_JMP|BPF_JSET|BPF_K:
318                         pc += (A & pc->k) ? pc->jt : pc->jf;
319                         continue;
320
321                 case BPF_JMP|BPF_JGT|BPF_X:
322                         pc += (A > X) ? pc->jt : pc->jf;
323                         continue;
324
325                 case BPF_JMP|BPF_JGE|BPF_X:
326                         pc += (A >= X) ? pc->jt : pc->jf;
327                         continue;
328
329                 case BPF_JMP|BPF_JEQ|BPF_X:
330                         pc += (A == X) ? pc->jt : pc->jf;
331                         continue;
332
333                 case BPF_JMP|BPF_JSET|BPF_X:
334                         pc += (A & X) ? pc->jt : pc->jf;
335                         continue;
336
337                 case BPF_ALU|BPF_ADD|BPF_X:
338                         A += X;
339                         continue;
340                         
341                 case BPF_ALU|BPF_SUB|BPF_X:
342                         A -= X;
343                         continue;
344                         
345                 case BPF_ALU|BPF_MUL|BPF_X:
346                         A *= X;
347                         continue;
348                         
349                 case BPF_ALU|BPF_DIV|BPF_X:
350                         if (X == 0)
351                                 return 0;
352                         A /= X;
353                         continue;
354                         
355                 case BPF_ALU|BPF_AND|BPF_X:
356                         A &= X;
357                         continue;
358                         
359                 case BPF_ALU|BPF_OR|BPF_X:
360                         A |= X;
361                         continue;
362
363                 case BPF_ALU|BPF_LSH|BPF_X:
364                         A <<= X;
365                         continue;
366
367                 case BPF_ALU|BPF_RSH|BPF_X:
368                         A >>= X;
369                         continue;
370
371                 case BPF_ALU|BPF_ADD|BPF_K:
372                         A += pc->k;
373                         continue;
374                         
375                 case BPF_ALU|BPF_SUB|BPF_K:
376                         A -= pc->k;
377                         continue;
378                         
379                 case BPF_ALU|BPF_MUL|BPF_K:
380                         A *= pc->k;
381                         continue;
382                         
383                 case BPF_ALU|BPF_DIV|BPF_K:
384                         A /= pc->k;
385                         continue;
386                         
387                 case BPF_ALU|BPF_AND|BPF_K:
388                         A &= pc->k;
389                         continue;
390                         
391                 case BPF_ALU|BPF_OR|BPF_K:
392                         A |= pc->k;
393                         continue;
394
395                 case BPF_ALU|BPF_LSH|BPF_K:
396                         A <<= pc->k;
397                         continue;
398
399                 case BPF_ALU|BPF_RSH|BPF_K:
400                         A >>= pc->k;
401                         continue;
402
403                 case BPF_ALU|BPF_NEG:
404                         (int)A = -((int)A);
405                         continue;
406
407                 case BPF_MISC|BPF_TAX:
408                         X = A;
409                         continue;
410
411                 case BPF_MISC|BPF_TXA:
412                         A = X;
413                         continue;
414
415 /* TME INSTRUCTIONS */
416                 case BPF_MISC|BPF_TME|BPF_LOOKUP:
417                         j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
418                         if (j==TME_ERROR)
419                                 return 0;       
420                         pc += (j == TME_TRUE) ? pc->jt : pc->jf;
421                         continue;
422
423                 case BPF_MISC|BPF_TME|BPF_EXECUTE:
424                         if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR)
425                                 return 0;
426                         continue;
427
428                 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
429                         if (set_active_tme_block(tme,pc->k)==TME_ERROR)
430                                 return 0;
431                         continue;
432
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)
435                                 return 0;
436                         A=j;
437                         continue;
438
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)
441                                 return 0;
442                         continue;
443 /* END TME INSTRUCTIONS */
444
445                 }
446         }
447 }
448
449 //-------------------------------------------------------------------
450
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;
453         register u_char *p;
454         register u_char *pd;
455         register int headersize; 
456         u_int wirelen;
457         register u_int buflen;
458         PMEM_TYPE mem_ex;
459         PTME_CORE tme;
460         struct time_conv *time_ref;
461 {
462         register u_int32 A, X;
463         register int k;
464         int32 mem[BPF_MEMWORDS];
465         u_int32 j,tmp;
466         u_short tmp2;
467
468         if (pc == 0)
469                 /*
470                  * No filter means accept all.
471                  */
472                 return (u_int)-1;
473         A = 0;
474         X = 0;
475         --pc;
476         while (1) {
477                 ++pc;
478                 switch (pc->code) {
479
480                 default:
481                 
482                         return 0;
483
484                 case BPF_RET|BPF_K:
485                         return (u_int)pc->k;
486
487                 case BPF_RET|BPF_A:
488                         return (u_int)A;
489
490                 case BPF_LD|BPF_W|BPF_ABS:
491                         k = pc->k;
492                         if (k + sizeof(int32) > buflen) {
493                                 return 0;
494                         }
495                         
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);
502                         }
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);
508                         }
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);
514                         }
515                         A = EXTRACT_LONG(&pd[k-headersize]);
516                         
517                         continue;
518                         
519                 case BPF_LD|BPF_H|BPF_ABS:
520                         k = pc->k;
521                         if (k + sizeof(short) > buflen) {
522                                 return 0;
523                         }
524                         
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);
529                         }
530                         A = EXTRACT_SHORT(&pd[k-headersize]);
531                         
532                         continue;
533
534                 case BPF_LD|BPF_B|BPF_ABS:
535                         k = pc->k;
536                         if ((int)k >= (int)buflen) {
537                                 return 0;
538                         }
539
540                         if(k<headersize) A = p[k];
541                          else A = pd[k-headersize];
542
543                         continue;
544
545                 case BPF_LD|BPF_W|BPF_LEN:
546                         A = wirelen;
547                         continue;
548
549                 case BPF_LDX|BPF_W|BPF_LEN:
550                         X = wirelen;
551                         continue;
552
553                 case BPF_LD|BPF_W|BPF_IND:
554                         k = X + pc->k;
555                         if (k + sizeof(int32) > buflen) {
556                                 return 0;
557                         }
558
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);
565                         }
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);
571                         }
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);
577                         }
578                         A = EXTRACT_LONG(&pd[k-headersize]);
579                         
580                         continue;
581                         
582                 case BPF_LD|BPF_H|BPF_IND:
583                         k = X + pc->k;
584                         if (k + sizeof(short) > buflen) {
585                                 return 0;
586                         }
587                         
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);
592                         }
593                         A = EXTRACT_SHORT(&pd[k-headersize]);
594
595                         continue;
596
597                 case BPF_LD|BPF_B|BPF_IND:
598                         k = X + pc->k;
599                         if ((int)k >= (int)buflen) {
600                                 return 0;
601                         }
602
603                         if(k<headersize) A = p[k];
604                          else A = pd[k-headersize];
605
606                         continue;
607
608                 case BPF_LDX|BPF_MSH|BPF_B:
609                         k = pc->k;
610                         if ((int)k >= (int)buflen) {
611                                 return 0;
612                         }
613                         
614                         if((pc->k)<headersize) X = (p[pc->k] & 0xf) << 2;
615                          else X = (pd[(pc->k)-headersize] & 0xf) << 2;
616
617                         continue;
618
619                 case BPF_LD|BPF_IMM:
620                         A = pc->k;
621                         continue;
622
623                 case BPF_LDX|BPF_IMM:
624                         X = pc->k;
625                         continue;
626
627                 case BPF_LD|BPF_MEM:
628                         A = mem[pc->k];
629                         continue;
630                         
631                 case BPF_LDX|BPF_MEM:
632                         X = mem[pc->k];
633                         continue;
634
635 /* LD NO PACKET INSTRUCTIONS */
636
637                 case BPF_LD|BPF_MEM_EX_IMM|BPF_B:
638                         A= mem_ex->buffer[pc->k];
639                         continue;
640
641                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_B:
642                         X= mem_ex->buffer[pc->k];
643                         continue;
644
645                 case BPF_LD|BPF_MEM_EX_IMM|BPF_H:
646                         A = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
647                         continue;
648
649                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_H:
650                         X = EXTRACT_SHORT(&mem_ex->buffer[pc->k]);
651                         continue;
652
653                 case BPF_LD|BPF_MEM_EX_IMM|BPF_W:
654                         A = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
655                         continue;
656
657                 case BPF_LDX|BPF_MEM_EX_IMM|BPF_W:
658                         X = EXTRACT_LONG(&mem_ex->buffer[pc->k]);
659                         continue;
660                         
661                 case BPF_LD|BPF_MEM_EX_IND|BPF_B:
662                         k = X + pc->k;
663                         if ((int32)k>= (int32)mem_ex->size) {
664                                 return 0;
665                         }
666                         A= mem_ex->buffer[k];
667                         continue;
668
669                 case BPF_LD|BPF_MEM_EX_IND|BPF_H:
670                         k = X + pc->k;
671                         if ((int32)(k+1)>= (int32)mem_ex->size) {
672                                 return 0;
673                         }
674                         A=EXTRACT_SHORT((uint32*)&mem_ex->buffer[k]);
675                         continue;
676
677                 case BPF_LD|BPF_MEM_EX_IND|BPF_W:
678                         k = X + pc->k;
679                         if ((int32)(k+3)>= (int32)mem_ex->size) {
680                                 return 0;
681                         }
682                         A=EXTRACT_LONG((uint32*)&mem_ex->buffer[k]);
683                         continue;
684 /* END LD NO PACKET INSTRUCTIONS */
685                 
686                 case BPF_ST:
687                         mem[pc->k] = A;
688                         continue;
689
690                 case BPF_STX:
691                         mem[pc->k] = X;
692                         continue;
693
694
695 /* STORE INSTRUCTIONS */
696                 case BPF_ST|BPF_MEM_EX_IMM|BPF_B:
697                         mem_ex->buffer[pc->k]=(uint8)A;
698                         continue;
699
700                 case BPF_STX|BPF_MEM_EX_IMM|BPF_B:
701                         mem_ex->buffer[pc->k]=(uint8)X;
702                         continue;
703
704                 case BPF_ST|BPF_MEM_EX_IMM|BPF_W:
705                         tmp=A;
706                         *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
707                         continue;
708
709                 case BPF_STX|BPF_MEM_EX_IMM|BPF_W:
710                         tmp=X;
711                         *(uint32*)&(mem_ex->buffer[pc->k])=EXTRACT_LONG(&tmp);
712                         continue;
713
714                 case BPF_ST|BPF_MEM_EX_IMM|BPF_H:
715                         tmp2=(uint16)A;
716                         *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
717                         continue;
718
719                 case BPF_STX|BPF_MEM_EX_IMM|BPF_H:
720                         tmp2=(uint16)X;
721                         *(uint16*)&mem_ex->buffer[pc->k]=EXTRACT_SHORT(&tmp2);
722                         continue;
723
724                 case BPF_ST|BPF_MEM_EX_IND|BPF_B:
725                         mem_ex->buffer[pc->k+X]=(uint8)A;
726
727                 case BPF_ST|BPF_MEM_EX_IND|BPF_W:
728                         tmp=A;
729                         *(uint32*)&mem_ex->buffer[pc->k+X]=EXTRACT_LONG(&tmp);
730                         continue;
731
732                 case BPF_ST|BPF_MEM_EX_IND|BPF_H:
733                         tmp2=(uint16)A;
734                         *(uint16*)&mem_ex->buffer[pc->k+X]=EXTRACT_SHORT(&tmp2);
735                         continue;
736 /* END STORE INSTRUCTIONS */
737                 
738                 
739                 
740                 case BPF_JMP|BPF_JA:
741                         pc += pc->k;
742                         continue;
743
744                 case BPF_JMP|BPF_JGT|BPF_K:
745                         pc += ((int)A > (int)pc->k) ? pc->jt : pc->jf;
746                         continue;
747
748                 case BPF_JMP|BPF_JGE|BPF_K:
749                         pc += ((int)A >= (int)pc->k) ? pc->jt : pc->jf;
750                         continue;
751
752                 case BPF_JMP|BPF_JEQ|BPF_K:
753                         pc += ((int)A == (int)pc->k) ? pc->jt : pc->jf;
754                         continue;
755
756                 case BPF_JMP|BPF_JSET|BPF_K:
757                         pc += (A & pc->k) ? pc->jt : pc->jf;
758                         continue;
759
760                 case BPF_JMP|BPF_JGT|BPF_X:
761                         pc += (A > X) ? pc->jt : pc->jf;
762                         continue;
763
764                 case BPF_JMP|BPF_JGE|BPF_X:
765                         pc += (A >= X) ? pc->jt : pc->jf;
766                         continue;
767
768                 case BPF_JMP|BPF_JEQ|BPF_X:
769                         pc += (A == X) ? pc->jt : pc->jf;
770                         continue;
771
772                 case BPF_JMP|BPF_JSET|BPF_X:
773                         pc += (A & X) ? pc->jt : pc->jf;
774                         continue;
775
776                 case BPF_ALU|BPF_ADD|BPF_X:
777                         A += X;
778                         continue;
779                         
780                 case BPF_ALU|BPF_SUB|BPF_X:
781                         A -= X;
782                         continue;
783                         
784                 case BPF_ALU|BPF_MUL|BPF_X:
785                         A *= X;
786                         continue;
787                         
788                 case BPF_ALU|BPF_DIV|BPF_X:
789                         if (X == 0)
790                                 return 0;
791                         A /= X;
792                         continue;
793                         
794                 case BPF_ALU|BPF_AND|BPF_X:
795                         A &= X;
796                         continue;
797                         
798                 case BPF_ALU|BPF_OR|BPF_X:
799                         A |= X;
800                         continue;
801
802                 case BPF_ALU|BPF_LSH|BPF_X:
803                         A <<= X;
804                         continue;
805
806                 case BPF_ALU|BPF_RSH|BPF_X:
807                         A >>= X;
808                         continue;
809
810                 case BPF_ALU|BPF_ADD|BPF_K:
811                         A += pc->k;
812                         continue;
813                         
814                 case BPF_ALU|BPF_SUB|BPF_K:
815                         A -= pc->k;
816                         continue;
817                         
818                 case BPF_ALU|BPF_MUL|BPF_K:
819                         A *= pc->k;
820                         continue;
821                         
822                 case BPF_ALU|BPF_DIV|BPF_K:
823                         A /= pc->k;
824                         continue;
825                         
826                 case BPF_ALU|BPF_AND|BPF_K:
827                         A &= pc->k;
828                         continue;
829                         
830                 case BPF_ALU|BPF_OR|BPF_K:
831                         A |= pc->k;
832                         continue;
833
834                 case BPF_ALU|BPF_LSH|BPF_K:
835                         A <<= pc->k;
836                         continue;
837
838                 case BPF_ALU|BPF_RSH|BPF_K:
839                         A >>= pc->k;
840                         continue;
841
842                 case BPF_ALU|BPF_NEG:
843                         (int)A = -((int)A);
844                         continue;
845
846                 case BPF_MISC|BPF_TAX:
847                         X = A;
848                         continue;
849
850                 case BPF_MISC|BPF_TXA:
851                         A = X;
852                         continue;
853
854 /* TME INSTRUCTIONS */
855                 case BPF_MISC|BPF_TME|BPF_LOOKUP:
856                         j=lookup_frontend(mem_ex,tme,pc->k,time_ref);
857                         if (j==TME_ERROR)
858                                 return 0;       
859                         pc += (j == TME_TRUE) ? pc->jt : pc->jf;
860                         continue;
861
862                 case BPF_MISC|BPF_TME|BPF_EXECUTE:
863                         if (execute_frontend(mem_ex,tme,wirelen,pc->k)==TME_ERROR)
864                                 return 0;
865                         continue;
866
867                 case BPF_MISC|BPF_TME|BPF_SET_ACTIVE:
868                         if (set_active_tme_block(tme,pc->k)==TME_ERROR)
869                                 return 0;
870                         continue;
871
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)
874                                 return 0;
875                         A=j;
876                         continue;
877
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)
880                                 return 0;
881                         continue;
882 /* END TME INSTRUCTIONS */
883
884                 }
885         }
886 }
887
888 int32
889 bpf_validate(f, len,mem_ex_size)
890         struct bpf_insn *f;
891         int32 len;
892         uint32 mem_ex_size;     
893 {
894         register int32 i,j;
895         register struct bpf_insn *p;
896         int32 flag;
897                 
898         for (i = 0; i < len; ++i) {
899                 /*
900                  * Check that that jumps are forward, and within 
901                  * the code block.
902                  */
903                 
904                 p = &f[i];
905
906                 IF_LOUD(DbgPrint("Validating program");)
907                 
908                 flag=0;
909                 for(j=0;j<VALID_INSTRUCTIONS_LEN;j++)
910                         if (p->code==valid_instructions[j])
911                                 flag=1;
912                 if (flag==0)
913                         return 0;
914
915                 IF_LOUD(DbgPrint("Validating program: no unknown instructions");)
916                 
917                 if (BPF_CLASS(p->code) == BPF_JMP) {
918                         register int32 from = i + 1;
919
920                         if (BPF_OP(p->code) == BPF_JA) {
921                                 if (from + p->k >= len)
922                                         return 0;
923                         }
924                         else if (from + p->jt >= len || from + p->jf >= len)
925                                 return 0;
926                 }
927
928                 IF_LOUD(DbgPrint("Validating program: no wrong JUMPS");)
929         
930                 /*
931                  * Check that memory operations use valid addresses.
932                  */
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))
937                         return 0;
938                 
939                 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD memory locations");)
940                         
941                 /*
942                  * Check if key stores use valid addresses 
943                  */ 
944                 if (BPF_CLASS(p->code) == BPF_ST && (p->code &BPF_MEM_EX_IMM)==BPF_MEM_EX_IMM)
945             switch (BPF_SIZE(p->code))
946                 {
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;
950                 }
951
952                 IF_LOUD(DbgPrint("Validating program: no wrong ST/LD mem_ex locations");)
953
954                 /*
955                  * Check for constant division by 0.
956                  */
957                 if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
958                         return 0;
959         }
960         return BPF_CLASS(f[len - 1].code) == BPF_RET;
961 }
962