#!/usr/bin/env perl

# Set some vars

# Filter on netmask
$MASK = $ARGV[0];
# Otherwise return all.
if ( ! $MASK ) {
  $MASK = ".*";
}

# Print the header
print "Node 1 name, Node 1 ip, Node 2 ip, $node 2 name\n";

use File::Basename;

sub parse_config {
  # Set some vars;
  my $workingfile = $_[0];
  my $id = $_[1];

  # Undifine config, to avoid polution
  undef %config;

  # Load config file
  do($workingfile);

  # Run through all the interfaces
  foreach my $if (keys %config) {

    # Config file has interface with semicolumn in it, not possible to use these a vars.
    $ifwithsemicolumn=$if;
    $if=~s/://g;

    # Get interface info
    my $cfg=$config{$ifwithsemicolumn};

    # Run through all the parameters of the interface
    while ($cfg) {

      # Remove newlines
      $cfg=~s/^([^\n\r]+)[\r\n]*//m;

      # Get first word from the sentence
      my $line=$1;

      # Remove unwanted characters
      $line=~s/\s*#.*//;

      # Split key and values
      if (((my $name, my $value)=split(/=/,$line)) eq 2) {

        # Create a variable of the splited info
        my $doit = "\$$if\_$id\{\"$name\"\}=\"$value\";";
        eval($doit);
      };

      # Remove newlines
      $cfg=~s/[\r\n]*$//m;
    };
  };
};


sub getneighboril {
  ## I got an IP, just want to know to which node it belongs

  # Get ip from parent
  $search=$_[0];

  # Open the config file dir
  opendir ($il_hdir, $dir);

  # Run through all the Nodes in the specified directory.
  while (my $il_node = readdir($il_hdir)) {

    # Only Allow Directories which represent Nodes
    if ($il_node =~ /^CNode/) {

      # Read config file
      $file="$il_node/$configfile";
      parse_config("$file", "il");
 
      # Run through all the interfaces  in the config file
      foreach my $il_if (sort keys %config) {

        # Told you before, can't have semicolumns in variable names
        $il_if=~s/://g;

        # Get the ipinfo of the interface
        $il_ip = getvar($il_if, "IP", "il");

        # Split the ip and the subnetmask
        (my $il_ip, my $il_mask) = split(/\//, $il_ip);

        # Match the current ip of node/if with the ip specified in the search
        # Match the netmask specified
        if (($il_ip eq $search) && ($il_mask =~ /$MASK/)) {
          return $il_node;
        }
      }
    }
  }
}




sub getvar {
  ## Make an var from different variabls

  # Get var from parent
  $if=$_[0];
  $var=$_[1];
  $id=$_[2];

  # Make the var, just forgor why this works :-) (yes I made it myself). Didn't specify the value of the var
  $retval = eval("\$$if\_$id\{\"$var\"\}");
  return $retval;
}

sub getneighborip {

  ## The the ip of the neighboring interface

  # Get var (ip) from parent
  $ip=$_[0];

  # Split ip into oclets
  (my $oclet1, my $oclet2, my $oclet3, my $oclet4) = split(/\./, $ip);

  # Mod the 4th oclet
  $neighbor = $oclet4 % 4;

  # 0 = network address, 1 is what we want, 2 makes double values, 3 is broadcast address
  if ($neighbor eq 1) {

    # Upper the 4th oclet by one (which makes the 2 if the previous comment 
    $oclet4++;
  }

  # Make the neightboring ip address
  $neighbor="$oclet1.$oclet2.$oclet3.$oclet4";

  # If the neighbor and this ip match, we return zero the block further actions
  if($neighbor eq $ip) {
    return NULL;
  }  

  # Return neighboring ip
  return $neighbor;
}

# Get relative path of the genesis config dir
$dir=dirname(".");

# wleiden.con fconfig file
$configfile="wleiden.conf";

# Open genesis config directory
opendir ($main_hdir, $dir);

# Run through all items in this directory
while (my $main_node = readdir($main_hdir)) {

  # Only open config file which have CNode in the name
  if ($main_node =~ /^CNode/) {
    $main_file="$main_node/$configfile";
    parse_config("$main_file", "main");

    # Run through all the interface in the config file
    foreach my $main_if (sort keys %config) {

      # Told you before, can't have semicolumns in variable names
      $main_if=~s/://g;

      # Get the ipinfo of the interface
      $main_ip = getvar($main_if, "IP", "main");

      # Get the interface type
      $main_extra_type = getvar($main_if, "EXTRA_TYPE", "main");

      # Seperate ip and subnet mask
      (my $main_ip, my $main_mask) = split(/\//, $main_ip);

      # We only want /30 netmasks and eth2wifibridges 
      if(($main_mask eq 30) && ($main_extra_type =~ /eth2wifibridge/i)) {

        # Get the neighboring ip
        $main_neighbor = getneighborip($main_ip);

        # Disregard if empty.
        if($main_neighbor) {

          # Search the name of the neighboring Node
          $main_nodename = getneighboril($main_neighbor);

          # Can be empty for valid reasons, but needs the disregarded
          if ($main_nodename) {
             
             # Print the information we have collected
             print "$main_node,$main_ip,$main_neighbor,$main_nodename\n";
          }
        }
      }
    }
  }
}

exit 0
