This is written in Linux.

When I'm travelling, it is useful to know my home dynamic IP address in case I want transfer files, or, look at my camera. I have an always-on Raspberry Pi (which replaced my unSlung NSLU2) as network central: I can ssh, sftp files, or, wake-on-lan other computers, as needed. I usually have ssh and openvpn listening on forwarded ports to handle multiple situations.

In the past, I used DynDNS to provide a connection, but a change in policy a few years ago meant I needed to find another way—I decided to have the RPi test the address and email changes.

It's possible to get the address from the Internet, but, not all sites respond to wget. For example in May 2016:
http://www.findurip.com/ does, and,
https://www.whatismyip.com/ does not.
I needed a more reliable way, and, decided to stay on my own network. I can get the address from either the DSL modem or router's status page—I went with the router. The modem and old Airlink router provide status pages without log-in, but, my new TP Link router requires log-in, so I changed from wget to ddclient.

Then, I changed to Uverse and while double NATed behind the multi-function unit provided, I needed to go back to wget to pick up the public address. I have included that as a separate script at the end.

The short story is the method for getting the address may need to change based on device requirements.

In any case, the address needs to be picked and stored for use, but, it's not hard to grep the page captured from the device.

I have a cron job that runs the script to get the address. If the address doesn't change it logs it. If it changes, the new address is emailed and sent to my phone as MMS. One day a week it does the email even if there's been no change—just as a test. I usually run the script twice a day, but sometimes more often, depending on how important I think it is to verify the address.

I'm using sendEmail to deliver the mail/MMS through smtp.google.com. Since sendEmail puts the server/username/password on the command line, I hide those in /root/{Files} and use variables to insert them. The TPL router also needs creds—I handle them the same way. I've also used sendmail, but it's larger and harder to configure.

So, the flow:

Make sure we're in the right directory, then go to t_do_vars:

t_do_vars()
Load values from /root/{Files} into the variables. The date and day of week are loaded using 'date'. Also, load T2 with the value from old_ip.dat, or create the file if it doesn't exist. Then, move on to t_get_address:

t_get_address()
Either, wget the modem/router's status page, or, ddclient the log-in-required router's status page, and, grep the resulting file to get the addresses. In all cases, there's more than one line with addresses, so I pick the right line. The address is put in the the variable 'ip' and echo'd to the file ip_address for later use. Continue to t_test_new:

t_test_new()
The comparison here is $ip from t_get_address to the stored old address which is in $T2.
Check to see if it's test day (3) and that the address hasn't changed. If met, t_send_email.
If it's not test day, and the address hasn't changed, just log it and t_cleanup.
If it isn't test day and the address has changed: t_send_email.

t_send_email()
When appropriate, send an email, save the IP to the log file, then, t_cleanup. Since it's possible to email to a cell phone as a text message, I do that, as well. (See note at bottom.)

t_cleanup()
Delete and move files to clean things up. Copy the log to user's desktop and chmod it so the user can delete it.


That's what happens: here's the {Files} used:

/root/.local/bin/ip_check/

ip_check_log — the log
ip_check_t1-root — executable, the script
old_ip.dat — the saved last address

/root/.config/i_p/ — readable by root only, and, immutable bit set on the files to prevent accidental change or deletion. They are single line files with no line feed.

ip1f.dat — the "from"
ip1p.dat — smtp user's password
ip1t.dat — the "to"
ip1u.dat — the "user" for authentication on smtp server
ip1x.dat — smtp address and port
ip2t.dat — my 10 digit cell phone number, as "to"
ip3u.dat — TP Link router user
ip3p.dat — TP Link router password

/etc/crontab
# run (as root) ip check at 5:31am and 11:31am
31 5,11 * * * root /root/.local/bin/ip_check/ip_check_t1-root


That's the story. The script follows. Watch the no-line-wrap.
File name: /root/.local/bin/ip_check/ip_check_t1-root

#!/bin/bash
# get the current IP address from the router
# email if it's changed or test day and log it
# copy log to user desktop for review
# called daily or more from crontab

t_get_address() {
# Comment/uncoment as needed for device

# Airlink router
# wget http://192.168.1.1/status.htm
# grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' status.htm > ip1
# ip=$(head -1 ip1)

# modem
# wget http://192.168.0.1
# grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' index.html > ip1
# ip=$(head -1 ip1)

# TP Link router
ddclient -geturl 192.168.1.1/userRpm/WanDynamicIpCfgRpm.htm -login $ip3u -password $ip3p > index.html
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' index.html > ip1
ip=$(cat ip1 | head -2 | tail -1)

echo $ip > ip_address
t_test_new
}

t_test_new() {
if [ "$now12" = 3 ] && [ "$ip" = "$T2" ]; then
 ipm="It's test day, the IP is: $ip"
 t_send_email
else
 if [ "$ip" = "$T2" ]; then
  echo "On $now11 IP is still ---- $ip" >> ip_check_log;
  t_cleanup
else
 ipm="IP Changed. New IP: $ip"
 fi
fi
t_send_email
}

