首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ip_rcv ( ip_input.c for ipv4)循环模式下的行为

ip_rcv ( ip_input.c for ipv4)循环模式下的行为
EN

Stack Overflow用户
提问于 2019-11-30 10:14:48
回答 1查看 183关注 0票数 0

因此,我想在ip_rcv函数中放置几条printk消息,看看在从特定IP接收数据包后是否有消息打印出来。我正在附加整个ip_rcv函数,它具有printk修改:

代码语言:javascript
复制
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
    const struct iphdr *iph;
    struct net *net;
    u32 len;

    /* When the interface is in promisc. mode, drop all the crap
     * that it receives, do not try to analyse it.
     */
    if (skb->pkt_type == PACKET_OTHERHOST)
        goto drop;


    net = dev_net(dev);
    __IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);

    skb = skb_share_check(skb, GFP_ATOMIC);
    if (!skb) {
        __IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
        goto out;
    }

    if (!pskb_may_pull(skb, sizeof(struct iphdr)))
        goto inhdr_error;

    iph = ip_hdr(skb);

    //**PSK's Modification**
    if (iph->saddr == 0x08080808)
        printk("\n***PSK: %x IP's message recieved: Google***\n", iph->saddr);
    if (iph->saddr == 0x0202000A)
        printk("\n***PSK: %x IP's message recieved: Gateway***\n", iph->saddr);
    if (iph->saddr == 0x010000FF)
        printk("\n***PSK: %x IP's message recieved : Home***\n", iph->saddr);

     /* RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum.
     *
     *  Is the datagram acceptable?
     *
     *  1.  Length at least the size of an ip header
     *  2.  Version of 4
     *  3.  Checksums correctly. [Speed optimisation for later, skip loopback checksums]
     *  4.  Doesn't have a bogus length
     */

    if (iph->ihl < 5 || iph->version != 4)
        goto inhdr_error;

    BUILD_BUG_ON(IPSTATS_MIB_ECT1PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_1);
    BUILD_BUG_ON(IPSTATS_MIB_ECT0PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_0);
    BUILD_BUG_ON(IPSTATS_MIB_CEPKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_CE);
    __IP_ADD_STATS(net,
               IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
               max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));

    if (!pskb_may_pull(skb, iph->ihl*4))
        goto inhdr_error;

    iph = ip_hdr(skb);

    if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
        goto csum_error;

    len = ntohs(iph->tot_len);
    if (skb->len < len) {
        __IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
        goto drop;
    } else if (len < (iph->ihl*4))
        goto inhdr_error;

    /* Our transport medium may have padded the buffer out. Now we know it
     * is IP we can trim to the true length of the frame.
     * Note this now means skb->len holds ntohs(iph->tot_len).
     */
    if (pskb_trim_rcsum(skb, len)) {
        __IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
        goto drop;
    }

    iph = ip_hdr(skb);
    skb->transport_header = skb->network_header + iph->ihl*4;

    /* Remove any debris in the socket control block */
    memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
    IPCB(skb)->iif = skb->skb_iif;

    /* Must drop socket now because of tproxy. */
    skb_orphan(skb);

    return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
               net, NULL, skb, dev, NULL,
               ip_rcv_finish);

csum_error:
    __IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
inhdr_error:
    __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
drop:
    kfree_skb(skb);
out:
    return NET_RX_DROP;
}

在从Google、本地网关(10.0.2.2)或回送地址(127.0.0.1)获得数据包后,我应该将一条消息打印到内核缓冲区中。这对于DNS和网关是很好的,但是当我平本地主机或尝试运行一个程序时,这是很好的,这涉及到一个本地主机的来回。是否还有其他内核函数调用专门处理本地主机的数据包,或者我缺少一些非常基本的东西?我认为环回数据包应该在堆栈中跟踪与任何其他数据包相同的路径,至少直到L3为止。我也希望有人能简要地解释一下环回交通的处理方法,并给出答案。

系统规格: System- Ubuntu on 内核- 4.15.0-70通用

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-30 23:56:16

我觉得这里出了点问题

代码语言:javascript
复制
if (iph->saddr == 0x010000FF)

也许你的意思是:

代码语言:javascript
复制
if (iph->saddr == 0x0100007F)

回送数据包应该跟踪相同的路径。

是的,一般说来。

详细了解回环装置的详细信息。

而且,您总是可以使用一些有用的工具(如https://linux.die.net/man/1/trace-cmd )操作。F.e.要查看函数图,您可以这样做:

代码语言:javascript
复制
trace-cmd record -p function_graph -g net_rx_action

然后启动ping 127.0.0.1,然后停止跟踪并查看报告,如

代码语言:javascript
复制
trace-cmd report | vim -

在这里,您可以看到“路径”,并确保您的本地主机点击最终落入ip_rcv()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59115140

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档