Created
February 21, 2022 02:40
-
-
Save ryo/5faf4d75bf4f8045a63c19baabb11f6a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/perl | |
use strict; | |
use warnings; | |
use Getopt::Std; | |
sub usage { | |
die <<__USAGE__ | |
tcpdump_dd2h [options] | |
-c output C format | |
-v verbose | |
e.g.) | |
tcpdump -dd port 0x1234 | tcpdump_dd2h | |
__USAGE__ | |
} | |
getopts('cv', my $opts = {}) || usage(); | |
my $BPF_CLASS_MASK = 0x07; | |
my %BPF_CLASS = ( | |
0x00 => 'BPF_LD', | |
0x01 => 'BPF_LDX', | |
0x02 => 'BPF_ST', | |
0x03 => 'BPF_STX', | |
0x04 => 'BPF_ALU', | |
0x05 => 'BPF_JMP', | |
0x06 => 'BPF_RET', | |
0x07 => 'BPF_MISC' | |
); | |
my $BPF_SIZE_MASK = 0x18; | |
my %BPF_SIZE = ( | |
0x00 => 'BPF_W', | |
0x08 => 'BPF_H', | |
0x10 => 'BPF_B' | |
); | |
my $BPF_MODE_MASK = 0xe0; | |
my %BPF_MODE = ( | |
0x00 => 'BPF_IMM', | |
0x20 => 'BPF_ABS', | |
0x40 => 'BPF_IND', | |
0x60 => 'BPF_MEM', | |
0x80 => 'BPF_LEN', | |
0xa0 => 'BPF_MSH' | |
); | |
my $BPF_OP_MASK = 0xf0; | |
my %BPF_OP = ( | |
0x00 => 'BPF_ADD', | |
0x10 => 'BPF_SUB', | |
0x20 => 'BPF_MUL', | |
0x30 => 'BPF_DIV', | |
0x40 => 'BPF_OR', | |
0x50 => 'BPF_AND', | |
0x60 => 'BPF_LSH', | |
0x70 => 'BPF_RSH', | |
0x80 => 'BPF_NEG', | |
0x00 => 'BPF_JA', | |
0x10 => 'BPF_JEQ', | |
0x20 => 'BPF_JGT', | |
0x30 => 'BPF_JGE', | |
0x40 => 'BPF_JSET' | |
); | |
my $BPF_SRC_MASK = 0x08; | |
my %BPF_SRC = ( | |
0x00 => 'BPF_K', | |
0x08 => 'BPF_X' | |
); | |
my $BPF_RVAL_MASK = 0x18; | |
my %BPF_RVAL = ( | |
0x00 => 'BPF_K', | |
0x08 => 'BPF_X', | |
0x10 => 'BPF_A' | |
); | |
my $BPF_MISCOP_MASK = 0xf8; | |
my %BPF_MISCOP = ( | |
0x00 => 'BPF_TAX', | |
0x80 => 'BPF_TXA' | |
); | |
my $RE_NUM = qr/((0x[\da-f]+)|(0[0-7]*)|([1-9][\d]*))/; | |
# | |
# parse output of "tcpdump -dd ..." | |
# e.g.) { 0x6, 0, 0, 0x00000000 }, | |
# | |
my @code; | |
while (<>) { | |
chop; | |
my $line = $_; | |
if (m/^{\s*$RE_NUM\s*,\s*$RE_NUM\s*,\s*$RE_NUM\s*,\s*$RE_NUM\s*},$/) { | |
s/,$//; | |
tr/{}/()/; | |
push(@code, [ $line, eval($_) ]); | |
} else { | |
warn "unrecognized input: $_\n"; | |
} | |
} | |
my $lineno = 0; | |
for my $insnref (@code) { | |
my ($line, $code, $jt, $jf, $k) = @$insnref; | |
my @result; | |
if (exists $opts->{c}) { | |
if ($lineno == 0) { | |
print "struct bpf_insn insns[] = {\n"; | |
} | |
unless (exists $opts->{v}) { | |
print "\t"; | |
} | |
} | |
if (exists $opts->{v}) { | |
if ($lineno == 0) { | |
print "/* Line: code jt(#) jf(#) k struct bpf_insn[] */\n"; | |
print "/* ---- ---- -------- -------- ---------- ---------------------------- */\n"; | |
} | |
printf("/* %4s: 0x%02x, %3d%5s, %3d%5s, 0x%08x */ ", | |
"#" . $lineno, | |
$code, | |
$jt, (($jt + $jt) == 0) ? "" : "(#" . ($jt + $lineno) . ")", | |
$jf, (($jt + $jt) == 0) ? "" : "(#" . ($jf + $lineno) . ")", | |
$k); | |
} | |
$lineno++; | |
$_ = $BPF_CLASS{$code & $BPF_CLASS_MASK}; | |
push(@result, $_); | |
if (m/_LD/) { | |
$_ = $BPF_SIZE{$code & $BPF_SIZE_MASK}; | |
push(@result, $_); | |
$_ = $BPF_MODE{$code & $BPF_MODE_MASK}; | |
push(@result, $_); | |
} elsif (m/_(JMP|ALU)/) { | |
$_ = $BPF_OP{$code & $BPF_OP_MASK}; | |
push(@result, $_); | |
$_ = $BPF_SRC{$code & $BPF_SRC_MASK}; | |
push(@result, $_); | |
} elsif (m/_RET/) { | |
$_ = $BPF_RVAL{$code & $BPF_RVAL_MASK}; | |
push(@result, $_); | |
} elsif (m/_MISC/) { | |
$_ = $BPF_MISCOP{$code & $BPF_MISCOP_MASK}; | |
push(@result, $_); | |
} else { | |
die "$line\n"; | |
} | |
if ($result[0] =~ m/_JMP/) { | |
print "BPF_JUMP("; | |
print join(" + ", @result); | |
printf ", 0x%08x", $k; | |
printf ", %d, %d),", $jt, $jf; | |
} else { | |
print "BPF_STMT("; | |
print join(" + ", @result); | |
printf ", 0x%08x),", $k; | |
} | |
print "\n"; | |
} | |
if (exists $opts->{c}) { | |
print "};\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment