#============================================================================
#
# Program: libcli-dis.pl
# Programmer: ?
#
#============================================================================
package cli;
use dis;

# original my $prompt = '/(?m:^[\w.-]+\s?(?:\(config[^\)]*\))?\s?[\$#>]\s?(?:\(enable\))?\s*$)/';
my $prompt = '/.+?[#>]\s?(?:\(enable\)\s*)?$/';

#============================================================================
# Find login, if device is compatible for mac-address-table or config retrieval
#============================================================================
sub PrepDev{

	my $us    = "";
	my $nok   = 2;										#  clibad=2 means very true ;-)
	my $pnmap = 1;										# port not mapped -> ssh will be tried...
	my @users = @misc::users;

	if($_[1] eq "fwd" and $main::dev{$_[0]}{os} !~ /^IOS/){					# Only IOS has support for mac-address stuff
		return $nok;
	}
	if(defined $main::dev{$_[0]}{cp} and $main::dev{$_[0]}{cp} != 0){			# Undef -> it's new, 0 -> set to be prepd
		if(!$main::dev{$_[0]}{us}){							# Do we have a  user?
			print "Pu";
			return $nok;								# No user but a real port -> failed before
		}elsif(exists $misc::login{$main::dev{$_[0]}{us}}){				# OK if in nedi.conf
			return 0;								# Lets use that then (clibad=false)
		}else{
			print "Pc";								# User not in nedi.conf -> Prep
		}
	}
	if(defined $misc::map{$main::dev{$_[0]}{ip}}{cp}){					# Disable SSH upon telnet port map
		$main::dev{$_[0]}{cp} = $misc::map{$main::dev{$_[0]}{ip}}{cp};
		print "M$main::dev{$_[0]}{cp}" if $main::opt{d};
		$pnmap = 0;
	}else{
		$main::dev{$_[0]}{cp} = 23;
	}
	if( $main::dev{$_[0]}{os} =~ /^(Cat1900|NoTrtel)/){	# Nortel doesn't work (yet) due to ESC sequences and the login screen...
		do {
			$us = shift (@users);
			print " P:$us" if $main::opt{d};

			DIS CODE HERE (see lib-netssh to get ideas)

		} while ($#users ne "-1" and $nok);						# Stop if ok or we ran out of logins
	}else{
		$main::dev{$_[0]}{cp} = 0;							# Port=0 for unsupported device
		return $nok;
	}
	if($nok){
		print "Tu";
	}else{
		print ":$main::dev{$_[0]}{cp} " if $main::opt{d};
		$main::dev{$_[0]}{us} = $us;
		sleep 1;									# Some (HP)devices need a pause
	}
	return $nok;
}

#============================================================================
# Get Ios mac address table.
#============================================================================
sub BridgeFwd{

	my $line = "";
	my $nspo = 0;
	my @cam  = ();
	my $cmd  = "sh mac-address-table dyn";
	my $cmd2  = "sh port-security addr";							# Thanks Duane Walker 7/2007
	my $cap  = 0;

	if($main::dev{$_[0]}{os} eq "IOS-wl"){							# Cisco WLan specific...
		$cap = 1;									# Needed to avoid using counters as vlans
		$cmd = 'sh bridge | exclude \*\*\*';						# Work around aged (***) forwarding entries
	}
	print " F:$main::dev{$_[0]}{us}:$main::dev{$_[0]}{cp} " if $main::opt{d};

	DIS CODE HERE (see lib-netssh to get ideas)

	foreach my $l (@cam){
		if ($l =~ /\s+(dynamic|forward|secure(dynamic|sticky))\s+/i){			# (secure) Thanks to Duane Walker 7/2007
			my $mc = "";
			my $po = "";
			my $vl = "";
			my @mactab = split (/\s+/,$l);
			foreach my $col (@mactab){
				if ($col =~ /^(Gi|Fa|Do|Po|Vi)/){$po = &misc::Shif($col)}
				elsif ($col =~ /^[0-9|a-f]{4}\./){$mc = $col}			
				elsif (!$cap and $col =~ /^[0-9]{1,4}$/ and !$vl){$vl = $col}	# Only use this, if it's not a Cisco AP
			}
			if( exists($misc::portprop{$_[0]}{$po}) ){				# Make sure IFidx exists before using IF
				if($po =~ /\.[0-9]/){						# Does it look like a subinterface?
					my @subpo = split(/\./,$po);
					$vl = $subpo[1];
					if($misc::portprop{$_[0]}{$subpo[0]}{upl}){$misc::portprop{$_[0]}{$po}{upl} = 1}	# inherit uplink metric on subinterface
				}
				$mc =~ s/\.//g;

				if ($vl !~ /$misc::ignoredvlans/){
					if ($po =~ /^.EC-|^Po[0-9]|channel/){
						$misc::portprop{$_[0]}{$po}{chn} = 1;
					}
					$misc::portprop{$_[0]}{$po}{pop}++;
					$misc::portnew{$mc}{$_[0]}{po} = $po;
					$misc::portnew{$mc}{$_[0]}{vl} = $vl;
					print "\n FWC:$mc on $po vl$vl" if $main::opt{v};
					$nspo++;
				}
			}
		}
	}
	print " f$nspo ";
	return 0;
}

#============================================================================
# Fetch  Config and return it in an array.
#============================================================================
sub Config{

	my $go  = 0;
	my $cl	= 0;
	my @run = ();
	my @cfg = ();

	my $cmdrun = "show run";
	my $cmdpag = "terminal length 0";

	if($main::dev{$_[0]}{os} eq "Ironware"){
		$cmdpag = "skip-page-display";
	}elsif($main::dev{$_[0]}{os} eq "ProCurve"){
		$cmdpag = "no page";
	}elsif($main::dev{$_[0]}{os} eq "CatOS"){
		$cmdpag = "set length 0";
		$cmdrun = "show conf";
	}elsif($main::dev{$_[0]}{os} eq "IOS-fw"){
		$cmdpag = "pager 0";
	}
	print " B:$main::dev{$_[0]}{us}:$main::dev{$_[0]}{cp}-$cmdpag/$cmdrun " if $main::opt{d};

	DIS CODE HERE (see lib-netssh to get ideas)

	foreach my $line (@run){
		$line =~ s/[\r\n]//g;
		if ($line =~ /^(Running|Current|PIX|FWSM|ASA)\s|^begin$/){$go = 1}
		if ($go and $line !~ /--More--|^$/){
			print "\n CFG:$line" if $main::opt{v};
			push @cfg,$line;
			$cl++;
		}
	}
	if( defined($cfg[$#cfg]) ){ 
		if($cfg[$#cfg] eq "" ){pop @cfg}						# Remove empty line at the end.
	}else{											# Empty config can't be good...
		push @cfg,"Empty config!";
	}
	print "Bf";
	print "-$cl" if $main::opt{d};
	return @cfg;
}

1;
