简体   繁体   中英

How to replace inet_pton with getaddrinfo

Consider the inet_pton function:

#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst)

As far as I understand, this function takes an IP-address string in dotted decimal form as input (src) and converts this string to byte form, which is required by some network programming tasks. In fact, src gets converted to a struct in_addr which is copied to dst (provided af = AF_INET). And within this struct, there should be an entry of the IP address in byte form (pls correct me if I am wrong!).

I want to be able to use inet_pton but instead of giving src in dotted decimal form, I want to give a name that can be resolved by my DNS server.

Example: Instead of inet_pton(AF_INET, "10.70.1.114", buf) I want to use inet_pton(AF_INET, "myPC", buf)

I was thinking, maybe I can use getaddrinfo and getnameinfo before to resolve my name. I was thinking of a function like this:

char* resolvename(const char* name)
{
    struct addrinfo *infoptr, hints;
    char host[256];

    hints.ai_family=AF_INET;
    int result = getaddrinfo(name,NULL,&hints,&infoptr);
    if(result){
        fprintf(stderr, "getaddrinfo: %s\n", gai_stderror(result));
        exit(1);
        }
    getnameinfo(infoptr->ai_addr, infoptr->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

    return host; 

}

I should then be able to do sth like this:

mySrc = resolvename("myPC");
inet_pton(AF_INET, mySrc, buf);

Does this make any sense at all? Just saying: I have no experience in network programming whatsoever. All of these functions are very new to me, so pls enlighten me!

char host[256]; ... return host;

You return pointer to an automatic array. The array is destroyed automatically at the end of the scope and therefore you return a dangling pointer. The behaviour of indirecting through a dangling pointer is undefined.

Furthermore, by failing to call freeaddrinfo , you leak memory.

getaddrinfo returns a list of sockaddr , which already contain the IP in byte form. Example of how to get it out:

for (; infoptr; infoptr = infoptr->ai_next) {
    if (infoptr->ai_family == AF_INET) {
        assert(infoptr->ai_addrlen == sizeof(sockaddr_in));
        sockaddr_in addr;
        std::memcpy(&addr, infoptr->ai_addr, sizeof addr);
        std::memcpy(buf, addr.sin_addr, sizeof addr.sin_addr);
        break;
    }
}

If you're very clever, there might in theory be a way to use offsetof to get rid of the intermediary memcpy to local sockaddr_in .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM