A Discrete-Event Network Simulator
API
ipv4-interface.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ipv4-interface.h"
22 #include "loopback-net-device.h"
23 #include "ipv4-l3-protocol.h"
24 #include "ipv4-queue-disc-item.h"
25 #include "arp-l3-protocol.h"
26 #include "arp-cache.h"
27 #include "ns3/net-device.h"
28 #include "ns3/log.h"
29 #include "ns3/packet.h"
30 #include "ns3/node.h"
31 #include "ns3/pointer.h"
32 
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
37 
38 NS_OBJECT_ENSURE_REGISTERED (Ipv4Interface);
39 
40 TypeId
42 {
43  static TypeId tid = TypeId ("ns3::Ipv4Interface")
44  .SetParent<Object> ()
45  .SetGroupName ("Internet")
46  .AddAttribute ("ArpCache",
47  "The arp cache for this ipv4 interface",
48  PointerValue (0),
51  MakePointerChecker<ArpCache> ())
52  ;
53  ;
54  return tid;
55 }
56 
63  : m_ifup (false),
64  m_forwarding (true),
65  m_metric (1),
66  m_node (0),
67  m_device (0),
68  m_tc (0),
69  m_cache (0)
70 {
71  NS_LOG_FUNCTION (this);
72 }
73 
75 {
76  NS_LOG_FUNCTION (this);
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION (this);
83  m_node = 0;
84  m_device = 0;
85  m_tc = 0;
86  m_cache = 0;
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION (this << node);
94  m_node = node;
95  DoSetup ();
96 }
97 
98 void
100 {
101  NS_LOG_FUNCTION (this << device);
102  m_device = device;
103  DoSetup ();
104 }
105 
106 void
108 {
109  NS_LOG_FUNCTION (this << tc);
110  m_tc = tc;
111 }
112 
113 void
115 {
116  NS_LOG_FUNCTION (this);
117  if (m_node == 0 || m_device == 0)
118  {
119  return;
120  }
121  if (!m_device->NeedsArp ())
122  {
123  return;
124  }
126  m_cache = arp->CreateCache (m_device, this);
127 }
128 
131 {
132  NS_LOG_FUNCTION (this);
133  return m_device;
134 }
135 
136 void
137 Ipv4Interface::SetMetric (uint16_t metric)
138 {
139  NS_LOG_FUNCTION (this << metric);
140  m_metric = metric;
141 }
142 
143 uint16_t
145 {
146  NS_LOG_FUNCTION (this);
147  return m_metric;
148 }
149 
150 void
152 {
153  NS_LOG_FUNCTION (this << a);
154  m_cache = a;
155 }
156 
159 {
160  NS_LOG_FUNCTION (this);
161  return m_cache;
162 }
163 
169 bool
171 {
172  NS_LOG_FUNCTION (this);
173  return m_ifup;
174 }
175 
176 bool
178 {
179  NS_LOG_FUNCTION (this);
180  return !m_ifup;
181 }
182 
183 void
185 {
186  NS_LOG_FUNCTION (this);
187  m_ifup = true;
188 }
189 
190 void
192 {
193  NS_LOG_FUNCTION (this);
194  m_ifup = false;
195 }
196 
197 bool
199 {
200  NS_LOG_FUNCTION (this);
201  return m_forwarding;
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION (this << val);
208  m_forwarding = val;
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (this << *p << dest);
215  if (!IsUp ())
216  {
217  return;
218  }
219 
220  // Check for a loopback device, if it's the case we don't pass through
221  // traffic control layer
222  if (DynamicCast<LoopbackNetDevice> (m_device))
223  {
226  p->AddHeader (hdr);
227  m_device->Send (p, m_device->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER);
228  return;
229  }
230 
231  NS_ASSERT (m_tc != 0);
232 
233  // is this packet aimed at a local interface ?
234  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
235  {
236  if (dest == (*i).GetLocal ())
237  {
238  p->AddHeader (hdr);
240  m_device->GetBroadcast (),
241  m_device->GetBroadcast (),
243  return;
244  }
245  }
246  if (m_device->NeedsArp ())
247  {
248  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
250  Address hardwareDestination;
251  bool found = false;
252  if (dest.IsBroadcast ())
253  {
254  NS_LOG_LOGIC ("All-network Broadcast");
255  hardwareDestination = m_device->GetBroadcast ();
256  found = true;
257  }
258  else if (dest.IsMulticast ())
259  {
260  NS_LOG_LOGIC ("IsMulticast");
261  NS_ASSERT_MSG (m_device->IsMulticast (),
262  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
263  "non-multicast device");
264 
265  hardwareDestination = m_device->GetMulticast (dest);
266  found = true;
267  }
268  else
269  {
270  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
271  {
272  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
273  {
274  NS_LOG_LOGIC ("Subnetwork Broadcast");
275  hardwareDestination = m_device->GetBroadcast ();
276  found = true;
277  break;
278  }
279  }
280  if (!found)
281  {
282  NS_LOG_LOGIC ("ARP Lookup");
283  found = arp->Lookup (p, hdr, dest, m_device, m_cache, &hardwareDestination);
284  }
285  }
286 
287  if (found)
288  {
289  NS_LOG_LOGIC ("Address Resolved. Send.");
290  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER, hdr));
291  }
292  }
293  else
294  {
295  NS_LOG_LOGIC ("Doesn't need ARP");
296  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, m_device->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER, hdr));
297  }
298 }
299 
300 uint32_t
302 {
303  NS_LOG_FUNCTION (this);
304  return m_ifaddrs.size ();
305 }
306 
307 bool
309 {
310  NS_LOG_FUNCTION (this << addr);
311  m_ifaddrs.push_back (addr);
312  return true;
313 }
314 
316 Ipv4Interface::GetAddress (uint32_t index) const
317 {
318  NS_LOG_FUNCTION (this << index);
319  if (index < m_ifaddrs.size ())
320  {
321  uint32_t tmp = 0;
322  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
323  {
324  if (tmp == index)
325  {
326  return *i;
327  }
328  ++tmp;
329  }
330  }
331  else
332  {
333  NS_FATAL_ERROR ("index " << index << " out of bounds");
334  }
336  return (addr); // quiet compiler
337 }
338 
341 {
342  NS_LOG_FUNCTION (this << index);
343  if (index >= m_ifaddrs.size ())
344  {
345  NS_FATAL_ERROR ("Bug in Ipv4Interface::RemoveAddress");
346  }
348  uint32_t tmp = 0;
349  while (i != m_ifaddrs.end ())
350  {
351  if (tmp == index)
352  {
353  Ipv4InterfaceAddress addr = *i;
354  m_ifaddrs.erase (i);
355  return addr;
356  }
357  ++tmp;
358  ++i;
359  }
360  NS_FATAL_ERROR ("Address " << index << " not found");
362  return (addr); // quiet compiler
363 }
364 
367 {
368  NS_LOG_FUNCTION(this << address);
369 
370  if (address == address.GetLoopback())
371  {
372  NS_LOG_WARN ("Cannot remove loopback address.");
373  return Ipv4InterfaceAddress();
374  }
375 
376  for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
377  {
378  if((*it).GetLocal() == address)
379  {
380  Ipv4InterfaceAddress ifAddr = *it;
381  m_ifaddrs.erase(it);
382  return ifAddr;
383  }
384  }
385  return Ipv4InterfaceAddress();
386 }
387 
388 } // namespace ns3
389 
void SetDown(void)
Disable this interface.
void SetForwarding(bool val)
Ipv4Interface()
By default, Ipv4 interface are created in the "down" state with no IP addresses.
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:462
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Ptr< ArpCache > GetArpCache() const
bool IsMulticast(void) const
Ipv4InterfaceAddress RemoveAddress(uint32_t index)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
bool AddAddress(Ipv4InterfaceAddress address)
Packet addressed oo us.
Definition: net-device.h:608
Ptr< NetDevice > m_device
The associated NetDevice.
Ptr< ArpCache > m_cache
ARP cache.
void SetNode(Ptr< Node > node)
Set node associated with interface.
a polymophic address class
Definition: address.h:90
std::list< Ipv4InterfaceAddress >::const_iterator Ipv4InterfaceAddressListCI
Container Iterator for the Ipv4InterfaceAddresses.
bool m_forwarding
Forwarding state.
bool IsSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
Packet header for IPv4.
Definition: ipv4-header.h:33
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:220
static TypeId GetTypeId(void)
Get the type ID.
void SetTrafficControl(Ptr< TrafficControlLayer > tc)
Set the TrafficControlLayer.
bool IsBroadcast(void) const
Ptr< TrafficControlLayer > m_tc
The associated TrafficControlLayer.
void SetDevice(Ptr< NetDevice > device)
Set the NetDevice.
Ipv4InterfaceAddressList m_ifaddrs
Address list.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Ipv4InterfaceAddress GetAddress(uint32_t index) const
virtual ~Ipv4Interface()
bool IsDown(void) const
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr.
Definition: pointer.h:36
std::list< Ipv4InterfaceAddress >::iterator Ipv4InterfaceAddressListI
Const Container Iterator for the Ipv4InterfaceAddresses.
static Ipv4Address GetLoopback(void)
Ptr< Node > m_node
The associated node.
uint16_t GetMetric(void) const
#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:90
uint16_t m_metric
Interface metric.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void SetArpCache(Ptr< ArpCache > arpCache)
Set ARP cache used by this interface.
a class to store IPv4 address information on an interface
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
Ptr< NetDevice > GetDevice(void) const
bool m_ifup
The state of this interface.
An implementation of the ARP protocol.
void SetMetric(uint16_t metric)
A base class which provides memory management and object aggregation.
Definition: object.h:87
tuple address
Definition: first.py:37
void DoSetup(void)
Initialize interface.
virtual void DoDispose(void)
Destructor implementation.
uint32_t GetNAddresses(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
bool IsForwarding(void) const
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
bool IsUp(void) const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetUp(void)
Enable this interface.