View | Details | Raw Unified | Return to bug 236
Collapse All | Expand All

(-)a/examples/tcp-large-transfer.cc (+3 lines)
 Lines 71-76   int main (int argc, char *argv[]) Link Here 
71
  // Make the random number generators generate reproducible results.
71
  // Make the random number generators generate reproducible results.
72
  //
72
  //
73
  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
73
  RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
74
75
  Config::SetDefault("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue(true));
76
  Config::SetDefault("ns3::TcpL4Protocol::CalcChecksum", BooleanValue(true));
74
77
75
  // Allow the user to override any of the defaults and the above
78
  // Allow the user to override any of the defaults and the above
76
  // Bind()s at run-time, via command-line arguments
79
  // Bind()s at run-time, via command-line arguments
(-)a/examples/udp-echo.cc (+3 lines)
 Lines 66-71   main (int argc, char *argv[]) Link Here 
66
  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
66
  LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
67
  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
67
  LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
68
#endif
68
#endif
69
70
  Config::SetDefault("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue(true));
71
  Config::SetDefault("ns3::UdpL4Protocol::CalcChecksum", BooleanValue(true));
69
72
70
// Allow the user to override any of the defaults and the above Bind() at
73
// Allow the user to override any of the defaults and the above Bind() at
71
// run-time, via command-line arguments
74
// run-time, via command-line arguments
(-)a/src/common/buffer.cc (+23 lines)
 Lines 1105-1110   Buffer::Iterator::ReadU8 (void) Link Here 
1105
1105
1106
#endif /* BUFFER_USE_INLINE */
1106
#endif /* BUFFER_USE_INLINE */
1107
1107
1108
uint16_t
1109
Buffer::Iterator::CalculateIpChecksum(uint16_t size)
1110
{
1111
  return CalculateIpChecksum(size, 0);
1112
}
1113
1114
uint16_t
1115
Buffer::Iterator::CalculateIpChecksum(uint16_t size, uint32_t initialChecksum)
1116
{
1117
  /* see RFC 1071 to understand this code. */
1118
  uint32_t sum = initialChecksum;
1119
1120
  for (int j = 0; j < size/2; j++)
1121
    sum += ReadU16 ();
1122
1123
  if (size & 1)
1124
     sum += ReadU8 ();
1125
1126
  while (sum >> 16)
1127
    sum = (sum & 0xffff) + (sum >> 16);
1128
  return ~sum;
1129
}
1130
1108
} // namespace ns3
1131
} // namespace ns3
1109
1132
1110
1133
(-)a/src/common/buffer.h (+16 lines)
 Lines 342-347   public: Link Here 
342
       * bytes read.
342
       * bytes read.
343
       */
343
       */
344
      void Read (uint8_t *buffer, uint32_t size);
344
      void Read (uint8_t *buffer, uint32_t size);
345
346
      /**
347
       * \brief Calculate the checksum.
348
       * \param size size of the buffer.
349
       * \return checksum
350
       */
351
      uint16_t CalculateIpChecksum(uint16_t size);
352
353
      /**
354
       * \brief Calculate the checksum.
355
       * \param size size of the buffer.
356
       * \param initialChecksum initial value
357
       * \return checksum
358
       */
359
      uint16_t CalculateIpChecksum(uint16_t size, uint32_t initialChecksum);
360
345
  private:
361
  private:
346
      friend class Buffer;
362
      friend class Buffer;
347
      Iterator (Buffer const*buffer);
363
      Iterator (Buffer const*buffer);
