1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2009 University of Washington 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation; 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * 18 * Author: Craig Dowell (craigdo@ee.washington.edu) 19 */ 20 21 #ifndef PCAP_FILE_H 22 #define PCAP_FILE_H 23 24 #include <string> 25 #include <fstream> 26 #include <stdint.h> 27 #include "ns3/ptr.h" 28 29 namespace ns3 { 30 31 class Packet; 32 class Header; 33 34 35 /** 36 * \brief A class representing a pcap file 37 * 38 * A class representing a pcap file. This allows easy creation, writing and 39 * reading of files composed of stored packets; which may be viewed using 40 * standard tools. 41 */ 42 class PcapFile 43 { 44 public: 45 static const int32_t ZONE_DEFAULT = 0; /**< Time zone offset for current location */ 46 static const uint32_t SNAPLEN_DEFAULT = 65535; /**< Default value for maximum octets to save per packet */ 47 48 public: 49 PcapFile (); 50 ~PcapFile (); 51 52 /** 53 * \return true if the 'fail' bit is set in the underlying iostream, false otherwise. 54 */ 55 bool Fail (void) const; 56 /** 57 * \return true if the 'eof' bit is set in the underlying iostream, false otherwise. 58 */ 59 bool Eof (void) const; 60 /** 61 * Clear all state bits of the underlying iostream. 62 */ 63 void Clear (void); 64 65 /** 66 * Create a new pcap file or open an existing pcap file. Semantics are 67 * similar to the stdc++ io stream classes, but differ in that 68 * positions in the file are based on packets not characters. For example 69 * if the file is opened for reading, the file position indicator (seek 70 * position) points to the beginning of the first packet in the file, not 71 * zero (which would point to the start of the pcap header). 72 * 73 * Since a pcap file is always a binary file, the file type is automatically 74 * selected as a binary file (fstream::binary is automatically ored with the mode 75 * field). 76 * 77 * \param filename String containing the name of the file. 78 * 79 * \param mode the access mode for the file. 80 */ 81 void Open (std::string const &filename, std::ios::openmode mode); 82 83 /** 84 * Close the underlying file. 85 */ 86 void Close (void); 87 88 /** 89 * Initialize the pcap file associated with this object. This file must have 90 * been previously opened with write permissions. 91 * 92 * \param dataLinkType A data link type as defined in the pcap library. If 93 * you want to make resulting pcap files visible in existing tools, the 94 * data link type must match existing definitions, such as PCAP_ETHERNET, 95 * PCAP_PPP, PCAP_80211, etc. If you are storing different kinds of packet 96 * data, such as naked TCP headers, you are at liberty to locally define your 97 * own data link types. According to the pcap-linktype man page, "well-known" 98 * pcap linktypes range from 0 to 263. If you use a large random number for 99 * your type, chances are small for a collision. 100 * 101 * \param snapLen An optional maximum size for packets written to the file. 102 * Defaults to 65535. If packets exceed this length they are truncated. 103 * 104 * \param timeZoneCorrection An integer describing the offset of your local 105 * time zone from UTC/GMT. For example, Pacific Standard Time in the US is 106 * GMT-8, so one would enter -8 for that correction. Defaults to 0 (UTC). 107 * 108 * \param swapMode Flag indicating a difference in endianness of the 109 * writing system. Defaults to false. 110 * 111 * \param nanosecMode Flag indicating the time resolution of the writing 112 * system. Default to false. 113 * 114 * \warning Calling this method on an existing file will result in the loss 115 * any existing data. 116 */ 117 void Init (uint32_t dataLinkType, 118 uint32_t snapLen = SNAPLEN_DEFAULT, 119 int32_t timeZoneCorrection = ZONE_DEFAULT, 120 bool swapMode = false, 121 bool nanosecMode = false); 122 123 /** 124 * \brief Write next packet to file 125 * 126 * \param tsSec Packet timestamp, seconds 127 * \param tsUsec Packet timestamp, microseconds 128 * \param data Data buffer 129 * \param totalLen Total packet length 130 * 131 */ 132 void Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen); 133 134 /** 135 * \brief Write next packet to file 136 * 137 * \param tsSec Packet timestamp, seconds 138 * \param tsUsec Packet timestamp, microseconds 139 * \param p Packet to write 140 * 141 */ 142 void Write (uint32_t tsSec, uint32_t tsUsec, Ptr<const Packet> p); 143 /** 144 * \brief Write next packet to file 145 * 146 * \param tsSec Packet timestamp, seconds 147 * \param tsUsec Packet timestamp, microseconds 148 * \param header Header to write, in front of packet 149 * \param p Packet to write 150 * 151 */ 152 void Write (uint32_t tsSec, uint32_t tsUsec, const Header &header, Ptr<const Packet> p); 153 154 155 /** 156 * \brief Read next packet from file 157 * 158 * \param data [out] Data buffer 159 * \param maxBytes Allocated data buffer size 160 * \param tsSec [out] Packet timestamp, seconds 161 * \param tsUsec [out] Packet timestamp, microseconds 162 * \param inclLen [out] Included length 163 * \param origLen [out] Original length 164 * \param readLen [out] Number of bytes read 165 * 166 */ 167 void Read (uint8_t * const data, 168 uint32_t maxBytes, 169 uint32_t &tsSec, 170 uint32_t &tsUsec, 171 uint32_t &inclLen, 172 uint32_t &origLen, 173 uint32_t &readLen); 174 175 /** 176 * \brief Get the swap mode of the file. 177 * 178 * Pcap files use a magic number that is overloaded to identify both the 179 * format of the file itself and the byte ordering of the file. The magic 180 * number (and all data) is written into the file according to the native 181 * byte ordering of the writing system. If a reading application reads 182 * the magic number identically (for example 0xa1b2c3d4) then no byte 183 * swapping is required to correctly interpret the file data. If the reading 184 * application sees the magic number is byte swapped (for example 0xd4c3b2a1) 185 * then it knows that it needs to byteswap appropriate fields in the format. 186 * 187 * GetSWapMode returns a value indicating whether or not the fields are being 188 * byteswapped. Used primarily for testing the class itself, but may be 189 * useful as a flag indicating a difference in endianness of the writing 190 * system. 191 * 192 * \returns swap mode of the file 193 */ 194 bool GetSwapMode (void); 195 196 /** 197 * \brief Get the nanosecond mode of the file. 198 * 199 * \returns true if the packet timestamps in the PCAP 200 * file have nanosecond resolution. 201 */ 202 bool IsNanoSecMode (void); 203 204 /** 205 * \brief Returns the magic number of the pcap file as defined by the magic_number 206 * field in the pcap global header. 207 * 208 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 209 * 210 * \returns magic number 211 */ 212 uint32_t GetMagic (void); 213 214 /** 215 * \brief Returns the major version of the pcap file as defined by the version_major 216 * field in the pcap global header. 217 * 218 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 219 * 220 * \returns major version 221 */ 222 uint16_t GetVersionMajor (void); 223 224 /** 225 * \brief Returns the minor version of the pcap file as defined by the version_minor 226 * field in the pcap global header. 227 * 228 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 229 * 230 * \returns minor version 231 */ 232 uint16_t GetVersionMinor (void); 233 234 /** 235 * \brief Returns the time zone offset of the pcap file as defined by the thiszone 236 * field in the pcap global header. 237 * 238 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 239 * 240 * \returns time zone offset 241 */ 242 int32_t GetTimeZoneOffset (void); 243 244 /** 245 * \brief Returns the accuracy of timestamps field of the pcap file as defined 246 * by the sigfigs field in the pcap global header. 247 * 248 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 249 * 250 * \returns accuracy of timestamps 251 */ 252 uint32_t GetSigFigs (void); 253 254 /** 255 * \brief Returns the max length of saved packets field of the pcap file as 256 * defined by the snaplen field in the pcap global header. 257 * 258 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 259 * 260 * \returns max length of saved packets field 261 */ 262 uint32_t GetSnapLen (void); 263 264 /** 265 * \brief Returns the data link type field of the pcap file as defined by the 266 * network field in the pcap global header. 267 * 268 * See http://wiki.wireshark.org/Development/LibpcapFileFormat 269 * 270 * \returns data link type field 271 */ 272 uint32_t GetDataLinkType (void); 273 274 /** 275 * \brief Compare two PCAP files packet-by-packet 276 * 277 * \return true if files are different, false otherwise 278 * 279 * \param f1 First PCAP file name 280 * \param f2 Second PCAP file name 281 * \param sec [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ. 282 * \param usec [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ. 283 * \param packets [out] Number of first different packet. Total number of parsed packets if files doesn't differ. 284 * \param snapLen Snap length (if used) 285 */ 286 static bool Diff (std::string const & f1, std::string const & f2, 287 uint32_t & sec, uint32_t & usec, uint32_t & packets, 288 uint32_t snapLen = SNAPLEN_DEFAULT); 289 290 private: 291 /** 292 * \brief Pcap file header 293 */ 294 typedef struct { 295 uint32_t m_magicNumber; /**< Magic number identifying this as a pcap file */ 296 uint16_t m_versionMajor; /**< Major version identifying the version of pcap used in this file */ 297 uint16_t m_versionMinor; /**< Minor version identifying the version of pcap used in this file */ 298 int32_t m_zone; /**< Time zone correction to be applied to timestamps of packets */ 299 uint32_t m_sigFigs; /**< Unused by pretty much everybody */ 300 uint32_t m_snapLen; /**< Maximum length of packet data stored in records */ 301 uint32_t m_type; /**< Data link type of packet data */ 302 } PcapFileHeader; 303 304 /** 305 * \brief Pcap record header 306 */ 307 typedef struct { 308 uint32_t m_tsSec; /**< seconds part of timestamp */ 309 uint32_t m_tsUsec; /**< microseconds part of timestamp (nsecs for PCAP_NSEC_MAGIC) */ 310 uint32_t m_inclLen; /**< number of octets of packet saved in file */ 311 uint32_t m_origLen; /**< actual length of original packet */ 312 } PcapRecordHeader; 313 314 /** 315 * \brief Swap a value byte order 316 * \param val the value 317 * \returns the value with byte order swapped 318 */ 319 uint8_t Swap (uint8_t val); 320 /** 321 * \brief Swap a value byte order 322 * \param val the value 323 * \returns the value with byte order swapped 324 */ 325 uint16_t Swap (uint16_t val); 326 /** 327 * \brief Swap a value byte order 328 * \param val the value 329 * \returns the value with byte order swapped 330 */ 331 uint32_t Swap (uint32_t val); 332 /** 333 * \brief Swap the byte order of a Pcap file header 334 * \param from original file header 335 * \param to swapped file header 336 */ 337 void Swap (PcapFileHeader *from, PcapFileHeader *to); 338 /** 339 * \brief Swap the byte order of a Pcap record header 340 * \param from original record header 341 * \param to swapped record header 342 */ 343 void Swap (PcapRecordHeader *from, PcapRecordHeader *to); 344 345 /** 346 * \brief Write a Pcap file header 347 */ 348 void WriteFileHeader (void); 349 /** 350 * \brief Write a Pcap packet header 351 * 352 * The pcap header has a fixed length of 24 bytes. The last 4 bytes 353 * represent the link-layer type 354 * 355 * \param tsSec Time stamp (seconds part) 356 * \param tsUsec Time stamp (microseconds part) 357 * \param totalLen total packet length 358 * \returns the length of the packet to write in the Pcap file 359 */ 360 uint32_t WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen); 361 362 /** 363 * \brief Read and verify a Pcap file header 364 */ 365 void ReadAndVerifyFileHeader (void); 366 367 std::string m_filename; //!< file name 368 std::fstream m_file; //!< file stream 369 PcapFileHeader m_fileHeader; //!< file header 370 bool m_swapMode; //!< swap mode 371 bool m_nanosecMode; //!< nanosecond timestamp mode 372 }; 373 374 } // namespace ns3 375 376 #endif /* PCAP_FILE_H */ 377