implement PacketHistory::Print

Mathieu Lacage 2007-06-05 15:47:29 +02:00
parent dc62fabc0b
commit 35dbade0a9
4 changed files with 261 additions and 51 deletions

View File

@ -331,8 +331,8 @@ PacketHistory::Enable (void)
PacketHistory::PacketHistory (uint32_t uid, uint32_t size)
: m_data (0),
m_begin (0),
m_end (0),
m_begin (0xffff),
m_end (0xffff),
m_used (0),
m_packetUid (uid)
{
@ -436,9 +436,9 @@ PacketHistory::GetUleb128Size (uint32_t value) const
return n;
}
uint32_t
PacketHistory::ReadUleb128 (uint8_t **pBuffer) const
PacketHistory::ReadUleb128 (const uint8_t **pBuffer) const
{
uint8_t *buffer = *pBuffer;
const uint8_t *buffer = *pBuffer;
uint32_t result = 0;
uint8_t byte;
result = 0;
@ -540,21 +540,25 @@ PacketHistory::TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end)
}
bool
PacketHistory::IsZero16 (uint16_t index)
PacketHistory::IsFF16 (uint16_t index)
{
return m_data->m_data[index] == 0 && m_data->m_data[index+1] == 0;
return m_data->m_data[index] == 0xff && m_data->m_data[index+1] == 0xff;
}
bool
PacketHistory::CanAdd (bool atStart)
{
if (atStart)
if (atStart && m_begin != 0xffff)
{
return IsZero16 (m_begin+2);
return IsFF16 (m_begin+2);
}
else if (!atStart && m_end != 0xffff)
{
return IsFF16 (m_end);
}
else
{
return IsZero16 (m_end);
return false;
}
}
@ -565,7 +569,7 @@ PacketHistory::AddSmall (bool atStart,
if (m_data == 0)
{
m_data = PacketHistory::Create (10);
memset (m_data->m_data, 0, 4);
memset (m_data->m_data, 0xff, 4);
}
NS_ASSERT (m_data != 0);
uint16_t chunkUid = m_chunkUid;
@ -583,11 +587,11 @@ PacketHistory::AddSmall (bool atStart,
if (atStart)
{
next = m_begin;
prev = 0;
prev = 0xffff;
}
else
{
next = 0;
next = 0xffff;
prev = m_end;
}
@ -599,7 +603,13 @@ PacketHistory::AddSmall (bool atStart,
{
uintptr_t written = buffer - start;
NS_ASSERT (written <= 0xffff);
if (atStart)
if (m_begin == 0xffff)
{
NS_ASSERT (m_end == 0xffff);
m_begin = m_used;
m_end = m_used;
}
else if (atStart)
{
m_begin = m_used;
}
@ -607,6 +617,8 @@ PacketHistory::AddSmall (bool atStart,
{
m_end = m_used;
}
NS_ASSERT (m_end != 0xffff);
NS_ASSERT (m_begin != 0xffff);
m_used += written;
m_data->m_dirtyEnd = m_used;
return;
@ -622,9 +634,9 @@ PacketHistory::AddSmall (bool atStart,
}
void
PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer)
PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const
{
uint8_t *buffer = *pBuffer;
const uint8_t *buffer = *pBuffer;
item->next = buffer[0];
item->next |= (buffer[1]) << 8;
item->prev = buffer[2];
@ -636,7 +648,7 @@ PacketHistory::ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuff
}
void
PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer)
PacketHistory::ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const
{
item->fragmentStart = ReadUleb128 (pBuffer);
item->fragmentEnd = ReadUleb128 (pBuffer);
@ -743,7 +755,7 @@ PacketHistory::RemoveHeader (uint32_t uid, Chunk const & header, uint32_t size)
NS_FATAL_ERROR ("Removing header from empty packet.");
}
struct PacketHistory::SmallItem item;
uint8_t *buffer = &m_data->m_data[m_begin];
const uint8_t *buffer = &m_data->m_data[m_begin];
ReadSmall (&item, &buffer);
NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]);
if ((item.typeUid & 0xfffffffd) != uid ||
@ -790,7 +802,7 @@ PacketHistory::RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size
NS_FATAL_ERROR ("Removing trailer from empty packet.");
}
struct PacketHistory::SmallItem item;
uint8_t *buffer = &m_data->m_data[m_end];
const uint8_t *buffer = &m_data->m_data[m_end];
ReadSmall (&item, &buffer);
NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]);
if ((item.typeUid & 0xfffffffd) != uid ||
@ -902,14 +914,148 @@ PacketHistory::PrintDefault (std::ostream &os, Buffer buffer) const
Print (os, buffer, PacketPrinter::GetDefault ());
}
uint32_t
PacketHistory::DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer,
Buffer data, uint32_t offset, const PacketPrinter &printer,
std::ostream &os) const
{
ReadSmall (item, &buffer);
bool isExtra = (item->typeUid & 0x1) == 0x1;
uint32_t uid = item->typeUid & 0xfffffffd;
uint32_t fragmentStart, fragmentEnd;
uint32_t packetUid;
if (isExtra)
{
PacketHistory::ExtraItem extraItem;
ReadExtra (&extraItem, &buffer);
fragmentStart = extraItem.fragmentStart;
fragmentEnd = extraItem.fragmentEnd;
packetUid = extraItem.packetUid;
}
else
{
fragmentStart = 0;
fragmentEnd = item->size;
packetUid = m_packetUid;
}
NS_ASSERT (buffer < &m_data->m_data[m_data->m_size]);
if (uid == 0)
{
// payload.
printer.PrintPayload (os, packetUid, item->size,
fragmentStart,
fragmentEnd);
}
else if (fragmentStart != 0 &&
fragmentEnd != item->size)
{
printer.PrintChunkFragment (uid, os, packetUid, item->size,
fragmentStart, fragmentEnd);
}
else if (PacketPrinter::IsHeader (uid))
{
ns3::Buffer::Iterator j = data.Begin ();
j.Next (offset);
printer.PrintChunk (uid, j, os, packetUid, item->size);
}
else if (PacketPrinter::IsTrailer (uid))
{
ns3::Buffer::Iterator j = data.End ();
j.Prev (data.GetSize () - (offset + item->size));
printer.PrintChunk (uid, j, os, packetUid, item->size);
}
else
{
NS_ASSERT (false);
}
return fragmentEnd - fragmentStart;
}
uint32_t
PacketHistory::GetTotalSize (void) const
{
uint32_t totalSize = 0;
uint16_t current = m_begin;
uint16_t end = m_end;
while (current != 0xffff)
{
const uint8_t *buffer = &m_data->m_data[current];
struct PacketHistory::SmallItem item;
ReadSmall (&item, &buffer);
bool isExtra = (item.typeUid & 0x1) == 0x1;
uint32_t fragmentStart, fragmentEnd;
if (isExtra)
{
PacketHistory::ExtraItem extraItem;
ReadExtra (&extraItem, &buffer);
fragmentStart = extraItem.fragmentStart;
fragmentEnd = extraItem.fragmentEnd;
}
else
{
fragmentStart = 0;
fragmentEnd = item.size;
}
totalSize += fragmentEnd - fragmentStart;
current = item.next;
if (current == end)
{
break;
}
}
return totalSize;
}
void
PacketHistory::Print (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const
PacketHistory::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const
{
if (!m_enable)
{
return;
}
if (m_data == 0)
{
return;
}
NS_ASSERT (GetTotalSize () == data.GetSize ());
if (printer.m_forward)
{
uint32_t end = m_end;
uint32_t begin = m_begin;
uint32_t current = begin;
uint32_t offset = 0;
while (current != 0xffff)
{
uint8_t *buffer = &m_data->m_data[current];
struct PacketHistory::SmallItem item;
uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os);
offset += realSize;
current = item.next;
if (current == end)
{
break;
}
}
}
else
{
uint32_t end = m_begin;
uint32_t begin = m_end;
uint32_t current = begin;
uint32_t offset = 0;
while (current != 0xffff)
{
uint8_t *buffer = &m_data->m_data[current];
struct PacketHistory::SmallItem item;
uint32_t realSize = DoPrint (&item, buffer, data, offset, printer, os);
offset -= realSize;
current = item.prev;
if (current == end)
{
break;
}
}
}
}
@ -1117,8 +1263,8 @@ PacketHistoryTest::RegisterHeader (void)
static bool registered = false;
if (!registered)
{
m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintHeader<N>, this),
MakeCallback (&PacketHistoryTest::PrintFragment, this));
m_printer.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader<N>, this),
MakeCallback (&PacketHistoryTest::PrintFragment, this));
registered = true;
}
}
@ -1130,8 +1276,8 @@ PacketHistoryTest::RegisterTrailer (void)
static bool registered = false;
if (!registered)
{
m_printer.AddPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer<N>, this),
MakeCallback (&PacketHistoryTest::PrintFragment, this));
m_printer.AddTrailerPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer<N>, this),
MakeCallback (&PacketHistoryTest::PrintFragment, this));
registered = true;
}
}

