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