in simulation/src/internet/model/rip.cc [789:949]
void Rip::HandleRequests (RipHeader requestHdr, Ipv4Address senderAddress, uint16_t senderPort, uint32_t incomingInterface, uint8_t hopLimit)
{
NS_LOG_FUNCTION (this << senderAddress << int (senderPort) << incomingInterface << int (hopLimit) << requestHdr);
std::list<RipRte> rtes = requestHdr.GetRteList ();
if (rtes.empty ())
{
return;
}
// check if it's a request for the full table from a neighbor
if (rtes.size () == 1)
{
if (rtes.begin ()->GetPrefix () == Ipv4Address::GetAny () &&
rtes.begin ()->GetSubnetMask ().GetPrefixLength () == 0 &&
rtes.begin ()->GetRouteMetric () == m_linkDown)
{
// Output whole thing. Use Split Horizon
if (m_interfaceExclusions.find (incomingInterface) == m_interfaceExclusions.end ())
{
// we use one of the sending sockets, as they're bound to the right interface
// and the local address might be used on different interfaces.
Ptr<Socket> sendingSocket;
for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
{
if (iter->second == incomingInterface)
{
sendingSocket = iter->first;
}
}
NS_ASSERT_MSG (sendingSocket, "HandleRequest - Impossible to find a socket to send the reply");
uint16_t mtu = m_ipv4->GetMtu (incomingInterface);
uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();
Ptr<Packet> p = Create<Packet> ();
SocketIpTtlTag tag;
p->RemovePacketTag (tag);
if (senderAddress == Ipv4Address(RIP_ALL_NODE))
{
tag.SetTtl (1);
}
else
{
tag.SetTtl (255);
}
p->AddPacketTag (tag);
RipHeader hdr;
hdr.SetCommand (RipHeader::RESPONSE);
for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
{
bool splitHorizoning = (rtIter->first->GetInterface () == incomingInterface);
Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
(rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
(rtIter->first->GetInterface () != incomingInterface));
if ((isGlobal || isDefaultRoute) &&
(rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID) )
{
RipRte rte;
rte.SetPrefix (rtIter->first->GetDestNetwork ());
rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
{
rte.SetRouteMetric (m_linkDown);
}
else
{
rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
}
rte.SetRouteTag (rtIter->first->GetRouteTag ());
if ((m_splitHorizonStrategy != SPLIT_HORIZON) ||
(m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning))
{
hdr.AddRte (rte);
}
}
if (hdr.GetRteNumber () == maxRte)
{
p->AddHeader (hdr);
NS_LOG_DEBUG ("SendTo: " << *p);
sendingSocket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
p->RemoveHeader (hdr);
hdr.ClearRtes ();
}
}
if (hdr.GetRteNumber () > 0)
{
p->AddHeader (hdr);
NS_LOG_DEBUG ("SendTo: " << *p);
sendingSocket->SendTo (p, 0, InetSocketAddress (senderAddress, RIP_PORT));
}
}
}
}
else
{
// note: we got the request as a single packet, so no check is necessary for MTU limit
Ptr<Packet> p = Create<Packet> ();
SocketIpTtlTag tag;
p->RemovePacketTag (tag);
if (senderAddress == Ipv4Address(RIP_ALL_NODE))
{
tag.SetTtl (1);
}
else
{
tag.SetTtl (255);
}
p->AddPacketTag (tag);
RipHeader hdr;
hdr.SetCommand (RipHeader::RESPONSE);
for (std::list<RipRte>::iterator iter = rtes.begin ();
iter != rtes.end (); iter++)
{
bool found = false;
for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
{
Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress (rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());
if ((rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL) &&
(rtIter->first->GetRouteStatus () == RipRoutingTableEntry::RIP_VALID))
{
Ipv4Address requestedAddress = iter->GetPrefix ();
requestedAddress.CombineMask (iter->GetSubnetMask ());
Ipv4Address rtAddress = rtIter->first->GetDestNetwork ();
rtAddress.CombineMask (rtIter->first->GetDestNetworkMask ());
if (requestedAddress == rtAddress)
{
iter->SetRouteMetric (rtIter->first->GetRouteMetric ());
iter->SetRouteTag (rtIter->first->GetRouteTag ());
hdr.AddRte (*iter);
found = true;
break;
}
}
}
if (!found)
{
iter->SetRouteMetric (m_linkDown);
iter->SetRouteTag (0);
hdr.AddRte (*iter);
}
}
p->AddHeader (hdr);
NS_LOG_DEBUG ("SendTo: " << *p);
m_multicastRecvSocket->SendTo (p, 0, InetSocketAddress (senderAddress, senderPort));
}
}