Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libpcap/bpf_image.c
39475 views
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
#include <config.h>
23
24
#include <pcap-types.h>
25
26
#include <stdio.h>
27
#include <string.h>
28
29
#ifdef __linux__
30
#include <linux/types.h>
31
#include <linux/if_packet.h>
32
#include <linux/filter.h>
33
34
/*
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.)
38
*/
39
#undef BPF_STMT
40
#undef BPF_JUMP
41
#endif
42
43
#include "pcap-int.h"
44
45
#include "thread-local.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 thread_local 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
}
425
426