A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
udp-l4-protocol.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "udp-l4-protocol.h"
10
12#include "ipv4-end-point.h"
13#include "ipv4-route.h"
14#include "ipv4.h"
16#include "ipv6-end-point.h"
17#include "ipv6-route.h"
18#include "ipv6.h"
19#include "udp-header.h"
21#include "udp-socket-impl.h"
22
23#include "ns3/assert.h"
24#include "ns3/boolean.h"
25#include "ns3/log.h"
26#include "ns3/node.h"
27#include "ns3/object-map.h"
28#include "ns3/packet.h"
29
30#include <unordered_map>
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("UdpL4Protocol");
36
37NS_OBJECT_ENSURE_REGISTERED(UdpL4Protocol);
38
39TypeId
41{
42 static TypeId tid =
43 TypeId("ns3::UdpL4Protocol")
45 .SetGroupName("Internet")
46 .AddConstructor<UdpL4Protocol>()
47 .AddAttribute("SocketList",
48 "A container of sockets associated to this protocol. "
49 "The underlying type is an unordered map, the attribute name "
50 "is kept for backward compatibility.",
54 return tid;
55}
56
58 : m_endPoints(new Ipv4EndPointDemux()),
59 m_endPoints6(new Ipv6EndPointDemux())
60{
61 NS_LOG_FUNCTION(this);
62}
63
68
69void
71{
72 m_node = node;
73}
74
75/*
76 * This method is called by AggregateObject and completes the aggregation
77 * by setting the node in the udp stack and link it to the ipv4 object
78 * present in the node along with the socket factory
79 */
80void
82{
83 NS_LOG_FUNCTION(this);
84 Ptr<Node> node = this->GetObject<Node>();
85 Ptr<Ipv4> ipv4 = this->GetObject<Ipv4>();
86 Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
87
88 if (!m_node)
89 {
90 if (node && (ipv4 || ipv6))
91 {
92 this->SetNode(node);
94 udpFactory->SetUdp(this);
95 node->AggregateObject(udpFactory);
96 }
97 }
98
99 // We set at least one of our 2 down targets to the IPv4/IPv6 send
100 // functions. Since these functions have different prototypes, we
101 // need to keep track of whether we are connected to an IPv4 or
102 // IPv6 lower layer and call the appropriate one.
103
104 if (ipv4 && m_downTarget.IsNull())
105 {
106 ipv4->Insert(this);
108 }
109 if (ipv6 && m_downTarget6.IsNull())
110 {
111 ipv6->Insert(this);
113 }
115}
116
117int
119{
120 return PROT_NUMBER;
121}
122
123void
125{
126 NS_LOG_FUNCTION(this);
127 for (auto i = m_sockets.begin(); i != m_sockets.end(); i++)
128 {
129 i->second = nullptr;
130 }
131 m_sockets.clear();
132
133 if (m_endPoints != nullptr)
134 {
135 delete m_endPoints;
136 m_endPoints = nullptr;
137 }
138 if (m_endPoints6 != nullptr)
139 {
140 delete m_endPoints6;
141 m_endPoints6 = nullptr;
142 }
143 m_node = nullptr;
146 /*
147 = MakeNullCallback<void,Ptr<Packet>, Ipv4Address, Ipv4Address, uint8_t, Ptr<Ipv4Route> > ();
148 */
150}
151
154{
155 NS_LOG_FUNCTION(this);
157 socket->SetNode(m_node);
158 socket->SetUdp(this);
159 m_sockets[m_socketIndex++] = socket;
160 return socket;
161}
162
165{
166 NS_LOG_FUNCTION(this);
167 return m_endPoints->Allocate();
168}
169
172{
173 NS_LOG_FUNCTION(this << address);
174 return m_endPoints->Allocate(address);
175}
176
183
186{
187 NS_LOG_FUNCTION(this << boundNetDevice << address << port);
188 return m_endPoints->Allocate(boundNetDevice, address, port);
189}
190
193 Ipv4Address localAddress,
194 uint16_t localPort,
196 uint16_t peerPort)
197{
198 NS_LOG_FUNCTION(this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
200}
201
202void
208
211{
212 NS_LOG_FUNCTION(this);
213 return m_endPoints6->Allocate();
214}
215
218{
219 NS_LOG_FUNCTION(this << address);
220 return m_endPoints6->Allocate(address);
221}
222
229
236
239 Ipv6Address localAddress,
240 uint16_t localPort,
242 uint16_t peerPort)
243{
244 NS_LOG_FUNCTION(this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
246}
247
248void
254
255void
257 uint8_t icmpTtl,
258 uint8_t icmpType,
259 uint8_t icmpCode,
263 const uint8_t payload[8])
264{
267 uint16_t src;
268 uint16_t dst;
269 src = payload[0] << 8;
270 src |= payload[1];
271 dst = payload[2] << 8;
272 dst |= payload[3];
273
275 if (endPoint != nullptr)
276 {
278 }
279 else
280 {
281 NS_LOG_DEBUG("no endpoint found source=" << payloadSource
282 << ", destination=" << payloadDestination
283 << ", src=" << src << ", dst=" << dst);
284 }
285}
286
287void
289 uint8_t icmpTtl,
290 uint8_t icmpType,
291 uint8_t icmpCode,
295 const uint8_t payload[8])
296{
299 uint16_t src;
300 uint16_t dst;
301 src = payload[0] << 8;
302 src |= payload[1];
303 dst = payload[2] << 8;
304 dst |= payload[3];
305
308 if (endPoint != nullptr)
309 {
311 }
312 else
313 {
314 NS_LOG_DEBUG("no endpoint found source=" << payloadSource
315 << ", destination=" << payloadDestination
316 << ", src=" << src << ", dst=" << dst);
317 }
318}
319
322{
323 NS_LOG_FUNCTION(this << packet << header);
326 {
328 }
329
330 udpHeader.InitializeChecksum(header.GetSource(), header.GetDestination(), PROT_NUMBER);
331
332 // We only peek at the header for now (instead of removing it) so that it will be intact
333 // if we have to pass it to a IPv6 endpoint via:
334 //
335 // UdpL4Protocol::Receive (Ptr<Packet> packet, Ipv6Address &src, Ipv6Address &dst, ...)
336
337 packet->PeekHeader(udpHeader);
338
339 if (!udpHeader.IsChecksumOk())
340 {
341 NS_LOG_INFO("Bad checksum : dropping packet!");
343 }
344
345 NS_LOG_DEBUG("Looking up dst " << header.GetDestination() << " port "
346 << udpHeader.GetDestinationPort());
348 udpHeader.GetDestinationPort(),
349 header.GetSource(),
350 udpHeader.GetSourcePort(),
351 interface);
352 if (endPoints.empty())
353 {
354 if (this->GetObject<Ipv6>())
355 {
356 NS_LOG_LOGIC(" No Ipv4 endpoints matched on UdpL4Protocol, trying Ipv6 " << this);
361 ipv6Header.SetSource(src);
362 ipv6Header.SetDestination(dst);
363 return (this->Receive(packet, ipv6Header, fakeInterface));
364 }
365
366 NS_LOG_LOGIC("RX_ENDPOINT_UNREACH");
368 }
369
370 packet->RemoveHeader(udpHeader);
371 for (auto endPoint = endPoints.begin(); endPoint != endPoints.end(); endPoint++)
372 {
373 (*endPoint)->ForwardUp(packet->Copy(), header, udpHeader.GetSourcePort(), interface);
374 }
375 return IpL4Protocol::RX_OK;
376}
377
380{
381 NS_LOG_FUNCTION(this << packet << header.GetSource() << header.GetDestination());
384 {
386 }
387
388 udpHeader.InitializeChecksum(header.GetSource(), header.GetDestination(), PROT_NUMBER);
389
390 packet->RemoveHeader(udpHeader);
391
392 if (!udpHeader.IsChecksumOk() && !header.GetSource().IsIpv4MappedAddress())
393 {
394 NS_LOG_INFO("Bad checksum : dropping packet!");
396 }
397
398 NS_LOG_DEBUG("Looking up dst " << header.GetDestination() << " port "
399 << udpHeader.GetDestinationPort());
401 udpHeader.GetDestinationPort(),
402 header.GetSource(),
403 udpHeader.GetSourcePort(),
404 interface);
405 if (endPoints.empty())
406 {
407 NS_LOG_LOGIC("RX_ENDPOINT_UNREACH");
409 }
410 for (auto endPoint = endPoints.begin(); endPoint != endPoints.end(); endPoint++)
411 {
412 (*endPoint)->ForwardUp(packet->Copy(), header, udpHeader.GetSourcePort(), interface);
413 }
414 return IpL4Protocol::RX_OK;
415}
416
417void
421 uint16_t sport,
422 uint16_t dport)
423{
424 NS_LOG_FUNCTION(this << packet << saddr << daddr << sport << dport);
425
428 {
430 udpHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
431 }
432 udpHeader.SetDestinationPort(dport);
433 udpHeader.SetSourcePort(sport);
434
435 packet->AddHeader(udpHeader);
436
437 m_downTarget(packet, saddr, daddr, PROT_NUMBER, nullptr);
438}
439
440void
444 uint16_t sport,
445 uint16_t dport,
447{
448 NS_LOG_FUNCTION(this << packet << saddr << daddr << sport << dport << route);
449
452 {
454 udpHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
455 }
456 udpHeader.SetDestinationPort(dport);
457 udpHeader.SetSourcePort(sport);
458
459 packet->AddHeader(udpHeader);
460
462}
463
464void
468 uint16_t sport,
469 uint16_t dport)
470{
471 NS_LOG_FUNCTION(this << packet << saddr << daddr << sport << dport);
472
475 {
477 udpHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
478 }
479 udpHeader.SetDestinationPort(dport);
480 udpHeader.SetSourcePort(sport);
481
482 packet->AddHeader(udpHeader);
483
484 m_downTarget6(packet, saddr, daddr, PROT_NUMBER, nullptr);
485}
486
487void
491 uint16_t sport,
492 uint16_t dport,
494{
495 NS_LOG_FUNCTION(this << packet << saddr << daddr << sport << dport << route);
496
499 {
501 udpHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
502 }
503 udpHeader.SetDestinationPort(dport);
504 udpHeader.SetSourcePort(sport);
505
506 packet->AddHeader(udpHeader);
507
509}
510
511void
517
520{
521 return m_downTarget;
522}
523
524void
530
533{
534 return m_downTarget6;
535}
536
537bool
539{
540 NS_LOG_FUNCTION(this << socket);
541
542 for (auto& socketItem : m_sockets)
543 {
544 if (socketItem.second == socket)
545 {
546 socketItem.second = nullptr;
547 m_sockets.erase(socketItem.first);
548 return true;
549 }
550 }
551 return false;
552}
553
554} // namespace ns3
void Nullify()
Discard the implementation, set it to null.
Definition callback.h:561
bool IsNull() const
Check for null implementation.
Definition callback.h:555
L4 Protocol abstract base class.
RxStatus
Rx status codes.
Ipv4 addresses are stored in host order in this class.
Demultiplexes packets to various transport layer endpoints.
Ipv4EndPoint * SimpleLookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport)
simple lookup for a match with all the parameters.
EndPoints Lookup(Ipv4Address daddr, uint16_t dport, Ipv4Address saddr, uint16_t sport, Ptr< Ipv4Interface > incomingInterface)
lookup for a match with all the parameters.
void DeAllocate(Ipv4EndPoint *endPoint)
Remove a end point.
Ipv4EndPoint * Allocate()
Allocate a Ipv4EndPoint.
std::list< Ipv4EndPoint * > EndPoints
Container of the IPv4 endpoints.
A representation of an internet endpoint/connection.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Forward the ICMP packet to the upper level.
Packet header for IPv4.
Definition ipv4-header.h:23
Ipv4Address GetSource() const
Ipv4Address GetDestination() const
virtual void Send(Ptr< Packet > packet, Ipv4Address source, Ipv4Address destination, uint8_t protocol, Ptr< Ipv4Route > route)=0
Describes an IPv6 address.
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Demultiplexer for end points.
EndPoints Lookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr< Ipv6Interface > incomingInterface)
lookup for a match with all the parameters.
Ipv6EndPoint * Allocate()
Allocate a Ipv6EndPoint.
Ipv6EndPoint * SimpleLookup(Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
Simple lookup for a four-tuple match.
void DeAllocate(Ipv6EndPoint *endPoint)
Remove a end point.
std::list< Ipv6EndPoint * > EndPoints
Container of the IPv6 endpoints.
A representation of an IPv6 endpoint/connection.
void ForwardIcmp(Ipv6Address src, uint8_t ttl, uint8_t type, uint8_t code, uint32_t info)
Forward the ICMP packet to the upper level.
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
Ipv6Address GetSource() const
Get the "Source address" field.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition ipv6.h:71
virtual void Send(Ptr< Packet > packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr< Ipv6Route > route)=0
Higher-level layers call this method to send a packet down the stack to the MAC and PHY layers.
static bool ChecksumEnabled()
Definition node.cc:267
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition object.cc:412
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Packet header for UDP packets.
Definition udp-header.h:30
void EnableChecksums()
Enable checksum calculation for UDP.
Definition udp-header.cc:19
Implementation of the UDP protocol.
void SetDownTarget6(IpL4Protocol::DownTargetCallback6 cb) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv6 ca...
Ptr< Socket > CreateSocket()
void Send(Ptr< Packet > packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport, uint16_t dport)
Send a packet via UDP (IPv4)
Ipv6EndPoint * Allocate6()
Allocate an IPv6 Endpoint.
void SetDownTarget(IpL4Protocol::DownTargetCallback cb) override
This method allows a caller to set the current down target callback set for this L4 protocol (IPv4 ca...
std::unordered_map< uint64_t, Ptr< UdpSocketImpl > > m_sockets
Unordered map of socket IDs and corresponding sockets.
Ipv6EndPointDemux * m_endPoints6
A list of IPv6 end points.
int GetProtocolNumber() const override
Returns the protocol number of this protocol.
Ptr< Node > m_node
The node this stack is associated with.
Ipv4EndPointDemux * m_endPoints
A list of IPv4 end points.
void ReceiveIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo, Ipv4Address payloadSource, Ipv4Address payloadDestination, const uint8_t payload[8]) override
Called from lower-level layers to send the ICMP packet up in the stack.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
IpL4Protocol::DownTargetCallback GetDownTarget() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv4 ca...
static TypeId GetTypeId()
Get the type ID.
IpL4Protocol::DownTargetCallback6 GetDownTarget6() const override
This method allows a caller to get the current down target callback set for this L4 protocol (IPv6 ca...
Ipv4EndPoint * Allocate()
Allocate an IPv4 Endpoint.
IpL4Protocol::RxStatus Receive(Ptr< Packet > p, const Ipv4Header &header, Ptr< Ipv4Interface > interface) override
Called from lower-level layers to send the packet up in the stack.
bool RemoveSocket(Ptr< UdpSocketImpl > socket)
Remove a socket from the internal list.
IpL4Protocol::DownTargetCallback m_downTarget
Callback to send packets over IPv4.
IpL4Protocol::DownTargetCallback6 m_downTarget6
Callback to send packets over IPv6.
void DoDispose() override
Destructor implementation.
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
void DeAllocate(Ipv4EndPoint *endPoint)
Remove an IPv4 Endpoint.
static constexpr uint8_t PROT_NUMBER
Protocol number (see http://www.iana.org/assignments/protocol-numbers)
uint64_t m_socketIndex
Index of the next socket to be created.
uint16_t port
Definition dsdv-manet.cc:33
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition object-map.h:29
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition object-map.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684