Change IP addresses from the Terminal

Apr 15, '02 09:12:42AM

Contributed by: evands

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>

Comments (3)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20020415091242448