Announcement

Collapse
No announcement yet.

Public IP Address to a string variable

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

  • 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

  • #2
    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.
    Scott Slater
    Summit Computer Networks, Inc.
    www.summitcn.com

    Comment


    • #3
      Modifying WebGet, now.
      Thanks!

      Comment


      • #4
        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.

        Comment


        • #5
          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
          Scott Slater
          Summit Computer Networks, Inc.
          www.summitcn.com

          Comment


          • #6
            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.

            Comment


            • #7
              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
              --
              Kevin Powick

              Comment


              • #8
                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.

                Comment


                • #9
                  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.

                  Comment


                  • #10
                    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.
                    There are no atheists in a fox hole or the morning of a math test.
                    If my flag offends you, I'll help you pack.

                    Comment


                    • #11
                      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.

                      Comment

                      Working...
                      X