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

📄 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 页
字号:
	    break;	  case TCPOPT_SACK: {	      if (opt + opt[1] > end_opt || (opt[1] % 8 != 2))		  goto bad_opt;	      if (!(mask & DO_TCPOPT_SACK))		  goto unknown;	      const uint8_t *end_sack = opt + opt[1];	      for (opt += 2; opt < end_sack; opt += 8) {		  uint32_t buf[2];		  memcpy(&buf[0], opt, 8);		  sa << sep << "sack" << ntohl(buf[0]) << '-' << ntohl(buf[1]);		  sep = ";";	      }	      break;	  }	  case TCPOPT_TIMESTAMP: {	      if (opt + opt[1] > end_opt || opt[1] != TCPOLEN_TIMESTAMP)		  goto bad_opt;	      if (!(mask & DO_TCPOPT_TIMESTAMP))		  goto unknown;	      uint32_t buf[2];	      memcpy(&buf[0], opt + 2, 8);	      sa << sep << "ts" << ntohl(buf[0]) << ':' << ntohl(buf[1]);	      opt += TCPOLEN_TIMESTAMP;	      sep = ";";	      break;	  }	  default: {	      if (opt + opt[1] > end_opt || opt[1] < 2)		  goto bad_opt;	      if (!(mask & DO_TCPOPT_UNKNOWN))		  goto unknown;	      sa << sep << (int)(opt[0]);	      const uint8_t *end_this_opt = opt + opt[1];	      char opt_sep = '=';	      for (opt += 2; opt < end_this_opt; opt++) {		  sa << opt_sep << (int)(*opt);		  opt_sep = ':';	      }	      sep = ";";	      break;	  }	  unknown:	    opt += (opt[1] >= 2 ? opt[1] : 128);	    break;	}  done:    if (sa.length() == initial_sa_len)	sa << '.';    return;  bad_opt:    sa.set_length(initial_sa_len);    sa << '?';}void unparse_tcp_opt(StringAccum& sa, const click_tcp* tcph, int mask){    unparse_tcp_opt(sa, reinterpret_cast<const uint8_t *>(tcph + 1), (tcph->th_off << 2) - sizeof(click_tcp), mask);}void unparse_tcp_opt_binary(StringAccum& sa, const uint8_t* opt, int opt_len, int mask){    if (mask == (int)DO_TCPOPT_ALL) {	// store all options	sa.append((char)opt_len);	sa.append(opt, opt_len);    }    const uint8_t *end_opt = opt + opt_len;    int initial_sa_len = sa.length();    sa.append('\0');    while (opt < end_opt) {	// one-byte options	if (*opt == TCPOPT_EOL) {	    if (mask & DO_TCPOPT_PADDING)		sa.append(opt, 1);	    goto done;	} else if (*opt == TCPOPT_NOP) {	    if (mask & DO_TCPOPT_PADDING)		sa.append(opt, 1);	    opt++;	    continue;	}	// quit copying options if you encounter something obviously invalid	if (opt[1] < 2 || opt + opt[1] > end_opt)	    break;	int this_content = (*opt > TCPOPT_TIMESTAMP ? (int)DO_TCPOPT_UNKNOWN : tcp_opt_mask_mapping[*opt]);	if (mask & this_content)	    sa.append(opt, opt[1]);	opt += opt[1];    }  done:    sa[initial_sa_len] = sa.length() - initial_sa_len - 1;}void unparse_tcp_opt_binary(StringAccum& sa, const click_tcp *tcph, int mask){    unparse_tcp_opt_binary(sa, reinterpret_cast<const uint8_t *>(tcph + 1), (tcph->th_off << 2) - sizeof(click_tcp), mask);}static void append_net_uint32_t(StringAccum &sa, uint32_t u){    sa << (char)(u >> 24) << (char)(u >> 16) << (char)(u >> 8) << (char)u;}static bool tcp_opt_ina(PacketOdesc &d, const String &str, const FieldReader *f){    if (!str || str.equals(".", 1))	return true;    else if (str.equals("-", 1))	return false;    const uint8_t *s = reinterpret_cast<const uint8_t *>(str.begin());    const uint8_t *end = reinterpret_cast<const uint8_t *>(str.end());    int contents = DO_TCPOPT_ALL;    if (f->user_data == T_TCP_SACK)	contents = DO_TCPOPT_SACK;    else if (f->user_data == T_TCP_NTOPT)	contents = DO_TCPOPT_NTALL;    d.sa.clear();    while (1) {	uint32_t u1, u2;	if (s + 3 < end && memcmp(s, "mss", 3) == 0	    && (contents & DO_TCPOPT_MSS)) {	    u1 = 0x10000U;	// bad value	    s = cp_integer(s + 3, end, 0, &u1);	    if (u1 <= 0xFFFFU)		d.sa << (char)TCPOPT_MAXSEG << (char)TCPOLEN_MAXSEG << (char)(u1 >> 8) << (char)u1;	    else		goto bad_opt;	} else if (s + 6 < end && memcmp(s, "wscale", 6) == 0		   && (contents & DO_TCPOPT_WSCALE)) {	    u1 = 256;		// bad value	    s = cp_integer(s + 6, end, 0, &u1);	    if (u1 <= 255)		d.sa << (char)TCPOPT_WSCALE << (char)TCPOLEN_WSCALE << (char)u1;	    else		goto bad_opt;	} else if (s + 6 <= end && memcmp(s, "sackok", 6) == 0		   && (contents & DO_TCPOPT_SACK)) {	    d.sa << (char)TCPOPT_SACK_PERMITTED << (char)TCPOLEN_SACK_PERMITTED;	    s += 6;	} else if (s + 4 < end && memcmp(s, "sack", 4) == 0		   && (contents & DO_TCPOPT_SACK)) {	    // combine adjacent SACK options into a block	    int sa_pos = d.sa.length();	    d.sa << (char)TCPOPT_SACK << (char)0;	    s += 4;	    while (1) {		const unsigned char *t = cp_integer(s, end, 0, &u1);		if (t >= end || (*t != ':' && *t != '-'))		    goto bad_opt;		t = cp_integer(t + 1, end, 0, &u2);		append_net_uint32_t(d.sa, u1);		append_net_uint32_t(d.sa, u2);		if (t < s + 3) // at least 1 digit in each block		    goto bad_opt;		s = t;		if (s + 5 >= end || memcmp(s, ",sack", 5) != 0)		    break;		s += 5;	    }	    d.sa[sa_pos + 1] = (char)(d.sa.length() - sa_pos);	} else if (s + 2 < end && memcmp(s, "ts", 2) == 0		   && (contents & DO_TCPOPT_TIMESTAMP)) {	    const unsigned char *t = cp_integer(s + 2, end, 0, &u1);	    if (t >= end || *t != ':')		goto bad_opt;	    t = cp_integer(t + 1, end, 0, &u2);	    if (d.sa.length() == 0)		d.sa << (char)TCPOPT_NOP << (char)TCPOPT_NOP;	    d.sa << (char)TCPOPT_TIMESTAMP << (char)TCPOLEN_TIMESTAMP;	    append_net_uint32_t(d.sa, u1);	    append_net_uint32_t(d.sa, u2);	    if (t < s + 5)	// at least 1 digit in each block		goto bad_opt;	    s = t;	} else if (s < end && isdigit(*s)		   && (contents & DO_TCPOPT_UNKNOWN)) {	    s = cp_integer(s, end, 0, &u1);	    if (u1 >= 256)		goto bad_opt;	    d.sa << (char)u1;	    if (s + 1 < end && *s == '=' && isdigit(s[1])) {		int pos0 = d.sa.length();		d.sa << (char)0;		do {		    s = cp_integer(s + 1, end, 0, &u1);		    if (u1 >= 256)			goto bad_opt;		    d.sa << (char)u1;		} while (s + 1 < end && *s == ':' && isdigit(s[1]));		if (d.sa.length() > pos0 + 254)		    goto bad_opt;		d.sa[pos0] = (char)(d.sa.length() - pos0 + 1);	    }	} else if (s + 3 <= end && memcmp(s, "nop", 3) == 0		   && (contents & DO_TCPOPT_PADDING)) {	    d.sa << (char)TCPOPT_NOP;	    s += 3;	} else if (s + 3 <= end && strncmp((const char *) s, "eol", 3) == 0		   && (contents & DO_TCPOPT_PADDING)		   && (s + 3 == end || s[3] != ',')) {	    d.sa << (char)TCPOPT_EOL;	    s += 3;	} else	    goto bad_opt;	if (s >= end || isspace(*s)) {	    // check for improper padding	    while (d.sa.length() > 40 && d.sa[0] == TCPOPT_NOP) {		memmove(&d.sa[0], &d.sa[1], d.sa.length() - 1);		d.sa.pop_back();	    }	    // options too long?	    if (d.sa.length() > 40)		goto bad_opt;	    // otherwise ok	    d.vptr[0] = reinterpret_cast<const uint8_t *>(d.sa.begin());	    d.vptr[1] = reinterpret_cast<const uint8_t *>(d.sa.end());	    return true;	} else if (*s != ',' && *s != ';')	    goto bad_opt;	s++;    }  bad_opt:    return false;}static const FieldWriter tcp_writers[] = {    { "tcp_seq", B_4, T_TCP_SEQ,      ip_prepare, tcp_extract, num_outa, outb },    { "tcp_ack", B_4, T_TCP_ACK,      ip_prepare, tcp_extract, num_outa, outb },    { "tcp_off", B_1, T_TCP_OFF,      ip_prepare, tcp_extract, num_outa, outb },    { "tcp_flags", B_1, T_TCP_FLAGS,      ip_prepare, tcp_extract, tcp_outa, outb },    { "tcp_window", B_2, T_TCP_WINDOW,      ip_prepare, tcp_extract, num_outa, outb },    { "tcp_urp", B_2, T_TCP_URP,      ip_prepare, tcp_extract, num_outa, outb },    { "tcp_opt", B_SPECIAL, T_TCP_OPT,      ip_prepare, tcp_extract, tcp_outa, tcp_outb },    { "tcp_ntopt", B_SPECIAL, T_TCP_NTOPT,      ip_prepare, tcp_extract, tcp_outa, tcp_outb },    { "tcp_sack", B_SPECIAL, T_TCP_SACK,      ip_prepare, tcp_extract, tcp_outa, tcp_outb }};static const FieldReader tcp_readers[] = {    { "tcp_seq", B_4, T_TCP_SEQ, order_transp,      num_ina, inb, tcp_inject },    { "tcp_ack", B_4, T_TCP_ACK, order_transp,      num_ina, inb, tcp_inject },    { "tcp_off", B_1, T_TCP_OFF, order_transp - 1,      num_ina, inb, tcp_inject },    { "tcp_flags", B_1, T_TCP_FLAGS, order_transp,      tcp_ina, inb, tcp_inject },    { "tcp_window", B_2, T_TCP_WINDOW, order_transp,      num_ina, inb, tcp_inject },    { "tcp_urp", B_2, T_TCP_URP, order_transp,      num_ina, inb, tcp_inject },    { "tcp_opt", B_SPECIAL, T_TCP_OPT, order_transp + 3,      tcp_opt_ina, tcp_inb, tcp_inject },    { "tcp_ntopt", B_SPECIAL, T_TCP_NTOPT, order_transp + 2,      tcp_opt_ina, tcp_inb, tcp_inject },    { "tcp_sack", B_SPECIAL, T_TCP_SACK, order_transp + 1,      tcp_opt_ina, tcp_inb, tcp_inject }};static const FieldSynonym tcp_synonyms[] = {    { "tcp_seqno", "tcp_seq" },    { "tcp_ackno", "tcp_ack" },    { "tcp_win", "tcp_window" }};}void IPSummaryDump_TCP::static_initialize(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(tcp_writers) / sizeof(tcp_writers[0]); ++i)	FieldWriter::add(&tcp_writers[i]);    for (size_t i = 0; i < sizeof(tcp_readers) / sizeof(tcp_readers[0]); ++i)	FieldReader::add(&tcp_readers[i]);    for (size_t i = 0; i < sizeof(tcp_synonyms) / sizeof(tcp_synonyms[0]); ++i)	FieldSynonym::add(&tcp_synonyms[i]);}void IPSummaryDump_TCP::static_cleanup(){    using namespace IPSummaryDump;    for (size_t i = 0; i < sizeof(tcp_writers) / sizeof(tcp_writers[0]); ++i)	FieldWriter::remove(&tcp_writers[i]);    for (size_t i = 0; i < sizeof(tcp_readers) / sizeof(tcp_readers[0]); ++i)	FieldReader::remove(&tcp_readers[i]);    for (size_t i = 0; i < sizeof(tcp_synonyms) / sizeof(tcp_synonyms[0]); ++i)	FieldSynonym::remove(&tcp_synonyms[i]);}ELEMENT_REQUIRES(userlevel IPSummaryDump)ELEMENT_PROVIDES(IPSummaryDump_TCP)CLICK_ENDDECLS

⌨️ 快捷键说明

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