00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/packet.h"
00022 #include "ns3/log.h"
00023 #include "ns3/callback.h"
00024 #include "ns3/ipv4-address.h"
00025 #include "ns3/ipv4-route.h"
00026 #include "ns3/node.h"
00027 #include "ns3/socket.h"
00028 #include "ns3/net-device.h"
00029 #include "ns3/uinteger.h"
00030 #include "ns3/trace-source-accessor.h"
00031 #include "ns3/object-vector.h"
00032 #include "ns3/ipv4-header.h"
00033 #include "ns3/boolean.h"
00034 #include "arp-l3-protocol.h"
00035
00036 #include "ipv4-l3-protocol.h"
00037 #include "ipv4-l4-protocol.h"
00038 #include "icmpv4-l4-protocol.h"
00039 #include "ipv4-interface.h"
00040 #include "ipv4-loopback-interface.h"
00041 #include "arp-ipv4-interface.h"
00042 #include "ipv4-raw-socket-impl.h"
00043
00044 NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
00045
00046 namespace ns3 {
00047
00048 const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
00049
00050 NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
00051
00052 TypeId
00053 Ipv4L3Protocol::GetTypeId (void)
00054 {
00055 static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
00056 .SetParent<Object> ()
00057 .AddConstructor<Ipv4L3Protocol> ()
00058 .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
00059 UintegerValue (64),
00060 MakeUintegerAccessor (&Ipv4L3Protocol::m_defaultTtl),
00061 MakeUintegerChecker<uint8_t> ())
00062 .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
00063 " and verify the checksum of incoming packets.",
00064 BooleanValue (false),
00065 MakeBooleanAccessor (&Ipv4L3Protocol::m_calcChecksum),
00066 MakeBooleanChecker ())
00067 .AddTraceSource ("Tx", "Send ipv4 packet to outgoing interface.",
00068 MakeTraceSourceAccessor (&Ipv4L3Protocol::m_txTrace))
00069 .AddTraceSource ("Rx", "Receive ipv4 packet from incoming interface.",
00070 MakeTraceSourceAccessor (&Ipv4L3Protocol::m_rxTrace))
00071 .AddTraceSource ("Drop", "Drop ipv4 packet",
00072 MakeTraceSourceAccessor (&Ipv4L3Protocol::m_dropTrace))
00073 .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
00074 ObjectVectorValue (),
00075 MakeObjectVectorAccessor (&Ipv4L3Protocol::m_interfaces),
00076 MakeObjectVectorChecker<Ipv4Interface> ())
00077 ;
00078 return tid;
00079 }
00080
00081 Ipv4L3Protocol::Ipv4L3Protocol()
00082 : m_nInterfaces (0),
00083 m_identification (0)
00084 {
00085 NS_LOG_FUNCTION_NOARGS ();
00086 m_staticRouting = CreateObject<Ipv4StaticRouting> ();
00087 AddRoutingProtocol (m_staticRouting, 0);
00088 }
00089
00090 Ipv4L3Protocol::~Ipv4L3Protocol ()
00091 {
00092 NS_LOG_FUNCTION (this);
00093 }
00094
00095 void
00096 Ipv4L3Protocol::Insert(Ptr<Ipv4L4Protocol> protocol)
00097 {
00098 m_protocols.push_back (protocol);
00099 }
00100 Ptr<Ipv4L4Protocol>
00101 Ipv4L3Protocol::GetProtocol(int protocolNumber) const
00102 {
00103 for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
00104 {
00105 if ((*i)->GetProtocolNumber () == protocolNumber)
00106 {
00107 return *i;
00108 }
00109 }
00110 return 0;
00111 }
00112 void
00113 Ipv4L3Protocol::Remove (Ptr<Ipv4L4Protocol> protocol)
00114 {
00115 m_protocols.remove (protocol);
00116 }
00117
00118 void
00119 Ipv4L3Protocol::SetNode (Ptr<Node> node)
00120 {
00121 m_node = node;
00122 SetupLoopback ();
00123 }
00124
00125 Ptr<Socket>
00126 Ipv4L3Protocol::CreateRawSocket (void)
00127 {
00128 NS_LOG_FUNCTION (this);
00129 Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
00130 socket->SetNode (m_node);
00131 m_sockets.push_back (socket);
00132 return socket;
00133 }
00134 void
00135 Ipv4L3Protocol::DeleteRawSocket (Ptr<Socket> socket)
00136 {
00137 NS_LOG_FUNCTION (this << socket);
00138 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
00139 {
00140 if ((*i) == socket)
00141 {
00142 m_sockets.erase (i);
00143 return;
00144 }
00145 }
00146 return;
00147 }
00148
00149 void
00150 Ipv4L3Protocol::DoDispose (void)
00151 {
00152 NS_LOG_FUNCTION (this);
00153 for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
00154 {
00155 (*i)->Dispose ();
00156 *i = 0;
00157 }
00158 m_protocols.clear ();
00159
00160 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
00161 {
00162 Ptr<Ipv4Interface> interface = *i;
00163 interface->Dispose ();
00164 }
00165 m_interfaces.clear ();
00166 m_node = 0;
00167 m_staticRouting->Dispose ();
00168 m_staticRouting = 0;
00169 Object::DoDispose ();
00170 }
00171
00172 void
00173 Ipv4L3Protocol::SetupLoopback (void)
00174 {
00175 NS_LOG_FUNCTION_NOARGS ();
00176
00177 Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
00178 interface->SetNode (m_node);
00179 interface->SetAddress (Ipv4Address::GetLoopback ());
00180 interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
00181 uint32_t index = AddIpv4Interface (interface);
00182 AddHostRouteTo (Ipv4Address::GetLoopback (), index);
00183 interface->SetUp ();
00184 }
00185
00186 void
00187 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
00188 {
00189 NS_LOG_FUNCTION_NOARGS ();
00190 m_defaultTtl = ttl;
00191 }
00192
00193
00194 void
00195 Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
00196 Ipv4Address nextHop,
00197 uint32_t interface)
00198 {
00199 NS_LOG_FUNCTION (this << dest << nextHop << interface);
00200 m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
00201 }
00202
00203 void
00204 Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
00205 uint32_t interface)
00206 {
00207 NS_LOG_FUNCTION (this << dest << interface);
00208 m_staticRouting->AddHostRouteTo (dest, interface);
00209 }
00210
00211 void
00212 Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
00213 Ipv4Mask networkMask,
00214 Ipv4Address nextHop,
00215 uint32_t interface)
00216 {
00217 NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
00218 m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
00219 }
00220
00221 void
00222 Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
00223 Ipv4Mask networkMask,
00224 uint32_t interface)
00225 {
00226 NS_LOG_FUNCTION (this << network << networkMask << interface);
00227 m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
00228 }
00229
00230 void
00231 Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
00232 uint32_t interface)
00233 {
00234 NS_LOG_FUNCTION (this << nextHop << interface);
00235 m_staticRouting->SetDefaultRoute (nextHop, interface);
00236 }
00237
00238 void
00239 Ipv4L3Protocol::Lookup (
00240 Ipv4Header const &ipHeader,
00241 Ptr<Packet> packet,
00242 Ipv4RoutingProtocol::RouteReplyCallback routeReply)
00243 {
00244 NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
00245
00246 Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
00247 }
00248
00249 void
00250 Ipv4L3Protocol::Lookup (
00251 uint32_t ifIndex,
00252 Ipv4Header const &ipHeader,
00253 Ptr<Packet> packet,
00254 Ipv4RoutingProtocol::RouteReplyCallback routeReply)
00255 {
00256 NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
00257
00258 for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
00259 m_routingProtocols.begin ();
00260 rprotoIter != m_routingProtocols.end ();
00261 rprotoIter++)
00262 {
00263 NS_LOG_LOGIC ("Requesting route");
00264 if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet,
00265 routeReply))
00266 return;
00267 }
00268
00269 if (ipHeader.GetDestination ().IsMulticast () &&
00270 ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
00271 {
00272 NS_LOG_LOGIC ("Multicast destination with local source");
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
00284
00285 if (route)
00286 {
00287 NS_LOG_LOGIC ("Local source. Using unicast default route for "
00288 "multicast packet");
00289
00290 routeReply (true, *route, packet, ipHeader);
00291 return;
00292 }
00293 }
00294
00295
00296
00297 routeReply (false, Ipv4Route (), packet, ipHeader);
00298 }
00299
00300 void
00301 Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
00302 int priority)
00303 {
00304 NS_LOG_FUNCTION (this << &routingProtocol << priority);
00305 m_routingProtocols.push_back
00306 (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
00307 m_routingProtocols.sort ();
00308 }
00309
00310 uint32_t
00311 Ipv4L3Protocol::GetNRoutes (void)
00312 {
00313 NS_LOG_FUNCTION_NOARGS ();
00314 return m_staticRouting->GetNRoutes ();
00315 }
00316
00317 Ipv4Route *
00318 Ipv4L3Protocol::GetRoute (uint32_t index)
00319 {
00320 NS_LOG_FUNCTION_NOARGS ();
00321 return m_staticRouting->GetRoute (index);
00322 }
00323
00324 void
00325 Ipv4L3Protocol::RemoveRoute (uint32_t index)
00326 {
00327 NS_LOG_FUNCTION (this << index);
00328 m_staticRouting->RemoveRoute (index);
00329 }
00330
00331 void
00332 Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin,
00333 Ipv4Address group,
00334 uint32_t inputInterface,
00335 std::vector<uint32_t> outputInterfaces)
00336 {
00337 NS_LOG_FUNCTION (this << origin << group << inputInterface << &outputInterfaces);
00338
00339 m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
00340 outputInterfaces);
00341 }
00342
00343 void
00344 Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
00345 {
00346 NS_LOG_FUNCTION (this << outputInterface);
00347
00348 m_staticRouting->SetDefaultMulticastRoute (outputInterface);
00349 }
00350
00351 uint32_t
00352 Ipv4L3Protocol::GetNMulticastRoutes (void) const
00353 {
00354 NS_LOG_FUNCTION_NOARGS ();
00355 return m_staticRouting->GetNMulticastRoutes ();
00356 }
00357
00358 Ipv4MulticastRoute *
00359 Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
00360 {
00361 NS_LOG_FUNCTION (this << index);
00362 return m_staticRouting->GetMulticastRoute (index);
00363 }
00364
00365 void
00366 Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin,
00367 Ipv4Address group,
00368 uint32_t inputInterface)
00369 {
00370 NS_LOG_FUNCTION (this << origin << group << inputInterface);
00371 m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
00372 }
00373
00374 void
00375 Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
00376 {
00377 NS_LOG_FUNCTION (this << index);
00378 m_staticRouting->RemoveMulticastRoute (index);
00379 }
00380
00381 uint32_t
00382 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
00383 {
00384 NS_LOG_FUNCTION (this << &device);
00385
00386 Ptr<Node> node = GetObject<Node> ();
00387 node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this),
00388 Ipv4L3Protocol::PROT_NUMBER, device);
00389 node->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
00390 ArpL3Protocol::PROT_NUMBER, device);
00391
00392 Ptr<ArpIpv4Interface> interface = CreateObject<ArpIpv4Interface> ();
00393 interface->SetNode (m_node);
00394 interface->SetDevice (device);
00395 return AddIpv4Interface (interface);
00396 }
00397
00398 uint32_t
00399 Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
00400 {
00401 NS_LOG_FUNCTION (this << interface);
00402 uint32_t index = m_nInterfaces;
00403 m_interfaces.push_back (interface);
00404 m_nInterfaces++;
00405 return index;
00406 }
00407
00408 Ptr<Ipv4Interface>
00409 Ipv4L3Protocol::GetInterface (uint32_t index) const
00410 {
00411 NS_LOG_FUNCTION (this << index);
00412 uint32_t tmp = 0;
00413 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
00414 {
00415 if (index == tmp)
00416 {
00417 return *i;
00418 }
00419 tmp++;
00420 }
00421 return 0;
00422 }
00423
00424 uint32_t
00425 Ipv4L3Protocol::GetNInterfaces (void) const
00426 {
00427 NS_LOG_FUNCTION_NOARGS ();
00428 return m_nInterfaces;
00429 }
00430
00431 uint32_t
00432 Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
00433 {
00434 NS_LOG_FUNCTION (this << addr);
00435
00436 uint32_t ifIndex = 0;
00437 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00438 i != m_interfaces.end ();
00439 i++, ifIndex++)
00440 {
00441 if ((*i)->GetAddress () == addr)
00442 {
00443 return ifIndex;
00444 }
00445 }
00446
00447 NS_FATAL_ERROR ("Ipv4L3Protocol::FindInterfaceForAddr (): "
00448 "Interface not found for IP address " << addr);
00449 return 0;
00450 }
00451
00452 uint32_t
00453 Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
00454 {
00455 NS_LOG_FUNCTION (this << addr << mask);
00456
00457 uint32_t ifIndex = 0;
00458 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00459 i != m_interfaces.end ();
00460 i++, ifIndex++)
00461 {
00462 if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
00463 {
00464 return ifIndex;
00465 }
00466 }
00467
00468 NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
00469 "Interface not found for masked IP address");
00470 return 0;
00471 }
00472
00473 int32_t
00474 Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
00475 {
00476 NS_LOG_FUNCTION (this << device);
00477
00478 uint32_t ifIndex = 0;
00479 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00480 i != m_interfaces.end ();
00481 i++, ifIndex++)
00482 {
00483 if ((*i)->GetDevice () == device)
00484 {
00485 return ifIndex;
00486 }
00487 }
00488
00489 return -1;
00490 }
00491
00492 Ptr<Ipv4Interface>
00493 Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
00494 {
00495 NS_LOG_FUNCTION (this << &device);
00496 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
00497 {
00498 if ((*i)->GetDevice () == device)
00499 {
00500 return *i;
00501 }
00502 }
00503 return 0;
00504 }
00505
00506 void
00507 Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
00508 const Address &to, NetDevice::PacketType packetType)
00509 {
00510 NS_LOG_FUNCTION (this << &device << p << protocol << from);
00511
00512 NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
00513
00514 Ptr<Packet> packet = p->Copy ();
00515
00516 uint32_t index = 0;
00517 Ptr<Ipv4Interface> ipv4Interface;
00518 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00519 i != m_interfaces.end ();
00520 i++)
00521 {
00522 ipv4Interface = *i;
00523 if (ipv4Interface->GetDevice () == device)
00524 {
00525 if (ipv4Interface->IsUp ())
00526 {
00527 m_rxTrace (packet, index);
00528 break;
00529 }
00530 else
00531 {
00532 NS_LOG_LOGIC ("Dropping received packet-- interface is down");
00533 m_dropTrace (packet);
00534 return;
00535 }
00536 }
00537 index++;
00538 }
00539 Ipv4Header ipHeader;
00540 if (m_calcChecksum)
00541 {
00542 ipHeader.EnableChecksum ();
00543 }
00544 packet->RemoveHeader (ipHeader);
00545
00546 if (!ipHeader.IsChecksumOk ())
00547 {
00548 m_dropTrace (packet);
00549 return;
00550 }
00551
00552 for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
00553 {
00554 Ptr<Ipv4RawSocketImpl> socket = *i;
00555 socket->ForwardUp (packet, ipHeader, device);
00556 }
00557
00558 if (Forwarding (index, packet, ipHeader, device))
00559 {
00560 return;
00561 }
00562
00563 ForwardUp (packet, ipHeader, ipv4Interface);
00564 }
00565
00566 Ptr<Icmpv4L4Protocol>
00567 Ipv4L3Protocol::GetIcmp (void) const
00568 {
00569 Ptr<Ipv4L4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
00570 if (prot != 0)
00571 {
00572 return prot->GetObject<Icmpv4L4Protocol> ();
00573 }
00574 else
00575 {
00576 return 0;
00577 }
00578 }
00579
00580 bool
00581 Ipv4L3Protocol::IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const
00582 {
00583 return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
00584 }
00585
00586 void
00587 Ipv4L3Protocol::Send (Ptr<Packet> packet,
00588 Ipv4Address source,
00589 Ipv4Address destination,
00590 uint8_t protocol)
00591 {
00592 NS_LOG_FUNCTION (this << packet << source << destination << protocol);
00593
00594 Ipv4Header ipHeader;
00595
00596 if (m_calcChecksum)
00597 {
00598 ipHeader.EnableChecksum ();
00599 }
00600
00601 ipHeader.SetSource (source);
00602 ipHeader.SetDestination (destination);
00603 ipHeader.SetProtocol (protocol);
00604 ipHeader.SetPayloadSize (packet->GetSize ());
00605 ipHeader.SetIdentification (m_identification);
00606
00607 m_identification ++;
00608
00609 SocketSetDontFragmentTag dfTag;
00610 bool found = packet->FindFirstMatchingTag (dfTag);
00611 if (found)
00612 {
00613 if (dfTag.IsEnabled ())
00614 {
00615 ipHeader.SetDontFragment ();
00616 }
00617 else
00618 {
00619 ipHeader.SetMayFragment ();
00620 }
00621 }
00622
00623
00624
00625
00626 SocketIpTtlTag tag;
00627 found = packet->FindFirstMatchingTag (tag);
00628
00629 if (destination.IsBroadcast ())
00630 {
00631 ipHeader.SetTtl (1);
00632 }
00633 else if (found)
00634 {
00635 ipHeader.SetTtl (tag.GetTtl ());
00636
00637 }
00638 else
00639 {
00640 ipHeader.SetTtl (m_defaultTtl);
00641 uint32_t ifaceIndex = 0;
00642 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
00643 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
00644 {
00645 Ptr<Ipv4Interface> outInterface = *ifaceIter;
00646 if (destination.IsSubnetDirectedBroadcast (
00647 outInterface->GetNetworkMask ()))
00648 {
00649 ipHeader.SetTtl (1);
00650 }
00651 }
00652 }
00653 if (destination.IsBroadcast ())
00654 {
00655 uint32_t ifaceIndex = 0;
00656 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
00657 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
00658 {
00659 Ptr<Ipv4Interface> outInterface = *ifaceIter;
00660 Ptr<Packet> packetCopy = packet->Copy ();
00661
00662 packetCopy->AddHeader (ipHeader);
00663 if (packetCopy->GetSize () > outInterface->GetMtu () &&
00664 ipHeader.IsDontFragment () &&
00665 IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
00666 {
00667 Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
00668 NS_ASSERT (icmp != 0);
00669 icmp->SendDestUnreachFragNeeded (ipHeader, packet, outInterface->GetMtu ());
00670 m_dropTrace (packetCopy);
00671 }
00672 else if (packet->GetSize () > outInterface->GetMtu () &&
00673 !ipHeader.IsDontFragment ())
00674 {
00675 NS_LOG_LOGIC ("Too big: need fragmentation but no frag support.");
00676 m_dropTrace (packet);
00677 }
00678 else
00679 {
00680 NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
00681 if (outInterface->IsUp ())
00682 {
00683 m_txTrace (packetCopy, ifaceIndex);
00684 outInterface->Send (packetCopy, destination);
00685 }
00686 else
00687 {
00688 m_dropTrace (packetCopy);
00689 }
00690 }
00691 }
00692 }
00693 else
00694 {
00695
00696
00697
00698
00699
00700
00701
00702
00703 Lookup (ipHeader, packet,
00704 MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
00705 }
00706 }
00707
00708 void
00709 Ipv4L3Protocol::SendRealOut (bool found,
00710 Ipv4Route const &route,
00711 Ptr<Packet> packet,
00712 Ipv4Header const &ipHeader)
00713 {
00714 NS_LOG_FUNCTION (this << found << &route << packet << &ipHeader);
00715
00716 packet->AddHeader (ipHeader);
00717 if (!found)
00718 {
00719 NS_LOG_WARN ("No route to host. Drop.");
00720 m_dropTrace (packet);
00721 return;
00722 }
00723
00724 NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
00725
00726 Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
00727 if (packet->GetSize () > outInterface->GetMtu () &&
00728 ipHeader.IsDontFragment () &&
00729 IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
00730 {
00731 NS_LOG_LOGIC ("Too big: need fragmentation but not allowed");
00732 Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
00733 NS_ASSERT (icmp != 0);
00734 Ptr<Packet> copyNoHeader = packet->Copy ();
00735 Ipv4Header tmp;
00736 copyNoHeader->RemoveHeader (tmp);
00737 icmp->SendDestUnreachFragNeeded (ipHeader, copyNoHeader, outInterface->GetMtu ());
00738 m_dropTrace (packet);
00739 }
00740 else if (packet->GetSize () > outInterface->GetMtu () &&
00741 !ipHeader.IsDontFragment ())
00742 {
00743 NS_LOG_LOGIC ("Too big: need fragmentation but no frag support.");
00744 m_dropTrace (packet);
00745 }
00746 else
00747 {
00748 if (route.IsGateway ())
00749 {
00750 if (outInterface->IsUp ())
00751 {
00752 NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
00753 m_txTrace (packet, route.GetInterface ());
00754 outInterface->Send (packet, route.GetGateway ());
00755 }
00756 else
00757 {
00758 NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route.GetGateway ());
00759 m_dropTrace (packet);
00760 }
00761 }
00762 else
00763 {
00764 if (outInterface->IsUp ())
00765 {
00766 NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
00767 m_txTrace (packet, route.GetInterface ());
00768 outInterface->Send (packet, ipHeader.GetDestination ());
00769 }
00770 else
00771 {
00772 NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route.GetGateway ());
00773 m_dropTrace (packet);
00774 }
00775 }
00776 }
00777 }
00778
00779 bool
00780 Ipv4L3Protocol::Forwarding (
00781 uint32_t ifIndex,
00782 Ptr<Packet> packet,
00783 Ipv4Header &ipHeader,
00784 Ptr<NetDevice> device)
00785 {
00786 NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
00787 NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
00788
00789 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00790 i != m_interfaces.end (); i++)
00791 {
00792 if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ()))
00793 {
00794 NS_LOG_LOGIC ("For me (destination match)");
00795 return false;
00796 }
00797 }
00798
00799 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
00800 i != m_interfaces.end (); i++)
00801 {
00802 Ptr<Ipv4Interface> interface = *i;
00803 if (interface->GetDevice () == device)
00804 {
00805 if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
00806 {
00807 NS_LOG_LOGIC ("For me (interface broadcast address)");
00808 return false;
00809 }
00810 break;
00811 }
00812 }
00813
00814 if (ipHeader.GetDestination ().IsBroadcast ())
00815 {
00816 NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
00817 return false;
00818 }
00819
00820 if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ()))
00821 {
00822 NS_LOG_LOGIC ("For me (Ipv4Addr any address)");
00823 return false;
00824 }
00825
00826
00827
00828
00829 for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin ();
00830 i != m_multicastGroups.end (); i++)
00831 {
00832 if ((*i).first.IsEqual (ipHeader.GetSource ()) &&
00833 (*i).second.IsEqual (ipHeader.GetDestination ()))
00834 {
00835 NS_LOG_LOGIC ("For me (Joined multicast group)");
00836
00837
00838 NS_LOG_LOGIC ("Forwarding (multicast).");
00839 DoForward (ifIndex, packet->Copy (), ipHeader);
00840 return false;
00841 }
00842 }
00843
00844 DoForward (ifIndex, packet, ipHeader);
00845 return true;
00846 }
00847
00848 void
00849 Ipv4L3Protocol::DoForward (uint32_t ifIndex,
00850 Ptr<Packet> packet,
00851 Ipv4Header ipHeader)
00852 {
00853 NS_LOG_FUNCTION (this << ifIndex << packet << ipHeader);
00854
00855 ipHeader.SetTtl (ipHeader.GetTtl () - 1);
00856 if (ipHeader.GetTtl () == 0)
00857 {
00858 if (IsUnicast (ipHeader.GetDestination (), GetInterface (ifIndex)->GetNetworkMask ()))
00859 {
00860 Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
00861 icmp->SendTimeExceededTtl (ipHeader, packet);
00862 }
00863 NS_LOG_WARN ("TTL exceeded. Drop.");
00864 m_dropTrace (packet);
00865 return;
00866 }
00867 NS_LOG_LOGIC ("Not for me, forwarding.");
00868 Lookup (ifIndex, ipHeader, packet,
00869 MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
00870 }
00871
00872
00873 void
00874 Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
00875 Ptr<Ipv4Interface> incomingInterface)
00876 {
00877 NS_LOG_FUNCTION (this << p << &ip);
00878
00879 Ptr<Ipv4L4Protocol> protocol = GetProtocol (ip.GetProtocol ());
00880 if (protocol != 0)
00881 {
00882
00883
00884 Ptr<Packet> copy = p->Copy ();
00885 enum Ipv4L4Protocol::RxStatus status =
00886 protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
00887 switch (status) {
00888 case Ipv4L4Protocol::RX_OK:
00889
00890 case Ipv4L4Protocol::RX_CSUM_FAILED:
00891 break;
00892 case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
00893 if (IsUnicast (ip.GetDestination (), incomingInterface->GetNetworkMask ()))
00894 {
00895 GetIcmp ()->SendDestUnreachPort (ip, copy);
00896 }
00897 break;
00898 }
00899 }
00900 }
00901
00902 void
00903 Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
00904 {
00905 NS_LOG_FUNCTION (this << origin << group);
00906 m_multicastGroups.push_back(
00907 std::pair<Ipv4Address, Ipv4Address> (origin, group));
00908 }
00909
00910 void
00911 Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
00912 {
00913 NS_LOG_FUNCTION (this << origin << group);
00914
00915 for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
00916 i != m_multicastGroups.end ();
00917 i++)
00918 {
00919 if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group))
00920 {
00921 m_multicastGroups.erase (i);
00922 return;
00923 }
00924 }
00925 }
00926
00927 void
00928 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
00929 {
00930 NS_LOG_FUNCTION (this << i << address);
00931 Ptr<Ipv4Interface> interface = GetInterface (i);
00932 interface->SetAddress (address);
00933 }
00934
00935 void
00936 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
00937 {
00938 NS_LOG_FUNCTION (this << i << mask);
00939 Ptr<Ipv4Interface> interface = GetInterface (i);
00940 interface->SetNetworkMask (mask);
00941 }
00942
00943 Ipv4Mask
00944 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
00945 {
00946 NS_LOG_FUNCTION (this << i);
00947 Ptr<Ipv4Interface> interface = GetInterface (i);
00948 return interface->GetNetworkMask ();
00949 }
00950
00951 Ipv4Address
00952 Ipv4L3Protocol::GetAddress (uint32_t i) const
00953 {
00954 NS_LOG_FUNCTION (this << i);
00955 Ptr<Ipv4Interface> interface = GetInterface (i);
00956 return interface->GetAddress ();
00957 }
00958
00959 void
00960 Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
00961 {
00962 NS_LOG_FUNCTION (i << metric);
00963 Ptr<Ipv4Interface> interface = GetInterface (i);
00964 interface->SetMetric (metric);
00965 }
00966
00967 uint16_t
00968 Ipv4L3Protocol::GetMetric (uint32_t i) const
00969 {
00970 NS_LOG_FUNCTION (i);
00971 Ptr<Ipv4Interface> interface = GetInterface (i);
00972 return interface->GetMetric ();
00973 }
00974
00975 bool
00976 Ipv4L3Protocol::GetIfIndexForDestination (
00977 Ipv4Address destination, uint32_t& ifIndex) const
00978 {
00979 NS_LOG_FUNCTION (this << destination << &ifIndex);
00980
00981
00982
00983
00984
00985 for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
00986 i != m_routingProtocols.end ();
00987 i++)
00988 {
00989 NS_LOG_LOGIC ("Requesting Source Address");
00990 uint32_t ifIndexTmp;
00991
00992 if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
00993 {
00994 NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
00995 ifIndex = ifIndexTmp;
00996 return true;
00997 }
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 if (GetNInterfaces () == 2)
01009 {
01010 NS_LOG_LOGIC ("One Interface. Using interface 1.");
01011 ifIndex = 1;
01012 return true;
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 NS_LOG_LOGIC ("Using default unicast route");
01030 Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
01031
01032 if (route == NULL)
01033 {
01034 NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
01035 "Unable to determine outbound interface. No default route set");
01036 return false;
01037 }
01038
01039 ifIndex = route->GetInterface ();
01040
01041 NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
01042 return true;
01043 }
01044
01045 uint16_t
01046 Ipv4L3Protocol::GetMtu (uint32_t i) const
01047 {
01048 NS_LOG_FUNCTION (this << i);
01049 Ptr<Ipv4Interface> interface = GetInterface (i);
01050 return interface->GetMtu ();
01051 }
01052
01053 bool
01054 Ipv4L3Protocol::IsUp (uint32_t i) const
01055 {
01056 NS_LOG_FUNCTION (this << i);
01057 Ptr<Ipv4Interface> interface = GetInterface (i);
01058 return interface->IsUp ();
01059 }
01060
01061 void
01062 Ipv4L3Protocol::SetUp (uint32_t i)
01063 {
01064 NS_LOG_FUNCTION (this << i);
01065 Ptr<Ipv4Interface> interface = GetInterface (i);
01066 interface->SetUp ();
01067
01068
01069
01070
01071 if ((interface->GetAddress ()) != (Ipv4Address ())
01072 && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
01073 {
01074 AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
01075 interface->GetNetworkMask (), i);
01076 }
01077 }
01078
01079 void
01080 Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
01081 {
01082 NS_LOG_FUNCTION (this << ifaceIndex);
01083 Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
01084 interface->SetDown ();
01085
01086
01087 bool modified = true;
01088 while (modified)
01089 {
01090 modified = false;
01091 for (uint32_t i = 0; i < GetNRoutes (); i++)
01092 {
01093 Ipv4Route *route = GetRoute (i);
01094 if (route->GetInterface () == ifaceIndex)
01095 {
01096 RemoveRoute (i);
01097 modified = true;
01098 break;
01099 }
01100 }
01101 }
01102 }
01103
01104 }