(-)a/src/internet-stack/tcp-header.cc (-22 / +73 lines)
 Lines 28-35   namespace ns3 { Link Here 
28
28
29
NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
29
NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
30
30
31
bool TcpHeader::m_calcChecksum = false;
32
33
TcpHeader::TcpHeader ()
31
TcpHeader::TcpHeader ()
34
  : m_sourcePort (0),
32
  : m_sourcePort (0),
35
    m_destinationPort (0),
33
    m_destinationPort (0),
 Lines 38-45   TcpHeader::TcpHeader () Link Here 
38
    m_length (5),
36
    m_length (5),
39
    m_flags (0),
37
    m_flags (0),
40
    m_windowSize (0xffff),
38
    m_windowSize (0xffff),
39
    m_urgentPointer (0),
40
    m_initialChecksum(0),
41
    m_checksum (0),
41
    m_checksum (0),
42
    m_urgentPointer (0)
42
    m_calcChecksum(false),
43
    m_goodChecksum(true)
43
{}
44
{}
44
45
45
TcpHeader::~TcpHeader ()
46
TcpHeader::~TcpHeader ()
 Lines 49-54   TcpHeader::EnableChecksums (void) Link Here 
49
TcpHeader::EnableChecksums (void)
50
TcpHeader::EnableChecksums (void)
50
{
51
{
51
  m_calcChecksum = true;
52
  m_calcChecksum = true;
53
}
54
55
void TcpHeader::SetPayloadSize(uint16_t payloadSize)
56
{
57
  m_payloadSize = payloadSize;
52
}
58
}
53
59
54
void TcpHeader::SetSourcePort (uint16_t port)
60
void TcpHeader::SetSourcePort (uint16_t port)
 Lines 130-137   TcpHeader::InitializeChecksum (Ipv4Addre Link Here 
130
                                   Ipv4Address destination,
136
                                   Ipv4Address destination,
131
                                   uint8_t protocol)
137
                                   uint8_t protocol)
132
{
138
{
133
  m_checksum = 0;
139
  Buffer buf = Buffer(12);
134
//XXX requires peeking into IP to get length of the TCP segment
140
  uint8_t tmp[4];
141
  Buffer::Iterator it;
142
  uint16_t tcpLength = m_payloadSize + GetSerializedSize();
143
144
  buf.AddAtStart(12);
145
  it = buf.Begin();
146
147
  source.Serialize(tmp);
148
  it.Write(tmp, 4); /* source IP address */
149
  destination.Serialize(tmp);
150
  it.Write(tmp, 4); /* destination IP address */
151
  it.WriteU8(0); /* protocol */
152
  it.WriteU8(protocol); /* protocol */
153
  it.WriteU8(tcpLength >> 8); /* length */
154
  it.WriteU8(tcpLength & 0xff); /* length */
155
156
  it = buf.Begin();
157
  /* we don't CompleteChecksum ( ~ ) now */
158
  m_initialChecksum = ~(it.CalculateIpChecksum(12));
159
}
160
161
bool
162
TcpHeader::IsChecksumOk (void) const
163
{
164
  return m_goodChecksum;
135
}
165
}
136
166
137
TypeId 
167
TypeId 
 Lines 188-215   uint32_t TcpHeader::GetSerializedSize (v Link Here 
188
}
218
}
189
void TcpHeader::Serialize (Buffer::Iterator start)  const
219
void TcpHeader::Serialize (Buffer::Iterator start)  const
190
{
220
{
191
  start.WriteHtonU16 (m_sourcePort);
221
  Buffer::Iterator i = start;
192
  start.WriteHtonU16 (m_destinationPort);
222
  uint16_t tcpLength = m_payloadSize + GetSerializedSize();
193
  start.WriteHtonU32 (m_sequenceNumber);
223
  i.WriteHtonU16 (m_sourcePort);
194
  start.WriteHtonU32 (m_ackNumber);
224
  i.WriteHtonU16 (m_destinationPort);
195
  start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
225
  i.WriteHtonU32 (m_sequenceNumber);
196
  start.WriteHtonU16 (m_windowSize);
226
  i.WriteHtonU32 (m_ackNumber);
197
  //XXX calculate checksum here
227
  i.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
198
  start.WriteHtonU16 (m_checksum);
228
  i.WriteHtonU16 (m_windowSize);
199
  start.WriteHtonU16 (m_urgentPointer);
229
  i.WriteHtonU16 (0);
230
  i.WriteHtonU16 (m_urgentPointer);
231
232
  if(m_calcChecksum)
233
  {
234
    i = start;
235
    uint16_t checksum = i.CalculateIpChecksum(tcpLength, m_initialChecksum);
236
    
237
    i = start;
238
    i.Next(16);
239
    i.WriteU16(checksum);
240
  }
200
}
241
}
201
uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
242
uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
202
{
243
{
203
  m_sourcePort = start.ReadNtohU16 ();
244
  Buffer::Iterator i = start;
204
  m_destinationPort = start.ReadNtohU16 ();
245
  m_sourcePort = i.ReadNtohU16 ();
205
  m_sequenceNumber = start.ReadNtohU32 ();
246
  m_destinationPort = i.ReadNtohU16 ();
206
  m_ackNumber = start.ReadNtohU32 ();
247
  m_sequenceNumber = i.ReadNtohU32 ();
207
  uint16_t field = start.ReadNtohU16 ();
248
  m_ackNumber = i.ReadNtohU32 ();
249
  uint16_t field = i.ReadNtohU16 ();
208
  m_flags = field & 0x3F;
250
  m_flags = field & 0x3F;
209
  m_length = field>>12;
251
  m_length = field>>12;
210
  m_windowSize = start.ReadNtohU16 ();
252
  m_windowSize = i.ReadNtohU16 ();
211
  m_checksum = start.ReadNtohU16 ();
253
  m_checksum = i.ReadU16 ();
212
  m_urgentPointer = start.ReadNtohU16 ();
254
  m_urgentPointer = i.ReadNtohU16 ();
255
256
  if(m_calcChecksum)
257
  {
258
      i = start;
259
      uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum);
260
261
      m_goodChecksum = (checksum == 0);
262
  }
263
213
  return GetSerializedSize ();
264
  return GetSerializedSize ();
214
}
265
}
215
266
(-)a/src/internet-stack/tcp-header.h (-3 / +18 lines)
 Lines 47-53   public: Link Here 
