A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
udp-header.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-header.h"
10
11#include "ns3/address-utils.h"
12
13namespace ns3
14{
15
17
18void
23
24void
29
30void
35
36uint16_t
38{
39 return m_sourcePort;
40}
41
42uint16_t
47
48void
49UdpHeader::InitializeChecksum(Address source, Address destination, uint8_t protocol)
50{
51 m_source = source;
52 m_destination = destination;
53 m_protocol = protocol;
54}
55
56void
57UdpHeader::InitializeChecksum(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
58{
59 m_source = source;
60 m_destination = destination;
61 m_protocol = protocol;
62}
63
64void
65UdpHeader::InitializeChecksum(Ipv6Address source, Ipv6Address destination, uint8_t protocol)
66{
67 m_source = source;
68 m_destination = destination;
69 m_protocol = protocol;
70}
71
72uint16_t
74{
75 Buffer buf = Buffer((2 * Address::MAX_SIZE) + 8);
76 buf.AddAtStart((2 * Address::MAX_SIZE) + 8);
77 Buffer::Iterator it = buf.Begin();
78 uint32_t hdrSize = 0;
79
80 WriteTo(it, m_source);
83 {
84 it.WriteU8(0); /* protocol */
85 it.WriteU8(m_protocol); /* protocol */
86 it.WriteU8(size >> 8); /* length */
87 it.WriteU8(size & 0xff); /* length */
88 hdrSize = 12;
89 }
91 {
92 it.WriteU16(0);
93 it.WriteU8(size >> 8); /* length */
94 it.WriteU8(size & 0xff); /* length */
95 it.WriteU16(0);
96 it.WriteU8(0);
97 it.WriteU8(m_protocol); /* protocol */
98 hdrSize = 40;
99 }
100
101 it = buf.Begin();
102 /* we don't CompleteChecksum ( ~ ) now */
103 return ~(it.CalculateIpChecksum(hdrSize));
104}
105
106bool
108{
109 return m_goodChecksum;
110}
111
112void
113UdpHeader::ForceChecksum(uint16_t checksum)
114{
115 m_checksum = checksum;
116}
117
118void
119UdpHeader::ForcePayloadSize(uint16_t payloadSize)
120{
121 m_forcedPayloadSize = payloadSize;
122}
123
124TypeId
126{
127 static TypeId tid = TypeId("ns3::UdpHeader")
128 .SetParent<Header>()
129 .SetGroupName("Internet")
130 .AddConstructor<UdpHeader>();
131 return tid;
132}
133
134TypeId
136{
137 return GetTypeId();
138}
139
140void
141UdpHeader::Print(std::ostream& os) const
142{
143 os << "length: " << m_payloadSize + GetSerializedSize() << " " << m_sourcePort << " > "
145}
146
149{
150 return 8;
151}
152
153void
155{
156 Buffer::Iterator i = start;
157
160 if (m_forcedPayloadSize == 0)
161 {
162 i.WriteHtonU16(start.GetSize());
163 }
164 else
165 {
167 }
168
169 if (m_checksum == 0)
170 {
171 i.WriteU16(0);
172
173 if (m_calcChecksum)
174 {
175 uint16_t headerChecksum = CalculateHeaderChecksum(start.GetSize());
176 i = start;
177 uint16_t checksum = i.CalculateIpChecksum(start.GetSize(), headerChecksum);
178
179 i = start;
180 i.Next(6);
181
182 // RFC 768: If the computed checksum is zero, it is transmitted as all ones
183 if (checksum == 0)
184 {
185 checksum = 0xffff;
186 }
187 i.WriteU16(checksum);
188 }
189 }
190 else
191 {
193 }
194}
195
198{
199 Buffer::Iterator i = start;
203 m_checksum = i.ReadU16();
204
205 // RFC 768: An all zero transmitted checksum value means that the
206 // transmitter generated no checksum (for debugging or for higher
207 // level protocols that don't care).
208 //
209 // This is common in IPv4, while IPv6 requires UDP to use its checksum.
210 //
211 // As strange as it might sound, flipping from 0x0000 to 0xffff does not
212 // change anything in the verification.
213 //
214 // According to RFC 1141, the following holds:
215 // ~C' = ~(C + (-m) + m') = ~C + (m - m') = ~C + m + ~m'
216 // If ~C (the original CRC) is zero, m (the CRC field) is zero, and m' is 0xffff,
217 // then, according to the formula, we have that ~C' is zero.
218 // I.e., changing the CRC from 0 to 0xffff has no effect on the Rx verification.
219 //
220 // Fun fact: if you take an IPv4 header with an Identification field set to zero
221 // and you change it to 0xffff, the checksum will not change (~_^)
223 {
224 uint16_t headerChecksum = CalculateHeaderChecksum(start.GetSize());
225 i = start;
226 uint16_t checksum = i.CalculateIpChecksum(start.GetSize(), headerChecksum);
227
228 m_goodChecksum = (checksum == 0);
229 }
230
231 return GetSerializedSize();
232}
233
234uint16_t
236{
237 return m_checksum;
238}
239
240} // namespace ns3
a polymophic address class
Definition address.h:90
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition address.h:96
iterator in a Buffer instance
Definition buffer.h:89
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition buffer.cc:1124
void WriteU8(uint8_t data)
Definition buffer.h:870
void WriteU16(uint16_t data)
Definition buffer.cc:848
void WriteHtonU16(uint16_t data)
Definition buffer.h:904
uint16_t ReadNtohU16()
Definition buffer.h:943
uint16_t ReadU16()
Definition buffer.h:1024
void Next()
go forward by one byte
Definition buffer.h:842
automatically resized byte buffer
Definition buffer.h:83
void AddAtStart(uint32_t start)
Definition buffer.cc:303
Buffer::Iterator Begin() const
Definition buffer.h:1063
Protocol header serialization and deserialization.
Definition header.h:33
Ipv4 addresses are stored in host order in this class.
static bool IsMatchingType(const Address &address)
Describes an IPv6 address.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Packet header for UDP packets.
Definition udp-header.h:30
uint32_t GetSerializedSize() const override
void Serialize(Buffer::Iterator start) const override
Address m_destination
Destination IP address.
Definition udp-header.h:161
uint16_t CalculateHeaderChecksum(uint16_t size) const
Calculate the header checksum.
Definition udp-header.cc:73
void EnableChecksums()
Enable checksum calculation for UDP.
Definition udp-header.cc:19
uint8_t m_protocol
Protocol number.
Definition udp-header.h:162
uint16_t m_destinationPort
Destination port.
Definition udp-header.h:156
uint16_t GetDestinationPort() const
Definition udp-header.cc:43
Address m_source
Source IP address.
Definition udp-header.h:160
uint16_t m_payloadSize
Payload size.
Definition udp-header.h:157
void ForceChecksum(uint16_t checksum)
Force the UDP checksum to a given value.
uint16_t m_sourcePort
Source port.
Definition udp-header.h:155
uint16_t GetSourcePort() const
Definition udp-header.cc:37
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
bool m_calcChecksum
Flag to calculate checksum.
Definition udp-header.h:164
void Print(std::ostream &os) const override
void ForcePayloadSize(uint16_t payloadSize)
Force the UDP payload length to a given value.
bool IsChecksumOk() const
Is the UDP checksum correct ?
uint32_t Deserialize(Buffer::Iterator start) override
uint16_t m_forcedPayloadSize
Payload size (forced)
Definition udp-header.h:158
uint16_t GetChecksum() const
Return the checksum (only known after a Deserialize)
uint16_t m_checksum
Forced Checksum value.
Definition udp-header.h:163
void InitializeChecksum(Address source, Address destination, uint8_t protocol)
Definition udp-header.cc:49
static TypeId GetTypeId()
Get the type ID.
void SetSourcePort(uint16_t port)
Definition udp-header.cc:31
bool m_goodChecksum
Flag to indicate that checksum is correct.
Definition udp-header.h:165
void SetDestinationPort(uint16_t port)
Definition udp-header.cc:25
uint16_t port
Definition dsdv-manet.cc:33
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.