我需要知道我的 Rx 收到的数据包是否是 ARP,以便为我的进程丢弃它们。
我查看了 ns3 的手册和教程,但我在它们中都没有发现任何关于哪个协议位于数据包内的信息。
ns3 中是否有任何功能或部分可以让我知道数据包中的协议?还是需要我查找标头的十六进制代码并将其与 ARP 代码进行比较?这应该是非常低效的的,因为我必须对我在模拟中收到的每个数据包都这样做。(而且由于我还没有完成,我不确定这是正确的方法,也不可能)。
谢谢阅读
GetUid() 不相关;它只是与所承载的协议无关的数据包数据结构的内部 ID。
在 ns-3 中,数据包按网络字节顺序序列化为 Buffer 对象,类似于 Linux 内核的 skbuff。检查数据包内容的一种强力方法是将数据包内容反序列化(复制)到一个单独的缓冲区中,并挑选字节,正如您所提到的。但是,还有更好的方法。
如果您在 Wifi 层,并且想了解您拥有的数据包是否是 ARP 数据包,您可以通过两种主要方式来了解这一点。首先,您可以检查数据包的标头。如果您位于堆栈中仅由 WifiNetDevice 添加 LlcSnapHeader 的位置,您可以尝试查看标头并查看协议号(存储在 Type 字段中)。给定一个 Ptr pkt,您可以尝试:
LlcSnapHeader llc;
pkt->PeekHeader (llc);
if (llc.GetType () == 0x0806)
{
// found an ARP packet
}
但是,请注意,如果您在堆栈中使用各种帧类型的位置,则并非所有数据包都具有 LlcSnapHeader,因此上述偷看可能不可靠,或者您可能需要检查其他可能性。此外,如果您不够幸运,您关心的标头位于数据包的最前面,请记住复制数据包并从数据包副本中删除标头并不昂贵(基本上将它们从数据包中弹出) stack) 以获取所需的标题。
如果您在模拟中启用了数据包元数据,则可以使用第二种技术。这是一个数据结构,包含有关已添加的所有标头和尾标的元数据,并且可以作为可以扫描标头信息的链表返回给客户端。默认情况下,出于性能原因,它在模拟中被禁用,但可以通过在 main() 程序的开头调用它来启用:
Packet::EnablePrinting ();
然后使用 Packet 类的 BeginItem() 迭代器(参见 ns-3 Doxygen)。据我所知,没有很好的示例程序使用它,但是 src/network/test 中存在一个可以提供提示的测试套件。
我只是使用数据包大小来过滤 ARP 数据包。我认为if (packet->GetSize () != 58)
在回调中使用 if 条件是最简单的解决方案。