src/common/pcap-writer.cc
changeset 4709 b0743dbc4e55
parent 4693 ca8cbdd42786
child 4715 d0041768ff60
     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)