X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fnet%2Fnpf%2Fwin_bpf_filter_init.c;fp=drivers%2Fnet%2Fnpf%2Fwin_bpf_filter_init.c;h=51fb5d458ba4fe9e335823d189990e37253cd849;hp=0000000000000000000000000000000000000000;hb=e3ed2d773259cc445c7ff8181ebd934931365328;hpb=d378c68f5a9bb25c9e671dacd482d2e25d211df3 diff --git a/drivers/net/npf/win_bpf_filter_init.c b/drivers/net/npf/win_bpf_filter_init.c new file mode 100644 index 0000000..51fb5d4 --- /dev/null +++ b/drivers/net/npf/win_bpf_filter_init.c @@ -0,0 +1,689 @@ +/* + * Copyright (c) 2001 + * Politecnico di Torino. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the Politecnico + * di Torino, and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * + * Portions copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from the Stanford/CMU enet packet filter, + * (net/enet.c) distributed as part of 4.3BSD, and code contributed + * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence + * Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "tme.h" +#include "win_bpf.h" + +/* + * Initialize the filter machine + */ +uint32 bpf_filter_init(register struct bpf_insn *pc, MEM_TYPE *mem_ex, TME_CORE *tme, struct time_conv *time_ref) +{ + register uint32 A, X; + int32 mem[BPF_MEMWORDS]; + register int32 k; + uint32 *tmp; + uint16 *tmp2; + uint32 j; + if (pc == 0) + /* + * No filter means accept all. + */ + return (uint32)-1; + A = 0; + X = 0; + --pc; + while (1) { + ++pc; + switch (pc->code) { + + default: + return 0; + +/* RET INSTRUCTIONS */ + case BPF_RET|BPF_K: + return (uint32)pc->k; + + case BPF_RET|BPF_A: + return (uint32)A; +/* END RET INSTRUCTIONS */ + +/* LD NO PACKET INSTRUCTIONS */ + case BPF_LD|BPF_IMM: + A = pc->k; + continue; + + case BPF_LDX|BPF_IMM: + X = pc->k; + continue; + + case BPF_LD|BPF_MEM: + A = mem[pc->k]; + continue; + + case BPF_LDX|BPF_MEM: + X = mem[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_B: + A= mem_ex->buffer[pc->k]; + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_B: + X= mem_ex->buffer[pc->k]; + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_LDX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov X, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_B: + k = X + pc->k; + if ((int32)k>= (int32)mem_ex->size) { + return 0; + } + A= mem_ex->buffer[k]; + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_H: + k = X + pc->k; + if ((int32)(k+1)>= (int32)mem_ex->size) { + return 0; + } + tmp2=(uint16*)&mem_ex->buffer[k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp2 + xor eax, eax + mov ax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_LD|BPF_MEM_EX_IND|BPF_W: + k = X + pc->k; + if ((int32)(k+3)>= (int32)mem_ex->size) { + return 0; + } + tmp=(uint32*)&mem_ex->buffer[k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx,tmp + mov eax, [ebx] + bswap eax + mov A, eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; +/* END LD NO PACKET INSTRUCTIONS */ + +/* STORE INSTRUCTIONS */ + case BPF_ST: + mem[pc->k] = A; + continue; + + case BPF_STX: + mem[pc->k] = X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)A; + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_B: + mem_ex->buffer[pc->k]=(uint8)X; + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, X + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; + + case BPF_STX|BPF_MEM_EX_IMM|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, X + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(X),"=c"(tmp2): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_B: + mem_ex->buffer[pc->k+X]=(uint8)A; + + case BPF_ST|BPF_MEM_EX_IND|BPF_W: + tmp=(uint32*)&mem_ex->buffer[pc->k+X]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp + mov eax, A + bswap eax + mov [ebx], eax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp): ); +#endif + continue; + + case BPF_ST|BPF_MEM_EX_IND|BPF_H: + tmp2=(uint16*)&mem_ex->buffer[pc->k+X]; +#ifndef __GNUC__ + __asm + { + push eax + push ebx + mov ebx, tmp2 + mov eax, A + xchg ah, al + mov [ebx], ax + pop ebx + pop eax + } +#else + asm("push %%eax;" + "push %%ebx;" + "mov %1,%%ebx;" + "xor %%eax, %%eax;" + "mov (%%ebx), %%ax;" + "bswap %%eax;" + "mov %%eax, %0;" + "pop %%ebx;" + "pop %%eax;" + :"=a"(A),"=c"(tmp2): ); +#endif + continue; +/* END STORE INSTRUCTIONS */ + +/* JUMP INSTRUCTIONS */ + case BPF_JMP|BPF_JA: + pc += pc->k; + continue; + + case BPF_JMP|BPF_JGT|BPF_K: + pc += ((int32)A > (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_K: + pc += ((int32)A >= (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_K: + pc += ((int32)A == (int32)pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_K: + pc += (A & pc->k) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGT|BPF_X: + pc += (A > X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JGE|BPF_X: + pc += (A >= X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JEQ|BPF_X: + pc += (A == X) ? pc->jt : pc->jf; + continue; + + case BPF_JMP|BPF_JSET|BPF_X: + pc += (A & X) ? pc->jt : pc->jf; + continue; +/* END JUMP INSTRUCTIONS */ + +/* ARITHMETIC INSTRUCTIONS */ + case BPF_ALU|BPF_ADD|BPF_X: + A += X; + continue; + + case BPF_ALU|BPF_SUB|BPF_X: + A -= X; + continue; + + case BPF_ALU|BPF_MUL|BPF_X: + A *= X; + continue; + + case BPF_ALU|BPF_DIV|BPF_X: + if (X == 0) + return 0; + A /= X; + continue; + + case BPF_ALU|BPF_AND|BPF_X: + A &= X; + continue; + + case BPF_ALU|BPF_OR|BPF_X: + A |= X; + continue; + + case BPF_ALU|BPF_LSH|BPF_X: + A <<= X; + continue; + + case BPF_ALU|BPF_RSH|BPF_X: + A >>= X; + continue; + + case BPF_ALU|BPF_ADD|BPF_K: + A += pc->k; + continue; + + case BPF_ALU|BPF_SUB|BPF_K: + A -= pc->k; + continue; + + case BPF_ALU|BPF_MUL|BPF_K: + A *= pc->k; + continue; + + case BPF_ALU|BPF_DIV|BPF_K: + A /= pc->k; + continue; + + case BPF_ALU|BPF_AND|BPF_K: + A &= pc->k; + continue; + + case BPF_ALU|BPF_OR|BPF_K: + A |= pc->k; + continue; + + case BPF_ALU|BPF_LSH|BPF_K: + A <<= pc->k; + continue; + + case BPF_ALU|BPF_RSH|BPF_K: + A >>= pc->k; + continue; + + case BPF_ALU|BPF_NEG: + (int32)A = -((int32)A); + continue; +/* ARITHMETIC INSTRUCTIONS */ + +/* MISC INSTRUCTIONS */ + case BPF_MISC|BPF_TAX: + X = A; + continue; + + case BPF_MISC|BPF_TXA: + A = X; + continue; +/* END MISC INSTRUCTIONS */ + +/* TME INSTRUCTIONS */ + case BPF_MISC|BPF_TME|BPF_LOOKUP: + j=lookup_frontend(mem_ex,tme,pc->k,time_ref); + if (j==TME_ERROR) + return 0; + pc += (j == TME_TRUE) ? pc->jt : pc->jf; + continue; + + case BPF_MISC|BPF_TME|BPF_EXECUTE: + if (execute_frontend(mem_ex,tme,0,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_INIT: + if (init_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_VALIDATE: + if (validate_tme_block(mem_ex,tme,A,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_MEMORY: + if (init_extended_memory(pc->k,mem_ex)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_ACTIVE_READ: + if (set_active_tme_block(tme,pc->k)==TME_ERROR) + return 0; + continue; + case BPF_MISC|BPF_TME|BPF_SET_WORKING: + if ((pc->k<0)||(pc->k>=MAX_TME_DATA_BLOCKS)) + return 0; + tme->working=pc->k; + continue; + + + + case BPF_MISC|BPF_TME|BPF_RESET: + if (reset_tme(tme)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_GET_REGISTER_VALUE: + if (get_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,&j)==TME_ERROR) + return 0; + A=j; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_REGISTER_VALUE: + if (set_tme_block_register(&tme->block_data[tme->working],mem_ex,pc->k,A,TRUE)==TME_ERROR) + return 0; + continue; + + case BPF_MISC|BPF_TME|BPF_SET_AUTODELETION: + set_autodeletion(&tme->block_data[tme->working],pc->k); + continue; + +/* END TME INSTRUCTIONS */ + + } + } +} +