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

📄 aggregateip.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * aggregateip.{cc,hh} -- set aggregate annotation based on IP field * Eddie Kohler * * Copyright (c) 2001-2003 International Computer Science Institute * Copyright (c) 2005 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 "aggregateip.hh"#include <click/error.hh>#include <click/hashmap.hh>#include <click/straccum.hh>#include <click/confparse.hh>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>#include <click/packet_anno.hh>CLICK_DECLSAggregateIP::AggregateIP()    : Element(1, 1){}AggregateIP::~AggregateIP(){}voidAggregateIP::notify_noutputs(int n){    set_noutputs(n <= 1 ? 1 : 2);}intAggregateIP::configure(Vector<String> &conf, ErrorHandler *errh){    String arg;    _incremental = _unshift_ip_addr = false;    if (cp_va_parse(conf, this, errh,		    cpArgument, "field specification", &arg,		    cpKeywords,		    "INCREMENTAL", cpBool, "incremental?", &_incremental,		    "UNSHIFT_IP_ADDR", cpBool, "unshift IP address fields?", &_unshift_ip_addr,		    cpEnd) < 0)	return -1;    const char *end = IPField::parse(arg.begin(), arg.end(), -1, &_f, errh, this);    if (end == arg.begin())	return -1;    else if (end != arg.end())	return errh->error("garbage after field specification");    int32_t right = _f.bit_offset() + _f.bit_length() - 1;    if ((_f.bit_offset() / 32) != (right / 32))	return errh->error("field specification does not fit within a single word");    if (_f.bit_length() > 32)	return errh->error("too many aggregates: field length too large, max 32");    else if (_f.bit_length() == 32 && _incremental)	return errh->error("`INCREMENTAL' is incompatible with field length 32");    if (_f.bit_length() == 32)	_mask = 0xFFFFFFFFU;    else	_mask = (1 << _f.bit_length()) - 1;    _offset = (_f.bit_offset() / 32) * 4;    if (!_unshift_ip_addr || _f.proto() != 0 || _f.bit_offset() < 12*8 || _f.bit_offset() >= 20*8)	_shift = 31 - right % 32;    else {	_mask <<= 31 - right % 32;	_shift = 0;    }    return 0;}Packet *AggregateIP::bad_packet(Packet *p){    if (noutputs() == 2)	output(1).push(p);    else	p->kill();    return 0;}Packet *AggregateIP::handle_packet(Packet *p){    const click_ip *iph = p->ip_header();    if (!iph)	return bad_packet(p);        int offset = p->length();    switch (_f.proto()) {      case 0:	offset = p->network_header_offset();	break;      case IP_PROTO_TCP_OR_UDP:	if (IP_FIRSTFRAG(iph) && (iph->ip_p == IP_PROTO_TCP || iph->ip_p == IP_PROTO_UDP))	    offset = p->transport_header_offset();	break;      case IP_PROTO_TRANSP:	if (IP_FIRSTFRAG(iph))	    offset = p->transport_header_offset();	break;      case IP_PROTO_PAYLOAD:	if (!IP_FIRSTFRAG(iph))	    /* bad; will be thrown away below */;	else if (iph->ip_p == IPPROTO_TCP && p->transport_header_offset() + sizeof(click_tcp) <= p->length()) {	    const click_tcp *tcph = (const click_tcp *)p->transport_header();	    offset = p->transport_header_offset() + (tcph->th_off << 2);	} else if (iph->ip_p == IPPROTO_UDP)	    offset = p->transport_header_offset() + sizeof(click_udp);	break;      default:	if (IP_FIRSTFRAG(iph) && iph->ip_p == _f.proto())	    offset = p->transport_header_offset();	break;    }    offset += _offset;    if (offset + 4 > (int)p->length())	return bad_packet(p);    uint32_t udata = *((const uint32_t *)(p->data() + offset));    uint32_t agg = (ntohl(udata) >> _shift) & _mask;    if (_incremental)	SET_AGGREGATE_ANNO(p, AGGREGATE_ANNO(p)*(_mask + 1) + agg);    else	SET_AGGREGATE_ANNO(p, agg);    return p;}voidAggregateIP::push(int, Packet *p){    if (Packet *q = handle_packet(p))	output(0).push(q);}Packet *AggregateIP::pull(int){    Packet *p = input(0).pull();    if (p)	p = handle_packet(p);    return p;}StringAggregateIP::read_handler(Element *e, void *thunk){    AggregateIP *aip = static_cast<AggregateIP *>(e);    switch ((intptr_t)thunk) {      case 0:	return NameInfo::revquery_int(NameInfo::T_IP_PROTO, e, aip->_f.proto());      case 1:	return String(aip->_f.bit_offset()) + "\n";      case 2:	return String(aip->_f.bit_length()) + "\n";      case 3:	return aip->_f.unparse(e, false) + "\n";      default:	return "<error>\n";    }}voidAggregateIP::add_handlers(){    add_read_handler("header", read_handler, (void *)0);    add_read_handler("bit_offset", read_handler, (void *)1);    add_read_handler("bit_length", read_handler, (void *)2);    add_read_handler("field", read_handler, (void *)3);}ELEMENT_REQUIRES(userlevel IPFieldInfo)EXPORT_ELEMENT(AggregateIP)#include <click/vector.cc>CLICK_ENDDECLS

⌨️ 快捷键说明

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