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

📄 protocoltranslator64.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * protocoltranslator64{cc,hh} -- element that translates an IPv6 packet to  * an IPv4 packet.  * When translating an IPv6 packet to IPv4 packet, assuming the addresses has  * already been IPv4-mapped IPv6 addresses (e.g.,::ffff:18.26.4.17), the IPv4 * addresses will be the lowest 32 bits of IPv6 addresses. * *  * Peilei Fan * * Copyright (c) 1999-2001 Massachusetts Institute of Technology. * * This software is being provided by the copyright holders under the GNU * General Public License, either version 2 or, at your discretion, any later * version. For more information, see the `COPYRIGHT' file in the source * distribution. */#include <click/config.h>#include "protocoltranslator64.hh"#include <click/confparse.hh>#include <click/error.hh>#include <clicknet/ip.h>#include <clicknet/ip6.h>#include <clicknet/icmp.h>#include <clicknet/icmp6.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>CLICK_DECLSProtocolTranslator64::ProtocolTranslator64(){  add_input(); /*IPv6 packets */  add_output(); /* IPv4 packets */}ProtocolTranslator64::~ProtocolTranslator64(){}intProtocolTranslator64::configure(Vector<String> &conf, ErrorHandler *errh){   int before = errh->nerrors();   if (!(conf.size()==0))    {      errh->error("there should be no arguments");    }  return (before ==errh->nerrors() ? 0: -1); }//make the ipv6->ipv4 translation of the packet according to SIIT (RFC 2765)Packet *ProtocolTranslator64::make_translate64(IPAddress src,				     IPAddress dst,				     click_ip6 * ip6,				     unsigned char *a) {  click_ip *ip;  click_tcp *tcp;  click_udp *udp;  WritablePacket *q = Packet::make(sizeof(*ip) + ntohs(ip6->ip6_plen));    if (q==0) {    click_chatter("can not make packet!");    assert(0);  }  memset(q->data(), '\0', q->length());  ip = (click_ip *)q->data();  tcp = (click_tcp *)(ip+1);  udp = (click_udp *)(ip+1);    //set ipv4 header  ip->ip_v = 4;  ip->ip_hl =5;   ip->ip_tos =0;  ip->ip_len = htons(sizeof(*ip) + ntohs(ip6->ip6_plen));    ip->ip_id = htons(0);  //need to change  //ip->ip_id[0]=ip6->ip_flow[1];  //ip->ip_id[1]=ip6->ip_flow[2];    //set Don't Fragment flag to true, all other flags to false,   //set fragement offset: 0  ip->ip_off = htons(IP_DF);  //need to deal with fragmentation later  //we do not change the ttl since the packet has to go through v4 routing table  ip->ip_ttl = ip6->ip6_hlim;   //set the src and dst address  ip->ip_src = src.in_addr();  ip->ip_dst = dst.in_addr();   //copy the actual payload of packet   memcpy((unsigned char *)tcp, a, ntohs(ip6->ip6_plen));  //set the tcp header checksum  //The tcp checksum for ipv4 packet is include the tcp packet, and the 96 bits   //TCP pseudoheader, which consists of Source Address, Destination Address,   //1 byte zero, 1 byte PTCL, 2 byte TCP length.      if (ip6->ip6_nxt == 6) //TCP    {      ip->ip_p = ip6->ip6_nxt;            //set the ip header checksum      ip->ip_sum=0;       tcp->th_sum = 0;      tcp->th_sum = htons(in_ip4_cksum(src.addr(), dst.addr(), ip6->ip6_plen, ip->ip_p, 0, (unsigned char *)tcp, ip6->ip6_plen));      ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip));    }    else if (ip6->ip6_nxt ==17) //UDP    {      ip->ip_p = ip6->ip6_nxt;            //set the ip header checksum      ip->ip_sum=0;       udp->uh_sum = 0;      udp->uh_sum = htons(in_ip4_cksum(src.addr(), dst.addr(), ip6->ip6_plen, ip->ip_p, 0, (unsigned char *)udp, ip6->ip6_plen));      ip->ip_sum = click_in_cksum((unsigned char *)ip, sizeof(click_ip));    }    else if (ip6->ip6_nxt== 58)    {      ip->ip_p = 1;      //icmp 4->6 translation is dealt by caller    }  else     {      // will deal with other protocols later    }  return q;	   }Packet *ProtocolTranslator64::make_icmp_translate64(unsigned char *a,			      unsigned char payload_length){    click_ip6 *ip6=0;  unsigned char *ip=0;  unsigned char icmp6_type= a[0];  unsigned char icmp6_code= a[1];  unsigned char icmp_length;  WritablePacket *q2 = 0;  // set type, code, length , and checksum of ICMP header  switch (icmp6_type) {   case ICMP6_ECHO: ;   case ICMP6_ECHOREPLY : {      icmp_length = payload_length -sizeof(click_icmp6_echo) + sizeof(click_icmp_echo);      click_icmp6_echo *icmp6 = (click_icmp6_echo *)a;      ip6 = (click_ip6 *)(icmp6+1);            q2 = Packet::make(icmp_length);      memset(q2->data(), '\0', q2->length());      click_icmp_echo *icmp = (click_icmp_echo *)q2->data();      ip = (unsigned char *)(icmp+1);      if (icmp6_type == ICMP6_ECHO ) { // icmp6_type ==128 	icmp->icmp_type = ICMP_ECHO;                 // icmp_type =8        }      else if (icmp6_type == ICMP6_ECHOREPLY ) { // icmp6_type ==129 	icmp->icmp_type = ICMP_ECHOREPLY;              // icmp_type = 0         }      icmp->icmp_identifier = (icmp6->icmp6_identifier);      icmp->icmp_sequence = (icmp6->icmp6_sequence);      memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_echo)));      icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);    }  break;   case  ICMP6_UNREACH : {      // icmp6_type ==11       icmp_length = payload_length-sizeof(click_icmp6_unreach)+sizeof(click_icmp_unreach);      click_icmp6_unreach *icmp6 = (click_icmp6_unreach *)a;      ip6 = (click_ip6 *)(icmp6+1);      q2 = Packet::make(icmp_length);      memset(q2->data(), '\0', q2->length());      click_icmp_unreach *icmp = (click_icmp_unreach *)q2->data();      ip = (unsigned char *)(icmp+1);      icmp->icmp_type = ICMP_UNREACH;             // icmp_type =3             switch (icmp6_code) {      case 0: icmp->icmp_code =0;  break;      case 1: icmp->icmp_code =10; break;      case 2: icmp->icmp_code =5;  break;      case 3: icmp->icmp_code =1;  break;      case 4: icmp->icmp_code =3;  break;      default: ; break;      }      memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_unreach)));      icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);        }  break;    case ICMP6_PKTTOOBIG : {      icmp_length = payload_length-sizeof(click_icmp6_pkttoobig)+sizeof(click_icmp_unreach);      click_icmp6_pkttoobig *icmp6 = (click_icmp6_pkttoobig*)a;      ip6 = (click_ip6 *)(icmp6+1);      q2 = Packet::make(icmp_length);      memset(q2->data(), '\0', q2->length());      click_icmp_unreach *icmp = (click_icmp_unreach *)q2->data();      ip = (unsigned char *)(icmp+1);      icmp->icmp_type = ICMP_UNREACH; //icmp_type = 3      icmp->icmp_code = 4;      memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_pkttoobig)));      icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);    }  break;    case ICMP6_TIMXCEED : {       icmp_length = payload_length-sizeof(click_icmp6_timxceed)+sizeof(click_icmp_timxceed);      click_icmp6_timxceed *icmp6 = (click_icmp6_timxceed *)a;      ip6 = (click_ip6 *)(icmp6+1);      q2 = Packet::make(icmp_length);      memset(q2->data(), '\0', q2->length());      click_icmp_timxceed *icmp = (click_icmp_timxceed *)q2->data();      ip = (unsigned char *)(icmp+1);      icmp->icmp_type =ICMP_TIMXCEED;            //icmp_type = 11       icmp->icmp_code = icmp6_code;      memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_timxceed)));      icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);    }  break;    case ICMP6_PARAMPROB : { // icmp6_type == 4            click_icmp6_paramprob *icmp6 = (click_icmp6_paramprob *)a;      ip6=(click_ip6 *)(icmp6+1);      if (icmp6_code ==2 || icmp6_code ==0) 	{	  icmp_length = payload_length-sizeof(click_icmp6_paramprob)+sizeof(click_icmp_paramprob);	  q2 = Packet::make(icmp_length);	  memset(q2->data(), '\0', q2->length());	  click_icmp_paramprob *icmp = (click_icmp_paramprob *)q2->data();	  ip = (unsigned char *)(icmp +1);	  icmp->icmp_type = ICMP_PARAMPROB;         // icmp_type = 12 	  icmp->icmp_code = 0;	  if (icmp6_code ==2) {	    icmp->icmp_pointer = -1;	  }	  else if(icmp6_code ==0)	    {	      switch (ntohl(icmp6->icmp6_pointer)) {	      case 0 : icmp->icmp_pointer = 0;  break;	      case 4 : icmp->icmp_pointer = 2;  break;	      case 7 : icmp->icmp_pointer = 8;  break;	      case 6 : icmp->icmp_pointer = 9;  break;	      case 8 : icmp->icmp_pointer = 12; break;	      case 24: icmp->icmp_pointer = -1; break;	      default: ; break; 	      }	      	    }	  memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_paramprob)));	  icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);	}      else if (icmp6_code ==1) 	{	  icmp_length = payload_length-sizeof(click_icmp6_paramprob)+sizeof(click_icmp_unreach);	  q2 = Packet::make(icmp_length);	  memset(q2->data(), '\0', q2->length());	  click_icmp_unreach *icmp = (click_icmp_unreach *)q2->data();      	  ip = (unsigned char *)(icmp +1);	  icmp->icmp_type = ICMP_UNREACH; // icmp_type = 3 	  icmp->icmp_code = 2;	  memcpy(ip, ip6, (payload_length - sizeof(click_icmp6_paramprob)));	  icmp->icmp_cksum = click_in_cksum((unsigned char *)icmp, icmp_length);	}  }  break;    default: ; break;  }  return q2;}voidProtocolTranslator64::push(int, Packet *p){  handle_ip6(p);}void ProtocolTranslator64::handle_ip6(Packet *p){  click_ip6 *ip6 = (click_ip6 *) p->data();  IP6Address ip6_dst = IP6Address(ip6->ip6_dst);  IP6Address ip6_src = IP6Address(ip6->ip6_src);  IPAddress ipa_dst, ipa_src;  if (ip6_dst.ip4_address(ipa_dst) && ip6_src.ip4_address(ipa_src))    {              //translate protocol according to SIIT       unsigned char * start_of_p= (unsigned char *)(ip6+1);       Packet *q = 0;       q = make_translate64(ipa_src, ipa_dst, ip6, start_of_p);        //see if it is an icmp6 packet, if it is, translate the icmp6 packet        if (ip6->ip6_nxt == 0x3a) 	 {	   click_ip * ip4= (click_ip *)q->data();	   unsigned char * icmp6 = (unsigned char *)(ip4+1);	  	   Packet *q2 = 0;	   q2 = make_icmp_translate64(icmp6, (q->length()-sizeof(click_ip)));	   WritablePacket *q3=Packet::make(sizeof(click_ip)+q2->length());	   memset(q3->data(), '\0', q3->length());	   click_ip *ip = (click_ip *)q3->data();	   memcpy(ip, q->data(), sizeof(click_ip));	   unsigned char *start_of_icmp = (unsigned char *)(ip+1);	   memcpy(start_of_icmp, q2->data(), q2->length()); 	   ip->ip_len = htons(q3->length());	   ip->ip_sum=0;	   ip->ip_sum = click_in_cksum((unsigned char *)ip, q3->length());	   p->kill();	   q->kill();	   q2->kill();	   output(0).push(q3);	 }       else 	 {	   p->kill();	   output(0).push(q);	 }    }  else    {      p->kill();      return;    }} CLICK_ENDDECLSEXPORT_ELEMENT(ProtocolTranslator64)

⌨️ 快捷键说明

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