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 
40 TypeId
42 {
43  static TypeId tid = TypeId ("ns3::Ipv4Interface")
44  .SetParent<Object> ()
45  .AddAttribute ("ArpCache",
46  "The arp cache for this ipv4 interface",
47  PointerValue (0),
48  MakePointerAccessor (&Ipv4Interface::SetArpCache,
50  MakePointerChecker<ArpCache> ())
51  ;
52  ;
53  return tid;
54 }
55 
62  : m_ifup (false),
63  m_forwarding (true),
64  m_metric (1),
65  m_node (0),
66  m_device (0),
67  m_cache (0)
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
73 {
74  NS_LOG_FUNCTION (this);
75 }
76 
77 void
79 {
80  NS_LOG_FUNCTION (this);
81  m_node = 0;
82  m_device = 0;
84 }
85 
86 void
88 {
89  NS_LOG_FUNCTION (this << node);
90  m_node = node;
91  DoSetup ();
92 }
93 
94 void
96 {
97  NS_LOG_FUNCTION (this << device);
98  m_device = device;
99  DoSetup ();
100 }
101 
102 void
104 {
105  NS_LOG_FUNCTION (this);
106  if (m_node == 0 || m_device == 0)
107  {
108  return;
109  }
110  if (!m_device->NeedsArp ())
111  {
112  return;
113  }
115  m_cache = arp->CreateCache (m_device, this);
116 }
117 
120 {
121  NS_LOG_FUNCTION (this);
122  return m_device;
123 }
124 
125 void
126 Ipv4Interface::SetMetric (uint16_t metric)
127 {
128  NS_LOG_FUNCTION (this << metric);
129  m_metric = metric;
130 }
131 
132 uint16_t
134 {
135  NS_LOG_FUNCTION (this);
136  return m_metric;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << a);
143  m_cache = a;
144 }
145 
148 {
149  NS_LOG_FUNCTION (this);
150  return m_cache;
151 }
152 
158 bool
160 {
161  NS_LOG_FUNCTION (this);
162  return m_ifup;
163 }
164 
165 bool
167 {
168  NS_LOG_FUNCTION (this);
169  return !m_ifup;
170 }
171 
172 void
174 {
175  NS_LOG_FUNCTION (this);
176  m_ifup = true;
177 }
178 
179 void
181 {
182  NS_LOG_FUNCTION (this);
183  m_ifup = false;
184 }
185 
186 bool
188 {
189  NS_LOG_FUNCTION (this);
190  return m_forwarding;
191 }
192 
193 void
195 {
196  NS_LOG_FUNCTION (this << val);
197  m_forwarding = val;
198 }
199 
200 void
202 {
203  NS_LOG_FUNCTION (this << *p << dest);
204  if (!IsUp ())
205  {
206  return;
207  }
208  // Check for a loopback device
209  if (DynamicCast<LoopbackNetDevice> (m_device))
210  {
213  m_device->Send (p, m_device->GetBroadcast (),
215  return;
216  }
217  // is this packet aimed at a local interface ?
218  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
219  {
220  if (dest == (*i).GetLocal ())
221  {
223 
224  ipv4->Receive (m_device, p, Ipv4L3Protocol::PROT_NUMBER,
225  m_device->GetBroadcast (),
226  m_device->GetBroadcast (),
227  NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
228  );
229  return;
230  }
231  }
232  if (m_device->NeedsArp ())
233  {
234  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
236  Address hardwareDestination;
237  bool found = false;
238  if (dest.IsBroadcast ())
239  {
240  NS_LOG_LOGIC ("All-network Broadcast");
241  hardwareDestination = m_device->GetBroadcast ();
242  found = true;
243  }
244  else if (dest.IsMulticast ())
245  {
246  NS_LOG_LOGIC ("IsMulticast");
247  NS_ASSERT_MSG (m_device->IsMulticast (),
248  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
249  "non-multicast device");
250 
251  hardwareDestination = m_device->GetMulticast (dest);
252  found = true;
253  }
254  else
255  {
256  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
257  {
258  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
259  {
260  NS_LOG_LOGIC ("Subnetwork Broadcast");
261  hardwareDestination = m_device->GetBroadcast ();
262  found = true;
263  break;
264  }
265  }
266  if (!found)
267  {
268  NS_LOG_LOGIC ("ARP Lookup");
269  found = arp->Lookup (p, dest, m_device, m_cache, &hardwareDestination);
270  }
271  }
272 
273  if (found)
274  {
275  NS_LOG_LOGIC ("Address Resolved. Send.");
276  m_device->Send (p, hardwareDestination,
278  }
279  }
280  else
281  {
282  NS_LOG_LOGIC ("Doesn't need ARP");
283  m_device->Send (p, m_device->GetBroadcast (),
285  }
286 }
287 
288 uint32_t
290 {
291  NS_LOG_FUNCTION (this);
292  return m_ifaddrs.size ();
293 }
294 
295 bool
297 {
298  NS_LOG_FUNCTION (this << addr);
299  m_ifaddrs.push_back (addr);
300  return true;
301 }
302 
304 Ipv4Interface::GetAddress (uint32_t index) const
305 {
306  NS_LOG_FUNCTION (this << index);
307  if (index < m_ifaddrs.size ())
308  {
309  uint32_t tmp = 0;
310  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
311  {
312  if (tmp == index)
313  {
314  return *i;
315  }
316  ++tmp;
317  }
318  }
319  NS_ASSERT (false); // Assert if not found
321  return (addr); // quiet compiler
322 }
323 
326 {
327  NS_LOG_FUNCTION (this << index);
328  if (index >= m_ifaddrs.size ())
329  {
330  NS_ASSERT_MSG (false, "Bug in Ipv4Interface::RemoveAddress");
331  }
333  uint32_t tmp = 0;
334  while (i != m_ifaddrs.end ())
335  {
336  if (tmp == index)
337  {
338  Ipv4InterfaceAddress addr = *i;
339  m_ifaddrs.erase (i);
340  return addr;
341  }
342  ++tmp;
343  ++i;
344  }
345  NS_ASSERT_MSG (false, "Address " << index << " not found");
347  return (addr); // quiet compiler
348 }
349 
352 {
353  NS_LOG_FUNCTION(this << address);
354 
355  if (address == address.GetLoopback())
356  {
357  NS_LOG_WARN ("Cannot remove loopback address.");
358  return Ipv4InterfaceAddress();
359  }
360 
361  for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
362  {
363  if((*it).GetLocal() == address)
364  {
365  Ipv4InterfaceAddress ifAddr = *it;
366  m_ifaddrs.erase(it);
367  return ifAddr;
368  }
369  }
370  return Ipv4InterfaceAddress();
371 }
372 
373 } // namespace ns3
374 
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)
Definition: log.h:345
void Send(Ptr< Packet > p, Ipv4Address dest)
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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:336
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)
Definition: log.h:368
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.
NS_LOG_COMPONENT_DEFINE("Ipv4Interface")
uint16_t GetMetric(void) const
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
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:272
#define NS_LOG_WARN(msg)
Definition: log.h:280
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:63
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:361
uint32_t GetNAddresses(void) const
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
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.