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

📄 etherpausesource.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
/* * etherpausesource.{cc,hh} -- generates Ethernet PAUSE MAC control frames * Eddie Kohler, based on etherpause.cc by Roman Chertov * * 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 "etherpausesource.hh"#include <click/confparse.hh>#include <click/etheraddress.hh>#include <clicknet/ether.h>#include <click/error.hh>#include <click/glue.hh>CLICK_DECLSstatic const unsigned char default_destination[6] = {    0x01, 0x80, 0xC2, 0x00, 0x00, 0x01};EtherPauseSource::EtherPauseSource()    : _packet(0), _timer(this){}EtherPauseSource::~EtherPauseSource(){}intEtherPauseSource::configure(Vector<String> &conf, ErrorHandler *errh){    EtherAddress src, dst(default_destination);    uint16_t pausetime;    _limit = -1;    _active = true;    _interval = 1000;    if (cp_va_kparse(conf, this, errh,		     "SRC", cpkP+cpkM, cpEtherAddress, &src,		     "PAUSETIME", cpkP+cpkM, cpUnsignedShort, &pausetime,		     "DST", 0, cpEtherAddress, &dst,		     "LIMIT", 0, cpInteger, &_limit,		     "ACTIVE", 0, cpBool, &_active,		     "INTERVAL", 0, cpSecondsAsMilli, &_interval,		     cpEnd) < 0)        return -1;    // build PAUSE frame    WritablePacket *q;    if (!(q = Packet::make(64)))	return errh->error("out of memory!"), -ENOMEM;    q->set_mac_header(q->data(), sizeof(click_ether));    click_ether *ethh = q->ether_header();    memcpy(ethh->ether_dhost, &dst, 6);    memcpy(ethh->ether_shost, &src, 6);    ethh->ether_type = htons(ETHERTYPE_MACCONTROL);    click_ether_macctl *emch = (click_ether_macctl *) q->network_header();    emch->ether_macctl_opcode = htons(ETHER_MACCTL_OP_PAUSE);    emch->ether_macctl_param = htons(pausetime);    memset(emch->ether_macctl_reserved, 0, sizeof(emch->ether_macctl_reserved));    _packet = q;    return 0;}intEtherPauseSource::initialize(ErrorHandler *){    _count = 0;    _timer.initialize(this);    if (_limit != 0 && _active && output_is_push(0))	_timer.schedule_after_msec(_interval);    return 0;}voidEtherPauseSource::cleanup(CleanupStage){    if (_packet) {        _packet->kill();        _packet = 0;    }}voidEtherPauseSource::run_timer(Timer *){    if (Packet *p = _packet->clone()) {	++_count;	output(0).push(p);    }    if (_limit < 0 || _count < _limit)	_timer.reschedule_after_msec(_interval);}Packet *EtherPauseSource::pull(int){    if (!_active || (_limit >= 0 && _count >= _limit))        return 0;    if (Packet *p = _packet->clone()) {	++_count;	return p;    } else	return 0;}StringEtherPauseSource::reader(Element *e, void *user_data){    EtherPauseSource *eps = static_cast<EtherPauseSource *>(e);    switch ((intptr_t) user_data) {    case h_src:	return EtherAddress(eps->_packet->ether_header()->ether_shost).unparse();    case h_dst:	return EtherAddress(eps->_packet->ether_header()->ether_dhost).unparse();    case h_pausetime: {	const click_ether_macctl *emc = (const click_ether_macctl *) eps->_packet->network_header();	return String(ntohs(emc->ether_macctl_param));    }    default:	return String();    }}intEtherPauseSource::rewrite_packet(const void *data, uint32_t offset, uint32_t size, ErrorHandler *errh){    if (WritablePacket *q = Packet::make(64)) {	memcpy(q->data(), _packet->data(), 64);	memcpy(q->data() + offset, data, size);	q->set_mac_header(q->data(), sizeof(click_ether));	_packet->kill();	_packet = q;	return 0;    } else	return errh->error("out of memory!"), -ENOMEM;}voidEtherPauseSource::check_awake(){    if (output_is_push(0) && !_timer.scheduled() && _active)	_timer.schedule_now();}intEtherPauseSource::writer(const String &str, Element *e, void *user_data, ErrorHandler *errh){    EtherPauseSource *eps = static_cast<EtherPauseSource *>(e);    switch ((intptr_t) user_data) {    case h_src:    case h_dst: {	EtherAddress a;	if (!cp_ethernet_address(str, &a, e))	    return errh->error("type mismatch");	return eps->rewrite_packet(&a, ((intptr_t) user_data == h_src ? offsetof(click_ether, ether_shost) : offsetof(click_ether, ether_dhost)), 6, errh);    }    case h_pausetime: {	uint32_t x;	if (!cp_integer(str, &x) || x > 0xFFFF)	    return errh->error("type mismatch");	uint16_t param = htons((uint16_t) x);	return eps->rewrite_packet(&param, sizeof(click_ether) + offsetof(click_ether_macctl, ether_macctl_param), 2, errh);    }    case h_limit:	if (!cp_integer(str, &eps->_limit))	    return errh->error("type mismatch");	eps->check_awake();	return 0;    case h_active:	if (!cp_bool(str, &eps->_active))	    return errh->error("type mismatch");	eps->check_awake();	return 0;    case h_reset_counts:	eps->_count = 0;	eps->check_awake();	return 0;    default:	return 0;    }}voidEtherPauseSource::add_handlers(){    add_data_handlers("count", Handler::OP_READ, &_count);    add_data_handlers("limit", Handler::OP_READ, &_limit);    add_write_handler("limit", writer, h_limit);    add_data_handlers("active", Handler::OP_READ | Handler::CHECKBOX, &_active);    add_write_handler("active", writer, h_active);    add_read_handler("src", reader, h_src);    add_write_handler("src", writer, h_src);    add_read_handler("dst", reader, h_dst);    add_write_handler("dst", writer, h_dst);    add_read_handler("pausetime", reader, h_pausetime);    add_write_handler("pausetime", writer, h_pausetime);    add_write_handler("reset_counts", writer, h_reset_counts);}CLICK_ENDDECLSEXPORT_ELEMENT(EtherPauseSource)

⌨️ 快捷键说明

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