-
I've seen this asked but never really answered. I'm working on a small VB app that will display my external IP address (the IP address assigned by my ISP and viewable to the external network or internet). I wrote a program that gets my local IP (using winsock) and emails it to my account at work. But, that does little good because I'm not connecting through a LAN; I'm connecting over the Internet.
Could some one please help me and the tens of other people looking for similar code.
How do I get that external address in VB???????
TIA-
JustaHustla
-
still desperately seeking an answer
-
Find your IP?
Module:
Option Explicit
Public Const MAX_WSADescription = 256
Public Const MAX_WSASYSStatus = 128
Public Const ERROR_SUCCESS As Long = 0
Public Const WS_VERSION_REQD As Long = &H101
Public Const WS_VERSION_MAJOR As Long = WS_VERSION_REQD \ &H100 And &HFF&
Public Const WS_VERSION_MINOR As Long = WS_VERSION_REQD And &HFF&
Public Const MIN_SOCKETS_REQD As Long = 1
Public Const SOCKET_ERROR As Long = -1
Public Type HOSTENT
hName As Long
hAliases As Long
hAddrType As Integer
hLen As Integer
hAddrList As Long
End Type
Public Type WSADATA
wVersion As Integer
wHighVersion As Integer
szDescription(0 To MAX_WSADescription) As Byte
szSystemStatus(0 To MAX_WSASYSStatus) As Byte
wMaxSockets As Integer
wMaxUDPDG As Integer
dwVendorInfo As Long
End Type
Public Declare Function WSAGetLastError Lib "WSOCK32.DLL" () As Long
Public Declare Function WSAStartup Lib "WSOCK32.DLL" _
(ByVal wVersionRequired As Long, lpWSADATA As WSADATA) As Long
Public Declare Function WSACleanup Lib "WSOCK32.DLL" () As Long
Public Declare Function gethostname Lib "WSOCK32.DLL" _
(ByVal szHost As String, ByVal dwHostLen As Long) As Long
Public Declare Function gethostbyname Lib "WSOCK32.DLL" _
(ByVal szHost As String) As Long
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)
Module Code:
Public Function GetIPAddress() As String
'example
'x = GetIPAddress
'Label1.Caption = "ip: " + x + ""
Dim sHostName As String * 256
Dim lpHost As Long
Dim HOST As HOSTENT
Dim dwIPAddr As Long
Dim tmpIPAddr() As Byte
Dim i As Integer
Dim sIPAddr As String
If Not SocketsInitialize() Then
GetIPAddress = ""
Exit Function
End If
If gethostname(sHostName, 256) = SOCKET_ERROR Then
GetIPAddress = ""
MsgBox "Windows Sockets error " & Str$(WSAGetLastError()) & _
" has occurred. Unable to successfully get Host Name."
SocketsCleanup
Exit Function
End If
sHostName = Trim$(sHostName)
lpHost = gethostbyname(sHostName)
If lpHost = 0 Then
GetIPAddress = ""
MsgBox "Windows Sockets are not responding. " & _
"Unable to successfully get Host Name."
SocketsCleanup
Exit Function
End If
CopyMemory HOST, lpHost, Len(HOST)
CopyMemory dwIPAddr, HOST.hAddrList, 4
ReDim tmpIPAddr(1 To HOST.hLen)
CopyMemory tmpIPAddr(1), dwIPAddr, HOST.hLen
For i = 1 To HOST.hLen
sIPAddr = sIPAddr & tmpIPAddr(i) & "."
Next
GetIPAddress = Mid$(sIPAddr, 1, Len(sIPAddr) - 1)
SocketsCleanup
End Function
Public Function GetIPHostName() As String
'example
'l = GetIPHostName
'Label1.Caption = "hostname: " + l + ""
Dim sHostName As String * 256
If Not SocketsInitialize() Then
GetIPHostName = ""
Exit Function
End If
If gethostname(sHostName, 256) = SOCKET_ERROR Then
GetIPHostName = ""
MsgBox "Windows Sockets error " & Str$(WSAGetLastError()) & _
" has occurred. Unable to successfully get Host Name."
SocketsCleanup
Exit Function
End If
GetIPHostName = Left$(sHostName, InStr(sHostName, Chr(0)) - 1)
SocketsCleanup
End Function
Public Function HiByte(ByVal wParam As Integer)
HiByte = wParam \ &H100 And &HFF&
End Function
Public Function LoByte(ByVal wParam As Integer)
LoByte = wParam And &HFF&
End Function
Public Sub SocketsCleanup()
If WSACleanup() <> ERROR_SUCCESS Then
MsgBox "Socket error occurred in Cleanup."
End If
End Sub
Public Function SocketsInitialize() As Boolean
Dim WSAD As WSADATA
Dim sLoByte As String
Dim sHiByte As String
If WSAStartup(WS_VERSION_REQD, WSAD) <> ERROR_SUCCESS Then
MsgBox "The 32-bit Windows Socket is not responding."
SocketsInitialize = False
Exit Function
End If
If WSAD.wMaxSockets < MIN_SOCKETS_REQD Then
MsgBox "This application requires a minimum of " & _
CStr(MIN_SOCKETS_REQD) & " supported sockets."
SocketsInitialize = False
Exit Function
End If
If LoByte(WSAD.wVersion) < WS_VERSION_MAJOR Or _
(LoByte(WSAD.wVersion) = WS_VERSION_MAJOR And _
HiByte(WSAD.wVersion) < WS_VERSION_MINOR) Then
sHiByte = CStr(HiByte(WSAD.wVersion))
sLoByte = CStr(LoByte(WSAD.wVersion))
MsgBox "Sockets version " & sLoByte & "." & sHiByte & _
" is not supported by 32-bit Windows Sockets."
SocketsInitialize = False
Exit Function
End If
SocketsInitialize = True
End Function
Hopes thats somewhat of what your looking for.
[Edited by Matthew Gates on 05-11-2000 at 03:48 PM]
-
Thanks for responding Matthew, but this is not the code that I am looking for. I have this code and it works for finding my local IP address, but I am looking for my EXTERNAL IP address, the one that is assigned by my ISP.
Example:
I have a local IP address that is - 10.127.71.28
*not viewable outside my local LAN
But when I log onto the internet, my IP address is - 107.14.72.30
*viewable outside my local LAN (for TCP/IP communication over the internet)
Still looking for some insight…
P.S. Don’t bother flaming, spamming, or hacking these addresses cuz they’re not real.
-
I'm afraid that due to the way things work, your computer is not able to see your "external" IP address. This is why.
Lets say you want to connect to a computer - 128.118.87.74, for example. (My IP address when I was at college :).
Fairly simple pipeline:
[You] <-> [Remote]
Typical method goes like this
[You] -> [Remote] I wanna connect
[You] <- [Remote] Sure thang, sugar.
[You] -> [Remote] Alllllllrighty then :)
This is normally absolutely no problem for anybody. You say "Hi", the remote machine says "Hi" back, and then you're connected. However, when you're on a private LAN, the remote machine can't send data to your IP address (cuz its designated as private and isn't routable). So the situation changes to this:
[You] <-> [NAT Proxy] <-> [Remote]
The NAT proxy acts as a middle man. Because it's on the LAN, it knows where your IP address goes to, and since it's also on the Net, it knows where everybody else is, too. So what happens is this:
[You] -> -> [Remote] I wanna connect
the NAT proxy intercepts this message and does two things:
1. Jots down in its memory that you requested this connection.
2. Changes the 'From' address from your private IP address to its public IP, and forwards the packet on to the Remote machine.
Then when the remote machine replies:
[NAT Proxy] <- [Remote] Sure thang, sugar.
The NAT proxy looks up in its memory to see who asked to connect to the remote machine. It sees that it was you, and replaces the 'To' address from its own IP to the one on your computer.
The final effect is that your machine thinks it's talking directly to the remote machine, the remote machine thinks it's talking to the NAT proxy, and neither machine has any idea that there is a proxy involved.
Therefore, there is only one surefire way to figure out your IP address from behind a NAT proxy. Remember, the remote machine thinks it's talking to the proxy, not you - so you have to connect somewhere and get the remote machine to tell you what it thinks your IP address is. I can think of three ways off the top of my head:
[1] IRC servers tell you your IP address or hostname when you connect.
[2] Most SMTP servers tell you your IP address after you say 'HELO'.
[3] You can write a program that runs on a shell or something and echos the IP address of whoever connects to it.
-
Thanks for the info Stevie-O! It helps me to see why it’s been so difficult finding an answer to my problem. I have one more request though… Now that I know WHAT needs to be done, I would like some more info on HOW to do it.
Any info on setting up a shell or talking to my SMTP server (which in this case would probably be easiest) in VB would be greatly appreciated. I’m not looking for handouts here, but if some1 could point me in the right direction, I promise to post a link to the finished product here, as I’m sure a program like this would be useful to more and more people as the DSL and Cable networks grow.
TIA-
JustaHustla
-
Alas, there is no standard response for an SMTP server HELO reply, so you can't easily parse it.
-
If some1 could point me in the right direction for finding the syntax for SMTP communication, I can parse the specific reply and set up a menu for modifying how that reply is parsed for different ISP's.
I've gotten over 20 requests for this program already. Please, let's make this happen.
TIA-
JustaHustla
-
A good place to start would be the SMTP RFC, at http://www.rfc-editor.org/. Choose 'search for an RFC'.
-
Stevie-O, Thanks again for your wisdom. I am making some progress. I know a lot more about SMTP now (great reference) but all I get back from the HELO request to the SMTP is '220 VPOP3 SMTP Server Ready'. No IP address. I'll keep hunting for the right answer. I know it can be done, because I just came across a great little program called Zoomspy that works for those folks using Zoomtown's DSL connection in the Cincinnati area. It keeps your connection from timing out and posts your external IP address.
If anyone else can shed a little light here, please respond.