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

📄 ipfragmenter.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
// -*- c-basic-offset: 4 -*-/* * ipfragmenter.{cc,hh} -- element fragments IP packets * Robert Morris, Eddie Kohler * * Copyright (c) 1999-2000 Massachusetts Institute of Technology * Copyright (c) 2002 International Computer Science Institute * * 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 "ipfragmenter.hh"#include <clicknet/ip.h>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>CLICK_DECLSIPFragmenter::IPFragmenter()    : Element(1, 1), _honor_df(true), _verbose(false), _mtu(0){    _fragments = 0;    _drops = 0;}IPFragmenter::~IPFragmenter(){}voidIPFragmenter::notify_noutputs(int n){    // allow 2 outputs -- then packet is pushed onto 2d output instead of    // dropped    set_noutputs(n < 2 ? 1 : 2);}intIPFragmenter::configure(Vector<String> &conf, ErrorHandler *errh){    if (cp_va_parse(conf, this, errh,		    cpUnsigned, "MTU", &_mtu,		    cpOptional,		    cpBool, "HONOR_DF", &_honor_df,		    cpKeywords,		    "HONOR_DF", cpBool, "honor DF bit?", &_honor_df,		    "VERBOSE", cpBool, "be verbose?", &_verbose,		    cpEnd) < 0)	return -1;    if (_mtu < 8)	return errh->error("MTU must be at least 8");    return 0;}intIPFragmenter::optcopy(const click_ip *ip1, click_ip *ip2){    int opts_len = (ip1->ip_hl << 2) - sizeof(click_ip);    u_char *oin = (u_char *) (ip1 + 1);    u_char *oout = (u_char *) (ip2 + 1);    int outpos = 0;    for (int i = 0; i < opts_len; ) {	int opt = oin[i], optlen;	if (opt == IPOPT_NOP)	    optlen = 1;	else if (opt == IPOPT_EOL || i == opts_len - 1		 || i + (optlen = oin[i+1]) > opts_len)	    break;	if (opt & 0x80) {	// copy the option	    if (ip2)		memcpy(oout + outpos, oin + i, optlen);	    outpos += optlen;	}    }    for (; (outpos & 3) != 0; outpos++)	if (ip2)	    oout[outpos] = IPOPT_EOL;    return outpos;}voidIPFragmenter::fragment(Packet *p_in){    const click_ip *ip_in = p_in->ip_header();    int hlen = ip_in->ip_hl << 2;    int first_dlen = (_mtu - hlen) & ~7;    int in_dlen = ntohs(ip_in->ip_len) - hlen;    if (((ip_in->ip_off & htons(IP_DF)) && _honor_df) || first_dlen < 8) {	if (_verbose || _drops < 5)	    click_chatter("IPFragmenter(%d) DF %s %s len=%d", _mtu, IPAddress(ip_in->ip_src).s().cc(), IPAddress(ip_in->ip_dst).s().cc(), p_in->length());	_drops++;	checked_output_push(1, p_in);	return;    }    // make sure we can modify the packet    WritablePacket *p = p_in->uniqueify();    if (!p)	return;    click_ip *ip = p->ip_header();    // output the first fragment    // If we're cheating the DF bit, we can't trust the ip_id; set to random.    if (ip->ip_off & htons(IP_DF)) {	ip->ip_id = random();	ip->ip_off &= ~htons(IP_DF);    }    bool had_mf = (ip->ip_off & htons(IP_MF)) != 0;    ip->ip_len = htons(hlen + first_dlen);    ip->ip_off |= htons(IP_MF);    ip->ip_sum = 0;    ip->ip_sum = click_in_cksum((const unsigned char *)ip, hlen);    Packet *first_fragment = p->clone();    first_fragment->take(p->length() - p->network_header_offset() - hlen - first_dlen);    output(0).push(first_fragment);    _fragments++;    // output the remaining fragments    int out_hlen = sizeof(click_ip) + optcopy(ip, 0);    for (int off = first_dlen; off < in_dlen; ) {	// prepare packet	int out_dlen = (_mtu - out_hlen) & ~7;	if (out_dlen + off > in_dlen)	    out_dlen = in_dlen - off;	WritablePacket *q = Packet::make(out_hlen + out_dlen);	if (q) {	    q->set_network_header(q->data(), out_hlen);	    click_ip *qip = q->ip_header();	    	    memcpy(qip, ip, sizeof(click_ip));	    optcopy(ip, qip);	    memcpy(q->transport_header(), p->transport_header() + off, out_dlen);	    qip->ip_hl = out_hlen >> 2;	    qip->ip_off = htons(ntohs(ip->ip_off) + (off >> 3));	    if (out_dlen + off >= in_dlen && !had_mf)		qip->ip_off &= ~htons(IP_MF);	    qip->ip_len = htons(out_hlen + out_dlen);	    qip->ip_sum = 0;	    qip->ip_sum = click_in_cksum((const unsigned char *)qip, out_hlen);	    q->copy_annotations(p);	    	    output(0).push(q);	    _fragments++;	}	off += out_dlen;    }        p->kill();}voidIPFragmenter::push(int, Packet *p){    if (p->length() - p->network_header_offset() <= _mtu)	output(0).push(p);    else	fragment(p);}static StringIPFragmenter_read_drops(Element *xf, void *){    IPFragmenter *f = (IPFragmenter *)xf;    return String(f->drops()) + "\n";}static StringIPFragmenter_read_fragments(Element *xf, void *){    IPFragmenter *f = (IPFragmenter *)xf;    return String(f->fragments()) + "\n";}voidIPFragmenter::add_handlers(){    add_read_handler("drops", IPFragmenter_read_drops, 0);    add_read_handler("fragments", IPFragmenter_read_fragments, 0);}CLICK_ENDDECLSEXPORT_ELEMENT(IPFragmenter)ELEMENT_MT_SAFE(IPFragmenter)

⌨️ 快捷键说明

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