linux 系统调用---ioctl

来源:互联网 发布:java如何安装与卸载 编辑:程序博客网 时间:2024/04/30 03:45
  1. /***************************************************/  
  2. /**** 一个用ioctl实现的类似ifconfig命令的小程序 ****/  
  3. /***************************************************/  
  4. #include <stdio.h> //printf()   
  5. #include <unistd.h> //ioctl()   
  6. #include <sys/ioctl.h> //ioctl   
  7. #include <sys/socket.h> //socket()   
  8. #include <net/if.h> //struct ifconf{} & struct ifreq{}   
  9. #include <string.h> //strcpy()   
  10. #include <arpa/inet.h> //inet_ntoa()   
  11. #include <stdlib.h> //malloc() & free()   
  12.   
  13. int print_if_addr(int fd, char *interface_name); //打印接口的ip地址   
  14. int print_if_mac(int fd, char *interface_name); //打印接口的mac地址   
  15. int print_if_broadaddr(int fd, char *interface_name); //打印接口的广播地址   
  16. int print_if_mask(int fd, char *interface_name); //打印接口的掩码   
  17. int print_if_mtu(int fd, char *interface_name); //打印接口的mtu   
  18. int print_all_interface(); //打印所有接口的基本信息   
  19. int print_if_addr6(char *interface_name); //打印接口的ipv6地址   
  20. int print_interface_info(char *interface_name); //打印接口的以上所有信息   
  21. int set_if_up(char *interface_name); //启动接口   
  22. int set_if_down(char *interface_name); //关闭接口   
  23. int set_if_ip(char *interface_name, char *ip_str); //设置接口的ip地址   
  24. void usage(); //打印该程序的使用手册   
  25.   
  26. int main(int argc, char **argv)   
  27. {   
  28.     int sockfd;   
  29.     printf("/n **********funway:用ioctl函数来实现ifconfig命令的效果**********/n");   
  30.     switch(argc)   
  31.     {   
  32.         case 1:   
  33.             print_all_interface();   
  34.             break;   
  35.         case 2:   
  36.             print_interface_info(argv[1]);   
  37.             break;   
  38.         case 3:   
  39.             if(strcmp(argv[2], "up") == 0)   
  40.                 set_if_up(argv[1]);   
  41.             else if(strcmp(argv[2], "down") == 0)   
  42.                 set_if_down(argv[1]);   
  43.             else   
  44.             set_if_ip(argv[1], argv[2]);   
  45.                 break;   
  46.         default:   
  47.             usage();   
  48.             break;   
  49.     }   
  50.   
  51.     return 0;   
  52. }   
  53.   
  54. void usage()   
  55. {   
  56.     printf("usage: ./myifconfig [interface [down|up|ip]]/n");   
  57. }   
  58.   
  59. int print_if_addr(int fd, char *if_name)   
  60. {   
  61.     struct sockaddr_in *ip;   
  62.     struct ifreq ifr;   
  63.   
  64.     strcpy(ifr.ifr_name, if_name);   
  65.   
  66.     if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)   
  67.     {   
  68.         perror("ioctl SIOCGIFADDR error");   
  69.         return -1;   
  70.     }   
  71.   
  72.     ip = (struct sockaddr_in *)&ifr.ifr_addr; //获得ipv4地址   
  73.     printf(" IP: %s/n", inet_ntoa(ip->sin_addr)); //将ipv4地址转换为主机字节序的字符串并输出   
  74.     return 0;   
  75. }   
  76.   
  77. int print_if_broadaddr(int fd, char *if_name)   
  78. {   
  79.     struct sockaddr_in *ip;   
  80.     struct ifreq ifr;   
  81.   
  82.     strcpy(ifr.ifr_name, if_name);   
  83.   
  84.     if(ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)   
  85.     {   
  86.         perror("ioctl SIOCGIFBRDADDR error");   
  87.         return -1;   
  88.     }   
  89.   
  90.     ip = (struct sockaddr_in *)&ifr.ifr_broadaddr; //获得广播地址   
  91.     printf(" Broadcast: %s/n", inet_ntoa(ip->sin_addr));   
  92.     return 0;   
  93. }   
  94.   
  95. int print_if_mask(int fd, char *if_name)   
  96. {   
  97.     struct sockaddr_in *ip;   
  98.     struct ifreq ifr;   
  99.   
  100.     strcpy(ifr.ifr_name, if_name);   
  101.   
  102.     if(ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)   
  103.     {   
  104.         perror("ioctl SIOCGIFNETMASK error");   
  105.         return -1;   
  106.     }   
  107.   
  108.     ip = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_netmask; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回   
  109.     printf(" Mask: %s/n", inet_ntoa(ip->sin_addr));   
  110.     return 0;   
  111. }   
  112.   
  113. int print_if_mac(int fd, char *if_name)   
  114. {   
  115.     unsigned char *p; //这里要用unsigned char,因为char要对[1xxx xxxx]这样的数进行补码运算的,但mac地址是不需要符号的数值   
  116.     struct ifreq ifr;   
  117.   
  118.     strcpy(ifr.ifr_name, if_name);   
  119.   
  120.     if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)   
  121.     {   
  122.         perror("ioctl SIOCGIFHWADDR error");   
  123.         return -1;   
  124.     }   
  125.   
  126.     p = (char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0]; //获得接口的MAC地址,用字符串指针返回   
  127.     printf(" MAC: %02x:%02x:%02x:%02x:%02x:%02x/n", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5));   
  128.     return 0;   
  129. }   
  130.   
  131. int print_if_mtu(int fd, char *if_name)   
  132. {   
  133.     unsigned int mtu;   
  134.     struct ifreq ifr;   
  135.   
  136.     strcpy(ifr.ifr_name, if_name);   
  137.   
  138.     if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)   
  139.     {   
  140.         perror("ioctl SIOCGIFMTU error");   
  141.         return -1;   
  142.     }   
  143.   
  144.     mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回   
  145.     printf(" MTU: %d/n", mtu);   
  146.     return 0;   
  147. }   
  148.   
  149. int print_if_addr6(char *if_name)   
  150. {   
  151.     unsigned int mtu;   
  152.     struct ifreq ifr;   
  153.     int sockfd;   
  154.   
  155.     if((sockfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)   
  156.     {   
  157.         perror("Socket error");   
  158.         return -1;   
  159.     } // 创建用来检查网络接口的套接字   
  160.   
  161.     /* strcpy(ifr.ifr_name, if_name);  
  162.  
  163.     if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)  
  164.     {  
  165.         perror("ioctl SIOCGIFMTU error");  
  166.         return -1;  
  167.     }  
  168.  
  169.     mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回  
  170.     printf(" ipv6: %d/n", mtu);  
  171.     */   
  172.     //未写完,不知道怎么获得ipv6地址。。。   
  173.     return 0;   
  174. }   
  175.   
  176. int print_all_interface()   
  177. {   
  178.     struct ifconf ifc;   
  179.     struct ifreq *ifr_p;   
  180.     int sockfd, len, old_len = 0, i;   
  181.     char *buf;   
  182.   
  183.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)   
  184.     {   
  185.         perror("Socket error");   
  186.         return -1;   
  187.     } // 创建用来检查网络接口的套接字   
  188.   
  189.     len = 10 * sizeof(struct ifreq);   
  190.     for( ; ; )   
  191.     {   
  192.         if((buf = malloc(len)) == NULL)   
  193.         {   
  194.             perror("malloc error");   
  195.             return -1;   
  196.         }   
  197.         ifc.ifc_len = len;   
  198.         ifc.ifc_buf = buf;   
  199.         if(ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)   
  200.         {   
  201.             perror("ioctl SIOCGIFCONF error");   
  202.             return -1;   
  203.         }   
  204.         if(ifc.ifc_len == old_len)   
  205.         break;   
  206.         old_len = ifc.ifc_len;   
  207.         len += 10 * sizeof(struct ifreq);   
  208.         free(buf);   
  209.     }   
  210.     printf("we have %d interfaces/n", ifc.ifc_len / sizeof(struct ifreq));   
  211.   
  212.     for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++)   
  213.     {   
  214.         ifr_p = &ifc.ifc_req[i];   
  215.         printf("/ninterface [%s]:/n", ifr_p->ifr_name);   
  216.   
  217.         print_if_addr(sockfd, ifr_p->ifr_name);   
  218.         print_if_broadaddr(sockfd, ifr_p->ifr_name);   
  219.         print_if_mask(sockfd, ifr_p->ifr_name);   
  220.         print_if_mac(sockfd, ifr_p->ifr_name);   
  221.         print_if_mtu(sockfd, ifr_p->ifr_name);   
  222.     }   
  223.     close(sockfd);   
  224.     return 0;   
  225. }   
  226.   
  227. int print_interface_info(char *if_name)   
  228. {   
  229.     int sockfd;   
  230.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)   
  231.     {   
  232.         perror("Socket error");   
  233.         return -1;   
  234.     } // 创建用来检查网络接口的套接字   
  235.   
  236.     printf("%s:/n", if_name);   
  237.     print_if_addr(sockfd, if_name);   
  238.     print_if_broadaddr(sockfd, if_name);   
  239.     print_if_mask(sockfd, if_name);   
  240.     print_if_mac(sockfd, if_name);   
  241.     print_if_mtu(sockfd, if_name);   
  242.     close(sockfd);   
  243.     return 0;   
  244. }   
  245.   
  246. int set_if_up(char *if_name) //启动接口   
  247. {   
  248.     struct ifreq ifr;   
  249.     int sockfd;   
  250.   
  251.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)   
  252.     {   
  253.         perror("Socket error");   
  254.         return -1;   
  255.     } // 创建用来检查网络接口的套接字   
  256.   
  257.     strcpy(ifr.ifr_name, if_name);   
  258.     if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)   
  259.     {   
  260.         perror("ioctl SIOCGIFFLAGS error");   
  261.         return -1;   
  262.     }   
  263.     ifr.ifr_flags |= IFF_UP;   
  264.     if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)   
  265.     {   
  266.         perror("ioctl SIOCSIFFLAGS error");   
  267.         return -1;   
  268.     }   
  269.     return 0;   
  270. }   
  271.   
  272. int set_if_down(char *if_name) //关闭接口   
  273. {   
  274.     struct ifreq ifr;   
  275.     int sockfd;   
  276.   
  277.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)   
  278.     {   
  279.         perror("Socket error");   
  280.         return -1;   
  281.     } // 创建用来检查网络接口的套接字   
  282.   
  283.     strcpy(ifr.ifr_name, if_name);   
  284.     if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)   
  285.     {   
  286.         perror("ioctl SIOCGIFFLAGS error");   
  287.         return -1;   
  288.     }   
  289.     ifr.ifr_flags &= ~IFF_UP; //将IIF_UP取反后与原来的标志进行 与运算。   
  290.     if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)   
  291.     {   
  292.         perror("ioctl SIOCSIFFLAGS error");   
  293.         return -1;   
  294.     }   
  295.     return 0;   
  296. }   
  297.   
  298. int set_if_ip(char *if_name, char *ip_str) //设置接口的ip地址   
  299. {   
  300.     struct ifreq ifr;   
  301.     struct sockaddr_in ip_addr;   
  302.     int sockfd;   
  303.   
  304.     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)   
  305.     {   
  306.         perror("Socket error");   
  307.         return -1;   
  308.     } // 创建用来检查网络接口的套接字   
  309.   
  310.     ip_addr.sin_family = AF_INET;   
  311.     if(inet_pton(AF_INET, ip_str, &ip_addr.sin_addr) < 1)   
  312.     {   
  313.         perror("error ipv4 addr:");   
  314.         return -1;   
  315.     }   
  316.   
  317.     strcpy(ifr.ifr_name, if_name);   
  318.     memcpy(&ifr.ifr_addr, &ip_addr, sizeof(struct sockaddr_in));   
  319.     if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)   
  320.     {   
  321.         perror("ioctl SIOCSIFADDR error");   
  322.         return -1;   
  323.     }   
  324.     return 0;   
  325. }   


注:有线连接mac接口名:eth0
   无线连接MAC接口名:wlan0
0 0
原创粉丝点击