#!/usr/pkg/bin/perl -w
# port_control - Script that used to be called by front-end of netdisco to 
#                enable and disable ports.
# Max Baker
#
# Usage : port_control [-d] switch port up/down
# exits non zero on problems

# Security : This file houses read-write community strings for switches.  All read access
#			 is disabled except for the web server user.

# Exit Codes:
#   0 - Success
#   1 - Command line args bad
#   2 - Host Problems (probably not up)
#   3 - Bad Port Name, couldn't map back to an IID
#   4 - set() failed.  
#   5 - SNMP Problems (probably bad PW) 

use strict;

use FindBin;
use lib $FindBin::Bin;
use SNMP::Info;
use SNMP::Info::Layer1;
use SNMP::Info::Layer1::Allied;
use SNMP::Info::Layer1::Asante;
use SNMP::Info::Layer2;
use SNMP::Info::Layer2::Bay;
use SNMP::Info::Layer2::C1900;
use SNMP::Info::Layer2::C2900;
use SNMP::Info::Layer2::Catalyst;
use SNMP::Info::Layer2::HP;
use SNMP::Info::Layer3;
use SNMP::Info::Layer3::Aironet;
use SNMP::Info::Layer3::C3550;
use SNMP::Info::Layer3::Foundry;

use vars qw/%args $DEBUG $Host $Port $Dir @Comm/;

use Getopt::Std;
getopts('d',\%args);

$DEBUG = defined $args{d} ? 1 : 0 ;
$Host = shift;
$Port = shift;
$Dir = shift;
# @Comm holds RW community strings
@Comm = qw/read write community strings here/;

unless (defined $Host and defined $Port and defined $Dir) {
    print "ERR: Usage : port_control Switch Port up/down\n";
    quit(1);
}

unless ($Dir =~ /^(up|down)$/) {
    quit(1);
}

print "Connecting to $Host\n" if $DEBUG;

my $dev = undef;

CONNECT:
foreach my $ver (qw/2 1/){
    foreach my $comm (@Comm){
        print "Trying Community String : $comm Version : $ver \n" if $DEBUG;
        $dev = get_dev($comm);
        last CONNECT if defined $dev;
    }
}
quit(5) unless defined $dev;

print "Success.\n" if $DEBUG;
$dev->debug(1) if $DEBUG;

# get interfaces
my $if = $dev->interfaces();

my %map = reverse %$if;

# Map physical name to IID
my $iid = $map{$Port};

quit(3) unless defined $iid;

my $rv = $dev->set_i_up_admin($Dir,$iid);
unless (defined $rv) {
    quit(4);
}
print "$rv\n" if $DEBUG;
exit(0);

#------------------------------------------------------------------

sub get_dev {
    my $Comm = shift;
    my $ver  = shift;
    my $device = new SNMP::Info( 'DestHost'  => $Host,
                                 'Community' => $Comm,
                                 'Version'   => $ver,
                                 'Retries'   => 2
                               );
    
    # Device inaccessable
    quit(2) unless defined $device;

    my $obj = $device->device_type();

    # Device won't accept SNMP settings
    return undef unless defined $obj;

    print "Using object type $obj\n" if $DEBUG;

    $device = new $obj( 'DestHost'  => $Host,
                        'Community' => $Comm,
                        'Version'   => $ver,
                      );

    # Weird.
    quit(2) unless defined $device;

    return $device;
}

sub quit {
    my $err = shift;
    print "quiting with value $err\n" if $DEBUG;
    exit($err);
}

