A Discrete-Event Network Simulator
API
ipv4-interface.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ipv4-interface.h"
22 #include "loopback-net-device.h"
23 #include "ipv4-l3-protocol.h"
24 #include "ipv4-queue-disc-item.h"
25 #include "arp-l3-protocol.h"
26 #include "arp-cache.h"
27 #include "ns3/net-device.h"
28 #include "ns3/log.h"
29 #include "ns3/packet.h"
30 #include "ns3/node.h"
31 #include "ns3/pointer.h"
32 #include "ns3/traffic-control-layer.h"
33 
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
38 
39 NS_OBJECT_ENSURE_REGISTERED (Ipv4Interface);
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::Ipv4Interface")
45  .SetParent<Object> ()
46  .SetGroupName ("Internet")
47  .AddAttribute ("ArpCache",
48  "The arp cache for this ipv4 interface",
49  PointerValue (0),
52  MakePointerChecker<ArpCache> ())
53  ;
54  ;
55  return tid;
56 }
57 
64  : m_ifup (false),
65  m_forwarding (true),
66  m_metric (1),
67  m_node (0),
68  m_device (0),
69  m_tc (0),
70  m_cache (0)
71 {
72  NS_LOG_FUNCTION (this);
73 }
74 
76 {
77  NS_LOG_FUNCTION (this);
78 }
79 
80 void
82 {
83  NS_LOG_FUNCTION (this);
84  m_node = 0;
85  m_device = 0;
86  m_tc = 0;
87  m_cache = 0;
89 }
90 
91 void
93 {
94  NS_LOG_FUNCTION (this << node);
95  m_node = node;
96  DoSetup ();
97 }
98 
99 void
101 {
102  NS_LOG_FUNCTION (this << device);
103  m_device = device;
104  DoSetup ();
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION (this << tc);
111  m_tc = tc;
112 }
113 
114 void
116 {
117  NS_LOG_FUNCTION (this);
118  if (m_node == 0 || m_device == 0)
119  {
120  return;
121  }
122  if (!m_device->NeedsArp ())
123  {
124  return;
125  }
127  m_cache = arp->CreateCache (m_device, this);
128 }
129 
132 {
133  NS_LOG_FUNCTION (this);
134  return m_device;
135 }
136 
137 void
138 Ipv4Interface::SetMetric (uint16_t metric)
139 {
140  NS_LOG_FUNCTION (this << metric);
141  m_metric = metric;
142 }
143 
144 uint16_t
146 {
147  NS_LOG_FUNCTION (this);
148  return m_metric;
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION (this << a);
155  m_cache = a;
156 }
157 
160 {
161  NS_LOG_FUNCTION (this);
162  return m_cache;
163 }
164 
170 bool
172 {
173  NS_LOG_FUNCTION (this);
174  return m_ifup;
175 }
176 
177 bool
179 {
180  NS_LOG_FUNCTION (this);
181  return !m_ifup;
182 }
183 
184 void
186 {
187  NS_LOG_FUNCTION (this);
188  m_ifup = true;
189 }
190 
191 void
193 {
194  NS_LOG_FUNCTION (this);
195  m_ifup = false;
196 }
197 
198 bool
200 {
201  NS_LOG_FUNCTION (this);
202  return m_forwarding;
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION (this << val);
209  m_forwarding = val;
210 }
211 
212 void
214 {
215  NS_LOG_FUNCTION (this << *p << dest);
216  if (!IsUp ())
217  {
218  return;
219  }
220 
221  // Check for a loopback device, if it's the case we don't pass through
222  // traffic control layer
223  if (DynamicCast<LoopbackNetDevice> (m_device))
224  {
227  p->AddHeader (hdr);
228  m_device->Send (p, m_device->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER);
229  return;
230  }
231 
232  NS_ASSERT (m_tc != 0);
233 
234  // is this packet aimed at a local interface ?
235  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
236  {
237  if (dest == (*i).GetLocal ())
238  {
239  p->AddHeader (hdr);
241  m_device->GetBroadcast (),
242  m_device->GetBroadcast (),
244  return;
245  }
246  }
247  if (m_device->NeedsArp ())
248  {
249  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
251  Address hardwareDestination;
252  bool found = false;
253  if (dest.IsBroadcast ())
254  {
255  NS_LOG_LOGIC ("All-network Broadcast");
256  hardwareDestination = m_device->GetBroadcast ();
257  found = true;
258  }
259  else if (dest.IsMulticast ())
260  {
261  NS_LOG_LOGIC ("IsMulticast");
262  NS_ASSERT_MSG (m_device->IsMulticast (),
263  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
264  "non-multicast device");
265 
266  hardwareDestination = m_device->GetMulticast (dest);
267  found = true;
268  }
269  else
270  {
271  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
272  {
273  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
274  {
275  NS_LOG_LOGIC ("Subnetwork Broadcast");
276  hardwareDestination = m_device->GetBroadcast ();
277  found = true;
278  break;
279  }
280  }
281  if (!found)
282  {
283  NS_LOG_LOGIC ("ARP Lookup");
284  found = arp->Lookup (p, hdr, dest, m_device, m_cache, &hardwareDestination);
285  }
286  }
287 
288  if (found)
289  {
290  NS_LOG_LOGIC ("Address Resolved. Send.");
291  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER, hdr));
292  }
293  }
294  else
295  {
296  NS_LOG_LOGIC ("Doesn't need ARP");
297  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, m_device->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER, hdr));
298  }
299 }
300 
301 uint32_t
303 {
304  NS_LOG_FUNCTION (this);
305  return m_ifaddrs.size ();
306 }
307 
308 bool
310 {
311  NS_LOG_FUNCTION (this << addr);
312  m_ifaddrs.push_back (addr);
313  return true;
314 }
315 
317 Ipv4Interface::GetAddress (uint32_t index) const
318 {
319  NS_LOG_FUNCTION (this << index);
320  if (index < m_ifaddrs.size ())
321  {
322  uint32_t tmp = 0;
323  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
324  {
325  if (tmp == index)
326  {
327  return *i;
328  }
329  ++tmp;
330  }
331  }
332  else
333  {
334  NS_FATAL_ERROR ("index " << index << " out of bounds");
335  }
337  return (addr); // quiet compiler
338 }
339 
342 {
343  NS_LOG_FUNCTION (this << index);
344  if (index >= m_ifaddrs.size ())
345  {
346  NS_FATAL_ERROR ("Bug in Ipv4Interface::RemoveAddress");
347  }
349  uint32_t tmp = 0;
350  while (i != m_ifaddrs.end ())
351  {
352  if (tmp == index)
353  {
354  Ipv4InterfaceAddress addr = *i;
355  m_ifaddrs.erase (i);
356  return addr;
357  }
358  ++tmp;
359  ++i;
360  }
361  NS_FATAL_ERROR ("Address " << index << " not found");
363  return (addr); // quiet compiler
364 }
365 
368 {
369  NS_LOG_FUNCTION(this << address);
370 
371  if (address == address.GetLoopback())
372  {
373  NS_LOG_WARN ("Cannot remove loopback address.");
374  return Ipv4InterfaceAddress();
375  }
376 
377  for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
378  {
379  if((*it).GetLocal() == address)
380  {
381  Ipv4InterfaceAddress ifAddr = *it;
382  m_ifaddrs.erase(it);
383  return ifAddr;
384  }
385  }
386  return Ipv4InterfaceAddress();
387 }
388 
389 } // namespace ns3
390 
void SetDown(void)
Disable this interface.
void SetForwarding(bool val)
Ipv4Interface()
By default, Ipv4 interface are created in the "down" state with no IP addresses.
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Ptr< ArpCache > GetArpCache() const
bool IsMulticast(void) const
Ipv4InterfaceAddress RemoveAddress(uint32_t index)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
bool AddAddress(Ipv4InterfaceAddress address)
Packet addressed oo us.
Definition: net-device.h:298
Ptr< NetDevice > m_device
The associated NetDevice.
Ptr< ArpCache > m_cache
ARP cache.
void SetNode(Ptr< Node > node)
Set node associated with interface.
a polymophic address class
Definition: address.h:90
std::list< Ipv4InterfaceAddress >::const_iterator Ipv4InterfaceAddressListCI
Container Iterator for the Ipv4InterfaceAddresses.
bool m_forwarding
Forwarding state.
bool IsSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
Packet header for IPv4.
Definition: ipv4-header.h:33
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:220
static TypeId GetTypeId(void)
Get the type ID.
void SetTrafficControl(Ptr< TrafficControlLayer > tc)
Set the TrafficControlLayer.
bool IsBroadcast(void) const
Ptr< TrafficControlLayer > m_tc
The associated TrafficControlLayer.
void SetDevice(Ptr< NetDevice > device)
Set the NetDevice.
Ipv4InterfaceAddressList m_ifaddrs
Address list.
Ipv4InterfaceAddress GetAddress(uint32_t index) const
virtual ~Ipv4Interface()
bool IsDown(void) const
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr.
Definition: pointer.h:36
std::list< Ipv4InterfaceAddress >::iterator Ipv4InterfaceAddressListI
Const Container Iterator for the Ipv4InterfaceAddresses.
static Ipv4Address GetLoopback(void)
Ptr< Node > m_node
The associated node.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
uint16_t GetMetric(void) const
#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:90
uint16_t m_metric
Interface metric.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void SetArpCache(Ptr< ArpCache > arpCache)
Set ARP cache used by this interface.
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
Ptr< NetDevice > GetDevice(void) const
bool m_ifup
The state of this interface.
An implementation of the ARP protocol.
void SetMetric(uint16_t metric)
A base class which provides memory management and object aggregation.
Definition: object.h:87
tuple address
Definition: first.py:37
void DoSetup(void)
Initialize interface.
virtual void DoDispose(void)
Destructor implementation.
uint32_t GetNAddresses(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
bool IsForwarding(void) const
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
bool IsUp(void) const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetUp(void)
Enable this interface.