etherdump.cc revision 2665
113481Sgiacomo.travaglini@arm.com/* 213481Sgiacomo.travaglini@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 313481Sgiacomo.travaglini@arm.com * All rights reserved. 413481Sgiacomo.travaglini@arm.com * 513481Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without 613481Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are 713481Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright 813481Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer; 913481Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright 1013481Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the 1113481Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution; 1213481Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its 1313481Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from 1413481Sgiacomo.travaglini@arm.com * this software without specific prior written permission. 1513481Sgiacomo.travaglini@arm.com * 1613481Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1713481Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1813481Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1913481Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2013481Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2113481Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2213481Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2313481Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2413481Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2513481Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2613481Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2713481Sgiacomo.travaglini@arm.com * 2813481Sgiacomo.travaglini@arm.com * Authors: Nathan Binkert 2913481Sgiacomo.travaglini@arm.com */ 3013481Sgiacomo.travaglini@arm.com 3113481Sgiacomo.travaglini@arm.com/* @file 3213481Sgiacomo.travaglini@arm.com * Simple object for creating a simple pcap style packet trace 3313481Sgiacomo.travaglini@arm.com */ 3413481Sgiacomo.travaglini@arm.com 3513481Sgiacomo.travaglini@arm.com#include <sys/time.h> 3613481Sgiacomo.travaglini@arm.com 3713481Sgiacomo.travaglini@arm.com#include <algorithm> 3813481Sgiacomo.travaglini@arm.com#include <string> 3913481Sgiacomo.travaglini@arm.com 4013481Sgiacomo.travaglini@arm.com#include "base/misc.hh" 4113481Sgiacomo.travaglini@arm.com#include "base/output.hh" 4213481Sgiacomo.travaglini@arm.com#include "dev/etherdump.hh" 4313481Sgiacomo.travaglini@arm.com#include "sim/builder.hh" 4413481Sgiacomo.travaglini@arm.com#include "sim/root.hh" 4513481Sgiacomo.travaglini@arm.com 4613481Sgiacomo.travaglini@arm.comusing std::string; 4713481Sgiacomo.travaglini@arm.com 4813481Sgiacomo.travaglini@arm.comEtherDump::EtherDump(const string &name, const string &file, int max) 4913481Sgiacomo.travaglini@arm.com : SimObject(name), stream(file.c_str()), maxlen(max) 5013481Sgiacomo.travaglini@arm.com{ 5113481Sgiacomo.travaglini@arm.com} 5213481Sgiacomo.travaglini@arm.com 5313481Sgiacomo.travaglini@arm.com#define DLT_EN10MB 1 // Ethernet (10Mb) 5413481Sgiacomo.travaglini@arm.com#define TCPDUMP_MAGIC 0xa1b2c3d4 5513481Sgiacomo.travaglini@arm.com#define PCAP_VERSION_MAJOR 2 5613481Sgiacomo.travaglini@arm.com#define PCAP_VERSION_MINOR 4 5713481Sgiacomo.travaglini@arm.com 5813481Sgiacomo.travaglini@arm.comstruct pcap_file_header { 5913481Sgiacomo.travaglini@arm.com uint32_t magic; 6013481Sgiacomo.travaglini@arm.com uint16_t version_major; 6113481Sgiacomo.travaglini@arm.com uint16_t version_minor; 6213481Sgiacomo.travaglini@arm.com int32_t thiszone; // gmt to local correction 6313481Sgiacomo.travaglini@arm.com uint32_t sigfigs; // accuracy of timestamps 6413481Sgiacomo.travaglini@arm.com uint32_t snaplen; // max length saved portion of each pkt 6513481Sgiacomo.travaglini@arm.com uint32_t linktype; // data link type (DLT_*) 6613481Sgiacomo.travaglini@arm.com}; 6713481Sgiacomo.travaglini@arm.com 6813481Sgiacomo.travaglini@arm.comstruct pcap_pkthdr { 6913481Sgiacomo.travaglini@arm.com uint32_t seconds; 7013481Sgiacomo.travaglini@arm.com uint32_t microseconds; 7113481Sgiacomo.travaglini@arm.com uint32_t caplen; // length of portion present 7213481Sgiacomo.travaglini@arm.com uint32_t len; // length this packet (off wire) 7313481Sgiacomo.travaglini@arm.com}; 7413481Sgiacomo.travaglini@arm.com 7513481Sgiacomo.travaglini@arm.comvoid 7613481Sgiacomo.travaglini@arm.comEtherDump::init() 7713481Sgiacomo.travaglini@arm.com{ 7813481Sgiacomo.travaglini@arm.com curtime = time(NULL); 7913481Sgiacomo.travaglini@arm.com struct pcap_file_header hdr; 8013481Sgiacomo.travaglini@arm.com hdr.magic = TCPDUMP_MAGIC; 8113481Sgiacomo.travaglini@arm.com hdr.version_major = PCAP_VERSION_MAJOR; 8213481Sgiacomo.travaglini@arm.com hdr.version_minor = PCAP_VERSION_MINOR; 8313481Sgiacomo.travaglini@arm.com 8413481Sgiacomo.travaglini@arm.com hdr.thiszone = -5 * 3600; 8513481Sgiacomo.travaglini@arm.com hdr.snaplen = 1500; 8613481Sgiacomo.travaglini@arm.com hdr.sigfigs = 0; 8713481Sgiacomo.travaglini@arm.com hdr.linktype = DLT_EN10MB; 8813481Sgiacomo.travaglini@arm.com 8913481Sgiacomo.travaglini@arm.com stream.write(reinterpret_cast<char *>(&hdr), sizeof(hdr)); 9013481Sgiacomo.travaglini@arm.com 9113481Sgiacomo.travaglini@arm.com /* 9213481Sgiacomo.travaglini@arm.com * output an empty packet with the current time so that we know 9313481Sgiacomo.travaglini@arm.com * when the simulation began. This allows us to correlate packets 9413481Sgiacomo.travaglini@arm.com * to sim_cycles. 9513481Sgiacomo.travaglini@arm.com */ 9613481Sgiacomo.travaglini@arm.com pcap_pkthdr pkthdr; 9713481Sgiacomo.travaglini@arm.com pkthdr.seconds = curtime; 9813481Sgiacomo.travaglini@arm.com pkthdr.microseconds = 0; 9913481Sgiacomo.travaglini@arm.com pkthdr.caplen = 0; 10013481Sgiacomo.travaglini@arm.com pkthdr.len = 0; 10113481Sgiacomo.travaglini@arm.com stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); 10213481Sgiacomo.travaglini@arm.com 10313481Sgiacomo.travaglini@arm.com stream.flush(); 10413481Sgiacomo.travaglini@arm.com} 10513481Sgiacomo.travaglini@arm.com 10613481Sgiacomo.travaglini@arm.comvoid 10713481Sgiacomo.travaglini@arm.comEtherDump::dumpPacket(EthPacketPtr &packet) 10813481Sgiacomo.travaglini@arm.com{ 10913481Sgiacomo.travaglini@arm.com pcap_pkthdr pkthdr; 11013481Sgiacomo.travaglini@arm.com pkthdr.seconds = curtime + (curTick / Clock::Int::s); 11113481Sgiacomo.travaglini@arm.com pkthdr.microseconds = (curTick / Clock::Int::us) % ULL(1000000); 11213481Sgiacomo.travaglini@arm.com pkthdr.caplen = std::min(packet->length, maxlen); 11313481Sgiacomo.travaglini@arm.com pkthdr.len = packet->length; 11413481Sgiacomo.travaglini@arm.com stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); 11513481Sgiacomo.travaglini@arm.com stream.write(reinterpret_cast<char *>(packet->data), pkthdr.caplen); 11613481Sgiacomo.travaglini@arm.com stream.flush(); 11713481Sgiacomo.travaglini@arm.com} 11813481Sgiacomo.travaglini@arm.com 11913481Sgiacomo.travaglini@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump) 12013481Sgiacomo.travaglini@arm.com 12113481Sgiacomo.travaglini@arm.com Param<string> file; 12213481Sgiacomo.travaglini@arm.com Param<int> maxlen; 12313481Sgiacomo.travaglini@arm.com 12413481Sgiacomo.travaglini@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(EtherDump) 12513481Sgiacomo.travaglini@arm.com 12613481Sgiacomo.travaglini@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump) 12713481Sgiacomo.travaglini@arm.com 12813481Sgiacomo.travaglini@arm.com INIT_PARAM(file, "file to dump packets to"), 12913481Sgiacomo.travaglini@arm.com INIT_PARAM(maxlen, "max portion of packet data to dump") 13013481Sgiacomo.travaglini@arm.com 13113481Sgiacomo.travaglini@arm.comEND_INIT_SIM_OBJECT_PARAMS(EtherDump) 13213481Sgiacomo.travaglini@arm.com 13313481Sgiacomo.travaglini@arm.comCREATE_SIM_OBJECT(EtherDump) 13413481Sgiacomo.travaglini@arm.com{ 13513481Sgiacomo.travaglini@arm.com return new EtherDump(getInstanceName(), simout.resolve(file), maxlen); 13613481Sgiacomo.travaglini@arm.com} 13713481Sgiacomo.travaglini@arm.com 13813481Sgiacomo.travaglini@arm.comREGISTER_SIM_OBJECT("EtherDump", EtherDump) 13913481Sgiacomo.travaglini@arm.com