Source and Destination IP Addresses in Phy MonitorSnifferRx trace

108 views
Skip to first unread message

Hassam Mughal

unread,
Mar 11, 2020, 12:26:03 PM3/11/20
to ns-3-users
Greetings everyone!

I am trying to get the source and destination IP address of the packet in my Phy MonitorSnifferRx trace by using the following method;
Ipv4Address GetSourceAddress(Ptr<const Packet> p)
{
 
Ipv4Address src;
 
// To get a header from Ptr<Packet> packet first, copy the packet
 
Ptr<Packet> q = p->Copy();
 
// Use indicator to search the packet
 
PacketMetadata::ItemIterator metadataIterator = q->BeginItem();
 
PacketMetadata::Item item;
 
while (metadataIterator.HasNext())
 
{
 item
= metadataIterator.Next();
 NS_LOG_FUNCTION
("item name: " << item.tid.GetName());
 
// If we want to have a dsdv header
 
if(item.tid.GetName() == "ns3::ArpHeader")
 
{
 
Callback<ObjectBase *> constr = item.tid.GetConstructor();
 NS_ASSERT
(!constr.IsNull());
 
// Ptr<> and DynamicCast<> won't work here as all headers are from ObjectBase, not Object
 
ObjectBase *instance = constr();
 NS_ASSERT
(instance != 0);
 
ArpHeader* arpHeader = dynamic_cast<ArpHeader*>(instance);
 NS_ASSERT
(arpHeader != 0);
 arpHeader
->Deserialize(item.current);
 src
= arpHeader->GetSourceIpv4Address();
 
}
 
}
 
return src;
}

Ipv4Address GetDestAddress(Ptr<const Packet> p)
{
 
Ipv4Address dest;
 
// To get a header from Ptr<Packet> packet first, copy the packet
 
Ptr<Packet> q = p->Copy();
 
// Use indicator to search the packet
 
PacketMetadata::ItemIterator metadataIterator = q->BeginItem();
 
PacketMetadata::Item item;
 
while (metadataIterator.HasNext())
 
{
 item
= metadataIterator.Next();
 NS_LOG_FUNCTION
("item name: " << item.tid.GetName());
 
// If we want to have a dsdv header
 
if(item.tid.GetName() == "ns3::ArpHeader")
 
{
 
Callback<ObjectBase *> constr = item.tid.GetConstructor();
 NS_ASSERT
(!constr.IsNull());
 
// Ptr<> and DynamicCast<> won't work here as all headers are from ObjectBase, not Object
 
ObjectBase *instance = constr();
 NS_ASSERT
(instance != 0);
 
ArpHeader* arpHeader = dynamic_cast<ArpHeader*>(instance);
 NS_ASSERT
(arpHeader != 0);
 arpHeader
->Deserialize(item.current);
 dest
= arpHeader->GetDestinationIpv4Address();
 
}
 
}
 
return dest;
}
And in this trace method I am calling them.
void
Rx (std::string context, Ptr <const Packet> packet, uint16_t channelFreqMhz,  WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise){
       
//context will include info about the source of this event. Use string manipulation if you want to extract info.
       
//std::cout << BOLD_CODE <<  context << END_CODE << std::endl;
       
//Print the info.
       
Packet::EnablePrinting();
               
Packet::EnableChecking();
        packet
->Print(std::cout << "\nTime: " << Simulator::Now().GetSeconds() << "s, Packet Details are: ");
       
Ipv4Address src_ip = GetSourceAddress(packet);
       
Ipv4Address des_ip = GetDestAddress(packet);    if(packet->GetSize() >= 500){
                counterAppRX
++;
       
} else {
                counterRX
++;
       
}
       
//Packet Received from: " << src_ip << ", Destination address in Packet: " << des_ip<< ",       NS_LOG_DEBUG(" Packet Received from: " << src_ip << ", Destination address in Packet: " << des_ip<< ", Size = " << packet->GetSize()
                         
<< " Freq = "<<channelFreqMhz
                         
<< " Mode = " << txVector.GetMode()
                         
<< " ReceptionDataRate = " << txVector.GetMode().GetDataRate(txVector)
                         
<< " RX Counter: " << counterRX << "\t RX APP Counter: " << counterAppRX);
        m_rxDataRate
