如何从 ns3 中的 QueueDiscItem 中提取 ip 地址?

how to extract ip address from QueueDiscItem in ns3?

我是 NS3 的新手,我试图从 QueueDiscItem 中提取数据包的 IP 地址,

当我有: Ptr< QueueDiscItem > 项启动并调用:

item->Print(std::cout);

我得到的输出是
"tos 0x0 DSCP Default ECN Not-ECT ttl 63 id 265 protocol 6 offset (bytes) 0 flags [none] length: 76 10.1.4.2 > 10.1.2.1 0x7fffc67ec880 Dst addr 02-06-ff:ff:ff:ff:ff:ff proto 2048 txq"

但是当我打电话时:

Ipv4Header header;
item->GetPacket()->PeekHeader(header);
header.Print(std::cout);

我得到的输出是
"tos 0x0 DSCP Default ECN Not-ECT ttl 0 id 0 protocol 0 offset (bytes) 0 flags [none] length: 20 102.102.102.102 > 102.102.102.102"

如何获取Header数据

根据 list of TraceSources,与 QueueDiscItems 关联的 TraceSources 用于 Queues。我猜你正试图附加到其中一个 TraceSources。

A QueueDiscItem encapsulates several things: a Ptr<Packet>, a MAC address, and several more things. Since you are using IPv4, the QueueDiscItem is actually an Ipv4QueueDiscItem(后者是前者的子类)。那么,让我们开始通过

QueueDiscItem 转换为 Ipv4QueueDiscItem
Ptr<const Ipv4QueueDiscItem> ipItem = DynamicCast<const Ipv4QueueDiscItem>(item);

接下来,您需要知道在模拟的这一点上,Ipv4Header 还没有 添加到 Ptr<Packet> 中。这可能是一个设计选择(我不明白)。那么,我们怎样才能得到这些信息呢?好吧,Ipv4QueueDiscItem 封装了 Ipv4Header,并且在将 Ptr<Packet> 传递给 L2 之前的某个时刻,header 被添加到数据包中。这个 Header 可以通过

检索
const Ipv4Header ipHeader = ipItem->GetHeader();

所以,现在我们有了您感兴趣的数据包的 Ipv4Header。现在,我们可以通过

Ipv4QueueDiscItem 中安全地获取地址
ipHeader.GetSource();
ipHeader.GetDestination();

总之,您的 TraceSource 函数应如下所示:

void
EnqueueTrace (Ptr<const QueueDiscItem> item) {
    Ptr<const Ipv4QueueDiscItem> ipItem = DynamicCast<const Ipv4QueueDiscItem>(item);
    const Ipv4Header ipHeader = ipItem->GetHeader();
    NS_LOG_UNCOND("Packet received at " << Simulator::Now() << " going from " << ipHeader.GetSource() << " to " << ipHeader.GetDestination());
}

为什么 item->Print(std::cout); 有效?

以上都是有道理的,但为什么

item->Print(std::cout);

打印正确的地址?首先,重要的是要认识到这里的 Print()QueueDiscItem 的函数,而不是 Packet 的函数。如果我们转到此函数的 the source,我们会发现 Print() 如果已经添加,则只打印 Header