Home AMX User Forum NetLinx Studio

Embedded Function for WAN IP Return?

Greetings,

Can anyone suggest a way to get the WAN IP address of a network in code? My Netlinx Master is connected to the Internet through a basic router. I am trying to find a way to be alerted if my WAN IP changes. I have i! system monitor out running and can have an email sent to me if my code can be aware of the change. Thanks! This stuff is so much fun!

Comments

  • There's a Dyndns module in here somewhere that should be able to provide this feedback for you. Might be a really long way of doing it, so maybe someone else can chime in with a quick and dirty way of just getting the IP info..

    Kevin D.
  • DHawthorneDHawthorne Posts: 4,584
    There is nothing in the NetLinx master itself that stores the WAN address that I have been able to find. Generally, this is supplied by the OS, and if the OS can't provide it, you need a web service. You can run a simple script on any web server - a Google search will give you pagfes of results. If you don't have your own server to send queries to, you can use checkip.dyndnsalias.org and parse the HTML response. DynDNS.org only requests you do not query their system more than once per 15 minutes.

    Here is a snippet of code my module uses for this (modified a bit for simplicity) :
    DEFINE_DEVICE
    
    dvConnection = 0.5.0       // change if needed to prevent conflicts
    
    DEFINE_VARIABLE
    
    CHAR sIP_Buffer[2048]
    
    DEFINE_START
    
    CREATE_BUFFER dvConnection, sIP_Buffer
    
    DEFINE_CALL 'OnIP_Error' (SLONG nErrorCode)
    {
        SWITCH(nErrorCode)
        {
    	CASE  1 : SEND_STRING 0, "'IP Connect Error:  invalid server address'"
    	CASE  2 : SEND_STRING 0, "'IP Connect Error:  invalid server port'"
    	CASE  3 : SEND_STRING 0, "'IP Connect Error:  invalid value for Protocol'"
    	CASE  4 : SEND_STRING 0, "'IP Connect Error:  unable to open communication port with server'"
    	CASE  6 : SEND_STRING 0, "'IP Connect Error:  Connection refused'"
    	CASE  7 : SEND_STRING 0, "'IP Connect Error:  Connection timed out'"
    	CASE  8 : SEND_STRING 0, "'IP Connect Error:  Unknown connection error'"
    	CASE  9 : SEND_STRING 0, "'IP Connect Error:  Already closed'"
    	CASE 10 : SEND_STRING 0, "'IP Connect Error:  Binding error'"
    	CASE 11 : SEND_STRING 0, "'IP Connect Error:  Listening error'"
    	CASE 14 : SEND_STRING 0, "'IP Connect Error:  Local port already used'"
    	CASE 15 : SEND_STRING 0, "'IP Connect Error:  UDP socket already listening'"
    	CASE 16 : SEND_STRING 0, "'IP Connect Error:  Too many open sockets'" 
        }
    }
    
    DEFINE_CALL 'Get IP'
    {
        SLONG nError
        
        nError = IP_CLIENT_OPEN(dvConnection.PORT, "'checkip.dyndns.org'", 80, 1)
        IF(nError)
            CALL 'OnIP_Error' (nError)
        
    }
    
    DEFINE_CALL 'Parse IP Buffer' 
    {
        CHAR sNewIP[25]
        
        REMOVE_STRING (sIP_Buffer, "'Address: '", 1)
        sNewIP  = REMOVE_STRING (sIP_Buffer, "'</body>'", 1)
        sNewIP =  LEFT_STRING(sNewIP, LENGTH_STRING(sNewIP) - 7)
        SEND_STRING 0, "'Current WAN IP = ', sNewIP"
    }
    
    DATA_EVENT [dvConnection]
    {
        OFFLINE: CALL 'Parse IP Buffer'
    }
    
    

    dvConnection is the local device used to make the connection; sIP_Buffer is the port's buffer and I call 'Parse IP Buffer' on a OFFLINE event, because that is how simple HTML connections like this work, they send their data and drop the connection. Note you don't have to actually send anything to the connection, just make it. This only applies to DynDNS's IP service, one using a different HTML variant might require a GET command or something similar. This also assumes the response will be in a form that has the the text "Address: ", followed by the IP number.
  • TurnipTruckTurnipTruck Posts: 1,485
    Wow! I was not aware of the dyndns.org's ability to send you back your IP. That is a VERY useful service.

    In your code, when you SEND_STRING 0, ... where is the string going?

    Thanks!
  • SEND_STRING 0's will send the string to the master. Its a form of debugging. If you telnet into the master and type MSG ON, any message the master revceives will be displayed.

    It's most likely for demonstration, you would want to compare the old vs new and do what you need to do.

    Kevin D.
  • DHawthorneDHawthorne Posts: 4,584
    Originally posted by shr00m-dew
    SEND_STRING 0's will send the string to the master. Its a form of debugging. If you telnet into the master and type MSG ON, any message the master revceives will be displayed.

    It's most likely for demonstration, you would want to compare the old vs new and do what you need to do.

    Kevin D.
    Exacty - that was just an example piece of code. You would have to actualy do something with the data besides send it to your telnet session :). I cut all that out of the actual code the DynDNS module uses, it would be too confusing to make a point otherwise because you didn't have the entire source.
  • alexanboalexanbo Posts: 282
    Hey Dave,

    Thanks for posting that code. I was playing with it today and had some problems. When I opened the IP_Client it didn't seem like any data was returned at all. I put in some debugging statements in to see if any data was coming in but nothing showed up. If after the connection was opened I sent something like 13,10,13,10 I would then get data back in the form of error messages form the server. I tried changing the website it was pointing to just to see if I could get data going and some worked and some didn't return data.

    What I finally ended up doing was finding a website www.webyield.net which uses a CGI Post to return the address. So I open the connection and then send a string with the Post method and parse the incoming data fine.

    I am at the office behind a firewall so perhaps thats what is causing the problem with the code you had but thought I'd get your thoughts on it.

    Thanks

    Andre
  • DHawthorneDHawthorne Posts: 4,584
    It's more likely their service was down for a short time, I've had it happen before. I can't imagine a firewall would block it, but you could check that just by pointing your browser at the same address.
  • Hey Dave? Have you really had luck getting checkip.dyndns.org to return the IP address info >just< by opening a TCP connection to the server?

    I haven't tried it that way - apps I've written that access web servers do something along these lines:
    DATA_EVENT [TCPDev]
    { 
      ONLINE:
      {                       
          SEND_STRING TCPDev, "'GET /index.html HTTP/1.0',crlf,crlf"
      }
    }
    

    (That snippet is an abbreviation of the code from the DynDNS module I wrote, FWIW)

    If you just open a connection to a web server >without< sending an HTTP request of some kind, I didn't think you got any response at all.

    - Chip
  • Joe HebertJoe Hebert Posts: 2,159
    I was scratching my head a bit too when I read that. I've always thought the bare bone minimum after a connect was:

    SEND_STRING dvIP, "'GET / HTTP/1.0',13,10,13,10"

    which will return the default document whatever that may be. I've never run across a web server that returned anything without asking for something first.
    Originally posted by Chip Moody
    Hey Dave? Have you really had luck getting checkip.dyndns.org to return the IP address info >just< by opening a TCP connection to the server? ... If you just open a connection to a web server >without< sending an HTTP request of some kind, I didn't think you got any response at all.

    Joe
  • alexanboalexanbo Posts: 282
    I was able to get the IP check web page to come up in my browser. It wouldn't send any data to the netlinx socket though unless I sent a command to it. I hadn't thought about sending the Get \index.html command like Joe suggested though so maybe I'll try that.
  • DHawthorneDHawthorne Posts: 4,584
    Originally posted by Chip Moody
    Hey Dave? Have you really had luck getting checkip.dyndns.org to return the IP address info >just< by opening a TCP connection to the server?

    I haven't tried it that way - apps I've written that access web servers do something along these lines:

    DATA_EVENT [TCPDev]
    { 
      ONLINE:
      {                       
          SEND_STRING TCPDev, "'GET /index.html HTTP/1.0',crlf,crlf"
      }
    }
    

    (That snippet is an abbreviation of the code from the DynDNS module I wrote, FWIW)

    If you just open a connection to a web server >without< sending an HTTP request of some kind, I didn't think you got any response at all.

    - Chip
    You may be right, I clipped that out of a larger code block that had a lot of other baggage in it, since the same segment handled IP checks as well as service updates. Sometimes, I just can't remember exactly what I did the day before :). I probably forgot I had the GET line in there and clipped it out without realizing. HTTP protocol is not an expert area of mine, I'm afraid, I have to look some things up every time I need them.
  • Gettting WAN IP address

    First post here, having just discovered this forum. Chip and I have traded ideas a bit from time to time. I have a little module working which does the GET HTTP routine to a website called myipaddress.com every hour. It then compares the IP address it gets with the one it got an hour ago, and if it changed, then it sends me an e-mail. The e-mailing part is crude and clunky but seems to work OK. I just read up about how e-mail works (RFC822) - a standard developed in the 1980s! I was amazed how simple it is.

    Here in LA I have dynamic IP DSL from the phone company and sometimes it changes just once every 2-3 days, sometimes 2-3 times a day.
  • TurnipTruckTurnipTruck Posts: 1,485
    Re: Gettting WAN IP address
    Originally posted by Spannertech
    I have a little module working which does the GET HTTP routine to a website called myipaddress.com every hour. It then compares the IP address it gets with the one it got an hour ago, and if it changed, then it sends me an e-mail.

    This is the direction I am going. I already have the comparison and email part working. I add the I-Equipment Monitor Out module to most of my systems, including the one I am working on now. All I need is to return the IP address to my code and I'll be good to go.

    Another suggestion for people who like to access their system from afar using a dynamic IP address is to use something like I Equipment Monitor In and to send a message to your system to have it reply to you with its IP.

    If you have two-way text messaging on your cell phone that can can send and receive with a standard email address, you have one of the most powerful AMX user interfaces.
Sign In or Register to comment.