#!/usr/bin/perl -w
###
### Parse MyASN report and generate a BGPlay URL of the form
### http://www.ris.ripe.net/cgi-bin/bgplay.cgi?prefix=195.135.220.0/22&start=2005-05-30+05:00&end=2005-05-30+09:09
###
### This tool is written by Simon Leinen <simon@limmat.switch.ch>.

use strict;
use Time::Local;

sub parse_message ();
sub gmt_to_unix ($ );
sub init_months ();
sub unixtime_to_bgplay ($ );
sub make_bgplay_url ($$$$);

## BGPlay this many seconds before the earliest "first seen"
## value in the MyASN alert.
##
my $seconds_before_first_seen = 120;

## BGPlay this many seconds after the last "last seen" value in the
## MyASN alert.
##
my $seconds_after_last_seen = 300;

my $echo = 0;
init_months ();
my ($prefix, $rrcs, $first, $last)
    = parse_message ();
print make_bgplay_url ($prefix, $rrcs, $first, $last),"\n";

sub parse_message () {
    my ($very_first, $very_last, @rrcs, %rrcs);
    my (@colnames, @columns, $columns, $line, $k,
	$rrc, $prefix, $first, $last);
    while (<>) {
	print if $echo;
	next if /^[.|\']=--+/;
	warn "Cannot parse $_", next unless ($columns) = m@^\| (.*) \|$@;
	@columns = map { /^(.*\S+)\s*$/ } split (/ \| /, $columns);
	if (! $colnames[0]) {
	    @colnames = @columns;
	} else {
	    $line = {};
	    for ($k = 0; $#columns >= 0; ++$k) {
		$line->{$colnames[$k]} = shift @columns;
	    }
	    $prefix = $line->{'Prefix'} or die "missing Prefix column";
	    $rrc = $line->{'RRC'} or die "missing RRC column";
	    $first = $line->{'First seen'} or die "missing First seen column";
	    $last = $line->{'Last seen'} or die "missing Last seen column";
	    ++$rrcs{$rrc};
	    $first = gmt_to_unix ($first);
	    $last = gmt_to_unix ($last);
	    $very_first = $first
		if !defined $very_first or $first < $very_first;
	    $very_last = $last
		if !defined $very_last or $last > $very_last;
	}
    }
    @rrcs = sort keys %rrcs;
    return ($prefix, \@rrcs,
	    $very_first-$seconds_before_first_seen,
	    $very_last+$seconds_after_last_seen);
}

my %ugly_months = ();

sub init_months () {
    my $k = 0;
    my @pretty_months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    foreach my $month (@pretty_months) {
	$ugly_months{$month} = $k++;
    }
}

sub gmt_to_unix ($ ) {
    my ($gmt_string) = @_;
    my ($wday, $mname, $mon, $mday, $hour, $min, $sec, $year);
    die "malformed GMT string $gmt_string"
	unless (($wday, $mname, $mday, $hour, $min, $sec, $year)
		= $gmt_string =~
		m@(Mon|Tue|Wed|Thu|Fri|Sat|Sun)
		\ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
		\ \s*(\d+)
		\ (\d\d):(\d\d):(\d\d)\ (\d\d\d\d)$@ix);
    die "unknown month $mname" unless $mon = $ugly_months{$mname};
    return timegm ($sec, $min, $hour, $mday, $mon, $year);
}

sub unixtime_to_bgplay ($ ) {
    my ($time) = @_;
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) =
	gmtime($time);
    return sprintf ("%04d-%02d-%02d+%02d:%02d",
		    $year+1900, $mon+1, $mday, $hour, $min);
}

sub make_bgplay_url ($$$$) {
    my ($prefix, $rrcs, $first, $last) = @_;
    my $base_url = "http://www.ris.ripe.net/cgi-bin/bgplay.cgi";
    return sprintf ("%s?prefix=%s&start=%s&end=%s",
		    $base_url,
		    $prefix,
		    unixtime_to_bgplay ($first),
		    unixtime_to_bgplay ($last));
}
