linux获取链路层数据,Linux原始数据链路层套接字仅返回部分数据包(96字节)(Linux raw datalink layer socket only returns partial pack...

Linux原始数据链路层套接字仅返回部分数据包(96字节)(Linux raw datalink layer socket only returns partial packet (96 bytes))

在我的应用程序中,我使用原始套接字(type PF_PACKET, SOCK_RAW)在数据链路层接收数据包。 我发现的是我只得到任何数据包的前96个字节。 我假设有一些选项阻止我收到整个数据包,但是什么? 这是从我的代码剪切:

int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

int nBytesRead = read(sock, (char *) buf, 1500);

int nFlags = fcntl(m_sock, F_GETFL, 0); // make it non-blocking

fcntl(sock, F_SETFL, nFlags | O_NONBLOCK);

In my application, I am receiving packets at the data link layer using a raw socket (type PF_PACKET, SOCK_RAW). What I am finding is that I only get the first 96 bytes of any packet. I'm assuming there is some option somewhere that is preventing me from receiving the entire packet, but what? Here is a snipped from my code:

int sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

int nBytesRead = read(sock, (char *) buf, 1500);

int nFlags = fcntl(m_sock, F_GETFL, 0); // make it non-blocking

fcntl(sock, F_SETFL, nFlags | O_NONBLOCK);

nBytesRead is never more than 96, even though my network sniffer shows longer packets. This is uClinux if that makes a difference. I found someone else with the same problem at http://www.network-builders.com/raw-socket-captures-only-first-96-bytes-packet-t57283.html but no answers there.

原文:https://stackoverflow.com/questions/17958703

更新时间:2019-12-25 07:50

最满意答案

解决了! 我在原帖中没有提到的是我在原始套接字上附加了一个过滤器,因此它只接收某些TCP / IP端口上的流量。 此过滤器代码是使用TCPDUMP创建的,默认情况下将捕获限制为96字节。 我必须在我的TCPDUMP命令行中添加-s0选项,告诉它捕获所有内容: tcpdump -dd -s0 "ip and tcp and dst port 60001" 。

有了这个改变,它现在给了我完整的数据包。 感谢这篇博客文章的线索。 希望这有助于将来的其他人。

Solved it! What I failed to mention in my original post was that I was attaching a filter to the raw socket so it would only receive traffic on certain TCP/IP ports. This filter code was created with TCPDUMP, which apprently limits capture to 96 bytes by default. I had to add the -s0 option to my TCPDUMP command line to tell it to capture everything: tcpdump -dd -s0 "ip and tcp and dst port 60001".

With that change, it now gives me the full packet. Thanks to this blog post for the clue. Hope this helps someone else in the future.

2013-07-31

相关问答

您正在接收数据包并将其存储在buffer ,但是您正在从ip和tcp打印数据而不解析该缓冲区。 您应该在收到 buffer 后 , 在打印之前解析数据包。 你的代码假设所有的数据包都是TCP,事实并非如此。 RAW插座仅支持第3层协议(IP,ICMP等)。 换句话说,在创建RAW套接字时使用IPPROTO_TCP会造成误导。 坚持IPPROTO_IP ,并为您关心的每个协议(TCP,UDP等)添加必要的条件。 由于Linux内核验证协议编号,并且回IPPROTO_IP ,所以这恰好工作。 但是,这

...

假设关心的是将所有数据包放在RAM中,则可以使用yield创建一个IEnumerable,其中不包含RAM中的所有内容。 这种方式作为Dumper转储数据包,它会调用您的方法来使用yield来填充下一个项目。 Well, despite this is not an answer but a workaround, and since nobody wrote a better solution this is how a fixed it: Use SharPcap instead of Pca

...

提示是所有目标Mac地址都以0x45 。 这是IP头的第一个字节。 因此,您的代码将获取所有IP数据包,但不会获取这些帧的MAC头。 The hint is that all your Destination Mac addresses start with 0x45. That's the first byte of the IP header. So your code is getting all the IP packets, but not the MAC header for thos

...

LuaSocket不是为此而制作的。 也许看看libpcap和libnet ? LuaSocket is not made for this. Maybe look at libpcap and libnet?

解决了! 我在原帖中没有提到的是我在原始套接字上附加了一个过滤器,因此它只接收某些TCP / IP端口上的流量。 此过滤器代码是使用TCPDUMP创建的,默认情况下将捕获限制为96字节。 我必须在我的TCPDUMP命令行中添加-s0选项,告诉它捕获所有内容: tcpdump -dd -s0 "ip and tcp and dst port 60001" 。 有了这个改变,它现在给了我完整的数据包。 感谢这篇博客文章的线索。 希望这有助于将来的其他人。 Solved it! What I faile

...

那么,如果你使用UDP,你并不真的发送RAW。 RAW根本不是IP,在这种情况下,你必须自己处理碎片。 使用UDP,您可以获得IP的分段支持,这对于短距离网络来说足够好,因为在这种网络中碰撞应该很小。 使两个系统之间的链接成为专用子网,这根本不是问题。 什么TCP通过UDP购买你(除其他之外)是堆栈能够重新发送一个片段,如果它以某种方式丢失或损坏。 如果发生UDP,则必须丢弃整个消息。 尽管如此,对于大多数现代化的网络来说,您可能还会忍受这种折衷。 Well, if you are using U

...

你最后的两个论点是错误的, rbytes = recvfrom (Rsock , buffer , 65536 , 0 , &saddr ,(socklen_t *)sizeof saddr);

不要转换最后一个参数,你需要在实际指针中过去。 您还需要传入指向特定sockaddr类型的指针,而不是指向struct sockaddr的指针以及您可能需要转换的参数。 struct sockaddr_storage saddr; //Or sockaddr_in if you are certain

...

你可以使用: ctypes是标准库的一部分,或 Construct旨在支持网络协议, bitarray不是, bitstring不是那么好。 这是一个例子: from ctypes import c_int32, c_uint32, Structure, Union

class _bits(Structure):

_fields_ = [

("odd", c_uint32, 1),

("half", c_uint32, 31),

]

class

...

你的字符串切片语句中有一个额外的[0] : ethernetHeader=receivedPacket[0][0:14]

应该只是 ethernetHeader=receivedPacket[0:14]

错误告诉你struct.unpack需要一个长度为14的字符串。如果你打印传递给它的字符串,你可能会看到它只有length = 1.这是一个例子: >>> s = 'this is a test'

>>> s[0]

't'

>>> s[0][0:4]

't'

>>> s[0:4]

'this'

...

对不起,这是我的错。 这段代码是我的旧代码,包含大量文件。 最近我有一些空闲时间,并决定做一些TODO任务。 由于我将套接字更改为RAW,因此写入次数增加(data_length + udp_header + ip_header),但在其他地方(另一个文件)中存在另一个代码安静,其中包含以下内容: if(number_of_written != data_length) {

repeat_socket_process();

}

有了这段代码,我实际上是DOS(拒绝服务攻击)我自己的路由

...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值