A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-interface.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006,2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "ipv4-interface.h"
10
11#include "arp-cache.h"
12#include "arp-l3-protocol.h"
13#include "ipv4-l3-protocol.h"
15#include "loopback-net-device.h"
16
17#include "ns3/log.h"
18#include "ns3/net-device.h"
19#include "ns3/node.h"
20#include "ns3/packet.h"
21#include "ns3/pointer.h"
22#include "ns3/traffic-control-layer.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("Ipv4Interface");
28
29NS_OBJECT_ENSURE_REGISTERED(Ipv4Interface);
30
31TypeId
33{
34 static TypeId tid = TypeId("ns3::Ipv4Interface")
36 .SetGroupName("Internet")
37 .AddAttribute("ArpCache",
38 "The arp cache for this ipv4 interface",
39 PointerValue(nullptr),
43 ;
44 return tid;
45}
46
47/**
48 * By default, Ipv4 interface are created in the "down" state
49 * with no IP addresses. Before becoming usable, the user must
50 * invoke SetUp on them once an Ipv4 address and mask have been set.
51 */
53 : m_ifup(false),
54 m_forwarding(true),
55 m_metric(1),
56 m_node(nullptr),
57 m_device(nullptr),
58 m_tc(nullptr),
59 m_cache(nullptr)
60{
61 NS_LOG_FUNCTION(this);
62}
63
68
69void
71{
72 NS_LOG_FUNCTION(this);
73 m_node = nullptr;
74 m_device = nullptr;
75 m_tc = nullptr;
76 m_cache = nullptr;
78}
79
80void
82{
83 NS_LOG_FUNCTION(this << node);
84 m_node = node;
85 DoSetup();
86}
87
88void
90{
91 NS_LOG_FUNCTION(this << device);
92 m_device = device;
93 DoSetup();
94}
95
96void
102
103void
105{
106 NS_LOG_FUNCTION(this);
107 if (!m_node || !m_device)
108 {
109 return;
110 }
111 if (!m_device->NeedsArp())
112 {
113 return;
114 }
116 m_cache = arp->CreateCache(m_device, this);
117}
118
121{
122 NS_LOG_FUNCTION(this);
123 return m_device;
124}
125
126void
128{
129 NS_LOG_FUNCTION(this << metric);
130 m_metric = metric;
131}
132
133uint16_t
135{
136 NS_LOG_FUNCTION(this);
137 return m_metric;
138}
139
140void
146
149{
150 NS_LOG_FUNCTION(this);
151 return m_cache;
152}
153
154/**
155 * These are IP interface states and may be distinct from
156 * NetDevice states, such as found in real implementations
157 * (where the device may be down but IP interface state is still up).
158 */
159bool
161{
162 NS_LOG_FUNCTION(this);
163 return m_ifup;
164}
165
166bool
168{
169 NS_LOG_FUNCTION(this);
170 return !m_ifup;
171}
172
173void
175{
176 NS_LOG_FUNCTION(this);
177 m_ifup = true;
178}
179
180void
182{
183 NS_LOG_FUNCTION(this);
184 m_ifup = false;
185}
186
187bool
189{
190 NS_LOG_FUNCTION(this);
191 return m_forwarding;
192}
193
194void
196{
197 NS_LOG_FUNCTION(this << val);
198 m_forwarding = val;
199}
200
201void
203{
204 NS_LOG_FUNCTION(this << *p << dest);
205 if (!IsUp())
206 {
207 return;
208 }
209
210 // Check for a loopback device, if it's the case we don't pass through
211 // traffic control layer
213 {
214 /// \todo additional checks needed here (such as whether multicast
215 /// goes to loopback)?
216 p->AddHeader(hdr);
217 m_device->Send(p, m_device->GetBroadcast(), Ipv4L3Protocol::PROT_NUMBER);
218 return;
219 }
220
222
223 // is this packet aimed at a local interface ?
224 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
225 {
226 if (dest == (*i).GetLocal())
227 {
228 p->AddHeader(hdr);
230 m_tc,
231 m_device,
232 p,
234 m_device->GetBroadcast(),
235 m_device->GetBroadcast(),
237 return;
238 }
239 }
240 if (m_device->NeedsArp())
241 {
242 NS_LOG_LOGIC("Needs ARP"
243 << " " << dest);
245 Address hardwareDestination;
246 bool found = false;
247 if (dest.IsBroadcast())
248 {
249 NS_LOG_LOGIC("All-network Broadcast");
250 hardwareDestination = m_device->GetBroadcast();
251 found = true;
252 }
253 else if (dest.IsMulticast())
254 {
255 NS_LOG_LOGIC("IsMulticast");
256 NS_ASSERT_MSG(m_device->IsMulticast(),
257 "ArpIpv4Interface::SendTo (): Sending multicast packet over "
258 "non-multicast device");
259
260 hardwareDestination = m_device->GetMulticast(dest);
261 found = true;
262 }
263 else
264 {
265 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
266 {
267 if (dest.IsSubnetDirectedBroadcast((*i).GetMask()))
268 {
269 NS_LOG_LOGIC("Subnetwork Broadcast");
270 hardwareDestination = m_device->GetBroadcast();
271 found = true;
272 break;
273 }
274 }
275 if (!found)
276 {
277 NS_LOG_LOGIC("ARP Lookup");
278 found = arp->Lookup(p, hdr, dest, m_device, m_cache, &hardwareDestination);
279 }
280 }
281
282 if (found)
283 {
284 NS_LOG_LOGIC("Address Resolved. Send.");
285 m_tc->Send(m_device,
287 hardwareDestination,
289 hdr));
290 }
291 }
292 else
293 {
294 NS_LOG_LOGIC("Doesn't need ARP");
295 m_tc->Send(m_device,
297 m_device->GetBroadcast(),
299 hdr));
300 }
301}
302
305{
306 NS_LOG_FUNCTION(this);
307 return m_ifaddrs.size();
308}
309
310bool
312{
313 NS_LOG_FUNCTION(this << addr);
314 m_ifaddrs.push_back(addr);
315 if (!m_addAddressCallback.IsNull())
316 {
317 m_addAddressCallback(this, addr);
318 }
319 return true;
320}
321
324{
325 NS_LOG_FUNCTION(this << index);
326 if (index < m_ifaddrs.size())
327 {
328 uint32_t tmp = 0;
329 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); i++)
330 {
331 if (tmp == index)
332 {
333 return *i;
334 }
335 ++tmp;
336 }
337 }
338 else
339 {
340 NS_FATAL_ERROR("index " << index << " out of bounds");
341 }
343 return addr; // quiet compiler
344}
345
348{
349 NS_LOG_FUNCTION(this << index);
350 if (index >= m_ifaddrs.size())
351 {
352 NS_FATAL_ERROR("Bug in Ipv4Interface::RemoveAddress");
353 }
354 auto i = m_ifaddrs.begin();
355 uint32_t tmp = 0;
356 while (i != m_ifaddrs.end())
357 {
358 if (tmp == index)
359 {
360 Ipv4InterfaceAddress addr = *i;
361 m_ifaddrs.erase(i);
362 if (!m_removeAddressCallback.IsNull())
363 {
364 m_removeAddressCallback(this, addr);
365 }
366 return addr;
367 }
368 ++tmp;
369 ++i;
370 }
371 NS_FATAL_ERROR("Address " << index << " not found");
373 return addr; // quiet compiler
374}
375
378{
379 NS_LOG_FUNCTION(this << address);
380
381 if (address == Ipv4Address::GetLoopback())
382 {
383 NS_LOG_WARN("Cannot remove loopback address.");
384 return Ipv4InterfaceAddress();
385 }
386
387 for (auto it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
388 {
389 if ((*it).GetLocal() == address)
390 {
391 Ipv4InterfaceAddress ifAddr = *it;
392 m_ifaddrs.erase(it);
393 if (!m_removeAddressCallback.IsNull())
394 {
395 m_removeAddressCallback(this, ifAddr);
396 }
397 return ifAddr;
398 }
399 }
400 return Ipv4InterfaceAddress();
401}
402
403void
405 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
406{
407 NS_LOG_FUNCTION(this << &removeAddressCallback);
408 m_removeAddressCallback = removeAddressCallback;
409}
410
411void
413 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback)
414{
415 NS_LOG_FUNCTION(this << &addAddressCallback);
416 m_addAddressCallback = addAddressCallback;
417}
418
419} // namespace ns3
a polymophic address class
Definition address.h:90
An implementation of the ARP protocol.
Callback template class.
Definition callback.h:422
Ipv4 addresses are stored in host order in this class.
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:23
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:290
A base class which provides memory management and object aggregation.
Definition object.h:78
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
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:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
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:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580