#!/usr/bin/perl -w # Take 2 Hosting, Inc. # www.Take2Hosting.com # support@take2hosting.com # Copyright 2007-2013 # This script will help configure static IP addresses # on a Take2Hosting server. This may not work correctly # on servers not on the Take2Hosting network. # Please visit: https://www.take2hosting.com/?p=userFaq # for additional information. ## Load libs ## use strict; use Getopt::Long; ### Init variables ### ## Flags ## my $bDebug = 0; # debugging output flag my $bHelp = 0; # help message flag my $bTest = 0; # test flag my $bRemoveIPs = 0; # remove IPs from configuration my $bVPS = 0; # Assign IPs for VPSes my $bNotVPS = 0; # Assign IPs as normal statics my $bForce = 0; # Continue on error ## IPs ## my $sNetworkIP = ''; # network IP for subnet my $sGatewayIP = ''; # gateway IP for subnet my $sBroadcastIP = ''; # broadcast IP for subnet my $sCClass = ''; # AAA.BBB.CCC my $iCIDRNetwork = ''; # CIDR network instead of broadcast my($iNetworkLastOctet, $iBroadcastLastOctet); my $iIPCount = 0; # number of IPs in network my $lastOctet = ''; # temp valiable last octet of current IP my $sSkipIP = ''; # skip an IP in the block (IPMI) ## Other ## my $sInterface = 'eth0'; # physical interface to use my $sOSVersion = `cat /proc/version`; # Version of Linux OS my $sIfconfig = &getIfconfig(); # dump of ifconfig my %interfaceAlias = (); # the eth0:X number for each IP address my $iAlias = ''; # Interface Alias Number ## network masks based on IP count ## my %netmask = ('1' => '255.255.255.255', '4' => '255.255.255.252', '8' => '255.255.255.248', '16' => '255.255.255.240', '32' => '255.255.255.224', '64' => '255.255.255.192', '128' => '255.255.255.128', '256' => '255.255.255.0' ); # CIDR notation => number of IPs # my %CIDRmap = ('32' => '1', '31' => '2', '30' => '4', '29' => '8', '28' => '16', '27' => '32', '26' => '64', '25' => '128', '24' => '256' ); # Number of IPs to CIDR notation # my %CIDRmapReverse = ('1' => '32', '2' => '31', '4' => '30', '8' => '29', '16' => '28', '32' => '27', '64' => '26', '128' => '25', '256' => '24' ); ## Help message ## my $sUsage = "addips --network=FIRST_IP --broadcast=LAST_IP [OPTIONS] addips is a small script that helps Take2Hosting customers configure additional static IPs on a Take2Hosting server. The T2 network routes static IPs differently than some providers, so this script will only work with Take2Hosting. This script must be run as root to work. It will modify your network configuration files, bring up new IP interfaces, and add routes as needed. There is also a Remove Mode to undo changes that the script has made. All file changes will be backed up in the same directory as *.bak or *.removed so you can see the changes always have backup copies of the files. The script will try to detect your OS automatically. Otherwise, you may specify the OS. IPs can be added for the use with a VPS or as just as additional IPs on the server. If they are for a VPS, then use the --vps option. addips comes with a test mode (--test), where the script will not make any changes to the server, but will show you what will happen when not in test mode. You can then make sure the changes will be correct. Then you can run the script again without test mode to make the changes to the server. The changes that the script makes are per our FAQ on configuring additional IP addresses. You may use either this script or use the instructions on our FAQ. The final result is the same. For additional information about configuring IPs, please try: https://www.take2hosting.com/?p=userFaq&search=Configuring+Additional+IP+Addresses Script Command Line Options: --network=IP/CIDR The network IP of the new subnet (CIDR notation optional) --broadcast=IP The broadcast IP of the new subnet --remove Remove IPs instead of adding them [DESTRUCTIVE] --vps Assign IPs for use with VPS (Not static IPs) --static Assign IPs as statics (Not for use with VPSes) --interface=ethX Physical interface to use (Defaults 'eth0') --force Continue past errors --skip=IP Skip an IP in the network block (for IPMI IP) --verbose Show extra information when running --test Do not make changes, but test the command safely --help This message Examples: # Add 10.0.0.0 - 10.0.0.7 (/29) to XenServer 5.5 ./addips --network=10.0.0.0 --broadcast=10.0.0.7 You may also use CIDR Notation for the same command ./addips --network=10.0.0.0/29 # Add 10.0.0.0 - 10.0.0.7 (/29) to XenServer 5.5 with Verbose output and in Test Mode # In test mode, nothing on the server will change, but it will show you the steps # You should always use test mode first to make sure this is the correct change. ./addips --network=10.0.0.0 --broadcast=10.0.0.7 -v --test # Removing 10.0.0.0 - 10.0.0.7 (/29) from XenServer 5.5 with Verbose output # Remove Mode will undo changes that this script did before ./addips --network=10.0.0.0 --broadcast=10.0.0.7 -v --remove ## Supported OSes ## This script should only be expected to work on these OSes: RedHat EL5 RedHat EL6 CentOS 5.* CentOS 6.* Fedora 8-14 Ubuntu 10.10 - 12.10 XenServer 5.5 - 5.6 It may work outside of these, but is not designed to... Use at your own risk for other OSes or versions. "; # get command line options... # if (!GetOptions( 'network=s' => \$sNetworkIP, 'broadcast=s' => \$sBroadcastIP, 'remove' => \$bRemoveIPs, 'vps' => \$bVPS, 'static' => \$bNotVPS, 'os=s' => \$sOSVersion, 'force' => \$bForce, 'skip=s' => \$sSkipIP, 'verbose+' => \$bDebug, 'test+' => \$bTest, 'help' => \$bHelp )) { print("\nUSAGE: $sUsage\n"); exit(0); } # if '--help' was called, then print end exit # if($bHelp){ print("USAGE: $sUsage\n"); exit(0); } ###################### ## Validate Options ## ###################### # Check for network (required option) # if($sNetworkIP !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ && $sNetworkIP !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/){ print "\n!!! The network IP that you provided ($sNetworkIP) is not correct. Please correct the IP and try again. (ie '--network=10.0.0.0' or '--network=10.0.0.0/29')\n"; print("USAGE: $sUsage\n"); exit(0); } # Check for CIDR notation # if($sNetworkIP =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3})\.(\d{1,3})\/(\d{1,2})$/){ $sCClass = $1; $iNetworkLastOctet = $2; $iCIDRNetwork = $3; $sNetworkIP = "${sCClass}.$iNetworkLastOctet"; # update broadcast data based on CIDR # $iBroadcastLastOctet = $iNetworkLastOctet + $CIDRmap{$iCIDRNetwork} - 1; $sBroadcastIP = "${sCClass}.$iBroadcastLastOctet"; } else { # parse network # if($sNetworkIP =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3})\.(\d{1,3})$/){ $sCClass = $1; $iNetworkLastOctet = $2; } # parse broadcast # if($sBroadcastIP =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3})\.(\d{1,3})$/){ $sCClass = $1; $iBroadcastLastOctet = $2; # determine CIDR from broadcast # $iIPCount = ($iBroadcastLastOctet - $iNetworkLastOctet) + 1; $iCIDRNetwork = $CIDRmapReverse{$iIPCount}; } else { print "\n!!! The broadcast IP that you provided ($sBroadcastIP) is not correct. Please correct the IP and try again. (ie '--broadcast=10.0.0.7')\n"; exit(0); } } # check that IP is in range # if($iNetworkLastOctet < 0 || $iNetworkLastOctet > 255){ print "\n!!! The network IP that you provided is not correct. Please correct the IP and try again. (ie '--network=10.0.0.0')\n"; exit(0); } # validate broadcast IP # $iBroadcastLastOctet = $sBroadcastIP; $iBroadcastLastOctet =~ s/^\d+\.\d+\.\d+\.(\d+)$/$1/; if($iBroadcastLastOctet < 0 || $iBroadcastLastOctet > 255){ print "\n!!! The broadcast IP that you provided is not correct. Please correct the IP and try again. (ie '--broadcast=10.0.0.255')\n"; exit(0); } # check IP order # # Note: this blocks single IP addition (/32). if($iBroadcastLastOctet < $iNetworkLastOctet){ print "\n!!! The network IP or the broadcast IP that you provided is not correct. Please correct this and try again.\n"; exit(0); } # make sure given network is reasonable # if($sNetworkIP !~ /$sCClass/ || $sBroadcastIP !~ /$sCClass/){ print "\n!!! The IPs you provided are not correct. Please correct the IPs and try again.\n"; exit(0); } ## gateway IP ## $sGatewayIP = "${sCClass}." . ($iNetworkLastOctet + 1); ## Check for Take2Hosting IP malformed ## if($sCClass !~ /^(204|74|173|50|198)\.(74|82|252|115|144)\./ ){ if(! $bForce){ print "!!! IP range is not from Take2Hosting. Maybe it was mis-typed? Is this an old version of addips? Use --force to run anyway.\n"; exit(0); } } ## unroll IP range ## if(! $iIPCount){ $iIPCount = 0; foreach my $lastOctet ($iNetworkLastOctet..$iBroadcastLastOctet){ $iIPCount ++; } } # validate network against CIDR table # if(! $CIDRmap{$iCIDRNetwork}){ print "\n!!! Network does not start or end on natural CIDR boundary. Please correct the IPs and try again\n"; exit(0); } # validate IPs against CIDR table # if ($iNetworkLastOctet % $CIDRmap{$iCIDRNetwork} == 0 && (($iBroadcastLastOctet + 1) - $CIDRmap{$iCIDRNetwork}) % $CIDRmap{$iCIDRNetwork} == 0){ } else { print "\n!!! Network does not start on natural CIDR boundary. Please correct the IPs and try again\n"; exit(0); } ## Notes: # first the OS is detected. # then are we adding or removing IPs # Are the IPs for VPSes or not chomp($sOSVersion); if($sOSVersion =~ /fedora/i || $sOSVersion =~ /centos/i){ # RedHat OS # print "+++ OS detected: RedHat based ($sOSVersion)\n" if $bDebug; ## add or remove IPs ## if($bRemoveIPs){ print "+++ Removing IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # normal statics # foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; if($sIfconfig =~ /${sInterface}:(\d+)\s+Link encap:Ethernet\s+HWaddr .*?inet addr:${sCClass}.$lastOctet\s+Bcast:${sCClass}.*?\s+Mask:255\.255\.255\.\d+.*?UP BROADCAST RUNNING/i){ $interfaceAlias{"${sCClass}.$lastOctet"} = "$1"; $iAlias = $interfaceAlias{"${sCClass}.$lastOctet"}; $sIfconfig =~ s/${sInterface}:$iAlias//; # remove data to stop future pattern match (due to bobo code) } else { # IP is not UP on server # print "\n!!! Could not find IP address '${sCClass}.$lastOctet' configured UP!\n"; if(! $bForce){ next; } } # bring down interface # if(length($iAlias)){ print "+++ bringing DOWN ${sInterface}:$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("/sbin/ifdown ${sInterface}:$iAlias"); } } else { print "!!! Can not find interface for ${sCClass}.$lastOctet !\n"; next; } # re(move) config file # print "+++ Removing config file /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n" if $bDebug; if(! $bTest){ system("/bin/mv -f /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias.removed"); } } } else { # VPS remove # my $iCount = 1; foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # only remove gateway IP # if($iCount != 2){ $iCount ++; next; } &testInterfaceBlind(); # if($sIfconfig =~ /${sInterface}:(\d+)\s+Link encap:Ethernet\s+HWaddr .*?inet addr:${sCClass}.$lastOctet\s+Bcast:${sCClass}.*?\s+Mask:255\.255\.255\.\d+\s+UP BROADCAST RUNNING/i){ # $interfaceAlias{"${sCClass}.$lastOctet"} = "$1"; # $iAlias = $interfaceAlias{"${sCClass}.$lastOctet"}; # $sIfconfig =~ s/${sInterface}:$iAlias//; # remove data to stop future pattern match (due to bobo code) # } else { # # IP is not UP on server # # print "\n!!! Could not find IP address '${sCClass}.$lastOctet' configured UP!\n"; # } # bring down interface # if(length($iAlias)){ print "+++ bringing DOWN ${sInterface}:$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("/sbin/ifdown ${sInterface}:$iAlias"); } } else { print "!!! Can not find interface for ${sCClass}.$lastOctet !\n"; next; } # re(move) config file # print "+++ Removing config file /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n" if $bDebug; if(! $bTest){ system("/bin/mv -f /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias.removed"); } last; } } ## end removing IPs ## } else { ## Adding IPs ## print "+++ Adding IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # Normal Statics # # get last eth0 alias $iAlias = &getAlias(); $iAlias ++; # check interfaces again # $sIfconfig = &getIfconfig(); foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # Skip an IP as needed # if($sSkipIP eq "${sCClass}.$lastOctet"){ next; } # see if ips are already configured if($sIfconfig =~ /addr:${sCClass}.$lastOctet\s/){ print "\n!!! IP ${sCClass}.$lastOctet is already configured UP !\n"; next; } # configure IPs if(-e "/etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias"){ print "!!! File exists: /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n" if $bDebug; print "+++ Moving /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias to /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias.bak\n" if $bDebug; if(! $bTest){ system("/bin/mv -f /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias /etc/sysconfig/network-scripts/ifcfg-${sInterface}:${iAlias}.bak"); } } # interface config # my $sInterfaceTemplate = "# Networking Interface added by T2H addip script DEVICE=${sInterface}:$iAlias ONBOOT=yes BOOTPROTO=static NETMASK=255.255.255.255 IPADDR=${sCClass}.$lastOctet "; # create file # print "+++ Creating /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n\n$sInterfaceTemplate\n\n" if $bDebug; if(! $bTest){ system("echo '$sInterfaceTemplate' > /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias"); } # bring them up print "+++ Bringing up ${sInterface}:$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("/sbin/ifup ${sInterface}:$iAlias"); } # check for failure # &testInterface(); # next... # $iAlias ++; } } else { # VPS # # get last eth0 alias $iAlias = &getAlias(); $iAlias ++; # check interfaces again # $sIfconfig = &getIfconfig(); my $iCount = 1; foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # Skip an IP as needed # if($sSkipIP eq "${sCClass}.$lastOctet"){ next; } # only configure gateway IP... $ if($iCount != 2){ $iCount ++; next; } # see if ips are already configured if($sIfconfig =~ /addr:${sCClass}.$lastOctet\s/){ print "\n!!! IP ${sCClass}.$lastOctet is already configured UP !\n"; next; } # configure IPs if(-e "/etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias"){ print "!!! File exists: /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n" if $bDebug; print "+++ Moving /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias to /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias.bak\n" if $bDebug; if(! $bTest){ system("/bin/mv -f /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias /etc/sysconfig/network-scripts/ifcfg-${sInterface}:${iAlias}.bak"); } } # interface config # my $sInterfaceTemplate = "# Networking Interface added by T2H addip script DEVICE=${sInterface}:$iAlias ONBOOT=yes BOOTPROTO=static NETMASK=$netmask{$iIPCount} IPADDR=${sCClass}.$lastOctet "; # create file # print "+++ Creating /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias\n$sInterfaceTemplate\n" if $bDebug; if(! $bTest){ system("echo '$sInterfaceTemplate' > /etc/sysconfig/network-scripts/ifcfg-${sInterface}:$iAlias"); } # bring them up print "+++ Bringing up ${sInterface}:$iAlias ${sCClass}.$lastOctet as Gateway IP\n" if $bDebug; if(! $bTest){ system("/sbin/ifup ${sInterface}:$iAlias"); } # check for failure # &testInterface(); # next... # $iAlias ++; $iCount ++; } } } } elsif ($sOSVersion =~ /ubuntu/i || $sOSVersion =~ /debian/i){ # Ubuntu OS # print "+++ OS detected: Debian based ($sOSVersion)\n" if $bDebug; ## add or remove IPs ## if($bRemoveIPs){ print "+++ Removing IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # normal statics # print "+++ Backing up /etc/network/interfaces to /etc/network/interfaces.bak\n" if $bDebug; if(! $bTest){ system("/bin/cp -f /etc/network/interfaces /etc/network/interfaces.bak"); } foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # HACK ? if($sIfconfig =~ /${sInterface}:(\d+)\s+Link encap:Ethernet\s+HWaddr .*?inet addr:${sCClass}.$lastOctet\s+Bcast:${sCClass}.*?\s+Mask:255\.255\.255\.\d+\s+UP BROADCAST RUNNING/i){ $interfaceAlias{"${sCClass}.$lastOctet"} = "$1"; $iAlias = $interfaceAlias{"${sCClass}.$lastOctet"}; $sIfconfig =~ s/${sInterface}:$iAlias//; # remove data to stop future pattern match (due to bobo code) } else { # IP is not UP on server # print "\n!!! Could not find IP address '${sCClass}.$lastOctet' configured UP!\n"; } # bring down interface # if(length($iAlias)){ print "+++ bringing DOWN ${sInterface}:$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("/sbin/ifdown ${sInterface}:$iAlias"); } } else { print "!!! Can not find interface for ${sCClass}.$lastOctet !\n"; next; } # re(move) config file # print "+++ Removing config for ${sInterface}:$iAlias\n" if $bDebug; if(! $bTest){ my $sConfig = `cat /etc/network/interfaces`; $sConfig =~ s/\nauto ${sInterface}:$iAlias\niface ${sInterface}:$iAlias inet static\n address ${sCClass}\.$lastOctet\n netmask 255\.255\.255\..*?\n broadcast ${sCClass}\.$lastOctet\n//; system("echo '$sConfig' > /etc/network/interfaces"); } } } else { # VPS remove # # NOTE: no VPS support for Ubuntu at this time } ## end removing IPs ## } else { ## Adding IPs ## print "+++ Adding IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # Normal Statics # # get last eth0 alias $iAlias = &getAlias(); $iAlias ++; # check interfaces again # $sIfconfig = &getIfconfig(); # back up config # print "+++ Backing up /etc/network/interfaces to /etc/network/interfaces.bak\n" if $bDebug; if(! $bTest){ system("/bin/cp /etc/network/interfaces /etc/network/interfaces.bak"); } foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # Skip an IP as needed # if($sSkipIP eq "${sCClass}.$lastOctet"){ next; } # see if ips are already configured if($sIfconfig =~ /addr:${sCClass}.$lastOctet\s/){ print "\n!!! IP ${sCClass}.$lastOctet is already configured UP !\n"; next; } # interface config # my $sInterfaceTemplate = "\nauto ${sInterface}:$iAlias iface ${sInterface}:$iAlias inet static address ${sCClass}.$lastOctet netmask 255.255.255.255 broadcast ${sCClass}.$lastOctet\n"; # Append to config # print "+++ Adding interface\n$sInterfaceTemplate\n" if $bDebug; if(! $bTest){ system("echo -n '$sInterfaceTemplate' >> /etc/network/interfaces"); } # bring them up print "+++ Bringing up ${sInterface}:$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("/sbin/ifup ${sInterface}:$iAlias"); } # check for failure # &testInterface(); # next... # $iAlias ++; } } else { # VPS # # NOTE: currently no VPS support } } } elsif ($sOSVersion =~ /xen/i){ # XenServer OS # ## assume VPS ## $bVPS ++; print "+++ OS detected: RedHat based XenServer ($sOSVersion)\n" if $bDebug; ## add or remove IPs ## if($bRemoveIPs){ print "+++ Removing IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # normal statics # # NOTE: not supported } else { # VPS remove # # XenServer convention # $sInterface = 'dummy'; # determine gateway to select proper interface $iAlias = getXenAlias(); # HACK determine which interface to use my $iCount = 1; foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # only remove gateway IP # if($iCount != 2){ $iCount ++; next; } # HACK do we need this? # test alias or last # &testInterface(); ($sInterface, $iAlias) = &GetInterfaceAlias(); # bring down interface # print "+++ bringing DOWN ${sInterface}$iAlias ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ if($sInterface && length($iAlias)){ system("/sbin/ifdown ${sInterface}$iAlias"); } else { print "!!! No interface to bring down!"; } } # re(move) config file # print "+++ Removing config file /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias\n" if $bDebug; if(! $bTest){ system("/bin/mv -f /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias.removed"); } last; } foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # remove route from rc.local # print "+++ Removing route from /etc/rc.local\n" if $bDebug; if(! $bTest){ my $sConfig = `cat /etc/rc.local`; # read in file $sConfig =~ s/ip route add ${sCClass}.$lastOctet dev xenbr0\n//g; # clean ref $sConfig =~ s/'/\'/g; # escape ' due to echo system("echo '$sConfig' > /etc/rc.local"); # replace file with clean version # remove route # system("/sbin/ip route del ${sCClass}.$lastOctet dev xenbr0 > /dev/null 2>&1"); } } # remove header text # if(! $bTest){ my $sConfig = `cat /etc/rc.local`; # read in file $sConfig =~ s/## VPS IP Routes ##\n\n*?//g; $sConfig =~ s/'/\'/g; # escape ' due to echo system("echo '$sConfig' > /etc/rc.local"); # replace file with clean version # remove route # system("/sbin/ip route del ${sCClass}.$lastOctet dev xenbr0 > /dev/null 2>&1"); } } ## end removing IPs ## } else { ## Adding IPs ## print "+++ Adding IP range ${sCClass}.${iNetworkLastOctet}-.${iBroadcastLastOctet}\n" if $bDebug; if($bNotVPS || ! $bVPS){ # Normal Statics # # NOTE: not currently supported print "\n!!! This is currently not supported!\n"; } else { # VPS # $sInterface = 'dummy'; # convention... # get last interface alias (dummy0 ?) $iAlias = &getXenAlias(); $iAlias ++; # check interfaces again # $sIfconfig = &getIfconfig(); my $iCount = 1; foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # Skip an IP as needed # if($sSkipIP eq "${sCClass}.$lastOctet"){ next; } # only configure gateway IP due to VPS routing... # # gateway IP is count 2 # if($iCount != 2){ $iCount ++; next; } # see if ip is already configured # if($sIfconfig =~ /addr:${sCClass}.$lastOctet\s/){ print "\n!!! IP ${sCClass}.$lastOctet is already configured UP! Skipping ${sCClass}.$lastOctet\n"; if(! $bForce){ exit; } } elsif($sIfconfig =~ /$sInterface$iAlias\s+Link encap/){ print "\n!!! Interface $sInterface$iAlias is already configured UP! Skipping $sInterface$iAlias\n"; exit; } # configure IPs if(-e "/etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias"){ print "!!! File exists: /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias\n" if $bDebug; print "+++ Moving /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias to /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias.bak\n" if $bDebug; if(! $bTest){ rename("/etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias", "/etc/sysconfig/network-scripts/ifcfg-${sInterface}${iAlias}.bak"); } } # interface config # my $sInterfaceTemplate = "# Networking Interface added by T2H addip script DEVICE=${sInterface}$iAlias BOOTPROTO=none ONBOOT=yes USERCTL=no IPV6INIT=no PEERDNS=yes TYPE=Ethernet IPADDR=${sCClass}.$lastOctet NETMASK=$netmask{$iIPCount} DNS1=173.252.208.226 ARP=yes\n"; # create file # print "+++ Creating /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias\n$sInterfaceTemplate\n" if $bDebug; if(! $bTest){ system("echo '$sInterfaceTemplate' > /etc/sysconfig/network-scripts/ifcfg-${sInterface}$iAlias"); } # bring them up print "+++ Bringing up Interface ${sInterface}$iAlias with ${sCClass}.$lastOctet as Gateway\n" if $bDebug; if(! $bTest){ system("/sbin/ifup ${sInterface}$iAlias"); } # check for failure # &testInterface(); last; } # back up rc.local # print "+++ Backing up /etc/rc.local to /etc/rc.local.bak\n" if $bDebug; if(! $bTest){ system("cp -f /etc/rc.local /etc/rc.local.bak"); } if(! $bTest){ system("echo '## VPS IP Routes ##' >> /etc/rc.local"); } $iCount = 1; foreach my $octet ($iNetworkLastOctet..$iBroadcastLastOctet){ $lastOctet = $octet; # skip network and gateway IPs # if($iCount == 1 || $iCount == 2){ $iCount ++; next; } # skip broadcast IP # if($lastOctet eq $iBroadcastLastOctet){ last; } # Skip an IP as needed # if($sSkipIP eq "${sCClass}.$lastOctet"){ next; } ## add routing ## print "+++ Adding route for ${sCClass}.$lastOctet\n" if $bDebug; if(! $bTest){ system("ip route add ${sCClass}.$lastOctet dev xenbr0"); } # add routing to /etc/rc.local # print "+++ Adding route for ${sCClass}.$lastOctet to /etc/rc.local\n" if $bDebug; if(! $bTest){ system("echo 'ip route add ${sCClass}.$lastOctet dev xenbr0' >> /etc/rc.local"); } $iCount ++; } } } } elsif ($sOSVersion =~ /gentoo/i){ # no gentoo yet... # print "\n!!! Sorry, we do not currently support GenToo Linux...\n"; } elsif ($sOSVersion =~ /arch/i){ # no arch yet... # print "\n!!! Sorry, we do not currently support Arch Linux...\n"; } else { print "\n!!! We were unable to detect the OS. Maybe try '--os=centos' or '--os=xen'\n"; exit(0); } ## check firewall for forwarding ## if(! `cat /proc/sys/net/ipv4/ip_forward`){ print "!!! IPTables Firewall not forwarding! Run: 'echo 1 > /proc/sys/net/ipv4/ip_forward\n'" if $bDebug; } ## Exit Script ## exit; ######## # Subs # ######## # dump ifconfig # sub getIfconfig { my $tmp = `/sbin/ifconfig`; $tmp =~ s/\n/ /g; # remove line breaks $tmp =~ s/\s+/ /g; # remove extra whitespace return $tmp; } # check if an IP is up on an interface # sub testInterface { if(! $bTest){ $sIfconfig = &getIfconfig(); if($sIfconfig !~ /${sInterface}.*?$iAlias\s+Link\s+encap:Ethernet\s+HWaddr.*?\s+inet addr:${sCClass}.${lastOctet}\s+Bcast:${sCClass}.\d+\s+Mask:.*?UP BROADCAST RUNNING/i){ print "\n!!! The IP '${sCClass}.${lastOctet}' is not UP!\n"; return 0; } } return 1; } # check if an IP is up on an interface without knowing Alias# sub testInterfaceBlind { if(! $bTest){ $sIfconfig = &getIfconfig(); if($sIfconfig !~ /${sInterface}(\d+)\s+Link encap:Ethernet\s+HWaddr.*?\s+inet addr:${sCClass}.${lastOctet}\s+Bcast:${sCClass}.$iBroadcastLastOctet\s+Mask:$netmask{$iIPCount}.*?UP BROADCAST RUNNING/i){ $iAlias = $1; print "\n!!! The IP '${sCClass}.${lastOctet}' is not UP!\n"; return 0; } } return 1; } # check if an IP is up on an interface # # return the interface and alias # sub GetInterfaceAlias { if(! $bTest){ $sIfconfig = &getIfconfig(); # if($sIfconfig !~ /${sInterface}.*?$iAlias\s+Link encap:Ethernet\s+HWaddr.*?\s+inet addr:${sCClass}.${lastOctet}\s+Bcast:${sCClass}.$iBroadcastLastOctet\s+Mask:$netmask{$iIPCount}.*?UP BROADCAST RUNNING/i){ if($sIfconfig !~ /(\w+).*?(\d+)\s+Link encap:Ethernet\s+HWaddr.*?\s+inet addr:${sCClass}.${lastOctet}\s+Bcast:${sCClass}.$iBroadcastLastOctet\s+Mask:$netmask{$iIPCount}.*?UP BROADCAST RUNNING/i){ print "\n!!! The IP '${sCClass}.${lastOctet}' is not UP!\n"; return 0; } else { return($1, $2); } } return 1; } # return the next interface alias number to use # sub getAlias { my $tmp = `/sbin/ifconfig | grep '${sInterface}'`; if(length($tmp)){ $tmp =~ /${sInterface}:(\d+).*?$/; # get last used alias return $1; } return 0; # default base value (ie eth0:0) } # return the next interface alias number to use # sub getXenAlias { my $tmp = `/sbin/ifconfig | grep '${sInterface}'`; if(length($tmp)){ $tmp =~ /$sInterface(\d*?)\s+.*?$/; # get last used alias return $1; } else { return -1; # default base value (ie dummy0) } } ##__EOF__##