2 * Routines for Mongo Wire Protocol dissection
3 * Copyright 2010, Alexis La Goutte <alexis.lagoutte at gmail dot com>
4 * BSON dissection added 2011, Thomas Buchanan <tom at thomasbuchanan dot com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 * See Mongo Wire Protocol Specification
29 * http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
30 * See also BSON Specification
31 * http://bsonspec.org/#/specification
38 #include <epan/packet.h>
39 #include <epan/exceptions.h>
40 #include <epan/prefs.h>
41 #include <epan/expert.h>
42 #include "packet-tcp.h"
44 /* This is not IANA assigned nor registered */
45 #define TCP_PORT_MONGO 27017
49 #define OP_UPDATE 2001
50 #define OP_INSERT 2002
51 #define OP_RESERVED 2003
53 #define OP_GET_MORE 2005
54 #define OP_DELETE 2006
55 #define OP_KILL_CURSORS 2007
57 /**************************************************************************/
59 /**************************************************************************/
60 static const value_string opcode_vals
[] = {
61 { OP_REPLY
, "Reply" },
62 { OP_MSG
, "Message" },
63 { OP_UPDATE
, "Update document" },
64 { OP_INSERT
, "Insert document" },
65 { OP_RESERVED
,"Reserved" },
66 { OP_QUERY
, "Query" },
67 { OP_GET_MORE
, "Get More" },
68 { OP_DELETE
, "Delete document" },
69 { OP_KILL_CURSORS
, "Kill Cursors" },
73 /* BSON Element types */
74 /* See http://bsonspec.org/#/specification for detail */
75 #define BSON_ELEMENT_TYPE_DOUBLE 1
76 #define BSON_ELEMENT_TYPE_STRING 2
77 #define BSON_ELEMENT_TYPE_DOC 3
78 #define BSON_ELEMENT_TYPE_ARRAY 4
79 #define BSON_ELEMENT_TYPE_BINARY 5
80 #define BSON_ELEMENT_TYPE_UNDEF 6 /* Deprecated */
81 #define BSON_ELEMENT_TYPE_OBJ_ID 7
82 #define BSON_ELEMENT_TYPE_BOOL 8
83 #define BSON_ELEMENT_TYPE_DATETIME 9
84 #define BSON_ELEMENT_TYPE_NULL 10
85 #define BSON_ELEMENT_TYPE_REGEX 11
86 #define BSON_ELEMENT_TYPE_DB_PTR 12 /* Deprecated */
87 #define BSON_ELEMENT_TYPE_JS_CODE 13
88 #define BSON_ELEMENT_TYPE_SYMBOL 14
89 #define BSON_ELEMENT_TYPE_JS_CODE_SCOPE 15
90 #define BSON_ELEMENT_TYPE_INT32 16 /* 0x10 */
91 #define BSON_ELEMENT_TYPE_TIMESTAMP 17 /* 0x11 */
92 #define BSON_ELEMENT_TYPE_INT64 18 /* 0x12 */
93 #define BSON_ELEMENT_TYPE_MIN_KEY 255 /* 0xFF */
94 #define BSON_ELEMENT_TYPE_MAX_KEY 127 /* 0x7F */
96 static const value_string element_type_vals
[] = {
97 { BSON_ELEMENT_TYPE_DOUBLE
, "Double" },
98 { BSON_ELEMENT_TYPE_STRING
, "String" },
99 { BSON_ELEMENT_TYPE_DOC
, "Document" },
100 { BSON_ELEMENT_TYPE_ARRAY
, "Array" },
101 { BSON_ELEMENT_TYPE_BINARY
, "Binary" },
102 { BSON_ELEMENT_TYPE_UNDEF
, "Undefined" },
103 { BSON_ELEMENT_TYPE_OBJ_ID
, "Object ID" },
104 { BSON_ELEMENT_TYPE_BOOL
, "Boolean" },
105 { BSON_ELEMENT_TYPE_DATETIME
, "Datetime" },
106 { BSON_ELEMENT_TYPE_NULL
, "NULL" },
107 { BSON_ELEMENT_TYPE_REGEX
, "Regular Expression" },
108 { BSON_ELEMENT_TYPE_DB_PTR
, "DBPointer" },
109 { BSON_ELEMENT_TYPE_JS_CODE
, "JavaScript Code" },
110 { BSON_ELEMENT_TYPE_SYMBOL
, "Symbol" },
111 { BSON_ELEMENT_TYPE_JS_CODE_SCOPE
, "JavaScript Code w/Scope" },
112 { BSON_ELEMENT_TYPE_INT32
, "Int32" },
113 { BSON_ELEMENT_TYPE_TIMESTAMP
, "Timestamp" },
114 { BSON_ELEMENT_TYPE_INT64
, "Int64" },
115 { BSON_ELEMENT_TYPE_MIN_KEY
, "Min Key" },
116 { BSON_ELEMENT_TYPE_MAX_KEY
, "Max Key" },
120 /* BSON Element Binary subtypes */
121 #define BSON_ELEMENT_BINARY_TYPE_GENERIC 0
122 #define BSON_ELEMENT_BINARY_TYPE_FUNCTION 1
123 #define BSON_ELEMENT_BINARY_TYPE_BINARY 2 /* OLD */
124 #define BSON_ELEMENT_BINARY_TYPE_UUID 3
125 #define BSON_ELEMENT_BINARY_TYPE_MD5 4
126 #define BSON_ELEMENT_BINARY_TYPE_USER 128 /* 0x80 */
129 static const value_string binary_type_vals
[] = {
130 { BSON_ELEMENT_BINARY_TYPE_GENERIC
, "Generic" },
131 { BSON_ELEMENT_BINARY_TYPE_FUNCTION
, "Function" },
132 { BSON_ELEMENT_BINARY_TYPE_BINARY
, "Binary" },
133 { BSON_ELEMENT_BINARY_TYPE_UUID
, "UUID" },
134 { BSON_ELEMENT_BINARY_TYPE_MD5
, "MD5" },
135 { BSON_ELEMENT_BINARY_TYPE_USER
, "User" },
140 void proto_reg_handoff_mongo(void);
143 static int proto_mongo
= -1;
144 static int hf_mongo_message_length
= -1;
145 static int hf_mongo_request_id
= -1;
146 static int hf_mongo_response_to
= -1;
147 static int hf_mongo_op_code
= -1;
148 static int hf_mongo_fullcollectionname
= -1;
149 static int hf_mongo_database_name
= -1;
150 static int hf_mongo_collection_name
= -1;
151 static int hf_mongo_reply_flags
= -1;
152 static int hf_mongo_reply_flags_cursornotfound
= -1;
153 static int hf_mongo_reply_flags_queryfailure
= -1;
154 static int hf_mongo_reply_flags_sharedconfigstale
= -1;
155 static int hf_mongo_reply_flags_awaitcapable
= -1;
156 static int hf_mongo_cursor_id
= -1;
157 static int hf_mongo_starting_from
= -1;
158 static int hf_mongo_number_returned
= -1;
159 static int hf_mongo_message
= -1;
160 static int hf_mongo_zero
= -1;
161 static int hf_mongo_update_flags
= -1;
162 static int hf_mongo_update_flags_upsert
= -1;
163 static int hf_mongo_update_flags_multiupdate
= -1;
164 static int hf_mongo_selector
= -1;
165 static int hf_mongo_update
= -1;
166 static int hf_mongo_insert_flags
= -1;
167 static int hf_mongo_insert_flags_continueonerror
= -1;
168 static int hf_mongo_query_flags
= -1;
169 static int hf_mongo_query_flags_tailablecursor
= -1;
170 static int hf_mongo_query_flags_slaveok
= -1;
171 static int hf_mongo_query_flags_oplogreplay
= -1;
172 static int hf_mongo_query_flags_nocursortimeout
= -1;
173 static int hf_mongo_query_flags_awaitdata
= -1;
174 static int hf_mongo_query_flags_exhaust
= -1;
175 static int hf_mongo_query_flags_partial
= -1;
176 static int hf_mongo_number_to_skip
= -1;
177 static int hf_mongo_number_to_return
= -1;
178 static int hf_mongo_query
= -1;
179 static int hf_mongo_return_field_selector
= -1;
180 static int hf_mongo_document
= -1;
181 static int hf_mongo_document_length
= -1;
182 static int hf_mongo_document_empty
= -1;
183 static int hf_mongo_delete_flags
= -1;
184 static int hf_mongo_delete_flags_singleremove
= -1;
185 static int hf_mongo_number_of_cursor_ids
= -1;
186 static int hf_mongo_elements
= -1;
187 static int hf_mongo_element_name
= -1;
188 static int hf_mongo_element_type
= -1;
189 static int hf_mongo_element_length
= -1;
190 static int hf_mongo_element_value_boolean
= -1;
191 static int hf_mongo_element_value_int32
= -1;
192 static int hf_mongo_element_value_int64
= -1;
193 static int hf_mongo_element_value_double
= -1;
194 static int hf_mongo_element_value_string
= -1;
195 static int hf_mongo_element_value_string_length
= -1;
196 static int hf_mongo_element_value_binary
= -1;
197 static int hf_mongo_element_value_binary_length
= -1;
198 static int hf_mongo_element_value_regex_pattern
= -1;
199 static int hf_mongo_element_value_regex_options
= -1;
200 static int hf_mongo_element_value_objectid
= -1;
201 static int hf_mongo_element_value_objectid_time
= -1;
202 static int hf_mongo_element_value_objectid_machine
= -1;
203 static int hf_mongo_element_value_objectid_pid
= -1;
204 static int hf_mongo_element_value_objectid_inc
= -1;
205 static int hf_mongo_element_value_db_ptr
= -1;
206 static int hf_mongo_element_value_js_code
= -1;
207 static int hf_mongo_element_value_js_scope
= -1;
208 static int hf_mongo_unknown
= -1;
210 static guint global_mongo_tcp_port
= TCP_PORT_MONGO
;
212 static gint ett_mongo
= -1;
213 static gint ett_mongo_doc
= -1;
214 static gint ett_mongo_elements
= -1;
215 static gint ett_mongo_element
= -1;
216 static gint ett_mongo_objectid
= -1;
217 static gint ett_mongo_code
= -1;
218 static gint ett_mongo_fcn
= -1;
219 static gint ett_mongo_flags
= -1;
221 static expert_field ei_mongo_document_recursion_exceeded
= EI_INIT
;
222 static expert_field ei_mongo_document_length_bad
= EI_INIT
;
223 static expert_field ei_mongo_unknown
= EI_INIT
;
226 dissect_fullcollectionname(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
)
228 gint32 fcn_length
, dbn_length
;
230 proto_tree
*fcn_tree
;
232 fcn_length
= tvb_strsize(tvb
, offset
);
233 ti
= proto_tree_add_item(tree
, hf_mongo_fullcollectionname
, tvb
, offset
, fcn_length
, ENC_ASCII
|ENC_NA
);
235 /* If this doesn't find anything, we'll just throw an exception below */
236 dbn_length
= tvb_find_guint8(tvb
, offset
, fcn_length
, '.') - offset
;
238 fcn_tree
= proto_item_add_subtree(ti
, ett_mongo_fcn
);
240 proto_tree_add_item(fcn_tree
, hf_mongo_database_name
, tvb
, offset
, dbn_length
, ENC_ASCII
|ENC_NA
);
242 proto_tree_add_item(fcn_tree
, hf_mongo_collection_name
, tvb
, offset
+ 1 + dbn_length
, fcn_length
- dbn_length
- 2, ENC_ASCII
|ENC_NA
);
247 /* http://docs.mongodb.org/manual/reference/limits/ */
248 /* http://www.mongodb.org/display/DOCS/Documents */
249 #define BSON_MAX_NESTING 100
250 #define BSON_MAX_DOC_SIZE (16 * 1000 * 1000)
252 dissect_bson_document(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
, int hf_mongo_doc
, int nest_level
)
254 gint32 document_length
;
256 proto_item
*ti
, *elements
, *element
, *objectid
, *js_code
, *js_scope
;
257 proto_tree
*doc_tree
, *elements_tree
, *element_sub_tree
, *objectid_sub_tree
, *js_code_sub_tree
, *js_scope_sub_tree
;
259 document_length
= tvb_get_letohl(tvb
, offset
);
261 ti
= proto_tree_add_item(tree
, hf_mongo_doc
, tvb
, offset
, document_length
, ENC_NA
);
262 doc_tree
= proto_item_add_subtree(ti
, ett_mongo_doc
);
264 proto_tree_add_item(doc_tree
, hf_mongo_document_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
266 if (nest_level
> BSON_MAX_NESTING
) {
267 expert_add_info_format(pinfo
, ti
, &ei_mongo_document_recursion_exceeded
, "BSON document recursion exceeds %u", BSON_MAX_NESTING
);
268 THROW(ReportedBoundsError
);
271 if (document_length
< 5) {
272 expert_add_info_format(pinfo
, ti
, &ei_mongo_document_length_bad
, "BSON document length too short: %u", document_length
);
273 THROW(ReportedBoundsError
);
276 if (document_length
> BSON_MAX_DOC_SIZE
) {
277 expert_add_info_format(pinfo
, ti
, &ei_mongo_document_length_bad
, "BSON document length too long: %u", document_length
);
278 THROW(ReportedBoundsError
);
281 if (document_length
== 5) {
282 /* document with length 5 is an empty document */
283 /* don't display the element subtree */
284 proto_tree_add_item(tree
, hf_mongo_document_empty
, tvb
, offset
, document_length
, ENC_NA
);
285 return document_length
;
288 final_offset
= offset
+ document_length
;
291 elements
= proto_tree_add_item(doc_tree
, hf_mongo_elements
, tvb
, offset
, document_length
-5, ENC_NA
);
292 elements_tree
= proto_item_add_subtree(elements
, ett_mongo_elements
);
295 /* Read document elements */
296 guint8 e_type
= -1; /* Element type */
297 gint str_len
= -1; /* String length */
298 gint e_len
= -1; /* Element length */
299 gint doc_len
= -1; /* Document length */
301 e_type
= tvb_get_guint8(tvb
, offset
);
302 tvb_get_stringz(wmem_packet_scope(), tvb
, offset
+1, &str_len
);
304 element
= proto_tree_add_item(elements_tree
, hf_mongo_element_name
, tvb
, offset
+1, str_len
-1, ENC_UTF_8
|ENC_NA
);
305 element_sub_tree
= proto_item_add_subtree(element
, ett_mongo_element
);
306 proto_tree_add_item(element_sub_tree
, hf_mongo_element_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
311 case BSON_ELEMENT_TYPE_DOUBLE
:
312 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_double
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
315 case BSON_ELEMENT_TYPE_STRING
:
316 case BSON_ELEMENT_TYPE_JS_CODE
:
317 case BSON_ELEMENT_TYPE_SYMBOL
:
318 str_len
= tvb_get_letohl(tvb
, offset
);
319 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_string_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
320 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_string
, tvb
, offset
+4, str_len
, ENC_UTF_8
|ENC_NA
);
323 case BSON_ELEMENT_TYPE_DOC
:
324 case BSON_ELEMENT_TYPE_ARRAY
:
325 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, element_sub_tree
, hf_mongo_document
, nest_level
+1);
327 case BSON_ELEMENT_TYPE_BINARY
:
328 e_len
= tvb_get_letohl(tvb
, offset
);
329 /* TODO - Add functions to decode various binary subtypes */
330 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_binary_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
331 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_binary
, tvb
, offset
+5, e_len
, ENC_NA
);
334 case BSON_ELEMENT_TYPE_UNDEF
:
335 case BSON_ELEMENT_TYPE_NULL
:
336 case BSON_ELEMENT_TYPE_MIN_KEY
:
337 case BSON_ELEMENT_TYPE_MAX_KEY
:
338 /* Nothing to do, as there is no element content */
340 case BSON_ELEMENT_TYPE_OBJ_ID
:
341 objectid
= proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_objectid
, tvb
, offset
, 12, ENC_NA
);
342 objectid_sub_tree
= proto_item_add_subtree(objectid
, ett_mongo_objectid
);
343 /* Unlike most BSON elements, parts of ObjectID are stored Big Endian, so they can be compared bit by bit */
344 proto_tree_add_item(objectid_sub_tree
, hf_mongo_element_value_objectid_time
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
345 proto_tree_add_item(objectid_sub_tree
, hf_mongo_element_value_objectid_machine
, tvb
, offset
+4, 3, ENC_LITTLE_ENDIAN
);
346 proto_tree_add_item(objectid_sub_tree
, hf_mongo_element_value_objectid_pid
, tvb
, offset
+7, 2, ENC_LITTLE_ENDIAN
);
347 proto_tree_add_item(objectid_sub_tree
, hf_mongo_element_value_objectid_inc
, tvb
, offset
+9, 3, ENC_BIG_ENDIAN
);
350 case BSON_ELEMENT_TYPE_BOOL
:
351 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_boolean
, tvb
, offset
, 1, ENC_NA
);
354 case BSON_ELEMENT_TYPE_REGEX
:
356 tvb_get_stringz(wmem_packet_scope(), tvb
, offset
, &str_len
);
357 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_regex_pattern
, tvb
, offset
, str_len
, ENC_UTF_8
|ENC_NA
);
360 tvb_get_stringz(wmem_packet_scope(), tvb
, offset
, &str_len
);
361 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_regex_options
, tvb
, offset
, str_len
, ENC_UTF_8
|ENC_NA
);
364 case BSON_ELEMENT_TYPE_DB_PTR
:
365 str_len
= tvb_get_letohl(tvb
, offset
);
366 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_string_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
367 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_string
, tvb
, offset
+4, str_len
, ENC_UTF_8
|ENC_NA
);
369 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_db_ptr
, tvb
, offset
, 12, ENC_NA
);
372 case BSON_ELEMENT_TYPE_JS_CODE_SCOPE
:
373 /* code_w_s ::= int32 string document */
374 proto_tree_add_item(element_sub_tree
, hf_mongo_element_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
375 e_len
= tvb_get_letohl(tvb
, offset
);
377 str_len
= tvb_get_letohl(tvb
, offset
);
378 js_code
= proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_js_code
, tvb
, offset
, str_len
+4, ENC_NA
);
379 js_code_sub_tree
= proto_item_add_subtree(js_code
, ett_mongo_code
);
380 proto_tree_add_item(js_code_sub_tree
, hf_mongo_element_value_string_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
381 proto_tree_add_item(js_code_sub_tree
, hf_mongo_element_value_string
, tvb
, offset
+4, str_len
, ENC_UTF_8
|ENC_NA
);
383 doc_len
= e_len
- (str_len
+ 8);
384 js_scope
= proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_js_scope
, tvb
, offset
, doc_len
, ENC_NA
);
385 js_scope_sub_tree
= proto_item_add_subtree(js_scope
, ett_mongo_code
);
386 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, js_scope_sub_tree
, hf_mongo_document
, nest_level
+1);
388 case BSON_ELEMENT_TYPE_INT32
:
389 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_int32
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
392 case BSON_ELEMENT_TYPE_DATETIME
:
393 case BSON_ELEMENT_TYPE_TIMESTAMP
:
394 /* TODO Implement routine to convert datetime & timestamp values to UTC date/time */
395 /* for now, simply display the integer value */
396 case BSON_ELEMENT_TYPE_INT64
:
397 proto_tree_add_item(element_sub_tree
, hf_mongo_element_value_int64
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
403 } while (offset
< final_offset
-1);
405 return document_length
;
408 dissect_mongo_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
)
411 proto_tree
*flags_tree
;
412 gint i
, number_returned
;
414 ti
= proto_tree_add_item(tree
, hf_mongo_reply_flags
, tvb
, offset
, 4, ENC_NA
);
415 flags_tree
= proto_item_add_subtree(ti
, ett_mongo_flags
);
416 proto_tree_add_item(flags_tree
, hf_mongo_reply_flags_cursornotfound
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
417 proto_tree_add_item(flags_tree
, hf_mongo_reply_flags_queryfailure
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
418 proto_tree_add_item(flags_tree
, hf_mongo_reply_flags_sharedconfigstale
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
419 proto_tree_add_item(flags_tree
, hf_mongo_reply_flags_awaitcapable
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
422 proto_tree_add_item(tree
, hf_mongo_cursor_id
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
425 proto_tree_add_item(tree
, hf_mongo_starting_from
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
428 proto_tree_add_item(tree
, hf_mongo_number_returned
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
429 number_returned
= tvb_get_letohl(tvb
, offset
);
432 for (i
=0; i
< number_returned
; i
++)
434 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_document
, 1);
439 dissect_mongo_msg(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
)
441 proto_tree_add_item(tree
, hf_mongo_message
, tvb
, offset
, -1, ENC_ASCII
|ENC_NA
);
442 offset
+= tvb_strsize(tvb
, offset
);
448 dissect_mongo_update(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
)
451 proto_tree
*flags_tree
;
453 proto_tree_add_item(tree
, hf_mongo_zero
, tvb
, offset
, 4, ENC_NA
);
456 offset
+= dissect_fullcollectionname(tvb
, offset
, tree
);
458 ti
= proto_tree_add_item(tree
, hf_mongo_update_flags
, tvb
, offset
, 4, ENC_NA
);
459 flags_tree
= proto_item_add_subtree(ti
, ett_mongo_flags
);
460 proto_tree_add_item(flags_tree
, hf_mongo_update_flags_upsert
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
461 proto_tree_add_item(flags_tree
, hf_mongo_update_flags_multiupdate
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
464 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_selector
, 1);
466 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_update
, 1);
472 dissect_mongo_insert(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
)
475 proto_tree
*flags_tree
;
477 ti
= proto_tree_add_item(tree
, hf_mongo_insert_flags
, tvb
, offset
, 4, ENC_NA
);
478 flags_tree
= proto_item_add_subtree(ti
, ett_mongo_flags
);
479 proto_tree_add_item(flags_tree
, hf_mongo_insert_flags_continueonerror
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
482 offset
+= dissect_fullcollectionname(tvb
, offset
, tree
);
484 while(offset
< tvb_reported_length(tvb
)) {
485 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_document
, 1);
492 dissect_mongo_query(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
)
495 proto_tree
*flags_tree
;
497 ti
= proto_tree_add_item(tree
, hf_mongo_query_flags
, tvb
, offset
, 4, ENC_NA
);
498 flags_tree
= proto_item_add_subtree(ti
, ett_mongo_flags
);
499 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_tailablecursor
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
500 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_slaveok
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
501 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_oplogreplay
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
502 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_nocursortimeout
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
503 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_awaitdata
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
504 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_exhaust
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
505 proto_tree_add_item(flags_tree
, hf_mongo_query_flags_partial
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
508 offset
+= dissect_fullcollectionname(tvb
, offset
, tree
);
510 proto_tree_add_item(tree
, hf_mongo_number_to_skip
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
513 proto_tree_add_item(tree
, hf_mongo_number_to_return
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
516 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_query
, 1);
518 while(offset
< tvb_reported_length(tvb
)) {
519 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_return_field_selector
, 1);
525 dissect_mongo_getmore(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
)
528 proto_tree_add_item(tree
, hf_mongo_zero
, tvb
, offset
, 4, ENC_NA
);
531 offset
+= dissect_fullcollectionname(tvb
, offset
, tree
);
533 proto_tree_add_item(tree
, hf_mongo_number_to_return
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
536 proto_tree_add_item(tree
, hf_mongo_cursor_id
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
543 dissect_mongo_delete(tvbuff_t
*tvb
, packet_info
*pinfo
, guint offset
, proto_tree
*tree
)
546 proto_tree
*flags_tree
;
548 proto_tree_add_item(tree
, hf_mongo_zero
, tvb
, offset
, 4, ENC_NA
);
551 offset
+= dissect_fullcollectionname(tvb
, offset
, tree
);
553 ti
= proto_tree_add_item(tree
, hf_mongo_delete_flags
, tvb
, offset
, 4, ENC_NA
);
554 flags_tree
= proto_item_add_subtree(ti
, ett_mongo_flags
);
555 proto_tree_add_item(flags_tree
, hf_mongo_delete_flags_singleremove
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
558 offset
+= dissect_bson_document(tvb
, pinfo
, offset
, tree
, hf_mongo_selector
, 1);
564 dissect_mongo_kill_cursors(tvbuff_t
*tvb
, guint offset
, proto_tree
*tree
)
567 proto_tree_add_item(tree
, hf_mongo_zero
, tvb
, offset
, 4, ENC_NA
);
570 proto_tree_add_item(tree
, hf_mongo_number_of_cursor_ids
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
573 while(offset
< tvb_reported_length(tvb
)) {
574 proto_tree_add_item(tree
, hf_mongo_cursor_id
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
580 dissect_mongo_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
583 proto_tree
*mongo_tree
;
584 guint offset
= 0, opcode
;
586 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MONGO");
588 ti
= proto_tree_add_item(tree
, proto_mongo
, tvb
, 0, -1, ENC_NA
);
590 mongo_tree
= proto_item_add_subtree(ti
, ett_mongo
);
592 proto_tree_add_item(mongo_tree
, hf_mongo_message_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
595 proto_tree_add_item(mongo_tree
, hf_mongo_request_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
598 proto_tree_add_item(mongo_tree
, hf_mongo_response_to
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
601 proto_tree_add_item(mongo_tree
, hf_mongo_op_code
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
602 opcode
= tvb_get_letohl(tvb
, offset
);
607 col_set_str(pinfo
->cinfo
, COL_INFO
, "Response :");
611 col_set_str(pinfo
->cinfo
, COL_INFO
, "Request :");
614 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", val_to_str_const(opcode
, opcode_vals
, "Unknown"));
618 offset
= dissect_mongo_reply(tvb
, pinfo
, offset
, mongo_tree
);
621 offset
= dissect_mongo_msg(tvb
, offset
, mongo_tree
);
624 offset
= dissect_mongo_update(tvb
, pinfo
, offset
, mongo_tree
);
627 offset
= dissect_mongo_insert(tvb
, pinfo
, offset
, mongo_tree
);
630 offset
= dissect_mongo_query(tvb
, pinfo
, offset
, mongo_tree
);
633 offset
= dissect_mongo_getmore(tvb
, offset
, mongo_tree
);
636 offset
= dissect_mongo_delete(tvb
, pinfo
, offset
, mongo_tree
);
638 case OP_KILL_CURSORS
:
639 offset
= dissect_mongo_kill_cursors(tvb
, offset
, mongo_tree
);
642 /* No default Action */
645 if(offset
< tvb_reported_length(tvb
))
647 ti
= proto_tree_add_item(mongo_tree
, hf_mongo_unknown
, tvb
, offset
, -1, ENC_NA
);
648 expert_add_info(pinfo
, ti
, &ei_mongo_unknown
);
651 return tvb_length(tvb
);
654 get_mongo_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
659 * Get the length of the MONGO packet.
661 plen
= tvb_get_letohl(tvb
, offset
);
667 dissect_mongo(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
669 tcp_dissect_pdus(tvb
, pinfo
, tree
, 1, 4, get_mongo_pdu_len
, dissect_mongo_pdu
, data
);
670 return tvb_length(tvb
);
674 proto_register_mongo(void)
676 module_t
*mongo_module
;
677 expert_module_t
* expert_mongo
;
679 static hf_register_info hf
[] = {
680 { &hf_mongo_message_length
,
681 { "Message Length", "mongo.message_length",
682 FT_INT32
, BASE_DEC
, NULL
, 0x0,
683 "Total message size (include this)", HFILL
}
685 { &hf_mongo_request_id
,
686 { "Request ID", "mongo.request_id",
687 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0,
688 "Identifier for this message", HFILL
}
690 { &hf_mongo_response_to
,
691 { "Response To", "mongo.response_to",
692 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0,
693 "RequestID from the original request", HFILL
}
696 { "OpCode", "mongo.opcode",
697 FT_INT32
, BASE_DEC
, VALS(opcode_vals
), 0x0,
698 "Type of request message", HFILL
}
700 { &hf_mongo_query_flags
,
701 { "Query Flags", "mongo.query.flags",
702 FT_NONE
, BASE_NONE
, NULL
, 0x0,
703 "Bit vector of query options.", HFILL
}
705 { &hf_mongo_fullcollectionname
,
706 { "fullCollectionName", "mongo.full_collection_name",
707 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
708 "The full collection name is the concatenation of the database name with the"
709 " collection name, using a dot for the concatenation", HFILL
}
711 { &hf_mongo_database_name
,
712 { "Database Name", "mongo.database_name",
713 FT_STRING
, BASE_NONE
, NULL
, 0x0,
716 { &hf_mongo_collection_name
,
717 { "Collection Name", "mongo.collection_name",
718 FT_STRING
, BASE_NONE
, NULL
, 0x0,
721 { &hf_mongo_reply_flags
,
722 { "Reply Flags", "mongo.reply.flags",
723 FT_NONE
, BASE_NONE
, NULL
, 0x0,
724 "Bit vector of reply options.", HFILL
}
726 { &hf_mongo_reply_flags_cursornotfound
,
727 { "Cursor Not Found", "mongo.reply.flags.cursornotfound",
728 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
729 "Set when getMore is called but the cursor id is not valid at the server", HFILL
}
731 { &hf_mongo_reply_flags_queryfailure
,
732 { "Query Failure", "mongo.reply.flags.queryfailure",
733 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000002,
734 "Set when query failed. Results consist of one document containing an $err"
735 " field describing the failure.", HFILL
}
737 { &hf_mongo_reply_flags_sharedconfigstale
,
738 { "Shared Config Stale", "mongo.reply.flags.sharedconfigstale",
739 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000004,
742 { &hf_mongo_reply_flags_awaitcapable
,
743 { "Await Capable", "mongo.reply.flags.awaitcapable",
744 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000008,
745 "Set when the server supports the AwaitData Query option", HFILL
}
748 { "Message", "mongo.message",
749 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
750 "Message for the database", HFILL
}
752 { &hf_mongo_cursor_id
,
753 { "Cursor ID", "mongo.cursor_id",
754 FT_INT64
, BASE_DEC
, NULL
, 0x0,
755 "Cursor id if client needs to do get more's", HFILL
}
757 { &hf_mongo_starting_from
,
758 { "Starting From", "mongo.starting_from",
759 FT_INT32
, BASE_DEC
, NULL
, 0x0,
760 "Where in the cursor this reply is starting", HFILL
}
762 { &hf_mongo_number_returned
,
763 { "Number Returned", "mongo.number_returned",
764 FT_INT32
, BASE_DEC
, NULL
, 0x0,
765 "Number of documents in the reply", HFILL
}
767 { &hf_mongo_document
,
768 { "Document", "mongo.document",
769 FT_NONE
, BASE_NONE
, NULL
, 0x0,
772 { &hf_mongo_document_length
,
773 { "Document length", "mongo.document.length",
774 FT_INT32
, BASE_DEC
, NULL
, 0x0,
775 "Length of BSON Document", HFILL
}
777 { &hf_mongo_document_empty
,
778 { "Empty Document", "mongo.document.empty",
779 FT_NONE
, BASE_NONE
, NULL
, 0x0,
780 "Document with no elements", HFILL
}
783 { "Zero", "mongo.document.zero",
784 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
785 "Reserved (Must be is Zero)", HFILL
}
787 { &hf_mongo_update_flags
,
788 { "Update Flags", "mongo.update.flags",
789 FT_NONE
, BASE_NONE
, NULL
, 0x0,
790 "Bit vector of update options.", HFILL
}
792 { &hf_mongo_update_flags_upsert
,
793 { "Upsert", "mongo.update.flags.upsert",
794 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
795 "If set, the database will insert the supplied object into the collection if no"
796 " matching document is found", HFILL
}
798 { &hf_mongo_update_flags_multiupdate
,
799 { "Multi Update", "mongo.update.flags.multiupdate",
800 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000002,
801 "If set, the database will update all matching objects in the collection."
802 " Otherwise only updates first matching doc.", HFILL
}
804 { &hf_mongo_selector
,
805 { "Selector", "mongo.selector",
806 FT_NONE
, BASE_NONE
, NULL
, 0x0,
807 "The query to select the document", HFILL
}
810 { "Update", "mongo.update",
811 FT_NONE
, BASE_NONE
, NULL
, 0x0,
812 "Specification of the update to perform", HFILL
}
814 { &hf_mongo_insert_flags
,
815 { "Insert Flags", "mongo.insert.flags",
816 FT_NONE
, BASE_NONE
, NULL
, 0x0,
817 "Bit vector of insert options.", HFILL
}
819 { &hf_mongo_insert_flags_continueonerror
,
820 { "ContinueOnError", "mongo.insert.flags.continueonerror",
821 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
822 "If set, the database will not stop processing a bulk insert if one fails"
823 " (eg due to duplicate IDs)", HFILL
}
825 { &hf_mongo_query_flags_tailablecursor
,
826 { "Tailable Cursor", "mongo.query.flags.tailable_cursor",
827 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000002,
828 "Tailable means cursor is not closed when the last data is retrieved", HFILL
}
830 { &hf_mongo_query_flags_slaveok
,
831 { "Slave OK", "mongo.query.flags.slave_ok",
832 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000004,
833 "Allow query of replica slave", HFILL
}
835 { &hf_mongo_query_flags_oplogreplay
,
836 { "Op Log Reply", "mongo.query.flags.op_log_reply",
837 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000008,
838 "Internal replication use only", HFILL
}
840 { &hf_mongo_query_flags_nocursortimeout
,
841 { "No Cursor Timeout", "mongo.query.flags.no_cursor_timeout",
842 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000010,
843 "The server normally times out idle cursors after an inactivity period (10 minutes)"
844 " to prevent excess memory use. Set this option to prevent that", HFILL
}
846 { &hf_mongo_query_flags_awaitdata
,
847 { "AwaitData", "mongo.query.flags.awaitdata",
848 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000020,
849 "If we are at the end of the data, block for a while rather than returning no data."
850 " After a timeout period, we do return as normal", HFILL
}
852 { &hf_mongo_query_flags_exhaust
,
853 { "Exhaust", "mongo.query.flags.exhaust",
854 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000040,
855 "Stream the data down full blast in multiple more packages, on the assumption"
856 " that the client will fully read all data queried", HFILL
}
858 { &hf_mongo_query_flags_partial
,
859 { "Partial", "mongo.query.flags.partial",
860 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000080,
861 "Get partial results from a mongos if some shards are down (instead of throwing an error)", HFILL
}
863 { &hf_mongo_number_to_skip
,
864 { "Number To Skip", "mongo.number_to_skip",
865 FT_INT32
, BASE_DEC
, NULL
, 0x0,
866 "Number of documents in the skip", HFILL
}
868 { &hf_mongo_number_to_return
,
869 { "Number to Return", "mongo.number_to_return",
870 FT_INT32
, BASE_DEC
, NULL
, 0x0,
871 "Number of documents in the return", HFILL
}
874 { "Query", "mongo.query",
875 FT_NONE
, BASE_NONE
, NULL
, 0x0,
876 "Query BSON Document", HFILL
}
878 { &hf_mongo_return_field_selector
,
879 { "Return Field Selector", "mongo.return_field_selector",
880 FT_NONE
, BASE_NONE
, NULL
, 0x0,
881 "Return Field Selector BSON Document", HFILL
}
883 { &hf_mongo_delete_flags
,
884 { "Delete Flags", "mongo.delete.flags",
885 FT_NONE
, BASE_NONE
, NULL
, 0x0,
886 "Bit vector of delete options.", HFILL
}
888 { &hf_mongo_delete_flags_singleremove
,
889 { "Single Remove", "mongo.delete.flags.singleremove",
890 FT_BOOLEAN
, 32, TFS(&tfs_yes_no
), 0x00000001,
891 "If set, the database will remove only the first matching document in the"
892 " collection. Otherwise all matching documents will be removed", HFILL
}
894 { &hf_mongo_number_of_cursor_ids
,
895 { "Number of Cursor IDS", "mongo.number_to_cursor_ids",
896 FT_INT32
, BASE_DEC
, NULL
, 0x0,
897 "Number of cursorIDs in message", HFILL
}
899 { &hf_mongo_elements
,
900 { "Elements", "mongo.elements",
901 FT_NONE
, BASE_NONE
, NULL
, 0x0,
902 "Document Elements", HFILL
}
904 { &hf_mongo_element_name
,
905 { "Element", "mongo.element.name",
906 FT_STRING
, BASE_NONE
, NULL
, 0x0,
907 "Element Name", HFILL
}
909 { &hf_mongo_element_type
,
910 { "Type", "mongo.element.type",
911 FT_UINT8
, BASE_HEX_DEC
, VALS(element_type_vals
), 0x0,
912 "Element Type", HFILL
}
914 { &hf_mongo_element_length
,
915 { "Length", "mongo.element.length",
916 FT_INT32
, BASE_DEC
, NULL
, 0x0,
917 "Element Length", HFILL
}
919 { &hf_mongo_element_value_boolean
,
920 { "Value", "mongo.element.value.bool",
921 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
922 "Element Value", HFILL
}
924 { &hf_mongo_element_value_int32
,
925 { "Value", "mongo.element.value.int",
926 FT_INT32
, BASE_DEC
, NULL
, 0x0,
927 "Element Value", HFILL
}
929 { &hf_mongo_element_value_int64
,
930 { "Value", "mongo.element.value.int64",
931 FT_INT64
, BASE_DEC
, NULL
, 0x0,
932 "Element Value", HFILL
}
934 { &hf_mongo_element_value_double
,
935 { "Value", "mongo.element.value.double",
936 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
937 "Element Value", HFILL
}
939 { &hf_mongo_element_value_string
,
940 { "Value", "mongo.element.value.string",
941 FT_STRING
, BASE_NONE
, NULL
, 0x0,
942 "Element Value", HFILL
}
944 { &hf_mongo_element_value_string_length
,
945 { "Length", "mongo.element.value.length",
946 FT_INT32
, BASE_DEC
, NULL
, 0x0,
947 "Element Value Length", HFILL
}
949 { &hf_mongo_element_value_binary
,
950 { "Value", "mongo.element.value.bytes",
951 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
952 "Element Value", HFILL
}
954 { &hf_mongo_element_value_binary_length
,
955 { "Length", "mongo.element.value.length",
956 FT_INT32
, BASE_DEC
, NULL
, 0x0,
957 "Binary Element Length", HFILL
}
959 { &hf_mongo_element_value_regex_pattern
,
960 { "Value", "mongo.element.value.regex.pattern",
961 FT_STRING
, BASE_NONE
, NULL
, 0x0,
962 "Regex Pattern", HFILL
}
964 { &hf_mongo_element_value_regex_options
,
965 { "Value", "mongo.element.value.regex.options",
966 FT_STRING
, BASE_NONE
, NULL
, 0x0,
967 "Regex Options", HFILL
}
969 { &hf_mongo_element_value_objectid
,
970 { "ObjectID", "mongo.element.value.objectid",
971 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
972 "ObjectID Value", HFILL
}
974 { &hf_mongo_element_value_objectid_time
,
975 { "ObjectID Time", "mongo.element.value.objectid.time",
976 FT_INT32
, BASE_DEC
, NULL
, 0x0,
977 "ObjectID timestampt", HFILL
}
979 { &hf_mongo_element_value_objectid_machine
,
980 { "ObjectID Machine", "mongo.element.value.objectid.machine",
981 FT_UINT24
, BASE_HEX
, NULL
, 0x0,
982 "ObjectID machine ID", HFILL
}
984 { &hf_mongo_element_value_objectid_pid
,
985 { "ObjectID PID", "mongo.element.value.objectid.pid",
986 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
987 "ObjectID process ID", HFILL
}
989 { &hf_mongo_element_value_objectid_inc
,
990 { "ObjectID inc", "mongo.element.value.objectid.inc",
991 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
992 "ObjectID increment", HFILL
}
994 { &hf_mongo_element_value_db_ptr
,
995 { "ObjectID", "mongo.element.value.db_ptr",
996 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
999 { &hf_mongo_element_value_js_code
,
1000 { "JavaScript code", "mongo.element.value.js_code",
1001 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1002 "JavaScript code to be evaluated", HFILL
}
1004 { &hf_mongo_element_value_js_scope
,
1005 { "JavaScript scope", "mongo.element.value.js_scope",
1006 FT_NONE
, BASE_NONE
, NULL
, 0x0,
1007 "Scope document for JavaScript evaluation", HFILL
}
1009 { &hf_mongo_unknown
,
1010 { "Unknown", "mongo.unknown",
1011 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1012 "Unknown Data type", HFILL
}
1016 static gint
*ett
[] = {
1019 &ett_mongo_elements
,
1021 &ett_mongo_objectid
,
1027 static ei_register_info ei
[] = {
1028 { &ei_mongo_document_recursion_exceeded
, { "mongo.document.recursion_exceeded", PI_MALFORMED
, PI_ERROR
, "BSON document recursion exceeds", EXPFILL
}},
1029 { &ei_mongo_document_length_bad
, { "mongo.document.length.bad", PI_MALFORMED
, PI_ERROR
, "BSON document length bad", EXPFILL
}},
1030 { &ei_mongo_unknown
, { "mongo.unknown.expert", PI_UNDECODED
, PI_WARN
, "Unknown Data (not interpreted)", EXPFILL
}},
1033 proto_mongo
= proto_register_protocol("Mongo Wire Protocol", "MONGO", "mongo");
1035 proto_register_field_array(proto_mongo
, hf
, array_length(hf
));
1036 proto_register_subtree_array(ett
, array_length(ett
));
1037 expert_mongo
= expert_register_protocol(proto_mongo
);
1038 expert_register_field_array(expert_mongo
, ei
, array_length(ei
));
1040 mongo_module
= prefs_register_protocol(proto_mongo
,
1041 proto_reg_handoff_mongo
);
1043 prefs_register_uint_preference(mongo_module
, "tcp.port", "MONGO TCP Port",
1044 "MONGO TCP port if other than the default",
1045 10, &global_mongo_tcp_port
);
1050 proto_reg_handoff_mongo(void)
1052 static gboolean initialized
= FALSE
;
1053 static dissector_handle_t mongo_handle
;
1054 static int currentPort
;
1058 mongo_handle
= new_create_dissector_handle(dissect_mongo
, proto_mongo
);
1061 dissector_delete_uint("tcp.port", currentPort
, mongo_handle
);
1064 currentPort
= global_mongo_tcp_port
;
1066 dissector_add_uint("tcp.port", currentPort
, mongo_handle
);
1075 * indent-tabs-mode: nil
1078 * ex: set shiftwidth=2 tabstop=8 expandtab:
1079 * :indentSize=2:tabSize=8:noTabs=true: