Search code examples
c++socketsnetwork-programmingposix

converting data to struct hostent from getaddrinfo()


I am replacing old code to linux. I was using:

server_host = getipnodebyname(host.c_str(), AF_INET, 0, &err_num);

and

server_host = getipnodebyaddr(addr, sizeof(INET_ADDRSTRLEN), AF_INET, &err_num);

that it has to be replaced by the new getaddrinfo().

At moment I added:

struct addrinfo *p_addr = (struct addrinfo *) NULL;
struct addrinfo hints={0};                                          //Initialize the addrinfo hints
char addr[INET_ADDRSTRLEN]={0};
int result = 0;

memset(&hints, 0, sizeof(hints));

hints.ai_family = AF_INET;                                          //Request for IPV4 ADDRESSES ONLY

result = getaddrinfo(host.c_str(), NULL, &hints, &p_addr);

but I need to populate the gathered information in the hostent structure:

hostent     *server_host;

for compatibility with other code. I could use the gethostbyname() to get directly the hostent structure but I want avoid it. What do you suggest?


Solution

  • There is no C library function to convert an addrinfo into a hostent. You will have to construct the hostent yourself using the data from the addrinfo, eg:

    #include <vector>
    
    addrinfo hints = {0};
    hints.ai_family = AF_INET;
    hints.ai_flags = AI_CANONNAME;
    
    addrinfo *p_addrs = NULL;
    
    int result = getaddrinfo(host.c_str(), NULL, &hints, &p_addrs);
    if (result != 0) ... // error handling...
    
    std::vector<in_addr*> in_addrs;
    
    for(addrinfo *p_addr = p_addrs; p_addr != NULL; p_addr = p_addr->ai_next) {
        in_addrs.push_back(&reinterpret_cast<sockaddr_in*>(p_addr->ai_addr)->sin_addr);
    }
    in_addrs.push_back(NULL);
    
    hostent hst;
    h.h_name = p_addrs->ai_canonname;
    h.h_aliases = NULL;
    h.h_addrtype = AF_INET;
    h.h_length = sizeof(in_addr);
    h.h_addr_list = reinterpret_cast<char**>(&in_addrs[0]/* or: in_addrs.data() */);
    
    // use hst as needed ...
    
    freeaddrinfo(p_addrs);