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

📄 fromipsumdump.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * fromipsumdump.{cc,hh} -- element reads packets from IP summary dump file * Eddie Kohler * * Copyright (c) 2001 International Computer Science Institute * Copyright (c) 2008 Meraki, Inc. * * 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 "fromipsumdump.hh"#include <click/confparse.hh>#include <click/router.hh>#include <click/standard/scheduleinfo.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <clicknet/ip.h>#include <clicknet/udp.h>#include <clicknet/tcp.h>#include <clicknet/icmp.h>#include <click/packet_anno.hh>#include <click/nameinfo.hh>#include <click/userutils.hh>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>CLICK_DECLS#ifdef i386# define GET4(p)	ntohl(*reinterpret_cast<const uint32_t *>((p)))# define GET2(p)	ntohs(*reinterpret_cast<const uint16_t *>((p)))#else# define GET4(p)	(((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])# define GET2(p)	(((p)[0]<<8) | (p)[1])#endif#define GET1(p)		((p)[0])FromIPSummaryDump::FromIPSummaryDump()    : _work_packet(0), _task(this), _timer(this){    _ff.set_landmark_pattern("%f:%l");}FromIPSummaryDump::~FromIPSummaryDump(){}void *FromIPSummaryDump::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);}intFromIPSummaryDump::configure(Vector<String> &conf, ErrorHandler *errh){    bool stop = false, active = true, zero = true, checksum = false, multipacket = false, timing = false;    uint8_t default_proto = IP_PROTO_TCP;    _sampling_prob = (1 << SAMPLING_SHIFT);    String default_contents, default_flowid;    if (cp_va_kparse(conf, this, errh,		     "FILENAME", cpkP+cpkM, cpFilename, &_ff.filename(),		     "STOP", 0, cpBool, &stop,		     "ACTIVE", 0, cpBool, &active,		     "ZERO", 0, cpBool, &zero,		     "TIMING", 0, cpBool, &timing,		     "CHECKSUM", 0, cpBool, &checksum,		     "SAMPLE", 0, cpUnsignedReal2, SAMPLING_SHIFT, &_sampling_prob,		     "PROTO", 0, cpByte, &default_proto,		     "MULTIPACKET", 0, cpBool, &multipacket,		     "DEFAULT_CONTENTS", 0, cpArgument, &default_contents,		     "DEFAULT_FLOWID", 0, cpArgument, &default_flowid,		     "CONTENTS", 0, cpArgument, &default_contents,		     "FLOWID", 0, cpArgument, &default_flowid,		     cpEnd) < 0)	return -1;    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");    _default_proto = default_proto;    _stop = stop;    _active = active;    _zero = zero;    _checksum = checksum;    _timing = timing;    _have_timing = false;    _multipacket = multipacket;    _have_flowid = _have_aggregate = _binary = false;    if (default_contents)	bang_data(default_contents, errh);    if (default_flowid)	bang_flowid(default_flowid, errh);    return 0;}intFromIPSummaryDump::read_binary(String &result, ErrorHandler *errh){    assert(_binary);    uint8_t record_storage[4];    const uint8_t *record = _ff.get_unaligned(4, record_storage, errh);    if (!record)	return 0;    int record_length = GET4(record) & 0x7FFFFFFFU;    if (record_length < 4)	return _ff.error(errh, "binary record too short");    bool textual = (record[0] & 0x80 ? true : false);    result = _ff.get_string(record_length - 4, errh);    if (!result)	return 0;    if (textual) {	const char *s = result.begin(), *e = result.end();	while (e > s && e[-1] == 0)	    e--;	if (e != result.end())	    result = result.substring(s, e);    }    _ff.set_lineno(_ff.lineno() + 1);    return (textual ? 2 : 1);}intFromIPSummaryDump::initialize(ErrorHandler *errh){    // make sure notifier is initialized    if (!output_is_push(0))	_notifier.initialize(Notifier::EMPTY_NOTIFIER, router());    _timer.initialize(this);    if (_ff.initialize(errh) < 0)	return -1;    _minor_version = IPSummaryDump::MINOR_VERSION; // expected minor version    String line;    if (_ff.peek_line(line, errh, true) < 0)	return -1;    else if (line.substring(0, 14) == "!IPSummaryDump") {	int major_version;	if (sscanf(line.c_str() + 14, " %d.%d", &major_version, &_minor_version) == 2) {	    if (major_version != IPSummaryDump::MAJOR_VERSION || _minor_version > IPSummaryDump::MINOR_VERSION) {		_ff.warning(errh, "unexpected IPSummaryDump version %d.%d", major_version, _minor_version);		_minor_version = IPSummaryDump::MINOR_VERSION;	    }	}	(void) _ff.read_line(line, errh, true); // throw away line    } else {	// parse line again, warn if this doesn't look like a dump	if (!line.substring(0, 8).equals("!creator", 8)	    && !line.substring(0, 5).equals("!data", 5)	    && !line.substring(0, 9).equals("!contents", 9)	    && !line.substring(0, 6).equals("!proto", 6)	    && !line.substring(0, 7).equals("!flowid", 7)) {	    if (!_fields.size() /* don't warn on DEFAULT_CONTENTS */)		_ff.warning(errh, "missing banner line; is this an IP summary dump?");	}    }    _format_complaint = false;    if (output_is_push(0))	ScheduleInfo::initialize_task(this, &_task, _active, errh);    return 0;}voidFromIPSummaryDump::cleanup(CleanupStage){    _ff.cleanup();    if (_work_packet)	_work_packet->kill();    _work_packet = 0;}intFromIPSummaryDump::sort_fields_compare(const void *ap, const void *bp,				       void *user_data){    int a = *reinterpret_cast<const int *>(ap);    int b = *reinterpret_cast<const int *>(bp);    FromIPSummaryDump *f = reinterpret_cast<FromIPSummaryDump *>(user_data);    const IPSummaryDump::FieldReader *fa = f->_fields[a];    const IPSummaryDump::FieldReader *fb = f->_fields[b];    if (fa->order < fb->order)	return -1;    if (fa->order > fb->order)	return 1;    return (a < b ? -1 : (a == b ? 0 : 1));}voidFromIPSummaryDump::bang_data(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    _fields.clear();    _field_order.clear();    for (int i = 0; i < words.size(); i++) {	String word = cp_unquote(words[i]);	if (i == 0 && (word == "!data" || word == "!contents"))	    continue;	const IPSummaryDump::FieldReader *f = IPSummaryDump::FieldReader::find(word);	if (!f) {	    _ff.warning(errh, "unknown content type '%s'", word.c_str());	    f = &IPSummaryDump::null_reader;	} else if (!f->inject) {	    _ff.warning(errh, "content type '%s' ignored on input", word.c_str());	    f = &IPSummaryDump::null_reader;	}	_fields.push_back(f);	_field_order.push_back(_fields.size() - 1);    }    if (_fields.size() == 0)	_ff.error(errh, "no contents specified");    click_qsort(_field_order.begin(), _fields.size(), sizeof(int),		sort_fields_compare, this);}voidFromIPSummaryDump::bang_proto(const String &line, const char *type,			      ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    int proto;    if (words.size() != 2)	_ff.error(errh, "bad %s", type);    else if (cp_integer(words[1], &proto) && proto < 256)	_default_proto = proto;    else if (words[1] == "T")	_default_proto = IP_PROTO_TCP;    else if (words[1] == "U")	_default_proto = IP_PROTO_UDP;    else if (words[1] == "I")	_default_proto = IP_PROTO_ICMP;    else	_ff.error(errh, "bad protocol in %s", type);}voidFromIPSummaryDump::bang_flowid(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    IPAddress src, dst;    uint32_t sport = 0, dport = 0;    if (words.size() < 5	|| (!cp_ip_address(words[1], &src) && words[1] != "-")	|| (!cp_integer(words[2], &sport) && words[2] != "-")	|| (!cp_ip_address(words[3], &dst) && words[3] != "-")	|| (!cp_integer(words[4], &dport) && words[4] != "-")	|| sport > 65535 || dport > 65535) {	_ff.error(errh, "bad !flowid specification");	_have_flowid = false;    } else {	if (words.size() >= 6)	    bang_proto(String::make_stable("! ", 2) + words[5], "!flowid", errh);	_given_flowid = IPFlowID(src, htons(sport), dst, htons(dport));	_have_flowid = true;    }}voidFromIPSummaryDump::bang_aggregate(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    if (words.size() != 2	|| !cp_integer(words[1], &_aggregate)) {	_ff.error(errh, "bad !aggregate specification");	_have_aggregate = false;    } else	_have_aggregate = true;}voidFromIPSummaryDump::bang_binary(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    if (words.size() != 1)	_ff.error(errh, "bad !binary specification");    _binary = true;    _ff.set_landmark_pattern("%f:record %l");    _ff.set_lineno(1);}static voidset_checksums(WritablePacket *q, click_ip *iph){    assert(iph == q->ip_header());    iph->ip_sum = 0;    iph->ip_sum = click_in_cksum((uint8_t *)iph, iph->ip_hl << 2);    if (IP_ISFRAG(iph))	/* nada */;    else if (iph->ip_p == IP_PROTO_TCP) {	click_tcp *tcph = q->tcp_header();	tcph->th_sum = 0;	unsigned csum = click_in_cksum((uint8_t *)tcph, q->transport_length());	tcph->th_sum = click_in_cksum_pseudohdr(csum, iph, q->transport_length());    } else if (iph->ip_p == IP_PROTO_UDP) {	click_udp *udph = q->udp_header();	udph->uh_sum = 0;	unsigned csum = click_in_cksum((uint8_t *)udph, q->transport_length());	udph->uh_sum = click_in_cksum_pseudohdr(csum, iph, q->transport_length());    }}Packet *FromIPSummaryDump::read_packet(ErrorHandler *errh){    // read non-packet lines    bool binary;    String line;    const char *data;    const char *end;    while (1) {	if ((binary = _binary)) {	    int result = read_binary(line, errh);	    if (result <= 0)		goto eof;	    else		binary = (result == 1);	} else if (_ff.read_line(line, errh, true) <= 0) {	  eof:	    _ff.cleanup();	    return 0;	}	data = line.begin();	end = line.end();	if (data == end)	    /* do nothing */;	else if (binary || (data[0] != '!' && data[0] != '#'))	    /* real packet */	    break;	// parse bang lines	if (data[0] == '!') {	    if (data + 6 <= end && memcmp(data, "!data", 5) == 0 && isspace((unsigned char) data[5]))		bang_data(line, errh);	    else if (data + 8 <= end && memcmp(data, "!flowid", 7) == 0 && isspace((unsigned char) data[7]))		bang_flowid(line, errh);	    else if (data + 7 <= end && memcmp(data, "!proto", 6) == 0 && isspace((unsigned char) data[6]))		bang_proto(line, "!proto", errh);	    else if (data + 11 <= end && memcmp(data, "!aggregate", 10) == 0 && isspace((unsigned char) data[10]))		bang_aggregate(line, errh);	    else if (data + 8 <= end && memcmp(data, "!binary", 7) == 0 && isspace((unsigned char) data[7]))		bang_binary(line, errh);	    else if (data + 10 <= end && memcmp(data, "!contents", 9) == 0 && isspace((unsigned char) data[9]))		bang_data(line, errh);	}    }    // read packet data    WritablePacket *q = Packet::make(16, (const unsigned char *) 0, 0, 1000);    if (!q) {	_ff.error(errh, strerror(ENOMEM));	return 0;    }    if (_zero)	memset(q->buffer(), 0, q->buffer_length());    // prepare packet data    StringAccum sa;    IPSummaryDump::PacketOdesc d(this, q, _default_proto, (_have_flowid ? &_flowid : 0), _minor_version);    int nfields = 0;    // new code goes here

⌨️ 快捷键说明

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