1335640Shselasky/* 2335640Shselasky * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996 3335640Shselasky * The Regents of the University of California. All rights reserved. 4335640Shselasky * 5335640Shselasky * Redistribution and use in source and binary forms, with or without 6335640Shselasky * modification, are permitted provided that: (1) source code distributions 7335640Shselasky * retain the above copyright notice and this paragraph in its entirety, (2) 8335640Shselasky * distributions including binary code include the above copyright notice and 9335640Shselasky * this paragraph in its entirety in the documentation or other materials 10335640Shselasky * provided with the distribution, and (3) all advertising materials mentioning 11335640Shselasky * features or use of this software display the following acknowledgement: 12335640Shselasky * ``This product includes software developed by the University of California, 13335640Shselasky * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14335640Shselasky * the University nor the names of its contributors may be used to endorse 15335640Shselasky * or promote products derived from this software without specific prior 16335640Shselasky * written permission. 17335640Shselasky * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18335640Shselasky * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19335640Shselasky * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20335640Shselasky */ 21335640Shselasky 22335640Shselasky#ifdef HAVE_CONFIG_H 23335640Shselasky#include <config.h> 24335640Shselasky#endif 25335640Shselasky 26335640Shselasky#include <pcap-types.h> 27335640Shselasky 28335640Shselasky#include <stdio.h> 29335640Shselasky#include <string.h> 30335640Shselasky 31335640Shselasky#include "pcap-int.h" 32335640Shselasky 33335640Shselasky#ifdef HAVE_OS_PROTO_H 34335640Shselasky#include "os-proto.h" 35335640Shselasky#endif 36335640Shselasky 37335640Shselaskychar * 38335640Shselaskybpf_image(const struct bpf_insn *p, int n) 39335640Shselasky{ 40335640Shselasky const char *op; 41335640Shselasky static char image[256]; 42335640Shselasky char operand_buf[64]; 43335640Shselasky const char *operand; 44335640Shselasky 45335640Shselasky switch (p->code) { 46335640Shselasky 47335640Shselasky default: 48335640Shselasky op = "unimp"; 49335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "0x%x", p->code); 50335640Shselasky operand = operand_buf; 51335640Shselasky break; 52335640Shselasky 53335640Shselasky case BPF_RET|BPF_K: 54335640Shselasky op = "ret"; 55335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 56335640Shselasky operand = operand_buf; 57335640Shselasky break; 58335640Shselasky 59335640Shselasky case BPF_RET|BPF_A: 60335640Shselasky op = "ret"; 61335640Shselasky operand = ""; 62335640Shselasky break; 63335640Shselasky 64335640Shselasky case BPF_LD|BPF_W|BPF_ABS: 65335640Shselasky op = "ld"; 66335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 67335640Shselasky operand = operand_buf; 68335640Shselasky break; 69335640Shselasky 70335640Shselasky case BPF_LD|BPF_H|BPF_ABS: 71335640Shselasky op = "ldh"; 72335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 73335640Shselasky operand = operand_buf; 74335640Shselasky break; 75335640Shselasky 76335640Shselasky case BPF_LD|BPF_B|BPF_ABS: 77335640Shselasky op = "ldb"; 78335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[%d]", p->k); 79335640Shselasky operand = operand_buf; 80335640Shselasky break; 81335640Shselasky 82335640Shselasky case BPF_LD|BPF_W|BPF_LEN: 83335640Shselasky op = "ld"; 84335640Shselasky operand = "#pktlen"; 85335640Shselasky break; 86335640Shselasky 87335640Shselasky case BPF_LD|BPF_W|BPF_IND: 88335640Shselasky op = "ld"; 89335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 90335640Shselasky operand = operand_buf; 91335640Shselasky break; 92335640Shselasky 93335640Shselasky case BPF_LD|BPF_H|BPF_IND: 94335640Shselasky op = "ldh"; 95335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 96335640Shselasky operand = operand_buf; 97335640Shselasky break; 98335640Shselasky 99335640Shselasky case BPF_LD|BPF_B|BPF_IND: 100335640Shselasky op = "ldb"; 101335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "[x + %d]", p->k); 102335640Shselasky operand = operand_buf; 103335640Shselasky break; 104335640Shselasky 105335640Shselasky case BPF_LD|BPF_IMM: 106335640Shselasky op = "ld"; 107335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 108335640Shselasky operand = operand_buf; 109335640Shselasky break; 110335640Shselasky 111335640Shselasky case BPF_LDX|BPF_IMM: 112335640Shselasky op = "ldx"; 113335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 114335640Shselasky operand = operand_buf; 115335640Shselasky break; 116335640Shselasky 117335640Shselasky case BPF_LDX|BPF_MSH|BPF_B: 118335640Shselasky op = "ldxb"; 119335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "4*([%d]&0xf)", p->k); 120335640Shselasky operand = operand_buf; 121335640Shselasky break; 122335640Shselasky 123335640Shselasky case BPF_LD|BPF_MEM: 124335640Shselasky op = "ld"; 125335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 126335640Shselasky operand = operand_buf; 127335640Shselasky break; 128335640Shselasky 129335640Shselasky case BPF_LDX|BPF_MEM: 130335640Shselasky op = "ldx"; 131335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 132335640Shselasky operand = operand_buf; 133335640Shselasky break; 134335640Shselasky 135335640Shselasky case BPF_ST: 136335640Shselasky op = "st"; 137335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 138335640Shselasky operand = operand_buf; 139335640Shselasky break; 140335640Shselasky 141335640Shselasky case BPF_STX: 142335640Shselasky op = "stx"; 143335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "M[%d]", p->k); 144335640Shselasky operand = operand_buf; 145335640Shselasky break; 146335640Shselasky 147335640Shselasky case BPF_JMP|BPF_JA: 148335640Shselasky op = "ja"; 149335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "%d", n + 1 + p->k); 150335640Shselasky operand = operand_buf; 151335640Shselasky break; 152335640Shselasky 153335640Shselasky case BPF_JMP|BPF_JGT|BPF_K: 154335640Shselasky op = "jgt"; 155335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 156335640Shselasky operand = operand_buf; 157335640Shselasky break; 158335640Shselasky 159335640Shselasky case BPF_JMP|BPF_JGE|BPF_K: 160335640Shselasky op = "jge"; 161335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 162335640Shselasky operand = operand_buf; 163335640Shselasky break; 164335640Shselasky 165335640Shselasky case BPF_JMP|BPF_JEQ|BPF_K: 166335640Shselasky op = "jeq"; 167335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 168335640Shselasky operand = operand_buf; 169335640Shselasky break; 170335640Shselasky 171335640Shselasky case BPF_JMP|BPF_JSET|BPF_K: 172335640Shselasky op = "jset"; 173335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 174335640Shselasky operand = operand_buf; 175335640Shselasky break; 176335640Shselasky 177335640Shselasky case BPF_JMP|BPF_JGT|BPF_X: 178335640Shselasky op = "jgt"; 179335640Shselasky operand = "x"; 180335640Shselasky break; 181335640Shselasky 182335640Shselasky case BPF_JMP|BPF_JGE|BPF_X: 183335640Shselasky op = "jge"; 184335640Shselasky operand = "x"; 185335640Shselasky break; 186335640Shselasky 187335640Shselasky case BPF_JMP|BPF_JEQ|BPF_X: 188335640Shselasky op = "jeq"; 189335640Shselasky operand = "x"; 190335640Shselasky break; 191335640Shselasky 192335640Shselasky case BPF_JMP|BPF_JSET|BPF_X: 193335640Shselasky op = "jset"; 194335640Shselasky operand = "x"; 195335640Shselasky break; 196335640Shselasky 197335640Shselasky case BPF_ALU|BPF_ADD|BPF_X: 198335640Shselasky op = "add"; 199335640Shselasky operand = "x"; 200335640Shselasky break; 201335640Shselasky 202335640Shselasky case BPF_ALU|BPF_SUB|BPF_X: 203335640Shselasky op = "sub"; 204335640Shselasky operand = "x"; 205335640Shselasky break; 206335640Shselasky 207335640Shselasky case BPF_ALU|BPF_MUL|BPF_X: 208335640Shselasky op = "mul"; 209335640Shselasky operand = "x"; 210335640Shselasky break; 211335640Shselasky 212335640Shselasky case BPF_ALU|BPF_DIV|BPF_X: 213335640Shselasky op = "div"; 214335640Shselasky operand = "x"; 215335640Shselasky break; 216335640Shselasky 217335640Shselasky case BPF_ALU|BPF_MOD|BPF_X: 218335640Shselasky op = "mod"; 219335640Shselasky operand = "x"; 220335640Shselasky break; 221335640Shselasky 222335640Shselasky case BPF_ALU|BPF_AND|BPF_X: 223335640Shselasky op = "and"; 224335640Shselasky operand = "x"; 225335640Shselasky break; 226335640Shselasky 227335640Shselasky case BPF_ALU|BPF_OR|BPF_X: 228335640Shselasky op = "or"; 229335640Shselasky operand = "x"; 230335640Shselasky break; 231335640Shselasky 232335640Shselasky case BPF_ALU|BPF_XOR|BPF_X: 233335640Shselasky op = "xor"; 234335640Shselasky operand = "x"; 235335640Shselasky break; 236335640Shselasky 237335640Shselasky case BPF_ALU|BPF_LSH|BPF_X: 238335640Shselasky op = "lsh"; 239335640Shselasky operand = "x"; 240335640Shselasky break; 241335640Shselasky 242335640Shselasky case BPF_ALU|BPF_RSH|BPF_X: 243335640Shselasky op = "rsh"; 244335640Shselasky operand = "x"; 245335640Shselasky break; 246335640Shselasky 247335640Shselasky case BPF_ALU|BPF_ADD|BPF_K: 248335640Shselasky op = "add"; 249335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 250335640Shselasky operand = operand_buf; 251335640Shselasky break; 252335640Shselasky 253335640Shselasky case BPF_ALU|BPF_SUB|BPF_K: 254335640Shselasky op = "sub"; 255335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 256335640Shselasky operand = operand_buf; 257335640Shselasky break; 258335640Shselasky 259335640Shselasky case BPF_ALU|BPF_MUL|BPF_K: 260335640Shselasky op = "mul"; 261335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 262335640Shselasky operand = operand_buf; 263335640Shselasky break; 264335640Shselasky 265335640Shselasky case BPF_ALU|BPF_DIV|BPF_K: 266335640Shselasky op = "div"; 267335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 268335640Shselasky operand = operand_buf; 269335640Shselasky break; 270335640Shselasky 271335640Shselasky case BPF_ALU|BPF_MOD|BPF_K: 272335640Shselasky op = "mod"; 273335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 274335640Shselasky operand = operand_buf; 275335640Shselasky break; 276335640Shselasky 277335640Shselasky case BPF_ALU|BPF_AND|BPF_K: 278335640Shselasky op = "and"; 279335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 280335640Shselasky operand = operand_buf; 281335640Shselasky break; 282335640Shselasky 283335640Shselasky case BPF_ALU|BPF_OR|BPF_K: 284335640Shselasky op = "or"; 285335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 286335640Shselasky operand = operand_buf; 287335640Shselasky break; 288335640Shselasky 289335640Shselasky case BPF_ALU|BPF_XOR|BPF_K: 290335640Shselasky op = "xor"; 291335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#0x%x", p->k); 292335640Shselasky operand = operand_buf; 293335640Shselasky break; 294335640Shselasky 295335640Shselasky case BPF_ALU|BPF_LSH|BPF_K: 296335640Shselasky op = "lsh"; 297335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 298335640Shselasky operand = operand_buf; 299335640Shselasky break; 300335640Shselasky 301335640Shselasky case BPF_ALU|BPF_RSH|BPF_K: 302335640Shselasky op = "rsh"; 303335640Shselasky (void)pcap_snprintf(operand_buf, sizeof operand_buf, "#%d", p->k); 304335640Shselasky operand = operand_buf; 305335640Shselasky break; 306335640Shselasky 307335640Shselasky case BPF_ALU|BPF_NEG: 308335640Shselasky op = "neg"; 309335640Shselasky operand = ""; 310335640Shselasky break; 311335640Shselasky 312335640Shselasky case BPF_MISC|BPF_TAX: 313335640Shselasky op = "tax"; 314335640Shselasky operand = ""; 315335640Shselasky break; 316335640Shselasky 317335640Shselasky case BPF_MISC|BPF_TXA: 318335640Shselasky op = "txa"; 319335640Shselasky operand = ""; 320335640Shselasky break; 321335640Shselasky } 322335640Shselasky if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) { 323335640Shselasky (void)pcap_snprintf(image, sizeof image, 324335640Shselasky "(%03d) %-8s %-16s jt %d\tjf %d", 325335640Shselasky n, op, operand, n + 1 + p->jt, n + 1 + p->jf); 326335640Shselasky } else { 327335640Shselasky (void)pcap_snprintf(image, sizeof image, 328335640Shselasky "(%03d) %-8s %s", 329335640Shselasky n, op, operand); 330335640Shselasky } 331335640Shselasky return image; 332335640Shselasky} 333