2014-07-09 12:58:13 +00:00
/* packet-couchbase.c
*
* Routines for Couchbase Protocol
2018-02-05 09:34:13 +00:00
*
2019-07-17 09:32:36 +00:00
* Copyright 2019 , Trond Norbye < trond @ couchbase . com >
2018-02-05 09:34:13 +00:00
* Copyright 2018 , Jim Walker < jim @ couchbase . com >
2016-02-03 12:32:25 +00:00
* Copyright 2015 - 2016 , Dave Rigby < daver @ couchbase . com >
2014-07-09 12:58:13 +00:00
* Copyright 2011 , Sergey Avseyev < sergey . avseyev @ gmail . com >
*
* With contributions from Mark Woosey < mark @ markwoosey . com >
*
*
* Based on packet - memcache . c : mecmcache binary protocol .
*
* Routines for Memcache Binary Protocol
* http : //code.google.com/p/memcached/wiki/MemcacheBinaryProtocol
*
* Copyright 2009 , Stig Bjorlykke < stig @ bjorlykke . org >
*
* Routines for Memcache Textual Protocol
* http : //code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt
*
* Copyright 2009 , Rama Chitta < rama @ gear6 . com >
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
2018-02-12 11:23:27 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2014-07-09 12:58:13 +00:00
*/
# include "config.h"
# include <epan/packet.h>
# include <epan/prefs.h>
# include <epan/expert.h>
2017-12-20 21:24:35 +00:00
# ifdef HAVE_SNAPPY
# include <snappy-c.h>
# endif
2014-07-09 12:58:13 +00:00
# include "packet-tcp.h"
2018-09-14 15:30:31 +00:00
# include "packet-tls.h"
2014-07-09 12:58:13 +00:00
2018-02-05 14:40:33 +00:00
# include <math.h>
2014-07-09 12:58:13 +00:00
# define PNAME "Couchbase Protocol"
# define PSNAME "Couchbase"
# define PFNAME "couchbase"
2014-12-10 01:19:55 +00:00
# define COUCHBASE_DEFAULT_PORT "11210"
2014-07-09 12:58:13 +00:00
# define COUCHBASE_HEADER_LEN 24
2022-02-22 11:55:54 +00:00
/* Magic Byte */
enum {
/**
* The magic used for a normal request sent from the client to the
* server . Layout described in :
* https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#request-header
*/
MAGIC_CLIENT_REQUEST = 0x80 ,
/**
* The magic used for a normal response sent from the server to
* the client . Layout described in :
* https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#response-header
*/
MAGIC_CLIENT_RESPONSE = 0x81 ,
/**
* The magic used when the client want to inject a set of extensions
* to the command sent to the server . Layout described in :
* https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#request-header-with-flexible-framing-extras
*/
MAGIC_CLIENT_RESPONSE_FLEX = 0x18 ,
/**
* The magic used by the server when the server needs to inject a set of
* extensions in the response packet . Layout described in :
* https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#response-header-with-flexible-framing-extras
*/
MAGIC_CLIENT_REQUEST_FLEX = 0x08 ,
/**
* The magic used for server initiated push requests . These packets
* use the same layout as client flex request packets ( with a different
* namespace for the frame id ' s )
*/
MAGIC_SERVER_REQUEST = 0x82 ,
/**
* The magic used for responses to server initiated push requests . These
* packets use the same layout as client flex response packet ( with
* a different namespace for the frame id ' s )
*/
MAGIC_SERVER_RESPONSE = 0x83
} ;
/** Does the magic represent a flex encoded packet type */
static bool is_flex_encoded ( guint8 magic ) {
switch ( magic ) {
case MAGIC_CLIENT_RESPONSE_FLEX :
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_SERVER_REQUEST :
case MAGIC_SERVER_RESPONSE :
return TRUE ;
case MAGIC_CLIENT_REQUEST :
case MAGIC_CLIENT_RESPONSE :
default :
return FALSE ;
}
}
/** Does the magic represent server initiated packet types */
static bool is_server_magic ( guint8 magic ) {
switch ( magic ) {
case MAGIC_SERVER_REQUEST :
case MAGIC_SERVER_RESPONSE :
return TRUE ;
case MAGIC_CLIENT_RESPONSE_FLEX :
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_CLIENT_REQUEST :
case MAGIC_CLIENT_RESPONSE :
default :
return FALSE ;
}
}
/** Does the magic represent a request or a response */
static bool is_request_magic ( guint8 magic ) {
switch ( magic ) {
case MAGIC_SERVER_REQUEST :
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_CLIENT_REQUEST :
return TRUE ;
case MAGIC_SERVER_RESPONSE :
case MAGIC_CLIENT_RESPONSE_FLEX :
case MAGIC_CLIENT_RESPONSE :
default :
return FALSE ;
}
}
2014-07-09 12:58:13 +00:00
/* Response Status */
2022-02-21 08:34:07 +00:00
# define STATUS_SUCCESS 0x00
# define STATUS_KEY_ENOENT 0x01
# define STATUS_KEY_EEXISTS 0x02
# define STATUS_E2BIG 0x03
# define STATUS_EINVAL 0x04
# define STATUS_NOT_STORED 0x05
# define STATUS_DELTA_BADVAL 0x06
# define STATUS_NOT_MY_VBUCKET 0x07
# define STATUS_NO_VBUCKET 0x08
# define STATUS_LOCKED 0x09
# define STATUS_DCP_STREAM_NOT_FOUND 0x0a
# define STATUS_OPAQUE_NO_MATCH 0x0b
2022-08-16 10:34:18 +00:00
# define STATUS_EWOULDTHROTTLE 0x0c
# define STATUS_ECONFIGONLY 0x0d
2022-02-21 08:34:07 +00:00
# define STATUS_AUTH_STALE 0x1f
# define STATUS_AUTH_ERROR 0x20
# define STATUS_AUTH_CONTINUE 0x21
# define STATUS_ERANGE 0x22
# define STATUS_ROLLBACK 0x23
# define STATUS_EACCESS 0x24
# define STATUS_NOT_INITIALIZED 0x25
# define STATUS_RATELIMITED_NETWORK_INGRESS 0x30
# define STATUS_RATELIMITED_NETWORK_EGRESS 0x31
# define STATUS_RATELIMITED_MAX_CONNECTIONS 0x32
# define STATUS_RATELIMITED_MAX_COMMANDS 0x33
# define STATUS_SCOPE_SIZE_LIMIT_EXCEEDED 0x34
# define STATUS_UNKNOWN_COMMAND 0x81
# define STATUS_ENOMEM 0x82
# define STATUS_NOT_SUPPORTED 0x83
# define STATUS_EINTERNAL 0x84
# define STATUS_EBUSY 0x85
# define STATUS_ETMPFAIL 0x86
# define STATUS_XATTR_EINVAL 0x87
# define STATUS_UNKNOWN_COLLECTION 0x88
# define STATUS_NO_COLLECTIONS_MANIFEST 0x89
# define STATUS_CANNOT_APPLY_MANIFEST 0x8a
# define STATUS_MANIFEST_IS_AHEAD 0x8b
# define STATUS_UNKNOWN_SCOPE 0x8c
# define STATUS_DCP_STREAMID_INVALID 0x8d
# define STATUS_DURABILITY_INVALID_LEVEL 0xa0
# define STATUS_DURABILITY_IMPOSSIBLE 0xa1
# define STATUS_SYNC_WRITE_IN_PROGRESS 0xa2
# define STATUS_SYNC_WRITE_AMBIGUOUS 0xa3
# define STATUS_SYNC_WRITE_RECOMMIT_IN_PROGRESS 0xa4
2022-08-16 10:34:18 +00:00
# define STATUS_RANGE_SCAN_CANCELLED 0xa5
# define STATUS_RANGE_SCAN_MORE 0xa6
# define STATUS_RANGE_SCAN_COMPLETE 0xa7
2022-10-19 14:00:37 +00:00
# define STATUS_VBUUID_NOT_EQUAL 0xa8
2022-02-21 08:34:07 +00:00
# define STATUS_SUBDOC_PATH_ENOENT 0xc0
# define STATUS_SUBDOC_PATH_MISMATCH 0xc1
# define STATUS_SUBDOC_PATH_EINVAL 0xc2
# define STATUS_SUBDOC_PATH_E2BIG 0xc3
# define STATUS_SUBDOC_DOC_E2DEEP 0xc4
# define STATUS_SUBDOC_VALUE_CANTINSERT 0xc5
# define STATUS_SUBDOC_DOC_NOTJSON 0xc6
# define STATUS_SUBDOC_NUM_ERANGE 0xc7
# define STATUS_SUBDOC_DELTA_ERANGE 0xc8
# define STATUS_SUBDOC_PATH_EEXISTS 0xc9
# define STATUS_SUBDOC_VALUE_ETOODEEP 0xca
# define STATUS_SUBDOC_INVALID_COMBO 0xcb
# define STATUS_SUBDOC_MULTI_PATH_FAILURE 0xcc
# define STATUS_SUBDOC_SUCCESS_DELETED 0xcd
# define STATUS_SUBDOC_XATTR_INVALID_FLAG_COMBO 0xce
# define STATUS_SUBDOC_XATTR_INVALID_KEY_COMBO 0xcf
# define STATUS_SUBDOC_XATTR_UNKNOWN_MACRO 0xd0
# define STATUS_SUBDOC_XATTR_UNKNOWN_VATTR 0xd1
# define STATUS_SUBDOC_XATTR_CANT_MODIFY_VATTR 0xd2
# define STATUS_SUBDOC_MULTI_PATH_FAILURE_DELETED 0xd3
# define STATUS_SUBDOC_INVALID_XATTR_ORDER 0xd4
# define STATUS_SUBDOC_XATTR_UNKNOWN_VATTR_MACRO 0xd5
# define STATUS_SUBDOC_CAN_ONLY_REVIVE_DELETED_DOCUMENTS 0xd6
# define STATUS_SUBDOC_DELETED_DOCUMENT_CANT_HAVE_VALUE 0xd7
2014-07-09 12:58:13 +00:00
/* Command Opcodes */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_GET 0x00
# define CLIENT_OPCODE_SET 0x01
# define CLIENT_OPCODE_ADD 0x02
# define CLIENT_OPCODE_REPLACE 0x03
# define CLIENT_OPCODE_DELETE 0x04
# define CLIENT_OPCODE_INCREMENT 0x05
# define CLIENT_OPCODE_DECREMENT 0x06
# define CLIENT_OPCODE_QUIT 0x07
# define CLIENT_OPCODE_FLUSH 0x08
# define CLIENT_OPCODE_GETQ 0x09
# define CLIENT_OPCODE_NOOP 0x0a
# define CLIENT_OPCODE_VERSION 0x0b
# define CLIENT_OPCODE_GETK 0x0c
# define CLIENT_OPCODE_GETKQ 0x0d
# define CLIENT_OPCODE_APPEND 0x0e
# define CLIENT_OPCODE_PREPEND 0x0f
# define CLIENT_OPCODE_STAT 0x10
# define CLIENT_OPCODE_SETQ 0x11
# define CLIENT_OPCODE_ADDQ 0x12
# define CLIENT_OPCODE_REPLACEQ 0x13
# define CLIENT_OPCODE_DELETEQ 0x14
# define CLIENT_OPCODE_INCREMENTQ 0x15
# define CLIENT_OPCODE_DECREMENTQ 0x16
# define CLIENT_OPCODE_QUITQ 0x17
# define CLIENT_OPCODE_FLUSHQ 0x18
# define CLIENT_OPCODE_APPENDQ 0x19
# define CLIENT_OPCODE_PREPENDQ 0x1a
# define CLIENT_OPCODE_VERBOSITY 0x1b
# define CLIENT_OPCODE_TOUCH 0x1c
# define CLIENT_OPCODE_GAT 0x1d
# define CLIENT_OPCODE_GATQ 0x1e
# define CLIENT_OPCODE_HELLO 0x1f
2014-07-09 12:58:13 +00:00
/* SASL operations */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_SASL_LIST_MECHS 0x20
# define CLIENT_OPCODE_SASL_AUTH 0x21
# define CLIENT_OPCODE_SASL_STEP 0x22
2014-07-09 12:58:13 +00:00
2014-11-18 18:11:22 +00:00
/* Control */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_IOCTL_GET 0x23
# define CLIENT_OPCODE_IOCTL_SET 0x24
# define CLIENT_OPCODE_CONFIG_VALIDATE 0x25
# define CLIENT_OPCODE_CONFIG_RELOAD 0x26
# define CLIENT_OPCODE_AUDIT_PUT 0x27
# define CLIENT_OPCODE_AUDIT_CONFIG_RELOAD 0x28
# define CLIENT_OPCODE_SHUTDOWN 0x29
2014-11-18 18:11:22 +00:00
2014-07-09 12:58:13 +00:00
/* Range operations.
* These commands are used for range operations and exist within
* protocol_binary . h for use in other projects . Range operations are
* not expected to be implemented in the memcached server itself .
*/
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_RGET 0x30
# define CLIENT_OPCODE_RSET 0x31
# define CLIENT_OPCODE_RSETQ 0x32
# define CLIENT_OPCODE_RAPPEND 0x33
# define CLIENT_OPCODE_RAPPENDQ 0x34
# define CLIENT_OPCODE_RPREPEND 0x35
# define CLIENT_OPCODE_RPREPENDQ 0x36
# define CLIENT_OPCODE_RDELETE 0x37
# define CLIENT_OPCODE_RDELETEQ 0x38
# define CLIENT_OPCODE_RINCR 0x39
# define CLIENT_OPCODE_RINCRQ 0x3a
# define CLIENT_OPCODE_RDECR 0x3b
# define CLIENT_OPCODE_RDECRQ 0x3c
2014-07-09 12:58:13 +00:00
/* VBucket commands */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_SET_VBUCKET 0x3d
# define CLIENT_OPCODE_GET_VBUCKET 0x3e
# define CLIENT_OPCODE_DEL_VBUCKET 0x3f
2014-07-09 12:58:13 +00:00
/* TAP commands */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_TAP_CONNECT 0x40
# define CLIENT_OPCODE_TAP_MUTATION 0x41
# define CLIENT_OPCODE_TAP_DELETE 0x42
# define CLIENT_OPCODE_TAP_FLUSH 0x43
# define CLIENT_OPCODE_TAP_OPAQUE 0x44
# define CLIENT_OPCODE_TAP_VBUCKET_SET 0x45
# define CLIENT_OPCODE_TAP_CHECKPOINT_START 0x46
# define CLIENT_OPCODE_TAP_CHECKPOINT_END 0x47
2014-07-09 12:58:13 +00:00
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_GET_ALL_VB_SEQNOS 0x48
2015-10-30 07:39:01 +00:00
2022-02-15 14:07:27 +00:00
/* DCP commands */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_DCP_OPEN_CONNECTION 0x50
# define CLIENT_OPCODE_DCP_ADD_STREAM 0x51
# define CLIENT_OPCODE_DCP_CLOSE_STREAM 0x52
# define CLIENT_OPCODE_DCP_STREAM_REQUEST 0x53
# define CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST 0x54
# define CLIENT_OPCODE_DCP_STREAM_END 0x55
# define CLIENT_OPCODE_DCP_SNAPSHOT_MARKER 0x56
# define CLIENT_OPCODE_DCP_MUTATION 0x57
# define CLIENT_OPCODE_DCP_DELETION 0x58
# define CLIENT_OPCODE_DCP_EXPIRATION 0x59
# define CLIENT_OPCODE_DCP_FLUSH 0x5a
# define CLIENT_OPCODE_DCP_SET_VBUCKET_STATE 0x5b
# define CLIENT_OPCODE_DCP_NOOP 0x5c
# define CLIENT_OPCODE_DCP_BUFFER_ACKNOWLEDGEMENT 0x5d
# define CLIENT_OPCODE_DCP_CONTROL 0x5e
# define CLIENT_OPCODE_DCP_SYSTEM_EVENT 0x5f
# define CLIENT_OPCODE_DCP_PREPARE 0x60
# define CLIENT_OPCODE_DCP_SEQNO_ACK 0x61
# define CLIENT_OPCODE_DCP_COMMIT 0x62
# define CLIENT_OPCODE_DCP_ABORT 0x63
# define CLIENT_OPCODE_DCP_SEQNO_ADVANCED 0x64
# define CLIENT_OPCODE_DCP_OSO_SNAPSHOT 0x65
2022-02-15 14:07:27 +00:00
2014-07-09 12:58:13 +00:00
/* Commands from EP (eventually persistent) and bucket engines */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_STOP_PERSISTENCE 0x80
# define CLIENT_OPCODE_START_PERSISTENCE 0x81
# define CLIENT_OPCODE_SET_PARAM 0x82
# define CLIENT_OPCODE_GET_REPLICA 0x83
# define CLIENT_OPCODE_CREATE_BUCKET 0x85
# define CLIENT_OPCODE_DELETE_BUCKET 0x86
# define CLIENT_OPCODE_LIST_BUCKETS 0x87
# define CLIENT_OPCODE_EXPAND_BUCKET 0x88
# define CLIENT_OPCODE_SELECT_BUCKET 0x89
# define CLIENT_OPCODE_START_REPLICATION 0x90
# define CLIENT_OPCODE_OBSERVE_SEQNO 0x91
# define CLIENT_OPCODE_OBSERVE 0x92
# define CLIENT_OPCODE_EVICT_KEY 0x93
# define CLIENT_OPCODE_GET_LOCKED 0x94
# define CLIENT_OPCODE_UNLOCK_KEY 0x95
# define CLIENT_OPCODE_SYNC 0x96
# define CLIENT_OPCODE_LAST_CLOSED_CHECKPOINT 0x97
# define CLIENT_OPCODE_RESTORE_FILE 0x98
# define CLIENT_OPCODE_RESTORE_ABORT 0x99
# define CLIENT_OPCODE_RESTORE_COMPLETE 0x9a
# define CLIENT_OPCODE_ONLINE_UPDATE_START 0x9b
# define CLIENT_OPCODE_ONLINE_UPDATE_COMPLETE 0x9c
# define CLIENT_OPCODE_ONLINE_UPDATE_REVERT 0x9d
# define CLIENT_OPCODE_DEREGISTER_TAP_CLIENT 0x9e
# define CLIENT_OPCODE_RESET_REPLICATION_CHAIN 0x9f
# define CLIENT_OPCODE_GET_META 0xa0
# define CLIENT_OPCODE_GETQ_META 0xa1
# define CLIENT_OPCODE_SET_WITH_META 0xa2
# define CLIENT_OPCODE_SETQ_WITH_META 0xa3
# define CLIENT_OPCODE_ADD_WITH_META 0xa4
# define CLIENT_OPCODE_ADDQ_WITH_META 0xa5
# define CLIENT_OPCODE_SNAPSHOT_VB_STATES 0xa6
# define CLIENT_OPCODE_VBUCKET_BATCH_COUNT 0xa7
# define CLIENT_OPCODE_DEL_WITH_META 0xa8
# define CLIENT_OPCODE_DELQ_WITH_META 0xa9
# define CLIENT_OPCODE_CREATE_CHECKPOINT 0xaa
# define CLIENT_OPCODE_NOTIFY_VBUCKET_UPDATE 0xac
# define CLIENT_OPCODE_ENABLE_TRAFFIC 0xad
# define CLIENT_OPCODE_DISABLE_TRAFFIC 0xae
# define CLIENT_OPCODE_IFCONFIG 0xaf
# define CLIENT_OPCODE_CHANGE_VB_FILTER 0xb0
# define CLIENT_OPCODE_CHECKPOINT_PERSISTENCE 0xb1
# define CLIENT_OPCODE_RETURN_META 0xb2
# define CLIENT_OPCODE_COMPACT_DB 0xb3
# define CLIENT_OPCODE_SET_CLUSTER_CONFIG 0xb4
# define CLIENT_OPCODE_GET_CLUSTER_CONFIG 0xb5
# define CLIENT_OPCODE_GET_RANDOM_KEY 0xb6
# define CLIENT_OPCODE_SEQNO_PERSISTENCE 0xb7
# define CLIENT_OPCODE_GET_KEYS 0xb8
# define CLIENT_OPCODE_COLLECTIONS_SET_MANIFEST 0xb9
# define CLIENT_OPCODE_COLLECTIONS_GET_MANIFEST 0xba
# define CLIENT_OPCODE_COLLECTIONS_GET_ID 0xbb
# define CLIENT_OPCODE_COLLECTIONS_GET_SCOPE_ID 0xbc
# define CLIENT_OPCODE_SET_DRIFT_COUNTER_STATE 0xc1
# define CLIENT_OPCODE_GET_ADJUSTED_TIME 0xc2
2018-03-20 12:21:08 +00:00
2015-08-20 15:05:57 +00:00
/* Sub-document API commands */
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_SUBDOC_GET 0xc5
# define CLIENT_OPCODE_SUBDOC_EXISTS 0xc6
# define CLIENT_OPCODE_SUBDOC_DICT_ADD 0xc7
# define CLIENT_OPCODE_SUBDOC_DICT_UPSERT 0xc8
# define CLIENT_OPCODE_SUBDOC_DELETE 0xc9
# define CLIENT_OPCODE_SUBDOC_REPLACE 0xca
# define CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_LAST 0xcb
# define CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_FIRST 0xcc
# define CLIENT_OPCODE_SUBDOC_ARRAY_INSERT 0xcd
# define CLIENT_OPCODE_SUBDOC_ARRAY_ADD_UNIQUE 0xce
# define CLIENT_OPCODE_SUBDOC_COUNTER 0xcf
# define CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP 0xd0
# define CLIENT_OPCODE_SUBDOC_MULTI_MUTATION 0xd1
# define CLIENT_OPCODE_SUBDOC_GET_COUNT 0xd2
# define CLIENT_OPCODE_SUBDOC_REPLACE_BODY_WITH_XATTR 0xd3
2022-10-19 14:00:37 +00:00
# define CLIENT_OPCODE_RANGE_SCAN_CREATE 0xda
# define CLIENT_OPCODE_RANGE_SCAN_CONTINUE 0xdb
# define CLIENT_OPCODE_RANGE_SCAN_CANCEL 0xdc
2022-02-21 08:34:07 +00:00
# define CLIENT_OPCODE_SCRUB 0xf0
# define CLIENT_OPCODE_ISASL_REFRESH 0xf1
# define CLIENT_OPCODE_SSL_CERTS_REFRESH 0xf2
# define CLIENT_OPCODE_GET_CMD_TIMER 0xf3
# define CLIENT_OPCODE_SET_CTRL_TOKEN 0xf4
# define CLIENT_OPCODE_GET_CTRL_TOKEN 0xf5
# define CLIENT_OPCODE_UPDATE_EXTERNAL_USER_PERMISSIONS 0xf6
# define CLIENT_OPCODE_RBAC_REFRESH 0xf7
# define CLIENT_OPCODE_AUTH_PROVIDER 0xf8
# define CLIENT_OPCODE_DROP_PRIVILEGE 0xfb
# define CLIENT_OPCODE_ADJUST_TIMEOFDAY 0xfc
# define CLIENT_OPCODE_EWOULDBLOCK_CTL 0xfd
# define CLIENT_OPCODE_GET_ERROR_MAP 0xfe
2014-07-09 12:58:13 +00:00
/* vBucket states */
# define VBUCKET_ACTIVE 0x01
# define VBUCKET_PENDING 0x02
# define VBUCKET_REPLICA 0x03
# define VBUCKET_DEAD 0x04
/* Data Types */
# define DT_RAW_BYTES 0x00
2017-02-01 17:04:56 +00:00
# define DT_JSON 0x01
# define DT_SNAPPY 0x02
# define DT_XATTR 0x04
2014-07-09 12:58:13 +00:00
2014-10-27 22:57:05 +00:00
void proto_register_couchbase ( void ) ;
void proto_reg_handoff_couchbase ( void ) ;
2014-07-09 12:58:13 +00:00
static int proto_couchbase = - 1 ;
static int hf_magic = - 1 ;
static int hf_opcode = - 1 ;
2022-02-22 11:55:54 +00:00
static int hf_server_opcode = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_extlength = - 1 ;
static int hf_keylength = - 1 ;
static int hf_value_length = - 1 ;
static int hf_datatype = - 1 ;
2017-02-01 17:04:56 +00:00
static int hf_datatype_json = - 1 ;
static int hf_datatype_snappy = - 1 ;
static int hf_datatype_xattr = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_vbucket = - 1 ;
static int hf_status = - 1 ;
static int hf_total_bodylength = - 1 ;
static int hf_opaque = - 1 ;
static int hf_cas = - 1 ;
static int hf_ttp = - 1 ;
static int hf_ttr = - 1 ;
2018-12-03 11:38:24 +00:00
static int hf_collection_key_id = - 1 ;
static int hf_collection_key_logical = - 1 ;
2019-02-14 14:30:18 +00:00
static int hf_collection_manifest_id = - 1 ;
2018-12-03 11:38:24 +00:00
2018-02-05 14:40:33 +00:00
static int hf_flex_extras_length = - 1 ;
static int hf_flex_keylength = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_extras = - 1 ;
static int hf_extras_flags = - 1 ;
static int hf_extras_flags_backfill = - 1 ;
static int hf_extras_flags_dump = - 1 ;
static int hf_extras_flags_list_vbuckets = - 1 ;
static int hf_extras_flags_takeover_vbuckets = - 1 ;
static int hf_extras_flags_support_ack = - 1 ;
static int hf_extras_flags_request_keys_only = - 1 ;
static int hf_extras_flags_checkpoint = - 1 ;
2014-11-18 18:11:22 +00:00
static int hf_extras_flags_dcp_connection_type = - 1 ;
static int hf_extras_flags_dcp_add_stream_takeover = - 1 ;
static int hf_extras_flags_dcp_add_stream_diskonly = - 1 ;
static int hf_extras_flags_dcp_add_stream_latest = - 1 ;
2014-12-10 01:19:55 +00:00
static int hf_extras_flags_dcp_snapshot_marker_memory = - 1 ;
static int hf_extras_flags_dcp_snapshot_marker_disk = - 1 ;
static int hf_extras_flags_dcp_snapshot_marker_chk = - 1 ;
static int hf_extras_flags_dcp_snapshot_marker_ack = - 1 ;
2017-02-01 17:04:56 +00:00
static int hf_extras_flags_dcp_include_xattrs = - 1 ;
static int hf_extras_flags_dcp_no_value = - 1 ;
2018-02-05 09:30:43 +00:00
static int hf_extras_flags_dcp_include_delete_times = - 1 ;
static int hf_extras_flags_dcp_collections = - 1 ;
2020-02-18 14:25:15 +00:00
static int hf_extras_flags_dcp_oso_snapshot_begin = - 1 ;
static int hf_extras_flags_dcp_oso_snapshot_end = - 1 ;
2017-08-10 14:13:44 +00:00
static int hf_subdoc_doc_flags = - 1 ;
static int hf_subdoc_doc_flags_mkdoc = - 1 ;
static int hf_subdoc_doc_flags_add = - 1 ;
static int hf_subdoc_doc_flags_accessdeleted = - 1 ;
2020-06-29 13:25:24 +00:00
static int hf_subdoc_doc_flags_createasdeleted = - 1 ;
2021-10-12 11:20:10 +00:00
static int hf_subdoc_doc_flags_revivedocument = - 1 ;
2017-08-10 14:13:44 +00:00
static int hf_subdoc_doc_flags_reserved = - 1 ;
2015-08-20 15:05:57 +00:00
static int hf_subdoc_flags = - 1 ;
static int hf_subdoc_flags_mkdirp = - 1 ;
2017-02-01 17:04:56 +00:00
static int hf_subdoc_flags_xattrpath = - 1 ;
static int hf_subdoc_flags_expandmacros = - 1 ;
2017-08-10 14:13:44 +00:00
static int hf_subdoc_flags_reserved = - 1 ;
2014-11-18 18:11:22 +00:00
static int hf_extras_seqno = - 1 ;
2019-09-16 10:58:14 +00:00
static int hf_extras_mutation_seqno = - 1 ;
2014-11-18 18:11:22 +00:00
static int hf_extras_opaque = - 1 ;
static int hf_extras_reserved = - 1 ;
static int hf_extras_start_seqno = - 1 ;
static int hf_extras_end_seqno = - 1 ;
2019-08-19 14:21:42 +00:00
static int hf_extras_high_completed_seqno = - 1 ;
2019-11-28 13:39:26 +00:00
static int hf_extras_max_visible_seqno = - 1 ;
2022-04-22 07:35:36 +00:00
static int hf_extras_timestamp = - 1 ;
2019-11-28 13:39:26 +00:00
static int hf_extras_marker_version = - 1 ;
2014-11-18 18:11:22 +00:00
static int hf_extras_vbucket_uuid = - 1 ;
static int hf_extras_snap_start_seqno = - 1 ;
static int hf_extras_snap_end_seqno = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_extras_expiration = - 1 ;
static int hf_extras_delta = - 1 ;
static int hf_extras_initial = - 1 ;
static int hf_extras_unknown = - 1 ;
2014-12-10 01:19:55 +00:00
static int hf_extras_by_seqno = - 1 ;
static int hf_extras_rev_seqno = - 1 ;
2018-12-10 10:18:00 +00:00
static int hf_extras_prepared_seqno = - 1 ;
static int hf_extras_commit_seqno = - 1 ;
static int hf_extras_abort_seqno = - 1 ;
static int hf_extras_deleted = - 1 ;
2014-12-10 01:19:55 +00:00
static int hf_extras_lock_time = - 1 ;
static int hf_extras_nmeta = - 1 ;
static int hf_extras_nru = - 1 ;
2015-10-30 07:39:01 +00:00
static int hf_extras_bytes_to_ack = - 1 ;
2018-02-05 09:30:43 +00:00
static int hf_extras_delete_time = - 1 ;
2018-12-03 11:38:24 +00:00
static int hf_extras_delete_unused = - 1 ;
2018-02-05 09:30:43 +00:00
static int hf_extras_system_event_id = - 1 ;
2018-12-03 11:38:24 +00:00
static int hf_extras_system_event_version = - 1 ;
2015-08-20 15:05:57 +00:00
static int hf_extras_pathlen = - 1 ;
2020-02-18 14:25:15 +00:00
static int hf_extras_dcp_oso_snapshot_flags = - 1 ;
2022-02-22 11:55:54 +00:00
static int hf_server_extras_cccp_epoch = - 1 ;
static int hf_server_extras_cccp_revno = - 1 ;
static int hf_server_clustermap_value = - 1 ;
static int hf_server_authentication = - 1 ;
static int hf_server_external_users = - 1 ;
static int hf_server_get_authorization = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_key = - 1 ;
2015-08-20 15:05:57 +00:00
static int hf_path = - 1 ;
2014-07-09 12:58:13 +00:00
static int hf_value = - 1 ;
static int hf_uint64_response = - 1 ;
static int hf_observe = - 1 ;
static int hf_observe_vbucket = - 1 ;
static int hf_observe_keylength = - 1 ;
static int hf_observe_key = - 1 ;
static int hf_observe_status = - 1 ;
static int hf_observe_cas = - 1 ;
2016-07-05 22:22:11 +00:00
static int hf_observe_vbucket_uuid = - 1 ;
static int hf_observe_failed_over = - 1 ;
static int hf_observe_last_persisted_seqno = - 1 ;
static int hf_observe_current_seqno = - 1 ;
static int hf_observe_old_vbucket_uuid = - 1 ;
static int hf_observe_last_received_seqno = - 1 ;
2014-07-09 12:58:13 +00:00
2017-08-10 10:00:20 +00:00
static int hf_get_errmap_version = - 1 ;
2014-11-18 18:11:22 +00:00
static int hf_failover_log = - 1 ;
static int hf_failover_log_size = - 1 ;
static int hf_failover_log_vbucket_uuid = - 1 ;
static int hf_failover_log_vbucket_seqno = - 1 ;
2015-10-30 07:39:01 +00:00
static int hf_vbucket_states = - 1 ;
static int hf_vbucket_states_state = - 1 ;
static int hf_vbucket_states_size = - 1 ;
static int hf_vbucket_states_id = - 1 ;
static int hf_vbucket_states_seqno = - 1 ;
2017-02-03 12:42:32 +00:00
static int hf_bucket_type = - 1 ;
static int hf_bucket_config = - 1 ;
static int hf_config_key = - 1 ;
static int hf_config_value = - 1 ;
2015-08-20 15:05:57 +00:00
static int hf_multipath_opcode = - 1 ;
static int hf_multipath_index = - 1 ;
static int hf_multipath_pathlen = - 1 ;
static int hf_multipath_path = - 1 ;
static int hf_multipath_valuelen = - 1 ;
static int hf_multipath_value = - 1 ;
2017-02-02 15:28:59 +00:00
static int hf_meta_flags = - 1 ;
static int hf_meta_expiration = - 1 ;
static int hf_meta_revseqno = - 1 ;
static int hf_meta_cas = - 1 ;
static int hf_skip_conflict = - 1 ;
static int hf_force_accept = - 1 ;
static int hf_regenerate_cas = - 1 ;
2019-01-22 15:51:57 +00:00
static int hf_force_meta = - 1 ;
static int hf_is_expiration = - 1 ;
2017-02-02 15:28:59 +00:00
static int hf_meta_options = - 1 ;
static int hf_metalen = - 1 ;
static int hf_meta_reqextmeta = - 1 ;
static int hf_meta_deleted = - 1 ;
static int hf_exptime = - 1 ;
static int hf_extras_meta_seqno = - 1 ;
static int hf_confres = - 1 ;
2017-02-01 17:04:56 +00:00
static int hf_hello_features = - 1 ;
static int hf_hello_features_feature = - 1 ;
static int hf_xattr_length = - 1 ;
static int hf_xattr_pair_length = - 1 ;
static int hf_xattr_key = - 1 ;
static int hf_xattr_value = - 1 ;
static int hf_xattrs = - 1 ;
2017-02-02 15:28:59 +00:00
2018-02-05 14:40:33 +00:00
static int hf_flex_extras = - 1 ;
2018-12-03 11:37:54 +00:00
static int hf_flex_extras_n = - 1 ;
static int hf_flex_frame_id_byte0 = - 1 ;
static int hf_flex_frame_id_req = - 1 ;
static int hf_flex_frame_id_res = - 1 ;
static int hf_flex_frame_id_req_esc = - 1 ;
static int hf_flex_frame_id_res_esc = - 1 ;
2018-02-05 14:40:33 +00:00
static int hf_flex_frame_len = - 1 ;
static int hf_flex_frame_len_esc = - 1 ;
static int hf_flex_frame_tracing_duration = - 1 ;
2022-08-16 10:34:18 +00:00
static int hf_flex_frame_ru_count = - 1 ;
static int hf_flex_frame_wu_count = - 1 ;
2018-12-03 11:37:54 +00:00
static int hf_flex_frame_durability_req = - 1 ;
static int hf_flex_frame_dcp_stream_id = - 1 ;
2020-02-18 11:50:08 +00:00
static int hf_flex_frame_impersonated_user = - 1 ;
2018-02-05 14:40:33 +00:00
2022-10-19 14:00:37 +00:00
static int hf_range_scan_uuid = - 1 ;
static int hf_range_scan_item_limit = - 1 ;
static int hf_range_scan_time_limit = - 1 ;
static int hf_range_scan_byte_limit = - 1 ;
2014-07-09 12:58:13 +00:00
static expert_field ef_warn_shall_not_have_value = EI_INIT ;
static expert_field ef_warn_shall_not_have_extras = EI_INIT ;
static expert_field ef_warn_shall_not_have_key = EI_INIT ;
2017-12-20 21:24:35 +00:00
static expert_field ef_compression_error = EI_INIT ;
2018-12-03 11:37:54 +00:00
static expert_field ef_warn_unknown_flex_unsupported = EI_INIT ;
static expert_field ef_warn_unknown_flex_id = EI_INIT ;
static expert_field ef_warn_unknown_flex_len = EI_INIT ;
2014-07-09 12:58:13 +00:00
static expert_field ei_value_missing = EI_INIT ;
static expert_field ef_warn_must_have_extras = EI_INIT ;
static expert_field ef_warn_must_have_key = EI_INIT ;
static expert_field ef_warn_illegal_extras_length = EI_INIT ;
static expert_field ef_warn_illegal_value_length = EI_INIT ;
static expert_field ef_warn_unknown_magic_byte = EI_INIT ;
static expert_field ef_warn_unknown_opcode = EI_INIT ;
2022-02-22 11:55:54 +00:00
static expert_field ef_warn_unknown_extras = EI_INIT ;
2014-07-09 12:58:13 +00:00
static expert_field ef_note_status_code = EI_INIT ;
2017-02-03 12:42:32 +00:00
static expert_field ef_separator_not_found = EI_INIT ;
static expert_field ef_illegal_value = EI_INIT ;
2014-07-09 12:58:13 +00:00
static gint ett_couchbase = - 1 ;
static gint ett_extras = - 1 ;
static gint ett_extras_flags = - 1 ;
static gint ett_observe = - 1 ;
2014-11-18 18:11:22 +00:00
static gint ett_failover_log = - 1 ;
2015-10-30 07:39:01 +00:00
static gint ett_vbucket_states = - 1 ;
2015-08-20 15:05:57 +00:00
static gint ett_multipath = - 1 ;
2017-02-03 12:42:32 +00:00
static gint ett_config = - 1 ;
static gint ett_config_key = - 1 ;
2017-02-01 17:04:56 +00:00
static gint ett_hello_features = - 1 ;
static gint ett_datatype = - 1 ;
static gint ett_xattrs = - 1 ;
static gint ett_xattr_pair = - 1 ;
2018-02-05 14:40:33 +00:00
static gint ett_flex_frame_extras = - 1 ;
2018-12-03 11:38:24 +00:00
static gint ett_collection_key = - 1 ;
2014-07-09 12:58:13 +00:00
static const value_string magic_vals [ ] = {
2022-02-22 11:55:54 +00:00
{ MAGIC_CLIENT_REQUEST , " Request " } ,
{ MAGIC_CLIENT_RESPONSE , " Response " } ,
{ MAGIC_CLIENT_RESPONSE_FLEX , " Response with flexible framing extras " } ,
{ MAGIC_CLIENT_REQUEST_FLEX , " Request with flexible framing extras " } ,
{ MAGIC_SERVER_REQUEST , " Server Request " } ,
{ MAGIC_SERVER_RESPONSE , " Server Response " } ,
2018-02-05 14:40:33 +00:00
{ 0 , NULL }
} ;
2018-12-03 11:37:54 +00:00
# define FLEX_ESCAPE 0x0F
/*
The flex extension identifiers are different for request / response
i . e . 0 in a response is not 0 in a request
Response IDs
*/
# define FLEX_RESPONSE_ID_RX_TX_DURATION 0
2022-08-16 10:34:18 +00:00
# define FLEX_RESPONSE_ID_RU_USAGE 1
# define FLEX_RESPONSE_ID_WU_USAGE 2
2018-12-03 11:37:54 +00:00
/* Request IDs */
# define FLEX_REQUEST_ID_REORDER 0
# define FLEX_REQUEST_ID_DURABILITY 1
# define FLEX_REQUEST_ID_DCP_STREAM_ID 2
2020-02-18 11:50:08 +00:00
# define FLEX_REQUEST_ID_OPEN_TRACING 3
# define FLEX_REQUEST_ID_IMPERSONATE 4
# define FLEX_REQUEST_ID_PRESERVE_TTL 5
2018-12-03 11:37:54 +00:00
static const value_string flex_frame_response_ids [ ] = {
{ FLEX_RESPONSE_ID_RX_TX_DURATION , " Server Recv->Send duration " } ,
2022-08-16 10:34:18 +00:00
{ FLEX_RESPONSE_ID_RU_USAGE , " Read units " } ,
{ FLEX_RESPONSE_ID_WU_USAGE , " Write units " } ,
2018-12-03 11:37:54 +00:00
{ 0 , NULL }
} ;
static const value_string flex_frame_request_ids [ ] = {
{ FLEX_REQUEST_ID_REORDER , " Out of order Execution " } ,
{ FLEX_REQUEST_ID_DURABILITY , " Durability Requirements " } ,
{ FLEX_REQUEST_ID_DCP_STREAM_ID , " DCP Stream Identifier " } ,
2020-02-18 11:50:08 +00:00
{ FLEX_REQUEST_ID_OPEN_TRACING , " Open Tracing " } ,
{ FLEX_REQUEST_ID_IMPERSONATE , " Impersonate User " } ,
{ FLEX_REQUEST_ID_PRESERVE_TTL , " Preserve TTL " } ,
2018-12-03 11:37:54 +00:00
{ 0 , NULL }
} ;
static const value_string flex_frame_durability_req [ ] = {
{ 1 , " Majority " } ,
{ 2 , " Majority and persist on active " } ,
{ 3 , " Persist to majority " } ,
2014-11-18 18:11:22 +00:00
{ 0 , NULL }
} ;
2014-07-09 12:58:13 +00:00
static const value_string status_vals [ ] = {
2022-02-21 08:34:07 +00:00
{ STATUS_SUCCESS , " Success " } ,
{ STATUS_KEY_ENOENT , " Key not found " } ,
{ STATUS_KEY_EEXISTS , " Key exists " } ,
{ STATUS_E2BIG , " Value too big " } ,
{ STATUS_EINVAL , " Invalid arguments " } ,
{ STATUS_NOT_STORED , " Key not stored " } ,
{ STATUS_DELTA_BADVAL , " Bad value to incr/decr " } ,
{ STATUS_NOT_MY_VBUCKET , " Not my vBucket " } ,
{ STATUS_NO_VBUCKET , " Not connected to a bucket " } ,
{ STATUS_LOCKED , " The requested resource is locked " } ,
{ STATUS_DCP_STREAM_NOT_FOUND , " No DCP Stream for this request " } ,
{ STATUS_OPAQUE_NO_MATCH , " Opaque does not match " } ,
2022-08-16 10:34:18 +00:00
{ STATUS_EWOULDTHROTTLE , " Command would have been throttled " } ,
{ STATUS_ECONFIGONLY , " Command can't be executed in config-only bucket " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_AUTH_STALE , " Authentication context is stale. Should reauthenticate. " } ,
{ STATUS_AUTH_ERROR , " Authentication error " } ,
{ STATUS_AUTH_CONTINUE , " Authentication continue " } ,
{ STATUS_ERANGE , " Range error " } ,
{ STATUS_ROLLBACK , " Rollback " } ,
{ STATUS_EACCESS , " Access error " } ,
{ STATUS_NOT_INITIALIZED ,
2017-08-18 11:42:40 +00:00
" The Couchbase cluster is currently initializing this node, and "
" the Cluster manager has not yet granted all users access to the cluster. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_RATELIMITED_NETWORK_INGRESS , " Rate limit: Network ingress " } ,
{ STATUS_RATELIMITED_NETWORK_EGRESS , " Rate limit: Network Egress " } ,
{ STATUS_RATELIMITED_MAX_CONNECTIONS , " Rate limit: Max Connections " } ,
{ STATUS_RATELIMITED_MAX_COMMANDS , " Rate limit: Max Commands " } ,
{ STATUS_SCOPE_SIZE_LIMIT_EXCEEDED , " To much data in Scope " } ,
{ STATUS_UNKNOWN_COMMAND , " Unknown command " } ,
{ STATUS_ENOMEM , " Out of memory " } ,
{ STATUS_NOT_SUPPORTED , " Command isn't supported " } ,
{ STATUS_EINTERNAL , " Internal error " } ,
{ STATUS_EBUSY , " Server is busy " } ,
{ STATUS_ETMPFAIL , " Temporary failure " } ,
{ STATUS_XATTR_EINVAL ,
2017-08-18 11:42:40 +00:00
" There is something wrong with the syntax of the provided XATTR. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_UNKNOWN_COLLECTION ,
2017-08-18 11:42:40 +00:00
" Operation attempted with an unknown collection. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_NO_COLLECTIONS_MANIFEST ,
2019-11-28 11:51:21 +00:00
" No collections manifest has been set " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_CANNOT_APPLY_MANIFEST ,
2019-11-28 11:51:21 +00:00
" Cannot apply the given manifest " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_MANIFEST_IS_AHEAD ,
2019-11-28 11:51:21 +00:00
" Operation attempted with a manifest ahead of the server " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_UNKNOWN_SCOPE ,
2019-11-28 11:51:21 +00:00
" Operation attempted with an unknown scope. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_DCP_STREAMID_INVALID ,
2019-11-28 11:51:21 +00:00
" DCP Stream ID is invalid " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_DURABILITY_INVALID_LEVEL ,
2019-05-24 13:06:28 +00:00
" The specified durability level is invalid " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_DURABILITY_IMPOSSIBLE ,
2019-05-24 13:06:28 +00:00
" The specified durability requirements are not currently possible " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SYNC_WRITE_IN_PROGRESS ,
2019-05-24 13:06:28 +00:00
" A SyncWrite is already in progress on the specified key " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SYNC_WRITE_AMBIGUOUS ,
2019-05-24 13:06:28 +00:00
" The SyncWrite request has not completed in the specified time and has ambiguous result " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SYNC_WRITE_RECOMMIT_IN_PROGRESS ,
2019-05-24 13:06:28 +00:00
" The SyncWrite is being re-committed after a change in active node " } ,
2022-08-16 10:34:18 +00:00
{ STATUS_RANGE_SCAN_CANCELLED , " RangeScan was cancelled " } ,
{ STATUS_RANGE_SCAN_MORE , " RangeScan has more data available " } ,
{ STATUS_RANGE_SCAN_COMPLETE , " RangeScan has completed " } ,
2022-10-19 14:00:37 +00:00
{ STATUS_VBUUID_NOT_EQUAL , " VB UUID does not equal server value " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_PATH_ENOENT ,
2015-08-20 15:05:57 +00:00
" Subdoc: Path not does not exist " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_PATH_MISMATCH ,
2015-08-20 15:05:57 +00:00
" Subdoc: Path mismatch " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_PATH_EINVAL ,
2015-08-20 15:05:57 +00:00
" Subdoc: Invalid path " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_PATH_E2BIG ,
2015-08-20 15:05:57 +00:00
" Subdoc: Path too large " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_DOC_E2DEEP ,
2015-08-20 15:05:57 +00:00
" Subdoc: Document too deep " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_VALUE_CANTINSERT ,
2015-08-20 15:05:57 +00:00
" Subdoc: Cannot insert specified value " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_DOC_NOTJSON ,
2015-08-20 15:05:57 +00:00
" Subdoc: Existing document not JSON " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_NUM_ERANGE ,
2015-08-20 15:05:57 +00:00
" Subdoc: Existing number outside valid arithmetic range " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_DELTA_ERANGE ,
2015-08-20 15:05:57 +00:00
" Subdoc: Delta outside valid arithmetic range " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_PATH_EEXISTS ,
2015-08-20 15:05:57 +00:00
" Subdoc: Document path already exists " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_VALUE_ETOODEEP ,
2015-08-20 15:05:57 +00:00
" Subdoc: Inserting value would make document too deep " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_INVALID_COMBO ,
2015-08-20 15:05:57 +00:00
" Subdoc: Invalid combination for multi-path command " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_MULTI_PATH_FAILURE ,
2015-08-20 15:05:57 +00:00
" Subdoc: One or more paths in a multi-path command failed " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_SUCCESS_DELETED ,
2017-08-18 11:42:40 +00:00
" Subdoc: The operation completed successfully, but operated on a deleted document. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_INVALID_FLAG_COMBO ,
2017-08-18 11:42:40 +00:00
" Subdoc: The combination of the subdoc flags for the xattrs doesn't make any sense. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_INVALID_KEY_COMBO ,
2017-08-18 11:42:40 +00:00
" Subdoc: Only a single xattr key may be accessed at the same time. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_UNKNOWN_MACRO ,
2017-08-18 11:42:40 +00:00
" Subdoc: The server has no knowledge of the requested macro. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_UNKNOWN_VATTR ,
2017-08-18 11:42:40 +00:00
" Subdoc: The server has no knowledge of the requested virtual xattr. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_CANT_MODIFY_VATTR ,
2017-08-18 11:42:40 +00:00
" Subdoc: Virtual xattrs can't be modified. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_MULTI_PATH_FAILURE_DELETED ,
2017-08-18 11:42:40 +00:00
" Subdoc: Specified key was found as a deleted document, but one or more path operations failed. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_INVALID_XATTR_ORDER ,
2017-08-18 11:42:40 +00:00
" Subdoc: According to the spec all xattr commands should come first, followed by the commands for the document body. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_XATTR_UNKNOWN_VATTR_MACRO ,
2021-10-12 11:00:53 +00:00
" Subdoc: The server does not know about this virtual macro. " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_CAN_ONLY_REVIVE_DELETED_DOCUMENTS ,
2021-10-12 11:00:53 +00:00
" Subdoc: The document isn't dead (and we wanted to revive the document). " } ,
2022-02-21 08:34:07 +00:00
{ STATUS_SUBDOC_DELETED_DOCUMENT_CANT_HAVE_VALUE ,
2021-10-12 11:00:53 +00:00
" Subdoc: A deleted document can't have a user value. " } ,
2014-07-09 12:58:13 +00:00
{ 0 , NULL }
} ;
static value_string_ext status_vals_ext = VALUE_STRING_EXT_INIT ( status_vals ) ;
2022-02-22 11:55:54 +00:00
static const value_string client_opcode_vals [ ] = {
2022-02-21 08:34:07 +00:00
{ CLIENT_OPCODE_GET , " Get " } ,
{ CLIENT_OPCODE_SET , " Set " } ,
{ CLIENT_OPCODE_ADD , " Add " } ,
{ CLIENT_OPCODE_REPLACE , " Replace " } ,
{ CLIENT_OPCODE_DELETE , " Delete " } ,
{ CLIENT_OPCODE_INCREMENT , " Increment " } ,
{ CLIENT_OPCODE_DECREMENT , " Decrement " } ,
{ CLIENT_OPCODE_QUIT , " Quit " } ,
{ CLIENT_OPCODE_FLUSH , " Flush " } ,
{ CLIENT_OPCODE_GETQ , " Get Quietly " } ,
{ CLIENT_OPCODE_NOOP , " NOOP " } ,
{ CLIENT_OPCODE_VERSION , " Version " } ,
{ CLIENT_OPCODE_GETK , " Get Key " } ,
{ CLIENT_OPCODE_GETKQ , " Get Key Quietly " } ,
{ CLIENT_OPCODE_APPEND , " Append " } ,
{ CLIENT_OPCODE_PREPEND , " Prepend " } ,
{ CLIENT_OPCODE_STAT , " Statistics " } ,
{ CLIENT_OPCODE_SETQ , " Set Quietly " } ,
{ CLIENT_OPCODE_ADDQ , " Add Quietly " } ,
{ CLIENT_OPCODE_REPLACEQ , " Replace Quietly " } ,
{ CLIENT_OPCODE_DELETEQ , " Delete Quietly " } ,
{ CLIENT_OPCODE_INCREMENTQ , " Increment Quietly " } ,
{ CLIENT_OPCODE_DECREMENTQ , " Decrement Quietly " } ,
{ CLIENT_OPCODE_QUITQ , " Quit Quietly " } ,
{ CLIENT_OPCODE_FLUSHQ , " Flush Quietly " } ,
{ CLIENT_OPCODE_APPENDQ , " Append Quietly " } ,
{ CLIENT_OPCODE_PREPENDQ , " Prepend Quietly " } ,
{ CLIENT_OPCODE_VERBOSITY , " Verbosity " } ,
{ CLIENT_OPCODE_TOUCH , " Touch " } ,
{ CLIENT_OPCODE_GAT , " Get and Touch " } ,
{ CLIENT_OPCODE_GATQ , " Gat and Touch Quietly " } ,
{ CLIENT_OPCODE_HELLO , " Hello " } ,
{ CLIENT_OPCODE_SASL_LIST_MECHS , " List SASL Mechanisms " } ,
{ CLIENT_OPCODE_SASL_AUTH , " SASL Authenticate " } ,
{ CLIENT_OPCODE_SASL_STEP , " SASL Step " } ,
{ CLIENT_OPCODE_IOCTL_GET , " IOCTL Get " } ,
{ CLIENT_OPCODE_IOCTL_SET , " IOCTL Set " } ,
{ CLIENT_OPCODE_CONFIG_VALIDATE , " Config Validate " } ,
{ CLIENT_OPCODE_CONFIG_RELOAD , " Config Reload " } ,
{ CLIENT_OPCODE_AUDIT_PUT , " Audit Put " } ,
{ CLIENT_OPCODE_AUDIT_CONFIG_RELOAD , " Audit Config Reload " } ,
{ CLIENT_OPCODE_SHUTDOWN , " Shutdown " } ,
{ CLIENT_OPCODE_RGET , " Range Get " } ,
{ CLIENT_OPCODE_RSET , " Range Set " } ,
{ CLIENT_OPCODE_RSETQ , " Range Set Quietly " } ,
{ CLIENT_OPCODE_RAPPEND , " Range Append " } ,
{ CLIENT_OPCODE_RAPPENDQ , " Range Append Quietly " } ,
{ CLIENT_OPCODE_RPREPEND , " Range Prepend " } ,
{ CLIENT_OPCODE_RPREPENDQ , " Range Prepend Quietly " } ,
{ CLIENT_OPCODE_RDELETE , " Range Delete " } ,
{ CLIENT_OPCODE_RDELETEQ , " Range Delete Quietly " } ,
{ CLIENT_OPCODE_RINCR , " Range Increment " } ,
{ CLIENT_OPCODE_RINCRQ , " Range Increment Quietly " } ,
{ CLIENT_OPCODE_RDECR , " Range Decrement " } ,
{ CLIENT_OPCODE_RDECRQ , " Range Decrement Quietly " } ,
{ CLIENT_OPCODE_SET_VBUCKET , " Set VBucket " } ,
{ CLIENT_OPCODE_GET_VBUCKET , " Get VBucket " } ,
{ CLIENT_OPCODE_DEL_VBUCKET , " Delete VBucket " } ,
{ CLIENT_OPCODE_TAP_CONNECT , " TAP Connect " } ,
{ CLIENT_OPCODE_TAP_MUTATION , " TAP Mutation " } ,
{ CLIENT_OPCODE_TAP_DELETE , " TAP Delete " } ,
{ CLIENT_OPCODE_TAP_FLUSH , " TAP Flush " } ,
{ CLIENT_OPCODE_TAP_OPAQUE , " TAP Opaque " } ,
{ CLIENT_OPCODE_TAP_VBUCKET_SET , " TAP VBucket Set " } ,
{ CLIENT_OPCODE_TAP_CHECKPOINT_START , " TAP Checkpoint Start " } ,
{ CLIENT_OPCODE_TAP_CHECKPOINT_END , " TAP Checkpoint End " } ,
{ CLIENT_OPCODE_GET_ALL_VB_SEQNOS , " Get All VBucket Seqnos " } ,
{ CLIENT_OPCODE_DCP_OPEN_CONNECTION , " DCP Open Connection " } ,
{ CLIENT_OPCODE_DCP_ADD_STREAM , " DCP Add Stream " } ,
{ CLIENT_OPCODE_DCP_CLOSE_STREAM , " DCP Close Stream " } ,
{ CLIENT_OPCODE_DCP_STREAM_REQUEST , " DCP Stream Request " } ,
{ CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST , " DCP Get Failover Log " } ,
{ CLIENT_OPCODE_DCP_STREAM_END , " DCP Stream End " } ,
{ CLIENT_OPCODE_DCP_SNAPSHOT_MARKER , " DCP Snapshot Marker " } ,
{ CLIENT_OPCODE_DCP_MUTATION , " DCP (Key) Mutation " } ,
{ CLIENT_OPCODE_DCP_DELETION , " DCP (Key) Deletion " } ,
{ CLIENT_OPCODE_DCP_EXPIRATION , " DCP (Key) Expiration " } ,
{ CLIENT_OPCODE_DCP_FLUSH , " DCP Flush " } ,
{ CLIENT_OPCODE_DCP_SET_VBUCKET_STATE , " DCP Set VBucket State " } ,
{ CLIENT_OPCODE_DCP_NOOP , " DCP NOOP " } ,
{ CLIENT_OPCODE_DCP_BUFFER_ACKNOWLEDGEMENT , " DCP Buffer Acknowledgement " } ,
{ CLIENT_OPCODE_DCP_CONTROL , " DCP Control " } ,
{ CLIENT_OPCODE_DCP_SYSTEM_EVENT , " DCP System Event " } ,
{ CLIENT_OPCODE_DCP_PREPARE , " DCP Prepare " } ,
{ CLIENT_OPCODE_DCP_SEQNO_ACK , " DCP Seqno Acknowledgement " } ,
{ CLIENT_OPCODE_DCP_COMMIT , " DCP Commit " } ,
{ CLIENT_OPCODE_DCP_ABORT , " DCP Abort " } ,
{ CLIENT_OPCODE_DCP_SEQNO_ADVANCED , " DCP Seqno Advanced " } ,
{ CLIENT_OPCODE_DCP_OSO_SNAPSHOT , " DCP Out of Sequence Order Snapshot " } ,
{ CLIENT_OPCODE_STOP_PERSISTENCE , " Stop Persistence " } ,
{ CLIENT_OPCODE_START_PERSISTENCE , " Start Persistence " } ,
{ CLIENT_OPCODE_SET_PARAM , " Set Parameter " } ,
{ CLIENT_OPCODE_GET_REPLICA , " Get Replica " } ,
{ CLIENT_OPCODE_CREATE_BUCKET , " Create Bucket " } ,
{ CLIENT_OPCODE_DELETE_BUCKET , " Delete Bucket " } ,
{ CLIENT_OPCODE_LIST_BUCKETS , " List Buckets " } ,
{ CLIENT_OPCODE_EXPAND_BUCKET , " Expand Bucket " } ,
{ CLIENT_OPCODE_SELECT_BUCKET , " Select Bucket " } ,
{ CLIENT_OPCODE_START_REPLICATION , " Start Replication " } ,
{ CLIENT_OPCODE_OBSERVE_SEQNO , " Observe Sequence Number " } ,
{ CLIENT_OPCODE_OBSERVE , " Observe " } ,
{ CLIENT_OPCODE_EVICT_KEY , " Evict Key " } ,
{ CLIENT_OPCODE_GET_LOCKED , " Get Locked " } ,
{ CLIENT_OPCODE_UNLOCK_KEY , " Unlock Key " } ,
{ CLIENT_OPCODE_SYNC , " Sync " } ,
{ CLIENT_OPCODE_LAST_CLOSED_CHECKPOINT , " Last Closed Checkpoint " } ,
{ CLIENT_OPCODE_RESTORE_FILE , " Restore File " } ,
{ CLIENT_OPCODE_RESTORE_ABORT , " Restore Abort " } ,
{ CLIENT_OPCODE_RESTORE_COMPLETE , " Restore Complete " } ,
{ CLIENT_OPCODE_ONLINE_UPDATE_START , " Online Update Start " } ,
{ CLIENT_OPCODE_ONLINE_UPDATE_COMPLETE , " Online Update Complete " } ,
{ CLIENT_OPCODE_ONLINE_UPDATE_REVERT , " Online Update Revert " } ,
{ CLIENT_OPCODE_DEREGISTER_TAP_CLIENT , " Deregister TAP Client " } ,
{ CLIENT_OPCODE_RESET_REPLICATION_CHAIN , " Reset Replication Chain " } ,
{ CLIENT_OPCODE_GET_META , " Get Meta " } ,
{ CLIENT_OPCODE_GETQ_META , " Get Meta Quietly " } ,
{ CLIENT_OPCODE_SET_WITH_META , " Set with Meta " } ,
{ CLIENT_OPCODE_SETQ_WITH_META , " Set with Meta Quietly " } ,
{ CLIENT_OPCODE_ADD_WITH_META , " Add with Meta " } ,
{ CLIENT_OPCODE_ADDQ_WITH_META , " Add with Meta Quietly " } ,
{ CLIENT_OPCODE_SNAPSHOT_VB_STATES , " Snapshot VBuckets States " } ,
{ CLIENT_OPCODE_VBUCKET_BATCH_COUNT , " VBucket Batch Count " } ,
{ CLIENT_OPCODE_DEL_WITH_META , " Delete with Meta " } ,
{ CLIENT_OPCODE_DELQ_WITH_META , " Delete with Meta Quietly " } ,
{ CLIENT_OPCODE_CREATE_CHECKPOINT , " Create Checkpoint " } ,
{ CLIENT_OPCODE_NOTIFY_VBUCKET_UPDATE , " Notify VBucket Update " } ,
{ CLIENT_OPCODE_ENABLE_TRAFFIC , " Enable Traffic " } ,
{ CLIENT_OPCODE_DISABLE_TRAFFIC , " Disable Traffic " } ,
{ CLIENT_OPCODE_IFCONFIG , " Ifconfig " } ,
{ CLIENT_OPCODE_CHANGE_VB_FILTER , " Change VBucket Filter " } ,
{ CLIENT_OPCODE_CHECKPOINT_PERSISTENCE , " Checkpoint Persistence " } ,
{ CLIENT_OPCODE_RETURN_META , " Return Meta " } ,
{ CLIENT_OPCODE_COMPACT_DB , " Compact Database " } ,
{ CLIENT_OPCODE_SET_CLUSTER_CONFIG , " Set Cluster Config " } ,
{ CLIENT_OPCODE_GET_CLUSTER_CONFIG , " Get Cluster Config " } ,
{ CLIENT_OPCODE_GET_RANDOM_KEY , " Get Random Key " } ,
{ CLIENT_OPCODE_SEQNO_PERSISTENCE , " Seqno Persistence " } ,
{ CLIENT_OPCODE_GET_KEYS , " Get Keys " } ,
{ CLIENT_OPCODE_COLLECTIONS_SET_MANIFEST , " Set Collection's Manifest " } ,
{ CLIENT_OPCODE_COLLECTIONS_GET_MANIFEST , " Get Collection's Manifest " } ,
{ CLIENT_OPCODE_COLLECTIONS_GET_ID , " Get Collection ID " } ,
{ CLIENT_OPCODE_COLLECTIONS_GET_SCOPE_ID , " Get Scope ID " } ,
{ CLIENT_OPCODE_SET_DRIFT_COUNTER_STATE , " Set Drift Counter State " } ,
{ CLIENT_OPCODE_GET_ADJUSTED_TIME , " Get Adjusted Time " } ,
{ CLIENT_OPCODE_SUBDOC_GET , " Subdoc Get " } ,
{ CLIENT_OPCODE_SUBDOC_EXISTS , " Subdoc Exists " } ,
{ CLIENT_OPCODE_SUBDOC_DICT_ADD , " Subdoc Dictionary Add " } ,
{ CLIENT_OPCODE_SUBDOC_DICT_UPSERT , " Subdoc Dictionary Upsert " } ,
{ CLIENT_OPCODE_SUBDOC_DELETE , " Subdoc Delete " } ,
{ CLIENT_OPCODE_SUBDOC_REPLACE , " Subdoc Replace " } ,
{ CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_LAST , " Subdoc Array Push Last " } ,
{ CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_FIRST , " Subdoc Array Push First " } ,
{ CLIENT_OPCODE_SUBDOC_ARRAY_INSERT , " Subdoc Array Insert " } ,
{ CLIENT_OPCODE_SUBDOC_ARRAY_ADD_UNIQUE , " Subdoc Array Add Unique " } ,
{ CLIENT_OPCODE_SUBDOC_COUNTER , " Subdoc Counter " } ,
{ CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP , " Subdoc Multipath Lookup " } ,
{ CLIENT_OPCODE_SUBDOC_MULTI_MUTATION , " Subdoc Multipath Mutation " } ,
{ CLIENT_OPCODE_SUBDOC_GET_COUNT , " Subdoc Get Count " } ,
{ CLIENT_OPCODE_SUBDOC_REPLACE_BODY_WITH_XATTR , " Subdoc Replace Body With Xattr " } ,
2022-10-19 14:00:37 +00:00
{ CLIENT_OPCODE_RANGE_SCAN_CREATE , " RangeScan Create " } ,
{ CLIENT_OPCODE_RANGE_SCAN_CONTINUE , " RangeScan Continue " } ,
{ CLIENT_OPCODE_RANGE_SCAN_CANCEL , " RangeScan Cancel " } ,
2022-02-21 08:34:07 +00:00
{ CLIENT_OPCODE_SCRUB , " Scrub " } ,
{ CLIENT_OPCODE_ISASL_REFRESH , " isasl Refresh " } ,
{ CLIENT_OPCODE_SSL_CERTS_REFRESH , " SSL Certificates Refresh " } ,
{ CLIENT_OPCODE_GET_CMD_TIMER , " Internal Timer Control " } ,
{ CLIENT_OPCODE_SET_CTRL_TOKEN , " Set Control Token " } ,
{ CLIENT_OPCODE_GET_CTRL_TOKEN , " Get Control Token " } ,
{ CLIENT_OPCODE_UPDATE_EXTERNAL_USER_PERMISSIONS , " Update External User Permissions " } ,
{ CLIENT_OPCODE_RBAC_REFRESH , " RBAC Refresh " } ,
{ CLIENT_OPCODE_AUTH_PROVIDER , " Auth Provider " } ,
{ CLIENT_OPCODE_DROP_PRIVILEGE , " Drop Privilege " } ,
{ CLIENT_OPCODE_ADJUST_TIMEOFDAY , " Adjust Timeofday " } ,
{ CLIENT_OPCODE_EWOULDBLOCK_CTL , " EWOULDBLOCK Control " } ,
{ CLIENT_OPCODE_GET_ERROR_MAP , " Get Error Map " } ,
2014-12-02 14:32:34 +00:00
2014-07-09 12:58:13 +00:00
/* Internally defined values not valid here */
{ 0 , NULL }
} ;
2022-02-22 11:55:54 +00:00
static value_string_ext client_opcode_vals_ext = VALUE_STRING_EXT_INIT ( client_opcode_vals ) ;
typedef enum {
SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION = 0x01 ,
SERVER_OPCODE_AUTHENTICATE = 0x02 ,
SERVER_OPCODE_ACTIVE_EXTERNAL_USERS = 0x03 ,
SERVER_OPCODE_GET_AUTHORIZATION = 0x04
} server_opcode_t ;
static const value_string server_opcode_vals [ ] = {
{ SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION , " ClustermapChangeNotification " } ,
{ SERVER_OPCODE_AUTHENTICATE , " Authenticate " } ,
{ SERVER_OPCODE_ACTIVE_EXTERNAL_USERS , " ActiveExternalUsers " } ,
{ SERVER_OPCODE_GET_AUTHORIZATION , " GetAuthorization " } ,
{ 0 , NULL }
} ;
static value_string_ext server_opcode_vals_ext = VALUE_STRING_EXT_INIT ( server_opcode_vals ) ;
2014-07-09 12:58:13 +00:00
2021-02-14 15:36:32 +00:00
static const value_string dcp_connection_type_vals [ ] = {
2014-11-18 18:11:22 +00:00
{ 0 , " Consumer " } ,
{ 1 , " Producer " } ,
{ 2 , " Notifier " } ,
{ 0 , NULL }
} ;
2021-02-14 15:36:32 +00:00
static const value_string vbucket_states_vals [ ] = {
2015-10-30 07:39:01 +00:00
{ 1 , " Active " } ,
{ 2 , " Replica " } ,
{ 3 , " Pending " } ,
{ 4 , " Dead " } ,
{ 0 , NULL }
} ;
2020-06-19 01:14:46 +00:00
static int * const datatype_vals [ ] = {
2017-02-01 17:04:56 +00:00
& hf_datatype_json ,
& hf_datatype_snappy ,
& hf_datatype_xattr ,
NULL
2014-07-09 12:58:13 +00:00
} ;
2020-06-19 01:14:46 +00:00
static int * const subdoc_flags [ ] = {
2015-08-20 15:05:57 +00:00
& hf_subdoc_flags_mkdirp ,
2017-02-01 17:04:56 +00:00
& hf_subdoc_flags_xattrpath ,
& hf_subdoc_flags_expandmacros ,
2017-08-10 14:13:44 +00:00
& hf_subdoc_flags_reserved ,
NULL
} ;
2020-06-19 01:14:46 +00:00
static int * const subdoc_doc_flags [ ] = {
2017-08-10 14:13:44 +00:00
& hf_subdoc_doc_flags_mkdoc ,
& hf_subdoc_doc_flags_add ,
& hf_subdoc_doc_flags_accessdeleted ,
2020-06-29 13:25:24 +00:00
& hf_subdoc_doc_flags_createasdeleted ,
2021-10-12 11:20:10 +00:00
& hf_subdoc_doc_flags_revivedocument ,
2017-08-10 14:13:44 +00:00
& hf_subdoc_doc_flags_reserved ,
2015-08-20 15:05:57 +00:00
NULL
} ;
2020-06-19 01:14:46 +00:00
static int * const set_with_meta_extra_flags [ ] = {
2019-01-22 15:51:57 +00:00
& hf_force_meta ,
& hf_force_accept ,
& hf_regenerate_cas ,
& hf_skip_conflict ,
NULL
} ;
2020-06-19 01:14:46 +00:00
static int * const del_with_meta_extra_flags [ ] = {
2019-01-22 15:51:57 +00:00
& hf_force_meta ,
& hf_force_accept ,
& hf_regenerate_cas ,
& hf_skip_conflict ,
& hf_is_expiration ,
NULL
} ;
2017-02-01 17:04:56 +00:00
static const value_string feature_vals [ ] = {
2018-02-05 09:34:13 +00:00
{ 0x01 , " Datatype (deprecated) " } ,
2017-08-25 07:51:49 +00:00
{ 0x02 , " TLS " } ,
{ 0x03 , " TCP Nodelay " } ,
{ 0x04 , " Mutation Seqno " } ,
{ 0x05 , " TCP Delay " } ,
{ 0x06 , " XATTR " } ,
{ 0x07 , " Error Map " } ,
{ 0x08 , " Select Bucket " } ,
2019-01-28 07:58:15 +00:00
{ 0x09 , " Collections (deprecated) " } ,
2017-08-25 07:51:49 +00:00
{ 0x0a , " Snappy " } ,
{ 0x0b , " JSON " } ,
{ 0x0c , " Duplex " } ,
2018-02-05 09:34:13 +00:00
{ 0x0d , " Clustermap Change Notification " } ,
{ 0x0e , " Unordered Execution " } ,
{ 0x0f , " Tracing " } ,
2019-01-28 07:58:15 +00:00
{ 0x10 , " AltRequestSupport " } ,
{ 0x11 , " SyncReplication " } ,
{ 0x12 , " Collections " } ,
2020-02-18 11:50:08 +00:00
{ 0x13 , " OpenTracing " } ,
{ 0x14 , " PreserveTtl " } ,
2020-06-29 13:25:24 +00:00
{ 0x15 , " VAttr " } ,
{ 0x16 , " Point in Time Recovery " } ,
{ 0x17 , " SubdocCreateAsDeleted " } ,
2022-02-24 08:33:51 +00:00
{ 0x18 , " SubdocDocumentMacroSupport " } ,
{ 0x19 , " SubdocReplaceBodyWithXattr " } ,
2022-08-16 10:34:18 +00:00
{ 0x1a , " ReportUnitUsage " } ,
{ 0x1b , " NonBlockingThrottlingMode " } ,
2017-02-01 17:04:56 +00:00
{ 0 , NULL }
} ;
2018-02-05 09:30:43 +00:00
static const value_string dcp_system_event_id_vals [ ] = {
{ 0 , " CreateCollection " } ,
2018-12-03 11:38:24 +00:00
{ 1 , " DropCollection " } ,
{ 2 , " FlushCollection " } ,
{ 3 , " CreateScope " } ,
{ 4 , " DropScope " } ,
2018-02-05 09:30:43 +00:00
{ 0 , NULL }
} ;
2020-06-19 01:14:46 +00:00
static int * const snapshot_marker_flags [ ] = {
2019-11-28 13:39:26 +00:00
& hf_extras_flags_dcp_snapshot_marker_memory ,
& hf_extras_flags_dcp_snapshot_marker_disk ,
& hf_extras_flags_dcp_snapshot_marker_chk ,
& hf_extras_flags_dcp_snapshot_marker_ack ,
NULL
} ;
2017-02-14 15:07:46 +00:00
static dissector_handle_t couchbase_handle ;
2014-07-09 12:58:13 +00:00
static dissector_handle_t json_handle ;
/* desegmentation of COUCHBASE payload */
static gboolean couchbase_desegment_body = TRUE ;
2017-02-14 15:07:46 +00:00
static guint couchbase_ssl_port = 11207 ;
static guint couchbase_ssl_port_pref = 11207 ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
/** Read out the magic byte (located at offset 0 in the header) */
static guint8 get_magic ( tvbuff_t * tvb ) {
return tvb_get_guint8 ( tvb , 0 ) ;
}
/** Read out the opcode (located at offset 1 in the header) */
static guint8 get_opcode ( tvbuff_t * tvb ) {
return tvb_get_guint8 ( tvb , 1 ) ;
}
/** Read out the status code from the header (only "valid" for response packets) */
static guint16 get_status ( tvbuff_t * tvb ) {
return tvb_get_ntohs ( tvb , 6 ) ;
}
/** Read out flex size (using the upper bits of the key length when using flex encoding) */
static guint8 get_flex_framing_extras_length ( tvbuff_t * tvb ) {
if ( is_flex_encoded ( get_magic ( tvb ) ) ) {
return tvb_get_guint8 ( tvb , 2 ) ;
}
return 0 ;
}
/** Read out the size of the extras section (located at offset 4) */
static guint8 get_extras_length ( tvbuff_t * tvb ) {
return tvb_get_guint8 ( tvb , 4 ) ;
}
/** Read out the datatype section (located at offset 5) */
static guint8 get_datatype ( tvbuff_t * tvb ) {
return tvb_get_guint8 ( tvb , 5 ) ;
}
/** Read out the length of the key (1 or 2 bytes depending on the encoding) */
static guint16 get_key_length ( tvbuff_t * tvb ) {
if ( is_flex_encoded ( get_magic ( tvb ) ) ) {
return tvb_get_guint8 ( tvb , 3 ) ;
}
return tvb_get_ntohs ( tvb , 2 ) ;
}
/** Read out the size for the rest of the frame data */
static guint32 get_body_length ( tvbuff_t * tvb ) {
return tvb_get_ntohl ( tvb , 8 ) ;
}
2014-07-09 12:58:13 +00:00
2015-08-20 15:05:57 +00:00
/* Returns true if the specified opcode's response value is JSON. */
static gboolean
2018-03-20 12:21:08 +00:00
has_json_value ( gboolean is_request , guint8 opcode )
2015-08-20 15:05:57 +00:00
{
2018-03-20 12:21:08 +00:00
if ( is_request ) {
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_AUDIT_PUT :
2022-10-19 14:00:37 +00:00
case CLIENT_OPCODE_RANGE_SCAN_CREATE :
2018-03-20 12:21:08 +00:00
return TRUE ;
2015-08-20 15:05:57 +00:00
2018-03-20 12:21:08 +00:00
default :
return FALSE ;
}
} else {
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET_CLUSTER_CONFIG :
case CLIENT_OPCODE_SUBDOC_GET :
case CLIENT_OPCODE_COLLECTIONS_GET_MANIFEST :
case CLIENT_OPCODE_COLLECTIONS_SET_MANIFEST :
2018-03-20 12:21:08 +00:00
return TRUE ;
default :
return FALSE ;
}
2015-08-20 15:05:57 +00:00
}
}
2017-02-01 17:04:56 +00:00
static void dissect_dcp_xattrs ( tvbuff_t * tvb , proto_tree * tree ,
guint32 value_len , gint offset ,
packet_info * pinfo ) {
guint32 xattr_size , pair_len ;
gint mark ;
proto_tree * xattr_tree , * pair_tree ;
proto_item * ti ;
2017-02-19 18:04:54 +00:00
proto_tree_add_item_ret_uint ( tree , hf_xattr_length , tvb , offset , 4 , ENC_BIG_ENDIAN , & xattr_size ) ;
2017-02-01 17:04:56 +00:00
value_len = value_len - ( xattr_size + 4 ) ;
offset + = 4 ;
ti = proto_tree_add_item ( tree , hf_xattrs , tvb , offset , xattr_size , ENC_NA ) ;
xattr_tree = proto_item_add_subtree ( ti , ett_xattrs ) ;
while ( xattr_size > 0 ) {
ti = proto_tree_add_item_ret_uint ( xattr_tree , hf_xattr_pair_length , tvb , offset , 4 , ENC_BIG_ENDIAN , & pair_len ) ;
pair_tree = proto_item_add_subtree ( ti , ett_xattr_pair ) ;
offset + = 4 ;
xattr_size - = 4 ;
mark = tvb_find_guint8 ( tvb , offset , pair_len , 0x00 ) ;
if ( mark = = - 1 ) {
expert_add_info_format ( pinfo , ti , & ef_separator_not_found , " Null byte not found " ) ;
return ;
}
ti = proto_tree_add_item ( pair_tree , hf_xattr_key , tvb , offset , mark - offset , ENC_ASCII | ENC_NA ) ;
xattr_size - = ( mark - offset ) + 1 ;
pair_len - = ( mark - offset ) + 1 ;
offset = mark + 1 ;
mark = tvb_find_guint8 ( tvb , offset , pair_len , 0x00 ) ;
if ( mark = = - 1 ) {
expert_add_info_format ( pinfo , ti , & ef_separator_not_found , " Null byte not found " ) ;
return ;
}
proto_tree_add_item ( pair_tree , hf_xattr_value , tvb , offset , mark - offset , ENC_ASCII | ENC_NA ) ;
xattr_size - = ( mark - offset ) + 1 ;
offset = mark + 1 ;
}
//The regular value
proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
}
2016-02-19 13:36:31 +00:00
/* Dissects the required extras for subdoc single-path packets */
static void
dissect_subdoc_spath_required_extras ( tvbuff_t * tvb , proto_tree * extras_tree ,
guint8 extlen , gboolean request , gint * offset ,
guint16 * path_len , gboolean * illegal )
{
if ( request ) {
if ( extlen > = 3 ) {
* path_len = tvb_get_ntohs ( tvb , * offset ) ;
proto_tree_add_item ( extras_tree , hf_extras_pathlen , tvb , * offset , 2 ,
ENC_BIG_ENDIAN ) ;
* offset + = 2 ;
proto_tree_add_bitmask ( extras_tree , tvb , * offset , hf_subdoc_flags ,
ett_extras_flags , subdoc_flags , ENC_BIG_ENDIAN ) ;
* offset + = 1 ;
} else {
/* Must always have at least 3 bytes of extras */
* illegal = TRUE ;
}
}
}
2022-02-22 11:55:54 +00:00
static void dissect_server_request_extras ( tvbuff_t * tvb _U_ , packet_info * pinfo _U_ , proto_tree * tree , gint offset , guint8 extlen , guint8 opcode ) {
if ( extlen = = 0 ) {
switch ( opcode ) {
case SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION :
proto_tree_add_expert_format ( tree , pinfo , & ef_warn_must_have_extras , tvb , offset , 0 ,
" ClustermapChangeNotification request must have extras " ) ;
return ;
case SERVER_OPCODE_GET_AUTHORIZATION :
case SERVER_OPCODE_AUTHENTICATE :
case SERVER_OPCODE_ACTIVE_EXTERNAL_USERS :
// Success! none of these commands use extras
default :
// Probably ok as we don't know about the opcode
return ;
}
}
proto_item * extras_item = proto_tree_add_item ( tree , hf_extras , tvb , offset , extlen , ENC_NA ) ;
proto_tree * extras_tree = proto_item_add_subtree ( extras_item , ett_extras ) ;
if ( opcode = = SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION ) {
// Expected 16 bytes of extras!
if ( extlen < 16 ) {
proto_tree_add_expert_format ( extras_tree , pinfo ,
& ef_warn_illegal_extras_length , tvb ,
offset , extlen ,
" ClustermapChangeNotification should have 16 bytes of extras " ) ;
return ;
}
proto_tree_add_item ( extras_tree , hf_server_extras_cccp_epoch , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_server_extras_cccp_revno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
if ( extlen > 16 ) {
proto_tree_add_expert_format ( extras_tree , pinfo ,
& ef_warn_illegal_extras_length , tvb ,
offset + 16 , extlen - 16 ,
" Unexpected amount of extras " ) ;
}
return ;
}
// we don't know how to decode this!
proto_tree_add_item ( extras_tree , hf_extras_unknown , tvb , offset , extlen , ENC_NA ) ;
}
static void
dissect_server_response_extras ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * tree , gint offset , guint8 extlen ,
guint8 opcode _U_ ) {
if ( extlen = = 0 ) {
// Success! none of the known commands use extras
return ;
}
proto_item * extras_item = proto_tree_add_item ( tree , hf_extras , tvb , offset ,
extlen , ENC_NA ) ;
proto_tree * extras_tree = proto_item_add_subtree ( extras_item , ett_extras ) ;
proto_tree_add_expert_format ( extras_tree , pinfo ,
& ef_warn_illegal_extras_length , tvb ,
offset , extlen ,
" Unexpected amount of extras " ) ;
}
2014-07-09 12:58:13 +00:00
static void
2022-02-22 11:55:54 +00:00
dissect_client_extras ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
gint offset , guint8 extlen , guint8 opcode , gboolean request ,
guint16 * path_len )
2014-07-09 12:58:13 +00:00
{
proto_tree * extras_tree = NULL ;
proto_item * extras_item = NULL ;
gint save_offset = offset , ii ;
guint bpos ;
gboolean illegal = FALSE ; /* Set when extras shall not be present */
gboolean missing = FALSE ; /* Set when extras is missing */
gboolean first_flag ;
guint32 flags ;
proto_item * tf ;
const gchar * tap_connect_flags [ ] = {
" BACKFILL " , " DUMP " , " LIST_VBUCKETS " , " TAKEOVER_VBUCKETS " ,
" SUPPORT_ACK " , " REQUEST_KEYS_ONLY " , " CHECKPOINT " , " REGISTERED_CLIENT "
} ;
2015-08-20 15:05:57 +00:00
* path_len = 0 ;
2014-07-09 12:58:13 +00:00
if ( extlen ) {
extras_item = proto_tree_add_item ( tree , hf_extras , tvb , offset , extlen , ENC_NA ) ;
extras_tree = proto_item_add_subtree ( extras_item , ett_extras ) ;
}
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET :
case CLIENT_OPCODE_GETQ :
case CLIENT_OPCODE_GETK :
case CLIENT_OPCODE_GETKQ :
2014-07-09 12:58:13 +00:00
if ( extlen ) {
if ( request ) {
/* Request shall not have extras */
illegal = TRUE ;
} else {
proto_tree_add_item ( extras_tree , hf_extras_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
} else if ( ! request ) {
/* Response must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SET :
case CLIENT_OPCODE_SETQ :
case CLIENT_OPCODE_ADD :
case CLIENT_OPCODE_ADDQ :
case CLIENT_OPCODE_REPLACE :
case CLIENT_OPCODE_REPLACEQ :
2014-07-09 12:58:13 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
2019-09-16 10:58:14 +00:00
proto_tree_add_item ( extras_tree , hf_extras_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_mutation_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
2014-07-09 12:58:13 +00:00
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_INCREMENT :
case CLIENT_OPCODE_INCREMENTQ :
case CLIENT_OPCODE_DECREMENT :
case CLIENT_OPCODE_DECREMENTQ :
2014-07-09 12:58:13 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_delta , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_initial , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
2019-09-16 10:58:14 +00:00
proto_tree_add_item ( extras_tree , hf_extras_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_mutation_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
2014-07-09 12:58:13 +00:00
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_FLUSH :
case CLIENT_OPCODE_FLUSHQ :
2014-07-09 12:58:13 +00:00
if ( extlen ) {
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DELETE :
case CLIENT_OPCODE_DELETEQ :
case CLIENT_OPCODE_APPEND :
case CLIENT_OPCODE_APPENDQ :
case CLIENT_OPCODE_PREPEND :
case CLIENT_OPCODE_PREPENDQ :
2019-09-16 10:58:14 +00:00
if ( extlen ) {
if ( request ) {
/* Must not have extras */
illegal = TRUE ;
} else {
proto_tree_add_item ( extras_tree , hf_extras_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_mutation_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_QUIT :
case CLIENT_OPCODE_QUITQ :
case CLIENT_OPCODE_VERSION :
case CLIENT_OPCODE_STAT :
case CLIENT_OPCODE_OBSERVE :
case CLIENT_OPCODE_OBSERVE_SEQNO :
2014-07-09 12:58:13 +00:00
/* Must not have extras */
if ( extlen ) {
illegal = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET_ALL_VB_SEQNOS :
2015-10-30 07:39:01 +00:00
if ( extlen ) {
if ( request ) {
/* May have extras */
proto_tree_add_item ( extras_tree , hf_vbucket_states_state , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
/* Must not have extras */
illegal = TRUE ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_TAP_CONNECT :
2014-07-09 12:58:13 +00:00
{
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2014-07-09 12:58:13 +00:00
& hf_extras_flags_backfill ,
& hf_extras_flags_dump ,
& hf_extras_flags_list_vbuckets ,
& hf_extras_flags_takeover_vbuckets ,
& hf_extras_flags_support_ack ,
& hf_extras_flags_request_keys_only ,
& hf_extras_flags_checkpoint ,
NULL
} ;
2022-12-15 13:28:05 +00:00
/* TODO: extra_flags fields are 16-bits wide, whereas flags is 4 bytes? */
2014-07-09 12:58:13 +00:00
tf = proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
flags = tvb_get_ntohl ( tvb , offset ) ;
first_flag = TRUE ;
for ( ii = 0 ; ii < 8 ; ii + + ) {
bpos = 1 < < ii ;
if ( flags & bpos ) {
if ( first_flag ) {
proto_item_append_text ( tf , " ( " ) ;
}
proto_item_append_text ( tf , " %s%s " ,
first_flag ? " " : " , " ,
tap_connect_flags [ ii ] ) ;
first_flag = FALSE ;
}
}
if ( first_flag = = TRUE ) {
proto_item_append_text ( tf , " <None> " ) ;
} else {
proto_item_append_text ( tf , " ) " ) ;
}
offset + = 4 ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_TAP_MUTATION :
case CLIENT_OPCODE_TAP_DELETE :
case CLIENT_OPCODE_TAP_FLUSH :
case CLIENT_OPCODE_TAP_OPAQUE :
case CLIENT_OPCODE_TAP_VBUCKET_SET :
case CLIENT_OPCODE_TAP_CHECKPOINT_START :
case CLIENT_OPCODE_TAP_CHECKPOINT_END :
2014-07-09 12:58:13 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_OPEN_CONNECTION :
2014-11-18 18:11:22 +00:00
if ( extlen ) {
if ( request ) {
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2014-11-18 18:11:22 +00:00
& hf_extras_flags_dcp_connection_type ,
2017-02-01 17:04:56 +00:00
& hf_extras_flags_dcp_include_xattrs ,
& hf_extras_flags_dcp_no_value ,
2018-02-05 09:30:43 +00:00
& hf_extras_flags_dcp_collections ,
& hf_extras_flags_dcp_include_delete_times ,
2014-11-18 18:11:22 +00:00
NULL
} ;
proto_tree_add_item ( extras_tree , hf_extras_seqno , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
/* Response must not have extras (response is in Value) */
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
2014-07-09 12:58:13 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_ADD_STREAM :
2014-11-18 18:11:22 +00:00
if ( extlen ) {
if ( request ) {
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2014-11-18 18:11:22 +00:00
& hf_extras_flags_dcp_add_stream_takeover ,
& hf_extras_flags_dcp_add_stream_diskonly ,
& hf_extras_flags_dcp_add_stream_latest ,
NULL
} ;
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
proto_tree_add_item ( extras_tree , hf_extras_opaque , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
} else {
missing = TRUE ;
}
2014-07-09 12:58:13 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_STREAM_REQUEST :
2014-11-18 18:11:22 +00:00
if ( extlen ) {
if ( request ) {
2022-01-18 19:35:15 +00:00
/* No extra_flags and proto_tree_add_bitmask don't work with empty flags See Bug:17890
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2014-11-18 18:11:22 +00:00
NULL
} ;
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
2022-12-15 13:28:05 +00:00
*/
2022-01-18 19:35:15 +00:00
proto_tree_add_item ( extras_tree , hf_extras_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
2014-11-18 18:11:22 +00:00
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_reserved , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_start_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_end_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_snap_start_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_snap_end_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
2014-07-09 12:58:13 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_SNAPSHOT_MARKER :
2014-12-10 01:19:55 +00:00
if ( extlen ) {
if ( request ) {
2019-11-28 13:39:26 +00:00
// Two formats exist and the extlen allows us to know which is which
if ( extlen = = 1 ) {
proto_tree_add_item ( extras_tree , hf_extras_marker_version , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
} else if ( extlen = = 20 ) {
proto_tree_add_item ( extras_tree , hf_extras_start_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
2019-08-19 14:21:42 +00:00
offset + = 8 ;
2019-11-28 13:39:26 +00:00
proto_tree_add_item ( extras_tree , hf_extras_end_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , snapshot_marker_flags , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
illegal = TRUE ;
2019-08-19 14:21:42 +00:00
}
2014-12-10 01:19:55 +00:00
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_MUTATION :
2014-12-10 01:19:55 +00:00
if ( extlen ) {
if ( request ) {
2022-01-18 19:35:15 +00:00
/* No extra_flags and proto_tree_add_bitmask don't work with empty flags See Bug:17890
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2014-12-10 01:19:55 +00:00
NULL
} ;
2022-01-18 19:35:15 +00:00
*/
2014-12-10 01:19:55 +00:00
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_rev_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
2022-01-18 19:35:15 +00:00
/*
2014-12-10 01:19:55 +00:00
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
2022-01-18 19:35:15 +00:00
*/
proto_tree_add_item ( extras_tree , hf_extras_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
2014-12-10 01:19:55 +00:00
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_lock_time , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_nmeta , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
proto_tree_add_item ( extras_tree , hf_extras_nru , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_DELETION :
2018-02-05 09:30:43 +00:00
if ( request ) {
if ( extlen = = 18 | | extlen = = 21 ) {
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_rev_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
// Is this a delete with delete_time (21 bytes) or not (18 bytes)?
if ( extlen = = 18 ) {
proto_tree_add_item ( extras_tree , hf_extras_nmeta , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
} else if ( extlen = = 21 ) {
proto_tree_add_item ( extras_tree , hf_extras_delete_time , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
2018-12-03 11:38:24 +00:00
proto_tree_add_item ( extras_tree , hf_extras_delete_unused , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
2018-02-05 09:30:43 +00:00
offset + = 1 ;
}
} else if ( extlen = = 0 ) {
missing = TRUE ; // request with no extras
}
} else if ( extlen ) {
illegal = TRUE ; // response with extras
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_EXPIRATION :
2018-10-29 14:32:33 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_rev_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
if ( extlen = = 20 ) {
proto_tree_add_item ( extras_tree , hf_extras_delete_time , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
// Handle legacy expiration packet (despite its lack of use)
proto_tree_add_item ( extras_tree , hf_extras_nmeta , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
}
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_FLUSH :
2014-12-10 01:19:55 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_rev_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_nmeta , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_BUFFER_ACKNOWLEDGEMENT :
2015-10-30 07:39:01 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_bytes_to_ack , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_SYSTEM_EVENT : {
2018-12-03 11:38:24 +00:00
if ( request & & extlen = = 13 ) {
2018-02-05 09:30:43 +00:00
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_system_event_id , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
2018-12-03 11:38:24 +00:00
proto_tree_add_item ( extras_tree , hf_extras_system_event_version , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
2018-02-05 09:30:43 +00:00
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_PREPARE : {
2018-12-10 10:18:00 +00:00
if ( extlen ) {
if ( request ) {
2022-01-18 19:35:15 +00:00
/* No extra_flags and proto_tree_add_bitmask don't work with empty flags See Bug:17890
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2018-12-10 10:18:00 +00:00
NULL
} ;
2022-01-18 19:35:15 +00:00
*/
2018-12-10 10:18:00 +00:00
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_rev_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
2022-01-18 19:35:15 +00:00
/*
2018-12-10 10:18:00 +00:00
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_extras_flags , ett_extras_flags , extra_flags , ENC_BIG_ENDIAN ) ;
2022-01-18 19:35:15 +00:00
*/
proto_tree_add_item ( extras_tree , hf_extras_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
2018-12-10 10:18:00 +00:00
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_lock_time , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_nru , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item ( extras_tree , hf_extras_deleted , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item ( extras_tree , hf_flex_frame_durability_req , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_SEQNO_ACK : {
2018-12-10 10:18:00 +00:00
if ( extlen ) {
if ( request ) {
2019-05-24 13:06:28 +00:00
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
2018-12-10 10:18:00 +00:00
offset + = 8 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_COMMIT : {
2018-12-10 10:18:00 +00:00
if ( extlen ) {
if ( request ) {
2019-06-24 07:34:59 +00:00
proto_tree_add_item ( extras_tree , hf_extras_prepared_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
2019-05-24 13:06:28 +00:00
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
2018-12-10 10:18:00 +00:00
offset + = 8 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_ABORT : {
2018-12-10 10:18:00 +00:00
if ( extlen ) {
if ( request ) {
2019-06-14 16:31:09 +00:00
proto_tree_add_item ( extras_tree , hf_extras_prepared_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_extras_abort_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
2018-12-10 10:18:00 +00:00
offset + = 8 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_SEQNO_ADVANCED : {
2020-02-18 14:25:15 +00:00
if ( extlen ) {
if ( request ) {
proto_tree_add_item ( extras_tree , hf_extras_by_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_OSO_SNAPSHOT : {
2020-02-18 14:25:15 +00:00
if ( extlen ) {
if ( request ) {
2020-06-19 01:14:46 +00:00
static int * const extra_flags [ ] = {
2020-02-18 14:25:15 +00:00
& hf_extras_flags_dcp_oso_snapshot_begin ,
& hf_extras_flags_dcp_oso_snapshot_end ,
NULL
} ;
proto_tree_add_bitmask ( extras_tree ,
tvb ,
offset ,
hf_extras_dcp_oso_snapshot_flags ,
ett_extras_flags ,
extra_flags ,
ENC_BIG_ENDIAN ) ;
offset + = 4 ;
} else {
illegal = TRUE ;
}
} else if ( request ) {
/* Request must have extras */
missing = TRUE ;
}
break ;
}
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SUBDOC_GET :
case CLIENT_OPCODE_SUBDOC_EXISTS :
2016-02-19 13:36:31 +00:00
dissect_subdoc_spath_required_extras ( tvb , extras_tree , extlen , request ,
& offset , path_len , & illegal ) ;
2017-08-10 14:13:44 +00:00
if ( extlen = = 4 ) {
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_subdoc_doc_flags ,
ett_extras_flags , subdoc_doc_flags , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
}
2016-02-19 13:36:31 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SUBDOC_DICT_ADD :
case CLIENT_OPCODE_SUBDOC_DICT_UPSERT :
case CLIENT_OPCODE_SUBDOC_DELETE :
case CLIENT_OPCODE_SUBDOC_REPLACE :
case CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_LAST :
case CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_FIRST :
case CLIENT_OPCODE_SUBDOC_ARRAY_INSERT :
case CLIENT_OPCODE_SUBDOC_ARRAY_ADD_UNIQUE :
case CLIENT_OPCODE_SUBDOC_COUNTER :
2016-02-19 13:36:31 +00:00
dissect_subdoc_spath_required_extras ( tvb , extras_tree , extlen , request ,
& offset , path_len , & illegal ) ;
if ( request ) {
/* optional expiry only permitted for mutation requests,
2017-08-10 14:13:44 +00:00
if and only if ( extlen = = 7 | | extlen = = 8 ) */
if ( extlen = = 7 | | extlen = = 8 ) {
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset ,
4 , ENC_BIG_ENDIAN ) ;
2016-02-19 13:36:31 +00:00
offset + = 4 ;
2017-08-10 14:13:44 +00:00
}
/* optional doc flags only permitted if and only if
( extlen = = 4 | | extlen = = 8 ) */
if ( extlen = = 4 | | extlen = = 8 ) {
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_subdoc_doc_flags ,
ett_extras_flags , subdoc_doc_flags ,
ENC_BIG_ENDIAN ) ;
offset + = 1 ;
}
if ( extlen ! = 3 & & extlen ! = 7 & & extlen ! = 4 & & extlen ! = 8 ) {
2016-02-19 13:36:31 +00:00
illegal = TRUE ;
}
2015-08-20 15:05:57 +00:00
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP :
2015-08-20 15:05:57 +00:00
if ( request ) {
2017-08-10 14:13:44 +00:00
if ( extlen = = 1 ) {
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_subdoc_doc_flags ,
ett_extras_flags , subdoc_doc_flags ,
ENC_BIG_ENDIAN ) ;
offset + = 1 ;
} else {
illegal = TRUE ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SUBDOC_MULTI_MUTATION :
2017-08-10 14:13:44 +00:00
if ( request ) {
if ( extlen = = 4 | | extlen = = 5 ) {
proto_tree_add_item ( extras_tree , hf_extras_expiration , tvb , offset , 4 ,
ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
if ( extlen = = 1 | | extlen = = 5 ) {
proto_tree_add_bitmask ( extras_tree , tvb , offset , hf_subdoc_doc_flags ,
ett_extras_flags , subdoc_doc_flags , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
}
if ( extlen ! = 1 & & extlen ! = 4 & & extlen ! = 5 ) {
2015-08-20 15:05:57 +00:00
illegal = TRUE ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DEL_WITH_META :
case CLIENT_OPCODE_SET_WITH_META :
2017-02-02 15:28:59 +00:00
if ( request ) {
proto_tree_add_item ( extras_tree , hf_meta_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_meta_expiration , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_meta_revseqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_meta_cas , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
/*The previous 24 bytes are required. The next two fields are optional,
* hence we are checking the extlen to see what fields we have . As they
* are different lengths we can do this by just checking the length . */
// Options field (4 bytes)
if ( extlen = = 28 | | extlen = = 30 ) {
2022-12-15 13:28:05 +00:00
/* TODO: these fields are all 16 bits wide, but field is 32 bits? */
2019-01-22 15:51:57 +00:00
proto_tree_add_bitmask (
extras_tree ,
tvb ,
offset ,
hf_meta_options ,
ett_extras_flags ,
2022-02-21 08:34:07 +00:00
( opcode = = CLIENT_OPCODE_DEL_WITH_META ) ?
2019-01-22 15:51:57 +00:00
del_with_meta_extra_flags : set_with_meta_extra_flags ,
ENC_BIG_ENDIAN ) ;
offset + = 4 ;
2017-02-02 15:28:59 +00:00
}
// Meta Length field (2 bytes)
if ( extlen = = 26 | | extlen = = 30 ) {
proto_tree_add_item ( extras_tree , hf_metalen , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET_META :
2017-02-02 15:28:59 +00:00
if ( request ) {
if ( extlen ) {
proto_tree_add_item ( extras_tree , hf_meta_reqextmeta , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
}
} else {
proto_tree_add_item ( extras_tree , hf_meta_deleted , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_meta_flags , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_exptime , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_extras_meta_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
if ( extlen = = 21 ) {
proto_tree_add_item ( extras_tree , hf_confres , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
}
}
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_COLLECTIONS_GET_ID :
2019-02-14 14:30:18 +00:00
if ( ! request ) {
proto_tree_add_item ( extras_tree , hf_collection_manifest_id , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( extras_tree , hf_collection_key_id , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
break ;
2022-10-19 14:00:37 +00:00
case CLIENT_OPCODE_RANGE_SCAN_CONTINUE :
// https://github.com/couchbase/kv_engine/blob/master/docs/range_scans/range_scan_continue.md
if ( request ) {
proto_tree_add_item ( extras_tree , hf_range_scan_uuid , tvb , offset , 16 , ENC_BIG_ENDIAN ) ;
offset + = 16 ;
proto_tree_add_item ( extras_tree , hf_range_scan_item_limit , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_range_scan_time_limit , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
proto_tree_add_item ( extras_tree , hf_range_scan_byte_limit , tvb , offset , 4 , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
}
break ;
case CLIENT_OPCODE_RANGE_SCAN_CANCEL :
// https://github.com/couchbase/kv_engine/blob/master/docs/range_scans/range_scan_cancel.md
if ( request ) {
proto_tree_add_item ( extras_tree , hf_range_scan_uuid , tvb , offset , 16 , ENC_BIG_ENDIAN ) ;
offset + = 16 ;
}
break ;
2014-07-09 12:58:13 +00:00
default :
if ( extlen ) {
/* Decode as unknown extras */
proto_tree_add_item ( extras_tree , hf_extras_unknown , tvb , offset , extlen , ENC_NA ) ;
offset + = extlen ;
}
break ;
}
if ( illegal ) {
proto_tree_add_expert_format ( extras_tree , pinfo , & ef_warn_shall_not_have_extras , tvb , offset , 0 ,
" %s %s should not have extras " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode 0x%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
offset + = extlen ;
} else if ( missing ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_warn_must_have_extras , tvb , offset , 0 ,
" %s %s must have Extras " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode Ox%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
}
if ( ( offset - save_offset ) ! = extlen ) {
expert_add_info_format ( pinfo , extras_item , & ef_warn_illegal_extras_length ,
" Illegal Extras length, should be %d " , offset - save_offset ) ;
}
}
2018-12-03 11:38:24 +00:00
/*
Decode an unsigned leb128 int from a slice within a tvbuff_t
@ param tvb buffer to read from
@ param start index of the first byte of ' slice '
@ param end index of the last byte of the buffer ' slice '
@ param [ out ] value the decoded value
@ returns next byte after the leb128 bytes or - 1 if we failed to decode
*/
static gint
dissect_unsigned_leb128 ( tvbuff_t * tvb , gint start , gint end , guint32 * value ) {
guint8 byte = tvb_get_guint8 ( tvb , start ) ;
* value = byte & 0x7f ;
if ( ( byte & 0x80 ) = = 0x80 ) {
guint32 shift = 7 ;
2019-01-03 01:00:22 +00:00
gint byte_idx ;
for ( byte_idx = start + 1 ; byte_idx < end ; byte_idx + + ) {
byte = tvb_get_guint8 ( tvb , byte_idx ) ;
2019-03-04 13:12:59 +00:00
/* Ensure we are using a valid shift */
if ( shift > 32 )
return - 1 ;
2018-12-03 11:38:24 +00:00
* value | = ( byte & 0x7f ) < < shift ;
if ( ( byte & 0x80 ) = = 0 ) {
break ;
}
shift + = 7 ;
}
2019-01-03 01:00:22 +00:00
return ( byte_idx = = end ) ? - 1 : byte_idx + 1 ;
2018-12-03 11:38:24 +00:00
}
return start + 1 ;
}
2022-02-22 11:55:54 +00:00
static void dissect_server_key ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , gint offset , int keylen , guint8 opcode , bool request ) {
if ( keylen = = 0 ) {
switch ( opcode ) {
case SERVER_OPCODE_GET_AUTHORIZATION :
if ( request ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_warn_must_have_key ,
tvb , offset , 0 ,
" GetAuthorization request must have key " ) ;
}
return ;
case SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION :
if ( request ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_warn_must_have_key ,
tvb , offset , 0 ,
" ClustermapChangeNotification request must have key " ) ;
}
case SERVER_OPCODE_AUTHENTICATE :
case SERVER_OPCODE_ACTIVE_EXTERNAL_USERS :
// Success! none of these commands want a key
default :
// Probably ok as we don't know about the opcode
return ;
}
}
proto_item * ti = proto_tree_add_item ( tree , hf_key , tvb , offset , keylen , ENC_UTF_8 | ENC_STR_HEX ) ;
switch ( opcode ) {
case SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION :
if ( ! request ) {
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_key ,
" ClustermapChangeNotification response shall not have key " ) ;
}
break ;
case SERVER_OPCODE_AUTHENTICATE :
case SERVER_OPCODE_ACTIVE_EXTERNAL_USERS :
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_key ,
" %s %s shall not have Key " ,
val_to_str_ext ( opcode ,
& server_opcode_vals_ext ,
" Opcode 0x%x " ) ,
request ? " Request " : " Response " ) ;
break ;
case SERVER_OPCODE_GET_AUTHORIZATION :
if ( ! request ) {
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_key ,
" GetAuthorization response shall not have key " ) ;
}
break ;
default :
break ;
}
}
2014-07-09 12:58:13 +00:00
static void
2022-02-22 11:55:54 +00:00
dissect_client_key ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
gint offset , int keylen , guint8 opcode , gboolean request )
2014-07-09 12:58:13 +00:00
{
proto_item * ti = NULL ;
gboolean illegal = FALSE ; /* Set when key shall not be present */
gboolean missing = FALSE ; /* Set when key is missing */
if ( keylen ) {
2022-02-24 09:00:44 +00:00
bool collection_encoded_key = TRUE ;
switch ( opcode ) {
case CLIENT_OPCODE_STAT :
case CLIENT_OPCODE_HELLO :
case CLIENT_OPCODE_SASL_AUTH :
case CLIENT_OPCODE_SASL_STEP :
case CLIENT_OPCODE_IOCTL_GET :
case CLIENT_OPCODE_IOCTL_SET :
case CLIENT_OPCODE_DCP_CONTROL :
case CLIENT_OPCODE_SET_PARAM :
case CLIENT_OPCODE_CREATE_BUCKET :
case CLIENT_OPCODE_DELETE_BUCKET :
case CLIENT_OPCODE_SELECT_BUCKET :
case CLIENT_OPCODE_IFCONFIG :
collection_encoded_key = FALSE ;
break ;
default :
break ;
}
2018-12-07 11:58:31 +00:00
ti = proto_tree_add_item ( tree , hf_key , tvb , offset , keylen , ENC_UTF_8 | ENC_STR_HEX ) ;
2018-12-03 11:38:24 +00:00
2022-02-24 09:00:44 +00:00
if ( collection_encoded_key ) {
/* assume collections are enabled and add a field for the CID */
guint32 cid = 0 ;
gint ok = dissect_unsigned_leb128 ( tvb , offset , offset + keylen , & cid ) ;
/* Add collection info to a subtree */
proto_tree * cid_tree = proto_item_add_subtree ( ti , ett_collection_key ) ;
if ( ok = = - 1 ) {
/* cid decode issue, could just be a non-collection stream, don't warn
just add some info */
proto_tree_add_string_format ( cid_tree ,
hf_collection_key_logical ,
tvb ,
offset ,
keylen ,
NULL ,
" Collection ID didn't decode, maybe no CID. " ) ;
} else {
proto_tree_add_uint ( cid_tree , hf_collection_key_id , tvb , offset ,
( ok - offset ) , cid ) ;
proto_tree_add_item ( cid_tree , hf_collection_key_logical , tvb ,
ok , keylen - ( ok - offset ) , ENC_UTF_8 | ENC_STR_HEX ) ;
}
2018-12-03 11:38:24 +00:00
}
2014-07-09 12:58:13 +00:00
offset + = keylen ;
}
/* inSanity check */
if ( keylen ) {
2014-11-18 18:11:22 +00:00
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_QUIT :
case CLIENT_OPCODE_QUITQ :
case CLIENT_OPCODE_NOOP :
case CLIENT_OPCODE_VERSION :
case CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST :
case CLIENT_OPCODE_DCP_BUFFER_ACKNOWLEDGEMENT :
case CLIENT_OPCODE_GET_ALL_VB_SEQNOS :
2014-07-09 12:58:13 +00:00
/* Request and Response must not have key */
illegal = TRUE ;
2014-11-18 18:11:22 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SET :
case CLIENT_OPCODE_ADD :
case CLIENT_OPCODE_REPLACE :
case CLIENT_OPCODE_DELETE :
case CLIENT_OPCODE_SETQ :
case CLIENT_OPCODE_ADDQ :
case CLIENT_OPCODE_REPLACEQ :
case CLIENT_OPCODE_DELETEQ :
case CLIENT_OPCODE_FLUSH :
case CLIENT_OPCODE_APPEND :
case CLIENT_OPCODE_PREPEND :
case CLIENT_OPCODE_FLUSHQ :
case CLIENT_OPCODE_APPENDQ :
case CLIENT_OPCODE_PREPENDQ :
2014-07-09 12:58:13 +00:00
/* Response must not have a key */
if ( ! request ) {
illegal = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_ADD_STREAM :
case CLIENT_OPCODE_DCP_CLOSE_STREAM :
case CLIENT_OPCODE_DCP_STREAM_END :
case CLIENT_OPCODE_DCP_SNAPSHOT_MARKER :
case CLIENT_OPCODE_DCP_FLUSH :
case CLIENT_OPCODE_DCP_SET_VBUCKET_STATE :
2014-07-09 12:58:13 +00:00
/* Request must not have a key */
if ( request ) {
illegal = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2014-07-09 12:58:13 +00:00
}
} else {
2014-11-18 18:11:22 +00:00
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET :
case CLIENT_OPCODE_GETQ :
case CLIENT_OPCODE_GETK :
case CLIENT_OPCODE_GETKQ :
case CLIENT_OPCODE_SET :
case CLIENT_OPCODE_ADD :
case CLIENT_OPCODE_REPLACE :
case CLIENT_OPCODE_DELETE :
case CLIENT_OPCODE_SETQ :
case CLIENT_OPCODE_ADDQ :
case CLIENT_OPCODE_REPLACEQ :
case CLIENT_OPCODE_DELETEQ :
case CLIENT_OPCODE_INCREMENT :
case CLIENT_OPCODE_DECREMENT :
case CLIENT_OPCODE_INCREMENTQ :
case CLIENT_OPCODE_DECREMENTQ :
case CLIENT_OPCODE_DCP_OPEN_CONNECTION :
case CLIENT_OPCODE_DCP_MUTATION :
case CLIENT_OPCODE_DCP_DELETION :
case CLIENT_OPCODE_DCP_EXPIRATION :
case CLIENT_OPCODE_DCP_SYSTEM_EVENT :
2014-07-09 12:58:13 +00:00
/* Request must have key */
if ( request ) {
missing = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2014-07-09 12:58:13 +00:00
}
}
if ( illegal ) {
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_key , " %s %s shall not have Key " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode 0x%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
} else if ( missing ) {
proto_tree_add_expert_format ( tree , pinfo , & ef_warn_must_have_key , tvb , offset , 0 ,
" %s %s must have Key " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode Ox%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
}
}
2015-08-20 15:05:57 +00:00
static void
dissect_multipath_lookup_response ( tvbuff_t * tvb , packet_info * pinfo ,
proto_tree * tree , gint offset , guint32 value_len )
{
gint end = offset + value_len ;
int spec_idx = 0 ;
while ( offset < end ) {
proto_item * ti ;
proto_tree * multipath_tree ;
tvbuff_t * json_tvb ;
guint32 result_len ;
gint start_offset = offset ;
ti = proto_tree_add_subtree_format ( tree , tvb , offset , - 1 , ett_multipath ,
& multipath_tree , " Lookup Result [ %u ] " ,
spec_idx ) ;
proto_tree_add_item ( multipath_tree , hf_status , tvb , offset , 2 ,
ENC_BIG_ENDIAN ) ;
offset + = 2 ;
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 ) {
2017-01-10 06:18:49 +00:00
json_tvb = tvb_new_subset_length_caplen ( tvb , offset , result_len , result_len ) ;
2015-08-20 15:05:57 +00:00
call_dissector ( json_handle , json_tvb , pinfo , multipath_tree ) ;
}
offset + = result_len ;
proto_item_set_len ( ti , offset - start_offset ) ;
spec_idx + + ;
}
}
2016-02-03 12:32:25 +00:00
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 ;
2022-02-21 08:34:07 +00:00
if ( status = = STATUS_SUCCESS ) {
2016-02-03 12:32:25 +00:00
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 ) {
2017-01-10 06:18:49 +00:00
json_tvb = tvb_new_subset_length_caplen ( tvb , offset , result_len , result_len ) ;
2016-02-03 12:32:25 +00:00
call_dissector ( json_handle , json_tvb , pinfo , multipath_tree ) ;
}
offset + = result_len ;
}
proto_item_set_len ( ti , offset - start_offset ) ;
spec_idx + + ;
}
}
2015-08-20 15:05:57 +00:00
static void
dissect_multipath_value ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
gint offset , guint32 value_len , gboolean is_mutation ,
gboolean request )
{
gint end = offset + value_len ;
int spec_idx = 0 ;
proto_item * ti ;
proto_tree * multipath_tree ;
if ( request ) {
gint min_spec_size ;
2017-09-01 08:12:37 +00:00
/* Minimum size is the fixed header. */
min_spec_size = ( is_mutation ? 8 : 4 ) ;
2015-08-20 15:05:57 +00:00
2017-07-13 11:21:04 +00:00
while ( offset + min_spec_size < = end ) {
2015-08-20 15:05:57 +00:00
guint32 path_len ;
guint32 spec_value_len = 0 ;
gint start_offset = offset ;
ti = proto_tree_add_subtree_format ( tree , tvb , offset , - 1 , ett_multipath ,
& multipath_tree ,
( is_mutation ? " Mutation spec [ %u ] "
: " Lookup spec [ %u ] " ) ,
spec_idx ) ;
proto_tree_add_item ( multipath_tree , hf_multipath_opcode , tvb , offset , 1 ,
ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_bitmask ( multipath_tree , tvb , offset , hf_subdoc_flags ,
ett_extras_flags , subdoc_flags , ENC_BIG_ENDIAN ) ;
offset + = 1 ;
proto_tree_add_item_ret_uint ( multipath_tree , hf_multipath_pathlen , tvb ,
offset , 2 , ENC_BIG_ENDIAN , & path_len ) ;
offset + = 2 ;
if ( is_mutation ) {
proto_tree_add_item_ret_uint ( multipath_tree , hf_multipath_valuelen ,
tvb , offset , 4 , ENC_BIG_ENDIAN ,
& spec_value_len ) ;
offset + = 4 ;
}
2017-09-01 08:12:37 +00:00
if ( path_len ) {
proto_tree_add_item ( multipath_tree , hf_multipath_path , tvb , offset , path_len ,
ENC_ASCII | ENC_NA ) ;
offset + = path_len ;
}
2015-08-20 15:05:57 +00:00
if ( spec_value_len > 0 ) {
2016-02-05 12:21:35 +00:00
proto_tree_add_item ( multipath_tree , hf_multipath_value , tvb , offset ,
2015-08-20 15:05:57 +00:00
spec_value_len , ENC_ASCII | ENC_NA ) ;
offset + = spec_value_len ;
}
proto_item_set_len ( ti , offset - start_offset ) ;
spec_idx + + ;
}
} else {
if ( is_mutation ) {
2016-02-03 12:32:25 +00:00
dissect_multipath_mutation_response ( tvb , pinfo , tree , offset , value_len ) ;
2015-08-20 15:05:57 +00:00
} else {
dissect_multipath_lookup_response ( tvb , pinfo , tree , offset , value_len ) ;
}
}
}
2014-07-09 12:58:13 +00:00
static void
dissect_value ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
2015-08-20 15:05:57 +00:00
gint offset , guint32 value_len , guint16 path_len , guint8 opcode ,
2017-02-01 17:04:56 +00:00
gboolean request , guint8 datatype )
2014-07-09 12:58:13 +00:00
{
proto_item * ti = NULL ;
gboolean illegal = FALSE ; /* Set when value shall not be present */
gboolean missing = FALSE ; /* Set when value is missing */
if ( value_len > 0 ) {
2022-02-21 08:34:07 +00:00
if ( opcode = = CLIENT_OPCODE_OBSERVE ) {
2014-11-18 18:11:22 +00:00
proto_tree * observe_tree ;
2014-07-09 12:58:13 +00:00
gint oo = offset , end = offset + value_len ;
2022-02-15 02:45:20 +00:00
ti = proto_tree_add_item ( tree , hf_observe , tvb , offset , value_len , ENC_ASCII ) ;
2014-07-09 12:58:13 +00:00
observe_tree = proto_item_add_subtree ( ti , ett_observe ) ;
while ( oo < end ) {
guint16 kl ; /* keylength */
proto_tree_add_item ( observe_tree , hf_observe_vbucket , tvb , oo , 2 , ENC_BIG_ENDIAN ) ;
oo + = 2 ;
kl = tvb_get_ntohs ( tvb , oo ) ;
proto_tree_add_item ( observe_tree , hf_observe_keylength , tvb , oo , 2 , ENC_BIG_ENDIAN ) ;
oo + = 2 ;
2022-02-15 02:45:20 +00:00
proto_tree_add_item ( observe_tree , hf_observe_key , tvb , oo , kl , ENC_ASCII ) ;
2014-07-09 12:58:13 +00:00
oo + = kl ;
if ( ! request ) {
proto_tree_add_item ( observe_tree , hf_observe_status , tvb , oo , 1 , ENC_BIG_ENDIAN ) ;
oo + + ;
proto_tree_add_item ( observe_tree , hf_observe_cas , tvb , oo , 8 , ENC_BIG_ENDIAN ) ;
oo + = 8 ;
}
}
2022-02-21 08:34:07 +00:00
} else if ( opcode = = CLIENT_OPCODE_OBSERVE_SEQNO ) {
2016-07-05 22:22:11 +00:00
if ( request ) {
ti = proto_tree_add_item ( tree , hf_observe_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
if ( value_len ! = 8 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be 8 " ) ;
}
} else {
/*
* < format_type , vbucket id , vbucket uuid , last_persisted_seqno , current_seqno >
*
* - format_type is of type uint8_t and it describes whether
* the vbucket has failed over or not . 1 indicates a hard
* failover , 0 indicates otherwise .
* - vbucket id is of type uint16_t and it is the identifier for
* the vbucket .
* - vbucket uuid is of type uint64_t and it represents a UUID for
* the vbucket .
* - last_persisted_seqno is of type uint64_t and it is the
* last sequence number that was persisted for this
* vbucket .
* - current_seqno is of the type uint64_t and it is the
* sequence number of the latest mutation in the vbucket .
*
* In the case of a hard failover , the tuple is of the form
* < format_type , vbucket id , vbucket uuid , last_persisted_seqno , current_seqno ,
* old vbucket uuid , last_received_seqno >
*
* - old vbucket uuid is of type uint64_t and it is the
* vbucket UUID of the vbucket prior to the hard failover .
*
* - last_received_seqno is of type uint64_t and it is the
* last received sequence number in the old vbucket uuid .
*
* The other fields are the same as that mentioned in the normal case .
*/
guint8 failed_over ;
proto_tree_add_item ( tree , hf_observe_failed_over , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
failed_over = tvb_get_guint8 ( tvb , offset ) ;
offset + + ;
proto_tree_add_item ( tree , hf_observe_vbucket , tvb , offset , 2 , ENC_BIG_ENDIAN ) ;
offset + = 2 ;
proto_tree_add_item ( tree , hf_observe_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( tree , hf_observe_last_persisted_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( tree , hf_observe_current_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
if ( failed_over ) {
proto_tree_add_item ( tree , hf_observe_old_vbucket_uuid , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( tree , hf_observe_last_received_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
}
}
2022-02-21 08:34:07 +00:00
} else if ( ! request & & ( opcode = = CLIENT_OPCODE_DCP_STREAM_REQUEST | | opcode = = CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST ) ) {
2014-11-18 18:11:22 +00:00
if ( value_len % 16 ! = 0 ) {
2015-10-30 07:39:01 +00:00
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Response with bad failover log length " ) ;
2014-11-18 18:11:22 +00:00
} else {
proto_tree * failover_log_tree ;
gint cur = offset , end = offset + value_len ;
2022-02-15 02:45:20 +00:00
ti = proto_tree_add_item ( tree , hf_failover_log , tvb , offset , value_len , ENC_ASCII ) ;
2014-11-18 18:11:22 +00:00
failover_log_tree = proto_item_add_subtree ( ti , ett_failover_log ) ;
ti = proto_tree_add_uint ( failover_log_tree , hf_failover_log_size , tvb , offset , 0 , ( end - cur ) / 16 ) ;
2019-04-03 21:32:30 +00:00
proto_item_set_generated ( ti ) ;
2014-11-18 18:11:22 +00:00
while ( cur < end ) {
proto_tree_add_item ( failover_log_tree , hf_failover_log_vbucket_uuid , tvb , cur , 8 , ENC_BIG_ENDIAN ) ;
cur + = 8 ;
proto_tree_add_item ( failover_log_tree , hf_failover_log_vbucket_seqno , tvb , cur , 8 , ENC_BIG_ENDIAN ) ;
cur + = 8 ;
}
}
2022-02-21 08:34:07 +00:00
} else if ( ! request & & opcode = = CLIENT_OPCODE_GET_ALL_VB_SEQNOS ) {
2015-10-30 07:39:01 +00:00
if ( value_len % 10 ! = 0 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Response with bad body length " ) ;
} else {
proto_tree * vbucket_states_tree ;
gint cur = offset , end = offset + value_len ;
2022-02-15 02:45:20 +00:00
ti = proto_tree_add_item ( tree , hf_vbucket_states , tvb , offset , value_len , ENC_ASCII ) ;
2015-10-30 07:39:01 +00:00
vbucket_states_tree = proto_item_add_subtree ( ti , ett_vbucket_states ) ;
ti = proto_tree_add_uint ( vbucket_states_tree , hf_vbucket_states_size , tvb , offset , 0 , ( end - cur ) / 10 ) ;
2019-04-03 21:32:30 +00:00
proto_item_set_generated ( ti ) ;
2015-10-30 07:39:01 +00:00
while ( cur < end ) {
proto_tree_add_item ( vbucket_states_tree , hf_vbucket_states_id , tvb , cur , 2 , ENC_BIG_ENDIAN ) ;
cur + = 2 ;
proto_tree_add_item ( vbucket_states_tree , hf_vbucket_states_seqno , tvb , cur , 8 , ENC_BIG_ENDIAN ) ;
cur + = 8 ;
}
}
2022-02-21 08:34:07 +00:00
} else if ( ! request & & ( opcode = = CLIENT_OPCODE_INCREMENT | | opcode = = CLIENT_OPCODE_DECREMENT ) ) {
2014-07-09 12:58:13 +00:00
ti = proto_tree_add_item ( tree , hf_uint64_response , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
if ( value_len ! = 8 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be 8 " ) ;
}
2018-03-20 12:21:08 +00:00
} else if ( has_json_value ( request , opcode ) ) {
2014-07-09 12:58:13 +00:00
tvbuff_t * json_tvb ;
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
2017-01-10 06:18:49 +00:00
json_tvb = tvb_new_subset_length_caplen ( tvb , offset , value_len , value_len ) ;
2014-07-09 12:58:13 +00:00
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
2015-08-20 15:05:57 +00:00
2022-02-21 08:34:07 +00:00
} else if ( opcode = = CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP | |
opcode = = CLIENT_OPCODE_SUBDOC_MULTI_MUTATION ) {
2015-08-20 15:05:57 +00:00
dissect_multipath_value ( tvb , pinfo , tree , offset , value_len ,
2022-02-21 08:34:07 +00:00
( opcode = = CLIENT_OPCODE_SUBDOC_MULTI_MUTATION ) ,
2015-08-20 15:05:57 +00:00
request ) ;
2022-02-21 08:34:07 +00:00
} else if ( opcode = = CLIENT_OPCODE_HELLO ) {
2017-02-01 17:04:56 +00:00
gint curr = offset , end = offset + value_len ;
proto_tree * hello_features_tree ;
2022-02-15 02:45:20 +00:00
ti = proto_tree_add_item ( tree , hf_hello_features , tvb , offset , value_len , ENC_ASCII ) ;
2017-02-01 17:04:56 +00:00
hello_features_tree = proto_item_add_subtree ( ti , ett_hello_features ) ;
while ( curr < end ) {
proto_tree_add_item ( hello_features_tree , hf_hello_features_feature , tvb , curr , 2 , ENC_BIG_ENDIAN ) ;
curr + = 2 ;
}
2022-10-19 14:00:37 +00:00
} else if ( ! request & & opcode = = CLIENT_OPCODE_RANGE_SCAN_CREATE ) {
proto_tree_add_item ( tree , hf_range_scan_uuid , tvb , offset , 16 , ENC_BIG_ENDIAN ) ;
2015-08-20 15:05:57 +00:00
} else if ( path_len ! = 0 ) {
ti = proto_tree_add_item ( tree , hf_path , tvb , offset , path_len , ENC_ASCII | ENC_NA ) ;
value_len - = path_len ;
if ( value_len > 0 ) {
ti = proto_tree_add_item ( tree , hf_value , tvb , offset + path_len ,
value_len , ENC_ASCII | ENC_NA ) ;
}
2022-02-21 08:34:07 +00:00
} else if ( request & & opcode = = CLIENT_OPCODE_CREATE_BUCKET ) {
2017-02-03 12:42:32 +00:00
gint sep , equals_pos , sep_pos , config_len ;
2017-09-05 11:39:09 +00:00
proto_tree * key_tree , * config_tree = NULL ;
2017-02-03 12:42:32 +00:00
/* There are 2 main items stored in the value. The bucket type (represented by a path to the engine) and the
* bucket config . These are separated by a NULL byte with the bucket type coming first . */
sep = tvb_find_guint8 ( tvb , offset , value_len , 0x00 ) ;
if ( sep = = - 1 ) {
2022-02-15 02:45:20 +00:00
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII ) ;
2017-02-03 12:42:32 +00:00
expert_add_info_format ( pinfo , ti , & ef_separator_not_found , " Null byte not found " ) ;
} else {
proto_tree_add_item ( tree , hf_bucket_type , tvb , offset , sep - offset , ENC_ASCII | ENC_NA ) ;
config_len = value_len - ( sep - offset ) - 1 ; //Don't include NULL byte in length
if ( config_len < = 0 ) {
expert_add_info_format ( pinfo , ti , & ef_separator_not_found , " Separator not found in expected location " ) ;
} else {
offset = sep + 1 ; // Ignore NULL byte
ti = proto_tree_add_item ( tree , hf_bucket_config , tvb , offset , config_len , ENC_ASCII | ENC_NA ) ;
config_tree = proto_item_add_subtree ( ti , ett_config ) ;
}
/* The config is arranged as "key=value;key=value..."*/
while ( config_len > 0 ) {
// Get the key
equals_pos = tvb_find_guint8 ( tvb , offset , config_len , 0x3d ) ;
if ( equals_pos = = - 1 ) {
expert_add_info_format ( pinfo , ti , & ef_illegal_value , " Each key needs a value " ) ;
break ; // Break out the while loop
}
ti = proto_tree_add_item ( config_tree , hf_config_key , tvb , offset , equals_pos - offset , ENC_ASCII | ENC_NA ) ;
key_tree = proto_item_add_subtree ( ti , ett_config_key ) ;
config_len - = ( equals_pos - offset + 1 ) ;
offset = equals_pos + 1 ;
if ( config_len < = 0 ) {
expert_add_info_format ( pinfo , ti , & ef_illegal_value , " Corresponding value missing " ) ;
break ; //Break out of while loop
}
// Get the value
sep_pos = tvb_find_guint8 ( tvb , offset , config_len , 0x3b ) ;
if ( sep_pos = = - 1 ) {
expert_add_info_format ( pinfo , ti , & ef_separator_not_found , " Each key-value pair must be terminated by semi-colon " ) ;
break ; // Break out the while loop
}
proto_tree_add_item ( key_tree , hf_config_value , tvb , offset , sep_pos - offset , ENC_ASCII | ENC_NA ) ;
config_len - = ( sep_pos - offset + 1 ) ;
offset = sep_pos + 1 ;
}
}
2022-02-21 08:34:07 +00:00
} else if ( ( datatype & DT_XATTR ) & & ( opcode = = CLIENT_OPCODE_SET_WITH_META | |
opcode = = CLIENT_OPCODE_DCP_MUTATION | | opcode = = CLIENT_OPCODE_DCP_DELETION | |
opcode = = CLIENT_OPCODE_DCP_EXPIRATION | | opcode = = CLIENT_OPCODE_DCP_PREPARE | |
opcode = = CLIENT_OPCODE_DEL_WITH_META | | opcode = = CLIENT_OPCODE_ADD_WITH_META | |
opcode = = CLIENT_OPCODE_SETQ_WITH_META | | opcode = = CLIENT_OPCODE_DELQ_WITH_META | |
opcode = = CLIENT_OPCODE_ADDQ_WITH_META ) ) {
2017-02-01 17:04:56 +00:00
dissect_dcp_xattrs ( tvb , tree , value_len , offset , pinfo ) ;
2022-02-21 08:34:07 +00:00
} else if ( request & & opcode = = CLIENT_OPCODE_GET_ERROR_MAP ) {
2017-08-10 10:00:20 +00:00
if ( value_len ! = 2 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be 2 " ) ;
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
} else {
ti = proto_tree_add_item ( tree , hf_get_errmap_version , tvb , offset , value_len , ENC_BIG_ENDIAN ) ;
}
2022-02-21 08:34:07 +00:00
} else if ( request & & opcode = = CLIENT_OPCODE_DCP_SNAPSHOT_MARKER ) {
2022-04-22 07:35:36 +00:00
if ( value_len < 20 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be at least 20 " ) ;
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
}
2019-11-28 13:39:26 +00:00
proto_tree_add_item ( tree , hf_extras_start_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( tree , hf_extras_end_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_bitmask ( tree , tvb , offset , hf_extras_flags , ett_extras_flags , snapshot_marker_flags , ENC_BIG_ENDIAN ) ;
offset + = 4 ;
2022-04-22 07:35:36 +00:00
if ( value_len > 20 ) {
if ( value_len < 36 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be at least 36 " ) ;
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
}
proto_tree_add_item ( tree , hf_extras_max_visible_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
proto_tree_add_item ( tree , hf_extras_high_completed_seqno , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
offset + = 8 ;
if ( value_len > 36 ) {
if ( value_len ! = 44 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_illegal_value_length , " Illegal Value length, should be 44 " ) ;
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
}
proto_tree_add_item ( tree , hf_extras_timestamp , tvb , offset , 8 , ENC_BIG_ENDIAN ) ;
}
}
2014-07-09 12:58:13 +00:00
} else {
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , value_len , ENC_ASCII | ENC_NA ) ;
2017-12-20 21:24:35 +00:00
# ifdef HAVE_SNAPPY
if ( datatype & DT_SNAPPY ) {
size_t orig_size = 0 ;
snappy_status ret ;
guchar * decompressed_buffer = NULL ;
tvbuff_t * compressed_tvb = NULL ;
ret = snappy_uncompressed_length ( tvb_get_ptr ( tvb , offset , - 1 ) ,
tvb_captured_length_remaining ( tvb , offset ) ,
& orig_size ) ;
if ( ret = = SNAPPY_OK ) {
decompressed_buffer = ( guchar * ) wmem_alloc ( pinfo - > pool , orig_size ) ;
ret = snappy_uncompress ( tvb_get_ptr ( tvb , offset , - 1 ) ,
tvb_captured_length_remaining ( tvb , offset ) ,
decompressed_buffer ,
& orig_size ) ;
if ( ret = = SNAPPY_OK ) {
compressed_tvb = tvb_new_child_real_data ( tvb , decompressed_buffer , ( guint32 ) orig_size , ( guint32 ) orig_size ) ;
add_new_data_source ( pinfo , compressed_tvb , " Decompressed Data " ) ;
if ( datatype & DT_JSON ) {
call_dissector ( json_handle , compressed_tvb , pinfo , tree ) ;
}
} else {
expert_add_info_format ( pinfo , ti , & ef_compression_error , " Error uncompressing snappy data " ) ;
}
} else {
expert_add_info_format ( pinfo , ti , & ef_compression_error , " Error uncompressing snappy data " ) ;
}
}
# endif
2014-07-09 12:58:13 +00:00
}
2014-11-18 18:11:22 +00:00
}
2014-07-09 12:58:13 +00:00
/* Sanity check */
if ( value_len ) {
2014-11-18 18:11:22 +00:00
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_GET :
case CLIENT_OPCODE_GETQ :
case CLIENT_OPCODE_GETK :
case CLIENT_OPCODE_GETKQ :
case CLIENT_OPCODE_INCREMENT :
case CLIENT_OPCODE_DECREMENT :
case CLIENT_OPCODE_VERSION :
case CLIENT_OPCODE_INCREMENTQ :
case CLIENT_OPCODE_DECREMENTQ :
case CLIENT_OPCODE_DCP_OPEN_CONNECTION :
case CLIENT_OPCODE_DCP_ADD_STREAM :
case CLIENT_OPCODE_DCP_CLOSE_STREAM :
case CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST :
case CLIENT_OPCODE_DCP_STREAM_END :
case CLIENT_OPCODE_DCP_DELETION :
case CLIENT_OPCODE_DCP_EXPIRATION :
case CLIENT_OPCODE_DCP_FLUSH :
case CLIENT_OPCODE_DCP_SET_VBUCKET_STATE :
2014-07-09 12:58:13 +00:00
/* Request must not have value */
if ( request ) {
illegal = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DELETE :
case CLIENT_OPCODE_QUIT :
case CLIENT_OPCODE_FLUSH :
case CLIENT_OPCODE_NOOP :
case CLIENT_OPCODE_DELETEQ :
case CLIENT_OPCODE_QUITQ :
case CLIENT_OPCODE_FLUSHQ :
2014-07-09 12:58:13 +00:00
/* Request and Response must not have value */
illegal = TRUE ;
2014-11-18 18:11:22 +00:00
break ;
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_SET :
case CLIENT_OPCODE_ADD :
case CLIENT_OPCODE_REPLACE :
case CLIENT_OPCODE_SETQ :
case CLIENT_OPCODE_ADDQ :
case CLIENT_OPCODE_REPLACEQ :
case CLIENT_OPCODE_APPEND :
case CLIENT_OPCODE_PREPEND :
case CLIENT_OPCODE_APPENDQ :
case CLIENT_OPCODE_PREPENDQ :
2014-07-09 12:58:13 +00:00
/* Response must not have value */
if ( ! request ) {
illegal = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2014-07-09 12:58:13 +00:00
}
} else {
2014-11-18 18:11:22 +00:00
switch ( opcode ) {
2022-02-21 08:34:07 +00:00
case CLIENT_OPCODE_DCP_FAILOVER_LOG_REQUEST :
2014-07-09 12:58:13 +00:00
/* Successful response must have value */
if ( ! request ) {
missing = TRUE ;
}
2014-11-18 18:11:22 +00:00
break ;
2014-07-09 12:58:13 +00:00
}
}
if ( illegal ) {
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_value , " %s %s shall not have Value " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode 0x%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
} else if ( missing ) {
expert_add_info_format ( pinfo , ti , & ei_value_missing , " %s %s must have Value " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Opcode 0x%x " ) ,
2014-07-09 12:58:13 +00:00
request ? " Request " : " Response " ) ;
}
}
2018-12-03 11:37:54 +00:00
static void flex_frame_duration_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
if ( length ! = 2 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" FlexFrame: RX/TX Duration with illegal length %d " , length ) ;
} else {
guint16 encoded_micros = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_double ( frame_tree ,
hf_flex_frame_tracing_duration ,
tvb ,
offset ,
2 ,
pow ( encoded_micros , 1.74 ) / 2 ) ;
}
}
2018-02-05 14:40:33 +00:00
2022-08-16 10:34:18 +00:00
static void flex_frame_ru_usage_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
if ( length ! = 2 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" Read unit illegal length %d " , length ) ;
} else {
guint16 units = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_uint ( frame_tree , hf_flex_frame_ru_count , tvb , offset , 2 , units ) ;
}
}
static void flex_frame_wu_usage_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
if ( length ! = 2 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" Write unit illegal length %d " , length ) ;
} else {
guint16 units = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_uint ( frame_tree , hf_flex_frame_wu_count , tvb , offset , 2 , units ) ;
}
}
2018-12-03 11:37:54 +00:00
static void flex_frame_reorder_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
/* Expects no data, so just check len */
if ( length ! = 0 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" FlexFrame: Out Of Order with illegal length %d " , length ) ;
}
}
static void flex_frame_durability_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
if ( ! ( length = = 1 | | length = = 3 ) ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" FlexFrame: Durability with illegal length %d " , length ) ;
return ;
}
proto_tree_add_item ( frame_tree , hf_flex_frame_durability_req , tvb , offset , 1 , ENC_BIG_ENDIAN ) ;
2018-02-05 14:40:33 +00:00
}
2018-12-03 11:37:54 +00:00
static void flex_frame_dcp_stream_id_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
if ( length ! = 2 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" FlexFrame: DCP Stream ID with illegal length %d " , length ) ;
} else {
guint16 sid = tvb_get_ntohs ( tvb , offset ) ;
proto_tree_add_uint ( frame_tree , hf_flex_frame_dcp_stream_id , tvb , offset , 2 , sid ) ;
}
}
2020-02-18 11:50:08 +00:00
static void flex_frame_impersonate_dissect ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
proto_tree_add_item ( frame_tree ,
hf_flex_frame_impersonated_user ,
tvb ,
offset ,
length ,
ENC_UTF_8 | ENC_STR_HEX ) ;
}
static void flex_frame_preserve_ttl ( tvbuff_t * tvb ,
proto_tree * frame_tree ,
gint offset ,
gint length ) {
/* Expects no data, so just check len */
if ( length ! = 0 ) {
proto_tree_add_expert_format ( frame_tree ,
NULL ,
& ef_warn_unknown_flex_len ,
tvb ,
offset ,
length ,
" FlexFrame: Preserve TTL with illegal length %d " , length ) ;
}
}
2018-12-03 11:37:54 +00:00
typedef void ( * flex_frame_by_id_dissect_fn ) ( tvbuff_t * ,
proto_tree * ,
gint ,
gint ) ;
struct flex_frame_by_id_dissect {
guint32 id ;
flex_frame_by_id_dissect_fn handler ;
} ;
static const struct flex_frame_by_id_dissect flex_frame_response_dissect [ ] = {
{ FLEX_RESPONSE_ID_RX_TX_DURATION , & flex_frame_duration_dissect } ,
2022-08-16 10:34:18 +00:00
{ FLEX_RESPONSE_ID_RU_USAGE , & flex_frame_ru_usage_dissect } ,
{ FLEX_RESPONSE_ID_WU_USAGE , & flex_frame_wu_usage_dissect } ,
2018-12-03 11:37:54 +00:00
{ 0 , NULL }
} ;
static const struct flex_frame_by_id_dissect flex_frame_request_dissect [ ] = {
{ FLEX_REQUEST_ID_REORDER , & flex_frame_reorder_dissect } ,
{ FLEX_REQUEST_ID_DURABILITY , & flex_frame_durability_dissect } ,
{ FLEX_REQUEST_ID_DCP_STREAM_ID , & flex_frame_dcp_stream_id_dissect } ,
2020-02-18 11:50:08 +00:00
{ FLEX_REQUEST_ID_IMPERSONATE , & flex_frame_impersonate_dissect } ,
{ FLEX_REQUEST_ID_PRESERVE_TTL , & flex_frame_preserve_ttl } ,
2018-12-03 11:37:54 +00:00
{ 0 , NULL }
} ;
2018-02-05 14:40:33 +00:00
/*
Flexible Framing Extras :
https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md
*/
static void dissect_flexible_framing_extras ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
2018-12-03 11:37:54 +00:00
guint8 flex_frame_extra_len ,
gboolean request ) {
/* select some request/response ID decoders */
const struct flex_frame_by_id_dissect * id_dissectors = flex_frame_response_dissect ;
int info_id = hf_flex_frame_id_res ;
int info_id_esc = hf_flex_frame_id_res_esc ;
int info_len_id = hf_flex_frame_len ;
if ( request ) {
id_dissectors = flex_frame_request_dissect ;
info_id = hf_flex_frame_id_req ;
info_id_esc = hf_flex_frame_id_req_esc ;
}
2018-02-05 14:40:33 +00:00
2018-12-03 11:37:54 +00:00
/* This first item shows the entire extent of all frame extras.
If we have multiple frames , we will add them in the iteration */
proto_tree_add_uint ( tree ,
hf_flex_extras ,
tvb ,
offset ,
flex_frame_extra_len ,
flex_frame_extra_len ) ;
2018-02-05 14:40:33 +00:00
/* iterate until we've consumed the flex_frame_extra_len */
gint bytes_remaining = flex_frame_extra_len ;
2018-12-03 11:37:54 +00:00
int frame_index = 0 ;
while ( bytes_remaining > 0 ) {
/* FrameInfo starts with a 'tag' byte which is formed from 2 nibbles */
guint8 tag_byte = tvb_get_guint8 ( tvb , offset ) ;
/* 0xff isn't defined yet in the spec as to what it should do */
if ( tag_byte = = 0xFF ) {
proto_tree_add_expert_format ( tree ,
pinfo ,
& ef_warn_unknown_flex_unsupported ,
tvb ,
offset ,
1 ,
" Cannot decode 0xFF id/len byte " ) ;
return ;
}
/* extract the nibbles into u16, if the id/len nibbles are escapes, their
true values come from following bytes and can be larger than u8 */
guint16 id = tag_byte > > 4 ;
guint16 len = tag_byte & 0x0F ;
int id_size = 1 ;
/* Calculate the id/len and add to the tree */
if ( id = = FLEX_ESCAPE ) {
id = id + tvb_get_guint8 ( tvb , offset + 1 ) ;
id_size + + ;
info_id = info_id_esc ;
}
int len_size = 1 ;
if ( len = = FLEX_ESCAPE ) {
len = len + tvb_get_guint8 ( tvb , offset + 1 ) ;
len_size + + ;
info_len_id = hf_flex_frame_len_esc ;
}
/* add a new sub-tree for this FrameInfo */
proto_item * flex_item = proto_tree_add_string_format ( tree ,
hf_flex_extras_n ,
tvb ,
offset ,
1 + len ,
NULL ,
" Flexible Frame %d " ,
frame_index ) ;
2018-02-05 14:40:33 +00:00
proto_tree * frame_tree = proto_item_add_subtree ( flex_item ,
ett_flex_frame_extras ) ;
2018-12-03 11:37:54 +00:00
/* Now add the info under the sub-tree */
proto_tree_add_uint ( frame_tree , info_id , tvb , offset , id_size , id ) ;
proto_tree_add_uint ( frame_tree , info_len_id , tvb , offset , len_size , len ) ;
/* this is broken if both len and id are escaped, but we've returned earlier
for that case ( with a warning ) */
offset = offset + 1 + ( len_size - 1 ) + ( id_size - 1 ) ;
bytes_remaining = bytes_remaining - 1 - ( len_size - 1 ) - ( id_size - 1 ) ; ;
/* lookup a dissector function by id */
2019-01-15 22:43:49 +00:00
int id_index = 0 , found = 0 ;
while ( id_dissectors [ id_index ] . handler ) {
if ( id_dissectors [ id_index ] . id = = id ) {
id_dissectors [ id_index ] . handler ( tvb , frame_tree , offset , len ) ;
2018-12-03 11:37:54 +00:00
found = 1 ;
break ;
}
2019-01-15 22:43:49 +00:00
id_index + + ;
2018-02-05 14:40:33 +00:00
}
2018-12-03 11:37:54 +00:00
if ( ! found ) {
proto_tree_add_expert_format ( frame_tree ,
pinfo ,
& ef_warn_unknown_flex_id ,
tvb ,
offset ,
len ,
" FlexFrame: no dissector function for %d " , id ) ;
2018-02-05 14:40:33 +00:00
}
offset + = len ;
bytes_remaining - = len ;
2018-12-03 11:37:54 +00:00
frame_index + + ;
2018-02-05 14:40:33 +00:00
}
}
2017-09-14 10:37:42 +00:00
static gboolean
is_xerror ( guint8 datatype , guint16 status )
{
2022-02-21 08:34:07 +00:00
if ( ( datatype & DT_JSON ) & & status ! = STATUS_SUBDOC_MULTI_PATH_FAILURE ) {
2017-09-14 10:37:42 +00:00
return TRUE ;
}
return FALSE ;
}
2022-02-22 11:55:54 +00:00
/// The following section contains dissector functions for the various
/// server initiated push messages (and responses for them).
/// It's easier to understand the logic with a single function per opcode
/// than a long function with a ton of if/else statements
static void d_s_o_clustermap_change_notification_req ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
// this is an error!
expert_add_info_format ( pinfo , tree , & ef_warn_illegal_value_length ,
" Clustermap not present " ) ;
return ;
}
// The payload is the clustermap in JSON
proto_tree_add_item ( tree , hf_server_clustermap_value , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size , size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
static void d_s_o_authenticate_req ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
// this is an error!
expert_add_info_format ( pinfo , tree , & ef_warn_illegal_value_length ,
" Authentication payload not present " ) ;
return ;
}
// The payload is an JSON object with the authentication request
proto_tree_add_item ( tree , hf_server_authentication , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size , size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
static void d_s_o_active_external_users_req ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
// this is an error!
expert_add_info_format ( pinfo , tree , & ef_warn_illegal_value_length ,
" ActiveExternalUsers payload not present " ) ;
return ;
}
// The payload is an JSON array with the list of the users
proto_tree_add_item ( tree , hf_server_external_users , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size , size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
static void d_s_o_get_authorization_req ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size > 0 ) {
// this is an error!
proto_item * ti = proto_tree_add_item ( tree , hf_value , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_value ,
" GetAuthorization shall not have a value " ) ;
}
}
/// Dissect the response to a server initiated push message which
/// don't require a response (the client may send it, but the server
/// will silently just ignore the response).
/// If sent the body should not contain value unless the status code
/// is an error and if so it shall be a JSON payload following the
/// standard error format.
static void d_s_o_server_ignored_response ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
return ;
}
proto_item * ti = proto_tree_add_item ( tree , hf_value , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
if ( get_status ( tvb ) = = STATUS_SUCCESS ) {
expert_add_info_format ( pinfo , ti , & ef_warn_shall_not_have_value ,
" Success should not carry value " ) ;
} else {
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size ,
size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
}
static void d_s_o_authenticate_res ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
return ;
}
// Payload is JSON (for success and if there is an error)
proto_tree_add_item ( tree , hf_server_authentication , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size ,
size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
static void d_s_o_get_authorization_res ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
if ( size = = 0 ) {
return ;
}
// Payload is JSON (for success and if there is an error)
proto_tree_add_item ( tree , hf_server_get_authorization , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
tvbuff_t * json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size ,
size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
}
2022-02-21 12:18:15 +00:00
/**
* Does the opcode use the vbucket or not ? ( does it make any sense to
* add the vbucket to the info )
*/
static bool opcode_use_vbucket ( guint8 magic _U_ , guint8 opcode ) {
switch ( opcode ) {
case CLIENT_OPCODE_OBSERVE :
case CLIENT_OPCODE_COLLECTIONS_GET_ID :
case CLIENT_OPCODE_IFCONFIG :
case CLIENT_OPCODE_SASL_LIST_MECHS :
case CLIENT_OPCODE_SASL_AUTH :
case CLIENT_OPCODE_SASL_STEP :
case CLIENT_OPCODE_SHUTDOWN :
case CLIENT_OPCODE_AUDIT_CONFIG_RELOAD :
case CLIENT_OPCODE_AUDIT_PUT :
case CLIENT_OPCODE_CONFIG_RELOAD :
case CLIENT_OPCODE_CONFIG_VALIDATE :
case CLIENT_OPCODE_IOCTL_SET :
case CLIENT_OPCODE_IOCTL_GET :
case CLIENT_OPCODE_HELLO :
case CLIENT_OPCODE_VERBOSITY :
case CLIENT_OPCODE_VERSION :
case CLIENT_OPCODE_NOOP :
case CLIENT_OPCODE_QUIT :
case CLIENT_OPCODE_LIST_BUCKETS :
case CLIENT_OPCODE_CREATE_BUCKET :
case CLIENT_OPCODE_DELETE_BUCKET :
case CLIENT_OPCODE_SELECT_BUCKET :
return FALSE ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
default :
return TRUE ;
}
}
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
/**
* Each frame header consist of 24 bytes in two slightly different formats
* ( byte 6 and 7 is vbucket id in a request and status in a response ) .
*
* This method dissect the frame header . Please refer to
* https : //github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#request-header
* for the layout of the frame header .
*/
static void dissect_frame_header ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * couchbase_tree , proto_item * couchbase_item ) {
guint8 magic = get_magic ( tvb ) ;
proto_item * ti = proto_tree_add_item ( couchbase_tree , hf_magic , tvb , 0 , 1 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
if ( try_val_to_str ( magic , magic_vals ) = = NULL ) {
expert_add_info_format ( pinfo , ti , & ef_warn_unknown_magic_byte , " Unknown magic byte: 0x%x " , magic ) ;
}
2022-02-21 12:18:15 +00:00
guint8 opcode = get_opcode ( tvb ) ;
2014-07-09 12:58:13 +00:00
2022-02-22 11:55:54 +00:00
const gchar * opcode_name ;
if ( is_server_magic ( magic ) ) {
ti = proto_tree_add_item ( couchbase_tree , hf_server_opcode , tvb , 1 , 1 , ENC_BIG_ENDIAN ) ;
opcode_name = try_val_to_str_ext ( opcode , & server_opcode_vals_ext ) ;
} else {
ti = proto_tree_add_item ( couchbase_tree , hf_opcode , tvb , 1 , 1 , ENC_BIG_ENDIAN ) ;
opcode_name = try_val_to_str_ext ( opcode , & client_opcode_vals_ext ) ;
}
2022-02-21 12:18:15 +00:00
if ( opcode_name = = NULL ) {
2014-07-09 12:58:13 +00:00
expert_add_info_format ( pinfo , ti , & ef_warn_unknown_opcode , " Unknown opcode: 0x%x " , opcode ) ;
2022-02-21 12:18:15 +00:00
opcode_name = " Unknown opcode " ;
2014-07-09 12:58:13 +00:00
}
proto_item_append_text ( couchbase_item , " , %s %s, Opcode: 0x%x " ,
2022-02-21 12:18:15 +00:00
opcode_name ,
2014-07-09 12:58:13 +00:00
val_to_str ( magic , magic_vals , " Unknown magic (0x%x) " ) ,
opcode ) ;
col_append_fstr ( pinfo - > cinfo , COL_INFO , " %s %s, Opcode: 0x%x " ,
2022-02-21 12:18:15 +00:00
opcode_name ,
2014-07-09 12:58:13 +00:00
val_to_str ( magic , magic_vals , " Unknown magic (0x%x) " ) ,
opcode ) ;
2018-12-03 11:37:54 +00:00
/* Check for flex magic, which changes the header format */
2022-02-21 12:18:15 +00:00
guint16 keylen ;
guint8 flex_frame_extras = get_flex_framing_extras_length ( tvb ) ;
if ( is_flex_encoded ( magic ) ) {
2018-02-05 14:40:33 +00:00
/* 2 separate bytes for the flex_extras and keylen */
2022-02-21 12:18:15 +00:00
proto_tree_add_item ( couchbase_tree , hf_flex_extras_length , tvb , 2 , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( couchbase_tree , hf_flex_keylength , tvb , 3 , 1 , ENC_BIG_ENDIAN ) ;
2018-02-05 14:40:33 +00:00
} else {
/* 2 bytes for the key */
2022-02-21 12:18:15 +00:00
proto_tree_add_item ( couchbase_tree , hf_keylength , tvb , 2 , 2 , ENC_BIG_ENDIAN ) ;
2018-02-05 14:40:33 +00:00
}
2022-02-21 12:18:15 +00:00
keylen = get_key_length ( tvb ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
guint8 extlen = get_extras_length ( tvb ) ;
proto_tree_add_item ( couchbase_tree , hf_extlength , tvb , 4 , 1 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
proto_tree_add_bitmask ( couchbase_tree , tvb , 5 , hf_datatype , ett_datatype , datatype_vals , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
if ( is_request_magic ( magic ) ) {
guint16 vbucket = tvb_get_ntohs ( tvb , 6 ) ;
proto_tree_add_item ( couchbase_tree , hf_vbucket , tvb , 6 , 2 , ENC_BIG_ENDIAN ) ;
if ( opcode_use_vbucket ( magic , opcode ) ) {
proto_item_append_text ( couchbase_item , " , vb:%d " , vbucket ) ;
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , vb:%d " , vbucket ) ;
}
} else {
/* This is a response or invalid magic... */
guint16 status = get_status ( tvb ) ;
ti = proto_tree_add_item ( couchbase_tree , hf_status , tvb , 6 , 2 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
if ( status ! = 0 ) {
expert_add_info_format ( pinfo , ti , & ef_warn_unknown_opcode , " %s: %s " ,
2022-02-22 11:55:54 +00:00
val_to_str_ext ( opcode , & client_opcode_vals_ext , " Unknown opcode (0x%x) " ) ,
2014-07-09 12:58:13 +00:00
val_to_str_ext ( status , & status_vals_ext , " Status: 0x%x " ) ) ;
}
}
2022-02-21 12:18:15 +00:00
guint32 bodylen = get_body_length ( tvb ) ;
guint32 value_len = bodylen - extlen - keylen - flex_frame_extras ;
ti = proto_tree_add_uint ( couchbase_tree , hf_value_length , tvb , 8 , 0 , value_len ) ;
2019-04-03 21:32:30 +00:00
proto_item_set_generated ( ti ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
proto_tree_add_item ( couchbase_tree , hf_total_bodylength , tvb , 8 , 4 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
/*
* use little endian ( network ) encoding for the opaque as this is an opaque
* field the client could use for whatever they want
*/
proto_tree_add_item ( couchbase_tree , hf_opaque , tvb , 12 , 4 , ENC_LITTLE_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
// Finally we've got the CAS (which observe has a special use for)
2022-02-21 08:34:07 +00:00
if ( opcode = = CLIENT_OPCODE_OBSERVE ) {
2022-02-21 12:18:15 +00:00
proto_tree_add_item ( couchbase_tree , hf_ttp , tvb , 16 , 4 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( couchbase_tree , hf_ttr , tvb , 20 , 4 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
} else {
2022-02-21 12:18:15 +00:00
proto_tree_add_item ( couchbase_tree , hf_cas , tvb , 16 , 8 , ENC_BIG_ENDIAN ) ;
2014-07-09 12:58:13 +00:00
}
2022-02-21 12:18:15 +00:00
}
2014-07-09 12:58:13 +00:00
2022-02-21 12:18:15 +00:00
/**
* Dissect the flexible frame info ' s encoded in the packet
*/
static void dissect_frame_flex_info_section ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
guint8 size ,
guint8 magic ) {
2022-02-22 11:55:54 +00:00
if ( size = = 0 ) {
return ;
}
switch ( magic ) {
case MAGIC_SERVER_RESPONSE :
case MAGIC_SERVER_REQUEST :
// None of the server initiated messages use flex frame encoding!
proto_tree_add_item ( tree , hf_flex_extras , tvb , offset , size , ENC_UTF_8 | ENC_STR_HEX ) ;
proto_tree_add_expert_format ( tree ,
pinfo ,
& ef_warn_unknown_flex_unsupported ,
tvb ,
offset ,
size ,
" Server initiated messages don't use flex framing " ) ;
break ;
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_CLIENT_RESPONSE_FLEX :
dissect_flexible_framing_extras ( tvb ,
pinfo ,
tree ,
offset ,
size ,
is_request_magic ( magic ) ) ;
break ;
default :
proto_tree_add_item ( tree , hf_flex_extras , tvb , offset , size , ENC_UTF_8 | ENC_STR_HEX ) ;
proto_tree_add_expert_format ( tree ,
pinfo ,
& ef_warn_unknown_flex_unsupported ,
tvb ,
offset ,
size ,
" According to the magic we should not have flex encoding " ) ;
2018-03-20 10:05:51 +00:00
}
2022-02-21 12:18:15 +00:00
}
2018-03-20 10:05:51 +00:00
2022-02-21 12:18:15 +00:00
/**
* Dissect the extras section in the frame
*/
static void dissect_frame_extras ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
guint8 size ,
guint8 magic ,
guint8 opcode ,
guint16 * subdoc_path_len ) {
2022-02-22 11:55:54 +00:00
switch ( magic ) {
case MAGIC_SERVER_RESPONSE :
dissect_server_response_extras ( tvb , pinfo , tree , offset , size , opcode ) ;
break ;
case MAGIC_SERVER_REQUEST :
dissect_server_request_extras ( tvb , pinfo , tree , offset , size , opcode ) ;
break ;
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_CLIENT_RESPONSE_FLEX :
case MAGIC_CLIENT_REQUEST :
case MAGIC_CLIENT_RESPONSE :
dissect_client_extras ( tvb , pinfo , tree , offset , size ,
opcode , is_request_magic ( magic ) , subdoc_path_len ) ;
break ;
default :
proto_tree_add_item ( tree , hf_extras , tvb , offset , size , ENC_UTF_8 | ENC_STR_HEX ) ;
proto_tree_add_expert_format ( tree ,
pinfo ,
& ef_warn_unknown_extras ,
tvb ,
offset ,
size ,
" Invalid magic so we can't interpret extras " ) ;
}
2022-02-21 12:18:15 +00:00
}
2015-08-20 15:05:57 +00:00
2022-02-21 12:18:15 +00:00
/**
* Dissect the key section in the frame
*/
static void dissect_frame_key ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
guint16 size ,
guint8 magic ,
guint8 opcode ) {
2022-02-22 11:55:54 +00:00
if ( is_server_magic ( magic ) ) {
dissect_server_key ( tvb , pinfo , tree , offset , size , opcode ,
is_request_magic ( magic ) ) ;
} else {
dissect_client_key ( tvb , pinfo , tree , offset , size , opcode ,
is_request_magic ( magic ) ) ;
}
2022-02-21 12:18:15 +00:00
}
2015-08-20 15:05:57 +00:00
2022-02-22 11:55:54 +00:00
static void dissect_client_value ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
guint32 size ,
guint8 magic ,
guint8 opcode ,
guint16 subdoc_path_len ) {
2022-02-21 12:18:15 +00:00
guint8 datatype = get_datatype ( tvb ) ;
if ( is_request_magic ( magic ) ) {
dissect_value ( tvb , pinfo , tree , offset , size , subdoc_path_len , opcode , true , datatype ) ;
2014-07-09 12:58:13 +00:00
} else {
2022-02-21 12:18:15 +00:00
guint16 status = get_status ( tvb ) ;
if ( status = = 0 ) {
dissect_value ( tvb , pinfo , tree , offset , size , subdoc_path_len , opcode , false , datatype ) ;
} else if ( size ) {
proto_tree_add_item ( tree , hf_value , tvb , offset , size , ENC_ASCII | ENC_NA ) ;
if ( status = = STATUS_NOT_MY_VBUCKET | | is_xerror ( datatype , status ) ) {
tvbuff_t * json_tvb ;
json_tvb = tvb_new_subset_length_caplen ( tvb , offset , size , size ) ;
call_dissector ( json_handle , json_tvb , pinfo , tree ) ;
} else if ( opcode = = CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP ) {
dissect_multipath_lookup_response ( tvb , pinfo , tree , offset , size ) ;
} else if ( opcode = = CLIENT_OPCODE_SUBDOC_MULTI_MUTATION ) {
dissect_multipath_mutation_response ( tvb , pinfo , tree , offset , size ) ;
}
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , %s " ,
val_to_str_ext ( status , & status_vals_ext ,
" Unknown status: 0x%x " ) ) ;
} else {
/* Newer opcodes do not include a value in non-SUCCESS responses. */
proto_tree * ti ;
switch ( opcode ) {
case CLIENT_OPCODE_SUBDOC_GET :
case CLIENT_OPCODE_SUBDOC_EXISTS :
case CLIENT_OPCODE_SUBDOC_DICT_ADD :
case CLIENT_OPCODE_SUBDOC_DICT_UPSERT :
case CLIENT_OPCODE_SUBDOC_DELETE :
case CLIENT_OPCODE_SUBDOC_REPLACE :
case CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_LAST :
case CLIENT_OPCODE_SUBDOC_ARRAY_PUSH_FIRST :
case CLIENT_OPCODE_SUBDOC_ARRAY_INSERT :
case CLIENT_OPCODE_SUBDOC_ARRAY_ADD_UNIQUE :
case CLIENT_OPCODE_SUBDOC_COUNTER :
case CLIENT_OPCODE_SUBDOC_MULTI_LOOKUP :
case CLIENT_OPCODE_SUBDOC_MULTI_MUTATION :
break ;
2015-08-20 15:05:57 +00:00
2022-02-21 12:18:15 +00:00
default :
ti = proto_tree_add_item ( tree , hf_value , tvb , offset , 0 ,
ENC_ASCII | ENC_NA ) ;
expert_add_info_format ( pinfo , ti , & ei_value_missing ,
" %s with status %s (0x%x) must have Value " ,
val_to_str_ext ( opcode ,
2022-02-22 11:55:54 +00:00
& client_opcode_vals_ext ,
2022-02-21 12:18:15 +00:00
" Opcode 0x%x " ) ,
val_to_str_ext ( status ,
& status_vals_ext ,
" Unknown " ) ,
status ) ;
}
2015-08-20 15:05:57 +00:00
}
2014-07-09 12:58:13 +00:00
}
2022-02-21 12:18:15 +00:00
}
2022-02-22 11:55:54 +00:00
static void dissect_server_request_value ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
switch ( get_opcode ( tvb ) ) {
case SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION :
d_s_o_clustermap_change_notification_req ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_AUTHENTICATE :
d_s_o_authenticate_req ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_ACTIVE_EXTERNAL_USERS :
d_s_o_active_external_users_req ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_GET_AUTHORIZATION :
d_s_o_get_authorization_req ( tvb , pinfo , tree , offset , size ) ;
return ;
default :
// Unknown packet type.. just dump the data
if ( size > 0 ) {
proto_tree_add_item ( tree , hf_value , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
}
return ;
}
}
static void dissect_server_response_value ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
gint size ) {
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , %s " ,
val_to_str_ext ( get_status ( tvb ) , & status_vals_ext ,
" Unknown status: 0x%x " ) ) ;
switch ( get_opcode ( tvb ) ) {
case SERVER_OPCODE_CLUSTERMAP_CHANGE_NOTIFICATION :
d_s_o_server_ignored_response ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_AUTHENTICATE :
d_s_o_authenticate_res ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_ACTIVE_EXTERNAL_USERS :
d_s_o_server_ignored_response ( tvb , pinfo , tree , offset , size ) ;
return ;
case SERVER_OPCODE_GET_AUTHORIZATION :
d_s_o_get_authorization_res ( tvb , pinfo , tree , offset , size ) ;
return ;
default :
// Unknown packet type.. just dump the data
if ( size > 0 ) {
proto_tree_add_item ( tree , hf_value , tvb , offset , size ,
ENC_ASCII | ENC_NA ) ;
}
return ;
}
}
/**
* Dissect the value section in the frame
*/
static void dissect_frame_value ( tvbuff_t * tvb ,
packet_info * pinfo ,
proto_tree * tree ,
gint offset ,
guint32 size ,
guint8 magic ,
guint8 opcode ,
guint16 subdoc_path_len ) {
if ( size > G_MAXINT32 ) {
// The packet size isn't supported
}
switch ( magic ) {
case MAGIC_CLIENT_REQUEST :
case MAGIC_CLIENT_RESPONSE :
case MAGIC_CLIENT_REQUEST_FLEX :
case MAGIC_CLIENT_RESPONSE_FLEX :
dissect_client_value ( tvb , pinfo , tree , offset , size , magic , opcode , subdoc_path_len ) ;
return ;
case MAGIC_SERVER_REQUEST :
dissect_server_request_value ( tvb , pinfo , tree , offset , ( gint ) size ) ;
return ;
case MAGIC_SERVER_RESPONSE :
dissect_server_response_value ( tvb , pinfo , tree , offset , ( gint ) size ) ;
return ;
default :
// Unknown magic... just dump the data
if ( size > 0 ) {
proto_tree_add_item ( tree , hf_value , tvb , offset , ( gint ) size , ENC_ASCII | ENC_NA ) ;
}
return ;
}
}
2022-02-21 12:18:15 +00:00
/**
* Each frame in the protocol consists of a 24 byte header , followed by
* a variable number of sections ( all of the sizes is located in the
* first 24 byte header ) :
*
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
* | Fixed 24 byte frame header |
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
* | n bytes flex frame info |
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
* | n bytes extras |
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
* | n bytes key |
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
* | n bytes value |
* | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
*
* Call each function responsible for printing the segment
*/
static int
dissect_couchbase ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
{
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , PSNAME ) ;
col_clear ( pinfo - > cinfo , COL_INFO ) ;
proto_item * couchbase_item = proto_tree_add_item ( tree , proto_couchbase , tvb , 0 , - 1 , ENC_NA ) ;
proto_tree * couchbase_tree = proto_item_add_subtree ( couchbase_item , ett_couchbase ) ;
dissect_frame_header ( tvb , pinfo , couchbase_tree , couchbase_item ) ;
guint8 magic = get_magic ( tvb ) ;
gint offset = 24 ;
guint8 flex_frame_extra_len = get_flex_framing_extras_length ( tvb ) ;
guint8 opcode = get_opcode ( tvb ) ;
guint8 extras_length = get_extras_length ( tvb ) ;
guint16 key_length = get_key_length ( tvb ) ;
guint32 body_length = get_body_length ( tvb ) ;
guint32 value_len = body_length - key_length - extras_length - flex_frame_extra_len ;
dissect_frame_flex_info_section ( tvb , pinfo , couchbase_tree , offset , flex_frame_extra_len , magic ) ;
offset + = flex_frame_extra_len ;
guint16 subdoc_path_len = 0 ;
// Dissect the extras section
dissect_frame_extras ( tvb , pinfo , couchbase_tree , offset , extras_length , magic , opcode , & subdoc_path_len ) ;
offset + = extras_length ;
// dissect the key
dissect_frame_key ( tvb , pinfo , couchbase_tree , offset , key_length , magic , opcode ) ;
offset + = key_length ;
dissect_frame_value ( tvb , pinfo , couchbase_tree , offset , value_len , magic , opcode , subdoc_path_len ) ;
2014-07-09 12:58:13 +00:00
return tvb_reported_length ( tvb ) ;
}
2022-02-24 12:32:28 +00:00
static guint
get_couchbase_pdu_length ( packet_info * pinfo _U_ , tvbuff_t * tvb , int offset ,
void * data _U_ ) {
// See https://github.com/couchbase/kv_engine/blob/master/docs/BinaryProtocol.md#packet-structure
// for a description of each packet.
// The "length" field is located at offset 8 within the frame and does
// not include the fixed header.
return tvb_get_ntohl ( tvb , offset + 8 ) + COUCHBASE_HEADER_LEN ;
}
/* Dissect the couchbase packet */
2014-07-09 12:58:13 +00:00
static int
2022-02-24 12:32:28 +00:00
dissect_couchbase_pdu ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree ,
void * data ) {
if ( try_val_to_str ( tvb_get_guint8 ( tvb , 0 ) , magic_vals ) = = NULL ) {
// Magic isn't one of the know magics used by the Couchbase dissector
2022-02-21 12:18:15 +00:00
return 0 ;
}
2014-07-09 12:58:13 +00:00
2022-02-24 12:32:28 +00:00
tcp_dissect_pdus ( tvb , pinfo , tree , couchbase_desegment_body ,
COUCHBASE_HEADER_LEN ,
get_couchbase_pdu_length , dissect_couchbase , data ) ;
2014-10-22 17:48:34 +00:00
return tvb_captured_length ( tvb ) ;
2014-07-09 12:58:13 +00:00
}
/* Registration functions; register couchbase protocol,
* its configuration options and also register the tcp dissectors .
*/
void
proto_register_couchbase ( void )
{
static hf_register_info hf [ ] = {
{ & hf_magic , { " Magic " , " couchbase.magic " , FT_UINT8 , BASE_HEX , VALS ( magic_vals ) , 0x0 , " Magic number " , HFILL } } ,
2022-02-22 11:55:54 +00:00
{ & hf_opcode , { " Opcode " , " couchbase.opcode " , FT_UINT8 , BASE_HEX | BASE_EXT_STRING , & client_opcode_vals_ext , 0x0 , " Command code " , HFILL } } ,
{ & hf_server_opcode , { " Server Opcode " , " couchbase.server.opcode " , FT_UINT8 , BASE_HEX | BASE_EXT_STRING , & server_opcode_vals_ext , 0x0 , " Command code " , HFILL } } ,
2014-07-09 12:58:13 +00:00
{ & hf_extlength , { " Extras Length " , " couchbase.extras.length " , FT_UINT8 , BASE_DEC , NULL , 0x0 , " Length in bytes of the command extras " , HFILL } } ,
{ & hf_keylength , { " Key Length " , " couchbase.key.length " , FT_UINT16 , BASE_DEC , NULL , 0x0 , " Length in bytes of the text key that follows the command extras " , HFILL } } ,
{ & hf_value_length , { " Value Length " , " couchbase.value.length " , FT_UINT32 , BASE_DEC , NULL , 0x0 , " Length in bytes of the value that follows the key " , HFILL } } ,
2017-02-01 17:04:56 +00:00
{ & hf_datatype , { " Data Type " , " couchbase.datatype " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_datatype_json , { " JSON " , " couchbase.datatype.json " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , DT_JSON , " JSON datatype " , HFILL } } ,
{ & hf_datatype_snappy , { " Snappy " , " couchbase.datatype.snappy " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , DT_SNAPPY , " Snappy Compressed " , HFILL } } ,
{ & hf_datatype_xattr , { " XATTR " , " couchbase.datatype.xattr " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , DT_XATTR , " Xattrs included " , HFILL } } ,
2014-11-18 18:11:22 +00:00
{ & hf_vbucket , { " VBucket " , " couchbase.vbucket " , FT_UINT16 , BASE_DEC_HEX , NULL , 0x0 , " VBucket ID " , HFILL } } ,
2014-07-09 12:58:13 +00:00
{ & hf_status , { " Status " , " couchbase.status " , FT_UINT16 , BASE_HEX | BASE_EXT_STRING , & status_vals_ext , 0x0 , " Status of the response " , HFILL } } ,
{ & hf_total_bodylength , { " Total Body Length " , " couchbase.total_bodylength " , FT_UINT32 , BASE_DEC , NULL , 0x0 , " Length in bytes of extra + key + value " , HFILL } } ,
{ & hf_opaque , { " Opaque " , " couchbase.opaque " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_cas , { " CAS " , " couchbase.cas " , FT_UINT64 , BASE_HEX , NULL , 0x0 , " Data version check " , HFILL } } ,
{ & hf_ttp , { " Time to Persist " , " couchbase.ttp " , FT_UINT32 , BASE_DEC , NULL , 0x0 , " Approximate time needed to persist the key (milliseconds) " , HFILL } } ,
{ & hf_ttr , { " Time to Replicate " , " couchbase.ttr " , FT_UINT32 , BASE_DEC , NULL , 0x0 , " Approximate time needed to replicate the key (milliseconds) " , HFILL } } ,
2018-12-03 11:37:54 +00:00
2018-12-07 11:58:31 +00:00
{ & hf_collection_key_id , { " Collection ID " , " couchbase.key.collection_id " , FT_UINT32 , BASE_HEX , NULL , 0x0 , " If this a collection stream, this is the collection-ID " , HFILL } } ,
{ & hf_collection_key_logical , { " Collection Logical Key " , " couchbase.key.logical_key " , FT_STRING , BASE_NONE , NULL , 0x0 , " If this a collection stream, this is the key in the collection " , HFILL } } ,
2019-02-14 14:30:18 +00:00
{ & hf_collection_manifest_id , { " Collections Manifest ID " , " couchbase.key.collection_manifest_id " , FT_UINT64 , BASE_HEX , NULL , 0x0 , " The collections manifest id " , HFILL } } ,
2018-12-03 11:38:24 +00:00
2018-02-05 14:40:33 +00:00
{ & hf_flex_keylength , { " Key Length " , " couchbase.key.length " , FT_UINT8 , BASE_DEC , NULL , 0x0 , " Length in bytes of the text key that follows the command extras " , HFILL } } ,
{ & hf_flex_extras_length , { " Flexible Framing Extras Length " , " couchbase.flex_extras " , FT_UINT8 , BASE_DEC , NULL , 0x0 , " Length in bytes of the flexible framing extras that follows the response header " , HFILL } } ,
2018-12-03 11:37:54 +00:00
{ & hf_flex_extras , { " Flexible Framing Extras " , " couchbase.flex_frame_extras " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2020-07-23 12:54:50 +00:00
{ & hf_flex_extras_n , { " Flexible Framing Extras " , " couchbase.flex_frame_extras.string " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2018-12-03 11:37:54 +00:00
{ & hf_flex_frame_id_byte0 , { " Flexible Frame Byte0 " , " couchbase.flex_frame.byte0 " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_id_req , { " Flexible Frame ID (request) " , " couchbase.flex_frame.frame.id " , FT_UINT8 , BASE_DEC , VALS ( flex_frame_request_ids ) , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_id_res , { " Flexible Frame ID (response) " , " couchbase.flex_frame.frame.id " , FT_UINT8 , BASE_DEC , VALS ( flex_frame_response_ids ) , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_id_req_esc , { " Flexible Frame ID esc (request) " , " couchbase.flex_frame.frame.id " , FT_UINT16 , BASE_DEC , VALS ( flex_frame_request_ids ) , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_id_res_esc , { " Flexible Frame ID esc (response) " , " couchbase.flex_frame.frame.id " , FT_UINT16 , BASE_DEC , VALS ( flex_frame_response_ids ) , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_len , { " Flexible Frame Len " , " couchbase.flex_frame.frame.len " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_flex_frame_len_esc , { " Flexible Frame Len (esc) " , " couchbase.flex_frame.frame.len " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2018-02-20 06:29:03 +00:00
{ & hf_flex_frame_tracing_duration , { " Server Recv->Send duration " , " couchbase.flex_frame.frame.duration " , FT_DOUBLE , BASE_NONE | BASE_UNIT_STRING , & units_microseconds , 0 , NULL , HFILL } } ,
2022-08-16 10:34:18 +00:00
{ & hf_flex_frame_ru_count , { " Read unit count " , " couchbase.flex_frame.frame.ru_count " , FT_UINT16 , BASE_DEC , NULL , 0 , NULL , HFILL } } ,
{ & hf_flex_frame_wu_count , { " Write unit count " , " couchbase.flex_frame.frame.wu_count " , FT_UINT16 , BASE_DEC , NULL , 0 , NULL , HFILL } } ,
2018-12-03 11:37:54 +00:00
{ & hf_flex_frame_durability_req , { " Durability Requirement " , " couchbase.flex_frame.frame.durability_req " , FT_UINT8 , BASE_DEC , VALS ( flex_frame_durability_req ) , 0 , NULL , HFILL } } ,
{ & hf_flex_frame_dcp_stream_id , { " DCP Stream Identifier " , " couchbase.flex_frame.frame.dcp_stream_id " , FT_UINT16 , BASE_DEC , NULL , 0 , NULL , HFILL } } ,
2020-02-18 11:50:08 +00:00
{ & hf_flex_frame_impersonated_user , { " Impersonated User " , " couchbase.flex_frame.frame.impersonated_user " , FT_STRING , BASE_NONE , NULL , 0 , NULL , HFILL } } ,
2018-02-05 14:40:33 +00:00
2014-07-09 12:58:13 +00:00
{ & hf_extras , { " Extras " , " couchbase.extras " , FT_NONE , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_flags , { " Flags " , " couchbase.extras.flags " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2022-12-15 13:28:05 +00:00
{ & hf_extras_flags_backfill , { " Backfill Age " , " couchbase.extras.flags.backfill " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0001 , NULL , HFILL } } ,
{ & hf_extras_flags_dump , { " Dump " , " couchbase.extras.flags.dump " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0002 , NULL , HFILL } } ,
{ & hf_extras_flags_list_vbuckets , { " List VBuckets " , " couchbase.extras.flags.list_vbuckets " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0004 , NULL , HFILL } } ,
{ & hf_extras_flags_takeover_vbuckets , { " Takeover VBuckets " , " couchbase.extras.flags.takeover_vbuckets " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0008 , NULL , HFILL } } ,
{ & hf_extras_flags_support_ack , { " Support ACK " , " couchbase.extras.flags.support_ack " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0010 , NULL , HFILL } } ,
{ & hf_extras_flags_request_keys_only , { " Request Keys Only " , " couchbase.extras.flags.request_keys_only " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0020 , NULL , HFILL } } ,
{ & hf_extras_flags_checkpoint , { " Checkpoint " , " couchbase.extras.flags.checkpoint " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0040 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
2015-08-20 15:05:57 +00:00
/* Sub-document */
2017-02-01 17:04:56 +00:00
{ & hf_subdoc_flags , { " Subdoc flags " , " couchbase.extras.subdoc.flags " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_subdoc_flags_mkdirp , { " MKDIR_P " , " couchbase.extras.subdoc.flags.mkdir_p " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x01 , " Create non-existent intermediate paths " , HFILL } } ,
{ & hf_subdoc_flags_xattrpath , { " XATTR_PATH " , " couchbase.extras.subdoc.flags.xattr_path " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x04 , " If set path refers to extended attribute (XATTR) " , HFILL } } ,
{ & hf_subdoc_flags_expandmacros , { " EXPAND_MACROS " , " couchbase.extras.subdoc.flags.expand_macros " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x10 , " Expand macro values inside XATTRs " , HFILL } } ,
2017-08-10 14:13:44 +00:00
{ & hf_subdoc_flags_reserved , { " Reserved fields " , " couchbase.extras.subdoc.flags.reserved " , FT_UINT8 , BASE_HEX , NULL , 0xEA , " A reserved field " , HFILL } } ,
{ & hf_subdoc_doc_flags , { " Subdoc Doc flags " , " couchbase.extras.subdoc.doc_flags " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_subdoc_doc_flags_mkdoc , { " MKDOC " , " couchbase.extras.subdoc.doc_flags.mkdoc " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x01 , " Create document if it does not exist, implies mkdir_p " , HFILL } } ,
{ & hf_subdoc_doc_flags_add , { " ADD " , " couchbase.extras.subdoc.doc_flags.add " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x02 , " Fail if doc already exists " , HFILL } } ,
{ & hf_subdoc_doc_flags_accessdeleted , { " ACCESS_DELETED " , " couchbase.extras.subdoc.doc_flags.access_deleted " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x04 , " Allow access to XATTRs for deleted documents " , HFILL } } ,
2020-06-29 13:25:24 +00:00
{ & hf_subdoc_doc_flags_createasdeleted , { " CREATE_AS_DELETED " , " couchbase.extras.subdoc.doc_flags.create_as_deleted " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x08 , " If the document does not exist then create it in the Deleted state, instead of the normal Alive state " , HFILL } } ,
2021-10-12 11:20:10 +00:00
{ & hf_subdoc_doc_flags_revivedocument , { " REVIVE_DOCUMENT " , " couchbase.extras.subdoc.doc_flags.revive_document " , FT_BOOLEAN , 8 , TFS ( & tfs_set_notset ) , 0x10 , " If the document exists in the Deleted state, revive it to the normal Alive state " , HFILL } } ,
2020-06-29 13:25:24 +00:00
{ & hf_subdoc_doc_flags_reserved , { " Reserved fields " , " couchbase.extras.subdoc.doc_flags.reserved " , FT_UINT8 , BASE_HEX , NULL , 0xF0 , " A reserved field " , HFILL } } ,
2015-08-20 15:05:57 +00:00
{ & hf_extras_pathlen , { " Path Length " , " couchbase.extras.pathlen " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
/* DCP flags */
2022-12-15 13:28:05 +00:00
{ & hf_extras_flags_dcp_connection_type , { " Connection Type " , " couchbase.extras.flags.dcp_connection_type " , FT_UINT32 , BASE_HEX , VALS ( dcp_connection_type_vals ) , 0x00000003 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_add_stream_takeover , { " Take Over " , " couchbase.extras.flags.dcp_add_stream_takeover " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0001 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_add_stream_diskonly , { " Disk Only " , " couchbase.extras.flags.dcp_add_stream_diskonly " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0002 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_add_stream_latest , { " Latest " , " couchbase.extras.flags.dcp_add_stream_latest " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0004 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_snapshot_marker_memory , { " Memory " , " couchbase.extras.flags.dcp_snapshot_marker_memory " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0001 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_snapshot_marker_disk , { " Disk " , " couchbase.extras.flags.dcp_snapshot_marker_disk " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0002 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_snapshot_marker_chk , { " Chk " , " couchbase.extras.flags.dcp_snapshot_marker_chk " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0004 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_snapshot_marker_ack , { " Ack " , " couchbase.extras.flags.dcp_snapshot_marker_ack " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0008 , NULL , HFILL } } ,
{ & hf_extras_flags_dcp_include_xattrs , { " Include XATTRs " , " couchbase.extras.flags.dcp_include_xattrs " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0004 , " Indicates the server should include documents XATTRs " , HFILL } } ,
{ & hf_extras_flags_dcp_no_value , { " No Value " , " couchbase.extras.flags.dcp_no_value " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0008 , " Indicates the server should strip off values " , HFILL } } ,
{ & hf_extras_flags_dcp_collections , { " Enable Collections " , " couchbase.extras.flags.dcp_collections " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0010 , " Indicates the server should stream collections " , HFILL } } ,
{ & hf_extras_flags_dcp_include_delete_times , { " Include Delete Times " , " couchbase.extras.flags.dcp_include_delete_times " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0020 , " Indicates the server should include delete timestamps " , HFILL } } ,
{ & hf_extras_flags_dcp_oso_snapshot_begin , { " OSO Begin " , " couchbase.extras.flags.dcp_oso_snapshot_begin " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0001 , " The start of an OSO snapshot " , HFILL } } ,
{ & hf_extras_flags_dcp_oso_snapshot_end , { " OSO End " , " couchbase.extras.flags.dcp_oso_snapshot_end " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0002 , " The end of an OSO snapshot " , HFILL } } ,
2020-02-18 14:25:15 +00:00
2019-06-19 12:37:58 +00:00
{ & hf_extras_seqno , { " Sequence number " , " couchbase.extras.seqno " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2019-09-16 10:58:14 +00:00
{ & hf_extras_mutation_seqno , { " Mutation Sequence Number " , " couchbase.extras.mutation_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
{ & hf_extras_opaque , { " Opaque (vBucket identifier) " , " couchbase.extras.opaque " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_reserved , { " Reserved " , " couchbase.extras.reserved " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2019-06-19 12:37:58 +00:00
{ & hf_extras_start_seqno , { " Start Sequence Number " , " couchbase.extras.start_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2019-08-19 14:21:42 +00:00
{ & hf_extras_end_seqno , { " End Sequence Number " , " couchbase.extras.end_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_high_completed_seqno , { " High Completed Sequence Number " , " couchbase.extras.high_completed_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2019-11-28 13:39:26 +00:00
{ & hf_extras_max_visible_seqno , { " Max Visible Seqno " , " couchbase.extras.max_visible_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2022-04-22 07:35:36 +00:00
{ & hf_extras_timestamp , { " PiTR timestamp " , " couchbase.extras.timestamp " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2019-11-28 13:39:26 +00:00
{ & hf_extras_marker_version , { " Snapshot Marker Version " , " couchbase.extras.marker_version " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
{ & hf_extras_vbucket_uuid , { " VBucket UUID " , " couchbase.extras.vbucket_uuid " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2019-06-19 12:37:58 +00:00
{ & hf_extras_snap_start_seqno , { " Snapshot Start Sequence Number " , " couchbase.extras.snap_start_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2020-09-26 22:14:23 +00:00
{ & hf_extras_snap_end_seqno , { " Snapshot End Sequence Number " , " couchbase.extras.snap_end_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2019-06-19 12:37:58 +00:00
{ & hf_extras_by_seqno , { " by_seqno " , " couchbase.extras.by_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_prepared_seqno , { " by_seqno (prepared) " , " couchbase.extras.by_seqno_prepared " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_commit_seqno , { " by_seqno (commit) " , " couchbase.extras.by_seqno_commit " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_abort_seqno , { " by_seqno (abort) " , " couchbase.extras.by_seqno_abort " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_rev_seqno , { " rev_seqno " , " couchbase.extras.rev_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-12-10 01:19:55 +00:00
{ & hf_extras_lock_time , { " lock_time " , " couchbase.extras.lock_time " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2020-11-01 19:59:37 +00:00
{ & hf_extras_nmeta , { " nmeta " , " couchbase.extras.nmeta " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_nru , { " nru " , " couchbase.extras.nru " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2018-12-10 10:18:00 +00:00
{ & hf_extras_deleted , { " deleted " , " couchbase.extras.deleted " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2015-10-30 07:39:01 +00:00
{ & hf_extras_bytes_to_ack , { " bytes_to_ack " , " couchbase.extras.bytes_to_ack " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2018-02-05 09:30:43 +00:00
{ & hf_extras_delete_time , { " delete_time " , " couchbase.extras.delete_time " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2018-12-03 11:38:24 +00:00
{ & hf_extras_delete_unused , { " unused " , " couchbase.extras.delete_unused " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2018-02-05 09:30:43 +00:00
{ & hf_extras_system_event_id , { " system_event_id " , " couchbase.extras.system_event_id " , FT_UINT32 , BASE_DEC , VALS ( dcp_system_event_id_vals ) , 0x0 , NULL , HFILL } } ,
2018-12-03 11:38:24 +00:00
{ & hf_extras_system_event_version , { " system_event_version " , " couchbase.extras.system_event_version " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2020-02-18 14:25:15 +00:00
{ & hf_extras_dcp_oso_snapshot_flags , { " OSO snapshot flags " , " couchbase.extras.dcp_oso_snapshot_flags " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
{ & hf_failover_log , { " Failover Log " , " couchbase.dcp.failover_log " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_failover_log_size , { " Size " , " couchbase.dcp.failover_log.size " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_failover_log_vbucket_uuid , { " VBucket UUID " , " couchbase.dcp.failover_log.vbucket_uuid " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2019-06-19 12:37:58 +00:00
{ & hf_failover_log_vbucket_seqno , { " Sequence Number " , " couchbase.dcp.failover_log.seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-11-18 18:11:22 +00:00
2015-10-30 07:39:01 +00:00
{ & hf_vbucket_states , { " VBucket States " , " couchbase.vbucket_states " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vbucket_states_state , { " State " , " couchbase.vbucket_states.state " , FT_UINT32 , BASE_HEX , VALS ( vbucket_states_vals ) , 0x0 , NULL , HFILL } } ,
{ & hf_vbucket_states_size , { " Size " , " couchbase.vbucket_states.size " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vbucket_states_id , { " VBucket " , " couchbase.vbucket_states.id " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_vbucket_states_seqno , { " Sequence Number " , " couchbase.vbucket_states.seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
2014-07-09 12:58:13 +00:00
{ & hf_extras_expiration , { " Expiration " , " couchbase.extras.expiration " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_delta , { " Amount to Add " , " couchbase.extras.delta " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_initial , { " Initial Value " , " couchbase.extras.initial " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_unknown , { " Unknown " , " couchbase.extras.unknown " , FT_BYTES , BASE_NONE , NULL , 0x0 , " Unknown Extras " , HFILL } } ,
2018-12-07 11:58:31 +00:00
{ & hf_key , { " Key " , " couchbase.key " , FT_STRING , BASE_NONE , NULL , 0x0 , " If this is a collection stream, the key is formed of a leb128 prefix and then the key " , HFILL } } ,
2015-08-20 15:05:57 +00:00
{ & hf_path , { " Path " , " couchbase.path " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2014-07-09 12:58:13 +00:00
{ & hf_value , { " Value " , " couchbase.value " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_uint64_response , { " Response " , " couchbase.extras.response " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe , { " Observe " , " couchbase.observe " , FT_STRING , BASE_NONE , NULL , 0x0 , " The observe properties " , HFILL } } ,
{ & hf_observe_key , { " Key " , " couchbase.observe.key " , FT_STRING , BASE_NONE , NULL , 0x0 , " The observable key " , HFILL } } ,
{ & hf_observe_keylength , { " Key Length " , " couchbase.observe.keylength " , FT_UINT16 , BASE_DEC , NULL , 0x0 , " The length of the observable key " , HFILL } } ,
{ & hf_observe_vbucket , { " VBucket " , " couchbase.observe.vbucket " , FT_UINT16 , BASE_HEX , NULL , 0x0 , " VBucket of the observable key " , HFILL } } ,
{ & hf_observe_status , { " Status " , " couchbase.observe.status " , FT_UINT8 , BASE_HEX , NULL , 0x0 , " Status of the observable key " , HFILL } } ,
2022-02-22 11:55:54 +00:00
{ & hf_observe_cas , { " CAS " , " couchbase.observe.cas " , FT_UINT64 , BASE_HEX , NULL , 0x0 , " CAS value of the observable key " , HFILL } } ,
{ & hf_observe_vbucket_uuid , { " VBucket UUID " , " couchbase.observe.vbucket_uuid " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe_last_persisted_seqno , { " Last persisted sequence number " , " couchbase.observe.last_persisted_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe_current_seqno , { " Current sequence number " , " couchbase.observe.current_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe_old_vbucket_uuid , { " Old VBucket UUID " , " couchbase.observe.old_vbucket_uuid " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe_last_received_seqno , { " Last received sequence number " , " couchbase.observe.last_received_seqno " , FT_UINT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_observe_failed_over , { " Failed over " , " couchbase.observe.failed_over " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_get_errmap_version , { " Version " , " couchbase.geterrmap.version " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_multipath_opcode , { " Opcode " , " couchbase.multipath.opcode " , FT_UINT8 , BASE_HEX | BASE_EXT_STRING , & client_opcode_vals_ext , 0x0 , " Command code " , HFILL } } ,
{ & hf_multipath_index , { " Index " , " couchbase.multipath.index " , FT_UINT8 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_multipath_pathlen , { " Path Length " , " couchbase.multipath.path.length " , FT_UINT16 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_multipath_path , { " Path " , " couchbase.multipath.path " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_multipath_valuelen , { " Value Length " , " couchbase.multipath.value.length " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_multipath_value , { " Value " , " couchbase.multipath.value " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_flags , { " Flags " , " couchbase.extras.flags " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_expiration , { " Expiration " , " couchbase.extras.expiration " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_revseqno , { " RevSeqno " , " couchbase.extras.revseqno " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_cas , { " CAS " , " couchbase.extras.cas " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2017-02-02 15:28:59 +00:00
{ & hf_meta_options , { " Options " , " couchbase.extras.options " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
2022-12-15 13:28:05 +00:00
{ & hf_force_meta , { " FORCE_WITH_META_OP " , " couchbase.extras.options.force_with_meta_op " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0001 , NULL , HFILL } } ,
{ & hf_force_accept , { " FORCE_ACCEPT_WITH_META_OPS " , " couchbase.extras.options.force_accept_with_meta_ops " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0002 , NULL , HFILL } } ,
{ & hf_regenerate_cas , { " REGENERATE_CAS " , " couchbase.extras.option.regenerate_cas " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0004 , NULL , HFILL } } ,
{ & hf_skip_conflict , { " SKIP_CONFLICT_RESOLUTION " , " couchbase.extras.options.skip_conflict_resolution " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0008 , NULL , HFILL } } ,
{ & hf_is_expiration , { " IS_EXPIRATION " , " couchbase.extras.options.is_expiration " , FT_BOOLEAN , 16 , TFS ( & tfs_set_notset ) , 0x0010 , NULL , HFILL } } ,
2017-02-02 15:28:59 +00:00
{ & hf_metalen , { " Meta Length " , " couchbase.extras.meta_length " , FT_UINT16 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_reqextmeta , { " ReqExtMeta " , " couchbase.extras.reqextmeta " , FT_UINT8 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_meta_deleted , { " Deleted " , " couchbase.extras.deleted " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_exptime , { " Expiry " , " couchbase.extras.expiry " , FT_UINT32 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_extras_meta_seqno , { " Seqno " , " couchbase.extras.meta.seqno " , FT_UINT64 , BASE_HEX , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_confres , { " ConfRes " , " couchbase.extras.confres " , FT_UINT8 , BASE_HEX , NULL , 0x0 , " Conflict Resolution Mode " , HFILL } } ,
2017-02-03 12:42:32 +00:00
{ & hf_bucket_type , { " Bucket Type " , " couchbase.bucket.type " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_bucket_config , { " Bucket Config " , " couchbase.bucket.config " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_config_key , { " Key " , " couchbase.bucket.config.key " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_config_value , { " Value " , " couchbase.bucket.config.value " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2022-02-24 08:33:51 +00:00
{ & hf_hello_features , { " Hello Features " , " couchbase.hello.features " , FT_NONE , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2017-02-01 17:04:56 +00:00
{ & hf_hello_features_feature , { " Feature " , " couchbase.hello.features.feature " , FT_UINT16 , BASE_HEX , VALS ( feature_vals ) , 0x0 , NULL , HFILL } } ,
{ & hf_xattrs , { " XATTRs " , " couchbase.xattrs " , FT_NONE , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_xattr_length , { " XATTR Length " , " couchbase.xattrs.length " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_xattr_pair_length , { " XATTR Pair Length " , " couchbase.xattrs.pair.length " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_xattr_key , { " Key " , " couchbase.xattrs.pair.key " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_xattr_value , { " Value " , " couchbase.xattrs.pair.value " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2022-02-22 11:55:54 +00:00
{ & hf_server_extras_cccp_epoch , { " Epoch " , " couchbase.server.extras.cccp.epoch " , FT_INT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_server_extras_cccp_revno , { " Revision " , " couchbase.server.extras.cccp.revision " , FT_INT64 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_server_clustermap_value , { " Clustermap " , " couchbase.server.clustermap.value " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_server_authentication , { " Authentication " , " couchbase.server.authentication " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_server_external_users , { " External users " , " couchbase.server.external_users " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_server_get_authorization , { " Authorization " , " couchbase.server.authorization " , FT_STRING , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
2022-10-19 14:00:37 +00:00
{ & hf_range_scan_uuid , { " Range Scan UUID " , " couchbase.range_scan.uuid " , FT_GUID , BASE_NONE , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_range_scan_item_limit , { " Range Scan item limit " , " couchbase.range_scan.item_limit " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_range_scan_time_limit , { " Range Scan time limit " , " couchbase.range_scan.time_limit " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } } ,
{ & hf_range_scan_byte_limit , { " Range Scan byte limit " , " couchbase.range_scan.byte_limit " , FT_UINT32 , BASE_DEC , NULL , 0x0 , NULL , HFILL } }
2014-07-09 12:58:13 +00:00
} ;
static ei_register_info ei [ ] = {
{ & ei_value_missing , { " couchbase.value_missing " , PI_PROTOCOL , PI_WARN , " Value is mandatory for this command " , EXPFILL } } ,
{ & ef_warn_shall_not_have_value , { " couchbase.warn.shall_not_have_value " , PI_UNDECODED , PI_WARN , " Packet shall not have value " , EXPFILL } } ,
{ & ef_warn_shall_not_have_extras , { " couchbase.warn.shall_not_have_extras " , PI_UNDECODED , PI_WARN , " Packet shall not have extras " , EXPFILL } } ,
{ & ef_warn_shall_not_have_key , { " couchbase.warn.shall_not_have_key " , PI_UNDECODED , PI_WARN , " Packet shall not have key " , EXPFILL } } ,
{ & ef_warn_must_have_extras , { " couchbase.warn.must_have_extras " , PI_UNDECODED , PI_WARN , " Packet must have extras " , EXPFILL } } ,
{ & ef_warn_must_have_key , { " couchbase.warn.must_have_key " , PI_UNDECODED , PI_WARN , " %s %s must have Key " , EXPFILL } } ,
{ & ef_warn_illegal_extras_length , { " couchbase.warn.illegal_extras_length " , PI_UNDECODED , PI_WARN , " Illegal Extras length " , EXPFILL } } ,
{ & ef_warn_illegal_value_length , { " couchbase.warn.illegal_value_length " , PI_UNDECODED , PI_WARN , " Illegal Value length " , EXPFILL } } ,
{ & ef_warn_unknown_magic_byte , { " couchbase.warn.unknown_magic_byte " , PI_UNDECODED , PI_WARN , " Unknown magic byte " , EXPFILL } } ,
{ & ef_warn_unknown_opcode , { " couchbase.warn.unknown_opcode " , PI_UNDECODED , PI_WARN , " Unknown opcode " , EXPFILL } } ,
2022-02-22 11:55:54 +00:00
{ & ef_warn_unknown_extras , { " couchbase.warn.unknown_extras " , PI_UNDECODED , PI_WARN , " Unknown extras " , EXPFILL } } ,
2017-02-03 12:42:32 +00:00
{ & ef_note_status_code , { " couchbase.note.status_code " , PI_RESPONSE_CODE , PI_NOTE , " Status " , EXPFILL } } ,
{ & ef_separator_not_found , { " couchbase.warn.separator_not_found " , PI_UNDECODED , PI_WARN , " Separator not found " , EXPFILL } } ,
2017-12-20 21:24:35 +00:00
{ & ef_illegal_value , { " couchbase.warn.illegal_value " , PI_UNDECODED , PI_WARN , " Illegal value for command " , EXPFILL } } ,
2018-02-05 14:40:33 +00:00
{ & ef_compression_error , { " couchbase.error.compression " , PI_UNDECODED , PI_WARN , " Compression error " , EXPFILL } } ,
2018-12-03 11:37:54 +00:00
{ & ef_warn_unknown_flex_unsupported , { " couchbase.warn.unsupported_flexible_frame " , PI_UNDECODED , PI_WARN , " Flexible Response ID warning " , EXPFILL } } ,
{ & ef_warn_unknown_flex_id , { " couchbase.warn.unknown_flexible_frame_id " , PI_UNDECODED , PI_WARN , " Flexible Response ID warning " , EXPFILL } } ,
{ & ef_warn_unknown_flex_len , { " couchbase.warn.unknown_flexible_frame_len " , PI_UNDECODED , PI_WARN , " Flexible Response ID warning " , EXPFILL } }
2014-07-09 12:58:13 +00:00
} ;
static gint * ett [ ] = {
& ett_couchbase ,
& ett_extras ,
2018-02-05 14:40:33 +00:00
& ett_flex_frame_extras ,
2014-07-09 12:58:13 +00:00
& ett_extras_flags ,
2014-11-18 18:11:22 +00:00
& ett_observe ,
2015-08-20 15:05:57 +00:00
& ett_failover_log ,
2015-10-30 07:39:01 +00:00
& ett_vbucket_states ,
2017-02-03 12:42:32 +00:00
& ett_multipath ,
& ett_config ,
2017-02-01 17:04:56 +00:00
& ett_config_key ,
& ett_hello_features ,
& ett_datatype ,
& ett_xattrs ,
2018-12-03 11:38:24 +00:00
& ett_xattr_pair ,
& ett_collection_key
2014-07-09 12:58:13 +00:00
} ;
module_t * couchbase_module ;
expert_module_t * expert_couchbase ;
proto_couchbase = proto_register_protocol ( PNAME , PSNAME , PFNAME ) ;
proto_register_field_array ( proto_couchbase , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
expert_couchbase = expert_register_protocol ( proto_couchbase ) ;
expert_register_field_array ( expert_couchbase , ei , array_length ( ei ) ) ;
/* Register our configuration options */
2017-02-14 15:07:46 +00:00
couchbase_module = prefs_register_protocol ( proto_couchbase , & proto_reg_handoff_couchbase ) ;
2022-02-24 12:32:28 +00:00
couchbase_handle = register_dissector ( " couchbase " , dissect_couchbase_pdu , proto_couchbase ) ;
2014-07-09 12:58:13 +00:00
prefs_register_bool_preference ( couchbase_module , " desegment_pdus " ,
" Reassemble PDUs spanning multiple TCP segments " ,
2022-02-24 12:32:28 +00:00
" Whether the Couchbase dissector should reassemble PDUs "
2014-07-09 12:58:13 +00:00
" spanning multiple TCP segments. "
" To use this option, you must also enable \" Allow subdissectors "
" to reassemble TCP streams \" in the TCP protocol settings. " ,
& couchbase_desegment_body ) ;
2017-02-14 15:07:46 +00:00
2018-09-25 16:23:09 +00:00
prefs_register_uint_preference ( couchbase_module , " tls.port " , " SSL/TLS Data Port " ,
2018-09-13 15:40:27 +00:00
" The port used for communicating with the data service via SSL/TLS " ,
2017-02-14 15:07:46 +00:00
10 , & couchbase_ssl_port_pref ) ;
2018-09-25 16:23:09 +00:00
prefs_register_obsolete_preference ( couchbase_module , " ssl_port " ) ;
2014-07-09 12:58:13 +00:00
}
/* Register the tcp couchbase dissector. */
void
proto_reg_handoff_couchbase ( void )
{
2017-02-14 15:07:46 +00:00
static gboolean initialized = FALSE ;
2014-07-09 12:58:13 +00:00
2017-02-14 15:07:46 +00:00
if ( ! initialized ) {
json_handle = find_dissector_add_dependency ( " json " , proto_couchbase ) ;
dissector_add_uint_range_with_preference ( " tcp.port " , COUCHBASE_DEFAULT_PORT , couchbase_handle ) ;
initialized = TRUE ;
} else {
ssl_dissector_delete ( couchbase_ssl_port , couchbase_handle ) ;
}
couchbase_ssl_port = couchbase_ssl_port_pref ;
ssl_dissector_add ( couchbase_ssl_port , couchbase_handle ) ;
2014-07-09 12:58:13 +00:00
}
/*
* Editor modelines
*
* Local Variables :
* c - basic - offset : 2
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* ex : set shiftwidth = 2 tabstop = 8 expandtab :
* : indentSize = 2 : tabSize = 8 : noTabs = true :
*/