📄 availablerates.cc
字号:
/* * availablerates.{cc,hh} -- Poor man's arp table * John Bicket * * Copyright (c) 2003 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 <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <clicknet/ether.h>#include "availablerates.hh"CLICK_DECLSAvailableRates::AvailableRates(){ /* bleh */ static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; _bcast = EtherAddress(bcast_addr);}AvailableRates::~AvailableRates(){}void *AvailableRates::cast(const char *n){ if (strcmp(n, "AvailableRates") == 0) return (AvailableRates *) this; else return 0;}intAvailableRates::parse_and_insert(String s, ErrorHandler *errh){ EtherAddress e; Vector<int> rates; Vector<String> args; cp_spacevec(s, args); if (args.size() < 2) { return errh->error("error param %s must have > 1 arg", s.c_str()); } bool default_rates = false; if (args[0] == "DEFAULT") { default_rates = true; _default_rates.clear(); } else { if (!cp_ethernet_address(args[0], &e)) return errh->error("error param %s: must start with ethernet address", s.c_str()); } for (int x = 1; x< args.size(); x++) { int r; cp_integer(args[x], &r); if (default_rates) { _default_rates.push_back(r); } else { rates.push_back(r); } } if (default_rates) { return 0; } DstInfo d = DstInfo(e); d._rates = rates; d._eth = e; _rtable.insert(e, d); return 0;}intAvailableRates::configure(Vector<String> &conf, ErrorHandler *errh){ int res = 0; _debug = false; for (int x = 0; x < conf.size(); x++) { res = parse_and_insert(conf[x], errh); if (res != 0) { return res; } } return res;}voidAvailableRates::take_state(Element *e, ErrorHandler *){ AvailableRates *q = (AvailableRates *)e->cast("AvailableRates"); if (!q) return; _rtable = q->_rtable; _default_rates = _default_rates;}Vector<int>AvailableRates::lookup(EtherAddress eth){ if (!eth) { click_chatter("%s: lookup called with NULL eth!\n", name().c_str()); return Vector<int>(); } DstInfo *dst = _rtable.findp(eth); if (dst) { return dst->_rates; } if (_default_rates.size()) { return _default_rates; } return Vector<int>();}intAvailableRates::insert(EtherAddress eth, Vector<int> rates){ if (!(eth)) { if (_debug) { click_chatter("AvailableRates %s: You fool, you tried to insert %s\n", name().c_str(), eth.unparse().c_str()); } return -1; } DstInfo *dst = _rtable.findp(eth); if (!dst) { _rtable.insert(eth, DstInfo(eth)); dst = _rtable.findp(eth); } dst->_eth = eth; dst->_rates.clear(); if (_default_rates.size()) { /* only add rates that are in the default rates */ for (int x = 0; x < rates.size(); x++) { for (int y = 0; y < _default_rates.size(); y++) { if (rates[x] == _default_rates[y]) { dst->_rates.push_back(rates[x]); } } } } else { dst->_rates = rates; } return 0;}enum {H_DEBUG, H_INSERT, H_REMOVE, H_RATES};static StringAvailableRates_read_param(Element *e, void *thunk){ AvailableRates *td = (AvailableRates *)e; switch ((uintptr_t) thunk) { case H_DEBUG: return String(td->_debug) + "\n"; case H_RATES: { StringAccum sa; if (td->_default_rates.size()) { sa << "DEFAULT "; for (int x = 0; x < td->_default_rates.size(); x++) { sa << " " << td->_default_rates[x]; } sa << "\n"; } for (AvailableRates::RIter iter = td->_rtable.begin(); iter.live(); iter++) { AvailableRates::DstInfo n = iter.value(); sa << n._eth.unparse() << " "; for (int x = 0; x < n._rates.size(); x++) { sa << " " << n._rates[x]; } sa << "\n"; } return sa.take_string(); } default: return String(); }}static intAvailableRates_write_param(const String &in_s, Element *e, void *vparam, ErrorHandler *errh){ AvailableRates *f = (AvailableRates *)e; String s = cp_uncomment(in_s); switch((intptr_t)vparam) { case H_DEBUG: { bool debug; if (!cp_bool(s, &debug)) return errh->error("debug parameter must be boolean"); f->_debug = debug; break; } case H_INSERT: return f->parse_and_insert(in_s, errh); case H_REMOVE: { EtherAddress e; if (!cp_ethernet_address(s, &e)) return errh->error("remove parameter must be ethernet address"); f->_rtable.erase(e); break; } } return 0;}voidAvailableRates::add_handlers(){ add_read_handler("debug", AvailableRates_read_param, (void *) H_DEBUG); add_read_handler("rates", AvailableRates_read_param, (void *) H_RATES); add_write_handler("debug", AvailableRates_write_param, (void *) H_DEBUG); add_write_handler("insert", AvailableRates_write_param, (void *) H_INSERT); add_write_handler("remove", AvailableRates_write_param, (void *) H_REMOVE);}CLICK_ENDDECLSEXPORT_ELEMENT(AvailableRates)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -