2 * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
3 * The Regents of the University of California. All rights reserved.
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
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.
26 #include <pcap-types.h>
32 #include <linux/types.h>
33 #include <linux/if_packet.h>
34 #include <linux/filter.h>
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.)
47 #ifdef HAVE_OS_PROTO_H
53 * Symbolic names for offsets that refer to the special Linux BPF locations.
55 static const char *offsets[SKF_AD_MAX] = {
56 #ifdef SKF_AD_PROTOCOL
57 [SKF_AD_PROTOCOL] = "proto",
60 [SKF_AD_PKTTYPE] = "type",
63 [SKF_AD_IFINDEX] = "ifidx",
66 [SKF_AD_NLATTR] = "nla",
68 #ifdef SKF_AD_NLATTR_NEST
69 [SKF_AD_NLATTR_NEST] = "nlan",
72 [SKF_AD_MARK] = "mark",
75 [SKF_AD_QUEUE] = "queue",
78 [SKF_AD_HATYPE] = "hatype",
81 [SKF_AD_RXHASH] = "rxhash",
86 #ifdef SKF_AD_ALU_XOR_X
87 [SKF_AD_ALU_XOR_X] = "xor_x",
89 #ifdef SKF_AD_VLAN_TAG
90 [SKF_AD_VLAN_TAG] = "vlan_tci",
92 #ifdef SKF_AD_VLAN_TAG_PRESENT
93 [SKF_AD_VLAN_TAG_PRESENT] = "vlanp",
95 #ifdef SKF_AD_PAY_OFFSET
96 [SKF_AD_PAY_OFFSET] = "poff",
99 [SKF_AD_RANDOM] = "random",
101 #ifdef SKF_AD_VLAN_TPID
102 [SKF_AD_VLAN_TPID] = "vlan_tpid"
108 bpf_print_abs_load_operand(char *buf, size_t bufsize, const struct bpf_insn *p)
114 * It's an absolute load.
115 * Is the offset a special Linux offset that we know about?
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) {
121 * Yes. Print the offset symbolically.
123 (void)snprintf(buf, bufsize, "[%s]", sym);
126 (void)snprintf(buf, bufsize, "[%d]", p->k);
130 bpf_image(const struct bpf_insn *p, int n)
133 static char image[256];
134 char operand_buf[64];
141 (void)snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code);
142 operand = operand_buf;
147 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
148 operand = operand_buf;
156 case BPF_LD|BPF_W|BPF_ABS:
158 bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
159 operand = operand_buf;
162 case BPF_LD|BPF_H|BPF_ABS:
164 bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
165 operand = operand_buf;
168 case BPF_LD|BPF_B|BPF_ABS:
170 bpf_print_abs_load_operand(operand_buf, sizeof operand_buf, p);
171 operand = operand_buf;
174 case BPF_LD|BPF_W|BPF_LEN:
179 case BPF_LD|BPF_W|BPF_IND:
181 (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
182 operand = operand_buf;
185 case BPF_LD|BPF_H|BPF_IND:
187 (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
188 operand = operand_buf;
191 case BPF_LD|BPF_B|BPF_IND:
193 (void)snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k);
194 operand = operand_buf;
199 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
200 operand = operand_buf;
203 case BPF_LDX|BPF_IMM:
205 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
206 operand = operand_buf;
209 case BPF_LDX|BPF_MSH|BPF_B:
211 (void)snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k);
212 operand = operand_buf;
217 (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
218 operand = operand_buf;
221 case BPF_LDX|BPF_MEM:
223 (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
224 operand = operand_buf;
229 (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
230 operand = operand_buf;
235 (void)snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k);
236 operand = operand_buf;
241 (void)snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k);
242 operand = operand_buf;
245 case BPF_JMP|BPF_JGT|BPF_K:
247 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
248 operand = operand_buf;
251 case BPF_JMP|BPF_JGE|BPF_K:
253 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
254 operand = operand_buf;
257 case BPF_JMP|BPF_JEQ|BPF_K:
259 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
260 operand = operand_buf;
263 case BPF_JMP|BPF_JSET|BPF_K:
265 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
266 operand = operand_buf;
269 case BPF_JMP|BPF_JGT|BPF_X:
274 case BPF_JMP|BPF_JGE|BPF_X:
279 case BPF_JMP|BPF_JEQ|BPF_X:
284 case BPF_JMP|BPF_JSET|BPF_X:
289 case BPF_ALU|BPF_ADD|BPF_X:
294 case BPF_ALU|BPF_SUB|BPF_X:
299 case BPF_ALU|BPF_MUL|BPF_X:
304 case BPF_ALU|BPF_DIV|BPF_X:
309 case BPF_ALU|BPF_MOD|BPF_X:
314 case BPF_ALU|BPF_AND|BPF_X:
319 case BPF_ALU|BPF_OR|BPF_X:
324 case BPF_ALU|BPF_XOR|BPF_X:
329 case BPF_ALU|BPF_LSH|BPF_X:
334 case BPF_ALU|BPF_RSH|BPF_X:
339 case BPF_ALU|BPF_ADD|BPF_K:
341 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
342 operand = operand_buf;
345 case BPF_ALU|BPF_SUB|BPF_K:
347 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
348 operand = operand_buf;
351 case BPF_ALU|BPF_MUL|BPF_K:
353 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
354 operand = operand_buf;
357 case BPF_ALU|BPF_DIV|BPF_K:
359 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
360 operand = operand_buf;
363 case BPF_ALU|BPF_MOD|BPF_K:
365 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
366 operand = operand_buf;
369 case BPF_ALU|BPF_AND|BPF_K:
371 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
372 operand = operand_buf;
375 case BPF_ALU|BPF_OR|BPF_K:
377 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
378 operand = operand_buf;
381 case BPF_ALU|BPF_XOR|BPF_K:
383 (void)snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k);
384 operand = operand_buf;
387 case BPF_ALU|BPF_LSH|BPF_K:
389 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
390 operand = operand_buf;
393 case BPF_ALU|BPF_RSH|BPF_K:
395 (void)snprintf(operand_buf, sizeof operand_buf, "#%d", p->k);
396 operand = operand_buf;
399 case BPF_ALU|BPF_NEG:
404 case BPF_MISC|BPF_TAX:
409 case BPF_MISC|BPF_TXA:
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);
419 (void)snprintf(image, sizeof image,