80 lines
2.1 KiB
Perl
Executable File
80 lines
2.1 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# vim:set ts=4 sw=4:
|
|
|
|
use strict;
|
|
use POSIX;
|
|
use Socket;
|
|
|
|
use FindBin;
|
|
use lib "$FindBin::Bin/lib";
|
|
use l0gger;
|
|
|
|
l0gger::init();
|
|
|
|
|
|
use constant AF_NETLINK => 16;
|
|
#use Socket::Netlink;
|
|
|
|
# Netlink setup
|
|
socket my $sock,AF_NETLINK,SOCK_RAW,0 #(domain, type, bus//protocol)
|
|
or die "socket: $!\n";
|
|
bind $sock, pack("vvVV",AF_NETLINK,0,0,1) #(domain, zero , pid, group);
|
|
or die "bind: $!\n";
|
|
|
|
while(1){
|
|
sysread($sock,my $msg, 65535) or die "recv: $!";
|
|
my ($ifname,$state)=(undef,undef);
|
|
|
|
# print unpack("H*",substr($message,0,16)),"\n"; # ifi_type etc.
|
|
$msg=substr($msg,16);
|
|
|
|
my (undef,undef,undef,undef,undef,$type)=unpack("nnnnCC",$msg);
|
|
$msg=substr($msg,16);
|
|
# print "Type=$type\n";
|
|
next if($type!=16); # RTM_NEWLINK
|
|
|
|
while(length($msg)){
|
|
my($len,$type)=unpack("vv",$msg);
|
|
# print "len= $len,type=$type\n";
|
|
last if($len<4);
|
|
|
|
$msg=substr($msg,4);
|
|
if ($type == 3){ # IFLA_IFNAME
|
|
$ifname=unpack("Z*",$msg);
|
|
}elsif($type == 16){ # IFLA_OPERSTATE
|
|
$state=unpack("v",$msg);
|
|
}else{
|
|
# print "content=",unpack("H*",substr($msg,0,$len-4)),"\n";
|
|
};
|
|
|
|
$len=(int(($len-1)/4))*4; # 4-byte alignment
|
|
$msg=substr($msg,$len);
|
|
};
|
|
next if(!defined($ifname) || !defined($state));
|
|
# print "ifname=$ifname, state=$state\n";
|
|
# IF_OPER_UNKNOWN (0):
|
|
# Interface is in unknown state, neither driver nor userspace has set
|
|
# operational state. Interface must be considered for user data as
|
|
# setting operational state has not been implemented in every driver.
|
|
# IF_OPER_NOTPRESENT (1):
|
|
# Unused in current kernel (notpresent interfaces normally disappear),
|
|
# just a numerical placeholder.
|
|
# IF_OPER_DOWN (2):
|
|
# Interface is unable to transfer data on L1, f.e. ethernet is not
|
|
# plugged or interface is ADMIN down.
|
|
# IF_OPER_LOWERLAYERDOWN (3):
|
|
# Interfaces stacked on an interface that is IF_OPER_DOWN show this
|
|
# state (f.e. VLAN).
|
|
# IF_OPER_TESTING (4):
|
|
# Unused in current kernel.
|
|
# IF_OPER_DORMANT (5):
|
|
# Interface is L1 up, but waiting for an external event, f.e. for a
|
|
# protocol to establish. (802.1X)
|
|
# IF_OPER_UP (6):
|
|
# Interface is operational up and can be used.
|
|
if($state==6){
|
|
l0gger::send("$ifname up");
|
|
};
|
|
}
|