1.1 --- a/src/common/pcap-writer.cc Fri Jul 24 07:04:29 2009 -0700
1.2 +++ b/src/common/pcap-writer.cc Thu Aug 13 09:36:53 2009 +0200
1.3 @@ -29,6 +29,7 @@
1.4 #include "ns3/assert.h"
1.5 #include "ns3/abort.h"
1.6 #include "ns3/simulator.h"
1.7 +#include "ns3/uinteger.h"
1.8 #include "pcap-writer.h"
1.9 #include "packet.h"
1.10
1.11 @@ -36,6 +37,8 @@
1.12
1.13 namespace ns3 {
1.14
1.15 +NS_OBJECT_ENSURE_REGISTERED (PcapWriter);
1.16 +
1.17 enum {
1.18 PCAP_ETHERNET = 1,
1.19 PCAP_PPP = 9,
1.20 @@ -45,6 +48,21 @@
1.21 PCAP_80211_RADIOTAP = 127,
1.22 };
1.23
1.24 +TypeId
1.25 +PcapWriter::GetTypeId (void)
1.26 +{
1.27 + static TypeId tid = TypeId ("ns3::PcapWriter")
1.28 + .SetParent<Object> ()
1.29 + .AddConstructor<PcapWriter> ()
1.30 + .AddAttribute ("CaptureSize",
1.31 + "Number of bytes to capture at the start of each packet written in the pcap file. Zero means capture all bytes.",
1.32 + UintegerValue (0),
1.33 + MakeUintegerAccessor (&PcapWriter::m_captureSize),
1.34 + MakeUintegerChecker<uint32_t> ())
1.35 + ;
1.36 + return tid;
1.37 +}
1.38 +
1.39 PcapWriter::PcapWriter ()
1.40 {
1.41 NS_LOG_FUNCTION (this);
1.42 @@ -162,9 +180,18 @@
1.43 uint64_t us = current % 1000000;
1.44 Write32 (s & 0xffffffff);
1.45 Write32 (us & 0xffffffff);
1.46 - Write32 (packet->GetSize ());
1.47 - Write32 (packet->GetSize ());
1.48 - packet->CopyData (m_writer, packet->GetSize ());
1.49 + uint32_t thisCaptureSize;
1.50 + if (m_captureSize == 0)
1.51 + {
1.52 + thisCaptureSize = packet->GetSize ();
1.53 + }
1.54 + else
1.55 + {
1.56 + thisCaptureSize = std::min (m_captureSize, packet->GetSize ());
1.57 + }
1.58 + Write32 (thisCaptureSize);
1.59 + Write32 (packet->GetSize ()); // actual packet size
1.60 + packet->CopyData (m_writer, thisCaptureSize);
1.61 }
1.62 }
1.63
1.64 @@ -203,7 +230,10 @@
1.65 // real devices (e.g. madwifi) handle this case, especially for TX
1.66 // packets (radiotap specs says TSFT is not used for TX packets,
1.67 // but madwifi actually uses it).
1.68 - uint64_t tsft = current;
1.69 + uint64_t tsft = current;
1.70 +
1.71 +
1.72 + uint32_t wifiMonitorHeaderSize;
1.73
1.74 if (m_pcapMode == PCAP_80211_PRISM)
1.75 {
1.76 @@ -226,10 +256,17 @@
1.77 #define PRISM_ITEM_LENGTH 4
1.78
1.79
1.80 -
1.81 - uint32_t size = packet->GetSize () + PRISM_MSG_LENGTH;
1.82 - Write32 (size); // total packet size
1.83 - Write32 (size); // captured size
1.84 + wifiMonitorHeaderSize = PRISM_MSG_LENGTH;
1.85 + if (m_captureSize == 0)
1.86 + {
1.87 + Write32 (packet->GetSize () + wifiMonitorHeaderSize); // captured size == actual packet size
1.88 + }
1.89 + else
1.90 + {
1.91 + uint32_t thisCaptureSize = std::min (m_captureSize, packet->GetSize () + wifiMonitorHeaderSize);
1.92 + Write32 (thisCaptureSize);
1.93 + }
1.94 + Write32 (packet->GetSize () + wifiMonitorHeaderSize); // actual packet size
1.95
1.96 Write32(PRISM_MSG_CODE);
1.97 Write32(PRISM_MSG_LENGTH);
1.98 @@ -349,18 +386,26 @@
1.99
1.100 #define RADIOTAP_TX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL)
1.101 #define RADIOTAP_TX_LENGTH (8+8+1+1+2+2)
1.102 -
1.103 - uint32_t size;
1.104 +
1.105 if (isTx)
1.106 {
1.107 - size = packet->GetSize () + RADIOTAP_TX_LENGTH;
1.108 + wifiMonitorHeaderSize = RADIOTAP_TX_LENGTH;
1.109 }
1.110 else
1.111 {
1.112 - size = packet->GetSize () + RADIOTAP_RX_LENGTH;
1.113 + wifiMonitorHeaderSize = RADIOTAP_RX_LENGTH;
1.114 + }
1.115 +
1.116 + if (m_captureSize == 0)
1.117 + {
1.118 + Write32 (packet->GetSize () + wifiMonitorHeaderSize); // captured size == actual packet size
1.119 }
1.120 - Write32 (size); // total packet size
1.121 - Write32 (size); // captured size
1.122 + else
1.123 + {
1.124 + uint32_t thisCaptureSize = std::min (m_captureSize, packet->GetSize () + wifiMonitorHeaderSize);
1.125 + Write32 (thisCaptureSize);
1.126 + }
1.127 + Write32 (packet->GetSize () + wifiMonitorHeaderSize); // actual packet size
1.128
1.129 Write8(0); // radiotap version
1.130 Write8(0); // padding
1.131 @@ -412,11 +457,23 @@
1.132 }
1.133
1.134 // finally, write rest of packet
1.135 - packet->CopyData (m_writer, packet->GetSize ());
1.136 + if (m_captureSize == 0)
1.137 + {
1.138 + packet->CopyData (m_writer, packet->GetSize ());
1.139 + }
1.140 + else
1.141 + {
1.142 + packet->CopyData (m_writer, m_captureSize - wifiMonitorHeaderSize);
1.143 + }
1.144 +
1.145 }
1.146
1.147
1.148 -
1.149 +void
1.150 +PcapWriter::SetCaptureSize (uint32_t size)
1.151 +{
1.152 + m_captureSize = size;
1.153 +}
1.154
1.155 int8_t
1.156 PcapWriter::RoundToInt8 (double value)