Merge with Fabian's repository.
--- a/src/internet-stack/ipv6-extension-header.cc Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-extension-header.cc Wed Nov 11 16:25:10 2009 +0100
@@ -120,6 +120,83 @@
return GetSerializedSize ();
}
+OptionField::OptionField (uint32_t optionsOffset)
+ : m_optionData (0),
+ m_optionsOffset (optionsOffset)
+{
+}
+
+OptionField::~OptionField ()
+{
+}
+
+uint32_t OptionField::GetSerializedSize () const
+{
+ return m_optionData.GetSize () + CalculatePad ((Ipv6OptionHeader::Alignment) {8,0});
+}
+
+void OptionField::Serialize (Buffer::Iterator start) const
+{
+ start.Write (m_optionData.Begin (), m_optionData.End ());
+ uint32_t fill = CalculatePad ((Ipv6OptionHeader::Alignment) {8,0});
+ NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
+ switch (fill)
+ {
+ case 0: return;
+ case 1: Ipv6OptionPad1Header ().Serialize (start);
+ return;
+ default: Ipv6OptionPadnHeader (fill).Serialize (start);
+ return;
+ }
+}
+
+uint32_t OptionField::Deserialize (Buffer::Iterator start, uint32_t length)
+{
+ uint8_t buf[length];
+ start.Read (buf,length);
+ m_optionData = Buffer ();
+ m_optionData.AddAtEnd (length);
+ m_optionData.Begin ().Write (buf,length);
+ return length;
+}
+
+void OptionField::AddOption (Ipv6OptionHeader const& option)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ uint32_t pad = CalculatePad (option.GetAlignment ());
+ NS_LOG_LOGIC ("need " << pad << " bytes padding");
+ switch (pad)
+ {
+ case 0: break; //no padding needed
+ case 1: AddOption (Ipv6OptionPad1Header ());
+ break;
+ default: AddOption (Ipv6OptionPadnHeader (pad));
+ break;
+ }
+
+ m_optionData.AddAtEnd (option.GetSerializedSize ());
+ Buffer::Iterator it = m_optionData.End ();
+ it.Prev (option.GetSerializedSize ());
+ option.Serialize (it);
+}
+
+uint32_t OptionField::CalculatePad (Ipv6OptionHeader::Alignment alignment) const
+{
+ return (alignment.offset - (m_optionData.GetSize () + m_optionsOffset)) % alignment.factor;
+}
+
+uint32_t OptionField::GetOptionsOffset ()
+{
+ return m_optionsOffset;
+}
+
+Buffer OptionField::GetOptionBuffer ()
+{
+ return m_optionData;
+}
+
+
NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHopByHopHeader);
TypeId Ipv6ExtensionHopByHopHeader::GetTypeId ()
@@ -137,6 +214,7 @@
}
Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader ()
+ : OptionField (2)
{
}
@@ -151,7 +229,7 @@
uint32_t Ipv6ExtensionHopByHopHeader::GetSerializedSize () const
{
- return 2;
+ return 2 + OptionField::GetSerializedSize ();
}
void Ipv6ExtensionHopByHopHeader::Serialize (Buffer::Iterator start) const
@@ -160,6 +238,7 @@
i.WriteU8 (GetNextHeader ());
i.WriteU8 ((GetLength () >> 3) - 1);
+ OptionField::Serialize (i);
}
uint32_t Ipv6ExtensionHopByHopHeader::Deserialize (Buffer::Iterator start)
@@ -168,6 +247,7 @@
SetNextHeader (i.ReadU8 ());
SetLength ((i.ReadU8 () + 1) << 3);
+ OptionField::Deserialize (i, GetLength () - 2);
return GetSerializedSize ();
}
@@ -189,6 +269,7 @@
}
Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader ()
+ : OptionField (2)
{
}
@@ -203,7 +284,7 @@
uint32_t Ipv6ExtensionDestinationHeader::GetSerializedSize () const
{
- return 2;
+ return 2 + OptionField::GetSerializedSize ();
}
void Ipv6ExtensionDestinationHeader::Serialize (Buffer::Iterator start) const
@@ -212,6 +293,8 @@
i.WriteU8 (GetNextHeader ());
i.WriteU8 ((GetLength () >> 3) - 1);
+
+ OptionField::Serialize (i);
}
uint32_t Ipv6ExtensionDestinationHeader::Deserialize (Buffer::Iterator start)
@@ -220,6 +303,7 @@
SetNextHeader (i.ReadU8 ());
SetLength ((i.ReadU8 () + 1) << 3);
+ OptionField::Deserialize (i, GetLength () - 2);
return GetSerializedSize ();
}
--- a/src/internet-stack/ipv6-extension-header.h Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-extension-header.h Wed Nov 11 16:25:10 2009 +0100
@@ -22,10 +22,12 @@
#define IPV6_EXTENSION_HEADER_H
#include <vector>
+#include <list>
#include <ostream>
#include "ns3/header.h"
#include "ns3/ipv6-address.h"
+#include "ipv6-option-header.h"
namespace ns3
{
@@ -127,10 +129,68 @@
};
/**
+ * \brief Option field for an IPv6ExtensionHeader
+ * Enables adding options to an IPv6ExtensionHeader
+ *
+ * Implementor's note: Make sure to add the result of
+ * OptionField::GetSerializedSize () to your IPv6ExtensionHeader::GetSerializedSize ()
+ * return value. Call OptionField::Serialize and OptionField::Deserialize at the
+ * end of your corresponding IPv6ExtensionHeader methods.
+ */
+
+class OptionField
+{
+ public:
+ OptionField (uint32_t opitonsOffset);
+ ~OptionField ();
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize all added options.
+ * \param start Buffer iterator
+ */
+ void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ uint32_t Deserialize (Buffer::Iterator start, uint32_t length);
+
+ /**
+ * \brief Serialize the option, prepending pad1 or padn option as necessary
+ * \param option the option header to serialize
+ */
+ void AddOption (Ipv6OptionHeader const& option);
+
+ /**
+ * \brief Get the offset where the options begin, measured from the start of
+ * the extension header.
+ * \return the offset from the start of the extension header
+ */
+ uint32_t GetOptionsOffset ();
+
+ Buffer GetOptionBuffer ();
+
+ private:
+
+ uint32_t CalculatePad (Ipv6OptionHeader::Alignment alignment) const;
+
+ Buffer m_optionData;
+ uint32_t m_optionsOffset;
+};
+
+/**
* \class Ipv6ExtensionHopByHopHeader
* \brief Header of IPv6 Extension "Hop by Hop"
*/
-class Ipv6ExtensionHopByHopHeader : public Ipv6ExtensionHeader
+class Ipv6ExtensionHopByHopHeader : public Ipv6ExtensionHeader, public OptionField
{
public:
/**
@@ -186,7 +246,7 @@
* \class Ipv6ExtensionDestinationHeader
* \brief Header of IPv6 Extension Destination
*/
-class Ipv6ExtensionDestinationHeader : public Ipv6ExtensionHeader
+class Ipv6ExtensionDestinationHeader : public Ipv6ExtensionHeader, public OptionField
{
public:
/**
--- a/src/internet-stack/ipv6-extension.cc Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-extension.cc Wed Nov 11 16:25:10 2009 +0100
@@ -81,6 +81,89 @@
return m_node;
}
+uint8_t Ipv6Extension::ProcessOptions (Ptr<Packet>& packet, uint8_t offset, uint8_t length, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
+
+ // For ICMPv6 Error packets
+ Ptr<Packet> malformedPacket = packet->Copy ();
+ malformedPacket->AddHeader (ipv6Header);
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
+ Ptr<Ipv6Option> ipv6Option;
+
+ uint8_t processedSize = 0;
+ const uint8_t *data = p->PeekData ();
+ uint8_t optionType = 0;
+ uint8_t optionLength = 0;
+
+ while (length > processedSize && !isDropped)
+ {
+ optionType = *(data + processedSize);
+ ipv6Option = ipv6OptionDemux->GetOption (optionType);
+
+ if (ipv6Option == 0)
+ {
+ optionType >>= 6;
+ switch (optionType)
+ {
+ case 0:
+ optionLength = *(data + processedSize + 1);
+ break;
+
+ case 1:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 2:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 3:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+
+ if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
+ {
+ icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+ }
+
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ else
+ {
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
+ }
+
+ processedSize += optionLength;
+ p->RemoveAtStart (optionLength);
+ }
+
+ return processedSize;
+}
+
NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHopByHop);
@@ -114,10 +197,6 @@
{
NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
- // For ICMPv6 Error packets
- Ptr<Packet> malformedPacket = packet->Copy ();
- malformedPacket->AddHeader (ipv6Header);
-
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -128,74 +207,11 @@
*nextHeader = hopbyhopHeader.GetNextHeader ();
}
- Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
-
- Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
- Ptr<Ipv6Option> ipv6Option;
-
- uint8_t totalSize = hopbyhopHeader.GetLength ();
- uint8_t processedSize = hopbyhopHeader.GetSerializedSize ();
- const uint8_t *data = p->PeekData ();
- uint8_t optionType = 0;
- uint8_t optionLength = 0;
- isDropped = false;
-
- while (totalSize > processedSize && !isDropped)
- {
- optionType = *(data + processedSize);
- ipv6Option = ipv6OptionDemux->GetOption (optionType);
-
- /* unknow option */
- if (ipv6Option == 0)
- {
- optionType >>= 6;
- switch (optionType)
- {
- case 0:
- optionLength = *(data + processedSize + 1);
- break;
-
- case 1:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
+ uint8_t processedSize = hopbyhopHeader.GetOptionsOffset ();
+ offset += processedSize;
+ uint8_t length = hopbyhopHeader.GetLength () - hopbyhopHeader.GetOptionsOffset ();
- case 2:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
-
- case 3:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
-
- if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
- {
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- }
-
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
-
- default:
- isDropped = true;
- break;
- }
- }
- else
- {
- optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
- }
-
- processedSize += optionLength;
- p->RemoveAtStart (optionLength);
- }
+ processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
return processedSize;
}
@@ -233,10 +249,6 @@
{
NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
- // For ICMPv6 Error packets
- Ptr<Packet> malformedPacket = packet->Copy ();
- malformedPacket->AddHeader (ipv6Header);
-
Ptr<Packet> p = packet->Copy ();
p->RemoveAtStart (offset);
@@ -247,72 +259,11 @@
*nextHeader = destinationHeader.GetNextHeader ();
}
- Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
-
- Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
- Ptr<Ipv6Option> ipv6Option;
-
- uint8_t totalSize = destinationHeader.GetLength ();
- uint8_t processedSize = destinationHeader.GetSerializedSize ();
- const uint8_t *data = p->PeekData ();
- uint8_t optionType = 0;
- uint8_t optionLength = 0;
- isDropped = false;
-
- while (totalSize > processedSize && !isDropped)
- {
- optionType = *(data + processedSize);
- ipv6Option = ipv6OptionDemux->GetOption (optionType);
-
- if (ipv6Option == 0)
- {
- optionType >>= 6;
- switch (optionType)
- {
- case 0:
- optionLength = *(data + processedSize + 1);
- break;
-
- case 1:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
+ uint8_t processedSize = destinationHeader.GetOptionsOffset ();
+ offset += processedSize;
+ uint8_t length = destinationHeader.GetLength () - destinationHeader.GetOptionsOffset ();
- case 2:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
-
- case 3:
- NS_LOG_LOGIC ("Unknown Option. Drop!");
-
- if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
- {
- icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
- }
-
- m_dropTrace (packet);
- optionLength = 0;
- isDropped = true;
- break;
-
- default:
- break;
- }
- }
- else
- {
- optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
- }
-
- processedSize += optionLength;
- p->RemoveAtStart (optionLength);
- }
+ processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
return processedSize;
}
@@ -862,7 +813,7 @@
{
*nextHeader = routingHeader.GetNextHeader ();
}
-
+
Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
Ipv6Address srcAddress = ipv6header.GetSourceAddress ();
@@ -931,7 +882,7 @@
* the packet was for us so we resend it to
* the new destination (modified in the header above).
*/
-
+
Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
Socket::SocketErrno err;
@@ -946,7 +897,7 @@
}
else
{
- NS_LOG_INFO("No route for next router");
+ NS_LOG_INFO ("No route for next router");
}
/* as we directly send packet, mark it as dropped */
--- a/src/internet-stack/ipv6-extension.h Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-extension.h Wed Nov 11 16:25:10 2009 +0100
@@ -90,7 +90,25 @@
*/
virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped) = 0;
+ /**
+ * \brief Process options
+ * Called by implementing classes to process the options
+ *
+ * \param packet the packet
+ * \param offset the offset of the first option to process
+ * \param length the total length of all options (as specified in the extension header)
+ * \param ipv6Header the IPv6 header of packet received
+ * \param dst destination address of the packet received (i.e. us)
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t ProcessOptions (Ptr<Packet>& packet, uint8_t offset, uint8_t length, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
+
protected:
+ /**
+ * \brief Drop trace callback.
+ */
TracedCallback<Ptr<const Packet> > m_dropTrace;
private:
@@ -431,7 +449,7 @@
/**
* \brief Dispose this object.
*/
- virtual void DoDispose();
+ virtual void DoDispose ();
private:
typedef std::list<Ptr<Ipv6ExtensionRouting> > Ipv6ExtensionRoutingList_t;
--- a/src/internet-stack/ipv6-option-header.cc Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-option-header.cc Wed Nov 11 16:25:10 2009 +0100
@@ -81,7 +81,7 @@
uint32_t Ipv6OptionHeader::GetSerializedSize () const
{
- return 1;
+ return m_length + 2;
}
void Ipv6OptionHeader::Serialize (Buffer::Iterator start) const
@@ -89,6 +89,9 @@
Buffer::Iterator i = start;
i.WriteU8 (m_type);
+ i.WriteU8 (m_length);
+
+ i.Write (m_data.Begin (), m_data.End ());
}
uint32_t Ipv6OptionHeader::Deserialize (Buffer::Iterator start)
@@ -96,10 +99,23 @@
Buffer::Iterator i = start;
m_type = i.ReadU8 ();
+ m_length = i.ReadU8 ();
+
+ m_data = Buffer ();
+ m_data.AddAtEnd (m_length);
+ Buffer::Iterator dataStart = i;
+ i.Next (m_length);
+ Buffer::Iterator dataEnd = i;
+ m_data.Begin ().Write (dataStart, dataEnd);
return GetSerializedSize ();
}
+Ipv6OptionHeader::Alignment Ipv6OptionHeader::GetAlignment () const
+{
+ return (Alignment){1,0};
+}
+
NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionPad1Header);
TypeId Ipv6OptionPad1Header::GetTypeId ()
@@ -118,6 +134,7 @@
Ipv6OptionPad1Header::Ipv6OptionPad1Header ()
{
+ SetType (0);
}
Ipv6OptionPad1Header::~Ipv6OptionPad1Header ()
@@ -166,8 +183,11 @@
return GetTypeId ();
}
-Ipv6OptionPadnHeader::Ipv6OptionPadnHeader ()
+Ipv6OptionPadnHeader::Ipv6OptionPadnHeader (uint32_t pad)
{
+ SetType (1);
+ NS_ASSERT_MSG (pad >= 2, "PadN must be at least 2 bytes long");
+ SetLength (pad - 2);
}
Ipv6OptionPadnHeader::~Ipv6OptionPadnHeader ()
@@ -225,6 +245,7 @@
Ipv6OptionJumbogramHeader::Ipv6OptionJumbogramHeader ()
{
+ SetType (0xC2);
SetLength (4);
}
@@ -258,7 +279,7 @@
i.WriteU8 (GetType ());
i.WriteU8 (GetLength ());
- i.WriteHtonU16 (m_dataLength);
+ i.WriteHtonU32 (m_dataLength);
}
uint32_t Ipv6OptionJumbogramHeader::Deserialize (Buffer::Iterator start)
@@ -272,6 +293,11 @@
return GetSerializedSize ();
}
+Ipv6OptionHeader::Alignment Ipv6OptionJumbogramHeader::GetAlignment () const
+{
+ return (Alignment){4,2}; //4n+2
+}
+
NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionRouterAlertHeader);
TypeId Ipv6OptionRouterAlertHeader::GetTypeId ()
@@ -338,5 +364,10 @@
return GetSerializedSize ();
}
+Ipv6OptionHeader::Alignment Ipv6OptionRouterAlertHeader::GetAlignment () const
+{
+ return (Alignment){2,0}; //2n+0
+}
+
} /* namespace ns3 */
--- a/src/internet-stack/ipv6-option-header.h Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/ipv6-option-header.h Wed Nov 11 16:25:10 2009 +0100
@@ -35,6 +35,20 @@
class Ipv6OptionHeader : public Header
{
public:
+
+ /**
+ * \brief represents the alignment requirements of an option header
+ *
+ * Represented as factor*n+offset (eg. 8n+2) See RFC 2460.
+ * No alignemt is represented as 1n+0.
+ *
+ */
+ struct Alignment
+ {
+ uint8_t factor;
+ uint8_t offset;
+ };
+
/**
* \brief Get the type identificator.
* \return type identificator
@@ -107,6 +121,15 @@
*/
virtual uint32_t Deserialize (Buffer::Iterator start);
+ /**
+ * \brief Get the Alignment requirement of this option header
+ * \return The required alignment
+ *
+ * Subclasses should only implement this method, if special alignemt is
+ * required. Default is no alignment (1n+0).
+ */
+ virtual Alignment GetAlignment () const;
+
private:
/**
* \brief The type of the option.
@@ -118,6 +141,10 @@
*/
uint8_t m_length;
+ /**
+ * \brief The anonymous data of this option
+ */
+ Buffer m_data;
};
/**
@@ -197,8 +224,9 @@
/**
* \brief Constructor.
+ * \param pad Number of bytes to pad (>=2)
*/
- Ipv6OptionPadnHeader ();
+ Ipv6OptionPadnHeader (uint32_t pad = 2);
/**
* \brief Destructor.
@@ -299,6 +327,12 @@
*/
virtual uint32_t Deserialize (Buffer::Iterator start);
+ /**
+ * \brief Get the Alignment requirement of this option header
+ * \return The required alignment
+ */
+ virtual Alignment GetAlignment () const;
+
private:
/**
* \brief The data length.
@@ -372,6 +406,12 @@
*/
virtual uint32_t Deserialize (Buffer::Iterator start);
+ /**
+ * \brief Get the Alignment requirement of this option header
+ * \return The required alignment
+ */
+ virtual Alignment GetAlignment () const;
+
private:
/**
* \brief The value.
--- a/src/internet-stack/wscript Wed Nov 04 14:42:58 2009 +0100
+++ b/src/internet-stack/wscript Wed Nov 11 16:25:10 2009 +0100
@@ -130,6 +130,7 @@
'ipv4-l3-protocol.h',
'ipv6-l3-protocol.h',
'ipv6-extension-header.h',
+ 'ipv6-option-header.h',
'arp-l3-protocol.h',
'udp-l4-protocol.h',
'tcp-l4-protocol.h',