/*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 * 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. * * @(#)bpf.c 7.5 (Berkeley) 7/15/91 */ #define union struct #include "sys/param.h" #include "sys/types.h" #include "sys/time.h" #include "bpf.h" extern void abort(); #define int32 bpf_int32 #define u_int32 bpf_u_int32 #define EXTRACT_SHORT(p)\ ((u_short)\ ((u_short)*((u_char *)p+0)<<8|\ (u_short)*((u_char *)p+1)<<0)) #define EXTRACT_LONG(p)\ ((u_int32)*((u_char *)p+0)<<24|\ (u_int32)*((u_char *)p+1)<<16|\ (u_int32)*((u_char *)p+2)<<8|\ (u_int32)*((u_char *)p+3)<<0) #define ISCODE(X) (pc->code == (X)) u_int32 bpf_A = 0, X = 0; int k; int32 mem[BPF_MEMWORDS]; extern int foobared(); /* * Execute the filter program starting at pc on the packet p * wirelen is the length of the original packet * buflen is the amount of data present */ u_int _bpf_filter (struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) { int done = 0; u_int r = 0; if (pc == 0) /* * No filter means accept all. */ return (u_int)-1; do { if(ISCODE(BPF_RET|BPF_K)) { r = (u_int)pc->k; done = 1; } else if(ISCODE(BPF_RET|BPF_A)) { r = (u_int)bpf_A; done = 1; } else if(ISCODE(BPF_LD|BPF_W|BPF_ABS)) { k = pc->k; if (k + sizeof(int32) > buflen) { return(0); } bpf_A = EXTRACT_LONG(&p[k]); } else if(ISCODE(BPF_LD|BPF_H|BPF_ABS)) { k = pc->k; if (k + sizeof(short) > buflen) { return(0); } bpf_A = EXTRACT_SHORT(&p[k]); } else if(ISCODE(BPF_LD|BPF_B|BPF_ABS)) { k = pc->k; if (k >= buflen) { return(0); } bpf_A = p[k]; } else if(ISCODE(BPF_LD|BPF_W|BPF_LEN)) { bpf_A = wirelen; } else if(ISCODE(BPF_LDX|BPF_W|BPF_LEN)) { X = wirelen; } else if(ISCODE(BPF_LD|BPF_W|BPF_IND)) { k = X + pc->k; if (k + sizeof(int32) > buflen) { return(0); } bpf_A = EXTRACT_LONG(&p[k]); } else if(ISCODE(BPF_LD|BPF_H|BPF_IND)) { k = X + pc->k; if (k + sizeof(short) > buflen) { return(0); } bpf_A = EXTRACT_SHORT(&p[k]); } else if(ISCODE(BPF_LD|BPF_B|BPF_IND)) { k = X + pc->k; if (k >= buflen) { return(0); } bpf_A = p[k]; } else if(ISCODE(BPF_LDX|BPF_MSH|BPF_B)) { k = pc->k; if (k >= buflen) { return(0); } else X = (p[pc->k] & 0xf) << 2; } else if(ISCODE(BPF_LD|BPF_IMM)) { bpf_A = pc->k; } else if(ISCODE(BPF_LDX|BPF_IMM)) { X = pc->k; } else if(ISCODE(BPF_LD|BPF_MEM)) { bpf_A = mem[pc->k]; } else if(ISCODE(BPF_LDX|BPF_MEM)) { X = mem[pc->k]; } else if(ISCODE(BPF_ST)) { mem[pc->k] = bpf_A; } else if(ISCODE(BPF_STX)) { mem[pc->k] = X; } else if(ISCODE(BPF_JMP|BPF_JA)) { r = _bpf_filter (pc + pc->k + 1,p,wirelen,buflen); done = 1; done = 1; } else if(ISCODE(BPF_JMP|BPF_JGT|BPF_K)) { if(bpf_A > pc->k) { r = _bpf_filter(pc + pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc + pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JGE|BPF_K)) { if(bpf_A >= pc->k) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JEQ|BPF_K)) { if(bpf_A == pc->k) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JSET|BPF_K)) { if(bpf_A & pc->k) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JGT|BPF_X)) { if(bpf_A > X) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JGE|BPF_X)) { if(bpf_A >= X) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JEQ|BPF_X)) { if(bpf_A == X) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_JMP|BPF_JSET|BPF_X)) { if(bpf_A & X) { r = _bpf_filter(pc +pc->jt + 1,p,wirelen,buflen); } else { r = _bpf_filter(pc +pc->jf + 1,p,wirelen,buflen); } /* else */ done = 1; } else if(ISCODE(BPF_ALU|BPF_ADD|BPF_X)) { bpf_A += X; } else if(ISCODE(BPF_ALU|BPF_SUB|BPF_X)) { bpf_A -= X; } else if(ISCODE(BPF_ALU|BPF_MUL|BPF_X)) { bpf_A *= X; } else if(ISCODE(BPF_ALU|BPF_DIV|BPF_X)) { if (X == 0) { return(0); } bpf_A /= X; } else if(ISCODE(BPF_ALU|BPF_AND|BPF_X)) { bpf_A &= X; } else if(ISCODE(BPF_ALU|BPF_OR|BPF_X)) { bpf_A |= X; } else if(ISCODE(BPF_ALU|BPF_LSH|BPF_X)) { bpf_A <<= X; } else if(ISCODE(BPF_ALU|BPF_RSH|BPF_X)) { bpf_A >>= X; } else if(ISCODE(BPF_ALU|BPF_ADD|BPF_K)) { bpf_A += pc->k; } else if(ISCODE(BPF_ALU|BPF_SUB|BPF_K)) { bpf_A -= pc->k; } else if(ISCODE(BPF_ALU|BPF_MUL|BPF_K)) { bpf_A *= pc->k; } else if(ISCODE(BPF_ALU|BPF_DIV|BPF_K)) { bpf_A /= pc->k; } else if(ISCODE(BPF_ALU|BPF_AND|BPF_K)) { bpf_A &= pc->k; } else if(ISCODE(BPF_ALU|BPF_OR|BPF_K)) { bpf_A |= pc->k; } else if(ISCODE(BPF_ALU|BPF_LSH|BPF_K)) { bpf_A <<= pc->k; } else if(ISCODE(BPF_ALU|BPF_RSH|BPF_K)) { bpf_A >>= pc->k; } else if(ISCODE(BPF_ALU|BPF_NEG)) { bpf_A = -bpf_A; } else if(ISCODE(BPF_MISC|BPF_TAX)) { X = bpf_A; } else if(ISCODE(BPF_MISC|BPF_TXA)) { bpf_A = X; } else { abort(); } /* else */ pc++; } while (! done); /* while */ return(r); } /* bpf_filter */ /* Filtre de recherche des adresses IP : Source : 131.254.50.11 = 0x83.FE.32.12 */ static struct bpf_insn dummy_program[] = {{BPF_LD|BPF_H|BPF_ABS , 0, 0, 14}, /* A <-P[14:2] */ {BPF_JMP|BPF_JEQ|BPF_K , 0, 1, 0x320B}, /* pc+=(A==3212)?0:3 */ {BPF_RET|BPF_K , 0, 0, 1}, /* RET 1 */ {BPF_RET|BPF_K , 0, 0, 0} /* RET 0 */ }; u_int top(u_char *p, u_int wirelen, u_int buflen) { return _bpf_filter(dummy_program,p,wirelen,buflen); }