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 * 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"
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
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("Ipv4Interface");
39
40NS_OBJECT_ENSURE_REGISTERED(Ipv4Interface);
41
42TypeId
44{
45 static TypeId tid = TypeId("ns3::Ipv4Interface")
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
58/**
59 * By default, Ipv4 interface are created in the "down" state
60 * with no IP addresses. Before becoming usable, the user must
61 * invoke SetUp on them once an Ipv4 address and mask have been set.
62 */
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
80void
82{
83 NS_LOG_FUNCTION(this);
84 m_node = nullptr;
85 m_device = nullptr;
86 m_tc = nullptr;
87 m_cache = nullptr;
89}
90
91void
93{
94 NS_LOG_FUNCTION(this << node);
95 m_node = node;
96 DoSetup();
97}
98
99void
101{
102 NS_LOG_FUNCTION(this << device);
103 m_device = device;
104 DoSetup();
105}
106
107void
109{
110 NS_LOG_FUNCTION(this << tc);
111 m_tc = tc;
112}
113
114void
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
137void
139{
140 NS_LOG_FUNCTION(this << metric);
141 m_metric = metric;
142}
143
144uint16_t
146{
147 NS_LOG_FUNCTION(this);
148 return m_metric;
149}
150
151void
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
165/**
166 * These are IP interface states and may be distinct from
167 * NetDevice states, such as found in real implementations
168 * (where the device may be down but IP interface state is still up).
169 */
170bool
172{
173 NS_LOG_FUNCTION(this);
174 return m_ifup;
175}
176
177bool
179{
180 NS_LOG_FUNCTION(this);
181 return !m_ifup;
182}
183
184void
186{
187 NS_LOG_FUNCTION(this);
188 m_ifup = true;
189}
190
191void
193{
194 NS_LOG_FUNCTION(this);
195 m_ifup = false;
196}
197
198bool
200{
201 NS_LOG_FUNCTION(this);
202 return m_forwarding;
203}
204
205void
207{
208 NS_LOG_FUNCTION(this << val);
209 m_forwarding = val;
210}
211
212void
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 {
225 /// \todo additional checks needed here (such as whether multicast
226 /// goes to loopback)?
227 p->AddHeader(hdr);
228 m_device->Send(p, m_device->GetBroadcast(), Ipv4L3Protocol::PROT_NUMBER);
229 return;
230 }
231
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
316{
317 NS_LOG_FUNCTION(this);
318 return m_ifaddrs.size();
319}
320
321bool
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
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
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 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
414void
416 Callback<void, Ptr<Ipv4Interface>, Ipv4InterfaceAddress> removeAddressCallback)
417{
418 NS_LOG_FUNCTION(this << &removeAddressCallback);
419 m_removeAddressCallback = removeAddressCallback;
420}
421
422void
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:522
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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:932
#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
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.