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);
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