1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2009 Strasbourg University
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: David Gross <gdavid.devel@gmail.com>
19  */
20 
21 #ifndef IPV6_EXTENSION_H
22 #define IPV6_EXTENSION_H
23 
24 #include <map>
25 #include <list>
26 #include <tuple>
27 
28 #include "ns3/object.h"
29 #include "ns3/node.h"
30 #include "ns3/ptr.h"
31 #include "ipv6-interface.h"
32 #include "ns3/ipv6-header.h"
33 #include "ns3/buffer.h"
34 #include "ns3/packet.h"
35 #include "ns3/random-variable-stream.h"
36 #include "ns3/ipv6-address.h"
37 #include "ns3/ipv6-l3-protocol.h"
38 #include "ns3/traced-callback.h"
39 
40 
41 namespace ns3 {
42 
43 /**
44  * \ingroup ipv6
45  * \defgroup ipv6HeaderExt IPV6 Header extension system.
46  */
47 
48 /**
49  * \ingroup ipv6HeaderExt
50  *
51  * \brief IPv6 Extension base
52  * If you want to implement a new IPv6 extension, all you have to do is
53  * implement a subclass of this class and add it to an Ipv6ExtensionDemux.
54  */
55 class Ipv6Extension : public Object
56 {
57 public:
58   /**
59    * \brief Get the type identificator.
60    * \return type identificator
61    */
62   static TypeId GetTypeId ();
63 
64   /**
65    * \brief Constructor.
66    */
67   Ipv6Extension ();
68 
69   /**
70    * \brief Destructor.
71    */
72   virtual ~Ipv6Extension ();
73 
74   /**
75    * \brief Set the node.
76    * \param node the node to set
77    */
78   void SetNode (Ptr<Node> node);
79 
80   /**
81    * \brief Get the node.
82    * \return the node
83    */
84   Ptr<Node> GetNode () const;
85 
86   /**
87    * \brief Get the extension number.
88    * \return extension number
89    */
90   virtual uint8_t GetExtensionNumber () const = 0;
91 
92   /**
93    * \brief Process method
94    * Called from Ipv6L3Protocol::Receive.
95    *
96    * \param packet the packet
97    * \param offset the offset of the extension to process
98    * \param ipv6Header the IPv6 header of packet received
99    * \param dst destination address of the packet received (i.e. us)
100    * \param nextHeader the next header
101    * \param stopProcessing true if the packet must not be further processed
102    * \param isDropped true if the packet must be dropped
103    * \param dropReason dropping reason
104    * \return the size processed
105    */
106   virtual uint8_t Process (Ptr<Packet>& packet,
107                            uint8_t offset,
108                            Ipv6Header const& ipv6Header,
109                            Ipv6Address dst,
110                            uint8_t *nextHeader,
111                            bool& stopProcessing,
112                            bool& isDropped,
113                            Ipv6L3Protocol::DropReason& dropReason) = 0;
114 
115   /**
116    * \brief Process options
117    * Called by implementing classes to process the options
118    *
119    * \param packet the packet
120    * \param offset the offset of the first option to process
121    * \param length the total length of all options (as specified in the extension header)
122    * \param ipv6Header the IPv6 header of packet received
123    * \param dst destination address of the packet received (i.e. us)
124    * \param nextHeader the next header
125    * \param stopProcessing true if the packet must not be further processed
126    * \param isDropped true if the packet must be dropped
127    * \param dropReason dropping reason
128    * \return the size processed
129    */
130   virtual uint8_t ProcessOptions (Ptr<Packet>& packet,
131                                   uint8_t offset,
132                                   uint8_t length,
133                                   Ipv6Header const& ipv6Header,
134                                   Ipv6Address dst,
135                                   uint8_t *nextHeader,
136                                   bool& stopProcessing,
137                                   bool& isDropped,
138                                   Ipv6L3Protocol::DropReason& dropReason
139                                   );
140 
141  /**
142   * Assign a fixed random variable stream number to the random variables
143   * used by this model.  Return the number of streams (possibly zero) that
144   * have been assigned.
145   *
146   * \param stream first stream index to use
147   * \return the number of stream indices assigned by this model
148   */
149   int64_t AssignStreams (int64_t stream);
150 
151 protected:
152   /**
153    * \brief Provides uniform random variables.
154    */
155   Ptr<UniformRandomVariable> m_uvar;
156 
157 private:
158   /**
159    * \brief The node.
160    */
161   Ptr<Node> m_node;
162 };
163 
164 /**
165  * \ingroup ipv6HeaderExt
166  *
167  * \brief IPv6 Extension "Hop By Hop"
168  */
169 class Ipv6ExtensionHopByHop : public Ipv6Extension
170 {
171 public:
172   /**
173    * \brief Hop-by-hop extension number.
174    */
175   static const uint8_t EXT_NUMBER = 0;
176 
177   /**
178    * \brief Get the type identificator.
179    * \return type identificator
180    */
181   static TypeId GetTypeId ();
182 
183   /**
184    * \brief Constructor.
185    */
186   Ipv6ExtensionHopByHop ();
187 
188   /**
189    * \brief Destructor.
190    */
191   ~Ipv6ExtensionHopByHop ();
192 
193   /**
194    * \brief Get the extension number.
195    * \return extension number
196    */
197   virtual uint8_t GetExtensionNumber () const;
198 
199   virtual uint8_t Process (Ptr<Packet>& packet,
200                            uint8_t offset,
201                            Ipv6Header const& ipv6Header,
202                            Ipv6Address dst,
203                            uint8_t *nextHeader,
204                            bool& stopProcessing,
205                            bool& isDropped,
206                            Ipv6L3Protocol::DropReason& dropReason);
207 };
208 
209 /**
210  * \ingroup ipv6HeaderExt
211  *
212  * \brief IPv6 Extension Destination
213  */
214 class Ipv6ExtensionDestination : public Ipv6Extension
215 {
216 public:
217   /**
218    * \brief Destination extension number.
219    */
220   static const uint8_t EXT_NUMBER = 60;
221 
222   /**
223    * \brief Get the type identificator.
224    * \return type identificator
225    */
226   static TypeId GetTypeId ();
227 
228   /**
229    * \brief Constructor.
230    */
231   Ipv6ExtensionDestination ();
232 
233   /**
234    * \brief Destructor.
235    */
236   ~Ipv6ExtensionDestination ();
237 
238   /**
239    * \brief Get the extension number.
240    * \return extension number
241    */
242   virtual uint8_t GetExtensionNumber () const;
243 
244   virtual uint8_t Process (Ptr<Packet>& packet,
245                            uint8_t offset,
246                            Ipv6Header const& ipv6Header,
247                            Ipv6Address dst,
248                            uint8_t *nextHeader,
249                            bool& stopProcessing,
250                            bool& isDropped,
251                            Ipv6L3Protocol::DropReason& dropReason);
252 };
253 
254 /**
255  * \ingroup ipv6HeaderExt
256  *
257  * \brief IPv6 Extension Fragment
258  */
259 class Ipv6ExtensionFragment : public Ipv6Extension
260 {
261 public:
262   /**
263    * \brief Fragmentation extension number.
264    */
265   static const uint8_t EXT_NUMBER = 44;
266 
267   /**
268     * \brief Get the type identificator.
269     * \return type identificator
270     */
271   static TypeId GetTypeId ();
272 
273   /**
274    * \brief Constructor.
275    */
276   Ipv6ExtensionFragment ();
277 
278   /**
279    * \brief Destructor.
280    */
281   ~Ipv6ExtensionFragment ();
282 
283   /**
284    * \brief Get the extension number.
285    * \return extension number
286    */
287   virtual uint8_t GetExtensionNumber () const;
288 
289   virtual uint8_t Process (Ptr<Packet>& packet,
290                            uint8_t offset,
291                            Ipv6Header const& ipv6Header,
292                            Ipv6Address dst,
293                            uint8_t *nextHeader,
294                            bool& stopProcessing,
295                            bool& isDropped,
296                            Ipv6L3Protocol::DropReason& dropReason);
297 
298   /**
299    * \brief Pair of a packet and an Ipv6 header.
300    */
301   typedef std::pair<Ptr<Packet>, Ipv6Header> Ipv6PayloadHeaderPair;
302 
303   /**
304    * \brief Fragment a packet.
305    *
306    * \param packet the packet.
307    * \param ipv6Header the IPv6 header.
308    * \param fragmentSize the maximal size of the fragment (unfragmentable part + fragmentation header + fragmentable part).
309    * \param listFragments the list of fragments.
310    */
311   void GetFragments (Ptr<Packet> packet, Ipv6Header ipv6Header, uint32_t fragmentSize, std::list<Ipv6PayloadHeaderPair>& listFragments);
312 
313 protected:
314   /**
315    * \brief Dispose this object.
316    */
317   virtual void DoDispose ();
318 
319 private:
320 
321   /**
322    * Key identifying a fragmented packet
323    */
324   typedef std::pair<Ipv6Address, uint32_t> FragmentKey_t;
325 
326   /**
327    * Container for fragment timeouts.
328    */
329   typedef std::list< std::tuple <Time, FragmentKey_t, Ipv6Header > > FragmentsTimeoutsList_t;
330   /**
331    * Container Iterator for fragment timeouts.
332    */
333   typedef std::list< std::tuple <Time, FragmentKey_t, Ipv6Header > >::iterator FragmentsTimeoutsListI_t;
334 
335   /**
336    * \ingroup ipv6HeaderExt
337    *
338    * \brief This class stores the fragments of a packet waiting to be rebuilt.
339    */
340   class Fragments : public SimpleRefCount<Fragments>
341   {
342 public:
343     /**
344      * \brief Constructor.
345      */
346     Fragments ();
347 
348     /**
349      * \brief Destructor.
350      */
351     ~Fragments ();
352 
353     /**
354      * \brief Add a fragment.
355      * \param fragment the fragment
356      * \param fragmentOffset the offset of the fragment
357      * \param moreFragment the bit "More Fragment"
358      */
359     void AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment);
360 
361     /**
362      * \brief Set the unfragmentable part of the packet.
363      * \param unfragmentablePart the unfragmentable part
364      */
365     void SetUnfragmentablePart (Ptr<Packet> unfragmentablePart);
366 
367     /**
368      * \brief If all fragments have been added.
369      * \returns true if the packet is entire
370      */
371     bool IsEntire () const;
372 
373     /**
374      * \brief Get the entire packet.
375      * \return the entire packet
376      */
377     Ptr<Packet> GetPacket () const;
378 
379     /**
380      * \brief Get the packet parts so far received.
381      * \return the partial packet
382      */
383     Ptr<Packet> GetPartialPacket () const;
384 
385     /**
386      * \brief Set the Timeout iterator.
387      * \param iter The iterator.
388      */
389     void SetTimeoutIter (FragmentsTimeoutsListI_t iter);
390 
391     /**
392      * \brief Get the Timeout iterator.
393      * \returns The iterator.
394      */
395     FragmentsTimeoutsListI_t GetTimeoutIter ();
396 
397 private:
398     /**
399      * \brief If other fragments will be sent.
400      */
401     bool m_moreFragment;
402 
403     /**
404      * \brief The current fragments.
405      */
406     std::list<std::pair<Ptr<Packet>, uint16_t> > m_packetFragments;
407 
408     /**
409      * \brief The unfragmentable part.
410      */
411     Ptr<Packet> m_unfragmentable;
412 
413     /**
414      * \brief Timeout iterator to "event" handler
415      */
416     FragmentsTimeoutsListI_t m_timeoutIter;
417   };
418 
419   /**
420    * \brief Process the timeout for packet fragments
421    * \param key representing the packet fragments
422    * \param ipHeader the IP header of the original packet
423    */
424   void HandleFragmentsTimeout (FragmentKey_t key, Ipv6Header ipHeader);
425 
426   /**
427    * \brief Get the packet parts so far received.
428    * \return the partial packet
429    */
430   Ptr<Packet> GetPartialPacket () const;
431 
432   /**
433    * \brief Set the Timeout EventId.
434    * \param event The event.
435    */
436   void SetTimeoutEventId (EventId event);
437 
438   /**
439    * \brief Cancel the timeout event
440    */
441   void CancelTimeout ();
442 
443   /**
444    * \brief Container for the packet fragments.
445    */
446   typedef std::map<FragmentKey_t, Ptr<Fragments> > MapFragments_t;
447 
448   /**
449    * \brief The hash of fragmented packets.
450    */
451   MapFragments_t m_fragments;
452 
453   /**
454    * \brief Set a new timeout "event" for a fragmented packet
455    * \param key the fragment identification
456    * \param ipHeader the IPv6 header of the fragmented packet
457    * \return an iterator to the inserted "event"
458    */
459   FragmentsTimeoutsListI_t SetTimeout (FragmentKey_t key, Ipv6Header ipHeader);
460 
461   /**
462    * \brief Handles a fragmented packet timeout
463    */
464   void HandleTimeout (void);
465 
466   FragmentsTimeoutsList_t m_timeoutEventList;  //!< Timeout "events" container
467   EventId m_timeoutEvent;  //!< Event for the next scheduled timeout
468   Time m_fragmentExpirationTimeout; //!< Expiration timeout
469 };
470 
471 /**
472  * \ingroup ipv6HeaderExt
473  *
474  * \brief IPv6 Extension Routing.
475  *
476  * If you want to implement a new IPv6 routing extension, all you have to do is
477  * implement a subclass of this class and add it to an Ipv6ExtensionRoutingDemux.
478  */
479 class Ipv6ExtensionRouting : public Ipv6Extension
480 {
481 public:
482   /**
483    * \brief Routing extension number.
484    */
485   static const uint8_t EXT_NUMBER = 43;
486 
487   /**
488    * \brief Get the type identificator.
489    * \return type identificator
490    */
491   static TypeId GetTypeId ();
492 
493   /**
494    * \brief Constructor.
495    */
496   Ipv6ExtensionRouting ();
497 
498   /**
499    * \brief Destructor.
500    */
501   ~Ipv6ExtensionRouting ();
502 
503   /**
504    * \brief Get the extension number.
505    * \return extension number
506    */
507   virtual uint8_t GetExtensionNumber () const;
508 
509   /**
510    * \brief Get the type of routing.
511    * \return type of routing
512    */
513   virtual uint8_t GetTypeRouting () const;
514 
515   virtual uint8_t Process (Ptr<Packet>& packet,
516                            uint8_t offset,
517                            Ipv6Header const& ipv6Header,
518                            Ipv6Address dst,
519                            uint8_t *nextHeader,
520                            bool& stopProcessing,
521                            bool& isDropped,
522                            Ipv6L3Protocol::DropReason& dropReason);
523 };
524 
525 /**
526  * \ingroup ipv6HeaderExt
527  *
528  * \brief IPv6 Extension Routing Demux.
529  */
530 class Ipv6ExtensionRoutingDemux : public Object
531 {
532 public:
533   /**
534    * \brief The interface ID.
535    * \return type ID
536    */
537   static TypeId GetTypeId ();
538 
539   /**
540    * \brief Constructor.
541    */
542   Ipv6ExtensionRoutingDemux ();
543 
544   /**
545    * \brief Destructor.
546    */
547   virtual ~Ipv6ExtensionRoutingDemux ();
548 
549   /**
550    * \brief Set the node.
551    * \param node the node to set
552    */
553   void SetNode (Ptr<Node> node);
554 
555   /**
556    * \brief Insert a new IPv6 Routing Extension.
557    * \param extensionRouting the routing extension to insert
558    */
559   void Insert (Ptr<Ipv6ExtensionRouting> extensionRouting);
560 
561   /**
562    * \brief Get the routing extension corresponding to typeRouting.
563    * \param typeRouting the number of the routing extension to retrieve
564    * \return a matching IPv6 routing extension
565    */
566   Ptr<Ipv6ExtensionRouting> GetExtensionRouting (uint8_t typeRouting);
567 
568   /**
569    * \brief Remove a routing extension from this demux.
570    * \param extensionRouting pointer on the extension to remove
571    */
572   void Remove (Ptr<Ipv6ExtensionRouting> extensionRouting);
573 
574 protected:
575   /**
576    * \brief Dispose this object.
577    */
578   virtual void DoDispose ();
579 
580 private:
581   /**
582    * \brief Container for the extension routing.
583    */
584   typedef std::list<Ptr<Ipv6ExtensionRouting> > Ipv6ExtensionRoutingList_t;
585 
586   /**
587    * \brief List of IPv6 Routing Extensions supported.
588    */
589   Ipv6ExtensionRoutingList_t m_extensionsRouting;
590 
591   /**
592    * \brief The node.
593    */
594   Ptr<Node> m_node;
595 };
596 
597 /**
598  * \ingroup ipv6HeaderExt
599  *
600  * \brief IPv6 Extension Loose Routing
601  */
602 class Ipv6ExtensionLooseRouting : public Ipv6ExtensionRouting
603 {
604 public:
605   /**
606    * \brief Routing type.
607    */
608   static const uint8_t TYPE_ROUTING = 0;
609 
610   /**
611    * \brief Get the type identificator.
612    * \return type identificator
613    */
614   static TypeId GetTypeId ();
615 
616   /**
617    * \brief Constructor.
618    */
619   Ipv6ExtensionLooseRouting ();
620 
621   /**
622    * \brief Destructor.
623    */
624   ~Ipv6ExtensionLooseRouting ();
625 
626   /**
627    * \brief Get the type of routing.
628    * \return type of routing
629    */
630   virtual uint8_t GetTypeRouting () const;
631 
632   virtual uint8_t Process (Ptr<Packet>& packet,
633                            uint8_t offset,
634                            Ipv6Header const& ipv6Header,
635                            Ipv6Address dst,
636                            uint8_t *nextHeader,
637                            bool& stopProcessing,
638                            bool& isDropped,
639                            Ipv6L3Protocol::DropReason& dropReason);
640 };
641 
642 /**
643  * \ingroup ipv6HeaderExt
644  *
645  * \brief IPv6 Extension ESP (Encapsulating Security Payload)
646  */
647 class Ipv6ExtensionESP : public Ipv6Extension
648 {
649 public:
650   /**
651    * \brief ESP extension number.
652    */
653   static const uint8_t EXT_NUMBER = 50;
654 
655   /**
656    * \brief Get the type identificator.
657    * \return type identificator
658    */
659   static TypeId GetTypeId ();
660 
661   /**
662    * \brief Constructor.
663    */
664   Ipv6ExtensionESP ();
665 
666   /**
667    * \brief Destructor.
668    */
669   ~Ipv6ExtensionESP ();
670 
671   /**
672    * \brief Get the extension number.
673    * \return extension number
674    */
675   virtual uint8_t GetExtensionNumber () const;
676 
677   virtual uint8_t Process (Ptr<Packet>& packet,
678                            uint8_t offset,
679                            Ipv6Header const& ipv6Header,
680                            Ipv6Address dst,
681                            uint8_t *nextHeader,
682                            bool& stopProcessing,
683                            bool& isDropped,
684                            Ipv6L3Protocol::DropReason& dropReason);
685 };
686 
687 /**
688  * \ingroup ipv6HeaderExt
689  *
690  * \brief IPv6 Extension AH (Authentication Header)
691  */
692 class Ipv6ExtensionAH : public Ipv6Extension
693 {
694 public:
695   /**
696    * \brief AH extension number.
697    */
698   static const uint8_t EXT_NUMBER = 51;
699 
700   /**
701    * \brief Get the type identificator.
702    * \return type identificator
703    */
704   static TypeId GetTypeId ();
705 
706   /**
707    * \brief Constructor.
708    */
709   Ipv6ExtensionAH ();
710 
711   /**
712    * \brief Destructor.
713    */
714   ~Ipv6ExtensionAH ();
715 
716   /**
717    * \brief Get the extension number.
718    * \return extension number
719    */
720   virtual uint8_t GetExtensionNumber () const;
721 
722   virtual uint8_t Process (Ptr<Packet>& packet,
723                            uint8_t offset,
724                            Ipv6Header const& ipv6Header,
725                            Ipv6Address dst,
726                            uint8_t *nextHeader,
727                            bool& stopProcessing,
728                            bool& isDropped,
729                            Ipv6L3Protocol::DropReason& dropReason);
730 };
731 
732 } /* namespace ns3 */
733 
734 #endif /* IPV6_EXTENSION_H */
735 
736