#!/usr/bin/perl
#
# A simple CT network traffic monitor
#
# Last Change: Sat Nov  6 18:32:11 GMT 1999 DL6RAI

use IO::Socket;
use Time::localtime;
use strict;
use constant MAXLEN => 1024;

my $port = 9870;
my $data;

my $S = IO::Socket::INET->new(Proto     => 'udp',
                              Type      => SOCK_DGRAM,
                              LocalPort => $port
                              ) || die "can't make socket: $!";

while (1) {
    my $sender = $S->recv($data,MAXLEN,0) || die "recv(): $!";
    # print ("F:",fileno($S),"\n");

    my ($remote_port,$remote_host) = sockaddr_in($sender);
    $remote_host = inet_ntoa($remote_host);
    warn "Received ",length($data)," bytes from [$remote_host,$remote_port]\n";

    my $offset = 0;
    chomp($data);

    my $len = length($data);
    my @array = unpack('C*', $data);
    for (@array) {
        $_ = sprintf('%2.2x',$_);
    }
    push(@array,' ') while $len++ < 16;
    # print "ARRAY: $#array elements.\n";
    # $data =~ s/[^ -~]/./g;
    printf "%8.8lx    ",$offset;
    printf "%s%s%s%s %s%s%s%s %s%s%s%s %s%s%s%s    %s\n",@array,$data;

    my $checksum = ord(substr($data,-1));
    $data = substr($data,0,-1);
    print("DATA: >$data<\n");

    my $c_checksum = unpack("%32C*",$data);
    $c_checksum |= 0x80;
    $c_checksum &= 0xFF;
    # printf("C-Checksum: %02x\n",$c_checksum);
    if ( $c_checksum ne $checksum ) {
	print "Network bad checksum ($checksum ne $c_checksum)\n";
    } else {

       my $stn_nr = ord(substr($data,1,1))-48;
       printf("Stn %02d: ",$stn_nr);

       if ($data =~ /^A.*/) {
         $data = substr($data,2);
         printf(">TNC %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^B.*/) {
         $data = substr($data,2);
         printf("<TNC %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^C.*/) {
         $data = substr($data,2);
         printf("BMAP %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^E.*/) {
         $data = substr($data,2);
         printf("NOTE %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^G.*/) {
         $data = substr($data,2);
         printf("PFRQ %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^L.*/) {
         $data = substr($data,2);
         printf("LOG  %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^M.*/) {
         $data = substr($data,2);
         printf("QRG  %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^N.*/) {
         $data = substr($data,2);
         printf("SER  %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^P.*/) {
         $data = substr($data,2);
         printf("PASS %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^S.*/) {
         $data = substr($data,2);
         printf("SKED %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^T.*/) {
         $data = substr($data,3);
         printf("GAB  %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^U.*/) {
         $data = substr($data,3);
         printf("UPD  %s\n",$data);
         goto DONE;
       }

       if ($data =~ /^Z.*/) {
         $data = substr($data,2);
         $data =~ s/\s//g;
         my $time_str = ctime($data);
         printf("TIME %s\n",$time_str);
         goto DONE;
       }

    DONE:
    }

    # print($data,"\n");
    print("\n");
}

__END__
