Linux中的ioctl函数是与内核交互的一种方法, 在驱动和网络中的使用都非常的广泛。
ioctl函数在网络编程中有相当多的选项,下边我们就利用ioctl函数来获得当前系统中物理网卡的地址。
首先看一下ioctl函数的原型:
int ioctl(int d, int request, ...);
参数:d, 表示要操作的文件描述符
request, 表示ioctl函数的操作选项,不同的选项具有不同的功能。
第三参数,是一个void*的指针类型,要根据request参数来决定。
通过ioctl_list可以查看当前ioctl函数在网络中的常用选项,其中SIOCGIFHWADDR 选项用于获得物理网卡的地址,并且第三个参数是struct ifreq的指针类型。
要想获得物理网卡的地址,需要对struct ifreq的结构体成员赋值,其中包括对ifreq.ifr_ifrn.ifrn_name成员赋值为要获得那块网卡的的名字,比如:strcpy(req.ifr_ifrn.ifrn_name, "eth0"),表示要获得eth0的地址。当执行完ioctl函数之后,网卡的地址就会保存在ifreq.ifr_ifru.ifru_hwaddr.sa_data成员中,我们只需将得到的值进行转换即可。
代码示例:
int main(int argc, const char *argv[])
{
int sockfd;
struct ifreq req;
char buf[32] = {0};
int i = 0;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("fail to create socket ..!");
exit(1);
}
strcpy(req.ifr_ifrn.ifrn_name, "eth0");
/* *获得eth0的MAC地址 */
if (ioctl(sockfd, SIOCGIFHWADDR, &req) < 0) {
perror("fail to ioctl ");
close(sockfd);
exit(1);
}
close(sockfd);
memcpy(buf, req.ifr_ifru.ifru_hwaddr.sa_data, 6);
//strncpy(buf, req.ifr_ifru.ifru_hwaddr.sa_data, 6);
/* *按照xx:xx:xx:xx:xx:xx的格式显示 */
for (i = 0; i < 6; i++)
printf("%02x:", buf[i] & 0xff);
puts("\b ");///后输出不带":"
return 0;
}
Copyright © 2004-2024 华清远见教育科技集团 版权所有
京ICP备16055225号-5,京公海网安备11010802025203号