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

📄 ipsumdump_icmp.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_icmp.{cc,hh} -- IP transport summary dump unparsers * Eddie Kohler * * Copyright (c) 2002 International Computer Science Institute * Copyright (c) 2004 Regents of the University of California * Copyright (c) 2008 Meraki, Inc. * * 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_icmp.hh"#include <click/packet.hh>#include <click/nameinfo.hh>#include <clicknet/ip.h>#include <clicknet/icmp.h>#include <click/confparse.hh>CLICK_DECLSnamespace IPSummaryDump {enum { T_ICMP_TYPE, T_ICMP_TYPE_NAME, T_ICMP_CODE, T_ICMP_CODE_NAME,       T_ICMP_FLOWID, T_ICMP_SEQ, T_ICMP_NEXTMTU };enum {    ICMP_TYPE_HAVE_FLOW = ((1U << ICMP_ECHO) | (1U << ICMP_ECHOREPLY)			   | (1U << ICMP_IREQ) | (1U << ICMP_IREQREPLY)			   | (1U << ICMP_TSTAMP) | (1U << ICMP_TSTAMPREPLY))};static bool icmp_extract(PacketDesc& d, const FieldWriter *f){    int transport_length = d.p->transport_length();    switch (f->user_data) {#define CHECK(l) do { if (!d.icmph || transport_length < (l)) return field_missing(d, IP_PROTO_ICMP, (l)); } while (0)      case T_ICMP_TYPE:      case T_ICMP_TYPE_NAME:	CHECK(1);	d.v = d.icmph->icmp_type;	return true;      case T_ICMP_CODE:      case T_ICMP_CODE_NAME:	CHECK(2);	d.v = d.icmph->icmp_code;	return true;      case T_ICMP_FLOWID:	CHECK(1);	if (d.icmph->icmp_type >= 32	    || (ICMP_TYPE_HAVE_FLOW & (1 << d.icmph->icmp_type)) == 0)	    return false;	CHECK(6);	d.v = ntohs(reinterpret_cast<const click_icmp_sequenced *>(d.icmph)->icmp_identifier);	return true;      case T_ICMP_SEQ:	CHECK(1);	if (d.icmph->icmp_type >= 32	    || (ICMP_TYPE_HAVE_FLOW & (1 << d.icmph->icmp_type)) == 0)	    return false;	CHECK(8);	d.v = ntohs(reinterpret_cast<const click_icmp_sequenced *>(d.icmph)->icmp_sequence);	return true;      case T_ICMP_NEXTMTU:	CHECK(2);	if (d.icmph->icmp_type != ICMP_UNREACH	    || d.icmph->icmp_code != ICMP_UNREACH_NEEDFRAG)	    return false;	CHECK(8);	d.v = ntohs(reinterpret_cast<const click_icmp_needfrag *>(d.icmph)->icmp_nextmtu);	return true;#undef CHECK      default:	return false;    }}static void icmp_inject(PacketOdesc& d, const FieldReader *f){    if (!d.make_ip(IP_PROTO_ICMP) || !d.make_transp())	return;    if (d.p->transport_length() < (int) sizeof(click_icmp)	&& !(d.p = d.p->put(sizeof(click_icmp) - d.p->transport_length())))	return;    click_icmp *icmph = d.p->icmp_header();    switch (f->user_data) {    case T_ICMP_TYPE:    case T_ICMP_TYPE_NAME: {	icmph->icmp_type = d.v;	d.have_icmp_type = true;	int len = click_icmp_hl(d.v);	if (d.p->transport_length() < len	    && !(d.p = d.p->put(len - d.p->transport_length())))	    return;	break;    }    case T_ICMP_CODE:    case T_ICMP_CODE_NAME:	icmph->icmp_code = d.v;	d.have_icmp_code = true;	break;    case T_ICMP_FLOWID:	if (!d.have_icmp_type	    || (icmph->icmp_type < 32		&& (ICMP_TYPE_HAVE_FLOW & (1 << icmph->icmp_type)))) {	    if (d.p->transport_length() < (int) sizeof(click_icmp_sequenced)) {		if (!(d.p = d.p->put(sizeof(click_icmp_sequenced) - d.p->transport_length())))		    return;		icmph = d.p->icmp_header();	    }	    reinterpret_cast<click_icmp_sequenced *>(icmph)->icmp_identifier = htons(d.v);	}	break;    case T_ICMP_SEQ:	if (!d.have_icmp_type	    || (icmph->icmp_type < 32		&& (ICMP_TYPE_HAVE_FLOW & (1 << icmph->icmp_type)))) {	    if (d.p->transport_length() < (int) sizeof(click_icmp_sequenced)) {		if (!(d.p = d.p->put(sizeof(click_icmp_sequenced) - d.p->transport_length())))		    return;		icmph = d.p->icmp_header();	    }	    reinterpret_cast<click_icmp_sequenced *>(icmph)->icmp_sequence = htons(d.v);	}	break;    case T_ICMP_NEXTMTU:	if ((!d.have_icmp_type || icmph->icmp_type == ICMP_UNREACH)	    && (!d.have_icmp_code || icmph->icmp_code == ICMP_UNREACH_NEEDFRAG)) {	    if (d.p->transport_length() < (int) sizeof(click_icmp_needfrag)) {		if (!(d.p = d.p->put(sizeof(click_icmp_needfrag) - d.p->transport_length())))		    return;		icmph = d.p->icmp_header();	    }	    reinterpret_cast<click_icmp_needfrag *>(icmph)->icmp_nextmtu = htons(d.v);	}	break;    }}static void icmp_outa(const PacketDesc &d, const FieldWriter *f){    switch (f->user_data) {      case T_ICMP_TYPE_NAME:	if (String s = NameInfo::revquery_int(NameInfo::T_ICMP_TYPE, d.e, d.v))	    *d.sa << s;	else	    *d.sa << d.v;	break;      case T_ICMP_CODE_NAME:	if (String s = NameInfo::revquery_int(NameInfo::T_ICMP_CODE + d.icmph->icmp_type, d.e, d.v))	    *d.sa << s;	else	    *d.sa << d.v;	break;    }}static bool icmp_ina(PacketOdesc &d, const String &str, const FieldReader *f){    switch (f->user_data) {    case T_ICMP_TYPE:    case T_ICMP_TYPE_NAME:	if (NameInfo::query_int(NameInfo::T_ICMP_TYPE, d.e, str, &d.v)	    && d.v < 256)	    return true;	break;    case T_ICMP_CODE:    case T_ICMP_CODE_NAME:	if (d.have_icmp_type) {	    if (NameInfo::query_int(NameInfo::T_ICMP_CODE + d.p->icmp_header()->icmp_type, d.e, str, &d.v)		&& d.v < 256)		return true;	} else {	    if (cp_integer(str, &d.v) && d.v < 256)		return true;	}	break;    }    return false;}static const FieldWriter icmp_writers[] = {    { "icmp_type", B_1, T_ICMP_TYPE,      ip_prepare, icmp_extract, num_outa, outb },    { "icmp_code", B_1, T_ICMP_CODE,      ip_prepare, icmp_extract, num_outa, outb },    { "icmp_type_name", B_1, T_ICMP_TYPE_NAME,      ip_prepare, icmp_extract, icmp_outa, outb },    { "icmp_code_name", B_1, T_ICMP_CODE_NAME,      ip_prepare, icmp_extract, icmp_outa, outb },    { "icmp_flowid", B_2, T_ICMP_FLOWID,      ip_prepare, icmp_extract, num_outa, outb },    { "icmp_seq", B_2, T_ICMP_SEQ,      ip_prepare, icmp_extract, num_outa, outb },    { "icmp_nextmtu", B_2, T_ICMP_NEXTMTU,      ip_prepare, icmp_extract, num_outa, outb }};static const FieldReader icmp_readers[] = {    { "icmp_type", B_1, T_ICMP_TYPE, order_transp,      icmp_ina, inb, icmp_inject },    { "icmp_code", B_1, T_ICMP_CODE, order_transp + 1,      icmp_ina, inb, icmp_inject },    { "icmp_type_name", B_1, T_ICMP_TYPE_NAME, order_transp,      icmp_ina, inb, icmp_inject },    { "icmp_code_name", B_1, T_ICMP_CODE_NAME, order_transp + 1,      icmp_ina, inb, icmp_inject },    { "icmp_flowid", B_2, T_ICMP_FLOWID, order_transp + 2,      num_ina, inb, icmp_inject },    { "icmp_seq", B_2, T_ICMP_SEQ, order_transp + 2,      num_ina, inb, icmp_inject },    { "icmp_nextmtu", B_2, T_ICMP_NEXTMTU, order_transp + 2,      num_ina, inb, icmp_inject }};}void IPSummaryDump_ICMP::static_initialize(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(icmp_writers) / sizeof(icmp_writers[0]); ++i)	FieldWriter::add(&icmp_writers[i]);    for (size_t i = 0; i < sizeof(icmp_readers) / sizeof(icmp_readers[0]); ++i)	FieldReader::add(&icmp_readers[i]);}void IPSummaryDump_ICMP::static_cleanup(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(icmp_writers) / sizeof(icmp_writers[0]); ++i)	FieldWriter::remove(&icmp_writers[i]);    for (size_t i = 0; i < sizeof(icmp_readers) / sizeof(icmp_readers[0]); ++i)	FieldReader::remove(&icmp_readers[i]);}ELEMENT_REQUIRES(userlevel IPSummaryDump)ELEMENT_PROVIDES(IPSummaryDump_ICMP)CLICK_ENDDECLS

⌨️ 快捷键说明

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