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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "udp-header.h"
21
22#include "ns3/address-utils.h"
23
24namespace ns3
25{
26
28
29void
31{
32 m_calcChecksum = true;
33}
34
35void
37{
39}
40
41void
43{
45}
46
47uint16_t
49{
50 return m_sourcePort;
51}
52
53uint16_t
55{
56 return m_destinationPort;
57}
58
59void
60UdpHeader::InitializeChecksum(Address source, Address destination, uint8_t protocol)
61{
62 m_source = source;
63 m_destination = destination;
64 m_protocol = protocol;
65}
66
67void
68UdpHeader::InitializeChecksum(Ipv4Address source, Ipv4Address destination, uint8_t protocol)
69{
70 m_source = source;
71 m_destination = destination;
72 m_protocol = protocol;
73}
74
75void
76UdpHeader::InitializeChecksum(Ipv6Address source, Ipv6Address destination, uint8_t protocol)
77{
78 m_source = source;
79 m_destination = destination;
80 m_protocol = protocol;
81}
82
83uint16_t
85{
86 Buffer buf = Buffer((2 * Address::MAX_SIZE) + 8);
87 buf.AddAtStart((2 * Address::MAX_SIZE) + 8);
88 Buffer::Iterator it = buf.Begin();
89 uint32_t hdrSize = 0;
90
91 WriteTo(it, m_source);
94 {
95 it.WriteU8(0); /* protocol */
96 it.WriteU8(m_protocol); /* protocol */
97 it.WriteU8(size >> 8); /* length */
98 it.WriteU8(size & 0xff); /* length */
99 hdrSize = 12;
100 }
102 {
103 it.WriteU16(0);
104 it.WriteU8(size >> 8); /* length */
105 it.WriteU8(size & 0xff); /* length */
106 it.WriteU16(0);
107 it.WriteU8(0);
108 it.WriteU8(m_protocol); /* protocol */
109 hdrSize = 40;
110 }
111
112 it = buf.Begin();
113 /* we don't CompleteChecksum ( ~ ) now */
114 return ~(it.CalculateIpChecksum(hdrSize));
115}
116
117bool
119{
120 return m_goodChecksum;
121}
122
123void
124UdpHeader::ForceChecksum(uint16_t checksum)
125{
126 m_checksum = checksum;
127}
128
129void
130UdpHeader::ForcePayloadSize(uint16_t payloadSize)
131{
132 m_forcedPayloadSize = payloadSize;
133}
134
135TypeId
137{
138 static TypeId tid = TypeId("ns3::UdpHeader")
139 .SetParent<Header>()
140 .SetGroupName("Internet")
141 .AddConstructor<UdpHeader>();
142 return tid;
143}
144
145TypeId
147{
148 return GetTypeId();
149}
150
151void
152UdpHeader::Print(std::ostream& os) const
153{
154 os << "length: " << m_payloadSize + GetSerializedSize() << " " << m_sourcePort << " > "
156}
157
160{
161 return 8;
162}
163
164void
166{
167 Buffer::Iterator i = start;
168
171 if (m_forcedPayloadSize == 0)
172 {
173 i.WriteHtonU16(start.GetSize());
174 }
175 else
176 {
178 }
179
180 if (m_checksum == 0)
181 {
182 i.WriteU16(0);
183
184 if (m_calcChecksum)
185 {
186 uint16_t headerChecksum = CalculateHeaderChecksum(start.GetSize());
187 i = start;
188 uint16_t checksum = i.CalculateIpChecksum(start.GetSize(), headerChecksum);
189
190 i = start;
191 i.Next(6);
192
193 // RFC 768: If the computed checksum is zero, it is transmitted as all ones
194 if (checksum == 0)
195 {
196 checksum = 0xffff;
197 }
198 i.WriteU16(checksum);
199 }
200 }
201 else
202 {
204 }
205}
206
209{
210 Buffer::Iterator i = start;
214 m_checksum = i.ReadU16();
215
216 // RFC 768: An all zero transmitted checksum value means that the
217 // transmitter generated no checksum (for debugging or for higher
218 // level protocols that don't care).
219 //
220 // This is common in IPv4, while IPv6 requires UDP to use its checksum.
221 //
222 // As strange as it might sound, flipping from 0x0000 to 0xffff does not
223 // change anything in the verification.
224 //
225 // According to RFC 1141, the following holds:
226 // ~C' = ~(C + (-m) + m') = ~C + (m - m') = ~C + m + ~m'
227 // If ~C (the original CRC) is zero, m (the CRC field) is zero, and m' is 0xffff,
228 // then, according to the formula, we have that ~C' is zero.
229 // I.e., changing the CRC from 0 to 0xffff has no effect on the Rx verification.
230 //
231 // Fun fact: if you take an IPv4 header with an Identification field set to zero
232 // and you change it to 0xffff, the checksum will not change (~_^)
234 {
235 uint16_t headerChecksum = CalculateHeaderChecksum(start.GetSize());
236 i = start;
237 uint16_t checksum = i.CalculateIpChecksum(start.GetSize(), headerChecksum);
238
239 m_goodChecksum = (checksum == 0);
240 }
241
242 return GetSerializedSize();
243}
244
245uint16_t
247{
248 return m_checksum;
249}
250
251} // namespace ns3
a polymophic address class
Definition: address.h:101
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition: address.h:107
iterator in a Buffer instance
Definition: buffer.h:100
uint16_t CalculateIpChecksum(uint16_t size)
Calculate the checksum.
Definition: buffer.cc:1135
void WriteU8(uint8_t data)
Definition: buffer.h:881
void WriteU16(uint16_t data)
Definition: buffer.cc:859
void WriteHtonU16(uint16_t data)
Definition: buffer.h:915
uint16_t ReadNtohU16()
Definition: buffer.h:954
uint16_t ReadU16()
Definition: buffer.h:1035
void Next()
go forward by one byte
Definition: buffer.h:853
automatically resized byte buffer
Definition: buffer.h:94
void AddAtStart(uint32_t start)
Definition: buffer.cc:314
Buffer::Iterator Begin() const
Definition: buffer.h:1074
Protocol header serialization and deserialization.
Definition: header.h:44
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static bool IsMatchingType(const Address &address)
Describes an IPv6 address.
Definition: ipv6-address.h:49
static bool IsMatchingType(const Address &address)
If the Address matches the type.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Packet header for UDP packets.
Definition: udp-header.h:41
uint32_t GetSerializedSize() const override
Definition: udp-header.cc:159
void Serialize(Buffer::Iterator start) const override
Definition: udp-header.cc:165
Address m_destination
Destination IP address.
Definition: udp-header.h:172
uint16_t CalculateHeaderChecksum(uint16_t size) const
Calculate the header checksum.
Definition: udp-header.cc:84
void EnableChecksums()
Enable checksum calculation for UDP.
Definition: udp-header.cc:30
uint8_t m_protocol
Protocol number.
Definition: udp-header.h:173
uint16_t m_destinationPort
Destination port.
Definition: udp-header.h:167
uint16_t GetDestinationPort() const
Definition: udp-header.cc:54
Address m_source
Source IP address.
Definition: udp-header.h:171
uint16_t m_payloadSize
Payload size.
Definition: udp-header.h:168
void ForceChecksum(uint16_t checksum)
Force the UDP checksum to a given value.
Definition: udp-header.cc:124
uint16_t m_sourcePort
Source port.
Definition: udp-header.h:166
uint16_t GetSourcePort() const
Definition: udp-header.cc:48
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: udp-header.cc:146
bool m_calcChecksum
Flag to calculate checksum.
Definition: udp-header.h:175
void Print(std::ostream &os) const override
Definition: udp-header.cc:152
void ForcePayloadSize(uint16_t payloadSize)
Force the UDP payload length to a given value.
Definition: udp-header.cc:130
bool IsChecksumOk() const
Is the UDP checksum correct ?
Definition: udp-header.cc:118
uint32_t Deserialize(Buffer::Iterator start) override
Definition: udp-header.cc:208
uint16_t m_forcedPayloadSize
Payload size (forced)
Definition: udp-header.h:169
uint16_t GetChecksum() const
Return the checksum (only known after a Deserialize)
Definition: udp-header.cc:246
uint16_t m_checksum
Forced Checksum value.
Definition: udp-header.h:174
void InitializeChecksum(Address source, Address destination, uint8_t protocol)
Definition: udp-header.cc:60
static TypeId GetTypeId()
Get the type ID.
Definition: udp-header.cc:136
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:42
bool m_goodChecksum
Flag to indicate that checksum is correct.
Definition: udp-header.h:176
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:36
uint16_t port
Definition: dsdv-manet.cc:44
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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.