in simulation/src/dsr/model/dsr-options.cc [1195:1402]
uint8_t DsrOptionSR::Process (Ptr<Packet> packet, Ptr<Packet> dsrP, Ipv4Address ipv4Address, Ipv4Address source, Ipv4Header const& ipv4Header, uint8_t protocol, bool& isPromisc, Ipv4Address promiscSource)
{
NS_LOG_FUNCTION (this << packet << dsrP << ipv4Address << source << ipv4Address << ipv4Header << (uint32_t)protocol << isPromisc);
Ptr<Packet> p = packet->Copy ();
// Get the number of routers' address field
uint8_t buf[2];
p->CopyData (buf, sizeof(buf));
uint8_t numberAddress = (buf[1] - 2) / 4;
DsrOptionSRHeader sourceRoute;
sourceRoute.SetNumberAddress (numberAddress);
p->RemoveHeader (sourceRoute);
// The route size saved in the source route
std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
uint8_t segsLeft = sourceRoute.GetSegmentsLeft ();
uint8_t salvage = sourceRoute.GetSalvage ();
/*
* Get the node from IP address and get the DSR extension object
*/
Ptr<Node> node = GetNodeWithAddress (ipv4Address);
Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
/*
* Get the source and destination address from ipv4 header
*/
Ipv4Address srcAddress = ipv4Header.GetSource ();
Ipv4Address destAddress = ipv4Header.GetDestination ();
// Get the node list destination
Ipv4Address destination = nodeList.back ();
/*
* If it's a promiscuous receive data packet,
* 1. see if automatic route shortening possible or not
* 2. see if it is a passive acknowledgment
*/
if (isPromisc)
{
NS_LOG_LOGIC ("We process promiscuous receipt data packet");
if (ContainAddressAfter (ipv4Address, destAddress, nodeList))
{
NS_LOG_LOGIC ("Send back the gratuitous reply");
dsr->SendGratuitousReply (source, srcAddress, nodeList, protocol);
}
uint16_t fragmentOffset = ipv4Header.GetFragmentOffset ();
uint16_t identification = ipv4Header.GetIdentification ();
if (destAddress != destination)
{
NS_LOG_DEBUG ("Process the promiscuously received packet");
bool findPassive = false;
int32_t nNodes = NodeList::GetNNodes ();
for (int32_t i = 0; i < nNodes; ++i)
{
NS_LOG_DEBUG ("Working with node " << i);
Ptr<Node> node = NodeList::GetNode (i);
Ptr<dsr::DsrRouting> dsrNode = node->GetObject<dsr::DsrRouting> ();
// The source and destination addresses here are the real source and destination for the packet
findPassive = dsrNode->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, false);
if (findPassive)
{
break;
}
}
if (findPassive)
{
NS_LOG_DEBUG ("We find one previously received passive entry");
/*
* Get the node from IP address and get the DSR extension object
* the srcAddress would be the source address from ip header
*/
PrintVector (nodeList);
NS_LOG_DEBUG ("promisc source " << promiscSource);
Ptr<Node> node = GetNodeWithAddress (promiscSource);
Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting> ();
dsrSrc->CancelPassiveTimer (packet, source, destination, segsLeft);
}
else
{
NS_LOG_DEBUG ("Saved the entry for further use");
dsr->PassiveEntryCheck (packet, source, destination, segsLeft, fragmentOffset, identification, true);
}
}
/// Safely terminate promiscuously received packet
return 0;
}
else
{
/*
* Get the number of address from the source route header
*/
uint8_t length = sourceRoute.GetLength ();
uint8_t nextAddressIndex;
Ipv4Address nextAddress;
// Get the option type value
uint32_t size = p->GetSize ();
uint8_t *data = new uint8_t[size];
p->CopyData (data, size);
uint8_t optionType = 0;
optionType = *(data);
/// When the option type is 160, means there is ACK request header after the source route, we need
/// to send back acknowledgment
if (optionType == 160)
{
NS_LOG_LOGIC ("Remove the ack request header and add ack header to the packet");
// Here we remove the ack packet to the previous hop
DsrOptionAckReqHeader ackReq;
p->RemoveHeader (ackReq);
uint16_t ackId = ackReq.GetAckId ();
/*
* Send back acknowledgment packet to the earlier hop
* If the node list is not empty, find the previous hop from the node list,
* otherwise, use srcAddress
*/
Ipv4Address ackAddress = srcAddress;
if (!nodeList.empty ())
{
if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total number of ip addresses
{
NS_LOG_LOGIC ("Malformed header. Drop!");
m_dropTrace (packet);
return 0;
}
// -fstrict-overflow sensitive, see bug 1868
if (numberAddress - segsLeft < 2) // The index is invalid
{
NS_LOG_LOGIC ("Malformed header. Drop!");
m_dropTrace (packet);
return 0;
}
ackAddress = nodeList[numberAddress - segsLeft - 2];
}
m_ipv4Route = SetRoute (ackAddress, ipv4Address);
NS_LOG_DEBUG ("Send back ACK to the earlier hop " << ackAddress << " from us " << ipv4Address);
dsr->SendAck (ackId, ackAddress, source, destination, protocol, m_ipv4Route);
}
/*
* After send back ACK, check if the segments left value has turned to 0 or not, if yes, update the route entry
* and return header length
*/
if (segsLeft == 0)
{
NS_LOG_DEBUG ("This is the final destination");
isPromisc = false;
return sourceRoute.GetSerializedSize ();
}
if (length % 2 != 0)
{
NS_LOG_LOGIC ("Malformed header. Drop!");
m_dropTrace (packet);
return 0;
}
if (segsLeft > numberAddress) // The segmentsLeft field should not be larger than the total number of ip addresses
{
NS_LOG_LOGIC ("Malformed header. Drop!");
m_dropTrace (packet);
return 0;
}
DsrOptionSRHeader newSourceRoute;
newSourceRoute.SetSegmentsLeft (segsLeft - 1);
newSourceRoute.SetSalvage (salvage);
newSourceRoute.SetNodesAddress (nodeList);
nextAddressIndex = numberAddress - segsLeft;
nextAddress = newSourceRoute.GetNodeAddress (nextAddressIndex);
NS_LOG_DEBUG ("The next address of source route option " << nextAddress << " and the nextAddressIndex: " << (uint32_t)nextAddressIndex << " and the segments left : " << (uint32_t)segsLeft);
/*
* Get the target Address in the node list
*/
Ipv4Address targetAddress = nodeList.back ();
Ipv4Address realSource = nodeList.front ();
/*
* Search the vector for next hop address
*/
Ipv4Address nextHop = SearchNextHop (ipv4Address, nodeList);
PrintVector (nodeList);
if (nextHop == "0.0.0.0")
{
NS_LOG_DEBUG ("Before new packet " << *dsrP);
dsr->PacketNewRoute (dsrP, realSource, targetAddress, protocol);
return 0;
}
if (ipv4Address == nextHop)
{
NS_LOG_DEBUG ("We have reached the destination");
newSourceRoute.SetSegmentsLeft (0);
return newSourceRoute.GetSerializedSize ();
}
// Verify the multicast address, leave it here for now
if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
{
m_dropTrace (packet);
return 0;
}
// Set the route and forward the data packet
SetRoute (nextAddress, ipv4Address);
NS_LOG_DEBUG ("dsr packet size " << dsrP->GetSize ());
dsr->ForwardPacket (dsrP, newSourceRoute, ipv4Header, realSource, nextAddress, targetAddress, protocol, m_ipv4Route);
}
return sourceRoute.GetSerializedSize ();
}