Files
unison/src/node/packetbb.h
2010-02-01 15:24:40 +00:00

1731 lines
48 KiB
C++

/* -*- 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 <tom5760@gmail.com>
*/
/* 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 <list>
#include "ns3/ptr.h"
#include "ns3/address.h"
#include "ns3/header.h"
#include "ns3/buffer.h"
#include "ns3/simple-ref-count.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<PbbTlv> >::iterator Iterator;
typedef std::list< Ptr<PbbTlv> >::const_iterator ConstIterator;
PbbTlvBlock (void);
~PbbTlvBlock (void);
/**
* \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<PbbTlv> Front (void) const;
/**
* \return a smart pointer to the last TLV in this block.
*/
Ptr<PbbTlv> 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<PbbTlv> 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<PbbTlv> 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<PbbTlv> 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<PbbTlv> > m_tlvList;
};
/**
* \brief A block of Address TLVs (PbbAddressTlv).
*
* Acts similar to a C++ STL container.
*/
class PbbAddressTlvBlock
{
public:
typedef std::list< Ptr<PbbAddressTlv> >::iterator Iterator;
typedef std::list< Ptr<PbbAddressTlv> >::const_iterator ConstIterator;
PbbAddressTlvBlock (void);
~PbbAddressTlvBlock (void);
/**
* \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<PbbAddressTlv> Front (void) const;
/**
* \return the last AddressTLV in this block.
*/
Ptr<PbbAddressTlv> 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<PbbAddressTlv> 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<PbbAddressTlv> 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<PbbAddressTlv> 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<PbbAddressTlv> > 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 SimpleRefCount<PbbPacket,Header>
{
public:
typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
typedef std::list< Ptr<PbbTlv> >::const_iterator ConstTlvIterator;
typedef std::list< Ptr<PbbMessage> >::iterator MessageIterator;
typedef std::list< Ptr<PbbMessage> >::const_iterator ConstMessageIterator;
PbbPacket (void);
~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<PbbTlv> TlvFront (void);
/**
* \return a const smart pointer to the first packet TLV in this packet.
*/
const Ptr<PbbTlv> TlvFront (void) const;
/**
* \return a smart pointer to the last packet TLV in this packet.
*/
Ptr<PbbTlv> TlvBack (void);
/**
* \return a const smart pointer to the last packet TLV in this packet.
*/
const Ptr<PbbTlv> 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<PbbTlv> 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<PbbTlv> 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<PbbMessage> MessageFront (void);
/**
* \return a cosnt smart pointer to the first message in this packet.
*/
const Ptr<PbbMessage> MessageFront (void) const;
/**
* \return a smart pointer to the last message in this packet.
*/
Ptr<PbbMessage> MessageBack (void);
/**
* \return a cosnt smart pointer to the last message in this packet.
*/
const Ptr<PbbMessage> 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<PbbMessage> 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<PbbMessage> 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);
/* 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.
* \param start start offset
* \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:
private:
PbbTlvBlock m_tlvList;
std::list< Ptr<PbbMessage> > m_messageList;
uint8_t m_version;
bool m_hasseqnum;
uint16_t m_seqnum;
};
/**
* \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 SimpleRefCount<PbbMessage>
{
public:
typedef std::list< Ptr<PbbTlv> >::iterator TlvIterator;
typedef std::list< Ptr<PbbTlv> >::const_iterator ConstTlvIterator;
typedef std::list< Ptr<PbbAddressBlock> >::iterator AddressBlockIterator;
typedef std::list< Ptr<PbbAddressBlock> >::const_iterator ConstAddressBlockIterator;
PbbMessage ();
virtual ~PbbMessage ();
/**
* \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<PbbTlv> TlvFront (void);
/**
* \return a const smart pointer to the first message TLV in this message.
*/
const Ptr<PbbTlv> TlvFront (void) const;
/**
* \return a smart pointer to the last message TLV in this message.
*/
Ptr<PbbTlv> TlvBack (void);
/**
* \return a const smart pointer to the last message TLV in this message.
*/
const Ptr<PbbTlv> 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<PbbTlv> 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<PbbTlv> 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<PbbAddressBlock> AddressBlockFront (void);
/**
* \return a const smart pointer to the first address block in this message.
*/
const Ptr<PbbAddressBlock> AddressBlockFront (void) const;
/**
* \return a smart pointer to the last address block in this message.
*/
Ptr<PbbAddressBlock> AddressBlockBack (void);
/**
* \return a const smart pointer to the last address block in this message.
*/
const Ptr<PbbAddressBlock> 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<PbbAddressBlock> 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<PbbAddressBlock> 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);
/**
* \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<PbbMessage> 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<PbbAddressBlock> AddressBlockDeserialize (Buffer::Iterator &start) const = 0;
private:
PbbTlvBlock m_tlvList;
std::list< Ptr<PbbAddressBlock> > 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;
};
/**
* \brief Concrete IPv4 specific PbbMessage.
*
* This message will only contain IPv4 addresses.
*/
class PbbMessageIpv4 : public PbbMessage {
public:
PbbMessageIpv4 ();
virtual ~PbbMessageIpv4 ();
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<PbbAddressBlock> AddressBlockDeserialize (Buffer::Iterator &start) const;
};
/**
* \brief Concrete IPv6 specific PbbMessage class.
*
* This message will only contain IPv6 addresses.
*/
class PbbMessageIpv6 : public PbbMessage {
public:
PbbMessageIpv6 ();
virtual ~PbbMessageIpv6 ();
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<PbbAddressBlock> 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 SimpleRefCount<PbbAddressBlock>
{
public:
typedef std::list< Address >::iterator AddressIterator;
typedef std::list< Address >::const_iterator ConstAddressIterator;
typedef std::list<uint8_t>::iterator PrefixIterator;
typedef std::list<uint8_t>::const_iterator ConstPrefixIterator;
typedef PbbAddressTlvBlock::Iterator TlvIterator;
typedef PbbAddressTlvBlock::ConstIterator ConstTlvIterator;
PbbAddressBlock ();
virtual ~PbbAddressBlock ();
/* 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<PbbAddressTlv> TlvFront (void);
/**
* \return a const smart pointer to the first address TLV in this message.
*/
const Ptr<PbbAddressTlv> TlvFront (void) const;
/**
* \return a smart pointer to the last address TLV in this message.
*/
Ptr<PbbAddressTlv> TlvBack (void);
/**
* \return a const smart pointer to the last address TLV in this message.
*/
const Ptr<PbbAddressTlv> 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<PbbAddressTlv> 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<PbbAddressTlv> 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<PbbTlv> 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);
/**
* \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<Address> m_addressList;
std::list<uint8_t> m_prefixList;
PbbAddressTlvBlock m_addressTlvList;
};
/**
* \brief Concrete IPv4 specific PbbAddressBlock.
*
* This address block will only contain IPv4 addresses.
*/
class PbbAddressBlockIpv4 : public PbbAddressBlock
{
public:
PbbAddressBlockIpv4 ();
virtual ~PbbAddressBlockIpv4 ();
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
{
public:
PbbAddressBlockIpv6 ();
virtual ~PbbAddressBlockIpv6 ();
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 SimpleRefCount<PbbTlv>
{
public:
PbbTlv (void);
virtual ~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;
/**
* \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;
};
/**
* \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 */