|
mathieu@236
|
1 |
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
|
|
mathieu@236
|
2 |
//
|
|
mathieu@236
|
3 |
// Copyright (c) 2006 Georgia Tech Research Corporation
|
|
mathieu@236
|
4 |
// All rights reserved.
|
|
mathieu@236
|
5 |
//
|
|
mathieu@236
|
6 |
// This program is free software; you can redistribute it and/or modify
|
|
mathieu@236
|
7 |
// it under the terms of the GNU General Public License version 2 as
|
|
mathieu@236
|
8 |
// published by the Free Software Foundation;
|
|
mathieu@236
|
9 |
//
|
|
mathieu@236
|
10 |
// This program is distributed in the hope that it will be useful,
|
|
mathieu@236
|
11 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
mathieu@236
|
12 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
mathieu@236
|
13 |
// GNU General Public License for more details.
|
|
mathieu@236
|
14 |
//
|
|
mathieu@236
|
15 |
// You should have received a copy of the GNU General Public License
|
|
mathieu@236
|
16 |
// along with this program; if not, write to the Free Software
|
|
mathieu@236
|
17 |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
mathieu@236
|
18 |
//
|
|
mathieu@236
|
19 |
// Author: George F. Riley<riley@ece.gatech.edu>
|
|
mathieu@236
|
20 |
//
|
|
mathieu@236
|
21 |
|
|
mathieu@236
|
22 |
#include "ns3/packet.h"
|
|
craigdo@1504
|
23 |
#include "ns3/log.h"
|
|
tomh@345
|
24 |
#include "ns3/composite-trace-resolver.h"
|
|
tomh@345
|
25 |
#include "ns3/callback.h"
|
|
mathieu@524
|
26 |
#include "ns3/ipv4-address.h"
|
|
mathieu@524
|
27 |
#include "ns3/ipv4-route.h"
|
|
mathieu@729
|
28 |
#include "ns3/node.h"
|
|
mathieu@568
|
29 |
#include "ns3/net-device.h"
|
|
mathieu@236
|
30 |
|
|
mathieu@733
|
31 |
#include "ipv4-l3-protocol.h"
|
|
mathieu@236
|
32 |
#include "ipv4-l4-protocol.h"
|
|
mathieu@236
|
33 |
#include "ipv4-header.h"
|
|
mathieu@236
|
34 |
#include "ipv4-interface.h"
|
|
mathieu@444
|
35 |
#include "ipv4-loopback-interface.h"
|
|
mathieu@444
|
36 |
#include "arp-ipv4-interface.h"
|
|
mathieu@236
|
37 |
#include "ipv4-l4-demux.h"
|
|
mathieu@236
|
38 |
|
|
craigdo@1504
|
39 |
NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
|
|
mathieu@236
|
40 |
|
|
mathieu@236
|
41 |
namespace ns3 {
|
|
mathieu@236
|
42 |
|
|
mathieu@734
|
43 |
const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
|
|
mathieu@293
|
44 |
|
|
mathieu@2249
|
45 |
NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
|
|
mathieu@2249
|
46 |
|
|
mathieu@2250
|
47 |
TypeId
|
|
mathieu@2251
|
48 |
Ipv4L3Protocol::GetTypeId (void)
|
|
mathieu@2232
|
49 |
{
|
|
mathieu@2252
|
50 |
static TypeId tid = TypeId ("Ipv4L3Protocol")
|
|
mathieu@2238
|
51 |
.SetParent<Object> ();
|
|
mathieu@2252
|
52 |
return tid;
|
|
mathieu@2232
|
53 |
}
|
|
mathieu@2232
|
54 |
|
|
mathieu@1229
|
55 |
Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement ()
|
|
mathieu@1229
|
56 |
: m_type (TX)
|
|
craigdo@1504
|
57 |
{
|
|
craigdo@1504
|
58 |
NS_LOG_FUNCTION;
|
|
craigdo@1504
|
59 |
}
|
|
craigdo@1504
|
60 |
|
|
mathieu@1229
|
61 |
Ipv4L3ProtocolTraceContextElement::Ipv4L3ProtocolTraceContextElement (enum Type type)
|
|
mathieu@1229
|
62 |
: m_type (type)
|
|
craigdo@1504
|
63 |
{
|
|
craigdo@1504
|
64 |
NS_LOG_FUNCTION;
|
|
craigdo@1504
|
65 |
}
|
|
craigdo@1504
|
66 |
|
|
mathieu@1229
|
67 |
bool
|
|
mathieu@1229
|
68 |
Ipv4L3ProtocolTraceContextElement::IsTx (void) const
|
|
mathieu@1229
|
69 |
{
|
|
craigdo@1504
|
70 |
NS_LOG_FUNCTION;
|
|
mathieu@1229
|
71 |
return m_type == TX;
|
|
mathieu@1229
|
72 |
}
|
|
craigdo@1504
|
73 |
|
|
mathieu@1229
|
74 |
bool
|
|
mathieu@1229
|
75 |
Ipv4L3ProtocolTraceContextElement::IsRx (void) const
|
|
mathieu@1229
|
76 |
{
|
|
craigdo@1504
|
77 |
NS_LOG_FUNCTION;
|
|
mathieu@1229
|
78 |
return m_type == RX;
|
|
mathieu@1229
|
79 |
}
|
|
craigdo@1504
|
80 |
|
|
mathieu@1229
|
81 |
bool
|
|
mathieu@1229
|
82 |
Ipv4L3ProtocolTraceContextElement::IsDrop (void) const
|
|
mathieu@1229
|
83 |
{
|
|
craigdo@1504
|
84 |
NS_LOG_FUNCTION;
|
|
mathieu@1229
|
85 |
return m_type == DROP;
|
|
mathieu@1229
|
86 |
}
|
|
craigdo@1504
|
87 |
|
|
mathieu@1229
|
88 |
void
|
|
mathieu@1229
|
89 |
Ipv4L3ProtocolTraceContextElement::Print (std::ostream &os) const
|
|
mathieu@1229
|
90 |
{
|
|
craigdo@1504
|
91 |
NS_LOG_FUNCTION;
|
|
mathieu@1229
|
92 |
os << "ipv4=";
|
|
mathieu@1229
|
93 |
switch (m_type)
|
|
mathieu@1229
|
94 |
{
|
|
mathieu@1229
|
95 |
case TX:
|
|
mathieu@1229
|
96 |
os << "tx";
|
|
mathieu@1229
|
97 |
break;
|
|
mathieu@1229
|
98 |
case RX:
|
|
mathieu@1229
|
99 |
os << "rx";
|
|
mathieu@1229
|
100 |
break;
|
|
mathieu@1229
|
101 |
case DROP:
|
|
mathieu@1229
|
102 |
os << "drop";
|
|
mathieu@1229
|
103 |
break;
|
|
mathieu@1229
|
104 |
}
|
|
mathieu@1229
|
105 |
}
|
|
craigdo@1504
|
106 |
|
|
mathieu@1229
|
107 |
uint16_t
|
|
mathieu@1229
|
108 |
Ipv4L3ProtocolTraceContextElement::GetUid (void)
|
|
mathieu@1229
|
109 |
{
|
|
craigdo@1504
|
110 |
NS_LOG_FUNCTION;
|
|
mathieu@1235
|
111 |
static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement");
|
|
mathieu@1229
|
112 |
return uid;
|
|
mathieu@1229
|
113 |
}
|
|
craigdo@1504
|
114 |
|
|
mathieu@1364
|
115 |
std::string
|
|
mathieu@1401
|
116 |
Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const
|
|
mathieu@1364
|
117 |
{
|
|
craigdo@1504
|
118 |
NS_LOG_FUNCTION;
|
|
mathieu@1401
|
119 |
return "ns3::Ipv4L3ProtocolTraceContextElement";
|
|
mathieu@1364
|
120 |
}
|
|
mathieu@1229
|
121 |
|
|
mathieu@1341
|
122 |
Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex ()
|
|
mathieu@1229
|
123 |
: m_index (0)
|
|
craigdo@1504
|
124 |
{
|
|
craigdo@1504
|
125 |
NS_LOG_FUNCTION;
|
|
craigdo@1504
|
126 |
}
|
|
craigdo@1504
|
127 |
|
|
mathieu@1341
|
128 |
Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index)
|
|
mathieu@1229
|
129 |
: m_index (index)
|
|
craigdo@1504
|
130 |
{
|
|
craigdo@1504
|
131 |
NS_LOG_FUNCTION;
|
|
craigdo@1504
|
132 |
}
|
|
craigdo@1504
|
133 |
|
|
mathieu@1229
|
134 |
uint32_t
|
|
mathieu@1341
|
135 |
Ipv4L3ProtocolInterfaceIndex::Get (void) const
|
|
mathieu@1229
|
136 |
{
|
|
craigdo@1504
|
137 |
NS_LOG_FUNCTION;
|
|
mathieu@1229
|
138 |
return m_index;
|
|
mathieu@1229
|
139 |
}
|
|
craigdo@1504
|
140 |
|
|
mathieu@1229
|
141 |
void
|
|
mathieu@1341
|
142 |
Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const
|
|
mathieu@1229
|
143 |
{
|
|
mathieu@1229
|
144 |
os << "ipv4-interface=" << m_index;
|
|
mathieu@1229
|
145 |
}
|
|
craigdo@1504
|
146 |
|
|
mathieu@1229
|
147 |
uint16_t
|
|
mathieu@1341
|
148 |
Ipv4L3ProtocolInterfaceIndex::GetUid (void)
|
|
mathieu@1229
|
149 |
{
|
|
craigdo@1504
|
150 |
NS_LOG_FUNCTION;
|
|
mathieu@1341
|
151 |
static uint16_t uid = AllocateUid<Ipv4L3ProtocolInterfaceIndex> ("Ipv4L3ProtocolInterfaceIndex");
|
|
mathieu@1229
|
152 |
return uid;
|
|
mathieu@1229
|
153 |
}
|
|
craigdo@1504
|
154 |
|
|
mathieu@1364
|
155 |
std::string
|
|
mathieu@1401
|
156 |
Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const
|
|
mathieu@1364
|
157 |
{
|
|
craigdo@1504
|
158 |
NS_LOG_FUNCTION;
|
|
mathieu@1401
|
159 |
return "ns3::Ipv4L3ProtocolInterfaceIndex";
|
|
mathieu@1364
|
160 |
}
|
|
mathieu@1229
|
161 |
|
|
mathieu@1229
|
162 |
|
|
mathieu@734
|
163 |
Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
|
|
mathieu@1176
|
164 |
: m_nInterfaces (0),
|
|
mathieu@236
|
165 |
m_defaultTtl (64),
|
|
mathieu@236
|
166 |
m_identification (0),
|
|
mathieu@241
|
167 |
m_node (node)
|
|
mathieu@444
|
168 |
{
|
|
craigdo@1504
|
169 |
NS_LOG_FUNCTION;
|
|
mathieu@2230
|
170 |
m_staticRouting = CreateObject<Ipv4StaticRouting> ();
|
|
gjc@983
|
171 |
AddRoutingProtocol (m_staticRouting, 0);
|
|
mathieu@444
|
172 |
SetupLoopback ();
|
|
mathieu@444
|
173 |
}
|
|
craigdo@1429
|
174 |
|
|
mathieu@734
|
175 |
Ipv4L3Protocol::~Ipv4L3Protocol ()
|
|
craigdo@1429
|
176 |
{
|
|
craigdo@1504
|
177 |
NS_LOG_FUNCTION;
|
|
craigdo@1429
|
178 |
}
|
|
mathieu@496
|
179 |
|
|
mathieu@496
|
180 |
void
|
|
mathieu@734
|
181 |
Ipv4L3Protocol::DoDispose (void)
|
|
mathieu@496
|
182 |
{
|
|
craigdo@1504
|
183 |
NS_LOG_FUNCTION;
|
|
mathieu@496
|
184 |
m_interfaces.clear ();
|
|
mathieu@555
|
185 |
m_node = 0;
|
|
gjc@983
|
186 |
m_staticRouting->Dispose ();
|
|
gjc@983
|
187 |
m_staticRouting = 0;
|
|
mathieu@1176
|
188 |
Object::DoDispose ();
|
|
mathieu@236
|
189 |
}
|
|
mathieu@236
|
190 |
|
|
mathieu@444
|
191 |
void
|
|
mathieu@734
|
192 |
Ipv4L3Protocol::SetupLoopback (void)
|
|
mathieu@444
|
193 |
{
|
|
craigdo@1504
|
194 |
NS_LOG_FUNCTION;
|
|
craigdo@1429
|
195 |
|
|
mathieu@2230
|
196 |
Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> (m_node);
|
|
mathieu@444
|
197 |
interface->SetAddress (Ipv4Address::GetLoopback ());
|
|
mathieu@444
|
198 |
interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
|
|
mathieu@444
|
199 |
uint32_t index = AddIpv4Interface (interface);
|
|
mathieu@444
|
200 |
AddHostRouteTo (Ipv4Address::GetLoopback (), index);
|
|
mathieu@444
|
201 |
interface->SetUp ();
|
|
mathieu@444
|
202 |
}
|
|
mathieu@444
|
203 |
|
|
mathieu@1333
|
204 |
Ptr<TraceResolver>
|
|
mathieu@1383
|
205 |
Ipv4L3Protocol::GetTraceResolver (void) const
|
|
tomh@345
|
206 |
{
|
|
craigdo@1504
|
207 |
NS_LOG_FUNCTION;
|
|
craigdo@1429
|
208 |
|
|
mathieu@1333
|
209 |
Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
|
|
mathieu@1379
|
210 |
resolver->AddSource ("tx",
|
|
mathieu@1379
|
211 |
TraceDoc ("send ipv4 packet to outgoing interface",
|
|
mathieu@1866
|
212 |
"Ptr<const Packet>", "packet sent",
|
|
mathieu@1379
|
213 |
"uint32_t", "index of output ipv4 interface"),
|
|
mathieu@1372
|
214 |
m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX));
|
|
mathieu@1379
|
215 |
resolver->AddSource ("rx",
|
|
mathieu@1379
|
216 |
TraceDoc ("receive ipv4 packet from incoming interface",
|
|
mathieu@1866
|
217 |
"Ptr<const Packet>", "packet received",
|
|
mathieu@1379
|
218 |
"uint32_t", "index of input ipv4 interface"),
|
|
mathieu@1372
|
219 |
m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX));
|
|
mathieu@1379
|
220 |
resolver->AddSource ("drop",
|
|
mathieu@1379
|
221 |
TraceDoc ("drop ipv4 packet",
|
|
mathieu@1866
|
222 |
"Ptr<const Packet>", "packet dropped"),
|
|
mathieu@1372
|
223 |
m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP));
|
|
mathieu@1341
|
224 |
resolver->AddArray ("interfaces",
|
|
mathieu@1341
|
225 |
m_interfaces.begin (), m_interfaces.end (),
|
|
mathieu@1341
|
226 |
Ipv4L3ProtocolInterfaceIndex ());
|
|
tomh@345
|
227 |
return resolver;
|
|
tomh@345
|
228 |
}
|
|
tomh@345
|
229 |
|
|
mathieu@236
|
230 |
void
|
|
mathieu@734
|
231 |
Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
|
|
mathieu@236
|
232 |
{
|
|
craigdo@1504
|
233 |
NS_LOG_FUNCTION;
|
|
mathieu@236
|
234 |
m_defaultTtl = ttl;
|
|
mathieu@236
|
235 |
}
|
|
mathieu@236
|
236 |
|
|
mathieu@236
|
237 |
|
|
mathieu@236
|
238 |
void
|
|
mathieu@734
|
239 |
Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
|
tomh@345
|
240 |
Ipv4Address nextHop,
|
|
tomh@345
|
241 |
uint32_t interface)
|
|
mathieu@236
|
242 |
{
|
|
craigdo@1504
|
243 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
244 |
NS_LOG_PARAMS (this << dest << nextHop << interface);
|
|
gjc@983
|
245 |
m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
|
|
mathieu@236
|
246 |
}
|
|
craigdo@1429
|
247 |
|
|
mathieu@236
|
248 |
void
|
|
mathieu@734
|
249 |
Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
|
mathieu@236
|
250 |
uint32_t interface)
|
|
mathieu@236
|
251 |
{
|
|
craigdo@1504
|
252 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
253 |
NS_LOG_PARAMS (this << dest << interface);
|
|
gjc@983
|
254 |
m_staticRouting->AddHostRouteTo (dest, interface);
|
|
mathieu@236
|
255 |
}
|
|
craigdo@1429
|
256 |
|
|
mathieu@236
|
257 |
void
|
|
mathieu@734
|
258 |
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
|
mathieu@236
|
259 |
Ipv4Mask networkMask,
|
|
mathieu@236
|
260 |
Ipv4Address nextHop,
|
|
mathieu@236
|
261 |
uint32_t interface)
|
|
mathieu@236
|
262 |
{
|
|
craigdo@1504
|
263 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
264 |
NS_LOG_PARAMS (this << network << networkMask << nextHop << interface);
|
|
gjc@983
|
265 |
m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
|
|
mathieu@236
|
266 |
}
|
|
craigdo@1504
|
267 |
|
|
mathieu@236
|
268 |
void
|
|
mathieu@734
|
269 |
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
|
mathieu@236
|
270 |
Ipv4Mask networkMask,
|
|
mathieu@236
|
271 |
uint32_t interface)
|
|
mathieu@236
|
272 |
{
|
|
craigdo@1504
|
273 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
274 |
NS_LOG_PARAMS (this << network << networkMask << interface);
|
|
gjc@983
|
275 |
m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
|
|
mathieu@236
|
276 |
}
|
|
craigdo@1504
|
277 |
|
|
mathieu@236
|
278 |
void
|
|
mathieu@734
|
279 |
Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
|
|
mathieu@236
|
280 |
uint32_t interface)
|
|
mathieu@236
|
281 |
{
|
|
craigdo@1504
|
282 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
283 |
NS_LOG_PARAMS (this << nextHop << interface);
|
|
gjc@983
|
284 |
m_staticRouting->SetDefaultRoute (nextHop, interface);
|
|
mathieu@236
|
285 |
}
|
|
mathieu@236
|
286 |
|
|
mathieu@1235
|
287 |
void
|
|
craigdo@1432
|
288 |
Ipv4L3Protocol::Lookup (
|
|
craigdo@1432
|
289 |
Ipv4Header const &ipHeader,
|
|
mathieu@1866
|
290 |
Ptr<Packet> packet,
|
|
craigdo@1432
|
291 |
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
|
mathieu@1235
|
292 |
{
|
|
craigdo@1504
|
293 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
294 |
NS_LOG_PARAMS (this << &ipHeader << packet << &routeReply);
|
|
craigdo@1432
|
295 |
|
|
craigdo@1432
|
296 |
Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
|
|
craigdo@1432
|
297 |
}
|
|
gjc@983
|
298 |
|
|
gjc@983
|
299 |
void
|
|
craigdo@1432
|
300 |
Ipv4L3Protocol::Lookup (
|
|
craigdo@1432
|
301 |
uint32_t ifIndex,
|
|
craigdo@1432
|
302 |
Ipv4Header const &ipHeader,
|
|
mathieu@1866
|
303 |
Ptr<Packet> packet,
|
|
craigdo@1432
|
304 |
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
|
mathieu@236
|
305 |
{
|
|
craigdo@1504
|
306 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
307 |
NS_LOG_PARAMS (this << ifIndex << &ipHeader << packet << &routeReply);
|
|
craigdo@1429
|
308 |
|
|
craigdo@1428
|
309 |
for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
|
|
craigdo@1428
|
310 |
m_routingProtocols.begin ();
|
|
craigdo@1428
|
311 |
rprotoIter != m_routingProtocols.end ();
|
|
craigdo@1428
|
312 |
rprotoIter++)
|
|
mathieu@236
|
313 |
{
|
|
craigdo@1504
|
314 |
NS_LOG_LOGIC ("Requesting route");
|
|
craigdo@1432
|
315 |
if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet,
|
|
craigdo@1432
|
316 |
routeReply))
|
|
gjc@983
|
317 |
return;
|
|
mathieu@236
|
318 |
}
|
|
craigdo@1428
|
319 |
|
|
craigdo@1440
|
320 |
if (ipHeader.GetDestination ().IsMulticast () &&
|
|
craigdo@1440
|
321 |
ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
|
|
craigdo@1440
|
322 |
{
|
|
craigdo@1504
|
323 |
NS_LOG_LOGIC ("Multicast destination with local source");
|
|
craigdo@1440
|
324 |
//
|
|
craigdo@1445
|
325 |
// We have a multicast packet originating from the current node and were not
|
|
craigdo@1445
|
326 |
// able to send it using the usual RequestRoute process. Since the usual
|
|
craigdo@1445
|
327 |
// process includes trying to use a default multicast route, this means that
|
|
craigdo@1445
|
328 |
// there was no specific route out of the node found, and there was no default
|
|
craigdo@1445
|
329 |
// multicast route set.
|
|
craigdo@1440
|
330 |
//
|
|
craigdo@1445
|
331 |
// The fallback position is to look for a default unicast route and use that
|
|
craigdo@1445
|
332 |
// to get the packet off the node if we have one.
|
|
craigdo@1445
|
333 |
//
|
|
craigdo@1445
|
334 |
Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
|
|
craigdo@1440
|
335 |
|
|
craigdo@1445
|
336 |
if (route)
|
|
craigdo@1440
|
337 |
{
|
|
craigdo@1504
|
338 |
NS_LOG_LOGIC ("Local source. Using unicast default route for "
|
|
craigdo@1504
|
339 |
"multicast packet");
|
|
craigdo@1445
|
340 |
|
|
craigdo@1445
|
341 |
routeReply (true, *route, packet, ipHeader);
|
|
craigdo@1445
|
342 |
return;
|
|
craigdo@1440
|
343 |
}
|
|
craigdo@1440
|
344 |
}
|
|
craigdo@1445
|
345 |
//
|
|
craigdo@1445
|
346 |
// No route found
|
|
craigdo@1445
|
347 |
//
|
|
gjc@983
|
348 |
routeReply (false, Ipv4Route (), packet, ipHeader);
|
|
gjc@983
|
349 |
}
|
|
gjc@983
|
350 |
|
|
gjc@983
|
351 |
void
|
|
gjc@983
|
352 |
Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
|
gjc@983
|
353 |
int priority)
|
|
gjc@983
|
354 |
{
|
|
craigdo@1504
|
355 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
356 |
NS_LOG_PARAMS (this << &routingProtocol << priority);
|
|
gjc@983
|
357 |
m_routingProtocols.push_back
|
|
gjc@983
|
358 |
(std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
|
|
gjc@983
|
359 |
m_routingProtocols.sort ();
|
|
mathieu@236
|
360 |
}
|
|
mathieu@236
|
361 |
|
|
mathieu@236
|
362 |
uint32_t
|
|
mathieu@734
|
363 |
Ipv4L3Protocol::GetNRoutes (void)
|
|
mathieu@236
|
364 |
{
|
|
craigdo@1504
|
365 |
NS_LOG_FUNCTION;
|
|
gjc@983
|
366 |
return m_staticRouting->GetNRoutes ();
|
|
mathieu@236
|
367 |
}
|
|
gjc@983
|
368 |
|
|
mathieu@236
|
369 |
Ipv4Route *
|
|
mathieu@734
|
370 |
Ipv4L3Protocol::GetRoute (uint32_t index)
|
|
mathieu@236
|
371 |
{
|
|
craigdo@1504
|
372 |
NS_LOG_FUNCTION;
|
|
gjc@983
|
373 |
return m_staticRouting->GetRoute (index);
|
|
mathieu@236
|
374 |
}
|
|
gjc@983
|
375 |
|
|
mathieu@236
|
376 |
void
|
|
mathieu@734
|
377 |
Ipv4L3Protocol::RemoveRoute (uint32_t index)
|
|
mathieu@236
|
378 |
{
|
|
craigdo@1504
|
379 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
380 |
NS_LOG_PARAMS (this << index);
|
|
gjc@983
|
381 |
m_staticRouting->RemoveRoute (index);
|
|
mathieu@236
|
382 |
}
|
|
mathieu@236
|
383 |
|
|
craigdo@1428
|
384 |
void
|
|
craigdo@1428
|
385 |
Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin,
|
|
craigdo@1428
|
386 |
Ipv4Address group,
|
|
craigdo@1428
|
387 |
uint32_t inputInterface,
|
|
craigdo@1428
|
388 |
std::vector<uint32_t> outputInterfaces)
|
|
craigdo@1428
|
389 |
{
|
|
craigdo@1504
|
390 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
391 |
NS_LOG_PARAMS (this << origin << group << inputInterface << &outputInterfaces);
|
|
craigdo@1429
|
392 |
|
|
craigdo@1428
|
393 |
m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
|
|
craigdo@1428
|
394 |
outputInterfaces);
|
|
craigdo@1428
|
395 |
}
|
|
craigdo@1428
|
396 |
|
|
craigdo@1442
|
397 |
void
|
|
craigdo@1444
|
398 |
Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
|
|
craigdo@1442
|
399 |
{
|
|
craigdo@1504
|
400 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
401 |
NS_LOG_PARAMS (this << outputInterface);
|
|
craigdo@1442
|
402 |
|
|
craigdo@1444
|
403 |
m_staticRouting->SetDefaultMulticastRoute (outputInterface);
|
|
craigdo@1442
|
404 |
}
|
|
craigdo@1442
|
405 |
|
|
craigdo@1428
|
406 |
uint32_t
|
|
craigdo@1428
|
407 |
Ipv4L3Protocol::GetNMulticastRoutes (void) const
|
|
craigdo@1428
|
408 |
{
|
|
craigdo@1504
|
409 |
NS_LOG_FUNCTION;
|
|
craigdo@1428
|
410 |
return m_staticRouting->GetNMulticastRoutes ();
|
|
craigdo@1428
|
411 |
}
|
|
craigdo@1428
|
412 |
|
|
craigdo@1428
|
413 |
Ipv4MulticastRoute *
|
|
craigdo@1428
|
414 |
Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
|
|
craigdo@1428
|
415 |
{
|
|
craigdo@1504
|
416 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
417 |
NS_LOG_PARAMS (this << index);
|
|
craigdo@1428
|
418 |
return m_staticRouting->GetMulticastRoute (index);
|
|
craigdo@1428
|
419 |
}
|
|
craigdo@1428
|
420 |
|
|
craigdo@1428
|
421 |
void
|
|
craigdo@1428
|
422 |
Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin,
|
|
craigdo@1428
|
423 |
Ipv4Address group,
|
|
craigdo@1428
|
424 |
uint32_t inputInterface)
|
|
craigdo@1428
|
425 |
{
|
|
craigdo@1504
|
426 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
427 |
NS_LOG_PARAMS (this << origin << group << inputInterface);
|
|
craigdo@1428
|
428 |
m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
|
|
craigdo@1428
|
429 |
}
|
|
craigdo@1428
|
430 |
|
|
craigdo@1428
|
431 |
void
|
|
craigdo@1428
|
432 |
Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
|
|
craigdo@1428
|
433 |
{
|
|
craigdo@1504
|
434 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
435 |
NS_LOG_PARAMS (this << index);
|
|
craigdo@1428
|
436 |
m_staticRouting->RemoveMulticastRoute (index);
|
|
craigdo@1428
|
437 |
}
|
|
mathieu@236
|
438 |
|
|
mathieu@236
|
439 |
uint32_t
|
|
mathieu@734
|
440 |
Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
|
|
mathieu@444
|
441 |
{
|
|
craigdo@1504
|
442 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
443 |
NS_LOG_PARAMS (this << &device);
|
|
mathieu@2230
|
444 |
Ptr<Ipv4Interface> interface = CreateObject<ArpIpv4Interface> (m_node, device);
|
|
mathieu@444
|
445 |
return AddIpv4Interface (interface);
|
|
mathieu@444
|
446 |
}
|
|
craigdo@1429
|
447 |
|
|
mathieu@444
|
448 |
uint32_t
|
|
mathieu@1341
|
449 |
Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
|
|
mathieu@236
|
450 |
{
|
|
craigdo@1504
|
451 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
452 |
NS_LOG_PARAMS (this << interface);
|
|
mathieu@236
|
453 |
uint32_t index = m_nInterfaces;
|
|
mathieu@236
|
454 |
m_interfaces.push_back (interface);
|
|
mathieu@236
|
455 |
m_nInterfaces++;
|
|
mathieu@236
|
456 |
return index;
|
|
mathieu@236
|
457 |
}
|
|
craigdo@1429
|
458 |
|
|
mathieu@1341
|
459 |
Ptr<Ipv4Interface>
|
|
mathieu@734
|
460 |
Ipv4L3Protocol::GetInterface (uint32_t index) const
|
|
mathieu@236
|
461 |
{
|
|
craigdo@1504
|
462 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
463 |
NS_LOG_PARAMS (this << index);
|
|
mathieu@236
|
464 |
uint32_t tmp = 0;
|
|
mathieu@236
|
465 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
|
|
mathieu@236
|
466 |
{
|
|
mathieu@236
|
467 |
if (index == tmp)
|
|
mathieu@236
|
468 |
{
|
|
mathieu@236
|
469 |
return *i;
|
|
mathieu@236
|
470 |
}
|
|
mathieu@236
|
471 |
tmp++;
|
|
mathieu@236
|
472 |
}
|
|
mathieu@236
|
473 |
return 0;
|
|
mathieu@236
|
474 |
}
|
|
craigdo@1429
|
475 |
|
|
mathieu@236
|
476 |
uint32_t
|
|
mathieu@734
|
477 |
Ipv4L3Protocol::GetNInterfaces (void) const
|
|
mathieu@236
|
478 |
{
|
|
craigdo@1504
|
479 |
NS_LOG_FUNCTION;
|
|
mathieu@236
|
480 |
return m_nInterfaces;
|
|
mathieu@236
|
481 |
}
|
|
mathieu@236
|
482 |
|
|
craigdo@1440
|
483 |
uint32_t
|
|
craigdo@1440
|
484 |
Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
|
|
craigdo@1440
|
485 |
{
|
|
craigdo@1504
|
486 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
487 |
NS_LOG_PARAMS (this << addr);
|
|
craigdo@1440
|
488 |
|
|
craigdo@1440
|
489 |
uint32_t ifIndex = 0;
|
|
craigdo@1440
|
490 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
|
craigdo@1440
|
491 |
i != m_interfaces.end ();
|
|
craigdo@1440
|
492 |
i++, ifIndex++)
|
|
craigdo@1440
|
493 |
{
|
|
craigdo@1440
|
494 |
if ((*i)->GetAddress () == addr)
|
|
craigdo@1440
|
495 |
{
|
|
craigdo@1440
|
496 |
return ifIndex;
|
|
craigdo@1440
|
497 |
}
|
|
craigdo@1440
|
498 |
}
|
|
craigdo@1440
|
499 |
|
|
craigdo@1440
|
500 |
NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
|
|
craigdo@1440
|
501 |
"Interface not found for IP address");
|
|
craigdo@1440
|
502 |
return 0;
|
|
craigdo@1440
|
503 |
}
|
|
craigdo@1440
|
504 |
|
|
craigdo@1440
|
505 |
uint32_t
|
|
craigdo@1440
|
506 |
Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
|
|
craigdo@1440
|
507 |
{
|
|
craigdo@1504
|
508 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
509 |
NS_LOG_PARAMS (this << addr << mask);
|
|
craigdo@1440
|
510 |
|
|
craigdo@1440
|
511 |
uint32_t ifIndex = 0;
|
|
craigdo@1440
|
512 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
|
craigdo@1440
|
513 |
i != m_interfaces.end ();
|
|
craigdo@1440
|
514 |
i++, ifIndex++)
|
|
craigdo@1440
|
515 |
{
|
|
craigdo@1440
|
516 |
if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
|
|
craigdo@1440
|
517 |
{
|
|
craigdo@1440
|
518 |
return ifIndex;
|
|
craigdo@1440
|
519 |
}
|
|
craigdo@1440
|
520 |
}
|
|
craigdo@1440
|
521 |
|
|
craigdo@1440
|
522 |
NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
|
|
craigdo@1440
|
523 |
"Interface not found for masked IP address");
|
|
craigdo@1440
|
524 |
return 0;
|
|
craigdo@1440
|
525 |
}
|
|
craigdo@1440
|
526 |
|
|
mathieu@1341
|
527 |
Ptr<Ipv4Interface>
|
|
mathieu@734
|
528 |
Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
|
|
mathieu@242
|
529 |
{
|
|
craigdo@1504
|
530 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
531 |
NS_LOG_PARAMS (this << &device);
|
|
mathieu@242
|
532 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
|
|
mathieu@242
|
533 |
{
|
|
mathieu@568
|
534 |
if ((*i)->GetDevice () == device)
|
|
mathieu@242
|
535 |
{
|
|
mathieu@242
|
536 |
return *i;
|
|
mathieu@242
|
537 |
}
|
|
mathieu@242
|
538 |
}
|
|
mathieu@242
|
539 |
return 0;
|
|
mathieu@242
|
540 |
}
|
|
mathieu@236
|
541 |
|
|
mathieu@236
|
542 |
void
|
|
mathieu@1866
|
543 |
Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
|
|
mathieu@236
|
544 |
{
|
|
craigdo@1504
|
545 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
546 |
NS_LOG_PARAMS (this << &device << packet << protocol << from);
|
|
craigdo@1429
|
547 |
|
|
craigdo@1504
|
548 |
NS_LOG_LOGIC ("Packet from " << from);
|
|
craigdo@1443
|
549 |
|
|
mathieu@457
|
550 |
uint32_t index = 0;
|
|
gjc@1524
|
551 |
Ptr<Ipv4Interface> ipv4Interface;
|
|
craigdo@1432
|
552 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
|
craigdo@1432
|
553 |
i != m_interfaces.end ();
|
|
craigdo@1432
|
554 |
i++)
|
|
mathieu@457
|
555 |
{
|
|
gjc@1524
|
556 |
ipv4Interface = *i;
|
|
gjc@1524
|
557 |
if (ipv4Interface->GetDevice () == device)
|
|
mathieu@457
|
558 |
{
|
|
mathieu@1866
|
559 |
m_rxTrace (packet, index);
|
|
mathieu@457
|
560 |
break;
|
|
mathieu@457
|
561 |
}
|
|
mathieu@457
|
562 |
index++;
|
|
mathieu@457
|
563 |
}
|
|
mathieu@236
|
564 |
Ipv4Header ipHeader;
|
|
mathieu@1866
|
565 |
packet->RemoveHeader (ipHeader);
|
|
mathieu@236
|
566 |
|
|
mathieu@236
|
567 |
if (!ipHeader.IsChecksumOk ())
|
|
mathieu@236
|
568 |
{
|
|
mathieu@236
|
569 |
return;
|
|
mathieu@236
|
570 |
}
|
|
mathieu@236
|
571 |
|
|
craigdo@1432
|
572 |
if (Forwarding (index, packet, ipHeader, device))
|
|
mathieu@236
|
573 |
{
|
|
mathieu@236
|
574 |
return;
|
|
mathieu@236
|
575 |
}
|
|
mathieu@236
|
576 |
|
|
craigdo@1504
|
577 |
NS_LOG_LOGIC ("Forward up");
|
|
gjc@1524
|
578 |
ForwardUp (packet, ipHeader, ipv4Interface);
|
|
mathieu@236
|
579 |
}
|
|
mathieu@236
|
580 |
|
|
gjc@983
|
581 |
|
|
mathieu@236
|
582 |
void
|
|
mathieu@1866
|
583 |
Ipv4L3Protocol::Send (Ptr<Packet> packet,
|
|
mathieu@457
|
584 |
Ipv4Address source,
|
|
mathieu@457
|
585 |
Ipv4Address destination,
|
|
mathieu@457
|
586 |
uint8_t protocol)
|
|
mathieu@236
|
587 |
{
|
|
craigdo@1504
|
588 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
589 |
NS_LOG_PARAMS (this << packet << source << destination << protocol);
|
|
craigdo@1429
|
590 |
|
|
mathieu@236
|
591 |
Ipv4Header ipHeader;
|
|
mathieu@236
|
592 |
|
|
mathieu@236
|
593 |
ipHeader.SetSource (source);
|
|
mathieu@236
|
594 |
ipHeader.SetDestination (destination);
|
|
mathieu@236
|
595 |
ipHeader.SetProtocol (protocol);
|
|
mathieu@1866
|
596 |
ipHeader.SetPayloadSize (packet->GetSize ());
|
|
mathieu@236
|
597 |
ipHeader.SetTtl (m_defaultTtl);
|
|
mathieu@236
|
598 |
ipHeader.SetMayFragment ();
|
|
mathieu@236
|
599 |
ipHeader.SetIdentification (m_identification);
|
|
mathieu@236
|
600 |
|
|
mathieu@236
|
601 |
m_identification ++;
|
|
mathieu@236
|
602 |
|
|
gjc@983
|
603 |
if (destination.IsBroadcast ())
|
|
mathieu@236
|
604 |
{
|
|
gjc@983
|
605 |
uint32_t ifaceIndex = 0;
|
|
gjc@983
|
606 |
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
|
|
gjc@983
|
607 |
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
|
|
gjc@983
|
608 |
{
|
|
mathieu@1341
|
609 |
Ptr<Ipv4Interface> outInterface = *ifaceIter;
|
|
mathieu@1866
|
610 |
Ptr<Packet> packetCopy = packet->Copy ();
|
|
mathieu@1308
|
611 |
|
|
mathieu@1866
|
612 |
NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
|
|
mathieu@1866
|
613 |
packetCopy->AddHeader (ipHeader);
|
|
mathieu@1308
|
614 |
m_txTrace (packetCopy, ifaceIndex);
|
|
mathieu@1308
|
615 |
outInterface->Send (packetCopy, destination);
|
|
gjc@983
|
616 |
}
|
|
gjc@983
|
617 |
}
|
|
gjc@983
|
618 |
else
|
|
gjc@983
|
619 |
{
|
|
gjc@983
|
620 |
// XXX Note here that in most ipv4 stacks in the world,
|
|
gjc@983
|
621 |
// the route calculation for an outgoing packet is not
|
|
gjc@983
|
622 |
// done in the ip layer. It is done within the application
|
|
gjc@983
|
623 |
// socket when the first packet is sent to avoid this
|
|
gjc@983
|
624 |
// costly lookup on a per-packet basis.
|
|
gjc@983
|
625 |
// That would require us to get the route from the packet,
|
|
gjc@983
|
626 |
// most likely with a packet tag. The higher layers do not
|
|
gjc@983
|
627 |
// do this yet for us.
|
|
gjc@983
|
628 |
Lookup (ipHeader, packet,
|
|
gjc@983
|
629 |
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
|
|
gjc@983
|
630 |
}
|
|
gjc@983
|
631 |
}
|
|
gjc@983
|
632 |
|
|
gjc@983
|
633 |
void
|
|
gjc@983
|
634 |
Ipv4L3Protocol::SendRealOut (bool found,
|
|
gjc@983
|
635 |
Ipv4Route const &route,
|
|
mathieu@1866
|
636 |
Ptr<Packet> packet,
|
|
gjc@983
|
637 |
Ipv4Header const &ipHeader)
|
|
gjc@983
|
638 |
{
|
|
craigdo@1504
|
639 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
640 |
NS_LOG_PARAMS (this << found << &route << packet << &ipHeader);
|
|
craigdo@1429
|
641 |
|
|
gjc@2325
|
642 |
packet->AddHeader (ipHeader);
|
|
gjc@983
|
643 |
if (!found)
|
|
gjc@983
|
644 |
{
|
|
craigdo@1504
|
645 |
NS_LOG_WARN ("No route to host. Drop.");
|
|
tomh@345
|
646 |
m_dropTrace (packet);
|
|
mathieu@236
|
647 |
return;
|
|
mathieu@236
|
648 |
}
|
|
craigdo@1430
|
649 |
|
|
craigdo@1504
|
650 |
NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
|
|
craigdo@1430
|
651 |
|
|
mathieu@1341
|
652 |
Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
|
|
mathieu@1866
|
653 |
NS_ASSERT (packet->GetSize () <= outInterface->GetMtu ());
|
|
mathieu@457
|
654 |
m_txTrace (packet, route.GetInterface ());
|
|
mathieu@236
|
655 |
if (route.IsGateway ())
|
|
mathieu@236
|
656 |
{
|
|
craigdo@1504
|
657 |
NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
|
|
mathieu@236
|
658 |
outInterface->Send (packet, route.GetGateway ());
|
|
mathieu@236
|
659 |
}
|
|
mathieu@236
|
660 |
else
|
|
mathieu@236
|
661 |
{
|
|
craigdo@1504
|
662 |
NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
|
|
gjc@983
|
663 |
outInterface->Send (packet, ipHeader.GetDestination ());
|
|
mathieu@236
|
664 |
}
|
|
mathieu@236
|
665 |
}
|
|
mathieu@236
|
666 |
|
|
mathieu@1235
|
667 |
bool
|
|
craigdo@1432
|
668 |
Ipv4L3Protocol::Forwarding (
|
|
craigdo@1432
|
669 |
uint32_t ifIndex,
|
|
mathieu@1866
|
670 |
Ptr<Packet> packet,
|
|
craigdo@1432
|
671 |
Ipv4Header &ipHeader,
|
|
craigdo@1432
|
672 |
Ptr<NetDevice> device)
|
|
mathieu@1235
|
673 |
{
|
|
craigdo@1504
|
674 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
675 |
NS_LOG_PARAMS (ifIndex << packet << &ipHeader<< device);
|
|
mathieu@236
|
676 |
|
|
mathieu@236
|
677 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
|
mathieu@236
|
678 |
i != m_interfaces.end (); i++)
|
|
mathieu@236
|
679 |
{
|
|
mathieu@236
|
680 |
if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ()))
|
|
mathieu@236
|
681 |
{
|
|
craigdo@1504
|
682 |
NS_LOG_LOGIC ("For me (destination match)");
|
|
mathieu@236
|
683 |
return false;
|
|
mathieu@236
|
684 |
}
|
|
mathieu@236
|
685 |
}
|
|
mathieu@236
|
686 |
|
|
mathieu@236
|
687 |
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
|
mathieu@236
|
688 |
i != m_interfaces.end (); i++)
|
|
mathieu@236
|
689 |
{
|
|
mathieu@1341
|
690 |
Ptr<Ipv4Interface> interface = *i;
|
|
mathieu@568
|
691 |
if (interface->GetDevice () == device)
|
|
mathieu@236
|
692 |
{
|
|
mathieu@236
|
693 |
if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
|
|
mathieu@236
|
694 |
{
|
|
craigdo@1504
|
695 |
NS_LOG_LOGIC ("For me (interface broadcast address)");
|
|
mathieu@236
|
696 |
return false;
|
|
mathieu@236
|
697 |
}
|
|
mathieu@236
|
698 |
break;
|
|
mathieu@236
|
699 |
}
|
|
mathieu@236
|
700 |
}
|
|
mathieu@236
|
701 |
|
|
gjc@983
|
702 |
if (ipHeader.GetDestination ().IsBroadcast ())
|
|
mathieu@236
|
703 |
{
|
|
craigdo@1504
|
704 |
NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
|
|
mathieu@236
|
705 |
return false;
|
|
mathieu@236
|
706 |
}
|
|
craigdo@1430
|
707 |
|
|
mathieu@236
|
708 |
if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ()))
|
|
mathieu@236
|
709 |
{
|
|
craigdo@1504
|
710 |
NS_LOG_LOGIC ("For me (Ipv4Addr any address)");
|
|
mathieu@236
|
711 |
return false;
|
|
mathieu@236
|
712 |
}
|
|
craigdo@1430
|
713 |
|
|
mathieu@236
|
714 |
if (ipHeader.GetTtl () == 1)
|
|
mathieu@236
|
715 |
{
|
|
mathieu@236
|
716 |
// Should send ttl expired here
|
|
mathieu@236
|
717 |
// XXX
|
|
craigdo@1504
|
718 |
NS_LOG_LOGIC ("Not for me (TTL expired). Drop");
|
|
tomh@345
|
719 |
m_dropTrace (packet);
|
|
mathieu@236
|
720 |
return true;
|
|
mathieu@236
|
721 |
}
|
|
mathieu@236
|
722 |
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
|
|
gjc@983
|
723 |
|
|
craigdo@1504
|
724 |
NS_LOG_LOGIC ("Forwarding packet.");
|
|
craigdo@1432
|
725 |
Lookup (ifIndex, ipHeader, packet,
|
|
gjc@983
|
726 |
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
|
|
craigdo@1428
|
727 |
//
|
|
craigdo@1428
|
728 |
// If this is a to a multicast address and this node is a member of the
|
|
craigdo@1428
|
729 |
// indicated group we need to return false so the multicast is forwarded up.
|
|
craigdo@1428
|
730 |
// Note that we may have just forwarded this packet too.
|
|
craigdo@1428
|
731 |
//
|
|
craigdo@1428
|
732 |
for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin ();
|
|
craigdo@1428
|
733 |
i != m_multicastGroups.end (); i++)
|
|
craigdo@1428
|
734 |
{
|
|
craigdo@1428
|
735 |
if ((*i).first.IsEqual (ipHeader.GetSource ()) &&
|
|
craigdo@1428
|
736 |
(*i).second.IsEqual (ipHeader.GetDestination ()))
|
|
craigdo@1428
|
737 |
{
|
|
craigdo@1504
|
738 |
NS_LOG_LOGIC ("For me (Joined multicast group)");
|
|
craigdo@1428
|
739 |
return false;
|
|
craigdo@1428
|
740 |
}
|
|
craigdo@1428
|
741 |
}
|
|
craigdo@1428
|
742 |
|
|
craigdo@1504
|
743 |
NS_LOG_LOGIC("Not for me.");
|
|
mathieu@236
|
744 |
return true;
|
|
mathieu@236
|
745 |
}
|
|
mathieu@236
|
746 |
|
|
mathieu@236
|
747 |
void
|
|
mathieu@1866
|
748 |
Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
|
|
gjc@1524
|
749 |
Ptr<Ipv4Interface> incomingInterface)
|
|
mathieu@236
|
750 |
{
|
|
craigdo@1504
|
751 |
NS_LOG_FUNCTION;
|
|
mathieu@1870
|
752 |
NS_LOG_PARAMS (this << p << &ip);
|
|
craigdo@1504
|
753 |
|
|
mathieu@2257
|
754 |
Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
|
|
mathieu@568
|
755 |
Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
|
|
gjc@1524
|
756 |
protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
|
|
mathieu@236
|
757 |
}
|
|
mathieu@236
|
758 |
|
|
mathieu@444
|
759 |
void
|
|
craigdo@1428
|
760 |
Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
|
craigdo@1428
|
761 |
{
|
|
craigdo@1504
|
762 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
763 |
NS_LOG_PARAMS (this << origin << group);
|
|
craigdo@1428
|
764 |
m_multicastGroups.push_back(
|
|
craigdo@1428
|
765 |
std::pair<Ipv4Address, Ipv4Address> (origin, group));
|
|
craigdo@1428
|
766 |
}
|
|
craigdo@1428
|
767 |
|
|
craigdo@1428
|
768 |
void
|
|
craigdo@1428
|
769 |
Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
|
craigdo@1428
|
770 |
{
|
|
craigdo@1504
|
771 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
772 |
NS_LOG_PARAMS (this << origin << group);
|
|
craigdo@1429
|
773 |
|
|
craigdo@1428
|
774 |
for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
|
|
craigdo@1428
|
775 |
i != m_multicastGroups.end ();
|
|
craigdo@1428
|
776 |
i++)
|
|
craigdo@1428
|
777 |
{
|
|
craigdo@1428
|
778 |
if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group))
|
|
craigdo@1428
|
779 |
{
|
|
craigdo@1428
|
780 |
m_multicastGroups.erase (i);
|
|
craigdo@1428
|
781 |
return;
|
|
craigdo@1428
|
782 |
}
|
|
craigdo@1428
|
783 |
}
|
|
craigdo@1428
|
784 |
}
|
|
craigdo@1428
|
785 |
|
|
craigdo@1428
|
786 |
void
|
|
mathieu@734
|
787 |
Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
|
|
mathieu@444
|
788 |
{
|
|
craigdo@1504
|
789 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
790 |
NS_LOG_PARAMS (this << i << address);
|
|
mathieu@1341
|
791 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
792 |
interface->SetAddress (address);
|
|
mathieu@444
|
793 |
}
|
|
craigdo@1429
|
794 |
|
|
mathieu@444
|
795 |
void
|
|
mathieu@734
|
796 |
Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
|
|
mathieu@444
|
797 |
{
|
|
craigdo@1504
|
798 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
799 |
NS_LOG_PARAMS (this << i << mask);
|
|
mathieu@1341
|
800 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
801 |
interface->SetNetworkMask (mask);
|
|
mathieu@444
|
802 |
}
|
|
craigdo@1429
|
803 |
|
|
mathieu@444
|
804 |
Ipv4Mask
|
|
mathieu@734
|
805 |
Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
|
|
mathieu@444
|
806 |
{
|
|
craigdo@1504
|
807 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
808 |
NS_LOG_PARAMS (this << i);
|
|
mathieu@1341
|
809 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
810 |
return interface->GetNetworkMask ();
|
|
mathieu@444
|
811 |
}
|
|
craigdo@1429
|
812 |
|
|
mathieu@444
|
813 |
Ipv4Address
|
|
mathieu@734
|
814 |
Ipv4L3Protocol::GetAddress (uint32_t i) const
|
|
mathieu@444
|
815 |
{
|
|
craigdo@1504
|
816 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
817 |
NS_LOG_PARAMS (this << i);
|
|
mathieu@1341
|
818 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
819 |
return interface->GetAddress ();
|
|
mathieu@444
|
820 |
}
|
|
craigdo@1429
|
821 |
|
|
tomh@1776
|
822 |
void
|
|
tomh@1776
|
823 |
Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
|
|
tomh@1776
|
824 |
{
|
|
tomh@1776
|
825 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
826 |
NS_LOG_PARAMS ("(" << i << ", " << metric << ")");
|
|
tomh@1776
|
827 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
tomh@1776
|
828 |
interface->SetMetric (metric);
|
|
tomh@1776
|
829 |
}
|
|
tomh@1776
|
830 |
|
|
tomh@1776
|
831 |
uint16_t
|
|
tomh@1776
|
832 |
Ipv4L3Protocol::GetMetric (uint32_t i) const
|
|
tomh@1776
|
833 |
{
|
|
tomh@1776
|
834 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
835 |
NS_LOG_PARAMS ("(" << i << ")");
|
|
tomh@1776
|
836 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
tomh@1776
|
837 |
return interface->GetMetric ();
|
|
tomh@1776
|
838 |
}
|
|
tomh@1776
|
839 |
|
|
craigdo@1434
|
840 |
bool
|
|
craigdo@1434
|
841 |
Ipv4L3Protocol::GetIfIndexForDestination (
|
|
craigdo@1434
|
842 |
Ipv4Address destination, uint32_t& ifIndex) const
|
|
craigdo@1434
|
843 |
{
|
|
craigdo@1504
|
844 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
845 |
NS_LOG_PARAMS (this << destination << &ifIndex);
|
|
craigdo@1442
|
846 |
//
|
|
craigdo@1442
|
847 |
// The first thing we do in trying to determine a source address is to
|
|
craigdo@1442
|
848 |
// consult the routing protocols. These will also check for a default route
|
|
craigdo@1442
|
849 |
// if one has been set.
|
|
craigdo@1442
|
850 |
//
|
|
craigdo@1434
|
851 |
for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
|
|
craigdo@1434
|
852 |
i != m_routingProtocols.end ();
|
|
craigdo@1434
|
853 |
i++)
|
|
craigdo@1434
|
854 |
{
|
|
craigdo@1504
|
855 |
NS_LOG_LOGIC ("Requesting Source Address");
|
|
craigdo@1435
|
856 |
uint32_t ifIndexTmp;
|
|
craigdo@1434
|
857 |
|
|
craigdo@1435
|
858 |
if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
|
|
craigdo@1434
|
859 |
{
|
|
craigdo@1504
|
860 |
NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
|
|
craigdo@1435
|
861 |
ifIndex = ifIndexTmp;
|
|
craigdo@1434
|
862 |
return true;
|
|
craigdo@1434
|
863 |
}
|
|
craigdo@1434
|
864 |
}
|
|
craigdo@1440
|
865 |
//
|
|
craigdo@1442
|
866 |
// If there's no routing table entry telling us what *single* interface will
|
|
craigdo@1442
|
867 |
// be used to send a packet to this destination, we'll have to just pick one.
|
|
craigdo@1440
|
868 |
// If there's only one interface on this node, a good answer isn't very hard
|
|
craigdo@1440
|
869 |
// to come up with. Before jumping to any conclusions, remember that the
|
|
craigdo@1440
|
870 |
// zeroth interface is the loopback interface, so what we actually want is
|
|
craigdo@1440
|
871 |
// a situation where there are exactly two interfaces on the node, in which
|
|
craigdo@1442
|
872 |
// case interface one is the "single" interface connected to the outside world.
|
|
craigdo@1440
|
873 |
//
|
|
craigdo@1440
|
874 |
if (GetNInterfaces () == 2)
|
|
craigdo@1440
|
875 |
{
|
|
craigdo@1504
|
876 |
NS_LOG_LOGIC ("One Interface. Using interface 1.");
|
|
craigdo@1440
|
877 |
ifIndex = 1;
|
|
craigdo@1440
|
878 |
return true;
|
|
craigdo@1440
|
879 |
}
|
|
craigdo@1440
|
880 |
//
|
|
craigdo@1440
|
881 |
// If we fall through to here, we have a node with multiple interfaces and
|
|
craigdo@1442
|
882 |
// no routes to guide us in determining what interface to choose. Either
|
|
craigdo@1442
|
883 |
// no default route was found (for unicast or multicast), or in the case of a
|
|
craigdo@1442
|
884 |
// multicast, the default route contained multiple outbound interfaces.
|
|
craigdo@1442
|
885 |
//
|
|
craigdo@1442
|
886 |
// The fallback position is to just get the unicast default route and use
|
|
craigdo@1442
|
887 |
// the outgoing interface specified there. We don't want to leave the source
|
|
craigdo@1442
|
888 |
// address unset, so we just assert here.
|
|
craigdo@1442
|
889 |
//
|
|
craigdo@1442
|
890 |
// N.B. that in the case of a multicast with a route containing multiple
|
|
craigdo@1442
|
891 |
// outgoing interfaces, the source address of packets from that node will be
|
|
craigdo@1442
|
892 |
// set to the IP address of the interface set in the default unicast route.
|
|
craigdo@1442
|
893 |
// Also, in the case of a broadcast, the same will be true.
|
|
craigdo@1442
|
894 |
//
|
|
craigdo@1504
|
895 |
NS_LOG_LOGIC ("Using default unicast route");
|
|
craigdo@1440
|
896 |
Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
|
|
craigdo@1440
|
897 |
|
|
gjc@2324
|
898 |
if (route == NULL)
|
|
gjc@2324
|
899 |
{
|
|
gjc@2324
|
900 |
NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
|
|
gjc@2324
|
901 |
"Unable to determine outbound interface. No default route set");
|
|
gjc@2324
|
902 |
return false;
|
|
gjc@2324
|
903 |
}
|
|
craigdo@1440
|
904 |
|
|
craigdo@1440
|
905 |
ifIndex = route->GetInterface ();
|
|
craigdo@1440
|
906 |
|
|
craigdo@1504
|
907 |
NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
|
|
craigdo@1440
|
908 |
return true;
|
|
craigdo@1434
|
909 |
}
|
|
craigdo@1434
|
910 |
|
|
mathieu@444
|
911 |
uint16_t
|
|
mathieu@734
|
912 |
Ipv4L3Protocol::GetMtu (uint32_t i) const
|
|
mathieu@444
|
913 |
{
|
|
craigdo@1504
|
914 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
915 |
NS_LOG_PARAMS (this << i);
|
|
mathieu@1341
|
916 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
917 |
return interface->GetMtu ();
|
|
mathieu@444
|
918 |
}
|
|
craigdo@1429
|
919 |
|
|
mathieu@444
|
920 |
bool
|
|
mathieu@734
|
921 |
Ipv4L3Protocol::IsUp (uint32_t i) const
|
|
mathieu@444
|
922 |
{
|
|
craigdo@1504
|
923 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
924 |
NS_LOG_PARAMS (this << i);
|
|
mathieu@1341
|
925 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
926 |
return interface->IsUp ();
|
|
mathieu@444
|
927 |
}
|
|
craigdo@1429
|
928 |
|
|
mathieu@444
|
929 |
void
|
|
mathieu@734
|
930 |
Ipv4L3Protocol::SetUp (uint32_t i)
|
|
mathieu@444
|
931 |
{
|
|
craigdo@1504
|
932 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
933 |
NS_LOG_PARAMS (this << i);
|
|
mathieu@1341
|
934 |
Ptr<Ipv4Interface> interface = GetInterface (i);
|
|
mathieu@444
|
935 |
interface->SetUp ();
|
|
tomh@979
|
936 |
|
|
tomh@979
|
937 |
// If interface address and network mask have been set, add a route
|
|
tomh@979
|
938 |
// to the network of the interface (like e.g. ifconfig does on a
|
|
tomh@979
|
939 |
// Linux box)
|
|
tomh@979
|
940 |
if ((interface->GetAddress ()) != (Ipv4Address ())
|
|
tomh@979
|
941 |
&& (interface->GetNetworkMask ()) != (Ipv4Mask ()))
|
|
tomh@979
|
942 |
{
|
|
tomh@979
|
943 |
AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
|
|
tomh@979
|
944 |
interface->GetNetworkMask (), i);
|
|
tomh@979
|
945 |
}
|
|
mathieu@444
|
946 |
}
|
|
craigdo@1429
|
947 |
|
|
mathieu@444
|
948 |
void
|
|
tomh@979
|
949 |
Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
|
|
mathieu@444
|
950 |
{
|
|
craigdo@1504
|
951 |
NS_LOG_FUNCTION;
|
|
tomh@1828
|
952 |
NS_LOG_PARAMS (this << ifaceIndex);
|
|
mathieu@1341
|
953 |
Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
|
|
mathieu@444
|
954 |
interface->SetDown ();
|
|
tomh@979
|
955 |
|
|
tomh@979
|
956 |
// Remove all routes that are going through this interface
|
|
tomh@979
|
957 |
bool modified = true;
|
|
tomh@979
|
958 |
while (modified)
|
|
tomh@979
|
959 |
{
|
|
tomh@979
|
960 |
modified = false;
|
|
tomh@979
|
961 |
for (uint32_t i = 0; i < GetNRoutes (); i++)
|
|
tomh@979
|
962 |
{
|
|
tomh@979
|
963 |
Ipv4Route *route = GetRoute (i);
|
|
tomh@979
|
964 |
if (route->GetInterface () == ifaceIndex)
|
|
tomh@979
|
965 |
{
|
|
tomh@979
|
966 |
RemoveRoute (i);
|
|
tomh@979
|
967 |
modified = true;
|
|
tomh@979
|
968 |
break;
|
|
tomh@979
|
969 |
}
|
|
tomh@979
|
970 |
}
|
|
tomh@979
|
971 |
}
|
|
mathieu@444
|
972 |
}
|
|
mathieu@444
|
973 |
|
|
mathieu@236
|
974 |
}//namespace ns3
|