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