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

📄 dsrroutetable.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 4 页
字号:
    // either this is a normal source-routed packet, or a RREP or RERR    // with a source route header    click_dsr_source *dsr_source = (click_dsr_source *)(dsr_option);    assert(dsr_source->dsr_type == DSR_TYPE_SOURCE_ROUTE);    unsigned char segments = dsr_source->dsr_segsleft;    unsigned char source_hops = dsr_source->num_addrs();    assert(segments <= source_hops);    int index = source_hops - segments;    if (segments == 0) { // this is the last hop      IPAddress dst(ip->ip_dst.s_addr);      return dst;    } else {      return dsr_source->addr[index-1].ip();    }  }  assert(0);  return IPAddress();}// returns ip of next hop on source route; split out from forward_sr// so we can use it when generating route error messages.  offset is// the offset of the source route option in this packet.IPAddressDSRRouteTable::next_sr_hop(Packet *p_in, unsigned int offset){  assert(offset + sizeof(click_dsr_source) <= p_in->length());  click_dsr_source *dsr_source = (click_dsr_source *)(p_in->data() +						      offset);  // click_chatter("type is %d\n", dsr_source->dsr_type);  assert (dsr_source->dsr_type == DSR_TYPE_SOURCE_ROUTE);  unsigned char segments = dsr_source->dsr_segsleft;  unsigned char source_hops = dsr_source->num_addrs();  // click_chatter("segments %02x, source_hops %02x\n", segments, source_hops);  assert(segments <= source_hops);  // this is the index of the address to which this packet should be forwarded  int index = source_hops - segments;  if (segments == 0) { // this is the last hop    const click_ip *ip = p_in->ip_header();    IPAddress final_dst(ip->ip_dst.s_addr);    return final_dst;  } else {    return dsr_source->addr[index].ip();  }}// offset is the offset of the source route option in this packetvoidDSRRouteTable::forward_sr(Packet *p_in, unsigned int offset, int port){  if (offset > p_in->length()) {    DEBUG_CHATTER(" * offset passed to forwardSRPacket is too big!  (%d > %d)\n",		  offset, p_in->length());    p_in->kill();    return;  }  WritablePacket *p=p_in->uniqueify();  click_dsr_source *dsr_source = (click_dsr_source *)(p->data() +						      offset);  if (dsr_source->dsr_type != DSR_TYPE_SOURCE_ROUTE) {    DEBUG_CHATTER(" * source route option not found where expected in forward_sr\n");    p->kill();    return;  }  // after we forward it there will be (segsleft-1) hops left;  dsr_source->dsr_segsleft--;  p->set_dst_ip_anno(next_sr_hop(p, offset));  DEBUG_CHATTER("forward_sr: forwarding to %s\n", next_sr_hop(p, offset).unparse().c_str());  output(port).push(p);  return;}// rebroadcast a route request.  we've already checked that we haven't// seen this RREQ lately, and added the info to the forwarded_rreq_map.voidDSRRouteTable::forward_rreq(Packet *p_in){  click_dsr *orig_dsr = (click_dsr *)(p_in->data()+				     sizeof(click_ip));  click_dsr_rreq *orig_rreq = (click_dsr_rreq *)(p_in->data() +						sizeof(click_ip) +						sizeof(click_dsr));  int hop_count = orig_rreq->num_addrs();  assert(ntohs(orig_dsr->dsr_len) == (sizeof(click_dsr_rreq) +				      hop_count * sizeof(DSRHop)));  // add my address to the end of the packet  WritablePacket *p=p_in->uniqueify();  p = p->put(sizeof(DSRHop));  click_ip *ip = reinterpret_cast<click_ip *>(p->data());  click_dsr *dsr = (click_dsr *)(p->data()+				 sizeof(click_ip));  click_dsr_rreq *dsr_rreq = (click_dsr_rreq *)(p->data() +						sizeof(click_ip) +						sizeof(click_dsr));  dsr_rreq->addr[hop_count]._ip.s_addr = me->addr();  EtherAddress last_eth = last_forwarder_eth(p);  dsr_rreq->addr[hop_count]._metric = get_metric(last_eth);  dsr_rreq->dsr_len += sizeof(DSRHop);  dsr->dsr_len = htons(ntohs(dsr->dsr_len)+sizeof(DSRHop));  ip->ip_ttl--;  ip->ip_len = htons(p->length());  ip->ip_sum = 0;  ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip));  p->set_dst_ip_anno(0xffffffff);  output(1).push(p);}// build and send out a request for the ipvoidDSRRouteTable::issue_rreq(IPAddress dst, unsigned int ttl, bool unicast){  // make a route request packet with room for gratuitious route repair rerrs  // XXX what does the above mean?  route repair rerrs??  unsigned payload = (sizeof(click_ip)+		      sizeof(click_dsr)+		      sizeof(click_dsr_rreq));  WritablePacket *p = Packet::make(payload);  // get header pointers  click_ip *ip = reinterpret_cast<click_ip *>(p->data());  click_dsr *dsr = (click_dsr*)(p->data() + sizeof(click_ip));  click_dsr_rreq *dsr_rreq = (click_dsr_rreq*)(p->data() +					       sizeof(click_ip) +					       sizeof(click_dsr));  ip->ip_v = 4;  ip->ip_hl = sizeof(click_ip) >> 2;  ip->ip_len = htons(p->length());  ip->ip_id = htons(_rreq_id); // XXX eh?  why this?  ip->ip_p = IP_PROTO_DSR;  ip->ip_src.s_addr = me->addr();  if (unicast)    ip->ip_dst.s_addr = dst.addr();  else    ip->ip_dst.s_addr = 0xffffffff;  ip->ip_tos = 0;  ip->ip_off = 0;  ip->ip_ttl = ttl;  ip->ip_sum = 0;  ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip));  dsr->dsr_next_header = 0;  dsr->dsr_len = htons(sizeof(click_dsr_rreq));  dsr->dsr_reserved = 0;  dsr_rreq->dsr_type = DSR_TYPE_RREQ;  dsr_rreq->dsr_len = 6;  dsr_rreq->dsr_id = htons(_rreq_id);  dsr_rreq->target.s_addr = dst.addr();  p->set_dst_ip_anno(ip->ip_dst.s_addr);  _rreq_id++;  output(1).push(p);}// start issuing requests for a host.voidDSRRouteTable::start_issuing_request(IPAddress host){  // check to see if we're already querying for this host  InitiatedReq *r = _initiated_rreq_map.findp(host);  if (r) {    DEBUG_CHATTER(" * start_issuing_request:  already issuing requests for %s\n", host.unparse().c_str());    return;  } else {    // send out the initial request and add an entry to the table    InitiatedReq new_rreq(host);    _initiated_rreq_map.insert(host, new_rreq);    issue_rreq(host, DSR_RREQ_TTL1, false);    return;  }}// we've received a route reply.  remove the cooresponding entry from// route request table, so we don't send out more requestsvoidDSRRouteTable::stop_issuing_request(IPAddress host){  InitiatedReq *r = _initiated_rreq_map.findp(host);  if (!r) {    DEBUG_CHATTER(" * stop_issuing_request:  no entry in request table for %s\n", host.unparse().c_str());    return;  } else {    _initiated_rreq_map.remove(host);    return;  }}voidDSRRouteTable::static_rreq_issue_hook(Timer *, void *v){  DSRRouteTable *r = (DSRRouteTable *)v;  r->rreq_issue_hook();}voidDSRRouteTable::rreq_issue_hook(){  // look through the initiated rreqs and check if it's time to send  // anything out  Timestamp curr_time = Timestamp::now();  // DEBUG_CHATTER("checking issued rreq table\n");  Vector<IPAddress> remove_list;  for (InitReqIter i = _initiated_rreq_map.begin(); i.live(); i++) {    InitiatedReq &ir = i.value();    assert(ir._target == i.key());    // we could find out a route by some other means than a direct    // RREP.  if this is the case, stop issuing requests.    _link_table->dijkstra(false);    Vector<IPAddress> route = _link_table->best_route(ir._target,false);    if (route.size() > 1) { // we have a route      remove_list.push_back(ir._target);      continue;    } else {      if (diff_in_ms(curr_time, ir._time_last_issued) > ir._backoff_interval) {	DEBUG_CHATTER("time to issue new request for host %s\n", ir._target.unparse().c_str());	if (ir._times_issued == 1) {	  // if this is the second request	  ir._backoff_interval = DSR_RREQ_DELAY2;	} else {	  ir._backoff_interval *= DSR_RREQ_BACKOFF_FACTOR;	  // i don't think there's any mention in the spec of a limit on	  // the backoff, but this MAX_DELAY seems reasonable	  if (ir._backoff_interval > DSR_RREQ_MAX_DELAY)	    ir._backoff_interval = DSR_RREQ_MAX_DELAY;	}	ir._times_issued++;	ir._time_last_issued = curr_time;	ir._ttl = DSR_RREQ_TTL2;	issue_rreq(ir._target, ir._ttl, false);      }    }  }  for (int j = 0 ; j < remove_list.size() ; j++) {    _initiated_rreq_map.remove(remove_list[j]);  }  _rreq_issue_timer.schedule_after_msec(DSR_RREQ_ISSUE_TIMER_INTERVAL);  check();}// random helper functionsDSRRouteDSRRouteTable::reverse_route(DSRRoute r){ DSRRoute rev; for(int i=r.size()-1; i>=0; i--) {   rev.push_back(r[i]); } return rev;}DSRRouteDSRRouteTable::truncate_route(DSRRoute r, IPAddress ip){ DSRRoute t; for (int i=0; i < r.size(); i++) {   t.push_back(r[i]);   if (r[i].ip() == ip) {     return t;   } } return DSRRoute();}intDSRRouteTable::route_index_of(DSRRoute r, IPAddress ip){ for (int i=0; i<r.size(); i++) {   if (r[i].ip() == ip)     return i; } return -1;}voidDSRRouteTable::add_route_to_link_table(DSRRoute route){  for (int i=0; i < route.size() - 1; i++) {    IPAddress ip1 = route[i].ip();    IPAddress ip2 = route[i+1].ip();    // ETX:    unsigned char metric = route[i+1]._metric;    if (metric == DSR_INVALID_HOP_METRIC)      _link_table->update_both_links(ip1, ip2, 0, 0, 9999);    else      _link_table->update_both_links(ip1, ip2, 0, 0, metric);    // DEBUG_CHATTER("_link_table->update_link %s %s %d\n",    //               route[i].unparse().c_str(), route[i+1].s().c_str(), metric);  }}intDSRRouteTable::check_blacklist(IPAddress ip){  if (!_use_blacklist) return DSR_BLACKLIST_NOENTRY;  BlacklistEntry *e = _blacklist.findp(ip);  if (! e) {    return DSR_BLACKLIST_NOENTRY;  } else {    return e->_status;  }}voidDSRRouteTable::set_blacklist(IPAddress ip, int s){  //  DEBUG_CHATTER ("set blacklist: %s %d\n", ip.unparse().c_str(), s);  //  DEBUG_CHATTER ("set blacklist: %d\n", check_blacklist(ip));  _blacklist.remove(ip);  if (s != DSR_BLACKLIST_NOENTRY) {    BlacklistEntry e;    e._time_updated.set_now();    e._status = s;    _blacklist.insert(ip, e);  }  //  DEBUG_CHATTER ("set blacklist: %d\n", check_blacklist(ip));}unsigned longDSRRouteTable::diff_in_ms(const Timestamp &t1, const Timestamp &t2){    Timestamp diff = t1 - t2;    assert(diff.sec() < (Timestamp::seconds_type) ((1 << 31) / 1000));    return diff.msecval();}// Ask LinkStat for the metric for the link from other to us.// ripped off from srcr.ccunsigned charDSRRouteTable::get_metric(EtherAddress other){#if 0  unsigned char dft = DSR_INVALID_HOP_METRIC; // default metric  if (_ls){    unsigned int tau;    Timestamp tv;    unsigned int frate, rrate;    bool res = _ls->get_forward_rate(other, &frate, &tau, &tv);    if(res == false) {      return dft;    }    res = _ls->get_reverse_rate(other, &rrate, &tau);    if (res == false) {      return dft;    }    if (frate == 0 || rrate == 0) {      return dft;    }    // rate is 100 * recv %    // m = 10 x 1/(fwd% x rev%)    u_short m = 10 * 100 * 100 / (frate * (int) rrate);    if (m > DSR_INVALID_HOP_METRIC) {      click_chatter("DSRRouteTable::get_metric: metric too big for one byte?\n");      return DSR_INVALID_HOP_METRIC;    }    return (unsigned char)m;  }#endif  if (_metric) {    GridGenericMetric::metric_t m = _metric->get_link_metric(other, false);    unsigned char c = _metric->scale_to_char(m);    if (!m.good() || c >= DSR_INVALID_HOP_METRIC)      return DSR_INVALID_HOP_METRIC;    return c;  }  else {    // default to hop-count, all links have a hop-count of 1    return 1;  }}boolDSRRouteTable::metric_preferable(unsigned short a, unsigned short b){  if (!_metric)    return (a < b); // fallback to minimum hop-count  else if (a == DSR_INVALID_ROUTE_METRIC || b == DSR_INVALID_ROUTE_METRIC)    return a; // make arbitrary choice  else    return _metric->metric_val_lt(_metric->unscale_from_char(a),				  _metric->unscale_from_char(b));}unsigned shortDSRRouteTable::route_metric(DSRRoute r){#if 0  unsigned short ret = 0;  // the metric in r[i+1] represents the link between r[i] and r[i+1],  // so we start at 1  for (int i = 1; i < r.size(); i++) {    if (r[i]._metric == DSR_INVALID_HOP_METRIC)      return DSR_INVALID_ROUTE_METRIC;    ret += r[i]._metric;  }  return ret;#endif  if (r.size() < 2) {    click_chatter("DSRRouteTable::route_metric: route is too short, less than two nodes?\n");    return DSR_INVALID_ROUTE_METRIC;  }  if (!_metric)    return r.size(); // fallback to hop-count  if (r[1]._metric == DSR_INVALID_HOP_METRIC)    return DSR_INVALID_ROUTE_METRIC;  GridGenericMetric::metric_t m(_metric->unscale_from_char(r[1]._metric));  for (int i = 2; i < r.size(); i++) {     if (r[i]._metric == DSR_INVALID_HOP_METRIC)      return DSR_INVALID_ROUTE_METRIC;     m = _metric->append_metric(m, _metric->unscale_from_char(r[i]._metric));  }  if (m.good())    return _metric->scale_to_char(m);  else    return DSR_INVALID_ROUTE_METRIC;}EtherAddressDSRRouteTable::last_forwarder_eth(Packet *p){  uint16_t d[3];  d[0] = DSR_LAST_HOP_ETH_ANNO1(p);  d[1] = DSR_LAST_HOP_ETH_ANNO2(p);  d[2] = DSR_LAST_HOP_ETH_ANNO3(p);  return (EtherAddress((unsigned char *)d));}ELEMENT_REQUIRES(LinkTable)EXPORT_ELEMENT(DSRRouteTable)CLICK_ENDDECLS

⌨️ 快捷键说明

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