aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt18
-rw-r--r--CMakeOptions.txt2
-rw-r--r--acinclude.m4160
-rw-r--r--cmake/modules/FindLZ4.cmake39
-rw-r--r--cmake/modules/FindSNAPPY.cmake38
-rw-r--r--cmakeconfig.h.in6
-rw-r--r--configure.ac88
-rw-r--r--epan/CMakeLists.txt14
-rw-r--r--epan/Makefile.am10
-rw-r--r--epan/dissectors/packet-cql.c148
-rw-r--r--epan/epan.c17
11 files changed, 512 insertions, 28 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ebfe8a1342..68af9a53bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -830,6 +830,16 @@ if(ENABLE_ZLIB)
set(PACKAGELIST ${PACKAGELIST} ZLIB)
endif()
+# LZ4 compression
+if(ENABLE_LZ4)
+ set(PACKAGELIST ${PACKAGELIST} LZ4)
+endif()
+
+# Snappy compression
+if(ENABLE_SNAPPY)
+ set(PACKAGELIST ${PACKAGELIST} SNAPPY)
+endif()
+
# Embedded Lua interpreter
if(ENABLE_LUA)
set(PACKAGELIST ${PACKAGELIST} LUA)
@@ -975,6 +985,12 @@ if(HAVE_LIBZLIB)
# bug in the Windows setup of GTK[23] which has a faulty zconf.h.
include_directories(BEFORE ${ZLIB_INCLUDE_DIRS})
endif()
+if(HAVE_LIBLZ4)
+ set(HAVE_LZ4 1)
+endif()
+if(SNAPPY_FOUND)
+ set(HAVE_SNAPPY 1)
+endif()
if (Qt5Widgets_FOUND)
#
# Qt5CoreConfigExtras.cmake in Qt 5.5.0 sets -fPIC unconditionally:
@@ -1452,6 +1468,8 @@ set(LIBEPAN_LIBS
${GNUTLS_LIBRARIES}
${SMI_LIBRARIES}
${ZLIB_LIBRARIES}
+ ${LZ4_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
${M_LIBRARIES}
${WINSPARKLE_LIBRARIES}
)
diff --git a/CMakeOptions.txt b/CMakeOptions.txt
index fa0d354e7d..00351ed49c 100644
--- a/CMakeOptions.txt
+++ b/CMakeOptions.txt
@@ -61,6 +61,8 @@ option(ENABLE_PCAP_NG_DEFAULT "Enable pcap-ng as default file format" ON)
option(ENABLE_PORTAUDIO "Build with PortAudio support" ON)
option(ENABLE_ZLIB "Build with zlib compression support" ON)
+option(ENABLE_LZ4 "Build with LZ4 compression support" ON)
+option(ENABLE_SNAPPY "Build with Snappy compression support" ON)
option(ENABLE_LUA "Build with Lua dissector support" ON)
option(ENABLE_SMI "Build with libsmi snmp support" ON)
option(ENABLE_GNUTLS "Build with GNU TLS support" ON)
diff --git a/acinclude.m4 b/acinclude.m4
index 8d5efd37de..38cc9f2713 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1920,3 +1920,163 @@ AC_DEFUN([AC_WIRESHARK_QT_TOOL_CHECK_LRELEASE],
])
AC_MSG_RESULT([ok, $lrelease_version])
])
+
+#
+# AC_WIRESHARK_LZ4_CHECK
+#
+AC_DEFUN([AC_WIRESHARK_LZ4_CHECK],
+[
+ AC_WIRESHARK_PUSH_FLAGS
+
+ if test "x$lz4_dir" != "x"
+ then
+ #
+ # The user specified a directory in which lz4 resides,
+ # so add the "include" subdirectory of that directory to
+ # the include file search path and the "lib" subdirectory
+ # of that directory to the library search path.
+ #
+ # XXX - if there's also a lz4 in a directory that's
+ # already in CPPFLAGS or LDFLAGS, this won't make us find
+ # the version in the specified directory, as the compiler
+ # and/or linker will search that other directory before it
+ # searches the specified directory.
+ #
+ LZ4_CFLAGS="-I$lz4_dir/include"
+ fi
+
+ #
+ # Make sure we have "lz4.h". If we don't, it means we probably
+ # don't have lz4, so don't use it.
+ #
+ AC_CHECK_HEADER(lz4.h,,
+ [
+ if test "x$lz4_dir" != "x"
+ then
+ #
+ # The user used "--with-lz4=" to specify a directory
+ # containing lz4, but we didn't find the header file
+ # there; that either means they didn't specify the
+ # right directory or are confused about whether lz4
+ # is, in fact, installed. Report the error and give up.
+ #
+ AC_MSG_ERROR([lz4 header not found in directory specified in --with-lz4])
+ else
+ if test "x$want_lz4" = "xyes"
+ then
+ #
+ # The user tried to force us to use the library, but we
+ # couldn't find the header file; report an error.
+ #
+ AC_MSG_ERROR(Header file lz4.h not found.)
+ else
+ #
+ # We couldn't find the header file; don't use the
+ # library, as it's probably not present.
+ #
+ want_lz4=no
+ fi
+ fi
+ ])
+
+ if test "x$want_lz4" != "xno"
+ then
+ #
+ # Well, we at least have the lz4 header file.
+ # We link with lz4 to support uncompression of
+ # CQL traffic.
+ #
+ LZ4_LIBS="-llz4"
+ ac_save_LIBS="$LIBS"
+ LIBS="$LZ4_LIBS $LIBS"
+ AC_DEFINE(HAVE_LZ4, 1, [Define to use lz4 library])
+ #
+ # Check for "LZ4_decompress_safe()" in lz4, which we need
+ # in order to read compressed capture files.
+ #
+ AC_CHECK_FUNCS(LZ4_decompress_safe)
+ LIBS="$ac_save_LIBS"
+ fi
+
+ AC_WIRESHARK_POP_FLAGS
+])
+
+#
+# AC_WIRESHARK_SNAPPY_CHECK
+#
+AC_DEFUN([AC_WIRESHARK_SNAPPY_CHECK],
+[
+ AC_WIRESHARK_PUSH_FLAGS
+
+ if test "x$snappy_dir" != "x"
+ then
+ #
+ # The user specified a directory in which snappy resides,
+ # so add the "include" subdirectory of that directory to
+ # the include file search path and the "lib" subdirectory
+ # of that directory to the library search path.
+ #
+ # XXX - if there's also a snappy in a directory that's
+ # already in CPPFLAGS or LDFLAGS, this won't make us find
+ # the version in the specified directory, as the compiler
+ # and/or linker will search that other directory before it
+ # searches the specified directory.
+ #
+ SNAPPY_CFLAGS="-I$snappy_dir/include"
+ fi
+
+ #
+ # Make sure we have "snappy-c.h". If we don't, it means we probably
+ # don't have snappy, so don't use it.
+ #
+ AC_CHECK_HEADER(snappy-c.h,,
+ [
+ if test "x$snappy_dir" != "x"
+ then
+ #
+ # The user used "--with-snappy=" to specify a directory
+ # containing snappy, but we didn't find the header file
+ # there; that either means they didn't specify the
+ # right directory or are confused about whether snappy
+ # is, in fact, installed. Report the error and give up.
+ #
+ AC_MSG_ERROR([snappy-c.header not found in directory specified in --with-snappy])
+ else
+ if test "x$want_snappy" = "xyes"
+ then
+ #
+ # The user tried to force us to use the library, but we
+ # couldn't find the header file; report an error.
+ #
+ AC_MSG_ERROR(Header file snappy-c.h not found.)
+ else
+ #
+ # We couldn't find the header file; don't use the
+ # library, as it's probably not present.
+ #
+ want_snappy=no
+ fi
+ fi
+ ])
+
+ if test "x$want_snappy" != "xno"
+ then
+ #
+ # Well, we at least have the snappy-c.header file.
+ # We link with snappy to support uncompression of
+ # compressed CQL traffic.
+ #
+ SNAPPY_LIBS=-lsnappy
+ ac_save_LIBS="$LIBS"
+ LIBS="$SNAPPY_LIBS $LIBS"
+ AC_DEFINE(HAVE_SNAPPY, 1, [Define to use snappy library])
+ #
+ # Check for "snappy_uncompress()" in snappy, which we need
+ # in order to read compressed capture files.
+ #
+ AC_CHECK_FUNCS(snappy_uncompress)
+ LIBS="$ac_save_LIBS"
+ fi
+
+ AC_WIRESHARK_POP_FLAGS
+])
diff --git a/cmake/modules/FindLZ4.cmake b/cmake/modules/FindLZ4.cmake
new file mode 100644
index 0000000000..5445c573ca
--- /dev/null
+++ b/cmake/modules/FindLZ4.cmake
@@ -0,0 +1,39 @@
+#
+# - Find lz4
+# Find LZ4 includes and library
+#
+# LZ4_INCLUDE_DIRS - where to find lz4.h, etc.
+# LZ4_LIBRARIES - List of libraries when using lz4.
+# LZ4_FOUND - True if lz4 found.
+
+find_package(PkgConfig)
+pkg_search_module(LZ4 lz4 liblz4)
+
+find_path(LZ4_INCLUDE_DIR
+ NAMES lz4.h
+ HINTS "${LZ4_INCLUDEDIR}"
+ PATHS
+ /usr/local/include
+ /usr/include
+)
+
+find_library(LZ4_LIBRARY
+ NAMES lz4 liblz4
+ HINTS "${LZ4_LIBDIR}"
+ PATHS
+ /usr/local/lib
+ /usr/lib
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args( LZ4 DEFAULT_MSG LZ4_INCLUDE_DIR LZ4_LIBRARY )
+
+if( LZ4_FOUND )
+ set( LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR} )
+ set( LZ4_LIBRARIES ${LZ4_LIBRARY} )
+else()
+ set( LZ4_INCLUDE_DIRS )
+ set( LZ4_LIBRARIES )
+endif()
+
+mark_as_advanced( LZ4_LIBRARIES LZ4_INCLUDE_DIRS )
diff --git a/cmake/modules/FindSNAPPY.cmake b/cmake/modules/FindSNAPPY.cmake
new file mode 100644
index 0000000000..cc018bbcba
--- /dev/null
+++ b/cmake/modules/FindSNAPPY.cmake
@@ -0,0 +1,38 @@
+#
+# - Find snappy
+# Find Snappy includes and library
+#
+# SNAPPY_INCLUDE_DIRS - where to find snappy.h, etc.
+# SNAPPY_LIBRARIES - List of libraries when using snappy.
+# SNAPPY_FOUND - True if snappy found.
+
+find_package(PkgConfig)
+pkg_search_module(SNAPPY libsnappy)
+
+find_path(SNAPPY_INCLUDE_DIR
+ NAMES snappy.h
+ HINTS "${SNAPPY_INCLUDEDIR}"
+ /usr/include
+ /usr/local/include
+)
+
+find_library(SNAPPY_LIBRARY
+ NAMES snappy
+ HINTS "${SNAPPY_LIBDIR}"
+ PATHS
+ /usr/lib
+ /usr/local/lib
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args( SNAPPY DEFAULT_MSG SNAPPY_INCLUDE_DIR SNAPPY_LIBRARY )
+
+if( SNAPPY_FOUND )
+ set( SNAPPY_INCLUDE_DIRS ${SNAPPY_INCLUDE_DIR} )
+ set( SNAPPY_LIBRARIES ${SNAPPY_LIBRARY} )
+else()
+ set( SNAPPY_INCLUDE_DIRS )
+ set( SNAPPY_LIBRARIES )
+endif()
+
+mark_as_advanced( SNAPPY_LIBRARIES SNAPPY_INCLUDE_DIRS )
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index 4856a22e54..71ea10cbd0 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -160,6 +160,12 @@
/* Define to use zlib library */
#cmakedefine HAVE_ZLIB 1
+/* Define to use lz4 library */
+#cmakedefine HAVE_LZ4 1
+
+/* Define to use snappy library */
+#cmakedefine HAVE_SNAPPY 1
+
/* Define to 1 if you have the <linux/sockios.h> header file. */
#cmakedefine HAVE_LINUX_SOCKIOS_H 1
diff --git a/configure.ac b/configure.ac
index 2fbf021c98..378477a1de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1995,6 +1995,92 @@ else
fi
fi
+dnl lz4 check
+LZ4_LIBS=''
+AC_MSG_CHECKING(whether to use lz4 compression and decompression)
+
+AC_ARG_WITH(lz4,
+ AC_HELP_STRING([--with-lz4@<:@=DIR@:>@],
+ [use lz4 (located in directory DIR, if supplied) for lz4 compression and decompression @<:@default=yes, if available@:>@]),
+[
+ if test "x$withval" = "xno"
+ then
+ want_lz4=no
+ elif test "x$withval" = "xyes"
+ then
+ want_lz4=yes
+ else
+ want_lz4=yes
+ lz4_dir="$withval"
+ fi
+],[
+ #
+ # Use lz4 if it's present, otherwise don't.
+ #
+ want_lz4=ifavailable
+ lz4_dir=
+])
+have_lz4=no
+if test "x$want_lz4" = "xno" ; then
+ AC_MSG_RESULT(no)
+else
+ AC_MSG_RESULT(yes)
+ AC_WIRESHARK_LZ4_CHECK
+ if test "x$want_lz4" = "xno" ; then
+ AC_MSG_RESULT(lz4 not found - disabling lz4 compression and decompression)
+ else
+ if test "x$ac_cv_func_LZ4_decompress_safe" = "xno" ; then
+ AC_MSG_RESULT(LZ4_decompress_safe not found in lz4 - disabling cql lz4 decompression)
+ else
+ have_lz4=yes
+ fi
+ fi
+fi
+AC_SUBST(LZ4_LIBS)
+
+dnl snappy check
+SNAPPY_LIBS=''
+AC_MSG_CHECKING(whether to use snappy compression and decompression)
+
+AC_ARG_WITH(snappy,
+ AC_HELP_STRING([--with-snappy@<:@=DIR@:>@],
+ [use snappy (located in directory DIR, if supplied) for snappy compression and decompression @<:@default=yes, if available@:>@]),
+[
+ if test "x$withval" = "xno"
+ then
+ want_snappy=no
+ elif test "x$withval" = "xyes"
+ then
+ want_snappy=yes
+ else
+ want_snappy=yes
+ snappy_dir="$withval"
+ fi
+],[
+ #
+ # Use snappy if it's present, otherwise don't.
+ #
+ want_snappy=ifavailable
+ snappy_dir=
+])
+have_snappy=no
+if test "x$want_snappy" = "xno" ; then
+ AC_MSG_RESULT(no)
+else
+ AC_MSG_RESULT(yes)
+ AC_WIRESHARK_SNAPPY_CHECK
+ if test "x$want_snappy" = "xno" ; then
+ AC_MSG_RESULT(snappy not found - disabling snappy compression and decompression)
+ else
+ if test "x$ac_cv_func_snappy_uncompress" = "xno" ; then
+ AC_MSG_RESULT(snappy_uncompress not found in snappy - disabling cql snappy decompression)
+ else
+ have_snappy=yes
+ fi
+ fi
+fi
+AC_SUBST(SNAPPY_LIBS)
+
dnl Lua check
AC_ARG_WITH(lua,
AC_HELP_STRING( [--with-lua@<:@=DIR@:>@],
@@ -3083,4 +3169,6 @@ echo " Have ssh_userauth_agent : $ssh_userauth_agent_message"
echo " Use nl library : $libnl_message"
echo " Use SBC codec library : $have_sbc"
echo " Use nghttp2 library : $nghttp2_message"
+echo " Use LZ4 library : $have_lz4"
+echo " Use Snappy library : $have_snappy"
#echo " Use GDK-Pixbuf with GResource: $have_gresource_pixbuf"
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index 4e48ff56b3..3bb415589c 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -189,17 +189,19 @@ add_lemon_files(LEMON_FILES GENERATED_FILES
set(epan_LIBS
wiretap
wsutil
- ${GLIB2_LIBRARIES}
- ${PCAP_LIBRARIES}
${CARES_LIBRARIES}
- ${KERBEROS_LIBRARIES}
- ${GEOIP_LIBRARIES}
${GCRYPT_LIBRARIES}
+ ${GEOIP_LIBRARIES}
+ ${GLIB2_LIBRARIES}
${GNUTLS_LIBRARIES}
- ${SMI_LIBRARIES}
+ ${KERBEROS_LIBRARIES}
+ ${LUA_LIBRARIES}
+ ${LZ4_LIBRARIES}
${M_LIBRARIES}
${NGHTTP2_LIBRARIES}
- ${LUA_LIBRARIES}
+ ${PCAP_LIBRARIES}
+ ${SMI_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
${WIN_PSAPI_LIBRARY}
)
diff --git a/epan/Makefile.am b/epan/Makefile.am
index e9eee8e0ba..5c53b84e94 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -40,7 +40,7 @@ DIST_SUBDIRS = $(SUBDIRS) $(wslua_dist_dir)
AM_CPPFLAGS = $(INCLUDEDIRS) -I$(builddir)/wslua $(WS_CPPFLAGS) \
$(GLIB_CFLAGS) $(LUA_CFLAGS) $(LIBGNUTLS_CFLAGS) \
$(LIBGCRYPT_CFLAGS) $(LIBSMI_CFLAGS) $(LIBGEOIP_CFLAGS) \
- $(KRB5_CFLAGS)
+ $(LZ4_CFLAGS) $(KRB5_CFLAGS) $(SNAPPY_CFLAGS)
noinst_LTLIBRARIES = libwireshark_generated.la libwireshark_asmopt.la
lib_LTLIBRARIES = libwireshark.la
@@ -323,13 +323,15 @@ libwireshark_la_LIBADD = \
${top_builddir}/wiretap/libwiretap.la \
${top_builddir}/wsutil/libwsutil.la \
@C_ARES_LIBS@ \
+ @GEOIP_LIBS@ \
+ @KRB5_LIBS@ \
@LIBGCRYPT_LIBS@ \
@LIBGNUTLS_LIBS@ \
- @KRB5_LIBS@ \
- @SSL_LIBS@ \
@LIBSMI_LDFLAGS@ \
- @GEOIP_LIBS@ \
+ @LZ4_LIBS@ \
@NGHTTP2_LIBS@ \
+ @SSL_LIBS@ \
+ @SNAPPY_LIBS@ \
@GLIB_LIBS@
libwireshark_la_DEPENDENCIES = \
diff --git a/epan/dissectors/packet-cql.c b/epan/dissectors/packet-cql.c
index e9577ed5a7..c524c3b684 100644
--- a/epan/dissectors/packet-cql.c
+++ b/epan/dissectors/packet-cql.c
@@ -31,10 +31,17 @@
#include <epan/dissectors/packet-tcp.h>
#include <epan/wmem/wmem.h>
#include <epan/expert.h>
-
+#ifdef HAVE_LZ4
+#include <lz4.h>
+#endif
+#ifdef HAVE_SNAPPY
+#include <snappy-c.h>
+#endif
#define CQL_DEFAULT_PORT 9042 /* Not IANA registered */
+/* the code can reasonably attempt to decompress buffer up to 10MB */
+#define MAX_UNCOMPRESSED_SIZE (10 * 1024 * 1024)
void proto_reg_handoff_cql(void);
void proto_register_cql(void);
@@ -71,6 +78,7 @@ static int hf_cql_value_count = -1;
static int hf_cql_short_bytes_length = -1;
static int hf_cql_bytes_length = -1;
static int hf_cql_bytes = -1;
+static int hf_cql_raw_compressed_bytes = -1;
static int hf_cql_paging_state = -1;
static int hf_cql_page_size = -1;
static int hf_cql_timestamp = -1;
@@ -515,10 +523,18 @@ cql_transaction_lookup(cql_conversation_type* conv,
return NULL;
}
+typedef enum {
+ CQL_COMPRESSION_NONE = 0,
+ CQL_COMPRESSION_LZ4 = 1,
+ CQL_COMPRESSION_SNAPPY = 2,
+ CQL_DECOMPRESSION_ATTEMPTED = 3,
+} cql_compression_level;
+
static int
-dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
+dissect_cql_tcp_pdu(tvbuff_t* raw_tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
{
proto_item* ti;
+ tvbuff_t* tvb = NULL;
proto_tree* cql_tree;
proto_tree* version_tree;
proto_tree* cql_subtree = NULL;
@@ -526,6 +542,7 @@ dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* d
proto_tree* metadata_subtree = NULL;
gint offset = 0;
+ guint8 flags = 0;
guint8 first_byte = 0;
guint8 cql_version = 0;
guint8 server_to_client = 0;
@@ -548,6 +565,7 @@ dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* d
conversation_t* conversation;
cql_conversation_type* cql_conv;
cql_transaction_type* cql_trans = NULL;
+ cql_compression_level compression_level = CQL_COMPRESSION_NONE;
static const int * cql_header_bitmaps_v3[] = {
&hf_cql_flag_compression,
@@ -568,10 +586,10 @@ dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* d
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CQL");
col_clear(pinfo->cinfo, COL_INFO);
- first_byte = tvb_get_guint8(tvb, 0);
+ first_byte = tvb_get_guint8(raw_tvb, 0);
cql_version = first_byte & (guint8)0x7F;
server_to_client = first_byte & (guint8)0x80;
- opcode = tvb_get_guint8(tvb, 4);
+ opcode = tvb_get_guint8(raw_tvb, 4);
col_add_fstr(pinfo->cinfo, COL_INFO, "v%d %s Type %s",
cql_version,
@@ -587,34 +605,34 @@ dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* d
conversation_add_proto_data(conversation, proto_cql, cql_conv);
}
- ti = proto_tree_add_item(tree, proto_cql, tvb, 0, -1, ENC_NA);
+ ti = proto_tree_add_item(tree, proto_cql, raw_tvb, 0, -1, ENC_NA);
cql_tree = proto_item_add_subtree(ti, ett_cql_protocol);
- ti = proto_tree_add_item(cql_tree, hf_cql_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ ti = proto_tree_add_item(cql_tree, hf_cql_version, raw_tvb, offset, 1, ENC_BIG_ENDIAN);
version_tree = proto_item_add_subtree(ti, ett_cql_version);
- proto_tree_add_item(version_tree, hf_cql_protocol_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(version_tree, hf_cql_direction, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(version_tree, hf_cql_protocol_version, raw_tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(version_tree, hf_cql_direction, raw_tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
switch(cql_version){
case 3:
- proto_tree_add_bitmask(cql_tree, tvb, offset, hf_cql_flags_bitmap, ett_cql_header_flags_bitmap, cql_header_bitmaps_v3, ENC_BIG_ENDIAN);
+ proto_tree_add_bitmask(cql_tree, raw_tvb, offset, hf_cql_flags_bitmap, ett_cql_header_flags_bitmap, cql_header_bitmaps_v3, ENC_BIG_ENDIAN);
break;
case 4:
- proto_tree_add_bitmask(cql_tree, tvb, offset, hf_cql_flags_bitmap, ett_cql_header_flags_bitmap, cql_header_bitmaps_v4, ENC_BIG_ENDIAN);
+ proto_tree_add_bitmask(cql_tree, raw_tvb, offset, hf_cql_flags_bitmap, ett_cql_header_flags_bitmap, cql_header_bitmaps_v4, ENC_BIG_ENDIAN);
break;
default:
- proto_tree_add_item(cql_tree, hf_cql_flags_bitmap, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(cql_tree, hf_cql_flags_bitmap, raw_tvb, offset, 1, ENC_BIG_ENDIAN);
break;
}
+ flags = tvb_get_guint8(raw_tvb, offset);
offset += 1;
- proto_tree_add_item_ret_int(cql_tree, hf_cql_stream, tvb, offset, 2, ENC_BIG_ENDIAN, &stream);
+ proto_tree_add_item_ret_int(cql_tree, hf_cql_stream, raw_tvb, offset, 2, ENC_BIG_ENDIAN, &stream);
offset += 2;
- proto_tree_add_item(cql_tree, hf_cql_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(cql_tree, hf_cql_opcode, raw_tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- proto_tree_add_item_ret_uint(cql_tree, hf_cql_length, tvb, offset, 4, ENC_BIG_ENDIAN, &message_length);
+ proto_tree_add_item_ret_uint(cql_tree, hf_cql_length, raw_tvb, offset, 4, ENC_BIG_ENDIAN, &message_length);
offset += 4;
-
/* Track the request/response. */
if (!pinfo->fd->flags.visited) {
if (server_to_client == 0) {
@@ -637,20 +655,104 @@ dissect_cql_tcp_pdu(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* d
/* Add state tracking to tree */
if (server_to_client == 0 && cql_trans->rep_frame) {
/* request */
- ti = proto_tree_add_uint(cql_tree, hf_cql_response_in, tvb, 0, 0, cql_trans->rep_frame);
+ ti = proto_tree_add_uint(cql_tree, hf_cql_response_in, raw_tvb, 0, 0, cql_trans->rep_frame);
PROTO_ITEM_SET_GENERATED(ti);
}
if (server_to_client && cql_trans->req_frame) {
/* reply */
nstime_t ns;
- ti = proto_tree_add_uint(cql_tree, hf_cql_response_to, tvb, 0, 0, cql_trans->req_frame);
+ ti = proto_tree_add_uint(cql_tree, hf_cql_response_to, raw_tvb, 0, 0, cql_trans->req_frame);
PROTO_ITEM_SET_GENERATED(ti);
nstime_delta(&ns, &pinfo->fd->abs_ts, &cql_trans->req_time);
- ti = proto_tree_add_time(cql_tree, hf_cql_response_time, tvb, 0, 0, &ns);
+ ti = proto_tree_add_time(cql_tree, hf_cql_response_time, raw_tvb, 0, 0, &ns);
PROTO_ITEM_SET_GENERATED(ti);
}
+ /* We cannot rely on compression negociation in the STARTUP message because the
+ * capture can be done at a random time hence missing the negociation.
+ * So we will first try to decompress LZ4 then snappy
+ */
+ if (flags & CQL_HEADER_FLAG_COMPRESSION) {
+ compression_level = CQL_DECOMPRESSION_ATTEMPTED;
+#ifdef HAVE_LZ4
+ if (tvb_captured_length_remaining(raw_tvb, offset) > 4) {
+ /* Set ret == 0 to make it fail in case decompression is skipped
+ * due to orig_size being too big
+ */
+ guint32 ret = 0, orig_size = tvb_get_ntohl(raw_tvb, offset);
+ guchar *decompressed_buffer = NULL;
+ offset += 4;
+
+ /* if the decompressed size is reasonably small try to decompress data */
+ if (orig_size <= MAX_UNCOMPRESSED_SIZE) {
+ decompressed_buffer = (guchar*)wmem_alloc(pinfo->pool, orig_size);
+ ret = LZ4_decompress_safe(tvb_get_ptr(raw_tvb, offset, -1),
+ decompressed_buffer,
+ tvb_captured_length_remaining(raw_tvb, offset),
+ orig_size);
+ }
+ /* Decompression attempt failed: rewind offset */
+ if (ret != orig_size) {
+ wmem_free(pinfo->pool, decompressed_buffer);
+ offset -= 4;
+ } else {
+ /* Now re-setup the tvb buffer to have the new data */
+ tvb = tvb_new_child_real_data(raw_tvb, decompressed_buffer, orig_size, orig_size);
+ add_new_data_source(pinfo, tvb, "Decompressed Data");
+ /* mark the decompression as successfull */
+ compression_level = CQL_COMPRESSION_LZ4;
+ message_length= orig_size;
+ }
+ }
+#endif
+#ifdef HAVE_SNAPPY
+ if (compression_level == CQL_DECOMPRESSION_ATTEMPTED) {
+ guchar *decompressed_buffer = NULL;
+ size_t orig_size = 0;
+ snappy_status ret;
+
+ /* get the raw data length */
+ ret = snappy_uncompressed_length(tvb_get_ptr(raw_tvb, offset, -1),
+ tvb_captured_length_remaining(raw_tvb, offset),
+ &orig_size);
+ /* if we get the length and it's reasonably short to allocate a buffer for it
+ * proceed to try decompressing the data
+ */
+ if (ret == SNAPPY_OK && orig_size <= MAX_UNCOMPRESSED_SIZE) {
+ decompressed_buffer = (guchar*)wmem_alloc(pinfo->pool, orig_size);
+
+ ret = snappy_uncompress(tvb_get_ptr(raw_tvb, offset, -1),
+ tvb_captured_length_remaining(raw_tvb, offset),
+ decompressed_buffer,
+ &orig_size);
+ } else {
+ /* else mark the input as invalid in order to skip the rest of the
+ * procedure
+ */
+ ret = SNAPPY_INVALID_INPUT;
+ }
+ /* if the decompression succeeded build the new tvb */
+ if (ret == SNAPPY_OK) {
+ tvb = tvb_new_child_real_data(raw_tvb, decompressed_buffer, orig_size, orig_size);
+ add_new_data_source(pinfo, tvb, "Decompressed Data");
+ compression_level = CQL_COMPRESSION_SNAPPY;
+ message_length= orig_size;
+ }
+ }
+#endif
+ }
+ if (compression_level == CQL_COMPRESSION_NONE) {
+ /* In case of decompression failure or uncompressed packet */
+ tvb = tvb_new_subset_remaining(raw_tvb, offset);
+ } else if (compression_level == CQL_DECOMPRESSION_ATTEMPTED) {
+ proto_tree_add_item(cql_tree, hf_cql_raw_compressed_bytes, raw_tvb, offset,
+ tvb_captured_length_remaining(raw_tvb, offset), ENC_NA);
+ return tvb_captured_length(raw_tvb);
+ }
+ offset = 0;
+
+
/* Dissect the operation. */
if (server_to_client == 0) {
switch (opcode) {
@@ -1375,6 +1477,16 @@ proto_register_cql(void)
}
},
{
+ &hf_cql_raw_compressed_bytes,
+ {
+ "Raw compressed bytes", "cql.raw_compressed_bytes",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ "Raw byte that failed to be decompressed", HFILL
+ }
+ },
+
+ {
&hf_cql_paging_state,
{
"Paging State", "cql.paging_state",
diff --git a/epan/epan.c b/epan/epan.c
index 056a447fbb..82e0d397e6 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -574,6 +574,23 @@ epan_get_compiled_version_info(GString *str)
#else
g_string_append(str, "without nghttp2");
#endif /* HAVE_NGHTTP2 */
+
+ /* LZ4 */
+ g_string_append(str, ", ");
+#ifdef HAVE_LZ4
+ g_string_append(str, "with LZ4");
+#else
+ g_string_append(str, "without LZ4");
+#endif /* HAVE_LZ4 */
+
+ /* Snappy */
+ g_string_append(str, ", ");
+#ifdef HAVE_SNAPPY
+ g_string_append(str, "with Snappy");
+#else
+ g_string_append(str, "without Snappy");
+#endif /* HAVE_SNAPPY */
+
}
/*