3 * The BPF engine used for offline ("display") filters in wiretap.
4 * The code is taken from the Linux Socket Filter, and only slightly
5 * modified for use in wiretap.
7 * Gilbert Ramirez <gram@verdict.uthscsa.edu>
11 * Linux Socket Filter - Kernel level socket filtering
14 * Jay Schulist <Jay.Schulist@spacs.k12.wi.us>
16 * Based on the design of:
17 * - The Berkeley Packet Filter
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version.
27 #include "bpf-engine.h"
31 * Decode and apply filter instructions to the skb->data.
32 * Return length to keep, 0 for none. skb is the data we are
33 * filtering, filter is the array of filter instructions, and
34 * len is the number of filter blocks in the array.
37 int bpf_run_filter(unsigned char *data, int len, struct bpf_instruction *filter, int flen)
39 struct bpf_instruction *fentry; /* We walk down these */
40 guint32 A = 0; /* Accumulator */
41 guint32 X = 0; /* Index Register */
42 guint32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
48 * Process array of filter instructions.
51 for(pc = 0; pc < flen; pc++)
54 if(fentry->code & BPF_X)
61 case BPF_ALU|BPF_ADD|BPF_X:
62 case BPF_ALU|BPF_ADD|BPF_K:
66 case BPF_ALU|BPF_SUB|BPF_X:
67 case BPF_ALU|BPF_SUB|BPF_K:
71 case BPF_ALU|BPF_MUL|BPF_X:
72 case BPF_ALU|BPF_MUL|BPF_K:
76 case BPF_ALU|BPF_DIV|BPF_X:
77 case BPF_ALU|BPF_DIV|BPF_K:
83 case BPF_ALU|BPF_AND|BPF_X:
84 case BPF_ALU|BPF_AND|BPF_K:
88 case BPF_ALU|BPF_OR|BPF_X:
89 case BPF_ALU|BPF_OR|BPF_K:
93 case BPF_ALU|BPF_LSH|BPF_X:
94 case BPF_ALU|BPF_LSH|BPF_K:
98 case BPF_ALU|BPF_RSH|BPF_X:
99 case BPF_ALU|BPF_RSH|BPF_K:
103 case BPF_ALU|BPF_NEG:
111 case BPF_JMP|BPF_JGT|BPF_K:
112 pc += (A > fentry->k) ? fentry->jt : fentry->jf;
115 case BPF_JMP|BPF_JGE|BPF_K:
116 pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
119 case BPF_JMP|BPF_JEQ|BPF_K:
120 pc += (A == fentry->k) ? fentry->jt : fentry->jf;
123 case BPF_JMP|BPF_JSET|BPF_K:
124 pc += (A & fentry->k) ? fentry->jt : fentry->jf;
127 case BPF_JMP|BPF_JGT|BPF_X:
128 pc += (A > X) ? fentry->jt : fentry->jf;
131 case BPF_JMP|BPF_JGE|BPF_X:
132 pc += (A >= X) ? fentry->jt : fentry->jf;
135 case BPF_JMP|BPF_JEQ|BPF_X:
136 pc += (A == X) ? fentry->jt : fentry->jf;
139 case BPF_JMP|BPF_JSET|BPF_X:
140 pc += (A & X) ? fentry->jt : fentry->jf;
142 case BPF_LD|BPF_W|BPF_ABS:
144 if(k + sizeof(long) > len)
146 A = pntohl(&data[k]);
149 case BPF_LD|BPF_H|BPF_ABS:
151 if(k + sizeof(short) > len)
153 A = pntohs(&data[k]);
156 case BPF_LD|BPF_B|BPF_ABS:
163 case BPF_LD|BPF_W|BPF_LEN:
167 case BPF_LDX|BPF_W|BPF_LEN:
171 case BPF_LD|BPF_W|BPF_IND:
173 if(k + sizeof(guint32) > len)
175 A = pntohl(&data[k]);
178 case BPF_LD|BPF_H|BPF_IND:
180 if(k + sizeof(guint16) > len)
182 A = pntohs(&data[k]);
185 case BPF_LD|BPF_B|BPF_IND:
192 case BPF_LDX|BPF_B|BPF_MSH:
194 * Hack for BPF to handle TOS etc
199 X = (data[fentry->k] & 0xf) << 2;
206 case BPF_LDX|BPF_IMM:
214 case BPF_LDX|BPF_MEM:
218 case BPF_MISC|BPF_TAX:
222 case BPF_MISC|BPF_TXA:
227 return ((unsigned int)fentry->k);
230 return ((unsigned int)A);
243 /* Invalid instruction counts as RET */
248 g_error("Filter ruleset ran off the end.\n");
253 * Check the user's filter code. If we let some ugly
254 * filter code slip through kaboom!
257 int bpf_chk_filter(struct bpf_instruction *filter, int flen)
259 struct bpf_instruction *ftest;
263 * Check the filter code now.
265 for(pc = 0; pc < flen; pc++)
268 * All jumps are forward as they are not signed
272 if(BPF_CLASS(ftest->code) == BPF_JMP)
275 * But they mustn't jump off the end.
277 if(BPF_OP(ftest->code) == BPF_JA)
279 if(pc + ftest->k + 1>= (unsigned)flen)
285 * For conditionals both must be safe
287 if(pc + ftest->jt +1 >= flen || pc + ftest->jf +1 >= flen)
293 * Check that memory operations use valid addresses.
296 if(ftest->k <0 || ftest->k >= BPF_MEMWORDS)
299 * But it might not be a memory operation...
302 if (BPF_CLASS(ftest->code) == BPF_ST)
304 if((BPF_CLASS(ftest->code) == BPF_LD) &&
305 (BPF_MODE(ftest->code) == BPF_MEM))
311 * The program must end with a return. We don't care where they
312 * jumped within the script (its always forwards) but in the
313 * end they _will_ hit this.
316 return (BPF_CLASS(filter[flen - 1].code) == BPF_RET)?0:-1;