IOCTL获取和配置IP地址/子网掩码/网关

2019-07-13 08:29发布

原文 点击打开链接
OS:LINUX

这部分代码包含:
1.获取IP地址,子网掩码,物理地址。
2.配置IP地址,子网掩码,网关等。
3.IP地址合法验证和子网掩码验证。

TIPS:部分代码摘自网上,代码已测试通过。

  1. #include <sys/socket.h>
  2. #include <arpa/inet.h>
  3. #include <net/if.h>
  4. #include <net/if_arp.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <sys/time.h>
  8. #include <sys/stat.h>
  9. #include <stdio.h>
  10. #include <netdb.h>
  11. #include <netinet/in.h>
  12. #include <sys/ioctl.h>
  13. #include <ctype.h>
  14. #include <net/route.h>
  15. #include <fcntl.h>
  16. #include <string.h>
  17. #include <pthread.h>
  18. #if defined(__GLIBC__) && __GLIBC__ >=&& __GLIBC_MINOR__ >= 1
  19. #include <netpacket/packet.h>
  20. #include <net/ethernet.h>
  21. #else
  22. #include <sys/types.h>
  23. #include <netinet/if_ether.h>
  24. #endif

  25. #include "xxx_ip.h"

  26. static int set_addr(unsigned char ip[16], int flag);
  27. static int get_addr(unsigned char ip[16], int flag);

  28. int get_ip(unsigned char ip[16])
  29. {
  30.     return get_addr(ip, SIOCGIFADDR);
  31. }

  32. int get_ip_netmask(unsigned char ip[16])
  33. {
  34.     return get_addr(ip, SIOCGIFNETMASK);
  35. }

  36. int get_mac(unsigned char addr[6])
  37. {
  38.     return get_addr(addr, SIOCGIFHWADDR);
  39. }

  40. static int get_addr(unsigned char *addr, int flag)
  41. {
  42.     SINT32 sockfd = 0;
  43.     struct sockaddr_in *sin;
  44.     struct ifreq ifr;

  45.     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  46.     {
  47.         perror("socket error! ");
  48.         return FALSE;
  49.     }

  50.     memset(&ifr, 0, sizeof(ifr));
  51.     snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);

  52.     if(ioctl(sockfd, flag, &ifr) < 0 )
  53.     {
  54.         perror("ioctl error! ");
  55.         close(sockfd);
  56.         return FALSE;
  57.     }
  58.     close(sockfd);

  59.     if (SIOCGIFHWADDR == flag){
  60.         memcpy((void *)addr, (const void *)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
  61.         /*printf("mac address: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);*/
  62.     }else{
  63.         sin = (struct sockaddr_in *)&ifr.ifr_addr;
  64.         snprintf((char *)addr, IP_LENGTH, "%s", inet_ntoa(sin->sin_addr));
  65.     }

  66.     return TRUE;
  67. }

  68. int is_valid_ip(unsigned char ipaddr[16])
  69. {
  70.     int ret = 0;
  71.     struct in_addr inp;
  72.     ret = inet_aton(ipaddr, &inp);
  73.     if (== ret)
  74.     {
  75.         return FALSE;
  76.     }
  77.     else
  78.     {
  79.         printf("inet_aton:ip=%lu ",ntohl(inp.s_addr));
  80.     }

  81.     return TRUE;
  82. }

  83. /*
  84.  * 先验证是否为合法IP,然后将掩码转化成32无符号整型,取反为000...00111...1,
  85.  * 然后再加1为00...01000...0,此时为2^n,如果满足就为合法掩码
  86.  *
  87.  * */
  88. int is_valid_netmask(unsigned char netmask[16])
  89. {
  90.     if(is_valid_ip(netmask) > 0)
  91.     {
  92.         unsigned int b = 0, i, n[4];
  93.         sscanf(netmask, "%u.%u.%u.%u", &n[3], &n[2], &n[1], &n[0]);
  94.         for(= 0; i < 4; ++i) //将子网掩码存入32位无符号整型
  95.             b += n[i] << (* 8);
  96.         b = ~+ 1;
  97.         if((& (- 1)) == 0) //判断是否为2^n
  98.             return TRUE;
  99.     }

  100.     return FALSE;
  101. }


  102. int set_ip_netmask(unsigned char ip[16])
  103. {
  104.     return set_addr(ip, SIOCSIFNETMASK);
  105. }

  106. int set_ip(unsigned char ip[16])
  107. {
  108.     return set_addr(ip, SIOCSIFADDR);
  109. }

  110. static int set_addr(unsigned char ip[16], int flag)
  111. {
  112.     struct ifreq ifr;
  113.     struct sockaddr_in sin;
  114.     int sockfd;

  115.     if (is_valid_ip(ip) < 0)
  116.     {
  117.         printf("ip was invalid! ");
  118.         return FALSE;
  119.     }

  120.     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  121.     if(sockfd == -1){
  122.         fprintf(stderr, "Could not get socket. ");
  123.         perror("eth0 ");
  124.         return FALSE;
  125.     }

  126.     snprintf(ifr.ifr_name, (sizeof(ifr.ifr_name) - 1), "%s", DEFAULT_ETH);

  127.     /* Read interface flags */
  128.     if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
  129.         fprintf(stderr, "ifdown: shutdown ");
  130.         perror(ifr.ifr_name);
  131.         return FALSE;
  132.     }

  133.     memset(&sin, 0, sizeof(struct sockaddr));
  134.     sin.sin_family = AF_INET;
  135.     inet_aton(ip, &sin.sin_addr.s_addr);
  136.     memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
  137.     if (ioctl(sockfd, flag, &ifr) < 0){
  138.         fprintf(stderr, "Cannot set IP address. ");
  139.         perror(ifr.ifr_name);
  140.         return FALSE;
  141.     }

  142.     return TRUE;
  143. }


  144. int set_gateway(unsigned char ip[16])
  145. {
  146.     int sockFd;
  147.     struct sockaddr_in sockaddr;
  148.     struct rtentry rt;

  149.     if (is_valid_ip(ip) < 0)
  150.     {
  151.         printf("gateway was invalid! ");
  152.         return FALSE;
  153.     }

  154.     sockFd = socket(AF_INET, SOCK_DGRAM, 0);
  155.     if (sockFd < 0)
  156.     {
  157.         perror("Socket create error. ");
  158.         return FALSE;
  159.     }

  160.     memset(&rt, 0, sizeof(struct rtentry));
  161.     memset(&sockaddr, 0, sizeof(struct sockaddr_in));
  162.     sockaddr.sin_family = AF_INET;
  163.     sockaddr.sin_port = 0;
  164.     if(inet_aton(ip, &sockaddr.sin_addr)<0)
  165.     {
  166.         perror("inet_aton error " );
  167.         close(sockFd);
  168.         return FALSE;
  169.     }

  170.     memcpy ( &rt.rt_gateway, &sockaddr, sizeof(struct sockaddr_in));
  171.     ((struct sockaddr_in *)&rt.rt_dst)->sin_family=AF_INET;
  172.     ((struct sockaddr_in *)&rt.rt_genmask)->sin_family=AF_INET;
  173.     rt.rt_flags = RTF_GATEWAY;
  174.     if (ioctl(sockFd, SIOCADDRT, &rt)<0)
  175.     {
  176.         perror("ioctl(SIOCADDRT) error in set_default_route ");
  177.         close(sockFd);
  178.         return FALSE;
  179.     }

  180.     return TRUE;
  181. }