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 =
35 TypeId("ns3::Ipv4Interface")
37 .SetGroupName("Internet")
38 .AddAttribute(
39 "ArpCache",
40 "The arp cache for this ipv4 interface",
41 PointerValue(nullptr),
44 .AddTraceSource("InterfaceStatus",
45 "Interface has been set up or down.",
47 "ns3::Ipv4Address::TracedCallback");
48 return tid;
49}
50
51/**
52 * By default, Ipv4 interface are created in the "down" state
53 * with no IP addresses. Before becoming usable, the user must
54 * invoke SetUp on them once an Ipv4 address and mask have been set.
55 */
57 : m_ifup(false),
58 m_forwarding(true),
59 m_metric(1),
60 m_node(nullptr),
61 m_device(nullptr),
62 m_tc(nullptr),
63 m_cache(nullptr)
64{
65 NS_LOG_FUNCTION(this);
66}
67
72
73void
75{
76 NS_LOG_FUNCTION(this);
77 m_node = nullptr;
78 m_device = nullptr;
79 m_tc = nullptr;
80 m_cache = nullptr;
82}
83
84void
86{
87 NS_LOG_FUNCTION(this << node);
88 m_node = node;
89 DoSetup();
90}
91
92void
94{
95 NS_LOG_FUNCTION(this << device);
96 m_device = device;
97 DoSetup();
98}
99
100void
106
107void
109{
110 NS_LOG_FUNCTION(this);
111 if (!m_node || !m_device)
112 {
113 return;
114 }
115 if (!m_device->NeedsArp())
116 {
117 return;
118 }
120 m_cache = arp->CreateCache(m_device, this);
121}
122
125{
126 NS_LOG_FUNCTION(this);
127 return m_device;
128}
129
130void
132{
133 NS_LOG_FUNCTION(this << metric);
134 m_metric = metric;
135}
136
137uint16_t
139{
140 NS_LOG_FUNCTION(this);
141 return m_metric;
142}
143
144void
150
153{
154 NS_LOG_FUNCTION(this);
155 return m_cache;
156}
157
158/**
159 * These are IP interface states and may be distinct from
160 * NetDevice states, such as found in real implementations
161 * (where the device may be down but IP interface state is still up).
162 */
163bool
165{
166 NS_LOG_FUNCTION(this);
167 return m_ifup;
168}
169
170bool
172{
173 NS_LOG_FUNCTION(this);
174 return !m_ifup;
175}
176
177void
179{
180 NS_LOG_FUNCTION(this);
181 m_ifup = true;
182
184 NS_ASSERT_MSG(ip, "IPv4 not installed on node.");
185 auto ifIndex = ip->GetInterfaceForDevice(m_device);
186 m_interfaceStatus(m_ifup, ifIndex);
187}
188
189void
191{
192 NS_LOG_FUNCTION(this);
193 m_ifup = false;
194
196 NS_ASSERT_MSG(ip, "IPv4 not installed on node.");
197 auto ifIndex = ip->GetInterfaceForDevice(m_device);
198 m_interfaceStatus(m_ifup, ifIndex);
199}
200
201bool
203{
204 NS_LOG_FUNCTION(this);
205 return m_forwarding;
206}
207
208void
210{
211 NS_LOG_FUNCTION(this << val);
212 m_forwarding = val;
213}
214
215void
217{
218 NS_LOG_FUNCTION(this << *p << dest);
219 if (!IsUp())
220 {
221 return;
222 }
223
224 // Check for a loopback device, if it's the case we don't pass through
225 // traffic control layer
227 {
228 /// @todo additional checks needed here (such as whether multicast
229 /// goes to loopback)?
230 p->AddHeader(hdr);
231 m_device->Send(p, m_device->GetBroadcast(), Ipv4L3Protocol::PROT_NUMBER);
232 return;
233 }
234
236
237 // is this packet aimed at a local interface ?
238 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
239 {
240 if (dest == (*i).GetLocal())
241 {
242 p->AddHeader(hdr);
244 m_tc,
245 m_device,
246 p,
248 m_device->GetBroadcast(),
249 m_device->GetBroadcast(),
251 return;
252 }
253 }
254 if (m_device->NeedsArp())
255 {
256 NS_LOG_LOGIC("Needs ARP " << dest);
258 Address hardwareDestination;
259 bool found = false;
260 if (dest.IsBroadcast())
261 {
262 NS_LOG_LOGIC("All-network Broadcast");
263 hardwareDestination = m_device->GetBroadcast();
264 found = true;
265 }
266 else if (dest.IsMulticast())
267 {
268 NS_LOG_LOGIC("IsMulticast");
269 NS_ASSERT_MSG(m_device->IsMulticast(),
270 "ArpIpv4Interface::SendTo (): Sending multicast packet over "
271 "non-multicast device");
272
273 hardwareDestination = m_device->GetMulticast(dest);
274 found = true;
275 }
276 else
277 {
278 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); ++i)
279 {
280 if (dest.IsSubnetDirectedBroadcast((*i).GetMask()))
281 {
282 NS_LOG_LOGIC("Subnetwork Broadcast");
283 hardwareDestination = m_device->GetBroadcast();
284 found = true;
285 break;
286 }
287 }
288 if (!found)
289 {
290 NS_LOG_LOGIC("ARP Lookup");
291 found = arp->Lookup(p, hdr, dest, m_device, m_cache, &hardwareDestination);
292 }
293 }
294
295 if (found)
296 {
297 NS_LOG_LOGIC("Address Resolved. Send.");
298 m_tc->Send(m_device,
300 hardwareDestination,
302 hdr));
303 }
304 }
305 else
306 {
307 NS_LOG_LOGIC("Doesn't need ARP");
308 m_tc->Send(m_device,
310 m_device->GetBroadcast(),
312 hdr));
313 }
314}
315
318{
319 NS_LOG_FUNCTION(this);
320 return m_ifaddrs.size();
321}
322
323bool
325{
326 NS_LOG_FUNCTION(this << addr);
327 m_ifaddrs.push_back(addr);
328 if (!m_addAddressCallback.IsNull())
329 {
330 m_addAddressCallback(this, addr);
331 }
332 return true;
333}
334
337{
338 NS_LOG_FUNCTION(this << index);
339 if (index >= m_ifaddrs.size())
340 {
341 NS_FATAL_ERROR("index " << index << " out of bounds");
342 }
343
344 uint32_t tmp = 0;
345 for (auto i = m_ifaddrs.begin(); i != m_ifaddrs.end(); i++)
346 {
347 if (tmp == index)
348 {
349 return *i;
350 }
351 ++tmp;
352 }
353
354 return {}; // 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
366 uint32_t tmp = 0;
367 for (auto it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
368 {
369 if (tmp == index)
370 {
371 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
372 Ipv4InterfaceAddress addr = *it;
373
374 m_ifaddrs.erase(it);
375 if (!m_removeAddressCallback.IsNull())
376 {
377 m_removeAddressCallback(this, addr);
378 }
379 return addr;
380 }
381 ++tmp;
382 }
383 NS_FATAL_ERROR("Address " << index << " not found");
384 return {}; // quiet compiler
385}
386
389{
390 NS_LOG_FUNCTION(this << address);
391
392 if (address == Ipv4Address::GetLoopback())
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 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
403 Ipv4InterfaceAddress ifAddr = *it;
404
405 m_ifaddrs.erase(it);
406 if (!m_removeAddressCallback.IsNull())
407 {
408 m_removeAddressCallback(this, ifAddr);
409 }
410 return ifAddr;
411 }
412 }
413 return {};
414}
415
416void
418 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
419{
420 NS_LOG_FUNCTION(this << &removeAddressCallback);
421 m_removeAddressCallback = removeAddressCallback;
422}
423
424void
426 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> addAddressCallback)
427{
428 NS_LOG_FUNCTION(this << &addAddressCallback);
429 m_addAddressCallback = addAddressCallback;
430}
431
432} // 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
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
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
ns3::TracedCallback< bool, int32_t > m_interfaceStatus
The trace fired when the interface state changes.
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
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
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