PeekHeader giving wrong values

279 views
Skip to first unread message

Boong Baang

unread,
Jun 3, 2020, 2:26:14 AM6/3/20
to ns-3-users
I create packets and append a custom header to it before sending. When the packet is about to dequeue from the queue, I create a copy of the packet and do a PeekHeader on the copy. And this is giving me wrong values. The values are correct while sending and receiving.

Either packet copying is where the mistake is, or my sequence of reading information from the header is wrong. But I use the same process to read packet header data at receiver, and it works.

So I have a few questions:

  1. Does creating packet copies copy the header associated with the packet ?
  2. PeekHeader vs RemoveHeader : PeekHeader doesn't tamper with the header, right ?
  3. If I have two headers, how do I read the seconds header without removing the first header ? I do PeekHeader and it doesn't generate errors, but the values are wrong and it typically happens when headers are read in the wrong way.
This is my code at Dequeue: I use the same logic (without the copy and `RemoveHeader` instead of `PeekHeader`) while receiving the packet at the receiver, and it works. It gives problems when used like this

  void BsmApplication::DequeueTrace(std::string context, Ptr<const  WifiMacQueueItem> item)
 
{
   
// BIPLAV starts
   
// BIPLAV receiving starts
   
Time rcv;
   
Time sqhd;
   
Time total_delay;
   
Ptr< Packet> packet = (item->GetPacket())->Copy();
   
SeqTsHeader seqTsx;
    rcv
= (Simulator::Now()); // time of reception
    packet
->PeekHeader(seqTsx);
    sqhd
= (seqTsx.GetTs()); //time stamp of when packet generated
   
// std::cerr<<"rcv = "<<rcv<<", sqhd = "<<sqhd<<std::endl;
    total_delay
= (rcv - sqhd); //total delay calculation
    loc_header new_header
;
    packet
->PeekHeader(new_header);
   
Vector old_position = new_header.GetLocation();
   
Vector old_velocity = new_header.GetSpeed();
   
// std::cout<<"the speeds are: "<<old_velocity<<std::endl;
    uint32_t
SenderId = new_header.GetSenderId();


    std
::cerr<<"Inside DequeTrace for node at T="<<rcv.GetSeconds()<<" for node "<<SenderId<<" from ("<<old_position<<") with vel ("<<old_velocity<<")"<<std::endl;
    std
::cerr<<"tx_attempt was "<<tx_attempts[SenderId];
    tx_attempts
[SenderId] = tx_attempts[SenderId] + 1;
    std
::cerr<<" and it became "<< tx_attempts[SenderId]<<std::endl;


 
}

The above trace `DequeueTrace` is connected in this way 
  std::string dequeue_path= "/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/*/$ns3::OcbWifiMac/*/Queue/Dequeue";
 
Config::Connect (dequeue_path, MakeCallback (&BsmApplication::DequeueTrace));



This is how I set the header when sending the packet to the queue:
new_header.SetSenderId(socket->GetNode()->GetId());



Tom Henderson

unread,
Jun 3, 2020, 9:14:00 AM6/3/20
to ns-3-...@googlegroups.com, Boong Baang
On 6/2/20 11:26 PM, Boong Baang wrote:
> I create packets and append a custom header to it before sending. When
> the packet is about to dequeue from the queue, I create a copy of the
> packet and do a PeekHeader on the copy. And this is giving me wrong
> values. The values are correct while sending and receiving.

My initial guess is that in the middle of the network, you are peeking a
packet that has different headers than the one at the endpoints.

Can you check first whether the packet size (GetSize ()) is the same at
both points?

>
> Either packet copying is where the mistake is, or my sequence of reading
> information from the header is wrong. But I use the same process to read
> packet header data at receiver, and it works.
>
> So I have a few questions:
>
> 1. Does creating packet copies copy the header associated with the packet ?

Yes, as needed.

> 2. PeekHeader vs RemoveHeader : PeekHeader doesn't tamper with the
> header, right ?

Right. Both PeekHeader and RemoveHeader copy the header bits into the
Header object that you have passed in.

> 3. If I have two headers, how do I read the seconds header without
> removing the first header ? I do PeekHeader and it doesn't generate
> errors, but the values are wrong and it typically happens when
> headers are read in the wrong way.

You can't peek more than the head-of-line header; if you need to look
further, you will usually need remove the first header and later add it
back.

- Tom

Boong Baang

unread,
Jun 3, 2020, 10:38:09 AM6/3/20
to ns-3-users


My initial guess is that in the middle of the network, you are peeking a
packet that has different headers than the one at the endpoints. 
Can you check first whether the packet size (GetSize ()) is the same at
both points?

All the packets are of the same size as I fix the BSM's sizes at the beginning. Also the values of the header info are drastically different, which normally happened with me when I used to deserialize the header incorrectly. E.g.
Sender is 36 and packet is generated from 866.434, 392, 0, -> this is the info that is written when generating the packet, and the info that I get from the packet about to be dequeued is 
Inside DequeTrace for node at T=373 for node 391999 from (1.07486e+06:7.20858e+14:2.55583e+15)As you see, both node and location coordinates are very different, so I do not think it to be a packet mismatch issue.
 

