src/node/packetbb.cc
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu Nov 12 13:01:01 2009 +0100 (2009-11-12)
changeset 5505 c0ac392289c3
parent 5263 a0283279fddd
child 5885 d6ee673adda4
permissions -rw-r--r--
replace RefCountBase with SimpleRefCount<> to avoid duplicate refcounting implementations.
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /* vim: set ts=2 sw=2 sta expandtab ai si cin: */
     3 /* 
     4  * Copyright (c) 2009 Drexel University
     5  * 
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License version 2 as
     8  * published by the Free Software Foundation;
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program; if not, write to the Free Software
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18  * 
    19  * Author: Tom Wambold <tom5760@gmail.com>
    20  */
    21 /* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network
    22  * (MANET) Packet/PbbMessage Format
    23  * See: http://tools.ietf.org/html/rfc5444 for details */
    24 
    25 #include "ns3/ipv4-address.h"
    26 #include "ns3/ipv6-address.h"
    27 #include "ns3/assert.h"
    28 
    29 #include "packetbb.h"
    30 
    31 static const uint8_t VERSION = 0;
    32 /* Packet flags */
    33 static const uint8_t PHAS_SEQ_NUM = 0x8;
    34 static const uint8_t PHAS_TLV = 0x4;
    35 
    36 /* PbbMessage flags */
    37 static const uint8_t MHAS_ORIG = 0x80;
    38 static const uint8_t MHAS_HOP_LIMIT = 0x40;
    39 static const uint8_t MHAS_HOP_COUNT = 0x20;
    40 static const uint8_t MHAS_SEQ_NUM = 0x10;
    41 
    42 /* Address block flags */
    43 static const uint8_t AHAS_HEAD = 0x80;
    44 static const uint8_t AHAS_FULL_TAIL = 0x40;
    45 static const uint8_t AHAS_ZERO_TAIL = 0x20;
    46 static const uint8_t AHAS_SINGLE_PRE_LEN = 0x10;
    47 static const uint8_t AHAS_MULTI_PRE_LEN = 0x08;
    48 
    49 /* TLV Flags */
    50 static const uint8_t THAS_TYPE_EXT = 0x80;
    51 static const uint8_t THAS_SINGLE_INDEX = 0x40;
    52 static const uint8_t THAS_MULTI_INDEX = 0x20;
    53 static const uint8_t THAS_VALUE = 0x10;
    54 static const uint8_t THAS_EXT_LEN = 0x08;
    55 static const uint8_t TIS_MULTIVALUE = 0x04;
    56 
    57 namespace ns3 {
    58 
    59 NS_OBJECT_ENSURE_REGISTERED (PbbPacket);
    60 
    61 PbbTlvBlock::PbbTlvBlock (void)
    62 {
    63   return;
    64 }
    65 
    66 PbbTlvBlock::~PbbTlvBlock (void)
    67 {
    68   Clear ();
    69 }
    70 
    71 PbbTlvBlock::Iterator
    72 PbbTlvBlock::Begin (void)
    73 {
    74   return m_tlvList.begin ();
    75 }
    76 
    77 PbbTlvBlock::ConstIterator
    78 PbbTlvBlock::Begin (void) const
    79 {
    80   return m_tlvList.begin ();
    81 }
    82 
    83 PbbTlvBlock::Iterator
    84 PbbTlvBlock::End (void)
    85 {
    86   return m_tlvList.end ();
    87 }
    88 
    89 PbbTlvBlock::ConstIterator
    90 PbbTlvBlock::End (void) const
    91 {
    92   return m_tlvList.end ();
    93 }
    94 
    95 int
    96 PbbTlvBlock::Size (void) const
    97 {
    98   return m_tlvList.size ();
    99 }
   100 
   101 bool
   102 PbbTlvBlock::Empty (void) const
   103 {
   104   return m_tlvList.empty ();
   105 }
   106 
   107 Ptr<PbbTlv>
   108 PbbTlvBlock::Front (void) const
   109 {
   110   return m_tlvList.front ();
   111 }
   112 
   113 Ptr<PbbTlv>
   114 PbbTlvBlock::Back (void) const
   115 {
   116   return m_tlvList.back ();
   117 }
   118 
   119 void
   120 PbbTlvBlock::PushFront (Ptr<PbbTlv> tlv)
   121 {
   122   m_tlvList.push_front (tlv);
   123 }
   124 
   125 void
   126 PbbTlvBlock::PopFront (void)
   127 {
   128   m_tlvList.pop_front ();
   129 }
   130 
   131 void
   132 PbbTlvBlock::PushBack (Ptr<PbbTlv> tlv)
   133 {
   134   m_tlvList.push_back (tlv);
   135 }
   136 
   137 void
   138 PbbTlvBlock::PopBack (void)
   139 {
   140   m_tlvList.pop_back ();
   141 }
   142 
   143 PbbTlvBlock::Iterator
   144 PbbTlvBlock::Insert (PbbTlvBlock::Iterator position, const Ptr<PbbTlv> tlv)
   145 {
   146   return m_tlvList.insert (position, tlv);
   147 }
   148 
   149 PbbTlvBlock::Iterator
   150 PbbTlvBlock::Erase (PbbTlvBlock::Iterator position)
   151 {
   152   return m_tlvList.erase (position);
   153 }
   154 
   155 PbbTlvBlock::Iterator
   156 PbbTlvBlock::Erase (PbbTlvBlock::Iterator first, PbbTlvBlock::Iterator last)
   157 {
   158   return m_tlvList.erase (first, last);
   159 }
   160 
   161 void
   162 PbbTlvBlock::Clear (void)
   163 {
   164   for (Iterator iter = Begin (); iter != End (); iter++)
   165     {
   166       *iter = 0;
   167     }
   168   m_tlvList.clear ();
   169 }
   170 
   171 uint32_t
   172 PbbTlvBlock::GetSerializedSize (void) const
   173 {
   174   /* tlv size */
   175   uint32_t size = 2;
   176   for (ConstIterator iter = Begin (); iter != End (); iter++)
   177     {
   178       size += (*iter)->GetSerializedSize ();
   179     }
   180   return size;
   181 }
   182 
   183 void
   184 PbbTlvBlock::Serialize (Buffer::Iterator &start) const
   185 {
   186   if (Empty ())
   187     {
   188       start.WriteHtonU16 (0);
   189       return;
   190     }
   191 
   192   /* We need to write the size of the TLV block in front, so save its
   193    * position. */
   194   Buffer::Iterator tlvsize = start;
   195   start.Next (2);
   196   for (ConstIterator iter = Begin (); iter != End (); iter++)
   197     {
   198       (*iter)->Serialize (start);
   199     }
   200   /* - 2 to not include the size field */
   201   uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
   202   tlvsize.WriteHtonU16 (size);
   203 }
   204 
   205 void
   206 PbbTlvBlock::Deserialize (Buffer::Iterator &start)
   207 {
   208   uint16_t size = start.ReadNtohU16 ();
   209 
   210   Buffer::Iterator tlvstart = start;
   211   if (size > 0)
   212     {
   213       while (start.GetDistanceFrom (tlvstart) < size)
   214         {
   215           Ptr<PbbTlv> newtlv = Create<PbbTlv> ();
   216           newtlv->Deserialize (start);
   217           PushBack (newtlv);
   218         }
   219     }
   220 }
   221 
   222 void
   223 PbbTlvBlock::Print (std::ostream &os) const
   224 {
   225   Print (os, 0);
   226 }
   227 
   228 void
   229 PbbTlvBlock::Print (std::ostream &os, int level) const
   230 {
   231   std::string prefix = "";
   232   for (int i = 0; i < level; i++)
   233     {
   234       prefix.append("\t");
   235     }
   236 
   237   os << prefix << "TLV Block {" << std::endl;
   238   os << prefix << "\tsize = " << Size () << std::endl;
   239   os << prefix << "\tmembers [" << std::endl;
   240 
   241   for (ConstIterator iter = Begin (); iter != End (); iter++)
   242     {
   243       (*iter)->Print (os, level+2);
   244     }
   245 
   246   os << prefix << "\t]" << std::endl;
   247   os << prefix << "}" << std::endl;
   248 }
   249 
   250 bool
   251 PbbTlvBlock::operator== (const PbbTlvBlock &other) const
   252 {
   253   if (Size () != other.Size ())
   254     {
   255       return false;
   256     }
   257 
   258   ConstIterator ti, oi;
   259   for (ti = Begin (), oi = other.Begin ();
   260       ti != End () && oi != other.End ();
   261       ti++, oi++)
   262     {
   263       if (**ti != **oi)
   264         {
   265           return false;
   266         }
   267     }
   268   return true;
   269 }
   270 
   271 bool
   272 PbbTlvBlock::operator!= (const PbbTlvBlock &other) const
   273 {
   274   return !(*this == other);
   275 }
   276 
   277 /* End PbbTlvBlock class */
   278 
   279 PbbAddressTlvBlock::PbbAddressTlvBlock (void)
   280 {
   281   return;
   282 }
   283 
   284 PbbAddressTlvBlock::~PbbAddressTlvBlock (void)
   285 {
   286   Clear ();
   287 }
   288 
   289 PbbAddressTlvBlock::Iterator
   290 PbbAddressTlvBlock::Begin (void)
   291 {
   292   return m_tlvList.begin ();
   293 }
   294 
   295 PbbAddressTlvBlock::ConstIterator
   296 PbbAddressTlvBlock::Begin (void) const
   297 {
   298   return m_tlvList.begin ();
   299 }
   300 
   301 PbbAddressTlvBlock::Iterator
   302 PbbAddressTlvBlock::End (void)
   303 {
   304   return m_tlvList.end ();
   305 }
   306 
   307 PbbAddressTlvBlock::ConstIterator
   308 PbbAddressTlvBlock::End (void) const
   309 {
   310   return m_tlvList.end ();
   311 }
   312 
   313 int
   314 PbbAddressTlvBlock::Size (void) const
   315 {
   316   return m_tlvList.size ();
   317 }
   318 
   319 bool
   320 PbbAddressTlvBlock::Empty (void) const
   321 {
   322   return m_tlvList.empty ();
   323 }
   324 
   325 Ptr<PbbAddressTlv>
   326 PbbAddressTlvBlock::Front (void) const
   327 {
   328   return m_tlvList.front ();
   329 }
   330 
   331 Ptr<PbbAddressTlv>
   332 PbbAddressTlvBlock::Back (void) const
   333 {
   334   return m_tlvList.back ();
   335 }
   336 
   337 void
   338 PbbAddressTlvBlock::PushFront (Ptr<PbbAddressTlv> tlv)
   339 {
   340   m_tlvList.push_front (tlv);
   341 }
   342 
   343 void
   344 PbbAddressTlvBlock::PopFront (void)
   345 {
   346   m_tlvList.pop_front ();
   347 }
   348 
   349 void
   350 PbbAddressTlvBlock::PushBack (Ptr<PbbAddressTlv> tlv)
   351 {
   352   m_tlvList.push_back (tlv);
   353 }
   354 
   355 void
   356 PbbAddressTlvBlock::PopBack (void)
   357 {
   358   m_tlvList.pop_back ();
   359 }
   360 
   361 PbbAddressTlvBlock::Iterator
   362 PbbAddressTlvBlock::Insert (PbbAddressTlvBlock::Iterator position, const Ptr<PbbAddressTlv> tlv)
   363 {
   364   return m_tlvList.insert (position, tlv);
   365 }
   366 
   367 PbbAddressTlvBlock::Iterator
   368 PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator position)
   369 {
   370   return m_tlvList.erase (position);
   371 }
   372 
   373 PbbAddressTlvBlock::Iterator
   374 PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator first, PbbAddressTlvBlock::Iterator last)
   375 {
   376   return m_tlvList.erase (first, last);
   377 }
   378 
   379 void
   380 PbbAddressTlvBlock::Clear (void)
   381 {
   382   for (Iterator iter = Begin (); iter != End (); iter++)
   383     {
   384       *iter = 0;
   385     }
   386   m_tlvList.clear ();
   387 }
   388 
   389 uint32_t
   390 PbbAddressTlvBlock::GetSerializedSize (void) const
   391 {
   392   /* tlv size */
   393   uint32_t size = 2;
   394   for (ConstIterator iter = Begin (); iter != End (); iter++)
   395     {
   396       size += (*iter)->GetSerializedSize ();
   397     }
   398   return size;
   399 }
   400 
   401 void
   402 PbbAddressTlvBlock::Serialize (Buffer::Iterator &start) const
   403 {
   404   if (Empty ())
   405     {
   406       start.WriteHtonU16 (0);
   407       return;
   408     }
   409 
   410   /* We need to write the size of the TLV block in front, so save its
   411    * position. */
   412   Buffer::Iterator tlvsize = start;
   413   start.Next (2);
   414   for (ConstIterator iter = Begin (); iter != End (); iter++)
   415     {
   416       (*iter)->Serialize (start);
   417     }
   418   /* - 2 to not include the size field */
   419   uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
   420   tlvsize.WriteHtonU16 (size);
   421 }
   422 
   423 void
   424 PbbAddressTlvBlock::Deserialize (Buffer::Iterator &start)
   425 {
   426   uint16_t size = start.ReadNtohU16 ();
   427 
   428   Buffer::Iterator tlvstart = start;
   429   if (size > 0)
   430     {
   431       while (start.GetDistanceFrom (tlvstart) < size)
   432       {
   433         Ptr<PbbAddressTlv> newtlv = Create<PbbAddressTlv> ();
   434         newtlv->Deserialize (start);
   435         PushBack (newtlv);
   436       }
   437     }
   438 }
   439 
   440 void
   441 PbbAddressTlvBlock::Print (std::ostream &os) const
   442 {
   443   Print (os, 0);
   444 }
   445 
   446 void
   447 PbbAddressTlvBlock::Print (std::ostream &os, int level) const
   448 {
   449   std::string prefix = "";
   450   for (int i = 0; i < level; i++)
   451     {
   452       prefix.append("\t");
   453     }
   454 
   455   os << prefix << "TLV Block {" << std::endl;
   456   os << prefix << "\tsize = " << Size () << std::endl;
   457   os << prefix << "\tmembers [" << std::endl;
   458 
   459   for (ConstIterator iter = Begin (); iter != End (); iter++)
   460     {
   461       (*iter)->Print (os, level+2);
   462     }
   463 
   464   os << prefix << "\t]" << std::endl;
   465   os << prefix << "}" << std::endl;
   466 }
   467 
   468 bool
   469 PbbAddressTlvBlock::operator== (const PbbAddressTlvBlock &other) const
   470 {
   471   if (Size () != other.Size ())
   472     {
   473       return false;
   474     }
   475 
   476   ConstIterator it, ot;
   477   for (it = Begin (), ot = other.Begin ();
   478       it != End () && ot != other.End ();
   479       it++, ot++)
   480     {
   481       if (**it != **ot)
   482         {
   483           return false;
   484         }
   485     }
   486   return true;
   487 }
   488 
   489 bool
   490 PbbAddressTlvBlock::operator!= (const PbbAddressTlvBlock &other) const
   491 {
   492   return !(*this == other);
   493 }
   494 
   495 
   496 /* End PbbAddressTlvBlock Class */
   497 
   498 PbbPacket::PbbPacket (void)
   499 {
   500   m_version = VERSION;
   501   m_hasseqnum = false;
   502 }
   503 
   504 PbbPacket::~PbbPacket (void)
   505 {
   506   MessageClear ();
   507 }
   508 
   509 uint8_t
   510 PbbPacket::GetVersion (void) const
   511 {
   512   return m_version;
   513 }
   514 
   515 void
   516 PbbPacket::SetSequenceNumber (uint16_t number)
   517 {
   518   m_seqnum = number;
   519   m_hasseqnum = true;
   520 }
   521 
   522 uint16_t
   523 PbbPacket::GetSequenceNumber (void) const
   524 {
   525   NS_ASSERT (HasSequenceNumber ());
   526   return m_seqnum;
   527 }
   528 
   529 bool
   530 PbbPacket::HasSequenceNumber (void) const
   531 {
   532   return m_hasseqnum;
   533 }
   534 
   535 /* Manipulating Packet TLVs */
   536 
   537 PbbPacket::TlvIterator
   538 PbbPacket::TlvBegin (void)
   539 {
   540   return m_tlvList.Begin ();
   541 }
   542 
   543 PbbPacket::ConstTlvIterator
   544 PbbPacket::TlvBegin (void) const
   545 {
   546   return m_tlvList.Begin ();
   547 }
   548 
   549 PbbPacket::TlvIterator
   550 PbbPacket::TlvEnd (void)
   551 {
   552   return m_tlvList.End ();
   553 }
   554 
   555 PbbPacket::ConstTlvIterator
   556 PbbPacket::TlvEnd (void) const
   557 {
   558   return m_tlvList.End ();
   559 }
   560 
   561 int
   562 PbbPacket::TlvSize (void) const
   563 {
   564   return m_tlvList.Size ();
   565 }
   566 
   567 bool
   568 PbbPacket::TlvEmpty (void) const
   569 {
   570   return m_tlvList.Empty ();
   571 }
   572 
   573 Ptr<PbbTlv>
   574 PbbPacket::TlvFront (void)
   575 {
   576   return m_tlvList.Front ();
   577 }
   578 
   579 const Ptr<PbbTlv>
   580 PbbPacket::TlvFront (void) const
   581 {
   582   return m_tlvList.Front ();
   583 }
   584 
   585 Ptr<PbbTlv>
   586 PbbPacket::TlvBack (void)
   587 {
   588   return m_tlvList.Back ();
   589 }
   590 
   591 const Ptr<PbbTlv>
   592 PbbPacket::TlvBack (void) const
   593 {
   594   return m_tlvList.Back ();
   595 }
   596 
   597 void
   598 PbbPacket::TlvPushFront (Ptr<PbbTlv> tlv)
   599 {
   600   m_tlvList.PushFront (tlv);
   601 }
   602 
   603 void
   604 PbbPacket::TlvPopFront (void)
   605 {
   606   m_tlvList.PopFront ();
   607 }
   608 
   609 void
   610 PbbPacket::TlvPushBack (Ptr<PbbTlv> tlv)
   611 {
   612   m_tlvList.PushBack (tlv);
   613 }
   614 
   615 void
   616 PbbPacket::TlvPopBack (void)
   617 {
   618   m_tlvList.PopBack ();
   619 }
   620 
   621 PbbPacket::TlvIterator
   622 PbbPacket::Erase (PbbPacket::TlvIterator position)
   623 {
   624   return m_tlvList.Erase (position);
   625 }
   626 
   627 PbbPacket::TlvIterator
   628 PbbPacket::Erase (PbbPacket::TlvIterator first, PbbPacket::TlvIterator last)
   629 {
   630   return m_tlvList.Erase (first, last);
   631 }
   632 
   633 void
   634 PbbPacket::TlvClear (void)
   635 {
   636   m_tlvList.Clear ();
   637 }
   638 
   639 /* Manipulating Packet Messages */
   640 
   641 PbbPacket::MessageIterator
   642 PbbPacket::MessageBegin (void)
   643 {
   644   return m_messageList.begin ();
   645 }
   646 
   647 PbbPacket::ConstMessageIterator
   648 PbbPacket::MessageBegin (void) const
   649 {
   650   return m_messageList.begin ();
   651 }
   652 
   653 PbbPacket::MessageIterator
   654 PbbPacket::MessageEnd (void)
   655 {
   656   return m_messageList.end ();
   657 }
   658 
   659 PbbPacket::ConstMessageIterator
   660 PbbPacket::MessageEnd (void) const
   661 {
   662   return m_messageList.end ();
   663 }
   664 
   665 int
   666 PbbPacket::MessageSize (void) const
   667 {
   668   return m_messageList.size ();
   669 }
   670 
   671 bool
   672 PbbPacket::MessageEmpty (void) const
   673 {
   674   return m_messageList.empty ();
   675 }
   676 
   677 Ptr<PbbMessage>
   678 PbbPacket::MessageFront (void)
   679 {
   680   return m_messageList.front ();
   681 }
   682 
   683 const Ptr<PbbMessage>
   684 PbbPacket::MessageFront (void) const
   685 {
   686   return m_messageList.front ();
   687 }
   688 
   689 Ptr<PbbMessage>
   690 PbbPacket::MessageBack (void)
   691 {
   692   return m_messageList.back ();
   693 }
   694 
   695 const Ptr<PbbMessage>
   696 PbbPacket::MessageBack (void) const
   697 {
   698   return m_messageList.back ();
   699 }
   700 
   701 void
   702 PbbPacket::MessagePushFront (Ptr<PbbMessage> tlv)
   703 {
   704   m_messageList.push_front (tlv);
   705 }
   706 
   707 void
   708 PbbPacket::MessagePopFront (void)
   709 {
   710   m_messageList.pop_front ();
   711 }
   712 
   713 void
   714 PbbPacket::MessagePushBack (Ptr<PbbMessage> tlv)
   715 {
   716   m_messageList.push_back (tlv);
   717 }
   718 
   719 void
   720 PbbPacket::MessagePopBack (void)
   721 {
   722   m_messageList.pop_back ();
   723 }
   724 
   725 PbbPacket::MessageIterator
   726 PbbPacket::Erase (PbbPacket::MessageIterator position)
   727 {
   728   return m_messageList.erase (position);
   729 }
   730 
   731 PbbPacket::MessageIterator
   732 PbbPacket::Erase (PbbPacket::MessageIterator first,
   733     PbbPacket::MessageIterator last)
   734 {
   735   return m_messageList.erase (first, last);
   736 }
   737 
   738 void
   739 PbbPacket::MessageClear (void)
   740 {
   741   for (MessageIterator iter = MessageBegin (); iter != MessageEnd (); iter++)
   742     {
   743       *iter = 0;
   744     }
   745   m_messageList.clear ();
   746 }
   747 
   748 
   749 TypeId
   750 PbbPacket::GetTypeId (void)
   751 {
   752   static TypeId tid = TypeId ("ns3::PbbPacket")
   753     .SetParent<Header> ()
   754     .AddConstructor<PbbPacket> ()
   755   ;
   756   return tid;
   757 }
   758 
   759 TypeId
   760 PbbPacket::GetInstanceTypeId (void) const
   761 {
   762   return GetTypeId ();
   763 }
   764 
   765 uint32_t
   766 PbbPacket::GetSerializedSize (void) const
   767 {
   768   /* Version number + flags */
   769   uint32_t size = 1;
   770 
   771   if (HasSequenceNumber())
   772     {
   773       size += 2;
   774     }
   775 
   776   if (!TlvEmpty ())
   777     {
   778       size += m_tlvList.GetSerializedSize ();
   779     }
   780 
   781   for (ConstMessageIterator iter = MessageBegin ();
   782       iter != MessageEnd ();
   783       iter++)
   784     {
   785       size += (*iter)->GetSerializedSize ();
   786     }
   787 
   788   return size;
   789 }
   790 
   791 void
   792 PbbPacket::Serialize (Buffer::Iterator start) const
   793 {
   794   /* We remember the start, so we can write the flags after we check for a
   795    * sequence number and TLV. */
   796   Buffer::Iterator bufref = start;
   797   start.Next ();
   798 
   799   uint8_t flags = VERSION;
   800   /* Make room for 4 bit flags */
   801   flags <<= 4;
   802 
   803   if (HasSequenceNumber ())
   804     {
   805       flags |= PHAS_SEQ_NUM;
   806       start.WriteHtonU16 (GetSequenceNumber ());
   807     }
   808 
   809   if (!TlvEmpty ())
   810     {
   811       flags |= PHAS_TLV;
   812       m_tlvList.Serialize (start);
   813     }
   814 
   815   bufref.WriteU8(flags);
   816 
   817   for (ConstMessageIterator iter = MessageBegin ();
   818       iter != MessageEnd ();
   819       iter++)
   820     {
   821       (*iter)->Serialize (start);
   822     }
   823 }
   824 
   825 uint32_t
   826 PbbPacket::Deserialize (Buffer::Iterator start)
   827 {
   828   Buffer::Iterator begin = start;
   829 
   830   uint8_t flags = start.ReadU8 ();
   831 
   832   if (flags & PHAS_SEQ_NUM)
   833     {
   834       SetSequenceNumber (start.ReadNtohU16 ());
   835     }
   836 
   837   if (flags & PHAS_TLV)
   838     {
   839       m_tlvList.Deserialize (start);
   840     }
   841 
   842   while (!start.IsEnd())
   843     {
   844       Ptr<PbbMessage> newmsg = PbbMessage::DeserializeMessage (start);
   845       if (newmsg == 0)
   846         {
   847           return start.GetDistanceFrom (begin);
   848         }
   849       MessagePushBack (newmsg);
   850     }
   851 
   852   flags >>= 4;
   853   m_version = flags;
   854 
   855   return start.GetDistanceFrom (begin);
   856 }
   857 
   858 void
   859 PbbPacket::Print (std::ostream &os) const
   860 {
   861   os << "PbbPacket {" << std::endl;
   862 
   863   if (HasSequenceNumber ())
   864     {
   865       os << "\tsequence number = " << GetSequenceNumber ();
   866     }
   867 
   868   os << std::endl;
   869 
   870   m_tlvList.Print (os, 1);
   871 
   872   for (ConstMessageIterator iter = MessageBegin ();
   873       iter != MessageEnd ();
   874       iter++)
   875     {
   876       (*iter)->Print (os, 1);
   877     }
   878 
   879   os << "}" << std::endl;
   880 }
   881 
   882 bool
   883 PbbPacket::operator== (const PbbPacket &other) const
   884 {
   885   if (GetVersion () != other.GetVersion ())
   886     {
   887       return false;
   888     }
   889 
   890   if (HasSequenceNumber () != other.HasSequenceNumber ())
   891     {
   892       return false;
   893     }
   894 
   895   if (HasSequenceNumber ())
   896     {
   897       if (GetSequenceNumber () != other.GetSequenceNumber ())
   898         return false;
   899     }
   900 
   901   if (m_tlvList != other.m_tlvList)
   902     {
   903       return false;
   904     }
   905 
   906   if (MessageSize () != other.MessageSize ())
   907     {
   908         return false;
   909     }
   910 
   911   ConstMessageIterator tmi, omi;
   912   for (tmi = MessageBegin (), omi = other.MessageBegin ();
   913     tmi != MessageEnd () && omi != other.MessageEnd ();
   914     tmi++, omi++)
   915     {
   916       if (**tmi != **omi)
   917         {
   918           return false;
   919         }
   920     }
   921   return true;
   922 }
   923 
   924 bool
   925 PbbPacket::operator!= (const PbbPacket &other) const
   926 {
   927   return !(*this == other);
   928 }
   929 
   930 /* End PbbPacket class */
   931 
   932 PbbMessage::PbbMessage ()
   933 {
   934   /* Default to IPv4 */
   935   m_addrSize = IPV4;
   936   m_hasOriginatorAddress = false;
   937   m_hasHopLimit = false;
   938   m_hasHopCount = false;
   939   m_hasSequenceNumber = false;
   940 }
   941 
   942 PbbMessage::~PbbMessage ()
   943 {
   944   AddressBlockClear ();
   945 }
   946 
   947 void
   948 PbbMessage::SetType (uint8_t type)
   949 {
   950   m_type = type;
   951 }
   952 
   953 uint8_t
   954 PbbMessage::GetType (void) const
   955 {
   956   return m_type;
   957 }
   958 
   959 PbbAddressLength
   960 PbbMessage::GetAddressLength (void) const
   961 {
   962   return m_addrSize;
   963 }
   964 
   965 void
   966 PbbMessage::SetOriginatorAddress (Address address)
   967 {
   968   m_originatorAddress = address;
   969   m_hasOriginatorAddress = true;
   970 }
   971 
   972 Address
   973 PbbMessage::GetOriginatorAddress (void) const
   974 {
   975   NS_ASSERT (HasOriginatorAddress ());
   976   return m_originatorAddress;
   977 }
   978 
   979 bool
   980 PbbMessage::HasOriginatorAddress (void) const
   981 {
   982   return m_hasOriginatorAddress;
   983 }
   984 
   985 void
   986 PbbMessage::SetHopLimit (uint8_t hopLimit)
   987 {
   988   m_hopLimit = hopLimit;
   989   m_hasHopLimit = true;
   990 }
   991 
   992 uint8_t
   993 PbbMessage::GetHopLimit (void) const
   994 {
   995   NS_ASSERT (HasHopLimit ());
   996   return m_hopLimit;
   997 }
   998 
   999 bool
  1000 PbbMessage::HasHopLimit (void) const
  1001 {
  1002   return m_hasHopLimit;
  1003 }
  1004 
  1005 void
  1006 PbbMessage::SetHopCount (uint8_t hopCount)
  1007 {
  1008   m_hopCount = hopCount;
  1009   m_hasHopCount = true;
  1010 }
  1011 
  1012 uint8_t
  1013 PbbMessage::GetHopCount (void) const
  1014 {
  1015   NS_ASSERT (HasHopCount ());
  1016   return m_hopCount;
  1017 }
  1018 
  1019 bool
  1020 PbbMessage::HasHopCount (void) const
  1021 {
  1022   return m_hasHopCount;
  1023 }
  1024 
  1025 void
  1026 PbbMessage::SetSequenceNumber (uint16_t sequenceNumber)
  1027 {
  1028   m_sequenceNumber = sequenceNumber;
  1029   m_hasSequenceNumber = true;
  1030 }
  1031 
  1032 uint16_t
  1033 PbbMessage::GetSequenceNumber (void) const
  1034 {
  1035   NS_ASSERT (HasSequenceNumber ());
  1036   return m_sequenceNumber;
  1037 }
  1038 
  1039 bool
  1040 PbbMessage::HasSequenceNumber (void) const
  1041 {
  1042   return m_hasSequenceNumber;
  1043 }
  1044 
  1045 /* Manipulating PbbMessage TLVs */
  1046 
  1047 PbbMessage::TlvIterator
  1048 PbbMessage::TlvBegin (void)
  1049 {
  1050   return m_tlvList.Begin();
  1051 }
  1052 
  1053 PbbMessage::ConstTlvIterator
  1054 PbbMessage::TlvBegin (void) const
  1055 {
  1056   return m_tlvList.Begin();
  1057 }
  1058 
  1059 PbbMessage::TlvIterator
  1060 PbbMessage::TlvEnd (void)
  1061 {
  1062   return m_tlvList.End();
  1063 }
  1064 
  1065 PbbMessage::ConstTlvIterator
  1066 PbbMessage::TlvEnd (void) const
  1067 {
  1068   return m_tlvList.End();
  1069 }
  1070 
  1071 int
  1072 PbbMessage::TlvSize (void) const
  1073 {
  1074   return m_tlvList.Size();
  1075 }
  1076 
  1077 bool
  1078 PbbMessage::TlvEmpty (void) const
  1079 {
  1080   return m_tlvList.Empty();
  1081 }
  1082 
  1083 Ptr<PbbTlv>
  1084 PbbMessage::TlvFront (void)
  1085 {
  1086   return m_tlvList.Front();
  1087 }
  1088 
  1089 const Ptr<PbbTlv>
  1090 PbbMessage::TlvFront (void) const
  1091 {
  1092   return m_tlvList.Front();
  1093 }
  1094 
  1095 Ptr<PbbTlv>
  1096 PbbMessage::TlvBack (void)
  1097 {
  1098   return m_tlvList.Back();
  1099 }
  1100 
  1101 const Ptr<PbbTlv>
  1102 PbbMessage::TlvBack (void) const
  1103 {
  1104   return m_tlvList.Back();
  1105 }
  1106 
  1107 void
  1108 PbbMessage::TlvPushFront (Ptr<PbbTlv> tlv)
  1109 {
  1110   m_tlvList.PushFront(tlv);
  1111 }
  1112 
  1113 void
  1114 PbbMessage::TlvPopFront (void)
  1115 {
  1116   m_tlvList.PopFront();
  1117 }
  1118 
  1119 void
  1120 PbbMessage::TlvPushBack (Ptr<PbbTlv> tlv)
  1121 {
  1122   m_tlvList.PushBack(tlv);
  1123 }
  1124 
  1125 void
  1126 PbbMessage::TlvPopBack (void)
  1127 {
  1128   m_tlvList.PopBack();
  1129 }
  1130 
  1131 PbbMessage::TlvIterator
  1132 PbbMessage::TlvErase (PbbMessage::TlvIterator position)
  1133 {
  1134   return m_tlvList.Erase(position);
  1135 }
  1136 
  1137 PbbMessage::TlvIterator
  1138 PbbMessage::TlvErase (PbbMessage::TlvIterator first, PbbMessage::TlvIterator last)
  1139 {
  1140   return m_tlvList.Erase(first, last);
  1141 }
  1142 
  1143 void
  1144 PbbMessage::TlvClear (void)
  1145 {
  1146   m_tlvList.Clear();
  1147 }
  1148 
  1149 /* Manipulating Address Block and Address TLV pairs */
  1150 
  1151 PbbMessage::AddressBlockIterator
  1152 PbbMessage::AddressBlockBegin (void)
  1153 {
  1154   return m_addressBlockList.begin();
  1155 }
  1156 
  1157 PbbMessage::ConstAddressBlockIterator
  1158 PbbMessage::AddressBlockBegin (void) const
  1159 {
  1160   return m_addressBlockList.begin();
  1161 }
  1162 
  1163 PbbMessage::AddressBlockIterator
  1164 PbbMessage::AddressBlockEnd (void)
  1165 {
  1166   return m_addressBlockList.end();
  1167 }
  1168 
  1169 PbbMessage::ConstAddressBlockIterator
  1170 PbbMessage::AddressBlockEnd (void) const
  1171 {
  1172   return m_addressBlockList.end();
  1173 }
  1174 
  1175 int
  1176 PbbMessage::AddressBlockSize (void) const
  1177 {
  1178   return m_addressBlockList.size();
  1179 }
  1180 
  1181 bool
  1182 PbbMessage::AddressBlockEmpty (void) const
  1183 {
  1184   return m_addressBlockList.empty();
  1185 }
  1186 
  1187 Ptr<PbbAddressBlock>
  1188 PbbMessage::AddressBlockFront (void)
  1189 {
  1190   return m_addressBlockList.front();
  1191 }
  1192 
  1193 const Ptr<PbbAddressBlock>
  1194 PbbMessage::AddressBlockFront (void) const
  1195 {
  1196   return m_addressBlockList.front();
  1197 }
  1198 
  1199 Ptr<PbbAddressBlock>
  1200 PbbMessage::AddressBlockBack (void)
  1201 {
  1202   return m_addressBlockList.back();
  1203 }
  1204 
  1205 const Ptr<PbbAddressBlock>
  1206 PbbMessage::AddressBlockBack (void) const
  1207 {
  1208   return m_addressBlockList.back();
  1209 }
  1210 
  1211 void
  1212 PbbMessage::AddressBlockPushFront (Ptr<PbbAddressBlock> tlv)
  1213 {
  1214   m_addressBlockList.push_front(tlv);
  1215 }
  1216 
  1217 void
  1218 PbbMessage::AddressBlockPopFront (void)
  1219 {
  1220   m_addressBlockList.pop_front();
  1221 }
  1222 
  1223 void
  1224 PbbMessage::AddressBlockPushBack (Ptr<PbbAddressBlock> tlv)
  1225 {
  1226   m_addressBlockList.push_back(tlv);
  1227 }
  1228 
  1229 void
  1230 PbbMessage::AddressBlockPopBack (void)
  1231 {
  1232   m_addressBlockList.pop_back();
  1233 }
  1234 
  1235 PbbMessage::AddressBlockIterator
  1236 PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator position)
  1237 {
  1238   return m_addressBlockList.erase(position);
  1239 }
  1240 
  1241 PbbMessage::AddressBlockIterator
  1242 PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator first,
  1243     PbbMessage::AddressBlockIterator last)
  1244 {
  1245   return m_addressBlockList.erase(first, last);
  1246 }
  1247 
  1248 void
  1249 PbbMessage::AddressBlockClear (void)
  1250 {
  1251   for (AddressBlockIterator iter = AddressBlockBegin ();
  1252       iter != AddressBlockEnd ();
  1253       iter++)
  1254     {
  1255       *iter = 0;
  1256     }
  1257   return m_addressBlockList.clear();
  1258 }
  1259 
  1260 uint32_t
  1261 PbbMessage::GetSerializedSize (void) const
  1262 {
  1263   /* msg-type + (msg-flags + msg-addr-length) + 2msg-size */
  1264   uint32_t size = 4;
  1265 
  1266   if (HasOriginatorAddress())
  1267     {
  1268       size += GetAddressLength() + 1;
  1269     }
  1270 
  1271   if (HasHopLimit())
  1272     {
  1273       size++;
  1274     }
  1275 
  1276   if (HasHopCount())
  1277     {
  1278       size++;
  1279     }
  1280 
  1281   if (HasSequenceNumber())
  1282     {
  1283       size += 2;
  1284     }
  1285 
  1286   size += m_tlvList.GetSerializedSize ();
  1287 
  1288   for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1289       iter != AddressBlockEnd ();
  1290       iter++)
  1291     {
  1292       size += (*iter)->GetSerializedSize ();
  1293     }
  1294 
  1295   return size;
  1296 }
  1297 
  1298 void
  1299 PbbMessage::Serialize (Buffer::Iterator &start) const
  1300 {
  1301   Buffer::Iterator front = start;
  1302 
  1303   start.WriteU8 (GetType());
  1304 
  1305   /* Save a reference to the spot where we will later write the flags */
  1306   Buffer::Iterator bufref = start;
  1307   start.Next (1);
  1308 
  1309   uint8_t flags = 0;
  1310 
  1311   flags = GetAddressLength ();
  1312 
  1313   Buffer::Iterator sizeref = start;
  1314   start.Next (2);
  1315 
  1316   if (HasOriginatorAddress ())
  1317     {
  1318       flags |= MHAS_ORIG;
  1319       SerializeOriginatorAddress (start);
  1320     }
  1321 
  1322   if (HasHopLimit ())
  1323     {
  1324       flags |= MHAS_HOP_LIMIT;
  1325       start.WriteU8 (GetHopLimit ());
  1326     }
  1327 
  1328   if (HasHopCount ())
  1329     {
  1330       flags |= MHAS_HOP_COUNT;
  1331       start.WriteU8 (GetHopCount ());
  1332     }
  1333 
  1334   if (HasSequenceNumber ())
  1335     {
  1336       flags |= MHAS_SEQ_NUM;
  1337       start.WriteHtonU16 (GetSequenceNumber ());
  1338     }
  1339 
  1340   bufref.WriteU8(flags);
  1341 
  1342   m_tlvList.Serialize (start);
  1343 
  1344   for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1345       iter != AddressBlockEnd ();
  1346       iter++)
  1347     {
  1348       (*iter)->Serialize (start);
  1349     }
  1350 
  1351   sizeref.WriteHtonU16 (front.GetDistanceFrom (start));
  1352 }
  1353 
  1354 Ptr<PbbMessage>
  1355 PbbMessage::DeserializeMessage (Buffer::Iterator &start)
  1356 {
  1357   /* We need to read the msg-addr-len field to determine what kind of object to
  1358    * construct. */
  1359   start.Next ();
  1360   uint8_t addrlen = start.ReadU8 ();
  1361   start.Prev (2); /* Go back to the start */
  1362 
  1363   /* The first four bytes of the flag is the address length.  Set the last four
  1364    * bytes to 0 to read it. */
  1365   addrlen = (addrlen & 0xf);
  1366 
  1367   Ptr<PbbMessage> newmsg;
  1368 
  1369   switch (addrlen)
  1370     {
  1371       case 0:
  1372       case IPV4:
  1373         newmsg = Create<PbbMessageIpv4> ();
  1374         break;
  1375       case IPV6:
  1376         newmsg = Create<PbbMessageIpv6> ();
  1377         break;
  1378       default:
  1379         return 0;
  1380         break;
  1381     }
  1382   newmsg->Deserialize (start);
  1383   return newmsg;
  1384 }
  1385 
  1386 void
  1387 PbbMessage::Deserialize (Buffer::Iterator &start)
  1388 {
  1389   Buffer::Iterator front = start;
  1390   SetType (start.ReadU8 ());
  1391   uint8_t flags = start.ReadU8 ();
  1392 
  1393   uint16_t size = start.ReadNtohU16 ();
  1394 
  1395   if (flags & MHAS_ORIG)
  1396     {
  1397       SetOriginatorAddress (DeserializeOriginatorAddress (start));
  1398     }
  1399 
  1400   if (flags & MHAS_HOP_LIMIT)
  1401     {
  1402       SetHopLimit (start.ReadU8 ());
  1403     }
  1404 
  1405   if (flags & MHAS_HOP_COUNT)
  1406     {
  1407       SetHopCount (start.ReadU8 ());
  1408     }
  1409 
  1410   if (flags & MHAS_SEQ_NUM)
  1411     {
  1412       SetSequenceNumber (start.ReadNtohU16 ());
  1413     }
  1414 
  1415   m_tlvList.Deserialize (start);
  1416 
  1417   if (size > 0)
  1418     {
  1419       while (start.GetDistanceFrom(front) < size)
  1420         {
  1421           Ptr<PbbAddressBlock> newab = AddressBlockDeserialize (start);
  1422           AddressBlockPushBack (newab);
  1423         }
  1424     }
  1425 }
  1426 
  1427 void
  1428 PbbMessage::Print (std::ostream &os) const
  1429 {
  1430   Print (os, 0);
  1431 }
  1432 
  1433 void
  1434 PbbMessage::Print (std::ostream &os, int level) const
  1435 {
  1436   std::string prefix = "";
  1437   for (int i = 0; i < level; i++)
  1438     {
  1439       prefix.append ("\t");
  1440     }
  1441 
  1442   os << prefix << "PbbMessage {" << std::endl;
  1443 
  1444   os << prefix << "\tmessage type = " << (int)GetType () << std::endl;
  1445   os << prefix << "\taddress size = " << GetAddressLength () << std::endl;
  1446 
  1447   if (HasOriginatorAddress ())
  1448     {
  1449       os << prefix << "\toriginator address = ";
  1450       PrintOriginatorAddress (os);
  1451       os << std::endl;
  1452     }
  1453 
  1454   if (HasHopLimit ())
  1455     {
  1456       os << prefix << "\thop limit = " << (int)GetHopLimit () << std::endl;
  1457     }
  1458 
  1459   if (HasHopCount ())
  1460     {
  1461       os << prefix << "\thop count = " << (int)GetHopCount () << std::endl;
  1462     }
  1463 
  1464   if (HasSequenceNumber ())
  1465     {
  1466       os << prefix << "\tseqnum = " << GetSequenceNumber () << std::endl;
  1467     }
  1468 
  1469   m_tlvList.Print (os, level+1);
  1470 
  1471   for (ConstAddressBlockIterator iter = AddressBlockBegin ();
  1472       iter != AddressBlockEnd ();
  1473       iter++)
  1474     {
  1475       (*iter)->Print (os, level+1);
  1476     }
  1477   os << prefix << "}" << std::endl;
  1478 }
  1479 
  1480 bool
  1481 PbbMessage::operator== (const PbbMessage &other) const
  1482 {
  1483   if (GetAddressLength () != other.GetAddressLength ())
  1484     {
  1485       return false;
  1486     }
  1487 
  1488   if (GetType () != other.GetType ())
  1489     {
  1490       return false;
  1491     }
  1492 
  1493   if (HasOriginatorAddress () != other.HasOriginatorAddress ())
  1494     {
  1495       return false;
  1496     }
  1497 
  1498   if (HasOriginatorAddress ())
  1499     {
  1500       if (GetOriginatorAddress () != other.GetOriginatorAddress ())
  1501         {
  1502           return false;
  1503         }
  1504     }
  1505 
  1506   if (HasHopLimit () != other.HasHopLimit ())
  1507     {
  1508       return false;
  1509     }
  1510 
  1511   if (HasHopLimit ())
  1512     {
  1513       if (GetHopLimit () != other.GetHopLimit ())
  1514         {
  1515           return false;
  1516         }
  1517     }
  1518 
  1519   if (HasHopCount () != other.HasHopCount ())
  1520     {
  1521       return false;
  1522     }
  1523 
  1524   if (HasHopCount ())
  1525     {
  1526       if (GetHopCount () != other.GetHopCount ())
  1527         {
  1528           return false;
  1529         }
  1530     }
  1531 
  1532   if (HasSequenceNumber () != other.HasSequenceNumber ())
  1533     {
  1534       return false;
  1535     }
  1536 
  1537   if (HasSequenceNumber ())
  1538     {
  1539       if (GetSequenceNumber () != other.GetSequenceNumber ())
  1540         {
  1541           return false;
  1542         }
  1543     }
  1544 
  1545   if (m_tlvList != other.m_tlvList)
  1546     {
  1547       return false;
  1548     }
  1549 
  1550   if (AddressBlockSize () != other.AddressBlockSize ())
  1551     {
  1552       return false;
  1553     }
  1554 
  1555   ConstAddressBlockIterator tai, oai;
  1556   for (tai = AddressBlockBegin (), oai = other.AddressBlockBegin ();
  1557       tai != AddressBlockEnd () && oai != other.AddressBlockEnd ();
  1558       tai++, oai++)
  1559     {
  1560       if (**tai != **oai)
  1561         {
  1562           return false;
  1563         }
  1564     }
  1565   return true;
  1566 }
  1567 
  1568 bool
  1569 PbbMessage::operator!= (const PbbMessage &other) const
  1570 {
  1571   return !(*this == other);
  1572 }
  1573 
  1574 /* End PbbMessage Class */
  1575 
  1576 PbbMessageIpv4::PbbMessageIpv4 ()
  1577 {
  1578 }
  1579 
  1580 PbbMessageIpv4::~PbbMessageIpv4 ()
  1581 {
  1582 }
  1583 
  1584 PbbAddressLength
  1585 PbbMessageIpv4::GetAddressLength (void) const
  1586 {
  1587   return IPV4;
  1588 }
  1589 
  1590 void
  1591 PbbMessageIpv4::SerializeOriginatorAddress (Buffer::Iterator &start) const
  1592 {
  1593   uint8_t buffer[GetAddressLength () + 1];
  1594   Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer);
  1595   start.Write (buffer, GetAddressLength () + 1);
  1596 }
  1597 
  1598 Address
  1599 PbbMessageIpv4::DeserializeOriginatorAddress (Buffer::Iterator &start) const
  1600 {
  1601   uint8_t buffer[GetAddressLength () + 1];
  1602   start.Read(buffer, GetAddressLength () + 1);
  1603   return Ipv4Address::Deserialize (buffer);
  1604 }
  1605 
  1606 void
  1607 PbbMessageIpv4::PrintOriginatorAddress (std::ostream &os) const
  1608 {
  1609   Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Print (os);
  1610 }
  1611 
  1612 Ptr<PbbAddressBlock>
  1613 PbbMessageIpv4::AddressBlockDeserialize (Buffer::Iterator &start) const
  1614 {
  1615   Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv4> ();
  1616   newab->Deserialize (start);
  1617   return newab;
  1618 }
  1619 
  1620 /* End PbbMessageIpv4 Class */
  1621 
  1622 PbbMessageIpv6::PbbMessageIpv6 ()
  1623 {
  1624 }
  1625 
  1626 PbbMessageIpv6::~PbbMessageIpv6 ()
  1627 {
  1628 }
  1629 
  1630 PbbAddressLength
  1631 PbbMessageIpv6::GetAddressLength (void) const
  1632 {
  1633   return IPV6;
  1634 }
  1635 
  1636 void
  1637 PbbMessageIpv6::SerializeOriginatorAddress (Buffer::Iterator &start) const
  1638 {
  1639   uint8_t buffer[GetAddressLength () + 1];
  1640   Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer);
  1641   start.Write (buffer, GetAddressLength () + 1);
  1642 }
  1643 
  1644 Address
  1645 PbbMessageIpv6::DeserializeOriginatorAddress (Buffer::Iterator &start) const
  1646 {
  1647   uint8_t buffer[GetAddressLength () + 1];
  1648   start.Read(buffer, GetAddressLength () + 1);
  1649   return Ipv6Address::Deserialize (buffer);
  1650 }
  1651 
  1652 void
  1653 PbbMessageIpv6::PrintOriginatorAddress (std::ostream &os) const
  1654 {
  1655   Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Print (os);
  1656 }
  1657 
  1658 Ptr<PbbAddressBlock>
  1659 PbbMessageIpv6::AddressBlockDeserialize (Buffer::Iterator &start) const
  1660 {
  1661   Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv6> ();
  1662   newab->Deserialize (start);
  1663   return newab;
  1664 }
  1665 
  1666 /* End PbbMessageIpv6 Class */
  1667 
  1668 PbbAddressBlock::PbbAddressBlock ()
  1669 {}
  1670 
  1671 PbbAddressBlock::~PbbAddressBlock ()
  1672 {}
  1673 
  1674 /* Manipulating the address block */
  1675 
  1676 PbbAddressBlock::AddressIterator
  1677 PbbAddressBlock::AddressBegin (void)
  1678 {
  1679   return m_addressList.begin();
  1680 }
  1681 
  1682 PbbAddressBlock::ConstAddressIterator
  1683 PbbAddressBlock::AddressBegin (void) const
  1684 {
  1685   return m_addressList.begin();
  1686 }
  1687 
  1688 PbbAddressBlock::AddressIterator
  1689 PbbAddressBlock::AddressEnd (void)
  1690 {
  1691   return m_addressList.end();
  1692 }
  1693 
  1694 PbbAddressBlock::ConstAddressIterator
  1695 PbbAddressBlock::AddressEnd (void) const
  1696 {
  1697   return m_addressList.end();
  1698 }
  1699 
  1700 int
  1701 PbbAddressBlock::AddressSize (void) const
  1702 {
  1703   return m_addressList.size();
  1704 }
  1705 
  1706 bool
  1707 PbbAddressBlock::AddressEmpty (void) const
  1708 {
  1709   return m_addressList.empty();
  1710 }
  1711 
  1712 Address
  1713 PbbAddressBlock::AddressFront (void) const
  1714 {
  1715   return m_addressList.front();
  1716 }
  1717 
  1718 Address
  1719 PbbAddressBlock::AddressBack (void) const
  1720 {
  1721   return m_addressList.back();
  1722 }
  1723 
  1724 void
  1725 PbbAddressBlock::AddressPushFront (Address tlv)
  1726 {
  1727   m_addressList.push_front(tlv);
  1728 }
  1729 
  1730 void
  1731 PbbAddressBlock::AddressPopFront (void)
  1732 {
  1733   m_addressList.pop_front();
  1734 }
  1735 
  1736 void
  1737 PbbAddressBlock::AddressPushBack (Address tlv)
  1738 {
  1739   m_addressList.push_back(tlv);
  1740 }
  1741 
  1742 void
  1743 PbbAddressBlock::AddressPopBack (void)
  1744 {
  1745   m_addressList.pop_back();
  1746 }
  1747 
  1748 PbbAddressBlock::AddressIterator
  1749 PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator position)
  1750 {
  1751   return m_addressList.erase(position);
  1752 }
  1753 
  1754 PbbAddressBlock::AddressIterator
  1755 PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator first,
  1756     PbbAddressBlock::AddressIterator last)
  1757 {
  1758   return m_addressList.erase(first, last);
  1759 }
  1760 
  1761   void
  1762 PbbAddressBlock::AddressClear (void)
  1763 {
  1764   return m_addressList.clear();
  1765 }
  1766 
  1767 /* Manipulating the prefix list */
  1768 
  1769 PbbAddressBlock::PrefixIterator
  1770 PbbAddressBlock::PrefixBegin (void)
  1771 {
  1772   return m_prefixList.begin ();
  1773 }
  1774 
  1775 PbbAddressBlock::ConstPrefixIterator
  1776 PbbAddressBlock::PrefixBegin (void) const
  1777 {
  1778   return m_prefixList.begin ();
  1779 }
  1780 
  1781 PbbAddressBlock::PrefixIterator
  1782 PbbAddressBlock::PrefixEnd (void)
  1783 {
  1784   return m_prefixList.end ();
  1785 }
  1786 
  1787 PbbAddressBlock::ConstPrefixIterator
  1788 PbbAddressBlock::PrefixEnd (void) const
  1789 {
  1790   return m_prefixList.end ();
  1791 }
  1792 
  1793 int
  1794 PbbAddressBlock::PrefixSize (void) const
  1795 {
  1796   return m_prefixList.size ();
  1797 }
  1798 
  1799 bool
  1800 PbbAddressBlock::PrefixEmpty (void) const
  1801 {
  1802   return m_prefixList.empty ();
  1803 }
  1804 
  1805 uint8_t
  1806 PbbAddressBlock::PrefixFront (void) const
  1807 {
  1808   return m_prefixList.front ();
  1809 }
  1810 
  1811 uint8_t
  1812 PbbAddressBlock::PrefixBack (void) const
  1813 {
  1814   return m_prefixList.back ();
  1815 }
  1816 
  1817 void
  1818 PbbAddressBlock::PrefixPushFront (uint8_t prefix)
  1819 {
  1820   m_prefixList.push_front (prefix);
  1821 }
  1822 
  1823 void
  1824 PbbAddressBlock::PrefixPopFront (void)
  1825 {
  1826   m_prefixList.pop_front ();
  1827 }
  1828 
  1829 void
  1830 PbbAddressBlock::PrefixPushBack (uint8_t prefix)
  1831 {
  1832   m_prefixList.push_back (prefix);
  1833 }
  1834 
  1835 void
  1836 PbbAddressBlock::PrefixPopBack (void)
  1837 {
  1838   m_prefixList.pop_back ();
  1839 }
  1840 
  1841 PbbAddressBlock::PrefixIterator
  1842 PbbAddressBlock::PrefixInsert (PbbAddressBlock::PrefixIterator position, const uint8_t value)
  1843 {
  1844   return m_prefixList.insert (position, value);
  1845 }
  1846 
  1847 PbbAddressBlock::PrefixIterator
  1848 PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator position)
  1849 {
  1850   return m_prefixList.erase (position);
  1851 }
  1852 
  1853 PbbAddressBlock::PrefixIterator
  1854 PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator first, PbbAddressBlock::PrefixIterator last)
  1855 {
  1856   return m_prefixList.erase (first, last);
  1857 }
  1858 
  1859 void
  1860 PbbAddressBlock::PrefixClear (void)
  1861 {
  1862   m_prefixList.clear ();
  1863 }
  1864 
  1865 /* Manipulating the TLV block */
  1866 
  1867 PbbAddressBlock::TlvIterator
  1868 PbbAddressBlock::TlvBegin (void)
  1869 {
  1870   return m_addressTlvList.Begin();
  1871 }
  1872 
  1873 PbbAddressBlock::ConstTlvIterator
  1874 PbbAddressBlock::TlvBegin (void) const
  1875 {
  1876   return m_addressTlvList.Begin();
  1877 }
  1878 
  1879 PbbAddressBlock::TlvIterator
  1880 PbbAddressBlock::TlvEnd (void)
  1881 {
  1882   return m_addressTlvList.End();
  1883 }
  1884 
  1885 PbbAddressBlock::ConstTlvIterator
  1886 PbbAddressBlock::TlvEnd (void) const
  1887 {
  1888   return m_addressTlvList.End();
  1889 }
  1890 
  1891 int
  1892 PbbAddressBlock::TlvSize (void) const
  1893 {
  1894   return m_addressTlvList.Size();
  1895 }
  1896 
  1897 bool
  1898 PbbAddressBlock::TlvEmpty (void) const
  1899 {
  1900   return m_addressTlvList.Empty();
  1901 }
  1902 
  1903 Ptr<PbbAddressTlv>
  1904 PbbAddressBlock::TlvFront (void)
  1905 {
  1906   return m_addressTlvList.Front();
  1907 }
  1908 
  1909 const Ptr<PbbAddressTlv>
  1910 PbbAddressBlock::TlvFront (void) const
  1911 {
  1912   return m_addressTlvList.Front();
  1913 }
  1914 
  1915 Ptr<PbbAddressTlv>
  1916 PbbAddressBlock::TlvBack (void)
  1917 {
  1918   return m_addressTlvList.Back();
  1919 }
  1920 
  1921 const Ptr<PbbAddressTlv>
  1922 PbbAddressBlock::TlvBack (void) const
  1923 {
  1924   return m_addressTlvList.Back();
  1925 }
  1926 
  1927 void
  1928 PbbAddressBlock::TlvPushFront (Ptr<PbbAddressTlv> tlv)
  1929 {
  1930   m_addressTlvList.PushFront(tlv);
  1931 }
  1932 
  1933 void
  1934 PbbAddressBlock::TlvPopFront (void)
  1935 {
  1936   m_addressTlvList.PopFront();
  1937 }
  1938 
  1939 void
  1940 PbbAddressBlock::TlvPushBack (Ptr<PbbAddressTlv> tlv)
  1941 {
  1942   m_addressTlvList.PushBack(tlv);
  1943 }
  1944 
  1945 void
  1946 PbbAddressBlock::TlvPopBack (void)
  1947 {
  1948   m_addressTlvList.PopBack();
  1949 }
  1950 
  1951 PbbAddressBlock::TlvIterator
  1952 PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator position)
  1953 {
  1954   return m_addressTlvList.Erase(position);
  1955 }
  1956 
  1957 PbbAddressBlock::TlvIterator
  1958 PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator first,
  1959     PbbAddressBlock::TlvIterator last)
  1960 {
  1961   return m_addressTlvList.Erase(first, last);
  1962 }
  1963 
  1964 void
  1965 PbbAddressBlock::TlvClear (void)
  1966 {
  1967   m_addressTlvList.Clear();
  1968 }
  1969 uint32_t
  1970 PbbAddressBlock::GetSerializedSize (void) const
  1971 {
  1972   /* num-addr + flags */
  1973   uint32_t size = 2;
  1974 
  1975   if (AddressSize () == 1)
  1976     {
  1977       size += GetAddressLength () + PrefixSize();
  1978     }
  1979   else if (AddressSize () > 0)
  1980     {
  1981       uint8_t head[GetAddressLength ()];
  1982       uint8_t headlen = 0;
  1983       uint8_t tail[GetAddressLength ()];
  1984       uint8_t taillen = 0;
  1985 
  1986       GetHeadTail (head, headlen, tail, taillen);
  1987 
  1988       if (headlen > 0)
  1989         {
  1990           size += 1 + headlen;
  1991         }
  1992 
  1993       if (taillen > 0)
  1994         {
  1995           size++;
  1996           if (!HasZeroTail (tail, taillen))
  1997             {
  1998               size += taillen;
  1999             }
  2000         }
  2001 
  2002       /* mid size */
  2003       size += (GetAddressLength () - headlen - taillen) * AddressSize ();
  2004 
  2005       size += PrefixSize ();
  2006     }
  2007 
  2008   size += m_addressTlvList.GetSerializedSize ();
  2009 
  2010   return size;
  2011 }
  2012 
  2013 void
  2014 PbbAddressBlock::Serialize (Buffer::Iterator &start) const
  2015 {
  2016   start.WriteU8 (AddressSize ());
  2017 
  2018   if (AddressSize () == 1)
  2019     {
  2020       start.WriteU8 (0);
  2021 
  2022       uint8_t buf[GetAddressLength ()];
  2023       SerializeAddress (buf, AddressBegin ());
  2024       start.Write (buf, GetAddressLength ());
  2025 
  2026       if (PrefixSize () == 1)
  2027         {
  2028           start.WriteU8 (PrefixFront ());
  2029         }
  2030     }
  2031   else if (AddressSize () > 0)
  2032     {
  2033       Buffer::Iterator bufref = start;
  2034       uint8_t flags = 0;
  2035       start.Next ();
  2036 
  2037       uint8_t head[GetAddressLength ()];
  2038       uint8_t tail[GetAddressLength ()];
  2039       uint8_t headlen = 0;
  2040       uint8_t taillen = 0;
  2041 
  2042       GetHeadTail (head, headlen, tail, taillen);
  2043 
  2044       if (headlen > 0)
  2045         {
  2046           flags |= AHAS_HEAD;
  2047           start.WriteU8 (headlen);
  2048           start.Write (head, headlen);
  2049         }
  2050 
  2051       if (taillen > 0)
  2052         {
  2053           start.WriteU8 (taillen);
  2054 
  2055           if (HasZeroTail (tail, taillen))
  2056             {
  2057               flags |= AHAS_ZERO_TAIL;
  2058             }
  2059           else
  2060             {
  2061               flags |= AHAS_FULL_TAIL;
  2062               start.Write (tail, taillen);
  2063             }
  2064         }
  2065 
  2066       if (headlen + taillen < GetAddressLength ())
  2067         {
  2068           uint8_t mid[GetAddressLength ()];
  2069           for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin ();
  2070               iter != AddressEnd ();
  2071               iter++)
  2072             {
  2073               SerializeAddress (mid, iter);
  2074               start.Write (mid + headlen, GetAddressLength () - headlen - taillen);
  2075             }
  2076         }
  2077 
  2078       flags |= GetPrefixFlags ();
  2079       bufref.WriteU8 (flags);
  2080 
  2081       for (ConstPrefixIterator iter = PrefixBegin ();
  2082           iter != PrefixEnd ();
  2083           iter++)
  2084         {
  2085           start.WriteU8 (*iter);
  2086         }
  2087     }
  2088   
  2089   m_addressTlvList.Serialize (start);
  2090 }
  2091 
  2092 void
  2093 PbbAddressBlock::Deserialize (Buffer::Iterator &start)
  2094 {
  2095   uint8_t numaddr = start.ReadU8 ();
  2096   uint8_t flags = start.ReadU8 ();
  2097 
  2098   if (numaddr > 0)
  2099     {
  2100       uint8_t headlen = 0;
  2101       uint8_t taillen = 0;
  2102       uint8_t addrtmp[GetAddressLength ()];
  2103       memset(addrtmp, 0, GetAddressLength ());
  2104 
  2105       if (flags & AHAS_HEAD)
  2106         {
  2107           headlen = start.ReadU8 ();
  2108           start.Read (addrtmp, headlen);
  2109         }
  2110 
  2111       if ((flags & AHAS_FULL_TAIL) ^ (flags & AHAS_ZERO_TAIL))
  2112         {
  2113           taillen = start.ReadU8 ();
  2114           
  2115           if (flags & AHAS_FULL_TAIL)
  2116             {
  2117               start.Read (addrtmp + GetAddressLength () - taillen, taillen);
  2118             }
  2119         }
  2120 
  2121       for (int i = 0; i < numaddr; i++)
  2122         {
  2123           start.Read (addrtmp + headlen, GetAddressLength () - headlen - taillen);
  2124           AddressPushBack (DeserializeAddress (addrtmp));
  2125         }
  2126 
  2127       if (flags & AHAS_SINGLE_PRE_LEN)
  2128         {
  2129           PrefixPushBack (start.ReadU8 ());
  2130         }
  2131       else if (flags & AHAS_MULTI_PRE_LEN)
  2132         {
  2133           for (int i = 0; i < numaddr; i++)
  2134             {
  2135               PrefixPushBack (start.ReadU8 ());
  2136             }
  2137         }
  2138     }
  2139 
  2140   m_addressTlvList.Deserialize (start);
  2141 }
  2142 
  2143 void
  2144 PbbAddressBlock::Print (std::ostream &os) const
  2145 {
  2146   Print (os, 0);
  2147 }
  2148 
  2149 void
  2150 PbbAddressBlock::Print (std::ostream &os, int level) const
  2151 {
  2152   std::string prefix = "";
  2153   for (int i = 0; i < level; i++)
  2154     {
  2155       prefix.append ("\t");
  2156     }
  2157 
  2158   os << prefix << "PbbAddressBlock {" << std::endl;
  2159   os << prefix << "\taddresses = " << std::endl;
  2160   for (ConstAddressIterator iter = AddressBegin ();
  2161       iter != AddressEnd ();
  2162       iter++)
  2163     {
  2164       os << prefix << "\t\t";
  2165       PrintAddress(os, iter);
  2166       os << std::endl;
  2167     }
  2168 
  2169   os << prefix << "\tprefixes = " << std::endl;
  2170   for (ConstPrefixIterator iter = PrefixBegin ();
  2171       iter != PrefixEnd ();
  2172       iter++)
  2173     {
  2174       os << prefix << "\t\t" << (int)(*iter) << std::endl;
  2175     }
  2176 
  2177   m_addressTlvList.Print (os, level+1);
  2178 }
  2179 
  2180 bool
  2181 PbbAddressBlock::operator== (const PbbAddressBlock &other) const
  2182 {
  2183   if (AddressSize () != other.AddressSize ())
  2184     {
  2185       return false;
  2186     }
  2187 
  2188   ConstAddressIterator tai, oai;
  2189   for (tai = AddressBegin (), oai = other.AddressBegin ();
  2190       tai != AddressEnd () && oai != other.AddressEnd ();
  2191       tai++, oai++)
  2192     {
  2193       if (*tai != *oai)
  2194         {
  2195           return false;
  2196         }
  2197     }
  2198 
  2199   if (PrefixSize () != other.PrefixSize ())
  2200     {
  2201       return false;
  2202     }
  2203 
  2204   ConstPrefixIterator tpi, opi;
  2205   for (tpi = PrefixBegin (), opi = other.PrefixBegin ();
  2206       tpi != PrefixEnd () && opi != other.PrefixEnd ();
  2207       tpi++, opi++)
  2208     {
  2209       if (*tpi != *opi)
  2210         {
  2211           return false;
  2212         }
  2213     }
  2214 
  2215   if (m_addressTlvList != other.m_addressTlvList)
  2216     {
  2217       return false;
  2218     }
  2219 
  2220   return true;
  2221 }
  2222 
  2223 bool
  2224 PbbAddressBlock::operator!= (const PbbAddressBlock &other) const
  2225 {
  2226   return !(*this == other);
  2227 }
  2228 
  2229 uint8_t
  2230 PbbAddressBlock::GetPrefixFlags (void) const
  2231 {
  2232   switch (PrefixSize ())
  2233     {
  2234       case 0:
  2235         return 0;
  2236         break;
  2237       case 1:
  2238         return AHAS_SINGLE_PRE_LEN;
  2239         break;
  2240       default:
  2241         return AHAS_MULTI_PRE_LEN;
  2242         break;
  2243     }
  2244 
  2245   /* Quiet compiler */
  2246   return 0;
  2247 }
  2248 
  2249 void
  2250 PbbAddressBlock::GetHeadTail (uint8_t *head, uint8_t &headlen,
  2251     uint8_t *tail, uint8_t &taillen) const
  2252 {
  2253   headlen = GetAddressLength ();
  2254   taillen = headlen;
  2255 
  2256   /* Temporary automatic buffers to store serialized addresses */
  2257   uint8_t * buflast = new uint8_t[GetAddressLength ()];
  2258   uint8_t * bufcur = new uint8_t[GetAddressLength ()];
  2259   uint8_t * tmp;
  2260 
  2261   SerializeAddress (buflast, AddressBegin ());
  2262 
  2263   /* Skip the first item */
  2264   for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin ()++;
  2265       iter != AddressEnd ();
  2266       iter++)
  2267     {
  2268       SerializeAddress (bufcur, iter);
  2269 
  2270       int i;
  2271       for (i = 0; i < headlen; i++)
  2272         {
  2273           if (buflast[i] != bufcur[i])
  2274             {
  2275               headlen = i;
  2276               break;
  2277             }
  2278         }
  2279 
  2280       /* If headlen == fulllen - 1, then tail is 0 */
  2281       if (headlen <= GetAddressLength () - 1)
  2282         {
  2283           for (i = GetAddressLength () - 1;
  2284               GetAddressLength () - 1 - i <= taillen && i > headlen;
  2285               i--)
  2286             {
  2287               if (buflast[i] != bufcur[i])
  2288                 {
  2289                   break;
  2290                 }
  2291             }
  2292           taillen = GetAddressLength () - 1 - i;
  2293         }
  2294       else if (headlen == 0)
  2295         {
  2296           taillen = 0;
  2297           break;
  2298         }
  2299 
  2300       tmp = buflast;
  2301       buflast = bufcur;
  2302       bufcur = tmp;
  2303     }
  2304 
  2305   memcpy(head, bufcur, headlen);
  2306   memcpy(tail, bufcur + (GetAddressLength () - taillen), taillen);
  2307 
  2308   delete[] buflast;
  2309   delete[] bufcur;
  2310 }
  2311 
  2312 bool
  2313 PbbAddressBlock::HasZeroTail (const uint8_t *tail, uint8_t taillen) const
  2314 {
  2315   int i;
  2316   for (i = 0; i < taillen; i++)
  2317     {
  2318       if (tail[i] != 0)
  2319         {
  2320           break;
  2321         }
  2322     }
  2323   return i == taillen;
  2324 }
  2325 
  2326 /* End PbbAddressBlock Class */
  2327 
  2328 PbbAddressBlockIpv4::PbbAddressBlockIpv4 ()
  2329 {
  2330 }
  2331 
  2332 PbbAddressBlockIpv4::~PbbAddressBlockIpv4 ()
  2333 {
  2334 }
  2335 
  2336 uint8_t
  2337 PbbAddressBlockIpv4::GetAddressLength (void) const
  2338 {
  2339   return 4;
  2340 }
  2341 
  2342 void
  2343 PbbAddressBlockIpv4::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const
  2344 {
  2345   Ipv4Address::ConvertFrom (*iter).Serialize (buffer);
  2346 }
  2347 
  2348 Address
  2349 PbbAddressBlockIpv4::DeserializeAddress (uint8_t *buffer) const
  2350 {
  2351   return Ipv4Address::Deserialize (buffer);
  2352 }
  2353 
  2354 void
  2355 PbbAddressBlockIpv4::PrintAddress (std::ostream &os, ConstAddressIterator iter) const
  2356 {
  2357   Ipv4Address::ConvertFrom (*iter).Print (os);
  2358 }
  2359 
  2360 /* End PbbAddressBlockIpv4 Class */
  2361 
  2362 PbbAddressBlockIpv6::PbbAddressBlockIpv6 ()
  2363 {
  2364 }
  2365 
  2366 PbbAddressBlockIpv6::~PbbAddressBlockIpv6 ()
  2367 {
  2368 }
  2369 
  2370 uint8_t
  2371 PbbAddressBlockIpv6::GetAddressLength (void) const
  2372 {
  2373   return 16;
  2374 }
  2375 
  2376 void
  2377 PbbAddressBlockIpv6::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const
  2378 {
  2379   Ipv6Address::ConvertFrom (*iter).Serialize (buffer);
  2380 }
  2381 
  2382 Address
  2383 PbbAddressBlockIpv6::DeserializeAddress (uint8_t *buffer) const
  2384 {
  2385   return Ipv6Address::Deserialize (buffer);
  2386 }
  2387 
  2388 void
  2389 PbbAddressBlockIpv6::PrintAddress (std::ostream &os, ConstAddressIterator iter) const
  2390 {
  2391   Ipv6Address::ConvertFrom (*iter).Print (os);
  2392 }
  2393 
  2394 /* End PbbAddressBlockIpv6 Class */
  2395 
  2396 PbbTlv::PbbTlv (void)
  2397 {
  2398   m_hasTypeExt = false;
  2399   m_hasIndexStart = false;
  2400   m_hasIndexStop = false;
  2401   m_isMultivalue = false;
  2402   m_hasValue = false;
  2403 }
  2404 
  2405 PbbTlv::~PbbTlv (void)
  2406 {
  2407   m_value.RemoveAtEnd (m_value.GetSize ());
  2408 }
  2409 
  2410 void
  2411 PbbTlv::SetType (uint8_t type)
  2412 {
  2413   m_type = type;
  2414 }
  2415 
  2416 uint8_t
  2417 PbbTlv::GetType (void) const
  2418 {
  2419   return m_type;
  2420 }
  2421 
  2422 void
  2423 PbbTlv::SetTypeExt (uint8_t typeExt)
  2424 {
  2425   m_typeExt = typeExt;
  2426   m_hasTypeExt = true;
  2427 }
  2428 
  2429 uint8_t
  2430 PbbTlv::GetTypeExt (void) const
  2431 {
  2432   NS_ASSERT (HasTypeExt ());
  2433   return m_typeExt;
  2434 }
  2435 
  2436 bool
  2437 PbbTlv::HasTypeExt (void) const
  2438 {
  2439   return m_hasTypeExt;
  2440 }
  2441 
  2442 void
  2443 PbbTlv::SetIndexStart (uint8_t index)
  2444 {
  2445   m_indexStart = index;
  2446   m_hasIndexStart = true;
  2447 }
  2448 
  2449 uint8_t
  2450 PbbTlv::GetIndexStart (void) const
  2451 {
  2452   NS_ASSERT (HasIndexStart ());
  2453   return m_indexStart;
  2454 }
  2455 
  2456 bool
  2457 PbbTlv::HasIndexStart (void) const
  2458 {
  2459   return m_hasIndexStart;
  2460 }
  2461 
  2462 void
  2463 PbbTlv::SetIndexStop (uint8_t index)
  2464 {
  2465   m_indexStop = index;
  2466   m_hasIndexStop = true;
  2467 }
  2468 
  2469 uint8_t
  2470 PbbTlv::GetIndexStop (void) const
  2471 {
  2472   NS_ASSERT (HasIndexStop ());
  2473   return m_indexStop;
  2474 }
  2475 
  2476 bool
  2477 PbbTlv::HasIndexStop (void) const
  2478 {
  2479   return m_hasIndexStop;
  2480 }
  2481 
  2482 void
  2483 PbbTlv::SetMultivalue (bool isMultivalue)
  2484 {
  2485   m_isMultivalue = isMultivalue;
  2486 }
  2487 
  2488 bool
  2489 PbbTlv::IsMultivalue (void) const
  2490 {
  2491   return m_isMultivalue;
  2492 }
  2493 
  2494 void
  2495 PbbTlv::SetValue (Buffer start)
  2496 {
  2497   m_hasValue = true;
  2498   m_value = start;
  2499 }
  2500 
  2501 void
  2502 PbbTlv::SetValue (const uint8_t * buffer, uint32_t size)
  2503 {
  2504   m_hasValue = true;
  2505   m_value.AddAtStart (size);
  2506   m_value.Begin ().Write (buffer, size);
  2507 }
  2508 
  2509 Buffer
  2510 PbbTlv::GetValue (void) const
  2511 {
  2512   NS_ASSERT (HasValue ());
  2513   return m_value;
  2514 }
  2515 
  2516 bool
  2517 PbbTlv::HasValue (void) const
  2518 {
  2519   return m_hasValue;
  2520 }
  2521 
  2522 uint32_t
  2523 PbbTlv::GetSerializedSize (void) const
  2524 {
  2525   /* type + flags */
  2526   uint32_t size = 2;
  2527 
  2528   if (HasTypeExt ())
  2529     {
  2530       size++;
  2531     }
  2532 
  2533   if (HasIndexStart ())
  2534     {
  2535       size++;
  2536     }
  2537 
  2538   if (HasIndexStop ())
  2539     {
  2540       size++;
  2541     }
  2542 
  2543   if (HasValue ())
  2544     {
  2545       if (GetValue ().GetSize () > 255)
  2546         {
  2547           size += 2;
  2548         } 
  2549       else 
  2550         {
  2551           size++;
  2552         }
  2553       size += GetValue ().GetSize ();
  2554     }
  2555 
  2556   return size;
  2557 }
  2558 
  2559 void
  2560 PbbTlv::Serialize (Buffer::Iterator &start) const
  2561 {
  2562   start.WriteU8 (GetType ());
  2563 
  2564   Buffer::Iterator bufref = start;
  2565   uint8_t flags = 0;
  2566   start.Next();
  2567 
  2568   if (HasTypeExt())
  2569     {
  2570       flags |= THAS_TYPE_EXT;
  2571       start.WriteU8 (GetTypeExt ());
  2572     }
  2573 
  2574   if (HasIndexStart ())
  2575     {
  2576       start.WriteU8 (GetIndexStart ());
  2577 
  2578       if (HasIndexStop ())
  2579         {
  2580           flags |= THAS_MULTI_INDEX;
  2581           start.WriteU8 (GetIndexStop ());
  2582         } 
  2583       else
  2584         {
  2585           flags |= THAS_SINGLE_INDEX;
  2586         }
  2587     }
  2588 
  2589   if (HasValue ()) 
  2590     {
  2591       flags |= THAS_VALUE;
  2592 
  2593       uint32_t size = GetValue ().GetSize ();
  2594       if (size > 255)
  2595         {
  2596           flags |= THAS_EXT_LEN;
  2597           start.WriteHtonU16 (size);
  2598         }
  2599       else
  2600         {
  2601           start.WriteU8 (size);
  2602         }
  2603 
  2604       if (IsMultivalue ())
  2605         {
  2606           flags |= TIS_MULTIVALUE;
  2607         }
  2608 
  2609       start.Write(GetValue ().Begin (), GetValue ().End ());
  2610     }
  2611 
  2612   bufref.WriteU8 (flags);
  2613 }
  2614 
  2615 void
  2616 PbbTlv::Deserialize (Buffer::Iterator &start)
  2617 {
  2618   SetType (start.ReadU8 ());
  2619 
  2620   uint8_t flags = start.ReadU8 ();
  2621 
  2622   if (flags & THAS_TYPE_EXT)
  2623     {
  2624       SetTypeExt (start.ReadU8 ());
  2625     }
  2626 
  2627   if (flags & THAS_MULTI_INDEX)
  2628     {
  2629       SetIndexStart (start.ReadU8 ());
  2630       SetIndexStop (start.ReadU8 ());
  2631     }
  2632   else if (flags & THAS_SINGLE_INDEX)
  2633     {
  2634       SetIndexStart (start.ReadU8 ());
  2635     }
  2636 
  2637   if (flags & THAS_VALUE)
  2638     {
  2639       uint16_t len = 0;
  2640 
  2641       if (flags & THAS_EXT_LEN)
  2642         {
  2643           len = start.ReadNtohU16 ();
  2644         }
  2645       else
  2646         {
  2647           len = start.ReadU8 ();
  2648         }
  2649 
  2650       m_value.AddAtStart (len);
  2651 
  2652       Buffer::Iterator valueStart = start;
  2653       start.Next (len);
  2654       m_value.Begin ().Write (valueStart, start);
  2655       m_hasValue = true;
  2656     }
  2657 }
  2658 
  2659 void
  2660 PbbTlv::Print (std::ostream &os) const
  2661 {
  2662   Print (os, 0);
  2663 }
  2664 
  2665 void
  2666 PbbTlv::Print (std::ostream &os, int level) const
  2667 {
  2668   std::string prefix = "";
  2669   for (int i = 0; i < level; i++)
  2670     {
  2671       prefix.append ("\t");
  2672     }
  2673 
  2674   os << prefix << "PbbTlv {" << std::endl;
  2675   os << prefix << "\ttype = " << (int)GetType () << std::endl;
  2676 
  2677   if (HasTypeExt ())
  2678     {
  2679       os << prefix << "\ttypeext = " << (int)GetTypeExt () << std::endl;
  2680     }
  2681 
  2682   if (HasIndexStart ())
  2683     {
  2684       os << prefix << "\tindexStart = " << (int)GetIndexStart () << std::endl;
  2685     }
  2686 
  2687   if (HasIndexStop ())
  2688     {
  2689       os << prefix << "\tindexStop = " << (int)GetIndexStop () << std::endl;
  2690     }
  2691 
  2692   os << prefix << "\tisMultivalue = " << IsMultivalue () << std::endl;
  2693 
  2694   if (HasValue ())
  2695     {
  2696       os << prefix << "\thas value; size = " << GetValue (). GetSize () << std::endl;
  2697     }
  2698 
  2699   os << prefix << "}" << std::endl;
  2700 }
  2701 
  2702 bool
  2703 PbbTlv::operator== (const PbbTlv &other) const
  2704 {
  2705   if (GetType () != other.GetType ())
  2706     {
  2707       return false;
  2708     }
  2709 
  2710   if (HasTypeExt () != other.HasTypeExt ())
  2711     {
  2712       return false;
  2713     }
  2714 
  2715   if (HasTypeExt ())
  2716     {
  2717       if (GetTypeExt () != other.GetTypeExt ())
  2718         {
  2719           return false;
  2720         }
  2721     }
  2722 
  2723   if (HasValue () != other.HasValue ())
  2724     {
  2725       return false;
  2726     }
  2727 
  2728   if (HasValue ())
  2729     {
  2730       Buffer tv = GetValue ();
  2731       Buffer ov = other.GetValue ();
  2732       if (tv.GetSize () != ov.GetSize ())
  2733         {
  2734           return false;
  2735         }
  2736 
  2737       /* The docs say I probably shouldn't use Buffer::PeekData, but I think it
  2738        * is justified in this case. */
  2739       if (memcmp (tv.PeekData (), ov.PeekData (), tv.GetSize ()) != 0)
  2740         {
  2741           return false;
  2742         }
  2743     }
  2744   return true;
  2745 }
  2746 
  2747 bool
  2748 PbbTlv::operator!= (const PbbTlv &other) const
  2749 {
  2750   return !(*this == other);
  2751 }
  2752 
  2753 /* End PbbTlv Class */
  2754 
  2755 void 
  2756 PbbAddressTlv::SetIndexStart (uint8_t index)
  2757 {
  2758   PbbTlv::SetIndexStart (index);
  2759 }
  2760 
  2761 uint8_t
  2762 PbbAddressTlv::GetIndexStart (void) const
  2763 {
  2764   return PbbTlv::GetIndexStart ();
  2765 }
  2766 
  2767 bool
  2768 PbbAddressTlv::HasIndexStart (void) const
  2769 {
  2770   return PbbTlv::HasIndexStart ();
  2771 }
  2772 
  2773 void 
  2774 PbbAddressTlv::SetIndexStop (uint8_t index)
  2775 {
  2776   PbbTlv::SetIndexStop (index);
  2777 }
  2778 
  2779 uint8_t
  2780 PbbAddressTlv::GetIndexStop (void) const
  2781 {
  2782   return PbbTlv::GetIndexStop ();
  2783 }
  2784 
  2785 bool
  2786 PbbAddressTlv::HasIndexStop (void) const
  2787 {
  2788   return PbbTlv::HasIndexStop ();
  2789 }
  2790 
  2791 void
  2792 PbbAddressTlv::SetMultivalue (bool isMultivalue)
  2793 {
  2794   PbbTlv::SetMultivalue (isMultivalue);
  2795 }
  2796 
  2797 bool
  2798 PbbAddressTlv::IsMultivalue (void) const
  2799 {
  2800   return PbbTlv::IsMultivalue ();
  2801 }
  2802 
  2803 } /* namespace ns3 */