DOS Batch Script to Determine When ISP Changes my IP Address

heylarson

Distinguished
Feb 18, 2010
27
0
18,530
The thread title pretty much sums it up. I want to write a batch script for my Windows 7 machine that is scheduled to run every night.

The functionality of it is pretty straight forward. Read the IP address and compare it to the one saved in a temp file. If they are different, send out an email to alert me of the new change. Because I am behind a router, an ipconfig would not be suffice. However, I think that maybe a tracert or arp command might include the IP address of the router. I have some basic DOS knowledge, but this is a bit out of my range.

If anyone has ideas on writing this, let me know.
 
Solution
Nice work and thinking!

Here is the batch file version. :) It will collect the IP and check against the last known one and generate different outputs depending on a change has been done.

It will need the wget.exe utility, a free tool available here. Save to the same folder as the script.



@ECHO OFF

SET url=http://www.whatismyip.com/automation/n09230945.asp
SET out=out.txt
SET oldipfile=oldipfile.txt

IF NOT EXIST wget.exe ECHO wget.exe is missing. && GOTO :eof
IF NOT EXIST %oldipfile% ECHO 0.0.0.0 > %oldipfile%

wget.exe -q -O %out% %url%
FOR /f "tokens=1" %%a IN (%out%) DO SET ip=%%a

ECHO.
ECHO The IP address is %ip%.
ECHO Checking last known IP..
ECHO.

TYPE %oldipfile% | FIND /i "%ip%" > nul
IF "%ERRORLEVEL%"=="0" ECHO...
Are you trying to read the IP off of your router or the computer? I doubt you can run a script to get the WAN IP off the router, and the internal IP of your computer should not change. You can do a tracert from your computer to another site but it will only show you the gateway and then the DNS server. To see the WAN port of your rounter, you have to know the IP of it to begin with, which won't do you any good if that changes.

Why don't you ask your IPS to give you a static IP, they may charge you a bit for it, but at least it will never change. You may poke around your Router config, maybe there is a way to have it email you it's settings every so often. I know many Routers have an "email errors to me" type settings, and that should be configurable so an error can be a change in IP address on the WAN port.
 
I'm guessing you could probably write a telnet script to get this information, depending upon the make and model of the router. But I think that you would need more than a batch file to do it - perhaps VBscript or even a quick and dirty C program.

I guess the real question is "Why do you want to know when your IP address changes?". Depending upon the answer to that there may be a better solution.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010
I agree with the above. The hard thing is to actually get hold of the external IP of your router.

If your router has a telnet interface it should be able to be done with a standard batch script.

If not having telnet access (which most consumer router does not have) perhaps it could be done with some free dynamic dns service, where you automaticly update your ip and a known host name. Then using the nslookup command in a batch file should be able to do what you wish.

 
I'm not so sure of that, as I don't think you can automate the Microsoft telent client in a batch file, but it would be easy enough using Perl or probably other scripting languages. Plain batch programs are really pretty limited in what they can do.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


It was some time since I looked at it, but I do think it could be done. From what I remember you will have to create an answer text file with all commands, and feed it to telnet.exe. I shall look at it.



Of course bat/cmd files are more limited compared to Perl and similar, but they are actually a lot more able than most people think. I belive I can do almost everything through batch files. ;)
 
That works fine with ftp, but not telnet (as far as I can see). It may work with other telnet clients.
I look forward to your batch file solution to this exercise with eager anticipation.;)
 
A bit of lateral thinking. Register your router with DynDNS.com. Then you can either ping the hostname or do an nslookup on it, piping the result into a text file. From there on it should be pretty simple to check whether the IP address has changed.

Note that there will be some delay between your IP address changing and DynDNS registering the change.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


I will make a solution for you. :) I will not be able to do it tonight, but perhaps tomorrow.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


Ok, so here is a draft for a working script. I have made it somewhat longer than might be necessary, but I like using variables for most things and only define them at the top.

There is also some pseudo code in here, since we do not know the syntax of the telnet interface (if exist at all!) :) This also apply to the fixing of the output from that command. (Done with FOR below.)

You were right about telnet.exe, when I did something similar some years ago I used netcat (nc.exe) for feeding a file directly to port tcp/23.

