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 #include "ns3/traffic-control-layer.h"
33 
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
38 
39 NS_OBJECT_ENSURE_REGISTERED (Ipv4Interface);
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::Ipv4Interface")
45  .SetParent<Object> ()
46  .SetGroupName ("Internet")
47  .AddAttribute ("ArpCache",
48  "The arp cache for this ipv4 interface",
49  PointerValue (0),
52  MakePointerChecker<ArpCache> ())
53  ;
54  ;
55  return tid;
56 }
57 
64  : m_ifup (false),
65  m_forwarding (true),
66  m_metric (1),
67  m_node (0),
68  m_device (0),
69  m_tc (0),
70  m_cache (0)
71 {
72  NS_LOG_FUNCTION (this);
73 }
74 
76 {
77  NS_LOG_FUNCTION (this);
78 }
79 
80 void
82 {
83  NS_LOG_FUNCTION (this);
84  m_node = 0;
85  m_device = 0;
86  m_tc = 0;
87  m_cache = 0;
89 }
90 
91 void
93 {
94  NS_LOG_FUNCTION (this << node);
95  m_node = node;
96  DoSetup ();
97 }
98 
99 void
101 {
102  NS_LOG_FUNCTION (this << device);
103  m_device = device;
104  DoSetup ();
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION (this << tc);
111  m_tc = tc;
112 }
113 
114 void
116 {
117  NS_LOG_FUNCTION (this);
118  if (m_node == 0 || m_device == 0)
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 
137 void
138 Ipv4Interface::SetMetric (uint16_t metric)
139 {
140  NS_LOG_FUNCTION (this << metric);
141  m_metric = metric;
142 }
143 
144 uint16_t
146 {
147  NS_LOG_FUNCTION (this);
148  return m_metric;
149 }
150 
151 void
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 
170 bool
172 {
173  NS_LOG_FUNCTION (this);
174  return m_ifup;
175 }
176 
177 bool
179 {
180  NS_LOG_FUNCTION (this);
181  return !m_ifup;
182 }
183 
184 void
186 {
187  NS_LOG_FUNCTION (this);
188  m_ifup = true;
189 }
190 
191 void
193 {
194  NS_LOG_FUNCTION (this);
195  m_ifup = false;
196 }
197 
198 bool
200 {
201  NS_LOG_FUNCTION (this);
202  return m_forwarding;
203 }
204 
205 void
207 {
208  NS_LOG_FUNCTION (this << val);
209  m_forwarding = val;
210 }
211 
212 void
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  {
227  p->AddHeader (hdr);
229  return;
230  }
231 
232  NS_ASSERT (m_tc != 0);
233 
234  // is this packet aimed at a local interface ?
235  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
236  {
237  if (dest == (*i).GetLocal ())
238  {
239  p->AddHeader (hdr);
244  return;
245  }
246  }
247  if (m_device->NeedsArp ())
248  {
249  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
251  Address hardwareDestination;
252  bool found = false;
253  if (dest.IsBroadcast ())
254  {
255  NS_LOG_LOGIC ("All-network Broadcast");
256  hardwareDestination = m_device->GetBroadcast ();
257  found = true;
258  }
259  else if (dest.IsMulticast ())
260  {
261  NS_LOG_LOGIC ("IsMulticast");
263  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
264  "non-multicast device");
265 
266  hardwareDestination = m_device->GetMulticast (dest);
267  found = true;
268  }
269  else
270  {
271  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
272  {
273  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
274  {
275  NS_LOG_LOGIC ("Subnetwork Broadcast");
276  hardwareDestination = m_device->GetBroadcast ();
277  found = true;
278  break;
279  }
280  }
281  if (!found)
282  {
283  NS_LOG_LOGIC ("ARP Lookup");
284  found = arp->Lookup (p, hdr, dest, m_device, m_cache, &hardwareDestination);
285  }
286  }
287 
288  if (found)
289  {
290  NS_LOG_LOGIC ("Address Resolved. Send.");
291  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER, hdr));
292  }
293  }
294  else
295  {
296  NS_LOG_LOGIC ("Doesn't need ARP");
297  m_tc->Send (m_device, Create<Ipv4QueueDiscItem> (p, m_device->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER, hdr));
298  }
299 }
300 
301 uint32_t
303 {
304  NS_LOG_FUNCTION (this);
305  return m_ifaddrs.size ();
306 }
307 
308 bool
310 {
311  NS_LOG_FUNCTION (this << addr);
312  m_ifaddrs.push_back (addr);
313  return true;
314 }
315 
317 Ipv4Interface::GetAddress (uint32_t index) const
318 {
319  NS_LOG_FUNCTION (this << index);
320  if (index < m_ifaddrs.size ())
321  {
322  uint32_t tmp = 0;
323  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
324  {
325  if (tmp == index)
326  {
327  return *i;
328  }
329  ++tmp;
330  }
331  }
332  else
333  {
334  NS_FATAL_ERROR ("index " << index << " out of bounds");
335  }
337  return (addr); // quiet compiler
338 }
339 
342 {
343  NS_LOG_FUNCTION (this << index);
344  if (index >= m_ifaddrs.size ())
345  {
346  NS_FATAL_ERROR ("Bug in Ipv4Interface::RemoveAddress");
347  }
349  uint32_t tmp = 0;
350  while (i != m_ifaddrs.end ())
351  {
352  if (tmp == index)
353  {
354  Ipv4InterfaceAddress addr = *i;
355  m_ifaddrs.erase (i);
356  return addr;
357  }
358  ++tmp;
359  ++i;
360  }
361  NS_FATAL_ERROR ("Address " << index << " not found");
363  return (addr); // quiet compiler
364 }
365 
368 {
369  NS_LOG_FUNCTION(this << address);
370 
371  if (address == address.GetLoopback())
372  {
373  NS_LOG_WARN ("Cannot remove loopback address.");
374  return Ipv4InterfaceAddress();
375  }
376 
377  for(Ipv4InterfaceAddressListI it = m_ifaddrs.begin(); it != m_ifaddrs.end(); it++)
378  {
379  if((*it).GetLocal() == address)
380  {
381  Ipv4InterfaceAddress ifAddr = *it;
382  m_ifaddrs.erase(it);
383  return ifAddr;
384  }
385  }
386  return Ipv4InterfaceAddress();
387 }
388 
389 } // namespace ns3
390 
a polymophic address class
Definition: address.h:91
An implementation of the ARP protocol.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
bool IsMulticast(void) const
bool IsBroadcast(void) const
bool IsSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
Packet header for IPv4.
Definition: ipv4-header.h:34
a class to store IPv4 address information on an interface
virtual void DoDispose(void)
Destructor implementation.
bool IsDown(void) 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.
void DoSetup(void)
Initialize interface.
void SetUp(void)
Enable this interface.
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.
uint32_t GetNAddresses(void) const
bool m_forwarding
Forwarding state.
std::list< Ipv4InterfaceAddress >::const_iterator Ipv4InterfaceAddressListCI
Container Iterator for the Ipv4InterfaceAddresses.
virtual ~Ipv4Interface()
Ptr< NetDevice > m_device
The associated NetDevice.
bool IsForwarding(void) const
Ptr< ArpCache > GetArpCache() const
void SetDevice(Ptr< NetDevice > device)
Set the NetDevice.
uint16_t GetMetric(void) const
Ipv4InterfaceAddressList m_ifaddrs
Address list.
static TypeId GetTypeId(void)
Get the type ID.
uint16_t m_metric
Interface metric.
Ptr< NetDevice > GetDevice(void) const
Ptr< ArpCache > m_cache
ARP cache.
void Send(Ptr< Packet > p, const Ipv4Header &hdr, Ipv4Address dest)
void SetDown(void)
Disable this interface.
bool m_ifup
The state of this interface.
std::list< Ipv4InterfaceAddress >::iterator Ipv4InterfaceAddressListI
Const Container Iterator for the Ipv4InterfaceAddresses.
bool IsUp(void) const
These are IP interface states and may be distinct from NetDevice states, such as found in real implem...
void SetForwarding(bool val)
void SetMetric(uint16_t metric)
Ipv4InterfaceAddress RemoveAddress(uint32_t index)
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
virtual bool IsMulticast(void) const =0
virtual Address GetBroadcast(void) const =0
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
virtual Address GetMulticast(Ipv4Address multicastGroup) const =0
Make and return a MAC multicast address using the provided multicast group.
virtual bool NeedsArp(void) const =0
@ PACKET_HOST
Packet addressed oo us.
Definition: net-device.h:298
A base class which provides memory management and object aggregation.
Definition: object.h:88
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Hold objects of type Ptr<T>.
Definition: pointer.h:37
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#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_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:88
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:227
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:265
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.