Get ip from domain - gethostbyname - Help please

Okay so ive been trying to figure this out and it is trolling me soo bad :/ I can't seem to figure it out. So ive come here to see if one of you guys can help me with my issue.
So I want people to be able to input a domain name I.e Www.google.com and it will get the ip of the website. But everytime I do it, it just gives 0000
Here is some code.

#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ostream>
#include <winsock2.h> // header file for WinSock 2
#include <stdio.h>
#pragma comment(lib, "ws2_32")
using namespace std;
#define NL '\n'

HOSTENT* webDomain;
char websiteConnect[50];
int main()
{
cout << "Enter your domain";
cout << NL;
cin >> websiteConnect;
cout << NL;
webDomain = gethostbyname(websiteConnect);
cout << NL;
cout << webDomain; // <--- This only is giving 0000 D:




return 0;
}

Okay so when webDomain is printed to the console it is only showing 000000. Can someone please help me here i'm having some real trouble figuring it out.
Cheers
Kingpulse

Well you're going to have several problems with that.
First, and most importantly, you have to start winsock. http://msdn.microsoft.com/en-us/library/windows/desktop/ms738566(v=vs.85).aspx

secondly, there's no overload for ostream << that supports outputting a HOSTENT structure. IP addresses are stored in HOSTENT.h_addr_list.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738552(v=vs.85).aspx (reference for HOSTENT structs.)


I'll try my best to provide some nice examples and elaborate on this, however, winsock takes extreme perseverance to become comfortable with.

Firstly, with any winsock program, you must initialize winsock. You do so as follows:
1
2
3
4
5
6
7
WSADATA wsaData; //structure that holds information about current wsock version.
if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) //start wsock version 2.2. Function returns
	//0 if successful, otherwise, there was an error that needs to be reported.
{
    cout << "WSAStartup failed: " << WSAGetLastError(); //report the error if     there is one
    return 1; //exit the program. 
}


So that bit initializes winsock, so you can now use it in your code. If you don't start winsock and try to use winsock functions, you'll get a whole bunch of undefined behavior, and probably some crashes.

Now, take input from the user to get the website name to lookup.
1
2
3
4
5
6
string websiteName;
cout << "Enter website name: ";
cin >> websiteName;

//and call gethostbyname to populate the webDomain HOSTENT structure you declared globally.
webDomain= gethostbyname(name.c_str()); 


HOSTENT structures contain several things, which you can see from the msdn reference link i posted earlier. You're looking for IP addresses, so the important member is h_addr_list, which MSDN says is "A NULL-terminated list of addresses for the host."
So we know that h_addr_list is an array of all the IP addresses owned by the host name, ending with a NULL entry.

So, because it is possible for a domain to have more than one IP address, we create a loop to go through all entries in h_addr_list.
1
2
3
4
5
6
7
8
9
10
11
for(int i = 0; ; ++i) //Purposefully left the second condition out, because we will
//be testing for it inside the loop.
{
    char *temp = webDomain->h_addr_list[i];
    if(temp == NULL) //we reached the end of the list
        break; //exit the loop. 

    in_addr *addr = reinterpret_cast<in_addr*>(temp);
    cout << inet_ntoa(*addr) << endl; //Output the IP.
    //I'll elaborate more on this next.
}


Now comes some more weird stuff.
values in h_addr_list are typically type-casted to in_addr, which is a winsock structure that represents an IPv4 address.
So we cast temp to be a pointer to an in_addr structure by using the reinterpret_cast function: reinterpret_cast<in_addr*>(temp).

So now we have an in_addr pointer to deal with. If you look at the documentation of the in_addr structure, it's horribly confusing, and 'ostream <<' isn't overloaded to directly output an in_addr structure.
Luckily, there's a winsock function that converts in_addr to an ASCII string, which 'ostream <<' can deal with. it's called inet_ntoa. (http://msdn.microsoft.com/en-us/library/windows/desktop/ms738564(v=vs.85).aspx)
So using inet_ntoa, we can output the IPv4 address:
cout << inet_ntoa(*addr) << endl;
Note, inet_ntoa does not take an in_addr pointer as a parameter. So we dereference it in order to use this function.


At the end of your code, because we started winsock, we must stop it by calling the WSACleanup function.
1
2
3
WSACleanup();
cout << "Program complete." << endl;
return 0;


So, I tried to explain that as well as I could. Winsock (and all windows APIs in my opinion) is terribly hard to put into layman's terms. And as you'll probably soon find out, learning to use Winsock involves massive amounts of digging through documentation.
I hope I helped to solve your problem!

-Thumper


EDIT:
Also, this isn't an entirely complete program. It lacks a bunch of exception handling (such as checking to see if the user entered a proper domain name, or whether or not we were receiving IPv4, or IPv6 addresses.)
I was just trying to provide you a guideline for where to begin.
Last edited on
Thanks heaps :D, its a little confusing for me because i'm just beggining programming in general but ill give it my best shot :D
Topic archived. No new replies allowed.