#!/bin/sh 
#! perl 
eval 'exec perl -x $0 ${1+"$@"}'
        if 0;

# Graham Phillips <graham@isi.edu>
# Los Angeles,  May 1999.
# 
# Converts MBONE topology file to adjacency list format.
# Usage:
# One argument is required, the name of the MBONE topology file.
# The output is written to stdout.
#
# The MBONE topology file came from Yuri Pryadkin <yuri@isi.edu> and
# has the following format:
# Address: <primary_query_address> group: <IGMP 'group' field> outstanding # : <no>
# <iface 1 addr> (metric, thresh, flags)
#        <nbr 1>
#        <nbr 2>
#        ...
#        <nbr n>
# <iface 2 addr> (metric, thresh, flags)
#        <nbr 1>
#        <nbr 2>
#        ...
#
# where 
#        primary_query_address is the address I'm sending queries to;
#        no - number of outstanding queries sent to the address (if
#                it's more than 3 e.g, this router is probably not
#                responding; perhaps because it's running an older dvrmp
#                version)
#        then there is a list of interfaces with an embedded list of
#        neighbors on each iface.
#
#
# The output file has the following format:
# The first line contains the number of nodes and the number of links
# in the network.  Each remaining line represents a link given as two 
# strings, which are the names of the nodes that the link connects 
# and an additional number (always 1), which represents the hop 
# distance. 
# 
# See http://www.isi.edu/~graham/contrib/index.html for more
# information.

$data_file = $ARGV[0];

sub Usage {
	print "Usage: mbone2adj <mbone_file>\
   Converts an MBONE topology file to an adjacency list format. The adjacency\
   list file is written to stdout.\
   See http://www.isi.edu/~graham/contrib/index.html for more\
   information.\n";
	exit;
}

for ($pass=1; $pass <= 3; $pass++) {
	# We perform 3 passes over the data file.
	# Pass 1: collect host addresses and create (interface,host) 
	#	mapping.
	# Pass 2: if we can't find the (interface,host) mapping for
	#       the interface on the other end of a link then simply
	#	make the interface equivalent to a host.
	# Pass 3: write the output file

	open(FILE, $data_file) || Usage(); 

	if ($pass == 3) {
		printf "$num_vertices $num_links\n";
	}	

	while (!eof(FILE)) {
		do { 
			$_ = <FILE>;
		} while (!eof(FILE) && /^\s*$/);
		$line = $_;
		if (s/^Address:\s*(\S+).*/\1/) {
			chomp;
			$host_address = $_;
			if ($pass == 1) {
				$num_vertices++;
				if (!$host{$host_address}) {
					$host{$host_address} = $host_address;
				}
			}
		} else  {
			die "No Address line\n";
		}
		$_ = <FILE>;
		while (!eof(FILE) && /^(\S+).*$/) {
			if ($pass == 1) {
				s/^(\S+).*$/\1/;
				chomp;
				$if = $_;
				$host{$if} = $host_address;
			} 
			$_ = <FILE>;
			while (!eof(FILE) && /^\t(\S+).*/) {
				s/^\t(\S+).*/\1/;
				chomp;
				$if = $_;
				$neighbour = $host{$if};
				if ($pass == 2) {
					if ($neighbour) {
						$num_links++;
					}
				} elsif ($pass == 3) {
					if ($neighbour) {
						print "$host_address $neighbour 1\n";
					}
				}
				$_ = <FILE>;
			}
		} 
		while (!eof(FILE) && !/^\s*$/) {
			$_ = <FILE>;
		}
	}
	close FILE;
}

