108 lines
2.0 KiB
Perl
Executable File
108 lines
2.0 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
use strict;
|
|
use Net::Pcap;
|
|
|
|
my $DLT_LINUX_LAPD = 177;
|
|
my $caplen = 255;
|
|
|
|
my $outfile = $ARGV[0];
|
|
my $pcap = Net::Pcap::open_dead($DLT_LINUX_LAPD, $caplen);
|
|
my $pcap_dumper = Net::Pcap::dump_open($pcap, $outfile);
|
|
|
|
sub write_pcap_pkt($)
|
|
{
|
|
my $pkt = shift;
|
|
my $hdr;
|
|
|
|
$hdr->{tv_sec} = 0;
|
|
$hdr->{tv_usec} = 0;
|
|
$hdr->{caplen} = $caplen;
|
|
$hdr->{len} = length($pkt);
|
|
|
|
Net::Pcap::dump($pcap_dumper, $hdr, $pkt);
|
|
}
|
|
|
|
sub make_linux_lapd_hdr($)
|
|
{
|
|
my $downlink = shift;
|
|
|
|
return pack('nnnQn', 4, 0, 0, $downlink, 48);
|
|
}
|
|
|
|
sub make_lapd_hdr($$$)
|
|
{
|
|
my $sapi = shift;
|
|
my $tei = shift;
|
|
my $downlink = shift;
|
|
|
|
my $addr1 = ($sapi << 2) | $downlink;
|
|
my $addr2 = ($tei << 1) | 1;
|
|
|
|
return pack('CCC', $addr1, $addr2, 3);
|
|
}
|
|
|
|
sub hex2bin($)
|
|
{
|
|
my $hexstring = shift;
|
|
|
|
$hexstring =~ s/\s+//g;
|
|
|
|
return pack('H*', $hexstring);
|
|
}
|
|
|
|
my $tei;
|
|
my $sapi;
|
|
my $state = 0;
|
|
my $msg_hex = "";
|
|
my %ces_to_tei;
|
|
|
|
while (my $line = <STDIN>) {
|
|
chomp($line);
|
|
|
|
if ($state != 0) {
|
|
if ($line =~ /^\S/) {
|
|
my $downlink;
|
|
# write the accumulated message
|
|
printf("%u: %s\n", $state, $msg_hex);
|
|
if ($state == 1) {
|
|
$downlink = 0;
|
|
} else {
|
|
$downlink = 1;
|
|
}
|
|
my $llh = make_linux_lapd_hdr($downlink);
|
|
my $lh = make_lapd_hdr($sapi, $tei, $downlink);
|
|
my $msg = hex2bin($msg_hex);
|
|
write_pcap_pkt($llh . $lh . $msg);
|
|
|
|
# fall back to state 0, handle message below
|
|
$state = 0;
|
|
}
|
|
}
|
|
if ($state == 0) {
|
|
if ($line =~ /MDL_ASSIGN_REQUEST ces = (\d+),tei = (\d+)/) {
|
|
$ces_to_tei{$1} = $2;
|
|
} elsif ($line =~ /^\**DL ESTABLISH REQUEST sapi = (\d+), ces = (\d+)/) {
|
|
$ces_to_tei{$2} = $1;
|
|
}
|
|
if ($line =~ /DL (UNIT )?DATA INDICATION sapi = (\d+), ces = (\d+)/) {
|
|
$tei = $ces_to_tei{$3};
|
|
$sapi = $2;
|
|
$state = 1;
|
|
$msg_hex = "";
|
|
} elsif ($line =~ /DL_(UNIT)?DATA_REQUEST sapi = (\d+)/) {
|
|
$sapi = $2;
|
|
$state = 2;
|
|
$msg_hex = "";
|
|
}
|
|
} else {
|
|
# accumulate hex bytes
|
|
if ($line =~ /\s+(.*)/) {
|
|
$msg_hex .= "$1 ";
|
|
}
|
|
}
|
|
}
|
|
|
|
Net::Pcap::dump_close($pcap_dumper);
|
|
Net::Pcap::close($pcap);
|