package Logic::Subnet;

use strict 'vars';
use Logic;
use Agent::T3;
use Logic::SWITCH;
use Agent::MCDATA;
use Logic::SE;
use Agent::9900;


# DISCOVER IP_LIST (used by Client::Discover)
#  monitor_on => "Y", prefix => "PREFIX"
#  callback => "deviceip"
#  type => "6130"
#
sub discover_ip_list {
  my($q) = @_;
  my @parts = split(/,/, $q->{ip_list});
  my ($x,@complete_list);
  $DB::single=1;

  foreach my $el (@parts) {
    if ($el =~ /^\d+\.\d+/) {                   # ip-number
      if ($el =~ /^\d+\.\d+\.\d+$/) {         # prefix
        for ($x=1; $x <= 254; $x++) {
           push(@complete_list, "$el.$x");
        }
      } elsif ($el =~ /^\d+\.\d+\.\d+\.\d+$/) { # specific IP
        push(@complete_list, $el);

      } elsif ($el =~ /^(\d+\.\d+\.\d+)\.(\d+)\-(\d+)$/) { # IP range
        my $ip    = $1;
        my $start = $2;
        $start = 1 if ($start < 1);
        my $end   = $3;
        $end = 254 if ($end > 254);
        for ($x=$start; $x <= $end; $x++) {
          push(@complete_list, "$ip.$x");
        }
      }
    } else {                                    # ip_address
      push(@complete_list, $el);
    }
  }
  
  my $start = 0;
  my(@L);

  while ($start <= $#complete_list) {
    my $end = $start+9;
    $end    = $#complete_list if ($#complete_list < $end);
    my @range = @complete_list[$start..$end];
    my $out = Logic::Subnet->snmpget_range( "public 1.1.0", \@range, 10, $q);
    foreach my $node (@$out) {
      use Data::Dumper;
      $Data::Dumper::Indent=0;
      Debug->print2("  FOUND DEVICE: " . Dumper($node));

      $node->{prefix}     = $q->{prefix}     if ($q->{prefix});
      $node->{monitor_on} = $q->{monitor_on} if ($q->{monitor_on});
      $node->{access_mode} = $q->{access_mode} if ($q->{access_mode});
      if ($q->{callback}) {
         Discover->logit($node->serial(), $q->{callback});
      }
      push(@L, $node);
    }
    $start += 10;
  }

  return \@L;
}

sub get_snmpdata {
  my($q) = @_;
  my(%T, @a, $ip, $out);
  my(%F, $d, $found, $l );
  my($xx, $sub, $remote, $x);

  $remote   = $q->{REM};

  my(@L);
  for ($x=1; $x <= 6; $x++) {
     $sub = $q->{"SUB$x"};
     next if ($sub !~ /^\d+\./);
     foreach my $x (0,20,40,60,80,100,120,140,160,180,200,220,240) {

        my $first = $x;
        my $last  = $x+19;
        $first = 1   if ($x == 0);
        $last  = 254 if ($x == 240);
        
        print "Probing ports $sub: $first..$last \n" if (!$remote);
        $out = Logic::Subnet->snmpget($sub, "public 1.1.0", $first, $last, $q->{timeout});

        foreach my $node (@$out) {
           push(@L, $node);
        }
     }
  }
  if ($remote) {
     print "OK" . join("\n", @L);
  } else {
     return \@L;
  }
}

sub snmpget_range {
  my($func , $snmp_info, $range, $sleep_time, $args) = @_;
  my($err, $l, $ipno, $comm, $cnt, $ret);
  if (!-d "/tmp") {
     mkdir "/tmp" , 0777;
  }
  # IF TYPE IS KNOWN, SKIP the SNMP STUFF.
  if ($args->{type}) {
    my (@out);
    foreach my $ipno (@$range) {
      Logic::Subnet->snmp_device($ipno, "", \@out, $args);
    }
    return \@out;
  }

  $sleep_time = 5 if (!$sleep_time);
  $sleep_time = 2 if ($sleep_time == 1);

  my($prog) = System->get_home() . "/snmp/bin/snmpget";
  foreach my $el (@$range) {
     unlink("/tmp/snmp_$el");
  }

  Debug->print2("snmpget_range: @$range");
  my %SKIP;
  foreach $ipno (@$range) {
     if (Util->ping($ipno, 5)) {
       $comm = "$prog -t " . ($sleep_time-1) ." -r 0 $ipno $snmp_info > /tmp/snmp_$ipno 2>&1";
        system("$comm&");
     } else {
        Debug->print1("Cannot ping $ipno, skipping!");
        $SKIP{$ipno} = 1;
     }
  }
  sleep($sleep_time+1);
  $cnt= 0;
  my (@out);
  foreach my $ipno (@$range) {
     next if ($SKIP{$ipno});
     open(O, "/tmp/snmp_$ipno");
     $ret = <O>; close(O);
     unlink("/tmp/snmp_$ipno");
     chop($ret);

     Logic::Subnet->snmp_device($ipno, $ret, \@out, $args);
  }
  return \@out;
}


sub snmpget {
  my($func , $ip, $f, $start, $end, $sleep_time) = @_;
  my($err, @out, $l, $x, $ipno, $comm, $cnt, $ret);
  if (!-d "/tmp") {
     mkdir "/tmp" , 0777;
  }

  $sleep_time = 5 if (!$sleep_time);
  $sleep_time = 2 if ($sleep_time == 1);

  my($prog) = System->get_home() . "/snmp/bin/snmpget";
  for ($x = $start; $x <= $end; $x++) {
     unlink("/tmp/snmp_$x");
  }
  for ($x = $start; $x <= $end; $x++) {
     last if ($x > 254);
     $ipno = "$ip." . $x;
     $comm = "$prog -t " . ($sleep_time-1) ." -r 0 $ipno $f > /tmp/snmp_$x 2>&1";
     system("$comm&");
  }
  sleep($sleep_time+1);
  $cnt= 0;
  for ($x = $start; $x <= $end; $x++) {
     last if ($x > 254);
     open(O, "/tmp/snmp_$x");
     $ret = <O>; close(O);
     unlink("/tmp/snmp_$x");

     chop($ret);
     $ipno = "$ip." . $x;
     Logic::Subnet->snmp_device($ipno, $ret, \@out);
  }
  return \@out;
}


sub snmpget1 {
  my($func , $ipno, $f, $sleep_time) = @_;

  $f = "public 1.1.0" if (!$f);
  $sleep_time= 5 if (!$sleep_time);

  my($prog) = System->get_home() . "/snmp/bin/snmpget";

  my $comm = "$prog -t $sleep_time -r 0 $ipno $f";
  my($err, $out) = Util->run_command($comm, "test", $sleep_time+2);
   
  my $out2 = join("", @$out);
  my @VAL;
  $func->snmp_device($ipno, $out2, \@VAL);
  return \@VAL;
}

use Discover;

sub snmp_device {
  my($class, $ipno, $ret, $out, $args) = @_;

  Debug->print2("$ipno, $ret");
  
  my $disco_object = Discover->fromIP($ipno, { sysDesc => $ret, 
                                                  type => $args->{type},
                                            });

  push(@$out, @$disco_object) if ($disco_object);
}


1;



