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

📄 ipsumdump_payload.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * ipsumdump_payload.{cc,hh} -- IP network layer IP summary dump unparsers * Eddie Kohler * * Copyright (c) 2002 International Computer Science Institute * Copyright (c) 2004-2008 Regents of the University of California * * 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 "ipsumdump_payload.hh"#include <click/packet.hh>#include <click/packet_anno.hh>#include <click/md5.h>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>#include <click/confparse.hh>#include <click/ipflowid.hh>CLICK_DECLSnamespace IPSummaryDump {enum { T_PAYLOAD_LEN, T_PAYLOAD, T_PAYLOAD_MD5, T_PAYLOAD_MD5_HEX };static void payload_info(Packet *p, const click_ip *iph,			 int32_t &off, uint32_t &len){    if (iph) {	len = ntohs(iph->ip_len);	off = p->transport_header_offset();	uint32_t nlen = len + p->network_header_offset();	if (IP_FIRSTFRAG(iph))	    switch (iph->ip_p) {	    case IP_PROTO_TCP:		if (p->transport_length() >= 13		    && ((uint32_t) off + (p->tcp_header()->th_off << 2) <= nlen			|| len == 0))		    off += (p->tcp_header()->th_off << 2);		break;	    case IP_PROTO_UDP:	    case IP_PROTO_UDPLITE:		if (off + sizeof(click_udp) <= nlen || len == 0)		    off += sizeof(click_udp);		break;	    }	len -= off - p->network_header_offset();    } else {	off = 0;	len = p->length();    }}static bool payload_extract(PacketDesc &d, const FieldWriter *f){    switch (f->user_data) {    case T_PAYLOAD_LEN: {	int32_t off;	payload_info(d.p, d.iph, off, d.v);	if (!d.iph || d.force_extra_length)	    d.v += EXTRA_LENGTH_ANNO(d.p);	return true;    }    case T_PAYLOAD:    case T_PAYLOAD_MD5:    case T_PAYLOAD_MD5_HEX:	return true;      default:	return false;    }}static void account_payload_len(PacketOdesc &d, int32_t &off, uint32_t plen){    if (!d.is_ip || (d.p->ip_header()->ip_len == 0 && d.want_len == 0))	d.want_len = off + plen;    else {	click_ip *iph = d.p->ip_header();	uint32_t ip_len = (iph->ip_len ? ntohs(iph->ip_len) : d.want_len)	    + d.p->network_header_offset();	if (ip_len > off + plen) {	    int delta = ip_len - (off + plen);	    click_tcp *tcph = d.p->tcp_header();	    if (IP_FIRSTFRAG(iph) && iph->ip_p == IP_PROTO_TCP		&& tcph->th_off == (sizeof(click_tcp) >> 2)) {		int th_delta = delta - (delta & 3);		if (th_delta + sizeof(click_tcp) > (15 << 2))		    th_delta = (15 << 2) - sizeof(click_tcp);		if (!(d.p = d.p->put(th_delta)))		    return;		iph = d.p->ip_header(); // may have shifted		unsigned char *tx = d.p->transport_header() + sizeof(click_tcp);		memmove(tx + th_delta, tx, d.p->end_data() - (tx + th_delta));		memset(tx, TCPOPT_EOL, th_delta);		d.p->tcp_header()->th_off = (sizeof(click_tcp) + th_delta) >> 2;		delta -= th_delta;	    }	    if (iph->ip_hl == (sizeof(click_ip) >> 2) && delta > 0) {		int ip_delta = delta - (delta & 3);		if (ip_delta + sizeof(click_ip) > (15 << 2))		    ip_delta = (15 << 2) - sizeof(click_ip);		if (!(d.p = d.p->put(ip_delta)))		    return;		iph = d.p->ip_header(); // may have shifted		unsigned char *nx = d.p->network_header() + sizeof(click_ip);		memmove(nx + ip_delta, nx, d.p->end_data() - (nx + ip_delta));		memset(nx, IPOPT_EOL, ip_delta);		iph->ip_hl = (sizeof(click_ip) + ip_delta) >> 2;		d.p->set_ip_header(iph, sizeof(click_ip) + ip_delta);	    }	}    }}static void payload_inject(PacketOdesc &d, const FieldReader *f){    if (d.make_ip(0))		// add default IPFlowID and protocol if nec.	d.make_transp();	// don't care if we fail    if (!d.p)	return;    int32_t off;    uint32_t len;    payload_info(d.p, d.is_ip ? d.p->ip_header() : 0, off, len);    switch (f->user_data) {    case T_PAYLOAD: {	if (!d.vptr[0] || d.vptr[0] == d.vptr[1])	    return;	uint32_t plen = d.vptr[1] - d.vptr[0];	account_payload_len(d, off, plen);	if (!d.p || (d.p->length() - off < plen		     && !(d.p = d.p->put(plen - (d.p->length() - off)))))	    return;	memcpy(d.p->data() + off, d.vptr[0], plen);	break;    }    case T_PAYLOAD_LEN:	account_payload_len(d, off, d.v);	break;    }}static void payload_outa(const PacketDesc& d, const FieldWriter *f){    switch (f->user_data) {    case T_PAYLOAD:    case T_PAYLOAD_MD5:    case T_PAYLOAD_MD5_HEX: {	int32_t off;	uint32_t len;	payload_info(d.p, d.iph, off, len);	if (off + len > (uint32_t) d.p->length())	    len = d.p->length() - off;	if (f->user_data == T_PAYLOAD) {	    String s = String::make_stable((const char *)(d.p->data() + off), len);	    *d.sa << cp_quote(s);	} else {	    md5_state_t pms;	    md5_init(&pms);	    md5_append(&pms, (const md5_byte_t *) (d.p->data() + off), len);	    if (f->user_data == T_PAYLOAD_MD5_HEX) {		if (char *buf = d.sa->extend(MD5_DIGEST_SIZE * 2)) {		    md5_finish(&pms, (md5_byte_t *) buf);		    const char digits[] = "0123456789abcdef";		    for (int i = MD5_DIGEST_SIZE - 1; i >= 0; --i) {			int b = (unsigned char) buf[i];			buf[2*i + 1] = digits[b & 15];			buf[2*i] = digits[b >> 4];		    }		}	    } else {		if (char *buf = d.sa->extend(MD5_TEXT_DIGEST_SIZE))		    md5_finish_text(&pms, buf, 1);	    }	    md5_free(&pms);	}	break;    }    }}static bool payload_ina(PacketOdesc& d, const String &str, const FieldReader *f){    switch (f->user_data) {    case T_PAYLOAD: {	String s;	if (cp_string(str, &s)) {	    d.sa.clear();	    d.sa << s;	    d.vptr[0] = (const uint8_t *) d.sa.begin();	    d.vptr[1] = (const uint8_t *) d.sa.end();	    return true;	}	break;    }    }    return false;}static void payload_outb(const PacketDesc& d, bool, const FieldWriter *f){    switch (f->user_data) {    case T_PAYLOAD_MD5:    case T_PAYLOAD_MD5_HEX: {	int32_t off;	uint32_t len;	payload_info(d.p, d.iph, off, len);	if (off + len > (uint32_t) d.p->length())	    len = d.p->length() - off;	md5_state_t pms;	md5_init(&pms);	md5_append(&pms, (const md5_byte_t *) (d.p->data() + off), len);	if (char *buf = d.sa->extend(MD5_DIGEST_SIZE))	    md5_finish(&pms, (md5_byte_t *) buf);	md5_free(&pms);	break;    }    }}static const FieldWriter payload_writers[] = {    { "payload_len", B_4, T_PAYLOAD_LEN,      ip_prepare, payload_extract, num_outa, outb },    { "payload", B_NOTALLOWED, T_PAYLOAD,      ip_prepare, payload_extract, payload_outa, 0 },    { "payload_md5", B_16, T_PAYLOAD_MD5,      ip_prepare, payload_extract, payload_outa, payload_outb },    { "payload_md5_hex", B_16, T_PAYLOAD_MD5_HEX,      ip_prepare, payload_extract, payload_outa, payload_outb }};static const FieldReader payload_readers[] = {    { "payload_len", B_4, T_PAYLOAD_LEN, order_payload + 1,      num_ina, inb, payload_inject },    { "payload", B_NOTALLOWED, T_PAYLOAD, order_payload,      payload_ina, 0, payload_inject }};static const FieldSynonym payload_synonyms[] = {    { "payload_length", "payload_len" }};}void IPSummaryDump_Payload::static_initialize(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(payload_writers) / sizeof(payload_writers[0]); ++i)	FieldWriter::add(&payload_writers[i]);    for (size_t i = 0; i < sizeof(payload_readers) / sizeof(payload_readers[0]); ++i)	FieldReader::add(&payload_readers[i]);    for (size_t i = 0; i < sizeof(payload_synonyms) / sizeof(payload_synonyms[0]); ++i)	FieldSynonym::add(&payload_synonyms[i]);}void IPSummaryDump_Payload::static_cleanup(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(payload_writers) / sizeof(payload_writers[0]); ++i)	FieldWriter::remove(&payload_writers[i]);    for (size_t i = 0; i < sizeof(payload_readers) / sizeof(payload_readers[0]); ++i)	FieldReader::remove(&payload_readers[i]);    for (size_t i = 0; i < sizeof(payload_synonyms) / sizeof(payload_synonyms[0]); ++i)	FieldSynonym::remove(&payload_synonyms[i]);}ELEMENT_REQUIRES(userlevel IPSummaryDump)ELEMENT_PROVIDES(IPSummaryDump_Payload)CLICK_ENDDECLS

⌨️ 快捷键说明

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