版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/89433063
一 代码
#include <net/if.h> /* for ifconf */
#include <linux/sockios.h> /* for net status mask */
#include <netinet/in.h> /* for sockaddr_in */
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h> //for close
#include <arpa/inet.h>
#include <string.h>
#define MAX_INTERFACE (16)
void port_status(unsigned int flags);
int get_if_info(int fd)
{
struct ifreq buf[MAX_INTERFACE];
struct ifconf ifc;
int ret = 0;
int if_num = 0;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t) buf;
ret = ioctl(fd, SIOCGIFCONF, (char*)&ifc);
if (ret)
{
printf("get if config info failed");
return -1;
}
/* 网口总数 ifc.ifc_len 应该是一个出入参数 */
if_num = ifc.ifc_len / sizeof(struct ifreq);
printf("interface num is interface = %d\n", if_num);
while (if_num-- > 0)
{
printf("net device: %s\n", buf[if_num].ifr_name);
/* 获取第n个网口信息 */
ret = ioctl(fd, SIOCGIFFLAGS, (char*)&buf[if_num]);
if (ret)
continue;
/* 获取网口状态 */
port_status(buf[if_num].ifr_flags);
/* 获取当前网卡的ip地址 */
ret = ioctl(fd, SIOCGIFADDR, (char*)&buf[if_num]);
if (ret)
continue;
printf("IP address is: \n%s\n", inet_ntoa(((struct sockaddr_in *)(&buf[if_num].ifr_addr))->sin_addr));
/* 获取当前网卡的mac */
ret = ioctl(fd, SIOCGIFHWADDR, (char*)&buf[if_num]);
if (ret)
continue;
printf("%02x:%02x:%02x:%02x:%02x:%02x\n\n",
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[0],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[1],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[2],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[3],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[4],
(unsigned char)buf[if_num].ifr_hwaddr.sa_data[5]);
}
}
void port_status(unsigned int flags)
{
if (flags & IFF_UP)
{
printf("is up\n");
}
if (flags & IFF_BROADCAST)
{
printf("is broadcast\n");
}
if (flags & IFF_LOOPBACK)
{
printf("is loop back\n");
}
if (flags & IFF_POINTOPOINT)
{
printf("is point to point\n");
}
if (flags & IFF_RUNNING)
{
printf("is running\n");
}
if (flags & IFF_PROMISC)
{
printf("is promisc\n");
}
}
int main()
{
int fd;
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd > 0)
{
get_if_info(fd);
close(fd);
}
return 0;
}
二 运行
[root@localhost test]# g++ test.cpp -o test
[root@localhost test]# ./test
interface num is interface = 2
net device: enp0s3
is up
is broadcast
is running
IP address is:
192.168.0.120
08:00:27:0c:3b:d3
net device: lo
is up
is loop back
is running
IP address is:
127.0.0.1
00:00:00:00:00:00
三 说明
1 网络相关的ioctl请求的request参数及arg地址必须指向的数据类型如下表所示:
接口 |
SIOCGIFCONF SIOCSIFADDR SIOCGIFADDR SIOCSIFBRDADDR SIOCGIFBRDADDR SIOCSIFNETMASK SIOCGIFNETMASK |
获取所有接口列表 设置接口地址 获取接口地址 设置广播地址 获取广播地址 设置子网掩码 获取子网掩码 |
Struct ifconf Struct ifreq Struct ifreq Struct ifreq Struct ifreq Struct ifreq Struct ifreq |
2 ifconf定义如下:
struct ifconf{
lint ifc_len;
union{
caddr_t ifcu_buf
Struct ifreq *ifcu_req;
}ifc_ifcu
}
#define ifc_buf ifc_ifcu.ifcu_buf
#define ifc_req ifc_ifcu.ifcu_req
3 本机所有的网卡信息都列举出来了,效果和ifconfig命令类似。