⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toipsumdump.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * toipsummarydump.{cc,hh} -- element writes packet summary in ASCII * Eddie Kohler * * Copyright (c) 2001-3 International Computer Science Institute * Copyright (c) 2004 Regents of the University of California * * 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 "toipsumdump.hh"#include <click/standard/scheduleinfo.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/packet_anno.hh>#include <clicknet/ip.h>#include <clicknet/udp.h>#include <clicknet/tcp.h>#include <unistd.h>#include <time.h>CLICK_DECLSToIPSummaryDump::ToIPSummaryDump()    : Element(1, 0), _f(0), _task(this){}ToIPSummaryDump::~ToIPSummaryDump(){}voidToIPSummaryDump::static_initialize(){    IPSummaryDump::anno_register_unparsers();    IPSummaryDump::ip_register_unparsers();    IPSummaryDump::tcp_register_unparsers();    IPSummaryDump::udp_register_unparsers();}voidToIPSummaryDump::static_cleanup(){    IPSummaryDump::static_cleanup();}intToIPSummaryDump::configure(Vector<String> &conf, ErrorHandler *errh){    int before = errh->nerrors();    String save = "timestamp ip_src";    bool verbose = false;    bool bad_packets = false;    bool careful_trunc = true;    bool multipacket = false;    bool binary = false;    if (cp_va_parse(conf, this, errh,		    cpFilename, "dump filename", &_filename,		    cpKeywords,		    "CONTENTS", cpArgument, "log contents", &save,		    "DATA", cpArgument, "log contents", &save,		    "VERBOSE", cpBool, "be verbose?", &verbose,		    "BANNER", cpString, "banner", &_banner,		    "MULTIPACKET", cpBool, "output multiple packets based on packet count anno?", &multipacket,		    "BAD_PACKETS", cpBool, "output '!bad' messages for non-IP or bad IP packets?", &bad_packets,		    "CAREFUL_TRUNC", cpBool, "output '!bad' messages for truncated IP packets?", &careful_trunc,		    "BINARY", cpBool, "output binary data?", &binary,		    cpEnd) < 0)	return -1;    Vector<String> v;    cp_spacevec(save, v);    _binary_size = 4;    for (int i = 0; i < v.size(); i++) {	String word = cp_unquote(v[i]);	const IPSummaryDump::Field* f = IPSummaryDump::find_field(word);	if (!f) {	    errh->error("unknown content type '%s'", word.c_str());	    continue;	}	// remember field	_fields.push_back(f);	// _prepare_fields	for (int j = 0; j < _prepare_fields.size(); j++)	    if (_prepare_fields[j]->prepare == f->prepare)		goto found_prepare;	if (f->prepare)	    _prepare_fields.push_back(f);	// binary size      found_prepare:	int s = f->binary_size();	if ((s < 0 || !f->outb) && binary)	    errh->error("cannot use CONTENTS %s with BINARY", word.c_str());	_binary_size += s;	// remove _multipacket if packet count specified	if (strcmp(f->name, "count") == 0)	    _multipacket = false;    }    if (_fields.size() == 0)	errh->error("no contents specified");        _verbose = verbose;    _bad_packets = bad_packets;    _careful_trunc = careful_trunc;    _multipacket = multipacket;    _binary = binary;    return (before == errh->nerrors() ? 0 : -1);}intToIPSummaryDump::initialize(ErrorHandler *errh){    assert(!_f);    if (_filename != "-") {	_f = fopen(_filename.c_str(), "wb");	if (!_f)	    return errh->error("%s: %s", _filename.cc(), strerror(errno));    } else {	_f = stdout;	_filename = "<stdout>";    }    if (input_is_pull(0)) {	ScheduleInfo::join_scheduler(this, &_task, errh);	_signal = Notifier::upstream_empty_signal(this, 0, &_task);    }    _active = true;    _output_count = 0;    // magic number    StringAccum sa;    sa << "!IPSummaryDump " << IPSummaryDump::MAJOR_VERSION << '.' << IPSummaryDump::MINOR_VERSION << '\n';    if (_banner)	sa << "!creator " << cp_quote(_banner) << '\n';        // host and start time    if (_verbose) {	char buf[BUFSIZ];	buf[BUFSIZ - 1] = '\0';	// ensure NUL-termination	if (gethostname(buf, BUFSIZ - 1) >= 0)	    sa << "!host " << buf << '\n';	time_t when = time(0);	const char *cwhen = ctime(&when);	struct timeval tv;	if (gettimeofday(&tv, 0) >= 0)	    sa << "!runtime " << tv << " (" << String(cwhen, strlen(cwhen) - 1) << ")\n";    }    // data description    sa << "!data ";    for (int i = 0; i < _fields.size(); i++)	sa << (i ? " " : "")	   << (strcmp(_fields[i]->name, "ntimestamp") == 0 && !_binary ? "timestamp" : _fields[i]->name);    sa << '\n';    // binary marker    if (_binary)	sa << "!binary\n";    // print output    fwrite(sa.data(), 1, sa.length(), _f);    return 0;}voidToIPSummaryDump::cleanup(CleanupStage){    if (_f && _f != stdout)	fclose(_f);    _f = 0;}boolToIPSummaryDump::summary(Packet* p, StringAccum& sa, StringAccum* bad_sa, bool force_extra_length) const{    IPSummaryDump::PacketDesc d(p, &sa, bad_sa, _careful_trunc, force_extra_length);    for (int i = 0; i < _prepare_fields.size(); i++)	_prepare_fields[i]->prepare(d);    if (_binary) {	sa.extend(4);	for (int i = 0; i < _fields.size(); i++) {	    d.clear_values();	    bool ok = _fields[i]->extract(d, _fields[i]->thunk);	    _fields[i]->outb(d, ok, _fields[i]->thunk);	}	*(reinterpret_cast<uint32_t*>(sa.data())) = htonl(sa.length());    } else {	for (int i = 0; i < _fields.size(); i++) {	    if (i)		sa << ' ';	    if (_fields[i]->extract(d, _fields[i]->thunk) && _fields[i]->outa)		_fields[i]->outa(d, _fields[i]->thunk);	    else		sa << '-';	}	sa << '\n';    }    return true;}voidToIPSummaryDump::write_packet(Packet* p, int multipacket){    if (multipacket > 0 && EXTRA_PACKETS_ANNO(p) > 0) {	uint32_t count = 1 + EXTRA_PACKETS_ANNO(p);	uint32_t total_len = p->length() + EXTRA_LENGTH_ANNO(p);	uint32_t len = p->length();	if (total_len < count * len)	    total_len = count * len;	// do timestamp stepping	Timestamp end_timestamp = p->timestamp_anno();	Timestamp timestamp_delta;	if (FIRST_TIMESTAMP_ANNO(p)) {	    timestamp_delta = (end_timestamp - FIRST_TIMESTAMP_ANNO(p)) / (count - 1);	    p->set_timestamp_anno(FIRST_TIMESTAMP_ANNO(p));	} else	    timestamp_delta = Timestamp();		SET_EXTRA_PACKETS_ANNO(p, 0);	for (uint32_t i = count; i > 0; i--) {	    uint32_t l = total_len / i;	    SET_EXTRA_LENGTH_ANNO(p, l - len);	    total_len -= l;	    write_packet(p, -1);	    if (i == 1)		p->timestamp_anno() = end_timestamp;	    else		p->timestamp_anno() += timestamp_delta;	}	    } else {	_sa.clear();	_bad_sa.clear();	summary(p, _sa, (_bad_packets ? &_bad_sa : 0), (multipacket < 0 || EXTRA_PACKETS_ANNO(p) > 0));	if (_bad_packets && _bad_sa)	    write_line(_bad_sa.take_string());	fwrite(_sa.data(), 1, _sa.length(), _f);	_output_count++;    }}voidToIPSummaryDump::push(int, Packet *p){    if (_active)	write_packet(p, _multipacket);    p->kill();}boolToIPSummaryDump::run_task(){    if (!_active)	return false;    if (Packet *p = input(0).pull()) {	write_packet(p, _multipacket);	p->kill();	_task.fast_reschedule();	return true;    } else if (_signal) {	_task.fast_reschedule();	return false;    } else	return false;}voidToIPSummaryDump::write_line(const String& s){    if (s.length()) {	assert(s.back() == '\n');	if (_binary) {	    uint32_t marker = htonl(s.length() | 0x80000000U);	    fwrite(&marker, 4, 1, _f);	}	fwrite(s.data(), 1, s.length(), _f);    }}voidToIPSummaryDump::add_note(const String &s){    if (s.length()) {	int extra = 1 + (s.back() == '\n' ? 0 : 1);	if (_binary) {	    uint32_t marker = htonl((s.length() + extra) | 0x80000000U);	    fwrite(&marker, 4, 1, _f);	}	fputc('#', _f);	fwrite(s.data(), 1, s.length(), _f);	if (extra > 1)	    fputc('\n', _f);    }}voidToIPSummaryDump::flush_buffer(){    fflush(_f);}voidToIPSummaryDump::add_handlers(){    if (input_is_pull(0))	add_task_handlers(&_task);}ELEMENT_REQUIRES(userlevel IPSummaryDump IPSummaryDump_Anno IPSummaryDump_IP IPSummaryDump_TCP)EXPORT_ELEMENT(ToIPSummaryDump)CLICK_ENDDECLS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -