[BACK]Return to su.cgi CVS log [TXT][DIR] Up to [local] / trango / Net-Telnet-Trango / scripts

File: [local] / trango / Net-Telnet-Trango / scripts / su.cgi (download)

Revision 1.1, Wed Feb 7 16:55:12 2007 UTC (17 years, 7 months ago) by andrew
Branch: MAIN

just put it all in one script.  That's way more better gooder.

#!/usr/bin/perl
# $RedRiver$
########################################################################
# su.cgi *** a CGI for Trango SU utilities.
# 
# 2007.02.07 #*#*# andrew fresh <andrew@mad-techies.org>
########################################################################
# Copyright (C) 2007 by Andrew Fresh
# 
# This program is free software; you can redistribute it and/or modify 
# it under the same terms as Perl itself.
########################################################################
use strict;
use warnings;

my $host_file = '/conf/wstationinfo/hosts.xml';

my $default_mac  = '0001DE';
my $default_suid = 'all';
my $default_cir  = 256;
my $default_mir  = 9999;
my $Start_SUID = 3;

use CGI qw/:standard/;
use XML::Simple;
use Net::Telnet::Trango;

use File::Basename;

my $me = basename($0);

print header,
      start_html('Trango SU Utilities'),
      h1('Trango SU Utilities');

my $aps = get_aps($host_file);

if (param()) {

	my $AP = param('AP');

	unless (exists $aps->{$AP}) {
		print h3("AP '$AP' does not exist!");
		print end_html;
		exit;
	}

	my $sumac = param('sumac');

	$sumac =~ s/[^0-9A-Fa-f]//g;
	$sumac = uc($sumac);

	my $suid = param('suid');

	if (length $sumac == 12) {
		add_su($aps->{$AP}, $sumac);
	} elsif (length $suid) {
		testrflink($aps->{$AP}, $suid);
	} else {
		print h3("Invalid SUID '$suid' and MAC '$sumac'");
		show_form($aps, $default_mac);
	}

} else {
	show_form($aps, $default_mac);
}


print end_html;


sub get_aps
{
	my $file = shift;

	my $conf = Read_Hosts($file);

	my %aps;

	foreach my $ap (@{ $conf }) {
		if ($ap->{'group'} eq 'Trango') {
			my $name = $ap->{'comment'} || $ap->{'name'};
			$aps{ $name } = $ap;
		}
	}

	return \%aps;

	return { 
		'rrlhcwap0000' => {
			group   => 'Trango',
			version => 1,
			name    => '192.168.1.1',
			port    => 161,
			Read_Community => 'private',
			Write_Community => 'private',
		}
	};

}

sub show_form
{
	my $aps  = shift;

	my %cache = ();
	my @ap_names = sort {
		my @a = $a =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
		my @b = $b =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;

		if (@a) {
			$cache{$a} ||= pack('C4' => @a);
		} else {
			$cache{$a} ||= lc($a);
		}
		if (@b) {
			$cache{$b} ||= pack('C4' => @b);
		} else {
			$cache{$b} ||= lc($b);
		}

		$cache{$a} cmp $cache{$b};
	} keys %{ $aps };

    print p(start_form(-method => 'GET'),
		'AP:    ', popup_menu(-name=>'AP', -values=>\@ap_names),br,
	    'SUMAC: ', textfield(-name=>'sumac',-default=>$default_mac),br,
	    'SUID:  ', textfield(-name=>'suid',-default=>$default_suid),br,
        submit,
        end_form);

	print p('Fill in the SUMAC if you wish to add an SU ',
	  'or fill in the SUID to run an rflinktest.');

	return 1;
}

sub login
{
	my $host     = shift;
	my $password = shift;

	my $t = new Net::Telnet::Trango ( Timeout => 5 );

	#$t->input_log('/tmp/telnet_log');
	#$t->dump_log('/tmp/telnet_log');

	unless ($t->open( Host => $host )) {
		print h3("Error connecting!");
		$t->close;
		return undef;
	}

	unless ($t->login( $password ) ) {
		print h3("Couldn't log in: $!");
		$t->exit;
		$t->close;
		return undef;
	}

	return $t;
}

