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