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

📄 fastudpsrc.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * fastudpsource.{cc,hh} -- fast udp source, a benchmark tool * * Copyright (c) 1999-2001 Massachusetts Institute of Technology * * 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 <clicknet/ip.h>#include "fastudpsrc.hh"#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/standard/alignmentinfo.hh>#include <machine/limits.h>FastUDPSource::FastUDPSource()  : _m(0){    _rate_limited = true;    _first = _last = 0;    _count = 0;    add_output();}FastUDPSource::~FastUDPSource(){}intFastUDPSource::configure(Vector<String> &conf, ErrorHandler *errh){    _cksum = true;    _active = true;    _interval = 0;    unsigned sp, dp;    unsigned rate;    int limit;    if (cp_va_parse(conf, this, errh,		    cpUnsigned, "send rate", &rate,		    cpInteger, "limit", &limit,		    cpUnsigned, "packet length", &_len,		    cpEthernetAddress, "src eth address", &_ethh.ether_shost,		    cpIPAddress, "src ip address", &_sipaddr,		    cpUnsigned, "src port", &sp,		    cpEthernetAddress, "dst eth address", &_ethh.ether_dhost,		    cpIPAddress, "dst ip address", &_dipaddr,		    cpUnsigned, "dst port", &dp,		    cpOptional,		    cpBool, "do UDP checksum?", &_cksum,		    cpUnsigned, "interval", &_interval,		    cpBool, "active?", &_active,		    cpEnd) < 0)	return -1;    if (sp >= 0x10000 || dp >= 0x10000)	return errh->error("source or destination port too large");    if (_len < 60) {	click_chatter("warning: packet length < 60, defaulting to 60");	_len = 60;    }    _ethh.ether_type = htons(0x0800);    _sport = sp;    _dport = dp;    if (rate != 0){	_rate_limited = true;	_rate.set_rate(rate, errh);    } else	_rate_limited = false;    _limit = (limit >= 0 ? limit : NO_LIMIT);    return 0;}voidFastUDPSource::incr_ports(){    click_ip *ip = reinterpret_cast<click_ip *>(_m->m_data+14);    click_udp *udp = reinterpret_cast<click_udp *>(ip + 1);    _incr++;    udp->uh_sport = htons(_sport+_incr);    udp->uh_dport = htons(_dport+_incr);    make_checksum(udp);}int FastUDPSource::initialize(ErrorHandler *){    // Create an mbuf with an mbuf cluster so copies are quick    // (we just add a reference to the cluster rather than doing    // a memory copy).    MGETHDR(_m, M_WAIT, MT_DATA);    if (_m == NULL) {	click_chatter("unable to get mbuf for FastUDPSource");	return -1;    }    MCLGET(_m, M_WAIT);    if ((_m->m_flags & M_EXT) == 0) {	m_freem(_m);	click_chatter("unable to get mbuf cluster for FastUDPSource");	return -1;    }    _m->m_len = _m->m_pkthdr.len = _len;    _count = 0;    _incr = 0;    memcpy(_m->m_data, &_ethh, 14);    click_ip *ip = reinterpret_cast<click_ip *>(_m->m_data+14);    click_udp *udp = reinterpret_cast<click_udp *>(ip + 1);    // set up IP header    ip->ip_v = 4;    ip->ip_hl = sizeof(click_ip) >> 2;    ip->ip_len = htons(_len-14);    ip->ip_id = 0;    ip->ip_p = IP_PROTO_UDP;    ip->ip_src = _sipaddr;    ip->ip_dst = _dipaddr;    ip->ip_tos = 0;    ip->ip_off = 0;    ip->ip_ttl = 250;    ip->ip_sum = 0;    ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip));    // set up UDP header    udp->uh_sport = htons(_sport);    udp->uh_dport = htons(_dport);    make_checksum(udp);    return 0;}voidFastUDPSource::cleanup(CleanupStage){    if (_m) {	m_freem(_m);	_m = 0;    }}Packet *FastUDPSource::pull(int){    Packet *p = 0;    struct mbuf *m;    if (!_active || (_limit != NO_LIMIT && _count >= _limit))	return 0;    // Ensure we can safely m_copypacket(_m) without overflowing    // the 8-bit refcount.    if ((_m->m_flags & M_EXT) == 0) {	static char _mcl_lost = 0;	// XXX should be in object ?	if (!_mcl_lost) {	    click_chatter("mbuf lost cluster!\n");	    _mcl_lost = 1;	}	return 0;    }    if (mclrefcnt[mtocl(_m->m_ext.ext_buf)] >= SCHAR_MAX) {	caddr_t mcl, mcl0;	MCLALLOC(mcl, M_WAIT);	if (!mcl) {	    click_chatter("failure to allocate new mbuf cluster\n");	    return 0;	}	bcopy(_m->m_data, mcl, _m->m_len);	mcl0 = _m->m_ext.ext_buf;	_m->m_data = mcl;	_m->m_ext.ext_buf = mcl;	MCLFREE(mcl0);    }    bool need_packet = false;    if (_rate_limited) {	struct timeval now;	click_gettimeofday(&now);	if (_rate.need_update(now)) {	    _rate.update();	    need_packet = true;	}    } else	need_packet = true;    if (!need_packet)	return 0;	// nothing to pull    m = m_copypacket(_m, M_WAIT);    if (!m) {	click_chatter("unable to m_copypacket\n");	return 0;	// bad luck.    }    p = Packet::make(m);    if (!p) {	click_chatter("unable to make packet\n");	return 0;	// bad luck.    }    _count++;    if (_count == 1)	_first = click_jiffies();    if (_limit != NO_LIMIT && _count >= _limit)	_last = click_jiffies();    if (_interval>0 && !(_count % _interval))	incr_ports();    return(p);}voidFastUDPSource::reset(){    _count = 0;    _first = 0;    _last = 0;    _incr = 0;}static StringFastUDPSource_read_count_handler(Element *e, void *){    FastUDPSource *c = (FastUDPSource *)e;    return String(c->count()) + "\n";}static StringFastUDPSource_read_rate_handler(Element *e, void *){    FastUDPSource *c = (FastUDPSource *)e;    if (c->last() != 0) {	int d = c->last() - c->first();	if (d < 1)	    d = 1;	int rate = c->count() * CLICK_HZ / d;	return String(rate) + "\n";    } else	return String("0\n");}static intFastUDPSource_reset_write_handler(const String &, Element *e, void *, ErrorHandler *){    FastUDPSource *c = (FastUDPSource *)e;    c->reset();    return 0;}static intFastUDPSource_limit_write_handler(const String &in_s, Element *e, void *, ErrorHandler *errh){    FastUDPSource *c = (FastUDPSource *)e;    String s = cp_uncomment(in_s);    unsigned limit;    if (!cp_unsigned(s, &limit))	return errh->error("limit parameter must be integer >= 0");    c->_limit = (limit >= 0 ? limit : c->NO_LIMIT);    return 0;}static intFastUDPSource_rate_write_handler(const String &in_s, Element *e, void *, ErrorHandler *errh){    FastUDPSource *c = (FastUDPSource *)e;    String s = cp_uncomment(in_s);    unsigned rate;    if (!cp_unsigned(s, &rate))	return errh->error("rate parameter must be integer >= 0");    if (rate > GapRate::MAX_RATE) // report error rather than pin to max	return errh->error("rate too large; max is %u", GapRate::MAX_RATE);    c->_rate.set_rate(rate);    return 0;}static intFastUDPSource_active_write_handler(const String &in_s, Element *e, void *, ErrorHandler *errh){    FastUDPSource *c = (FastUDPSource *)e;    String s = cp_uncomment(in_s);    bool active;    if (!cp_bool(s, &active)) 	return errh->error("active parameter must be boolean");    c->_active = active;    if (active)	c->reset();    return 0;}voidFastUDPSource::add_handlers(){    add_read_handler("count", FastUDPSource_read_count_handler, 0);    add_read_handler("rate", FastUDPSource_read_rate_handler, 0);    add_write_handler("rate", FastUDPSource_rate_write_handler, 0);    add_write_handler("reset", FastUDPSource_reset_write_handler, 0);    add_write_handler("active", FastUDPSource_active_write_handler, 0);    add_write_handler("limit", FastUDPSource_limit_write_handler, 0);}ELEMENT_REQUIRES(bsdmodule)EXPORT_ELEMENT(FastUDPSource)

⌨️ 快捷键说明

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