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

📄 ipoutputcombo.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * ipoutputcombo.{cc,hh} -- IP router output combination element * Eddie Kohler * * Copyright (c) 1999-2000 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 "ipoutputcombo.hh"#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <click/packet_anno.hh>CLICK_DECLSIPOutputCombo::IPOutputCombo()  : Element(1, 5){}IPOutputCombo::~IPOutputCombo(){}intIPOutputCombo::configure(Vector<String> &conf, ErrorHandler *errh){  if (cp_va_parse(conf, this, errh,		  cpUnsigned, "color (PaintTee)", &_color,		  cpIPAddress, "dest IP address", &_my_ip,		  cpUnsigned, "MTU (IPFragmenter)", &_mtu,		  cpEnd) < 0)    return -1;  return 0;}voidIPOutputCombo::push(int, Packet *p_in){  int do_cksum = 0;  int problem_offset = -1;  // DropBroadcasts  if (p_in->packet_type_anno() == Packet::BROADCAST || p_in->packet_type_anno() == Packet::MULTICAST) {    p_in->kill();    return;  }    // PaintTee  if (PAINT_ANNO(p_in) == _color)    output(1).push(p_in->clone());    // IPGWOptions  WritablePacket *p = p_in->uniqueify();  click_ip *ip = p->ip_header();  assert(ip);  unsigned hlen = (ip->ip_hl << 2);  if (hlen > sizeof(click_ip)) {    uint8_t *woa = p->network_header();    int hlen = p->network_header_length();    int oi;    for (oi = sizeof(click_ip); oi < hlen; ) {      // handle one-byte options      unsigned type = woa[oi];      if (type == IPOPT_NOP) {	oi++;	continue;      } else if (type == IPOPT_EOL)	/* end of option list */	break;      // otherwise, get option length      int xlen = woa[oi + 1];      if (xlen < 2 || oi + xlen > hlen) {	// bad length	problem_offset = oi + 1; // to point at length	goto ipgw_send_error;      } else if (type != IPOPT_RR && type != IPOPT_TS) {	// not for us to process	oi += xlen;	continue;      }      // have a writable packet already          if(type == IPOPT_RR){	/*	 * Record Route.	 * Apparently the pointer (oa[oi+2]) is 1-origin.	 */	int p = woa[oi+2] - 1;	if (p >= 3 && p + 4 <= xlen) {	  memcpy(woa + oi + p, &_my_ip, 4);	  woa[oi+2] += 4;	  do_cksum = 1;	} else if (p != xlen) {	  problem_offset = oi + 2;	  goto ipgw_send_error;	}      } else if(type == IPOPT_TS){	/*	 * Timestamp Option.	 * We can't do a good job with the pre-specified mode (flg=3),	 * since we don't know all our i/f addresses.	 */	int p = woa[oi+2] - 1;	int oflw = woa[oi+3] >> 4;	int flg = woa[oi+3] & 0xf;	bool overflowed = 0;	Timestamp now = Timestamp::now();	int ms = htonl((now.sec() % 86400)*1000 + now.msec());	if(p < 4){	  problem_offset = oi + 2;	  goto ipgw_send_error;	} else if(flg == 0){	  /* 32-bit timestamps only */	  if(p+4 <= xlen){	    memcpy(woa + oi + p, &ms, 4);	    woa[oi+2] += 4;	    do_cksum = 1;	  } else	    overflowed = 1;	} else if(flg == 1){	  /* ip address followed by timestamp */	  if(p+8 <= xlen){	    memcpy(woa + oi + p, &_my_ip, 4);	    memcpy(woa + oi + p + 4, &ms, 4);	    woa[oi+2] += 8;	    do_cksum = 1;	  } else	    overflowed = 1;	} else if (flg == 3 && p + 8 <= xlen) {	  /* only if it's my address */	  if (memcmp(woa + oi + p, &_my_ip, 4) == 0) {	    memcpy(woa + oi + p + 4, &ms, 4);	    woa[oi+2] += 8;	    do_cksum = 1;	  }	} else {	  problem_offset = oi + 3;	  goto ipgw_send_error;	}	if (overflowed) {	  if (oflw < 15) {	    woa[oi+3] = ((oflw + 1) << 4) | flg;	    do_cksum = 1;	  } else {	    problem_offset = oi + 3;	    goto ipgw_send_error;	  }	}      }            oi += xlen;    }  }  // FixIPSrc  if (FIX_IP_SRC_ANNO(p)) {    SET_FIX_IP_SRC_ANNO(p, 0);    ip->ip_src = _my_ip;    do_cksum = 1;  }    // IPGWOptions / FixIPSrc  if (do_cksum) {    ip->ip_sum = 0;    ip->ip_sum = click_in_cksum(p->data(), hlen);  }  // DecIPTTL  if (ip->ip_ttl <= 1) {    output(3).push(p);    return;  } else {    ip->ip_ttl--;    // 19.Aug.1999 - incrementally update IP checksum as suggested by SOSP    // reviewers, according to RFC1141 and RFC1624    unsigned long sum = (~ntohs(ip->ip_sum) & 0xFFFF) + 0xFEFF;    ip->ip_sum = ~htons(sum + (sum >> 16));  }  // Fragmenter  if (p->length() > _mtu) {    output(4).push(p);		// expect a Fragmenter there    return;  }  output(0).push(p);  return; ipgw_send_error:  SET_ICMP_PARAMPROB_ANNO(p, problem_offset);  output(2).push(p);}CLICK_ENDDECLSEXPORT_ELEMENT(IPOutputCombo)ELEMENT_MT_SAFE(IPOutputCombo)

⌨️ 快捷键说明

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