#!/usr/bin/perl -w # A lot of this code is commented out as this code is somewhat # in progress. Currently this code DOES NOT go to the db to check # if ips are good for certain customers, it just gets 250 random ips # that are not in use and hands them off to the modules to create the # natd conf file and the firewall rules. -dan 2/28/04 use NetAddr::IP; use Mysql; use lib qw( /usr/local/bin/exploder/ ); use NAT_EXPLODE qw( build_natd_conf build_ipfw_conf ); use strict; my $now; my $db="sanitized"; my $db_host="sanitized"; my $userid="sanitized"; my $passwd="sanitized"; my $numofips=250; my $dbh = Mysql->Connect($db_host,$db,$userid,$passwd); open LOG,">>/var/log/exploder.log"; #define interfaces my $int = "em0"; my $ext = "em1"; # Reusable counter my $counter=0; $now = `date`; print LOG "\nBegan Run Cycle NOW! $now\n"; undef $now; #get a list of current addresses open ( INET, "/sbin/ifconfig $ext|"); my @old_addrs; while () { if ( $_ =~ /inet/) { s/^\s+//g; my @line = split (/\s+/); push @old_addrs, $line[1]; $counter++; } } print LOG "Counted $counter old addresses on $ext \n\n"; # Reinitialize counter $counter=0; # get 250 ips from the database randomly, that are not in use my $query = " select IP_Address, Netmask from IP_List where In_Use = 0 order by rand() limit $numofips"; my $returnediii = $dbh->query($query); my @ipsandnetmasks; open LASTUSED,">/usr/local/bin/exploder/lastused.txt"; #grabs ips, and sets them listed as in use while (my @output = $returnediii->fetchrow_array) { push @ipsandnetmasks,"$output[0]|$output[1]"; print LASTUSED "$output[0]\n"; $counter++; } foreach (@ipsandnetmasks) { my ($host,$mask) = split(/\|/, $_); print LOG "Marking $host in use (netmask is $mask)\n"; $query = "update IP_List set In_Use = 1 where IP_Address ='$host'"; $dbh->query($query); } print LOG "Counted $counter ips pulled from database\n"; # Reinitalize counter $counter=0; #$number = scalar(@ipsandnetmasks); #print "Ips found for customer $cust_id : $number\n"; # this block sorts the ip addresses and makes sure that the # ipaddress/netmask comination received from the database is valid. my %nets = (); my %mask = (); for (sort @ipsandnetmasks) { # for debuging only -kbbrown print LOG "ipsandnetmasks $counter $_ \n"; my ($host, $mask) = split /\|/, $_, 2; my $net = new NetAddr::IP $host, $mask; $counter++; if (! defined $net) { warn "$host/$mask error!\n"; sleep 1; next; } push @{$nets{$net->network}}, $host; $mask{"$host"} = $mask; } print LOG "\nCounted $counter ips while working on sorting\n"; $counter=0; # BSD is finicky, and when you give it a bunch of ip # addresses all in the same block, the first one you assign MUST have # the real subnet with it, so we do a sort to first identify the # masks, then sort them, and assign the real subnet to the first ip # of each mask *phew*! # modify the netmask to 255.255.255.255 if it's not the first to be # configed in it's ip block. my @addrs; for my $net (sort keys %nets) { my ($first) = undef; for my $host ( @{$nets{$net}} ) { $counter++; my $mask; if (! defined $first) { $first = $host; $mask = $mask{"$host"}; } else { $mask = '255.255.255.255'; } print LOG "Sorted:", $host, "/", $mask, "\n"; push @addrs,"$host,$mask"; } } print LOG "Counted $counter ips while finding first ip in netblock\n"; $counter=0; # ifconfigging new addys # All the real work is done below this line, system calls, db writes, etc # took a sort out before addrs my @hosts; #this actually removes the old addresses from the interface #print "after first sql: " . scalar(@addrs) . "\n"; # We need to remove the routes before we remove the ip addresses # I need the results of these commands to goto the log for debug purposes -kbbrown print LOG "running /sbin/route delete default\n"; my $result = `/sbin/route delete default 2>&1`; print LOG $result; print LOG "running /sbin/route delete -net 130.94.121.144/29\n"; $result = `/sbin/route delete -net 130.94.121.144/29 2>&1`; print LOG $result; # we need to leave one address on the interface but we save it # so that it will be properly marked in the database later. -kbbrown 4/25/05 my $prime_old = shift @old_addrs; foreach (@old_addrs) { print LOG "removing $_ nm 255.255.255.255\n"; system qq( /sbin/ifconfig $ext -alias $_ netmask 255.255.255.255 ); $counter++; } print LOG "Counted $counter ips removed during ifconfig, this should\n"; print LOG "be one less then was on the interface to begin with.\n\n"; $counter=0; foreach (@addrs) { my ($host,$mask) = split(/,/, $_); if ($counter==0) { print LOG "Running ifconfig $ext $host netmask $mask \n"; system qq( /sbin/ifconfig $ext $host netmask $mask ); } else { print LOG "Running ifconfig $ext alias $host netmask $mask \n"; system qq( /sbin/ifconfig $ext alias $host netmask $mask ); } push @hosts,$host; $counter++; } print LOG "Counted $counter ips while ifconfigging new addys\n"; $counter=0; # this should mark the old addresses no longer in use #print "before second sql: " . scalar(@addrs) . "\n"; #print LOG "Counted $counter ips marking old not in use\n"; $counter=0; unshift @old_addrs, $prime_old; foreach my $ipp(@old_addrs) { $query = " update IP_List set In_Use = '0' where IP_Address = '$ipp'"; print LOG "Marking $ipp NOT in use\n"; $dbh->query($query); $counter++ } print LOG "Counted $counter ips while marking ip's not in use\n"; #builds the natd.conf and ipfw.conf files my $natd_conf = &build_natd_conf(@hosts); my $ipfw_conf = &build_ipfw_conf($int, $ext, @hosts); open (NATD,">","/usr/local/bin/exploder/natd.conf"); open (IPFW,">","/usr/local/bin/exploder/ipfw.conf"); # -- open (NATD,">","natd.conf.test"); # -- open (IPFW,">","ipfw.conf.test"); print LOG "Creating files...natd.conf..."; print NATD $natd_conf; print LOG "ipfw.conf..."; print IPFW $ipfw_conf; print LOG "done printing files.\n"; # add routes back in now that all of the ip addresses are back. print LOG "running /sbin/route add -net 130.94.121.144/29 -iface $ext\n"; $result = `/sbin/route add -net 130.94.121.144/29 -iface $ext 2>&1`; print LOG $result; print LOG "running /sbin/route add default 130.94.121.145\n"; $result = `/sbin/route add default 130.94.121.145 2>&1`; print LOG $result; # clear out the ipfw rules and apply the new ones. print LOG "running /sbin/ipfw -f flush\n"; $result = `/sbin/ipfw -f flush 2>&1`; print LOG $result; system qq( sh /usr/local/bin/exploder/ipfw.conf ); # kill natd and restart it. system qq( killall -9 natd ); system qq( /sbin/natd -f /usr/local/bin/exploder/natd.conf ); sleep 10; foreach (@ipsandnetmasks) { my ($host,$mask) = split(/\|/, $_); print LOG "Marking $host in use AGAIN\n"; $query = "update IP_List set In_Use = 1 where IP_Address ='$host'"; $dbh->query($query); } $now = `date`; print LOG "End Run Cycle NOW! $now\n"; close LOG; undef $now;