#!/usr/bin/perl -w # # Input is taken from standard input and we expect something like: # Tue Apr 17 13:50:55 2001 ( No Auth ): @159.148.113.125 [unknown] R 0 0Kb 2 0Kb # Tue Apr 17 13:50:58 2001 (G IP max): @192.167.9.240 [unknown] R 0 0Kb 2 0Kb # Tue Apr 17 13:50:58 2001 ( Unknown ): @ppp-40-94.15-151.iol.it [ffff] - 1 0Kb 2 0Kb # Tue Apr 17 13:51:01 2001 (G IP max): @192.167.9.240 [unknown] R 0 0Kb 2 0Kb # # This script filters No Auth lines and numeric addresses, tries to # make a whoisdb lookup and generates a list of hostmasks to which # ip belong. It also arranges networks in their respective blocks. # # Output is something similar to: # # # PROCESSING SECTION # Querying db for 159.148.113.0... # inetnum: 159.148.0.0 - 159.148.255.255 # netname: LATNET # country: LV # route: 159.148.0.0/16 # 4 matches # Added LATNET block from 159.148.0.0 to 159.148.255.255 route 159.148.0.0/16 # 159.148.113.0 belongs to LATNET block # Querying db for 200.61.148.0... # 0 matches # .... # # FILTERING RESUME SECTION # ============================ # netname: LATNET # country: LV # inetnum: 159.148.0.0 - 159.148.255.255 # route: 159.148.0.0/16 # networks: 159.148.113.0 23 connection/s # ============================ # .... # # I-LINES GENERATION SECTION # I:159.148.0.0/16::::2 # LV LATNET # I:195.129.0.0/16::::2 # EU ALET-IT # I:194.153.208.0/22::::2 # IT NOICOM-NET # Written by Rocco Lucia (rlucia@iscanet.com, http://elisa.utopianet.net/~rlucia ) # Fri Apr 20 03:11:17 CEST 2001 # This code is distributed under a BSD style license. You are free # to do with it as you please. Yes, I bet you won't live without it. use Socket; $whoisbin = "/usr/bin/whois"; $ircd_iclass = "2"; # first of all we get numeric IP addresses and No Auth lines # we also filter out duplicates %seen = (); while(<>) { if(/(\w+) (\w+) (\d+) (\d+):(\d+):(\d+) (\d+) \( No Auth \)\: \<(\w+)\>\@(\d+).(\d+).(\d+).(\d+) (.*)$/) { $elem = $9.".".$10.".".$11.".0"; push(@ipaddr,$elem) unless $seen{$elem}++; $count{$elem}++; } } print "# PROCESSING SECTION\n"; # let's check each c-class foreach $addr (@ipaddr) { $addrnum = inet_aton($addr); $not_exist = 1; # a c class may belong to a block foreach $network (@networks) { if( ($addrnum ge $b_start{$network}) && ($addrnum le $b_stop{$network})) { print $addr." belongs to ".$network." block\n"; push(@{ $cclasses{$network} },$addr); $not_exist = 0; last; } } # or not belong to any block if($not_exist) { $#whois = 0; $m = 0; $netname = ""; $country = ""; $route= ""; $netnum_start = ""; $netnum_stop= ""; # so we query WHOISdb print "Querying db for ".$addr."...\n"; open(WHOIS, $whoisbin." -h whois.ripe.net ".$addr." |"); # ... parse whois output while($line = ) { push(@whois,$line); if($line =~ m/^netname\:\s+(.*)$/) { $netname = $1; print "netname:\t".$netname."\n"; $m++; } if($line =~ m/^route\:\s+(\d+).(\d+).(\d+).(\d+)\/(\d+)(.*)$/) { $route = $1.".".$2.".".$3.".".$4."/".$5; print "route:\t".$route."\n"; $m++; } if($line =~ m/^country\:\s+(\w+)(.*)$/) { $country = $1; print "country:\t".$country."\n"; $m++; } if($line =~ m/^inetnum\:\s+(\d+).(\d+).(\d+).(\d+) - (\d+).(\d+).(\d+).(\d+)(.*)$/) { $netnum_start = $1.".".$2.".".$3.".".$4; $netnum_stop = $5.".".$6.".".$7.".".$8; print "inetnum:\t".$netnum_start." - ".$netnum_stop."\n"; $m++; } } close(WHOIS); print $m." matches\n"; # we also fix route block if db doesn't have it if($m eq 3 && $route eq "") { print "I didn't find any route info for ".$netname.". Figuring out netblock... "; $numbits = 0; $mask = 0; $diff = inet_aton($netnum_start) ^ inet_aton($netnum_stop); $bits = unpack("B32", $diff); $bits =~ s/^0+(?=\d)//; print $bits." "; $_ = $bits; while(/(\d)/gc) { $numbits++; if($1 eq "1") { $mask = $numbits; }; } $route = $netnum_start."/".(32-$mask); print $route."\n"; } # and fill up our tables if($m eq 4) { $network = $netname; push(@networks,$netname); $block{$network} = $route; $country{$network} = $country; $b_start{$network} = inet_aton($netnum_start); $b_stop{$network} = inet_aton($netnum_stop); print "Added ".$network." block from ".$netnum_start." to ".$netnum_stop." route ".$route."\n"; print $addr." belongs to ".$network." block\n"; push(@{ $cclasses{$network} },$addr); } } } # now we print netblocks with respective networks print "# FILTERING RESUME SECTION\n"; foreach $network (@networks) { print "============================\n"; print "netname:\t".$network."\n"; print "country:\t".$country{$network}."\n"; print "inetnum:\t".inet_ntoa($b_start{$network})." - ".inet_ntoa($b_stop{$network})."\n"; print "route:\t\t".$block{$network}."\n"; foreach $cclass (@{ $cclasses{$network}}) { print "networks:\t".$cclass."\t".$count{$cclass}." connection/s \n"; } } # and I-lines as we will add them in ircd.conf print "# I-LINES GENERATION SECTION\n"; foreach $network (@networks) { print "I:".$block{$network}."::::".$ircd_iclass." # ".$country{$network}." ".$network."\n" };