iotcl函数与网络接口
来源:互联网 发布:300036 超图软件 编辑:程序博客网 时间:2024/05/21 06:16
viewplaincopy to clipboardprint?
#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 SIOCGIFADDRerror");
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 SIOCGIFBRDADDRerror");
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 SIOCGIFNETMASKerror");
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!因为char要对[1xxx xxxx]这样的数进行补码运算的。
//但我们等下要打印的mac地址是不需要符号的数值
struct ifreq ifr;
strcpy(ifr.ifr_name, if_name);
if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
{
perror("ioctl SIOCGIFHWADDRerror");
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));
//printf(" MAC:%02x:%02x:%02x:%02x:%02x:%02x\n",*p++, *p++, *p++, *p++, *p++, *p++);
//这么写会导致输出为倒序。这并不是p指针有什么问题,不信你可以用
// for(;;)
// printf(p++);
//来试验就是正确的,我猜倒序的原因是编译器的优化问题吧
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 SIOCGIFMTUerror");
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("Socketerror");
return -1;
} // 创建用来检查网络接口的套接字
/* strcpy(ifr.ifr_name, if_name);
if(ioctl(fd, SIOCGIFMTU, &ifr) < 0)
{
perror("ioctl SIOCGIFMTUerror");
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("Socketerror");
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(structifreq);
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("Socketerror");
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("Socketerror");
return -1;
} // 创建用来检查网络接口的套接字
strcpy(ifr.ifr_name, if_name);
if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
{
perror("ioctl SIOCGIFFLAGSerror");
return -1;
}
ifr.ifr_flags |= IFF_UP;
if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
{
perror("ioctl SIOCSIFFLAGSerror");
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("Socketerror");
return -1;
} // 创建用来检查网络接口的套接字
strcpy(ifr.ifr_name, if_name);
if(ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0)
{
perror("ioctl SIOCGIFFLAGSerror");
return -1;
}
ifr.ifr_flags &= ~IFF_UP; //将IIF_UP取反后与原来的标志进行 与运算。
if(ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0)
{
perror("ioctl SIOCSIFFLAGSerror");
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 ipv4addr:");
return -1;
}
strcpy(ifr.ifr_name, if_name);
memcpy(&ifr.ifr_addr, &ip_addr, sizeof(structsockaddr_in));
if(ioctl(sockfd, SIOCSIFADDR, &ifr) < 0)
{
perror("ioctl SIOCSIFADDRerror");
return -1;
}
return 0;
}
#include <stdio.h> //printf()
#include <unistd.h> //ioctl()
#include <sys/ioctl.h> //ioctl
#include <sys/socket.h> //socket()
#include <net/if.h> //struct ifconf{} & structifreq{}
#include <string.h> //strcpy()
#include <arpa/inet.h> //inet_ntoa()
#include <stdlib.h> //malloc() & free()
intprint_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(); //打印该程序的使用手册
intmain(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;
}
return0;
}
voidusage()
{
printf("usage: ./myifconfig [interface [down|up|ip]]\n");
}
intprint_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;
}
intprint_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;
}
intprint_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;
}
intprint_if_mac(int fd, char *if_name)
{
unsigned char *p; //注意! 这里要用unsigned char,而不是char!因为char要对[1xxxxxxx]这样的数进行补码运算的。
//但我们等下要打印的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));
//printf(" MAC:%02x:%02x:%02x:%02x:%02x:%02x\n", *p++, *p++, *p++,*p++, *p++, *p++);
//这么写会导致输出为倒序。这并不是p指针有什么问题,不信你可以用
// for(;;)
// printf(p++);
//来试验就是正确的,我猜倒序的原因是编译器的优化问题吧
return 0;
}
intprint_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; //获得子网掩码。注意!我们仍放在structaockaddr_in结构中返回
printf(" MTU: %d\n", mtu);
return 0;
}
intprint_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; //获得子网掩码。注意!我们仍放在structaockaddr_in结构中返回
printf(" ipv6: %d\n", mtu);
*/
//未写完,不知道怎么获得ipv6地址。。。
return 0;
}
intprint_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(structifreq));
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;
}
intprint_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;
}
intset_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;
}
intset_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;
}
intset_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;
}
- iotcl函数与网络接口
- iotcl函数
- iotcl函数
- ioctl 函数与网络接口
- ioctl 函数与网络接口
- ioctl 函数与网络接口
- ioctl 函数与网络接口
- ioctl 函数与网络接口
- linux网络编程中iotcl的用法
- iotcl函数(转自http://blog.csdn.net/shanshanpt/article/details/19897897)
- 网络桥接与网络接口
- 《ASCE1885的网络编程》---Windows API基本函数の套接口与连接的建立
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
- 获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
- (NIDS)网络入侵检测函数接口说明
- ios获取网络接口信息的函数
- VOLTE网络架构、接口与功能实体
- TCP/IP之一:网络结构与网络接口层
- 对OD硬件断点的几点思考
- 《编码:隐匿在计算机软硬件背后的语言》TXT
- mysql-5.6.20-winx64免安装版数据库中文乱码终极解决方案
- 黑苹果安装及相关注意事项之五,安装Win7
- iOS 之AipArchive压缩和解压
- iotcl函数与网络接口
- 项目管理积分制度
- 你值得拥有:25 个 Linux 性能监控工具
- iOS 之沙盒
- ubantu下firefox扩展插件更新不了
- 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
- 献给21岁的自己
- iOS 之Autorelease
- Leetcode - C++ 目录