A Discrete-Event Network Simulator
API
ipv4-interface.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 
20 #include "ipv4-interface.h"
21 
22 #include "arp-cache.h"
23 #include "arp-l3-protocol.h"
24 #include "ipv4-l3-protocol.h"
25 #include "ipv4-queue-disc-item.h"
26 #include "loopback-net-device.h"
27 
28 #include "ns3/log.h"
29 #include "ns3/net-device.h"
30 #include "ns3/node.h"
31 #include "ns3/packet.h"
32 #include "ns3/pointer.h"
33 #include "ns3/traffic-control-layer.h"
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("Ipv4Interface");
39 
40 NS_OBJECT_ENSURE_REGISTERED(Ipv4Interface);
41 
42 TypeId
44 {
45  static TypeId tid = TypeId("ns3::Ipv4Interface")
46  .SetParent<Object>()
47  .SetGroupName("Internet")
48  .AddAttribute("ArpCache",
49  "The arp cache for this ipv4 interface",
50  PointerValue(nullptr),
53  MakePointerChecker<ArpCache>());
54  ;
55  return tid;
56 }
57 
64  : m_ifup(false),
65  m_forwarding(true),
66  m_metric(1),
67  m_node(nullptr),
68  m_device(nullptr),
69  m_tc(nullptr),
70  m_cache(nullptr)
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 = nullptr;
85  m_device = nullptr;
86  m_tc = nullptr;
87  m_cache = nullptr;
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 || !m_device)
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);
233 
234  // is this packet aimed at a local interface ?
235  for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
236  {
237  if (dest == (*i).GetLocal())
238  {
239  p->AddHeader(hdr);
241  m_tc,
242  m_device,
243  p,
245  m_device->GetBroadcast(),
246  m_device->GetBroadcast(),
248  return;
249  }
250  }
251  if (m_device->NeedsArp())
252  {
253  NS_LOG_LOGIC("Needs ARP"
254  << " " << dest);
256  Address hardwareDestination;
257  bool found = false;
258  if (dest.IsBroadcast())
259  {
260  NS_LOG_LOGIC("All-network Broadcast");
261  hardwareDestination = m_device->GetBroadcast();
262  found = true;
263  }
264  else if (dest.IsMulticast())
265  {
266  NS_LOG_LOGIC("IsMulticast");
267  NS_ASSERT_MSG(m_device->IsMulticast(),
268  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
269  "non-multicast device");
270 
271  hardwareDestination = m_device->GetMulticast(dest);
272  found = true;
273  }
274  else
275  {
276  for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
277  {
278  if (dest.IsSubnetDirectedBroadcast((*i).GetMask()))
279  {
280  NS_LOG_LOGIC("Subnetwork Broadcast");
281  hardwareDestination = m_device->GetBroadcast();
282  found = true;
283  break;
284  }
285  }
286  if (!found)
287  {
288  NS_LOG_LOGIC("ARP Lookup");
289  found = arp->Lookup(p, hdr, dest, m_device, m_cache, &hardwareDestination);
290  }
291  }
292 
293  if (found)
294  {
295  NS_LOG_LOGIC("Address Resolved. Send.");
296  m_tc->Send(m_device,
297  Create<Ipv4QueueDiscItem>(p,
298  hardwareDestination,
300  hdr));
301  }
302  }
303  else
304  {
305  NS_LOG_LOGIC("Doesn't need ARP");
306  m_tc->Send(m_device,
307  Create<Ipv4QueueDiscItem>(p,
308  m_device->GetBroadcast(),
310  hdr));
311  }
312 }
313 
314 uint32_t
316 {
317  NS_LOG_FUNCTION(this);
318  return m_ifaddrs.size();
319 }
320 
321 bool
323 {
324  NS_LOG_FUNCTION(this << addr);
325  m_ifaddrs.push_back(addr);
326  if (!m_addAddressCallback.IsNull())
327  {
328  m_addAddressCallback(this, addr);
329  }
330  return true;
331 }
332 
334 Ipv4Interface::GetAddress(uint32_t index) const
335 {
336  NS_LOG_FUNCTION(this << index);
337  if (index < m_ifaddrs.size())
338  {
339  uint32_t tmp = 0;
340  for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); i++)
341  {
342  if (tmp == index)
343  {
344  return *i;
345  }
346  ++tmp;
347  }
348  }
349  else
350  {
351  NS_FATAL_ERROR("index " << index << " out of bounds");
352  }
354  return addr; // quiet compiler
355 }
356 
359 {
360  NS_LOG_FUNCTION(this << index);
361  if (index >= m_ifaddrs.size())
362  {
363  NS_FATAL_ERROR("Bug in Ipv4Interface::RemoveAddress");
364  }
365  auto i = m_ifaddrs.begin();
366  uint32_t tmp = 0;
367  while (i != m_ifaddrs.end())
368  {
369  if (tmp == index)
370  {
371  Ipv4InterfaceAddress addr = *i;
372  m_ifaddrs.erase(i);
373  if (!m_removeAddressCallback.IsNull())
374  {
375  m_removeAddressCallback(this, addr);
376  }
377  return addr;
378  }
379  ++tmp;
380  ++i;
381  }
382  NS_FATAL_ERROR("Address " << index << " not found");
384  return addr; // quiet compiler
385 }
386 
389 {
390  NS_LOG_FUNCTION(this << address);
391 
393  {
394  NS_LOG_WARN("Cannot remove loopback address.");
395  return Ipv4InterfaceAddress();
396  }
397 
398  for (auto it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
399  {
400  if ((*it).GetLocal() == address)
401  {
402  Ipv4InterfaceAddress ifAddr = *it;
403  m_ifaddrs.erase(it);
404  if (!m_removeAddressCallback.IsNull())
405  {
406  m_removeAddressCallback(this, ifAddr);
407  }
408  return ifAddr;
409  }
410  }
411  return Ipv4InterfaceAddress();
412 }
413 
414 void
416  Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
417 {
418  NS_LOG_FUNCTION(this << &removeAddressCallback);
419  m_removeAddressCallback = removeAddressCallback;
420 }
421 
422 void
424  Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback)
425 {
426  NS_LOG_FUNCTION(this << &addAddressCallback);
427  m_addAddressCallback = addAddressCallback;
428 }
429 
430 } // namespace ns3
a polymophic address class
Definition: address.h:101
An implementation of the ARP protocol.
Callback template class.
Definition: callback.h:438
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetLoopback()
bool IsMulticast() const
bool IsSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
bool IsBroadcast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
a class to store IPv4 address information on an interface
static TypeId GetTypeId()
Get the type ID.
uint32_t GetNAddresses() const
Ptr< Node > m_node
The associated node.
void SetArpCache(Ptr< ArpCache > arpCache)
Set ARP cache used by this interface.
Ipv4Interface()
By default, Ipv4 interface are created in the "down" state with no IP addresses.
~Ipv4Interface() override
void RemoveAddressCallback(Callback< void, Ptr< Ipv4Interface >, Ipv4InterfaceAddress > removeAddressCallback)
This callback is set when an address is removed from an interface with auto-generated Arp cache and i...
void SetNode(Ptr< Node > node)
Set node associated with interface.
Ipv4InterfaceAddress GetAddress(uint32_t index) const
Ptr< TrafficControlLayer > m_tc
The associated TrafficControlLayer.
bool AddAddress(Ipv4InterfaceAddress address)
void SetTrafficControl(Ptr< TrafficControlLayer > tc)
Set the TrafficControlLayer.
bool m_forwarding
Forwarding state.
uint16_t GetMetric() const
Ptr< NetDevice > m_device
The associated NetDevice.
bool IsUp() const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetUp()
Enable this interface.
Ptr< ArpCache > GetArpCache() const
void SetDevice(Ptr< NetDevice > device)
Set the NetDevice.
void DoSetup()
Initialize interface.
Ptr< NetDevice > GetDevice() const
Ipv4InterfaceAddressList m_ifaddrs
Address list.
Callback< void, Ptr< Ipv4Interface >, Ipv4InterfaceAddress > m_addAddressCallback
add address callback
uint16_t m_metric
Interface metric.
void SetDown()
Disable this interface.
bool IsForwarding() const
void AddAddressCallback(Callback< void, Ptr< Ipv4Interface >, Ipv4InterfaceAddress > addAddressCallback)
This callback is set when an address is added from an interface with auto-generated Arp cache and it ...
void DoDispose() override
Destructor implementation.
Ptr< ArpCache > m_cache
ARP cache.
Callback< void, Ptr< Ipv4Interface >, Ipv4InterfaceAddress > m_removeAddressCallback
remove address callback
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
bool m_ifup
The state of this interface.
void SetForwarding(bool val)
void SetMetric(uint16_t metric)
Ipv4InterfaceAddress RemoveAddress(uint32_t index)
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227