1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Georgia Tech Research Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Raj Bhattacharjea <raj.b@gatech.edu>
19  */
20 
21 #ifndef TCP_HEADER_H
22 #define TCP_HEADER_H
23 
24 #include <stdint.h>
25 #include "ns3/header.h"
26 #include "ns3/tcp-option.h"
27 #include "ns3/buffer.h"
28 #include "ns3/tcp-socket-factory.h"
29 #include "ns3/ipv4-address.h"
30 #include "ns3/ipv6-address.h"
31 #include "ns3/sequence-number.h"
32 
33 namespace ns3 {
34 
35 /**
36  * \ingroup tcp
37  * \brief Header for the Transmission Control Protocol
38  *
39  * This class has fields corresponding to those in a network TCP header
40  * (port numbers, sequence and acknowledgement numbers, flags, etc) as well
41  * as methods for serialization to and deserialization from a byte buffer.
42  */
43 
44 class TcpHeader : public Header
45 {
46 public:
47   TcpHeader ();
48   virtual ~TcpHeader ();
49 
50   typedef std::list< Ptr<const TcpOption> > TcpOptionList; //!< List of TcpOption
51 
52   /**
53    * \brief Print a TCP header into an output stream
54    *
55    * \param os output stream
56    * \param tc TCP header to print
57    * \return The ostream passed as first argument
58    */
59   friend std::ostream& operator<< (std::ostream& os, TcpHeader const & tc);
60 
61   /**
62    * \brief Converts an integer into a human readable list of Tcp flags
63    *
64    * \param flags Bitfield of TCP flags to convert to a readable string
65    * \param delimiter String to insert between flags
66    *
67    * FIN=0x1, SYN=0x2, RST=0x4, PSH=0x8, ACK=0x10, URG=0x20, ECE=0x40, CWR=0x80
68    * TcpHeader::FlagsToString (0x1) should return the following string;
69    *     "FIN"
70    *
71    * TcpHeader::FlagsToString (0xff) should return the following string;
72    *     "FIN|SYN|RST|PSH|ACK|URG|ECE|CWR";
73    *
74    * \return the generated string
75    **/
76   static std::string FlagsToString (uint8_t flags, const std::string& delimiter = "|");
77 
78   /**
79    * \brief Enable checksum calculation for TCP
80    *
81    * \todo currently has no effect
82    */
83   void EnableChecksums (void);
84 
85 //Setters
86 
87 /**
88  * \brief Set the source port
89  * \param port The source port for this TcpHeader
90  */
91   void SetSourcePort (uint16_t port);
92 
93   /**
94    * \brief Set the destination port
95    * \param port the destination port for this TcpHeader
96    */
97   void SetDestinationPort (uint16_t port);
98 
99   /**
100    * \brief Set the sequence Number
101    * \param sequenceNumber the sequence number for this TcpHeader
102    */
103   void SetSequenceNumber (SequenceNumber32 sequenceNumber);
104 
105   /**
106    * \brief Set the ACK number
107    * \param ackNumber the ACK number for this TcpHeader
108    */
109   void SetAckNumber (SequenceNumber32 ackNumber);
110 
111   /**
112    * \brief Set flags of the header
113    * \param flags the flags for this TcpHeader
114    */
115   void SetFlags (uint8_t flags);
116 
117   /**
118    * \brief Set the window size
119    * \param windowSize the window size for this TcpHeader
120    */
121   void SetWindowSize (uint16_t windowSize);
122 
123   /**
124    * \brief Set the urgent pointer
125    * \param urgentPointer the urgent pointer for this TcpHeader
126    */
127   void SetUrgentPointer (uint16_t urgentPointer);
128 
129 //Getters
130 
131   /**
132    * \brief Get the source port
133    * \return The source port for this TcpHeader
134    */
135   uint16_t GetSourcePort () const;
136 
137   /**
138    * \brief Get the destination port
139    * \return the destination port for this TcpHeader
140    */
141   uint16_t GetDestinationPort () const;
142 
143   /**
144    * \brief Get the sequence number
145    * \return the sequence number for this TcpHeader
146    */
147   SequenceNumber32 GetSequenceNumber () const;
148 
149   /**
150    * \brief Get the ACK number
151    * \return the ACK number for this TcpHeader
152    */
153   SequenceNumber32 GetAckNumber () const;
154 
155   /**
156    * \brief Get the length in words
157    *
158    * A word is 4 bytes; without Tcp Options, header is 5 words (20 bytes).
159    * With options, it can reach up to 15 words (60 bytes).
160    *
161    * \return the length of this TcpHeader
162    */
163   uint8_t GetLength () const;
164 
165   /**
166    * \brief Get the flags
167    * \return the flags for this TcpHeader
168    */
169   uint8_t GetFlags () const;
170 
171   /**
172    * \brief Get the window size
173    * \return the window size for this TcpHeader
174    */
175   uint16_t GetWindowSize () const;
176 
177   /**
178    * \brief Get the urgent pointer
179    * \return the urgent pointer for this TcpHeader
180    */
181   uint16_t GetUrgentPointer () const;
182 
183   /**
184    * \brief Get the option specified
185    * \param kind the option to retrieve
186    * \return Whether the header contains a specific kind of option, or 0
187    */
188   Ptr<const TcpOption> GetOption (uint8_t kind) const;
189 
190   /**
191    * \brief Get the list of option in this header
192    * \return a const reference to the option list
193    */
194   const TcpOptionList& GetOptionList (void) const;
195 
196   /**
197    * \brief Get the total length of appended options
198    * \return the total length of options appended to this TcpHeader
199    */
200   uint8_t GetOptionLength () const;
201 
202   /**
203    * \brief Get maximum option length
204    * \return the maximum option length
205    */
206   uint8_t GetMaxOptionLength () const;
207 
208   /**
209    * \brief Check if the header has the option specified
210    * \param kind Option to check for
211    * \return true if the header has the option, false otherwise
212    */
213   bool HasOption (uint8_t kind) const;
214 
215   /**
216    * \brief Append an option to the TCP header
217    * \param option The option to append
218    * \return true if option has been appended, false otherwise
219    */
220   bool AppendOption (Ptr<const TcpOption> option);
221 
222   /**
223    * \brief Initialize the TCP checksum.
224    *
225    * If you want to use tcp checksums, you should call this
226    * method prior to adding the header to a packet.
227    *
228    * \param source the IP source to use in the underlying
229    *        IP packet.
230    * \param destination the IP destination to use in the
231    *        underlying IP packet.
232    * \param protocol the protocol number to use in the underlying
233    *        IP packet.
234    *
235    */
236   void InitializeChecksum (const Ipv4Address &source,
237                            const Ipv4Address &destination,
238                            uint8_t protocol);
239 
240   /**
241    * \brief Initialize the TCP checksum.
242    *
243    * If you want to use tcp checksums, you should call this
244    * method prior to adding the header to a packet.
245    *
246    * \param source the IP source to use in the underlying
247    *        IP packet.
248    * \param destination the IP destination to use in the
249    *        underlying IP packet.
250    * \param protocol the protocol number to use in the underlying
251    *        IP packet.
252    *
253    */
254   void InitializeChecksum (const Ipv6Address &source,
255                            const Ipv6Address &destination,
256                            uint8_t protocol);
257 
258   /**
259    * \brief Initialize the TCP checksum.
260    *
261    * If you want to use tcp checksums, you should call this
262    * method prior to adding the header to a packet.
263    *
264    * \param source the IP source to use in the underlying
265    *        IP packet.
266    * \param destination the IP destination to use in the
267    *        underlying IP packet.
268    * \param protocol the protocol number to use in the underlying
269    *        IP packet.
270    *
271    */
272   void InitializeChecksum (const Address &source,
273                            const Address &destination,
274                            uint8_t protocol);
275 
276   /**
277    * \brief TCP flag field values
278    */
279   typedef enum
280   {
281     NONE = 0,   //!< No flags
282     FIN  = 1,   //!< FIN
283     SYN  = 2,   //!< SYN
284     RST  = 4,   //!< Reset
285     PSH  = 8,   //!< Push
286     ACK  = 16,  //!< Ack
287     URG  = 32,  //!< Urgent
288     ECE  = 64,  //!< ECE
289     CWR  = 128  //!< CWR
290   } Flags_t;
291 
292   /**
293    * \brief Get the type ID.
294    * \return the object TypeId
295    */
296   static TypeId GetTypeId (void);
297   virtual TypeId GetInstanceTypeId (void) const;
298   virtual void Print (std::ostream &os) const;
299   virtual uint32_t GetSerializedSize (void) const;
300   virtual void Serialize (Buffer::Iterator start) const;
301   virtual uint32_t Deserialize (Buffer::Iterator start);
302 
303   /**
304    * \brief Is the TCP checksum correct ?
305    * \returns true if the checksum is correct, false otherwise.
306    */
307   bool IsChecksumOk (void) const;
308 
309   /**
310    * Comparison operator
311    * \param lhs left operand
312    * \param rhs right operand
313    * \return true if the operands are equal
314    */
315   friend bool operator== (const TcpHeader &lhs, const TcpHeader &rhs);
316 
317 private:
318   /**
319    * \brief Calculate the header checksum
320    * \param size packet size
321    * \returns the checksum
322    */
323   uint16_t CalculateHeaderChecksum (uint16_t size) const;
324 
325   /**
326    * \brief Calculates the header length (in words)
327    *
328    * Given the standard size of the header, the method checks for options
329    * and calculates the real length (in words).
330    *
331    * \return header length in 4-byte words
332    */
333   uint8_t CalculateHeaderLength () const;
334 
335   uint16_t m_sourcePort;        //!< Source port
336   uint16_t m_destinationPort;   //!< Destination port
337   SequenceNumber32 m_sequenceNumber;  //!< Sequence number
338   SequenceNumber32 m_ackNumber;       //!< ACK number
339   uint8_t m_length;             //!< Length (really a uint4_t) in words.
340   uint8_t m_flags;              //!< Flags (really a uint6_t)
341   uint16_t m_windowSize;        //!< Window size
342   uint16_t m_urgentPointer;     //!< Urgent pointer
343 
344   Address m_source;       //!< Source IP address
345   Address m_destination;  //!< Destination IP address
346   uint8_t m_protocol;     //!< Protocol number
347 
348   bool m_calcChecksum;    //!< Flag to calculate checksum
349   bool m_goodChecksum;    //!< Flag to indicate that checksum is correct
350 
351   static const uint8_t m_maxOptionsLen = 40;         //!< Maximum options length
352   TcpOptionList m_options;     //!< TcpOption present in the header
353   uint8_t m_optionsLen;        //!< Tcp options length.
354 };
355 
356 } // namespace ns3
357 
358 #endif /* TCP_HEADER */
359