00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdint.h>
00022 #include <iostream>
00023 #include "tcp-socket-impl.h"
00024 #include "tcp-header.h"
00025 #include "ns3/buffer.h"
00026 #include "ns3/address-utils.h"
00027
00028 namespace ns3 {
00029
00030 NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
00031
00032 TcpHeader::TcpHeader ()
00033 : m_sourcePort (0),
00034 m_destinationPort (0),
00035 m_sequenceNumber (0),
00036 m_ackNumber (0),
00037 m_length (5),
00038 m_flags (0),
00039 m_windowSize (0xffff),
00040 m_urgentPointer (0),
00041 m_calcChecksum(false),
00042 m_goodChecksum(true)
00043 {}
00044
00045 TcpHeader::~TcpHeader ()
00046 {}
00047
00048 void
00049 TcpHeader::EnableChecksums (void)
00050 {
00051 m_calcChecksum = true;
00052 }
00053
00054 void TcpHeader::SetSourcePort (uint16_t port)
00055 {
00056 m_sourcePort = port;
00057 }
00058 void TcpHeader::SetDestinationPort (uint16_t port)
00059 {
00060 m_destinationPort = port;
00061 }
00062 void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber)
00063 {
00064 m_sequenceNumber = sequenceNumber;
00065 }
00066 void TcpHeader::SetAckNumber (SequenceNumber ackNumber)
00067 {
00068 m_ackNumber = ackNumber;
00069 }
00070 void TcpHeader::SetLength (uint8_t length)
00071 {
00072 m_length = length;
00073 }
00074 void TcpHeader::SetFlags (uint8_t flags)
00075 {
00076 m_flags = flags;
00077 }
00078 void TcpHeader::SetWindowSize (uint16_t windowSize)
00079 {
00080 m_windowSize = windowSize;
00081 }
00082 void TcpHeader::SetUrgentPointer (uint16_t urgentPointer)
00083 {
00084 m_urgentPointer = urgentPointer;
00085 }
00086
00087 uint16_t TcpHeader::GetSourcePort () const
00088 {
00089 return m_sourcePort;
00090 }
00091 uint16_t TcpHeader::GetDestinationPort () const
00092 {
00093 return m_destinationPort;
00094 }
00095 SequenceNumber TcpHeader::GetSequenceNumber () const
00096 {
00097 return m_sequenceNumber;
00098 }
00099 SequenceNumber TcpHeader::GetAckNumber () const
00100 {
00101 return m_ackNumber;
00102 }
00103 uint8_t TcpHeader::GetLength () const
00104 {
00105 return m_length;
00106 }
00107 uint8_t TcpHeader::GetFlags () const
00108 {
00109 return m_flags;
00110 }
00111 uint16_t TcpHeader::GetWindowSize () const
00112 {
00113 return m_windowSize;
00114 }
00115 uint16_t TcpHeader::GetUrgentPointer () const
00116 {
00117 return m_urgentPointer;
00118 }
00119
00120 void
00121 TcpHeader::InitializeChecksum (Ipv4Address source,
00122 Ipv4Address destination,
00123 uint8_t protocol)
00124 {
00125 m_source = source;
00126 m_destination = destination;
00127 m_protocol = protocol;
00128 }
00129
00130 uint16_t
00131 TcpHeader::CalculateHeaderChecksum (uint16_t size) const
00132 {
00133 Buffer buf = Buffer (12);
00134 buf.AddAtStart (12);
00135 Buffer::Iterator it = buf.Begin ();
00136
00137 WriteTo (it, m_source);
00138 WriteTo (it, m_destination);
00139 it.WriteU8 (0);
00140 it.WriteU8 (m_protocol);
00141 it.WriteU8 (size >> 8);
00142 it.WriteU8 (size & 0xff);
00143
00144 it = buf.Begin ();
00145
00146 return ~(it.CalculateIpChecksum (12));
00147 }
00148
00149 bool
00150 TcpHeader::IsChecksumOk (void) const
00151 {
00152 return m_goodChecksum;
00153 }
00154
00155 TypeId
00156 TcpHeader::GetTypeId (void)
00157 {
00158 static TypeId tid = TypeId ("ns3::TcpHeader")
00159 .SetParent<Header> ()
00160 .AddConstructor<TcpHeader> ()
00161 ;
00162 return tid;
00163 }
00164 TypeId
00165 TcpHeader::GetInstanceTypeId (void) const
00166 {
00167 return GetTypeId ();
00168 }
00169 void TcpHeader::Print (std::ostream &os) const
00170 {
00171 os << m_sourcePort << " > " << m_destinationPort;
00172 if(m_flags!=0)
00173 {
00174 os<<" [";
00175 if((m_flags & FIN) != 0)
00176 {
00177 os<<" FIN ";
00178 }
00179 if((m_flags & SYN) != 0)
00180 {
00181 os<<" SYN ";
00182 }
00183 if((m_flags & RST) != 0)
00184 {
00185 os<<" RST ";
00186 }
00187 if((m_flags & PSH) != 0)
00188 {
00189 os<<" PSH ";
00190 }
00191 if((m_flags & ACK) != 0)
00192 {
00193 os<<" ACK ";
00194 }
00195 if((m_flags & URG) != 0)
00196 {
00197 os<<" URG ";
00198 }
00199 os<<"]";
00200 }
00201 os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
00202 }
00203 uint32_t TcpHeader::GetSerializedSize (void) const
00204 {
00205 return 4*m_length;
00206 }
00207 void TcpHeader::Serialize (Buffer::Iterator start) const
00208 {
00209 Buffer::Iterator i = start;
00210 i.WriteHtonU16 (m_sourcePort);
00211 i.WriteHtonU16 (m_destinationPort);
00212 i.WriteHtonU32 (m_sequenceNumber);
00213 i.WriteHtonU32 (m_ackNumber);
00214 i.WriteHtonU16 (m_length << 12 | m_flags);
00215 i.WriteHtonU16 (m_windowSize);
00216 i.WriteHtonU16 (0);
00217 i.WriteHtonU16 (m_urgentPointer);
00218
00219 if(m_calcChecksum)
00220 {
00221 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
00222 i = start;
00223 uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum);
00224
00225 i = start;
00226 i.Next(16);
00227 i.WriteU16(checksum);
00228 }
00229 }
00230 uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
00231 {
00232 Buffer::Iterator i = start;
00233 m_sourcePort = i.ReadNtohU16 ();
00234 m_destinationPort = i.ReadNtohU16 ();
00235 m_sequenceNumber = i.ReadNtohU32 ();
00236 m_ackNumber = i.ReadNtohU32 ();
00237 uint16_t field = i.ReadNtohU16 ();
00238 m_flags = field & 0x3F;
00239 m_length = field>>12;
00240 m_windowSize = i.ReadNtohU16 ();
00241 i.Next (2);
00242 m_urgentPointer = i.ReadNtohU16 ();
00243
00244 if(m_calcChecksum)
00245 {
00246 uint16_t headerChecksum = CalculateHeaderChecksum (start.GetSize ());
00247 i = start;
00248 uint16_t checksum = i.CalculateIpChecksum(start.GetSize (), headerChecksum);
00249 m_goodChecksum = (checksum == 0);
00250 }
00251
00252 return GetSerializedSize ();
00253 }
00254
00255
00256 };