Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F120492678
printroutingpacket.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Jul 4, 18:50
Size
20 KB
Mime Type
text/x-c
Expires
Sun, Jul 6, 18:50 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
27185472
Attached To
R6591 HyMAB
printroutingpacket.cc
View Options
#include <click/config.h>
#include <clicknet/ether.h>
#include <clicknet/ip.h>
#include <click/args.hh>
#include <click/error.hh>
#include <click/straccum.hh>
#include "printroutingpacket.hh"
#include <click/timestamp.hh>
#ifdef CLICK_LINUXMODULE
#include <linux/kernel.h>
#endif
CLICK_DECLS
PrintRoutingPacket::PrintRoutingPacket()
{
}
PrintRoutingPacket::~PrintRoutingPacket()
{
}
int
PrintRoutingPacket::configure(Vector<String> &conf, ErrorHandler *errh)
{
_active = true;
_all_msgs = false;
_with_eth = true;
_test_time = "";
_nb_packets = 0;
_wait_time = 0;
_begin = false;
_test_mab_id = false;
_mab_ctrl_msgs = false;
_print_every = 1;
_count_every = 0;
_count_every_all = 0;
_ts_only = false;
_print_special = false;
if(Args(this, errh).bind(conf)
.read("LABEL", _label)
.read("ACTIVE", _active)
.read("ALL_MSGS", _all_msgs)
.read("ETH_HDR_PRESENT", _with_eth)
.read("TIMESTAMP_ONLY", _ts_only)
.read("TEST_TIME", _test_time)
.read("WAIT_TIME", _wait_time)
.read("TEST_MAB_ID", _test_mab_id)
.read("MAB_CTRL_MSGS", _mab_ctrl_msgs)
.read("PRINT_EVERY", _print_every)
.read("PRINT_SPECIAL", _print_special)
.complete() < 0)
return -1;
if (!(_test_time.compare("") == 0 || _test_time.compare("fwd") == 0 || _test_time.compare("mfl") == 0 ||
_test_time.compare("price") == 0 || _test_time.compare("queue") == 0 ||
_test_time.compare("out") == 0 || _test_time.compare("final") == 0)) {
click_chatter("WARNING: unknown TEST_TIME argument in PrintRoutingPacket.");
_test_time = "";
}
return 0;
}
void
PrintRoutingPacket::push(int port, Packet *p) {
if (_active) {
if (_test_time.compare("") == 0)
print_packet(p);
else
p = update_packet_test_time(p);
}
else {
output(port).push(p);
return;
}
if (p)
output(port).push(p);
else
click_chatter("Error in PrintRoutingPacket, packet dropped");
}
Packet *
PrintRoutingPacket::pull(int port) {
Packet *p = input(port).pull();
if(p == 0) return 0;
if (_active) {
if (_test_time.compare("") == 0)
print_packet(p);
else
p = update_packet_test_time(p);
}
return p;
}
Packet *
PrintRoutingPacket::update_packet_test_time(Packet *p) {
Timestamp now;
now.assign_now();
if (_test_time.compare("fwd") == 0) {
// Header is acne_header
acne_header *acne_hdr = (acne_header *) (p->data());
if (acne_hdr->_type == PROTO_IP_TEST) {
test_time_header *tt_hdr = (test_time_header *) (p->data() + sizeof(acne_header));
tt_hdr->_ts_fwd = now;
}
return p;
}
// Header is ethernet header + acne_header
acne_header *acne_hdr = (acne_header *) (p->data() + sizeof(click_ether));
test_time_header *tt_hdr;
if (acne_hdr->_type == PROTO_IP_TEST) {
tt_hdr = (test_time_header *) (p->data() + sizeof(click_ether) + sizeof(acne_header));
}
else
return p;
if (_test_time.compare("mfl") == 0) {
tt_hdr->_ts_mfl = now;
return p;
}
if (_test_time.compare("price") == 0) {
tt_hdr->_ts_price = now;
return p;
}
if (_test_time.compare("queue") == 0) {
tt_hdr->_ts_queue = now;
return p;
}
if (_test_time.compare("out") == 0) {
tt_hdr->_ts_out = now;
return p;
}
if (_test_time.compare("final") == 0) {
if (_time_first_packet == Timestamp())
_time_first_packet = now;
if (_begin || (now - _time_first_packet).sec() >= _wait_time) {
if (!_begin)
_time_first_packet = now;
_begin = true;
_time_last_packet = now;
_nb_packets++;
_bytes_received += p->length();
_time_cc_fwd += (tt_hdr->_ts_fwd - tt_hdr->_ts_cc);
if ((tt_hdr->_ts_fwd - tt_hdr->_ts_cc) > _max_time_cc_fwd)
_max_time_cc_fwd = (tt_hdr->_ts_fwd - tt_hdr->_ts_cc);
_time_fwd_mfl += (tt_hdr->_ts_mfl - tt_hdr->_ts_fwd);
if ((tt_hdr->_ts_mfl - tt_hdr->_ts_fwd) > _max_time_fwd_mfl)
_max_time_fwd_mfl = (tt_hdr->_ts_mfl - tt_hdr->_ts_fwd);
_time_mfl_price += (tt_hdr->_ts_price - tt_hdr->_ts_mfl);
if ((tt_hdr->_ts_price - tt_hdr->_ts_mfl) > _max_time_mfl_price)
_max_time_mfl_price = (tt_hdr->_ts_price - tt_hdr->_ts_mfl);
_time_price_queue += (tt_hdr->_ts_queue - tt_hdr->_ts_price);
if ((tt_hdr->_ts_queue - tt_hdr->_ts_price) > _max_time_price_queue)
_max_time_price_queue = (tt_hdr->_ts_queue - tt_hdr->_ts_price);
_time_queue_out += (tt_hdr->_ts_out - tt_hdr->_ts_queue);
if ((tt_hdr->_ts_out - tt_hdr->_ts_queue) > _max_time_queue_out)
_max_time_queue_out = (tt_hdr->_ts_out - tt_hdr->_ts_queue);
}
return p;
}
return p;
}
void
PrintRoutingPacket::print_packet(Packet *p) {
if (_ts_only) {
Timestamp now;
now.assign_now();
if(_label)
click_chatter("%s: %s", _label.c_str(), now.unparse().c_str());
else
click_chatter("%s", now.unparse().c_str());
return;
}
String str;
StringAccum s;
click_ether *eth_hdr;
click_ether_vlan *vlan_hdr;
if (_with_eth) {
eth_hdr = (click_ether *) (p->data());
vlan_hdr = (click_ether_vlan *) p->data();
}
if(!_with_eth || ntohs(eth_hdr->ether_type) == ETHERTYPE_ACNE) {
acne_header *hdr = (acne_header *)(p->data() + _with_eth*sizeof(click_ether));
if(hdr->_type == REGULAR_TRAFFIC || (_print_special && hdr->_type == SPECIAL_TRAFFIC) || hdr->_type == PROTO_IP_TEST || hdr->_type == DUMMY_TRAFFIC_MAB) {
_count_every++;
String last_str = "";
if(!hdr->_is_last) {
if(_count_every < _print_every)
return;
_count_every = 0;
}
else
last_str = " last";
if(!_test_mab_id || hdr->_id_rate_mab > 0) {
const click_ip *ip_hdr = (click_ip *) (p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
if(_label) {
s << _label;
s << ": ";
}
Timestamp now;
now.assign_now();
s << now << "(" << p->timestamp_anno() << ")";
s << ": ";
s << String(p->length());
s << " | ";
if (_with_eth){
s << "eth ";
s << " (" << String::make_numeric(static_cast<String::uintmax_t>(ntohs(eth_hdr->ether_type)), 16, true) << ") ";
s << EtherAddress(eth_hdr->ether_shost);
s << "->";
s << EtherAddress(eth_hdr->ether_dhost);
s << "; ";
}
if(hdr->_type == SPECIAL_TRAFFIC)
s << "SPECIAL_TRAF" << last_str;
else if (hdr->_type == REGULAR_TRAFFIC)
s << "REG_TRAF" << last_str;
else if (hdr->_type == PROTO_IP_TEST)
s << "IP_TEST" << last_str;
else if (hdr->_type == DUMMY_TRAFFIC_MAB)
s << "DUMMY_MAB" << last_str;
else
s << "type " << String(hdr->_type) << last_str;
s << ", seq "+String(hdr->_seq)+", from " << LastAddrBytes(hdr->_route._src).unparse() << " to " << LastAddrBytes(hdr->_route._dst).unparse();
s << " MAB id " << String(hdr->_id_rate_mab) << ", hop ";
str = String::make_garbage(1);
if (char *x = str.mutable_c_str())
sprintf(x, "%d",hdr->_hop);
s << str << ", route " << hdr->_route.unparse() << "; ";
s << "ip " << IPAddress(ip_hdr->ip_src) << "->" << IPAddress(ip_hdr->ip_dst);
click_chatter(s.c_str());
}
}
else if(_all_msgs || _mab_ctrl_msgs) {
StringAccum s;
if(_label) {
s << _label;
s << ": ";
}
Timestamp now;
now.assign_now();
s << now << "(" << p->timestamp_anno() << ")";
s << ": ";
s << String(p->length());
s << " | ";
if (_with_eth) {
s << "eth (" << String::make_numeric(static_cast<String::uintmax_t>(ntohs(eth_hdr->ether_type)), 16, true) << ") ";
s << EtherAddress(eth_hdr->ether_shost) << "->" << EtherAddress(eth_hdr->ether_dhost) << "; ";
}
hello_pkt *payload_hello = (hello_pkt *)(p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
mab_control *payload_mabctrl = (mab_control *)(p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
linkstate_header *ls_hdr = (linkstate_header *) (p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
flow_broadcast *flow_bdcst = (flow_broadcast *)(p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
mab_ack *payload_maback = (mab_ack *)(p->data() + _with_eth*sizeof(click_ether) + sizeof(acne_header));
bool pass = false;
switch (hdr->_type) {
case ROUTING_CTRL:
if(!_all_msgs)
return;
s << "RTG_CTRL, type " << ((int)ls_hdr->_type) << ", length " << String(p->length() - _with_eth*sizeof(click_ether)) << ": ";
break;
case HELLO_INT2:
if(!_all_msgs)
return;
s << "HELLO_INT2: src " << payload_hello->src_addr.unparse() << " ";
break;
case HELLO_INT1:
if(!_all_msgs)
return;
s << "HELLO_INT1: src " << payload_hello->src_addr.unparse() << " ";
break;
case MAB_CONTROL:
s << "MAB_CONTROL: id " << hdr->_id_rate_mab << ", type " << ((int)payload_mabctrl->_type);
s << ", flow " << FlowTuple(payload_mabctrl->_flow_src, payload_mabctrl->_flow_dst).unparse() ;
s << ", " << (int) payload_mabctrl->_max_nb_flows << " flows ";
if(payload_mabctrl->_first_message)
s << "(first message) ";
break;
case FLOW_BROADCAST_INT1:
if(_all_msgs)
s << "FLOW_BROADCAST_INT1: src " << flow_bdcst->_src.unparse() << ", " << ((int)flow_bdcst->_nb_flow_ids) << " flows ";
else pass = true;
break;
case FLOW_BROADCAST_INT2:
if(_all_msgs)
s << "FLOW_BROADCAST_INT2: src " << flow_bdcst->_src.unparse() << ", " << ((int)flow_bdcst->_nb_flow_ids) << " flows ";
else pass = true;
break;
case MAB_ACK:
s << "MAB_ACK: id " << hdr->_id_rate_mab << ", route " << payload_maback->_target_route.unparse() << ", " << ((int)payload_maback->_max_nb_flows) << " flows";
s << ", flow " << FlowTuple(payload_maback->_flow_src, payload_maback->_flow_dst).unparse() << ", ts " << payload_maback->_ctrl_id << " ";
break;
default:
if(!_all_msgs)
return;
s << "type ";
str = String::make_garbage(1);
if (char *x = str.mutable_c_str())
sprintf(x, "%d",hdr->_type);
s << str;
s << ": ";
break;
}
if(!pass) {
str = String::make_garbage(4);
if (char *x = str.mutable_c_str())
sprintf(x, "%02X%02X",hdr->_route._dst[0], hdr->_route._dst[1]);
//sprintf(x, "%02X%02X",hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP], hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP+1]);
s << "dst " << str;
click_chatter(s.c_str());
}
}
}
// with_eth == true here
else if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP) { // encapsulated IP
click_ip *ip_hdr = (click_ip *) (p->data() + sizeof(click_ether));
acne_header *hdr = (acne_header *)(p->data() + sizeof(click_ether) + sizeof(click_ip));
StringAccum s;
if(_label) {
s << _label;
s << ": ";
}
Timestamp now;
now.assign_now();
s << now << "(" << p->timestamp_anno() << ")";
s << ": ";
s << String(p->length());
s << " (encapsulated tos "<< String(ip_hdr->ip_tos) <<") | ";
if (_with_eth) {
s << "eth (" << String::make_numeric(static_cast<String::uintmax_t>(ntohs(eth_hdr->ether_type)), 16, true) << ") ";
s << EtherAddress(eth_hdr->ether_shost) << "->" << EtherAddress(eth_hdr->ether_dhost) << "; ";
}
mab_control *payload_mabctrl = (mab_control *)(p->data() + sizeof(click_ether) + sizeof(click_ip) + sizeof(acne_header));
mab_ack *payload_maback = (mab_ack *)(p->data() + sizeof(click_ether) + sizeof(click_ip) + sizeof(acne_header));
switch (hdr->_type) {
case MAB_CONTROL:
s << "MAB_CONTROL: id " << hdr->_id_rate_mab << ", type " << String((int) payload_mabctrl->_type);
s << ", flow " << FlowTuple(payload_mabctrl->_flow_src, payload_mabctrl->_flow_dst).unparse() << " ";
break;
case MAB_ACK:
s << "MAB_ACK: id " << hdr->_id_rate_mab << ", route " << payload_maback->_target_route.unparse() << ", " << ((int)payload_maback->_max_nb_flows) << " flows";
s << ", flow " << FlowTuple(payload_maback->_flow_src, payload_maback->_flow_dst).unparse() << ", ts " << payload_maback->_ctrl_id << " ";
break;
default:
return;
}
str = String::make_garbage(4);
if (char *x = str.mutable_c_str())
sprintf(x, "%02X%02X",hdr->_route._dst[0], hdr->_route._dst[1]);
//sprintf(x, "%02X%02X",hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP], hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP+1]);
s << "dst " << str;
click_chatter(s.c_str());
}
else if (ntohs(vlan_hdr->ether_vlan_proto) == ETHERTYPE_8021Q) { // encapuslated in VLAN packet
acne_header *hdr = (acne_header *)(p->data() + sizeof(click_ether_vlan));
StringAccum s;
if(_label) {
s << _label;
s << ": ";
}
Timestamp now;
now.assign_now();
s << now << "(" << p->timestamp_anno() << ")";
s << ": ";
s << String(p->length());
s << " (encapsulated VLAN proto "<< String::make_numeric(static_cast<String::uintmax_t>(ntohs(vlan_hdr->ether_vlan_encap_proto)), 16, true);
s << " tci " << String::make_numeric(static_cast<String::uintmax_t>(ntohs(vlan_hdr->ether_vlan_tci)), 16, true) << ") | ";
if (_with_eth) {
s << "eth (" << String::make_numeric(static_cast<String::uintmax_t>(ntohs(vlan_hdr->ether_vlan_proto)), 16, true) << ") ";
s << EtherAddress(vlan_hdr->ether_shost) << "->" << EtherAddress(vlan_hdr->ether_dhost) << "; ";
}
mab_control *payload_mabctrl = (mab_control *)(p->data() + sizeof(click_ether_vlan) + sizeof(acne_header));
mab_ack *payload_maback = (mab_ack *)(p->data() + sizeof(click_ether_vlan) + sizeof(acne_header));
nack_order *nack = (nack_order *) (p->data() + sizeof(click_ether_vlan) + sizeof(acne_header));
switch (hdr->_type) {
case MAB_CONTROL:
s << "MAB_CONTROL: id " << hdr->_id_rate_mab << ", type " << String((int) payload_mabctrl->_type);
s << ", flow " << FlowTuple(payload_mabctrl->_flow_src, payload_mabctrl->_flow_dst).unparse() << " ";
break;
case MAB_ACK:
s << "MAB_ACK: id " << hdr->_id_rate_mab << ", route " << payload_maback->_target_route.unparse() << ", " << ((int)payload_maback->_max_nb_flows) << " flows";
s << ", flow " << FlowTuple(payload_maback->_flow_src, payload_maback->_flow_dst).unparse() << ", ts " << payload_maback->_ctrl_id << " ";
break;
case SPECIAL_TRAFFIC:
if(!_print_special)
return;
s << "SPECIAL_TRAFFIC: seq " << hdr->_seq << ", route " << hdr->_route.unparse() << " ";
break;
case NACK_ORDER:
s << "NACK_ORDER: flow src " << nack->flow_src_addr.unparse() << " flow dst " << nack->flow_dst_addr.unparse() << ", last seq " << nack->last_seq;
s << ", with " << nack->nb_nacks << " nacks ";
break;
default:
break;
}
str = String::make_garbage(4);
if (char *x = str.mutable_c_str())
sprintf(x, "%02X%02X",hdr->_route._dst[0], hdr->_route._dst[1]);
//sprintf(x, "%02X%02X",hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP], hdr->_route._route[(hdr->_route._route_length-1)*NB_BYTES_HOP+1]);
s << "dst " << str;
click_chatter(s.c_str());
}
else if (_all_msgs) {
_count_every_all++;
if(_count_every_all < _print_every)
return;
_count_every_all = 0;
if(_label) {
s << _label;
s << ": ";
}
Timestamp now;
now.assign_now();
s << now << "(" << p->timestamp_anno() << ")";
s << ": ";
s << p->length();
s << " | ";
s << "eth (" << String::make_numeric(static_cast<String::uintmax_t>(ntohs(eth_hdr->ether_type)), 16, true) << ") ";
s << EtherAddress(eth_hdr->ether_shost);
s << "->";
s << EtherAddress(eth_hdr->ether_dhost);
s << "; ";
click_chatter(s.c_str());
}
}
String PrintRoutingPacket::print_info() {
StringAccum s;
if (_nb_packets > 0) {
s << "Statistics: received " << _nb_packets << " packets (" << _bytes_received <<" bytes) between "
<< _time_first_packet.unparse() << " and " << _time_last_packet.unparse() << ".";
if (_time_first_packet != _time_last_packet)
s << " Rate=" << int_divide(_bytes_received*1000, usec_timestamp(_time_last_packet - _time_first_packet)) << " kB/s.";
s << "\n";
s << "Average durations in us: CC->FWD=" << int_divide(usec_timestamp(_time_cc_fwd),_nb_packets) << ", "
<< "FWD->MFL=" << int_divide(usec_timestamp(_time_fwd_mfl),_nb_packets) << ", "
<< "MFL->PRICE=" << int_divide(usec_timestamp(_time_mfl_price),_nb_packets) << ", "
<< "PRICE->QUEUE=" << int_divide(usec_timestamp(_time_price_queue),_nb_packets) << ", "
<< "QUEUE->OUT=" << int_divide(usec_timestamp(_time_queue_out),_nb_packets) << ".\n";
s << "Max durations in us: CC->FWD=" << usec_timestamp(_max_time_cc_fwd) << ", "
<< "FWD->MFL=" << usec_timestamp(_max_time_fwd_mfl) << ", "
<< "MFL->PRICE=" << usec_timestamp(_max_time_mfl_price) << ", "
<< "PRICE->QUEUE=" << usec_timestamp(_max_time_price_queue) << ", "
<< "QUEUE->OUT=" << usec_timestamp(_max_time_queue_out) << ".\n";
}
else
s << "No packet received yet";
return s.take_string();
}
void
PrintRoutingPacket::reset() {
_nb_packets = 0;
_bytes_received = 0;
_begin = false;
_time_first_packet.clear();
_time_last_packet.clear();
_time_cc_fwd.clear();
_time_fwd_mfl.clear();
_time_mfl_price.clear();
_time_price_queue.clear();
_time_queue_out.clear();
_max_time_cc_fwd.clear();
_max_time_fwd_mfl.clear();
_max_time_mfl_price.clear();
_max_time_price_queue.clear();
_max_time_queue_out.clear();
}
static String
print_handler(Element *e, void *) {
PrintRoutingPacket *pr_rtg = (PrintRoutingPacket *)e;
return pr_rtg->print_info();
}
static int
reset_handler
(const String &, Element *e, void *, ErrorHandler *)
{
PrintRoutingPacket *c = (PrintRoutingPacket *)e;
c->reset();
return 0;
}
int
PrintRoutingPacket::active_handler(const String &s, Element *e, void *,
ErrorHandler *errh) {
PrintRoutingPacket *elmt = (PrintRoutingPacket *)e;
int active;
if(!cp_integer(s, &active))
return errh->error("Active must be 0 or 1");
if (!(active == 0 || active == 1))
return errh->error("Active must be 0 or 1");
elmt->set_active(active==1);
return 0;
}
void PrintRoutingPacket::add_handlers() {
add_read_handler("print_info", print_handler,0);
add_write_handler("reset", reset_handler, 0, Handler::BUTTON);
add_write_handler("active", active_handler, 0);
}
EXPORT_ELEMENT(PrintRoutingPacket)
CLICK_ENDDECLS
Event Timeline
Log In to Comment