Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Change IP addresses from the Terminal UNIX
The System Prefs panel makes it easy to change or add IP addresses, but what if you want to do it automatically or remotely? Most Darwin documentation talks about a nifty, "nonexistent since the Public Beta" tool called ipconfigd.

After much, much experimentation and research, I learned that to successfully change IPs from the command line the hard way, you must manually create a ton of routes. However, the ipconfig tool (not ipconfigd, which is now a plugin to configd) will do much of it for you. After manually setting the ip address of your interface (probably en0), just delete the current default route and recreate a route to your router.

Read the rest of the article for a script which uses this fact to automatically assign the next available IP using this technique.

[<b>Editor's note:</b> I have not tested this script.]

The script below automatically finds the next IP in a list of IP addresses called <b>ips</b>. This list must be one IP per line, and must not have a blank line at the end (i.e. save it with the cursor on the line of the last IP). The script uses <a href="http://www.fping.com/" target=_blank>fping</a>, although ping could be (used albeit a bit more slowly).

The script discovers whether or not the target IP is in use; if it is, it goes on to the next one recursively, updating the order of the <b>ips</b> file each time it runs. Otherwise, it updates your en0 IP and routes appropriately, optionally calling <a href="www.no-ip.com" target=_blank>noip</a> (the command line interface for free dynamic dns client)</a>. It won't loop infinitely as it stops if it reaches the beginning IP in the list. Check out the comments to see where you can easily make this a one-IP, command-line-input script.<pre>#!/bin/sh<br><br>#ips is in rotateip's dir, so cd to wherever you put this list.<br>#i use the bin directory in my home directory.<br>#remember you'll want to run this as root, so you'll<br>#need to hardcode it (~/bin won't work).<br>cd /users/evands/bin<br><br>#relevant network data<br>ROUTEME="129.59.56.1"<br>NETMASK="255.255.252.0"<br><br>echo Rotating IP address... please wait.<br><br>#rotate the IP list<br>NEWIP="`tail -n 1 ips`"<br>echo $NEWIP &gt; ips.new<br>grep -v $NEWIP ips &gt;&gt; ips.new<br>mv ips.new ips<br><br>#starting point file<br>if (test ! $START)<br>then<br> START=$NEWIP<br>fi<br><br>#fping it and output either nothing or an IP<br>#to use ping, do a ping -c 1 $NEWIP and look at the last<br>#line - 100% packet loss means it was unreachable<br>TheTest="`sudo fping $NEWIP | grep 'unreachable' | tail -n 1 | sed -e 's/is unreachable//g'`"<br>if (test $TheTest)<br>then<br> #It was unreachable<br> echo Updating IP to $NEWIP<br> sudo ipconfig set en0 MANUAL $NEWIP $NETMASK<br> echo Waiting for update<br> sudo ipconfig waitall<br> sleep 5<br> echo Routing $NEWIP to $ROUTEME<br> sudo route -q delete default<br> sudo route -q add default $ROUTEME<br><br> #send SIGHUP signal to netinfod (running -s local) and lookupd<br> sudo kill -HUP `sudo cat /var/run/netinfo_local.pid`<br> sudo kill -HUP `sudo cat /var/run/lookupd.pid`<br><br> #update dynamic dns using noip to the new ip address after<br> #waiting 2 secs for routes to update<br> #uncomment tabbed lines to enable<br> #sleep 2<br> #noip -i $NEWIP<br> #wait for NoIP to Finish<br> #NoIPpid="`/bin/ps aux | grep noip | grep -v grep | awk '{print $2}' | tail -n 1`"<br> #if (test NoIPpid)<br> # then<br> # echo Waiting for Dynamic DNS on PID $NoIPpid to update...<br> # wait $NoIPpid<br> #fi<br><br> echo Goodbye.<br><br> #Execute any change-of-IP commands here.<br> #I kill hxd at this point.<br> #ProgToKill=hxd<br> #sudo /bin/kill -9 `/bin/ps aux | grep $ProgToKill | grep -v grep | awk '{print $2}'`<br><br>else<br> #It was reachable<br> echo $NEWIP was reachable. Trying next IP.<br> #the next IP to check was our starting point<br> if (test $START != "`cat ips | tail -n 1`")<br> then<br> $0<br> else<br> echo All new IPs in &#092;"ips&#092;" were attempted and are in use.<br> fi<br> echo Exiting.<br>fi</pre>
    •    
  • Currently 2.67 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (3 votes cast)
 
[12,446 views]  

Change IP addresses from the Terminal | 3 comments | Create New Account
Click here to return to the 'Change IP addresses from the Terminal' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Reposting to correct HTML
Authored by: Loren on Apr 15, '02 10:15:02AM
[Editor's note: I have not tested this script.]
The script below automatically finds the next IP in a list of IP addresses called ips. This list must be one IP per line, and must not have a blank line at the end (i.e. save it with the cursor on the line of the last IP). The script uses fping, although ping could be (used albeit a bit more slowly).

The script discovers whether or not the target IP is in use; if it is, it goes on to the next one recursively, updating the order of the ips file each time it runs. Otherwise, it updates your en0 IP and routes appropriately, optionally calling noip (the command line interface for free dynamic dns client). It won't loop infinitely as it stops if it reaches the beginning IP in the list. Check out the comments to see where you can easily make this a one-IP, command-line-input script.
#!/bin/sh

#ips is in rotateip's dir, so cd to wherever you put this list.
#i use the bin directory in my home directory.
#remember you'll want to run this as root, so you'll
#need to hardcode it (~/bin won't work).
cd /users/evands/bin

#relevant network data
ROUTEME="129.59.56.1"
NETMASK="255.255.252.0"

echo Rotating IP address... please wait.

#rotate the IP list
NEWIP="`tail -n 1 ips`"
echo $NEWIP > ips.new
grep -v $NEWIP ips >> ips.new
mv ips.new ips

#starting point file
if (test ! $START)
then
START=$NEWIP
fi

#fping it and output either nothing or an IP
#to use ping, do a ping -c 1 $NEWIP and look at the last
#line - 100% packet loss means it was unreachable
TheTest="`sudo fping $NEWIP | grep 'unreachable' | tail -n 1 | sed -e 's/is unreachable//g'`"
if (test $TheTest)
then
#It was unreachable
echo Updating IP to $NEWIP
sudo ipconfig set en0 MANUAL $NEWIP $NETMASK
echo Waiting for update
sudo ipconfig waitall
sleep 5
echo Routing $NEWIP to $ROUTEME
sudo route -q delete default
sudo route -q add default $ROUTEME

#send SIGHUP signal to netinfod (running -s local) and lookupd
sudo kill -HUP `sudo cat /var/run/netinfo_local.pid`
sudo kill -HUP `sudo cat /var/run/lookupd.pid`

#update dynamic dns using noip to the new ip address after
#waiting 2 secs for routes to update
#uncomment tabbed lines to enable
#sleep 2
#noip -i $NEWIP
#wait for NoIP to Finish
#NoIPpid="`/bin/ps aux | grep noip | grep -v grep | awk '{print $2}' | tail -n 1`"
#if (test NoIPpid)
# then
# echo Waiting for Dynamic DNS on PID $NoIPpid to update...
# wait $NoIPpid
#fi

echo Goodbye.

#Execute any change-of-IP commands here.
#I kill hxd at this point.
#ProgToKill=hxd
#sudo /bin/kill -9 `/bin/ps aux | grep $ProgToKill | grep -v grep | awk '{print $2}'`

else
#It was reachable
echo $NEWIP was reachable. Trying next IP.
#the next IP to check was our starting point
if (test $START != "`cat ips | tail -n 1`")
then
$0
else
echo All new IPs in \"ips\" were attempted and are in use.
fi
echo Exiting.
fi


[ Reply to This | # ]
Reposting to correct HTML
Authored by: jluster on Apr 16, '02 12:11:44AM

This script is a bit ... well ... overly complicated. Why not just using a "for IP in `cat ${IPFILE}`" instead of the complicated mover routine? And why not simply make it a StartupItem and let it read the whole kaboozle from hostinfo, add a key named 'IP_ADDRESSES' and fill it with colon delimited values which you then split using cut, awk, sed, or something similar?



[ Reply to This | # ]
Overly complicated scripting ;p
Authored by: evands on Apr 16, '02 12:55:28AM

For some purposes, that probably would be more elegant... the fashion of the script was needed because of the need I had to actually rotate through a list (rather than just searching it); if I run the script twice, I don't want to come up with the same IP.
Anyhoo, the important part is really the ipconfig and route stuff in the middle, which I certainly didn't find in any clear documentation anywhere (no man info on ipconfig, among other things)... the script was my own application of it. *shrug* took me a while to get working right, so I thought I'd share in case someone had a similar need.



[ Reply to This | # ]