📄 decoderg_bak
字号:
/* * 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_new.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, 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"); } _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; } click_chatter("%s: push() packet matched me, idx is %d", id().cc(), idx); click_chatter("%s packet lengths %d %d", id().cc(), xorh->get_entry_len(0), xorh->get_entry_len(1)); 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() needs to xor with PID ( " << pid._src << ", " << pid._id << ")"; Packet *pkt_ovhd = _listenmgr->get_packet(pid); if (!pkt_ovhd) { click_chatter("%s: %s not found in cache", id().cc(), sa.c_str()); _undecodable++; p_enc->kill(); return; } click_chatter("%s lenght of packet I sent out %d", id().cc(), pkt_ovhd->length()); xor_decode(p_enc, pkt_ovhd, i); } Packet *decoded = finish_decode(p_enc, idx); struct click_ether *ehtmp = (struct click_ether *)decoded->data(); 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!!! 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 { StringAccum sa_t; sa_t << "Decoded IP Source " << IPAddress(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: %s %#0x k", id().cc(), sa.c_str(), tflag); return; } _nnewpkts++; _nnewbytes += declen; _scrambleq->register_next_ack_wakeup(); click_chatter("%s: %s %#0x p", id().cc(), 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 dec_len = dec->length() - xorh_len; int pkt_len = xorh->get_entry_len(idx); dec->pull(sizeof(struct click_ether)); dec->pull(xorh_len); 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); if (pkt_len < dec_len) { dec->take(dec_len-pkt_len); } return dec;}voidDecoderG::xor_decode(WritablePacket *enc, Packet *pkt, int idx){ // First modify the packet we have to make sure we xor with the right version WritablePacket *pkt_t = pkt->uniqueify(); click_ip *iph = pkt_t->ip_header(); iph->ip_ttl--; unsigned long sum = (~ntohs(iph->ip_sum) & 0xFFFF) + 0xFEFF; iph->ip_sum = ~htons(sum + (sum >> 16)); StringAccum sa_t; sa_t << "Decoding with src " << IPAddress(iph->ip_src) << " ipid " << ntohs(iph->ip_id); click_chatter("%s %s", id().cc(), sa_t.c_str()); struct click_ether *eh = (struct click_ether *)pkt_t->data(); struct srpacket *srh = (struct srpacket *)(eh+1); srh->set_next(srh->next()+1); sum = (~ntohs(srh->_cksum) & 0xFFFF) - 0xFFFE; srh->_cksum = ~htons(sum + (sum >> 16)); // Now do the decoding with the appropriate packet click_ether *eth_enc = (struct click_ether *)(enc->data()); struct click_xorn_header *xorh = (struct click_xorn_header *)(eth_enc + 1); int orig_plen = pkt_t->length() - sizeof(struct click_ether); int recd_plen = xorh->get_entry_len(idx) - sizeof(struct click_ether); int min_len = ((orig_plen < recd_plen) ? orig_plen : recd_plen); unsigned char *enc_data = (unsigned char *)enc->data() + sizeof(struct click_ether) + xorh->get_hlen(xorh->nentries()); const unsigned char *orig_data = (const unsigned char *)((struct click_ether *)(pkt_t->data()) + 1); for (int i = 0; i < min_len; i++) { enc_data[i] ^= orig_data[i]; } pkt_t->kill(); 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 + -