📄 fromdump.cc
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * fromdump.{cc,hh} -- element reads packets from tcpdump file * Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2001-2003 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "fromdump.hh"#include <click/confparse.hh>#include <click/router.hh>#include <click/straccum.hh>#include <click/standard/scheduleinfo.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/handlercall.hh>#include <click/packet_anno.hh>#include <click/userutils.hh>#if CLICK_NS# include <click/master.hh>#endif#include "fakepcap.hh"#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifdef ALLOW_MMAP#include <sys/mman.h>#endifCLICK_DECLS#define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))#define SWAPSHORT(y) \ ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )FromDump::FromDump() : _packet(0), _end_h(0), _count(0), _timer(this), _task(this){}FromDump::~FromDump(){ delete _end_h;}void *FromDump::cast(const char *n){ if (strcmp(n, Notifier::EMPTY_NOTIFIER) == 0 && !output_is_push(0)) return static_cast<Notifier *>(&_notifier); else return Element::cast(n);}StringFromDump::declaration() const{ StringAccum sa; sa << name() << " :: " << class_name(); if (_ff.initialized()) sa << '(' << _ff.print_filename() << ')'; return sa.take_string();}intFromDump::configure(Vector<String> &conf, ErrorHandler *errh){ bool timing = false, stop = false, active = true, force_ip = false; Timestamp first_time, first_time_off, last_time, last_time_off, interval; _sampling_prob = (1 << SAMPLING_SHIFT);#if CLICK_NS bool per_node = false;#endif _packet_filepos = 0; if (_ff.configure_keywords(conf, this, errh) < 0) return -1; if (cp_va_kparse(conf, this, errh, "FILENAME", cpkP+cpkM, cpFilename, &_ff.filename(), "TIMING", cpkP, cpBool, &timing, "STOP", 0, cpBool, &stop, "ACTIVE", 0, cpBool, &active, "SAMPLE", 0, cpUnsignedReal2, SAMPLING_SHIFT, &_sampling_prob, "FORCE_IP", 0, cpBool, &force_ip, "START", 0, cpTimestamp, &first_time, "START_AFTER", 0, cpTimestamp, &first_time_off, "END", 0, cpTimestamp, &last_time, "END_AFTER", 0, cpTimestamp, &last_time_off, "INTERVAL", 0, cpTimestamp, &interval, "END_CALL", 0, cpHandlerCallPtrWrite, &_end_h,#if CLICK_NS "PER_NODE", 0, cpBool, &per_node,#endif "FILEPOS", 0, cpFileOffset, &_packet_filepos, cpEnd) < 0) return -1; // check sampling rate if (_sampling_prob > (1 << SAMPLING_SHIFT)) { errh->warning("SAMPLE probability reduced to 1"); _sampling_prob = (1 << SAMPLING_SHIFT); } else if (_sampling_prob == 0) errh->warning("SAMPLE probability is 0; emitting no packets"); // check times _have_first_time = _have_last_time = true; _first_time_relative = _last_time_relative = _last_time_interval = false; if ((bool) first_time + (bool) first_time_off > 1) return errh->error("'START' and 'START_AFTER' are mutually exclusive"); else if (first_time) _first_time = first_time; else if (first_time_off) _first_time = first_time_off, _first_time_relative = true; else _have_first_time = false, _first_time_relative = true; if ((bool) last_time + (bool) last_time_off + (bool) interval > 1) return errh->error("'END', 'END_AFTER', and 'INTERVAL' are mutually exclusive"); else if (last_time) _last_time = last_time; else if (last_time_off) _last_time = last_time_off, _last_time_relative = true; else if (interval) _last_time = interval, _last_time_interval = true; else _have_last_time = false; if (stop && _end_h) return errh->error("'END_CALL' and 'STOP' are mutually exclusive"); else if (stop) _end_h = new HandlerCall(name() + ".stop"); else if (_have_last_time && !_end_h) _end_h = new HandlerCall(name() + ".active false"); // set other variables _have_any_times = false; _timing = timing; _force_ip = force_ip;#if CLICK_NS if (per_node) { char tmp[255]; int r = simclick_sim_command(router()->simnode(), SIMCLICK_GET_NODE_NAME, tmp,255); if (r >= 0) _ff.filename() = String(tmp) + String("_") + _ff.filename(); }#endif _active = active; return 0;}static voidswap_file_header(const fake_pcap_file_header *hp, fake_pcap_file_header *outp){ outp->magic = SWAPLONG(hp->magic); outp->version_major = SWAPSHORT(hp->version_major); outp->version_minor = SWAPSHORT(hp->version_minor); outp->thiszone = SWAPLONG(hp->thiszone); outp->sigfigs = SWAPLONG(hp->sigfigs); outp->snaplen = SWAPLONG(hp->snaplen); outp->linktype = SWAPLONG(hp->linktype);}static voidswap_packet_header(const fake_pcap_pkthdr *hp, fake_pcap_pkthdr *outp){ outp->ts.tv.tv_sec = SWAPLONG(hp->ts.tv.tv_sec); outp->ts.tv.tv_usec = SWAPLONG(hp->ts.tv.tv_usec); outp->caplen = SWAPLONG(hp->caplen); outp->len = SWAPLONG(hp->len);}FromDump *FromDump::hotswap_element() const{ if (Element *e = Element::hotswap_element()) if (FromDump *fd = static_cast<FromDump *>(e->cast("FromDump"))) if (fd->_ff.filename() == _ff.filename()) return fd; return 0;}intFromDump::initialize(ErrorHandler *errh){ // make sure notifier is initialized if (!output_is_push(0)) _notifier.initialize(Notifier::EMPTY_NOTIFIER, router()); // check handler call, initialize Task if (_end_h && _end_h->initialize_write(this, errh) < 0) return -1; if (output_is_push(0)) ScheduleInfo::initialize_task(this, &_task, _active, errh); _timer.initialize(this); // skip if hotswapping if (hotswap_element()) return 0; // open file if (_ff.initialize(errh) < 0) return -1; // check magic number fake_pcap_file_header swapped_fh; const fake_pcap_file_header *fh = (const fake_pcap_file_header *)_ff.get_aligned(sizeof(fake_pcap_file_header), &swapped_fh); if (!fh) return _ff.error(errh, "not a tcpdump file (too short)"); if (fh->magic == FAKE_PCAP_MAGIC || fh->magic == FAKE_MODIFIED_PCAP_MAGIC) _swapped = false; else { swap_file_header(fh, &swapped_fh); _swapped = true; fh = &swapped_fh; } if (fh->magic != FAKE_PCAP_MAGIC && fh->magic != FAKE_MODIFIED_PCAP_MAGIC) return _ff.error(errh, "not a tcpdump file (bad magic number)"); // compensate for extra crap appended to packet headers _extra_pkthdr_crap = (fh->magic == FAKE_PCAP_MAGIC ? 0 : sizeof(fake_modified_pcap_pkthdr) - sizeof(fake_pcap_pkthdr)); if (fh->version_major != FAKE_PCAP_VERSION_MAJOR) return _ff.error(errh, "unknown major version %d", fh->version_major); _minor_version = fh->version_minor; // map possible host link types to global link types _linktype = fake_pcap_canonical_dlt(fh->linktype, true); // if forcing IP packets, check datalink type to ensure we understand it if (_force_ip) { if (!fake_pcap_dlt_force_ipable(_linktype)) return _ff.error(errh, "unknown linktype %d; can't force IP packets", _linktype); } else if (_linktype == FAKE_DLT_RAW) // force FORCE_IP. _force_ip = true; // maybe skip ahead in the file if (_packet_filepos != 0) { int result = _ff.seek(_packet_filepos, errh); _packet_filepos = 0; return result; } else return 0;}voidFromDump::take_state(Element *e, ErrorHandler *errh){ FromDump *o = static_cast<FromDump *>(e); // checked by hotswap_element() _ff.take_state(o->_ff, errh); _packet = o->_packet; o->_packet = 0; _swapped = o->_swapped; _extra_pkthdr_crap = o->_extra_pkthdr_crap; _minor_version = o->_minor_version; _linktype = o->_linktype; if (_linktype == FAKE_DLT_RAW) _force_ip = true; else if (_force_ip && !fake_pcap_dlt_force_ipable(_linktype)) _ff.warning(errh, "unknown linktype %d; can't force IP packets", _linktype); _time_offset = o->_time_offset; _packet_filepos = o->_packet_filepos;}voidFromDump::cleanup(CleanupStage){ _ff.cleanup(); if (_packet) _packet->kill(); _packet = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -