1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #ifndef ICMPV4_H
22 #define ICMPV4_H
23 
24 #include "ns3/header.h"
25 #include "ns3/ptr.h"
26 #include "ns3/ipv4-header.h"
27 #include <stdint.h>
28 
29 namespace ns3 {
30 
31 class Packet;
32 
33 /**
34  * \ingroup icmp
35  *
36  * \brief Base class for all the ICMP packet headers.
37  *
38  * This header is the common part in all the ICMP packets.
39  */
40 class Icmpv4Header : public Header
41 {
42 public:
43 
44   /**
45    * ICMP type code.
46    */
47   enum Type_e {
48     ICMPV4_ECHO_REPLY = 0,
49     ICMPV4_DEST_UNREACH = 3,
50     ICMPV4_ECHO = 8,
51     ICMPV4_TIME_EXCEEDED = 11
52   };
53 
54   /**
55    * Enables ICMP Checksum calculation
56    */
57   void EnableChecksum (void);
58 
59   /**
60    * Set ICMP type
61    * \param type the ICMP type
62    */
63   void SetType (uint8_t type);
64 
65   /**
66    * Set ICMP code
67    * \param code the ICMP code
68    */
69   void SetCode (uint8_t code);
70 
71   /**
72    * Get ICMP type
73    * \returns the ICMP type
74    */
75   uint8_t GetType (void) const;
76   /**
77    * Get ICMP code
78    * \returns the ICMP code
79    */
80   uint8_t GetCode (void) const;
81 
82   /**
83    * \brief Get the type ID.
84    * \return the object TypeId
85    */
86   static TypeId GetTypeId (void);
87   Icmpv4Header ();
88   virtual ~Icmpv4Header ();
89 
90   virtual TypeId GetInstanceTypeId (void) const;
91   virtual uint32_t GetSerializedSize (void) const;
92   virtual void Serialize (Buffer::Iterator start) const;
93   virtual uint32_t Deserialize (Buffer::Iterator start);
94   virtual void Print (std::ostream &os) const;
95 
96 private:
97   uint8_t m_type; //!< ICMP type
98   uint8_t m_code; //!< ICMP code
99   bool m_calcChecksum;  //!< true if checksum is calculated
100 };
101 
102 /**
103  * \ingroup icmp
104  *
105  * \brief ICMP Echo header
106  */
107 class Icmpv4Echo : public Header
108 {
109 public:
110   /**
111    * \brief Set the Echo identifier
112    * \param id the identifier
113    */
114   void SetIdentifier (uint16_t id);
115   /**
116    * \brief Set the Echo sequence number
117    * \param seq the sequence number
118    */
119   void SetSequenceNumber (uint16_t seq);
120   /**
121    * \brief Set the Echo data
122    * \param data the data
123    */
124   void SetData (Ptr<const Packet> data);
125   /**
126    * \brief Get the Echo identifier
127    * \returns the identifier
128    */
129   uint16_t GetIdentifier (void) const;
130   /**
131    * \brief Get the Echo sequence number
132    * \returns the sequence number
133    */
134   uint16_t GetSequenceNumber (void) const;
135   /**
136    * \brief Get the Echo data size
137    * \returns the data size
138    */
139   uint32_t GetDataSize (void) const;
140   /**
141    * \brief Get the Echo data
142    * \param payload the data (filled)
143    * \returns the data length
144    */
145   uint32_t GetData (uint8_t payload[]) const;
146 
147 
148   /**
149    * Get ICMP type
150    * \returns the ICMP type
151    */
152   static TypeId GetTypeId (void);
153   Icmpv4Echo ();
154   virtual ~Icmpv4Echo ();
155   virtual TypeId GetInstanceTypeId (void) const;
156   virtual uint32_t GetSerializedSize (void) const;
157   virtual void Serialize (Buffer::Iterator start) const;
158   virtual uint32_t Deserialize (Buffer::Iterator start);
159   virtual void Print (std::ostream &os) const;
160 private:
161   uint16_t m_identifier; //!< identifier
162   uint16_t m_sequence;   //!< sequence number
163   uint8_t *m_data;       //!< data
164   uint32_t m_dataSize;   //!< data size
165 };
166 
167 /**
168  * \ingroup icmp
169  *
170  * \brief ICMP Destination Unreachable header
171  */
172 class Icmpv4DestinationUnreachable : public Header
173 {
174 public:
175   /**
176    * ICMP error code : Destination Unreachable
177    */
178   enum ErrorDestinationUnreachable_e {
179     ICMPV4_NET_UNREACHABLE = 0,
180     ICMPV4_HOST_UNREACHABLE = 1,
181     ICMPV4_PROTOCOL_UNREACHABLE = 2,
182     ICMPV4_PORT_UNREACHABLE = 3,
183     ICMPV4_FRAG_NEEDED = 4,
184     ICMPV4_SOURCE_ROUTE_FAILED = 5
185   };
186 
187   /**
188    * Get ICMP type
189    * \returns the ICMP type
190    */
191   static TypeId GetTypeId (void);
192   Icmpv4DestinationUnreachable ();
193   virtual ~Icmpv4DestinationUnreachable ();
194 
195   /**
196    * \brief Set the next hop MTU
197    * \param mtu the MTU
198    */
199   void SetNextHopMtu (uint16_t mtu);
200   /**
201    * \brief Get the next hop MTU
202    * \returns the MTU
203    */
204   uint16_t GetNextHopMtu (void) const;
205 
206   /**
207    * \brief Set the ICMP carried data
208    * \param data the data
209    */
210   void SetData (Ptr<const Packet> data);
211   /**
212    * \brief Set the ICMP carried IPv4 header
213    * \param header the header
214    */
215   void SetHeader (Ipv4Header header);
216 
217   /**
218    * \brief Get the ICMP carried data
219    * \param payload the data (filled)
220    */
221   void GetData (uint8_t payload[8]) const;
222   /**
223    * \brief Get the ICMP carried IPv4 header
224    * \returns the header
225    */
226   Ipv4Header GetHeader (void) const;
227 
228 private:
229   virtual TypeId GetInstanceTypeId (void) const;
230   virtual uint32_t GetSerializedSize (void) const;
231   virtual void Serialize (Buffer::Iterator start) const;
232   virtual uint32_t Deserialize (Buffer::Iterator start);
233   virtual void Print (std::ostream &os) const;
234 private:
235   uint16_t m_nextHopMtu; //!< next hop MTU
236   Ipv4Header m_header;   //!< carried IPv4 header
237   uint8_t m_data[8];     //!< carried data
238 };
239 
240 
241 /**
242  * \ingroup icmp
243  *
244  * \brief ICMP Time Exceeded header
245  */
246 class Icmpv4TimeExceeded : public Header
247 {
248 public:
249   /**
250    * \brief ICMP error code : Time Exceeded
251    */
252   enum ErrorTimeExceeded_e
253   {
254     ICMPV4_TIME_TO_LIVE = 0,
255     ICMPV4_FRAGMENT_REASSEMBLY = 1
256   };
257 
258   /**
259    * \brief Get the ICMP carried data
260    * \param data the data
261    */
262   void SetData (Ptr<const Packet> data);
263   /**
264    * \brief Set the ICMP carried IPv4 header
265    * \param header the header
266    */
267   void SetHeader (Ipv4Header header);
268 
269   /**
270    * \brief Get the ICMP carried data
271    * \param payload the data (filled)
272    */
273   void GetData (uint8_t payload[8]) const;
274   /**
275    * \brief Get the ICMP carried IPv4 header
276    * \returns the header
277    */
278   Ipv4Header GetHeader (void) const;
279 
280   /**
281    * Get ICMP type
282    * \returns the ICMP type
283    */
284   static TypeId GetTypeId (void);
285   Icmpv4TimeExceeded ();
286   virtual ~Icmpv4TimeExceeded ();
287   virtual TypeId GetInstanceTypeId (void) const;
288   virtual uint32_t GetSerializedSize (void) const;
289   virtual void Serialize (Buffer::Iterator start) const;
290   virtual uint32_t Deserialize (Buffer::Iterator start);
291   virtual void Print (std::ostream &os) const;
292 
293 private:
294   Ipv4Header m_header;   //!< carried IPv4 header
295   uint8_t m_data[8];     //!< carried data
296 };
297 
298 } // namespace ns3
299 
300 #endif /* ICMPV4_H */
301