libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

bpf_image.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
3  * The Regents of the University of California. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include <pcap-types.h>
27 
28 #include <stdio.h>
29 #include <string.h>
30 
31 #ifdef __linux__
32 #include <linux/types.h>
33 #include <linux/if_packet.h>
34 #include <linux/filter.h>
35 
36 /*
37  * We want our versions of these #defines, not Linux's version.
38  * (The two should be the same; if not, we have a problem; all BPF
39  * implementations *should* be source-compatible supersets of ours.)
40  */
41 #undef BPF_STMT
42 #undef BPF_JUMP
43 #endif
44 
45 #include "pcap-int.h"
46 
47 #ifdef HAVE_OS_PROTO_H
48 #include "os-proto.h"
49 #endif
50 
51 #ifdef SKF_AD_OFF
52 /*
53  * Symbolic names for offsets that refer to the special Linux BPF locations.
54  */
55 static const char *offsets[SKF_AD_MAX] = {
56 #ifdef SKF_AD_PROTOCOL
57  [SKF_AD_PROTOCOL] = "proto",
58 #endif
59 #ifdef SKF_AD_PKTTYPE
60  [SKF_AD_PKTTYPE] = "type",
61 #endif
62 #ifdef SKF_AD_IFINDEX
63  [SKF_AD_IFINDEX] = "ifidx",
64 #endif
65 #ifdef SKF_AD_NLATTR
66  [SKF_AD_NLATTR] = "nla",
67 #endif
68 #ifdef SKF_AD_NLATTR_NEST
69  [SKF_AD_NLATTR_NEST] = "nlan",
70 #endif
71 #ifdef SKF_AD_MARK
72  [SKF_AD_MARK] = "mark",
73 #endif
74 #ifdef SKF_AD_QUEUE
75  [SKF_AD_QUEUE] = "queue",
76 #endif
77 #ifdef SKF_AD_HATYPE
78  [SKF_AD_HATYPE] = "hatype",
79 #endif
80 #ifdef SKF_AD_RXHASH
81  [SKF_AD_RXHASH] = "rxhash",
82 #endif
83 #ifdef SKF_AD_CPU
84  [SKF_AD_CPU] = "cpu",
85 #endif
86 #ifdef SKF_AD_ALU_XOR_X
87  [SKF_AD_ALU_XOR_X] = "xor_x",
88 #endif
89 #ifdef SKF_AD_VLAN_TAG
90  [SKF_AD_VLAN_TAG] = "vlan_tci",
91 #endif
92 #ifdef SKF_AD_VLAN_TAG_PRESENT
93  [SKF_AD_VLAN_TAG_PRESENT] = "vlanp",
94 #endif
95 #ifdef SKF_AD_PAY_OFFSET
96  [SKF_AD_PAY_OFFSET] = "poff",
97 #endif
98 #ifdef SKF_AD_RANDOM
99  [SKF_AD_RANDOM] = "random",
100 #endif
101 #ifdef SKF_AD_VLAN_TPID
102  [SKF_AD_VLAN_TPID] = "vlan_tpid"
103 #endif
104 };
105 #endif
106 
107 static void
108 bpf_print_abs_load_operand(char *buf, size_t bufsize, const struct bpf_insn *p)
109 {
110 #ifdef SKF_AD_OFF
111  const char *sym;
112 
113  /*
114  * It's an absolute load.
115  * Is the offset a special Linux offset that we know about?
116  */
117  if (p->k >= (bpf_u_int32)SKF_AD_OFF &&
118  p->k < (bpf_u_int32)(SKF_AD_OFF + SKF_AD_MAX) &&
119  (sym = offsets[p->k - (bpf_u_int32)SKF_AD_OFF]) != NULL) {
120  /*
121  * Yes. Print the offset symbolically.
122  */
123  (void)snprintf(buf, bufsize, "[%s]", sym);
124  } else
125 #endif
126  (void)snprintf(buf, bufsize, "[%d]", p->k);
127 }
128 
129 char *
130 bpf_image(const struct bpf_insn *p, int n)
131 {
132  const char *op;
133  static char image[256];
134  char operand_buf[64];
135  const char *operand;
136 
137  switch (p->code) {
138 
139  default:
140  op = "unimp";
141  (void)snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code);
142  operand = operand_buf;
143  break;
144 
145  case BPF_RET|BPF_K:
146  op = "ret";
147  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
148  operand = operand_buf;
149  break;
150 
151  case BPF_RET|BPF_A:
152  op = "ret";
153  operand = "";
154  break;
155 
156  case BPF_LD|BPF_W|BPF_ABS:
157  op = "ld";
158  bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
159  operand = operand_buf;
160  break;
161 
162  case BPF_LD|BPF_H|BPF_ABS:
163  op = "ldh";
164  bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
165  operand = operand_buf;
166  break;
167 
168  case BPF_LD|BPF_B|BPF_ABS:
169  op = "ldb";
170  bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
171  operand = operand_buf;
172  break;
173 
174  case BPF_LD|BPF_W|BPF_LEN:
175  op = "ld";
176  operand = "#pktlen";
177  break;
178 
179  case BPF_LD|BPF_W|BPF_IND:
180  op = "ld";
181  (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
182  operand = operand_buf;
183  break;
184 
185  case BPF_LD|BPF_H|BPF_IND:
186  op = "ldh";
187  (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
188  operand = operand_buf;
189  break;
190 
191  case BPF_LD|BPF_B|BPF_IND:
192  op = "ldb";
193  (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
194  operand = operand_buf;
195  break;
196 
197  case BPF_LD|BPF_IMM:
198  op = "ld";
199  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
200  operand = operand_buf;
201  break;
202 
203  case BPF_LDX|BPF_IMM:
204  op = "ldx";
205  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
206  operand = operand_buf;
207  break;
208 
209  case BPF_LDX|BPF_MSH|BPF_B:
210  op = "ldxb";
211  (void)snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k);
212  operand = operand_buf;
213  break;
214 
215  case BPF_LD|BPF_MEM:
216  op = "ld";
217  (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
218  operand = operand_buf;
219  break;
220 
221  case BPF_LDX|BPF_MEM:
222  op = "ldx";
223  (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
224  operand = operand_buf;
225  break;
226 
227  case BPF_ST:
228  op = "st";
229  (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
230  operand = operand_buf;
231  break;
232 
233  case BPF_STX:
234  op = "stx";
235  (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
236  operand = operand_buf;
237  break;
238 
239  case BPF_JMP|BPF_JA:
240  op = "ja";
241  (void)snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k);
242  operand = operand_buf;
243  break;
244 
245  case BPF_JMP|BPF_JGT|BPF_K:
246  op = "jgt";
247  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
248  operand = operand_buf;
249  break;
250 
251  case BPF_JMP|BPF_JGE|BPF_K:
252  op = "jge";
253  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
254  operand = operand_buf;
255  break;
256 
257  case BPF_JMP|BPF_JEQ|BPF_K:
258  op = "jeq";
259  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
260  operand = operand_buf;
261  break;
262 
263  case BPF_JMP|BPF_JSET|BPF_K:
264  op = "jset";
265  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
266  operand = operand_buf;
267  break;
268 
269  case BPF_JMP|BPF_JGT|BPF_X:
270  op = "jgt";
271  operand = "x";
272  break;
273 
274  case BPF_JMP|BPF_JGE|BPF_X:
275  op = "jge";
276  operand = "x";
277  break;
278 
279  case BPF_JMP|BPF_JEQ|BPF_X:
280  op = "jeq";
281  operand = "x";
282  break;
283 
284  case BPF_JMP|BPF_JSET|BPF_X:
285  op = "jset";
286  operand = "x";
287  break;
288 
289  case BPF_ALU|BPF_ADD|BPF_X:
290  op = "add";
291  operand = "x";
292  break;
293 
294  case BPF_ALU|BPF_SUB|BPF_X:
295  op = "sub";
296  operand = "x";
297  break;
298 
299  case BPF_ALU|BPF_MUL|BPF_X:
300  op = "mul";
301  operand = "x";
302  break;
303 
304  case BPF_ALU|BPF_DIV|BPF_X:
305  op = "div";
306  operand = "x";
307  break;
308 
309  case BPF_ALU|BPF_MOD|BPF_X:
310  op = "mod";
311  operand = "x";
312  break;
313 
314  case BPF_ALU|BPF_AND|BPF_X:
315  op = "and";
316  operand = "x";
317  break;
318 
319  case BPF_ALU|BPF_OR|BPF_X:
320  op = "or";
321  operand = "x";
322  break;
323 
324  case BPF_ALU|BPF_XOR|BPF_X:
325  op = "xor";
326  operand = "x";
327  break;
328 
329  case BPF_ALU|BPF_LSH|BPF_X:
330  op = "lsh";
331  operand = "x";
332  break;
333 
334  case BPF_ALU|BPF_RSH|BPF_X:
335  op = "rsh";
336  operand = "x";
337  break;
338 
339  case BPF_ALU|BPF_ADD|BPF_K:
340  op = "add";
341  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
342  operand = operand_buf;
343  break;
344 
345  case BPF_ALU|BPF_SUB|BPF_K:
346  op = "sub";
347  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
348  operand = operand_buf;
349  break;
350 
351  case BPF_ALU|BPF_MUL|BPF_K:
352  op = "mul";
353  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
354  operand = operand_buf;
355  break;
356 
357  case BPF_ALU|BPF_DIV|BPF_K:
358  op = "div";
359  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
360  operand = operand_buf;
361  break;
362 
363  case BPF_ALU|BPF_MOD|BPF_K:
364  op = "mod";
365  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
366  operand = operand_buf;
367  break;
368 
369  case BPF_ALU|BPF_AND|BPF_K:
370  op = "and";
371  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
372  operand = operand_buf;
373  break;
374 
375  case BPF_ALU|BPF_OR|BPF_K:
376  op = "or";
377  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
378  operand = operand_buf;
379  break;
380 
381  case BPF_ALU|BPF_XOR|BPF_K:
382  op = "xor";
383  (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
384  operand = operand_buf;
385  break;
386 
387  case BPF_ALU|BPF_LSH|BPF_K:
388  op = "lsh";
389  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
390  operand = operand_buf;
391  break;
392 
393  case BPF_ALU|BPF_RSH|BPF_K:
394  op = "rsh";
395  (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
396  operand = operand_buf;
397  break;
398 
399  case BPF_ALU|BPF_NEG:
400  op = "neg";
401  operand = "";
402  break;
403 
404  case BPF_MISC|BPF_TAX:
405  op = "tax";
406  operand = "";
407  break;
408 
409  case BPF_MISC|BPF_TXA:
410  op = "txa";
411  operand = "";
412  break;
413  }
414  if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
415  (void)snprintf(image, sizeof image,
416  "(%03d) %-8s %-16s jt %d\tjf %d",
417  n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
418  } else {
419  (void)snprintf(image, sizeof image,
420  "(%03d) %-8s %s",
421  n, op, operand);
422  }
423  return image;
424 }
#define BPF_IND
Definition: bpf.h:155
#define BPF_STX
Definition: bpf.h:140
#define BPF_MOD
Definition: bpf.h:173
#define BPF_ST
Definition: bpf.h:139
#define BPF_JSET
Definition: bpf.h:185
#define BPF_OR
Definition: bpf.h:168
#define BPF_RSH
Definition: bpf.h:171
#define BPF_LD
Definition: bpf.h:137
#define BPF_TXA
Definition: bpf.h:225
u_int bpf_u_int32
Definition: bpf.h:98
#define BPF_XOR
Definition: bpf.h:174
#define BPF_IMM
Definition: bpf.h:153
#define BPF_NEG
Definition: bpf.h:172
#define BPF_OP(code)
Definition: bpf.h:163
#define BPF_JA
Definition: bpf.h:181
#define BPF_JGE
Definition: bpf.h:184
#define BPF_MEM
Definition: bpf.h:156
#define BPF_LSH
Definition: bpf.h:170
#define BPF_W
Definition: bpf.h:148
#define BPF_CLASS(code)
Definition: bpf.h:136
#define BPF_X
Definition: bpf.h:199
#define BPF_B
Definition: bpf.h:150
#define BPF_ADD
Definition: bpf.h:164
#define BPF_TAX
Definition: bpf.h:208
#define BPF_JGT
Definition: bpf.h:183
#define BPF_H
Definition: bpf.h:149
#define BPF_MISC
Definition: bpf.h:144
#define BPF_LEN
Definition: bpf.h:157
#define BPF_ALU
Definition: bpf.h:141
#define BPF_ABS
Definition: bpf.h:154
#define BPF_MSH
Definition: bpf.h:158
#define BPF_DIV
Definition: bpf.h:167
#define BPF_A
Definition: bpf.h:203
#define BPF_JMP
Definition: bpf.h:142
#define BPF_MUL
Definition: bpf.h:166
#define BPF_AND
Definition: bpf.h:169
#define BPF_LDX
Definition: bpf.h:138
#define BPF_SUB
Definition: bpf.h:165
#define BPF_JEQ
Definition: bpf.h:182
char * bpf_image(const struct bpf_insn *p, int n)
Definition: bpf_image.c:130
static void bpf_print_abs_load_operand(char *buf, size_t bufsize, const struct bpf_insn *p)
Definition: bpf_image.c:108
int snprintf(char *, size_t, const char *,...)
#define BPF_K
Definition: pcap-npf.c:53
#define BPF_RET
Definition: pcap-npf.c:52
Definition: bpf.h:245
bpf_u_int32 k
Definition: bpf.h:249
u_short code
Definition: bpf.h:246
u_char jf
Definition: bpf.h:248
u_char jt
Definition: bpf.h:247