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

📄 ip6ndadvertiser.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
/* * ip6ndadvertiser.{cc,hh} -- element that responds to * Neighbor Solitation Msg * Peilei Fan * * 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 "ip6ndadvertiser.hh"#include <clicknet/ether.h>#include <clicknet/ip6.h>#include <click/etheraddress.hh>#include <click/ip6address.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>CLICK_DECLSIP6NDAdvertiser::IP6NDAdvertiser(){}IP6NDAdvertiser::~IP6NDAdvertiser(){}voidIP6NDAdvertiser::add_map(const IP6Address &ipa, const IP6Address &mask, const EtherAddress &ena){  struct Entry e;  e.dst = ipa;  e.mask = mask;  e.ena = ena;  _v.push_back(e);}intIP6NDAdvertiser::configure(Vector<String> &conf, ErrorHandler *errh){  _v.clear();  int before = errh->nerrors();  for (int i = 0; i < conf.size(); i++) {    IP6Address ipa, mask;    EtherAddress ena;    bool have_ena = false;    int first = _v.size();    Vector<String> words;    cp_spacevec(conf[i], words);    for (int j = 0; j < words.size(); j++)      if (cp_ip6_prefix(words[j], (unsigned char *)&ipa, (unsigned char *)&mask, true, this))	add_map(ipa, mask, EtherAddress());      else if (cp_ip6_address(words[j], &ipa, this))	add_map(ipa, IP6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), EtherAddress());      else if (cp_ethernet_address(words[j], &ena, this)) {	if (have_ena)	  errh->error("argument %d has more than one Ethernet address", i);	have_ena = true;      } else {	errh->error("argument %d should be `IP6/MASK ETHADDR'", i);	j = words.size();      }    if (first == _v.size())      errh->error("argument %d had no IP6 address and masks", i);    for (int j = first; j < _v.size(); j++)      _v[j].ena = ena;  }  return (before == errh->nerrors() ? 0 : -1);}Packet *IP6NDAdvertiser::make_response(u_char dha[6],   /*  des eth address */			     u_char sha[6],   /*  src eth address */			     u_char dpa[16],  /*  dst IP6 address */			     u_char spa[16],  /*  src IP6 address */			     u_char tpa[16],  /*  target IP6 address */			     u_char tha[6])   /*  target eth address */{  click_ether *e;  click_ip6 *ip6;  click_nd_adv *ea;  WritablePacket *q = Packet::make(sizeof(*e) + sizeof(*ip6)+ sizeof(*ea));  if (q == 0) {    click_chatter("in NDadv: cannot make packet!");    assert(0);  }  memset(q->data(), '\0', q->length());  e = (click_ether *) q->data();  ip6=(click_ip6 *) (e+1);  ea = (click_nd_adv *) (ip6 + 1);  //set ethernet header  memcpy(e->ether_dhost, dha, 6);  memcpy(e->ether_shost, sha, 6);  e->ether_type = htons(ETHERTYPE_IP6);  //set ip6 header  ip6->ip6_flow = 0;		// set flow to 0 (includes version)  ip6->ip6_v = 6;		// then set version to 6  ip6->ip6_plen=htons(sizeof(click_nd_adv));  ip6->ip6_nxt=0x3a; //i.e. protocal: icmp6 message  ip6->ip6_hlim=0xff; //indicate no router has processed it  ip6->ip6_src = IP6Address(spa);  ip6->ip6_dst = IP6Address(dpa);  //set Neighborhood Solicitation Validation Message  ea->type = 0x88;  ea->code =0;  // fixed from 0x60 thanks to Simona Fischera  ea->flags = 0xC0; //  this is the same as setting the following                    //  ea->sender_is_router = 1;                    //  ea->solicited =1;                    //  ea->override = 0;  for (int i=0; i<3; i++) {    ea->reserved[i] = 0;  }  memcpy(ea->nd_tpa, tpa, 16);  ea->option_type = 0x2;  ea->option_length = 0x1;  memcpy(ea->nd_tha, tha, 6);  ea->checksum = htons(in6_fast_cksum(&ip6->ip6_src, &ip6->ip6_dst, ip6->ip6_plen, ip6->ip6_nxt, 0, (unsigned char *)ea, ip6->ip6_plen));  return q;}Packet *IP6NDAdvertiser::make_response2(u_char dha[6],   /*  des eth address */			     u_char sha[6],   /*  src eth address */			     u_char dpa[16],  /*  dst IP6 address */			     u_char spa[16],  /*  src IP6 address */			     u_char tpa[16])  /*  target IP6 address */{  click_ether *e;  click_ip6 *ip6;  click_nd_adv2 *ea;  WritablePacket *q = Packet::make(sizeof(*e) + sizeof(*ip6)+ sizeof(*ea));  if (q == 0) {    click_chatter("in IP6NDAdvertiser: cannot make packet!");    assert(0);  }  memset(q->data(), '\0', q->length());  e = (click_ether *) q->data();  ip6=(click_ip6 *) (e+1);  ea = (click_nd_adv2 *) (ip6 + 1);  //set ethernet header  memcpy(e->ether_dhost, dha, 6);  memcpy(e->ether_shost, sha, 6);  e->ether_type = htons(ETHERTYPE_IP6);  //set ip6 header  ip6->ip6_flow = 0;		// set flow to 0 (includes version)  ip6->ip6_v = 6;		// then set version to 6  ip6->ip6_plen=htons(sizeof(click_nd_adv2));  ip6->ip6_nxt=0x3a; //i.e. protocal: icmp6 message  ip6->ip6_hlim=0xff; //indicate no router has processed it  ip6->ip6_src = IP6Address(spa);  ip6->ip6_dst = IP6Address(dpa);  //set Neighbor Solicitation Validation Message  ea->type = 0x88;  ea->code =0;  // fixed from 0x60 thanks to Simona Fischera  ea->flags = 0xC0; //  this is the same as setting the following                    //  ea->sender_is_router = 1;                    //  ea->solicited =1;                    //  ea->override = 0;  for (int i=0; i<3; i++) {    ea->reserved[i] = 0;  }  memcpy(ea->nd_tpa, tpa, 16);  ea->checksum = htons(in6_fast_cksum(&ip6->ip6_src, &ip6->ip6_dst, ip6->ip6_plen, ip6->ip6_nxt, 0, (unsigned char *)(ip6+1), htons(sizeof(click_nd_adv2))));  return q;}boolIP6NDAdvertiser::lookup(const IP6Address &a, EtherAddress &ena) const{  int best = -1;  for (int i = 0; i < _v.size(); i++)    if (a.matches_prefix(_v[i].dst, _v[i].mask)) {      if (best < 0 || _v[i].mask.mask_as_specific(_v[best].mask))	best = i;    }  if (best < 0)    return false;  else {    ena = _v[best].ena;    return true;  }}Packet *IP6NDAdvertiser::simple_action(Packet *p){   click_ether *e = (click_ether *) p->data();   click_ip6 *ip6 = (click_ip6 *) (e + 1);   click_nd_sol *ea=(click_nd_sol *) (ip6 + 1);   unsigned char tpa[16];   unsigned char spa[16];   unsigned char dpa[16];   memcpy(&tpa, ea->nd_tpa, 16);   memcpy(&dpa, IP6Address(ip6->ip6_src).data(), 16);   IP6Address ipa = IP6Address(tpa);   //check see if the packet is corrupted by recalculating its checksum   unsigned short int csum2 = in6_fast_cksum(&ip6->ip6_src, &ip6->ip6_dst, ip6->ip6_plen, ip6->ip6_nxt, ea->checksum, (unsigned char *)(ip6+1), htons(sizeof(click_nd_sol)));   Packet *q = 0;  if (p->length() >= sizeof(*e) + sizeof(click_ip6) + sizeof(click_nd_sol) &&      ntohs(e->ether_type) == ETHERTYPE_IP6 &&      ip6->ip6_hlim ==0xff &&      ea->type == ND_SOL &&      ea->code == 0 &&      csum2 == ntohs(ea->checksum))    {      EtherAddress ena;      unsigned char host_ether[6];      if(lookup(ipa, ena))	{	  memcpy(&spa, ipa.data(), 16);	  memcpy(&host_ether, ena.data(),6);	  //use the finded ip6address as its source ip6 address in the	  //header in neighborhood advertisement message packet	  q = make_response(e->ether_shost, host_ether, dpa, spa, tpa, host_ether);	}    }  else    {      click_in6_addr ina;      memcpy(&ina, &ea->nd_tpa, 16);    }  p->kill();  return(q);}ELEMENT_REQUIRES(ip6)EXPORT_ELEMENT(IP6NDAdvertiser)CLICK_ENDDECLS

⌨️ 快捷键说明

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