A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv4-l3-click-protocol.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2006 Georgia Tech Research Corporation
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: George F. Riley <riley@ece.gatech.edu>
19 // Author: Lalith Suresh <suresh.lalith@gmail.com>
20 //
21 
22 #ifdef NS3_CLICK
23 
24 #include "ipv4-l3-click-protocol.h"
25 #include "ns3/ipv4-click-routing.h"
26 #include "ns3/node.h"
27 #include "ns3/socket.h"
28 #include "ns3/ethernet-header.h"
29 #include "ns3/llc-snap-header.h"
30 #include "ns3/net-device.h"
31 #include "ns3/uinteger.h"
32 #include "ns3/object-vector.h"
33 
34 #include "ns3/ipv4-raw-socket-impl.h"
35 #include "ns3/arp-l3-protocol.h"
36 #include "ns3/ip-l4-protocol.h"
37 #include "ns3/icmpv4-l4-protocol.h"
38 #include "ns3/loopback-net-device.h"
39 
40 NS_LOG_COMPONENT_DEFINE ("Ipv4L3ClickProtocol");
41 
42 namespace ns3 {
43 
44 const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
45 
46 
47 NS_OBJECT_ENSURE_REGISTERED (Ipv4L3ClickProtocol)
48  ;
49 
50 TypeId
52 {
53  static TypeId tid = TypeId ("ns3::Ipv4L3ClickProtocol")
54  .SetParent<Ipv4> ()
55  .AddConstructor<Ipv4L3ClickProtocol> ()
56  .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
57  UintegerValue (64),
58  MakeUintegerAccessor (&Ipv4L3ClickProtocol::m_defaultTtl),
59  MakeUintegerChecker<uint8_t> ())
60  .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
62  MakeObjectVectorAccessor (&Ipv4L3ClickProtocol::m_interfaces),
63  MakeObjectVectorChecker<Ipv4Interface> ())
64  ;
65  return tid;
66 }
67 
68 Ipv4L3ClickProtocol::Ipv4L3ClickProtocol ()
69  : m_identification (0)
70 {
71 }
72 
73 Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol ()
74 {
75 }
76 
77 void
79 {
80  NS_LOG_FUNCTION (this);
81  for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
82  {
83  *i = 0;
84  }
85  m_protocols.clear ();
86 
87  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
88  {
89  *i = 0;
90  }
91  m_interfaces.clear ();
92  m_sockets.clear ();
93  m_node = 0;
94  m_routingProtocol = 0;
96 }
97 
98 void
100 {
101  if (m_node == 0)
102  {
103  Ptr<Node>node = this->GetObject<Node> ();
104  // verify that it's a valid node and that
105  // the node has not been set before
106  if (node != 0)
107  {
108  this->SetNode (node);
109  }
110  }
112 }
113 
114 void
115 Ipv4L3ClickProtocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol)
116 {
117  NS_LOG_FUNCTION (this);
118  m_routingProtocol = routingProtocol;
119  m_routingProtocol->SetIpv4 (this);
120 }
121 
122 
123 Ptr<Ipv4RoutingProtocol>
125 {
126  return m_routingProtocol;
127 }
128 
129 Ptr<Ipv4Interface>
130 Ipv4L3ClickProtocol::GetInterface (uint32_t index) const
131 {
132  NS_LOG_FUNCTION (this << index);
133  if (index < m_interfaces.size ())
134  {
135  return m_interfaces[index];
136  }
137  return 0;
138 }
139 
140 uint32_t
142 {
144  return m_interfaces.size ();
145 }
146 
147 int32_t
149  Ipv4Address address) const
150 {
151  NS_LOG_FUNCTION (this << address);
152 
153  int32_t interface = 0;
154  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
155  i != m_interfaces.end ();
156  i++, interface++)
157  {
158  for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
159  {
160  if ((*i)->GetAddress (j).GetLocal () == address)
161  {
162  return interface;
163  }
164  }
165  }
166 
167  return -1;
168 }
169 
170 int32_t
172  Ipv4Address address,
173  Ipv4Mask mask) const
174 {
175  NS_LOG_FUNCTION (this << address << mask);
176 
177  int32_t interface = 0;
178  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
179  i != m_interfaces.end ();
180  i++, interface++)
181  {
182  for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
183  {
184  if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
185  {
186  return interface;
187  }
188  }
189  }
190 
191  return -1;
192 }
193 
194 int32_t
196  Ptr<const NetDevice> device) const
197 {
198  NS_LOG_FUNCTION (this << device->GetIfIndex ());
199 
200  int32_t interface = 0;
201  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
202  i != m_interfaces.end ();
203  i++, interface++)
204  {
205  if ((*i)->GetDevice () == device)
206  {
207  return interface;
208  }
209  }
210 
211  return -1;
212 }
213 
214 bool
215 Ipv4L3ClickProtocol::IsDestinationAddress (Ipv4Address address, uint32_t iif) const
216 {
217  NS_LOG_FUNCTION (this << address << " " << iif);
218 
219  // First check the incoming interface for a unicast address match
220  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
221  {
222  Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
223  if (address == iaddr.GetLocal ())
224  {
225  NS_LOG_LOGIC ("For me (destination " << address << " match)");
226  return true;
227  }
228  if (address == iaddr.GetBroadcast ())
229  {
230  NS_LOG_LOGIC ("For me (interface broadcast address)");
231  return true;
232  }
233  }
234 
235  if (address.IsMulticast ())
236  {
237 #ifdef NOTYET
238  if (MulticastCheckGroup (iif, address ))
239 #endif
240  if (true)
241  {
242  NS_LOG_LOGIC ("For me (Ipv4Addr multicast address");
243  return true;
244  }
245  }
246 
247  if (address.IsBroadcast ())
248  {
249  NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
250  return true;
251  }
252 
253  if (GetWeakEsModel ()) // Check other interfaces
254  {
255  for (uint32_t j = 0; j < GetNInterfaces (); j++)
256  {
257  if (j == uint32_t (iif))
258  {
259  continue;
260  }
261  for (uint32_t i = 0; i < GetNAddresses (j); i++)
262  {
263  Ipv4InterfaceAddress iaddr = GetAddress (j, i);
264  if (address == iaddr.GetLocal ())
265  {
266  NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
267  return true;
268  }
269  // This is a small corner case: match another interface's broadcast address
270  if (address == iaddr.GetBroadcast ())
271  {
272  NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
273  return true;
274  }
275  }
276  }
277  }
278  return false;
279 }
280 
281 void
283 {
284  NS_LOG_FUNCTION (this << forward);
285  m_ipForward = forward;
286  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
287  {
288  (*i)->SetForwarding (forward);
289  }
290 }
291 
292 bool
294 {
295  return m_ipForward;
296 }
297 
298 void
300 {
301  m_weakEsModel = model;
302 }
303 
304 bool
306 {
307  return m_weakEsModel;
308 }
309 
310 Ptr<NetDevice>
312 {
313  NS_LOG_FUNCTION (this << i);
314  return GetInterface (i)->GetDevice ();
315 }
316 
317 void
318 Ipv4L3ClickProtocol::SetDefaultTtl (uint8_t ttl)
319 {
321  m_defaultTtl = ttl;
322 }
323 
324 void
325 Ipv4L3ClickProtocol::SetupLoopback (void)
326 {
328 
329  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
330  Ptr<LoopbackNetDevice> device = 0;
331  // First check whether an existing LoopbackNetDevice exists on the node
332  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
333  {
334  if ((device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i))))
335  {
336  break;
337  }
338  }
339  if (device == 0)
340  {
341  device = CreateObject<LoopbackNetDevice> ();
342  m_node->AddDevice (device);
343  }
344  interface->SetDevice (device);
345  interface->SetNode (m_node);
346  Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
347  interface->AddAddress (ifaceAddr);
348  uint32_t index = AddIpv4Interface (interface);
349  Ptr<Node> node = GetObject<Node> ();
350  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
351  Ipv4L3ClickProtocol::PROT_NUMBER, device);
352  interface->SetUp ();
353  if (m_routingProtocol != 0)
354  {
355  m_routingProtocol->NotifyInterfaceUp (index);
356  }
357 }
358 
359 Ptr<Socket>
361 {
362  NS_LOG_FUNCTION (this);
363  Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
364  socket->SetNode (m_node);
365  m_sockets.push_back (socket);
366  return socket;
367 }
368 void
369 Ipv4L3ClickProtocol::DeleteRawSocket (Ptr<Socket> socket)
370 {
371  NS_LOG_FUNCTION (this << socket);
372  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
373  {
374  if ((*i) == socket)
375  {
376  m_sockets.erase (i);
377  return;
378  }
379  }
380  return;
381 }
382 
383 
384 void
385 Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
386 {
387  m_node = node;
388  // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
389  SetupLoopback ();
390 }
391 
392 bool
393 Ipv4L3ClickProtocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
394 {
395  NS_LOG_FUNCTION (this << i << address);
396  Ptr<Ipv4Interface> interface = GetInterface (i);
397  bool retVal = interface->AddAddress (address);
398  if (m_routingProtocol != 0)
399  {
400  m_routingProtocol->NotifyAddAddress (i, address);
401  }
402  return retVal;
403 }
404 
405 Ipv4InterfaceAddress
406 Ipv4L3ClickProtocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
407 {
408  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
409  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
410  return interface->GetAddress (addressIndex);
411 }
412 
413 uint32_t
414 Ipv4L3ClickProtocol::GetNAddresses (uint32_t interface) const
415 {
416  NS_LOG_FUNCTION (this << interface);
417  Ptr<Ipv4Interface> iface = GetInterface (interface);
418  return iface->GetNAddresses ();
419 }
420 
421 bool
422 Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
423 {
424  NS_LOG_FUNCTION (this << i << addressIndex);
425  Ptr<Ipv4Interface> interface = GetInterface (i);
426  Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
427  if (address != Ipv4InterfaceAddress ())
428  {
429  if (m_routingProtocol != 0)
430  {
431  m_routingProtocol->NotifyRemoveAddress (i, address);
432  }
433  return true;
434  }
435  return false;
436 }
437 
438 bool
439 Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, Ipv4Address address)
440 {
441  NS_LOG_FUNCTION (this << i << address);
442 
443  if (address == Ipv4Address::GetLoopback())
444  {
445  NS_LOG_WARN ("Cannot remove loopback address.");
446  return false;
447  }
448  Ptr<Ipv4Interface> interface = GetInterface (i);
449  Ipv4InterfaceAddress ifAddr = interface->RemoveAddress (address);
450  if (ifAddr != Ipv4InterfaceAddress ())
451  {
452  if (m_routingProtocol != 0)
453  {
454  m_routingProtocol->NotifyRemoveAddress (i, ifAddr);
455  }
456  return true;
457  }
458  return false;
459 }
460 
461 Ipv4Address
462 Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
463  Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
464 {
465  NS_LOG_FUNCTION (device << dst << scope);
466  Ipv4Address addr ("0.0.0.0");
467  Ipv4InterfaceAddress iaddr;
468  bool found = false;
469 
470  if (device != 0)
471  {
472  int32_t i = GetInterfaceForDevice (device);
473  NS_ASSERT_MSG (i >= 0, "No device found on node");
474  for (uint32_t j = 0; j < GetNAddresses (i); j++)
475  {
476  iaddr = GetAddress (i, j);
477  if (iaddr.IsSecondary ())
478  {
479  continue;
480  }
481  if (iaddr.GetScope () > scope)
482  {
483  continue;
484  }
485  if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
486  {
487  return iaddr.GetLocal ();
488  }
489  if (!found)
490  {
491  addr = iaddr.GetLocal ();
492  found = true;
493  }
494  }
495  }
496  if (found)
497  {
498  return addr;
499  }
500 
501  // Iterate among all interfaces
502  for (uint32_t i = 0; i < GetNInterfaces (); i++)
503  {
504  for (uint32_t j = 0; j < GetNAddresses (i); j++)
505  {
506  iaddr = GetAddress (i, j);
507  if (iaddr.IsSecondary ())
508  {
509  continue;
510  }
511  if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
512  && iaddr.GetScope () <= scope)
513  {
514  return iaddr.GetLocal ();
515  }
516  }
517  }
518  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
519  << scope << ", returning 0");
520  return addr;
521 }
522 
523 void
524 Ipv4L3ClickProtocol::SetMetric (uint32_t i, uint16_t metric)
525 {
526  NS_LOG_FUNCTION (i << metric);
527  Ptr<Ipv4Interface> interface = GetInterface (i);
528  interface->SetMetric (metric);
529 }
530 
531 uint16_t
532 Ipv4L3ClickProtocol::GetMetric (uint32_t i) const
533 {
534  NS_LOG_FUNCTION (i);
535  Ptr<Ipv4Interface> interface = GetInterface (i);
536  return interface->GetMetric ();
537 }
538 
539 uint16_t
540 Ipv4L3ClickProtocol::GetMtu (uint32_t i) const
541 {
542  NS_LOG_FUNCTION (this << i);
543  Ptr<Ipv4Interface> interface = GetInterface (i);
544  return interface->GetDevice ()->GetMtu ();
545 }
546 
547 bool
548 Ipv4L3ClickProtocol::IsUp (uint32_t i) const
549 {
550  NS_LOG_FUNCTION (this << i);
551  Ptr<Ipv4Interface> interface = GetInterface (i);
552  return interface->IsUp ();
553 }
554 
555 void
556 Ipv4L3ClickProtocol::SetUp (uint32_t i)
557 {
558  NS_LOG_FUNCTION (this << i);
559  Ptr<Ipv4Interface> interface = GetInterface (i);
560  interface->SetUp ();
561 
562  if (m_routingProtocol != 0)
563  {
564  m_routingProtocol->NotifyInterfaceUp (i);
565  }
566 }
567 
568 void
569 Ipv4L3ClickProtocol::SetDown (uint32_t ifaceIndex)
570 {
571  NS_LOG_FUNCTION (this << ifaceIndex);
572  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
573  interface->SetDown ();
574 
575  if (m_routingProtocol != 0)
576  {
577  m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
578  }
579 }
580 
581 bool
582 Ipv4L3ClickProtocol::IsForwarding (uint32_t i) const
583 {
584  NS_LOG_FUNCTION (this << i);
585  Ptr<Ipv4Interface> interface = GetInterface (i);
586  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
587  return interface->IsForwarding ();
588 }
589 
590 void
591 Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val)
592 {
593  NS_LOG_FUNCTION (this << i);
594  Ptr<Ipv4Interface> interface = GetInterface (i);
595  interface->SetForwarding (val);
596 }
597 
598 void
599 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
600 {
601  NS_ASSERT (i <= m_node->GetNDevices ());
602  Ptr<NetDevice> netdev = GetNetDevice (i);
603  NS_ASSERT (netdev);
604  Ptr<Node> node = GetObject<Node> ();
605  NS_ASSERT (node);
606  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
607  0, netdev,true);
608 }
609 
610 uint32_t
611 Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
612 {
613  NS_LOG_FUNCTION (this << &device);
614  Ptr<Node> node = GetObject<Node> ();
615  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
616  Ipv4L3ClickProtocol::PROT_NUMBER, device);
617  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
619 
620  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
621  interface->SetNode (m_node);
622  interface->SetDevice (device);
623  interface->SetForwarding (m_ipForward);
624  return AddIpv4Interface (interface);
625 }
626 
627 uint32_t
628 Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
629 {
630  NS_LOG_FUNCTION (this << interface);
631  uint32_t index = m_interfaces.size ();
632  m_interfaces.push_back (interface);
633  return index;
634 }
635 
639 Ipv4Header
640 Ipv4L3ClickProtocol::BuildHeader (
641  Ipv4Address source,
642  Ipv4Address destination,
643  uint8_t protocol,
644  uint16_t payloadSize,
645  uint8_t ttl,
646  bool mayFragment)
647 {
649  Ipv4Header ipHeader;
650  ipHeader.SetSource (source);
651  ipHeader.SetDestination (destination);
652  ipHeader.SetProtocol (protocol);
653  ipHeader.SetPayloadSize (payloadSize);
654  ipHeader.SetTtl (ttl);
655  if (mayFragment == true)
656  {
657  ipHeader.SetMayFragment ();
658  ipHeader.SetIdentification (m_identification);
659  m_identification++;
660  }
661  else
662  {
663  ipHeader.SetDontFragment ();
664  // TBD: set to zero here; will cause traces to change
665  ipHeader.SetIdentification (m_identification);
666  m_identification++;
667  }
668  if (Node::ChecksumEnabled ())
669  {
670  ipHeader.EnableChecksum ();
671  }
672  return ipHeader;
673 }
674 
675 void
676 Ipv4L3ClickProtocol::Send (Ptr<Packet> packet,
677  Ipv4Address source,
678  Ipv4Address destination,
679  uint8_t protocol,
680  Ptr<Ipv4Route> route)
681 {
682  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
683 
684  Ipv4Header ipHeader;
685  bool mayFragment = true;
686  uint8_t ttl = m_defaultTtl;
687  SocketIpTtlTag tag;
688  bool found = packet->RemovePacketTag (tag);
689  if (found)
690  {
691  ttl = tag.GetTtl ();
692  }
693 
694  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
695  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
696  if (Node::ChecksumEnabled ())
697  {
698  ipHeader.EnableChecksum ();
699  }
700  packet->AddHeader (ipHeader);
701  click->Send (packet->Copy (), source, destination);
702  return;
703 }
704 
705 void
706 Ipv4L3ClickProtocol::SendWithHeader (Ptr<Packet> packet,
707  Ipv4Header ipHeader,
708  Ptr<Ipv4Route> route)
709 {
710  NS_LOG_FUNCTION (this << packet << ipHeader << route);
711 
712  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
713  if (Node::ChecksumEnabled ())
714  {
715  ipHeader.EnableChecksum ();
716  }
717  packet->AddHeader (ipHeader);
718  click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
719 }
720 
721 void
722 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p, int ifid)
723 {
724  // Called by Ipv4ClickRouting.
725 
726  // NetDevice::Send () attaches ethernet headers,
727  // so the one that Click attaches isn't required
728  // but we need the destination address and
729  // protocol values from the header.
730 
731  Ptr<NetDevice> netdev = GetNetDevice (ifid);
732 
733  EthernetHeader header;
734  p->RemoveHeader (header);
735 
736  uint16_t protocol;
737 
738  if (header.GetLengthType () <= 1500)
739  {
740  LlcSnapHeader llc;
741  p->RemoveHeader (llc);
742  protocol = llc.GetType ();
743  }
744  else
745  {
746  protocol = header.GetLengthType ();
747  }
748 
749  // Use the destination address and protocol obtained
750  // from above to send the packet.
751  netdev->Send (p, header.GetDestination (), protocol);
752 }
753 
754 void
755 Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
756  const Address &to, NetDevice::PacketType packetType)
757 {
758  NS_LOG_FUNCTION (this << device << p << from << to);
759 
760  // Forward packet to raw sockets, if any
761  if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
762  {
763  Ptr<Packet> packetForRawSocket = p->Copy ();
764  uint32_t interface = 0;
765  Ptr<Ipv4Interface> ipv4Interface;
766  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
767  i != m_interfaces.end ();
768  i++, interface++)
769  {
770  ipv4Interface = *i;
771  if (ipv4Interface->GetDevice () == device)
772  {
773  if (ipv4Interface->IsUp ())
774  {
775  break;
776  }
777  else
778  {
779  NS_LOG_LOGIC ("Dropping received packet -- interface is down");
780  return;
781  }
782  }
783  }
784 
785  Ipv4Header ipHeader;
786  if (Node::ChecksumEnabled ())
787  {
788  ipHeader.EnableChecksum ();
789  }
790  packetForRawSocket->RemoveHeader (ipHeader);
791 
792 
793  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
794  {
795  NS_LOG_LOGIC ("Forwarding to raw socket");
796  Ptr<Ipv4RawSocketImpl> socket = *i;
797  socket->ForwardUp (packetForRawSocket, ipHeader, ipv4Interface);
798  }
799  }
800 
801  Ptr<Packet> packet = p->Copy ();
802 
803  // Add an ethernet frame. This allows
804  // Click to work with csma and wifi
805  EthernetHeader hdr;
806  hdr.SetSource (Mac48Address::ConvertFrom (from));
807  hdr.SetDestination (Mac48Address::ConvertFrom (to));
808  hdr.SetLengthType (protocol);
809  packet->AddHeader (hdr);
810 
811  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
812  click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
813 }
814 
815 void
816 Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
817 {
818  NS_LOG_FUNCTION (this << packet << &ip);
819  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
820 
821  m_localDeliverTrace (ip, packet, iif);
822 
823  Ptr<IpL4Protocol> protocol = GetProtocol (ip.GetProtocol ());
824  if (protocol != 0)
825  {
826  // we need to make a copy in the unlikely event we hit the
827  // RX_ENDPOINT_UNREACH codepath
828  Ptr<Packet> copy = p->Copy ();
829  enum IpL4Protocol::RxStatus status =
830  protocol->Receive (p, ip, GetInterface (iif));
831  switch (status)
832  {
833  case IpL4Protocol::RX_OK:
834  // fall through
836  // fall through
838  break;
840  if (ip.GetDestination ().IsBroadcast () == true
841  || ip.GetDestination ().IsMulticast () == true)
842  {
843  break; // Do not reply to broadcast or multicast
844  }
845  // Another case to suppress ICMP is a subnet-directed broadcast
846  bool subnetDirected = false;
847  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
848  {
849  Ipv4InterfaceAddress addr = GetAddress (iif, i);
850  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination ().CombineMask (addr.GetMask ())
851  && ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
852  {
853  subnetDirected = true;
854  }
855  }
856  if (subnetDirected == false)
857  {
858  GetIcmp ()->SendDestUnreachPort (ip, copy);
859  }
860  }
861  }
862 }
863 
864 Ptr<Icmpv4L4Protocol>
865 Ipv4L3ClickProtocol::GetIcmp (void) const
866 {
867  Ptr<IpL4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
868  if (prot != 0)
869  {
870  return prot->GetObject<Icmpv4L4Protocol> ();
871  }
872  else
873  {
874  return 0;
875  }
876 }
877 
878 void
879 Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol)
880 {
881  m_protocols.push_back (protocol);
882 }
883 
884 Ptr<IpL4Protocol>
885 Ipv4L3ClickProtocol::GetProtocol (int protocolNumber) const
886 {
887  for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
888  {
889  if ((*i)->GetProtocolNumber () == protocolNumber)
890  {
891  return *i;
892  }
893  }
894  return 0;
895 }
896 
897 
898 } // namespace ns3
899 
900 #endif // NS3_CLICK
static TypeId GetTypeId(void)
Get the type ID.
Definition: ipv4.cc:35
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberContainer)
Definition: object-vector.h:51
virtual uint32_t AddInterface(Ptr< NetDevice > device)=0
virtual int32_t GetInterfaceForPrefix(Ipv4Address address, Ipv4Mask mask) const =0
Return the interface number of first interface found that has an Ipv4 address within the prefix speci...
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
virtual void SetWeakEsModel(bool model)=0
Set or unset the Weak Es Model.
static bool ChecksumEnabled(void)
Definition: node.cc:266
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:171
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
virtual Ptr< NetDevice > GetNetDevice(uint32_t interface)=0
virtual void SetForwarding(uint32_t interface, bool val)=0
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(void) const =0
Get the routing protocol to be used by this Ipv4 stack.
Ptr< T > CreateObject(void)
Definition: object.h:420
virtual bool IsDestinationAddress(Ipv4Address address, uint32_t iif) const =0
Determine whether address and interface corresponding to received packet can be accepted for local de...
virtual bool GetIpForward(void) const =0
Get the IP forwarding state.
virtual void DeleteRawSocket(Ptr< Socket > socket)=0
Deletes a particular raw socket.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const =0
Ipv4()
Definition: ipv4.cc:61
virtual void SetUp(uint32_t interface)=0
virtual uint16_t GetMetric(uint32_t interface) const =0
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
virtual void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route)=0
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
static Mac48Address ConvertFrom(const Address &address)
virtual void NotifyNewAggregate(void)
This method is invoked whenever two sets of objects are aggregated together.
Definition: object.cc:315
virtual bool GetWeakEsModel(void) const =0
Get the Weak Es Model status.
static const uint16_t PROT_NUMBER
ARP protocol number (0x0806)
virtual bool IsForwarding(uint32_t interface) const =0
virtual uint16_t GetMtu(uint32_t interface) const =0
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
static Ipv4Address GetLoopback(void)
static Ipv4Mask GetLoopback(void)
virtual Ptr< Socket > CreateRawSocket(void)=0
Creates a raw socket.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
virtual bool IsUp(uint32_t interface) const =0
virtual void SetIpForward(bool forward)=0
Set or unset the IP forwarding state.
virtual void Insert(Ptr< IpL4Protocol > protocol)=0
#define NS_LOG_WARN(msg)
Definition: log.h:280
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
Because addresses can be removed, the addressIndex is not guaranteed to be static across calls to thi...
static uint16_t GetStaticProtocolNumber(void)
Get the protocol number.
virtual uint32_t GetNAddresses(uint32_t interface) const =0
virtual Ipv4Address SelectSourceAddress(Ptr< const NetDevice > device, Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)=0
Return the first primary source address with scope less than or equal to the requested scope...
virtual void SetMetric(uint32_t interface, uint16_t metric)=0
virtual int32_t GetInterfaceForDevice(Ptr< const NetDevice > device) const =0
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
RxStatus
Rx status codes.
virtual int32_t GetInterfaceForAddress(Ipv4Address address) const =0
Return the interface number of the interface that has been assigned the specified IP address...
ObjectPtrContainerValue ObjectVectorValue
Definition: object-vector.h:30
virtual void SetDown(uint32_t interface)=0
tuple address
Definition: first.py:37
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:270
virtual bool RemoveAddress(uint32_t interface, uint32_t addressIndex)=0
Remove the address at addressIndex on named interface.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
virtual uint32_t GetNInterfaces(void) const =0
virtual void SetRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol)=0
Register a new routing protocol to be used by this Ipv4 stack.