📄 adjustrate.cc
字号:
/* * adjustrate.{cc,hh} -- adjusts wifi txrate annotation on a packet * Wenjun Hu * * Copyright (c) 2005 University of Cambridge * Copyright (c) 2005 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/packet_anno.hh>#include <clicknet/ether.h>#include <clicknet/wifi.h>#include <clicknet/llc.h>#include "adjustrate.hh"#include "encodedheader.hh"CLICK_DECLSAdjustRate::AdjustRate() : Element(1, 1), _ip(), _eth(), _arp_table(0){}AdjustRate::~AdjustRate(){}intAdjustRate::configure(Vector<String> &conf, ErrorHandler *errh){ _rate = 0; _et = 0; _offset = 0; int ret = cp_va_parse(conf, this, errh, cpKeywords, "ETHTYPE", cpUnsigned, "Ethernet encapsulation type", &_et, "IP", cpIPAddress, "My IP address", &_ip, "ETH", cpEtherAddress, "Ethernet address", &_eth, "ARP", cpElement, "ARPTable", &_arp_table, cpOptional, cpUnsigned, "rate", &_rate, cpKeywords, "RATE", cpUnsigned, "rate", &_rate, "OFFSET", cpUnsigned, "offset", &_offset, cpEnd); if (!_et) return errh->error("ETHTYPE not specified"); if (!_ip) return errh->error("IP not specified"); if (!_eth) return errh->error("ETH not specified"); if (!_arp_table) return errh->error("ARP not specified"); if (_arp_table->cast("ARPTable") == 0) return errh->error("ARPTable element is not a ARPTable"); if (_rate < 0) return errh->error("RATE must be >= 0"); return ret;}Packet *AdjustRate::simple_action(Packet *p_in){ //debugging //click_chatter("%s: header lengths: click_wifi_extra %d, click_wifi %d, click_llc %d", id().cc(), sizeof(struct click_wifi_extra), sizeof(struct click_wifi), sizeof(struct click_llc)); struct click_wifi *w = (struct click_wifi *) p_in->data(); struct click_llc *llc = (struct click_llc *) (w+1); uint16_t ethtype_p = llc->llc_un.type_snap.ether_type; if (_et && ethtype_p != htons(_et)) { //click_chatter("%s: packet ether type is 0x%.4x", id().cc(), (unsigned long)ntohs(ethtype_p)); return p_in; } struct click_wifi_extra *ceh = (struct click_wifi_extra *) p_in->all_user_anno(); if (_rate) { ceh->rate = _rate; return p_in; } // update the neighbour rate table if necessary... int current_rate = ceh->rate; EtherAddress dst = EtherAddress(w->i_addr1); //EtherAddress dst = EtherAddress(eh->ether_dhost); //int *prev_rate = _nb_rate_table.findp(dst); //if (!prev_rate) _nb_rate_table.insert(dst, current_rate); // debugging click_chatter("%s: current rate %d, current dst %s", id().cc(), current_rate, dst.s().cc()); int alt_rate = current_rate; EtherAddress alt_dst; struct click_xored *xorh = (struct click_xored *) (llc+1); // now look into the xor header, // look up the corresponding ethernet addresses and rates for (int i = 0; i<2; i++) { IPAddress alt_ip = xorh->prev_hop[i]; if (alt_ip == _ip) { //int *rate_ptr = _nb_rate_table.findp(_eth); alt_dst = _eth; //continue; } else { alt_dst = _arp_table->lookup(alt_ip); if (alt_dst == _arp_table->_bcast) { click_chatter("%s: arp lookup failed for %s", id().cc(), alt_ip.s().cc()); // debugging continue; } } int *rate_ptr = _nb_rate_table.findp(alt_dst); if (!rate_ptr) { alt_rate = (alt_dst == dst)?current_rate:22; // start with the highest rate (for b, but higher rate for a/g unlikely to work well)... _nb_rate_table.insert(alt_dst, alt_rate); } else { alt_rate = *rate_ptr; if (current_rate >= alt_rate) { alt_rate = current_rate; alt_dst = dst; } } } // set the rate and destination accordingly ceh->rate = alt_rate; memcpy(w->i_addr1, alt_dst.data(), 6); // debugging click_chatter("%s: adjusted rate %d, adjusted dst %s", id().cc(), alt_rate, alt_dst.s().cc()); return p_in;}/*enum {H_RATE};StringAdjustRate::read_handler(Element *e, void *thunk){ SetTXRate *foo = (SetTXRate *)e; switch((uintptr_t) thunk) { case H_RATE: return String(foo->_rate) + "\n"; default: return "\n"; } }intAdjustRate::write_handler(const String &arg, Element *e, void *vparam, ErrorHandler *errh) { SetTXRate *f = (SetTXRate *) e; String s = cp_uncomment(arg); switch((int)vparam) { case H_RATE: { unsigned m; if (!cp_unsigned(s, &m)) return errh->error("rate parameter must be unsigned"); f->_rate = m; break; } } return 0;}voidSetTXRate::add_handlers(){ add_default_handlers(true); add_read_handler("rate", read_handler, (void *) H_RATE); add_write_handler("rate", write_handler, (void *) H_RATE);}*/// generate Vector template instance#include <click/bighashmap.cc>#if EXPLICIT_TEMPLATE_INSTANCEStemplate class HashMap<EtherAddress, int>;#endifCLICK_ENDDECLSEXPORT_ELEMENT(AdjustRate)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -