diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index f3a3770d0..60ab5efcf 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -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, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddHeaderPrinter (MakeCallback (&PacketHistoryTest::PrintHeader, 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, this), - MakeCallback (&PacketHistoryTest::PrintFragment, this)); + m_printer.AddTrailerPrinter (MakeCallback (&PacketHistoryTest::PrintTrailer, this), + MakeCallback (&PacketHistoryTest::PrintFragment, this)); registered = true; } } diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 5e4fc0f33..579522a6e 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -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 void PacketHistory::AddHeader (T const &header, uint32_t size) { - AddHeader (PacketPrinter::GetUid (), header, size); + AddHeader (PacketPrinter::GetHeaderUid (), header, size); } template void PacketHistory::RemoveHeader (T const &header, uint32_t size) { - RemoveHeader (PacketPrinter::GetUid (), header, size); + RemoveHeader (PacketPrinter::GetHeaderUid (), header, size); } template void PacketHistory::AddTrailer (T const &trailer, uint32_t size) { - AddTrailer (PacketPrinter::GetUid (), trailer, size); + AddTrailer (PacketPrinter::GetTrailerUid (), trailer, size); } template void PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) { - RemoveTrailer (PacketPrinter::GetUid (), trailer, size); + RemoveTrailer (PacketPrinter::GetTrailerUid (), trailer, size); } }; // namespace ns3 diff --git a/src/common/packet-printer.cc b/src/common/packet-printer.cc index ed04c4761..1d3a94592 100644 --- a/src/common/packet-printer.cc +++ b/src/common/packet-printer.cc @@ -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 diff --git a/src/common/packet-printer.h b/src/common/packet-printer.h index fbea25d26..416bcc7de 100644 --- a/src/common/packet-printer.h +++ b/src/common/packet-printer.h @@ -85,8 +85,15 @@ public: * \param fragmentPrinter printer for a fragment of the specified chunk */ template - void AddPrinter (Callback printer, - ChunkFragmentPrinter fragmentPrinter); + void AddHeaderPrinter (Callback printer, + ChunkFragmentPrinter fragmentPrinter); + /** + * \param printer printer for the specified chunk + * \param fragmentPrinter printer for a fragment of the specified chunk + */ + template + void AddTrailerPrinter (Callback 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, 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 m_fragmentPrinter; }; - typedef void (*DoPrintCallback) (Ptr, Buffer::Iterator, std::ostream &, - uint32_t, uint32_t); - typedef std::string (*DoGetNameCallback) (void); + struct RegisteredChunk + { + DoPrintCallback printCallback; + DoGetNameCallback getNameCallback; + bool isHeader; + }; typedef std::vector PrinterList; - typedef std::vector > RegisteredChunks; + typedef std::vector RegisteredChunks; static PacketPrinter GetDefault (void); @@ -138,10 +151,14 @@ private: template static std::string DoGetName (void); template - static uint32_t GetUid (void); + static uint32_t GetTrailerUid (void); template - static uint32_t AllocateUid (void); + static uint32_t GetHeaderUid (void); + template + 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 void -PacketPrinter::AddPrinter (Callback printer, +PacketPrinter::AddHeaderPrinter (Callback printer, Callback fragmentPrinter) { - static uint32_t uid = PacketPrinter::GetUid (); + static uint32_t uid = PacketPrinter::GetHeaderUid (); + DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter); +} + +template +void +PacketPrinter::AddTrailerPrinter (Callback printer, + Callback fragmentPrinter) +{ + static uint32_t uid = PacketPrinter::GetTrailerUid (); DoAddPrinter (uid, printer.GetImpl (), fragmentPrinter); } @@ -216,20 +247,31 @@ PacketPrinter::DoGetName (void) template uint32_t -PacketPrinter::GetUid (void) +PacketPrinter::GetHeaderUid (void) { - static uint32_t uid = PacketPrinter::AllocateUid (); + static uint32_t uid = PacketPrinter::AllocateUid (true); + return uid; +} + +template +uint32_t +PacketPrinter::GetTrailerUid (void) +{ + static uint32_t uid = PacketPrinter::AllocateUid (false); return uid; } template uint32_t -PacketPrinter::AllocateUid (void) +PacketPrinter::AllocateUid (bool isHeader) { RegisteredChunks *chunks = PacketPrinter::GetRegisteredChunks (); - chunks->push_back (std::make_pair(&PacketPrinter::DoPrint, - &PacketPrinter::DoGetName)); - uint32_t uid = chunks->size (); + RegisteredChunk chunk; + chunk.printCallback = &PacketPrinter::DoPrint; + chunk.getNameCallback = &PacketPrinter::DoGetName; + chunk.isHeader = isHeader; + chunks->push_back (chunk); + uint32_t uid = chunks->size () * 2; PacketPrinter::PeekDefault ()->DoAddPrinter (uid, MakeCallback (&PacketPrinter::DoDefaultPrint).GetImpl (), MakeCallback (&PacketPrinter::DoDefaultPrintFragment));