Page MenuHomec4science

controlmsgspriorityencap.cc
No OneTemporary

File Metadata

Created
Sun, Jul 6, 17:16

controlmsgspriorityencap.cc

#include <click/config.h>
#include "util.hh"
#include "controlmsgspriorityencap.hh"
#define DEBUG_CHATTER(arg, ...) do { if (_debug) { click_chatter(arg, ## __VA_ARGS__);} } while (0)
CLICK_DECLS
ControlMsgsPriorityEncap::ControlMsgsPriorityEncap()
{
}
ControlMsgsPriorityEncap::~ControlMsgsPriorityEncap()
{
}
int ControlMsgsPriorityEncap::configure(Vector<String> &conf, ErrorHandler *errh){
_active = true;
_debug = false;
if(Args(this, errh).bind(conf)
.read("ACTIVE", _active)
.read("DEBUG", _debug)
.complete() < 0)
return -1;
return 0;
}
int
ControlMsgsPriorityEncap::initialize(ErrorHandler *errh) {
return 0;
}
void
ControlMsgsPriorityEncap::push(int, Packet *p_in) {
output(0).push(encap(p_in));
}
Packet *
ControlMsgsPriorityEncap::pull(int) {
Packet *p = input(0).pull();
if(p == 0)
return p;
return encap(p);
}
Packet *
ControlMsgsPriorityEncap::encap(Packet *p_in) {
if(!_active) {
return p_in;
}
// check management messages
click_ether *init_hdr = (click_ether *) p_in->data();
if(init_hdr->ether_type == htons(ETHERTYPE_HP_AV)) {
return p_in;
}
int length = p_in->length();
Timestamp now;
if(_debug) {
now.assign_now();
click_chatter("[ControlMsgsPriorityEncap %s] Encapsulating packet of length %d", now.unparse().c_str(), length);
}
// assume ethernet header, store it
WritablePacket *eth_hdr = Packet::make(sizeof(click_ether));
memcpy(eth_hdr->data(), p_in->data(), sizeof(click_ether));
p_in->pull(sizeof(click_ether));
acne_header *acne_hdr = (acne_header *) (p_in->data());
int tos;
if(acne_hdr->_type == MAB_CONTROL || acne_hdr->_type == MAB_ACK) {
// add TOS with high priority
tos = 152; // 0x98, class 2 for PLC
}
else {
tos = 0;
}
WritablePacket *out = p_in->push(sizeof(click_ip));
out = out->push_mac_header(sizeof(click_ether));
click_ether *new_eth_hdr = (click_ether *) out->data();
click_ip *ip_hdr = (click_ip *) (out->data() + sizeof(click_ether));
memset(ip_hdr, 0, sizeof(click_ip));
// fake IP header (only TOS field is useful anyway)
ip_hdr->ip_v = 4;
ip_hdr->ip_p = IP_PROTO_IPIP; // use IP in IP protocol number
ip_hdr->ip_dst = IPAddress("10.10.10.100").in_addr();
ip_hdr->ip_src = IPAddress("10.10.10.100").in_addr();
ip_hdr->ip_len = length + sizeof(click_ip);
// TOS field
ip_hdr->ip_tos = tos;
#if HAVE_FAST_CHECKSUM
ip_hdr->ip_sum = ip_fast_csum((unsigned char *) ip_hdr, sizeof(click_ip) >> 2);
#else
ip_hdr->ip_sum = click_in_cksum((unsigned char *) ip_hdr, sizeof(click_ip));
#endif
out->set_ip_header(ip_hdr, sizeof(click_ip));
memcpy(new_eth_hdr, eth_hdr->data(), sizeof(click_ether));
// set ethertype to IP (to be sure that TOS is considered)
new_eth_hdr->ether_type = htons(ETHERTYPE_IP);
eth_hdr->kill();
return out;
}
int
ControlMsgsPriorityEncap::active_handler(const String &s, Element *e, void *,
ErrorHandler *errh) {
ControlMsgsPriorityEncap *elmt = (ControlMsgsPriorityEncap *)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 ControlMsgsPriorityEncap::add_handlers() {
add_write_handler("active", active_handler, 0);
}
EXPORT_ELEMENT(ControlMsgsPriorityEncap)
CLICK_ENDDECLS

Event Timeline