From 22a5194e18a3e328e07075f1f0e7d77f8e49ffbb Mon Sep 17 00:00:00 2001 From: dmiller Date: Wed, 24 Jun 2026 20:48:16 +0000 Subject: [PATCH] Replace yet another implementation of TCP option parsing with a standard function --- libnetutil/TCPHeader.cc | 135 +------------------------------------- libnetutil/TCPHeader.h | 2 - libnetutil/netutil.cc | 2 +- libnetutil/netutil.h | 2 +- libnetutil/packettrace.cc | 2 +- 5 files changed, 4 insertions(+), 139 deletions(-) diff --git a/libnetutil/TCPHeader.cc b/libnetutil/TCPHeader.cc index 0c2aaf036..94c0f8fdb 100644 --- a/libnetutil/TCPHeader.cc +++ b/libnetutil/TCPHeader.cc @@ -182,7 +182,7 @@ int TCPHeader::print(FILE *output, int detail) const { fprintf(output, " urp=%d", this->getUrgPointer() ); if(this->tcpoptlen>0 && (this->length >= TCP_HEADER_LEN+this->tcpoptlen) && this->tcpoptlen<=MAX_TCP_OPTIONS_LEN){ - this->__tcppacketoptinfo(this->h.options, this->tcpoptlen, optinfo, sizeof(optinfo)-1); + tcppacketoptinfo(this->h.options, this->tcpoptlen, optinfo, sizeof(optinfo)-1); optinfo[255]='\0'; fprintf(output, " %s", optinfo); } @@ -196,139 +196,6 @@ int TCPHeader::print(FILE *output, int detail) const { } /* End of print() */ -/* Get an ASCII information about a tcp option which is pointed by - optp, with a length of len. The result is stored in the result - buffer. The result may look like "" */ -void TCPHeader::__tcppacketoptinfo(const u8 *optp, int len, char *result, int bufsize) const { - assert(optp); - assert(result); - char *p, ch; - const u8 *q; - int opcode; - u16 tmpshort; - u32 tmpword1, tmpword2; - unsigned int i=0; - - p = result; - *p = '\0'; - q = optp; - ch = '<'; - - while (len > 0 && bufsize > 2) { - Snprintf(p, bufsize, "%c", ch); - bufsize--; - p++; - opcode = *q++; - if (!opcode) { /* End of List */ - - Snprintf(p, bufsize, "eol"); - bufsize -= strlen(p); - p += strlen(p); - - len--; - - } else if (opcode == 1) { /* No Op */ - Snprintf(p, bufsize, "nop"); - bufsize -= strlen(p); - p += strlen(p); - - len--; - } else if (opcode == 2) { /* MSS */ - if (len < 4) - break; /* MSS has 4 bytes */ - - q++; - memcpy(&tmpshort, q, 2); - - Snprintf(p, bufsize, "mss %u", ntohs(tmpshort)); - bufsize -= strlen(p); - p += strlen(p); - - q += 2; - len -= 4; - } else if (opcode == 3) { /* Window Scale */ - if (len < 3) - break; /* Window Scale option has 3 bytes */ - - q++; - - Snprintf(p, bufsize, "wscale %u", *q); - bufsize -= strlen(p); - p += strlen(p); - - q++; - len -= 3; - } else if (opcode == 4) { /* SACK permitted */ - if (len < 2) - break; /* SACK permitted option has 2 bytes */ - - Snprintf(p, bufsize, "sackOK"); - bufsize -= strlen(p); - p += strlen(p); - - q++; - len -= 2; - } else if (opcode == 5) { /* SACK */ - unsigned sackoptlen = *q; - if ((unsigned) len < sackoptlen) - break; - - /* This would break parsing, so it's best to just give up */ - if (sackoptlen < 2) - break; - - q++; - - if ((sackoptlen - 2) == 0 || ((sackoptlen - 2) % 8 != 0)) { - Snprintf(p, bufsize, "malformed sack"); - bufsize -= strlen(p); - p += strlen(p); - } else { - Snprintf(p, bufsize, "sack %d ", (sackoptlen - 2) / 8); - bufsize -= strlen(p); - p += strlen(p); - for (i = 0; i < sackoptlen - 2; i += 8) { - memcpy(&tmpword1, q + i, 4); - memcpy(&tmpword2, q + i + 4, 4); - Snprintf(p, bufsize, "{%u:%u}", tmpword1, tmpword2); - bufsize -= strlen(p); - p += strlen(p); - } - } - - q += sackoptlen - 2; - len -= sackoptlen; - } else if (opcode == 8) { /* Timestamp */ - if (len < 10) - break; /* Timestamp option has 10 bytes */ - - q++; - memcpy(&tmpword1, q, 4); - memcpy(&tmpword2, q + 4, 4); - - Snprintf(p, bufsize, "timestamp %u %u", ntohl(tmpword1), - ntohl(tmpword2)); - bufsize -= strlen(p); - p += strlen(p); - - q += 8; - len -= 10; - } - - ch = ','; - } - - if (len > 0) { - *result = '\0'; - return; - } - - Snprintf(p, bufsize, ">"); -} - - - /******************************************************************************/ /* PROTOCOL-SPECIFIC METHODS */ /******************************************************************************/ diff --git a/libnetutil/TCPHeader.h b/libnetutil/TCPHeader.h index adab6ea32..2517f86d0 100644 --- a/libnetutil/TCPHeader.h +++ b/libnetutil/TCPHeader.h @@ -161,8 +161,6 @@ class TCPHeader : public TransportLayerElement { int tcpoptlen; /**< Length of TCP options */ - void __tcppacketoptinfo(const u8 *optp, int len, char *result, int bufsize) const; - public: TCPHeader(); diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index 424eaef99..5a2daf187 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -1433,7 +1433,7 @@ static bool tcpopt_info(u8 opcode, u8 len, const u8 *data, void *ctx); optp, with a length of len. The result is stored in the result buffer. The result may look like "" */ -void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize) { +void tcppacketoptinfo(const u8 *optp, int len, char *result, int bufsize) { assert(optp); assert(result); assert(bufsize > 0); diff --git a/libnetutil/netutil.h b/libnetutil/netutil.h index 2abf6fedd..0ad9842e5 100644 --- a/libnetutil/netutil.h +++ b/libnetutil/netutil.h @@ -352,7 +352,7 @@ const char *proto2ascii_uppercase(u8 proto); optp, with a length of len. The result is stored in the result buffer. The result may look like "" */ -void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize); +void tcppacketoptinfo(const u8 *optp, int len, char *result, int bufsize); /* Convert an IP address to the device (IE ppp0 eth0) using that * address. Supplied "dev" must be able to hold at least 32 bytes. diff --git a/libnetutil/packettrace.cc b/libnetutil/packettrace.cc index 48b018811..af2fece73 100644 --- a/libnetutil/packettrace.cc +++ b/libnetutil/packettrace.cc @@ -764,7 +764,7 @@ int tcppackethdrinfo (const u8 *data, unsigned int datalen, tcpdataoffset = tcp.th_off * 4; if (tcpdataoffset > sizeof(struct tcp_hdr) && tcpdataoffset <= (u32) lastbyte) { - tcppacketoptinfo((u8*) data + sizeof(struct tcp_hdr) - frag_off, + tcppacketoptinfo((const u8*) data + sizeof(struct tcp_hdr) - frag_off, tcpdataoffset - sizeof(struct tcp_hdr), tcpoptinfo, sizeof(tcpoptinfo)); }