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 " << dest);
244 Address hardwareDestination;
245 bool found = false;
246 if (dest.IsBroadcast())
247 {
248 NS_LOG_LOGIC("All-network Broadcast");
249 hardwareDestination = m_device->GetBroadcast();
250 found = true;
251 }
252 else if (dest.IsMulticast())
253 {
254 NS_LOG_LOGIC("IsMulticast");
255 NS_ASSERT_MSG(m_device->IsMulticast(),
256 "ArpIpv4Interface::SendTo (): Sending multicast packet over "
257 "non-multicast device");
258
259 hardwareDestination = m_device->GetMulticast(dest);
260 found = true;
261 }
262 else
263 {
264 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
265 {
266 if (dest.IsSubnetDirectedBroadcast((*i).GetMask()))
267 {
268 NS_LOG_LOGIC("Subnetwork Broadcast");
269 hardwareDestination = m_device->GetBroadcast();
270 found = true;
271 break;
272 }
273 }
274 if (!found)
275 {
276 NS_LOG_LOGIC("ARP Lookup");
277 found = arp->Lookup(p, hdr, dest, m_device, m_cache, &hardwareDestination);
278 }
279 }
280
281 if (found)
282 {
283 NS_LOG_LOGIC("Address Resolved. Send.");
284 m_tc->Send(m_device,
286 hardwareDestination,
288 hdr));
289 }
290 }
291 else
292 {
293 NS_LOG_LOGIC("Doesn't need ARP");
294 m_tc->Send(m_device,
296 m_device->GetBroadcast(),
298 hdr));
299 }
300}
301
304{
305 NS_LOG_FUNCTION(this);
306 return m_ifaddrs.size();
307}
308
309bool
311{
312 NS_LOG_FUNCTION(this << addr);
313 m_ifaddrs.push_back(addr);
314 if (!m_addAddressCallback.IsNull())
315 {
316 m_addAddressCallback(this, addr);
317 }
318 return true;
319}
320
323{
324 NS_LOG_FUNCTION(this << index);
325 if (index >= m_ifaddrs.size())
326 {
327 NS_FATAL_ERROR("index " << index << " out of bounds");
328 }
329
330 uint32_t tmp = 0;
331 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); i++)
332 {
333 if (tmp == index)
334 {
335 return *i;
336 }
337 ++tmp;
338 }
339
340 return {}; // quiet compiler
341}
342
345{
346 NS_LOG_FUNCTION(this << index);
347 if (index >= m_ifaddrs.size())
348 {
349 NS_FATAL_ERROR("Bug in Ipv4Interface::RemoveAddress");
350 }
351
352 uint32_t tmp = 0;
353 for (auto it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
354 {
355 if (tmp == index)
356 {
357 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
358 Ipv4InterfaceAddress addr = *it;
359
360 m_ifaddrs.erase(it);
361 if (!m_removeAddressCallback.IsNull())
362 {
363 m_removeAddressCallback(this, addr);
364 }
365 return addr;
366 }
367 ++tmp;
368 }
369 NS_FATAL_ERROR("Address " << index << " not found");
370 return {}; // quiet compiler
371}
372
375{
376 NS_LOG_FUNCTION(this << address);
377
378 if (address == Ipv4Address::GetLoopback())
379 {
380 NS_LOG_WARN("Cannot remove loopback address.");
381 return Ipv4InterfaceAddress();
382 }
383
384 for (auto it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
385 {
386 if ((*it).GetLocal() == address)
387 {
388 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
389 Ipv4InterfaceAddress ifAddr = *it;
390
391 m_ifaddrs.erase(it);
392 if (!m_removeAddressCallback.IsNull())
393 {
394 m_removeAddressCallback(this, ifAddr);
395 }
396 return ifAddr;
397 }
398 }
399 return {};
400}
401
402void
404 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
405{
406 NS_LOG_FUNCTION(this << &removeAddressCallback);
407 m_removeAddressCallback = removeAddressCallback;
408}
409
410void
412 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback)
413{
414 NS_LOG_FUNCTION(this << &addAddressCallback);
415 m_addAddressCallback = addAddressCallback;
416}
417
418} // 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 constexpr uint16_t PROT_NUMBER
Protocol number.
@ 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:595
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:49
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