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