在Linux内核模块中获取接口网络掩码

我用netfilter钩子编写Linux内核模块。我想阻止任何不是来自子网的数据包。

是否有任何简单的方法可以在内核模式下获取接口的网络掩码?我发现只有在用户模式下使用ioctl()才能获得它的方法。

lgq890116 回答:在Linux内核模块中获取接口网络掩码

有一种很简单的方法来获取它。
网络设备由struct net_device描述。
<linux/netdevice.h>

struct net_device {
    ...
    struct in_device __rcu  *ip_ptr;
    ...

net_device有一个指向“ inet”设备(in_device)的指针。

<linux/inetdevice.h>

struct in_device {
    ...
    struct in_ifaddr    *ifa_list;  /* IP ifaddr chain      */
    ...

最终指向包含所有接口信息的in_ifaddr链:

struct in_ifaddr {
    struct hlist_node   hash;
    struct in_ifaddr    *ifa_next;
    struct in_device    *ifa_dev;
    struct rcu_head     rcu_head;
    __be32              ifa_local;
    __be32              ifa_address;
    __be32              ifa_mask;
    __u32               ifa_rt_priority;
    __be32              ifa_broadcast;
    unsigned char       ifa_scope;
    unsigned char       ifa_prefixlen;
    __u32               ifa_flags;
    char                ifa_label[IFNAMSIZ];

    /* In seconds,relative to tstamp. Expiry is at tstamp + HZ * lft. */
    __u32               ifa_valid_lft;
    __u32               ifa_preferred_lft;
    unsigned long       ifa_cstamp; /* created timestamp */
    unsigned long       ifa_tstamp; /* updated timestamp */
};

为使我的答案更加通用,下面是一个抽象示例(不绑定到设备逻辑):

struct in_ifaddr *ifa;
struct net_device *dev = dev_get_by_name(&init_net,"wlp7s0");
if(!dev) {
    printk(KERN_ERR "Can't obtain device\n");
    return;
}

// roughly
rcu_read_lock();
for(ifa = rcu_dereference(dev->ip_ptr->ifa_list);
          ifa;
          ifa = rcu_dereference(ifa->ifa_next))
    printk("address: %pI4,mask: %pI4\n",&ifa->ifa_address,&ifa->ifa_mask);
rcu_read_unlock();

从示例中您可以看到,您可以根据某些特定逻辑来处理整个链(注释中提到的@larsks)。

P.S。不要忘记包含<linux/netdevice.h><linux/inetdevice.h>

本文链接:https://www.f2er.com/2903283.html

大家都在问