Set IP address using SIOCSIFADDR ioctl - c

I am trying to get and set the IP address using the IOCTL interface on Linux.
I am successfully able to get and set it. When I set the ip address,
ifconfig eth0 shows a proper IP address, but then the system gets disconnected.
i.e. System is not pingable.
Here's my code for setting the IP address. Please let me know if I am missing something.
struct ifreq ifr;
in_addr_t in_addr;
struct sockaddr_in sin;
memset(&ifr, 0, sizeof(struct ifreq));
memset(&sin, 0, sizeof(struct sockaddr_in));
sockfd = socket(AF_INET, SOCK_STREAM, 0);
sprintf(ifr.ifr_name, "eth0");
in_addr = inet_addr("192.168.101.17");
sin.sin_addr.s_addr = in_addr;
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
io = ioctl(sockfd, SIOCSIFADDR, (char *)&ifr);

This will work for interfaces or aliases. Use "strace" to verify correct operation:
strace ./ifconfig
socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 5
ioctl(5, SIOCSIFADDR, {ifr_name="eth0:8", ifr_addr={AF_INET, inet_addr("192.168.1.202")}}) = 0
ioctl(5, SIOCGIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
ioctl(5, SIOCSIFFLAGS, {ifr_name="eth0:8", ifr_flags=IFF_UP|IFF_BROADCAST|IFF_RUNNING|IFF_MULTICAST}) = 0
close(5) = 0
Complete source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h> /* offsetof */
#include <net/if.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <netinet/in.h>
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_ether.h>
#endif
#define IFNAME "eth0:2"
#define HOST "192.168.1.204"
#define ifreq_offsetof(x) offsetof(struct ifreq, x)
int main(int argc, char **argv) {
struct ifreq ifr;
struct sockaddr_in sai;
int sockfd; /* socket fd we use to manipulate stuff with */
int selector;
unsigned char mask;
char *p;
/* Create a channel to the NET kernel. */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
/* get interface name */
strncpy(ifr.ifr_name, IFNAME, IFNAMSIZ);
memset(&sai, 0, sizeof(struct sockaddr));
sai.sin_family = AF_INET;
sai.sin_port = 0;
sai.sin_addr.s_addr = inet_addr(HOST);
p = (char *) &sai;
memcpy( (((char *)&ifr + ifreq_offsetof(ifr_addr) )),
p, sizeof(struct sockaddr));
ioctl(sockfd, SIOCSIFADDR, &ifr);
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
// ifr.ifr_flags &= ~selector; // unset something
ioctl(sockfd, SIOCSIFFLAGS, &ifr);
close(sockfd);
return 0;
}

Perhaps you forgot to set the interface to up?
ioctl(sockfd, SIOCGIFFLAGS, &ifr);
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
ioctl(sockfd, SIOCSIFFLAGS, &ifr);

Related

TCP server socket not listening by addrinfo method

So here is the code, code successfully compiles...
#include <stdio.h> // for printf
#include <linux/if_tun.h> //for IFF_TUN
#include <sys/socket.h> //socket, struct sockaddr_in
#include <fcntl.h> // for O_RDWR macros
#include <string.h> //for strcpy
#include <unistd.h> //for read();
#include <netdb.h> //for struct sockaddr
#include <net/if.h> //struct ifreq and IFNAMSIZ and other macros
#include <errno.h>
#include <stdlib.h>
// _check: error handler
static int _check(int retval, const char *msg)
{
if(retval == -1)
{
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(EXIT_FAILURE);
}
return retval;
}
int tcp_listen_sock(int listen_connection)
{
/*-------------------------socket-----------------------*/
int sock, tcp_sock;
struct addrinfo hints, *result;
struct sockaddr *addrin;
memset(&hints ,0 , sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
const char *host;
host = "0.0.0.0";
_check(getaddrinfo(host, NULL, &hints, &result), "getaddrinfo");
if (result->ai_family == AF_INET)
((struct sockaddr_in *)result->ai_addr)->sin_port = htons(5678);
else if (result->ai_family == AF_INET6)
((struct sockaddr_in6 *)result->ai_addr)->sin6_port = htons(5678);
else {
fprintf(stderr, "unknown ai_family %d", result->ai_family);
freeaddrinfo(result);
return -1;
}
memcpy(addrin, result->ai_addr, result->ai_addrlen);
// *client_len = result->ai_addrlen;
_check((sock = socket(AF_INET, SOCK_STREAM, 0)), "socket");
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "enp0s3");
_check(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)), "setsockopt");
int flags;
if((flags = fcntl(sock, F_GETFL)) != -1)
{
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}
else
perror("socket fcntl");
_check(bind(sock,result->ai_addr, result->ai_addrlen), "tcp bind");
int len = sizeof(struct sockaddr);
_check(listen(sock, listen_connection), "listen");
tcp_sock = accept(sock, result->ai_addr, &result->ai_addrlen );
printf("now listening on tcp!\n");
return tcp_sock;
}
int main(int argc, char **argv)
{
printf("Starting program\n");
int tcp = tcp_listen_sock(5);
printf("ending program\n");
return 0;
}
and ,
OUTPUT
Starting program
now listening on tcp!
ending program
but server socket is not actually listening...
expected output:
Starting program
now listening on tcp!
read...
write...
read...
write...
read...
write..
I can't figure our what I am missing, I know I didn't implemented read, write yet but I will do it after when server socket seems to working fine and listening properly.
NOTE: I am doing this in linux (specifically ubuntu)
Any help will be appreciated...
Calling getaddrinfo to initialize a local list socket seems like overkill.
Start with this. This is a simple "create a listen socket and wait for an incoming TCP connection" code sample.
int tcp_socket_listen(int listen_connection)
{
struct sockaddr_in addr = {0};
sockaddr_in addrRemote = {0};
socklen_t sizeRemote = 0;
int tcp_socket = -1;
s = socket(AF_INET, SOCK_STREAM, 0);
_check(s, "socket");
addr.sin_family = AF_INET;
addr.sin_port = htons(5678);
_check(bind(s, (sockaddr*)&addr, sizeof(addr)), "bind");
_check(listen(sock, listen_connection), "listen");
sizeRemote = sizeof(addrRemote);
tcp_sock = accept(s, (sockaddr*)&addrRemote, &sizeRemote);
_check(tcp_sock, "accept");
printf("now listening on TCP\n");
return tcp_sock;
}
Now if you want to bind to a specific adapter (e.g. "enp0s3") instead of the default ("all adapters") or need IPV6 support, you can peruse my sample code on github here for the GetSocketAddressForAdapter and use that address for the bind call instead of the default addr address above. It's C++, but you can probably port it to straight C with a little work.

