A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 "ns3/ipv4-address.h"
24 #include "ipv4-l3-protocol.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 NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
34 
35 namespace ns3 {
36 
37 NS_OBJECT_ENSURE_REGISTERED (Ipv4Interface);
38 
39 TypeId
41 {
42  static TypeId tid = TypeId ("ns3::Ipv4Interface")
43  .SetParent<Object> ()
44  .AddAttribute ("ArpCache",
45  "The arp cache for this ipv4 interface",
46  PointerValue (0),
47  MakePointerAccessor (&Ipv4Interface::SetArpCache,
49  MakePointerChecker<ArpCache> ())
50  ;
51  ;
52  return tid;
53 }
54 
61  : m_ifup (false),
62  m_forwarding (true),
63  m_metric (1),
64  m_node (0),
65  m_device (0),
66  m_cache (0)
67 {
68  NS_LOG_FUNCTION (this);
69 }
70 
72 {
73  NS_LOG_FUNCTION (this);
74 }
75 
76 void
78 {
79  NS_LOG_FUNCTION (this);
80  m_node = 0;
81  m_device = 0;
83 }
84 
85 void
87 {
88  NS_LOG_FUNCTION (this << node);
89  m_node = node;
90  DoSetup ();
91 }
92 
93 void
95 {
96  NS_LOG_FUNCTION (this << device);
97  m_device = device;
98  DoSetup ();
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION (this);
105  if (m_node == 0 || m_device == 0)
106  {
107  return;
108  }
109  if (!m_device->NeedsArp ())
110  {
111  return;
112  }
114  m_cache = arp->CreateCache (m_device, this);
115 }
116 
119 {
120  NS_LOG_FUNCTION (this);
121  return m_device;
122 }
123 
124 void
125 Ipv4Interface::SetMetric (uint16_t metric)
126 {
127  NS_LOG_FUNCTION (this << metric);
128  m_metric = metric;
129 }
130 
131 uint16_t
133 {
134  NS_LOG_FUNCTION (this);
135  return m_metric;
136 }
137 
138 void
140 {
141  NS_LOG_FUNCTION (this << a);
142  m_cache = a;
143 }
144 
147 {
148  NS_LOG_FUNCTION (this);
149  return m_cache;
150 }
151 
157 bool
159 {
160  NS_LOG_FUNCTION (this);
161  return m_ifup;
162 }
163 
164 bool
166 {
167  NS_LOG_FUNCTION (this);
168  return !m_ifup;
169 }
170 
171 void
173 {
174  NS_LOG_FUNCTION (this);
175  m_ifup = true;
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION (this);
182  m_ifup = false;
183 }
184 
185 bool
187 {
188  NS_LOG_FUNCTION (this);
189  return m_forwarding;
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (this << val);
196  m_forwarding = val;
197 }
198 
199 void
201 {
202  NS_LOG_FUNCTION (this << *p << dest);
203  if (!IsUp ())
204  {
205  return;
206  }
207  // Check for a loopback device
208  if (DynamicCast<LoopbackNetDevice> (m_device))
209  {
212  m_device->Send (p, m_device->GetBroadcast (),
214  return;
215  }
216  // is this packet aimed at a local interface ?
217  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
218  {
219  if (dest == (*i).GetLocal ())
220  {
222 
223  ipv4->Receive (m_device, p, Ipv4L3Protocol::PROT_NUMBER,
224  m_device->GetBroadcast (),
225  m_device->GetBroadcast (),
226  NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
227  );
228  return;
229  }
230  }
231  if (m_device->NeedsArp ())
232  {
233  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
235  Address hardwareDestination;
236  bool found = false;
237  if (dest.IsBroadcast ())
238  {
239  NS_LOG_LOGIC ("All-network Broadcast");
240  hardwareDestination = m_device->GetBroadcast ();
241  found = true;
242  }
243  else if (dest.IsMulticast ())
244  {
245  NS_LOG_LOGIC ("IsMulticast");
246  NS_ASSERT_MSG (m_device->IsMulticast (),
247  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
248  "non-multicast device");
249 
250  hardwareDestination = m_device->GetMulticast (dest);
251  found = true;
252  }
253  else
254  {
255  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
256  {
257  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
258  {
259  NS_LOG_LOGIC ("Subnetwork Broadcast");
260  hardwareDestination = m_device->GetBroadcast ();
261  found = true;
262  break;
263  }
264  }
265  if (!found)
266  {
267  NS_LOG_LOGIC ("ARP Lookup");
268  found = arp->Lookup (p, dest, m_device, m_cache, &hardwareDestination);
269  }
270  }
271 
272  if (found)
273  {
274  NS_LOG_LOGIC ("Address Resolved. Send.");
275  m_device->Send (p, hardwareDestination,
277  }
278  }
279  else
280  {
281  NS_LOG_LOGIC ("Doesn't need ARP");
282  m_device->Send (p, m_device->GetBroadcast (),
284  }
285 }
286 
287 uint32_t
289 {
290  NS_LOG_FUNCTION (this);
291  return m_ifaddrs.size ();
292 }
293 
294 bool
296 {
297  NS_LOG_FUNCTION (this << addr);
298  m_ifaddrs.push_back (addr);
299  return true;
300 }
301 
303 Ipv4Interface::GetAddress (uint32_t index) const
304 {
305  NS_LOG_FUNCTION (this << index);
306  if (index < m_ifaddrs.size ())
307  {
308  uint32_t tmp = 0;
309  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
310  {
311  if (tmp == index)
312  {
313  return *i;
314  }
315  ++tmp;
316  }
317  }
318  NS_ASSERT (false); // Assert if not found
320  return (addr); // quiet compiler
321 }
322 
325 {
326  NS_LOG_FUNCTION (this << index);
327  if (index >= m_ifaddrs.size ())
328  {
329  NS_ASSERT_MSG (false, "Bug in Ipv4Interface::RemoveAddress");
330  }
332  uint32_t tmp = 0;
333  while (i != m_ifaddrs.end ())
334  {
335  if (tmp == index)
336  {
337  Ipv4InterfaceAddress addr = *i;
338  m_ifaddrs.erase (i);
339  return addr;
340  }
341  ++tmp;
342  ++i;
343  }
344  NS_ASSERT_MSG (false, "Address " << index << " not found");
346  return (addr); // quiet compiler
347 }
348 
351 {
352  NS_LOG_FUNCTION(this << address);
353 
354  if (address == address.GetLoopback())
355  {
356  NS_LOG_WARN ("Cannot remove loopback address.");
357  return Ipv4InterfaceAddress();
358  }
359 
360  for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
361  {
362  if((*it).GetLocal() == address)
363  {
364  Ipv4InterfaceAddress ifAddr = *it;
365  m_ifaddrs.erase(it);
366  return ifAddr;
367  }
368  }
369  return Ipv4InterfaceAddress();
370 }
371 
372 } // namespace ns3
373 
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.
#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 the class in the ns-3 factory.
Definition: object-base.h:38
void Send(Ptr< Packet > p, Ipv4Address dest)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
Ptr< ArpCache > GetArpCache() const
bool IsMulticast(void) const
Ipv4InterfaceAddress RemoveAddress(uint32_t index)
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
bool AddAddress(Ipv4InterfaceAddress address)
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:86
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.
static TypeId GetTypeId(void)
Get the type ID.
bool IsBroadcast(void) const
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:233
Ipv4InterfaceAddress GetAddress(uint32_t index) const
virtual ~Ipv4Interface()
bool IsDown(void) const
Implement the Ipv4 layer.
hold objects of type Ptr
Definition: pointer.h:33
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:84
uint16_t m_metric
Interface metric.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
void SetArpCache(Ptr< ArpCache > arpCache)
Set ARP cache used by this interface.
a class to store IPv4 address information on an interface
Packet addressed oo us.
Definition: net-device.h:276
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
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:64
tuple address
Definition: first.py:37
void DoSetup(void)
Initialize interface.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< T > GetObject(void) const
Definition: object.h:362
uint32_t GetNAddresses(void) const
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
bool IsForwarding(void) const
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.