i p freely

August 17, 2005 under Computers, Internet, Programming

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 😉

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)
comments: 19 »

19 Responses to "i p freely"

  • barry says:

    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…

  • Chris says:

    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.

  • NoWayOut says:

    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!

    
    Public Function GetExternalIP() As String
        const String IP_URL = "http://checkip.dyndns.org"
        Dim strHTML As String, strIP As String
    
        ' Send the request and hopefully we'll get response.
        ' Try to parse out the IP address from the returned HTML
        Try
            Dim objWebReq As WebRequest = WebRequest.Create(IP_URL)
            Dim objWebResp As WebResponse = objWebReq.GetResponse()
            Dim strmResp As Stream = 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 ex As Exception
            Console.WriteLine("Can't retrieve external IP: " +
                              ex.Message)
            Return Nothing
        End Try
    End Function
    
    
  • Chris says:

    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:

    
    Imports System.Net.WebClient
    Imports System.Net
    Imports System.Web
    Imports System.Text.RegularExpressions
    Imports System.IO
    
    ' 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
    Function GetExternalIP() As String
        Const IP_URL As String = "http://checkip.dyndns.org"
        Dim strHTML As String, strIP As String
    
    
        ' Send the request and hopefully we'll get response.
        ' Try to parse out the IP address from the returned HTML
        Try
            Dim objWebReq As WebRequest = WebRequest.Create(IP_URL)
            Dim objWebResp As WebResponse = objWebReq.GetResponse()
            Dim strmResp As Stream = objWebResp.GetResponseStream()
            Dim srResp As StreamReader = New StreamReader(strmResp,_
                                                          True)
    
            strHTML = srResp.ReadToEnd()
            Dim regexIP As Regex = New Regex(_
                "\\b\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}\\b")
            strIP = regexIP.Match(strHTML).Value
            Return strIP
        Catch ex As Exception
            Console.WriteLine("Can't retrieve external IP: " + _
                                  ex.Message)
            Return Nothing
        End Try
    End Function
    
    

    Hope that helps 😀

  • NoWayOut says:

    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 ?

  • Chris says:

    I’ve just compiled the following console app using Visual Studio .NET 2003 with no problems:

    
    Imports System.Net.WebClient
    Imports System.Net
    Imports System.Web
    Imports System.Text.RegularExpressions
    Imports System.IO
    
    Module Module1
        ' 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
        Function GetExternalIP() As String
            Const IP_URL As String = "http://checkip.dyndns.org"
            Dim strHTML As String, strIP As String
    
            ' Send the request and hopefully we'll get response.
            ' Try to parse out the IP address from the returned HTML
            Try
                Dim objWebReq As WebRequest = _
                    WebRequest.Create(IP_URL)
                Dim objWebResp As WebResponse = _
                    objWebReq.GetResponse()
                Dim strmResp As Stream = _
                    objWebResp.GetResponseStream()
                Dim srResp As StreamReader = _
                    New StreamReader(strmResp, True)
    
                strHTML = srResp.ReadToEnd()
                Dim regexIP As Regex = _
                    New Regex("\\b\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}\\b")
                strIP = regexIP.Match(strHTML).Value
                Return strIP
            Catch ex As Exception
                Console.WriteLine("Can't retrieve external IP: " + _
                                      ex.Message)
                Return Nothing
            End Try
        End Function
    
        Sub Main()
            Console.WriteLine(GetExternalIP())
        End Sub
    End Module
    
    
  • NoWayOut says:

    worked it fine 🙂 great code man

  • NoWayOut says:

    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

  • Chris says:

    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 😉

  • nowayout says:

    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?

    
    Catch ex As Exception
    Dim message As String = "No Internet Connection Available"
    Return message
    
    

    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

  • Chris says:

    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:

    
    ' Try to contact the website for 10 seconds.
    objWebReq.Timeout = 10000
    
    

    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

    
    Imports System.Net.WebClient
    Imports System.Net
    Imports System.Web
    Imports System.Text.RegularExpressions
    Imports System.IO
    
    Public Class Class1
        Function GetWanIP() As String
            Const IP_URL As String = "http://checkip.dyndns.org"
            Dim strHTML As String, strIP As String
    
            Try
                Dim objWebReq As WebRequest = _
                    WebRequest.Create(IP_URL)
                Dim objWebResp As WebResponse = _
                    objWebReq.GetResponse()
                Dim streamResp As Stream = _
                    objWebResp.GetResponseStream()
                Dim srResp As StreamReader = _
                    New StreamReader(streamResp, True)
    
                strHTML = srResp.ReadToEnd()
                Dim regexIP As Regex = _
                    New Regex("\\b\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}\\b")
                strIP = regexIP.Match(strHTML).Value
                GetWanIP = strIP
            Catch ex As Exception
                GetWanIP = ex.Message
            End Try
        End Function
    End Class
    
    

    Form1.vb

    
    ' a bunch of Windows Form Designer generated code
    
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                    Handles Button1.Click
            Dim x As New Class1
    
            Me.TextBox1.Text = x.GetWanIP()
    
    
            x = Nothing
    End Sub
    
    

    Works for me.

  • scorpion53061 says:

    Excellent work. Works in 2005 too.

  • Chris says:

    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 🙁

  • scorpion53061 says:

    well it is huge.

    I am starting school next semester. I enrolled in Java, C++ and COBOL. Do you think i am crazy? 🙂

  • Chris says:

    Not at all. Well, maybe the COBOL class will be a tad crazy 😉

  • scorpion53061 says:

    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.

  • Carmen says:

    Any idea how you could create a socket connection between two computers behind NATs in C#???

    Carmen

  • Chris says:

    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

    
    // start the server
    TcpListener objSrvr = new TcpListener(6299);
    objSrvr.Start();
    
    

    client.cs

    
    // connect to the server
    try
    {
        // use IP of the server computer here instead of localhost
        TcpClient objClnt = new TcpClient("127.0.0.1", 6299);
    }
    catch
    {
        Console.WriteLine("Connection failed");
    }
    
    

    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.

  • Darkhorse says:

    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 Reply

Your email address will not be published. Required fields are marked *

Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>