Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
Linux:在KVM下未在本地接收原始套接字发送的数据包_Linux_Sockets_Networking - Fatal编程技术网

Linux:在KVM下未在本地接收原始套接字发送的数据包

Linux:在KVM下未在本地接收原始套接字发送的数据包,linux,sockets,networking,Linux,Sockets,Networking,我一直在尝试使用原始套接字发送UDP数据包,但是,发送的数据包不会在本地接收。如果发送到远程目的地,将接收相同的数据包。测试在KVM下进行。同样的测试似乎也在进行 插座设置为: 原始插座=插座(AF_数据包、SOCK_原始、htons(ETH_p_ALL)) 有一个接收过滤器连接,它被设置为滥交。正确接收数据包。发送的数据包在Wireshark中接收并正确分析。但是,本地程序(例如nc-l-u-p…)不接收数据包。如果我将相同的数据包发送到远程目的地,则数据包被正确接收。Wireshark接收数

我一直在尝试使用原始套接字发送UDP数据包,但是,发送的数据包不会在本地接收。如果发送到远程目的地,将接收相同的数据包。测试在KVM下进行。同样的测试似乎也在进行

插座设置为:

原始插座=插座(AF_数据包、SOCK_原始、htons(ETH_p_ALL))

有一个接收过滤器连接,它被设置为滥交。正确接收数据包。发送的数据包在Wireshark中接收并正确分析。但是,本地程序(例如nc-l-u-p…)不接收数据包。如果我将相同的数据包发送到远程目的地,则数据包被正确接收。Wireshark接收数据包的事实表明,它没有被任何iptables规则丢弃(我还检查了所有丢弃规则计数器,没有丢弃的数据包)

如果这有意义的话,看起来数据包被路由了,但没有被网络堆栈重新处理

这应该是网络课程中的一个示例代码,现在,我在学生面前丢了脸。希望他们都不在这个名单上;-)

非常感谢您的帮助, 尤瓦尔

关于代码的一些注释。为简洁起见,UDP校验和设置为0,IP校验和从标头计算。这两个都由Wireshark验证(并且也被KVM上的远程机器接受)。代码解析消息,并在收到的缓冲区上发送回复。udp_hdr和ip_hdr指向数据包缓冲区(buffer)中相应的报头,而负载指向L7数据的开始

代码如下: { /*处理请求*/ 谢谢你的消息; int max_len=sizeof(buffer)-(有效负载-buffer); 国际tmp_港; in_addr_t tmp_ip; 结构乙醚添加tmp乙醚

        msg_len = parse_and_send (ctx, payload, size, max_len);
        if (msg_len < 0)
        {
           /* Error */
           error_print (ctx, "Failed to parse and construct answer.");
       continue;
        }
        if (msg_len == 0)
        {
           /* No message to send. */
           continue;
        }

        /* Switch sources & destinations and update payload lengths. */
        tmp_port = udp_hdr->dest;
        udp_hdr->dest = udp_hdr->source;
        udp_hdr->source = tmp_port;
        udp_hdr->len = htons (msg_len +
                              (payload - (const uint8_t*) udp_hdr));
        tmp_ip = ip_hdr->daddr;
        compute_udp_cksum (udp_hdr);

        ip_hdr->daddr = ip_hdr->saddr;
    ip_hdr->saddr = tmp_ip;
        ip_hdr->tot_len = htons (msg_len +
                                 (payload - (const uint8_t*) ip_hdr));
        compute_ip_cksum (ip_hdr);

        memcpy (tmp_ether.ether_addr_octet, ether_hdr->ether_dhost,
                sizeof (tmp_ether));
        memcpy (ether_hdr->ether_dhost, ether_hdr->ether_shost, ETH_ALEN);
        memcpy (ether_hdr->ether_shost, tmp_ether.ether_addr_octet,
                sizeof (tmp_ether));

        if (sendto (ctx->raw_socket,
                    &buffer, msg_len + (payload - buffer), 0,
                    (struct sockaddr*) &ll_addr, sizeof (ll_addr)) < 0)
        {
           ERROR_SYSTEM (ctx, "Sending packet");
           error_print (ctx, "Failed to send packet");
       continue;
        }
     }
msg_len=parse_和发送(ctx、有效负载、大小、最大长度);
如果(消息长度<0)
{
/*错误*/
错误_print(ctx,“解析和构造答案失败”);
持续
}
如果(msg_len==0)
{
/*没有要发送的消息*/
持续
}
/*切换源和目的地并更新有效负载长度*/
tmp_端口=udp_hdr->dest;
udp_hdr->dest=udp_hdr->source;
udp_hdr->source=tmp_端口;
udp_hdr->len=htons(msg_len+
(有效负载-(常量uint8_t*)udp_hdr));
tmp_ip=ip_hdr->daddr;
计算udp校验和(udp hdr);
ip_hdr->daddr=ip_hdr->SADD;
ip_hdr->SADD=tmp_ip;
ip\U hdr->tot\U len=htons(msg\U len+
(有效载荷-(const uint8_t*)ip_hdr);
计算ip校验和(ip hdr);
memcpy(tmp_ether.ether_addr_octet,ether_hdr->ether_dhost,
sizeof(tmp_乙醚);
memcpy(以太hdr->以太dhost,以太hdr->以太shost,以太ALEN);
memcpy(Ethernet\u hdr->Ethernet\u shost,tmp\u Ethernet.Ethernet\u addr\u八位字节,
sizeof(tmp_乙醚);
如果(发送到)(ctx->raw_插座,
&缓冲区,msg_len+(有效负载-缓冲区),0,
(结构sockaddr*)&ll_addr,大小(ll_addr))<0)
{
错误_系统(ctx,“发送数据包”);
打印错误(ctx,“发送数据包失败”);
持续
}
}

让我们写下我们知道的事实:

1-您说过可以在数据包捕获程序中看到数据包(例如Wireshark)

2-您告诉我,当您将数据包发送到服务器时,无法使用netcat接收数据包 环回接口

3-您告诉我,当您将数据包发送到远程机器时,您可以接收数据包

因此,问题要么在代码中,要么在本地计算机中。我有很多建议:

1-在另一台机器上测试代码,并将数据包发送到环回接口,并尝试使用netcat捕获它们


2-尝试使用netcat向本地接口发送一组UDP数据包,并使用另一个netcat实例接收这些数据包,并检查其是否工作;如果成功,您知道问题出在您的代码中,否则问题可能是由于您的本地计算机造成的。

如果Wireshark接收到数据包,并不意味着它们没有被丢弃;但是如果你检查一下就可以了。请确切地说明您在shell中用于接收数据包的命令。为了使其更简单,我使用了nc-l-u-p2222。在远程机器上工作正常。在本地机器(带有原始套接字)上,没有收到任何信息。您能给出用于发送数据包的代码吗?下面是代码:显然,上面是代码。无法将代码放入注释中。。。谢谢。谢谢,我知道问题出在我的代码和KVM/OpenStack的结合上。它与同一个VM并行工作,因此它不是Linux的问题。我还知道,使用相同的代码将数据包发送到另一台机器,数据包将通过。我想找到答案的唯一方法就是通过内核跟踪数据包。我对学生们的解决方案是将数据包发送到另一台机器:-)。尤瓦尔。我很抱歉花了很长时间回答,我不在。