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