From 8f8581bedaeea9467fd6adfcfd4354b57c71f25b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 1 Sep 2018 10:22:41 +0200 Subject: [PATCH] decode/tcp: TCP fast open option decoding Support both regular TFO and TFO as part of the experimental options support. --- src/decode-tcp.c | 37 +++++++++++++++++++++++++++++++++++-- src/decode-tcp.h | 7 +++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/decode-tcp.c b/src/decode-tcp.c index d876c7dae5..0c81022bc3 100644 --- a/src/decode-tcp.c +++ b/src/decode-tcp.c @@ -151,6 +151,39 @@ static void DecodeTCPOptions(Packet *p, uint8_t *pkt, uint16_t pktlen) } } break; + case TCP_OPT_TFO: + SCLogDebug("TFO option, len %u", olen); + if (olen < TCP_OPT_TFO_MIN_LEN || + olen > TCP_OPT_TFO_MAX_LEN || + !((olen - 2) % 8 == 0)) + { + ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); + } else { + if (p->tcpvars.tfo.type != 0) { + ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); + } else { + SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]); + } + } + break; + /* experimental options, could be TFO */ + case TCP_OPT_EXP1: + case TCP_OPT_EXP2: + SCLogDebug("TCP EXP option, len %u", olen); + if (olen == 4 || olen == 12) { + uint16_t magic = SCNtohs(*(uint16_t *)tcp_opts[tcp_opt_cnt].data); + if (magic == 0xf989) { + if (p->tcpvars.tfo.type != 0) { + ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); + } else { + SET_OPTS(p->tcpvars.tfo, tcp_opts[tcp_opt_cnt]); + p->tcpvars.tfo.type = TCP_OPT_TFO; // treat as regular TFO + } + } + } else { + ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); + } + break; } pkt += olen; @@ -207,11 +240,11 @@ int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui } #ifdef DEBUG - SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s", + SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s%s", GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_HLEN(p), len, TCP_HAS_SACKOK(p) ? "SACKOK " : "", TCP_HAS_SACK(p) ? "SACK " : "", TCP_HAS_WSCALE(p) ? "WS " : "", TCP_HAS_TS(p) ? "TS " : "", - TCP_HAS_MSS(p) ? "MSS " : ""); + TCP_HAS_MSS(p) ? "MSS " : "", TCP_HAS_TFO(p) ? "TFO " : ""); #endif FlowSetupPacket(p); diff --git a/src/decode-tcp.h b/src/decode-tcp.h index 5f599279b4..ac9316fbe6 100644 --- a/src/decode-tcp.h +++ b/src/decode-tcp.h @@ -51,6 +51,9 @@ #define TCP_OPT_SACKOK 0x04 #define TCP_OPT_SACK 0x05 #define TCP_OPT_TS 0x08 +#define TCP_OPT_TFO 0x22 /* TCP Fast Open */ +#define TCP_OPT_EXP1 0xfd /* Experimental, could be TFO */ +#define TCP_OPT_EXP2 0xfe /* Experimental, could be TFO */ #define TCP_OPT_SACKOK_LEN 2 #define TCP_OPT_WS_LEN 3 @@ -58,6 +61,8 @@ #define TCP_OPT_MSS_LEN 4 #define TCP_OPT_SACK_MIN_LEN 10 /* hdr 2, 1 pair 8 = 10 */ #define TCP_OPT_SACK_MAX_LEN 34 /* hdr 2, 4 pair 32= 34 */ +#define TCP_OPT_TFO_MIN_LEN 6 /* kind, len, 6 */ +#define TCP_OPT_TFO_MAX_LEN 20 /* kind, len, 18 */ /** Max valid wscale value. */ #define TCP_WSCALE_MAX 14 @@ -88,6 +93,7 @@ #define TCP_HAS_SACKOK(p) ((p)->tcpvars.sackok.type == TCP_OPT_SACKOK) #define TCP_HAS_TS(p) ((p)->tcpvars.ts_set == TRUE) #define TCP_HAS_MSS(p) ((p)->tcpvars.mss.type == TCP_OPT_MSS) +#define TCP_HAS_TFO(p) ((p)->tcpvars.tfo.type == TCP_OPT_TFO) /** macro for getting the wscale from the packet. */ #define TCP_GET_WSCALE(p) (TCP_HAS_WSCALE((p)) ? \ @@ -154,6 +160,7 @@ typedef struct TCPVars_ TCPOpt sackok; TCPOpt ws; TCPOpt mss; + TCPOpt tfo; /* tcp fast open */ } TCPVars; #define CLEAR_TCP_PACKET(p) { \