| version 1.2, 2007/02/07 17:42:56 |
version 1.3, 2007/02/07 17:44:56 |
|
|
| #!/usr/bin/perl |
#!/usr/bin/perl |
| # $RedRiver: su.cgi,v 1.1 2007/02/07 16:55:12 andrew Exp $ |
# $RedRiver: su.cgi,v 1.2 2007/02/07 17:42:56 andrew Exp $ |
| ######################################################################## |
######################################################################## |
| # su.cgi *** a CGI for Trango SU utilities. |
# su.cgi *** a CGI for Trango SU utilities. |
| # |
# |
|
|
| |
|
| use CGI qw/:standard/; |
use CGI qw/:standard/; |
| use File::Basename; |
use File::Basename; |
| use YAML qw/ LoadFile Dump /; |
use YAML qw/ LoadFile /; |
| use Net::Telnet::Trango; |
use Net::Telnet::Trango; |
| |
|
| my $me = basename($0); |
my $me = basename($0); |
|
|
| |
|
| if (param()) { |
if (param()) { |
| |
|
| my $AP = param('AP'); |
my $AP = param('AP'); |
| |
|
| unless (exists $aps->{$AP}) { |
unless (exists $aps->{$AP}) { |
| print h3("AP '$AP' does not exist!"); |
print h3("AP '$AP' does not exist!"); |
| print end_html; |
print end_html; |
| exit; |
exit; |
| } |
} |
| |
|
| my $sumac = param('sumac'); |
my $sumac = param('sumac'); |
| |
|
| $sumac =~ s/[^0-9A-Fa-f]//g; |
$sumac =~ s/[^0-9A-Fa-f]//g; |
| $sumac = uc($sumac); |
$sumac = uc($sumac); |
| |
|
| my $suid = param('suid'); |
my $suid = param('suid'); |
| |
|
| if (length $sumac == 12) { |
if (length $sumac == 12) { |
| add_su($aps->{$AP}, $sumac); |
add_su($aps->{$AP}, $sumac); |
| } elsif (length $suid) { |
} elsif (length $suid) { |
| testrflink($aps->{$AP}, $suid); |
testrflink($aps->{$AP}, $suid); |
| } else { |
} else { |
| print h3("Invalid SUID '$suid' and MAC '$sumac'"); |
print h3("Invalid SUID '$suid' and MAC '$sumac'"); |
| show_form($aps, $default_mac); |
show_form($aps, $default_mac); |
| } |
} |
| |
|
| } else { |
} else { |
| show_form($aps, $default_mac); |
show_form($aps, $default_mac); |
| } |
} |
| |
|
| |
|
|
|
| |
|
| sub get_aps |
sub get_aps |
| { |
{ |
| my $file = shift; |
my $file = shift; |
| |
|
| my $conf = LoadFile($file); |
my $conf = LoadFile($file); |
| |
|
| my %aps; |
my %aps; |
| |
|
| foreach my $ap (keys %{ $conf }) { |
foreach my $ap (keys %{ $conf }) { |
| next if $ap eq 'default'; |
next if $ap eq 'default'; |
| $aps{ $ap } = $conf->{$ap}; |
$aps{ $ap } = $conf->{$ap}; |
| if (ref $conf->{default} eq 'HASH') { |
if (ref $conf->{default} eq 'HASH') { |
| foreach my $k (keys %{ $conf->{default} }) { |
foreach my $k (keys %{ $conf->{default} }) { |
| $aps{ $ap }{$k} ||= $conf->{default}->{$k}; |
$aps{ $ap }{$k} ||= $conf->{default}->{$k}; |
| } |
} |
| } |
} |
| } |
} |
| |
|
| return \%aps; |
return \%aps; |
| |
|
| return { |
return { |
| 'rrlhcwap0000' => { |
'rrlhcwap0000' => { |
| name => '192.168.1.1', |
name => '192.168.1.1', |
| password => 'trango', |
password => 'trango', |
| } |
} |
| }; |
}; |
| |
|
| } |
} |
| |
|
| sub show_form |
sub show_form |
| { |
{ |
| my $aps = shift; |
my $aps = shift; |
| |
|
| my %cache = (); |
my %cache = (); |
| my @ap_names = sort { |
my @ap_names = sort { |
| my @a = $a =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; |
my @a = $a =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; |
| my @b = $b =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; |
my @b = $b =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/; |
| |
|
| if (@a) { |
if (@a) { |
| $cache{$a} ||= pack('C4' => @a); |
$cache{$a} ||= pack('C4' => @a); |
| } else { |
} else { |
| $cache{$a} ||= lc($a); |
$cache{$a} ||= lc($a); |
| } |
} |
| if (@b) { |
if (@b) { |
| $cache{$b} ||= pack('C4' => @b); |
$cache{$b} ||= pack('C4' => @b); |
| } else { |
} else { |
| $cache{$b} ||= lc($b); |
$cache{$b} ||= lc($b); |
| } |
} |
| |
|
| $cache{$a} cmp $cache{$b}; |
$cache{$a} cmp $cache{$b}; |
| } keys %{ $aps }; |
} keys %{ $aps }; |
| |
|
| print p(start_form(-method => 'GET'), |
print p(start_form(-method => 'GET'), |
| 'AP: ', popup_menu(-name=>'AP', -values=>\@ap_names),br, |
'AP: ', popup_menu(-name=>'AP', -values=>\@ap_names),br, |
| 'SUMAC: ', textfield( -name=>'sumac', -default=>$default_mac),br, |
'SUMAC: ', textfield( -name=>'sumac', -default=>$default_mac),br, |
| 'SUID: ', textfield( -name=>'suid', -default=>$default_suid),br, |
'SUID: ', textfield( -name=>'suid', -default=>$default_suid),br, |
| submit, |
submit, |
| end_form); |
end_form); |
| |
|
| print p('Fill in the SUMAC if you wish to add an SU ', |
print p('Fill in the SUMAC if you wish to add an SU ', |
| 'or fill in the SUID to run an rflinktest.'); |
'or fill in the SUID to run an rflinktest.'); |
| |
|
| return 1; |
return 1; |
| } |
} |
| |
|
| sub login |
sub login |
| { |
{ |
| my $host = shift; |
my $host = shift; |
| my $password = shift; |
my $password = shift; |
| |
|
| my $t = new Net::Telnet::Trango ( Timeout => 5 ); |
my $t = new Net::Telnet::Trango ( Timeout => 5 ); |
| |
|
| #$t->input_log('/tmp/telnet_log'); |
#$t->input_log('/tmp/telnet_log'); |
| #$t->dump_log('/tmp/telnet_log'); |
#$t->dump_log('/tmp/telnet_log'); |
| |
|
| unless ($t->open( Host => $host )) { |
unless ($t->open( Host => $host )) { |
| print h3("Error connecting!"); |
print h3("Error connecting!"); |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| unless ($t->login( $password ) ) { |
unless ($t->login( $password ) ) { |
| print h3("Couldn't log in: $!"); |
print h3("Couldn't log in: $!"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| return $t; |
return $t; |
| } |
} |
| |
|
| sub add_su |
sub add_su |
| { |
{ |
| my $ap = shift; |
my $ap = shift; |
| my $sumac = shift; |
my $sumac = shift; |
| |
|
| my $t = login($ap->{name}, $ap->{password}); |
my $t = login($ap->{name}, $ap->{password}); |
| |
|
| my $cur_sus = $t->sudb_view; |
my $cur_sus = $t->sudb_view; |
| |
|
| my $new_suid = next_suid($cur_sus); |
my $new_suid = next_suid($cur_sus); |
| |
|
| foreach my $su (@{ $cur_sus }) { |
foreach my $su (@{ $cur_sus }) { |
| if ($sumac eq $su->{mac}) { |
if ($sumac eq $su->{mac}) { |
| print h3("MAC '$sumac' already in AP '$ap->{name}' " . |
print h3("MAC '$sumac' already in AP '$ap->{name}' " . |
| "with SUID '$su->{suid}'"); |
"with SUID '$su->{suid}'"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| } |
} |
| |
|
| unless ($t->sudb_add( |
unless ($t->sudb_add( |
| $new_suid, 'reg', $default_cir, $default_mir, $sumac |
$new_suid, 'reg', $default_cir, $default_mir, $sumac |
| ) ) { |
) ) { |
| print h3("Error adding SU!"); |
print h3("Error adding SU!"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| my $new_sus = $t->sudb_view; |
my $new_sus = $t->sudb_view; |
| my $added = 0; |
my $added = 0; |
| foreach my $su (@{ $new_sus }) { |
foreach my $su (@{ $new_sus }) { |
| if ($su->{suid} == $new_suid) { |
if ($su->{suid} == $new_suid) { |
| $added = 1; |
$added = 1; |
| last; |
last; |
| } |
} |
| } |
} |
| |
|
| unless ($added) { |
unless ($added) { |
| print h3("Couldn't add su id: $new_suid"); |
print h3("Couldn't add su id: $new_suid"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| unless ($t->save_sudb) { |
unless ($t->save_sudb) { |
| print h3("Couldn't save sudb"); |
print h3("Couldn't save sudb"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| print p( |
print p( |
| "Added new SU with ID '$new_suid' " . |
"Added new SU with ID '$new_suid' " . |
| "and MAC '$sumac' " . |
"and MAC '$sumac' " . |
| "to '$ap->{name}'. " . |
"to '$ap->{name}'. " . |
| '<a href="' . $me . '?' . |
'<a href="' . $me . '?' . |
| 'AP=' . $ap->{name} . '&' . |
'AP=' . $ap->{name} . '&' . |
| 'suid=' . $new_suid . |
'suid=' . $new_suid . |
| '">Test SU RFLink</a>' |
'">Test SU RFLink</a>' |
| ); |
); |
| |
|
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return 1; |
return 1; |
| |
|
| } |
} |
| |
|
| sub testrflink |
sub testrflink |
| { |
{ |
| my $ap = shift; |
my $ap = shift; |
| my $suid = shift; |
my $suid = shift; |
| |
|
| my $t = login($ap->{name}, $ap->{password}); |
my $t = login($ap->{name}, $ap->{password}); |
| |
|
| my $result = $t->su_testrflink( $suid ); |
my $result = $t->su_testrflink( $suid ); |
| |
|
| unless ($result) { |
unless ($result) { |
| print h3("Error testing SU rflink!"); |
print h3("Error testing SU rflink!"); |
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return undef; |
return undef; |
| } |
} |
| |
|
| my @keys = ('suid', 'AP Tx', 'AP Rx', 'SU Rx'); |
my @keys = ('suid', 'AP Tx', 'AP Rx', 'SU Rx'); |
| |
|
| my @table; |
my @table; |
| foreach my $su (@{ $result }) { |
foreach my $su (@{ $result }) { |
| next unless ref $su eq 'HASH'; |
next unless ref $su eq 'HASH'; |
| next unless exists $su->{suid}; |
next unless exists $su->{suid}; |
| $su->{suid} =~ s/\D//g; |
$su->{suid} =~ s/\D//g; |
| next unless $su->{suid}; |
next unless $su->{suid}; |
| |
|
| push @table, td([ @{ $su }{ @keys } ]); |
push @table, td([ @{ $su }{ @keys } ]); |
| } |
} |
| |
|
| print table({-border=>1,-cellspacing=>0,-cellpadding=>1}, |
print table({-border=>1,-cellspacing=>0,-cellpadding=>1}, |
| caption($ap->{name} . ': su testrflink ' . $suid), |
caption($ap->{name} . ': su testrflink ' . $suid), |
| Tr({-align=>'CENTER', -valign=>'TOP'}, |
Tr({-align=>'CENTER', -valign=>'TOP'}, |
| [ th(\@keys), @table ] |
[ th(\@keys), @table ] |
| ) |
) |
| ); |
); |
| |
|
| $t->exit; |
$t->exit; |
| $t->close; |
$t->close; |
| return 1; |
return 1; |
| |
|
| } |
} |
| |
|
| sub next_suid |
sub next_suid |
| { |
{ |
| my $sudb = shift; |
my $sudb = shift; |
| |
|
| my $next_id = $Start_SUID; |
my $next_id = $Start_SUID; |
| |
|
| my %ids = map { $_->{suid} => 1 } @{ $sudb }; |
my %ids = map { $_->{suid} => 1 } @{ $sudb }; |
| |
|
| my $next_key = sprintf('%04d', $next_id); |
my $next_key = sprintf('%04d', $next_id); |
| while (exists $ids{$next_key}) { |
while (exists $ids{$next_key}) { |
| $next_id++; |
$next_id++; |
| $next_key = sprintf('%04d', $next_id); |
$next_key = sprintf('%04d', $next_id); |
| } |
} |
| |
|
| return $next_id; |
return $next_id; |
| } |
} |