The script also uses the Windows command line mailer tool blat.exe. Both these files are freely available on the net.

Anyway, the script is totaly untested and should be seen mostly as a proof of concept.


Here is the script then:

@ECHO OFF

REM Change these parameters:
SET routerip=192.168.10.1
SET routerpw=secretpassword
SET smtp=mail.test.com
SET mail=example@test.com


REM Do not change these parameters
SET telnetfile=telnet.txt
SET telnetout=telnetout.txt
SET oldipfile=oldipfile.txt
SET tmp1=tempfile1.txt
SET ip=
SET mailfile=mailfile.txt


REM Checking for nc and blat
IF NOT EXIST nc.exe ECHO nc.exe is missing. && GOTO :eof
IF NOT EXIST blat.exe ECHO blat.exe is missing. && GOTO :eof


REM Create telnet answer file
ECHO %routerpw% > %telnetfile%
ECHO show ip interface 1 >> %telnetfile%
ECHO exit >> %telnetfile%


REM Creating old IP file if not existing
IF NOT EXIST %oldipfile% ECHO 0.0.0.0 > %oldipfile%


REM Use nc.exe to telnet the router and extract the ip address
nc.exe %routerip% 23 < %telnetfile% > %telnetout%


REM Extract the line with the actual IP address and put into "ip" variable
TYPE %telnetout% | FIND /i "IP Address:" > %tmp1%
FOR /f "tokens=3" %%a IN (%tmp1%) DO SET ip=%%a

ECHO The IP address is %ip%.
ECHO Checking last known IP..
ECHO.

REM Checking if changed
TYPE %oldipfile% | FIND /i "%ip%" > nul
IF "%ERRORLEVEL%"=="0" ECHO The same IP as before. && GOTO :cleanup

ECHO The IP has been changed. Old IP was:
TYPE %oldipfile%

REM Creating mail content

ECHO. > %mailfile%
ECHO Hello, >> %mailfile%
ECHO your outside IP address has been changed. >> %mailfile%
ECHO The new IP is %ip%. >> %mailfile%
ECHO. >> %mailfile%
ECHO Regards, your script. >> %mailfile%


REM Sending mail
blat.exe %mailfile% -to %mail% -f "Script" -i "Script" -s "IP has been changed!" -server %smtp%


REM Updating the oldipfile with the new IP
ECHO %ip% > %oldipfile%

:cleanup

REM Cleaning up
IF EXIST %tmp1% DEL %tmp1%
IF EXIST %telnetfile% DEL %telnetfile%
IF EXIST %telnetout% DEL %telnetout%
IF EXIST %mailfile% DEL %mailfile%
 
Impressive. But for a more generic solution I would prefer with my suggestion of creating a dynamic DNS account as a similar solution could then be produced using only commands that are standard in Windows, and no knowledge of the router internals is required.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


Thanks. Batch scripting is kind of fun I think. ;)




I actually agree with you on this (also suggested this early in the thread). If the OP knows if his router is capable of doing a dynamic dns registration we should be able to put together a script doing the same checks with nslookup.
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


If there is a PC based client perhaps it is able to drop the dyndns address somewhere localy? I have not tried any such client myself.

(Reading some of your 64bit assembly stuff now.) ;)
 
I got to thinking about this (the way you do) and wondered if it was possible to create a program that required no additional configuration (a la Dynamic DNS) and no knowledge of the router. I think I've managed to do it with a quick and dirty C# program by accessing one of those "your IP address" web sites. This simple console app prints out your external addresss:
Code:
using System;
using System.Net;

namespace ExtIP
{
    class Program
    {
        static void Main(string[] args)
        {
            String url = "http://whatismyipaddress.com/";
            String result = null;
            int res;

            try
            {
                WebClient client = new WebClient();
                result = client.DownloadString( url );
                res = result.IndexOf("LOOKUP");
                result = result.Substring(res + 22, 15);
                res = result.IndexOf("\"");
                result = result.Substring(0, res);
                Console.Write(result);
            }
            catch (Exception ex)
            {
                Console.Write("Sorry - couldn't get result.");;
            }
        }
    }
}
At any rate, it works for me. This could then be incorporated into a batch file, piping the output to a data file, or expanded to do whatever one wanted. If you'd like to try it, I've uploaded the executable to: http://ijack.org.uk/ExtIP.exe .
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010
Nice work and thinking!

