1 /* $OpenBSD: bpf_image.c,v 1.9 2004/01/27 06:58:02 tedu Exp $ */
2
3 /*
4 * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #include <sys/types.h>
25 #include <sys/time.h>
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "pcap-int.h"
31
32 #ifdef HAVE_OS_PROTO_H
33 #include "os-proto.h"
34 #endif
35
36 char *
bpf_image(p,n)37 bpf_image(p, n)
38 struct bpf_insn *p;
39 int n;
40 {
41 int v;
42 char *fmt, *op;
43 static char image[256];
44 char operand[64];
45
46 v = p->k;
47 switch (p->code) {
48
49 default:
50 op = "unimp";
51 fmt = "0x%x";
52 v = p->code;
53 break;
54
55 case BPF_RET|BPF_K:
56 op = "ret";
57 fmt = "#%d";
58 break;
59
60 case BPF_RET|BPF_A:
61 op = "ret";
62 fmt = "";
63 break;
64
65 case BPF_LD|BPF_W|BPF_ABS:
66 op = "ld";
67 fmt = "[%d]";
68 break;
69
70 case BPF_LD|BPF_H|BPF_ABS:
71 op = "ldh";
72 fmt = "[%d]";
73 break;
74
75 case BPF_LD|BPF_B|BPF_ABS:
76 op = "ldb";
77 fmt = "[%d]";
78 break;
79
80 case BPF_LD|BPF_W|BPF_LEN:
81 op = "ld";
82 fmt = "#pktlen";
83 break;
84
85 case BPF_LD|BPF_W|BPF_IND:
86 op = "ld";
87 fmt = "[x + %d]";
88 break;
89
90 case BPF_LD|BPF_H|BPF_IND:
91 op = "ldh";
92 fmt = "[x + %d]";
93 break;
94
95 case BPF_LD|BPF_B|BPF_IND:
96 op = "ldb";
97 fmt = "[x + %d]";
98 break;
99
100 case BPF_LD|BPF_IMM:
101 op = "ld";
102 fmt = "#0x%x";
103 break;
104
105 case BPF_LDX|BPF_IMM:
106 op = "ldx";
107 fmt = "#0x%x";
108 break;
109
110 case BPF_LDX|BPF_MSH|BPF_B:
111 op = "ldxb";
112 fmt = "4*([%d]&0xf)";
113 break;
114
115 case BPF_LD|BPF_MEM:
116 op = "ld";
117 fmt = "M[%d]";
118 break;
119
120 case BPF_LDX|BPF_MEM:
121 op = "ldx";
122 fmt = "M[%d]";
123 break;
124
125 case BPF_ST:
126 op = "st";
127 fmt = "M[%d]";
128 break;
129
130 case BPF_STX:
131 op = "stx";
132 fmt = "M[%d]";
133 break;
134
135 case BPF_JMP|BPF_JA:
136 op = "ja";
137 fmt = "%d";
138 v = n + 1 + p->k;
139 break;
140
141 case BPF_JMP|BPF_JGT|BPF_K:
142 op = "jgt";
143 fmt = "#0x%x";
144 break;
145
146 case BPF_JMP|BPF_JGE|BPF_K:
147 op = "jge";
148 fmt = "#0x%x";
149 break;
150
151 case BPF_JMP|BPF_JEQ|BPF_K:
152 op = "jeq";
153 fmt = "#0x%x";
154 break;
155
156 case BPF_JMP|BPF_JSET|BPF_K:
157 op = "jset";
158 fmt = "#0x%x";
159 break;
160
161 case BPF_JMP|BPF_JGT|BPF_X:
162 op = "jgt";
163 fmt = "x";
164 break;
165
166 case BPF_JMP|BPF_JGE|BPF_X:
167 op = "jge";
168 fmt = "x";
169 break;
170
171 case BPF_JMP|BPF_JEQ|BPF_X:
172 op = "jeq";
173 fmt = "x";
174 break;
175
176 case BPF_JMP|BPF_JSET|BPF_X:
177 op = "jset";
178 fmt = "x";
179 break;
180
181 case BPF_ALU|BPF_ADD|BPF_X:
182 op = "add";
183 fmt = "x";
184 break;
185
186 case BPF_ALU|BPF_SUB|BPF_X:
187 op = "sub";
188 fmt = "x";
189 break;
190
191 case BPF_ALU|BPF_MUL|BPF_X:
192 op = "mul";
193 fmt = "x";
194 break;
195
196 case BPF_ALU|BPF_DIV|BPF_X:
197 op = "div";
198 fmt = "x";
199 break;
200
201 case BPF_ALU|BPF_AND|BPF_X:
202 op = "and";
203 fmt = "x";
204 break;
205
206 case BPF_ALU|BPF_OR|BPF_X:
207 op = "or";
208 fmt = "x";
209 break;
210
211 case BPF_ALU|BPF_LSH|BPF_X:
212 op = "lsh";
213 fmt = "x";
214 break;
215
216 case BPF_ALU|BPF_RSH|BPF_X:
217 op = "rsh";
218 fmt = "x";
219 break;
220
221 case BPF_ALU|BPF_ADD|BPF_K:
222 op = "add";
223 fmt = "#%d";
224 break;
225
226 case BPF_ALU|BPF_SUB|BPF_K:
227 op = "sub";
228 fmt = "#%d";
229 break;
230
231 case BPF_ALU|BPF_MUL|BPF_K:
232 op = "mul";
233 fmt = "#%d";
234 break;
235
236 case BPF_ALU|BPF_DIV|BPF_K:
237 op = "div";
238 fmt = "#%d";
239 break;
240
241 case BPF_ALU|BPF_AND|BPF_K:
242 op = "and";
243 fmt = "#0x%x";
244 break;
245
246 case BPF_ALU|BPF_OR|BPF_K:
247 op = "or";
248 fmt = "#0x%x";
249 break;
250
251 case BPF_ALU|BPF_LSH|BPF_K:
252 op = "lsh";
253 fmt = "#%d";
254 break;
255
256 case BPF_ALU|BPF_RSH|BPF_K:
257 op = "rsh";
258 fmt = "#%d";
259 break;
260
261 case BPF_ALU|BPF_NEG:
262 op = "neg";
263 fmt = "";
264 break;
265
266 case BPF_MISC|BPF_TAX:
267 op = "tax";
268 fmt = "";
269 break;
270
271 case BPF_MISC|BPF_TXA:
272 op = "txa";
273 fmt = "";
274 break;
275 }
276 (void)snprintf(operand, sizeof operand, fmt, v);
277 (void)snprintf(image, sizeof image,
278 (BPF_CLASS(p->code) == BPF_JMP &&
279 BPF_OP(p->code) != BPF_JA) ?
280 "(%03d) %-8s %-16s jt %d\tjf %d"
281 : "(%03d) %-8s %s",
282 n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
283 return image;
284 }
285