>
> Either packet copying is where the mistake is, or my sequence of reading
> information from the header is wrong. But I use the same process to read
> packet header data at receiver, and it works.
>
> So I have a few questions:
>
>  1. Does creating packet copies copy the header associated with the packet ?

Yes, as needed.

>  2. PeekHeader vs RemoveHeader : PeekHeader doesn't tamper with the
>     header, right ?

Right.  Both PeekHeader and RemoveHeader copy the header bits into the
Header object that you have passed in.

>  3. If I have two headers, how do I read the seconds header without
>     removing the first header ? I do PeekHeader and it doesn't generate
>     errors, but the values are wrong and it typically happens when
>     headers are read in the wrong way.

You can't peek more than the head-of-line header; if you need to look
further, you will usually need remove the first header and later add it
back.
 
I used RemoveHeader() instead of PeekHeader() on the packet to remove the two headers, as I need to read from the seconds header. But still get the wrong values as I showed above.

One other issue that might be causing this is that I define the DequeueTrace() function in bsm-application.cc as a public function, and call it from the vanet-routing-compare.cc. I also set the trace path from vanet-routing-compare.cc. Could this be an issue due to the scope of the variables, like the packet information being local to  bsm-application.cc as I generate and receive the packets there. 

Also is there any particular order I need to follow for deserializing the data ? I do it in the same way at the receiver, but that is correct. 

My new function is: 

  void BsmApplication::DequeueTrace(std::string context, Ptr<const  WifiMacQueueItem> item) 
  {
    // BIPLAV starts
    // BIPLAV receiving starts
    Time rcv;
    Time sqhd;
    Time total_delay;
    Ptr< Packet> packet = (item->GetPacket())->Copy();
    SeqTsHeader seqTsx; 
    rcv = (Simulator::Now()); // time of reception
    packet->RemoveHeader(seqTsx);

    sqhd = (seqTsx.GetTs()); //time stamp of when packet generated
    // std::cerr<<"rcv = "<<rcv<<", sqhd = "<<sqhd<<std::endl;
    total_delay = (rcv - sqhd); //total delay calculation
    loc_header new_header;
    packet->RemoveHeader(new_header);
    Vector old_position = new_header.GetLocation(); // giving error
    Vector old_velocity = new_header.GetSpeed(); // giving error

    // std::cout<<"the speeds are: "<<old_velocity<<std::endl;
    uint32_t SenderId = new_header.GetSenderId(); // giving error

Adil Alsuhaim

unread,
Jun 3, 2020, 11:49:46 AM6/3/20
to ns-3-users
Oops, I think I am to blame for this since I suggested you use PeekHeader without enough details. When you PeekHeader, you have to do it in order, and remove the headers that you read. 

But first of all, examine the headers of your packet with packet->ToString (), which would require you have a call to PacketMetadata::Enable () early on in your program or it would print nothing, then print the packet as follows

std::cout << packet->ToString() << std::endl;

If your loc_header was done properly, it should show up in the list of headers printed. 

To answer your questions

1. Yes. Copying the packet copies the entire packet as it was at the time of copy. I believe it also copies the packet tags as well. By the way, packet tags are easier to work with than headers, since they don't change the actual content of the packet, just adds simulation information to them. 

2. PeekHeader checks the first header in the packet, but doesn't remove it. RemoveHeader removes it. I think what you can do is PeekHeader then remove when you want to get the next header. Keep in mind that your packet at the MAC level may have extra header added to it by the lower layers such as WifiMacHeader & LlcSnapHeader so I think you can check and remove in order. Perform packet->ToString() to print out the list of headers. 

3. Copy the packet, then do whatever you want with the copy. I think the way to do it is Peek/Remove. FYI, the code for packet->Print(std::ostream) in packet.cc file loops through all packet headers to print them (the code might look complicated if you're not too familiar with C++ & ns-3)

Boong Baang

unread,
Jun 3, 2020, 12:28:49 PM6/3/20
to ns-3-users
As per Adil's suggestion, the packet::ToString() gave me the following output:

Packet->ToString() gives = ns3::LlcSnapHeader (type 0x0) ns3::Ipv4Header (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) ns3::UdpHeader (length: 65536 0 > 1) ns3::SeqTsHeader ((seq=0 time=0)) ns3::loc_Header (Packet sent by Node 0 from (0,0,0
) Payload (size=120)


I see there are a number of headers - ns3::LlcSnapHeader, ns3::Ipv4Header, ns3::UdpHeader, ns3::SeqTsHeader, ns3::loc_Header. 
So the one that I am interested in, the ns3::loc_Header, has to be accessed by using RemoveHeader() 5 times. Am I right ?

Boong Baang

unread,
Jun 3, 2020, 12:51:10 PM6/3/20
to ns-3-users
Thanks everyone, I am able to get the required values. The key is that additional headers were added after I had "sent" the packet, and they have to be removed to access the needed header.

Adil Alsuhaim

unread,
Jun 5, 2020, 8:17:58 PM6/5/20
to ns-3-users
Glad it worked out!
Reply all
Reply to author
Forward
0 new messages