xref: /openbsd/lib/libpcap/bpf_image.c (revision 7b36286a)
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 *
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