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

📄 srforwarder.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * SRForwarder.{cc,hh} -- Source Route data path implementation * Robert Morris * John Bicket * * Copyright (c) 1999-2001 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/ipaddress.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/straccum.hh>#include <click/packet_anno.hh>#include <clicknet/ether.h>#include "srforwarder.hh"#include "srpacket.hh"#include "elements/wifi/arptable.hh"CLICK_DECLSSRForwarder::SRForwarder()  :  Element(1,2),      _ip(),     _eth(),     _et(0),     _datas(0),      _databytes(0),     _rcv_pkts(0),     _rcv_bytes(0),     _pkts_to_host(0),     _bytes_to_host(0),     _fwd_pkts(0),     _fwd_bytes(0),     _link_table(0),     _arp_table(0){  static unsigned char bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };  _bcast = EtherAddress(bcast_addr);}SRForwarder::~SRForwarder(){}intSRForwarder::configure (Vector<String> &conf, ErrorHandler *errh){  int res;  res = cp_va_parse(conf, this, errh,                    cpKeywords,		    "ETHTYPE", cpUnsigned, "Ethernet encapsulation type", &_et,                    "IP", cpIPAddress, "IP address", &_ip,		    "ETH", cpEtherAddress, "Ethernet Address", &_eth,		    "ARP", cpElement, "ARPTable element", &_arp_table,		    /* below not required */		    "LT", cpElement, "LinkTable element", &_link_table,                    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("ARPTable not specified");  if (_arp_table->cast("ARPTable") == 0)     return errh->error("ARPTable element is not a ARPTable");  if (_link_table && _link_table->cast("LinkTable") == 0)     return errh->error("LinkTable element is not a LinkTable");  if (res < 0) {    return res;  }  return res;}intSRForwarder::initialize (ErrorHandler *){  return 0;}boolSRForwarder::update_link(IPAddress from, IPAddress to, 			 uint32_t seq, uint32_t age, uint32_t metric) {  if (_link_table && !_link_table->update_link(from, to, seq, age, metric)) {    click_chatter("%{element} couldn't update link %s > %d > %s\n",		  this,		  from.s().cc(),		  metric,		  to.s().cc());    return false;  }  return true;}Packet *SRForwarder::encap(Packet *p_in, Vector<IPAddress> r, int flags){  sr_assert(r.size() > 1);  int hops = r.size() - 1;  unsigned extra = srpacket::len_wo_data(hops) + sizeof(click_ether);  unsigned payload_len = p_in->length();  WritablePacket *p = p_in->push(extra);  assert(extra + payload_len == p_in->length());  int next = index_of(r, _ip) + 1;  if (next < 0 || next >= r.size()) {    click_chatter("SRForwarder %s: encap couldn't find %s (%d) in path %s",		  id().cc(),		  _ip.s().cc(),		  next,		  path_to_string(r).cc());    p_in->kill();    return (0);  }  EtherAddress eth_dest = _arp_table->lookup(r[next]);  if (eth_dest == _arp_table->_bcast) {    click_chatter("SRForwarder %s: arp lookup failed for %s",		  id().cc(),		  r[next].s().cc());  }    click_ether *eh = (click_ether *) p->data();  memcpy(eh->ether_shost, _eth.data(), 6);  memcpy(eh->ether_dhost, eth_dest.data(), 6);  eh->ether_type = htons(_et);      struct srpacket *pk = (struct srpacket *) (eh+1);  memset(pk, '\0', srpacket::len_wo_data(hops));  pk->_version = _sr_version;  pk->_type = PT_DATA;  pk->set_data_len(payload_len);  pk->set_num_links(hops);  pk->set_next(next);  pk->set_flag(flags);  int i;  for(i = 0; i < hops; i++) {    pk->set_link_node(i, r[i]);  }  pk->set_link_node(hops, r[r.size()-1]);  PathInfo *nfo = _paths.findp(r);  if (!nfo) {    _paths.insert(r, PathInfo(r));    nfo = _paths.findp(r);  }  pk->set_data_seq(nfo->_seq);    click_gettimeofday(&nfo->_last_tx);  nfo->_seq++;  /* set the ip header anno */  const click_ip *ip = reinterpret_cast<const click_ip *>    (p->data() + pk->hlen_wo_data() + sizeof(click_ether));  p->set_ip_header(ip, sizeof(click_ip));  return p;}voidSRForwarder::push(int port, Packet *p_in){  // wenjun's addition  _rcv_pkts++;  _rcv_bytes += p_in->length();  WritablePacket *p = p_in->uniqueify();  if (!p) {    return;  }  if (port > 1) {    p->kill();    return;  }  click_ether *eh = (click_ether *) p->data();  struct srpacket *pk = (struct srpacket *) (eh+1);  if(eh->ether_type != htons(_et)){    click_chatter("SRForwarder %s: bad ether_type %04x",                  _ip.s().cc(),                  ntohs(eh->ether_type));    p->kill();    return;  }  if (pk->_type != PT_DATA) {    click_chatter("SRForwarder %s: bad packet_type %04x",                  _ip.s().cc(),                  pk->_type);    p->kill();    return ;  }  if(port == 0 && pk->get_link_node(pk->next()) != _ip){    if (EtherAddress(eh->ether_dhost) != _bcast) {      /*        * if the arp doesn't have a ethernet address, it       * will broadcast the packet. in this case,       * don't complain. But otherwise, something's up       */      click_chatter("SRForwarder %s: data not for me seq %d %d/%d ip %s eth %s",		    id().cc(),		    pk->data_seq(),		    pk->next(),		    pk->num_links(),		    pk->get_link_node(pk->next()).s().cc(),		    EtherAddress(eh->ether_dhost).s().cc());    }    p->kill();    return;  }  /* update the metrics from the packet */  IPAddress r_from = pk->get_random_from();  IPAddress r_to = pk->get_random_to();  uint32_t r_fwd_metric = pk->get_random_fwd_metric();  uint32_t r_rev_metric = pk->get_random_rev_metric();  uint32_t r_seq = pk->get_random_seq();  uint32_t r_age = pk->get_random_age();  if (r_from && r_to) {    if (r_fwd_metric && !update_link(r_from, r_to, r_seq, r_age, r_fwd_metric)) {      click_chatter("%{element} couldn't update r_fwd %s > %d > %s\n",		    this,		    r_from.s().cc(),		    r_fwd_metric,		    r_to.s().cc());    }    if (r_rev_metric && !update_link(r_to, r_from, r_seq, r_age, r_rev_metric)) {      click_chatter("%{element} couldn't update r_rev %s > %d > %s\n",		    this,		    r_to.s().cc(),		    r_rev_metric, 		    r_from.s().cc());    }  }  for(int i = 0; i < pk->num_links(); i++) {    IPAddress a = pk->get_link_node(i);    IPAddress b = pk->get_link_node(i+1);    uint32_t fwd_m = pk->get_link_fwd(i);    uint32_t rev_m = pk->get_link_rev(i);    uint32_t seq = pk->get_link_seq(i);    uint32_t age = pk->get_link_age(i);    if (fwd_m && !update_link(a,b,seq,age,fwd_m)) {      click_chatter("%{element} couldn't update fwd_m %s > %d > %s\n",		    this,		    a.s().cc(),		    fwd_m,		    b.s().cc());    }    if (rev_m && !update_link(b,a,seq,age,rev_m)) {      click_chatter("%{element} couldn't update rev_m %s > %d > %s\n",		    this,		    b.s().cc(),		    rev_m,		    a.s().cc());    }  }    IPAddress prev = pk->get_link_node(pk->next()-1);  _arp_table->insert(prev, EtherAddress(eh->ether_shost));  /* set the ip header anno */  const click_ip *ip = reinterpret_cast<const click_ip *>    (pk->data());  p->set_ip_header(ip, sizeof(click_ip));    uint32_t prev_fwd_metric = (_link_table) ? _link_table->get_link_metric(prev, _ip) : 0;  uint32_t prev_rev_metric = (_link_table) ? _link_table->get_link_metric(_ip, prev) : 0;  uint32_t seq = (_link_table) ? _link_table->get_link_seq(_ip, prev) : 0;  uint32_t age = (_link_table) ? _link_table->get_link_age(_ip, prev) : 0;  pk->set_link(pk->next()-1,	       pk->get_link_node(pk->next()-1), _ip,	       prev_fwd_metric, prev_rev_metric,	       seq,age);  if(pk->next() == pk->num_links()){    // I'm the ultimate consumer of this data.    /*     * set the dst to the gateway it came from      * this is kinda weird.     */    SET_MISC_IP_ANNO(p, pk->get_link_node(0));    // wenjun's addition    _pkts_to_host++;    _bytes_to_host += p->length();    output(1).push(p);    return;  }   pk->set_next(pk->next() + 1);  IPAddress nxt = pk->get_link_node(pk->next());    EtherAddress eth_dest = _arp_table->lookup(nxt);  if (eth_dest == _arp_table->_bcast) {    click_chatter("%{element}::%s arp lookup failed for %s",		  this,		  __func__,		  nxt.s().cc());  }  memcpy(eh->ether_dhost, eth_dest.data(), 6);  memcpy(eh->ether_shost, _eth.data(), 6);  // wenjun's addition  _fwd_pkts++;  _fwd_bytes += p->length();  output(0).push(p);  return;}StringSRForwarder::static_print_stats(Element *f, void *){  SRForwarder *d = (SRForwarder *) f;  return d->print_stats();}StringSRForwarder::print_stats(){    return    "received:packets: " + String(_rcv_pkts) + "; received bytes: " + String(_rcv_bytes) + "\n" +    "packets to host: " + String(_pkts_to_host) + "; bytes to host: " + String(_bytes_to_host) + "\n" +    "forwarded:packets: " + String(_fwd_pkts) + "; forwarded bytes: " + String(_fwd_bytes) + "\n";}intSRForwarder::static_clear(const String &arg, Element *e,			  void *, ErrorHandler *errh){  SRForwarder *d = (SRForwarder *)(e);  bool b;  if (!cp_bool(arg, &b))    return errh->error("`clear' must be a boolean");  if (b) {    d->clear();    click_chatter("%{element}: statistics cleared\n", d);  }  return 0;}void SRForwarder::clear(){  _rcv_pkts = 0;  _rcv_bytes = 0;  _pkts_to_host = 0;  _bytes_to_host = 0;  _fwd_pkts = 0;  _fwd_bytes = 0;}voidSRForwarder::add_handlers(){  add_read_handler("stats", static_print_stats, 0);  add_write_handler("clear", static_clear, 0);}// generate Vector template instance#include <click/vector.cc>#include <click/bighashmap.cc>#include <click/hashmap.cc>#if EXPLICIT_TEMPLATE_INSTANCES#endifCLICK_ENDDECLSEXPORT_ELEMENT(SRForwarder)

⌨️ 快捷键说明

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