#!/usr/bin/perl ######################################################################### ######################################################################### # MRTG IPChains Probe # (C) 1999 Robert Gash # gashalot@gashalot.com (www.gashalot.com) # # Distributed under the GNU GPL. # THE AUTHOR IS NOT RESPONSIBLE FOR ANY DAMAGE TO YOUR SYSTEM CAUSED BY # THIS PROGRAM. BY EXECUTING THIS PROGRAM YOU DO SO AT YOUR OWN RISK. # # $Id: mrtg-ipchains-devel.pl,v 0.4 1999/03/05 13:36:21 gashalot Exp gashalot $ # This is a development version written for the linux-net mailing list. # # This program reads the current data from /proc/net/ip_fwchains and prints # out data that can be used in MRTG. # # To use this probe in MRTG simply copy the standard config from a router and # edit the first line to look like this: # # Target[max.cybermax.net-80]: `/usr/local/noc/mrtg/run/mrtg-ipchains-probe.pl -i 207.19.133.11 -p 80 -m 255.255.255.255 -r accept` # # USAGE: # -i IP address (used as source and desitnation for stats) # -p port (the port, use 0 if you want stats for ALL traffic) # -m netmask (the netmask of the client, single hosts are 255.255.255.255) # -r policy (the policy, whether to accept or deny) # # TODO: # 1. Finish code to allow user to specify which chain to check in. # 2. Figgure out why the getopts will not work in the die line so the probe # will die if it isn't supplied all options. # 3. Provide facilities for host uptime and hostname to spit back to # MRTG. ############################################################################ ############################################################################ # Key to our @line, which contains data from /proc/net/ip_fwchains # @line[8] = input bytes # @line[10] = output bytes # @line[2] = source/mask->dest/mask # @line[11] = source port # @line[12] = dest port # @line[1] = chain name # @line[18] = rule name (accept/deny) # Call modules to handle the options and the hostname lookups use Socket; use Getopt::Std; $Usage = "mrtg-ipchains-probe -i host -p port -r policy -m netmask\n"; $Usage .= "\n-i host : host to run the checks on\n"; $Usage .= "-p port : port to check \(0 if all ports\)\n"; $Usage .= "-r policy : whether this is accept or deny policy\n"; $Usage .= "-m netmask : the netmask \(dotted quad\). Single hosts have 255.255.255.255\n"; # I need to figgure out why this won't die here, because you can possibly # omit the needed values until I fix this. #die $Usage unless getopt('impr', \%opts); # Get the commandline options. getopt('impr', \%opts); # Read the commandline options into the variables we need. $ip = $opts{i}; $mask = $opts{m}; $ipport = $opts{p}; $targetpolicy = $opts{r}; # Read our ip_fwchains data into an @RRAY open(FILE, "/proc/net/ip_fwchains"); @FILE = ; close(FILE); # Process each line of the ip_fwchains file foreach $line (@FILE) { # split our $line into @line where there is 1 or more space @line = split(/ +/, $line); # split our our source and destination addresses ($source, $dest) = split(/-\>/, @line[2]); # split our source address and netmask ($sip, $smask) = split(/\//, $source); # split our destination and netmask ($dip, $dmask) = split(/\//, $dest); # input and output. THIS IS WRONG, THE $input variable is REALLY the # of # packets that have been used. I have just been to lazy to fix this, since it # dosen't impede program preformance. $input = @line[8]; $output = @line[10]; # Split out our ports into the begin and end port. We only use the begin # port right now. (for both the send and dest ports) ($sbegport, $sendport) = split(/-/, @line[11]); ($dbegport, $dendport) = split(/-/, @line[12]); # change the 8 character HEX field into an IP address/netmask $sip = inet_ntoa(pack("H*",$sip)); $smask = inet_ntoa(pack("H*",$smask)); $dip = inet_ntoa(pack("H*",$dip)); $dmask = inet_ntoa(pack("H*",$dmask)); # If we match on the source address read the data into the targetout var if ($sip eq $ip && $smask eq $mask && $sbegport == $ipport && @line[18] =~ /$targetpolicy/i) { # print "$sip\/$smask -> $dip\/$dmask In: $input Out: $output\n"; # print "\t Source begin: $sbegport Source end: $sendport\n"; # print "\t Dest begin: $dbegport Dest end: $dendport\n"; $targetout = $output; # if we match the destination address read the data into the targetin var } elsif ($dip eq $ip && $dmask eq $mask && $dbegport == $ipport && @line[18] =~ /$targetpolicy/i) { # print "$sip\/$smask -> $dip\/$dmask In: $input Out: $output\n"; # print "\t Source begin: $sbegport Source end: $sendport\n"; # print "\t Dest begin: $dbegport Dest end: $dendport\n"; $targetin = $output; } } # print our target output and input back out so MRTG can use them. print "$targetin\n"; print "$targetout\n"; # End our wonderful program. exit(0);