Here is the batch file version. :) It will collect the IP and check against the last known one and generate different outputs depending on a change has been done.

It will need the wget.exe utility, a free tool available here. Save to the same folder as the script.



@ECHO OFF

SET url=http://www.whatismyip.com/automation/n09230945.asp
SET out=out.txt
SET oldipfile=oldipfile.txt

IF NOT EXIST wget.exe ECHO wget.exe is missing. && GOTO :eof
IF NOT EXIST %oldipfile% ECHO 0.0.0.0 > %oldipfile%

wget.exe -q -O %out% %url%
FOR /f "tokens=1" %%a IN (%out%) DO SET ip=%%a

ECHO.
ECHO The IP address is %ip%.
ECHO Checking last known IP..
ECHO.

TYPE %oldipfile% | FIND /i "%ip%" > nul
IF "%ERRORLEVEL%"=="0" ECHO The same IP address as before. && GOTO :eof

ECHO The IP has been changed. Old IP was:
TYPE %oldipfile%

ECHO %ip% > %oldipfile%
 
Solution

heylarson

Distinguished
Feb 18, 2010
27
0
18,530
@ricno - Absolutely!! Thank you all for taking time to help me out. It's been a pain having to remote into my router each and every time to verify what new IP address DHCP has assigned to my laptop.
 
OK guys, it's 2010 and there's no need to download special programs, query external web sites, or use DOS batch files. PowerShell is now built into every version of Windows 7 and it's got all of the power to do this without any fuss.

Here's a script I just put together which grabs the status page from my router, parses the IP address out if it and checks it for a particular value. The meat of it is in just 5 lines of code, all the lines starting with "#" are comments:

Code:
# Create a web client object with the required credentials to access the router:
# -----------------------------------------------------------------------------

    $WebClient = new-object System.Net.WebClient
    $WebClient.Credentials = new-object System.Net.NetworkCredential accountname,password

# change "accountname,password" in the above line to that required for your router,
# or uncomment the following if you want to enter the username/password at run time
# instead of hard-coding it into the script:

#    $WebClient.Credentials = Get-Credential



# Get the status page from the router and extract the IP address from it:
# ----------------------------------------------------------------------

    $StatusPage = $WebClient.DownloadString( "http://192.168.1.1/Status_Router.asp" )
    $StatusPage -match 'var wan_ip ".+"' | out-null
    $IPAddress = $matches[0].Split('"')[1]

# The last two lines above may need to be customized to the particular layout
# of your router's status page
    
    
# Complain if the IP address is different:
# ---------------------------------------

    if ( $IPAddress -ne "10.10.10.10" )
    {
        write-host -foregroundcolor red "`nIP Address has changed - it is now: $IPAddress`n"
        exit 1
    }
    else
    {
        write-host -foregroundcolor cyan "`nIP Address is still $IPAddress`n"
    }
You can run this by pasting it into a file with a ".ps1" file type, starting the PowerShell console, CD'ing to the folder that it's in and typing: .\filename.ps1.

If you get a message saying that the execution policy prevents script execution, then you need to enable script execution (you only need to do this once) by starting the PowerShell console as Administrator and typing: set-executionpolicy unrestricted
 

ricno

Distinguished
Apr 5, 2010
582
0
19,010


Powershell is indeed very powerful and it was interesting to see that solution. My only objection is that it perhaps is not generic, as not all routers will display a page called "Status_Router.asp" or even have a status page with a predictable URL.

Powershell does impress me in how much is builtin, that much be done very manual using classic command shell scripts. :)
 
It's true that you have to customize your script to the router, and while there is a small possibility that the status page won't have a fixed URL, a script could grab the router's home page (which MUST have a fixed URL) and parse it to get a link to the status page.

Scripts like this let you monitor anything on your router. For example you could use it to check the router's log file for signs of suspicious activity. You could also monitor other devices such as a network-attached printer.

Scripting is tons of fun! :D