Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
skb中的端口信息不';t与tcpdump';是一个_C_Linux_Networking_Linux Kernel_Network Programming - Fatal编程技术网

skb中的端口信息不';t与tcpdump';是一个

skb中的端口信息不';t与tcpdump';是一个,c,linux,networking,linux-kernel,network-programming,C,Linux,Networking,Linux Kernel,Network Programming,我在函数\uu netif\u receive\u skb\u core()的/net/core/dev.c文件中捕获网络数据包。我解析数据包并获取src_端口,dest_端口,等等。我在任何接口上获取了tcpdump。但是tcpdump的端口信息与我获取的端口信息不匹配。我不明白为什么 orig_dev = skb->dev; eth = eth_hdr(skb); __be16 src_port = 0, dest_port = 0; if (skb->protocol ==

我在函数
\uu netif\u receive\u skb\u core()
的/net/core/dev.c文件中捕获网络数据包。我解析数据包并获取
src_端口
dest_端口
,等等。我在任何接口上获取了tcpdump。但是tcpdump的端口信息与我获取的端口信息不匹配。我不明白为什么

orig_dev = skb->dev;
eth = eth_hdr(skb);
__be16 src_port = 0, dest_port = 0; 

if (skb->protocol == htons(ETH_P_IP))
{
    ih = ip_hdr(skb);
    proto_num = ih->protocol;
    switch (ih->protocol)
    {
    case IPPROTO_TCP:
    {
        struct tcphdr *th = tcp_hdr(skb);
        src_port = th->source;
        dest_port = th->dest;
        break;
    }
    case IPPROTO_UDP:
    {
        struct udphdr *uh = udp_hdr(skb);
        src_port = uh->source;
        dest_port = uh->dest;
        break;
    }
    default:
        src_port = 0;
        dest_port = 0;
    }

    fast_node = NULL;
    fast_node = (struct fast_pktlist *)kzalloc(sizeof(*fast_node), GFP_KERNEL);

    if (fast_node)
    {

        fast_node->protocol_num = proto_num;
        strcpy(fast_node->in_interface, orig_dev->name);
        fast_node->orgsrc_ip = ih->saddr;
        fast_node->orgdest_ip = ih->daddr;
        memcpy(fast_node->orgsrc_mac, eth->h_source, 6);

        fast_node->org_srcport = src_port;
        fast_node->org_destport = dest_port;

        INIT_LIST_HEAD(&fast_node->_list);
        list_add_tail(&fast_node->_list, &FAST_HEAD);
    }
    else
    {
        printk("can not allocate memory at line number = %d\n", __LINE__);
    }
}

我看不到您打印或比较端口的位置和方式(可能您在某处打印
src\u端口
dest\u端口
fast\u节点->org\u srcport
fast\u节点->org\u destport
%u
printk的说明符)。
但您必须考虑到端口in和头是非1字节字段(它有2个字节的长度),所以它有。特别是网络字节顺序。
这就是为什么要在打印时按主机字节顺序查看端口,应使用特殊功能交换字节——网络到主机短。粗略地说,“short”意味着is函数用于2字节变量

最后,如果您需要打印端口,它应该是:

printk(KERN_INFO "sport:%u dport:%u\n", ntohs(src_port), ntohs(dest_port));
如果您需要比较:

if (ntohs(dest_port) == 53)
顺便说一句,必须在通过
ip\u hdr()
/
tcp\u hdr()
/
/
udp\u hdr()
访问标头时设置
网络标头
传输标头
,否则返回的指针可能无效


您还必须注意如何在内核中的不同位置分配内存。

\uu netif\u receive\u skb\u core()
在原子上下文中执行,所以您不能在这里睡觉。标志允许对
kmalloc()
进行一些睡眠,因此您有一个bug。将
GFP\u内核
更改为。

我看不到打印或比较端口的位置和方式(可能您在某处打印
src\u端口
dest\u端口
fast\u节点->org\u srcport
fast\u节点->org\u destport
%u
printk
的说明符)。
但您必须考虑到端口in和头是非1字节字段(它有2个字节的长度),所以它有。特别是网络字节顺序。
这就是为什么要在打印时按主机字节顺序查看端口,应使用特殊功能交换字节——网络到主机短。粗略地说,“short”意味着is函数用于2字节变量

最后,如果您需要打印端口,它应该是:

printk(KERN_INFO "sport:%u dport:%u\n", ntohs(src_port), ntohs(dest_port));
如果您需要比较:

if (ntohs(dest_port) == 53)
顺便说一句,必须在通过
ip\u hdr()
/
tcp\u hdr()
/
/
udp\u hdr()
访问标头时设置
网络标头
传输标头
,否则返回的指针可能无效


您还必须注意如何在内核中的不同位置分配内存。

\uu netif\u receive\u skb\u core()
在原子上下文中执行,所以您不能在这里睡觉。标志允许对
kmalloc()
进行一些睡眠,因此您有一个bug。将GFP_内核更改为。

您所说的“函数中的捕获包”是什么意思?您修补了内核,即将代码添加到此函数?是的,我将代码添加到内核中,并希望在链接列表中加载收到的skb信息(srcport、destport等)。但srcport和目标端口当时与tcp转储不匹配。例如,我提出了许多dns请求。在tcp转储中,所有请求都有目标端口53,但在我的链接列表中,我没有得到目标端口53的数据包。您所说的“函数中捕获数据包”是什么意思?您修补了内核,即将代码添加到此函数?是的,我将代码添加到内核中,并希望在链接列表中加载收到的skb信息(srcport、destport等)。但srcport和目标端口当时与tcp转储不匹配。例如,我提出了许多dns请求。在tcp转储中,所有请求都有目标端口53,但在我的链接列表中,我没有得到目标端口53的数据包。顺便说一句,必须在访问这些数据头时设置network_头和transport_头。我不明白。请解释。@Nayan
skb->network\u header
skb->transport\u header
偏移量必须由网络堆栈正确设置。如果未设置-
ip_hdr()
&co将返回无效指针。因此,您应该将代码嵌入到已设置偏移的正确位置。我不知道你的代码在哪里,因为你没有在问题中描述它。所以这只是一个预先警告..案例IPPROTO_UDP:{struct udphdr*uh=UDP_hdr(skb);src_port=uh->source;dest_port=uh->dest;printk(KERN_INFO“sport:%u dport:%u\n”,ntohs(src_port),ntohs(dest_port));break;}src_port为所有数据包打印一个固定值(17664)。dest_端口随数据包的变化而变化,但为什么源端口从不变化,尽管在tcpdump中我得到了不同的srcport。@Nayan您如何准确地将
tcpdump
中的数据包映射到从内核打印的数据包?我认为linux路由器会接收netif_receive_skb_核心函数中的所有数据包,并使用相同的目标端口发送这些数据包(接收时与目标端口相同)通过uuu dev_queue_xmit。我对不对?顺便说一句,网络头和传输头必须在您访问头时设置。我无法理解。请解释。@Nayan
skb->network_头
skb->transport_头
偏移量必须由网络堆栈正确设置。如果未设置-
ip_hdr()
&co将返回无效的指针。因此,您应该将代码嵌入到已设置偏移量的正确位置。我不知道您的代码位于何处,因为您在问题中没有对其进行描述。因此,这只是一个预先警告。..case IPPROTO_UDP:{struct udphdr*uh=UDP_hdr(skb);src_port=uh->source;dest_port=uh->dest;printk(KERN_INFO“sport:%u dport:%u\n”、ntohs(src_port)、ntohs(dest_port));break;}src_port为