View File

@ -96,15 +96,19 @@ private:
void AddSmall (bool atStart,
uint32_t typeUid, uint32_t size);
uint32_t GetUleb128Size (uint32_t value) const;
uint32_t ReadUleb128 (uint8_t **pBuffer) const;
uint32_t ReadUleb128 (const uint8_t **pBuffer) const;
void Append16 (uint16_t value, uint8_t **pBuffer);
bool TryToAppend (uint32_t value, uint8_t **pBuffer, uint8_t *end);
bool IsZero16 (uint16_t index);
bool IsFF16 (uint16_t index);
bool CanAdd (bool atStart);
void ReadSmall (struct PacketHistory::SmallItem *item, uint8_t **pBuffer);
void ReadExtra (struct PacketHistory::ExtraItem *item, uint8_t **pBuffer);
void ReadSmall (struct PacketHistory::SmallItem *item, const uint8_t **pBuffer) const;
void ReadExtra (struct PacketHistory::ExtraItem *item, const uint8_t **pBuffer) const;
void Reserve (uint32_t n);
void ReserveCopy (uint32_t n);
uint32_t DoPrint (struct PacketHistory::SmallItem *item, uint8_t const*buffer,
Buffer data, uint32_t offset, const PacketPrinter &printer,
std::ostream &os) const;
uint32_t GetTotalSize (void) const;
static struct PacketHistory::Data *Create (uint32_t size);
static void Recycle (struct PacketHistory::Data *data);
@ -131,26 +135,26 @@ template <typename T>
void
PacketHistory::AddHeader (T const &header, uint32_t size)
{
AddHeader (PacketPrinter::GetUid<T> (), header, size);
AddHeader (PacketPrinter::GetHeaderUid<T> (), header, size);
}
template <typename T>
void
PacketHistory::RemoveHeader (T const &header, uint32_t size)
{
RemoveHeader (PacketPrinter::GetUid<T> (), header, size);
RemoveHeader (PacketPrinter::GetHeaderUid<T> (), header, size);
}
template <typename T>
void
PacketHistory::AddTrailer (T const &trailer, uint32_t size)
{
AddTrailer (PacketPrinter::GetUid<T> (), trailer, size);
AddTrailer (PacketPrinter::GetTrailerUid<T> (), trailer, size);
}
template <typename T>
void
PacketHistory::RemoveTrailer (T const &trailer, uint32_t size)
{
RemoveTrailer (PacketPrinter::GetUid<T> (), trailer, size);
RemoveTrailer (PacketPrinter::GetTrailerUid<T> (), trailer, size);
}
}; // namespace ns3

View File

@ -87,12 +87,12 @@ PacketPrinter::PrintChunk (uint32_t chunkUid,
{
if (i->m_chunkUid == chunkUid)
{
DoPrintCallback cb = (*registeredChunks)[chunkUid-1].first;
DoPrintCallback cb = (*registeredChunks)[chunkUid/2-1].printCallback;
cb (i->m_printer, start, os, packetUid, size);
return;
}
}
DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second;
DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].getNameCallback;
std::string name = cb ();
struct PacketPrinter::FragmentInformation info;
info.start = 0;
@ -109,7 +109,7 @@ PacketPrinter::PrintChunkFragment (uint32_t chunkUid,
{
RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks ();
NS_ASSERT (chunkUid >= 1);
DoGetNameCallback cb = (*registeredChunks)[chunkUid-1].second;
DoGetNameCallback cb = (*registeredChunks)[chunkUid/2-1].getNameCallback;
std::string name = cb ();
struct PacketPrinter::FragmentInformation info;
info.start = fragmentStart;
@ -186,5 +186,23 @@ PacketPrinter::DoAddPrinter (uint32_t uid,
m_printerList.push_back (p);
}
bool
PacketPrinter::IsTrailer (uint32_t uid)
{
RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks ();
NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ());
bool isHeader = (*registeredChunks)[uid/2-1].isHeader;
return !isHeader;
}
bool
PacketPrinter::IsHeader (uint32_t uid)
{
RegisteredChunks *registeredChunks = PacketPrinter::GetRegisteredChunks ();
NS_ASSERT (uid >= 1 && uid/2 < registeredChunks->size ());
bool isHeader = (*registeredChunks)[uid/2-1].isHeader;
return isHeader;
}
} // namespace ns3

View File