Adding multiple ip addresses using ioctl

By using strace and ifconfig, I found that I can set the IP address this way:
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <string.h>
int main(int argc, const char *argv[]) {
struct ifreq ifr;
const char * name = "eth1:0";
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_addr.sa_family = AF_INET;
inet_pton(AF_INET, "10.12.0.1", ifr.ifr_addr.sa_data + 2);
ioctl(fd, SIOCSIFADDR, &ifr);
inet_pton(AF_INET, "255.255.0.0", ifr.ifr_addr.sa_data + 2);
ioctl(fd, SIOCSIFNETMASK, &ifr);
ioctl(fd, SIOCGIFFLAGS, &ifr);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
ioctl(fd, SIOCSIFFLAGS, &ifr);
return 0;
}
Now I want to add multiple ip addresses on eth1:0. eth1:0 is the 'fake' interface created to add more addresses. Man page of ioctl shows to set and get ip address but is it possible to add multiple ip addresses using ioctl? If so how can I add?

How to know the set for IP address from C in linux is successful or fail

I use this code to setup the IP address
int
set_ip(const char *name, const char *ip)
{
struct ifreq ifr;
struct sockaddr_in *addr;
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_addr.sa_family = AF_INET;
addr = (struct sockaddr_in*)&ifr.ifr_addr;
/* inet_pton() returns 1 on success */
/* network address was successfully converted */
int s;
s = inet_pton(AF_INET, ip, &addr->sin_addr);
if (s <= 0) {
if (s == 0)
fprintf(stderr, "Set IP %s not in presentation format\n", ip);
else
perror ("inet_pton");
exit (EXIT_FAILURE);
}
ioctl(fd, SIOCSIFADDR, &ifr);
ioctl(fd, SIOCGIFFLAGS, &ifr);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
ioctl(fd, SIOCSIFFLAGS, &ifr);
return 0;
}
The code is modified from here How to set the IP address from C in linux.
My question is
How to know the ip address change successfully or not? Because the return value of ioctl always be 0.
$ uname -a
Linux DMA1 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
I have googled for hours but not found any solutions. So I post my question in here to ask experts in SO. Thanks in advance
Thank you all, below is the solution suggested by you experts:
#include <stdio.h>
#include <stdlib.h>
#include <ifaddrs.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <net/route.h> // struct rtentry
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int
set_addr (const char *name, const char *ip, unsigned long request)
{
struct ifreq ifr;
struct sockaddr_in *addr;
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_addr.sa_family = AF_INET;
addr = (struct sockaddr_in*)&ifr.ifr_addr;
// inet_pton() returns 1 on success
// network address was successfully converted
int s;
s = inet_pton(AF_INET, ip, &addr->sin_addr);
if (s <= 0) {
if (s == 0)
fprintf(stderr, "Set IP %s not in presentation format\n", ip);
else
perror ("inet_pton");
exit (EXIT_FAILURE);
}
if (ioctl(fd, request, &ifr) != 0) { // SIOCSIFADDR
perror ("ioctl");
exit (EXIT_FAILURE);
}
ioctl(fd, SIOCGIFFLAGS, &ifr);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
ioctl(fd, SIOCSIFFLAGS, &ifr);
return 0;
}
Don't forget to grant your program with root privilege using following commands in your Makefile or command line:
$ sudo chown root your_program
$ sudo chmod a+xs your_program
Otherwise, you will get a error message ioctl: Operation not permitted

How to listen to IGMPv3 frames

I need to get IGMPv3 Frames for this I'm using a socket like following:
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
the problem is that my program is filtring IGMPv3 Frames, i don't know why !! I don't get IGMP frames although I'm getting them when using wireshark. I tried also to use :
sockfd = socket(PF_PACKET, SOCK_RAW, htons(0x0800));
but I was capable of getting only ICMP frames and not IGMP ones.
PS: I tried my program on another machine and it worked, so I think the problem is with my kernel, does anyone know if there is any configuration to do with the socket ?
Here is the whole code:
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <unistd.h>
#define DEST_MAC0 0x01
#define DEST_MAC1 0x00
#define DEST_MAC2 0x5e
#define DEST_MAC3 0x00
#define DEST_MAC4 0x00
#define DEST_MAC5 0x16
#define ETHER_TYPE 0x0800
#define DEFAULT_IF "eth1"
#define BUF_SIZ 1024
int main(int argc, char *argv[])
{
char sender[INET6_ADDRSTRLEN];
int sockfd, ret, i, counter;
int sockopt;
ssize_t numbytes;
struct ifreq ifopts; /* set promiscuous mode */
struct ifreq if_ip; /* get ip addr */
struct sockaddr_storage their_addr;
uint8_t buf[BUF_SIZ];
char ifName[IFNAMSIZ];
/* Get interface name */
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Header structures */
struct ether_header *eh = (struct ether_header *) buf;
struct iphdr *iph = (struct iphdr *) (buf + sizeof(struct ether_header));
struct udphdr *udph = (struct udphdr *) (buf + sizeof(struct iphdr) + sizeof(struct ether_header));
memset(&if_ip, 0, sizeof(struct ifreq));
/* Open PF_PACKET socket, listening for EtherType ETHER_TYPE */
// if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
// perror("listener: socket");
// return -1;
// }
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE));
if (sockfd == -1) {
perror("listener: socket");
return -1;
}
/* Set interface to promiscuous mode - do we need to do this every time? */
strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
/* Allow the socket to be reused - incase connection is closed prematurely */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
perror("setsockopt");
close(sockfd);
exit(EXIT_FAILURE);
}
/* Bind to device */
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1) {
perror("SO_BINDTODEVICE");
close(sockfd);
exit(EXIT_FAILURE);
}
repeat: printf("listener: Waiting to recvfrom...\n");
numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
printf("listener: got packet %lu bytes\n Frame = {",(unsigned long int) numbytes);
for( counter = 0; counter < numbytes; counter++)
printf( "%02X ", buf[counter]);
printf( "}");
/* Check the packet is for me */
if (eh->ether_dhost[0] == DEST_MAC0 &&
eh->ether_dhost[1] == DEST_MAC1 &&
eh->ether_dhost[2] == DEST_MAC2 &&
eh->ether_dhost[3] == DEST_MAC3 &&
eh->ether_dhost[4] == DEST_MAC4 &&
eh->ether_dhost[5] == DEST_MAC5) {
printf("Correct destination MAC address\n");
} else {
printf("Wrong destination MAC: %x:%x:%x:%x:%x:%x\n",
eh->ether_dhost[0],
eh->ether_dhost[1],
eh->ether_dhost[2],
eh->ether_dhost[3],
eh->ether_dhost[4],
eh->ether_dhost[5]);
ret = -1;
goto done;
}
/* Get source IP */
((struct sockaddr_in *)&their_addr)->sin_addr.s_addr = iph->saddr;
inet_ntop(AF_INET, &((struct sockaddr_in*)&their_addr)->sin_addr, sender, sizeof sender);
/* Look up my device IP addr if possible */
strncpy(if_ip.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFADDR, &if_ip) >= 0) { /* if we can't check then don't */
printf("Source IP: %s\n My IP: %s\n", sender,
inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr));
/* ignore if I sent it */
if (strcmp(sender, inet_ntoa(((struct sockaddr_in *)&if_ip.ifr_addr)->sin_addr)) == 0) {
printf("but I sent it :(\n");
ret = -1;
goto done;
}
}
/* UDP payload length */
ret = ntohs(udph->len) - sizeof(struct udphdr);
/* Print packet */
printf("\tData:");
for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
printf("\n");
done: goto repeat;
close(sockfd);
return ret;
}
Please note that the address mac that I'm initializing is the address that I get from IGMP frame on wireshark. this code actually allows me to detect only ICMP frames.
When using:
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP);
instead of:
sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE);
I don't get nothing !
On wireshark I'm getting all the frames that I want including IGMP and ICMP!!