47
  /**
47
  /**
48
   * \brief Enable checksum calculation for TCP (XXX currently has no effect)
48
   * \brief Enable checksum calculation for TCP (XXX currently has no effect)
49
   */
49
   */
50
  static void EnableChecksums (void);
50
  void EnableChecksums (void);
51
//Setters
51
//Setters
52
  /**
52
  /**
53
   * \param port The source port for this TcpHeader
53
   * \param port The source port for this TcpHeader
 Lines 150-155   public: Link Here 
150
  virtual void Serialize (Buffer::Iterator start) const;
150
  virtual void Serialize (Buffer::Iterator start) const;
151
  virtual uint32_t Deserialize (Buffer::Iterator start);
151
  virtual uint32_t Deserialize (Buffer::Iterator start);
152
152
153
  /**
154
   * \param size The payload size in bytes
155
   */
156
  void SetPayloadSize (uint16_t size);
157
158
  /**
159
   * \brief Is the TCP checksum correct ?
160
   * \returns true if the checksum is correct, false otherwise.
161
   */
162
  bool IsChecksumOk (void) const;
163
153
private:
164
private:
154
  uint16_t m_sourcePort;
165
  uint16_t m_sourcePort;
155
  uint16_t m_destinationPort;
166
  uint16_t m_destinationPort;
 Lines 158-167   private: Link Here 
158
  uint8_t m_length; // really a uint4_t
169
  uint8_t m_length; // really a uint4_t
159
  uint8_t m_flags;      // really a uint6_t
170
  uint8_t m_flags;      // really a uint6_t
160
  uint16_t m_windowSize;
171
  uint16_t m_windowSize;
172
  uint16_t m_urgentPointer;
173
  uint16_t m_payloadSize;
174
  uint16_t m_initialChecksum;
161
  uint16_t m_checksum;
175
  uint16_t m_checksum;
162
  uint16_t m_urgentPointer;
163
176
164
  static bool m_calcChecksum;
177
  bool m_calcChecksum;
178
  bool m_goodChecksum;
179
165
};
180
};
166
181
167
}; // namespace ns3
182
}; // namespace ns3
(-)a/src/internet-stack/tcp-l4-protocol.cc (-3 / +36 lines)
 Lines 21-26    Link Here 
21
#include "ns3/assert.h"
21
#include "ns3/assert.h"
22
#include "ns3/log.h"
22
#include "ns3/log.h"
23
#include "ns3/nstime.h"
23
#include "ns3/nstime.h"
24
#include "ns3/boolean.h"
24
25
25
#include "ns3/packet.h"
26
#include "ns3/packet.h"
26
#include "ns3/node.h"
27
#include "ns3/node.h"
 Lines 328-333   TcpL4Protocol::GetTypeId (void) Link Here 
