]>
The Tcpdump Group git mirrors - libpcap/blob - bpf_image.c
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.
24 #include <pcap-types.h>
30 #include <linux/types.h>
31 #include <linux/if_packet.h>
32 #include <linux/filter.h>
35 * We want our versions of these #defines, not Linux's version.
36 * (The two should be the same; if not, we have a problem; all BPF
37 * implementations *should* be source-compatible supersets of ours.)
45 #include "thread-local.h"
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 thread_local
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
);
418 } else if (! *operand
) {
419 (void)snprintf(image
, sizeof image
,
423 (void)snprintf(image
, sizeof image
,