A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv4-l3-click-protocol.cc
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
50 Ipv4L3ClickProtocol::GetTypeId (void)
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.",
60  ObjectVectorValue (),
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
281 Ipv4L3ClickProtocol::SetIpForward (bool forward)
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
292 Ipv4L3ClickProtocol::GetIpForward (void) const
293 {
294  return m_ipForward;
295 }
296 
297 void
298 Ipv4L3ClickProtocol::SetWeakEsModel (bool model)
299 {
300  m_weakEsModel = model;
301 }
302 
303 bool
304 Ipv4L3ClickProtocol::GetWeakEsModel (void) const
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 Ipv4Address
438 Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
439  Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
440 {
441  NS_LOG_FUNCTION (device << dst << scope);
442  Ipv4Address addr ("0.0.0.0");
443  Ipv4InterfaceAddress iaddr;
444  bool found = false;
445 
446  if (device != 0)
447  {
448  int32_t i = GetInterfaceForDevice (device);
449  NS_ASSERT_MSG (i >= 0, "No device found on node");
450  for (uint32_t j = 0; j < GetNAddresses (i); j++)
451  {
452  iaddr = GetAddress (i, j);
453  if (iaddr.IsSecondary ())
454  {
455  continue;
456  }
457  if (iaddr.GetScope () > scope)
458  {
459  continue;
460  }
461  if (dst.CombineMask (iaddr.GetMask ()) == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
462  {
463  return iaddr.GetLocal ();
464  }
465  if (!found)
466  {
467  addr = iaddr.GetLocal ();
468  found = true;
469  }
470  }
471  }
472  if (found)
473  {
474  return addr;
475  }
476 
477  // Iterate among all interfaces
478  for (uint32_t i = 0; i < GetNInterfaces (); i++)
479  {
480  for (uint32_t j = 0; j < GetNAddresses (i); j++)
481  {
482  iaddr = GetAddress (i, j);
483  if (iaddr.IsSecondary ())
484  {
485  continue;
486  }
487  if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
488  && iaddr.GetScope () <= scope)
489  {
490  return iaddr.GetLocal ();
491  }
492  }
493  }
494  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
495  << scope << ", returning 0");
496  return addr;
497 }
498 
499 void
500 Ipv4L3ClickProtocol::SetMetric (uint32_t i, uint16_t metric)
501 {
502  NS_LOG_FUNCTION (i << metric);
503  Ptr<Ipv4Interface> interface = GetInterface (i);
504  interface->SetMetric (metric);
505 }
506 
507 uint16_t
508 Ipv4L3ClickProtocol::GetMetric (uint32_t i) const
509 {
510  NS_LOG_FUNCTION (i);
511  Ptr<Ipv4Interface> interface = GetInterface (i);
512  return interface->GetMetric ();
513 }
514 
515 uint16_t
516 Ipv4L3ClickProtocol::GetMtu (uint32_t i) const
517 {
518  NS_LOG_FUNCTION (this << i);
519  Ptr<Ipv4Interface> interface = GetInterface (i);
520  return interface->GetDevice ()->GetMtu ();
521 }
522 
523 bool
524 Ipv4L3ClickProtocol::IsUp (uint32_t i) const
525 {
526  NS_LOG_FUNCTION (this << i);
527  Ptr<Ipv4Interface> interface = GetInterface (i);
528  return interface->IsUp ();
529 }
530 
531 void
532 Ipv4L3ClickProtocol::SetUp (uint32_t i)
533 {
534  NS_LOG_FUNCTION (this << i);
535  Ptr<Ipv4Interface> interface = GetInterface (i);
536  interface->SetUp ();
537 
538  if (m_routingProtocol != 0)
539  {
540  m_routingProtocol->NotifyInterfaceUp (i);
541  }
542 }
543 
544 void
545 Ipv4L3ClickProtocol::SetDown (uint32_t ifaceIndex)
546 {
547  NS_LOG_FUNCTION (this << ifaceIndex);
548  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
549  interface->SetDown ();
550 
551  if (m_routingProtocol != 0)
552  {
553  m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
554  }
555 }
556 
557 bool
558 Ipv4L3ClickProtocol::IsForwarding (uint32_t i) const
559 {
560  NS_LOG_FUNCTION (this << i);
561  Ptr<Ipv4Interface> interface = GetInterface (i);
562  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
563  return interface->IsForwarding ();
564 }
565 
566 void
567 Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val)
568 {
569  NS_LOG_FUNCTION (this << i);
570  Ptr<Ipv4Interface> interface = GetInterface (i);
571  interface->SetForwarding (val);
572 }
573 
574 void
575 Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
576 {
577  NS_ASSERT (i <= m_node->GetNDevices ());
578  Ptr<NetDevice> netdev = GetNetDevice (i);
579  NS_ASSERT (netdev);
580  Ptr<Node> node = GetObject<Node> ();
581  NS_ASSERT (node);
582  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
583  0, netdev,true);
584 }
585 
586 uint32_t
587 Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
588 {
589  NS_LOG_FUNCTION (this << &device);
590  Ptr<Node> node = GetObject<Node> ();
591  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
592  Ipv4L3ClickProtocol::PROT_NUMBER, device);
593  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
594  ArpL3Protocol::PROT_NUMBER, device);
595 
596  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
597  interface->SetNode (m_node);
598  interface->SetDevice (device);
599  interface->SetForwarding (m_ipForward);
600  return AddIpv4Interface (interface);
601 }
602 
603 uint32_t
604 Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
605 {
606  NS_LOG_FUNCTION (this << interface);
607  uint32_t index = m_interfaces.size ();
608  m_interfaces.push_back (interface);
609  return index;
610 }
611 
612 // XXX when should we set ip_id? check whether we are incrementing
613 // m_identification on packets that may later be dropped in this stack
614 // and whether that deviates from Linux
615 Ipv4Header
616 Ipv4L3ClickProtocol::BuildHeader (
617  Ipv4Address source,
618  Ipv4Address destination,
619  uint8_t protocol,
620  uint16_t payloadSize,
621  uint8_t ttl,
622  bool mayFragment)
623 {
625  Ipv4Header ipHeader;
626  ipHeader.SetSource (source);
627  ipHeader.SetDestination (destination);
628  ipHeader.SetProtocol (protocol);
629  ipHeader.SetPayloadSize (payloadSize);
630  ipHeader.SetTtl (ttl);
631  if (mayFragment == true)
632  {
633  ipHeader.SetMayFragment ();
634  ipHeader.SetIdentification (m_identification);
635  m_identification++;
636  }
637  else
638  {
639  ipHeader.SetDontFragment ();
640  // TBD: set to zero here; will cause traces to change
641  ipHeader.SetIdentification (m_identification);
642  m_identification++;
643  }
644  if (Node::ChecksumEnabled ())
645  {
646  ipHeader.EnableChecksum ();
647  }
648  return ipHeader;
649 }
650 
651 void
652 Ipv4L3ClickProtocol::Send (Ptr<Packet> packet,
653  Ipv4Address source,
654  Ipv4Address destination,
655  uint8_t protocol,
656  Ptr<Ipv4Route> route)
657 {
658  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t (protocol) << route);
659 
660  Ipv4Header ipHeader;
661  bool mayFragment = true;
662  uint8_t ttl = m_defaultTtl;
663  SocketIpTtlTag tag;
664  bool found = packet->RemovePacketTag (tag);
665  if (found)
666  {
667  ttl = tag.GetTtl ();
668  }
669 
670  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
671  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
672  if (Node::ChecksumEnabled ())
673  {
674  ipHeader.EnableChecksum ();
675  }
676  packet->AddHeader (ipHeader);
677  click->Send (packet->Copy (), source, destination);
678  return;
679 }
680 
681 void
682 Ipv4L3ClickProtocol::SendWithHeader (Ptr<Packet> packet,
683  Ipv4Header ipHeader,
684  Ptr<Ipv4Route> route)
685 {
686  NS_LOG_FUNCTION (this << packet << ipHeader << route);
687 
688  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
689  if (Node::ChecksumEnabled ())
690  {
691  ipHeader.EnableChecksum ();
692  }
693  packet->AddHeader (ipHeader);
694  click->Send (packet->Copy (), ipHeader.GetSource (), ipHeader.GetDestination ());
695 }
696 
697 void
698 Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p, int ifid)
699 {
700  // Called by Ipv4ClickRouting.
701 
702  // NetDevice::Send () attaches ethernet headers,
703  // so the one that Click attaches isn't required
704  // but we need the destination address and
705  // protocol values from the header.
706 
707  Ptr<NetDevice> netdev = GetNetDevice (ifid);
708 
709  EthernetHeader header;
710  p->RemoveHeader (header);
711 
712  uint16_t protocol;
713 
714  if (header.GetLengthType () <= 1500)
715  {
716  LlcSnapHeader llc;
717  p->RemoveHeader (llc);
718  protocol = llc.GetType ();
719  }
720  else
721  {
722  protocol = header.GetLengthType ();
723  }
724 
725  // Use the destination address and protocol obtained
726  // from above to send the packet.
727  netdev->Send (p, header.GetDestination (), protocol);
728 }
729 
730 void
731 Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
732  const Address &to, NetDevice::PacketType packetType)
733 {
734  NS_LOG_FUNCTION (this << device << p << from << to);
735 
736  // Forward packet to raw sockets, if any
737  if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
738  {
739  Ptr<Packet> packetForRawSocket = p->Copy ();
740  uint32_t interface = 0;
741  Ptr<Ipv4Interface> ipv4Interface;
742  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
743  i != m_interfaces.end ();
744  i++, interface++)
745  {
746  ipv4Interface = *i;
747  if (ipv4Interface->GetDevice () == device)
748  {
749  if (ipv4Interface->IsUp ())
750  {
751  break;
752  }
753  else
754  {
755  NS_LOG_LOGIC ("Dropping received packet -- interface is down");
756  return;
757  }
758  }
759  }
760 
761  Ipv4Header ipHeader;
762  if (Node::ChecksumEnabled ())
763  {
764  ipHeader.EnableChecksum ();
765  }
766  packetForRawSocket->RemoveHeader (ipHeader);
767 
768 
769  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
770  {
771  NS_LOG_LOGIC ("Forwarding to raw socket");
772  Ptr<Ipv4RawSocketImpl> socket = *i;
773  socket->ForwardUp (packetForRawSocket, ipHeader, ipv4Interface);
774  }
775  }
776 
777  Ptr<Packet> packet = p->Copy ();
778 
779  // Add an ethernet frame. This allows
780  // Click to work with csma and wifi
781  EthernetHeader hdr;
782  hdr.SetSource (Mac48Address::ConvertFrom (from));
783  hdr.SetDestination (Mac48Address::ConvertFrom (to));
784  hdr.SetLengthType (protocol);
785  packet->AddHeader (hdr);
786 
787  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
788  click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
789 }
790 
791 void
792 Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
793 {
794  NS_LOG_FUNCTION (this << packet << &ip);
795  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
796 
797  m_localDeliverTrace (ip, packet, iif);
798 
799  Ptr<IpL4Protocol> protocol = GetProtocol (ip.GetProtocol ());
800  if (protocol != 0)
801  {
802  // we need to make a copy in the unlikely event we hit the
803  // RX_ENDPOINT_UNREACH codepath
804  Ptr<Packet> copy = p->Copy ();
805  enum IpL4Protocol::RxStatus status =
806  protocol->Receive (p, ip, GetInterface (iif));
807  switch (status)
808  {
809  case IpL4Protocol::RX_OK:
810  // fall through
811  case IpL4Protocol::RX_ENDPOINT_CLOSED:
812  // fall through
813  case IpL4Protocol::RX_CSUM_FAILED:
814  break;
815  case IpL4Protocol::RX_ENDPOINT_UNREACH:
816  if (ip.GetDestination ().IsBroadcast () == true
817  || ip.GetDestination ().IsMulticast () == true)
818  {
819  break; // Do not reply to broadcast or multicast
820  }
821  // Another case to suppress ICMP is a subnet-directed broadcast
822  bool subnetDirected = false;
823  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
824  {
825  Ipv4InterfaceAddress addr = GetAddress (iif, i);
826  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination ().CombineMask (addr.GetMask ())
827  && ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
828  {
829  subnetDirected = true;
830  }
831  }
832  if (subnetDirected == false)
833  {
834  GetIcmp ()->SendDestUnreachPort (ip, copy);
835  }
836  }
837  }
838 }
839 
840 Ptr<Icmpv4L4Protocol>
841 Ipv4L3ClickProtocol::GetIcmp (void) const
842 {
843  Ptr<IpL4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
844  if (prot != 0)
845  {
846  return prot->GetObject<Icmpv4L4Protocol> ();
847  }
848  else
849  {
850  return 0;
851  }
852 }
853 
854 void
855 Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol)
856 {
857  m_protocols.push_back (protocol);
858 }
859 
860 Ptr<IpL4Protocol>
861 Ipv4L3ClickProtocol::GetProtocol (int protocolNumber) const
862 {
863  for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
864  {
865  if ((*i)->GetProtocolNumber () == protocolNumber)
866  {
867  return *i;
868  }
869  }
870  return 0;
871 }
872 
873 
874 } // namespace ns3
875 
876 #endif // NS3_CLICK
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:311
static bool ChecksumEnabled(void)
Definition: node.cc:267
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void DoDispose(void)
Definition: object.cc:335
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
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.
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 void DeleteRawSocket(Ptr< Socket > socket)=0
Deletes a particular raw socket.
virtual Ptr< IpL4Protocol > GetProtocol(int protocolNumber) const =0
virtual void SetUp(uint32_t interface)=0
virtual uint16_t GetMetric(uint32_t interface) const =0
virtual enum RxStatus Receive(Ptr< Packet > p, Ipv4Header const &header, Ptr< Ipv4Interface > incomingInterface)=0
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
virtual void SendWithHeader(Ptr< Packet > packet, Ipv4Header ipHeader, Ptr< Ipv4Route > route)=0
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
static Mac48Address ConvertFrom(const Address &address)
virtual void NotifyNewAggregate(void)
Definition: object.cc:314
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 Insert(Ptr< IpL4Protocol > protocol)=0
#define NS_LOG_WARN(msg)
Definition: log.h:246
virtual Ipv4InterfaceAddress GetAddress(uint32_t interface, uint32_t addressIndex) const =0
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
virtual int32_t GetInterfaceForAddress(Ipv4Address address) const =0
Return the interface number of the interface that has been assigned the specified IP address...
virtual void SetDown(uint32_t interface)=0
virtual bool RemoveAddress(uint32_t interface, uint32_t addressIndex)=0
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.