📄 fromipsumdump.cc
字号:
sa[pos0] = (char)(sa.length() - pos0 + 1); } } else if (s + 3 <= end && memcmp(s, "nop", 3) == 0 && (contents & DO_IPOPT_PADDING)) { sa << (char)IPOPT_NOP; s += 3; } else if (s + 3 <= end && memcmp(s, "eol", 3) == 0 && (contents & DO_IPOPT_PADDING) && (s + 3 == end || s[3] != ',')) { sa << (char)IPOPT_EOL; s += 3; } else goto bad_opt; if (s >= end || isspace(*s)) { // check for improper padding while (sa.length() > 40 && sa[0] == TCPOPT_NOP) { memmove(&sa[0], &sa[1], sa.length() - 1); sa.pop_back(); } // options too long? if (sa.length() > 40) goto bad_opt; // otherwise ok *result = sa.take_string(); return s; } else if (*s != ',' && *s != ';') goto bad_opt; s++; } bad_opt: *result = String(); return begin;}const unsigned char *FromIPSummaryDump::parse_tcp_opt_ascii(const unsigned char *begin, const unsigned char *end, String *result, int contents){ StringAccum sa; const unsigned char *s = begin; 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_unsigned(s + 3, end, 0, &u1); if (u1 <= 0xFFFFU) 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_unsigned(s + 6, end, 0, &u1); if (u1 <= 255) 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)) { 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 = sa.length(); sa << (char)TCPOPT_SACK << (char)0; s += 4; while (1) { const unsigned char *t = cp_unsigned(s, end, 0, &u1); if (t >= end || (*t != ':' && *t != '-')) goto bad_opt; t = cp_unsigned(t + 1, end, 0, &u2); append_net_uint32_t(sa, u1); append_net_uint32_t(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; } sa[sa_pos + 1] = (char)(sa.length() - sa_pos); } else if (s + 2 < end && memcmp(s, "ts", 2) == 0 && (contents & DO_TCPOPT_TIMESTAMP)) { const unsigned char *t = cp_unsigned(s + 2, end, 0, &u1); if (t >= end || *t != ':') goto bad_opt; t = cp_unsigned(t + 1, end, 0, &u2); if (sa.length() == 0) sa << (char)TCPOPT_NOP << (char)TCPOPT_NOP; sa << (char)TCPOPT_TIMESTAMP << (char)TCPOLEN_TIMESTAMP; append_net_uint32_t(sa, u1); append_net_uint32_t(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_unsigned(s, end, 0, &u1); if (u1 >= 256) goto bad_opt; sa << (char)u1; if (s + 1 < end && *s == '=' && isdigit(s[1])) { int pos0 = sa.length(); sa << (char)0; do { s = cp_unsigned(s + 1, end, 0, &u1); if (u1 >= 256) goto bad_opt; sa << (char)u1; } while (s + 1 < end && *s == ':' && isdigit(s[1])); if (sa.length() > pos0 + 254) goto bad_opt; sa[pos0] = (char)(sa.length() - pos0 + 1); } } else if (s + 3 <= end && memcmp(s, "nop", 3) == 0 && (contents & DO_TCPOPT_PADDING)) { 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] != ',')) { sa << (char)TCPOPT_EOL; s += 3; } else goto bad_opt; if (s >= end || isspace(*s)) { // check for improper padding while (sa.length() > 40 && sa[0] == TCPOPT_NOP) { memmove(&sa[0], &sa[1], sa.length() - 1); sa.pop_back(); } // options too long? if (sa.length() > 40) goto bad_opt; // otherwise ok *result = sa.take_string(); return s; } else if (*s != ',' && *s != ';') goto bad_opt; s++; } bad_opt: *result = String(); return begin;}static WritablePacket *handle_ip_opt(WritablePacket *q, const String &optstr){ int olen = (optstr.length() + 3) & ~3; if (!(q = q->put(olen))) return 0; memmove(q->transport_header() + olen, q->transport_header(), sizeof(click_tcp)); q->ip_header()->ip_hl = (sizeof(click_ip) + olen) >> 2; memcpy(q->ip_header() + 1, optstr.data(), optstr.length()); if (optstr.length() & 3) *(reinterpret_cast<uint8_t *>(q->ip_header() + 1) + optstr.length()) = IPOPT_EOL; q->set_ip_header(q->ip_header(), sizeof(click_ip) + olen); return q;}static WritablePacket *handle_tcp_opt(WritablePacket *q, const String &optstr){ int olen = (optstr.length() + 3) & ~3; if (!(q = q->put(olen))) return 0; q->tcp_header()->th_off = (sizeof(click_tcp) + olen) >> 2; memcpy(q->tcp_header() + 1, optstr.data(), optstr.length()); if (optstr.length() & 3) *(reinterpret_cast<uint8_t *>(q->tcp_header() + 1) + optstr.length()) = TCPOPT_EOL; return q;}static voidset_checksums(WritablePacket *q, click_ip *iph){ assert(iph == q->ip_header()); iph->ip_sum = 0; iph->ip_sum = click_in_cksum((uint8_t *)iph, iph->ip_hl << 2); if (IP_ISFRAG(iph)) /* nada */; else if (iph->ip_p == IP_PROTO_TCP) { click_tcp *tcph = q->tcp_header(); tcph->th_sum = 0; unsigned csum = click_in_cksum((uint8_t *)tcph, q->transport_length()); tcph->th_sum = click_in_cksum_pseudohdr(csum, iph, q->transport_length()); } else if (iph->ip_p == IP_PROTO_UDP) { click_udp *udph = q->udp_header(); udph->uh_sum = 0; unsigned csum = click_in_cksum((uint8_t *)udph, q->transport_length()); udph->uh_sum = click_in_cksum_pseudohdr(csum, iph, q->transport_length()); }}Packet *FromIPSummaryDump::read_packet(ErrorHandler *errh){ WritablePacket *q = Packet::make(0, (const unsigned char *)0, sizeof(click_ip) + sizeof(click_tcp), 8); if (!q) { _ff.error(errh, strerror(ENOMEM)); return 0; } if (_zero) memset(q->data(), 0, q->length()); q->set_ip_header((click_ip *)q->data(), sizeof(click_ip)); click_ip *iph = q->ip_header(); iph->ip_v = 4; iph->ip_hl = sizeof(click_ip) >> 2; iph->ip_p = _default_proto; iph->ip_off = 0; String line; StringAccum payload; String ip_opt; String tcp_opt; while (1) { bool binary = _binary; if (binary) { int result = read_binary(line, errh); if (result <= 0) { q->kill(); return 0; } else binary = (result == 1); } else if (_ff.read_line(line, errh) <= 0) { q->kill(); return 0; } const unsigned char *data = (const unsigned char *) line.begin(); const unsigned char *end = (const unsigned char *) line.end(); if (data == end) continue; else if (!binary && data[0] == '!') { if (data + 6 <= end && memcmp(data, "!data", 5) == 0 && isspace(data[5])) bang_data(line, errh); else if (data + 8 <= end && memcmp(data, "!flowid", 7) == 0 && isspace(data[7])) bang_flowid(line, iph, errh); else if (data + 11 <= end && memcmp(data, "!aggregate", 10) == 0 && isspace(data[10])) bang_aggregate(line, errh); else if (data + 8 <= end && memcmp(data, "!binary", 7) == 0 && isspace(data[7])) bang_binary(line, errh); else if (data + 10 <= end && memcmp(data, "!contents", 9) == 0 && isspace(data[9])) bang_data(line, errh); continue; } else if (!binary && data[0] == '#') continue; int ok = (binary ? 1 : 0); int ip_ok = 0; uint32_t byte_count = 0; uint32_t payload_len = 0; bool have_payload_len = false; bool have_payload = false; bool have_ip_opt = false; bool have_tcp_opt = false; for (int i = 0; data < end && i < _contents.size(); i++) { const unsigned char *original_data = data; const unsigned char *next; uint32_t u1 = 0, u2 = 0; // check binary case if (binary) { switch (_contents[i]) { case W_NONE: break; case W_TIMESTAMP: case W_FIRST_TIMESTAMP: u1 = GET4(data); u2 = GET4(data + 4) * 1000; data += 8; break; case W_NTIMESTAMP: case W_FIRST_NTIMESTAMP: u1 = GET4(data); u2 = GET4(data + 4); data += 8; break; case W_TIMESTAMP_USEC1: u1 = GET4(data); u2 = GET4(data + 4); data += 8; break; case W_TIMESTAMP_SEC: case W_TIMESTAMP_USEC: case W_IP_LEN: case W_PAYLOAD_LEN: case W_IP_CAPTURE_LEN: case W_TCP_SEQ: case W_TCP_ACK: case W_COUNT: case W_AGGREGATE: case W_IP_SRC: case W_IP_DST: u1 = GET4(data); data += 4; break; case W_IP_ID: case W_SPORT: case W_DPORT: case W_IP_FRAGOFF: case W_TCP_WINDOW: case W_TCP_URP: u1 = GET2(data); data += 2; break; case W_IP_PROTO: case W_TCP_FLAGS: case W_LINK: case W_IP_TOS: case W_IP_TTL: u1 = GET1(data); data++; break; case W_IP_FRAG: // XXX less checking here if (*data == 'F') u1 = htons(IP_MF); else if (*data == 'f') u1 = htons(100); // random number data++; // u1 already 0 break; case W_IP_OPT: { const unsigned char *endopt = data + 1 + *data; if (endopt <= end) { ip_opt = line.substring((const char *) data + 1, (const char *) endopt); have_ip_opt = true; data = endopt; } break; } case W_TCP_OPT: case W_TCP_NTOPT: case W_TCP_SACK: { const unsigned char *endopt = data + 1 + *data; if (endopt <= end) { tcp_opt = line.substring((const char *) data + 1, (const char *) endopt); have_tcp_opt = true; data = endopt; } break; } } goto store_contents; } // otherwise, ascii // first, parse contents switch (_contents[i]) { case W_NONE: while (data < end && !isspace(*data)) data++; break; case W_TIMESTAMP: case W_NTIMESTAMP: case W_FIRST_TIMESTAMP: case W_FIRST_NTIMESTAMP: next = cp_unsigned(data, end, 10, &u1); if (next > data) { data = next; if (data + 1 < end && *data == '.') { int digit = 0; for (data++; digit < 9 && data < end && isdigit(*data); digit++, data++) u2 = (u2 * 10) + *data - '0'; for (; digit < 9; digit++) u2 = (u2 * 10); for (; data < end && isdigit(*data); data++) /* nada */; } } break; case W_TIMESTAMP_SEC: case W_TIMESTAMP_USEC: case W_IP_LEN: case W_PAYLOAD_LEN: case W_IP_CAPTURE_LEN: case W_IP_ID: case W_SPORT: case W_DPORT: case W_TCP_SEQ: case W_TCP_ACK: case W_COUNT: case W_AGGREGATE: case W_TCP_WINDOW: case W_TCP_URP: case W_IP_TOS: case W_IP_TTL: data = cp_unsigned(data, end, 0, &u1); break; case W_TIMESTAMP_USEC1: {#if HAVE_INT64_TYPES uint64_t uu; data = cp_unsigned(data, end, 0, &uu); u1 = (uint32_t)(uu >> 32); u2 = (uint32_t) uu;#else // silently truncate large numbers data = cp_unsigned(data, end, 0, &u2);#endif break; } case W_IP_SRC: case W_IP_DST: for (int j = 0; j < 4; j++) { const unsigned char *first = data; int x = 0; while (data < end && isdigit(*data) && x < 256) (x = (x * 10) + *data - '0'), data++; if (x >= 256 || data == first || (j < 3 && (data >= end || *data != '.'))) { data = original_data; break; } u1 = (u1 << 8) + x; if (j < 3) data++; } break; case W_IP_PROTO: if (*data == 'T') { u1 = IP_PROTO_TCP; data++; } else if (*data == 'U') { u1 = IP_PROTO_UDP; data++; } else if (*data == 'I') { u1 = IP_PROTO_ICMP; data++; } else data = cp_unsigned(data, end, 0, &u1); break; case W_IP_FRAG: if (*data == 'F') { u1 = htons(IP_MF); data++; } else if (*data == 'f') { u1 = htons(100); // random number data++; } else if (*data == '.') data++; // u1 already 0 break; case W_IP_FRAGOFF: next = cp_unsigned(data, end, 0, &u1); if (_minor_version == 0) // old-style file u1 <<= 3; if (next > data && (u1 & 7) == 0 && u1 < 65536) { u1 >>= 3; data = next; if (data < end && *data == '+') { u1 |= IP_MF; data++; } } break; case W_TCP_FLAGS: if (isdigit(*data)) data = cp_unsigned(data, end, 0, &u1); else if (*data == '.') data++; else while (data < end && IPSummaryDump::tcp_flag_mapping[*data]) { u1 |= 1 << (IPSummaryDump::tcp_flag_mapping[*data] - 1); data++; } break; case W_IP_OPT: if (*data == '.') data++; else if (*data != '-') { have_ip_opt = true; data = parse_ip_opt_ascii(data, end, &ip_opt, DO_IPOPT_ALL); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -