ruger 发表于 2006-4-4 10:36:24

sk_run_filter

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;
};





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;          /* 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;
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;
179load_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;
188load_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;
234                         continue;
235               case BPF_LDX|BPF_MEM:
236                         X = mem;
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 = A;
250                         continue;
251               case BPF_STX:
252                         mem = 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这块的基本理论,都有什么函数,有什么解构~~~~~~~,启蒙一下吧~~~
页: [1]
查看完整版本: sk_run_filter