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

📄 ipsumdump_tcp.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_tcp.{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_tcp.hh"#include <click/packet.hh>#include <click/nameinfo.hh>#include <clicknet/ip.h>#include <clicknet/tcp.h>#include <clicknet/udp.h>#include <clicknet/icmp.h>#include <click/confparse.hh>CLICK_DECLSnamespace IPSummaryDump {enum { T_TCP_SEQ, T_TCP_ACK, T_TCP_FLAGS, T_TCP_WINDOW, T_TCP_URP, T_TCP_OPT,       T_TCP_NTOPT, T_TCP_SACK, T_TCP_OFF };static bool tcp_extract(PacketDesc& d, const FieldWriter *f){    int transport_length = d.p->transport_length();    switch (f->user_data) {#define CHECK(l) do { if (!d.tcph || transport_length < (l)) return field_missing(d, IP_PROTO_TCP, (l)); } while (0)      case T_TCP_SEQ:	CHECK(8);	d.v = ntohl(d.tcph->th_seq);	return true;      case T_TCP_ACK:	CHECK(12);	d.v = ntohl(d.tcph->th_ack);	return true;      case T_TCP_FLAGS:	CHECK(14);	d.v = d.tcph->th_flags | (d.tcph->th_flags2 << 8);	return true;      case T_TCP_OFF:	CHECK(13);	d.v = d.tcph->th_off << 2;	return true;      case T_TCP_WINDOW:	CHECK(16);	d.v = ntohs(d.tcph->th_win);	return true;      case T_TCP_URP:	CHECK(20);	d.v = ntohs(d.tcph->th_urp);	return true;      case T_TCP_OPT:	// need to check that d.tcph->th_off exists	if (!d.tcph || transport_length < 13 || (d.tcph->th_off > 5 && transport_length < (int)(d.tcph->th_off << 2)))	    goto no_tcp_opt;	if (d.tcph->th_off <= 5)	    d.vptr[0] = d.vptr[1] = 0;	else {	    d.vptr[0] = (const uint8_t *) (d.tcph + 1);	    d.vptr[1] = d.vptr[0] + (d.tcph->th_off << 2) - sizeof(click_tcp);	}	return true;      case T_TCP_NTOPT:      case T_TCP_SACK:	// need to check that d.tcph->th_off exists	if (!d.tcph || transport_length < 13)	    goto no_tcp_opt;	else if (d.tcph->th_off <= 5		 || (d.tcph->th_off == 8 && transport_length >= 24		     && *(reinterpret_cast<const uint32_t *>(d.tcph + 1)) == htonl(0x0101080A)))	    d.vptr[0] = d.vptr[1] = 0;	else if (transport_length < (int)(d.tcph->th_off << 2))	    goto no_tcp_opt;	else {	    d.vptr[0] = (const uint8_t *) (d.tcph + 1);	    d.vptr[1] = d.vptr[0] + (d.tcph->th_off << 2) - sizeof(click_tcp);	}	return true;#undef CHECK      default:	return false;      no_tcp_opt:	return field_missing(d, IP_PROTO_TCP, transport_length + 1);    }}static void tcp_inject(PacketOdesc& d, const FieldReader *f){    if (!d.make_ip(IP_PROTO_TCP) || !d.make_transp())	return;    click_tcp *tcph = d.p->tcp_header();    switch (f->user_data) {    case T_TCP_SEQ:	tcph->th_seq = htonl(d.v);	break;    case T_TCP_ACK:	tcph->th_ack = htonl(d.v);	break;    case T_TCP_FLAGS:	tcph->th_flags = d.v;	tcph->th_flags2 = d.v >> 8;	break;    case T_TCP_OFF:	d.v = (d.v + 3) & ~3;	if ((int) d.v > (int) (tcph->th_off << 2)) {	    int more = d.v - (tcph->th_off << 2);	    if (!(d.p = d.p->put(more)))		return;	    tcph = d.p->tcp_header();	    memset(d.p->transport_header() + d.v - more, TCPOPT_EOL, more);	}	tcph->th_off = d.v >> 2;	break;    case T_TCP_WINDOW:	tcph->th_win = htons(d.v);	break;    case T_TCP_URP:	tcph->th_urp = htons(d.v);	break;    case T_TCP_OPT:    case T_TCP_NTOPT:    case T_TCP_SACK: {	if (!d.vptr[0] || d.vptr[0] == d.vptr[1])	    return;	int olen = d.vptr[1] - d.vptr[0];	int th_off = (sizeof(click_tcp) + olen + 3) & ~3;	if (d.p->transport_length() < th_off) {	    if (!(d.p = d.p->put(th_off - d.p->transport_length())))		return;	    tcph = d.p->tcp_header();	}	if (th_off > (int) (tcph->th_off << 2))	    tcph->th_off = th_off >> 2;	memcpy(d.p->transport_header() + sizeof(click_tcp), d.vptr[0], olen);	memset(d.p->transport_header() + sizeof(click_tcp) + olen,	       TCPOPT_EOL, th_off - olen);	break;    }    }}static void tcp_outa(const PacketDesc& d, const FieldWriter *f){    switch (f->user_data) {      case T_TCP_FLAGS:	if (d.v == (TH_ACK | TH_PUSH))	    *d.sa << 'P' << 'A';	else if (d.v == TH_ACK)	    *d.sa << 'A';	else if (d.v == 0)	    *d.sa << '.';	else	    for (int flag = 0; flag < 9; flag++)		if (d.v & (1 << flag))		    *d.sa << tcp_flags_word[flag];	break;      case T_TCP_OPT:	if (!d.vptr)	    *d.sa << '.';	else	    unparse_tcp_opt(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_ALL_NOPAD);	break;      case T_TCP_NTOPT:	if (!d.vptr)	    *d.sa << '.';	else	    unparse_tcp_opt(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_NTALL);	break;      case T_TCP_SACK:	if (!d.vptr)	    *d.sa << '.';	else	    unparse_tcp_opt(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_SACK);	break;    }}static bool tcp_ina(PacketOdesc& d, const String &str, const FieldReader *f){    switch (f->user_data) {    case T_TCP_FLAGS:	if (str.equals(".", 1))	    d.v = 0;	else if (!str)	    return false;	else if (isdigit((unsigned char) str[0]))	    return cp_integer(str, &d.v) && d.v < 0x1000;	else {	    d.v = 0;	    for (const char *s = str.begin(); s != str.end(); s++)		if (uint8_t fm = IPSummaryDump::tcp_flag_mapping[(unsigned char) *s])		    d.v |= 1 << (fm - 1);		else		    return false;	}	return true;    default:	return false;    }}static void tcp_outb(const PacketDesc& d, bool ok, const FieldWriter *f){    switch (f->user_data) {      case T_TCP_OPT:	if (!ok || !d.vptr)	    *d.sa << '\0';	else	    unparse_tcp_opt_binary(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_ALL);	break;      case T_TCP_NTOPT:	if (!ok || !d.vptr)	    *d.sa << '\0';	else	    unparse_tcp_opt_binary(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_NTALL);	break;      case T_TCP_SACK:	if (!ok || !d.vptr)	    *d.sa << '\0';	else	    unparse_tcp_opt_binary(*d.sa, d.vptr[0], d.vptr[1] - d.vptr[0], DO_TCPOPT_SACK);	break;    }}static const uint8_t* tcp_inb(PacketOdesc& d, const uint8_t* s, const uint8_t* ends, const FieldReader *f){    switch (f->user_data) {      case T_TCP_OPT:      case T_TCP_NTOPT:      case T_TCP_SACK:	if (s + s[0] + 1 <= ends) {	    d.vptr[0] = s + 1;	    d.vptr[1] = d.vptr[0] + s[0];	    return s + s[0] + 1;	}	break;    }    return ends;}static int tcp_opt_mask_mapping[] = {    DO_TCPOPT_PADDING, DO_TCPOPT_PADDING,	// EOL, NOP    DO_TCPOPT_MSS, DO_TCPOPT_WSCALE,		// MAXSEG, WSCALE    DO_TCPOPT_SACK, DO_TCPOPT_SACK,		// SACK_PERMITTED, SACK    DO_TCPOPT_UNKNOWN, DO_TCPOPT_UNKNOWN,	// 6, 7    DO_TCPOPT_TIMESTAMP				// TIMESTAMP};void unparse_tcp_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 TCPOPT_EOL:	    if (mask & DO_TCPOPT_PADDING)		sa << sep << "eol";	    goto done;	  case TCPOPT_NOP:	    if (mask & DO_TCPOPT_PADDING) {		sa << sep << "nop";		sep = ";";	    }	    opt++;	    break;	  case TCPOPT_MAXSEG:	    if (opt + opt[1] > end_opt || opt[1] != TCPOLEN_MAXSEG)		goto bad_opt;	    if (!(mask & DO_TCPOPT_MSS))		goto unknown;	    sa << sep << "mss" << ((opt[2] << 8) | opt[3]);	    opt += TCPOLEN_MAXSEG;	    sep = ";";	    break;	  case TCPOPT_WSCALE:	    if (opt + opt[1] > end_opt || opt[1] != TCPOLEN_WSCALE)		goto bad_opt;	    if (!(mask & DO_TCPOPT_WSCALE))		goto unknown;	    sa << sep << "wscale" << (int)(opt[2]);	    opt += TCPOLEN_WSCALE;	    sep = ";";	    break;	  case TCPOPT_SACK_PERMITTED:	    if (opt + opt[1] > end_opt || opt[1] != TCPOLEN_SACK_PERMITTED)		goto bad_opt;	    if (!(mask & DO_TCPOPT_SACK))		goto unknown;	    sa << sep << "sackok";	    opt += TCPOLEN_SACK_PERMITTED;	    sep = ";";

⌨️ 快捷键说明

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