|
struct sock_filter /* Filter block */
{
__u16 code; /* Actual filter code */
__u8 jt; /* Jump true */
__u8 jf; /* Jump false */
__u32 k; /* Generic multiuse field */
};
struct sk_filter
{
atomic_t refcnt;
unsigned int len; /* Number of filter blocks */
struct sock_filter insns[0];
};
int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
78 {
79 struct sock_filter *fentry; /* We walk down these */
80 void *ptr;
81 u32 A = 0; /* Accumulator */
82 u32 X = 0; /* Index Register */
83 u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */
84 u32 tmp;
85 int k;
86 int pc;
87
88 /*
89 * Process array of filter instructions.
90 */
91 for (pc = 0; pc < flen; pc++) {
92 fentry = &filter[pc];
93
94 switch (fentry->code) {
95 case BPF_ALU|BPF_ADD|BPF_X:
96 A += X;
97 continue;
98 case BPF_ALU|BPF_ADD|BPF_K:
99 A += fentry->k;
100 continue;
101 case BPF_ALU|BPF_SUB|BPF_X:
102 A -= X;
103 continue;
104 case BPF_ALU|BPF_SUB|BPF_K:
105 A -= fentry->k;
106 continue;
107 case BPF_ALU|BPF_MUL|BPF_X:
108 A *= X;
109 continue;
110 case BPF_ALU|BPF_MUL|BPF_K:
111 A *= fentry->k;
112 continue;
113 case BPF_ALU|BPF_DIV|BPF_X:
114 if (X == 0)
115 return 0;
116 A /= X;
117 continue;
118 case BPF_ALU|BPF_DIV|BPF_K:
119 if (fentry->k == 0)
120 return 0;
121 A /= fentry->k;
122 continue;
123 case BPF_ALU|BPF_AND|BPF_X:
124 A &= X;
125 continue;
126 case BPF_ALU|BPF_AND|BPF_K:
127 A &= fentry->k;
128 continue;
129 case BPF_ALU|BPF_OR|BPF_X:
130 A |= X;
131 continue;
132 case BPF_ALU|BPF_OR|BPF_K:
133 A |= fentry->k;
134 continue;
135 case BPF_ALU|BPF_LSH|BPF_X:
136 A <<= X;
137 continue;
138 case BPF_ALU|BPF_LSH|BPF_K:
139 A <<= fentry->k;
140 continue;
141 case BPF_ALU|BPF_RSH|BPF_X:
142 A >>= X;
143 continue;
144 case BPF_ALU|BPF_RSH|BPF_K:
145 A >>= fentry->k;
146 continue;
147 case BPF_ALU|BPF_NEG:
148 A = -A;
149 continue;
150 case BPF_JMP|BPF_JA:
151 pc += fentry->k;
152 continue;
153 case BPF_JMP|BPF_JGT|BPF_K:
154 pc += (A > fentry->k) ? fentry->jt : fentry->jf;
155 continue;
156 case BPF_JMP|BPF_JGE|BPF_K:
157 pc += (A >= fentry->k) ? fentry->jt : fentry->jf;
158 continue;
159 case BPF_JMP|BPF_JEQ|BPF_K:
160 pc += (A == fentry->k) ? fentry->jt : fentry->jf;
161 continue;
162 case BPF_JMP|BPF_JSET|BPF_K:
163 pc += (A & fentry->k) ? fentry->jt : fentry->jf;
164 continue;
165 case BPF_JMP|BPF_JGT|BPF_X:
166 pc += (A > X) ? fentry->jt : fentry->jf;
167 continue;
168 case BPF_JMP|BPF_JGE|BPF_X:
169 pc += (A >= X) ? fentry->jt : fentry->jf;
170 continue;
171 case BPF_JMP|BPF_JEQ|BPF_X:
172 pc += (A == X) ? fentry->jt : fentry->jf;
173 continue;
174 case BPF_JMP|BPF_JSET|BPF_X:
175 pc += (A & X) ? fentry->jt : fentry->jf;
176 continue;
177 case BPF_LD|BPF_W|BPF_ABS:
178 k = fentry->k;
179 load_w:
180 ptr = load_pointer(skb, k, 4, &tmp);
181 if (ptr != NULL) {
182 A = ntohl(*(u32 *)ptr);
183 continue;
184 }
185 return 0;
186 case BPF_LD|BPF_H|BPF_ABS:
187 k = fentry->k;
188 load_h:
189 ptr = load_pointer(skb, k, 2, &tmp);
190 if (ptr != NULL) {
191 A = ntohs(*(u16 *)ptr);
192 continue;
193 }
194 return 0;
195 case BPF_LD|BPF_B|BPF_ABS:
196 k = fentry->k;
197 load_b:
198 ptr = load_pointer(skb, k, 1, &tmp);
199 if (ptr != NULL) {
200 A = *(u8 *)ptr;
201 continue;
202 }
203 return 0;
204 case BPF_LD|BPF_W|BPF_LEN:
205 A = skb->len;
206 continue;
207 case BPF_LDX|BPF_W|BPF_LEN:
208 X = skb->len;
209 continue;
210 case BPF_LD|BPF_W|BPF_IND:
211 k = X + fentry->k;
212 goto load_w;
213 case BPF_LD|BPF_H|BPF_IND:
214 k = X + fentry->k;
215 goto load_h;
216 case BPF_LD|BPF_B|BPF_IND:
217 k = X + fentry->k;
218 goto load_b;
219 case BPF_LDX|BPF_B|BPF_MSH:
220 ptr = load_pointer(skb, fentry->k, 1, &tmp);
221 if (ptr != NULL) {
222 X = (*(u8 *)ptr & 0xf) << 2;
223 continue;
224 }
225 return 0;
226 case BPF_LD|BPF_IMM:
227 A = fentry->k;
228 continue;
229 case BPF_LDX|BPF_IMM:
230 X = fentry->k;
231 continue;
232 case BPF_LD|BPF_MEM:
233 A = mem[fentry->k];
234 continue;
235 case BPF_LDX|BPF_MEM:
236 X = mem[fentry->k];
237 continue;
238 case BPF_MISC|BPF_TAX:
239 X = A;
240 continue;
241 case BPF_MISC|BPF_TXA:
242 A = X;
243 continue;
244 case BPF_RET|BPF_K:
245 return ((unsigned int)fentry->k);
246 case BPF_RET|BPF_A:
247 return ((unsigned int)A);
248 case BPF_ST:
249 mem[fentry->k] = A;
250 continue;
251 case BPF_STX:
252 mem[fentry->k] = X;
253 continue;
254 default:
255 /* Invalid instruction counts as RET */
256 return 0;
257 }
258
259 /*
260 * Handle ancillary data, which are impossible
261 * (or very difficult) to get parsing packet contents.
262 */
263 switch (k-SKF_AD_OFF) {
264 case SKF_AD_PROTOCOL:
265 A = htons(skb->protocol);
266 continue;
267 case SKF_AD_PKTTYPE:
268 A = skb->pkt_type;
269 continue;
270 case SKF_AD_IFINDEX:
271 A = skb->dev->ifindex;
272 continue;
273 default:
274 return 0;
275 }
276 }
277
278 return 0;
279 }
能帮我解释一下这个函数起什么作用吗???还有就是filter这块的基本理论,都有什么函数,有什么解构~~~~~~~,启蒙一下吧~~~ |
|