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

📄 fromipsumdump.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 3 页
字号:
// -*- 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 * * 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 <click/packet_anno.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()    : Element(0, 1), _work_packet(0), _task(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)) {	_notifier.initialize(router());	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;    uint8_t default_proto = IP_PROTO_TCP;    _sampling_prob = (1 << SAMPLING_SHIFT);    String default_contents, default_flowid;        if (cp_va_parse(conf, this, errh,		    cpFilename, "dump file name", &_ff.filename(),		    cpKeywords,		    "STOP", cpBool, "stop driver when done?", &stop,		    "ACTIVE", cpBool, "start active?", &active,		    "ZERO", cpBool, "zero packet data?", &zero,		    "CHECKSUM", cpBool, "set packet checksums?", &checksum,		    "SAMPLE", cpUnsignedReal2, "sampling probability", SAMPLING_SHIFT, &_sampling_prob,		    "PROTO", cpByte, "default IP protocol", &default_proto,		    "MULTIPACKET", cpBool, "generate multiple packets per record?", &multipacket,		    "DEFAULT_CONTENTS", cpArgument, "default contents of log", &default_contents,		    "DEFAULT_FLOWID", cpArgument, "default flow ID", &default_flowid,		    "CONTENTS", cpArgument, "default contents of log", &default_contents,		    "FLOWID", cpArgument, "default flow ID", &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;    _multipacket = multipacket;    _have_flowid = _have_aggregate = _use_flowid = _use_aggregate = _binary = false;    if (default_contents)	bang_data(default_contents, errh);    if (default_flowid)	bang_flowid(default_flowid, 0, 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(router());        if (_ff.initialize(errh) < 0)	return -1;        _minor_version = IPSummaryDump::MINOR_VERSION; // expected minor version    String line;    if (_ff.peek_line(line, errh) < 0)	return -1;    else if (line.substring(0, 14) == "!IPSummaryDump") {	int major_version;	if (sscanf(line.cc() + 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); // throw away line    } else {	// parse line again, warn if this doesn't look like a dump	if (line.substring(0, 8) != "!creator" && line.substring(0, 5) != "!data" && line.substring(0, 9) != "!contents") {	    if (!_contents.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;}voidFromIPSummaryDump::bang_data(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    _contents.clear();    uint32_t all_contents = 0;    for (int i = 0; i < words.size(); i++) {	String word = cp_unquote(words[i]);	int what = parse_content(word);	if (what >= W_NONE && what < W_LAST) {	    _contents.push_back(what);	    all_contents |= (1 << (what - W_NONE));	} else if (i > 0 || (word != "!data" && word != "!contents")) {	    _ff.warning(errh, "unknown content type '%s'", word.c_str());	    _contents.push_back(W_NONE);	}    }    if (_contents.size() == 0)	_ff.error(errh, "no contents specified");    // If we have W_IP_FRAGOFF, ignore W_IP_FRAG.    if (all_contents & (1 << (W_IP_FRAGOFF - W_NONE)))	for (int i = 0; i < _contents.size(); i++)	    if (_contents[i] == W_IP_FRAG)		_contents[i] = W_NONE;    // recheck whether to use '!flowid' and '!aggregate'    check_defaults();}voidFromIPSummaryDump::check_defaults(){    _use_flowid = false;    _flowid = (_have_flowid ? _given_flowid : IPFlowID());    _use_aggregate = _have_aggregate;    for (int i = 0; i < _contents.size(); i++)	if (_contents[i] == W_IP_SRC)	    _flowid.set_saddr(IPAddress());	else if (_contents[i] == W_IP_DST)	    _flowid.set_daddr(IPAddress());	else if (_contents[i] == W_SPORT)	    _flowid.set_sport(0);	else if (_contents[i] == W_DPORT)	    _flowid.set_dport(0);	else if (_contents[i] == W_AGGREGATE)	    _use_aggregate = false;    if (_flowid || _flowid.sport() || _flowid.dport())	_use_flowid = true;}voidFromIPSummaryDump::bang_flowid(const String &line, click_ip *iph,			       ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    IPAddress src, dst;    uint32_t sport = 0, dport = 0, proto = 0;    if (words.size() < 5	|| (!cp_ip_address(words[1], &src) && words[1] != "-")	|| (!cp_unsigned(words[2], &sport) && words[2] != "-")	|| (!cp_ip_address(words[3], &dst) && words[3] != "-")	|| (!cp_unsigned(words[4], &dport) && words[4] != "-")	|| sport > 65535 || dport > 65535) {	_ff.error(errh, "bad !flowid specification");	_have_flowid = _use_flowid = false;    } else {	if (words.size() >= 6) {	    if (cp_unsigned(words[5], &proto) && proto < 256)		_default_proto = proto;	    else if (words[5] == "T")		_default_proto = IP_PROTO_TCP;	    else if (words[5] == "U")		_default_proto = IP_PROTO_UDP;	    else if (words[5] == "I")		_default_proto = IP_PROTO_ICMP;	    else		_ff.error(errh, "bad protocol in !flowid");	}	_given_flowid = IPFlowID(src, htons(sport), dst, htons(dport));	_have_flowid = true;	check_defaults();	if (iph)	    iph->ip_p = _default_proto;    }}voidFromIPSummaryDump::bang_aggregate(const String &line, ErrorHandler *errh){    Vector<String> words;    cp_spacevec(line, words);    if (words.size() != 2	|| !cp_unsigned(words[1], &_aggregate)) {	_ff.error(errh, "bad !aggregate specification");	_have_aggregate = _use_aggregate = false;    } else {	_have_aggregate = true;	check_defaults();    }}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");    for (int i = 0; i < _contents.size(); i++)	if (content_binary_size(_contents[i]) < 0) {	    _ff.error(errh, "contents incompatible with !binary");	    // XXX _pos = 0xFFFFFFFFU;	// prevent reading more data	}    _binary = true;    _ff.set_landmark_pattern("%f:record %l");    _ff.set_lineno(1);}static voidappend_net_uint32_t(StringAccum &sa, uint32_t u){    sa << (char)(u >> 24) << (char)(u >> 16) << (char)(u >> 8) << (char)u;}const unsigned char *FromIPSummaryDump::parse_ip_opt_ascii(const unsigned char *begin, const unsigned char *end, String *result, int contents){    StringAccum sa;    const unsigned char *s = begin;        while (1) {	const unsigned char *t;	uint32_t u1;	if (s + 3 < end && memcmp(s, "rr{", 3) == 0	    && (contents & DO_IPOPT_ROUTE)) {	    // record route	    sa << (char)IPOPT_RR;	    s += 3;	  parse_route:	    int sa_pos = sa.length() - 1;	    int pointer = -1;	    sa << '\0' << '\0';	    // loop over entries	    while (1) {		if (s < end && *s == '^' && pointer < 0)		    pointer = sa.length() - sa_pos + 1, s++;		if (s >= end || !isdigit(*s))		    break;		for (int i = 0; i < 4; i++) {		    u1 = 256;		    s = cp_unsigned(s, end, 10, &u1) + (i < 3);		    if (u1 > 255 || (i < 3 && (s > end || s[-1] != '.')))			goto bad_opt;		    sa << (char)u1;		}		if (s < end && *s == ',')		    s++;	    }	    if (s >= end || *s != '}') // must end with a brace		goto bad_opt;	    sa[sa_pos + 2] = (pointer >= 0 ? pointer : sa.length() - sa_pos + 1);	    if (s + 2 < end && s[1] == '+' && isdigit(s[2])) {		s = cp_unsigned(s + 2, end, 10, &u1);		if (u1 < 64)		    sa.append_fill('\0', u1 * 4);	    } else		s++;	    if (sa.length() - sa_pos > 255)		goto bad_opt;	    sa[sa_pos + 1] = sa.length() - sa_pos;	    	} else if (s + 5 < end && memcmp(s, "ssrr{", 5) == 0		   && (contents & DO_IPOPT_ROUTE)) {	    // strict source route option	    sa << (char)IPOPT_SSRR;	    s += 5;	    goto parse_route;	    	} else if (s + 5 < end && memcmp(s, "lsrr{", 5) == 0		   && (contents & DO_IPOPT_ROUTE)) {	    // loose source route option	    sa << (char)IPOPT_LSRR;	    s += 5;	    goto parse_route;	    	} else if (s + 3 < end		   && (memcmp(s, "ts{", 3) == 0 || memcmp(s, "ts.", 3) == 0)		   && (contents & DO_IPOPT_TS)) {	    // timestamp option	    int sa_pos = sa.length();	    sa << (char)IPOPT_TS << (char)0 << (char)0 << (char)0;	    uint32_t top_bit;	    int flag = -1;	    if (s[2] == '.') {		if (s + 6 < end && memcmp(s + 3, "ip{", 3) == 0)		    flag = 1, s += 6;		else if (s + 9 < end && memcmp(s + 3, "preip{", 6) == 0)		    flag = 3, s += 9;		else if (isdigit(s[3])			 && (t = cp_unsigned(s + 3, end, 0, (uint32_t *)&flag))			 && flag <= 15 && t < end && *t == '{')		    s = t + 1;		else		    goto bad_opt;	    } else		s += 3;	    int pointer = -1;	    	    // loop over timestamp entries	    while (1) {		if (s < end && *s == '^' && pointer < 0)		    pointer = sa.length() - sa_pos + 1, s++;		if (s >= end || (!isdigit(*s) && *s != '!'))		    break;		const unsigned char *entry = s;			      retry_entry:		if (flag == 1 || flag == 3 || flag == -2) {		    // parse IP address		    for (int i = 0; i < 4; i++) {			u1 = 256;			s = cp_unsigned(s, end, 10, &u1) + (i < 3);			if (u1 > 255 || (i < 3 && (s > end || s[-1] != '.')))			    goto bad_opt;			sa << (char)u1;		    }		    // prespecified IPs if we get here		    if (pointer >= 0 && flag == -2)			flag = 3;		    // check for valid value: either "=[DIGIT]", "=!", "=?"		    // (for pointer >= 0)		    if (s + 1 < end && *s == '=') {			if (isdigit(s[1]) || s[1] == '!')			    s++;			else if (s[1] == '?' && pointer >= 0) {			    sa << (char)0 << (char)0 << (char)0 << (char)0;			    s += 2;			    goto done_entry;			} else			    goto bad_opt;		    } else if (pointer >= 0) {			sa << (char)0 << (char)0 << (char)0 << (char)0;			goto done_entry;		    } else			goto bad_opt;		}				// parse timestamp value		assert(s < end);		top_bit = 0;		if (*s == '!')		    top_bit = 0x80000000U, s++;		if (s >= end || !isdigit(*s))		    goto bad_opt;		s = cp_unsigned(s, end, 0, &u1);		if (s < end && *s == '.' && flag == -1) {		    flag = -2;		    s = entry;		    goto retry_entry;		} else if (flag == -1)		    flag = 0;		u1 |= top_bit;		append_net_uint32_t(sa, u1);	      done_entry:		// check separator		if (s < end && *s == ',')		    s++;	    }	    	    // done with entries	    if (s < end && *s++ != '}')		goto bad_opt;	    if (flag == -2)		flag = 1;	    sa[sa_pos + 2] = (pointer >= 0 ? pointer : sa.length() - sa_pos + 1);	    if (s + 1 < end && *s == '+' && isdigit(s[1])		&& (s = cp_unsigned(s + 1, end, 0, &u1))		&& u1 < 64)		sa.append_fill('\0', u1 * (flag == 1 || flag == 3 ? 8 : 4));	    int overflow = 0;	    if (s + 2 < end && *s == '+' && s[1] == '+' && isdigit(s[2])		&& (s = cp_unsigned(s + 2, end, 0, &u1))		&& u1 < 16)		overflow = u1;	    sa[sa_pos + 3] = (overflow << 4) | flag;	    if (sa.length() - sa_pos > 255)		goto bad_opt;	    sa[sa_pos + 1] = sa.length() - sa_pos;	    	} else if (s < end && isdigit(*s) && (contents & DO_IPOPT_UNKNOWN)) {	    // unknown option	    s = cp_unsigned(s, end, 0, &u1);	    if (u1 >= 256)		goto bad_opt;	    sa << (char)u1;	    if (s + 1 < end && *s == '=' && isdigit(s[1])) {		int pos0 = sa.length();		sa << (char)0;		do {		    s = cp_unsigned(s + 1, end, 0, &u1);		    if (u1 >= 256)			goto bad_opt;		    sa << (char)u1;		} while (s + 1 < end && *s == ':' && isdigit(s[1]));		if (sa.length() > pos0 + 254)		    goto bad_opt;

⌨️ 快捷键说明

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