diff options
author | Dave Rigby <daver@couchbase.com> | 2016-02-03 12:32:25 +0000 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2016-02-04 05:02:54 +0000 |
commit | 2a2cb9dace5179565dcdd87bd60aef1c94440af4 (patch) | |
tree | 23b21f94f3dfc7120e2b62469af688edf3734695 /epan/dissectors/packet-couchbase.c | |
parent | 8899e006aab3e0831214d187596eef450b5e21b7 (diff) |
Couchbase: Dissect multi-path mutation responses
Multi-path mutation responses can have a variable number of values
encoded in them:
- Successful requests have 0..N values, one for each mutation which
wishes to return a value (e.g. SUBDOC_COUNTER)
- Unsuccessful requests have 1 value, specifying the index and status
of the first failing mutation
Add support for decoding a variable number of response values.
Change-Id: Ia1f682f7f701829bd808a44ee142ffe912095e15
Reviewed-on: https://code.wireshark.org/review/13688
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-couchbase.c')
-rw-r--r-- | epan/dissectors/packet-couchbase.c | 73 |
1 files changed, 53 insertions, 20 deletions
diff --git a/epan/dissectors/packet-couchbase.c b/epan/dissectors/packet-couchbase.c index 2888680614..c28a41cfa1 100644 --- a/epan/dissectors/packet-couchbase.c +++ b/epan/dissectors/packet-couchbase.c @@ -1,7 +1,7 @@ /* packet-couchbase.c * * Routines for Couchbase Protocol - * Copyright 2015, Dave Rigby <daver@couchbase.com> + * Copyright 2015-2016, Dave Rigby <daver@couchbase.com> * Copyright 2011, Sergey Avseyev <sergey.avseyev@gmail.com> * * With contributions from Mark Woosey <mark@markwoosey.com> @@ -1202,6 +1202,56 @@ dissect_multipath_lookup_response(tvbuff_t *tvb, packet_info *pinfo, } static void +dissect_multipath_mutation_response(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, gint offset, guint32 value_len) +{ + gint end = offset + value_len; + int spec_idx = 0; + + /* Expect a variable number of mutation responses: + * - If response.status == SUCCESS, zero to N responses, one for each mutation + * spec which returns a value. + * - If response.status != SUCCESS, exactly 1 response, for first failing + * spec. + */ + while (offset < end) { + proto_item *ti; + proto_tree *multipath_tree; + tvbuff_t *json_tvb; + guint32 status; + gint start_offset = offset; + + ti = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_multipath, + &multipath_tree, "Mutation Result [ %u ]", + spec_idx); + + proto_tree_add_item(multipath_tree, hf_multipath_index, tvb, offset, 1, + ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item_ret_uint(multipath_tree, hf_status, tvb, offset, 2, + ENC_BIG_ENDIAN, &status); + offset += 2; + if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) { + guint32 result_len; + proto_tree_add_item_ret_uint(multipath_tree, hf_value_length, tvb, + offset, 4, ENC_BIG_ENDIAN, &result_len); + offset += 4; + + proto_tree_add_item(multipath_tree, hf_value, tvb, offset, result_len, + ENC_ASCII | ENC_NA); + if (result_len > 0) { + json_tvb = tvb_new_subset(tvb, offset, result_len, result_len); + call_dissector(json_handle, json_tvb, pinfo, multipath_tree); + } + offset += result_len; + } + proto_item_set_len(ti, offset - start_offset); + + spec_idx++; + } +} + +static void dissect_multipath_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint32 value_len, gboolean is_mutation, gboolean request) @@ -1261,15 +1311,8 @@ dissect_multipath_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, spec_idx++; } } else { - /* Response - for lookup we expect one lookup_result per path. */ if (is_mutation) { - ti = proto_tree_add_item(tree, hf_value, tvb, offset, value_len, - ENC_ASCII | ENC_NA); - - expert_add_info_format(pinfo, ti, &ef_warn_shall_not_have_value, - "%s Response shall not have Value", - val_to_str_ext(PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION, - &opcode_vals_ext, "Opcode 0x%x")); + dissect_multipath_mutation_response(tvb, pinfo, tree, offset, value_len); } else { dissect_multipath_lookup_response(tvb, pinfo, tree, offset, value_len); } @@ -1566,17 +1609,7 @@ dissect_couchbase(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat dissect_multipath_lookup_response(tvb, pinfo, tree, offset, value_len); } else if (opcode == PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION) { - /* Upon non-success includes the index and status code of first path - * to fail. - */ - proto_tree *multipath_tree; - multipath_tree = proto_item_add_subtree(ti, ett_multipath); - - proto_tree_add_item(multipath_tree, hf_status, tvb, offset, 2, - ENC_BIG_ENDIAN); - offset += 2; - proto_tree_add_item(multipath_tree, hf_multipath_index, tvb, offset, 1, - ENC_BIG_ENDIAN); + dissect_multipath_mutation_response(tvb, pinfo, tree, offset, value_len); } col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_ext(status, &status_vals_ext, "Unknown status: 0x%x")); |