How to set the IP address from C in linux

前端 未结 4 1164
谎友^
谎友^ 2020-11-30 02:21

By using strace and ifconfig, I found that I can set the IP address this way:

#include 
#include 
#include 

        
4条回答
  •  粉色の甜心
    2020-11-30 03:27

    #include 
    #include 
    #include            // close()
    #include            // strcpy, memset(), and memcpy()
    
    #include             // struct addrinfo
    #include         // needed for socket(), uint8_t, uint16_t
    #include        // needed for socket()
    #include        // IPPROTO_RAW, INET_ADDRSTRLEN
    #include        // IP_MAXPACKET (which is 65535)
    #include         // inet_pton() and inet_ntop()
    #include         // macro ioctl is defined
    #include       // defines values for argument "request" of ioctl.
    #include            // struct ifreq
    #include    // ETH_P_ARP = 0x0806
    #include   // struct sockaddr_ll (see man 7 packet)
    #include 
    
    #include             // errno, perror()
    
    #include 
    #include     
    
    
     /**
        * 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  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");
    

提交回复
热议问题