sub add_su
{
	my $ap  = shift;
	my $sumac = shift;

	my $t = login($ap->{'name'}, $ap->{'Telnet_Password'});

	my $cur_sus = $t->sudb_view;

	my $new_suid = next_suid($cur_sus);

	foreach my $su (@{ $cur_sus }) {
		if ($sumac eq $su->{'mac'}) {
			print h3("MAC '$sumac' already in AP '$ap->{'name'}' with SUID '$su->{'suid'}'");
			$t->exit;
			$t->close;
			return undef;
		}
	}

	unless ($t->sudb_add(
		$new_suid, 'reg', $default_cir, $default_mir, $sumac
	) ) {
		print h3("Error adding SU!");
		$t->exit;
		$t->close;
		return undef;
	}

	my $new_sus = $t->sudb_view;
	my $added = 0;
	foreach my $su (@{ $new_sus }) {
		if ($su->{'suid'} == $new_suid) {
			$added = 1;
			last;
		}
	}

	unless ($added) {
		print h3("Couldn't add su id: $new_suid");
		$t->exit;
		$t->close;
		return undef;
	}

	unless ($t->save_sudb) {
		print h3("Couldn't save sudb");
		$t->exit;
		$t->close;
		return undef;
	}

	print p(
		"Added new SU with ID '$new_suid' " .
		"and MAC '$sumac' " .
		"to '$ap->{'name'}'.  " .
		'<a href="' . $me . '?' . 
		'AP=' . $ap->{'name'} . '&' . 
		'suid=' . $new_suid . 
		'">Test SU RFLink</a>'
	);

	$t->exit;
	$t->close;
	return 1;

}

sub testrflink
{
	my $ap  = shift;
	my $suid = shift;

	my $t = login($ap->{'name'}, $ap->{'Telnet_Password'});

	my $result = $t->su_testrflink( $suid );

	unless ($result) {
		print h3("Error testing SU rflink!");
		$t->exit;
		$t->close;
		return undef;
	}

	my @keys = ('suid', 'AP Tx', 'AP Rx', 'SU Rx');

	my @table;
	foreach my $su (@{ $result }) {
		next unless ref $su eq 'HASH';
		next unless exists $su->{'suid'};
		$su->{'suid'} =~ s/\D//g;
		next unless $su->{'suid'};

		push @table, td([ @{ $su }{ @keys } ]);
	}

	print table({-border=>1,-cellspacing=>0,-cellpadding=>1},
		caption($ap->{'name'} . ': su testrflink ' . $suid),
		Tr({-align=>'CENTER', -valign=>'TOP'},
			[ th(\@keys), @table ]
		)
	);

	$t->exit;
	$t->close;
	return 1;

}

sub next_suid
{
	my $sudb = shift;

	my $next_id = $Start_SUID;

	my %ids = map { $_->{'suid'} => 1 } @{ $sudb };

	my $next_key = sprintf('%04d', $next_id);
	while (exists $ids{$next_key}) {
		$next_id++;
		$next_key = sprintf('%04d', $next_id);
	}

	return $next_id;
}

sub Read_Hosts
{
    my $file = shift;
    my $xs = XML::Simple->new();

	my %Default_SNMP = (
    	Read_Community => 'public',
		Telnet_Password => 'password',
    	port => 161,
    	version => 1,
	);

    my @hosts;
    my $hosts = $xs->XMLin($file,
        keyattr => [ 'Station' ],
        ForceArray => qr/^Host$/,
    );

    foreach my $group (keys %{ $hosts }) {
        next if $group eq 'Read_Community';

        foreach my $host (@{ $hosts->{$group}->{Host} }) {
            foreach my $item ('Read_Community', 'Telnet_Password', 'port', 'version') {
                $host->{$item} =
                    $host->{$item} ||
                    $hosts->{$group}->{$item} ||
                    $hosts->{$item} ||
                    $Default_SNMP{$item};
            }
            $host->{group} = $group;

            push @hosts, $host;
        }
    }

    return \@hosts;
}