Merge zizzer:/bk/m5 into zeep.eecs.umich.edu:/z/saidi/work/m5
[gem5.git] / dev / etherdump.cc
index 89f1ce382c825b5e6403215996ede3d0b5eead6e..485d5599cba77f946c0d6e9c399497394f895322 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2002-2004 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <sys/time.h>
 
+#include <algorithm>
 #include <string>
 
+#include "base/misc.hh"
 #include "dev/etherdump.hh"
 #include "sim/builder.hh"
 #include "sim/universe.hh"
 
 using std::string;
 
-EtherDump::EtherDump(const string &name, const string &file)
-    : SimObject(name)
+EtherDump::EtherDump(const string &name, std::ostream *_stream, int max)
+    : SimObject(name), stream(_stream), maxlen(max)
 {
-    if (!file.empty()) {
-        stream.open(file.c_str());
-        if (stream.is_open())
-            init();
-    }
 }
 
 #define DLT_EN10MB             1               // Ethernet (10Mb)
@@ -66,7 +63,8 @@ struct pcap_file_header {
 };
 
 struct pcap_pkthdr {
-    struct timeval ts;         // time stamp
+    uint32_t seconds;
+    uint32_t microseconds;
     uint32_t caplen;           // length of portion present
     uint32_t len;              // length this packet (off wire)
 };
@@ -88,7 +86,7 @@ EtherDump::init()
     hdr.sigfigs = 0;
     hdr.linktype = DLT_EN10MB;
 
-    stream.write(reinterpret_cast<char *>(&hdr), sizeof(hdr));
+    stream->write(reinterpret_cast<char *>(&hdr), sizeof(hdr));
 
     /*
      * output an empty packet with the current time so that we know
@@ -96,57 +94,45 @@ EtherDump::init()
      * to sim_cycles.
      */
     pcap_pkthdr pkthdr;
-    pkthdr.ts.tv_sec = curtime;
-    pkthdr.ts.tv_usec = 0;
+    pkthdr.seconds = curtime;
+    pkthdr.microseconds = 0;
     pkthdr.caplen = 0;
     pkthdr.len = 0;
-    stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
+    stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
 
-    stream.flush();
+    stream->flush();
 }
 
 void
-EtherDump::dumpPacket(PacketPtr packet)
+EtherDump::dumpPacket(PacketPtr &packet)
 {
     pcap_pkthdr pkthdr;
-    pkthdr.ts.tv_sec = curtime + (curTick / s_freq);
-    pkthdr.ts.tv_usec = (curTick / us_freq) % ULL(1000000);
-    pkthdr.caplen = packet->length;
+    pkthdr.seconds = curtime + (curTick / s_freq);
+    pkthdr.microseconds = (curTick / us_freq) % ULL(1000000);
+    pkthdr.caplen = std::min(packet->length, maxlen);
     pkthdr.len = packet->length;
-    stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
-    stream.write(reinterpret_cast<char *>(packet->data), packet->length);
-    stream.flush();
+    stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
+    stream->write(reinterpret_cast<char *>(packet->data), pkthdr.caplen);
+    stream->flush();
 }
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
 
     Param<string> file;
+    Param<int> maxlen;
 
 END_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump)
 
-    INIT_PARAM(file, "file to dump packets to")
+    INIT_PARAM_DFLT(file, "file to dump packets to", "etherdump"),
+    INIT_PARAM_DFLT(maxlen, "max portion of packet data to dump", 96)
 
 END_INIT_SIM_OBJECT_PARAMS(EtherDump)
 
 CREATE_SIM_OBJECT(EtherDump)
 {
-    string filename;
-    if (file.isValid()) {
-        filename = file;
-
-        if (filename[0] != '/' && !outputDirectory.empty())
-            filename = outputDirectory + filename;
-    } else {
-        if (outputDirectory.empty()) {
-            filename = "etherdump";
-        } else {
-            filename = outputDirectory + "etherdump";
-        }
-    }
-
-    return new EtherDump(getInstanceName(), filename);
+    return new EtherDump(getInstanceName(), makeOutputStream(file), maxlen);
 }
 
 REGISTER_SIM_OBJECT("EtherDump", EtherDump)