@ -85,8 +85,15 @@ public:
* \param fragmentPrinter printer for a fragment of the specified chunk
*/
template <typename T>
void AddPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
ChunkFragmentPrinter fragmentPrinter);
void AddHeaderPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
ChunkFragmentPrinter fragmentPrinter);
/**
* \param printer printer for the specified chunk
* \param fragmentPrinter printer for a fragment of the specified chunk
*/
template <typename T>
void AddTrailerPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
ChunkFragmentPrinter fragmentPrinter);
/**
* \param printer printer for a chunk for which no callback was specified explicitely
*/
@ -95,6 +102,9 @@ public:
private:
friend class PacketHistory;
friend class ::ItemList;
typedef void (*DoPrintCallback) (Ptr<CallbackImplBase>, Buffer::Iterator, std::ostream &,
uint32_t, uint32_t);
typedef std::string (*DoGetNameCallback) (void);
struct Printer
{
uint32_t m_chunkUid;
@ -102,11 +112,14 @@ private:
Callback<void,std::ostream &,uint32_t,uint32_t,std::string &,struct PacketPrinter::FragmentInformation>
m_fragmentPrinter;
};
typedef void (*DoPrintCallback) (Ptr<CallbackImplBase>, Buffer::Iterator, std::ostream &,
uint32_t, uint32_t);
typedef std::string (*DoGetNameCallback) (void);
struct RegisteredChunk
{
DoPrintCallback printCallback;
DoGetNameCallback getNameCallback;
bool isHeader;
};
typedef std::vector<struct PacketPrinter::Printer> PrinterList;
typedef std::vector<std::pair<DoPrintCallback,DoGetNameCallback> > RegisteredChunks;
typedef std::vector<struct RegisteredChunk> RegisteredChunks;
static PacketPrinter GetDefault (void);
@ -138,10 +151,14 @@ private:
template <typename T>
static std::string DoGetName (void);
template <typename T>
static uint32_t GetUid (void);
static uint32_t GetTrailerUid (void);
template <typename T>
static uint32_t AllocateUid (void);
static uint32_t GetHeaderUid (void);
template <typename T>
static uint32_t AllocateUid (bool isHeader);
static RegisteredChunks *GetRegisteredChunks (void);
static bool IsTrailer (uint32_t uid);
static bool IsHeader (uint32_t uid);
void PrintChunk (uint32_t uid,
@ -179,7 +196,7 @@ namespace ns3 {
template <typename T>
void
PacketPrinter::AddPrinter (Callback<void,std::ostream &, uint32_t, uint32_t, const T *> printer,
PacketPrinter::AddHeaderPrinter (Callback<void,std::ostream &, uint32_t, uint32_t, const T *> printer,
Callback<void,
std::ostream &,
uint32_t,
@ -187,7 +204,21 @@ PacketPrinter::AddPrinter (Callback<void,std::ostream &, uint32_t, uint32_t, con
std::string &,
struct PacketPrinter::FragmentInformation> fragmentPrinter)
{
static uint32_t uid = PacketPrinter::GetUid<T> ();
static uint32_t uid = PacketPrinter::GetHeaderUid<T> ();
DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter);
}
template <typename T>
void
PacketPrinter::AddTrailerPrinter (Callback<void,std::ostream &, uint32_t, uint32_t, const T *> printer,
Callback<void,
std::ostream &,
uint32_t,
uint32_t,
std::string &,
struct PacketPrinter::FragmentInformation> fragmentPrinter)
{
static uint32_t uid = PacketPrinter::GetTrailerUid<T> ();
DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter);
}
@ -216,20 +247,31 @@ PacketPrinter::DoGetName (void)
template <typename T>
uint32_t
PacketPrinter::GetUid (void)
PacketPrinter::GetHeaderUid (void)
{
static uint32_t uid = PacketPrinter::AllocateUid<T> ();
static uint32_t uid = PacketPrinter::AllocateUid<T> (true);
return uid;
}
template <typename T>
uint32_t
PacketPrinter::GetTrailerUid (void)
{
static uint32_t uid = PacketPrinter::AllocateUid<T> (false);
return uid;
}
template <typename T>
uint32_t
PacketPrinter::AllocateUid (void)
PacketPrinter::AllocateUid (bool isHeader)
{
RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks ();
chunks->push_back (std::make_pair(&PacketPrinter::DoPrint<T>,
&PacketPrinter::DoGetName<T>));
uint32_t uid = chunks->size ();
RegisteredChunk chunk;
chunk.printCallback = &PacketPrinter::DoPrint<T>;
chunk.getNameCallback = &PacketPrinter::DoGetName<T>;
chunk.isHeader = isHeader;
chunks->push_back (chunk);
uint32_t uid = chunks->size () * 2;
PacketPrinter::PeekDefault ()->DoAddPrinter (uid,
MakeCallback (&PacketPrinter::DoDefaultPrint<T>).GetImpl (),
MakeCallback (&PacketPrinter::DoDefaultPrintFragment));