Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the external IP address in C++?

How would I go about finding the external IP of a user in C++? I need a method that would work for any system, not just mine. Additionally, the system could be behind a router, thus NAT would come into play making it harder to retrieve the external IP.

Ideally, I'd like to do this without using any 3rd party service like whatsmyip. However, I'm not sure if this is possible. If I don't use a 3rd party service, I'd have to go through the router and if ping is disabled I'm guessing this might not be possible (I could be wrong, not too sure).

If I were to use a 3rd party service like whatsmyip, how might I go about this? Is there a web service that they expose? I've seen this link: http://automation.whatismyip.com/n09230945.asp but it doesn't seem to be working. Would it be possible to fetch the external IP by using some HTTP methods and retrieve it, or would I effectively need to scrape the page to get the IP from it?

I'm limited to using Windows API's to accomplish this (no 3rd party API's)

like image 210
spdcbr Avatar asked Sep 07 '25 09:09

spdcbr


1 Answers

In theory, you can use the Windows uPnP API to do this. You'd start by using the UPnPDeviceFinder to enumerate Internet Gateway Devices. Then you get an IUPnPRemoteEndpointInfo for the gateway (well, there's usually only one, anyway) and invoke its GetStringValue, passing a string containing "RemoteAddress" to get its remote address (which I think means its external address, though I'll admit I'm not entirely certain). Oh, and since this is COM, that has to be a system string, not a normal string.

Getting the IP from an external provider is a lot easier. Without using any 3rd party libraries, code for it looks like this:

#include <windows.h>
#include <wininet.h>
#include <string>
#include <iostream>

std::string real_ip() { 

    HINTERNET net = InternetOpen("IP retriever",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        0);

    HINTERNET conn = InternetOpenUrl(net, 
                                     "http://myexternalip.com/raw", 
                                      NULL, 
                                      0, 
                                      INTERNET_FLAG_RELOAD, 
                                      0);

    char buffer[4096];
    DWORD read;

    InternetReadFile(conn, buffer, sizeof(buffer)/sizeof(buffer[0]), &read);
    InternetCloseHandle(net);    

    return std::string(buffer, read);
}

int main() {
    std::cout << real_ip() << "\n";
}

compiled with:

cl ip_addr.cpp wininet.lib

Note: if your machine is configured to use IPv6, this can (and will) retrieve your IPv6 address).

like image 179
Jerry Coffin Avatar answered Sep 09 '25 21:09

Jerry Coffin