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

📄 ipsumdump_ip.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- mode: c++; c-basic-offset: 4 -*-/* * ipsumdump_ip.{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_ip.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_DECLSenum { T_IP_SRC, T_IP_DST, T_IP_TOS, T_IP_TTL, T_IP_FRAG, T_IP_FRAGOFF,       T_IP_ID, T_IP_SUM, T_IP_PROTO, T_IP_OPT, T_IP_LEN, T_IP_CAPTURE_LEN,       T_SPORT, T_DPORT, T_IP_HL };namespace IPSummaryDump {static bool ip_extract(PacketDesc& d, const FieldWriter *f){    int network_length = d.p->network_length();    switch (f->user_data) {	// IP header properties#define CHECK(l) do { if (!d.iph || network_length < (l)) return field_missing(d, MISSING_IP, (l)); } while (0)      case T_IP_SRC:	CHECK(16);	d.v = d.iph->ip_src.s_addr;	return true;      case T_IP_DST:	CHECK(20);	d.v = d.iph->ip_dst.s_addr;	return true;      case T_IP_TOS:	CHECK(2);	d.v = d.iph->ip_tos;	return true;      case T_IP_TTL:	CHECK(9);	d.v = d.iph->ip_ttl;	return true;      case T_IP_FRAG:	CHECK(8);	if (IP_ISFRAG(d.iph))	    d.v = (IP_FIRSTFRAG(d.iph) ? 'F' : 'f');	else	    d.v = (d.iph->ip_off & htons(IP_DF) ? '!' : '.');	return true;      case T_IP_FRAGOFF:	CHECK(8);	d.v = ntohs(d.iph->ip_off);	return true;      case T_IP_ID:	CHECK(6);	d.v = ntohs(d.iph->ip_id);	return true;      case T_IP_SUM:	CHECK(12);	d.v = ntohs(d.iph->ip_sum);	return true;      case T_IP_PROTO:	CHECK(10);	d.v = d.iph->ip_p;	return true;      case T_IP_OPT:	if (!d.iph || (d.iph->ip_hl > 5 && network_length < (int)(d.iph->ip_hl << 2)))	    return field_missing(d, MISSING_IP, (d.iph ? d.iph->ip_hl << 2 : 20));	if (d.iph->ip_hl <= 5)	    d.vptr[0] = d.vptr[1] = 0;	else {	    d.vptr[0] = (const uint8_t *) (d.iph + 1);	    d.vptr[1] = d.vptr[0] + (d.iph->ip_hl << 2) - sizeof(click_ip);	}	return true;      case T_IP_LEN:	if (d.iph)	    d.v = ntohs(d.iph->ip_len);	else	    d.v = d.p->length();	if (d.force_extra_length)	    d.v += EXTRA_LENGTH_ANNO(d.p);	return true;      case T_IP_HL:	CHECK(1);	d.v = d.iph->ip_hl << 2;	return true;      case T_IP_CAPTURE_LEN: {	  uint32_t allow_len = (d.iph ? network_length : d.p->length());	  uint32_t len = (d.iph ? ntohs(d.iph->ip_len) : allow_len);	  d.v = (len < allow_len ? len : allow_len);	  return true;      }#undef CHECK      default:	return false;    }}static inline bool ip_proto_has_udp_ports(int ip_p){    return ip_p == IP_PROTO_TCP || ip_p == IP_PROTO_UDP	|| ip_p == IP_PROTO_DCCP || ip_p == IP_PROTO_UDPLITE;}static void ip_inject(PacketOdesc& d, const FieldReader *f){    if (!d.make_ip(0))	return;    click_ip *iph = d.p->ip_header();    switch (f->user_data) {	// IP header properties    case T_IP_SRC:	iph->ip_src.s_addr = d.v;	break;    case T_IP_DST:	iph->ip_dst.s_addr = d.v;	break;    case T_IP_TOS:	iph->ip_tos = d.v;	break;    case T_IP_TTL:	iph->ip_ttl = d.v;	break;    case T_IP_FRAG:    case T_IP_FRAGOFF:	iph->ip_off = htons(d.v);	break;    case T_IP_ID:	iph->ip_id = htons(d.v);	break;    case T_IP_SUM:	iph->ip_sum = htons(d.v);	break;    case T_IP_PROTO:	iph->ip_p = d.v;	break;    case T_IP_OPT: {	if (!d.vptr[0])	    return;	int olen = d.vptr[1] - d.vptr[0];	int ip_hl = (sizeof(click_ip) + olen + 3) & ~3;	if (d.p->network_length() < ip_hl) {	    if (!(d.p = d.p->put(ip_hl - d.p->network_length())))		return;	    iph = d.p->ip_header();	}	if (ip_hl > (int) (iph->ip_hl << 2)) {	    d.p->set_ip_header(iph, ip_hl);	    iph->ip_hl = ip_hl >> 2;	}	memcpy(d.p->network_header() + sizeof(click_ip), d.vptr[0], olen);	memset(d.p->network_header() + sizeof(click_ip) + olen,	       IPOPT_EOL, ip_hl - olen);	break;    }#if 0    case T_IP_CAPTURE_LEN: {	uint32_t allow_len = (iph ? network_length : d.p->length());	uint32_t len = (iph ? ntohs(iph->ip_len) : allow_len);	d.v = (len < allow_len ? len : allow_len);	break;    }#endif    case T_IP_HL:	d.v = (d.v + 3) & ~3;	if ((int) d.v > (int) (iph->ip_hl << 2)) {	    int more = d.v - (iph->ip_hl << 2);	    if (!(d.p = d.p->put(more)))		return;	    iph = d.p->ip_header();	    d.p->set_ip_header(iph, d.v);	    memset(d.p->transport_header() - more, IPOPT_EOL, more);	}	iph->ip_hl = d.v >> 2;	break;    case T_IP_LEN:	d.want_len = d.p->network_header_offset() + d.v;	break;    }}static void ip_outa(const PacketDesc& d, const FieldWriter *f){    switch (f->user_data) {      case T_IP_SRC:      case T_IP_DST:	*d.sa << IPAddress(d.v);	break;      case T_IP_FRAG:	*d.sa << (char) d.v;	break;      case T_IP_FRAGOFF:	*d.sa << ((d.v & IP_OFFMASK) << 3);	if (d.v & IP_MF)	    *d.sa << '+';	if (d.v & IP_DF)	    *d.sa << '!';	break;      case T_IP_PROTO:	switch (d.v) {	  case IP_PROTO_TCP:	*d.sa << 'T'; break;	  case IP_PROTO_UDP:	*d.sa << 'U'; break;	  case IP_PROTO_ICMP:	*d.sa << 'I'; break;	  default:		*d.sa << d.v; break;	}	break;      case T_IP_OPT:	if (!d.vptr[0])	    *d.sa << '.';	else	    unparse_ip_opt(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_IPOPT_ALL_NOPAD);	break;    }}static bool ip_ina(PacketOdesc& d, const String &s, const FieldReader *f){    switch (f->user_data) {    case T_IP_SRC:    case T_IP_DST: {	IPAddress a;	if (cp_ip_address(s, &a, d.e)) {	    d.v = a.addr();	    return true;	}	break;    }    case T_IP_FRAG:    case T_IP_FRAGOFF: {	if (s.length() == 1) {	    if (s[0] == '.') {		d.v = 0;		return true;	    } else if (s[0] == '!') {		d.v = IP_DF;		return true;	    } else if (s[0] == 'F') {		d.v = IP_MF;		return true;	    } else if (s[0] == 'f') {		d.v = 100;	// arbitrary nonzero offset		return true;	    }	}	d.v = 0;	const char *new_end = cp_integer(s.begin(), s.end(), 0, &d.v);	if (d.minor_version > 0)	    d.v >>= 3;	for (; new_end != s.end(); ++new_end)	    if (*new_end == '!')		d.v |= IP_DF;	    else if (*new_end == '+')		d.v |= IP_MF;	    else		break;	if (new_end == s.end() && s.length())	    return true;	break;    }    case T_IP_PROTO:	if (s.equals("T", 1)) {	    d.v = IP_PROTO_TCP;	    return true;	} else if (s.equals("U", 1)) {	    d.v = IP_PROTO_UDP;	    return true;	} else if (s.equals("I", 1)) {	    d.v = IP_PROTO_ICMP;	    return true;	} else if (cp_integer(s, &d.v) && d.v < 256)	    return true;	break;#if 0      case T_IP_OPT:	if (!d.vptr[0])	    *d.sa << '.';	else	    unparse_ip_opt(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_IPOPT_ALL_NOPAD);	break;#endif    }    return false;}static void ip_outb(const PacketDesc& d, bool ok, const FieldWriter *f){    if (f->user_data == T_IP_OPT) {	if (!ok || !d.vptr)	    *d.sa << '\0';	else	    unparse_ip_opt_binary(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_IPOPT_ALL);    }}static const uint8_t* ip_inb(PacketOdesc& d, const uint8_t *s, const uint8_t *ends, const FieldReader *f){    if (f->user_data == T_IP_OPT && s + s[0] + 1 <= ends) {	d.vptr[0] = s + 1;	d.vptr[1] = d.vptr[0] + s[0];	return s + s[0] + 1;    } else	return ends;}static bool transport_extract(PacketDesc& d, const FieldWriter *f){    Packet* p = d.p;    switch (f->user_data) {	// TCP/UDP header properties    case T_SPORT:    case T_DPORT: {	bool dport = (f->user_data == T_DPORT);	if (d.iph	    && p->network_length() > (int)(d.iph->ip_hl << 2)	    && IP_FIRSTFRAG(d.iph)	    && ip_proto_has_udp_ports(d.iph->ip_p)	    && p->transport_length() >= (dport ? 4 : 2)) {	    const click_udp *udph = p->udp_header();	    d.v = ntohs(dport ? udph->uh_dport : udph->uh_sport);	    return true;	}	return field_missing(d, IP_PROTO_TCP_OR_UDP, dport ? 4 : 2);    }    }    return false;}static void transport_inject(PacketOdesc& d, const FieldReader *f){    if (!d.make_ip(0) || !d.make_transp())	return;    click_ip *iph = d.p->ip_header();    if (iph->ip_p && !ip_proto_has_udp_ports(iph->ip_p))	return;    switch (f->user_data) {	// TCP/UDP header properties    case T_SPORT:	d.p->udp_header()->uh_sport = htons(d.v);	break;    case T_DPORT:	d.p->udp_header()->uh_dport = htons(d.v);	break;    }}#define U DO_IPOPT_UNKNOWNstatic int ip_opt_mask_mapping[] = {    DO_IPOPT_PADDING, DO_IPOPT_PADDING,		// EOL, NOP    U, U, U, U,	U,				// 2, 3, 4, 5, 6    DO_IPOPT_ROUTE,				// RR    U, U, U, U, U, U, U, U, U, U, U, U, U,	// 8-20    U, U, U, U, U, U, U, U, U, U,		// 21-30    U, U, U, U, U, U, U, U, U, U,		// 31-40    U, U, U, U, U, U, U, U, U, U,		// 41-50    U, U, U, U, U, U, U, U, U, U,		// 51-60    U, U, U, U, U, U, U,			// 61-67    DO_IPOPT_TS, U, U,				// TS, 69-70    U, U, U, U, U, U, U, U, U, U,		// 71-80    U, U, U, U, U, U, U, U, U, U,		// 81-90    U, U, U, U, U, U, U, U, U, U,		// 91-100    U, U, U, U, U, U, U, U, U, U,		// 101-110    U, U, U, U, U, U, U, U, U, U,		// 111-120    U, U, U, U, U, U, U, U, U,			// 121-129    DO_IPOPT_UNKNOWN, DO_IPOPT_ROUTE,		// SECURITY, LSRR    U, U, U, U,					// 132-135    DO_IPOPT_UNKNOWN, DO_IPOPT_ROUTE,		// SATID, SSRR    U, U, U,					// 138-140    U, U, U, U, U, U, U,			// 141-147    DO_IPOPT_UNKNOWN				// RA};#undef Uvoid unparse_ip_opt(StringAccum& sa, const uint8_t* opt, int opt_len, int mask){    int initial_sa_len = sa.length();    const uint8_t *end_opt = opt + opt_len;    const char *sep = "";    while (opt < end_opt)	switch (*opt) {	  case IPOPT_EOL:	    if (mask & DO_IPOPT_PADDING)		sa << sep << "eol";	    goto done;	  case IPOPT_NOP:	    if (mask & DO_IPOPT_PADDING) {		sa << sep << "nop";		sep = ";";	    }	    opt++;	    break;	  case IPOPT_RR:	    if (opt + opt[1] > end_opt || opt[1] < 3 || opt[2] < 4)		goto bad_opt;	    if (!(mask & DO_IPOPT_ROUTE))		goto unknown;	    sa << sep << "rr";	    goto print_route;	  case IPOPT_LSRR:	    if (opt + opt[1] > end_opt || opt[1] < 3 || opt[2] < 4)		goto bad_opt;	    if (!(mask & DO_IPOPT_ROUTE))		goto unknown;	    sa << sep << "lsrr";	    goto print_route;	  case IPOPT_SSRR:	    if (opt + opt[1] > end_opt || opt[1] < 3 || opt[2] < 4)		goto bad_opt;	    if (!(mask & DO_IPOPT_ROUTE))		goto unknown;	    sa << sep << "ssrr";	    goto print_route;	  print_route: {		const uint8_t *o = opt + 3, *ol = opt + opt[1], *op = opt + opt[2] - 1;		sep = "";		sa << '{';		for (; o + 4 <= ol; o += 4) {		    if (o == op) {			if (opt[0] == IPOPT_RR)			    break;			sep = "^";		    }		    sa << sep << (int)o[0] << '.' << (int)o[1] << '.' << (int)o[2] << '.' << (int)o[3];		    sep = ",";		}		if (o == ol && o == op && opt[0] != IPOPT_RR)		    sa << '^';		sa << '}';		if (o + 4 <= ol && o == op && opt[0] == IPOPT_RR)		    sa << '+' << (ol - o) / 4;		opt = ol;

⌨️ 快捷键说明

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