How to set the IP address from C in linux

By using strace and ifconfig, I found that I can set the IP address this way:
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <string.h>
int main(int argc, const char *argv[]) {
struct ifreq ifr;
const char * name = "eth1";
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_addr.sa_family = AF_INET;
inet_pton(AF_INET, "10.12.0.1", ifr.ifr_addr.sa_data + 2);
ioctl(fd, SIOCSIFADDR, &ifr);
inet_pton(AF_INET, "255.255.0.0", ifr.ifr_addr.sa_data + 2);
ioctl(fd, SIOCSIFNETMASK, &ifr);
ioctl(fd, SIOCGIFFLAGS, &ifr);
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
ioctl(fd, SIOCSIFFLAGS, &ifr);
return 0;
}
But I am not very happy with this solution:
inet_pton(AF_INET, "10.12.0.1", ifr.ifr_addr.sa_data + 2);
What is the "right" way of doing this?
The "correct" way for IPv4 without magic +2:
struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr;
inet_pton(AF_INET, "10.12.0.1", &addr->sin_addr);
To use IPv6, cast it to sockaddr_in6
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // close()
#include <string.h> // strcpy, memset(), and memcpy()
#include <netdb.h> // struct addrinfo
#include <sys/types.h> // needed for socket(), uint8_t, uint16_t
#include <sys/socket.h> // needed for socket()
#include <netinet/in.h> // IPPROTO_RAW, INET_ADDRSTRLEN
#include <netinet/ip.h> // IP_MAXPACKET (which is 65535)
#include <arpa/inet.h> // inet_pton() and inet_ntop()
#include <sys/ioctl.h> // macro ioctl is defined
#include <bits/ioctls.h> // defines values for argument "request" of ioctl.
#include <net/if.h> // struct ifreq
#include <linux/if_ether.h> // ETH_P_ARP = 0x0806
#include <linux/if_packet.h> // struct sockaddr_ll (see man 7 packet)
#include <net/ethernet.h>
#include <errno.h> // errno, perror()
#include <netinet/in.h>
#include <net/route.h>
/**
* Create socket function
*/
int create_socket() {
int sockfd = 0;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd == -1){
fprintf(stderr, "Could not get socket.\n");
return -1;
}
return sockfd;
}
/**
* Generic ioctrlcall to reduce code size
*/
int generic_ioctrlcall(int sockfd, u_long *flags, struct ifreq *ifr) {
if (ioctl(sockfd, (long unsigned int)flags, &ifr) < 0) {
fprintf(stderr, "ioctl: %s\n", (char *)flags);
return -1;
}
return 1;
}
/**
* Set route with metric 100
*/
int set_route(int sockfd, char *gateway_addr, struct sockaddr_in *addr) {
struct rtentry route;
int err = 0;
memset(&route, 0, sizeof(route));
addr = (struct sockaddr_in*) &route.rt_gateway;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(gateway_addr);
addr = (struct sockaddr_in*) &route.rt_dst;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("0.0.0.0");
addr = (struct sockaddr_in*) &route.rt_genmask;
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr("0.0.0.0");
route.rt_flags = RTF_UP | RTF_GATEWAY;
route.rt_metric = 100;
err = ioctl(sockfd, SIOCADDRT, &route);
if ((err) < 0) {
fprintf(stderr, "ioctl: %s\n", "mahdi MOAHMMADI Error");
return -1;
}
return 1;
}
/**
* Set ip function
*/
int set_ip(char *iface_name, char *ip_addr, char *gateway_addr)
{
if(!iface_name)
return -1;
struct ifreq ifr;
struct sockaddr_in sin;
int sockfd = create_socket();
sin.sin_family = AF_INET;
// Convert IP from numbers and dots to binary notation
inet_aton(ip_addr,&sin.sin_addr.s_addr);
/* get interface name */
strncpy(ifr.ifr_name, iface_name, IFNAMSIZ);
/* Read interface flags */
generic_ioctrlcall(sockfd, (u_long *)"SIOCGIFFLAGS", &ifr);
/*
* Expected in <net/if.h> according to
* "UNIX Network Programming".
*/
#ifdef ifr_flags
# define IRFFLAGS ifr_flags
#else /* Present on kFreeBSD */
# define IRFFLAGS ifr_flagshigh
#endif
// If interface is down, bring it up
if (ifr.IRFFLAGS | ~(IFF_UP)) {
ifr.IRFFLAGS |= IFF_UP;
generic_ioctrlcall(sockfd, (u_long *)"SIOCSIFFLAGS", &ifr);
}
// Set route
set_route(sockfd, gateway_addr , &sin);
memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
// Set interface address
if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
fprintf(stderr, "Cannot set IP address. ");
perror(ifr.ifr_name);
return -1;
}
#undef IRFFLAGS
return 0;
}
usage:
set_ip("eth0", "192.168.181.128", "192.168.181.1");
The "correct" way to do it is to spawn a copy of the iproute2 "ip" program (in /sbin/ip ) with relevant parameters.
the ioctl interface is generally obsolescent and doesn't allow you to configure all parameters (for example, un-named IP aliases).
Even daemons like dhcpcd which need to change the IP address, typically do it by spawning an external program... it's not like you're going to do it very often.
Hello: In the set_ip function, it gave me an error.
I had to change from :
inet_aton(ip_addr, &sin.sin_addr.s_addr);
to
inet_aton(ip_addr, &sin.sin_addr);
and worked well.

Resources