--- a/src/devices/csma/csma-net-device.cc Wed Dec 02 11:25:49 2009 -0800
+++ b/src/devices/csma/csma-net-device.cc Wed Dec 02 14:29:43 2009 -0800
@@ -421,6 +421,10 @@
header.SetLengthType (lengthType);
p->AddHeader (header);
+ if (Node::ChecksumEnabled ())
+ {
+ trailer.EnableFcs (true);
+ }
trailer.CalcFcs (p);
p->AddTrailer (trailer);
}
@@ -747,6 +751,10 @@
EthernetTrailer trailer;
packet->RemoveTrailer (trailer);
+ if (Node::ChecksumEnabled ())
+ {
+ trailer.EnableFcs (true);
+ }
trailer.CheckFcs (packet);
EthernetHeader header (false);
--- a/src/node/ethernet-trailer.cc Wed Dec 02 11:25:49 2009 -0800
+++ b/src/node/ethernet-trailer.cc Wed Dec 02 14:29:43 2009 -0800
@@ -29,17 +29,10 @@
NS_OBJECT_ENSURE_REGISTERED (EthernetTrailer);
-bool EthernetTrailer::m_calcFcs = false;
-
EthernetTrailer::EthernetTrailer ()
-{
- Init();
-}
-
-void EthernetTrailer::Init()
-{
- m_fcs = 0;
-}
+ : m_calcFcs (false),
+ m_fcs (0)
+{}
void
EthernetTrailer::EnableFcs (bool enable)
@@ -50,21 +43,37 @@
bool
EthernetTrailer::CheckFcs (Ptr<Packet> p) const
{
+ int len = p->GetSize ();
+ uint8_t *buffer;
+ uint32_t crc;
+
if (!m_calcFcs)
{
return true;
- }
- else
- {
- NS_LOG_WARN ("FCS calculation is not yet enabled");
- return false;
}
+
+ buffer = new uint8_t[len];
+ p->CopyData (buffer, len);
+ crc = DoCalcFcs (buffer, len);
+ delete[] buffer;
+ return (m_fcs == crc);
}
void
EthernetTrailer::CalcFcs (Ptr<Packet> p)
{
- NS_LOG_WARN ("FCS calculation is not yet enabled");
+ int len = p->GetSize ();
+ uint8_t *buffer;
+
+ if (!m_calcFcs)
+ {
+ return;
+ }
+
+ buffer = new uint8_t[len];
+ p->CopyData (buffer, len);
+ m_fcs = DoCalcFcs (buffer, len);
+ delete[] buffer;
}
void
@@ -130,4 +139,23 @@
return size;
}
+// This code is copied from /lib/crc32.c in the linux kernel.
+// It assumes little endian ordering.
+uint32_t
+EthernetTrailer::DoCalcFcs (uint8_t *buffer, size_t len) const
+{
+ uint32_t crc = 0xffffffff;
+ int i;
+
+ while (len--)
+ {
+ crc ^= *buffer++;
+ for (i = 0; i < 8; i++)
+ {
+ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+ }
+ }
+ return ~crc;
+}
+
}; // namespace ns3
--- a/src/node/ethernet-trailer.h Wed Dec 02 11:25:49 2009 -0800
+++ b/src/node/ethernet-trailer.h Wed Dec 02 14:29:43 2009 -0800
@@ -22,11 +22,11 @@
#define ETHERNET_TRAILER_H
#include "ns3/trailer.h"
+#include "ns3/packet.h"
#include <string>
namespace ns3 {
-class Packet;
/**
* \ingroup node
@@ -46,10 +46,10 @@
EthernetTrailer ();
/**
- * \brief Enable or disabled FCS checking and calculations
+ * \brief Enable or disable FCS checking and calculations
* \param enable If true, enables FCS calculations.
*/
- static void EnableFcs (bool enable);
+ void EnableFcs (bool enable);
/**
* \brief Updates the Fcs Field to the correct FCS
* \param p Reference to a packet on which the FCS should be
@@ -89,19 +89,15 @@
virtual void Serialize (Buffer::Iterator end) const;
virtual uint32_t Deserialize (Buffer::Iterator end);
private:
-
- /**
- * Initializes the trailer parameters during construction.
- */
- void Init (void);
-
/**
* Enabled FCS calculations. If false, fcs is set to 0 and checkFCS
* returns true.
*/
- static bool m_calcFcs;
+ bool m_calcFcs;
uint32_t m_fcs; /// Value of the fcs contained in the trailer
+ uint32_t DoCalcFcs (uint8_t *buffer, size_t len) const;
+
};
} // namespace ns3