117683Spst/*
217683Spst * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
317683Spst *	The Regents of the University of California.  All rights reserved.
417683Spst *
517683Spst * Redistribution and use in source and binary forms, with or without
617683Spst * modification, are permitted provided that: (1) source code distributions
717683Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817683Spst * distributions including binary code include the above copyright notice and
917683Spst * this paragraph in its entirety in the documentation or other materials
1017683Spst * provided with the distribution, and (3) all advertising materials mentioning
1117683Spst * features or use of this software display the following acknowledgement:
1217683Spst * ``This product includes software developed by the University of California,
1317683Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417683Spst * the University nor the names of its contributors may be used to endorse
1517683Spst * or promote products derived from this software without specific prior
1617683Spst * written permission.
1717683Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817683Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917683Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2017683Spst */
2117683Spst
2217683Spst#ifndef lint
23127664Sbmsstatic const char rcsid[] _U_ =
24214518Srpaulo    "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.28 2008-01-02 04:16:46 guy Exp $ (LBL)";
2517683Spst#endif
2617683Spst
2775107Sfenner#ifdef HAVE_CONFIG_H
2875107Sfenner#include "config.h"
2975107Sfenner#endif
3075107Sfenner
31214518Srpaulo#ifdef WIN32
32214518Srpaulo#include <pcap-stdinc.h>
33214518Srpaulo#else /* WIN32 */
34214518Srpaulo#if HAVE_INTTYPES_H
35214518Srpaulo#include <inttypes.h>
36214518Srpaulo#elif HAVE_STDINT_H
37214518Srpaulo#include <stdint.h>
38214518Srpaulo#endif
39214518Srpaulo#ifdef HAVE_SYS_BITYPES_H
40214518Srpaulo#include <sys/bitypes.h>
41214518Srpaulo#endif
42214518Srpaulo#include <sys/types.h>
43214518Srpaulo#endif /* WIN32 */
44214518Srpaulo
4517683Spst#include <stdio.h>
4617683Spst#include <string.h>
4717683Spst
4817683Spst#include "pcap-int.h"
4917683Spst
5017683Spst#ifdef HAVE_OS_PROTO_H
5117683Spst#include "os-proto.h"
5217683Spst#endif
5317683Spst
5417683Spstchar *
5517683Spstbpf_image(p, n)
56190944Srpaulo	struct bpf_insn *p;
5717683Spst	int n;
5817683Spst{
5917683Spst	int v;
60172677Smlaier	const char *fmt, *op;
6117683Spst	static char image[256];
6217683Spst	char operand[64];
6317683Spst
6417683Spst	v = p->k;
6517683Spst	switch (p->code) {
6617683Spst
6717683Spst	default:
6817683Spst		op = "unimp";
6917683Spst		fmt = "0x%x";
7017683Spst		v = p->code;
7117683Spst		break;
7217683Spst
7317683Spst	case BPF_RET|BPF_K:
7417683Spst		op = "ret";
7517683Spst		fmt = "#%d";
7617683Spst		break;
7717683Spst
7817683Spst	case BPF_RET|BPF_A:
7917683Spst		op = "ret";
8017683Spst		fmt = "";
8117683Spst		break;
8217683Spst
8317683Spst	case BPF_LD|BPF_W|BPF_ABS:
8417683Spst		op = "ld";
8517683Spst		fmt = "[%d]";
8617683Spst		break;
8717683Spst
8817683Spst	case BPF_LD|BPF_H|BPF_ABS:
8917683Spst		op = "ldh";
9017683Spst		fmt = "[%d]";
9117683Spst		break;
9217683Spst
9317683Spst	case BPF_LD|BPF_B|BPF_ABS:
9417683Spst		op = "ldb";
9517683Spst		fmt = "[%d]";
9617683Spst		break;
9717683Spst
9817683Spst	case BPF_LD|BPF_W|BPF_LEN:
9917683Spst		op = "ld";
10017683Spst		fmt = "#pktlen";
10117683Spst		break;
10217683Spst
10317683Spst	case BPF_LD|BPF_W|BPF_IND:
10417683Spst		op = "ld";
10517683Spst		fmt = "[x + %d]";
10617683Spst		break;
10717683Spst
10817683Spst	case BPF_LD|BPF_H|BPF_IND:
10917683Spst		op = "ldh";
11017683Spst		fmt = "[x + %d]";
11117683Spst		break;
11217683Spst
11317683Spst	case BPF_LD|BPF_B|BPF_IND:
11417683Spst		op = "ldb";
11517683Spst		fmt = "[x + %d]";
11617683Spst		break;
11717683Spst
11817683Spst	case BPF_LD|BPF_IMM:
11917683Spst		op = "ld";
12017683Spst		fmt = "#0x%x";
12117683Spst		break;
12217683Spst
12317683Spst	case BPF_LDX|BPF_IMM:
12417683Spst		op = "ldx";
12517683Spst		fmt = "#0x%x";
12617683Spst		break;
12717683Spst
12817683Spst	case BPF_LDX|BPF_MSH|BPF_B:
12917683Spst		op = "ldxb";
13017683Spst		fmt = "4*([%d]&0xf)";
13117683Spst		break;
13217683Spst
13317683Spst	case BPF_LD|BPF_MEM:
13417683Spst		op = "ld";
13517683Spst		fmt = "M[%d]";
13617683Spst		break;
13717683Spst
13817683Spst	case BPF_LDX|BPF_MEM:
13917683Spst		op = "ldx";
14017683Spst		fmt = "M[%d]";
14117683Spst		break;
14217683Spst
14317683Spst	case BPF_ST:
14417683Spst		op = "st";
14517683Spst		fmt = "M[%d]";
14617683Spst		break;
14717683Spst
14817683Spst	case BPF_STX:
14917683Spst		op = "stx";
15017683Spst		fmt = "M[%d]";
15117683Spst		break;
15217683Spst
15317683Spst	case BPF_JMP|BPF_JA:
15417683Spst		op = "ja";
15517683Spst		fmt = "%d";
15617683Spst		v = n + 1 + p->k;
15717683Spst		break;
15817683Spst
15917683Spst	case BPF_JMP|BPF_JGT|BPF_K:
16017683Spst		op = "jgt";
16117683Spst		fmt = "#0x%x";
16217683Spst		break;
16317683Spst
16417683Spst	case BPF_JMP|BPF_JGE|BPF_K:
16517683Spst		op = "jge";
16617683Spst		fmt = "#0x%x";
16717683Spst		break;
16817683Spst
16917683Spst	case BPF_JMP|BPF_JEQ|BPF_K:
17017683Spst		op = "jeq";
17117683Spst		fmt = "#0x%x";
17217683Spst		break;
17317683Spst
17417683Spst	case BPF_JMP|BPF_JSET|BPF_K:
17517683Spst		op = "jset";
17617683Spst		fmt = "#0x%x";
17717683Spst		break;
17817683Spst
17917683Spst	case BPF_JMP|BPF_JGT|BPF_X:
18017683Spst		op = "jgt";
18117683Spst		fmt = "x";
18217683Spst		break;
18317683Spst
18417683Spst	case BPF_JMP|BPF_JGE|BPF_X:
18517683Spst		op = "jge";
18617683Spst		fmt = "x";
18717683Spst		break;
18817683Spst
18917683Spst	case BPF_JMP|BPF_JEQ|BPF_X:
19017683Spst		op = "jeq";
19117683Spst		fmt = "x";
19217683Spst		break;
19317683Spst
19417683Spst	case BPF_JMP|BPF_JSET|BPF_X:
19517683Spst		op = "jset";
19617683Spst		fmt = "x";
19717683Spst		break;
19817683Spst
19917683Spst	case BPF_ALU|BPF_ADD|BPF_X:
20017683Spst		op = "add";
20117683Spst		fmt = "x";
20217683Spst		break;
20317683Spst
20417683Spst	case BPF_ALU|BPF_SUB|BPF_X:
20517683Spst		op = "sub";
20617683Spst		fmt = "x";
20717683Spst		break;
20817683Spst
20917683Spst	case BPF_ALU|BPF_MUL|BPF_X:
21017683Spst		op = "mul";
21117683Spst		fmt = "x";
21217683Spst		break;
21317683Spst
21417683Spst	case BPF_ALU|BPF_DIV|BPF_X:
21517683Spst		op = "div";
21617683Spst		fmt = "x";
21717683Spst		break;
21817683Spst
21917683Spst	case BPF_ALU|BPF_AND|BPF_X:
22017683Spst		op = "and";
22117683Spst		fmt = "x";
22217683Spst		break;
22317683Spst
22417683Spst	case BPF_ALU|BPF_OR|BPF_X:
22517683Spst		op = "or";
22617683Spst		fmt = "x";
22717683Spst		break;
22817683Spst
22917683Spst	case BPF_ALU|BPF_LSH|BPF_X:
23017683Spst		op = "lsh";
23117683Spst		fmt = "x";
23217683Spst		break;
23317683Spst
23417683Spst	case BPF_ALU|BPF_RSH|BPF_X:
23517683Spst		op = "rsh";
23617683Spst		fmt = "x";
23717683Spst		break;
23817683Spst
23917683Spst	case BPF_ALU|BPF_ADD|BPF_K:
24017683Spst		op = "add";
24117683Spst		fmt = "#%d";
24217683Spst		break;
24317683Spst
24417683Spst	case BPF_ALU|BPF_SUB|BPF_K:
24517683Spst		op = "sub";
24617683Spst		fmt = "#%d";
24717683Spst		break;
24817683Spst
24917683Spst	case BPF_ALU|BPF_MUL|BPF_K:
25017683Spst		op = "mul";
25117683Spst		fmt = "#%d";
25217683Spst		break;
25317683Spst
25417683Spst	case BPF_ALU|BPF_DIV|BPF_K:
25517683Spst		op = "div";
25617683Spst		fmt = "#%d";
25717683Spst		break;
25817683Spst
25917683Spst	case BPF_ALU|BPF_AND|BPF_K:
26017683Spst		op = "and";
26117683Spst		fmt = "#0x%x";
26217683Spst		break;
26317683Spst
26417683Spst	case BPF_ALU|BPF_OR|BPF_K:
26517683Spst		op = "or";
26617683Spst		fmt = "#0x%x";
26717683Spst		break;
26817683Spst
26917683Spst	case BPF_ALU|BPF_LSH|BPF_K:
27017683Spst		op = "lsh";
27117683Spst		fmt = "#%d";
27217683Spst		break;
27317683Spst
27417683Spst	case BPF_ALU|BPF_RSH|BPF_K:
27517683Spst		op = "rsh";
27617683Spst		fmt = "#%d";
27717683Spst		break;
27817683Spst
27917683Spst	case BPF_ALU|BPF_NEG:
28017683Spst		op = "neg";
28117683Spst		fmt = "";
28217683Spst		break;
28317683Spst
28417683Spst	case BPF_MISC|BPF_TAX:
28517683Spst		op = "tax";
28617683Spst		fmt = "";
28717683Spst		break;
28817683Spst
28917683Spst	case BPF_MISC|BPF_TXA:
29017683Spst		op = "txa";
29117683Spst		fmt = "";
29217683Spst		break;
29317683Spst	}
29475107Sfenner	(void)snprintf(operand, sizeof operand, fmt, v);
295251129Sdelphij	if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
296251129Sdelphij		(void)snprintf(image, sizeof image,
297251129Sdelphij			      "(%03d) %-8s %-16s jt %d\tjf %d",
298251129Sdelphij			      n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
299251129Sdelphij	} else {
300251129Sdelphij		(void)snprintf(image, sizeof image,
301251129Sdelphij			      "(%03d) %-8s %s",
302251129Sdelphij			      n, op, operand);
303251129Sdelphij	}
30417683Spst	return image;
30517683Spst}
306