1

宛先がローカルまたは直接接続されたネットワークでない場合、パケットをカプセル化するネットワーク モジュールがあります。そのために、このパケットがローカルかどうかを検出する機能があります。この関数は IPv4 パケット用であり、IPv6 用に同じことを行うには複製する必要があります。IPv4 の関数のコードは次のとおりです。

bool is_v4addr_local(struct iphdr *iph, const struct net_device *output_dev)
{
    struct flowi fl;
    struct rtable *rt;
    struct net_device *dev;

    if(output_dev == NULL) {
          printk(KERN_DEBUG "output_dev is NULL!");
          return 0;
    }
    memset(&fl, 0, sizeof(fl));
    fl.u.ip4.daddr = iph->daddr;
    fl.flowi_tos = RTO_ONLINK; //locally connected
    rt = ip_route_output_key(dev_net(output_dev), &fl.u.ip4);
    if (IS_ERR(rt))
        return 0;
    dev = rt->dst.dev;
    ip_rt_put(rt);
    if (!dev)
        return 0;

    // If we got anything, it's local
    return 1;
}

それを適応させるには、関数 fib6_rule_lookup を使用する必要があると思いますが、関数の最後のパラメーターを導入する方法を知っています (一部の例では、ip6_pol_route_lookup のみを配置しますが、機能しません)。

この機能を適応させるのを手伝ってもらえますか? カーネル空間でプログラミングするのは初めてです。

ありがとう

bool is_v6addr_local(struct ipv6hdr *iph, const struct net_device *output_dev)
{
    struct rt6_info *rt;
    struct net_device *dev;
    struct dst_entry *dst;
    struct flowi6 fl6;


    if(output_dev == NULL) {
          printk(KERN_DEBUG "output_dev is NULL!");
          return 0;
    }

    memset(&fl6, 0, sizeof(fl6));
    fl6.flowi6_tos = RTO_ONLINK;
    fl6.daddr = iph->daddr;


    dst = fib6_rule_lookup(dev_net(output_dev), &fl6, 0, ip6_pol_route_lookup);
    if (dst->error != 0)
        return 0;
    rt = (struct rt6_info *) dst;

    dev = rt->dst.dev;
    if (!dev)
        return 0;

    // If we got anything, it's local*/
    return 1;
}
4

0 に答える 0