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

📄 dsrarptable.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
/* * dsrarptable.{cc,hh} * Shweta Bhandare, Sagar Sanghani, Sheetalkumar Doshi, Timothy X Brown * Daniel Aguayo * * Copyright (c) 2003 Massachusetts Institute of Technology * Copyright (c) 2003 University of Colorado at Boulder * * 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/package.hh>#include <clicknet/ether.h>#include <click/glue.hh>#include <click/etheraddress.hh>#include <click/ipaddress.hh>#include <click/confparse.hh>#include <click/bitvector.hh>#include <click/error.hh>#include <clicknet/ip.h>#include <click/router.hh>#include <click/standard/scheduleinfo.hh>#include "dsrarptable.hh"#include "dsr.hh"CLICK_DECLS#define DEBUG_CHATTER  if (_debug) click_chatterDSRArpTable::DSRArpTable()  : _debug(false){}DSRArpTable::~DSRArpTable(){}intDSRArpTable::configure(Vector<String> &conf, ErrorHandler *errh){  unsigned int etht = 0x0800;  if (cp_va_kparse(conf, this, errh,		   "IP", cpkP+cpkM, cpIPAddress, &_me,		   "ETH", cpkP+cpkM, cpEthernetAddress, &_me_ether,		   "ETHERTYPE", 0, cpUnsigned, &etht,		   "DEBUG", 0, cpBool, &_debug,		   cpEnd) < 0)    return -1;  _etht = etht;  return 0;}intDSRArpTable::initialize(ErrorHandler *){  return 0;}Packet *DSRArpTable::pull(int port){  assert(port == 0 || port == 1);  // packets to which we want to add an ethernet header  Packet *p_in = input(port).pull();  if (!p_in)    return NULL;  WritablePacket *q = p_in->push(sizeof(click_ether));  if (!q) {    click_chatter("DSRArpTable::pull(%d):  could not push space for ethernet header\n", port);    return NULL;  }  click_ether *ether = (click_ether *)(q->data());  IPAddress dst_addr(q->dst_ip_anno());  EtherAddress dst_ether = lookup_ip(dst_addr);  if (! dst_ether) {    click_chatter ("DSRArpTable::push:  missing ARP table entry!  src: %s/%s dst: %s/%s\n",		   _me.unparse().c_str(), _me_ether.unparse().c_str(),		   dst_addr.unparse().c_str(), dst_ether.unparse().c_str());    q->kill();    return NULL;  }  memcpy(&ether->ether_shost, &_me_ether, 6);  memcpy(&ether->ether_dhost, dst_ether.data(), 6);  ether->ether_type = htons(_etht);  return q;}voidDSRArpTable::push(int port, Packet *p_in){  // packets from which we want to extract MAC addresses  assert(port == 2);  const click_ip *iph = (const click_ip*)(p_in->data() + sizeof(click_ether));  if (iph->ip_p != IP_PROTO_DSR) {    DEBUG_CHATTER ("DSRArpTable::push:  non-DSR packet passing through DSRArpTable\n");    output(2).push(p_in);    return;  }  const click_ether *eth = (const click_ether *)p_in->data();  EtherAddress mac = EtherAddress(eth->ether_shost);  IPAddress ip = last_hop_ip(p_in);  EtherAddress e = lookup_ip(ip);  if (!e) {    DEBUG_CHATTER("DSRArpTable::push:  adding ARP table entry for IP: %s; MAC: %s",		  ip.unparse().c_str(), mac.unparse().c_str());    add_entry(ip, mac);  } else if (e != mac) {    click_chatter("DSRArpTable::push:  existing entry for %s has different MAC!  %s, not %s",		  ip.unparse().c_str(), e.unparse().c_str(), mac.unparse().c_str());    delete_entry(ip);    add_entry(ip, mac);  }  WritablePacket *p = p_in->uniqueify();  SET_DSR_LAST_HOP_IP_ANNO(p, ip.addr());  const uint16_t *d = e.sdata();  SET_DSR_LAST_HOP_ETH_ANNO1(p, d[0]);  SET_DSR_LAST_HOP_ETH_ANNO2(p, d[1]);  SET_DSR_LAST_HOP_ETH_ANNO3(p, d[2]);  output(2).push(p);}// returns the ip of the last forwarder of this packet.  if this is a// route request, this comes from the accumulated route.  otherwise it// comes from the IP header (src and dst) and source route.  if there// is no source route option, a one-hop source route is implied.IPAddressDSRArpTable::last_hop_ip(Packet *p){  const click_ip *ip = (const click_ip *)(p->data() + sizeof(click_ether));  click_dsr *dsr = (click_dsr *)((char *)ip + sizeof(click_ip));  const unsigned int dsr_len = ntohs(dsr->dsr_len);  click_dsr_option *dsr_option = (click_dsr_option *)((char *)dsr +						      sizeof(click_dsr));//   click_chatter("last_hop_ip: dsr len is %d; first type is %x\n",//		dsr_len, dsr_option->dsr_type);  if (dsr_option->dsr_type == DSR_TYPE_RREQ) {    const click_dsr_rreq *dsr_rreq = (click_dsr_rreq *)dsr_option;    const unsigned int num_addr = dsr_rreq->num_addrs();    if (num_addr == 0) { // this route request is on its first hop      IPAddress src_addr(ip->ip_src.s_addr);      return (src_addr);    } else {      IPAddress last_hop = dsr_rreq->addr[num_addr-1].ip();      DEBUG_CHATTER ("saw a route request being forwarded by %s\n",		     last_hop.unparse().c_str());      return (last_hop);    }  } else if (dsr_option->dsr_type == DSR_TYPE_RREP) {    // if this is a route reply, then we expect a source route option    // immediately following -- move the dsr_option pointer down to    // the next header and handle as a normal source-routed packet.    // if there is no source route option following, then this must be    // a one-hop reply.    const click_dsr_rrep *dsr_rrep = (click_dsr_rrep *)dsr_option;    //    DEBUG_CHATTER(" * extracting IP from route reply; num_addr is %d\n", num_addr);    if (dsr_rrep->length() == dsr_len) {      // if this RREP option is the only option in the header      IPAddress src_addr(ip->ip_src.s_addr);      return (src_addr);    } else {      dsr_option = (click_dsr_option *)(dsr_rrep->next_option());      if (dsr_option->dsr_type != DSR_TYPE_SOURCE_ROUTE) {	DEBUG_CHATTER(" * DSRArpTable::last_hop: source route option did not follow route reply option (%x)\n",		      dsr_option->dsr_type);	IPAddress zeros;	return zeros;      }    }  } else if (dsr_option->dsr_type == DSR_TYPE_RERR) {    // if this is a route error, then we expect a source route option    // immediately following -- handle as we did with RREP.  if there    // is no source route option following, then this must be a    // one-hop reply.    //    // XXX we might have multiple RERRs.    const click_dsr_rerr *dsr_rerr = (click_dsr_rerr *)dsr_option;    if (dsr_rerr->length() == dsr_len) {      // if this RERR option is the only option in the header      IPAddress src_addr(ip->ip_src.s_addr);      return (src_addr);    } else {      dsr_option = (click_dsr_option *)(dsr_rerr->next_option());      if (dsr_option->dsr_type != DSR_TYPE_SOURCE_ROUTE) {	DEBUG_CHATTER(" * DSRArpTable::last_hop: source route option did not follow route error option (%x)\n",		      dsr_option->dsr_type);	IPAddress zeros;	return zeros;      }    }  }  if (dsr_option->dsr_type == DSR_TYPE_SOURCE_ROUTE) {    // 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 (index == 0) { // this is the first hop      IPAddress src(ip->ip_src.s_addr);      return src;    } else {      return dsr_source->addr[index-1].ip();    }  }  assert(0);  return IPAddress();}voidDSRArpTable::add_entry(IPAddress ip, EtherAddress eth){  EtherAddress *e =_ip_map.findp(ip);  assert(!e);  _ip_map.insert(ip, eth);}voidDSRArpTable::delete_entry(IPAddress ip){  EtherAddress *e =_ip_map.findp(ip);  assert(e);  _ip_map.remove(ip);}EtherAddressDSRArpTable::lookup_ip(IPAddress ip){  IPAddress bcast_ip("255.255.255.255");  if (ip == bcast_ip) {    EtherAddress bcast_eth((unsigned char *)("\xff\xff\xff\xff\xff\xff"));    return bcast_eth;  }  return (_ip_map.find(ip));}EXPORT_ELEMENT(DSRArpTable)CLICK_ENDDECLS

⌨️ 快捷键说明

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