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 {
74 }
75 
76 void
78 {
80  m_node = 0;
81  m_device = 0;
83 }
84 
85 void
87 {
88  m_node = node;
89  DoSetup ();
90 }
91 
92 void
94 {
95  m_device = device;
96  DoSetup ();
97 }
98 
99 void
101 {
102  if (m_node == 0 || m_device == 0)
103  {
104  return;
105  }
106  if (!m_device->NeedsArp ())
107  {
108  return;
109  }
111  m_cache = arp->CreateCache (m_device, this);
112 }
113 
116 {
117  return m_device;
118 }
119 
120 void
121 Ipv4Interface::SetMetric (uint16_t metric)
122 {
123  NS_LOG_FUNCTION (metric);
124  m_metric = metric;
125 }
126 
127 uint16_t
129 {
131  return m_metric;
132 }
133 
134 void
136 {
137  m_cache = a;
138 }
139 
142 {
143  return m_cache;
144 }
145 
151 bool
153 {
155  return m_ifup;
156 }
157 
158 bool
160 {
162  return !m_ifup;
163 }
164 
165 void
167 {
169  m_ifup = true;
170 }
171 
172 void
174 {
176  m_ifup = false;
177 }
178 
179 bool
181 {
183  return m_forwarding;
184 }
185 
186 void
188 {
190  m_forwarding = val;
191 }
192 
193 void
195 {
196  NS_LOG_FUNCTION (dest << *p);
197  if (!IsUp ())
198  {
199  return;
200  }
201  // Check for a loopback device
202  if (DynamicCast<LoopbackNetDevice> (m_device))
203  {
204  // XXX additional checks needed here (such as whether multicast
205  // goes to loopback)?
208  return;
209  }
210  // is this packet aimed at a local interface ?
211  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
212  {
213  if (dest == (*i).GetLocal ())
214  {
216 
220  NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
221  );
222  return;
223  }
224  }
225  if (m_device->NeedsArp ())
226  {
227  NS_LOG_LOGIC ("Needs ARP" << " " << dest);
229  Address hardwareDestination;
230  bool found = false;
231  if (dest.IsBroadcast ())
232  {
233  NS_LOG_LOGIC ("All-network Broadcast");
234  hardwareDestination = m_device->GetBroadcast ();
235  found = true;
236  }
237  else if (dest.IsMulticast ())
238  {
239  NS_LOG_LOGIC ("IsMulticast");
241  "ArpIpv4Interface::SendTo (): Sending multicast packet over "
242  "non-multicast device");
243 
244  hardwareDestination = m_device->GetMulticast (dest);
245  found = true;
246  }
247  else
248  {
249  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i != m_ifaddrs.end (); ++i)
250  {
251  if (dest.IsSubnetDirectedBroadcast ((*i).GetMask ()))
252  {
253  NS_LOG_LOGIC ("Subnetwork Broadcast");
254  hardwareDestination = m_device->GetBroadcast ();
255  found = true;
256  break;
257  }
258  }
259  if (!found)
260  {
261  NS_LOG_LOGIC ("ARP Lookup");
262  found = arp->Lookup (p, dest, m_device, m_cache, &hardwareDestination);
263  }
264  }
265 
266  if (found)
267  {
268  NS_LOG_LOGIC ("Address Resolved. Send.");
269  m_device->Send (p, hardwareDestination,
271  }
272  }
273  else
274  {
275  NS_LOG_LOGIC ("Doesn't need ARP");
278  }
279 }
280 
281 uint32_t
283 {
285  return m_ifaddrs.size ();
286 }
287 
288 bool
290 {
292  m_ifaddrs.push_back (addr);
293  return true;
294 }
295 
297 Ipv4Interface::GetAddress (uint32_t index) const
298 {
300  if (index < m_ifaddrs.size ())
301  {
302  uint32_t tmp = 0;
303  for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
304  {
305  if (tmp == index)
306  {
307  return *i;
308  }
309  ++tmp;
310  }
311  }
312  NS_ASSERT (false); // Assert if not found
314  return (addr); // quiet compiler
315 }
316 
319 {
321  if (index >= m_ifaddrs.size ())
322  {
323  NS_ASSERT_MSG (false, "Bug in Ipv4Interface::RemoveAddress");
324  }
326  uint32_t tmp = 0;
327  while (i != m_ifaddrs.end ())
328  {
329  if (tmp == index)
330  {
331  Ipv4InterfaceAddress addr = *i;
332  m_ifaddrs.erase (i);
333  return addr;
334  }
335  ++tmp;
336  ++i;
337  }
338  NS_ASSERT_MSG (false, "Address " << index << " not found");
340  return (addr); // quiet compiler
341 }
342 
343 } // namespace ns3
344