t_send_email() {
sendEmail -o tls=yes -f $ip1f -t $ip1t -s $ip1x -xu $ip1u -xp $ip1p -u "IP Address Update" -m $ipm
echo "At $now11 $ipm" >> ip_check_log;
sleep 1
sendEmail -o tls=yes -f $ip1f -t $ip2t -s $ip1x -xu $ip1u -xp $ip1p -u "IP Address Update-rasp2" -m $ipm
echo "At $now11 $ipm" >> ip_check_log;

t_cleanup
exit 0
}

t_do_vars() {
ip1x= ;read ip1x < /root/.config/i_p/ip1x.dat
ip1f= ;read ip1f < /root/.config/i_p/ip1f.dat
ip1t= ;read ip1t < /root/.config/i_p/ip1t.dat
ip1u= ;read ip1u < /root/.config/i_p/ip1u.dat
ip1p= ;read ip1p < /root/.config/i_p/ip1p.dat
ip2t= ;read ip2t < /root/.config/i_p/ip2t.dat
# log-in for TP Link router
ip3u= ;read ip3u < /root/.config/i_p/ip3u.dat
ip3p= ;read ip3p < /root/.config/i_p/ip3p.dat

now11=`date  "+%Y/%m/%d-%H%M"`
now12=`date  "+%w"`

if [ ! -f old_ip.dat ]; then
  touch old_ip.dat
fi
read T2 < old_ip.dat

t_get_address
}

t_cleanup() {
rm old_ip.dat
mv ip_address old_ip.dat
rm status.ht*
rm index.html
rm ip1
cd ..
cp /root/.local/bin/ip_check/ip_check_log /home/bob/Desktop/ip_check_log-root
chown bob:bob /home/bob/Desktop/ip_check_log-root
exit 0
}

cd /root/.local/bin/ip_check
t_do_vars

That's the script.

Note on emailing to a cell phone as a text message. In mid-2016 my reference is:
The Complete List Of Text Messaging Email Addresses | EmailTextMessages.com


Here's the slightly changed version I use for the NVG589 combo unit from AT&T. I needed to find the page that has the address, and, target that page in the wget. Also, the returned page is a little different than the others, so, I changed the method to load the variable ip.

#!/bin/bash
# get the current IP address from the nvg589 modem/router
# email if it's changed or test day and log it
# copy log to user desktop for review
# called daily or more from crontab

t_get_address() {

# arris ngv589

wget http://192.168.1.254/cgi-bin/broadbandstatistics.ha
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' broadbandstatistics.ha > ip1
ip=$(sed '2q;d' ip1)
# or ip=$(tail -n+3 ip1 | head -n1)

echo "$ip" > ip_address
#   read -rsp $'ip_address should be populated. Press enter to continue...\n'
t_test_new
}

t_test_new() {

if [ "$now12" = 3 ] && [ "$ip" = "$T2" ]; then
 ipm="It's test day, the IP is: $ip"
 t_send_email
else
 if [ "$ip" = "$T2" ]; then
  echo "On $now11 IP is still ---- $ip" >> ip_check_log;
  t_cleanup
else
 ipm="IP Changed. New IP: $ip"
 fi
fi
t_send_email
}

t_send_email() {
sendemail -o tls=yes -f "$ip1f" -t "$ip1t" -s "$ip1x" -xu "$ip1u" -xp "$ip1p" -u "Sparerephome Update-r2nvg" -m "$ipm"
echo "At $now11 $ipm" >> ip_check_log;
sleep 1
sendEmail -o tls=yes -f "$ip1f" -t "$ip2t" -s "$ip1x" -xu "$ip1u" -xp "$ip1p" -u "Sparerephome-r2nvg" -m "$ipm"
echo "At $now11 $ipm" >> ip_check_log;
t_cleanup
exit 0
}

t_do_vars() {
ip1x= ;read -r ip1x < /root/.config/i_p/ip1x.dat
ip1f= ;read -r ip1f < /root/.config/i_p/ip1f.dat
ip1t= ;read -r ip1t < /root/.config/i_p/ip1t.dat
ip1u= ;read -r ip1u < /root/.config/i_p/ip1u.dat
ip1p= ;read -r ip1p < /root/.config/i_p/ip1p.dat
ip2t= ;read -r ip2t < /root/.config/i_p/ip2t.dat

now11=$(date  "+%Y/%m/%d-%H%M")
now12=$(date  "+%w")

if [ ! -f old_ip.dat ]; then
  touch old_ip.dat
fi
read -r T2 < old_ip.dat

t_get_address
}

t_cleanup() {
rm broadbandstatistics.ha
rm old_ip.dat
mv ip_address old_ip.dat
rm ip1
cd ..
cp /root/.local/bin/ip_check_nvg589/ip_check_log /home/syncer/ip_check_log-nvg589
chown syncer:syncer /home/syncer/ip_check_log-nvg589
exit 0
}

cd /root/.local/bin/ip_check_nvg589
t_do_vars