IP addresses have been a hot topic lately, for whatever reason. According to my webserver stats, I’m getting plenty of hits on one of my scripts from search engines with terms like “get ip address” and “vb external ip”. Yesterday, Barry talked about a guy wanting to know how to get the IP address of visitors. So to make all of the wanna-be script kiddies out there happy, I’ll mention my favourite way to get IP addresses from a client application. Some of this came in handy when I wrote some stuff to hack a Russian software pirate, but I’ll save that story for another day.
Getting an internal IP address is a snap. All operating systems have a way to view the currently assigned IP address on a network adapter. ‘ipconfig’ in Windows XP and ‘ifconfig’ in UNIX are basically the same command-line interface utilities. With each, you can also redirect the output of these commands to a text file for later parsing. Take a peek at this VBScript that I wrote to grab my NIC’s IP address, save it to a temporary file on disk and then parse my IP out of it:
' Purpose: Retrieve the currently assigned internal IP address
' I: (none)
' O: IP address
Function GetInternalIP()
Const DEF_ADDRESS_TEXT = "Address"
Const DEF_9X_CMDLINE = "winipcfg /batch"
Const DEF_NT_CMDLINE = "%comspec% /c ipconfig >"
Dim objWSHShell
Dim objFSO
Dim strTempFile
Dim strTempLine
Dim strIP
' create the WSH object
Set objWSHShell = CreateObject("WScript.Shell")
' create the FSO object
Set objFSO = CreateObject("Scripting.FileSystemObject")
' assemble path to temp file in Windows' TEMP dir
strTempFile = objFSO.GetSpecialFolder(2) & "\ip.txt"
If (objWSHShell.Environment("SYSTEM")("OS") = "") Then
' Win9x/ME
objWSHShell.Run DEF_9X_CMDLINE & " " & strTempFile, _
0, True
Else
' WinNT4/2000/XP/2003
objWSHShell.Run DEF_NT_CMDLINE & " " & strTempFile, _
0, True
End If
' open the temp file
With objFSO.GetFile(strTempFile).OpenAsTextStream
Do While NOT .AtEndOfStream
' read a line from our temp file
strTempLine = .ReadLine
If (InStr(strTempLine, DEF_ADDRESS_TEXT) <> 0) Then
‘ strip out the IP address
strIP = Trim(Mid(strTempLine, _
InStr(strTempLine, “:”) 1))
End If
Loop
‘ close the temp file
.Close
End With
‘ return the IP address
GetInternalIP = strIP
‘ delete our temp file
objFSO.GetFile(strTempFile).Delete
‘ cleanup
Set objFSO = Nothing
Set objWSHShell = Nothing
End Function
It could be even simpler using the WMI Win32_NetworkAdapterSetting class, which would negate the need to run system-level commands and parse the output in a text file. In the case that WMI is not installed or you’re on a non-Windows computer and want something slicker, here’s how I do it in Python:
import socket
# Purpose: Retrieve the currently assigned internal IP address
# I: (none)
# O: IP address
def GetInternalIP():
strIP = socket.gethostbyname(socket.gethostname())
return strIP
Pretty simple, but for those folks behind a router using NAT (the main benefit of using a router in the first place), this isn’t your IP address on the Internet; it’s only your internal LAN IP address. The router will be assigned an “external” IP address from your ISP. But you can’t run DOS or UNIX shell commands on commercial routers, and that’s where a few websites come in handy. At the most basic level, these websites merely displaying the IP address that you are assigned to you by your ISP that makes the TCP protocol work over the big network we call the Internet. It does so by displaying the contents of an environment variable, called REMOTE_ADDR, that all webserver software stores for each visiting session. I like CheckIP (from DynDNS) but IP Chicken and ShowMyIP work fine as well. ShowMyIP is especially nice because it displays more info and even offers an XML document. Any language worth a damn should provide a way to send HTTP (and then some) requests out to the Web either natively or via external libraries. Here’s how I use CheckIP and a regular expression to retrieve the external IP address in C#:
using System;
using System.Net;
using System.Web;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
// Purpose: Get the external IP address of the computer. Using
// dyndns.org's checkip tool. This will work
// behind NAT routers.
// I: (none)
// O: external IP address
public string GetExternalIP()
{
const string IP_URL = "http://checkip.dyndns.org";
string strHTML, strIP;
// Send the request and hopefully we'll get response.
// Try to parse out the IP address from the returned HTML
try
{
WebRequest objWebReq = WebRequest.Create(IP_URL);
WebResponse objWebResp = objWebReq.GetResponse();
Stream strmResp = objWebResp.GetResponseStream();
StreamReader srResp = new StreamReader(strmResp,
Encoding.UTF8);
strHTML = srResp.ReadToEnd();
Regex regexIP = new Regex(
@"\\b\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}\\b");
strIP = regexIP.Match(strHTML).Value;
return strIP;
}
catch(Exception ex)
{
Console.WriteLine("Can't retrieve external IP: "
ex.Message);
return null;
}
}
There you go. Now all those folks who have been getting to my site via “get router ip” type Google queries will have a nice blog post describing what they’re looking for instead of simply copying some of my source code. Use it for good and never for evil ![]()
Facebook
Linkedin
Twitter
FriendFeed
Last.fm
Google Reader
Reddit
Digg
YouTube
Technorati
19 responses so far ↓
1 barry // Aug 18, 2005 at 10:52 am
Somedays I wonder if we should be spending our time trying to feed the children of africa than wondering how to get an IP from the client side…
2 Chris // Aug 18, 2005 at 11:45 am
That would be a different blog entry entirely, as opposed to ones about computers, music or living in the “docuverse” or whatever.
Actually, that was an entry of mine back in July.
3 NoWayOut // Sep 18, 2005 at 3:52 pm
This is the code for VB.Net!
But i get an error in first line saying Statement is not valid in a namespace.
Any help is appreciated!
4 Chris // Sep 18, 2005 at 4:59 pm
VB syntax is somewhat different from C# in terms of declaring/initialising variables like constants and objects. Something like the following should do the trick:
Hope that helps
5 NoWayOut // Sep 18, 2005 at 6:23 pm
i still get error: Function GetExternalIP() As String
Statement is not valid in a namespace.
Any idea bro? Have u tried the code to vb.net ? Could you have it a look please?
Or maybe its me ? I have something else to do that i didnt ?
6 Chris // Sep 18, 2005 at 6:37 pm
I’ve just compiled the following console app using Visual Studio .NET 2003 with no problems:
7 NoWayOut // Sep 18, 2005 at 6:56 pm
worked it fine
great code man
8 NoWayOut // Sep 18, 2005 at 7:24 pm
Could u re-write the code to use a backup url ? In case one is down it can use second or third one to get the ip!
Isnt that good way?
Also you could use the router knowing username and password from it and get the WAN IP!
Lemme know bro
9 Chris // Sep 19, 2005 at 10:48 am
It would be easy to modify the function to use other sites like IP Chicken. The regex that I use would also pick up the IP returned by IP Chicken or any other site that will display your IP Address as text and not as an image. You could either do it as separate function or implement it in the existing one. That’s one of the reasons why I posted my code in the first place…so people can learn from it and expand upon it
10 nowayout // Oct 1, 2005 at 2:49 pm
Great. I ve modified everything so far but i came up with a little problem. When my internet connection is not active my application sometimes work and sometimes stuck. I get the exception to return me a message to a textbox saying “There is no active connection”. Any ideas y it stucks?
I am calling it from the main form Dim x As New Class1 : x.GetWanIP()
Is there some other way of returning the exception without application freezing? Or somehow to test if internet is available and if its not return the message?
Thanks
nowayout
11 Chris // Oct 3, 2005 at 8:16 pm
You shouldn’t really need to explicitly state this unless you really want/need to, but how about if you use WebRequest’s Timout property? If the timeout value (in milliseconds) is reached before the GetResponse() method returns anything (Ex: website down, Internet connection has gone wonky, DNS hiccup, etc), it’ll throw a WebException but we’re already trapping that by using the System.Exception supertype:
I’m not sure why your app locks up, though. I’m wondering what else is going on. What happens if you test out the class and the GetWanIP() method from a simple form like this:
Class1.vb
Form1.vb
Works for me.
12 scorpion53061 // Dec 8, 2005 at 9:19 am
Excellent work. Works in 2005 too.
13 Chris // Dec 8, 2005 at 9:26 am
Thanks for letting me know that all is well with VS.NET 2005
I’m still running VS.NET 2003 on .NET 1.1 and haven’t had the opportunity to use .NET 2.0 yet
14 scorpion53061 // Dec 8, 2005 at 10:48 am
well it is huge.
I am starting school next semester. I enrolled in Java, C++ and COBOL. Do you think i am crazy?
15 Chris // Dec 8, 2005 at 10:53 am
Not at all. Well, maybe the COBOL class will be a tad crazy
16 scorpion53061 // Dec 8, 2005 at 11:05 am
COBOL. I never thought I would have to learn this. It was suppose to have died. Every where I go though they want hteir programmers to know this language.
17 Carmen // Dec 12, 2005 at 8:24 pm
Any idea how you could create a socket connection between two computers behind NATs in C#???
Carmen
18 Chris // Dec 12, 2005 at 9:19 pm
Depending on your application’s goals, you’d need to create server and client components for your project. System.Net.Sockets has everything that you need. If both NAT routers have the same holes poked in them, let’s say TCP 6299, then your server and client and components should do all communication over that port:
server.cs
client.cs
If the ports aren’t known beforehand, I suppose you could always have the client send a special hash to a range of ports that only the indended server will repspond to. So when the client gets the expected response, it should store which port it was on - esentially, an ad-hoc port scanner.
19 Darkhorse // Dec 17, 2005 at 10:34 am
The reason they want you to know COBOL is because there are TONS of legacy apps waiting to be migrated to alternative technology right now…
Leave a Comment