linux 系统调用---ioctl
来源:互联网 发布:java如何安装与卸载 编辑:程序博客网 时间:2024/04/30 03:45
- /***************************************************/
- /**** 一个用ioctl实现的类似ifconfig命令的小程序 ****/
- /***************************************************/
- #include <stdio.h> //printf()
- #include <unistd.h> //ioctl()
- #include <sys/ioctl.h> //ioctl
- #include <sys/socket.h> //socket()
- #include <net/if.h> //struct ifconf{} & struct ifreq{}
- #include <string.h> //strcpy()
- #include <arpa/inet.h> //inet_ntoa()
- #include <stdlib.h> //malloc() & free()
- int print_if_addr(int fd, char *interface_name); //打印接口的ip地址
- int print_if_mac(int fd, char *interface_name); //打印接口的mac地址
- int print_if_broadaddr(int fd, char *interface_name); //打印接口的广播地址
- int print_if_mask(int fd, char *interface_name); //打印接口的掩码
- int print_if_mtu(int fd, char *interface_name); //打印接口的mtu
- int print_all_interface(); //打印所有接口的基本信息
- int print_if_addr6(char *interface_name); //打印接口的ipv6地址
- int print_interface_info(char *interface_name); //打印接口的以上所有信息
- int set_if_up(char *interface_name); //启动接口
- int set_if_down(char *interface_name); //关闭接口
- int set_if_ip(char *interface_name, char *ip_str); //设置接口的ip地址
- void usage(); //打印该程序的使用手册
- int main(int argc, char **argv)
- {
- int sockfd;
- printf("/n **********funway:用ioctl函数来实现ifconfig命令的效果**********/n");
- switch(argc)
- {
- case 1:
- print_all_interface();
- break;
- case 2:
- print_interface_info(argv[1]);
- break;
- case 3:
- if(strcmp(argv[2], "up") == 0)
- set_if_up(argv[1]);
- else if(strcmp(argv[2], "down") == 0)
- set_if_down(argv[1]);
- else
- set_if_ip(argv[1], argv[2]);
- break;
- default:
- usage();
- break;
- }
- return 0;
- }
- void usage()
- {
- printf("usage: ./myifconfig [interface [down|up|ip]]/n");
- }
- int print_if_addr(int fd, char *if_name)
- {
- struct sockaddr_in *ip;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)
- {
- perror("ioctl SIOCGIFADDR error");
- return -1;
- }
- ip = (struct sockaddr_in *)&ifr.ifr_addr; //获得ipv4地址
- printf(" IP: %s/n", inet_ntoa(ip->sin_addr)); //将ipv4地址转换为主机字节序的字符串并输出
- return 0;
- }
- int print_if_broadaddr(int fd, char *if_name)
- {
- struct sockaddr_in *ip;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
- {
- perror("ioctl SIOCGIFBRDADDR error");
- return -1;
- }
- ip = (struct sockaddr_in *)&ifr.ifr_broadaddr; //获得广播地址
- printf(" Broadcast: %s/n", inet_ntoa(ip->sin_addr));
- return 0;
- }
- int print_if_mask(int fd, char *if_name)
- {
- struct sockaddr_in *ip;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
- {
- perror("ioctl SIOCGIFNETMASK error");
- return -1;
- }
- ip = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_netmask; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回
- printf(" Mask: %s/n", inet_ntoa(ip->sin_addr));
- return 0;
- }
- int print_if_mac(int fd, char *if_name)
- {
- unsigned char *p; //这里要用unsigned char,因为char要对[1xxx xxxx]这样的数进行补码运算的,但mac地址是不需要符号的数值
- struct ifreq ifr;
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
- {
- perror("ioctl SIOCGIFHWADDR error");
- return -1;
- }
- p = (char *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0]; //获得接口的MAC地址,用字符串指针返回
- printf(" MAC: %02x:%02x:%02x:%02x:%02x:%02x/n", *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5));
- return 0;
- }
- int print_if_mtu(int fd, char *if_name)
- {
- unsigned int mtu;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)
- {
- perror("ioctl SIOCGIFMTU error");
- return -1;
- }
- mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回
- printf(" MTU: %d/n", mtu);
- return 0;
- }
- int print_if_addr6(char *if_name)
- {
- unsigned int mtu;
- struct ifreq ifr;
- int sockfd;
- if((sockfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- /* strcpy(ifr.ifr_name, if_name);
- if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)
- {
- perror("ioctl SIOCGIFMTU error");
- return -1;
- }
- mtu = ifr.ifr_ifru.ifru_mtu; //获得子网掩码。注意!我们仍放在struct aockaddr_in结构中返回
- printf(" ipv6: %d/n", mtu);
- */
- //未写完,不知道怎么获得ipv6地址。。。
- return 0;
- }
- int print_all_interface()
- {
- struct ifconf ifc;
- struct ifreq *ifr_p;
- int sockfd, len, old_len = 0, i;
- char *buf;
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- len = 10 * sizeof(struct ifreq);
- for( ; ; )
- {
- if((buf = malloc(len)) == NULL)
- {
- perror("malloc error");
- return -1;
- }
- ifc.ifc_len = len;
- ifc.ifc_buf = buf;
- if(ioctl(sockfd, SIOCGIFCONF, &ifc) < 0)
- {
- perror("ioctl SIOCGIFCONF error");
- return -1;
- }
- if(ifc.ifc_len == old_len)
- break;
- old_len = ifc.ifc_len;
- len += 10 * sizeof(struct ifreq);
- free(buf);
- }
- printf("we have %d interfaces/n", ifc.ifc_len / sizeof(struct ifreq));
- for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++)
- {
- ifr_p = &ifc.ifc_req[i];
- printf("/ninterface [%s]:/n", ifr_p->ifr_name);
- print_if_addr(sockfd, ifr_p->ifr_name);
- print_if_broadaddr(sockfd, ifr_p->ifr_name);
- print_if_mask(sockfd, ifr_p->ifr_name);
- print_if_mac(sockfd, ifr_p->ifr_name);
- print_if_mtu(sockfd, ifr_p->ifr_name);
- }
- close(sockfd);
- return 0;
- }
- int print_interface_info(char *if_name)
- {
- int sockfd;
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- printf("%s:/n", if_name);
- print_if_addr(sockfd, if_name);
- print_if_broadaddr(sockfd, if_name);
- print_if_mask(sockfd, if_name);
- print_if_mac(sockfd, if_name);
- print_if_mtu(sockfd, if_name);
- close(sockfd);
- return 0;
- }
- int set_if_up(char *if_name) //启动接口
- {
- struct ifreq ifr;
- int sockfd;
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
- {
- perror("ioctl SIOCGIFFLAGS error");
- return -1;
- }
- ifr.ifr_flags |= IFF_UP;
- if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
- {
- perror("ioctl SIOCSIFFLAGS error");
- return -1;
- }
- return 0;
- }
- int set_if_down(char *if_name) //关闭接口
- {
- struct ifreq ifr;
- int sockfd;
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- strcpy(ifr.ifr_name, if_name);
- if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
- {
- perror("ioctl SIOCGIFFLAGS error");
- return -1;
- }
- ifr.ifr_flags &= ~IFF_UP; //将IIF_UP取反后与原来的标志进行 与运算。
- if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
- {
- perror("ioctl SIOCSIFFLAGS error");
- return -1;
- }
- return 0;
- }
- int set_if_ip(char *if_name, char *ip_str) //设置接口的ip地址
- {
- struct ifreq ifr;
- struct sockaddr_in ip_addr;
- int sockfd;
- if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
- {
- perror("Socket error");
- return -1;
- } // 创建用来检查网络接口的套接字
- ip_addr.sin_family = AF_INET;
- if(inet_pton(AF_INET, ip_str, &ip_addr.sin_addr) < 1)
- {
- perror("error ipv4 addr:");
- return -1;
- }
- strcpy(ifr.ifr_name, if_name);
- memcpy(&ifr.ifr_addr, &ip_addr, sizeof(struct sockaddr_in));
- if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)
- {
- perror("ioctl SIOCSIFADDR error");
- return -1;
- }
- return 0;
- }
注:有线连接mac接口名:eth0
无线连接MAC接口名:wlan0
0 0
- linux 系统调用---ioctl
- linux下系统调用劫持ioctl
- linux下ioctl系统调用(3)
- ioctl系统调用
- ioctl系统调用流程
- ioctl系统调用
- vm ioctl系统调用
- ioctl系统调用
- ioctl系统调用
- 系统调用fcntl 和 ioctl
- Linux系统ioctl使用示例 ioctl实验
- linux系统ioctl使用示例
- linux系统ioctl使用示例
- linux系统ioctl使用示例
- linux系统ioctl使用示例
- linux系统ioctl使用示例
- linux系统ioctl使用示例
- linux系统ioctl使用实例
- setsid()
- 道3----编程真经
- 最小的K个数,堆排序——剑指offor Java程序
- PHP 执行exec函数
- Preference使用总结
- linux 系统调用---ioctl
- 测试对于效率的提升都可以做些什么?
- 多播委托
- mssql单个用户与多个用户
- Android Canvas 绘图之 PorterDuffXfermode
- 工作线程(耗时操作)与UI线程实现异步更新
- 三星又推出新工具啦!Gear VR 可以兼容多个视频
- Android属性动画高阶用法-Interpolator,TypeEvaluatory以及贝塞尔曲线公式的使用
- java的第一天