Apparently I'm not the only one [having been] handicapped.
Even though, I was the one proclaiming that most loudly.
There are also 2 distinctly different possibilities to get ones external ip address, depending on the given circumstances.
If your router can be reached via DNS, when using Dynamic DNS [for running a server or whatever],
you can use a simple trick, someone once posted in this forum, like:
Code: Select all
Connection = OpenNetworkConnection(YourDnsName, 0, #PB_Network_UDP)
ExtIp = GetClientIP(Connection)
CloseNetworkConnection(Connection)
That is, if some
other mechanism is making sure, the DNS entry of your router stays up to date.
Also such a router supporting Dynamic DNS, can be set up to report the newly gotten external ip address to some server. Unless the router is restricted in that regard, it can report its new ip to a server running on your machine as well.
It will only give you updates on changes and your server must wait for such.
- If that is already in use, my previous suggesting should work.
OK, now I actually got to provide some
code about getting the external IP address from the router using upnp.
I even tested it, and it works fine here.
Code: Select all
EnableExplicit
; Get the external ip address from router using upnp
; compile as ASCII - NOT unicode, so the string can easily be used as buffer
#UserAgent = "UPNP ext. IPaddr"
#Router = "fritz.box" ; Adapt to your router
#StartToken = "<NewExternalIPAddress>"
#EndToken = "</NewExternalIPAddress>"
#recBufferLen = 2000
Macro Msg (pMessage, pFlags = #PB_MessageRequester_Ok)
MessageRequester(#UserAgent, pMessage, pFlags)
EndMacro
Define strBuffer.s, strReply.s, strIp.s
Define upnpConnection.i, nEvent.i
Define *recBuffer, recByteLen.i
Define Pos1.i, Pos2.i
Procedure.s FieldQuote (pFieldName.s)
ProcedureReturn Chr(34) + pFieldName + Chr(34)
EndProcedure
If InitNetwork() = 0
Msg("The network could not be initialized")
End
EndIf
*recBuffer = AllocateMemory(#recBufferLen)
If *recBuffer = 0
Msg("Memory allocation failed.")
End
EndIf
strBuffer = "POST /upnp/control/WANIPConn1 HTTP/1.1" + #CRLF$
strBuffer + "Host: " + #Router + #CRLF$
strBuffer + "User-Agent: " + #UserAgent + #CRLF$
strBuffer + "Content-Type: text/xml; charset=" + FieldQuote("utf-8") + #CRLF$
strBuffer + "Content-Length: 275" + #CRLF$
strBuffer + "SoapAction:urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress" + #CRLF$
strBuffer + "Connection: close" + #CRLF$
strBuffer + #CRLF$
strBuffer + "<?xml version=" + FieldQuote("1.0") + " encoding=" + FieldQuote("utf-8") + "?><s:Envelope xmlns:s=" + FieldQuote("http://schemas.xmlsoap.org/soap/envelope/") + " s:encodingStyle=" + FieldQuote("http://schemas.xmlsoap.org/soap/encoding/") + "><s:Body><u:GetExternalIPAddress xmlns:u=" + FieldQuote("urn:schemas-upnp-org:service:WANIPConnection:1") + " /></s:Body></s:Envelope>"
upnpConnection = OpenNetworkConnection(#Router, 49000, #PB_Network_TCP, 1000)
If upnpConnection = 0
Msg("Could not connect to " + #Router)
End
EndIf
SendNetworkData(upnpConnection, @strBuffer, Len(strBuffer))
Repeat
Delay(60)
nEvent = NetworkClientEvent(upnpConnection)
Select nEvent
Case #PB_NetworkEvent_Disconnect
Break
Case #PB_NetworkEvent_Data
recByteLen = ReceiveNetworkData(upnpConnection, *recBuffer, #recBufferLen)
strReply + PeekS(*recBuffer, recByteLen, #PB_Ascii)
EndSelect
ForEver
CloseNetworkConnection(upnpConnection)
Pos1 = FindString(strReply, #StartToken)
If Pos1
Pos1 + Len(#StartToken)
Pos2 = FindString(strReply, #EndToken)
If Pos2 > Pos1
strIp = Mid(strReply, Pos1, Pos2 - Pos1)
EndIf
EndIf
If strIp
Msg("External IP address: " + strIp)
Else
Msg("Failed to get external IP address.")
Debug strReply
EndIf
Provided as
example code, that can and probably should be made safer
- should f.e. not blindly trust the router [to close the connection in time] the way it currently does.(?)
You should be able to see the striking similarities to my post above.
If you can't, I'll be disappointed.
Hi
Vera
reading you, is loving you.
Edit1: Supplemented a code comment.