我有一个应用程序,它在数据链路层级别发送/接收数据包,即通过有线以太网连接从MAC地址发送到MAC地址的帧。
我使用pcap库来做这件事。
从终端运行ip a
将返回:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s25: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 50:7b:9d:84:34:93 brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 18:5e:0f:8f:d1:3f brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 brd 192.168.1.255 scope global dynamic wlp3s0
valid_lft 57882sec preferred_lft 57882sec
inet6 fe80::c215:9ad2:a358:6d3d/64 scope link
valid_lft forever preferred_lft forever
我的操作系统是ubuntu 16.04,它使用了systemd可预测的网络接口命名。在这种情况下,有线以太网接口的名称是enp0s25
。
目前,我已经在我的应用程序中硬编码了这一点,即
pcap=pcap_open_live("enp0s25", ETH_SNAPLEN, ETH_PROMISCUOUS, ETH_TIMEOUT, pcap_errbuf);
我希望能够做的是动态检索有线以太网接口的名称,以便它仍然可以在以太网接口名称可能不同于enp0s25
的设备上工作
我已经实现了:
/* automatically retrieve the ethernet interface name */
n = pcap_findalldevs(&alldevs, pcap_errbuf);
/* scan the list for a suitable device to capture from */
for (dev = alldevs; dev != NULL; dev = dev->next) {
/* Name */
printf("%s\n",dev->name);
}
pcap_freealldevs(alldevs);
这允许我遍历所有接口名称。
我的问题是,我如何找出与有线以太网接口对应的名称?
我还没有在多个设备上测试我的代码,所以不确定接口名称与enp0s25
有何不同。
有线以太网接口是否总是以enp
开头
在哪种情况下,可能的解决方案是使用检索到的接口名称的前3个字符执行strcmp
?
发布于 2018-03-23 19:31:11
ioctl(fd, SIOCGIWNAME)
将返回无线扩展协议版本,该版本仅在无线接口上可用。
以下函数检查接口是否为无线接口
bool check_type(const char* ifname) {
int sock = -1;
// set the name of the interface in the ioctl request struct
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
//Create a throw-away socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return FALSE;
}
// First check if the interface is up
// also proves that the interface exists
int r = ioctl(sock, SIOCGIFFLAGS, &ifr);
if (r != 0) {
close(sock);
return FALSE;
}
if (!(ifr.ifr_flags & IFF_UP)) {
close(sock);
return FALSE;
}
if (ioctl(sock, SIOCGIWNAME, &ifr) != -1) {
close(sock);
return TRUE;
}
close(sock);
return FALSE;
}
https://stackoverflow.com/questions/49447049
复制相似问题