Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set the IP address from C in linux

Tags:

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?

like image 428
Allan Avatar asked Jul 11 '11 15:07

Allan


People also ask

How do I assign an IP address in Linux?

To change your IP address on Linux, use the “ifconfig” command followed by the name of your network interface and the new IP address to be changed on your computer. To assign the subnet mask, you can either add a “netmask” clause followed by the subnet mask or use the CIDR notation directly.

How assign IP address to ifconfig in Linux?

To configure an IP address for a network interface, enter the following command: ifconfig interface_name IP_address interface_name is the name of the network interface. IP_address is the IP address that you want to assign to the network interface.

How do I change my eth0 IP address in Linux?

To assign an IP address to a specific interface, use the following command with an interface name (eth0) and ip address that you want to set. For example, “ifconfig eth0 172.16. 25.125” will set the IP address to interface eth0.


2 Answers

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

like image 151
grep Avatar answered Dec 12 '22 15:12

grep


#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"); 
like image 39
Mahdi Mohammadi Avatar answered Dec 12 '22 15:12

Mahdi Mohammadi