Page MenuHomec4science

counterpereth.cc
No OneTemporary

File Metadata

Created
Fri, Jul 4, 20:13

counterpereth.cc

/*
* CounterPerEth.{cc,hh} -- element counts packets, measures duration
* Benjie Chen
*
* Copyright (c) 1999-2000 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 "counterpereth.hh"
#include <click/args.hh>
#include <click/straccum.hh>
#include <click/sync.hh>
#include <click/glue.hh>
#include <click/error.hh>
CLICK_DECLS
CounterPerEth::CounterPerEth()
{
}
void
CounterPerEth::reset()
{
_count.clear();
_byte_count.clear();
_first.clear();
_last.clear();
_count_global = 0;
}
int
CounterPerEth::configure(Vector<String> &conf, ErrorHandler *errh)
{
_ignore = 0;
_verb_debug = false;
if (Args(conf, this, errh)
.read_p("IGNORE", _ignore)
.read("VERB_DEBUG", _verb_debug)
.complete() < 0)
return -1;
_ignore *= CLICK_HZ;
return 0;
}
int
CounterPerEth::initialize(ErrorHandler *)
{
reset();
return 0;
}
Packet *
CounterPerEth::simple_action(Packet *p)
{
const click_ether *eth_hdr = p->ether_header();
EtherAddress eth = EtherAddress(eth_hdr->ether_dhost);
uint32_t jpart = click_jiffies();
_first[eth].compare_swap(0, jpart);
if (jpart - _first[eth] >= _ignore) {
_count[eth]++;
_byte_count[eth] += p->length();
_count_global++;
}
if(_verb_debug)
click_chatter("[CounterPerEth %s] Received packet to %s, count is %s", Timestamp::now().unparse().c_str(),
eth.unparse().c_str(), String(_count[eth]).c_str());
_last[eth] = jpart;
return p;
}
String
CounterPerEth::print_counts(int a) {
StringAccum s;
for(HashTable<EtherAddress,atomic_uint32_t>::iterator it = _count.begin();it.live();it++) {
if(_verb_debug)
click_chatter("[CounterPerEth] Get count for address %s", it.key().unparse().c_str());
s << it.key().unparse() << ":" << String(a ? _byte_count[it.key()] : _count[it.key()]) << " ";
}
return s.take_string();
}
String
CounterPerEth::print_rates(int a) {
StringAccum s;
for(HashTable<EtherAddress,atomic_uint32_t>::iterator it = _count.begin();it.live();it++) {
if(_verb_debug)
click_chatter("[CounterPerEth] Get rate for address %s", it.key().unparse().c_str());
uint32_t d = _last[it.key()] - _first[it.key()];
d -= _ignore;
if (d < 1) d = 1;
uint32_t count = (a ? _byte_count[it.key()] : _count[it.key()]);
#if CLICK_USERLEVEL
s << it.key().unparse() << ":" << String(((double) count * CLICK_HZ) / d) << " ";
#else
uint32_t rate;
if (count < (uint32_t) (0xFFFFFFFFU / CLICK_HZ))
rate = (count * CLICK_HZ) / d;
else
rate = (count / d) * CLICK_HZ;
s << it.key().unparse() << ":" << String(rate) << " ";
#endif
}
return s.take_string();
}
static String
read_count_handler(Element *e, void *thunk)
{
CounterPerEth *c = (CounterPerEth *)e;
if(((intptr_t) thunk) == 2)
return String(c->count_global());
return c->print_counts((intptr_t) thunk);
}
static String
read_rate_handler(Element *e, void *thunk)
{
CounterPerEth *c = (CounterPerEth *)e;
return c->print_rates((intptr_t) thunk);
}
static int
reset_write_handler
(const String &, Element *e, void *, ErrorHandler *)
{
CounterPerEth *c = (CounterPerEth *)e;
c->reset();
return 0;
}
void
CounterPerEth::add_handlers()
{
add_read_handler("count", read_count_handler, 0);
add_read_handler("byte_count", read_count_handler, 1);
add_read_handler("count_global", read_count_handler, 2);
add_read_handler("rate", read_rate_handler, 0);
add_read_handler("byte_rate", read_rate_handler, 1);
add_write_handler("reset", reset_write_handler, 0, Handler::BUTTON);
}
CLICK_ENDDECLS
EXPORT_ELEMENT(CounterPerEth)
ELEMENT_MT_SAFE(CounterPerEth)

Event Timeline