= txVector.GetMode().GetDataRate(txVector)/1000000;        //We can also examine the WifiMacHeader
       
WifiMacHeader hdr;
       
if (packet->PeekHeader(hdr))
       
{
                NS_LOG_DEBUG
("\tDestination MAC : " << hdr.GetAddr1() << "\tSource MAC : " << hdr.GetAddr2());
       
}
}


However, I am receiving the following error in my log file as attached.
assert failed. cond="uid <= m_information.size () && uid != 0", file=../src/core/model/type-id.cc, line=458

Any guidance or help in this regard will be highly appreciated. 
Thanks 
 
log.out

Adil Alsuhaim

unread,
Mar 28, 2020, 11:32:12 AM3/28/20
to ns-3-users
MonitorSnifferRx will captures all types of packets, including data, ARP, and management frames. Some of those are not IP packet, and will not have an IP address. 

If you want to extract it from an IP packet, then check the Ipv4Header as follows:
Ipv4Header ip_head;
if(p->PeekHeader(ip_head)) //succeeds if packet have Ipv4Header
{
   
Ipv4Address source = ip_head.GetSource();
    Ipv4Address dest = ip_head.GetDestination ();
}

If you want to get the IP address contained in ARP packets, then you need to make sure that it is an ARP packet before you perform the perform the dynamic cast. This will definitely give you a run-time error, since the device will receive packets that does not have an ARP header. 

You do this by checking that the EtherType value. If the value is 0x0806, it's an ARP packet. If it's 0x0800, then it's an IPv4 packet. I think IPv6 is 0x86DD

The EtherType is stored in the LLC Snap Header

LlcSnapHeader llc;
if (p->PeekHeader (llc)) // succeeds if packet has the header
{
   
if (llc.GetType() == 0x0806)
   
{

       
//this is an ARP packet, you can try to peek ArpHeader, or do what you need to do
   
}
   
else if (llc.GetType() == 0x0800)
   
{
       
//This is an IPv4 packet
   
}
}




a

Hassam Mughal

unread,
May 9, 2020, 4:35:10 AM5/9/20
to ns-3-users
Dear Dr. Adil,

A bundle of thanks for your detailed response related to this post of mine.

Adil Alsuhaim

unread,
May 22, 2020, 8:46:08 PM5/22/20
to ns-3-users
I need to make a correction to this for anyone browsing this as an old thread. The function PeekHeader only works by examining the first header in a packet, so the way I suggested earlier here may not work as it is. You may need to remove the header, and perform another PeekHeader in get to the inner headers in the packet. 

Here's how it should look like (this code is from my head, I didn't test it)

Ptr<Packet> p = packet->Copy(); //Because MonitorSnifferRx gets a const Packet

//Examine if it is a WifiMacHeader
WifiMacHeader wifi_mac;
if (p->PeekHeader (wifi_mac))
{
   
//Remove that header and go to the next header
    p
->RemoveHeader (wifi_mac);
   
if (wifi_mac.IsMgt ()) // Is this a management Wi-Fi frame? Then ignore it.  
   
{
       
//do nothing
   
}
   
else
   
{
       
LlcSnapHeader snap;
       
if (p->PeekHeader (snap)
       
{
          p
->RemoveHeader (snap);
          uint16_t type
= snap.GetType();
         
if (type == 0x0800) // if ether type is IPv4
         
{
             
Ipv4Header ipv4_hdr;
             
if (p->PeekHeader (ipv4_hdr))
             
{
                  p
->RemoveHeader (ipv4_hdr);
                 
//You can examine the source & destination IP addresses.
                 
UdpHeader udp;
                 
if (p->PeekHeader (udp))
                 
{
                      uint16_t source_port
= udp.GetSourcePort();
                     
//....
                 
}
             
}
         
}
       
}
   
}

}



Edivaldo

unread,
May 23, 2020, 7:10:11 PM5/23/20
to ns-3-users
Great Adil,

Como sempre, muito atencioso e nos ajudando na luta pelo aprendizado com esta poderosa ferramenta de simulação.

Excelente! Muito obrigado.
Que Saúde e Paz o acompanhem.

Edivaldo
Reply all
Reply to author
Forward
0 new messages