]> git.ozlabs.org Git - ppp.git/blob - pppd/bpf_filter.c
change upap to pap in debug messages
[ppp.git] / pppd / bpf_filter.c
1 /*      $Id: bpf_filter.c,v 1.1 1996/04/04 04:22:23 paulus Exp $        */
2 /*      From: NetBSD: bpf_filter.c,v 1.11 1995/04/22 13:26:39 cgd Exp $ */
3
4 /*
5  * Copyright (c) 1990, 1991, 1992, 1993
6  *      The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from the Stanford/CMU enet packet filter,
9  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
10  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
11  * Berkeley Laboratory.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *      This product includes software developed by the University of
24  *      California, Berkeley and its contributors.
25  * 4. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  *      @(#)bpf_filter.c        8.1 (Berkeley) 6/10/93
42  */
43
44 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <net/ppp_defs.h>
48
49 #if !defined(i386) && !defined(m68k)
50 #define BPF_ALIGN
51 #endif
52
53 /* XXX we assume ints are 32 bits, shorts are 16 bits. */
54
55 #ifndef BPF_ALIGN
56 #define EXTRACT_SHORT(p)        ((unsigned short)ntohs(*(unsigned short *)p))
57 #define EXTRACT_LONG(p)         (ntohl(*(u_int32_t *)p))
58 #else
59 #define EXTRACT_SHORT(p)\
60         ((unsigned short)\
61                 ((unsigned short)*((u_char *)p+0)<<8|\
62                  (unsigned short)*((u_char *)p+1)<<0))
63 #define EXTRACT_LONG(p)\
64                 ((u_int32_t)*((u_char *)p+0)<<24|\
65                  (u_int32_t)*((u_char *)p+1)<<16|\
66                  (u_int32_t)*((u_char *)p+2)<<8|\
67                  (u_int32_t)*((u_char *)p+3)<<0)
68 #endif
69
70 #include <net/bpf.h>
71
72 /*
73  * Execute the filter program starting at pc on the packet p
74  * wirelen is the length of the original packet
75  * buflen is the amount of data present
76  */
77 u_int
78 bpf_filter(pc, p, wirelen, buflen)
79         register struct bpf_insn *pc;
80         register u_char *p;
81         u_int wirelen;
82         register u_int buflen;
83 {
84         register u_int32_t A, X;
85         register int k;
86         int mem[BPF_MEMWORDS];
87
88         if (pc == 0)
89                 /*
90                  * No filter means accept all.
91                  */
92                 return (u_int)-1;
93 #ifdef lint
94         A = 0;
95         X = 0;
96 #endif
97         --pc;
98         while (1) {
99                 ++pc;
100                 switch (pc->code) {
101
102                 default:
103                         return 0;       /* gak! */
104
105                 case BPF_RET|BPF_K:
106                         return (u_int)pc->k;
107
108                 case BPF_RET|BPF_A:
109                         return (u_int)A;
110
111                 case BPF_LD|BPF_W|BPF_ABS:
112                         k = pc->k;
113                         if (k + sizeof(int) > buflen) {
114                                 return 0;
115                         }
116                         A = EXTRACT_LONG(&p[k]);
117                         continue;
118
119                 case BPF_LD|BPF_H|BPF_ABS:
120                         k = pc->k;
121                         if (k + sizeof(short int) > buflen) {
122                                 return 0;
123                         }
124                         A = EXTRACT_SHORT(&p[k]);
125                         continue;
126
127                 case BPF_LD|BPF_B|BPF_ABS:
128                         k = pc->k;
129                         if (k >= buflen) {
130                                 return 0;
131                         }
132                         A = p[k];
133                         continue;
134
135                 case BPF_LD|BPF_W|BPF_LEN:
136                         A = wirelen;
137                         continue;
138
139                 case BPF_LDX|BPF_W|BPF_LEN:
140                         X = wirelen;
141                         continue;
142
143                 case BPF_LD|BPF_W|BPF_IND:
144                         k = X + pc->k;
145                         if (k + sizeof(int) > buflen) {
146                                 return 0;
147                         }
148                         A = EXTRACT_LONG(&p[k]);
149                         continue;
150
151                 case BPF_LD|BPF_H|BPF_IND:
152                         k = X + pc->k;
153                         if (k + sizeof(short int) > buflen) {
154                                 return 0;
155                         }
156                         A = EXTRACT_SHORT(&p[k]);
157                         continue;
158
159                 case BPF_LD|BPF_B|BPF_IND:
160                         k = X + pc->k;
161                         if (k >= buflen) {
162                                 return 0;
163                         }
164                         A = p[k];
165                         continue;
166
167                 case BPF_LDX|BPF_MSH|BPF_B:
168                         k = pc->k;
169                         if (k >= buflen) {
170                                 return 0;
171                         }
172                         X = (p[pc->k] & 0xf) << 2;
173                         continue;
174
175                 case BPF_LD|BPF_IMM:
176                         A = pc->k;
177                         continue;
178
179                 case BPF_LDX|BPF_IMM:
180                         X = pc->k;
181                         continue;
182
183                 case BPF_LD|BPF_MEM:
184                         A = mem[pc->k];
185                         continue;
186                         
187                 case BPF_LDX|BPF_MEM:
188                         X = mem[pc->k];
189                         continue;
190
191                 case BPF_ST:
192                         mem[pc->k] = A;
193                         continue;
194
195                 case BPF_STX:
196                         mem[pc->k] = X;
197                         continue;
198
199                 case BPF_JMP|BPF_JA:
200                         pc += pc->k;
201                         continue;
202
203                 case BPF_JMP|BPF_JGT|BPF_K:
204                         pc += (A > pc->k) ? pc->jt : pc->jf;
205                         continue;
206
207                 case BPF_JMP|BPF_JGE|BPF_K:
208                         pc += (A >= pc->k) ? pc->jt : pc->jf;
209                         continue;
210
211                 case BPF_JMP|BPF_JEQ|BPF_K:
212                         pc += (A == pc->k) ? pc->jt : pc->jf;
213                         continue;
214
215                 case BPF_JMP|BPF_JSET|BPF_K:
216                         pc += (A & pc->k) ? pc->jt : pc->jf;
217                         continue;
218
219                 case BPF_JMP|BPF_JGT|BPF_X:
220                         pc += (A > X) ? pc->jt : pc->jf;
221                         continue;
222
223                 case BPF_JMP|BPF_JGE|BPF_X:
224                         pc += (A >= X) ? pc->jt : pc->jf;
225                         continue;
226
227                 case BPF_JMP|BPF_JEQ|BPF_X:
228                         pc += (A == X) ? pc->jt : pc->jf;
229                         continue;
230
231                 case BPF_JMP|BPF_JSET|BPF_X:
232                         pc += (A & X) ? pc->jt : pc->jf;
233                         continue;
234
235                 case BPF_ALU|BPF_ADD|BPF_X:
236                         A += X;
237                         continue;
238                         
239                 case BPF_ALU|BPF_SUB|BPF_X:
240                         A -= X;
241                         continue;
242                         
243                 case BPF_ALU|BPF_MUL|BPF_X:
244                         A *= X;
245                         continue;
246                         
247                 case BPF_ALU|BPF_DIV|BPF_X:
248                         if (X == 0)
249                                 return 0;
250                         A /= X;
251                         continue;
252                         
253                 case BPF_ALU|BPF_AND|BPF_X:
254                         A &= X;
255                         continue;
256                         
257                 case BPF_ALU|BPF_OR|BPF_X:
258                         A |= X;
259                         continue;
260
261                 case BPF_ALU|BPF_LSH|BPF_X:
262                         A <<= X;
263                         continue;
264
265                 case BPF_ALU|BPF_RSH|BPF_X:
266                         A >>= X;
267                         continue;
268
269                 case BPF_ALU|BPF_ADD|BPF_K:
270                         A += pc->k;
271                         continue;
272                         
273                 case BPF_ALU|BPF_SUB|BPF_K:
274                         A -= pc->k;
275                         continue;
276                         
277                 case BPF_ALU|BPF_MUL|BPF_K:
278                         A *= pc->k;
279                         continue;
280                         
281                 case BPF_ALU|BPF_DIV|BPF_K:
282                         A /= pc->k;
283                         continue;
284                         
285                 case BPF_ALU|BPF_AND|BPF_K:
286                         A &= pc->k;
287                         continue;
288                         
289                 case BPF_ALU|BPF_OR|BPF_K:
290                         A |= pc->k;
291                         continue;
292
293                 case BPF_ALU|BPF_LSH|BPF_K:
294                         A <<= pc->k;
295                         continue;
296
297                 case BPF_ALU|BPF_RSH|BPF_K:
298                         A >>= pc->k;
299                         continue;
300
301                 case BPF_ALU|BPF_NEG:
302                         A = -A;
303                         continue;
304
305                 case BPF_MISC|BPF_TAX:
306                         X = A;
307                         continue;
308
309                 case BPF_MISC|BPF_TXA:
310                         A = X;
311                         continue;
312                 }
313         }
314 }