从Udpl4传下来之后
void
Ipv4L3Protocol::Send (Ptr<Packet> packet,
Ipv4Address source,
Ipv4Address destination,
uint8_t protocol,
Ptr<Ipv4Route> route)
{
NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
Ipv4Header ipHeader;
bool mayFragment = true; //是否可以分片
uint8_t ttl = m_defaultTtl; //设定默认TTL,或者读取PacketTag中的TTL
SocketIpTtlTag tag;
bool found = packet->RemovePacketTag (tag);
if (found)
{
ttl = tag.GetTtl ();
}
uint8_t tos = 0; //读取PacketTag中的Tos优先级
SocketIpTosTag ipTosTag;
found = packet->RemovePacketTag (ipTosTag);
if (found)
{
tos = ipTosTag.GetTos ();
}
// Handle a few cases:
// 1) packet is destined to limited broadcast address
// 2) packet is destined to a subnet-directed broadcast address
// 3) packet is not broadcast, and is passed in with a route entry
// 4) packet is not broadcast, and is passed in with a route entry but route->GetGateway is not set (e.g., on-demand)
// 5) packet is not broadcast, and route is NULL (e.g., a raw socket call, or ICMP)
//一般为3或者5
// 1) packet is destined to limited broadcast address or link-local multicast address
if (destination.IsBroadcast () || destination.IsLocalMulticast ())
{
NS_LOG_LOGIC ("Ipv4L3Protocol::Send case 1: limited broadcast");
ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tos, mayFragment);
uint32_t ifaceIndex = 0;
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
{
Ptr<Ipv4Interface> outInterface = *ifaceIter;
bool sendIt = false;
if (source == Ipv4Address::GetAny ())
{
sendIt = true;
}
for (uint32_t index = 0; index < outInterface->GetNAddresses (); index++)
{
if (outInterface->GetAddress (index).GetLocal () == source)
{
sendIt = true;
}
}
if (sendIt)
{
Ptr<Packet> packetCopy = packet->Copy ();
NS_ASSERT (packetCopy->GetSize () <= outInterface->GetDevice ()->GetMtu ());
m_sendOutgoingTrace (ipHeader, packetCopy, ifaceIndex);
CallTxTrace (ipHeader, packetCopy, m_node->GetObject<Ipv4> (), ifaceIndex);
outInterface->Send (packetCopy, ipHeader, destination);
}
}
return;
}
// 2) check: packet is destined to a subnet-directed broadcast address
uint32_t ifaceIndex = 0;
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.e