Linux下通过NetLink获取网口信息

原本是打算通过ioctl这个api获取网口是否插线状态,结果设备网口和驱动适配有问题 

查出来的结果跟实际网口对不上 即使用ifconfig也是对不上 (ifconfig也是用的ioctl)

然后发现ethtool命令查的是准确的,打算使用ethtool源码进行裁剪

无奈发现源码比预期大,错综复杂,裁剪也困难。正在一边看着ethtool源码出神

一边想怎么搞  忽然想到  既然ethtool是使用netlink进行获取的

那我直接写个简单的netlink程序获取不就OK了吗

于是就有了以下这段代码

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
 
 
#include 
typedef uint32_t u32;  
typedef uint16_t u16;  
  
struct nlsock {  
    int sock;  
    int seq;  
    struct sockaddr_nl snl;  
    char *name;  
} nl_cmd = { -1, 0, {0}, "netlink-cmd" };  
  
static int index_oif = 0;  
struct nl_if_info {  
    u32 addr;  
    char *name;  
};  
static int nl_socket ( struct nlsock *nl, unsigned long groups )  
{  
    int ret;  
    struct sockaddr_nl snl;  
    int sock;  
    int namelen;  
	
  	/*创建netlink套接字*/
    sock = socket ( AF_NETLINK, SOCK_RAW, NETLINK_ROUTE );  
    if ( sock < 0 ) {  
        fprintf ( stderr,  "Can't open %s socket: %s", nl->name,  
                strerror ( errno ) );  
        return -1;  
    }  
  
    ret = fcntl ( sock, F_SETFL, O_NONBLOCK );  
    if ( ret < 0 ) {  
        fprintf ( stderr,  "Can't set %s socket flags: %s", nl->name,  
                strerror ( errno ) );  
        close ( sock );  
        return -1;  
    }  
	
  	/*设置地址信息*/
    memset ( &snl, 0, sizeof snl );  
    snl.nl_family = AF_NETLINK;  
    snl.nl_groups = groups;  
  
    /* Bind the socket to the netlink structure for anything. */  
    ret = bind ( sock, ( struct sockaddr * ) &snl, sizeof snl );  
    if ( ret < 0 ) {  
        fprintf ( stderr,  "Can't bind %s socket to group 0x%x: %s",  
                nl->name, snl.nl_groups, strerror ( errno ) );  
        close ( sock );  
        return -1;  
    }  
  
    /* multiple netlink sockets will have different nl_pid */  
    namelen = sizeof snl;  
    ret = getsockname ( sock, ( struct sockaddr * ) &snl, &namelen );  
    if ( ret < 0 || namelen != sizeof snl )

你可能感兴趣的:(C语言,linux,运维,服务器)