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

📄 etherfilter.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
#include <click/config.h>#include "etherfilter.hh"#include "../wifi/netcoding/xorheader_general.hh"#include "../wifi/netcoding/recpheader.hh"#include "../wifi/netcoding/ackheader.hh"#include "../wifi/sr/srpacket.hh"#include <click/confparse.hh>#include <click/error.hh>#include <clicknet/ether.h>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>#include <click/etheraddress.hh>#include <click/ipaddress.hh>#include <click/timestamp.hh>#include <click/straccum.hh>#include <click/packet_anno.hh>EtherFilter::EtherFilter()  : Element(1, 1),    _enc_ethtype(0),    _basic_ethtype(0){}EtherFilter::~EtherFilter(){}char *EtherFilter::flags_to_string(uint8_t proto, uint8_t flags){  static char s[16];  int cur = 0;  if (proto == IP_PROTO_TCP) {    s[cur++] = 't';    s[cur++] = ':';  } else if (proto == IP_PROTO_UDP) {    s[cur++] = 'u';    s[cur++] = '\0';    return s;  } else if (proto == IP_PROTO_ICMP) {    s[cur++] = 'i';    s[cur++] = '\0';    return s;  } else {    s[cur++] = 'x';    s[cur++] = '\0';    return s;  }  if (flags & TH_FIN) {    s[cur++] = 'f';  }  if (flags & TH_SYN) {    s[cur++] = 's';  }  if (flags & TH_RST) {    s[cur++] = 'r';  }  if (flags & TH_PUSH) {    s[cur++] = 'p';  }  if (flags & TH_ACK) {    s[cur++] = 'a';  }  if (flags & TH_URG) {    s[cur++] = 'u';  }  if (flags & TH_ECE) {    s[cur++] = 'e';  }  if (flags & TH_CWR) {    s[cur++] = 'c';  }  s[cur] = '\0';  return s;}intEtherFilter::configure(Vector<String> &conf, ErrorHandler *errh){  String s;  int res = cp_va_parse(conf, this, errh,			cpKeywords,			"ETHERADDRESSES", cpString, "Space separated list of ether addresses to log", &s,			"ENCETHTYPE", cpUnsigned, "Ethernet encapsulation type for encoded", &_enc_ethtype,			"ACKETHTYPE", cpUnsigned, "Ethernet encapsulation type for ack", &_ack_ethtype,			"RECPETHTYPE", cpUnsigned, "Ethernet encapsulation type for recp", &_recp_ethtype,			"NOTHINGETHTYPE", cpUnsigned, "Ethernet encapsulation type for nothing", &_nothing_ethtype,			"BASICETHTYPE", cpUnsigned, "Ethernet encapsulation type for basic", &_basic_ethtype,			cpEnd);  if (!_enc_ethtype) {    return errh->error("ENCETHTYPE not specified");  }  if (!_basic_ethtype) {    return errh->error("BASICETHTYPE not specified");  }  // click_chatter("etheraddresses is %s", s.c_str());  int start = 0;  int end = 0;  do {    end = s.find_left(' ', start);    String eastr;    if (end != -1) {      eastr = s.substring(start, end-start);    } else {      eastr = s.substring(start, 17);    }    // click_chatter("start is %u, end is %u, eastr is %s", start, end, eastr.c_str());    EtherAddress ea;    if (!cp_ethernet_address(eastr, &ea)) {      return errh->error("Invalid format in ETHERADDRESSES");    }    for (EtherDests::iterator i = _edests.begin(); i != _edests.end(); i++) {      if (ea == *i) {	return errh->error("Repeated ethernet address in ETHERADDRESSES");      }    }    _edests.push_back(ea);    start = end+1;  } while (end != -1);      if (res < 0) {    return -1;  }  return res;}Packet *EtherFilter::drop(Packet *p){  /*  if (noutputs() == 2)    output(1).push(p);  else  */  p->kill();  return 0;}    Packet *EtherFilter::simple_action(Packet *p){  const click_ether *e = (const click_ether *)(p->data());  uint16_t et = ntohs(e->ether_type);    if ((et != _enc_ethtype) && (et != _ack_ethtype) && (et != _recp_ethtype) && (et != _nothing_ethtype) && (et != _basic_ethtype)) {    return drop(p);  }  // now the packet is known to have an ether type we know something about  // check that it is an etheraddress we care about  bool matched = 0;  for(EtherDests::iterator i = _edests.begin(); i != _edests.end(); i++) {    if (memcmp(e->ether_dhost, (*i).data(), 6) == 0) {      matched = 1;      break;    }  }  if (!matched) {    return drop(p);  }  int dup = SEND_ERR_ANNO(p);  StringAccum sa; // this will accumulate the output  /*  EtherAddress srcea = EtherAddress((const unsigned char *)e->ether_shost);  EtherAddress dstea = EtherAddress((const unsigned char *)e->ether_dhost);  StringAccum s2;  s2 << "src " << srcea << " dst " << dstea;  click_chatter("etherfilter saw a packet with type %#0x, %s", et, s2.c_str());  */  EtherAddress srcea = EtherAddress((const unsigned char *)e->ether_shost);  EtherAddress dstea = EtherAddress((const unsigned char *)e->ether_dhost);  sa << dup << " " << srcea << " " << dstea << " ";  uint8_t *next = (uint8_t *)(e+1);  if (et == _ack_ethtype) {    struct click_enc_ack *ackh = (struct click_enc_ack *)next;    uint16_t nentries = ackh->nentries();    sa << nentries << " ";    for (int i = 0; i < nentries; i++) {      uint16_t nb = ackh->get_entry_nb(i);      uint16_t seq = ackh->get_entry_seq(i);      uint16_t bmap = ackh->get_entry_bmap(i);      sa << nb << ":" << seq << ":" << bmap << ":";    }    next = next + ackh->get_hlen(nentries);    et = ntohs(ackh->_et_next);  } else {    sa << "0 -";  }  sa << " ";  if (et == _recp_ethtype) {    struct click_enc_recp *recph = (struct click_enc_recp *)next;    uint16_t nentries = recph->nentries();    sa << nentries << " ";    for (int i = 0; i < nentries; i++) {      uint32_t ipsrc = recph->get_entry_src(i);      uint16_t ipid = recph->get_entry_id(i);      uint16_t bmap = recph->get_entry_bmap(i);      sa << IPAddress(ipsrc) << ":" << ipid << ":" << bmap << ":";    }    next = next + recph->get_hlen(nentries);    et = ntohs(recph->_et_next);  } else {    sa << "0 -";  }  sa << " ";  WritablePacket *wp = 0;  if (et == _enc_ethtype) {    // all the information is in the XOR header    struct click_xorn_header *xorh = (struct click_xorn_header *)next;    uint32_t nentries = xorh->nentries();    sa << nentries;    for (unsigned int i = 0; i < nentries; i++) {    // IPSRC SPORT IPDST DPORT FLAGS+PROTO IPID IPLEN SEQ ACK      sa << " " << IPAddress(xorh->get_entry_src(i)) << " " << xorh->get_entry_sport(i) << " " << IPAddress(xorh->get_entry_dst(i)) << " " << xorh->get_entry_dport(i) << " " << flags_to_string(xorh->get_entry_proto(i), xorh->get_entry_tcp_flags(i)) << " " << xorh->get_entry_ipid(i) << " " << xorh->get_entry_iplen(i) << " " << xorh->get_entry_tcp_seq(i) << " " << xorh->get_entry_tcp_ack(i);    }  } else if (et == _basic_ethtype) {    wp = p->uniqueify();    struct srpacket *srh = (struct srpacket *)next;    next = next + srh->hlen_wo_data();    const click_ip *iph = reinterpret_cast<const click_ip *> (next);    wp->set_ip_header(iph, iph->ip_hl << 2);    uint16_t sport(0), dport(0);    tcp_seq_t seq(0), ack(0);    uint8_t proto(0), flags(0);    proto = iph->ip_p;    if (proto == IP_PROTO_TCP) {      const click_tcp *tcph = (click_tcp *)(wp->transport_header());      sport = ntohs(tcph->th_sport);      dport = ntohs(tcph->th_dport);      seq = ntohl(tcph->th_seq);      ack = ntohl(tcph->th_ack);      flags = tcph->th_flags;    } else if (proto == IP_PROTO_UDP) {      const click_udp *udph = (click_udp *)(wp->transport_header());      sport = ntohs(udph->uh_sport);      dport = ntohs(udph->uh_dport);    }    // IPSRC SPORT IPDST DPORT FLAGS+PROTO IPID IPLEN SEQ ACK    sa << 1 << " " << srh->nseq() << " " << IPAddress(iph->ip_src) << " " << sport << " " << IPAddress(iph->ip_dst) << " " << dport << " " << flags_to_string(proto, flags) << " " << ntohs(iph->ip_id) << " " << ntohs(iph->ip_len) << " " << seq << " " << ack;  } else if (et == _nothing_ethtype) {    sa << 0;  }    click_chatter("snooper %u %s", Timestamp::now().usec1(), sa.c_str());  if (wp) {    return drop(wp);  }  return drop(p);}    /*  // now we can get to the business of logging  if (et == _enc_ethtype) {    // all the information is in the xor header    sa << "1 " << dup << " " << srcea << " " << dstea << " ";    const struct click_xor_header *x = (struct click_xor_header *)(e+1);    sa << IPAddress(x->_src[0]) << " " << ntohs(x->_tcp_sport[0]) << " " << IPAddress(x->_dst[0]) << " " << ntohs(x->_tcp_dport[0]) << " " << ntohs(x->_ipid[0]) << " " << flags_to_string(x->_proto[0], x->_flags[0]) << " " << ntohs(x->_iplen[0]) << " " << ntohl(x->_tcp_seq[0]) << " " << ntohl(x->_tcp_ack[0]) << " " << ntohs(x->_tcp_win[0]) << " " << "-";    sa << " ";    sa << IPAddress(x->_src[1]) << " " << ntohs(x->_tcp_sport[1]) << " " << IPAddress(x->_dst[1]) << " " << ntohs(x->_tcp_dport[1]) << " " << ntohs(x->_ipid[1]) << " " << flags_to_string(x->_proto[1], x->_flags[1]) << " " << ntohs(x->_iplen[1]) << " " << ntohl(x->_tcp_seq[1]) << " " << ntohl(x->_tcp_ack[1]) << " " << ntohs(x->_tcp_win[1]) << " " << "-";    click_chatter("snooper %u %s", Timestamp::now().usec1(), sa.c_str());    return drop(p);  }    // this is an unencoded packet  sa << "0 " << dup << " " << srcea << " " << dstea << " ";    WritablePacket *pw = p->uniqueify();    struct srpacket *pk = (struct srpacket *)(e+1);  // click_chatter("%s: sr hdr len is %d", pk->hlen_wo_data());  int extra = pk->hlen_wo_data() + sizeof(click_ether);  pw->pull(extra);    const click_ip *i = reinterpret_cast<const click_ip *>(pw->data());  pw->set_ip_header(i, i->ip_hl << 2);    if (i->ip_p == IP_PROTO_TCP) {    const click_tcp *t = (click_tcp *)pw->transport_header();    // click_chatter("ip proto is %u, tcp header is %x", i->ip_p, t);    sa << IPAddress(i->ip_src) << " " << ntohs(t->th_sport) << " " << IPAddress(i->ip_dst) << " " << ntohs(t->th_dport) << " " << ntohs(i->ip_id) << " " << flags_to_string(i->ip_p, t->th_flags) << " " << ntohs(i->ip_len) << " " << ntohl(t->th_seq) << " " << ntohl(t->th_ack) << " " << ntohs(t->th_win);    // now get the window scaling option if set    int length = t->th_off*4 - sizeof(struct click_tcp);    unsigned char *ptr = (unsigned char *)(t+1);    unsigned char window_scale = 0;    unsigned char wscale_set = 0;    while ((length > 0) && (!wscale_set)) {      int opcode = *ptr++;      int opsize;      switch (opcode) {      case TCPOPT_EOL:	length = 0;	break;      case TCPOPT_NOP:        // Ref: RFC 793 section 3.1 	length--;	continue;      default:	opsize = *ptr++;	if (opsize < 2) {// "silly options" 	  length = 0;	  break;	}	if (opsize > length) {// don't parse partial options 	  length = 0;	  break; 	}	switch (opcode) {	case TCPOPT_WSCALE:	  if (opsize == TCPOLEN_WSCALE) {	    wscale_set = 1;	    window_scale = *(unsigned char *)ptr;	    if(window_scale > 14) {	      click_chatter("%s: window scale %u too large, setting to 14", id().cc(), window_scale);	      window_scale = 14;	    }	  }	  break;	}	ptr += opsize - 2;	length -= opsize;      }    }    if (wscale_set) {      sa << " " << (unsigned int)window_scale;    } else {      sa << " " << "-";    }        click_chatter("snooper %u %s", Timestamp::now().usec1(), sa.c_str());  } else if (i->ip_p == IP_PROTO_UDP) {    const click_udp *u = (click_udp *)pw->transport_header();    sa << IPAddress(i->ip_src) << " " << ntohs(u->uh_sport) << " " << IPAddress(i->ip_dst) << " " << ntohs(u->uh_dport) << " " << ntohs(i->ip_id) << " " << flags_to_string(i->ip_p, 0) << " " << ntohs(i->ip_len) << " " << 0 << " " << 0 << " " << 0 << " " << "-";    click_chatter("snooper %u %s", Timestamp::now().usec1(), sa.c_str());  }      return drop(pw);}// ETHERSRC ETHERDST ENCODED/NOT IPSRCADDR TCPSRCPORT IPDSTADDR TCPDSTPORT IPID TCPSEQNO TCPACKNO*/#include <click/vector.cc>#if EXPLICIT_TEMPLATE_INSTANCEStemplate class typedef Vector<EtherAddress>;#endifEXPORT_ELEMENT(EtherFilter)

⌨️ 快捷键说明

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