etherdump.cc revision 1388
12623SN/A/* 22623SN/A * Copyright (c) 2002-2004 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272623SN/A */ 282623SN/A 292623SN/A/* @file 302623SN/A * Simple object for creating a simple pcap style packet trace 312623SN/A */ 322623SN/A 332623SN/A#include <sys/time.h> 342623SN/A 352623SN/A#include <algorithm> 362623SN/A#include <string> 372623SN/A 382623SN/A#include "base/misc.hh" 392623SN/A#include "base/output.hh" 402623SN/A#include "dev/etherdump.hh" 412623SN/A#include "sim/builder.hh" 422623SN/A#include "sim/universe.hh" 432623SN/A 442623SN/Ausing std::string; 452623SN/A 462623SN/AEtherDump::EtherDump(const string &name, const string &file, int max) 472623SN/A : SimObject(name), stream(file.c_str()), maxlen(max) 482623SN/A{ 492623SN/A} 502623SN/A 512623SN/A#define DLT_EN10MB 1 // Ethernet (10Mb) 522623SN/A#define TCPDUMP_MAGIC 0xa1b2c3d4 532623SN/A#define PCAP_VERSION_MAJOR 2 542623SN/A#define PCAP_VERSION_MINOR 4 552623SN/A 562623SN/Astruct pcap_file_header { 572623SN/A uint32_t magic; 582623SN/A uint16_t version_major; 592623SN/A uint16_t version_minor; 602623SN/A int32_t thiszone; // gmt to local correction 612623SN/A uint32_t sigfigs; // accuracy of timestamps 622623SN/A uint32_t snaplen; // max length saved portion of each pkt 632630SN/A uint32_t linktype; // data link type (DLT_*) 642623SN/A}; 652623SN/A 662623SN/Astruct pcap_pkthdr { 672623SN/A uint32_t seconds; 682623SN/A uint32_t microseconds; 692623SN/A uint32_t caplen; // length of portion present 702630SN/A uint32_t len; // length this packet (off wire) 712623SN/A}; 722623SN/A 732623SN/Avoid 742623SN/AEtherDump::init() 752623SN/A{ 762623SN/A curtime = time(NULL); 772623SN/A s_freq = ticksPerSecond; 782631SN/A us_freq = ticksPerSecond / ULL(1000000); 792631SN/A 802631SN/A struct pcap_file_header hdr; 812623SN/A hdr.magic = TCPDUMP_MAGIC; 822623SN/A hdr.version_major = PCAP_VERSION_MAJOR; 832623SN/A hdr.version_minor = PCAP_VERSION_MINOR; 842623SN/A 852623SN/A hdr.thiszone = -5 * 3600; 862623SN/A hdr.snaplen = 1500; 872623SN/A hdr.sigfigs = 0; 882623SN/A hdr.linktype = DLT_EN10MB; 892623SN/A 902623SN/A stream.write(reinterpret_cast<char *>(&hdr), sizeof(hdr)); 912623SN/A 922623SN/A /* 932623SN/A * output an empty packet with the current time so that we know 942623SN/A * when the simulation began. This allows us to correlate packets 952623SN/A * to sim_cycles. 962623SN/A */ 972623SN/A pcap_pkthdr pkthdr; 982623SN/A pkthdr.seconds = curtime; 992623SN/A pkthdr.microseconds = 0; 1002623SN/A pkthdr.caplen = 0; 1012623SN/A pkthdr.len = 0; 1022623SN/A stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); 1032623SN/A 1042623SN/A stream.flush(); 1052623SN/A} 1062623SN/A 1072623SN/Avoid 1082623SN/AEtherDump::dumpPacket(PacketPtr &packet) 1092623SN/A{ 1102623SN/A pcap_pkthdr pkthdr; 1112623SN/A pkthdr.seconds = curtime + (curTick / s_freq); 1122623SN/A pkthdr.microseconds = (curTick / us_freq) % ULL(1000000); 1132623SN/A pkthdr.caplen = std::min(packet->length, maxlen); 1142623SN/A pkthdr.len = packet->length; 1152623SN/A stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr)); 1162623SN/A stream.write(reinterpret_cast<char *>(packet->data), pkthdr.caplen); 1172623SN/A stream.flush(); 1182623SN/A} 1192623SN/A 1202623SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump) 1212623SN/A 1222623SN/A Param<string> file; 1232623SN/A Param<int> maxlen; 1242623SN/A 1252623SN/AEND_DECLARE_SIM_OBJECT_PARAMS(EtherDump) 1262623SN/A 1272623SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(EtherDump) 1282623SN/A 1292623SN/A INIT_PARAM_DFLT(file, "file to dump packets to", "etherdump"), 1302623SN/A INIT_PARAM_DFLT(maxlen, "max portion of packet data to dump", 96) 1312623SN/A 1322623SN/AEND_INIT_SIM_OBJECT_PARAMS(EtherDump) 1332623SN/A 1342623SN/ACREATE_SIM_OBJECT(EtherDump) 1352623SN/A{ 1362623SN/A return new EtherDump(getInstanceName(), simout.resolve(file), maxlen); 1372623SN/A} 1382623SN/A 1392623SN/AREGISTER_SIM_OBJECT("EtherDump", EtherDump) 1402623SN/A