#!/usr/bin/perl
# fixsenao is a script that tries to work around the senao mac rewriting bug.
# It looks for packets that are sent to the broadcast mac address, grabs
# the IP address those packets were sent to, and sends a single ping packet
# from that IP address back across the senao to seed its arp table.
#
# Copyright 2004 Matt Kemner <matt@kemner.com.au>
# permission to use and distribute under the GNU GPL is granted.

if (! defined $ARGV[1]) {
  print "usage: $0 interface ip_address\n\n";
  print "       interface  = interface to monitor. This must be the ethernet\n";
  print "                    interface the Senao is plugged into\n";
  print "       ip_address = IP address to send the ping to. This must be\n";
  print "                    on the other side of the Senao.\n";
  exit;
}
$int=shift;
$destip=shift;


# We want our pipes to be piping hot(tm)
$|=1;
# grab all packets with a destination mac of ff:ff:ff:ff:ff:ff
open (TCPDUMP, "/usr/sbin/tcpdump -lnfpei $int ether dst ff:ff:ff:ff:ff:ff and not arp|");
while (<TCPDUMP>) {
  $line = $_;
  chomp $line;
  # ignore lines that don't start with timestamps
  next if $line !~ /^\d+\:\d+\:\d+/;
  # ignore arp packets
  next if $line =~ /arp who-has/;
  # ignore DHCP
  next if $line =~ /bootp/;
  print "$line\n";
  # grab the destination IP
  $line =~ s/^.*> (10\.\d+\.\d+\.\d+)(?:\:|\.).*$/$1/ or next;
  # ignore IP broadcasts.  I know this doesn't cover all cases, but is a good
  # start for now.
  next if $line =~ /255$/;
  print "$line\n";
  # send a faked ping packet to seed the senao cache
  system ("icmpush -echo -sp $line -data 'stupid senao bug' -to 0 $destip");
  #print ("icmpush -echo -sp $line -data 'stupid senao bug' -to 0 10.60.15.245");
}
close (TCPDUMP);
