0

I want to code this kind of program so that I can merge it with my ip handler program that adds ip addresses onto a database. My question now is how can I get the external ip address of the computer and not the router nor the ISP provider or something else. It is worth noting that I'm on Visual Studio 2017. Please note I'm using this for learning purposes and not for malicious purposes. Here's my revised version of the code:

IpHandler.cpp

#include "stdafx.h"
#include "IpHandler.h"
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _WINSOCK_DEPCRECATED 
#include <string.h>
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <locale>
#include <sstream>
#pragma comment(lib,"ws2_32.lib")

using std::cout; using std::locale; using std::istringstream;

string IpHandler::website_HTML = "";
char IpHandler::buffer[10000];

IpHandler::IpHandler(){ }

void IpHandler::get_Website(string url) {
    WSADATA wsaData;
    SOCKET Socket;
    SOCKADDR_IN SockAddr;
    struct hostent *host;
    string get_http = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n";

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "WSAStartup failed.\n";
        system("pause");
        return;
    }

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    host = gethostbyname(url.c_str());

    SockAddr.sin_port = htons(80);
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);

    if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) {
        cout << "Could not connect";
        system("pause");
        return;
    }
    send(Socket, get_http.c_str(), strlen(get_http.c_str()), 0);

    int nDataLength;
    while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            website_HTML += buffer[i];
            i += 1;
        }
    }
    closesocket(Socket);
    WSACleanup();
}
string IpHandler::GetExternalIp() {
    locale local;
    char lineBuffer[200][80] = { ' ' };
    char ip_address[16];
    int lineIndex = 0;

    get_Website("api.ipify.org");
    for (int i = 0; i < website_HTML.length(); ++i) { website_HTML[i] = tolower(website_HTML[i], local); }

    istringstream ss(website_HTML);
    string stoken;

    while (getline(ss, stoken, '\n')) {
        strcpy_s(lineBuffer[lineIndex], stoken.c_str());
        int dot = 0;
        for (int ii = 0; ii< strlen(lineBuffer[lineIndex]); ii++) {

            if (lineBuffer[lineIndex][ii] == '.') dot++;
            if (dot >= 3) {
                dot = 0;
                strcpy_s(ip_address, lineBuffer[lineIndex]);
            }
        }
        lineIndex++;
    }
    return ip_address;
}

IpHandler::~IpHandler()
{
}

IpHandler.h

#pragma once
#include <string>
using std::string;
class IpHandler
{
    static string website_HTML;
    static void get_Website(string url);
    static char buffer[10000];
public:
    IpHandler();
    static string GetExternalIp();
    ~IpHandler();
};
CraftedGaming
  • 499
  • 7
  • 21
  • 3
    You do realise that a few routers between you and the outside world may exist and may be transparent to you – Ed Heal Jan 02 '18 at 10:28
  • You forgot that only `nDataLength` bytes are valid. (I suspect that you got all your data at once earlier, but not his time.) – molbdnilo Jan 02 '18 at 10:32
  • @molbdnilo, Can you elaborate further? I'm still new to Sockets and how it works – CraftedGaming Jan 02 '18 at 10:52
  • 1
    Are you sure it is direct to the internet and not to you ISP? – Ed Heal Jan 02 '18 at 10:55
  • @CraftedGaming `recv` has only received `nDataLength` bytes and you may be reading outside the received data. – molbdnilo Jan 02 '18 at 11:02
  • 2
    In other words, you copied broken code to start with. – molbdnilo Jan 02 '18 at 11:08
  • @EdHeal Oh ok. I forgot about ISPs – CraftedGaming Jan 02 '18 at 12:56
  • @EdHeal, I managed to fix the code with the help of mol. However, how can I get the external ip of the computer itself and not the router nor the ISP? also I updated the question to fit my problem – CraftedGaming Jan 02 '18 at 13:19
  • Note that that code only shows you what `api.ipify.org` **tells you** your external IP address is -- there is no guarantee that that is the correct IP address for anything else, especially in the presence of a malicious MITM. (Or if someone else later takes over that domain name!) – Daniel Pryden Jan 02 '18 at 13:19
  • Hm that gave me an idea for my program like to check if the ip address is different from the former one haha thanks @DanielPryden – CraftedGaming Jan 02 '18 at 13:21
  • This whole question smells like an X-Y problem to me: what are you **actually** trying to do? You seem to be making a lot of assumptions which are not necessarily valid, and I'm pretty sure there's a better way to solve the problem you're trying to solve. For example, perhaps what you're looking for is some kind of dynamic DNS provider? – Daniel Pryden Jan 02 '18 at 13:22
  • @CraftedGaming: Also, if your ISP uses DHCP to assign IP addresses (most do) then your computer's IP address may arbitrarily change at any time determined by the ISP. You can't count on it staying stable unless you have a contract with the ISP that says it will (and, in my experience, not even then, with most ISPs). – Daniel Pryden Jan 02 '18 at 13:24
  • Hm I forgot the dynamic IPs. My question is flawed and has lots of holes. I'll do some more research before I ask again. I'd close my question for now. Thanks though – CraftedGaming Jan 02 '18 at 13:30

0 Answers0