osmo-rbs/racal6113/racal2pcap.pl

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);