cql: add lz4 and snappy decompression

We do not use the STARTUP negotiation since a stream
can be captured in its middle but try to decompress
if the flag is present and fallback if it fails.

Change-Id: Iecbf49a45220b04be7808869c9884548eb1e7694
Signed-off-by: Benoît Canet <benoit@scylladb.com>
Reviewed-on: https://code.wireshark.org/review/17952
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
This commit is contained in:
Benoît Canet 2016-09-26 16:25:11 +02:00 committed by Pascal Quantin
parent 5c42d8a24c
commit 47649d1c7f
11 changed files with 512 additions and 28 deletions

View File

@ -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}
)

View File

@ -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)

View File

@ -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
])

View File

@ -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 )

View File

@ -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 )

View File

@ -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

View File

@ -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"

View File

@ -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}
)

View File

@ -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 = \

View File

@ -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) {
@ -1374,6 +1476,16 @@ proto_register_cql(void)
"Raw byte array", HFILL
}
},
{
&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,
{

View File

@ -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 */
}
/*