I'm new to NS3 and i was trying to extract ip address of a packet from QueueDiscItem,
when i have: Ptr< QueueDiscItem > item initiated and call:
item->Print(std::cout);
the output i get is
"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"
but when i call:
Ipv4Header header;
item->GetPacket()->PeekHeader(header);
header.Print(std::cout);
the output i get is
"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
dataAccording to the list of TraceSources, the TraceSources associated with QueueDiscItems are for Queues. I'm guessing you were trying to attach to one of those 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
(the latter is a subclass of the former). So, let's start by casting the QueueDiscItem
to an Ipv4QueueDiscItem
by
Ptr<const Ipv4QueueDiscItem> ipItem = DynamicCast<const Ipv4QueueDiscItem>(item);
Next, you need to know that at this point in the simulation, the Ipv4Header
has not been added to the Ptr<Packet>
yet. This is probably a design choice (that I don't understand). So, how can we get this information? Well, the Ipv4QueueDiscItem
encapsulates the Ipv4Header
, and at some point before passing the Ptr<Packet>
to L2, the header is added to the packet. This Header
can be retrieved by
const Ipv4Header ipHeader = ipItem->GetHeader();
So, now we have the Ipv4Header
of the packet you're interested in. Now, we can safely get the address from the Ipv4QueueDiscItem
by
ipHeader.GetSource();
ipHeader.GetDestination();
In summary, your TraceSource function should look something like this:
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);
work?All of the above makes sense, but why does
item->Print(std::cout);
print the correct addresses? First, it is important to realize that here Print()
is a function of the QueueDiscItem
, not the Packet
. If we go to the source of this function, we find that Print()
just prints the Header
if it has already been added.