How to print IP address from getaddrinfo()

c, sockets

Solution

The code misses to include the prototype for `inet_ntoa()`.

The compiler should have told you this.

Do add:

#include <arpa/inet.h>

However the code still compiles as due to the missing protoype for `inet_ntoa()` it is assumed to return `int`, whereas it returns a `char*` which is a pointer, which on a 64bit system is 8 bytes, which is not the same size as `int` which typically has a size of `4`. Due to this mismatch things go terribly wrong and end up in a segmentation violation.

Also please note: `inet_ntoa()` is to be used for ipv4 addresses only. Verbatim from `man inet_ntoa` (italics by me):

The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite

To be able to convert both (IPv4 and IPv6) `struct sockaddr_XYZ`'s binary addresses to a `char[]` use `inet_ntop()`.

Problem

I’m trying to use socket in C on CentOS 6.4. Following LIST1 is my code. My code gets hostname from command line and sends datagram to server with UDP successfully. What I want to know is how to print IP address that `getaddrinfo()` resolved wiht `192.168.10.1` format. When I try to print IP address segmentation error happens. Does anyone know how to fix this code? ``` #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> int main(int argc,char *argv[]){ int sock; struct addrinfo hints,*res; int n; int err; if(argc != 2){ fprintf(stderr,"Usage : %s dst \n",argv[0]); return 1; } memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; err = getaddrinfo(argv[1],"12345",&hints,&res); if(err != 0){ perror("getaddrinfo"); printf("getaddrinfo %s\n",strerror(errno)); printf("getaddrinfo : %s \n",gai_strerror(err)); return 1; } sock = socket(res->ai_family,res->ai_socktype,0); if(sock < 0){ perror("socket"); return 1; const char *ipverstr; switch (res->ai_family){ case AF_INET: ipverstr = "IPv4"; break; case AF_INET6: ipverstr = "IPv6"; break; default: ipverstr = "unknown"; break; } printf("ipverstr = %s\n ",ipverstr); } n = sendto(sock,"HELLO",5,0,res->ai_addr,res->ai_addrlen); if(n<1){ perror("sendto"); return 1; } struct sockaddr_in *addr; addr = (struct sockaddr_in *)res->ai_addr; printf("inet_ntoa(in_addr)sin = %s\n",inet_ntoa((struct in_addr)addr->sin_addr)); printf("############ finish !! #######\n"); close(sock); freeaddrinfo(res); return 0; } ```

Original source