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

📄 decoderg.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_general.hh"#include "decoderg.hh"CLICK_DECLSDecoderG::DecoderG()  : Element(1,1),     _decodedpkts(0),     _undecodable(0),     _duplicatepkts(0),    _nnewpkts(0),    _decodedbytes(0),     _duplicatebytes(0),    _nnewbytes(0),    _myea(),    _myalias(0),    _listenmgr(0),    _aliases(0),    _recvmgr(0),    _scrambleq(0){}DecoderG::~DecoderG(){}void *DecoderG::cast(const char *n){    if (strcmp(n, "DecoderG") == 0)      return (DecoderG *)this;    else      return 0; }intDecoderG::configure(Vector<String> &conf, ErrorHandler *errh){    int res = cp_va_parse(conf, this, errh,			  cpKeywords,			  "ETH", cpEtherAddress, "Ethernet address", &_myea,			  "LISTENMGR", cpElement, "ListenManager element", &_listenmgr,			  "SCRAMBLEQUEUE", cpElement, "ScrambleQueue element", &_scrambleq,			  "ALIASTABLE", cpElement, "AliasTable element", &_aliases,			  "RECVMGR", cpElement, "RecvManager element", &_recvmgr,        "SENDMGR", cpElement, "SendManager element", &_sendmgr,			  cpEnd);    if (!_myea) {      return errh->error("ETH not specified");    }    if (!_listenmgr) {      return errh->error("LISTENMGR not specified");    }    if (_listenmgr->cast("ListenManager") == 0) {      return errh->error("LISTENMGR element is not a ListenManager");    }    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");    }    if (!_sendmgr) {      return errh->error("SENDMGR not specified");    }    if (_sendmgr->cast("SendManager") == 0) {      return errh->error("SENDMGR element is not a SendManager");    }    _myalias = _aliases->lookup(_myea);    click_chatter("decoder done");    return res;}voidDecoderG::push(int, Packet* p){  // see if that's for me  click_ether *eh = (click_ether *) p->data();  struct click_xorn_header *xorh = (struct click_xorn_header *)(eh + 1);  int nentries = xorh->nentries();  click_chatter("%s: push() got packet of length %u", id().cc(), p->length());  int idx = -1;  for (int i = 0; i < nentries; i++) {    if (xorh->get_entry_alias(i) == _myalias) {      idx = i;      break;    }  }  if (idx == -1) {    p->kill();    return;  }  for (unsigned int i = 0; i < xorh->nentries(); i++) {    StringAccum sa_t;    sa_t << "Ethtype " << xorh->get_entry_ethtype(i) << " IPID " << xorh->get_entry_ipid(i) << " Source " << IPAddress(xorh->get_entry_src(i)) << " Alias " << xorh->get_entry_alias(i) << " Length " << xorh->get_entry_len(i);    click_chatter("%s Coded packet %s", id().cc(), sa_t.c_str());  }    click_chatter("%s: push() packet matched me, idx is %d", id().cc(), idx);  StringAccum sa;  WritablePacket *p_enc = p->uniqueify();  for (int i = 0; i < nentries; i++) {    if (i==idx) continue;    IPAddress ip_t = IPAddress(xorh->get_entry_src(i));    uint16_t ipid_t = xorh->get_entry_ipid(i);    PacketRID pid(ip_t, ipid_t);    sa << "push() xor target PID ( " << pid._src << ", " <<  pid._id << ")";    Packet *pkt_ovhd = _listenmgr->get_packet(pid);    if (!pkt_ovhd) {      PacketGID pgid(ip_t, ipid_t);      pkt_ovhd = _sendmgr->take_packet(pgid);      if (!pkt_ovhd) {             click_chatter("%s: %s not found in cache", id().cc(), sa.c_str());        sa.clear();        _undecodable++;        p_enc->kill();        return;      }    }    xor_decode(p_enc, pkt_ovhd, i);    sa.clear();  }  click_chatter("finished xoring");  Packet *decoded = finish_decode(p_enc, idx);  // Mark the IP header  const click_ether *eth_dec = (const click_ether *)(decoded->data());  struct srpacket *pk = (struct srpacket *)(eth_dec+1);  int extra = pk->hlen_wo_data() + sizeof(click_ether);    const click_ip *i = reinterpret_cast<const click_ip *>(decoded->data()+extra);  decoded->set_ip_header(i, i->ip_hl << 2);    struct click_ether *ehtmp = (struct click_ether *)decoded->data();  sa << EtherAddress(ehtmp->ether_shost);  struct srpacket *srhtmp = (struct srpacket *)(ehtmp+1);  unsigned int declen = srhtmp->hlen_with_data() - srhtmp->hlen_wo_data();  // srhtmp->set_checksum();  // shouldn't need this!!!  _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();  click_chatter("%s: decoder received a packet from ethsrc = %s ipsrc = %s ipdst = %s ipid = %u iplen = %u coded = 1 srhlen = %u pktlen = %u isnew = %d", id().cc(), sa.c_str(), IPAddress(ciph->ip_src).s().c_str(), IPAddress(ciph->ip_dst).s().c_str(), ntohs(ciph->ip_id), ntohs(ciph->ip_len), srhtmp->hlen_wo_data(), decoded->length(), isnewpkt);  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 " << ciph->ip_src << " " << ntohs(ctcph->th_sport) << " " << ciph->ip_dst << " " << ntohs(ctcph->th_dport) << " " << ntohl(ctcph->th_seq) << " " << ntohl(ctcph->th_ack);  } else {    StringAccum sa_t;    sa_t << "Decoded IP Source " << ciph->ip_src << "ipid " << ntohs(ciph->ip_id);    click_chatter("%s: ip proto is %u %s", id().cc(), ciph->ip_p, sa_t.c_str());  }  // kill duplicate packets  if (!isnewpkt) {    click_chatter("%s: duplicate packet, killing", id().cc());    _duplicatepkts++;    _duplicatebytes += declen;    decoded->kill();    click_chatter("%s: %u %s %#0x k", id().cc(), Timestamp::now().msec1(), sa.c_str(), tflag);    return;  }    _nnewpkts++;  _nnewbytes += declen;  _scrambleq->wakeup_if_needed();  click_chatter("%s: %u %s %#0x p", id().cc(), Timestamp::now().msec1(), sa.c_str(), tflag);  output(0).push(decoded);}WritablePacket*DecoderG::finish_decode(WritablePacket *dec, int idx){  click_ether *eth_h = (struct click_ether *)(dec->data());  EtherAddress src = EtherAddress(eth_h->ether_shost);  struct click_xorn_header *xorh = (struct click_xorn_header *)(eth_h + 1);  uint16_t et = xorh->get_entry_ethtype(idx);  int xorh_len = xorh->get_hlen(xorh->nentries());  int srhs_len = xorh->get_sr_size();  int dec_len = dec->length() - xorh_len - srhs_len - sizeof(struct click_ether);  int pkt_len = xorh->get_entry_len(idx);  // First take off extra stuff at the end  if (pkt_len < dec_len) {    dec->take(dec_len-pkt_len);    click_chatter("taking out stuff at end %d %d", (dec_len-pkt_len), dec_len);  }    // Strip all the headers upto IP  WritablePacket *srh = Packet::make(srpacket::len_wo_data(xorh->get_entry_nhops(idx)));  click_chatter("offset to our sr header %d", (sizeof(struct click_ether) + xorh_len + xorh->get_sr_size_upto(idx)));  struct srpacket *srh_copy = (struct srpacket*)(dec->data() + sizeof(struct click_ether) + xorh_len + xorh->get_sr_size_upto(idx));  memcpy(srh->data(), srh_copy, srpacket::len_wo_data(xorh->get_entry_nhops(idx)));    dec->pull(sizeof(struct click_ether));  click_chatter("taking out ether %d", sizeof(struct click_ether));  dec->pull(xorh_len);  click_chatter("taking out xor header %d", xorh_len);  dec->pull(srhs_len);  click_chatter("taking out sr headers %d", srhs_len);    dec->push(srh->length());  memcpy((void*)dec->data(), srh->data(), srh->length());  click_chatter("pushing sr header %d", srh->length());  srh->kill();  dec->push(sizeof(struct click_ether));  click_ether *eh = (struct click_ether *)dec->data();  memcpy(eh->ether_shost, src.data(), 6);  memcpy(eh->ether_dhost, _myea.data(), 6);  eh->ether_type = htons(et);  click_chatter("%s decoded packet ethtype %04x", id().cc(), et);  return dec;}voidDecoderG::xor_decode(WritablePacket *enc, Packet *pkt, int i){  // Headers of the received encoded packet  click_ether *eth_enc = (struct click_ether *)(enc->data());  struct click_xorn_header *xorh = (struct click_xorn_header *)(eth_enc + 1);  // First modify the packet we have to make sure we xor with the right version  WritablePacket *pkt_t = pkt->uniqueify();  struct click_ether *eh = (struct click_ether *)pkt_t->data();  struct srpacket *srh = (struct srpacket *)(eh+1);  click_ip *iph = pkt_t->ip_header();  // First the IP header  iph->ip_ttl = xorh->get_entry_ipttl(i);  set_ip_cksum(pkt_t);  // Now do the decoding with the appropriate packet  int orig_plen = srh->hlen_with_data() - srh->hlen_wo_data();  int recd_plen = xorh->get_entry_len(i);  if (orig_plen != recd_plen) {    click_chatter("%s lengths do not match o:%d r:%d", id().cc(), orig_plen, recd_plen);  }  int min_len = ((orig_plen < recd_plen) ? orig_plen : recd_plen);  click_chatter("offset: %d size: %d", (sizeof(struct click_ether) + xorh->get_hlen(xorh->nentries()) + xorh->get_sr_size()), min_len);  unsigned char *enc_data = (unsigned char *)enc->data() + sizeof(struct click_ether) + xorh->get_hlen(xorh->nentries()) + xorh->get_sr_size();  const unsigned char *orig_data = (const unsigned char *)(pkt_t->ip_header());  for (int j = 0; j < min_len; j++) {    enc_data[j] ^= orig_data[j];  }    pkt_t->kill();  return;}  voidDecoderG::set_ip_cksum(WritablePacket *p){  click_ip *ip = p->ip_header();  unsigned plen = p->length() - p->ip_header_offset();  unsigned hlen;    if (!ip || plen < sizeof(click_ip))    goto bad;  hlen = ip->ip_hl << 2;  if (hlen < sizeof(click_ip) || hlen > plen)    goto bad;  ip->ip_sum = 0;  ip->ip_sum = click_in_cksum((unsigned char *)ip, hlen);  return; bad:  click_chatter("SetIPChecksum: bad lengths");  return;}StringDecoderG::stats(Element *e, void *){  StringAccum sa;  DecoderG *dec = static_cast<DecoderG *>(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();}intDecoderG::static_clear(const String &arg, Element *e,                        void *, ErrorHandler *errh){  DecoderG *dec = static_cast<DecoderG *>(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 DecoderG::add_handlers(){  add_read_handler("stats", stats, 0);  add_write_handler("clear", static_clear, 0);}CLICK_ENDDECLSEXPORT_ELEMENT(DecoderG)

⌨️ 快捷键说明

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