328
                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
329
                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
329
                   MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
330
                   MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
330
                   MakeObjectFactoryChecker ())
331
                   MakeObjectFactoryChecker ())
332
    .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
333
                   " and verify the checksum of incoming packets.",
334
                   BooleanValue (false),
335
                   MakeBooleanAccessor (&TcpL4Protocol::m_calcChecksum),
336
                   MakeBooleanChecker ())
331
    ;
337
    ;
332
  return tid;
338
  return tid;
333
}
339
}
 Lines 439-452   TcpL4Protocol::Receive (Ptr<Packet> pack Link Here 
439
  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
445
  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
440
446
441
  TcpHeader tcpHeader;
447
  TcpHeader tcpHeader;
448
  if(m_calcChecksum)
449
  {
450
    tcpHeader.EnableChecksums();
451
  }
452
  /* XXX very dirty but needs this to AddHeader again because of checksum */
453
  tcpHeader.SetLength(5); /* XXX TCP without options */
454
  tcpHeader.SetPayloadSize(packet->GetSize() - tcpHeader.GetSerializedSize());
455
  tcpHeader.InitializeChecksum(source, destination, PROT_NUMBER);
456
442
  //these two do a peek, so that the packet can be forwarded up
457
  //these two do a peek, so that the packet can be forwarded up
443
  packet->RemoveHeader (tcpHeader);
458
  packet->RemoveHeader (tcpHeader);
459
444
  NS_LOG_LOGIC("TcpL4Protocol " << this
460
  NS_LOG_LOGIC("TcpL4Protocol " << this
445
               << " receiving seq " << tcpHeader.GetSequenceNumber()
461
               << " receiving seq " << tcpHeader.GetSequenceNumber()
446
               << " ack " << tcpHeader.GetAckNumber()
462
               << " ack " << tcpHeader.GetAckNumber()
447
               << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
463
               << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
448
               << " data size " << packet->GetSize());
464
               << " data size " << packet->GetSize());
449
  packet->AddHeader (tcpHeader); 
465
466
  if(!tcpHeader.IsChecksumOk ())
467
  {
468
    NS_LOG_INFO("Bad checksum, dropping packet!");
469
    return;
470
  }
471
472
  packet->AddHeader (tcpHeader);
450
  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
473
  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
451
  Ipv4EndPointDemux::EndPoints endPoints =
474
  Ipv4EndPointDemux::EndPoints endPoints =
452
    m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (),
475
    m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (),
 Lines 478-483   TcpL4Protocol::Send (Ptr<Packet> packet, Link Here 
478
  TcpHeader tcpHeader;
501
  TcpHeader tcpHeader;
479
  tcpHeader.SetDestinationPort (dport);
502
  tcpHeader.SetDestinationPort (dport);
480
  tcpHeader.SetSourcePort (sport);
503
  tcpHeader.SetSourcePort (sport);
504
  tcpHeader.SetPayloadSize(packet->GetSize());
505
  if(m_calcChecksum)
506
  {
507
    tcpHeader.EnableChecksums();
508
  }
481
  tcpHeader.InitializeChecksum (saddr,
509
  tcpHeader.InitializeChecksum (saddr,
482
                               daddr,
510
                               daddr,
483
                               PROT_NUMBER);
511
                               PROT_NUMBER);
 Lines 507-514   TcpL4Protocol::SendPacket (Ptr<Packet> p Link Here 
507
  // XXX outgoingHeader cannot be logged
535
  // XXX outgoingHeader cannot be logged
508
536
509
  outgoingHeader.SetLength (5); //header length in units of 32bit words
537
  outgoingHeader.SetLength (5); //header length in units of 32bit words
510
  outgoingHeader.SetChecksum (0);  //XXX
538
  outgoingHeader.SetPayloadSize(packet->GetSize());
511
  outgoingHeader.SetUrgentPointer (0); //XXX
539
  /* outgoingHeader.SetUrgentPointer (0); //XXX */
540
  if(m_calcChecksum)
541
  {
542
    outgoingHeader.EnableChecksums();
543
  }
544
  outgoingHeader.InitializeChecksum(saddr, daddr, PROT_NUMBER);
512
545
513
  packet->AddHeader (outgoingHeader);
546
  packet->AddHeader (outgoingHeader);
514
547
(-)a/src/internet-stack/tcp-l4-protocol.h (+3 lines)
 Lines 117-122   private: Link Here 
117
  void SendPacket (Ptr<Packet>, TcpHeader,
117
  void SendPacket (Ptr<Packet>, TcpHeader,
118
                  Ipv4Address, Ipv4Address);
118
                  Ipv4Address, Ipv4Address);
119
  static ObjectFactory GetDefaultRttEstimatorFactory (void);
119
  static ObjectFactory GetDefaultRttEstimatorFactory (void);
120
121
  bool m_goodChecksum;
122
  bool m_calcChecksum;
120
};
123
};
121
124
122
}; // namespace ns3
125
}; // namespace ns3
(-)a/src/internet-stack/udp-header.cc (-29 / +50 lines)
 Lines 19-31    Link Here 
19
 */
19
 */
20
20
21
#include "udp-header.h"
21
#include "udp-header.h"
22
#include "ipv4-checksum.h"
23
22
24
namespace ns3 {
23
namespace ns3 {
25
24
26
NS_OBJECT_ENSURE_REGISTERED (UdpHeader);
25
NS_OBJECT_ENSURE_REGISTERED (UdpHeader);
27
28
bool UdpHeader::m_calcChecksum = false;
29
26
30
/* The magic values below are used only for debugging.
27
/* The magic values below are used only for debugging.
31
 * They can be used to easily detect memory corruption
28
 * They can be used to easily detect memory corruption
 Lines 35-41   UdpHeader::UdpHeader () Link Here 
35
  : m_sourcePort (0xfffd),
32
  : m_sourcePort (0xfffd),
36
    m_destinationPort (0xfffd),
33
    m_destinationPort (0xfffd),
37
    m_payloadSize (0xfffd),
34
    m_payloadSize (0xfffd),
38
    m_initialChecksum (0)
35
    m_initialChecksum (0),
36
    m_checksum(0),
37
    m_calcChecksum(false),
38
    m_goodChecksum(true)
39
{}
39
{}
40
UdpHeader::~UdpHeader ()
40
UdpHeader::~UdpHeader ()
41
{
41
{
 Lines 80-96   UdpHeader::InitializeChecksum (Ipv4Addre Link Here 
80
                              Ipv4Address destination,
80
                              Ipv4Address destination,
81
                              uint8_t protocol)
81
                              uint8_t protocol)
82
{
82
{
83
  uint8_t buf[12];
83
  Buffer buf = Buffer(12);
84
  source.Serialize (buf);
84
  uint8_t tmp[4];
85
  destination.Serialize (buf+4);
85
  Buffer::Iterator it;
86
  buf[8] = 0;
86
  uint16_t udpLength = m_payloadSize + GetSerializedSize();
87
  buf[9] = protocol;
88
  uint16_t udpLength = m_payloadSize + GetSerializedSize ();
89
  buf[10] = udpLength >> 8;
90
  buf[11] = udpLength & 0xff;
91
87
92
  m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12);
88
  buf.AddAtStart(12);
89
  it = buf.Begin();
90
91
  source.Serialize(tmp);
92
  it.Write(tmp, 4); /* source IP address */
93
  destination.Serialize(tmp);
94
  it.Write(tmp, 4); /* destination IP address */
95
  it.WriteU8(0); /* protocol */
96
  it.WriteU8(protocol); /* protocol */
97
  it.WriteU8(udpLength >> 8); /* length */
98
  it.WriteU8(udpLength & 0xff); /* length */
99
100
  it = buf.Begin();
101
  /* we don't CompleteChecksum ( ~ ) now */
102
  m_initialChecksum = ~(it.CalculateIpChecksum(12));
93
}
103
}
104
105
bool
106
UdpHeader::IsChecksumOk (void) const
107
{
108
  return m_goodChecksum; 
109
}
110
94
111
95
TypeId 
112
TypeId 
96
UdpHeader::GetTypeId (void)
113
UdpHeader::GetTypeId (void)
 Lines 125-147   UdpHeader::Serialize (Buffer::Iterator s Link Here 
125
UdpHeader::Serialize (Buffer::Iterator start) const
142
UdpHeader::Serialize (Buffer::Iterator start) const
126
{
143
{
127
  Buffer::Iterator i = start;
144
  Buffer::Iterator i = start;
145
  uint16_t udpLength = m_payloadSize + GetSerializedSize();
146
128
  i.WriteHtonU16 (m_sourcePort);
147
  i.WriteHtonU16 (m_sourcePort);
129
  i.WriteHtonU16 (m_destinationPort);
148
  i.WriteHtonU16 (m_destinationPort);
130
  i.WriteHtonU16 (m_payloadSize + GetSerializedSize ());
149
  i.WriteHtonU16 (udpLength);
131
  i.WriteU16 (0);
150
  i.WriteU16 (0);
132
151
133
  if (m_calcChecksum) 
152
  if (m_calcChecksum)
134
    {
153
    {
135
#if 0
154
      i = start;
136
      //XXXX
155
      uint16_t checksum = i.CalculateIpChecksum(udpLength, m_initialChecksum);
137
      uint16_t checksum = Ipv4ChecksumCalculate (m_initialChecksum, 
156
138
                                                  buffer->PeekData (), 
157
      i = start;
139
                                                  GetSerializedSize () + m_payloadSize);
158
      i.Next(6);
140
      checksum = Ipv4ChecksumComplete (checksum);
159
      i.WriteU16(checksum);
141
      i = buffer->Begin ();
142
      i.Next (6);
143
      i.WriteU16 (checksum);
144
#endif
145
    }
160
    }
146
}
161
}
147
uint32_t
162
uint32_t
 Lines 151-160   UdpHeader::Deserialize (Buffer::Iterator Link Here 
151
  m_sourcePort = i.ReadNtohU16 ();
166
  m_sourcePort = i.ReadNtohU16 ();
152
  m_destinationPort = i.ReadNtohU16 ();
167
  m_destinationPort = i.ReadNtohU16 ();
153
  m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
168
  m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
154
  if (m_calcChecksum) 
169
  m_checksum = i.ReadU16();
155
    {
170
156
      // XXX verify checksum.
171
  if(m_calcChecksum)
157
    }
172
  {
173
      i = start;
174
      uint16_t checksum = i.CalculateIpChecksum(m_payloadSize + GetSerializedSize(), m_initialChecksum);
175
176
      m_goodChecksum = (checksum == 0);
177
  }
178
158
  return GetSerializedSize ();
179
  return GetSerializedSize ();
159
}
180
}
160
181
(-)a/src/internet-stack/udp-header.h (-2 / +10 lines)
 Lines 49-55   public: Link Here 
49
  /**
49
  /**
50
   * \brief Enable checksum calculation for UDP (XXX currently has no effect)
50
   * \brief Enable checksum calculation for UDP (XXX currently has no effect)
51
   */
51
   */
52
  static void EnableChecksums (void);
52
  void EnableChecksums (void);
53
  /**
53
  /**
54
   * \param port the destination port for this UdpHeader
54
   * \param port the destination port for this UdpHeader
55
   */
55
   */
 Lines 93-105   public: Link Here 
93
  virtual void Serialize (Buffer::Iterator start) const;
93
  virtual void Serialize (Buffer::Iterator start) const;
94
  virtual uint32_t Deserialize (Buffer::Iterator start);
94
  virtual uint32_t Deserialize (Buffer::Iterator start);
95
95
96
  /**
97
   * \brief Is the UDP checksum correct ?
98
   * \returns true if the checksum is correct, false otherwise.
99
   */
100
  bool IsChecksumOk (void) const;
101
96
private:
102
private:
97
  uint16_t m_sourcePort;
103
  uint16_t m_sourcePort;
98
  uint16_t m_destinationPort;
104
  uint16_t m_destinationPort;
99
  uint16_t m_payloadSize;
105
  uint16_t m_payloadSize;
100
  uint16_t m_initialChecksum;
106
  uint16_t m_initialChecksum;
107
  uint16_t m_checksum;
101
108
102
  static bool m_calcChecksum;
109
  bool m_calcChecksum;
110
  bool m_goodChecksum;
