searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

arping 报文流程分析

2023-06-19 11:26:22
65
0

一 背景

arping 命令是用于发送arp请求到相邻主机的工具,通过目的主机ip获取目的主机mac地址,可用于探测局域网内某个ip是否已经被使用。

前段时间碰到一个问题,源(mask 16)和目的(mask 24)配置的网段长度不一致,且源端使用了*.0 结尾的地址,导致网络不通,arping探测被当作为网络地址返回失败,那么具体流程是什么样的呢。

二 现场模拟

正常情况下,同网段arping返回对方mac地址

指定源ip为网段地址,访问同一server端,返回失败。

三 流程分析

1 server端通过tcpdump抓包

如上图,上半部分为正常arping请求,下半部为sip为*.0情况下报文信息,可以看到该情况下,没有回复reply报文。

2 代码分析

static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
                   struct packet_type *pt, struct net_device *orig_dev)
{
        const struct arphdr *arp;

        /* do not tweak dropwatch on an ARP we will ignore */
        if (dev->flags & IFF_NOARP ||
            skb->pkt_type == PACKET_OTHERHOST ||
            skb->pkt_type == PACKET_LOOPBACK)
                goto consumeskb;

        skb = skb_share_check(skb, GFP_ATOMIC);
        if (!skb)
                goto out_of_mem;

        /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
        if (!pskb_may_pull(skb, arp_hdr_len(dev)))
                goto freeskb;

        arp = arp_hdr(skb);
        if (arp->ar_hln != dev->addr_len || arp->ar_pln != 4)
                goto freeskb;

        memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));

        return NF_HOOK(NFPROTO_ARP, NF_ARP_IN,
                       dev_net(dev), NULL, skb, dev, NULL,
                       arp_process);

consumeskb:
        consume_skb(skb);
        return NET_RX_SUCCESS;
freeskb:
        kfree_skb(skb);
out_of_mem:
        return NET_RX_DROP;
}

在经过一系列校验和hook函数过滤后,进入arp_process(), 该函数流程比较复杂,正常流程会在通过ip_route_input_noref()一系列路由检查后,返回 reply报文。

下面是ip_route_input_noref调用流程

ip_route_input_noref
    ip_route_input_rcu
        ip_route_input_slow
            fib_validate_source
                __fib_validate_source

最终通过fib_lookup(), 进行反向路由查找,其中*.0会被当做网络地址,返回res.type为RTN_BROADCAST

不满足条件,导致__fib_validate_source()返回EINVAL,最终结果就是没有回复reply报文,探测不通。

0条评论
0 / 1000
zhangzq
6文章数
1粉丝数
zhangzq
6 文章 | 1 粉丝
原创

arping 报文流程分析

2023-06-19 11:26:22
65
0

一 背景

arping 命令是用于发送arp请求到相邻主机的工具,通过目的主机ip获取目的主机mac地址,可用于探测局域网内某个ip是否已经被使用。

前段时间碰到一个问题,源(mask 16)和目的(mask 24)配置的网段长度不一致,且源端使用了*.0 结尾的地址,导致网络不通,arping探测被当作为网络地址返回失败,那么具体流程是什么样的呢。

二 现场模拟

正常情况下,同网段arping返回对方mac地址

指定源ip为网段地址,访问同一server端,返回失败。

三 流程分析

1 server端通过tcpdump抓包

如上图,上半部分为正常arping请求,下半部为sip为*.0情况下报文信息,可以看到该情况下,没有回复reply报文。

2 代码分析

static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
                   struct packet_type *pt, struct net_device *orig_dev)
{
        const struct arphdr *arp;

        /* do not tweak dropwatch on an ARP we will ignore */
        if (dev->flags & IFF_NOARP ||
            skb->pkt_type == PACKET_OTHERHOST ||
            skb->pkt_type == PACKET_LOOPBACK)
                goto consumeskb;

        skb = skb_share_check(skb, GFP_ATOMIC);
        if (!skb)
                goto out_of_mem;

        /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
        if (!pskb_may_pull(skb, arp_hdr_len(dev)))
                goto freeskb;

        arp = arp_hdr(skb);
        if (arp->ar_hln != dev->addr_len || arp->ar_pln != 4)
                goto freeskb;

        memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));

        return NF_HOOK(NFPROTO_ARP, NF_ARP_IN,
                       dev_net(dev), NULL, skb, dev, NULL,
                       arp_process);

consumeskb:
        consume_skb(skb);
        return NET_RX_SUCCESS;
freeskb:
        kfree_skb(skb);
out_of_mem:
        return NET_RX_DROP;
}

在经过一系列校验和hook函数过滤后,进入arp_process(), 该函数流程比较复杂,正常流程会在通过ip_route_input_noref()一系列路由检查后,返回 reply报文。

下面是ip_route_input_noref调用流程

ip_route_input_noref
    ip_route_input_rcu
        ip_route_input_slow
            fib_validate_source
                __fib_validate_source

最终通过fib_lookup(), 进行反向路由查找,其中*.0会被当做网络地址,返回res.type为RTN_BROADCAST

不满足条件,导致__fib_validate_source()返回EINVAL,最终结果就是没有回复reply报文,探测不通。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0