Home | History | Annotate | Download | only in libpcap
      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