103
};
111
};
104
112
105
} // namespace ns3
113
} // namespace ns3
(-)a/src/internet-stack/udp-l4-protocol.cc (-1 / +25 lines)
 Lines 22-27    Link Here 
22
#include "ns3/assert.h"
22
#include "ns3/assert.h"
23
#include "ns3/packet.h"
23
#include "ns3/packet.h"
24
#include "ns3/node.h"
24
#include "ns3/node.h"
25
#include "ns3/boolean.h"
25
26
26
#include "udp-l4-protocol.h"
27
#include "udp-l4-protocol.h"
27
#include "udp-header.h"
28
#include "udp-header.h"
 Lines 45-50   UdpL4Protocol::GetTypeId (void) Link Here 
45
  static TypeId tid = TypeId ("ns3::UdpL4Protocol")
46
  static TypeId tid = TypeId ("ns3::UdpL4Protocol")
46
    .SetParent<Ipv4L4Protocol> ()
47
    .SetParent<Ipv4L4Protocol> ()
47
    .AddConstructor<UdpL4Protocol> ()
48
    .AddConstructor<UdpL4Protocol> ()
49
    .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
50
                   " and verify the checksum of incoming packets.",
51
                   BooleanValue (false),
52
                   MakeBooleanAccessor (&UdpL4Protocol::m_calcChecksum),
53
                   MakeBooleanChecker ())
48
    ;
54
    ;
49
  return tid;
55
  return tid;
50
}
56
}
 Lines 151-159   UdpL4Protocol::Receive(Ptr<Packet> packe Link Here 
151
                       Ptr<Ipv4Interface> interface)
157
                       Ptr<Ipv4Interface> interface)
152
{
158
{
153
  NS_LOG_FUNCTION (this << packet << source << destination);
159
  NS_LOG_FUNCTION (this << packet << source << destination);
160
  UdpHeader udpHeader;
161
  if(m_calcChecksum)
162
  {
163
    udpHeader.EnableChecksums();
164
  }
154
165
155
  UdpHeader udpHeader;
166
  udpHeader.SetPayloadSize (packet->GetSize () - udpHeader.GetSerializedSize ());
167
  udpHeader.InitializeChecksum (source, destination, PROT_NUMBER);
168
156
  packet->RemoveHeader (udpHeader);
169
  packet->RemoveHeader (udpHeader);
170
171
  if(!udpHeader.IsChecksumOk ())
172
  {
173
    NS_LOG_INFO("Bad checksum : dropping packet!");
174
    return;
175
  }
176
157
  Ipv4EndPointDemux::EndPoints endPoints =
177
  Ipv4EndPointDemux::EndPoints endPoints =
158
    m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
178
    m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
159
                         source, udpHeader.GetSourcePort (), interface);
179
                         source, udpHeader.GetSourcePort (), interface);
 Lines 172-177   UdpL4Protocol::Send (Ptr<Packet> packet, Link Here 
172
  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
192
  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
173
193
174
  UdpHeader udpHeader;
194
  UdpHeader udpHeader;
195
  if(m_calcChecksum)
196
  {
197
    udpHeader.EnableChecksums();
198
  }
175
  udpHeader.SetDestinationPort (dport);
199
  udpHeader.SetDestinationPort (dport);
176
  udpHeader.SetSourcePort (sport);
200
  udpHeader.SetSourcePort (sport);
177
  udpHeader.SetPayloadSize (packet->GetSize ());
201
  udpHeader.SetPayloadSize (packet->GetSize ());
(-)a/src/internet-stack/udp-l4-protocol.h (+1 lines)
 Lines 93-98   private: Link Here 
93
private:
93
private:
94
  Ptr<Node> m_node;
94
  Ptr<Node> m_node;
95
  Ipv4EndPointDemux *m_endPoints;
95
  Ipv4EndPointDemux *m_endPoints;
96
  bool m_calcChecksum;
96
};
97
};
97
98
98
}; // namespace ns3
99
}; // namespace ns3
(-)a/src/node/ipv4-header.cc (-20 / +5 lines)
 Lines 38-43   Ipv4Header::Ipv4Header () Link Here 
38
    m_protocol (0),
38
    m_protocol (0),
39
    m_flags (0),
39
    m_flags (0),
