3

I am new to internet programming, and I am trying to use the gethostbyname() function. When I input a string such as "www.yahoo.com" to gethostbyname function it works fine, but when I input a char array, it will always return an empty buffer.

  char hostname[100];
  struct hostent* h;
  gethostname(hostname, sizeof hostname );
  printf("Hostname: %s\n", hostname);
  h = gethostbyname(hostname);

Any idea how to solve this?

user207421
  • 305,947
  • 44
  • 307
  • 483
BVBC
  • 375
  • 2
  • 4
  • 11
  • 1
    Is `gethostname()` returning a valid hostname? You are not checking the return value for error. In any case, there is little point in calling `gethostbyname()` for the hostname reported by `gethostname()`. That is a common mis-guided way to retrieve the IP addresses of the local machine. You should be using `GetAdaptersInfo`/`GetAdaptersAddresses` (Windows), `getifaddrs()` (*Nix), or other similar platform-specific function to enumerate the local interfaces directly instead. – Remy Lebeau Nov 17 '15 at 01:37
  • Yes, gethostname returns the correct hostname, but gethostbyname always returns null. – BVBC Nov 17 '15 at 01:41
  • 1
    What are you really trying to accomplish? `gethostbyname()` performs a DNS lookup. Using the hostname reported by `gethostname()` is not guaranteed to return a valid DNS result, depending on your machine's DNS settings. On some platforms, calling `gethostbyname()` using the local hostname will return a result, on some platforms it will not. If it fails, check `WSAGetLastError()`/`h_errno` to find out why. In any case, `gethostbyname()` is deprecated anyway, you should be using `getaddrinfo()` instead. – Remy Lebeau Nov 17 '15 at 01:55
  • @RemyLebeau I just try to find out the ip address of the machine I am running. Anyway, I think I will check out getaddrinfo() instead, Thanks! – BVBC Nov 17 '15 at 02:03
  • @SH.C What's your machine's hostname? – user253751 Nov 17 '15 at 02:06
  • "*I just try to find out the ip address of the machine I am running*" - like I said earlier, using `gethostbyname()` on the hostname reported by `gethostname()` is the **wrong** way to retrieve the local machine's IP addresses. There are other functions more suited for that purpose, and I already mentioned some of them to you. What you are trying **is not guaranteed** to work the way you are expecting, so use something else that **is guaranteed** to work. – Remy Lebeau Nov 17 '15 at 03:13
  • @StoneThrow does it really matter? `gethostbyname()` is the **wrong** way to get the calling machine's local IPs, so just don't do it. It doesn't matter if it "works" or not. Use `GetAdaptersInfo()`/`GetAdaptersAddresses()`, `getifaddrs()`, etc, depending on your platform. This is what they are specifically intended for. – Remy Lebeau Jan 18 '19 at 02:38
  • It doesn't 'return null'. It returns an errror code, which you are ignoring, and writes into a buffer. You got an error, which you should display with `perror()`, so it didn't do anything to your buffer. Never ignore the results of system calls. – user207421 Apr 02 '21 at 05:25

4 Answers4

1

Your server can't resolve itself. The most common way of "fixing" this is to put its own name into its hostfile. While this is a good idea for various reasons, the underlying problem really should be fixed.

  1. The DNS search list should normally be set to the domainname that contains the hostname -or- the hostname should be fully qualified itself.
  2. DNS should be correctly set up for the host.

This makes it not really a C problem at all, but a server configuration problem. Off it goes then.

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • Note to mods -- this answer is valid in the transfer target of serverfault. Probably not going to be voted very high but better than no answer at all. – Joshua Nov 17 '15 at 02:24
1
WSADATA wsaData;
int error;
if ((error = WSAStartup(MAKEWORD(1, 1), &wsaData)) !=0)
{      
    printf("Error %d in WSAStartup, result will fail\n",error);
}   
char hostname[100];
struct hostent* h;
gethostname(hostname, sizeof hostname );
printf("Hostname: %s\n", hostname);
h = gethostbyname(hostname);
0

In the linux programmers manual the function has the following declaration:

struct hostent *gethostbyname(const char *name);

This means the parameter must be a char array (or string in layman terms). A quoted string such as "yahoo.com" can be used directly when calling the function.

The following code is a working example on how gethostbyname works:

#include <stdio.h>
#include <string.h>
#include <netdb.h>

int main(){
  struct hostent* h=gethostbyname("yahoo.com");
  printf("Hostname: %s\n", h->h_name);
  printf("Address type #: %d\n", h->h_addrtype);
  printf("Address length: %d\n", h->h_length);

  char text[50]; // allocate 50 bytes (a.k.a. char array)
  strcpy(text,"bing.ca"); //copy string "bing.ca" to first 7 bytes of the array
  h=gethostbyname(text); //plug in the value into the function. text="bing.ca"
  printf("Hostname: %s\n", h->h_name);
  printf("Address type #: %d\n", h->h_addrtype);
  printf("Address length: %d\n", h->h_length);

  return 0;
}

I called it twice. Once for yahoo.com and once for bing.ca and I retrieved the hostname, the address type number and the address length (which is the number of bytes required to store the IP).

For calling the bing address, I allocated a char array, filled it with a string then passed that char array as a parameter to the function.

Mike -- No longer here
  • 2,064
  • 1
  • 15
  • 37
  • So it is the problem of gethostname then? In my case I do not know my hostname, so I cannot hardcode it into a char array. When I try your code with gethostname it still returns null. – BVBC Nov 17 '15 at 02:16
  • Do you have a working internet connection on the (virtual?) machine the code is running in? You could get the value from `gethostname()` and plug the value (1st parameter to gethostname function) directly into `gethostbyname()` right after, just like what you showed in your code, but put brackets around hostname after "sizeof". But I'm taking the ultimate guess your internet quality is poor at the time the function is executed. – Mike -- No longer here Nov 17 '15 at 02:20
  • Yes, I do have a working internet connection. So does it work when you add gethostname to your code? – BVBC Nov 17 '15 at 02:33
  • 1
    This is not an issue with having or not having an Internet connection. There is no guarantee that `gethostbyname()` can always resolve the hostname reported by `gethostname()` into an IP address on all platforms. So don't even try it, it is the wrong approach anyway. Use [`getifaddrs()`](http://man7.org/linux/man-pages/man3/getifaddrs.3.html) or similar function instead. – Remy Lebeau Nov 17 '15 at 03:10
0

One good reason why it's returning NULL is because the hostname what you are passing is not correct. Sometimes even doing hostname -v will not give the correct host name.

Try following:

cat /etc/hosts

this will show you output as:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain

That 'localhost' next to 127.0.0.1 in the output above is your host name. This will work perfectly with gethostbyname.