⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * decoder.{cc,hh} -- decodes received packets  * 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 <clicknet/ether.h>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <click/error.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <click/ipaddress.hh>#include <click/etheraddress.hh>#include <click/packet_anno.hh>#include <elements/wifi/sr/srpacket.hh>#include "sendmanager.hh"#include "xorheader.hh"#include "decoder.hh"CLICK_DECLSDecoder::Decoder()  : Element(1,1),     _decodedpkts(0),     _undecodable(0),     _duplicatepkts(0),    _nnewpkts(0),    _decodedbytes(0),     _duplicatebytes(0),    _nnewbytes(0),    _myea(),    _myalias(0),    _sendmgr(0),    _aliases(0),    _recvmgr(0)  //    ,_scrambleq(0){}Decoder::~Decoder(){}void *Decoder::cast(const char *n){    if (strcmp(n, "Decoder") == 0)      return (Decoder *)this;    else      return 0; }intDecoder::configure(Vector<String> &conf, ErrorHandler *errh){    int res = cp_va_parse(conf, this, errh,			  cpKeywords,			  "ETH", cpEtherAddress, "Ethernet address", &_myea,			  "SENDMGR", cpElement, "SendManager element", &_sendmgr,			  //"SCRAMBLEQUEUE", cpElement, "ScrambleQueue element", &_scrambleq,			  "ALIASTABLE", cpElement, "AliasTable element", &_aliases,			  "RECVMGR", cpElement, "RecvManager element", &_recvmgr,			  cpEnd);    if (!_myea) {      return errh->error("ETH not specified");    }    if (!_sendmgr) {      return errh->error("SENDMGR not specified");    }    if (_sendmgr->cast("SendManager") == 0) {      return errh->error("SENDMGR element is not a SendManager");    }    /*    if (!_scrambleq) {      return errh->error("SCRAMBLEQUEUE not specified");    }    if (_scrambleq->cast("ScrambleQueue") == 0) {      return errh->error("SCRAMBLEQUEUE element is not a ScrambleQueue");    }    */    if (!_aliases) {      return errh->error("ALIASTABLE not specified");    }    if (_aliases->cast("AliasTable") == 0) {      return errh->error("ALIASTABLE element is not an AliasTable");    }    if (!_recvmgr) {      return errh->error("RECVMGR not specified");    }    if (_recvmgr->cast("RecvManager") == 0) {      return errh->error("RECVMGR element is not a RecvManager");    }    _myalias = _aliases->lookup(_myea);    click_chatter("decoder done");    return res;}voidDecoder::push(int, Packet* p){  // there seem to be 4 bytes at the end, we will take them out now  p->take(4);  // see if that's for me  click_ether *eh = (click_ether *) p->data();  struct click_xor_header *xorh = (struct click_xor_header *)(eh + 1);  struct srpacket *srh = (struct srpacket *)(xorh + 1);  click_chatter("%s: push() got packet of length %u with srhlen %u", id().cc(), p->length(), srh->hlen_wo_data());  int idx = -1;  if (xorh->_alias[0] == _myalias) {    idx = 0;  } else if (xorh->_alias[1] == _myalias) {    idx = 1;  } else {    p->kill();    return;  }  click_chatter("%s: push() packet matched me, idx is %d, other alias is %d", id().cc(), idx, xorh->_alias[1-idx]);  // at this point, idx is 0 or 1  // if alias[i] is the destination (i.e. me), alias[1-i] is what i sent  // look up packet gid(_src[1-i], ipid[1-i]) and xor with it  // the new packet's eth type will be ethtype[i]  PacketGID pgid(IPAddress(xorh->_src[1-idx]), ntohs(xorh->_ipid[1-idx]));  StringAccum sa;  sa << "push() needs to xor with PGID ( " << pgid._src << ", " <<  pgid._id << ")";  Packet *sent = _sendmgr->take_packet(pgid);  if (!sent) {    click_chatter("%s: %s not found in cache", id().cc(), sa.c_str());    _undecodable++;    p->kill();    return;  }  struct click_ether *ehtmp = (struct click_ether *)sent->data();  struct srpacket *srhtmp = (struct srpacket *)(ehtmp+1);  click_chatter("%s: %s of length %u, srheader length %u", id().cc(), sa.c_str(), sent->length(), srhtmp->hlen_wo_data());  Packet *decoded = xor_decode(sent, p, _myea, idx);  ehtmp = (struct click_ether *)decoded->data();  srhtmp = (struct srpacket *)(ehtmp+1);  unsigned int declen = srhtmp->hlen_with_data() - srhtmp->hlen_wo_data();  // srhtmp->set_checksum();  // shouldn't need this!!!  click_chatter("%s: decoded packet has length %u, srheader len %u", id().cc(), decoded->length(), srhtmp->hlen_wo_data());  _decodedpkts++;  _decodedbytes += declen;  // now you need to add the sequence number of this packet to toack  bool isnewpkt = _recvmgr->register_packet_to_ack(decoded, Timestamp::now().msec1());  const struct click_ip *ciph = decoded->ip_header();  uint8_t tflag = 0;  if (ciph->ip_p == IP_PROTO_TCP) {    const struct click_tcp *ctcph = decoded->tcp_header();    tflag = ctcph->th_flags;    sa.clear();    sa << "tcp dc " << Timestamp::now().msec1() << " " << ciph->ip_src << " " << ntohs(ctcph->th_sport) << " " << ciph->ip_dst << " " << ntohs(ctcph->th_dport) << " " << ntohl(ctcph->th_seq) << " " << ntohl(ctcph->th_ack);  } else {    click_chatter("%s: ip proto is %u", id().cc(), ciph->ip_p);  }  // kill duplicate packets  if (!isnewpkt) {    click_chatter("%s: duplicate packet, killing", id().cc());    _duplicatepkts++;    _duplicatebytes += declen;    decoded->kill();    click_chatter("%s: %s %#0x k", id().cc(), sa.c_str(), tflag);    return;  }    _nnewpkts++;  _nnewbytes += declen;  // _scrambleq->register_next_ack_wakeup(_recvmgr->get_next_ack_time());  click_chatter("%s: %s %#0x p", id().cc(), sa.c_str(), tflag);  output(0).push(decoded);}StringDecoder::stats(Element *e, void *){  StringAccum sa;  Decoder *dec = static_cast<Decoder *>(e);  sa << "NDecodedPkts: " << dec->_decodedpkts << "; NDecodedBytes: " << dec->_decodedbytes << "; NUndecodable: " << dec->_undecodable << "; NDuplicatePkts: " << dec->_duplicatepkts << "; NDuplicateBytes: " << dec->_duplicatebytes << "; NNewPkts: " << dec->_nnewpkts << "; NNewBytes: " << dec->_nnewbytes << "\n";  click_chatter("%{element}: statistics ----------", dec);  return sa.take_string();}intDecoder::static_clear(const String &arg, Element *e,                        void *, ErrorHandler *errh){  Decoder *dec = static_cast<Decoder *>(e);  bool b;  if (!cp_bool(arg, &b))    return errh->error("`clear' must be a boolean");  if (b) {    dec->_decodedpkts = 0;    dec->_decodedbytes = 0;    dec->_undecodable = 0;    dec->_duplicatepkts = 0;    dec->_nnewpkts = 0;    dec->_duplicatebytes = 0;    dec->_nnewbytes = 0;    click_chatter("%{element}: statistics cleared\n", dec);  }  return 0;}void Decoder::add_handlers(){  add_read_handler("stats", stats, 0);  add_write_handler("clear", static_clear, 0);}CLICK_ENDDECLSEXPORT_ELEMENT(Decoder)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -