3
IFF_UP 与 IFF_RUNNING
source link: http://bean-li.github.io/if-is-up/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
IFF_UP 与 IFF_RUNNING
|
分类 Linux
|
标签 Linux
近期,发现判断网卡是否Ready的程序出了一些问题,有些网卡明明没有插线,依然会被判定为active的网卡。我去跟踪了下代码:
# struct ifreq { // FOR SIOCGIFFLAGS:
# char ifrn_name[IFNAMSIZ]
# short ifru_flags
# };
my $STRUCT_IFREQ_SIOCGIFFLAGS = 'Z' . IFNAMSIZ . 's1';
sub get_active_network_interfaces {
# Use the interface name list from /proc/net/dev
open my $fh, '<', '/proc/net/dev'
or die "failed to open /proc/net/dev: $!\n";
# And filter by IFF_UP flag fetched via a PF_INET6 socket ioctl:
my $sock;
socket($sock, PF_INET6, SOCK_DGRAM, &IPPROTO_IP)
or socket($sock, PF_INET, SOCK_DGRAM, &IPPROTO_IP)
or return [];
my $ifaces = [];
while(defined(my $line = <$fh>)) {
next if $line !~ /^\s*([^:\s]+):/;
my $ifname = $1;
my $ifreq = pack($STRUCT_IFREQ_SIOCGIFFLAGS, $ifname, 0);
if (!defined(ioctl($sock, SIOCGIFFLAGS, $ifreq))) {
warn "failed to get interface flags for: $ifname\n";
next;
}
my ($name, $flags) = unpack($STRUCT_IFREQ_SIOCGIFFLAGS, $ifreq);
push @$ifaces, $ifname if ($flags & IFF_UP);
}
close $fh;
close $sock;
return $ifaces;
}
发现源码使用通过调用 ioctl SIOCGIFFLAGS 来判定网卡是否已经ready。
关于SIOCGIFFLAGS
Linux ioctl支持一下两个标志位:
- SIOCGIFFLAGS: 获取设备的活动标志位
- SIOCSIFFLAGS: 修改设备的活动标志位
SIOCGIFFLAGS, SIOCSIFFLAGS
Get or set the active flag word of the device. ifr_flags contains a bit mask of the following values:
Device flags
IFF_UP Interface is running.
IFF_BROADCAST Valid broadcast address set.
IFF_DEBUG Internal debugging flag.
IFF_LOOPBACK Interface is a loopback interface.
IFF_POINTOPOINT Interface is a point-to-point link.
IFF_RUNNING Resources allocated.
IFF_NOARP No arp protocol, L2 destination address not set.
IFF_PROMISC Interface is in promiscuous mode.
IFF_NOTRAILERS Avoid use of trailers.
IFF_ALLMULTI Receive all multicast packets.
IFF_MASTER Master of a load balancing bundle.
IFF_SLAVE Slave of a load balancing bundle.
IFF_MULTICAST Supports multicast
IFF_PORTSEL Is able to select media type via ifmap.
IFF_AUTOMEDIA Auto media selection active.
IFF_DYNAMIC The addresses are lost when the interface goes down.
IFF_LOWER_UP Driver signals L1 up (since Linux 2.6.17)
IFF_DORMANT Driver signals dormant (since Linux 2.6.17)
IFF_ECHO Echo sent packets (since Linux 2.6.25)本次我们重点介绍IFF_UP和 IFF_RUNNING。
IFF_UP: 这个标志位表示的是从管理上讲,这个网口是UP的,是Ready的,但是并不代表连接状态。即网卡已经准备好了,但是并不意味着网线已插。
IFF_RUNNING: 这个标志位表示operational state,如果置位的话,表示CONNECTED的。
做个简单验证:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
struct ifreq ifr;
int sfd ;
memset(&ifr, '\0' , sizeof(struct ifreq));
strcpy(ifr.ifr_name, argv[1]);
sfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
int ret = ioctl(sfd, SIOCGIFFLAGS, (char *)&ifr);
if(ret !=0)
{
printf("failed to exec ioctl");
goto out;
}
printf("%10s IFF_UP: %d\n", argv[1], !!(ifr.ifr_flags & IFF_UP));
printf("%10s IFF_RUNNING: %d \n",argv[1], !!(ifr.ifr_flags & IFF_RUNNING));
out:
close(sfd);
exit(ret);
}
我的笔记本的网口情况如下:
manu-latitude3510 CODE/C » cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 1503282 11818 0 0 0 0 0 0 1503282 11818 0 0 0 0 0 0
eno1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
wlp1s0: 14947732561 40405691 0 822774 0 0 0 0 650855154 3591298 0 0 0 0 0 0
manu-latitude3510 CODE/C »
其中eno1 是有线,并未插线,wlp1s0是无线,已经连接的状态。
manu-latitude3510 CODE/C » ./nettool eno1
eno1 IFF_UP: 1
eno1 IFF_RUNNING: 0
manu-latitude3510 CODE/C » ./nettool wlp1s0
wlp1s0 IFF_UP: 1
wlp1s0 IFF_RUNNING: 1
manu-latitude3510 CODE/C » ./nettool lo
lo IFF_UP: 1
lo IFF_RUNNING: 1
manu-latitude3510 CODE/C
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK