20 // |
20 // |
21 |
21 |
22 #include "ns3/packet.h" |
22 #include "ns3/packet.h" |
23 #include "ns3/debug.h" |
23 #include "ns3/debug.h" |
24 #include "ns3/composite-trace-resolver.h" |
24 #include "ns3/composite-trace-resolver.h" |
25 #include "ns3/array-trace-resolver.h" |
|
26 #include "ns3/callback.h" |
25 #include "ns3/callback.h" |
27 #include "ns3/ipv4-address.h" |
26 #include "ns3/ipv4-address.h" |
28 #include "ns3/ipv4-route.h" |
27 #include "ns3/ipv4-route.h" |
29 #include "ns3/node.h" |
28 #include "ns3/node.h" |
30 #include "ns3/net-device.h" |
29 #include "ns3/net-device.h" |
86 Ipv4L3ProtocolTraceContextElement::GetUid (void) |
85 Ipv4L3ProtocolTraceContextElement::GetUid (void) |
87 { |
86 { |
88 static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement"); |
87 static uint16_t uid = AllocateUid<Ipv4L3ProtocolTraceContextElement> ("Ipv4L3ProtocolTraceContextElement"); |
89 return uid; |
88 return uid; |
90 } |
89 } |
91 |
90 std::string |
92 |
91 Ipv4L3ProtocolTraceContextElement::GetTypeName (void) const |
93 Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex () |
92 { |
|
93 return "ns3::Ipv4L3ProtocolTraceContextElement"; |
|
94 } |
|
95 |
|
96 |
|
97 Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex () |
94 : m_index (0) |
98 : m_index (0) |
95 {} |
99 {} |
96 Ipv4l3ProtocolInterfaceIndex::Ipv4l3ProtocolInterfaceIndex (uint32_t index) |
100 Ipv4L3ProtocolInterfaceIndex::Ipv4L3ProtocolInterfaceIndex (uint32_t index) |
97 : m_index (index) |
101 : m_index (index) |
98 {} |
102 {} |
99 uint32_t |
103 uint32_t |
100 Ipv4l3ProtocolInterfaceIndex::Get (void) const |
104 Ipv4L3ProtocolInterfaceIndex::Get (void) const |
101 { |
105 { |
102 return m_index; |
106 return m_index; |
103 } |
107 } |
104 void |
108 void |
105 Ipv4l3ProtocolInterfaceIndex::Print (std::ostream &os) const |
109 Ipv4L3ProtocolInterfaceIndex::Print (std::ostream &os) const |
106 { |
110 { |
107 os << "ipv4-interface=" << m_index; |
111 os << "ipv4-interface=" << m_index; |
108 } |
112 } |
109 uint16_t |
113 uint16_t |
110 Ipv4l3ProtocolInterfaceIndex::GetUid (void) |
114 Ipv4L3ProtocolInterfaceIndex::GetUid (void) |
111 { |
115 { |
112 static uint16_t uid = AllocateUid<Ipv4l3ProtocolInterfaceIndex> ("Ipv4l3ProtocolInterfaceIndex"); |
116 static uint16_t uid = AllocateUid<Ipv4L3ProtocolInterfaceIndex> ("Ipv4L3ProtocolInterfaceIndex"); |
113 return uid; |
117 return uid; |
|
118 } |
|
119 std::string |
|
120 Ipv4L3ProtocolInterfaceIndex::GetTypeName (void) const |
|
121 { |
|
122 return "ns3::Ipv4L3ProtocolInterfaceIndex"; |
114 } |
123 } |
115 |
124 |
116 |
125 |
117 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node) |
126 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node) |
118 : m_nInterfaces (0), |
127 : m_nInterfaces (0), |
129 {} |
138 {} |
130 |
139 |
131 void |
140 void |
132 Ipv4L3Protocol::DoDispose (void) |
141 Ipv4L3Protocol::DoDispose (void) |
133 { |
142 { |
134 for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) |
|
135 { |
|
136 delete (*i); |
|
137 } |
|
138 m_interfaces.clear (); |
143 m_interfaces.clear (); |
139 m_node = 0; |
144 m_node = 0; |
140 m_staticRouting->Dispose (); |
145 m_staticRouting->Dispose (); |
141 m_staticRouting = 0; |
146 m_staticRouting = 0; |
142 Object::DoDispose (); |
147 Object::DoDispose (); |
143 } |
148 } |
144 |
149 |
145 void |
150 void |
146 Ipv4L3Protocol::SetupLoopback (void) |
151 Ipv4L3Protocol::SetupLoopback (void) |
147 { |
152 { |
148 Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node); |
153 Ptr<Ipv4LoopbackInterface> interface = Create<Ipv4LoopbackInterface> (m_node); |
149 interface->SetAddress (Ipv4Address::GetLoopback ()); |
154 interface->SetAddress (Ipv4Address::GetLoopback ()); |
150 interface->SetNetworkMask (Ipv4Mask::GetLoopback ()); |
155 interface->SetNetworkMask (Ipv4Mask::GetLoopback ()); |
151 uint32_t index = AddIpv4Interface (interface); |
156 uint32_t index = AddIpv4Interface (interface); |
152 AddHostRouteTo (Ipv4Address::GetLoopback (), index); |
157 AddHostRouteTo (Ipv4Address::GetLoopback (), index); |
153 interface->SetUp (); |
158 interface->SetUp (); |
154 } |
159 } |
155 |
160 |
156 TraceResolver * |
161 Ptr<TraceResolver> |
157 Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context) |
162 Ipv4L3Protocol::GetTraceResolver (void) const |
158 { |
163 { |
159 CompositeTraceResolver *resolver = new CompositeTraceResolver (context); |
164 Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> (); |
160 resolver->Add ("tx", m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX)); |
165 resolver->AddSource ("tx", |
161 resolver->Add ("rx", m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX)); |
166 TraceDoc ("send ipv4 packet to outgoing interface", |
162 resolver->Add ("drop", m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP)); |
167 "const Packet &", "packet sent", |
163 resolver->Add ("interfaces", |
168 "uint32_t", "index of output ipv4 interface"), |
164 MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this)); |
169 m_txTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::TX)); |
165 return resolver; |
170 resolver->AddSource ("rx", |
166 } |
171 TraceDoc ("receive ipv4 packet from incoming interface", |
167 |
172 "const Packet &", "packet received", |
168 TraceResolver * |
173 "uint32_t", "index of input ipv4 interface"), |
169 Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const |
174 m_rxTrace, Ipv4L3ProtocolTraceContextElement(Ipv4L3ProtocolTraceContextElement::RX)); |
170 { |
175 resolver->AddSource ("drop", |
171 ArrayTraceResolver<Ipv4Interface *, Ipv4l3ProtocolInterfaceIndex> *resolver = |
176 TraceDoc ("drop ipv4 packet", |
172 new ArrayTraceResolver<Ipv4Interface *,Ipv4l3ProtocolInterfaceIndex> |
177 "const Packet &", "packet dropped"), |
173 (context, |
178 m_dropTrace, Ipv4L3ProtocolTraceContextElement (Ipv4L3ProtocolTraceContextElement::DROP)); |
174 MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this), |
179 resolver->AddArray ("interfaces", |
175 MakeCallback (&Ipv4L3Protocol::GetInterface, this)); |
180 m_interfaces.begin (), m_interfaces.end (), |
|
181 Ipv4L3ProtocolInterfaceIndex ()); |
176 return resolver; |
182 return resolver; |
177 } |
183 } |
178 |
184 |
179 void |
185 void |
180 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) |
186 Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl) |
263 |
269 |
264 |
270 |
265 uint32_t |
271 uint32_t |
266 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device) |
272 Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device) |
267 { |
273 { |
268 Ipv4Interface *interface = new ArpIpv4Interface (m_node, device); |
274 Ptr<Ipv4Interface> interface = Create<ArpIpv4Interface> (m_node, device); |
269 return AddIpv4Interface (interface); |
275 return AddIpv4Interface (interface); |
270 } |
276 } |
271 uint32_t |
277 uint32_t |
272 Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface) |
278 Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface) |
273 { |
279 { |
274 uint32_t index = m_nInterfaces; |
280 uint32_t index = m_nInterfaces; |
275 m_interfaces.push_back (interface); |
281 m_interfaces.push_back (interface); |
276 m_nInterfaces++; |
282 m_nInterfaces++; |
277 return index; |
283 return index; |
278 } |
284 } |
279 Ipv4Interface * |
285 Ptr<Ipv4Interface> |
280 Ipv4L3Protocol::GetInterface (uint32_t index) const |
286 Ipv4L3Protocol::GetInterface (uint32_t index) const |
281 { |
287 { |
282 uint32_t tmp = 0; |
288 uint32_t tmp = 0; |
283 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) |
289 for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) |
284 { |
290 { |
362 { |
368 { |
363 uint32_t ifaceIndex = 0; |
369 uint32_t ifaceIndex = 0; |
364 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin (); |
370 for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin (); |
365 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++) |
371 ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++) |
366 { |
372 { |
367 Ipv4Interface *outInterface = *ifaceIter; |
373 Ptr<Ipv4Interface> outInterface = *ifaceIter; |
368 Packet packetCopy = packet; |
374 Packet packetCopy = packet; |
369 |
375 |
370 NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ()); |
376 NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ()); |
371 packetCopy.AddHeader (ipHeader); |
377 packetCopy.AddHeader (ipHeader); |
372 m_txTrace (packetCopy, ifaceIndex); |
378 m_txTrace (packetCopy, ifaceIndex); |
399 NS_DEBUG ("no route to host. drop."); |
405 NS_DEBUG ("no route to host. drop."); |
400 m_dropTrace (packet); |
406 m_dropTrace (packet); |
401 return; |
407 return; |
402 } |
408 } |
403 packet.AddHeader (ipHeader); |
409 packet.AddHeader (ipHeader); |
404 Ipv4Interface *outInterface = GetInterface (route.GetInterface ()); |
410 Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ()); |
405 NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); |
411 NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); |
406 m_txTrace (packet, route.GetInterface ()); |
412 m_txTrace (packet, route.GetInterface ()); |
407 if (route.IsGateway ()) |
413 if (route.IsGateway ()) |
408 { |
414 { |
409 outInterface->Send (packet, route.GetGateway ()); |
415 outInterface->Send (packet, route.GetGateway ()); |
479 } |
485 } |
480 |
486 |
481 void |
487 void |
482 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address) |
488 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address) |
483 { |
489 { |
484 Ipv4Interface *interface = GetInterface (i); |
490 Ptr<Ipv4Interface> interface = GetInterface (i); |
485 interface->SetAddress (address); |
491 interface->SetAddress (address); |
486 } |
492 } |
487 void |
493 void |
488 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask) |
494 Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask) |
489 { |
495 { |
490 Ipv4Interface *interface = GetInterface (i); |
496 Ptr<Ipv4Interface> interface = GetInterface (i); |
491 interface->SetNetworkMask (mask); |
497 interface->SetNetworkMask (mask); |
492 } |
498 } |
493 Ipv4Mask |
499 Ipv4Mask |
494 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const |
500 Ipv4L3Protocol::GetNetworkMask (uint32_t i) const |
495 { |
501 { |
496 Ipv4Interface *interface = GetInterface (i); |
502 Ptr<Ipv4Interface> interface = GetInterface (i); |
497 return interface->GetNetworkMask (); |
503 return interface->GetNetworkMask (); |
498 } |
504 } |
499 Ipv4Address |
505 Ipv4Address |
500 Ipv4L3Protocol::GetAddress (uint32_t i) const |
506 Ipv4L3Protocol::GetAddress (uint32_t i) const |
501 { |
507 { |
502 Ipv4Interface *interface = GetInterface (i); |
508 Ptr<Ipv4Interface> interface = GetInterface (i); |
503 return interface->GetAddress (); |
509 return interface->GetAddress (); |
504 } |
510 } |
505 uint16_t |
511 uint16_t |
506 Ipv4L3Protocol::GetMtu (uint32_t i) const |
512 Ipv4L3Protocol::GetMtu (uint32_t i) const |
507 { |
513 { |
508 Ipv4Interface *interface = GetInterface (i); |
514 Ptr<Ipv4Interface> interface = GetInterface (i); |
509 return interface->GetMtu (); |
515 return interface->GetMtu (); |
510 } |
516 } |
511 bool |
517 bool |
512 Ipv4L3Protocol::IsUp (uint32_t i) const |
518 Ipv4L3Protocol::IsUp (uint32_t i) const |
513 { |
519 { |
514 Ipv4Interface *interface = GetInterface (i); |
520 Ptr<Ipv4Interface> interface = GetInterface (i); |
515 return interface->IsUp (); |
521 return interface->IsUp (); |
516 } |
522 } |
517 void |
523 void |
518 Ipv4L3Protocol::SetUp (uint32_t i) |
524 Ipv4L3Protocol::SetUp (uint32_t i) |
519 { |
525 { |
520 Ipv4Interface *interface = GetInterface (i); |
526 Ptr<Ipv4Interface> interface = GetInterface (i); |
521 interface->SetUp (); |
527 interface->SetUp (); |
522 |
528 |
523 // If interface address and network mask have been set, add a route |
529 // If interface address and network mask have been set, add a route |
524 // to the network of the interface (like e.g. ifconfig does on a |
530 // to the network of the interface (like e.g. ifconfig does on a |
525 // Linux box) |
531 // Linux box) |