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