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 #ifdef HAVE_CONFIG_H 23 #include <config.h> 24 #endif 25 26 #include <pcap-types.h> 27 28 #include <stdio.h> 29 #include <string.h> 30 31 #include "pcap-int.h" 32 33 #ifdef HAVE_OS_PROTO_H 34 #include "os-proto.h" 35 #endif 36 37 char * 38 bpf_image(const struct bpf_insn *p, int n) 39 { 40 const char *op; 41 static char image[256]; 42 char operand_buf[64]; 43 const char *operand; 44 45 switch (p->code) { 46 47 default: 48 op = "unimp"; 49 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code); 50 operand = operand_buf; 51 break; 52 53 case BPF_RET|BPF_K: 54 op = "ret"; 55 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 56 operand = operand_buf; 57 break; 58 59 case BPF_RET|BPF_A: 60 op = "ret"; 61 operand = ""; 62 break; 63 64 case BPF_LD|BPF_W|BPF_ABS: 65 op = "ld"; 66 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 67 operand = operand_buf; 68 break; 69 70 case BPF_LD|BPF_H|BPF_ABS: 71 op = "ldh"; 72 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 73 operand = operand_buf; 74 break; 75 76 case BPF_LD|BPF_B|BPF_ABS: 77 op = "ldb"; 78 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 79 operand = operand_buf; 80 break; 81 82 case BPF_LD|BPF_W|BPF_LEN: 83 op = "ld"; 84 operand = "#pktlen"; 85 break; 86 87 case BPF_LD|BPF_W|BPF_IND: 88 op = "ld"; 89 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 90 operand = operand_buf; 91 break; 92 93 case BPF_LD|BPF_H|BPF_IND: 94 op = "ldh"; 95 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 96 operand = operand_buf; 97 break; 98 99 case BPF_LD|BPF_B|BPF_IND: 100 op = "ldb"; 101 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 102 operand = operand_buf; 103 break; 104 105 case BPF_LD|BPF_IMM: 106 op = "ld"; 107 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 108 operand = operand_buf; 109 break; 110 111 case BPF_LDX|BPF_IMM: 112 op = "ldx"; 113 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 114 operand = operand_buf; 115 break; 116 117 case BPF_LDX|BPF_MSH|BPF_B: 118 op = "ldxb"; 119 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k); 120 operand = operand_buf; 121 break; 122 123 case BPF_LD|BPF_MEM: 124 op = "ld"; 125 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 126 operand = operand_buf; 127 break; 128 129 case BPF_LDX|BPF_MEM: 130 op = "ldx"; 131 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 132 operand = operand_buf; 133 break; 134 135 case BPF_ST: 136 op = "st"; 137 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 138 operand = operand_buf; 139 break; 140 141 case BPF_STX: 142 op = "stx"; 143 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 144 operand = operand_buf; 145 break; 146 147 case BPF_JMP|BPF_JA: 148 op = "ja"; 149 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k); 150 operand = operand_buf; 151 break; 152 153 case BPF_JMP|BPF_JGT|BPF_K: 154 op = "jgt"; 155 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 156 operand = operand_buf; 157 break; 158 159 case BPF_JMP|BPF_JGE|BPF_K: 160 op = "jge"; 161 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 162 operand = operand_buf; 163 break; 164 165 case BPF_JMP|BPF_JEQ|BPF_K: 166 op = "jeq"; 167 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 168 operand = operand_buf; 169 break; 170 171 case BPF_JMP|BPF_JSET|BPF_K: 172 op = "jset"; 173 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 174 operand = operand_buf; 175 break; 176 177 case BPF_JMP|BPF_JGT|BPF_X: 178 op = "jgt"; 179 operand = "x"; 180 break; 181 182 case BPF_JMP|BPF_JGE|BPF_X: 183 op = "jge"; 184 operand = "x"; 185 break; 186 187 case BPF_JMP|BPF_JEQ|BPF_X: 188 op = "jeq"; 189 operand = "x"; 190 break; 191 192 case BPF_JMP|BPF_JSET|BPF_X: 193 op = "jset"; 194 operand = "x"; 195 break; 196 197 case BPF_ALU|BPF_ADD|BPF_X: 198 op = "add"; 199 operand = "x"; 200 break; 201 202 case BPF_ALU|BPF_SUB|BPF_X: 203 op = "sub"; 204 operand = "x"; 205 break; 206 207 case BPF_ALU|BPF_MUL|BPF_X: 208 op = "mul"; 209 operand = "x"; 210 break; 211 212 case BPF_ALU|BPF_DIV|BPF_X: 213 op = "div"; 214 operand = "x"; 215 break; 216 217 case BPF_ALU|BPF_MOD|BPF_X: 218 op = "mod"; 219 operand = "x"; 220 break; 221 222 case BPF_ALU|BPF_AND|BPF_X: 223 op = "and"; 224 operand = "x"; 225 break; 226 227 case BPF_ALU|BPF_OR|BPF_X: 228 op = "or"; 229 operand = "x"; 230 break; 231 232 case BPF_ALU|BPF_XOR|BPF_X: 233 op = "xor"; 234 operand = "x"; 235 break; 236 237 case BPF_ALU|BPF_LSH|BPF_X: 238 op = "lsh"; 239 operand = "x"; 240 break; 241 242 case BPF_ALU|BPF_RSH|BPF_X: 243 op = "rsh"; 244 operand = "x"; 245 break; 246 247 case BPF_ALU|BPF_ADD|BPF_K: 248 op = "add"; 249 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 250 operand = operand_buf; 251 break; 252 253 case BPF_ALU|BPF_SUB|BPF_K: 254 op = "sub"; 255 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 256 operand = operand_buf; 257 break; 258 259 case BPF_ALU|BPF_MUL|BPF_K: 260 op = "mul"; 261 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 262 operand = operand_buf; 263 break; 264 265 case BPF_ALU|BPF_DIV|BPF_K: 266 op = "div"; 267 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 268 operand = operand_buf; 269 break; 270 271 case BPF_ALU|BPF_MOD|BPF_K: 272 op = "mod"; 273 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 274 operand = operand_buf; 275 break; 276 277 case BPF_ALU|BPF_AND|BPF_K: 278 op = "and"; 279 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 280 operand = operand_buf; 281 break; 282 283 case BPF_ALU|BPF_OR|BPF_K: 284 op = "or"; 285 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 286 operand = operand_buf; 287 break; 288 289 case BPF_ALU|BPF_XOR|BPF_K: 290 op = "xor"; 291 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 292 operand = operand_buf; 293 break; 294 295 case BPF_ALU|BPF_LSH|BPF_K: 296 op = "lsh"; 297 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 298 operand = operand_buf; 299 break; 300 301 case BPF_ALU|BPF_RSH|BPF_K: 302 op = "rsh"; 303 (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 304 operand = operand_buf; 305 break; 306 307 case BPF_ALU|BPF_NEG: 308 op = "neg"; 309 operand = ""; 310 break; 311 312 case BPF_MISC|BPF_TAX: 313 op = "tax"; 314 operand = ""; 315 break; 316 317 case BPF_MISC|BPF_TXA: 318 op = "txa"; 319 operand = ""; 320 break; 321 } 322 if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) { 323 (void)pcap_snprintf(image, sizeof image, 324 "(%03d) %-8s %-16s jt %d\tjf %d", 325 n, op, operand, n + 1 + p->jt, n + 1 + p->jf); 326 } else { 327 (void)pcap_snprintf(image, sizeof image, 328 "(%03d) %-8s %s", 329 n, op, operand); 330 } 331 return image; 332 } 333