40
    m_fragmentOffset (0),
40
    m_fragmentOffset (0),
41
    m_checksum(0),
41
    m_goodChecksum (true)
42
    m_goodChecksum (true)
42
{}
43
{}
43
44
 Lines 177-199   Ipv4Header::IsChecksumOk (void) const Link Here 
177
  return m_goodChecksum;
178
  return m_goodChecksum;
178
}
179
}
179
180
180
uint16_t
181
Ipv4Header::ChecksumCalculate(Buffer::Iterator &i, uint16_t size)
182
{
183
  /* see RFC 1071 to understand this code. */
184
  uint32_t sum = 0;
185
186
  for (int j = 0; j < size/2; j++)
187
    sum += i.ReadU16 ();
188
189
  if (size & 1)
190
     sum += i.ReadU8 ();
191
192
  while (sum >> 16)
193
    sum = (sum & 0xffff) + (sum >> 16);
194
  return ~sum;
195
}
196
197
TypeId 
181
TypeId 
198
Ipv4Header::GetTypeId (void)
182
Ipv4Header::GetTypeId (void)
199
{
183
{
 Lines 282-288   Ipv4Header::Serialize (Buffer::Iterator Link Here 
282
  if (m_calcChecksum) 
266
  if (m_calcChecksum) 
283
    {
267
    {
284
      i = start;
268
      i = start;
285
      uint16_t checksum = ChecksumCalculate(i, 20);
269
      uint16_t checksum = i.CalculateIpChecksum(20);
286
      NS_LOG_LOGIC ("checksum=" <<checksum);
270
      NS_LOG_LOGIC ("checksum=" <<checksum);
287
      i = start;
271
      i = start;
288
      i.Next (10);
272
      i.Next (10);
 Lines 318-331   Ipv4Header::Deserialize (Buffer::Iterato Link Here 
318
  m_fragmentOffset <<= 3;
302
  m_fragmentOffset <<= 3;
319
  m_ttl = i.ReadU8 ();
303
  m_ttl = i.ReadU8 ();
320
  m_protocol = i.ReadU8 ();
304
  m_protocol = i.ReadU8 ();
321
  i.Next (2); // checksum
305
  m_checksum = i.ReadU16();
306
  /* i.Next (2); // checksum */
322
  m_source.Set (i.ReadNtohU32 ());
307
  m_source.Set (i.ReadNtohU32 ());
323
  m_destination.Set (i.ReadNtohU32 ());
308
  m_destination.Set (i.ReadNtohU32 ());
324
309
325
  if (m_calcChecksum) 
310
  if (m_calcChecksum) 
326
    {
311
    {
327
      i = start;
312
      i = start;
328
      uint16_t checksum = ChecksumCalculate(i, headerSize);
313
      uint16_t checksum = i.CalculateIpChecksum(headerSize);
329
      NS_LOG_LOGIC ("checksum=" <<checksum);
314
      NS_LOG_LOGIC ("checksum=" <<checksum);
330
315
331
      m_goodChecksum = (checksum == 0);
316
      m_goodChecksum = (checksum == 0);
(-)a/src/node/ipv4-header.h (-1 / +1 lines)
 Lines 146-152   public: Link Here 
146
  virtual uint32_t Deserialize (Buffer::Iterator start);
146
  virtual uint32_t Deserialize (Buffer::Iterator start);
147
private:
147
private:
148
148
149
  static uint16_t ChecksumCalculate(Buffer::Iterator &i, uint16_t len);
150
  enum FlagsE {
149
  enum FlagsE {
151
    DONT_FRAGMENT = (1<<0),
150
    DONT_FRAGMENT = (1<<0),
152
    MORE_FRAGMENTS = (1<<1)
151
    MORE_FRAGMENTS = (1<<1)
 Lines 163-168   private: Link Here 
163
  uint16_t m_fragmentOffset : 13;
162
  uint16_t m_fragmentOffset : 13;
164
  Ipv4Address m_source;
163
  Ipv4Address m_source;
165
  Ipv4Address m_destination;
164
  Ipv4Address m_destination;
165
  uint16_t m_checksum;
166
  bool m_goodChecksum;
166
  bool m_goodChecksum;
167
};
167
};
168
168

Return to bug 236