diff --git a/src/node/packetbb.cc b/src/node/packetbb.cc new file mode 100644 index 000000000..4eeb13356 --- /dev/null +++ b/src/node/packetbb.cc @@ -0,0 +1,2782 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* vim: set ts=2 sw=2 sta expandtab ai si cin: */ +/* + * Copyright (c) 2009 Drexel University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Tom Wambold + */ +/* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network + * (MANET) Packet/PbbMessage Format + * See: http://tools.ietf.org/html/rfc5444 for details */ + +#include "ns3/ipv4-address.h" +#include "ns3/ipv6-address.h" +#include "ns3/assert.h" + +#include "packetbb.h" + +static const uint8_t VERSION = 0; +/* Packet flags */ +static const uint8_t PHAS_SEQ_NUM = 0x8; +static const uint8_t PHAS_TLV = 0x4; + +/* PbbMessage flags */ +static const uint8_t MHAS_ORIG = 0x80; +static const uint8_t MHAS_HOP_LIMIT = 0x40; +static const uint8_t MHAS_HOP_COUNT = 0x20; +static const uint8_t MHAS_SEQ_NUM = 0x10; + +/* Address block flags */ +static const uint8_t AHAS_HEAD = 0x80; +static const uint8_t AHAS_FULL_TAIL = 0x40; +static const uint8_t AHAS_ZERO_TAIL = 0x20; +static const uint8_t AHAS_SINGLE_PRE_LEN = 0x10; +static const uint8_t AHAS_MULTI_PRE_LEN = 0x08; + +/* TLV Flags */ +static const uint8_t THAS_TYPE_EXT = 0x80; +static const uint8_t THAS_SINGLE_INDEX = 0x40; +static const uint8_t THAS_MULTI_INDEX = 0x20; +static const uint8_t THAS_VALUE = 0x10; +static const uint8_t THAS_EXT_LEN = 0x08; +static const uint8_t TIS_MULTIVALUE = 0x04; + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (PbbPacket); + +PbbTlvBlock::Iterator +PbbTlvBlock::Begin (void) +{ + return m_tlvList.begin (); +} + +PbbTlvBlock::ConstIterator +PbbTlvBlock::Begin (void) const +{ + return m_tlvList.begin (); +} + +PbbTlvBlock::Iterator +PbbTlvBlock::End (void) +{ + return m_tlvList.end (); +} + +PbbTlvBlock::ConstIterator +PbbTlvBlock::End (void) const +{ + return m_tlvList.end (); +} + +int +PbbTlvBlock::Size (void) const +{ + return m_tlvList.size (); +} + +bool +PbbTlvBlock::Empty (void) const +{ + return m_tlvList.empty (); +} + +Ptr +PbbTlvBlock::Front (void) const +{ + return m_tlvList.front (); +} + +Ptr +PbbTlvBlock::Back (void) const +{ + return m_tlvList.back (); +} + +void +PbbTlvBlock::PushFront (Ptr tlv) +{ + m_tlvList.push_front (tlv); +} + +void +PbbTlvBlock::PopFront (void) +{ + m_tlvList.pop_front (); +} + +void +PbbTlvBlock::PushBack (Ptr tlv) +{ + m_tlvList.push_back (tlv); +} + +void +PbbTlvBlock::PopBack (void) +{ + m_tlvList.pop_back (); +} + +PbbTlvBlock::Iterator +PbbTlvBlock::Insert (PbbTlvBlock::Iterator position, const Ptr tlv) +{ + return m_tlvList.insert (position, tlv); +} + +PbbTlvBlock::Iterator +PbbTlvBlock::Erase (PbbTlvBlock::Iterator position) +{ + return m_tlvList.erase (position); +} + +PbbTlvBlock::Iterator +PbbTlvBlock::Erase (PbbTlvBlock::Iterator first, PbbTlvBlock::Iterator last) +{ + return m_tlvList.erase (first, last); +} + +void +PbbTlvBlock::Clear (void) +{ + m_tlvList.clear (); +} + +uint32_t +PbbTlvBlock::GetSerializedSize (void) const +{ + /* tlv size */ + uint32_t size = 2; + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + size += (*iter)->GetSerializedSize (); + } + return size; +} + +void +PbbTlvBlock::Serialize (Buffer::Iterator &start) const +{ + if (Empty ()) + { + start.WriteHtonU16 (0); + return; + } + + /* We need to write the size of the TLV block in front, so save its + * position. */ + Buffer::Iterator tlvsize = start; + start.Next (2); + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + (*iter)->Serialize (start); + } + /* - 2 to not include the size field */ + uint16_t size = start.GetDistanceFrom (tlvsize) - 2; + tlvsize.WriteHtonU16 (size); +} + +void +PbbTlvBlock::Deserialize (Buffer::Iterator &start) +{ + uint16_t size = start.ReadNtohU16 (); + + Buffer::Iterator tlvstart = start; + if (size > 0) + { + while (start.GetDistanceFrom (tlvstart) < size) + { + Ptr newtlv = Create (); + newtlv->Deserialize (start); + PushBack (newtlv); + } + } +} + +void +PbbTlvBlock::Print (std::ostream &os) const +{ + Print (os, 0); +} + +void +PbbTlvBlock::Print (std::ostream &os, int level) const +{ + std::string prefix = ""; + for (int i = 0; i < level; i++) + { + prefix.append("\t"); + } + + os << prefix << "TLV Block {" << std::endl; + os << prefix << "\tsize = " << Size () << std::endl; + os << prefix << "\tmembers [" << std::endl; + + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + (*iter)->Print (os, level+2); + } + + os << prefix << "\t]" << std::endl; + os << prefix << "}" << std::endl; +} + +bool +PbbTlvBlock::operator== (const PbbTlvBlock &other) const +{ + if (Size () != other.Size ()) + { + return false; + } + + ConstIterator ti, oi; + for (ti = Begin (), oi = other.Begin (); + ti != End () && oi != other.End (); + ti++, oi++) + { + if (**ti != **oi) + { + return false; + } + } + return true; +} + +bool +PbbTlvBlock::operator!= (const PbbTlvBlock &other) const +{ + return !(*this == other); +} + +/* End PbbTlvBlock class */ + +PbbAddressTlvBlock::Iterator +PbbAddressTlvBlock::Begin (void) +{ + return m_tlvList.begin (); +} + +PbbAddressTlvBlock::ConstIterator +PbbAddressTlvBlock::Begin (void) const +{ + return m_tlvList.begin (); +} + +PbbAddressTlvBlock::Iterator +PbbAddressTlvBlock::End (void) +{ + return m_tlvList.end (); +} + +PbbAddressTlvBlock::ConstIterator +PbbAddressTlvBlock::End (void) const +{ + return m_tlvList.end (); +} + +int +PbbAddressTlvBlock::Size (void) const +{ + return m_tlvList.size (); +} + +bool +PbbAddressTlvBlock::Empty (void) const +{ + return m_tlvList.empty (); +} + +Ptr +PbbAddressTlvBlock::Front (void) const +{ + return m_tlvList.front (); +} + +Ptr +PbbAddressTlvBlock::Back (void) const +{ + return m_tlvList.back (); +} + +void +PbbAddressTlvBlock::PushFront (Ptr tlv) +{ + m_tlvList.push_front (tlv); +} + +void +PbbAddressTlvBlock::PopFront (void) +{ + m_tlvList.pop_front (); +} + +void +PbbAddressTlvBlock::PushBack (Ptr tlv) +{ + m_tlvList.push_back (tlv); +} + +void +PbbAddressTlvBlock::PopBack (void) +{ + m_tlvList.pop_back (); +} + +PbbAddressTlvBlock::Iterator +PbbAddressTlvBlock::Insert (PbbAddressTlvBlock::Iterator position, const Ptr tlv) +{ + return m_tlvList.insert (position, tlv); +} + +PbbAddressTlvBlock::Iterator +PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator position) +{ + return m_tlvList.erase (position); +} + +PbbAddressTlvBlock::Iterator +PbbAddressTlvBlock::Erase (PbbAddressTlvBlock::Iterator first, PbbAddressTlvBlock::Iterator last) +{ + return m_tlvList.erase (first, last); +} + +void +PbbAddressTlvBlock::Clear (void) +{ + m_tlvList.clear (); +} + +uint32_t +PbbAddressTlvBlock::GetSerializedSize (void) const +{ + /* tlv size */ + uint32_t size = 2; + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + size += (*iter)->GetSerializedSize (); + } + return size; +} + +void +PbbAddressTlvBlock::Serialize (Buffer::Iterator &start) const +{ + if (Empty ()) + { + start.WriteHtonU16 (0); + return; + } + + /* We need to write the size of the TLV block in front, so save its + * position. */ + Buffer::Iterator tlvsize = start; + start.Next (2); + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + (*iter)->Serialize (start); + } + /* - 2 to not include the size field */ + uint16_t size = start.GetDistanceFrom (tlvsize) - 2; + tlvsize.WriteHtonU16 (size); +} + +void +PbbAddressTlvBlock::Deserialize (Buffer::Iterator &start) +{ + uint16_t size = start.ReadNtohU16 (); + + Buffer::Iterator tlvstart = start; + if (size > 0) + { + while (start.GetDistanceFrom (tlvstart) < size) + { + Ptr newtlv = Create (); + newtlv->Deserialize (start); + PushBack (newtlv); + } + } +} + +void +PbbAddressTlvBlock::Print (std::ostream &os) const +{ + Print (os, 0); +} + +void +PbbAddressTlvBlock::Print (std::ostream &os, int level) const +{ + std::string prefix = ""; + for (int i = 0; i < level; i++) + { + prefix.append("\t"); + } + + os << prefix << "TLV Block {" << std::endl; + os << prefix << "\tsize = " << Size () << std::endl; + os << prefix << "\tmembers [" << std::endl; + + for (ConstIterator iter = Begin (); iter != End (); iter++) + { + (*iter)->Print (os, level+2); + } + + os << prefix << "\t]" << std::endl; + os << prefix << "}" << std::endl; +} + +bool +PbbAddressTlvBlock::operator== (const PbbAddressTlvBlock &other) const +{ + if (Size () != other.Size ()) + { + return false; + } + + ConstIterator it, ot; + for (it = Begin (), ot = other.Begin (); + it != End () && ot != other.End (); + it++, ot++) + { + if (**it != **ot) + { + return false; + } + } + return true; +} + +bool +PbbAddressTlvBlock::operator!= (const PbbAddressTlvBlock &other) const +{ + return !(*this == other); +} + + +/* End PbbAddressTlvBlock Class */ + +PbbPacket::PbbPacket (void) +{ + m_refCount = 1; + m_version = VERSION; + m_hasseqnum = false; +} + +uint8_t +PbbPacket::GetVersion (void) const +{ + return m_version; +} + +void +PbbPacket::SetSequenceNumber (uint16_t number) +{ + m_seqnum = number; + m_hasseqnum = true; +} + +uint16_t +PbbPacket::GetSequenceNumber (void) const +{ + NS_ASSERT (HasSequenceNumber ()); + return m_seqnum; +} + +bool +PbbPacket::HasSequenceNumber (void) const +{ + return m_hasseqnum; +} + +/* Manipulating Packet TLVs */ + +PbbPacket::TlvIterator +PbbPacket::TlvBegin (void) +{ + return m_tlvList.Begin (); +} + +PbbPacket::ConstTlvIterator +PbbPacket::TlvBegin (void) const +{ + return m_tlvList.Begin (); +} + +PbbPacket::TlvIterator +PbbPacket::TlvEnd (void) +{ + return m_tlvList.End (); +} + +PbbPacket::ConstTlvIterator +PbbPacket::TlvEnd (void) const +{ + return m_tlvList.End (); +} + +int +PbbPacket::TlvSize (void) const +{ + return m_tlvList.Size (); +} + +bool +PbbPacket::TlvEmpty (void) const +{ + return m_tlvList.Empty (); +} + +Ptr +PbbPacket::TlvFront (void) +{ + return m_tlvList.Front (); +} + +const Ptr +PbbPacket::TlvFront (void) const +{ + return m_tlvList.Front (); +} + +Ptr +PbbPacket::TlvBack (void) +{ + return m_tlvList.Back (); +} + +const Ptr +PbbPacket::TlvBack (void) const +{ + return m_tlvList.Back (); +} + +void +PbbPacket::TlvPushFront (Ptr tlv) +{ + m_tlvList.PushFront (tlv); +} + +void +PbbPacket::TlvPopFront (void) +{ + m_tlvList.PopFront (); +} + +void +PbbPacket::TlvPushBack (Ptr tlv) +{ + m_tlvList.PushBack (tlv); +} + +void +PbbPacket::TlvPopBack (void) +{ + m_tlvList.PopBack (); +} + +PbbPacket::TlvIterator +PbbPacket::Erase (PbbPacket::TlvIterator position) +{ + return m_tlvList.Erase (position); +} + +PbbPacket::TlvIterator +PbbPacket::Erase (PbbPacket::TlvIterator first, PbbPacket::TlvIterator last) +{ + return m_tlvList.Erase (first, last); +} + +void +PbbPacket::TlvClear (void) +{ + m_tlvList.Clear (); +} + +/* Manipulating Packet Messages */ + +PbbPacket::MessageIterator +PbbPacket::MessageBegin (void) +{ + return m_messageList.begin (); +} + +PbbPacket::ConstMessageIterator +PbbPacket::MessageBegin (void) const +{ + return m_messageList.begin (); +} + +PbbPacket::MessageIterator +PbbPacket::MessageEnd (void) +{ + return m_messageList.end (); +} + +PbbPacket::ConstMessageIterator +PbbPacket::MessageEnd (void) const +{ + return m_messageList.end (); +} + +int +PbbPacket::MessageSize (void) const +{ + return m_messageList.size (); +} + +bool +PbbPacket::MessageEmpty (void) const +{ + return m_messageList.empty (); +} + +Ptr +PbbPacket::MessageFront (void) +{ + return m_messageList.front (); +} + +const Ptr +PbbPacket::MessageFront (void) const +{ + return m_messageList.front (); +} + +Ptr +PbbPacket::MessageBack (void) +{ + return m_messageList.back (); +} + +const Ptr +PbbPacket::MessageBack (void) const +{ + return m_messageList.back (); +} + +void +PbbPacket::MessagePushFront (Ptr tlv) +{ + m_messageList.push_front (tlv); +} + +void +PbbPacket::MessagePopFront (void) +{ + m_messageList.pop_front (); +} + +void +PbbPacket::MessagePushBack (Ptr tlv) +{ + m_messageList.push_back (tlv); +} + +void +PbbPacket::MessagePopBack (void) +{ + m_messageList.pop_back (); +} + +PbbPacket::MessageIterator +PbbPacket::Erase (PbbPacket::MessageIterator position) +{ + return m_messageList.erase (position); +} + +PbbPacket::MessageIterator +PbbPacket::Erase (PbbPacket::MessageIterator first, + PbbPacket::MessageIterator last) +{ + return m_messageList.erase (first, last); +} + +void +PbbPacket::MessageClear (void) +{ + m_messageList.clear (); +} + +void +PbbPacket::Ref (void) const +{ + m_refCount++; +} + +void +PbbPacket::Unref (void) const +{ + m_refCount--; + if (m_refCount == 0) + { + delete this; + } +} + +TypeId +PbbPacket::GetTypeId (void) +{ + static TypeId tid = TypeId ("PbbPacket") + .SetParent
() + .AddConstructor () + ; + return tid; +} + +TypeId +PbbPacket::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +PbbPacket::GetSerializedSize (void) const +{ + /* Version number + flags */ + uint32_t size = 1; + + if (HasSequenceNumber()) + { + size += 2; + } + + if (!TlvEmpty ()) + { + size += m_tlvList.GetSerializedSize (); + } + + for (ConstMessageIterator iter = MessageBegin (); + iter != MessageEnd (); + iter++) + { + size += (*iter)->GetSerializedSize (); + } + + return size; +} + +void +PbbPacket::Serialize (Buffer::Iterator start) const +{ + /* We remember the start, so we can write the flags after we check for a + * sequence number and TLV. */ + Buffer::Iterator bufref = start; + start.Next (); + + uint8_t flags = VERSION; + /* Make room for 4 bit flags */ + flags <<= 4; + + if (HasSequenceNumber ()) + { + flags |= PHAS_SEQ_NUM; + start.WriteHtonU16 (GetSequenceNumber ()); + } + + if (!TlvEmpty ()) + { + flags |= PHAS_TLV; + m_tlvList.Serialize (start); + } + + bufref.WriteU8(flags); + + for (ConstMessageIterator iter = MessageBegin (); + iter != MessageEnd (); + iter++) + { + (*iter)->Serialize (start); + } +} + +uint32_t +PbbPacket::Deserialize (Buffer::Iterator start) +{ + Buffer::Iterator begin = start; + + uint8_t flags = start.ReadU8 (); + + if (flags & PHAS_SEQ_NUM) + { + SetSequenceNumber (start.ReadNtohU16 ()); + } + + if (flags & PHAS_TLV) + { + m_tlvList.Deserialize (start); + } + + while (!start.IsEnd()) + { + Ptr newmsg = PbbMessage::DeserializeMessage (start); + if (newmsg == 0) + { + return start.GetDistanceFrom (begin); + } + MessagePushBack (newmsg); + } + + flags >>= 4; + m_version = flags; + + return start.GetDistanceFrom (begin); +} + +void +PbbPacket::Print (std::ostream &os) const +{ + os << "PbbPacket {" << std::endl; + + if (HasSequenceNumber ()) + { + os << "\tsequence number = " << GetSequenceNumber (); + } + + os << std::endl; + + m_tlvList.Print (os, 1); + + for (ConstMessageIterator iter = MessageBegin (); + iter != MessageEnd (); + iter++) + { + (*iter)->Print (os, 1); + } + + os << "}" << std::endl; +} + +bool +PbbPacket::operator== (const PbbPacket &other) const +{ + if (GetVersion () != other.GetVersion ()) + { + return false; + } + + if (HasSequenceNumber () != other.HasSequenceNumber ()) + { + return false; + } + + if (HasSequenceNumber ()) + { + if (GetSequenceNumber () != other.GetSequenceNumber ()) + return false; + } + + if (m_tlvList != other.m_tlvList) + { + return false; + } + + if (MessageSize () != other.MessageSize ()) + { + return false; + } + + ConstMessageIterator tmi, omi; + for (tmi = MessageBegin (), omi = other.MessageBegin (); + tmi != MessageEnd () && omi != other.MessageEnd (); + tmi++, omi++) + { + if (**tmi != **omi) + { + return false; + } + } + return true; +} + +bool +PbbPacket::operator!= (const PbbPacket &other) const +{ + return !(*this == other); +} + +/* End PbbPacket class */ + +PbbMessage::PbbMessage (void) +{ + m_refCount = 1; + /* Default to IPv4 */ + m_addrSize = IPV4; + m_hasOriginatorAddress = false; + m_hasHopLimit = false; + m_hasHopCount = false; + m_hasSequenceNumber = false; +} + +void +PbbMessage::SetType (uint8_t type) +{ + m_type = type; +} + +uint8_t +PbbMessage::GetType (void) const +{ + return m_type; +} + +PbbAddressLength +PbbMessage::GetAddressLength (void) const +{ + return m_addrSize; +} + +void +PbbMessage::SetOriginatorAddress (Address address) +{ + m_originatorAddress = address; + m_hasOriginatorAddress = true; +} + +Address +PbbMessage::GetOriginatorAddress (void) const +{ + NS_ASSERT (HasOriginatorAddress ()); + return m_originatorAddress; +} + +bool +PbbMessage::HasOriginatorAddress (void) const +{ + return m_hasOriginatorAddress; +} + +void +PbbMessage::SetHopLimit (uint8_t hopLimit) +{ + m_hopLimit = hopLimit; + m_hasHopLimit = true; +} + +uint8_t +PbbMessage::GetHopLimit (void) const +{ + NS_ASSERT (HasHopLimit ()); + return m_hopLimit; +} + +bool +PbbMessage::HasHopLimit (void) const +{ + return m_hasHopLimit; +} + +void +PbbMessage::SetHopCount (uint8_t hopCount) +{ + m_hopCount = hopCount; + m_hasHopCount = true; +} + +uint8_t +PbbMessage::GetHopCount (void) const +{ + NS_ASSERT (HasHopCount ()); + return m_hopCount; +} + +bool +PbbMessage::HasHopCount (void) const +{ + return m_hasHopCount; +} + +void +PbbMessage::SetSequenceNumber (uint16_t sequenceNumber) +{ + m_sequenceNumber = sequenceNumber; + m_hasSequenceNumber = true; +} + +uint16_t +PbbMessage::GetSequenceNumber (void) const +{ + NS_ASSERT (HasSequenceNumber ()); + return m_sequenceNumber; +} + +bool +PbbMessage::HasSequenceNumber (void) const +{ + return m_hasSequenceNumber; +} + +/* Manipulating PbbMessage TLVs */ + +PbbMessage::TlvIterator +PbbMessage::TlvBegin (void) +{ + return m_tlvList.Begin(); +} + +PbbMessage::ConstTlvIterator +PbbMessage::TlvBegin (void) const +{ + return m_tlvList.Begin(); +} + +PbbMessage::TlvIterator +PbbMessage::TlvEnd (void) +{ + return m_tlvList.End(); +} + +PbbMessage::ConstTlvIterator +PbbMessage::TlvEnd (void) const +{ + return m_tlvList.End(); +} + +int +PbbMessage::TlvSize (void) const +{ + return m_tlvList.Size(); +} + +bool +PbbMessage::TlvEmpty (void) const +{ + return m_tlvList.Empty(); +} + +Ptr +PbbMessage::TlvFront (void) +{ + return m_tlvList.Front(); +} + +const Ptr +PbbMessage::TlvFront (void) const +{ + return m_tlvList.Front(); +} + +Ptr +PbbMessage::TlvBack (void) +{ + return m_tlvList.Back(); +} + +const Ptr +PbbMessage::TlvBack (void) const +{ + return m_tlvList.Back(); +} + +void +PbbMessage::TlvPushFront (Ptr tlv) +{ + m_tlvList.PushFront(tlv); +} + +void +PbbMessage::TlvPopFront (void) +{ + m_tlvList.PopFront(); +} + +void +PbbMessage::TlvPushBack (Ptr tlv) +{ + m_tlvList.PushBack(tlv); +} + +void +PbbMessage::TlvPopBack (void) +{ + m_tlvList.PopBack(); +} + +PbbMessage::TlvIterator +PbbMessage::TlvErase (PbbMessage::TlvIterator position) +{ + return m_tlvList.Erase(position); +} + +PbbMessage::TlvIterator +PbbMessage::TlvErase (PbbMessage::TlvIterator first, PbbMessage::TlvIterator last) +{ + return m_tlvList.Erase(first, last); +} + +void +PbbMessage::TlvClear (void) +{ + return m_tlvList.Clear(); +} + +/* Manipulating Address Block and Address TLV pairs */ + +PbbMessage::AddressBlockIterator +PbbMessage::AddressBlockBegin (void) +{ + return m_addressBlockList.begin(); +} + +PbbMessage::ConstAddressBlockIterator +PbbMessage::AddressBlockBegin (void) const +{ + return m_addressBlockList.begin(); +} + +PbbMessage::AddressBlockIterator +PbbMessage::AddressBlockEnd (void) +{ + return m_addressBlockList.end(); +} + +PbbMessage::ConstAddressBlockIterator +PbbMessage::AddressBlockEnd (void) const +{ + return m_addressBlockList.end(); +} + +int +PbbMessage::AddressBlockSize (void) const +{ + return m_addressBlockList.size(); +} + +bool +PbbMessage::AddressBlockEmpty (void) const +{ + return m_addressBlockList.empty(); +} + +Ptr +PbbMessage::AddressBlockFront (void) +{ + return m_addressBlockList.front(); +} + +const Ptr +PbbMessage::AddressBlockFront (void) const +{ + return m_addressBlockList.front(); +} + +Ptr +PbbMessage::AddressBlockBack (void) +{ + return m_addressBlockList.back(); +} + +const Ptr +PbbMessage::AddressBlockBack (void) const +{ + return m_addressBlockList.back(); +} + +void +PbbMessage::AddressBlockPushFront (Ptr tlv) +{ + m_addressBlockList.push_front(tlv); +} + +void +PbbMessage::AddressBlockPopFront (void) +{ + m_addressBlockList.pop_front(); +} + +void +PbbMessage::AddressBlockPushBack (Ptr tlv) +{ + m_addressBlockList.push_back(tlv); +} + +void +PbbMessage::AddressBlockPopBack (void) +{ + m_addressBlockList.pop_back(); +} + +PbbMessage::AddressBlockIterator +PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator position) +{ + return m_addressBlockList.erase(position); +} + +PbbMessage::AddressBlockIterator +PbbMessage::AddressBlockErase (PbbMessage::AddressBlockIterator first, + PbbMessage::AddressBlockIterator last) +{ + return m_addressBlockList.erase(first, last); +} + +void +PbbMessage::AddressBlockClear (void) +{ + return m_addressBlockList.clear(); +} + +void +PbbMessage::Ref (void) const +{ + m_refCount++; +} + +void +PbbMessage::Unref (void) const +{ + m_refCount--; + if (m_refCount == 0) + { + delete this; + } +} + +uint32_t +PbbMessage::GetSerializedSize (void) const +{ + /* msg-type + (msg-flags + msg-addr-length) + 2msg-size */ + uint32_t size = 4; + + if (HasOriginatorAddress()) + { + size += GetAddressLength() + 1; + } + + if (HasHopLimit()) + { + size++; + } + + if (HasHopCount()) + { + size++; + } + + if (HasSequenceNumber()) + { + size += 2; + } + + size += m_tlvList.GetSerializedSize (); + + for (ConstAddressBlockIterator iter = AddressBlockBegin (); + iter != AddressBlockEnd (); + iter++) + { + size += (*iter)->GetSerializedSize (); + } + + return size; +} + +void +PbbMessage::Serialize (Buffer::Iterator &start) const +{ + Buffer::Iterator front = start; + + start.WriteU8 (GetType()); + + /* Save a reference to the spot where we will later write the flags */ + Buffer::Iterator bufref = start; + start.Next (1); + + uint8_t flags = 0; + + flags = GetAddressLength (); + + Buffer::Iterator sizeref = start; + start.Next (2); + + if (HasOriginatorAddress ()) + { + flags |= MHAS_ORIG; + SerializeOriginatorAddress (start); + } + + if (HasHopLimit ()) + { + flags |= MHAS_HOP_LIMIT; + start.WriteU8 (GetHopLimit ()); + } + + if (HasHopCount ()) + { + flags |= MHAS_HOP_COUNT; + start.WriteU8 (GetHopCount ()); + } + + if (HasSequenceNumber ()) + { + flags |= MHAS_SEQ_NUM; + start.WriteHtonU16 (GetSequenceNumber ()); + } + + bufref.WriteU8(flags); + + m_tlvList.Serialize (start); + + for (ConstAddressBlockIterator iter = AddressBlockBegin (); + iter != AddressBlockEnd (); + iter++) + { + (*iter)->Serialize (start); + } + + sizeref.WriteHtonU16 (front.GetDistanceFrom (start)); +} + +Ptr +PbbMessage::DeserializeMessage (Buffer::Iterator &start) +{ + /* We need to read the msg-addr-len field to determine what kind of object to + * construct. */ + start.Next (); + uint8_t addrlen = start.ReadU8 (); + start.Prev (2); /* Go back to the start */ + + /* The first four bytes of the flag is the address length. Set the last four + * bytes to 0 to read it. */ + addrlen = (addrlen & 0xf); + + Ptr newmsg; + + switch (addrlen) + { + case 0: + case IPV4: + newmsg = Create (); + break; + case IPV6: + newmsg = Create (); + break; + default: + return 0; + break; + } + newmsg->Deserialize (start); + return newmsg; +} + +void +PbbMessage::Deserialize (Buffer::Iterator &start) +{ + Buffer::Iterator front = start; + SetType (start.ReadU8 ()); + uint8_t flags = start.ReadU8 (); + + uint16_t size = start.ReadNtohU16 (); + + if (flags & MHAS_ORIG) + { + SetOriginatorAddress (DeserializeOriginatorAddress (start)); + } + + if (flags & MHAS_HOP_LIMIT) + { + SetHopLimit (start.ReadU8 ()); + } + + if (flags & MHAS_HOP_COUNT) + { + SetHopCount (start.ReadU8 ()); + } + + if (flags & MHAS_SEQ_NUM) + { + SetSequenceNumber (start.ReadNtohU16 ()); + } + + m_tlvList.Deserialize (start); + + if (size > 0) + { + while (start.GetDistanceFrom(front) < size) + { + Ptr newab = AddressBlockDeserialize (start); + AddressBlockPushBack (newab); + } + } +} + +void +PbbMessage::Print (std::ostream &os) const +{ + Print (os, 0); +} + +void +PbbMessage::Print (std::ostream &os, int level) const +{ + std::string prefix = ""; + for (int i = 0; i < level; i++) + { + prefix.append ("\t"); + } + + os << prefix << "PbbMessage {" << std::endl; + + os << prefix << "\tmessage type = " << (int)GetType () << std::endl; + os << prefix << "\taddress size = " << GetAddressLength () << std::endl; + + if (HasOriginatorAddress ()) + { + os << prefix << "\toriginator address = "; + PrintOriginatorAddress (os); + os << std::endl; + } + + if (HasHopLimit ()) + { + os << prefix << "\thop limit = " << (int)GetHopLimit () << std::endl; + } + + if (HasHopCount ()) + { + os << prefix << "\thop count = " << (int)GetHopCount () << std::endl; + } + + if (HasSequenceNumber ()) + { + os << prefix << "\tseqnum = " << GetSequenceNumber () << std::endl; + } + + m_tlvList.Print (os, level+1); + + for (ConstAddressBlockIterator iter = AddressBlockBegin (); + iter != AddressBlockEnd (); + iter++) + { + (*iter)->Print (os, level+1); + } + os << prefix << "}" << std::endl; +} + +bool +PbbMessage::operator== (const PbbMessage &other) const +{ + if (GetAddressLength () != other.GetAddressLength ()) + { + return false; + } + + if (GetType () != other.GetType ()) + { + return false; + } + + if (HasOriginatorAddress () != other.HasOriginatorAddress ()) + { + return false; + } + + if (HasOriginatorAddress ()) + { + if (GetOriginatorAddress () != other.GetOriginatorAddress ()) + { + return false; + } + } + + if (HasHopLimit () != other.HasHopLimit ()) + { + return false; + } + + if (HasHopLimit ()) + { + if (GetHopLimit () != other.GetHopLimit ()) + { + return false; + } + } + + if (HasHopCount () != other.HasHopCount ()) + { + return false; + } + + if (HasHopCount ()) + { + if (GetHopCount () != other.GetHopCount ()) + { + return false; + } + } + + if (HasSequenceNumber () != other.HasSequenceNumber ()) + { + return false; + } + + if (HasSequenceNumber ()) + { + if (GetSequenceNumber () != other.GetSequenceNumber ()) + { + return false; + } + } + + if (m_tlvList != other.m_tlvList) + { + return false; + } + + if (AddressBlockSize () != other.AddressBlockSize ()) + { + return false; + } + + ConstAddressBlockIterator tai, oai; + for (tai = AddressBlockBegin (), oai = other.AddressBlockBegin (); + tai != AddressBlockEnd () && oai != other.AddressBlockEnd (); + tai++, oai++) + { + if (**tai != **oai) + { + return false; + } + } + return true; +} + +bool +PbbMessage::operator!= (const PbbMessage &other) const +{ + return !(*this == other); +} + +/* End PbbMessage Class */ + +PbbAddressLength +PbbMessageIpv4::GetAddressLength (void) const +{ + return IPV4; +} + +void +PbbMessageIpv4::SerializeOriginatorAddress (Buffer::Iterator &start) const +{ + uint8_t buffer[GetAddressLength () + 1]; + Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer); + start.Write (buffer, GetAddressLength () + 1); +} + +Address +PbbMessageIpv4::DeserializeOriginatorAddress (Buffer::Iterator &start) const +{ + uint8_t buffer[GetAddressLength () + 1]; + start.Read(buffer, GetAddressLength () + 1); + return Ipv4Address::Deserialize (buffer); +} + +void +PbbMessageIpv4::PrintOriginatorAddress (std::ostream &os) const +{ + Ipv4Address::ConvertFrom (GetOriginatorAddress ()).Print (os); +} + +Ptr +PbbMessageIpv4::AddressBlockDeserialize (Buffer::Iterator &start) const +{ + Ptr newab = Create (); + newab->Deserialize (start); + return newab; +} + +/* End PbbMessageIpv4 Class */ + +PbbAddressLength +PbbMessageIpv6::GetAddressLength (void) const +{ + return IPV6; +} + +void +PbbMessageIpv6::SerializeOriginatorAddress (Buffer::Iterator &start) const +{ + uint8_t buffer[GetAddressLength () + 1]; + Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Serialize(buffer); + start.Write (buffer, GetAddressLength () + 1); +} + +Address +PbbMessageIpv6::DeserializeOriginatorAddress (Buffer::Iterator &start) const +{ + uint8_t buffer[GetAddressLength () + 1]; + start.Read(buffer, GetAddressLength () + 1); + return Ipv6Address::Deserialize (buffer); +} + +void +PbbMessageIpv6::PrintOriginatorAddress (std::ostream &os) const +{ + Ipv6Address::ConvertFrom (GetOriginatorAddress ()).Print (os); +} + +Ptr +PbbMessageIpv6::AddressBlockDeserialize (Buffer::Iterator &start) const +{ + Ptr newab = Create (); + newab->Deserialize (start); + return newab; +} + +/* End PbbMessageIpv6 Class */ + +PbbAddressBlock::PbbAddressBlock () +{ + m_refCount = 1; +} + +/* Manipulating the address block */ + +PbbAddressBlock::AddressIterator +PbbAddressBlock::AddressBegin (void) +{ + return m_addressList.begin(); +} + +PbbAddressBlock::ConstAddressIterator +PbbAddressBlock::AddressBegin (void) const +{ + return m_addressList.begin(); +} + +PbbAddressBlock::AddressIterator +PbbAddressBlock::AddressEnd (void) +{ + return m_addressList.end(); +} + +PbbAddressBlock::ConstAddressIterator +PbbAddressBlock::AddressEnd (void) const +{ + return m_addressList.end(); +} + +int +PbbAddressBlock::AddressSize (void) const +{ + return m_addressList.size(); +} + +bool +PbbAddressBlock::AddressEmpty (void) const +{ + return m_addressList.empty(); +} + +Address +PbbAddressBlock::AddressFront (void) const +{ + return m_addressList.front(); +} + +Address +PbbAddressBlock::AddressBack (void) const +{ + return m_addressList.back(); +} + +void +PbbAddressBlock::AddressPushFront (Address tlv) +{ + m_addressList.push_front(tlv); +} + +void +PbbAddressBlock::AddressPopFront (void) +{ + m_addressList.pop_front(); +} + +void +PbbAddressBlock::AddressPushBack (Address tlv) +{ + m_addressList.push_back(tlv); +} + +void +PbbAddressBlock::AddressPopBack (void) +{ + m_addressList.pop_back(); +} + +PbbAddressBlock::AddressIterator +PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator position) +{ + return m_addressList.erase(position); +} + +PbbAddressBlock::AddressIterator +PbbAddressBlock::AddressErase (PbbAddressBlock::AddressIterator first, + PbbAddressBlock::AddressIterator last) +{ + return m_addressList.erase(first, last); +} + + void +PbbAddressBlock::AddressClear (void) +{ + return m_addressList.clear(); +} + +/* Manipulating the prefix list */ + +PbbAddressBlock::PrefixIterator +PbbAddressBlock::PrefixBegin (void) +{ + return m_prefixList.begin (); +} + +PbbAddressBlock::ConstPrefixIterator +PbbAddressBlock::PrefixBegin (void) const +{ + return m_prefixList.begin (); +} + +PbbAddressBlock::PrefixIterator +PbbAddressBlock::PrefixEnd (void) +{ + return m_prefixList.end (); +} + +PbbAddressBlock::ConstPrefixIterator +PbbAddressBlock::PrefixEnd (void) const +{ + return m_prefixList.end (); +} + +int +PbbAddressBlock::PrefixSize (void) const +{ + return m_prefixList.size (); +} + +bool +PbbAddressBlock::PrefixEmpty (void) const +{ + return m_prefixList.empty (); +} + +uint8_t +PbbAddressBlock::PrefixFront (void) const +{ + return m_prefixList.front (); +} + +uint8_t +PbbAddressBlock::PrefixBack (void) const +{ + return m_prefixList.back (); +} + +void +PbbAddressBlock::PrefixPushFront (uint8_t prefix) +{ + m_prefixList.push_front (prefix); +} + +void +PbbAddressBlock::PrefixPopFront (void) +{ + m_prefixList.pop_front (); +} + +void +PbbAddressBlock::PrefixPushBack (uint8_t prefix) +{ + m_prefixList.push_back (prefix); +} + +void +PbbAddressBlock::PrefixPopBack (void) +{ + m_prefixList.pop_back (); +} + +PbbAddressBlock::PrefixIterator +PbbAddressBlock::PrefixInsert (PbbAddressBlock::PrefixIterator position, const uint8_t value) +{ + return m_prefixList.insert (position, value); +} + +PbbAddressBlock::PrefixIterator +PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator position) +{ + return m_prefixList.erase (position); +} + +PbbAddressBlock::PrefixIterator +PbbAddressBlock::PrefixErase (PbbAddressBlock::PrefixIterator first, PbbAddressBlock::PrefixIterator last) +{ + return m_prefixList.erase (first, last); +} + +void +PbbAddressBlock::PrefixClear (void) +{ + m_prefixList.clear (); +} + +/* Manipulating the TLV block */ + +PbbAddressBlock::TlvIterator +PbbAddressBlock::TlvBegin (void) +{ + return m_addressTlvList.Begin(); +} + +PbbAddressBlock::ConstTlvIterator +PbbAddressBlock::TlvBegin (void) const +{ + return m_addressTlvList.Begin(); +} + +PbbAddressBlock::TlvIterator +PbbAddressBlock::TlvEnd (void) +{ + return m_addressTlvList.End(); +} + +PbbAddressBlock::ConstTlvIterator +PbbAddressBlock::TlvEnd (void) const +{ + return m_addressTlvList.End(); +} + +int +PbbAddressBlock::TlvSize (void) const +{ + return m_addressTlvList.Size(); +} + +bool +PbbAddressBlock::TlvEmpty (void) const +{ + return m_addressTlvList.Empty(); +} + +Ptr +PbbAddressBlock::TlvFront (void) +{ + return m_addressTlvList.Front(); +} + +const Ptr +PbbAddressBlock::TlvFront (void) const +{ + return m_addressTlvList.Front(); +} + +Ptr +PbbAddressBlock::TlvBack (void) +{ + return m_addressTlvList.Back(); +} + +const Ptr +PbbAddressBlock::TlvBack (void) const +{ + return m_addressTlvList.Back(); +} + +void +PbbAddressBlock::TlvPushFront (Ptr tlv) +{ + m_addressTlvList.PushFront(tlv); +} + +void +PbbAddressBlock::TlvPopFront (void) +{ + m_addressTlvList.PopFront(); +} + +void +PbbAddressBlock::TlvPushBack (Ptr tlv) +{ + m_addressTlvList.PushBack(tlv); +} + +void +PbbAddressBlock::TlvPopBack (void) +{ + m_addressTlvList.PopBack(); +} + +PbbAddressBlock::TlvIterator +PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator position) +{ + return m_addressTlvList.Erase(position); +} + +PbbAddressBlock::TlvIterator +PbbAddressBlock::TlvErase (PbbAddressBlock::TlvIterator first, + PbbAddressBlock::TlvIterator last) +{ + return m_addressTlvList.Erase(first, last); +} + +void +PbbAddressBlock::TlvClear (void) +{ + return m_addressTlvList.Clear(); +} + +void +PbbAddressBlock::Ref (void) const +{ + m_refCount++; +} + +void +PbbAddressBlock::Unref (void) const +{ + m_refCount--; + if (m_refCount == 0) + { + delete this; + } +} + +uint32_t +PbbAddressBlock::GetSerializedSize (void) const +{ + /* num-addr + flags */ + uint32_t size = 2; + + if (AddressSize () == 1) + { + size += GetAddressLength () + PrefixSize(); + } + else if (AddressSize () > 0) + { + uint8_t head[GetAddressLength ()]; + uint8_t headlen = 0; + uint8_t tail[GetAddressLength ()]; + uint8_t taillen = 0; + + GetHeadTail (head, headlen, tail, taillen); + + if (headlen > 0) + { + size += 1 + headlen; + } + + if (taillen > 0) + { + size++; + if (!HasZeroTail (tail, taillen)) + { + size += taillen; + } + } + + /* mid size */ + size += (GetAddressLength () - headlen - taillen) * AddressSize (); + + size += PrefixSize (); + } + + size += m_addressTlvList.GetSerializedSize (); + + return size; +} + +void +PbbAddressBlock::Serialize (Buffer::Iterator &start) const +{ + start.WriteU8 (AddressSize ()); + + if (AddressSize () == 1) + { + start.WriteU8 (0); + + uint8_t buf[GetAddressLength ()]; + SerializeAddress (buf, AddressBegin ()); + start.Write (buf, GetAddressLength ()); + + if (PrefixSize () == 1) + { + start.WriteU8 (PrefixFront ()); + } + } + else if (AddressSize () > 0) + { + Buffer::Iterator bufref = start; + uint8_t flags = 0; + start.Next (); + + uint8_t head[GetAddressLength ()]; + uint8_t tail[GetAddressLength ()]; + uint8_t headlen = 0; + uint8_t taillen = 0; + + GetHeadTail (head, headlen, tail, taillen); + + if (headlen > 0) + { + flags |= AHAS_HEAD; + start.WriteU8 (headlen); + start.Write (head, headlen); + } + + if (taillen > 0) + { + start.WriteU8 (taillen); + + if (HasZeroTail (tail, taillen)) + { + flags |= AHAS_ZERO_TAIL; + } + else + { + flags |= AHAS_FULL_TAIL; + start.Write (tail, taillen); + } + } + + if (headlen + taillen < GetAddressLength ()) + { + uint8_t mid[GetAddressLength ()]; + for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin (); + iter != AddressEnd (); + iter++) + { + SerializeAddress (mid, iter); + start.Write (mid + headlen, GetAddressLength () - headlen - taillen); + } + } + + flags |= GetPrefixFlags (); + bufref.WriteU8 (flags); + + for (ConstPrefixIterator iter = PrefixBegin (); + iter != PrefixEnd (); + iter++) + { + start.WriteU8 (*iter); + } + } + + m_addressTlvList.Serialize (start); +} + +void +PbbAddressBlock::Deserialize (Buffer::Iterator &start) +{ + uint8_t numaddr = start.ReadU8 (); + uint8_t flags = start.ReadU8 (); + + if (numaddr > 0) + { + uint8_t headlen = 0; + uint8_t taillen = 0; + uint8_t addrtmp[GetAddressLength ()]; + memset(addrtmp, 0, GetAddressLength ()); + + if (flags & AHAS_HEAD) + { + headlen = start.ReadU8 (); + start.Read (addrtmp, headlen); + } + + if ((flags & AHAS_FULL_TAIL) ^ (flags & AHAS_ZERO_TAIL)) + { + taillen = start.ReadU8 (); + + if (flags & AHAS_FULL_TAIL) + { + start.Read (addrtmp + GetAddressLength () - taillen, taillen); + } + } + + for (int i = 0; i < numaddr; i++) + { + start.Read (addrtmp + headlen, GetAddressLength () - headlen - taillen); + AddressPushBack (DeserializeAddress (addrtmp)); + } + + if (flags & AHAS_SINGLE_PRE_LEN) + { + PrefixPushBack (start.ReadU8 ()); + } + else if (flags & AHAS_MULTI_PRE_LEN) + { + for (int i = 0; i < numaddr; i++) + { + PrefixPushBack (start.ReadU8 ()); + } + } + } + + m_addressTlvList.Deserialize (start); +} + +void +PbbAddressBlock::Print (std::ostream &os) const +{ + Print (os, 0); +} + +void +PbbAddressBlock::Print (std::ostream &os, int level) const +{ + std::string prefix = ""; + for (int i = 0; i < level; i++) + { + prefix.append ("\t"); + } + + os << prefix << "PbbAddressBlock {" << std::endl; + os << prefix << "\taddresses = " << std::endl; + for (ConstAddressIterator iter = AddressBegin (); + iter != AddressEnd (); + iter++) + { + os << prefix << "\t\t"; + PrintAddress(os, iter); + os << std::endl; + } + + os << prefix << "\tprefixes = " << std::endl; + for (ConstPrefixIterator iter = PrefixBegin (); + iter != PrefixEnd (); + iter++) + { + os << prefix << "\t\t" << (int)(*iter) << std::endl; + } + + m_addressTlvList.Print (os, level+1); +} + +bool +PbbAddressBlock::operator== (const PbbAddressBlock &other) const +{ + if (AddressSize () != other.AddressSize ()) + { + return false; + } + + ConstAddressIterator tai, oai; + for (tai = AddressBegin (), oai = other.AddressBegin (); + tai != AddressEnd () && oai != other.AddressEnd (); + tai++, oai++) + { + if (*tai != *oai) + { + return false; + } + } + + if (PrefixSize () != other.PrefixSize ()) + { + return false; + } + + ConstPrefixIterator tpi, opi; + for (tpi = PrefixBegin (), opi = other.PrefixBegin (); + tpi != PrefixEnd () && opi != other.PrefixEnd (); + tpi++, opi++) + { + if (*tpi != *opi) + { + return false; + } + } + + if (m_addressTlvList != other.m_addressTlvList) + { + return false; + } + + return true; +} + +bool +PbbAddressBlock::operator!= (const PbbAddressBlock &other) const +{ + return !(*this == other); +} + +uint8_t +PbbAddressBlock::GetPrefixFlags (void) const +{ + switch (PrefixSize ()) + { + case 0: + return 0; + break; + case 1: + return AHAS_SINGLE_PRE_LEN; + break; + default: + return AHAS_MULTI_PRE_LEN; + break; + } +} + +void +PbbAddressBlock::GetHeadTail (uint8_t *head, uint8_t &headlen, + uint8_t *tail, uint8_t &taillen) const +{ + headlen = GetAddressLength (); + taillen = headlen; + + /* Temporary automatic buffers to store serialized addresses */ + uint8_t * buflast = new uint8_t[GetAddressLength ()]; + uint8_t * bufcur = new uint8_t[GetAddressLength ()]; + uint8_t * tmp; + + SerializeAddress (buflast, AddressBegin ()); + + /* Skip the first item */ + for (PbbAddressBlock::ConstAddressIterator iter = AddressBegin ()++; + iter != AddressEnd (); + iter++) + { + SerializeAddress (bufcur, iter); + + int i; + for (i = 0; i < headlen; i++) + { + if (buflast[i] != bufcur[i]) + { + headlen = i; + break; + } + } + + /* If headlen == fulllen - 1, then tail is 0 */ + if (headlen <= GetAddressLength () - 1) + { + for (i = GetAddressLength () - 1; + GetAddressLength () - 1 - i <= taillen && i > headlen; + i--) + { + if (buflast[i] != bufcur[i]) + { + break; + } + } + taillen = GetAddressLength () - 1 - i; + } + else if (headlen == 0) + { + taillen = 0; + break; + } + + tmp = buflast; + buflast = bufcur; + bufcur = tmp; + } + + memcpy(head, bufcur, headlen); + memcpy(tail, bufcur + (GetAddressLength () - taillen), taillen); + + delete[] buflast; + delete[] bufcur; +} + +bool +PbbAddressBlock::HasZeroTail (const uint8_t *tail, uint8_t taillen) const +{ + int i; + for (i = 0; i < taillen; i++) + { + if (tail[i] != 0) + { + break; + } + } + return i == taillen; +} + +/* End PbbAddressBlock Class */ + +uint8_t +PbbAddressBlockIpv4::GetAddressLength (void) const +{ + return 4; +} + +void +PbbAddressBlockIpv4::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const +{ + Ipv4Address::ConvertFrom (*iter).Serialize (buffer); +} + +Address +PbbAddressBlockIpv4::DeserializeAddress (uint8_t *buffer) const +{ + return Ipv4Address::Deserialize (buffer); +} + +void +PbbAddressBlockIpv4::PrintAddress (std::ostream &os, ConstAddressIterator iter) const +{ + Ipv4Address::ConvertFrom (*iter).Print (os); +} + +/* End PbbAddressBlockIpv4 Class */ + +uint8_t +PbbAddressBlockIpv6::GetAddressLength (void) const +{ + return 16; +} + +void +PbbAddressBlockIpv6::SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const +{ + Ipv6Address::ConvertFrom (*iter).Serialize (buffer); +} + +Address +PbbAddressBlockIpv6::DeserializeAddress (uint8_t *buffer) const +{ + return Ipv6Address::Deserialize (buffer); +} + +void +PbbAddressBlockIpv6::PrintAddress (std::ostream &os, ConstAddressIterator iter) const +{ + Ipv6Address::ConvertFrom (*iter).Print (os); +} + +/* End PbbAddressBlockIpv6 Class */ + +PbbTlv::PbbTlv (void) +{ + m_refCount = 1; + m_hasTypeExt = false; + m_hasIndexStart = false; + m_hasIndexStop = false; + m_isMultivalue = false; + m_hasValue = false; +} + +void +PbbTlv::SetType (uint8_t type) +{ + m_type = type; +} + +uint8_t +PbbTlv::GetType (void) const +{ + return m_type; +} + +void +PbbTlv::SetTypeExt (uint8_t typeExt) +{ + m_typeExt = typeExt; + m_hasTypeExt = true; +} + +uint8_t +PbbTlv::GetTypeExt (void) const +{ + NS_ASSERT (HasTypeExt ()); + return m_typeExt; +} + +bool +PbbTlv::HasTypeExt (void) const +{ + return m_hasTypeExt; +} + +void +PbbTlv::SetIndexStart (uint8_t index) +{ + m_indexStart = index; + m_hasIndexStart = true; +} + +uint8_t +PbbTlv::GetIndexStart (void) const +{ + NS_ASSERT (HasIndexStart ()); + return m_indexStart; +} + +bool +PbbTlv::HasIndexStart (void) const +{ + return m_hasIndexStart; +} + +void +PbbTlv::SetIndexStop (uint8_t index) +{ + m_indexStop = index; + m_hasIndexStop = true; +} + +uint8_t +PbbTlv::GetIndexStop (void) const +{ + NS_ASSERT (HasIndexStop ()); + return m_indexStop; +} + +bool +PbbTlv::HasIndexStop (void) const +{ + return m_hasIndexStop; +} + +void +PbbTlv::SetMultivalue (bool isMultivalue) +{ + m_isMultivalue = isMultivalue; +} + +bool +PbbTlv::IsMultivalue (void) const +{ + return m_isMultivalue; +} + +void +PbbTlv::SetValue (Buffer start) +{ + m_hasValue = true; + m_value = start; +} + +void +PbbTlv::SetValue (const uint8_t * buffer, uint32_t size) +{ + Buffer value; + value.AddAtStart (size); + value.Begin ().Write (buffer, size); + SetValue (value); +} + +Buffer +PbbTlv::GetValue (void) const +{ + NS_ASSERT (HasValue ()); + return m_value; +} + +bool +PbbTlv::HasValue (void) const +{ + return m_hasValue; +} + +void +PbbTlv::Ref (void) const +{ + m_refCount++; +} + +void +PbbTlv::Unref (void) const +{ + m_refCount--; + if (m_refCount == 0) + { + delete this; + } +} + +uint32_t +PbbTlv::GetSerializedSize (void) const +{ + /* type + flags */ + uint32_t size = 2; + + if (HasTypeExt ()) + { + size++; + } + + if (HasIndexStart ()) + { + size++; + } + + if (HasIndexStop ()) + { + size++; + } + + if (HasValue ()) + { + if (GetValue ().GetSize () > 255) + { + size += 2; + } + else + { + size++; + } + size += GetValue ().GetSize (); + } + + return size; +} + +void +PbbTlv::Serialize (Buffer::Iterator &start) const +{ + start.WriteU8 (GetType ()); + + Buffer::Iterator bufref = start; + uint8_t flags = 0; + start.Next(); + + if (HasTypeExt()) + { + flags |= THAS_TYPE_EXT; + start.WriteU8 (GetTypeExt ()); + } + + if (HasIndexStart ()) + { + start.WriteU8 (GetIndexStart ()); + + if (HasIndexStop ()) + { + flags |= THAS_MULTI_INDEX; + start.WriteU8 (GetIndexStop ()); + } + else + { + flags |= THAS_SINGLE_INDEX; + } + } + + if (HasValue ()) + { + flags |= THAS_VALUE; + + uint32_t size = GetValue ().GetSize (); + if (size > 255) + { + flags |= THAS_EXT_LEN; + start.WriteHtonU16 (size); + } + else + { + start.WriteU8 (size); + } + + if (IsMultivalue ()) + { + flags |= TIS_MULTIVALUE; + } + + start.Write(GetValue ().Begin (), GetValue ().End ()); + } + + bufref.WriteU8 (flags); +} + +void +PbbTlv::Deserialize (Buffer::Iterator &start) +{ + SetType (start.ReadU8 ()); + + uint8_t flags = start.ReadU8 (); + + if (flags & THAS_TYPE_EXT) + { + SetTypeExt (start.ReadU8 ()); + } + + if (flags & THAS_MULTI_INDEX) + { + SetIndexStart (start.ReadU8 ()); + SetIndexStop (start.ReadU8 ()); + } + else if (flags & THAS_SINGLE_INDEX) + { + SetIndexStart (start.ReadU8 ()); + } + + if (flags & THAS_VALUE) + { + uint16_t len = 0; + + if (flags & THAS_EXT_LEN) + { + len = start.ReadNtohU16 (); + } + else + { + len = start.ReadU8 (); + } + + m_value.AddAtStart (len); + + Buffer::Iterator valueStart = start; + start.Next (len); + m_value.Begin ().Write (valueStart, start); + m_hasValue = true; + } +} + +void +PbbTlv::Print (std::ostream &os) const +{ + Print (os, 0); +} + +void +PbbTlv::Print (std::ostream &os, int level) const +{ + std::string prefix = ""; + for (int i = 0; i < level; i++) + { + prefix.append ("\t"); + } + + os << prefix << "PbbTlv {" << std::endl; + os << prefix << "\ttype = " << (int)GetType () << std::endl; + + if (HasTypeExt ()) + { + os << prefix << "\ttypeext = " << (int)GetTypeExt () << std::endl; + } + + if (HasIndexStart ()) + { + os << prefix << "\tindexStart = " << (int)GetIndexStart () << std::endl; + } + + if (HasIndexStop ()) + { + os << prefix << "\tindexStop = " << (int)GetIndexStop () << std::endl; + } + + os << prefix << "\tisMultivalue = " << IsMultivalue () << std::endl; + + if (HasValue ()) + { + os << prefix << "\thas value; size = " << GetValue (). GetSize () << std::endl; + } + + os << prefix << "}" << std::endl; +} + +bool +PbbTlv::operator== (const PbbTlv &other) const +{ + if (GetType () != other.GetType ()) + { + return false; + } + + if (HasTypeExt () != other.HasTypeExt ()) + { + return false; + } + + if (HasTypeExt ()) + { + if (GetTypeExt () != other.GetTypeExt ()) + { + return false; + } + } + + if (HasValue () != other.HasValue ()) + { + return false; + } + + if (HasValue ()) + { + Buffer tv = GetValue (); + Buffer ov = other.GetValue (); + if (tv.GetSize () != ov.GetSize ()) + { + return false; + } + + /* The docs say I probably shouldn't use Buffer::PeekData, but I think it + * is justified in this case. */ + if (memcmp (tv.PeekData (), ov.PeekData (), tv.GetSize ()) != 0) + { + return false; + } + } + return true; +} + +bool +PbbTlv::operator!= (const PbbTlv &other) const +{ + return !(*this == other); +} + +/* End PbbTlv Class */ + +void +PbbAddressTlv::SetIndexStart (uint8_t index) +{ + PbbTlv::SetIndexStart (index); +} + +uint8_t +PbbAddressTlv::GetIndexStart (void) const +{ + return PbbTlv::GetIndexStart (); +} + +bool +PbbAddressTlv::HasIndexStart (void) const +{ + return PbbTlv::HasIndexStart (); +} + +void +PbbAddressTlv::SetIndexStop (uint8_t index) +{ + PbbTlv::SetIndexStop (index); +} + +uint8_t +PbbAddressTlv::GetIndexStop (void) const +{ + return PbbTlv::GetIndexStop (); +} + +bool +PbbAddressTlv::HasIndexStop (void) const +{ + return PbbTlv::HasIndexStop (); +} + +void +PbbAddressTlv::SetMultivalue (bool isMultivalue) +{ + PbbTlv::SetMultivalue (isMultivalue); +} + +bool +PbbAddressTlv::IsMultivalue (void) const +{ + return PbbTlv::IsMultivalue (); +} + +} /* namespace ns3 */ diff --git a/src/node/packetbb.h b/src/node/packetbb.h new file mode 100644 index 000000000..5802f43af --- /dev/null +++ b/src/node/packetbb.h @@ -0,0 +1,1727 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* vim: set ts=2 sw=2 sta expandtab ai si cin: */ +/* + * Copyright (c) 2009 Drexel University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Tom Wambold + */ +/* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network + * (MANET) Packet/PbbMessage Format + * See: http://tools.ietf.org/html/rfc5444 for details */ + +#ifndef PACKETBB_H +#define PACKETBB_H + +#include + +#include "ns3/ptr.h" +#include "ns3/address.h" +#include "ns3/header.h" +#include "ns3/buffer.h" + +namespace ns3 { + +/* Forward declare objects */ +class PbbMessage; +class PbbAddressBlock; +class PbbTlv; +class PbbAddressTlv; + +/** Used in Messages to determine whether it contains IPv4 or IPv6 addresses */ +enum PbbAddressLength { + IPV4 = 3, + IPV6 = 15, +}; + +/** + * \brief A block of packet or message TLVs (PbbTlv). + * + * Acts similar to a C++ STL container. Should not be used for Address TLVs. + */ +class PbbTlvBlock +{ +public: + typedef std::list< Ptr >::iterator Iterator; + typedef std::list< Ptr >::const_iterator ConstIterator; + + /** + * \return an iterator to the first TLV in this block. + */ + Iterator Begin (void); + + /** + * \return a const iterator to the first TLV in this block. + */ + ConstIterator Begin (void) const; + + /** + * \return an iterator to the past-the-end element in this block. + */ + Iterator End (void); + + /** + * \return a const iterator to the past-the-end element in this block. + */ + ConstIterator End (void) const; + + /** + * \return the number of TLVs in this block. + */ + int Size (void) const; + + /** + * \return true if there are no TLVs in this block, false otherwise. + */ + bool Empty (void) const; + + /** + * \return a smart pointer to the first TLV in this block. + */ + Ptr Front (void) const; + + /** + * \return a smart pointer to the last TLV in this block. + */ + Ptr Back (void) const; + + /** + * \brief Prepends a TLV to the front of this block. + * \param tlv a smart pointer to the TLV to prepend. + */ + void PushFront (Ptr tlv); + + /** + * \brief Removes a TLV from the front of this block. + */ + void PopFront (void); + + /** + * \brief Appends a TLV to the back of this block. + * \param tlv a smart pointer to the TLV to append. + */ + void PushBack (Ptr tlv); + + /** + * \brief Removes a TLV from the back of this block. + */ + void PopBack (void); + + /** + * \brief Inserts a TLV at the specified position in this block. + * \param position an Iterator pointing to the position in this block to + * insert the TLV. + * \param tlv a smart pointer to the TLV to insert. + * \return An iterator pointing to the newly inserted TLV. + */ + Iterator Insert (Iterator position, const Ptr tlv); + + /** + * \brief Removes the TLV at the specified position. + * \param position an Iterator pointing to the TLV to erase. + * \return an iterator pointing to the next TLV in the block. + */ + Iterator Erase (Iterator position); + + /** + * \brief Removes all TLVs from [first, last) (includes first, not includes + * last). + * \param first an Iterator pointing to the first TLV to erase (inclusive). + * \param last an Iterator pointing to the element past the last TLV to erase. + * \return an iterator pointing to the next TLV in the block. + */ + Iterator Erase (Iterator first, Iterator last); + + /** + * \brief Removes all TLVs from this block. + */ + void Clear (void); + + /** + * \return The size (in bytes) needed to serialize this block. + */ + uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this block into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + * + * Users should not need to call this. Blocks will be serialized by their + * containing packet. + */ + void Serialize (Buffer::Iterator &start) const; + + /** + * \brief Deserializes a block from the specified buffer. + * \param start a reference to the point in a buffer to begin deserializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Deserialize (Buffer::Iterator &start); + + /** + * \brief Pretty-prints the contents of this block. + * \param os a stream object to print to. + */ + void Print (std::ostream &os) const; + + /** + * \brief Pretty-prints the contents of this block, with specified indentation. + * \param os a stream object to print to. + * \param level level of indentation. + * + * This probably never needs to be called by users. This is used when + * recursively printing sub-objects. + */ + void Print (std::ostream &os, int level) const; + + bool operator== (const PbbTlvBlock &other) const; + bool operator!= (const PbbTlvBlock &other) const; + +private: + std::list< Ptr > m_tlvList; +}; + +/** + * \brief A block of Address TLVs (PbbAddressTlv). + * + * Acts similar to a C++ STL container. + */ +class PbbAddressTlvBlock +{ +public: + typedef std::list< Ptr >::iterator Iterator; + typedef std::list< Ptr >::const_iterator ConstIterator; + + /** + * \return an iterator to the first Address TLV in this block. + */ + Iterator Begin (void); + + /** + * \return a const iterator to the first Address TLV in this block. + */ + ConstIterator Begin (void) const; + + /** + * \return an iterator to the past-the-end element in this block. + */ + Iterator End (void); + + /** + * \return a const iterator to the past-the-end element in this block. + */ + ConstIterator End (void) const; + + /** + * \return the number of Address TLVs in this block. + */ + int Size (void) const; + + /** + * \return true if there are no Address TLVs in this block, false otherwise. + */ + bool Empty (void) const; + + /** + * \return the first Address TLV in this block. + */ + Ptr Front (void) const; + + /** + * \return the last AddressTLV in this block. + */ + Ptr Back (void) const; + + /** + * \brief Prepends an Address TLV to the front of this block. + * \param tlv a smart pointer to the Address TLV to prepend. + */ + void PushFront (Ptr tlv); + + /** + * \brief Removes an AddressTLV from the front of this block. + */ + void PopFront (void); + + /** + * \brief Appends an Address TLV to the back of this block. + * \param tlv a smart pointer to the Address TLV to append. + */ + void PushBack (Ptr tlv); + + /** + * \brief Removes an Address TLV from the back of this block. + */ + void PopBack (void); + + /** + * \brief Inserts an Address TLV at the specified position in this block. + * \param position an Iterator pointing to the position in this block to + * insert the Address TLV. + * \param tlv a smart pointer to the Address TLV to insert. + * \return An iterator pointing to the newly inserted Address TLV. + */ + Iterator Insert (Iterator position, const Ptr tlv); + + /** + * \brief Removes the Address TLV at the specified position. + * \param position an Iterator pointing to the Address TLV to erase. + * \return an iterator pointing to the next Address TLV in the block. + */ + Iterator Erase (Iterator position); + + /** + * \brief Removes all Address TLVs from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first Address TLV to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last Address TLV + * to erase. + * \return an iterator pointing to the next Address TLV in the block. + */ + Iterator Erase (Iterator first, Iterator last); + + /** + * \brief Removes all Address TLVs from this block. + */ + void Clear (void); + + /** + * \return The size (in bytes) needed to serialize this block. + */ + uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this block into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + * + * Users should not need to call this. Blocks will be serialized by their + * containing packet. + */ + void Serialize (Buffer::Iterator &start) const; + + /** + * \brief Deserializes a block from the specified buffer. + * \param start a reference to the point in a buffer to begin deserializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Deserialize (Buffer::Iterator &start); + + /** + * \brief Pretty-prints the contents of this block. + * \param os a stream object to print to. + */ + void Print (std::ostream &os) const; + + /** + * \brief Pretty-prints the contents of this block, with specified indentation. + * \param os a stream object to print to. + * \param level level of indentation. + * + * This probably never needs to be called by users. This is used when + * recursively printing sub-objects. + */ + void Print (std::ostream &os, int level) const; + + bool operator== (const PbbAddressTlvBlock &other) const; + bool operator!= (const PbbAddressTlvBlock &other) const; + +private: + std::list< Ptr > m_tlvList; +}; + +/** + * \brief Main PacketBB Packet object. + * + * A PacketBB packet is made up of zero or more packet TLVs (PbbTlv), and zero + * or more messages (PbbMessage). + * + * See: http://tools.ietf.org/html/rfc5444 for details. + */ +class PbbPacket : public Header +{ +public: + typedef std::list< Ptr >::iterator TlvIterator; + typedef std::list< Ptr >::const_iterator ConstTlvIterator; + typedef std::list< Ptr >::iterator MessageIterator; + typedef std::list< Ptr >::const_iterator ConstMessageIterator; + + PbbPacket (void); + + /** + * \return the version of PacketBB that constructed this packet. + * + * This will always return 0 for packets constructed using this API. + */ + uint8_t GetVersion (void) const; + + /** + * \brief Sets the sequence number of this packet. + * \param number the sequence number. + */ + void SetSequenceNumber (uint16_t number); + + /** + * \return the sequence number of this packet. + * + * Calling this while HasSequenceNumber is False is undefined. Make sure you + * check it first. This will be checked by an assert in debug builds. + */ + uint16_t GetSequenceNumber (void) const; + + /** + * \brief Tests whether or not this packet has a sequence number. + * \return true if this packet has a sequence number, false otherwise. + * + * This should be called before calling GetSequenceNumber to make sure there + * actually is one. + */ + bool HasSequenceNumber (void) const; + + /* Manipulating Packet TLVs */ + + /** + * \return an iterator to the first Packet TLV in this packet. + */ + TlvIterator TlvBegin (void); + + /** + * \return a const iterator to the first Packet TLV in this packet. + */ + ConstTlvIterator TlvBegin (void) const; + + /** + * \return an iterator to the past-the-end element in this packet TLV block. + */ + TlvIterator TlvEnd (void); + + /** + * \return a const iterator to the past-the-end element in this packet TLV + * block. + */ + ConstTlvIterator TlvEnd (void) const; + + /** + * \return the number of packet TLVs in this packet. + */ + int TlvSize (void) const; + + /** + * \return true if there are no packet TLVs in this packet, false otherwise. + */ + bool TlvEmpty (void) const; + + /** + * \return a smart pointer to the first packet TLV in this packet. + */ + Ptr TlvFront (void); + + /** + * \return a const smart pointer to the first packet TLV in this packet. + */ + const Ptr TlvFront (void) const; + + /** + * \return a smart pointer to the last packet TLV in this packet. + */ + Ptr TlvBack (void); + + /** + * \return a const smart pointer to the last packet TLV in this packet. + */ + const Ptr TlvBack (void) const; + + /** + * \brief Prepends a packet TLV to the front of this packet. + * \param tlv a smart pointer to the packet TLV to prepend. + */ + void TlvPushFront (Ptr tlv); + + /** + * \brief Removes a packet TLV from the front of this packet. + */ + void TlvPopFront (void); + + /** + * \brief Appends a packet TLV to the back of this packet. + * \param tlv a smart pointer to the packet TLV to append. + */ + void TlvPushBack (Ptr tlv); + + /** + * \brief Removes a packet TLV from the back of this block. + */ + void TlvPopBack (void); + + /** + * \brief Removes the packet TLV at the specified position. + * \param position an Iterator pointing to the packet TLV to erase. + * \return an iterator pointing to the next packet TLV in the block. + */ + TlvIterator Erase (TlvIterator position); + + /** + * \brief Removes all packet TLVs from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first packet TLV to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last packet TLV + * to erase. + * \return an iterator pointing to the next packet TLV in the block. + */ + TlvIterator Erase (TlvIterator first, TlvIterator last); + + /** + * \brief Removes all packet TLVs from this packet. + */ + void TlvClear (void); + + /* Manipulating Packet Messages */ + + /** + * \return an iterator to the first message in this packet. + */ + MessageIterator MessageBegin (void); + + /** + * \return a const iterator to the first message in this packet. + */ + ConstMessageIterator MessageBegin (void) const; + + /** + * \return an iterator to the past-the-end element in this message block. + */ + MessageIterator MessageEnd (void); + + /** + * \return a const iterator to the past-the-end element in this message + * block. + */ + ConstMessageIterator MessageEnd (void) const; + + /** + * \return the number of messages in this packet. + */ + int MessageSize (void) const; + + /** + * \return true if there are no messages in this packet, false otherwise. + */ + bool MessageEmpty (void) const; + + /** + * \return a smart pointer to the first message in this packet. + */ + Ptr MessageFront (void); + + /** + * \return a cosnt smart pointer to the first message in this packet. + */ + const Ptr MessageFront (void) const; + + /** + * \return a smart pointer to the last message in this packet. + */ + Ptr MessageBack (void); + + /** + * \return a cosnt smart pointer to the last message in this packet. + */ + const Ptr MessageBack (void) const; + + /** + * \brief Prepends a message to the front of this packet. + * \param message a smart pointer to the message to prepend. + */ + void MessagePushFront (Ptr message); + + /** + * \brief Removes a message from the front of this packet. + */ + void MessagePopFront (void); + + /** + * \brief Appends a message to the back of this packet. + * \param message a smart pointer to the message to append. + */ + void MessagePushBack (Ptr message); + + /** + * \brief Removes a message from the back of this packet. + */ + void MessagePopBack (void); + + /** + * \brief Removes the message at the specified position. + * \param position an Iterator pointing to the message to erase. + * \return an iterator pointing to the next message in the packet. + */ + MessageIterator Erase (MessageIterator position); + + /** + * \brief Removes all messages from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first message to erase (inclusive). + * \param last an Iterator pointing to the element past the last message to erase. + * \return an iterator pointing to the next message in the block. + */ + MessageIterator Erase (MessageIterator first, MessageIterator last); + + /** + * \brief Removes all messages from this packet. + */ + void MessageClear (void); + + /* Smart pointer methods */ + void Ref (void) const; + void Unref (void) const; + + /* Methods implemented by all headers */ + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + /** + * \return The size (in bytes) needed to serialize this packet. + */ + virtual uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this packet into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + */ + virtual void Serialize (Buffer::Iterator start) const; + + /** + * \brief Deserializes a packet from the specified buffer. + * \return the number of bytes deserialized + * + * If this returns a number smaller than the total number of bytes in the + * buffer, there was an error. + */ + virtual uint32_t Deserialize (Buffer::Iterator start); + + /** + * \brief Pretty-prints the contents of this block. + * \param os a stream object to print to. + */ + virtual void Print (std::ostream &os) const; + + bool operator== (const PbbPacket &other) const; + bool operator!= (const PbbPacket &other) const; + +protected: + void SerializePacketTlv (Buffer::Iterator &start) const; + +private: + PbbTlvBlock m_tlvList; + std::list< Ptr > m_messageList; + + uint8_t m_version; + + bool m_hasseqnum; + uint16_t m_seqnum; + + mutable uint32_t m_refCount; +}; + +/** + * \brief A message within a PbbPacket packet. + * + * There may be any number of messages in one packet packet. This is a pure + * virtual base class, when creating a message, you should instantiate either + * PbbMessageIpv4 or PbbMessageIpv6. + */ +class PbbMessage +{ +public: + typedef std::list< Ptr >::iterator TlvIterator; + typedef std::list< Ptr >::const_iterator ConstTlvIterator; + typedef std::list< Ptr >::iterator AddressBlockIterator; + typedef std::list< Ptr >::const_iterator ConstAddressBlockIterator; + + PbbMessage (void); + + /** + * \brief Sets the type for this message. + * \param type the type to set. + */ + void SetType (uint8_t type); + + /** + * \return the type assigned to this packet + */ + uint8_t GetType (void) const; + + /** + * \brief Sets the address for the node that created this packet. + * \param address the originator address. + */ + void SetOriginatorAddress (Address address); + + /** + * \return the address of the node that created this packet. + * + * Calling this while HasOriginatorAddress is False is undefined. Make sure + * you check it first. This will be checked by an assert in debug builds. + */ + Address GetOriginatorAddress (void) const; + + /** + * \brief Tests whether or not this message has an originator address. + * \return true if this message has an originator address, false otherwise. + */ + bool HasOriginatorAddress (void) const; + + /** + * \brief Sets the maximum number of hops this message should travel + * \param hoplimit the limit to set + */ + void SetHopLimit (uint8_t hoplimit); + + /** + * \return the maximum number of hops this message should travel. + * + * Calling this while HasHopLimit is False is undefined. Make sure you check + * it first. This will be checked by an assert in debug builds. + */ + uint8_t GetHopLimit (void) const; + + /** + * \brief Tests whether or not this message has a hop limit. + * \return true if this message has a hop limit, false otherwise. + * + * If this is set, messages should not hop further than this limit. + */ + bool HasHopLimit (void) const; + + /** + * \brief Sets the current number of hops this message has traveled. + * \param hopcount the current number of hops + */ + void SetHopCount (uint8_t hopcount); + + /** + * \return the current number of hops this message has traveled. + * + * Calling this while HasHopCount is False is undefined. Make sure you check + * it first. This will be checked by an assert in debug builds. + */ + uint8_t GetHopCount (void) const; + + /** + * \brief Tests whether or not this message has a hop count. + * \return true if this message has a hop limit, false otherwise. + */ + bool HasHopCount (void) const; + + /** + * \brief Sets the sequence number of this message. + * \param seqnum the sequence number to set. + */ + void SetSequenceNumber (uint16_t seqnum); + + /** + * \return the sequence number of this message. + * + * Calling this while HasSequenceNumber is False is undefined. Make sure you + * check it first. This will be checked by an assert in debug builds. + */ + uint16_t GetSequenceNumber (void) const; + + /** + * \brief Tests whether or not this message has a sequence number. + * \return true if this message has a sequence number, false otherwise. + */ + bool HasSequenceNumber (void) const; + + /* Manipulating PbbMessage TLVs */ + + /** + * \return an iterator to the first message TLV in this message. + */ + TlvIterator TlvBegin (); + + /** + * \return a const iterator to the first message TLV in this message. + */ + ConstTlvIterator TlvBegin () const; + + /** + * \return an iterator to the past-the-end message TLV element in this + * message. + */ + TlvIterator TlvEnd (); + + /** + * \return a const iterator to the past-the-end message TLV element in this + * message. + */ + ConstTlvIterator TlvEnd () const; + + /** + * \return the number of message TLVs in this message. + */ + int TlvSize (void) const; + + /** + * \return true if there are no message TLVs in this message, false otherwise. + */ + bool TlvEmpty (void) const; + + /** + * \return a smart pointer to the first message TLV in this message. + */ + Ptr TlvFront (void); + + /** + * \return a const smart pointer to the first message TLV in this message. + */ + const Ptr TlvFront (void) const; + + /** + * \return a smart pointer to the last message TLV in this message. + */ + Ptr TlvBack (void); + + /** + * \return a const smart pointer to the last message TLV in this message. + */ + const Ptr TlvBack (void) const; + + /** + * \brief Prepends a message TLV to the front of this message. + * \param tlv a smart pointer to the message TLV to prepend. + */ + void TlvPushFront (Ptr tlv); + + /** + * \brief Removes a message TLV from the front of this message. + */ + void TlvPopFront (void); + + /** + * \brief Appends a message TLV to the back of this message. + * \param tlv a smart pointer to the message TLV to append. + */ + void TlvPushBack (Ptr tlv); + + /** + * \brief Removes a message TLV from the back of this message. + */ + void TlvPopBack (void); + + /** + * \brief Removes the message TLV at the specified position. + * \param position an Iterator pointing to the message TLV to erase. + * \return an iterator pointing to the next TLV in the block. + */ + TlvIterator TlvErase (TlvIterator position); + + /** + * \brief Removes all message TLVs from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first message TLV to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last message TLV + * to erase. + * \return an iterator pointing to the next message TLV in the message. + */ + TlvIterator TlvErase (TlvIterator first, TlvIterator last); + + /** + * \brief Removes all message TLVs from this block. + */ + void TlvClear (void); + + /* Manipulating Address Block and Address TLV pairs */ + + /** + * \return an iterator to the first address block in this message. + */ + AddressBlockIterator AddressBlockBegin (); + + /** + * \return a const iterator to the first address block in this message. + */ + ConstAddressBlockIterator AddressBlockBegin () const; + + /** + * \return an iterator to the past-the-end address block element in this + * message. + */ + AddressBlockIterator AddressBlockEnd (); + + /** + * \return a const iterator to the past-the-end address block element in this + * message. + */ + ConstAddressBlockIterator AddressBlockEnd () const; + + /** + * \return the number of address blocks in this message. + */ + int AddressBlockSize (void) const; + + /** + * \return true if there are no address blocks in this message, false + * otherwise. + */ + bool AddressBlockEmpty (void) const; + + /** + * \return a smart pointer to the first address block in this message. + */ + Ptr AddressBlockFront (void); + + /** + * \return a const smart pointer to the first address block in this message. + */ + const Ptr AddressBlockFront (void) const; + + /** + * \return a smart pointer to the last address block in this message. + */ + Ptr AddressBlockBack (void); + + /** + * \return a const smart pointer to the last address block in this message. + */ + const Ptr AddressBlockBack (void) const; + + /** + * \brief Prepends an address block to the front of this message. + * \param block a smart pointer to the address block to prepend. + */ + void AddressBlockPushFront (Ptr block); + + /** + * \brief Removes an address block from the front of this message. + */ + void AddressBlockPopFront (void); + + /** + * \brief Appends an address block to the front of this message. + * \param block a smart pointer to the address block to append. + */ + void AddressBlockPushBack (Ptr block); + + /** + * \brief Removes an address block from the back of this message. + */ + void AddressBlockPopBack (void); + + /** + * \brief Removes the address block at the specified position. + * \param position an Iterator pointing to the address block to erase. + * \return an iterator pointing to the next address block in the message. + */ + AddressBlockIterator AddressBlockErase (AddressBlockIterator position); + + /** + * \brief Removes all address blocks from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first address block to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last address + * block to erase. + * \return an iterator pointing to the next address block in the message. + */ + AddressBlockIterator AddressBlockErase (AddressBlockIterator first, + AddressBlockIterator last); + + /** + * \brief Removes all address blocks from this message. + */ + void AddressBlockClear (void); + + /* Smart pointer methods */ + void Ref (void) const; + void Unref (void) const; + + /** + * \brief Deserializes a message, returning the correct object depending on + * whether it is an IPv4 message or an IPv6 message. + * \param start a reference to the point in a buffer to begin deserializing. + * \return A pointer to the deserialized message, or 0 on error. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + static Ptr DeserializeMessage (Buffer::Iterator &start); + + /** + * \return The size (in bytes) needed to serialize this message. + */ + uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this message into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Serialize (Buffer::Iterator &start) const; + + /** + * \brief Deserializes a message from the specified buffer. + * \param start a reference to the point in a buffer to begin deserializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Deserialize (Buffer::Iterator &start); + + /** + * \brief Pretty-prints the contents of this message. + * \param os a stream object to print to. + */ + void Print (std::ostream &os) const; + + /** + * \brief Pretty-prints the contents of this message, with specified + * indentation. + * \param os a stream object to print to. + * \param level level of indentation. + * + * This probably never needs to be called by users. This is used when + * recursively printing sub-objects. + */ + void Print (std::ostream &os, int level) const; + + bool operator== (const PbbMessage &other) const; + bool operator!= (const PbbMessage &other) const; + +protected: + /* PbbMessage size in bytes - 1. + * + * IPv4 = 4 - 1 = 3, IPv6 = 16 - 1 = 15 + */ + virtual PbbAddressLength GetAddressLength (void) const = 0; + + virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const = 0; + virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const = 0; + virtual void PrintOriginatorAddress (std::ostream &os) const = 0; + + virtual Ptr AddressBlockDeserialize (Buffer::Iterator &start) const = 0; + +private: + PbbTlvBlock m_tlvList; + std::list< Ptr > m_addressBlockList; + + uint8_t m_type; + PbbAddressLength m_addrSize; + + bool m_hasOriginatorAddress; + Address m_originatorAddress; + + bool m_hasHopLimit; + uint8_t m_hopLimit; + + bool m_hasHopCount; + uint8_t m_hopCount; + + bool m_hasSequenceNumber; + uint16_t m_sequenceNumber; + + mutable uint32_t m_refCount; +}; + +/** + * \brief Concrete IPv4 specific PbbMessage. + * + * This message will only contain IPv4 addresses. + */ +class PbbMessageIpv4 : public PbbMessage { +protected: + virtual PbbAddressLength GetAddressLength (void) const; + + virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const; + virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const; + virtual void PrintOriginatorAddress (std::ostream &os) const; + + virtual Ptr AddressBlockDeserialize (Buffer::Iterator &start) const; +}; + +/** + * \brief Concrete IPv6 specific PbbMessage class. + * + * This message will only contain IPv6 addresses. + */ +class PbbMessageIpv6 : public PbbMessage { +protected: + virtual PbbAddressLength GetAddressLength (void) const; + + virtual void SerializeOriginatorAddress (Buffer::Iterator &start) const; + virtual Address DeserializeOriginatorAddress (Buffer::Iterator &start) const; + virtual void PrintOriginatorAddress (std::ostream &os) const; + + virtual Ptr AddressBlockDeserialize (Buffer::Iterator &start) const; +}; + +/** + * \brief An Address Block and its associated Address TLV Blocks. + * + * This is a pure virtual base class, when creating address blocks, you should + * instantiate either PbbAddressBlockIpv4 or PbbAddressBlockIpv6. + */ +class PbbAddressBlock +{ +public: + typedef std::list< Address >::iterator AddressIterator; + typedef std::list< Address >::const_iterator ConstAddressIterator; + + typedef std::list::iterator PrefixIterator; + typedef std::list::const_iterator ConstPrefixIterator; + + typedef PbbAddressTlvBlock::Iterator TlvIterator; + typedef PbbAddressTlvBlock::ConstIterator ConstTlvIterator; + + PbbAddressBlock (void); + + /* Manipulating the address block */ + + /** + * \return an iterator to the first address in this block. + */ + AddressIterator AddressBegin (void); + + /** + * \return a const iterator to the first address in this block. + */ + ConstAddressIterator AddressBegin (void) const; + + /** + * \return an iterator to the last address in this block. + */ + AddressIterator AddressEnd (void); + + /** + * \return a const iterator to the last address in this block. + */ + ConstAddressIterator AddressEnd (void) const; + + /** + * \return the number of addresses in this block. + */ + int AddressSize (void) const; + + /** + * \return true if there are no addresses in this block, false otherwise. + */ + bool AddressEmpty (void) const; + + /** + * \return the first address in this block. + */ + Address AddressFront (void) const; + + /** + * \return the last address in this block. + */ + Address AddressBack (void) const; + + /** + * \brief Prepends an address to the front of this block. + * \param address the address to prepend. + */ + void AddressPushFront (Address address); + + /** + * \brief Removes an address from the front of this block. + */ + void AddressPopFront (void); + + /** + * \brief Appends an address to the back of this block. + * \param address the address to append. + */ + void AddressPushBack (Address address); + + /** + * \brief Removes an address from the back of this block. + */ + void AddressPopBack (void); + + /** + * \brief Inserts an address at the specified position in this block. + * \param position an Iterator pointing to the position in this block to + * insert the address. + * \param value the address to insert. + * \return An iterator pointing to the newly inserted address. + */ + AddressIterator AddressInsert (AddressIterator position, + const Address value); + + /** + * \brief Removes the address at the specified position. + * \param position an Iterator pointing to the address to erase. + * \return an iterator pointing to the next address in the block. + */ + AddressIterator AddressErase (AddressIterator position); + + /** + * \brief Removes all addresses from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first address to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last address to + * erase. + * \return an iterator pointing to the next address in the block. + */ + AddressIterator AddressErase (AddressIterator first, AddressIterator last); + + /** + * \brief Removes all addresses from this block. + */ + void AddressClear (void); + + /* Prefix methods */ + + /** + * \return an iterator to the first prefix in this block. + */ + PrefixIterator PrefixBegin (void); + + /** + * \return a const iterator to the first prefix in this block. + */ + ConstPrefixIterator PrefixBegin (void) const; + + /** + * \return an iterator to the last prefix in this block. + */ + PrefixIterator PrefixEnd (void); + + /** + * \return a const iterator to the last prefix in this block. + */ + ConstPrefixIterator PrefixEnd (void) const; + + /** + * \return the number of prefixes in this block. + */ + int PrefixSize (void) const; + + /** + * \return true if there are no prefixes in this block, false otherwise. + */ + bool PrefixEmpty (void) const; + + /** + * \return the first prefix in this block. + */ + uint8_t PrefixFront (void) const; + + /** + * \return the last prefix in this block. + */ + uint8_t PrefixBack (void) const; + + /** + * \brief Prepends a prefix to the front of this block. + * \param prefix the prefix to prepend. + */ + void PrefixPushFront (uint8_t prefix); + + /** + * \brief Removes a prefix from the front of this block. + */ + void PrefixPopFront (void); + + /** + * \brief Appends a prefix to the back of this block. + * \param prefix the prefix to append. + */ + void PrefixPushBack (uint8_t prefix); + + /** + * \brief Removes a prefix from the back of this block. + */ + void PrefixPopBack (void); + + /** + * \brief Inserts a prefix at the specified position in this block. + * \param position an Iterator pointing to the position in this block to + * insert the prefix. + * \param value the prefix to insert. + * \return An iterator pointing to the newly inserted prefix. + */ + PrefixIterator PrefixInsert (PrefixIterator position, const uint8_t value); + + /** + * \brief Removes the prefix at the specified position. + * \param position an Iterator pointing to the prefix to erase. + * \return an iterator pointing to the next prefix in the block. + */ + PrefixIterator PrefixErase (PrefixIterator position); + + /** + * \brief Removes all prefixes from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first prefix to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last prefix to + * erase. + * \return an iterator pointing to the next prefix in the block. + */ + PrefixIterator PrefixErase (PrefixIterator first, PrefixIterator last); + + /** + * \brief Removes all prefixes from this block. + */ + void PrefixClear (void); + + /* Manipulating the TLV block */ + + /** + * \return an iterator to the first address TLV in this block. + */ + TlvIterator TlvBegin (void); + + /** + * \return a const iterator to the first address TLV in this block. + */ + ConstTlvIterator TlvBegin (void) const; + + /** + * \return an iterator to the last address TLV in this block. + */ + TlvIterator TlvEnd (void); + + /** + * \return a const iterator to the last address TLV in this block. + */ + ConstTlvIterator TlvEnd (void) const; + + /** + * \return the number of address TLVs in this block. + */ + int TlvSize (void) const; + + /** + * \return true if there are no address TLVs in this block, false otherwise. + */ + bool TlvEmpty (void) const; + + /** + * \return a smart pointer to the first address TLV in this block. + */ + Ptr TlvFront (void); + + /** + * \return a const smart pointer to the first address TLV in this message. + */ + const Ptr TlvFront (void) const; + + /** + * \return a smart pointer to the last address TLV in this message. + */ + Ptr TlvBack (void); + + /** + * \return a const smart pointer to the last address TLV in this message. + */ + const Ptr TlvBack (void) const; + + /** + * \brief Prepends an address TLV to the front of this message. + * \param address a smart pointer to the address TLV to prepend. + */ + void TlvPushFront (Ptr address); + + /** + * \brief Removes an address TLV from the front of this message. + */ + void TlvPopFront (void); + + /** + * \brief Appends an address TLV to the back of this message. + * \param address a smart pointer to the address TLV to append. + */ + void TlvPushBack (Ptr address); + + /** + * \brief Removes an address TLV from the back of this message. + */ + void TlvPopBack (void); + + /** + * \brief Inserts an address TLV at the specified position in this block. + * \param position an Iterator pointing to the position in this block to + * insert the address TLV. + * \param value the prefix to insert. + * \return An iterator pointing to the newly inserted address TLV. + */ + TlvIterator TlvInsert (TlvIterator position, const Ptr value); + + /** + * \brief Removes the address TLV at the specified position. + * \param position an Iterator pointing to the address TLV to erase. + * \return an iterator pointing to the next address TLV in the block. + */ + TlvIterator TlvErase (TlvIterator position); + + /** + * \brief Removes all address TLVs from [first, last) (includes first, not + * includes last). + * \param first an Iterator pointing to the first address TLV to erase + * (inclusive). + * \param last an Iterator pointing to the element past the last address TLV + * to erase. + * \return an iterator pointing to the next address TLV in the message. + */ + TlvIterator TlvErase (TlvIterator first, TlvIterator last); + + /** + * \brief Removes all address TLVs from this block. + */ + void TlvClear (void); + + /* Smart pointer methods */ + void Ref (void) const; + void Unref (void) const; + + /** + * \return The size (in bytes) needed to serialize this address block. + */ + uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this address block into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Serialize (Buffer::Iterator &start) const; + + /** + * \brief Deserializes an address block from the specified buffer. + * \param start a reference to the point in a buffer to begin deserializing. + * + * Users should not need to call this. Blocks will be deserialized by their + * containing packet. + */ + void Deserialize (Buffer::Iterator &start); + + /** + * \brief Pretty-prints the contents of this address block. + * \param os a stream object to print to. + */ + void Print (std::ostream &os) const; + + /** + * \brief Pretty-prints the contents of this address block, with specified + * indentation. + * \param os a stream object to print to. + * \param level level of indentation. + * + * This probably never needs to be called by users. This is used when + * recursively printing sub-objects. + */ + void Print (std::ostream &os, int level) const; + + bool operator== (const PbbAddressBlock &other) const; + bool operator!= (const PbbAddressBlock &other) const; + +protected: + virtual uint8_t GetAddressLength (void) const = 0; + + virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const = 0; + virtual Address DeserializeAddress (uint8_t *buffer) const = 0; + virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const = 0; + +private: + uint8_t GetPrefixFlags (void) const; + void GetHeadTail (uint8_t *head, uint8_t &headlen, + uint8_t *tail, uint8_t &taillen) const; + bool HasZeroTail (const uint8_t *tail, uint8_t taillen) const; + + std::list
m_addressList; + std::list m_prefixList; + PbbAddressTlvBlock m_addressTlvList; + + mutable uint32_t m_refCount; +}; + +/** + * \brief Concrete IPv4 specific PbbAddressBlock. + * + * This address block will only contain IPv4 addresses. + */ +class PbbAddressBlockIpv4 : public PbbAddressBlock +{ +protected: + virtual uint8_t GetAddressLength (void) const; + + virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const; + virtual Address DeserializeAddress (uint8_t *buffer) const; + virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const; +}; + +/** + * \brief Concrete IPv6 specific PbbAddressBlock. + * + * This address block will only contain IPv6 addresses. + */ +class PbbAddressBlockIpv6 : public PbbAddressBlock +{ +protected: + virtual uint8_t GetAddressLength (void) const; + + virtual void SerializeAddress (uint8_t *buffer, ConstAddressIterator iter) const; + virtual Address DeserializeAddress (uint8_t *buffer) const; + virtual void PrintAddress (std::ostream &os, ConstAddressIterator iter) const; +}; + +/** + * \brief A packet or message TLV + */ +class PbbTlv +{ +public: + PbbTlv (void); + + /** + * \brief Sets the type of this TLV. + * \param type the type value to set. + */ + void SetType (uint8_t type); + + /** + * \return the type of this TLV. + */ + uint8_t GetType (void) const; + + /** + * \brief Sets the type extension of this TLV. + * \param type the type extension value to set. + * + * The type extension is like a sub-type used to further distinguish between + * TLVs of the same type. + */ + void SetTypeExt (uint8_t type); + + /** + * \return the type extension for this TLV. + * + * Calling this while HasTypeExt is False is undefined. Make sure you check + * it first. This will be checked by an assert in debug builds. + */ + uint8_t GetTypeExt (void) const; + + /** + * \brief Tests whether or not this TLV has a type extension. + * \return true if this TLV has a type extension, false otherwise. + * + * This should be called before calling GetTypeExt to make sure there + * actually is one. + */ + bool HasTypeExt (void) const; + + /** + * \brief Sets the value of this message to the specified buffer. + * \param start a buffer instance. + * + * The buffer is _not_ copied until this TLV is serialized. You should not + * change the contents of the buffer you pass in to this function. + */ + void SetValue (Buffer start); + + /** + * \brief Sets the value of this message to a buffer with the specified data. + * \param buffer a pointer to data to put in the TLVs buffer. + * \param size the size of the buffer. + * + * The buffer *is copied* into a *new buffer instance*. You can free the + * data in the buffer provided anytime you wish. + */ + void SetValue (const uint8_t * buffer, uint32_t size); + + /** + * \return a Buffer pointing to the value of this TLV. + * + * Calling this while HasValue is False is undefined. Make sure you check it + * first. This will be checked by an assert in debug builds. + */ + Buffer GetValue (void) const; + + /** + * \brief Tests whether or not this TLV has a value. + * \return true if this tlv has a TLV, false otherwise. + * + * This should be called before calling GetTypeExt to make sure there + * actually is one. + */ + bool HasValue (void) const; + + /* Smart pointer methods */ + void Ref (void) const; + void Unref (void) const; + + /** + * \return The size (in bytes) needed to serialize this TLV. + */ + uint32_t GetSerializedSize (void) const; + + /** + * \brief Serializes this TLV into the specified buffer. + * \param start a reference to the point in a buffer to begin serializing. + * + * Users should not need to call this. TLVs will be serialized by their + * containing blocks. + */ + void Serialize (Buffer::Iterator &start) const; + + /** + * \brief Deserializes a TLV from the specified buffer. + * \param start a reference to the point in a buffer to begin deserializing. + * + * Users should not need to call this. TLVs will be deserialized by their + * containing blocks. + */ + void Deserialize (Buffer::Iterator &start); + + /** + * \brief Pretty-prints the contents of this TLV. + * \param os a stream object to print to. + */ + void Print (std::ostream &os) const; + + /** + * \brief Pretty-prints the contents of this TLV, with specified indentation. + * \param os a stream object to print to. + * \param level level of indentation. + * + * This probably never needs to be called by users. This is used when + * recursively printing sub-objects. + */ + void Print (std::ostream &os, int level) const; + + bool operator== (const PbbTlv &other) const; + bool operator!= (const PbbTlv &other) const; + +protected: + void SetIndexStart (uint8_t index); + uint8_t GetIndexStart (void) const; + bool HasIndexStart (void) const; + + void SetIndexStop (uint8_t index); + uint8_t GetIndexStop (void) const; + bool HasIndexStop (void) const; + + void SetMultivalue (bool isMultivalue); + bool IsMultivalue (void) const; + +private: + uint8_t m_type; + + bool m_hasTypeExt; + uint8_t m_typeExt; + + bool m_hasIndexStart; + uint8_t m_indexStart; + + bool m_hasIndexStop; + uint8_t m_indexStop; + + bool m_isMultivalue; + bool m_hasValue; + Buffer m_value; + + mutable uint32_t m_refCount; +}; + +/** + * \brief An Address TLV + */ +class PbbAddressTlv : public PbbTlv +{ +public: + /** + * \brief Sets the index of the first address in the associated address block + * that this address TLV applies to. + * \param index the index of the first address. + */ + void SetIndexStart (uint8_t index); + + /** + * \return the first (inclusive) index of the address in the corresponding + * address block that this TLV applies to. + * + * Calling this while HasIndexStart is False is undefined. Make sure you + * check it first. This will be checked by an assert in debug builds. + */ + uint8_t GetIndexStart (void) const; + + /** + * \brief Tests whether or not this address TLV has a start index. + * \return true if this address TLV has a start index, false otherwise. + * + * This should be called before calling GetIndexStart to make sure there + * actually is one. + */ + bool HasIndexStart (void) const; + + /** + * \brief Sets the index of the last address in the associated address block + * that this address TLV applies to. + * \param index the index of the last address. + */ + void SetIndexStop (uint8_t index); + + /** + * \return the last (inclusive) index of the address in the corresponding + * PbbAddressBlock that this TLV applies to. + * + * Calling this while HasIndexStop is False is undefined. Make sure you + * check it first. This will be checked by an assert in debug builds. + */ + uint8_t GetIndexStop (void) const; + + /** + * \brief Tests whether or not this address TLV has a stop index. + * \return true if this address TLV has a stop index, false otherwise. + * + * This should be called before calling GetIndexStop to make sure there + * actually is one. + */ + bool HasIndexStop (void) const; + + /** + * \brief Sets whether or not this address TLV is "multivalue" + * \param isMultivalue whether or not this address TLV should be multivalue. + * + * If true, this means the value associated with this TLV should be divided + * evenly into (GetIndexStop() - GetIndexStart() + 1) values. Otherwise, the + * value is one single value that applies to each address in the range. + */ + void SetMultivalue (bool isMultivalue); + + /** + * \brief Tests whether or not this address TLV is "multivalue" + * \return whether this address TLV is multivalue or not. + */ + bool IsMultivalue (void) const; +}; + +} /* namespace ns3 */ + +#endif /* PACKETBB_H */ diff --git a/src/node/test-packetbb.cc b/src/node/test-packetbb.cc new file mode 100644 index 000000000..28f9fa1d5 --- /dev/null +++ b/src/node/test-packetbb.cc @@ -0,0 +1,3835 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* vim: set ts=2 sw=2 sta expandtab ai si cin: */ +/* + * Copyright (c) 2009 Drexel University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Tom Wambold + */ + +#include + +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv6-address.h" +#include "ns3/packetbb.h" + +using namespace std; +using namespace ns3; + +class PacketBBTester +{ +public: + PacketBBTester (int testnum, PbbPacket &reference, const uint8_t * buffer, + uint32_t size) : + m_refPacket(reference) + { + m_refBuffer.AddAtStart (size); + m_refBuffer.Begin ().Write (buffer, size); + + cout << "Test " << testnum << " - "; + Test (); + } + + void Test (void) + { + if (TestSerialize ()) + { + cout << "Serialize Pass, "; + } + else + { + cout << "Serialize Fail, "; + } + + if (TestDeserialize ()) + { + cout << "Deserialize Pass"; + } + else + { + cout << "Deserialize Fail"; + } + + cout << endl; + } + + bool TestSerialize (void) + { + Buffer newBuffer; + newBuffer.AddAtStart (m_refPacket.GetSerializedSize ()); + m_refPacket.Serialize (newBuffer.Begin ()); + return CompareBuffers (m_refBuffer, newBuffer); + } + + bool TestDeserialize (void) + { + PbbPacket newPacket; + if (newPacket.Deserialize (m_refBuffer.Begin ()) != m_refBuffer.GetSize ()) + { + return false; + } + return m_refPacket == newPacket; + } + +private: + static bool CompareBuffers (Buffer a, Buffer b) + { + const uint8_t * abuf = a.PeekData (); + const uint8_t * bbuf = b.PeekData (); + + for (unsigned int i = 0; i < a.GetSize (); i++) + { + if (abuf[i] != bbuf[i]) + { + cout << "Difference - [" << i << "] - " << (int)abuf[i] << " - " << (int)bbuf[i] << endl; + } + } + + if (a.GetSize () != b.GetSize ()) + { + cout << "Buffers differ in size: " << a.GetSize () << ", " << b.GetSize() << endl; + return false; + } + + if (memcmp (a.PeekData (), b.PeekData (), a.GetSize ()) != 0) + { + return false; + } + + return true; + } + + Buffer m_refBuffer; + PbbPacket &m_refPacket; +}; + +int main (void) +{ + /* These tests are from: + * http://interop08.thomasclausen.org/packets-and-dumps.txt + */ + int testnum = 1; + + /* Test 1 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * `------------------ + */ + { + PbbPacket packet; + uint8_t buffer[] = {0x00}; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 2 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 8 + * | * Packet seq number: 2 + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (2); + uint8_t buffer[] = {0x08, 0x00, 0x02}; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 3 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 3 + * `------------------ + * This test has the phastlv flag set to 1 with no tlvs. + * I'll come back to this one later. + { + PbbPacket packet; + packet.SetSequenceNumber (3); + uint8_t buffer[] = {0x0c, 0x00, 0x03, 0x00, 0x00}; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + */ + std::cout << "Skipping test " << testnum++ << std::endl; + + /* Test 4 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 4 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (4); + + Ptr tlv = Create(); + tlv->SetType (1); + + packet.TlvPushBack (tlv); + uint8_t buffer[] = { + 0x0c, 0x00, 0x04, 0x00, + 0x02, 0x01, 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 5 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 5 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | | - TLV + * | | Flags = 128 + * | | Type = 2; Type ext. = 100; Value = (warning: parameter is NULL) + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (5); + + Ptr tlv1 = Create(); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr tlv2 = Create(); + tlv2->SetType (2); + tlv2->SetTypeExt (100); + packet.TlvPushBack (tlv2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x05, 0x00, + 0x05, 0x01, 0x00, 0x02, + 0x80, 0x64 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 6 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 6 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | | - TLV + * | | Flags = 144 + * | | Type = 2; Type ext. = 100; Value = 01 02 03 04 + * | | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (6); + + Ptr tlv1 = Create(); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr tlv2 = Create(); + tlv2->SetType (2); + tlv2->SetTypeExt (100); + + uint8_t tlv2val[] = {1, 2, 3, 4}; + tlv2->SetValue(tlv2val, sizeof(tlv2val)); + + packet.TlvPushBack (tlv2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x06, 0x00, + 0x0a, 0x01, 0x00, 0x02, + 0x90, 0x64, 0x04, 0x01, + 0x02, 0x03, 0x04 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 7 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 7 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | | - TLV + * | | Flags = 152 + * | | Type = 2; Type ext. = 100; Value = 00 01 02 03 + * | | 04 05 06 07 + * | | 08 09 0a 0b + * | | 0c 0d 0e 0f + * | | 10 11 12 13 + * | | 14 15 16 17 + * | | 18 19 1a 1b + * | | 1c 1d 1e 1f + * | | 20 21 22 23 + * | | 24 25 26 27 + * | | 28 29 2a 2b + * | | 2c 2d 2e 2f + * | | 30 31 32 33 + * | | 34 35 36 37 + * | | 38 39 3a 3b + * | | 3c 3d 3e 3f + * | | 40 41 42 43 + * | | 44 45 46 47 + * | | 48 49 4a 4b + * | | 4c 4d 4e 4f + * | | 50 51 52 53 + * | | 54 55 56 57 + * | | 58 59 5a 5b + * | | 5c 5d 5e 5f + * | | 60 61 62 63 + * | | 64 65 66 67 + * | | 68 69 6a 6b + * | | 6c 6d 6e 6f + * | | 70 71 72 73 + * | | 74 75 76 77 + * | | 78 79 7a 7b + * | | 7c 7d 7e 7f + * | | 80 81 82 83 + * | | 84 85 86 87 + * | | 88 89 8a 8b + * | | 8c 8d 8e 8f + * | | 90 91 92 93 + * | | 94 95 96 97 + * | | 98 99 9a 9b + * | | 9c 9d 9e 9f + * | | a0 a1 a2 a3 + * | | a4 a5 a6 a7 + * | | a8 a9 aa ab + * | | ac ad ae af + * | | b0 b1 b2 b3 + * | | b4 b5 b6 b7 + * | | b8 b9 ba bb + * | | bc bd be bf + * | | c0 c1 c2 c3 + * | | c4 c5 c6 c7 + * | | c8 c9 ca cb + * | | cc cd ce cf + * | | d0 d1 d2 d3 + * | | d4 d5 d6 d7 + * | | d8 d9 da db + * | | dc dd de df + * | | e0 e1 e2 e3 + * | | e4 e5 e6 e7 + * | | e8 e9 ea eb + * | | ec ed ee ef + * | | f0 f1 f2 f3 + * | | f4 f5 f6 f7 + * | | f8 f9 fa fb + * | | fc fd fe 00 + * | | 01 02 03 04 + * | | 05 06 07 08 + * | | 09 0a 0b 0c + * | | 0d 0e 0f 10 + * | | 11 12 13 14 + * | | 15 16 17 18 + * | | 19 1a 1b 1c + * | | 1d 1e 1f 20 + * | | 21 22 23 24 + * | | 25 26 27 28 + * | | 29 2a 2b 2c + * | | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (7); + + Ptr tlv1 = Create(); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr tlv2 = Create(); + tlv2->SetType (2); + tlv2->SetTypeExt (100); + + uint8_t tlv2val[] = { + 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, + 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c + }; + tlv2->SetValue(tlv2val, sizeof(tlv2val)); + + packet.TlvPushBack (tlv2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x07, 0x01, + 0x33, 0x01, 0x00, 0x02, + 0x98, 0x64, 0x01, 0x2c, + 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, + 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 8 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 8 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (8); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 9 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 9 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 128 + * | | * Originator address: 10.0.0.1 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (9); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x09, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00, 0x02, 0x83, 0x00, /* [14] used to be 0x80 */ + 0x0a, 0x0a, 0x00, 0x00, + 0x01, 0x00, 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 10 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 10 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 160 + * | | * Originator address: 10.0.0.1 + * | | * Hop count: 1 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (10); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + msg2->SetHopCount (1); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0a, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00, 0x02, 0xa3, 0x00, /* [14] used to be 0xa0 */ + 0x0b, 0x0a, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 11 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 11 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 224 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (11); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0b, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00, 0x02, 0xe3, 0x00, /* [14] used to be 0xe0 */ + 0x0c, 0x0a, 0x00, 0x00, + 0x01, 0xff, 0x01, 0x00, + 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 12 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 12 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (12); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0c, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00, 0x02, 0xf3, 0x00, /* [14] - 0xf0 */ + 0x0e, 0x0a, 0x00, 0x00, + 0x01, 0xff, 0x01, 0x30, + 0x39, 0x00, 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 13 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 13 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (13); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0d, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x06, 0x00, + 0x00, 0x02, 0xf3, 0x00, /* [14] - 0xf0 */ + 0x0e, 0x0a, 0x00, 0x00, + 0x01, 0xff, 0x01, 0x30, + 0x39, 0x00, 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 14 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 14 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (14); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress(Ipv4Address("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0e, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x0e, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 15 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 15 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (1 addresses) + * | | - 0.0.0.0/32 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (15); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("0.0.0.0")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x0f, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x16, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 16 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 16 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (1 addresses) + * | | - 255.255.255.255/32 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (16); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("255.255.255.255")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x10, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x16, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x01, 0x00, 0xff, + 0xff, 0xff, 0xff, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 17 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 17 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (1 addresses) + * | | - 0.0.0.1/32 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (17); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("0.0.0.1")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x11, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x16, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 18 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 18 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (1 addresses) + * | | - 10.0.0.0/32 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (18); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x12, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x16, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x01, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 19 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 19 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (1 addresses) + * | | - 10.0.0.1/32 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (19); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.1")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x13, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x16, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x01, 0x00, 0x0a, + 0x00, 0x00, 0x01, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 20 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 20 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.1/32 + * | | - 10.0.0.2/32 + * | | - Flags = 128 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (20); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.1")); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x14, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x18, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0x80, 0x03, + 0x0a, 0x00, 0x00, 0x01, + 0x02, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 21 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 21 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (21); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x15, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x1a, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 22 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 22 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (2 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - Flags = 32 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (22); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x16, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x21, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x02, 0x20, 0x03, + 0x0a, 0x0b, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 23 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 23 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (23); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x17, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x32, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 24 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 24 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (24); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + Ptr msg2a2tlv1 = Create (); + msg2a2tlv1->SetType (1); + msg2a2->TlvPushBack (msg2a2tlv1); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x18, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x34, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x00, + 0x02, 0x01, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 25 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 25 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 64 + * | | Index-start = 1 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (25); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + Ptr msg2a2tlv1 = Create (); + msg2a2tlv1->SetType (1); + msg2a2tlv1->SetIndexStart (1); + msg2a2->TlvPushBack (msg2a2tlv1); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x19, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x35, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x00, + 0x03, 0x01, 0x40, 0x01, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 26 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 26 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 32 + * | | Index-start = 1 + * | | Index-stop = 3 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (26); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + Ptr msg2a2tlv1 = Create (); + msg2a2tlv1->SetType (1); + msg2a2tlv1->SetIndexStart (1); + msg2a2tlv1->SetIndexStop (3); + msg2a2->TlvPushBack (msg2a2tlv1); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x1a, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x36, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x00, + 0x04, 0x01, 0x20, 0x01, + 0x03, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 27 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 27 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 52 + * | | Index-start = 1 + * | | Index-stop = 3 + * | | Type = 1; Value = 01 02 03 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (27); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + Ptr msg2a2tlv1 = Create (); + msg2a2tlv1->SetType (1); + msg2a2tlv1->SetIndexStart (1); + msg2a2tlv1->SetIndexStop (3); + + uint8_t value[] = {1, 2, 3}; + msg2a2tlv1->SetValue(value, sizeof (value)); + msg2a2tlv1->SetMultivalue (true); + + msg2a2->TlvPushBack (msg2a2tlv1); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x1b, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x00, 0x3a, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x00, + 0x08, 0x01, 0x34, 0x01, + 0x03, 0x03, 0x01, 0x02, + 0x03, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 28 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 28 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 56 + * | | Index-start = 1 + * | | Index-stop = 3 + * | | Type = 1; Value = 00 01 02 03 + * | | 04 05 06 07 + * | | 08 09 0a 0b + * | | 0c 0d 0e 0f + * | | 10 11 12 13 + * | | 14 15 16 17 + * | | 18 19 1a 1b + * | | 1c 1d 1e 1f + * | | 20 21 22 23 + * | | 24 25 26 27 + * | | 28 29 2a 2b + * | | 2c 2d 2e 2f + * | | 30 31 32 33 + * | | 34 35 36 37 + * | | 38 39 3a 3b + * | | 3c 3d 3e 3f + * | | 40 41 42 43 + * | | 44 45 46 47 + * | | 48 49 4a 4b + * | | 4c 4d 4e 4f + * | | 50 51 52 53 + * | | 54 55 56 57 + * | | 58 59 5a 5b + * | | 5c 5d 5e 5f + * | | 60 61 62 63 + * | | 64 65 66 67 + * | | 68 69 6a 6b + * | | 6c 6d 6e 6f + * | | 70 71 72 73 + * | | 74 75 76 77 + * | | 78 79 7a 7b + * | | 7c 7d 7e 7f + * | | 80 81 82 83 + * | | 84 85 86 87 + * | | 88 89 8a 8b + * | | 8c 8d 8e 8f + * | | 90 91 92 93 + * | | 94 95 96 97 + * | | 98 99 9a 9b + * | | 9c 9d 9e 9f + * | | a0 a1 a2 a3 + * | | a4 a5 a6 a7 + * | | a8 a9 aa ab + * | | ac ad ae af + * | | b0 b1 b2 b3 + * | | b4 b5 b6 b7 + * | | b8 b9 ba bb + * | | bc bd be bf + * | | c0 c1 c2 c3 + * | | c4 c5 c6 c7 + * | | c8 c9 ca cb + * | | cc cd ce cf + * | | d0 d1 d2 d3 + * | | d4 d5 d6 d7 + * | | d8 d9 da db + * | | dc dd de df + * | | e0 e1 e2 e3 + * | | e4 e5 e6 e7 + * | | e8 e9 ea eb + * | | ec ed ee ef + * | | f0 f1 f2 f3 + * | | f4 f5 f6 f7 + * | | f8 f9 fa fb + * | | fc fd fe 00 + * | | 01 02 03 04 + * | | 05 06 07 08 + * | | 09 0a 0b 0c + * | | 0d 0e 0f 10 + * | | 11 12 13 14 + * | | 15 16 17 18 + * | | 19 1a 1b 1c + * | | 1d 1e 1f 20 + * | | 21 22 23 24 + * | | 25 26 27 28 + * | | 29 2a 2b 2c + * | | + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (28); + + Ptr tlv1 = Create (); + tlv1->SetType (1); + packet.TlvPushBack (tlv1); + + Ptr msg1 = Create (); + msg1->SetType (1); + + Ptr msg1tlv1 = Create (); + msg1tlv1->SetType (1); + msg1->TlvPushBack (msg1tlv1); + + packet.MessagePushBack (msg1); + + Ptr msg2 = Create (); + msg2->SetType (2); + msg2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + msg2->SetHopLimit (255); + msg2->SetHopCount (1); + msg2->SetSequenceNumber (12345); + + Ptr msg2a1 = Create (); + msg2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + msg2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + msg2->AddressBlockPushBack (msg2a1); + + Ptr msg2a2 = Create (); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + msg2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (32); + msg2a2->PrefixPushBack (16); + msg2a2->PrefixPushBack (24); + + Ptr msg2a2tlv1 = Create (); + msg2a2tlv1->SetType (1); + msg2a2tlv1->SetIndexStart (1); + msg2a2tlv1->SetIndexStop (3); + + uint8_t value[] = { + 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, + 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + }; + msg2a2tlv1->SetValue(value, sizeof (value)); + + msg2a2->TlvPushBack (msg2a2tlv1); + + msg2->AddressBlockPushBack (msg2a2); + + packet.MessagePushBack (msg2); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x1c, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x03, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x01, 0x64, 0x0a, /* [16] - 0xf0 */ + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x01, + 0x32, 0x01, 0x38, 0x01, + 0x03, 0x01, 0x2c, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, + 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, + 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, + 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, + 0x9d, 0x9e, 0x9f, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, + 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xc0, + 0xc1, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, + 0xd1, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xdb, 0xdc, + 0xdd, 0xde, 0xdf, 0xe0, + 0xe1, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe6, 0xe7, 0xe8, + 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf0, + 0xf1, 0xf2, 0xf3, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0xfb, 0xfc, + 0xfd, 0xfe, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 29 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 1 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x0f, 0x00, + 0x06, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 30 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x16, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00 + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 31 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (1 addresses) + * | | - 10::1/128 + * | | - Flags = 0 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + Ptr m1a1 = Create (); + m1a1->AddressPushBack (Ipv6Address ("10::1")); + m1->AddressBlockPushBack (m1a1); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x2a, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 32 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::1/128 + * | | - 10::2/128 + * | | - Flags = 128 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + Ptr m1a1 = Create (); + m1a1->AddressPushBack (Ipv6Address ("10::1")); + m1a1->AddressPushBack (Ipv6Address ("10::2")); + m1->AddressBlockPushBack (m1a1); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x2c, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, + 0x80, 0x0f, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x00, + 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 33 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::2/128 + * | | - 10::11:2/128 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + Ptr m1a1 = Create (); + m1a1->AddressPushBack (Ipv6Address ("10::2")); + m1a1->AddressPushBack (Ipv6Address ("10::11:2")); + m1->AddressBlockPushBack (m1a1); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x2d, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, + 0xc0, 0x0d, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x11, + 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 34 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::2/128 + * | | - 10::11:2/128 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (2 addresses) + * | | - 10::/128 + * | | - 11::/128 + * | | - Flags = 160 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + Ptr m1a1 = Create (); + m1a1->AddressPushBack (Ipv6Address ("10::2")); + m1a1->AddressPushBack (Ipv6Address ("10::11:2")); + m1->AddressBlockPushBack (m1a1); + + Ptr m1a2 = Create (); + m1a2->AddressPushBack (Ipv6Address ("10::")); + m1a2->AddressPushBack (Ipv6Address ("11::")); + m1->AddressBlockPushBack (m1a2); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x36, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, + 0xc0, 0x0d, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x11, + 0x00, 0x00, 0x02, 0xa0, + 0x01, 0x00, 0x0e, 0x10, + 0x11, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 35 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 0 + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::2/128 + * | | - 10::11:2/128 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10::/128 + * | | - 11::/128 + * | | - 10::5/64 + * | | - 10::6/48 + * | | - Flags = 136 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + + Ptr m1 = Create (); + m1->SetType(1); + m1->SetOriginatorAddress (Ipv6Address("abcd::1")); + + Ptr m1a1 = Create (); + m1a1->AddressPushBack (Ipv6Address ("10::2")); + m1a1->AddressPushBack (Ipv6Address ("10::11:2")); + m1->AddressBlockPushBack (m1a1); + + Ptr m1a2 = Create (); + m1a2->AddressPushBack (Ipv6Address ("10::")); + m1a2->AddressPushBack (Ipv6Address ("11::")); + m1a2->AddressPushBack (Ipv6Address ("10::5")); + m1a2->AddressPushBack (Ipv6Address ("10::6")); + m1a2->PrefixPushBack (128); + m1a2->PrefixPushBack (128); + m1a2->PrefixPushBack (64); + m1a2->PrefixPushBack (48); + m1->AddressBlockPushBack (m1a2); + + packet.MessagePushBack (m1); + + uint8_t buffer[] = { + 0x00, 0x01, 0x8f, 0x00, + 0x73, 0xab, 0xcd, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, + 0xc0, 0x0d, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x11, + 0x00, 0x00, 0x04, 0x88, + 0x01, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x80, 0x80, + 0x40, 0x30, 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 36 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 29 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 56 + * | | Index-start = 1 + * | | Index-stop = 3 + * | | Type = 1; Value = 00 01 02 03 + * | | 04 05 06 07 + * | | 08 09 0a 0b + * | | 0c 0d 0e 0f + * | | 10 11 12 13 + * | | 14 15 16 17 + * | | 18 19 1a 1b + * | | 1c 1d 1e 1f + * | | 20 21 22 23 + * | | 24 25 26 27 + * | | 28 29 2a 2b + * | | 2c 2d 2e 2f + * | | 30 31 32 33 + * | | 34 35 36 37 + * | | 38 39 3a 3b + * | | 3c 3d 3e 3f + * | | 40 41 42 43 + * | | 44 45 46 47 + * | | 48 49 4a 4b + * | | 4c 4d 4e 4f + * | | 50 51 52 53 + * | | 54 55 56 57 + * | | 58 59 5a 5b + * | | 5c 5d 5e 5f + * | | 60 61 62 63 + * | | 64 65 66 67 + * | | 68 69 6a 6b + * | | 6c 6d 6e 6f + * | | 70 71 72 73 + * | | 74 75 76 77 + * | | 78 79 7a 7b + * | | 7c 7d 7e 7f + * | | 80 81 82 83 + * | | 84 85 86 87 + * | | 88 89 8a 8b + * | | 8c 8d 8e 8f + * | | 90 91 92 93 + * | | 94 95 96 97 + * | | 98 99 9a 9b + * | | 9c 9d 9e 9f + * | | a0 a1 a2 a3 + * | | a4 a5 a6 a7 + * | | a8 a9 aa ab + * | | ac ad ae af + * | | b0 b1 b2 b3 + * | | b4 b5 b6 b7 + * | | b8 b9 ba bb + * | | bc bd be bf + * | | c0 c1 c2 c3 + * | | c4 c5 c6 c7 + * | | c8 c9 ca cb + * | | cc cd ce cf + * | | d0 d1 d2 d3 + * | | d4 d5 d6 d7 + * | | d8 d9 da db + * | | dc dd de df + * | | e0 e1 e2 e3 + * | | e4 e5 e6 e7 + * | | e8 e9 ea eb + * | | ec ed ee ef + * | | f0 f1 f2 f3 + * | | f4 f5 f6 f7 + * | | f8 f9 fa fb + * | | fc fd fe 00 + * | | 01 02 03 04 + * | | 05 06 07 08 + * | | 09 0a 0b 0c + * | | 0d 0e 0f 10 + * | | 11 12 13 14 + * | | 15 16 17 18 + * | | 19 1a 1b 1c + * | | 1d 1e 1f 20 + * | | 21 22 23 24 + * | | 25 26 27 28 + * | | 29 2a 2b 2c + * | | + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::2/128 + * | | - 10::11:2/128 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10::/128 + * | | - 11::/128 + * | | - 10::5/64 + * | | - 10::6/48 + * | | - Flags = 136 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (29); + + Ptr ptlv1 = Create (); + ptlv1->SetType (1); + packet.TlvPushBack (ptlv1); + + Ptr m1 = Create (); + m1->SetType (1); + + Ptr m1tlv1 = Create (); + m1tlv1->SetType (1); + m1->TlvPushBack (m1tlv1); + packet.MessagePushBack (m1); + + Ptr m2 = Create (); + m2->SetType (2); + m2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + m2->SetHopLimit (255); + m2->SetHopCount (1); + m2->SetSequenceNumber (12345); + + Ptr m2a1 = Create (); + m2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + m2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + m2->AddressBlockPushBack (m2a1); + + Ptr m2a2 = Create (); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + m2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + m2a2->PrefixPushBack (32); + m2a2->PrefixPushBack (32); + m2a2->PrefixPushBack (16); + m2a2->PrefixPushBack (24); + + Ptr m2a2tlv1 = Create (); + m2a2tlv1->SetType (1); + m2a2tlv1->SetIndexStart (1); + m2a2tlv1->SetIndexStop (3); + + uint8_t value[] = { + 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, + 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + }; + m2a2tlv1->SetValue (value, sizeof(value)); + m2a2->TlvPushBack (m2a2tlv1); + + m2->AddressBlockPushBack (m2a2); + packet.MessagePushBack (m2); + + Ptr m3 = Create (); + m3->SetType (1); + m3->SetOriginatorAddress (Ipv6Address ("abcd::1")); + + Ptr m3a1 = Create (); + m3a1->AddressPushBack (Ipv6Address ("10::2")); + m3a1->AddressPushBack (Ipv6Address ("10::11:2")); + m3->AddressBlockPushBack (m3a1); + + Ptr m3a2 = Create (); + m3a2->AddressPushBack (Ipv6Address ("10::")); + m3a2->AddressPushBack (Ipv6Address ("11::")); + m3a2->AddressPushBack (Ipv6Address ("10::5")); + m3a2->AddressPushBack (Ipv6Address ("10::6")); + m3a2->PrefixPushBack (128); + m3a2->PrefixPushBack (128); + m3a2->PrefixPushBack (64); + m3a2->PrefixPushBack (48); + + m3->AddressBlockPushBack (m3a2); + packet.MessagePushBack (m3); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x1d, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x0f, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x01, 0x64, 0x0a, + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x01, + 0x32, 0x01, 0x38, 0x01, + 0x03, 0x01, 0x2c, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, + 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, + 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, + 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, + 0x9d, 0x9e, 0x9f, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, + 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xc0, + 0xc1, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, + 0xd1, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xdb, 0xdc, + 0xdd, 0xde, 0xdf, 0xe0, + 0xe1, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe6, 0xe7, 0xe8, + 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf0, + 0xf1, 0xf2, 0xf3, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0xfb, 0xfc, + 0xfd, 0xfe, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x01, + 0x8f, 0x00, 0x73, 0xab, + 0xcd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x00, 0x02, 0xc0, 0x0d, + 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, + 0x00, 0x11, 0x00, 0x00, + 0x04, 0x88, 0x01, 0x00, + 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x05, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, + 0x80, 0x80, 0x40, 0x30, + 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } + + /* Test 37 + * ,------------------ + * | PACKET + * |------------------ + * | * Packet version: 0 + * | * Packet flags: 12 + * | * Packet seq number: 30 + * | | * Packet TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 0 + * | | * Message TLV Block + * | | - TLV + * | | Flags = 0 + * | | Type = 1; Value = (warning: parameter is NULL) + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 2 + * | | * Message flags: 240 + * | | * Originator address: 10.0.0.1 + * | | * Hop limit: 255 + * | | * Hop count: 1 + * | | * Message seq number: 12345 + * | | - Address block (2 addresses) + * | | - 10.0.0.2/32 + * | | - 10.1.1.2/32 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10.0.0.0/32 + * | | - 11.0.0.0/32 + * | | - 10.0.0.5/16 + * | | - 10.0.0.6/24 + * | | - Flags = 8 + * | | - ADDRESS TLV block (1 TLVs) + * | | - TLV + * | | Flags = 56 + * | | Index-start = 1 + * | | Index-stop = 3 + * | | Type = 1; Value = 00 01 02 03 + * | | 04 05 06 07 + * | | 08 09 0a 0b + * | | 0c 0d 0e 0f + * | | 10 11 12 13 + * | | 14 15 16 17 + * | | 18 19 1a 1b + * | | 1c 1d 1e 1f + * | | 20 21 22 23 + * | | 24 25 26 27 + * | | 28 29 2a 2b + * | | 2c 2d 2e 2f + * | | 30 31 32 33 + * | | 34 35 36 37 + * | | 38 39 3a 3b + * | | 3c 3d 3e 3f + * | | 40 41 42 43 + * | | 44 45 46 47 + * | | 48 49 4a 4b + * | | 4c 4d 4e 4f + * | | 50 51 52 53 + * | | 54 55 56 57 + * | | 58 59 5a 5b + * | | 5c 5d 5e 5f + * | | 60 61 62 63 + * | | 64 65 66 67 + * | | 68 69 6a 6b + * | | 6c 6d 6e 6f + * | | 70 71 72 73 + * | | 74 75 76 77 + * | | 78 79 7a 7b + * | | 7c 7d 7e 7f + * | | 80 81 82 83 + * | | 84 85 86 87 + * | | 88 89 8a 8b + * | | 8c 8d 8e 8f + * | | 90 91 92 93 + * | | 94 95 96 97 + * | | 98 99 9a 9b + * | | 9c 9d 9e 9f + * | | a0 a1 a2 a3 + * | | a4 a5 a6 a7 + * | | a8 a9 aa ab + * | | ac ad ae af + * | | b0 b1 b2 b3 + * | | b4 b5 b6 b7 + * | | b8 b9 ba bb + * | | bc bd be bf + * | | c0 c1 c2 c3 + * | | c4 c5 c6 c7 + * | | c8 c9 ca cb + * | | cc cd ce cf + * | | d0 d1 d2 d3 + * | | d4 d5 d6 d7 + * | | d8 d9 da db + * | | dc dd de df + * | | e0 e1 e2 e3 + * | | e4 e5 e6 e7 + * | | e8 e9 ea eb + * | | ec ed ee ef + * | | f0 f1 f2 f3 + * | | f4 f5 f6 f7 + * | | f8 f9 fa fb + * | | fc fd fe 00 + * | | 01 02 03 04 + * | | 05 06 07 08 + * | | 09 0a 0b 0c + * | | 0d 0e 0f 10 + * | | 11 12 13 14 + * | | 15 16 17 18 + * | | 19 1a 1b 1c + * | | 1d 1e 1f 20 + * | | 21 22 23 24 + * | | 25 26 27 28 + * | | 29 2a 2b 2c + * | | + * | `------------------- + * | + * | ,------------------- + * | | MESSAGE + * | |------------------- + * | | * Message type: 1 + * | | * Message flags: 129 + * | | * Originator address: abcd::1 + * | | - Address block (2 addresses) + * | | - 10::2/128 + * | | - 10::11:2/128 + * | | - Flags = 192 + * | | - ADDRESS TLV block (0 TLVs) + * | | - Address block (4 addresses) + * | | - 10::/128 + * | | - 11::/128 + * | | - 10::5/64 + * | | - 10::6/48 + * | | - Flags = 136 + * | | - ADDRESS TLV block (0 TLVs) + * | `------------------- + * | + * `------------------ + */ + { + PbbPacket packet; + packet.SetSequenceNumber (30); + + Ptr ptlv1 = Create (); + ptlv1->SetType (1); + packet.TlvPushBack (ptlv1); + + Ptr m1 = Create (); + m1->SetType (1); + + Ptr m1tlv1 = Create (); + m1tlv1->SetType (1); + m1->TlvPushBack (m1tlv1); + packet.MessagePushBack (m1); + + Ptr m2 = Create (); + m2->SetType (2); + m2->SetOriginatorAddress (Ipv4Address ("10.0.0.1")); + m2->SetHopLimit (255); + m2->SetHopCount (1); + m2->SetSequenceNumber (12345); + + Ptr m2a1 = Create (); + m2a1->AddressPushBack (Ipv4Address ("10.0.0.2")); + m2a1->AddressPushBack (Ipv4Address ("10.1.1.2")); + m2->AddressBlockPushBack (m2a1); + + Ptr m2a2 = Create (); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.0")); + m2a2->AddressPushBack (Ipv4Address ("11.0.0.0")); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.5")); + m2a2->AddressPushBack (Ipv4Address ("10.0.0.6")); + m2a2->PrefixPushBack (32); + m2a2->PrefixPushBack (32); + m2a2->PrefixPushBack (16); + m2a2->PrefixPushBack (24); + + Ptr m2a2tlv1 = Create (); + m2a2tlv1->SetType (1); + m2a2tlv1->SetIndexStart (1); + m2a2tlv1->SetIndexStop (3); + + uint8_t value[] = { + 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, + 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, + 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, + 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, + 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, + 0xfc, 0xfd, 0xfe, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + }; + m2a2tlv1->SetValue (value, sizeof(value)); + m2a2->TlvPushBack (m2a2tlv1); + + m2->AddressBlockPushBack (m2a2); + packet.MessagePushBack (m2); + + Ptr m3 = Create (); + m3->SetType (1); + m3->SetOriginatorAddress (Ipv6Address ("abcd::1")); + + Ptr m3a1 = Create (); + m3a1->AddressPushBack (Ipv6Address ("10::2")); + m3a1->AddressPushBack (Ipv6Address ("10::11:2")); + m3->AddressBlockPushBack (m3a1); + + Ptr m3a2 = Create (); + m3a2->AddressPushBack (Ipv6Address ("10::")); + m3a2->AddressPushBack (Ipv6Address ("11::")); + m3a2->AddressPushBack (Ipv6Address ("10::5")); + m3a2->AddressPushBack (Ipv6Address ("10::6")); + m3a2->PrefixPushBack (128); + m3a2->PrefixPushBack (128); + m3a2->PrefixPushBack (64); + m3a2->PrefixPushBack (48); + + m3->AddressBlockPushBack (m3a2); + packet.MessagePushBack (m3); + + uint8_t buffer[] = { + 0x0c, 0x00, 0x1e, 0x00, + 0x02, 0x01, 0x00, 0x01, + 0x0f, 0x00, 0x08, 0x00, + 0x02, 0x01, 0x00, 0x02, + 0xf3, 0x01, 0x64, 0x0a, + 0x00, 0x00, 0x01, 0xff, + 0x01, 0x30, 0x39, 0x00, + 0x00, 0x02, 0xc0, 0x01, + 0x0a, 0x01, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x00, + 0x00, 0x04, 0x08, 0x0a, + 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x05, 0x0a, + 0x00, 0x00, 0x06, 0x20, + 0x20, 0x10, 0x18, 0x01, + 0x32, 0x01, 0x38, 0x01, + 0x03, 0x01, 0x2c, 0x00, + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, + 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, + 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, + 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, + 0x9d, 0x9e, 0x9f, 0xa0, + 0xa1, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, + 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xc0, + 0xc1, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7, 0xc8, + 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, + 0xd1, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xdb, 0xdc, + 0xdd, 0xde, 0xdf, 0xe0, + 0xe1, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe6, 0xe7, 0xe8, + 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf0, + 0xf1, 0xf2, 0xf3, 0xf4, + 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0xfb, 0xfc, + 0xfd, 0xfe, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x01, + 0x8f, 0x00, 0x73, 0xab, + 0xcd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, + 0x00, 0x02, 0xc0, 0x0d, + 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x02, + 0x00, 0x11, 0x00, 0x00, + 0x04, 0x88, 0x01, 0x00, + 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x05, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, + 0x80, 0x80, 0x40, 0x30, + 0x00, 0x00, + }; + PacketBBTester test(testnum++, packet, buffer, sizeof(buffer)); + } +} diff --git a/src/node/wscript b/src/node/wscript index 1430e63ef..416db3879 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -45,6 +45,7 @@ def build(bld): 'ipv6.cc', 'ipv6-raw-socket-factory.cc', 'ipv6-routing-protocol.cc', + 'packetbb.cc', ] headers = bld.new_task_gen('ns3header') @@ -91,4 +92,5 @@ def build(bld): 'ipv6.h', 'ipv6-raw-socket-factory.h', 'ipv6-routing-protocol.h', + 'packetbb.h', ]