#!/bin/sh
#
#	Discovery() - Discover the backbone
#
#
#
TIMEOUT=20
RETRIES=20
#SUBNETFILTER=NO
SUBNETFILTER=YES
FAST=YES

#############################################################################
#
#	Usage() - give command line options
#
Usage()
{
	echo usage: $0 network community UniqueID
	rm /tmp/*$$
	exit 1
}

#############################################################################
#
#	GetASNeighbors(): EGP Peers
#
GetASNeighbors()
{
	echo `date` 'GetASNeighbors('$UniqueID')' - this may take a while
	snmptable2 -r $RETRIES -t $TIMEOUT -c $community -h $UniqueID egpNeighAs | sed '1,$s/egpNeighAs.//g' | awk '{ print $2":"$3 }' > /tmp/egpNeighAs$$
	snmptable2 -r $RETRIES -t $TIMEOUT -c $community -h $UniqueID egpNeighState | sed '1,$s/egpNeighState.//g'  | awk '{ print $2" "$3 }'> /tmp/egpNeighState$$
	echo egpNeighAs
	cat /tmp/egpNeighAs$$
	echo egpNeighState
	cat /tmp/egpNeighState$$
	cat /tmp/egpNeighAs$$ /tmp/egpNeighState$$ | grep 'Did' 
	if [ $? -eq 0 ]
	then
		echo `date` no answer from $UniqueID
	rm /tmp/*$$
		exit 1
	fi
	for peer in `cat /tmp/egpNeighState$$ | awk '{ if ( $2 = "4" ) print $1}'`
	do
		ASNum=`cat /tmp/egpNeighAs$$ | grep $peer':' | awk -F: '{ print $2 }'`
		echo = 0 $UniqueID NODE AS $ASNum NotKnown UP
		echo  0 NODE AS NotKnown $ASNum UP >>$PINGKYDIR/$network.STATUS
		echo = 0 $UniqueID LINK ASLINK $UniqueID $ASNum UP
		echo  0 LINK ASLINK $UniqueID $ASNum UP >>$PINGKYDIR/$network.STATUS
	done
}

#############################################################################
#
#	GetMySubNet()
#
GetMySubNet()
{
	MySubNet=`echo $UniqueID | awk -F. '{ 
		if ( $1 <= 127 ) print $1
		else if ( $1 <=191 ) print $1"."$2
		else print $1"."$2"."$3
		}'`
	echo My Sub Net is $MySubNet

}

#############################################################################
#
#	GetNextHopTable() - issue the SNMP queries to fetch NextHop table
#			store the result in /tmp/NextHops$UniqueID
#
GetNextHopTable()
{
	echo `date` 'GetNextHopTable('$UniqueID')' - this may take a while
	snmptable2 -r $RETRIES -t $TIMEOUT -c $community -h $UniqueID ipRouteNextHop | \
		grep -v '0.0.0.0' >/tmp/neighbors$$
	cat /tmp/neighbors$$ | grep 'Did' 
	if [ $? -eq 0 ]
	then
		echo `date` no answer from $UniqueID
		rm /tmp/neighbors$$
		exit 1
	fi
	cp /tmp/neighbors$$ $network/NODES/${UniqueID}.RoutingTable
	cat /tmp/neighbors$$ | awk '{ print $3 }' | grep -v $UniqueID | sort | uniq > $network/NODES/${UniqueID}.NextHops
	echo `date` Done getting NextHops for $UniqueID
}

GetHostUniqueIDDNSName()
{
	NewUniqueID=`cat /tmp/ipAdEnt$$ | grep -v $MySubNet | awk -F: '{ print $1}'`
	if [ "$NewUniqueID" != "" ]
	then
		UniqueID=`echo $NewUniqueID | awk '{ print $1}'`	#Only one addr!
	fi
	UniqueIDDNSName=`./gethostname $UniqueID`
	echo '****----> UniqueID: '$UniqueID $UniqueIDDNSName' <----****'
}

#############################################################################
#
#	MakeNODEInterfaceTable() - make the node interface table for this UniqueID
#		This serves three purposes:
#			1) Shows that this node has been explored
#			2) Provides a list of IPAddresses for this UniqueID
#			   providing a IPAddr->Node Unique Identifier mapping
#			3) Provides a mapping to interface #
#
#
MakeNODEInterfaceTable()
{
	#
	#	Now, get the ipAdEntIndex values so we can
	#	determine which of these next hops are part of the backbone
	#
	#	This file is also consulted when trying to make ends meet
	#
	snmptable2 -r $RETRIES -t $TIMEOUT -c $community -h $UniqueID ipAdEntIfIndex \
		| sed '1,$s/ipAdEntIfIndex.//g' \
		| awk '{ print $2":"$3 }' > /tmp/ipAdEnt$$
	cat /tmp/ipAdEnt$$ | grep 'Did' 
	if [ $? -eq 0 ]
	then
		echo `date` ERROR: no answer from $UniqueID
		rm /tmp/ipAdEnt$$
		exit 1
	fi
	GetHostUniqueIDDNSName

	cat /tmp/ipAdEnt$$ > $network/NODES/${UniqueID}.Interfaces
	
	echo ipAdEntIndex: `cat $network/NODES/${UniqueID}.Interfaces`
}

#############################################################################
#	ProcessNextHop() - Deal with this Adjacent neighbor
#
ProcessNextHop()
{
	echo ProcessNextHop: Working on $UniqueID NextHop=$NextHop
	Neighbor=`grep $NextHop':' $network/NODES/*.Interfaces \
		| awk -F/ '{ print $3}' | awk -F: '{ print $1}' | \
		sed '1,$s/.Interfaces//g'`
	echo ProcessNextHop: Neighbor=$Neighbor
	if [ "$Neighbor" = "" ]
	then
		#
		#	We have never seen this interface address before
		#	call this the node's UniqueID- its name.
		#
		# Store remote end addr 
		echo $NextHop >>$network/LINKS/${UniqueID}	
		#echo = 0 LINK ISISLINK $UniqueID $NextHop UP
		#echo  0 LINK ISISLINK $UniqueID $NextHop UP >>$PINGKYDIR/${network}.STATUS
		echo '****' $UniqueID : Discovering new node to get LINKS file information: $0 $network $community $NextHop  
		if [ "$FAST" = "YES" ]
		then
			$0 $network $community $NextHop &
		else
			$0 $network $community $NextHop
		fi
	else
	#
	#	In this case where the neighbor has already been explored
	#	we can use its NODES file to get our local Interface Addr-his
	#	remote end next hop.  We don't know our local end, but can 
	#	infer this from his remote end discovery.
	#
		echo We have already discovered this node $NextHop : $Neighbor shows `cat $network/NODES/${Neighbor}.Interfaces`
		#
		#	for each of my interfaces, see if this neighbor knows
		#	about them
		#
		for interface in `cat $network/NODES/${UniqueID}.Interfaces | awk -F: '{ print $1}'`
		do
			#TESTING BEV localaddr=`cat $network/LINKS/${Neighbor} | grep $interface`
			localaddr=`cat $network/NODES/${Neighbor}.NextHops | grep $interface`
			if [ "$localaddr" != "" ]
			then				#GOT IT
				remoteaddr=$NextHop
				echo '****' my local addr is $localaddr 
				echo '****' remote addr is $remoteaddr 
				localif=`grep $localaddr $network/NODES/${UniqueID}.Interfaces | awk -F: '{ print $2}'`
				remoteif=`grep $remoteaddr $network/NODES/${Neighbor}.Interfaces | awk -F: '{ print $2}'`
				echo =0 $UniqueID $localaddr $localif $remoteif $remoteaddr $Neighbor  0 0 0 
				echo 0 $UniqueID $localaddr $localif $remoteif $remoteaddr $Neighbor  0 0 0 >>$network/${network}.LINKS
				echo =0 LINK ISISLINK $UniqueID $Neighbor UP 
				echo 0 LINK ISISLINK $UniqueID $Neighbor UP >>$PINGKYDIR/${network}.STATUS
				break
			fi
		done
		if [ "$localaddr" = "" ]
		then
			echo ERROR could not determine which of my local interfaces is used on this link
			echo 0 LINK ISISLINK $UniqueID Unknown $NextHop $Neighbor UP
		fi
	fi
}

###########################################################################
#	ProcessNextHopTable() - We have the NextHop table 
#		Determine whether or not we should explore neighbors
#
ProcessNextHopTable()
{
	#
	#	Get rid of my addresses and non-backbone nodes
	#	from the next hop nodes to query
	#
	if [ "$SUBNETFILTER" = "YES" ]
	then
		NextHops=`cat $network/NODES/${UniqueID}.NextHops | grep $MySubNet | awk '{ print ":"$1":" }'`
	else
		NextHops=`cat $network/NODES/${UniqueID}.NextHops | awk '{ print ":"$1":" }'`
	fi
	# Go beyond sub-network boundaries:
	#NextHops=`cat /tmp/NextHops$UniqueID | awk '{ print ":"$1":" }'`
	for MyAddr in `cat $network/NODES/${UniqueID}.Interfaces | awk -F: '{ print ":"$1":" }'`
	do
		NextHops=`echo $NextHops | sed '1,$s/'$MyAddr'//g'`
	done
	NextHops=`echo $NextHops | sed '1,$s/:/ /g'`
	echo $UniqueID NextHops: $NextHops
	if [ "$NextHops" != "" ]
	then  #BEVBEV
		echo = 0 NODE NSS $UniqueIDDNSName $UniqueID UP	
		echo  0 NODE NSS $UniqueIDDNSName $UniqueID UP	>>$PINGKYDIR/$network.STATUS
	else
		echo 0 NODE NSS $UniqueIDDNSName $UniqueID BUSY >>$PINGKYDIR/$network.STATUS
	fi
	#
	#	Process each Next Hop
	#
	for NextHop in $NextHops
	do
		ProcessNextHop		#Process this neighbor
	done
}



#############################################################################
#
#	DiscoverNode() - Discover this node and its attachements
#
DiscoverNode()
{
	GetASNeighbors	#Get A list of ASs that are reachable - output is stdout
	GetNextHopTable	#Results are in $network/NODES/${UniqueID}.NextHops
	ProcessNextHopTable #
}

##########################################################################
#		main
##########################################################################
	if [ $# -ne 3 ]
	then
		Usage
	fi
	network=$1
	shift
	if [ -d $network ]
	then
		echo $network directory already exists
	else
		mkdir $network	
		mkdir $network/NODES
		mkdir $network/LINKS
	fi
	community=$1
	shift
	UniqueID=$1
	echo $UniqueID | grep '\.' >/dev/null
	if [ $? -ne 0 ]
	then
		echo Invalid Node Address - must be IP Address 
		Usage
	fi
	ThisHostName=`./gethostname $UniqueID`
		
	echo '*****************' $network $ThisHostName $UniqueID '***************'
	GetMySubNet	#Figure out the SubNet Addresses to explore
	MakeNODEInterfaceTable 
	DiscoverNode	# Discover this node and attachements
	rm /tmp/*$$
