Announcement

Collapse
No announcement yet.

Public IP Address to a string variable

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mike Doty
    replied
    Not the same.
    The code I posted looks up the public IP address for the domain, records it and notifies me if it has changed so forwarding can be changed. Code has been in use for a couple of years. Just added a setup file.

    Also, this is not the same.
    This is for private IP addresses from the help file
    Like 192.168.0.1 not the public ip address.
    Code:
    FUNCTION HowManyIPs() AS LONG
      DIM p AS BYTE PTR
      LOCAL index AS LONG
      LOCAL ip    AS LONG
      LOCAL a     AS STRING
      RESET index&
     
      DO
        HOST ADDR(index&+1) TO ip&
        IF ISTRUE ip& THEN
          PRINT "counting"
          INCR index&
          p = VARPTR(ip&)
          a$ = USING$("#_.#_.#_.#", @p, @p[1], @p[2], @p[3])
          ? a$
        END IF
      LOOP UNTIL ip& = 0
      FUNCTION = index&
    END FUNCTION

    This is also incorrect because it only gives the address to the name server.
    The name server may be forwarding using your name.
    Code:
    FUNCTION PBMAIN AS LONG
      LOCAL ip AS LONG
      LOCAL p AS BYTE PTR
      LOCAL a AS STRING
      HOST ADDR "mysitehere.com" TO ip&
      p = VARPTR(ip&)
      a$ = USING$("#_.#_.#_.#", @p, @p[1], @p[2], @p[3])
      ? a$

    Code:
    'This gives public ip even if name server is using forwarding
    #INCLUDE "win32api.inc"
    %WaitTime  = 30000           'milliseconds to show current IP
    GLOBAL gMsg AS STRING
    FUNCTION PBMAIN AS LONG
      LOCAL hFile             AS LONG
      LOCAL sFile             AS STRING
      LOCAL sIP               AS STRING 'previous public ip
      LOCAL sPublicIP         AS STRING 'current  public ip from checkip.dyndns.com
      sFile = "IP.txt"
      hFile = FREEFILE
      REM KILL sFile:ERRCLEAR  'erase setup file for testing
      IF ISFILE(sFile) THEN
        OPEN sFile FOR INPUT AS #hFile
        IF ERR THEN
           ? "Unable to open " + sFile + ".  1-line which is IP address on file: 255.255.255.255
           EXIT FUNCTION
        ELSE
          LINE INPUT #hFile, sIP  'IP address on file
          IF ERR THEN ? "LINE INPUT ERROR" + STR$(ERRCLEAR)
          CLOSE #hFile
        END IF
      END IF
      sPublicIP = GetPublicIP(80,"checkip.dyndns.com","")         'public IP port
      IF sIP  <> sPublicIP THEN
        ? CHR$(sIp, " (old)", $CRLF, sPublicIP, " (new)",$CRLF,$CRLF, "CHANGE with REGISTRAR!"), +_
                  %MB_ICONERROR OR %MB_SYSTEMMODAL, sFile
     
     
     
        'Update IP address on file
        ? "Create " + sFile + " updating with public ip " + sPUblicIP
        hFile = FREEFILE
        OPEN sFile FOR OUTPUT AS #hFile
        IF ERR THEN ? "Unable to open for output error" + STR$(ERRCLEAR)
        PRINT #hFile, sPublicIP   'change to new public ip address change with registrar!
        CLOSE #hFile
      ELSE
        gMsg = sPublicIP
        SLEEPER %WaitTime    'execute thread if public ip is current
      END IF
    END FUNCTION
    FUNCTION GetPublicIP(PortNumber AS LONG, Site AS STRING, File AS STRING)  AS STRING
       'modified WebGet
       LOCAL buffer    AS STRING
       LOCAL temp      AS STRING
       LOCAL i         AS LONG
       LOCAL h         AS LONG
       LOCAL SearchFor AS STRING
       h = FREEFILE
       TCP OPEN PORT PortNumber AT site AS #h TIMEOUT 10000
       IF ERR THEN BEEP:EXIT FUNCTION
       TCP PRINT #h, "GET " & file & " HTTP/1.0"
       TCP PRINT #h, "Accept: */*"
       TCP PRINT #h, "Accept-Language: en-us"
       TCP PRINT #h, "Host: " & site
       TCP PRINT #h, "Pragma: no-cache"
       TCP PRINT #h, "Referer: URL=http://www.me.com"
       TCP PRINT #h, "User-Agent: GetIP modified 6/28/2010"
       TCP PRINT #h, ""
       DO
          TCP RECV #h, 4096, buffer
          temp = temp & buffer
       LOOP UNTIL LEN(Buffer) = 0 OR ERRCLEAR
       TCP CLOSE #h
       REM  ? temp
       SearchFor = "IP ADDRESS"
       i = INSTR(UCASE$(temp), SearchFor)
       IF i THEN
          REM ? "Found at byte" + STR$(i)
          Temp = MID$(temp,i + LEN(SearchFor)+2)
          i = INSTR(temp,"</") 'as in /BODY
          REM ? Temp
          REM ? "Last byte" + STR$(i)
          Temp = LEFT$(temp,i-1)
          REM ? Temp
          FUNCTION = Temp
       END IF
       TCP CLOSE #h
    END FUNCTION
    FUNCTION Sleeper (milliseconds AS DWORD) AS LONG
      LOCAL hThread AS DWORD
      IF LEN(COMMAND$) THEN                'override passed value
        milliseconds = ABS(VAL(COMMAND$))  'use value in COMMAND$
      END IF
      THREAD CREATE TimedMessageBoxThread(milliseconds) TO hThread
      SLEEP 50
      WaitForSingleObject hThread, milliseconds
      THREAD CLOSE hThread TO hThread
    END FUNCTION
    THREAD FUNCTION TimedMessageBoxThread(BYVAL milliseconds AS DWORD) AS LONG
    'IP did not change
    #IF %DEF(%PB_CC32)
      ? gMsg,,"IP current"
      WAITKEY$
    #ELSE
      ? gMsg,,"IP current"
    #ENDIF
    END FUNCTION
    Last edited by Mike Doty; 29 Jul 2010, 11:41 AM.

    Leave a comment:


  • Mel Bishop
    replied
    Pretty sure the source at:

    http://www.powerbasic.com/support/pb...ad.php?t=40185

    will do what you want.

    If not specifically, you should be able to mod it to suit your own particulars.

    Leave a comment:


  • Mike Doty
    replied
    Improved version that creates a setup file with current IP address.
    This is useful with dynamic DNS or port forwarding.

    If ISP changes your address this can be very useful

    Code:
    #INCLUDE "win32api.inc"
    %WaitTime  = 10000           'milliseconds to show current IP
    GLOBAL gMsg AS STRING
    FUNCTION PBMAIN AS LONG
      LOCAL hFile             AS LONG
      LOCAL sFile             AS STRING
      LOCAL sIP               AS STRING  'example: "192.111.111.111"
      LOCAL sPublicIP         AS STRING
      sFile = "IP.txt"
      hFile = FREEFILE
      REM KILL sFile:ERRCLEAR  'erase setup file for testing
      IF ISFILE(sFile) THEN
        OPEN sFile FOR INPUT AS #hFile
        IF ERR THEN
           ? "Unable to open " + sFile + ".  1-line which is IP address on file: 255.255.255.255
           EXIT FUNCTION
        ELSE
          LINE INPUT #hFile, sIP  'IP address on file
          IF ERR THEN ? "LINE INPUT ERROR" + STR$(ERRCLEAR)
          CLOSE #hFile
        END IF
      END IF
      sPublicIP = GetPublicIP(80,"checkip.dyndns.com","")         'public IP port
      IF sIP  <> sPublicIP THEN
        ? CHR$(sIp, " (old)", $CRLF, sPublicIP, " (new)",$CRLF,$CRLF, "CHANGE with REGISTRAR!"), +_
                  %MB_ICONERROR OR %MB_SYSTEMMODAL, sFile
     
     
     
        'Update IP address on file
        ? "Create " + sFile + " updating with public ip " + sPUblicIP
        hFile = FREEFILE
        OPEN sFile FOR OUTPUT AS #hFile
        IF ERR THEN ? "Unable to open for output error" + STR$(ERRCLEAR)
        PRINT #hFile, sPublicIP   'change to new public ip address change with registrar!
        CLOSE #hFile
      ELSE
        gMsg = sPublicIP
        SLEEPER %WaitTime    'execute thread if public ip is current
      END IF
    END FUNCTION
    FUNCTION GetPublicIP(PortNumber AS LONG, Site AS STRING, File AS STRING)  AS STRING
       'modified WebGet
       LOCAL buffer    AS STRING
       LOCAL temp      AS STRING
       LOCAL i         AS LONG
       LOCAL h         AS LONG
       LOCAL SearchFor AS STRING
       h = FREEFILE
       TCP OPEN PORT PortNumber AT site AS #h TIMEOUT 10000
       IF ERR THEN BEEP:EXIT FUNCTION
       TCP PRINT #h, "GET " & file & " HTTP/1.0"
       TCP PRINT #h, "Accept: */*"
       TCP PRINT #h, "Accept-Language: en-us"
       TCP PRINT #h, "Host: " & site
       TCP PRINT #h, "Pragma: no-cache"
       TCP PRINT #h, "Referer: URL=http://www.me.com"
       TCP PRINT #h, "User-Agent: GetIP modified 6/28/2010"
       TCP PRINT #h, ""
       DO
          TCP RECV #h, 4096, buffer
          temp = temp & buffer
       LOOP UNTIL LEN(Buffer) = 0 OR ERRCLEAR
       TCP CLOSE #h
       REM  ? temp
       SearchFor = "IP ADDRESS"
       i = INSTR(UCASE$(temp), SearchFor)
       IF i THEN
          REM ? "Found at byte" + STR$(i)
          Temp = MID$(temp,i + LEN(SearchFor)+2)
          i = INSTR(temp,"</") 'as in /BODY
          REM ? Temp
          REM ? "Last byte" + STR$(i)
          Temp = LEFT$(temp,i-1)
          REM ? Temp
          FUNCTION = Temp
       END IF
       TCP CLOSE #h
    END FUNCTION
    FUNCTION Sleeper (milliseconds AS DWORD) AS LONG
      LOCAL hThread AS DWORD
      IF LEN(COMMAND$) THEN                'override passed value
        milliseconds = ABS(VAL(COMMAND$))  'use value in COMMAND$
      END IF
      THREAD CREATE TimedMessageBoxThread(milliseconds) TO hThread
      SLEEP 50
      WaitForSingleObject hThread, milliseconds
      THREAD CLOSE hThread TO hThread
    END FUNCTION
    THREAD FUNCTION TimedMessageBoxThread(BYVAL milliseconds AS DWORD) AS LONG
    'IP did not change
    #IF %DEF(%PB_CC32)
      ? gMsg,,"IP current"
      WAITKEY$
    #ELSE
      ? gMsg,,"IP current"
    #ENDIF
    END FUNCTION
    Last edited by Mike Doty; 29 Jul 2010, 09:05 AM.

    Leave a comment:


  • Mike Doty
    replied
    I contacted them and they said the format of the page will not change so my code above should continue to work.
    Last edited by Mike Doty; 3 Sep 2009, 06:48 PM.

    Leave a comment:


  • Kevin Powick
    replied
    Hi Mike,

    Originally posted by Mike Doty View Post
    I use Dyndns so hopefully they won't change the format of the page.
    It shouldn't change, as they have a published specification for it as a service for developers.

    http://www.dyndns.com/developers/checkip.html

    Note however that they ask you not check more than once every 10 minutes.

    --
    Kevin Powick

    Leave a comment:


  • Mike Doty
    replied
    Scott,
    Thanks for the posting.
    I get "Timeout ERROR!"

    I use Dyndns so hopefully they won't change the format of the page.
    Also, if they are unavailable there is a good chance my routing is down.

    Leave a comment:


  • Scott Slater
    replied
    Here's a really old piece of code that uses the ICMP method, but as I stated earlier, this won't always work. I am on a Cisco 800 series (real Cisco, not Linksys) and it returns the wrong remote port address since there are 2 subnets here. It returns the other subnet's port address instead of the WAN port address. It used to return the WAN address before the other subnet was added.

    My Network Layout: Using routine on subnet A will return Subnet B's router port address.
    Code:
                          +--------+
                          |        | --- Subnet A
    Internet         <----+ Router +
                          |        | --- Subnet B
                          +--------+
    So though flawed in this case, it still may work for you. Here is the code.
    Code:
    '
    '  Tested with PBWin 6, 7 & 8:  Returns the IP/Address of The 2nd Hop,
    ' usually the Router's WAN Port.
    '
     
    #Compile Exe
     
    #Include "WSOCK32.INC"
     
    Type ICMP_OPTIONS
      Ttl             As Byte
      Tos             As Byte
      Flags           As Byte
      OptionsSize     As Byte
      OptionsData     As Long
    End Type
     
    Type ICMP_ECHO_REPLY
      Address         As Long
      Status          As Long
      RoundTripTime   As Long
      DataSize        As Integer
      Reserved        As Integer
      DataPointer     As Long
      Options         As ICMP_OPTIONS
      zData           As Asciiz * 250
    End Type
     
    ' Ping Function used for Ping/TraceRoute:
    ' ----------------------------------------------
    Function Ping(DestAddress As Asciiz, MaxHops As Long, PingTimeOut As Long, _
                  TripTime As Long, Address As String, HostName As String) As Long
     
       Local hostent            As HostEntStru Ptr
       Local PingOptions        As ICMP_OPTIONS
       Local ER                 As ICMP_ECHO_REPLY
       Local lpaddr             As in_addr
       Local wDat               As WSAdata
       Local hPing              As Long
       Local DestinationAddress As Long
       Local Result             As Long
       Local ReqSize            As Integer
       Local theirIP            As Asciiz Ptr
       Local pReqData           As Asciiz * 40
     
       If MaxHops < 1 Then MaxHops = 100
       If PingTimeOut < 1 Then PingTimeOut = 8000
     
       Result = WsaStartup(257, wdat)
       hPing = IcmpCreateFile
     
       DestinationAddress = inet_addr(DestAddress)
       PingOptions.Ttl = CByt(MaxHops) 'Set Time to Live
       PingOptions.Flags = 2
       PingOptions.Tos=16
     
       pReqData = "1234567890123456789012345678901"+Chr$(0)
       ReqSize  = 32
     
       Result = IcmpSendEcho(ByVal hPing, ByVal DestinationAddress, pReqData, _
                             ByVal ReqSize, PingOptions, ER, SizeOf(ER), _
                             PingTimeOut)
     
       IcmpCloseHandle hPing
     
       If Result Then
     
          TripTime = ER.RoundTripTime
          If Er.DataSize < 1 Then TripTime = -1
          theirIP = inet_ntoa(Er.Address)
          Address = @theirIP
     
          lpaddr.s_addr = Er.Address
          hostent = GetHostByAddr(lpaddr.s_addr, 4, %PF_INET)
          If hostent = 0 Then
             HostName = ""
          Else
             HostName = @[email protected]_name
          End If
          Function = 1
       Else
          Address = ""
          HostName = ""
          Function = 0
       End If
     
       wsaCleanup
     
    End Function
    
    ' Return a String with Router's IP Address In it
    ' ---------------------------------------------------------
    Function Whats_My_Routers_IP As String
     
       Local zAddress  As Asciiz * 128
       Local PngTimOut As Long
       Local TripTime  As Long
       Local RtnHost   As String
       Local RtnAddr   As String
       Local sWork     As String
     
       zAddress = "12.108.1.204"  ' Use microsoft.com's address, we simply need a final dest
       PngTimOut = 2000           ' even though we won't actually use it.
     
       If Ping(zAddress, 2, PngTimOut, TripTime, RtnAddr, RtnHost) Then
                        '^
                        '|------- Hop 2 - should be your routers WAN Side Address...
     
          If Len(RtnHost) Then
             sWork = RtnAddr & " (" & RtnHost & ")"
          Else
             sWork = RtnAddr
          End If
       Else
          sWork = "Timeout ERROR!"
       End If
    
       Function = sWork
     
    End Function
     
    Function PBMain
       #If %Def(%Pb_Cc32)
          StdOut Whats_My_Routers_IP
       #Else
          MsgBox Whats_My_Routers_IP
       #EndIf
    End Function

    Leave a comment:


  • Mike Doty
    replied
    Testers appreciated. Used dyndns in this version.

    Testers comments welcome!

    Code:
     
    FUNCTION PBMAIN AS LONG
    REM Dyndns says the format of the page will not change so this should work. 
     
      ? GetPublicIP(80,"checkip.dyndns.com","")
     
    END FUNCTION
    FUNCTION GetPublicIP(PortNumber AS LONG, Site AS STRING, File AS STRING)  AS STRING
     
       'modified WebGet
       LOCAL buffer    AS STRING
       LOCAL temp      AS STRING
       LOCAL i         AS LONG
       LOCAL h         AS LONG
       LOCAL SearchFor AS STRING
       h = FREEFILE
       TCP OPEN PORT PortNumber AT site AS #h TIMEOUT 10000
       IF ERR THEN BEEP:EXIT FUNCTION
       TCP PRINT #h, "GET " & file & " HTTP/1.0"
       TCP PRINT #h, "Accept: */*"
       TCP PRINT #h, "Accept-Language: en-us"
       TCP PRINT #h, "Host: " & site
       TCP PRINT #h, "Pragma: no-cache"
       TCP PRINT #h, "Referer: URL=http://www.me.com"
       TCP PRINT #h, "User-Agent: webget modified 1.3 [URL="http://www.me.com"]www.me.com[/URL]"
       TCP PRINT #h, ""
       DO
          TCP RECV #h, 4096, buffer
          temp = temp & buffer
       LOOP UNTIL LEN(Buffer) = 0 OR ERRCLEAR
       TCP CLOSE #h
       REM  ? temp
       SearchFor = "IP ADDRESS"
       i = INSTR(UCASE$(temp), SearchFor)
       IF i THEN
          REM ? "Found at byte" + STR$(i)
          Temp = MID$(temp,i + LEN(SearchFor)+2)
          i = INSTR(temp,"</") 'as in /BODY
          REM ? Temp
          REM ? "Last byte" + STR$(i)
          Temp = LEFT$(temp,i-1)
          REM ? Temp
          FUNCTION = Temp
       END IF
       TCP CLOSE #h
     
    END FUNCTION
    Last edited by Mike Doty; 3 Sep 2009, 06:51 PM.

    Leave a comment:


  • Mike Doty
    replied
    Modifying WebGet, now.
    Thanks!

    Leave a comment:


  • Scott Slater
    replied
    You will more than likely need to get this information from a web site that returns your information. Since the PC can only see it subnet and pass other information off to the gateway (router), there is not any set way of doing this without using an outside source.

    Some routers will return the WAN port address if you do an ICMP TRACEROUTE for hop #1, but this will not always work. Going to a website and then parsing the html code will probably be your best bet.

    Leave a comment:


  • Mike Doty
    started a topic Public IP Address to a string variable

    Public IP Address to a string variable

    How do you return your public ip address to a string variable?
    A dynamic name service would return their IP and not your IP address using the code below.
    http://checkip.dyndns.com.

    Code:
    REM In this example the DNS service is returned
     
       zServer = "MyServer.com"
       HOST ADDR zServer TO ip&
       IF ip THEN
          DIM p AS BYTE PTR
          p = VARPTR(ip&)
          zServer = USING$("#_.#_.#_.#", @p, @p[1], @p[2], @p[3])
       ELSE
          ? "Unable to convert " + zServer + " to an IP address."
          EXIT FUNCTION
       END IF      
       IF zServer = "204.13.248.125" THEN
          ? "Dynamic name service IP address can not be used."
          EXIT FUNCTION
       END IF
    Last edited by Mike Doty; 3 Sep 2009, 06:34 AM. Reason: Added some more code and cosmetic changes
Working...
X