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
2275107Sfenner#ifdef HAVE_CONFIG_H
2375107Sfenner#include "config.h"
2475107Sfenner#endif
2575107Sfenner
26214518Srpaulo#ifdef WIN32
27214518Srpaulo#include <pcap-stdinc.h>
28214518Srpaulo#else /* WIN32 */
29214518Srpaulo#if HAVE_INTTYPES_H
30214518Srpaulo#include <inttypes.h>
31214518Srpaulo#elif HAVE_STDINT_H
32214518Srpaulo#include <stdint.h>
33214518Srpaulo#endif
34214518Srpaulo#ifdef HAVE_SYS_BITYPES_H
35214518Srpaulo#include <sys/bitypes.h>
36214518Srpaulo#endif
37214518Srpaulo#include <sys/types.h>
38214518Srpaulo#endif /* WIN32 */
39214518Srpaulo
4017683Spst#include <stdio.h>
4117683Spst#include <string.h>
4217683Spst
4317683Spst#include "pcap-int.h"
4417683Spst
4517683Spst#ifdef HAVE_OS_PROTO_H
4617683Spst#include "os-proto.h"
4717683Spst#endif
4817683Spst
4917683Spstchar *
5017683Spstbpf_image(p, n)
51257466Ssbruno	const struct bpf_insn *p;
5217683Spst	int n;
5317683Spst{
5417683Spst	int v;
55172677Smlaier	const char *fmt, *op;
5617683Spst	static char image[256];
5717683Spst	char operand[64];
5817683Spst
5917683Spst	v = p->k;
6017683Spst	switch (p->code) {
6117683Spst
6217683Spst	default:
6317683Spst		op = "unimp";
6417683Spst		fmt = "0x%x";
6517683Spst		v = p->code;
6617683Spst		break;
6717683Spst
6817683Spst	case BPF_RET|BPF_K:
6917683Spst		op = "ret";
7017683Spst		fmt = "#%d";
7117683Spst		break;
7217683Spst
7317683Spst	case BPF_RET|BPF_A:
7417683Spst		op = "ret";
7517683Spst		fmt = "";
7617683Spst		break;
7717683Spst
7817683Spst	case BPF_LD|BPF_W|BPF_ABS:
7917683Spst		op = "ld";
8017683Spst		fmt = "[%d]";
8117683Spst		break;
8217683Spst
8317683Spst	case BPF_LD|BPF_H|BPF_ABS:
8417683Spst		op = "ldh";
8517683Spst		fmt = "[%d]";
8617683Spst		break;
8717683Spst
8817683Spst	case BPF_LD|BPF_B|BPF_ABS:
8917683Spst		op = "ldb";
9017683Spst		fmt = "[%d]";
9117683Spst		break;
9217683Spst
9317683Spst	case BPF_LD|BPF_W|BPF_LEN:
9417683Spst		op = "ld";
9517683Spst		fmt = "#pktlen";
9617683Spst		break;
9717683Spst
9817683Spst	case BPF_LD|BPF_W|BPF_IND:
9917683Spst		op = "ld";
10017683Spst		fmt = "[x + %d]";
10117683Spst		break;
10217683Spst
10317683Spst	case BPF_LD|BPF_H|BPF_IND:
10417683Spst		op = "ldh";
10517683Spst		fmt = "[x + %d]";
10617683Spst		break;
10717683Spst
10817683Spst	case BPF_LD|BPF_B|BPF_IND:
10917683Spst		op = "ldb";
11017683Spst		fmt = "[x + %d]";
11117683Spst		break;
11217683Spst
11317683Spst	case BPF_LD|BPF_IMM:
11417683Spst		op = "ld";
11517683Spst		fmt = "#0x%x";
11617683Spst		break;
11717683Spst
11817683Spst	case BPF_LDX|BPF_IMM:
11917683Spst		op = "ldx";
12017683Spst		fmt = "#0x%x";
12117683Spst		break;
12217683Spst
12317683Spst	case BPF_LDX|BPF_MSH|BPF_B:
12417683Spst		op = "ldxb";
12517683Spst		fmt = "4*([%d]&0xf)";
12617683Spst		break;
12717683Spst
12817683Spst	case BPF_LD|BPF_MEM:
12917683Spst		op = "ld";
13017683Spst		fmt = "M[%d]";
13117683Spst		break;
13217683Spst
13317683Spst	case BPF_LDX|BPF_MEM:
13417683Spst		op = "ldx";
13517683Spst		fmt = "M[%d]";
13617683Spst		break;
13717683Spst
13817683Spst	case BPF_ST:
13917683Spst		op = "st";
14017683Spst		fmt = "M[%d]";
14117683Spst		break;
14217683Spst
14317683Spst	case BPF_STX:
14417683Spst		op = "stx";
14517683Spst		fmt = "M[%d]";
14617683Spst		break;
14717683Spst
14817683Spst	case BPF_JMP|BPF_JA:
14917683Spst		op = "ja";
15017683Spst		fmt = "%d";
15117683Spst		v = n + 1 + p->k;
15217683Spst		break;
15317683Spst
15417683Spst	case BPF_JMP|BPF_JGT|BPF_K:
15517683Spst		op = "jgt";
15617683Spst		fmt = "#0x%x";
15717683Spst		break;
15817683Spst
15917683Spst	case BPF_JMP|BPF_JGE|BPF_K:
16017683Spst		op = "jge";
16117683Spst		fmt = "#0x%x";
16217683Spst		break;
16317683Spst
16417683Spst	case BPF_JMP|BPF_JEQ|BPF_K:
16517683Spst		op = "jeq";
16617683Spst		fmt = "#0x%x";
16717683Spst		break;
16817683Spst
16917683Spst	case BPF_JMP|BPF_JSET|BPF_K:
17017683Spst		op = "jset";
17117683Spst		fmt = "#0x%x";
17217683Spst		break;
17317683Spst
17417683Spst	case BPF_JMP|BPF_JGT|BPF_X:
17517683Spst		op = "jgt";
17617683Spst		fmt = "x";
17717683Spst		break;
17817683Spst
17917683Spst	case BPF_JMP|BPF_JGE|BPF_X:
18017683Spst		op = "jge";
18117683Spst		fmt = "x";
18217683Spst		break;
18317683Spst
18417683Spst	case BPF_JMP|BPF_JEQ|BPF_X:
18517683Spst		op = "jeq";
18617683Spst		fmt = "x";
18717683Spst		break;
18817683Spst
18917683Spst	case BPF_JMP|BPF_JSET|BPF_X:
19017683Spst		op = "jset";
19117683Spst		fmt = "x";
19217683Spst		break;
19317683Spst
19417683Spst	case BPF_ALU|BPF_ADD|BPF_X:
19517683Spst		op = "add";
19617683Spst		fmt = "x";
19717683Spst		break;
19817683Spst
19917683Spst	case BPF_ALU|BPF_SUB|BPF_X:
20017683Spst		op = "sub";
20117683Spst		fmt = "x";
20217683Spst		break;
20317683Spst
20417683Spst	case BPF_ALU|BPF_MUL|BPF_X:
20517683Spst		op = "mul";
20617683Spst		fmt = "x";
20717683Spst		break;
20817683Spst
20917683Spst	case BPF_ALU|BPF_DIV|BPF_X:
21017683Spst		op = "div";
21117683Spst		fmt = "x";
21217683Spst		break;
21317683Spst
214276768Sdelphij	case BPF_ALU|BPF_MOD|BPF_X:
215276768Sdelphij		op = "mod";
216276768Sdelphij		fmt = "x";
217276768Sdelphij		break;
218276768Sdelphij
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
229276768Sdelphij	case BPF_ALU|BPF_XOR|BPF_X:
230276768Sdelphij		op = "xor";
231276768Sdelphij		fmt = "x";
232276768Sdelphij		break;
233276768Sdelphij
23417683Spst	case BPF_ALU|BPF_LSH|BPF_X:
23517683Spst		op = "lsh";
23617683Spst		fmt = "x";
23717683Spst		break;
23817683Spst
23917683Spst	case BPF_ALU|BPF_RSH|BPF_X:
24017683Spst		op = "rsh";
24117683Spst		fmt = "x";
24217683Spst		break;
24317683Spst
24417683Spst	case BPF_ALU|BPF_ADD|BPF_K:
24517683Spst		op = "add";
24617683Spst		fmt = "#%d";
24717683Spst		break;
24817683Spst
24917683Spst	case BPF_ALU|BPF_SUB|BPF_K:
25017683Spst		op = "sub";
25117683Spst		fmt = "#%d";
25217683Spst		break;
25317683Spst
25417683Spst	case BPF_ALU|BPF_MUL|BPF_K:
25517683Spst		op = "mul";
25617683Spst		fmt = "#%d";
25717683Spst		break;
25817683Spst
25917683Spst	case BPF_ALU|BPF_DIV|BPF_K:
26017683Spst		op = "div";
26117683Spst		fmt = "#%d";
26217683Spst		break;
26317683Spst
264276768Sdelphij	case BPF_ALU|BPF_MOD|BPF_K:
265276768Sdelphij		op = "mod";
266276768Sdelphij		fmt = "#%d";
267276768Sdelphij		break;
268276768Sdelphij
26917683Spst	case BPF_ALU|BPF_AND|BPF_K:
27017683Spst		op = "and";
27117683Spst		fmt = "#0x%x";
27217683Spst		break;
27317683Spst
27417683Spst	case BPF_ALU|BPF_OR|BPF_K:
27517683Spst		op = "or";
27617683Spst		fmt = "#0x%x";
27717683Spst		break;
27817683Spst
279276768Sdelphij	case BPF_ALU|BPF_XOR|BPF_K:
280276768Sdelphij		op = "xor";
281276768Sdelphij		fmt = "#0x%x";
282276768Sdelphij		break;
283276768Sdelphij
28417683Spst	case BPF_ALU|BPF_LSH|BPF_K:
28517683Spst		op = "lsh";
28617683Spst		fmt = "#%d";
28717683Spst		break;
28817683Spst
28917683Spst	case BPF_ALU|BPF_RSH|BPF_K:
29017683Spst		op = "rsh";
29117683Spst		fmt = "#%d";
29217683Spst		break;
29317683Spst
29417683Spst	case BPF_ALU|BPF_NEG:
29517683Spst		op = "neg";
29617683Spst		fmt = "";
29717683Spst		break;
29817683Spst
29917683Spst	case BPF_MISC|BPF_TAX:
30017683Spst		op = "tax";
30117683Spst		fmt = "";
30217683Spst		break;
30317683Spst
30417683Spst	case BPF_MISC|BPF_TXA:
30517683Spst		op = "txa";
30617683Spst		fmt = "";
30717683Spst		break;
30817683Spst	}
30975107Sfenner	(void)snprintf(operand, sizeof operand, fmt, v);
310251129Sdelphij	if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
311251129Sdelphij		(void)snprintf(image, sizeof image,
312251129Sdelphij			      "(%03d) %-8s %-16s jt %d\tjf %d",
313251129Sdelphij			      n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
314251129Sdelphij	} else {
315251129Sdelphij		(void)snprintf(image, sizeof image,
316251129Sdelphij			      "(%03d) %-8s %s",
317251129Sdelphij			      n, op, operand);
318251129Sdelphij	}
31917683Spst	return image;
32017683Spst}
321