}
}
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;
}
#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);
#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
#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
#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)) ? \
TCPOpt sackok;
TCPOpt ws;
TCPOpt mss;
+ TCPOpt tfo; /* tcp fast open */
} TCPVars;
#define CLEAR_TCP_PACKET(p) { \