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;
}
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()
.
The counterpart of getaddrinfo()
is getnameinfo()
. This turns a struct sockaddr
into a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With