/src/wireshark/epan/dissectors/packet-idmp.c
Line | Count | Source |
1 | | /* Do not modify this file. Changes will be overwritten. */ |
2 | | /* Generated automatically by the ASN.1 to Wireshark dissector compiler */ |
3 | | /* packet-idmp.c */ |
4 | | /* asn2wrs.py -b -q -L -p idmp -c ./idmp.cnf -s ./packet-idmp-template -D . -O ../.. IDMProtocolSpecification.asn CommonProtocolSpecification.asn */ |
5 | | |
6 | | /* packet-idmp.c |
7 | | * Routines for X.519 Internet Directly Mapped Protocol (IDMP) packet dissection |
8 | | * Graeme Lunt 2010 |
9 | | * |
10 | | * Wireshark - Network traffic analyzer |
11 | | * By Gerald Combs <gerald@wireshark.org> |
12 | | * Copyright 1998 Gerald Combs |
13 | | * |
14 | | * SPDX-License-Identifier: GPL-2.0-or-later |
15 | | */ |
16 | | |
17 | | #include "config.h" |
18 | | |
19 | | #include <epan/packet.h> |
20 | | #include <epan/prefs.h> |
21 | | #include <epan/reassemble.h> |
22 | | #include <epan/conversation.h> |
23 | | #include <epan/oids.h> |
24 | | #include <epan/asn1.h> |
25 | | #include <epan/strutil.h> |
26 | | |
27 | | #include <wsutil/str_util.h> |
28 | | #include <wsutil/array.h> |
29 | | |
30 | | #include "packet-tcp.h" |
31 | | #include "packet-iana-data.h" |
32 | | |
33 | | #include "packet-ber.h" |
34 | | #include "packet-ros.h" |
35 | | #include "packet-x509ce.h" |
36 | | |
37 | | |
38 | 14 | #define PNAME "X.519 Internet Directly Mapped Protocol" |
39 | 14 | #define PSNAME "IDMP" |
40 | 14 | #define PFNAME "idmp" |
41 | | |
42 | | void proto_register_idmp(void); |
43 | | void proto_reg_handoff_idm(void); |
44 | | void register_idmp_protocol_info(const char *oid, const ros_info_t *rinfo, int proto _U_, const char *name); |
45 | | |
46 | | static bool idmp_desegment = true; |
47 | 14 | #define IDMP_TCP_PORT 1102 /* made up for now - not IANA registered */ |
48 | | static bool idmp_reassemble = true; |
49 | | static dissector_handle_t idmp_handle; |
50 | | |
51 | | static proto_tree *top_tree; |
52 | | static const char *protocolID; |
53 | | static const char *saved_protocolID; |
54 | | static uint32_t opcode = -1; |
55 | | |
56 | | /* Initialize the protocol and registered fields */ |
57 | | int proto_idmp; |
58 | | |
59 | | static int hf_idmp_version; |
60 | | static int hf_idmp_final; |
61 | | static int hf_idmp_length; |
62 | | static int hf_idmp_PDU; |
63 | | |
64 | | static reassembly_table idmp_reassembly_table; |
65 | | |
66 | | static int hf_idmp_fragments; |
67 | | static int hf_idmp_fragment; |
68 | | static int hf_idmp_fragment_overlap; |
69 | | static int hf_idmp_fragment_overlap_conflicts; |
70 | | static int hf_idmp_fragment_multiple_tails; |
71 | | static int hf_idmp_fragment_too_long_fragment; |
72 | | static int hf_idmp_fragment_error; |
73 | | static int hf_idmp_fragment_count; |
74 | | static int hf_idmp_reassembled_in; |
75 | | static int hf_idmp_reassembled_length; |
76 | | static int hf_idmp_segment_data; |
77 | | |
78 | | static int ett_idmp_fragment; |
79 | | static int ett_idmp_fragments; |
80 | | |
81 | | static const fragment_items idmp_frag_items = { |
82 | | /* Fragment subtrees */ |
83 | | &ett_idmp_fragment, |
84 | | &ett_idmp_fragments, |
85 | | /* Fragment fields */ |
86 | | &hf_idmp_fragments, |
87 | | &hf_idmp_fragment, |
88 | | &hf_idmp_fragment_overlap, |
89 | | &hf_idmp_fragment_overlap_conflicts, |
90 | | &hf_idmp_fragment_multiple_tails, |
91 | | &hf_idmp_fragment_too_long_fragment, |
92 | | &hf_idmp_fragment_error, |
93 | | &hf_idmp_fragment_count, |
94 | | /* Reassembled in field */ |
95 | | &hf_idmp_reassembled_in, |
96 | | /* Reassembled length field */ |
97 | | &hf_idmp_reassembled_length, |
98 | | /* Reassembled data field */ |
99 | | NULL, |
100 | | /* Tag */ |
101 | | "IDMP fragments" |
102 | | }; |
103 | | |
104 | | |
105 | | static int call_idmp_oid_callback(tvbuff_t *tvb, int offset, packet_info *pinfo, int op, proto_tree *tree, struct SESSION_DATA_STRUCTURE *session) |
106 | 143 | { |
107 | 143 | if(session != NULL) { |
108 | | |
109 | | /* XXX saved_protocolID should be part of session data */ |
110 | 143 | if (!saved_protocolID) { |
111 | 3 | saved_protocolID = "[ unknown ]"; |
112 | 3 | } |
113 | | |
114 | | /* mimic ROS! */ |
115 | 143 | session->ros_op = op; |
116 | 143 | offset = call_ros_oid_callback(saved_protocolID, tvb, offset, pinfo, tree, session); |
117 | 143 | } |
118 | | |
119 | 143 | return offset; |
120 | | |
121 | 143 | } |
122 | | |
123 | | static int hf_idmp_bind; /* IdmBind */ |
124 | | static int hf_idmp_bindResult; /* IdmBindResult */ |
125 | | static int hf_idmp_bindError; /* IdmBindError */ |
126 | | static int hf_idmp_request; /* Request */ |
127 | | static int hf_idmp_idm_result; /* IdmResult */ |
128 | | static int hf_idmp_idm_error; /* Error */ |
129 | | static int hf_idmp_reject; /* IdmReject */ |
130 | | static int hf_idmp_unbind; /* Unbind */ |
131 | | static int hf_idmp_abort; /* Abort */ |
132 | | static int hf_idmp_startTLS; /* StartTLS */ |
133 | | static int hf_idmp_tLSResponse; /* TLSResponse */ |
134 | | static int hf_idmp_protocolID; /* OBJECT_IDENTIFIER */ |
135 | | static int hf_idmp_callingAETitle; /* GeneralName */ |
136 | | static int hf_idmp_calledAETitle; /* GeneralName */ |
137 | | static int hf_idmp_bind_argument; /* Bind_argument */ |
138 | | static int hf_idmp_respondingAETitle; /* GeneralName */ |
139 | | static int hf_idmp_bind_result; /* Bind_result */ |
140 | | static int hf_idmp_aETitleError; /* T_aETitleError */ |
141 | | static int hf_idmp_bind_error; /* Bind_error */ |
142 | | static int hf_idmp_invokeID; /* INTEGER */ |
143 | | static int hf_idmp_opcode; /* Code */ |
144 | | static int hf_idmp_argument; /* T_argument */ |
145 | | static int hf_idmp_idm_invokeID; /* INTEGER */ |
146 | | static int hf_idmp_result; /* T_result */ |
147 | | static int hf_idmp_errcode; /* T_errcode */ |
148 | | static int hf_idmp_error; /* T_error */ |
149 | | static int hf_idmp_reason; /* T_reason */ |
150 | | static int hf_idmp_local; /* T_local */ |
151 | | static int hf_idmp_global; /* OBJECT_IDENTIFIER */ |
152 | | |
153 | | /* Initialize the subtree pointers */ |
154 | | static int ett_idmp; |
155 | | static int ett_idmp_IDM_PDU; |
156 | | static int ett_idmp_IdmBind; |
157 | | static int ett_idmp_IdmBindResult; |
158 | | static int ett_idmp_IdmBindError; |
159 | | static int ett_idmp_Request; |
160 | | static int ett_idmp_IdmResult; |
161 | | static int ett_idmp_Error; |
162 | | static int ett_idmp_IdmReject; |
163 | | static int ett_idmp_Code; |
164 | | |
165 | | |
166 | | |
167 | | static unsigned |
168 | 2 | dissect_idmp_OBJECT_IDENTIFIER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
169 | 2 | offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &protocolID); |
170 | | |
171 | 2 | return offset; |
172 | 2 | } |
173 | | |
174 | | |
175 | | |
176 | | static unsigned |
177 | 0 | dissect_idmp_Bind_argument(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
178 | 0 | struct SESSION_DATA_STRUCTURE *session = (struct SESSION_DATA_STRUCTURE*)actx->private_data; |
179 | 0 | offset = call_idmp_oid_callback(tvb, offset, actx->pinfo, (ROS_OP_BIND | ROS_OP_ARGUMENT), top_tree, session); |
180 | | |
181 | |
|
182 | 0 | return offset; |
183 | 0 | } |
184 | | |
185 | | |
186 | | static const ber_sequence_t IdmBind_sequence[] = { |
187 | | { &hf_idmp_protocolID , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_idmp_OBJECT_IDENTIFIER }, |
188 | | { &hf_idmp_callingAETitle , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL, dissect_x509ce_GeneralName }, |
189 | | { &hf_idmp_calledAETitle , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_x509ce_GeneralName }, |
190 | | { &hf_idmp_bind_argument , BER_CLASS_CON, 2, 0, dissect_idmp_Bind_argument }, |
191 | | { NULL, 0, 0, 0, NULL } |
192 | | }; |
193 | | |
194 | | static unsigned |
195 | 3 | dissect_idmp_IdmBind(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
196 | 3 | protocolID = saved_protocolID = NULL; |
197 | 3 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
198 | 3 | IdmBind_sequence, hf_index, ett_idmp_IdmBind); |
199 | | |
200 | 3 | if (protocolID) { |
201 | 0 | saved_protocolID = wmem_strdup(wmem_epan_scope(), protocolID); |
202 | 0 | } |
203 | 3 | return offset; |
204 | 3 | } |
205 | | |
206 | | |
207 | | |
208 | | static unsigned |
209 | 0 | dissect_idmp_Bind_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
210 | 0 | struct SESSION_DATA_STRUCTURE *session = (struct SESSION_DATA_STRUCTURE*)actx->private_data; |
211 | 0 | offset = call_idmp_oid_callback(tvb, offset, actx->pinfo, (ROS_OP_BIND | ROS_OP_RESULT), top_tree, session); |
212 | | |
213 | |
|
214 | 0 | return offset; |
215 | 0 | } |
216 | | |
217 | | |
218 | | static const ber_sequence_t IdmBindResult_sequence[] = { |
219 | | { &hf_idmp_protocolID , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_idmp_OBJECT_IDENTIFIER }, |
220 | | { &hf_idmp_respondingAETitle, BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL, dissect_x509ce_GeneralName }, |
221 | | { &hf_idmp_bind_result , BER_CLASS_CON, 1, 0, dissect_idmp_Bind_result }, |
222 | | { NULL, 0, 0, 0, NULL } |
223 | | }; |
224 | | |
225 | | static unsigned |
226 | 1 | dissect_idmp_IdmBindResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
227 | 1 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
228 | 1 | IdmBindResult_sequence, hf_index, ett_idmp_IdmBindResult); |
229 | | |
230 | 1 | return offset; |
231 | 1 | } |
232 | | |
233 | | |
234 | | static const value_string idmp_T_aETitleError_vals[] = { |
235 | | { 0, "callingAETitleNotAccepted" }, |
236 | | { 1, "calledAETitleNotRecognized" }, |
237 | | { 0, NULL } |
238 | | }; |
239 | | |
240 | | |
241 | | static unsigned |
242 | 0 | dissect_idmp_T_aETitleError(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
243 | 0 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
244 | 0 | NULL); |
245 | |
|
246 | 0 | return offset; |
247 | 0 | } |
248 | | |
249 | | |
250 | | |
251 | | static unsigned |
252 | 0 | dissect_idmp_Bind_error(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
253 | 0 | struct SESSION_DATA_STRUCTURE *session = (struct SESSION_DATA_STRUCTURE*)actx->private_data; |
254 | 0 | offset = call_idmp_oid_callback(tvb, offset, actx->pinfo, (ROS_OP_BIND| ROS_OP_ERROR), top_tree, session); |
255 | | |
256 | |
|
257 | 0 | return offset; |
258 | 0 | } |
259 | | |
260 | | |
261 | | static const ber_sequence_t IdmBindError_sequence[] = { |
262 | | { &hf_idmp_protocolID , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_idmp_OBJECT_IDENTIFIER }, |
263 | | { &hf_idmp_respondingAETitle, BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL, dissect_x509ce_GeneralName }, |
264 | | { &hf_idmp_aETitleError , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_idmp_T_aETitleError }, |
265 | | { &hf_idmp_bind_error , BER_CLASS_CON, 1, 0, dissect_idmp_Bind_error }, |
266 | | { NULL, 0, 0, 0, NULL } |
267 | | }; |
268 | | |
269 | | static unsigned |
270 | 1 | dissect_idmp_IdmBindError(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
271 | 1 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
272 | 1 | IdmBindError_sequence, hf_index, ett_idmp_IdmBindError); |
273 | | |
274 | 1 | return offset; |
275 | 1 | } |
276 | | |
277 | | |
278 | | |
279 | | static unsigned |
280 | 1 | dissect_idmp_INTEGER(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
281 | 1 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
282 | 1 | NULL); |
283 | | |
284 | 1 | return offset; |
285 | 1 | } |
286 | | |
287 | | |
288 | | |
289 | | static unsigned |
290 | 1 | dissect_idmp_T_local(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
291 | 1 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
292 | 1 | &opcode); |
293 | | |
294 | 1 | return offset; |
295 | 1 | } |
296 | | |
297 | | |
298 | | static const value_string idmp_Code_vals[] = { |
299 | | { 0, "local" }, |
300 | | { 1, "global" }, |
301 | | { 0, NULL } |
302 | | }; |
303 | | |
304 | | static const ber_choice_t Code_choice[] = { |
305 | | { 0, &hf_idmp_local , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_idmp_T_local }, |
306 | | { 1, &hf_idmp_global , BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_idmp_OBJECT_IDENTIFIER }, |
307 | | { 0, NULL, 0, 0, 0, NULL } |
308 | | }; |
309 | | |
310 | | static unsigned |
311 | 144 | dissect_idmp_Code(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
312 | 144 | offset = dissect_ber_choice(actx, tree, tvb, offset, |
313 | 144 | Code_choice, hf_index, ett_idmp_Code, |
314 | 144 | NULL); |
315 | | |
316 | 144 | return offset; |
317 | 144 | } |
318 | | |
319 | | |
320 | | |
321 | | static unsigned |
322 | 2 | dissect_idmp_T_argument(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
323 | 2 | struct SESSION_DATA_STRUCTURE *session = (struct SESSION_DATA_STRUCTURE*)actx->private_data; |
324 | 2 | offset = call_idmp_oid_callback(tvb, offset, actx->pinfo, (ROS_OP_INVOKE | ROS_OP_ARGUMENT | opcode), top_tree, session); |
325 | | |
326 | | |
327 | 2 | return offset; |
328 | 2 | } |
329 | | |
330 | | |
331 | | static const ber_sequence_t Request_sequence[] = { |
332 | | { &hf_idmp_invokeID , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_idmp_INTEGER }, |
333 | | { &hf_idmp_opcode , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_idmp_Code }, |
334 | | { &hf_idmp_argument , BER_CLASS_ANY, 0, BER_FLAGS_NOOWNTAG, dissect_idmp_T_argument }, |
335 | | { NULL, 0, 0, 0, NULL } |
336 | | }; |
337 | | |
338 | | static unsigned |
339 | 2 | dissect_idmp_Request(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
340 | 2 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
341 | 2 | Request_sequence, hf_index, ett_idmp_Request); |
342 | | |
343 | 2 | return offset; |
344 | 2 | } |
345 | | |
346 | | |
347 | | |
348 | | static unsigned |
349 | 141 | dissect_idmp_T_result(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
350 | 141 | struct SESSION_DATA_STRUCTURE *session = (struct SESSION_DATA_STRUCTURE*)actx->private_data; |
351 | 141 | offset = call_idmp_oid_callback(tvb, offset, actx->pinfo, (ROS_OP_INVOKE | ROS_OP_RESULT | opcode), top_tree, session); |
352 | | |
353 | | |
354 | 141 | return offset; |
355 | 141 | } |
356 | | |
357 | | |
358 | | static const ber_sequence_t IdmResult_sequence[] = { |
359 | | { &hf_idmp_idm_invokeID , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_idmp_INTEGER }, |
360 | | { &hf_idmp_opcode , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_idmp_Code }, |
361 | | { &hf_idmp_result , BER_CLASS_ANY, 0, BER_FLAGS_NOOWNTAG, dissect_idmp_T_result }, |
362 | | { NULL, 0, 0, 0, NULL } |
363 | | }; |
364 | | |
365 | | static unsigned |
366 | 147 | dissect_idmp_IdmResult(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
367 | 147 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
368 | 147 | IdmResult_sequence, hf_index, ett_idmp_IdmResult); |
369 | | |
370 | 147 | return offset; |
371 | 147 | } |
372 | | |
373 | | |
374 | | |
375 | | static unsigned |
376 | 1 | dissect_idmp_T_errcode(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
377 | | |
378 | | |
379 | 1 | return offset; |
380 | 1 | } |
381 | | |
382 | | |
383 | | |
384 | | static unsigned |
385 | 0 | dissect_idmp_T_error(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
386 | | |
387 | |
|
388 | 0 | return offset; |
389 | 0 | } |
390 | | |
391 | | |
392 | | static const ber_sequence_t Error_sequence[] = { |
393 | | { &hf_idmp_invokeID , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_idmp_INTEGER }, |
394 | | { &hf_idmp_errcode , BER_CLASS_ANY, 0, BER_FLAGS_NOOWNTAG, dissect_idmp_T_errcode }, |
395 | | { &hf_idmp_error , BER_CLASS_ANY, 0, BER_FLAGS_NOOWNTAG, dissect_idmp_T_error }, |
396 | | { NULL, 0, 0, 0, NULL } |
397 | | }; |
398 | | |
399 | | static unsigned |
400 | 1 | dissect_idmp_Error(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
401 | 1 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
402 | 1 | Error_sequence, hf_index, ett_idmp_Error); |
403 | | |
404 | 1 | return offset; |
405 | 1 | } |
406 | | |
407 | | |
408 | | static const value_string idmp_T_reason_vals[] = { |
409 | | { 0, "mistypedPDU" }, |
410 | | { 1, "duplicateInvokeIDRequest" }, |
411 | | { 2, "unsupportedOperationRequest" }, |
412 | | { 3, "unknownOperationRequest" }, |
413 | | { 4, "mistypedArgumentRequest" }, |
414 | | { 5, "resourceLimitationRequest" }, |
415 | | { 6, "unknownInvokeIDResult" }, |
416 | | { 7, "mistypedResultRequest" }, |
417 | | { 8, "unknownInvokeIDError" }, |
418 | | { 9, "unknownError" }, |
419 | | { 10, "mistypedParameterError" }, |
420 | | { 11, "unsupportedIdmVersion" }, |
421 | | { 12, "unsuitableIdmVersion" }, |
422 | | { 13, "invalidIdmVersion" }, |
423 | | { 0, NULL } |
424 | | }; |
425 | | |
426 | | |
427 | | static unsigned |
428 | 0 | dissect_idmp_T_reason(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
429 | 0 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
430 | 0 | NULL); |
431 | |
|
432 | 0 | return offset; |
433 | 0 | } |
434 | | |
435 | | |
436 | | static const ber_sequence_t IdmReject_sequence[] = { |
437 | | { &hf_idmp_invokeID , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_idmp_INTEGER }, |
438 | | { &hf_idmp_reason , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_idmp_T_reason }, |
439 | | { NULL, 0, 0, 0, NULL } |
440 | | }; |
441 | | |
442 | | static unsigned |
443 | 1 | dissect_idmp_IdmReject(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
444 | 1 | offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, |
445 | 1 | IdmReject_sequence, hf_index, ett_idmp_IdmReject); |
446 | | |
447 | 1 | return offset; |
448 | 1 | } |
449 | | |
450 | | |
451 | | |
452 | | static unsigned |
453 | 1 | dissect_idmp_Unbind(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
454 | 1 | offset = dissect_ber_null(implicit_tag, actx, tree, tvb, offset, hf_index); |
455 | | |
456 | 1 | return offset; |
457 | 1 | } |
458 | | |
459 | | |
460 | | static const value_string idmp_Abort_vals[] = { |
461 | | { 0, "mistypedPDU" }, |
462 | | { 1, "unboundRequest" }, |
463 | | { 2, "invalidPDU" }, |
464 | | { 3, "resourceLimitation" }, |
465 | | { 4, "connectionFailed" }, |
466 | | { 5, "invalidProtocol" }, |
467 | | { 6, "reasonNotSpecified" }, |
468 | | { 0, NULL } |
469 | | }; |
470 | | |
471 | | |
472 | | static unsigned |
473 | 2 | dissect_idmp_Abort(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
474 | 2 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
475 | 2 | NULL); |
476 | | |
477 | 2 | return offset; |
478 | 2 | } |
479 | | |
480 | | |
481 | | |
482 | | static unsigned |
483 | 0 | dissect_idmp_StartTLS(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
484 | 0 | offset = dissect_ber_null(implicit_tag, actx, tree, tvb, offset, hf_index); |
485 | |
|
486 | 0 | return offset; |
487 | 0 | } |
488 | | |
489 | | |
490 | | static const value_string idmp_TLSResponse_vals[] = { |
491 | | { 0, "success" }, |
492 | | { 1, "operationsError" }, |
493 | | { 2, "protocolError" }, |
494 | | { 3, "unavailable" }, |
495 | | { 0, NULL } |
496 | | }; |
497 | | |
498 | | |
499 | | static unsigned |
500 | 1 | dissect_idmp_TLSResponse(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
501 | 1 | offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index, |
502 | 1 | NULL); |
503 | | |
504 | 1 | return offset; |
505 | 1 | } |
506 | | |
507 | | |
508 | | static const value_string idmp_IDM_PDU_vals[] = { |
509 | | { 0, "bind" }, |
510 | | { 1, "bindResult" }, |
511 | | { 2, "bindError" }, |
512 | | { 3, "request" }, |
513 | | { 4, "result" }, |
514 | | { 5, "error" }, |
515 | | { 6, "reject" }, |
516 | | { 7, "unbind" }, |
517 | | { 8, "abort" }, |
518 | | { 9, "startTLS" }, |
519 | | { 10, "tLSResponse" }, |
520 | | { 0, NULL } |
521 | | }; |
522 | | |
523 | | static const ber_choice_t IDM_PDU_choice[] = { |
524 | | { 0, &hf_idmp_bind , BER_CLASS_CON, 0, 0, dissect_idmp_IdmBind }, |
525 | | { 1, &hf_idmp_bindResult , BER_CLASS_CON, 1, 0, dissect_idmp_IdmBindResult }, |
526 | | { 2, &hf_idmp_bindError , BER_CLASS_CON, 2, 0, dissect_idmp_IdmBindError }, |
527 | | { 3, &hf_idmp_request , BER_CLASS_CON, 3, 0, dissect_idmp_Request }, |
528 | | { 4, &hf_idmp_idm_result , BER_CLASS_CON, 4, 0, dissect_idmp_IdmResult }, |
529 | | { 5, &hf_idmp_idm_error , BER_CLASS_CON, 5, 0, dissect_idmp_Error }, |
530 | | { 6, &hf_idmp_reject , BER_CLASS_CON, 6, 0, dissect_idmp_IdmReject }, |
531 | | { 7, &hf_idmp_unbind , BER_CLASS_CON, 7, 0, dissect_idmp_Unbind }, |
532 | | { 8, &hf_idmp_abort , BER_CLASS_CON, 8, 0, dissect_idmp_Abort }, |
533 | | { 9, &hf_idmp_startTLS , BER_CLASS_CON, 9, 0, dissect_idmp_StartTLS }, |
534 | | { 10, &hf_idmp_tLSResponse , BER_CLASS_CON, 10, 0, dissect_idmp_TLSResponse }, |
535 | | { 0, NULL, 0, 0, 0, NULL } |
536 | | }; |
537 | | |
538 | | static unsigned |
539 | 198 | dissect_idmp_IDM_PDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, unsigned offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
540 | 198 | offset = dissect_ber_choice(actx, tree, tvb, offset, |
541 | 198 | IDM_PDU_choice, hf_index, ett_idmp_IDM_PDU, |
542 | 198 | NULL); |
543 | | |
544 | 198 | return offset; |
545 | 198 | } |
546 | | |
547 | | |
548 | | void |
549 | | register_idmp_protocol_info(const char *oid, const ros_info_t *rinfo, int proto _U_, const char *name) |
550 | 14 | { |
551 | | /* just register with ROS for now */ |
552 | 14 | register_ros_protocol_info(oid, rinfo, proto, name, false); |
553 | 14 | } |
554 | | |
555 | | |
556 | | static int dissect_idmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_) |
557 | 448 | { |
558 | 448 | int offset = 0; |
559 | | |
560 | 448 | proto_item *item; |
561 | 448 | proto_tree *tree; |
562 | 448 | asn1_ctx_t asn1_ctx; |
563 | 448 | struct SESSION_DATA_STRUCTURE session; |
564 | 448 | bool idmp_final; |
565 | 448 | uint32_t idmp_length; |
566 | 448 | fragment_head *fd_head; |
567 | 448 | conversation_t *conv; |
568 | 448 | uint32_t dst_ref = 0; |
569 | | |
570 | 448 | asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo); |
571 | | |
572 | 448 | conv = find_conversation_pinfo(pinfo, 0); |
573 | 448 | if (conv) { |
574 | | /* Found a conversation, also use index for the generated dst_ref */ |
575 | 448 | dst_ref = conv->conv_index; |
576 | 448 | } |
577 | | |
578 | | /* save parent_tree so subdissectors can create new top nodes */ |
579 | 448 | top_tree=parent_tree; |
580 | | |
581 | 448 | item = proto_tree_add_item(parent_tree, proto_idmp, tvb, 0, -1, ENC_NA); |
582 | 448 | tree = proto_item_add_subtree(item, ett_idmp); |
583 | | |
584 | 448 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "IDMP"); |
585 | | |
586 | | /* now check the segment fields */ |
587 | | |
588 | 448 | proto_tree_add_item(tree, hf_idmp_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; |
589 | 448 | proto_tree_add_item(tree, hf_idmp_final, tvb, offset, 1, ENC_BIG_ENDIAN); |
590 | 448 | idmp_final = tvb_get_uint8(tvb, offset); offset++; |
591 | 448 | proto_tree_add_item(tree, hf_idmp_length, tvb, offset, 4, ENC_BIG_ENDIAN); |
592 | 448 | idmp_length = tvb_get_ntohl(tvb, offset); offset += 4; |
593 | | |
594 | 448 | asn1_ctx.private_data = &session; |
595 | | |
596 | 448 | if(idmp_reassemble) { |
597 | | |
598 | 405 | pinfo->fragmented = !idmp_final; |
599 | | |
600 | 405 | col_append_fstr(pinfo->cinfo, COL_INFO, " [%sIDMP fragment, %u byte%s]", |
601 | 405 | idmp_final ? "Final " : "" , |
602 | 405 | idmp_length, plurality(idmp_length, "", "s")); |
603 | | |
604 | 405 | fd_head = fragment_add_seq_next(&idmp_reassembly_table, tvb, offset, |
605 | 405 | pinfo, dst_ref, NULL, |
606 | 405 | idmp_length, !idmp_final); |
607 | | |
608 | 405 | if(fd_head && fd_head->next) { |
609 | 23 | proto_tree_add_item(tree, hf_idmp_segment_data, tvb, offset, (idmp_length) ? -1 : 0, ENC_NA); |
610 | | |
611 | 23 | if (idmp_final) { |
612 | | /* This is the last segment */ |
613 | 18 | tvb = process_reassembled_data (tvb, offset, pinfo, |
614 | 18 | "Reassembled IDMP", fd_head, &idmp_frag_items, NULL, tree); |
615 | 18 | offset = 0; |
616 | 18 | } else if (pinfo->num != fd_head->reassembled_in) { |
617 | | /* Add a "Reassembled in" link if not reassembled in this frame */ |
618 | 0 | proto_tree_add_uint (tree, hf_idmp_reassembled_in, |
619 | 0 | tvb, 0, 0, fd_head->reassembled_in); |
620 | 0 | } |
621 | 23 | } |
622 | | |
623 | 405 | } else { |
624 | 43 | if(!idmp_final) { |
625 | |
|
626 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " [IDMP fragment, %u byte%s, IDMP reassembly not enabled]", |
627 | 0 | idmp_length, plurality(idmp_length, "", "s")); |
628 | |
|
629 | 0 | proto_tree_add_bytes_format_value(tree, hf_idmp_segment_data, tvb, offset, (idmp_length) ? -1 : 0, |
630 | 0 | NULL, "(IDMP reassembly not enabled)"); |
631 | 0 | } |
632 | 43 | } |
633 | | /* not reassembling - just dissect */ |
634 | 448 | if(idmp_final) { |
635 | 198 | asn1_ctx.private_data = &session; |
636 | 198 | dissect_idmp_IDM_PDU(false, tvb, offset, &asn1_ctx, tree, hf_idmp_PDU); |
637 | 198 | } |
638 | | |
639 | 448 | return tvb_captured_length(tvb); |
640 | 448 | } |
641 | | |
642 | | static unsigned get_idmp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, |
643 | | int offset, void *data _U_) |
644 | 450 | { |
645 | 450 | uint32_t len; |
646 | | |
647 | 450 | len = tvb_get_ntohl(tvb, offset + 2); |
648 | | |
649 | 450 | return len + 6; |
650 | 450 | } |
651 | | |
652 | | static int dissect_idmp_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) |
653 | 185 | { |
654 | 185 | tcp_dissect_pdus(tvb, pinfo, parent_tree, idmp_desegment, 0, get_idmp_pdu_len, dissect_idmp, data); |
655 | 185 | return tvb_captured_length(tvb); |
656 | 185 | } |
657 | | |
658 | | static void idmp_reassemble_cleanup(void) |
659 | 0 | { |
660 | 0 | protocolID = NULL; // packet scoped |
661 | 0 | saved_protocolID = NULL; // epan scoped copy of protocolID |
662 | 0 | opcode = -1; |
663 | 0 | } |
664 | | |
665 | | /*--- proto_register_idmp -------------------------------------------*/ |
666 | | void proto_register_idmp(void) |
667 | 14 | { |
668 | | /* List of fields */ |
669 | 14 | static hf_register_info hf[] = { |
670 | 14 | { &hf_idmp_version, |
671 | 14 | { "version", "idmp.version", |
672 | 14 | FT_INT8, BASE_DEC, NULL, 0, |
673 | 14 | "idmp.INTEGER", HFILL }}, |
674 | 14 | { &hf_idmp_final, |
675 | 14 | { "final", "idmp.final", |
676 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
677 | 14 | "idmp.BOOLEAN", HFILL }}, |
678 | 14 | { &hf_idmp_length, |
679 | 14 | { "length", "idmp.length", |
680 | 14 | FT_INT32, BASE_DEC, NULL, 0, |
681 | 14 | "idmp.INTEGER", HFILL }}, |
682 | 14 | { &hf_idmp_PDU, |
683 | 14 | { "IDM-PDU", "idmp.pdu", |
684 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_IDM_PDU_vals), 0, |
685 | 14 | "idmp.PDU", HFILL }}, |
686 | | /* Fragment entries */ |
687 | 14 | { &hf_idmp_fragments, |
688 | 14 | { "IDMP fragments", "idmp.fragments", FT_NONE, BASE_NONE, |
689 | 14 | NULL, 0x00, NULL, HFILL } }, |
690 | 14 | { &hf_idmp_fragment, |
691 | 14 | { "IDMP fragment", "idmp.fragment", FT_FRAMENUM, BASE_NONE, |
692 | 14 | NULL, 0x00, NULL, HFILL } }, |
693 | 14 | { &hf_idmp_fragment_overlap, |
694 | 14 | { "IDMP fragment overlap", "idmp.fragment.overlap", FT_BOOLEAN, |
695 | 14 | BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
696 | 14 | { &hf_idmp_fragment_overlap_conflicts, |
697 | 14 | { "IDMP fragment overlapping with conflicting data", |
698 | 14 | "idmp.fragment.overlap.conflicts", FT_BOOLEAN, BASE_NONE, |
699 | 14 | NULL, 0x00, NULL, HFILL } }, |
700 | 14 | { &hf_idmp_fragment_multiple_tails, |
701 | 14 | { "IDMP has multiple tail fragments", |
702 | 14 | "idmp.fragment.multiple_tails", FT_BOOLEAN, BASE_NONE, |
703 | 14 | NULL, 0x00, NULL, HFILL } }, |
704 | 14 | { &hf_idmp_fragment_too_long_fragment, |
705 | 14 | { "IDMP fragment too long", "idmp.fragment.too_long_fragment", |
706 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
707 | 14 | { &hf_idmp_fragment_error, |
708 | 14 | { "IDMP defragmentation error", "idmp.fragment.error", FT_FRAMENUM, |
709 | 14 | BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
710 | 14 | { &hf_idmp_fragment_count, |
711 | 14 | { "IDMP fragment count", "idmp.fragment.count", FT_UINT32, BASE_DEC, |
712 | 14 | NULL, 0x00, NULL, HFILL } }, |
713 | 14 | { &hf_idmp_reassembled_in, |
714 | 14 | { "Reassembled IDMP in frame", "idmp.reassembled.in", FT_FRAMENUM, BASE_NONE, |
715 | 14 | NULL, 0x00, "This IDMP packet is reassembled in this frame", HFILL } }, |
716 | 14 | { &hf_idmp_reassembled_length, |
717 | 14 | { "Reassembled IDMP length", "idmp.reassembled.length", FT_UINT32, BASE_DEC, |
718 | 14 | NULL, 0x00, "The total length of the reassembled payload", HFILL } }, |
719 | 14 | { &hf_idmp_segment_data, |
720 | 14 | { "IDMP segment data", "idmp.segment_data", FT_BYTES, BASE_NONE, |
721 | 14 | NULL, 0x00, NULL, HFILL } }, |
722 | | |
723 | 14 | { &hf_idmp_bind, |
724 | 14 | { "bind", "idmp.bind_element", |
725 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
726 | 14 | "IdmBind", HFILL }}, |
727 | 14 | { &hf_idmp_bindResult, |
728 | 14 | { "bindResult", "idmp.bindResult_element", |
729 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
730 | 14 | "IdmBindResult", HFILL }}, |
731 | 14 | { &hf_idmp_bindError, |
732 | 14 | { "bindError", "idmp.bindError_element", |
733 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
734 | 14 | "IdmBindError", HFILL }}, |
735 | 14 | { &hf_idmp_request, |
736 | 14 | { "request", "idmp.request_element", |
737 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
738 | 14 | NULL, HFILL }}, |
739 | 14 | { &hf_idmp_idm_result, |
740 | 14 | { "result", "idmp.idm_result_element", |
741 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
742 | 14 | "IdmResult", HFILL }}, |
743 | 14 | { &hf_idmp_idm_error, |
744 | 14 | { "error", "idmp.idm_error_element", |
745 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
746 | 14 | NULL, HFILL }}, |
747 | 14 | { &hf_idmp_reject, |
748 | 14 | { "reject", "idmp.reject_element", |
749 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
750 | 14 | "IdmReject", HFILL }}, |
751 | 14 | { &hf_idmp_unbind, |
752 | 14 | { "unbind", "idmp.unbind_element", |
753 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
754 | 14 | NULL, HFILL }}, |
755 | 14 | { &hf_idmp_abort, |
756 | 14 | { "abort", "idmp.abort", |
757 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_Abort_vals), 0, |
758 | 14 | NULL, HFILL }}, |
759 | 14 | { &hf_idmp_startTLS, |
760 | 14 | { "startTLS", "idmp.startTLS_element", |
761 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
762 | 14 | NULL, HFILL }}, |
763 | 14 | { &hf_idmp_tLSResponse, |
764 | 14 | { "tLSResponse", "idmp.tLSResponse", |
765 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_TLSResponse_vals), 0, |
766 | 14 | NULL, HFILL }}, |
767 | 14 | { &hf_idmp_protocolID, |
768 | 14 | { "protocolID", "idmp.protocolID", |
769 | 14 | FT_OID, BASE_NONE, NULL, 0, |
770 | 14 | "OBJECT_IDENTIFIER", HFILL }}, |
771 | 14 | { &hf_idmp_callingAETitle, |
772 | 14 | { "callingAETitle", "idmp.callingAETitle", |
773 | 14 | FT_UINT32, BASE_DEC, VALS(x509ce_GeneralName_vals), 0, |
774 | 14 | "GeneralName", HFILL }}, |
775 | 14 | { &hf_idmp_calledAETitle, |
776 | 14 | { "calledAETitle", "idmp.calledAETitle", |
777 | 14 | FT_UINT32, BASE_DEC, VALS(x509ce_GeneralName_vals), 0, |
778 | 14 | "GeneralName", HFILL }}, |
779 | 14 | { &hf_idmp_bind_argument, |
780 | 14 | { "argument", "idmp.bind_argument_element", |
781 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
782 | 14 | "Bind_argument", HFILL }}, |
783 | 14 | { &hf_idmp_respondingAETitle, |
784 | 14 | { "respondingAETitle", "idmp.respondingAETitle", |
785 | 14 | FT_UINT32, BASE_DEC, VALS(x509ce_GeneralName_vals), 0, |
786 | 14 | "GeneralName", HFILL }}, |
787 | 14 | { &hf_idmp_bind_result, |
788 | 14 | { "result", "idmp.bind_result_element", |
789 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
790 | 14 | "Bind_result", HFILL }}, |
791 | 14 | { &hf_idmp_aETitleError, |
792 | 14 | { "aETitleError", "idmp.aETitleError", |
793 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_T_aETitleError_vals), 0, |
794 | 14 | NULL, HFILL }}, |
795 | 14 | { &hf_idmp_bind_error, |
796 | 14 | { "error", "idmp.bind_error_element", |
797 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
798 | 14 | "Bind_error", HFILL }}, |
799 | 14 | { &hf_idmp_invokeID, |
800 | 14 | { "invokeID", "idmp.invokeID", |
801 | 14 | FT_INT32, BASE_DEC, NULL, 0, |
802 | 14 | "INTEGER", HFILL }}, |
803 | 14 | { &hf_idmp_opcode, |
804 | 14 | { "opcode", "idmp.opcode", |
805 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_Code_vals), 0, |
806 | 14 | "Code", HFILL }}, |
807 | 14 | { &hf_idmp_argument, |
808 | 14 | { "argument", "idmp.argument_element", |
809 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
810 | 14 | NULL, HFILL }}, |
811 | 14 | { &hf_idmp_idm_invokeID, |
812 | 14 | { "invokeID", "idmp.idmResult.invokeID", |
813 | 14 | FT_INT32, BASE_DEC, NULL, 0, |
814 | 14 | "INTEGER", HFILL }}, |
815 | 14 | { &hf_idmp_result, |
816 | 14 | { "result", "idmp.result_element", |
817 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
818 | 14 | NULL, HFILL }}, |
819 | 14 | { &hf_idmp_errcode, |
820 | 14 | { "errcode", "idmp.errcode_element", |
821 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
822 | 14 | NULL, HFILL }}, |
823 | 14 | { &hf_idmp_error, |
824 | 14 | { "error", "idmp.error_element", |
825 | 14 | FT_NONE, BASE_NONE, NULL, 0, |
826 | 14 | NULL, HFILL }}, |
827 | 14 | { &hf_idmp_reason, |
828 | 14 | { "reason", "idmp.reason", |
829 | 14 | FT_UINT32, BASE_DEC, VALS(idmp_T_reason_vals), 0, |
830 | 14 | NULL, HFILL }}, |
831 | 14 | { &hf_idmp_local, |
832 | 14 | { "local", "idmp.local", |
833 | 14 | FT_INT32, BASE_DEC, NULL, 0, |
834 | 14 | NULL, HFILL }}, |
835 | 14 | { &hf_idmp_global, |
836 | 14 | { "global", "idmp.global", |
837 | 14 | FT_OID, BASE_NONE, NULL, 0, |
838 | 14 | "OBJECT_IDENTIFIER", HFILL }}, |
839 | 14 | }; |
840 | | |
841 | | /* List of subtrees */ |
842 | 14 | static int *ett[] = { |
843 | 14 | &ett_idmp, |
844 | 14 | &ett_idmp_fragment, |
845 | 14 | &ett_idmp_fragments, |
846 | 14 | &ett_idmp_IDM_PDU, |
847 | 14 | &ett_idmp_IdmBind, |
848 | 14 | &ett_idmp_IdmBindResult, |
849 | 14 | &ett_idmp_IdmBindError, |
850 | 14 | &ett_idmp_Request, |
851 | 14 | &ett_idmp_IdmResult, |
852 | 14 | &ett_idmp_Error, |
853 | 14 | &ett_idmp_IdmReject, |
854 | 14 | &ett_idmp_Code, |
855 | 14 | }; |
856 | 14 | module_t *idmp_module; |
857 | | |
858 | | /* Register protocol */ |
859 | 14 | proto_idmp = proto_register_protocol(PNAME, PSNAME, PFNAME); |
860 | | |
861 | | /* Register fields and subtrees */ |
862 | 14 | proto_register_field_array(proto_idmp, hf, array_length(hf)); |
863 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
864 | | |
865 | 14 | idmp_handle = register_dissector("idmp", dissect_idmp_tcp, proto_idmp); |
866 | | |
867 | 14 | register_cleanup_routine (&idmp_reassemble_cleanup); |
868 | 14 | reassembly_table_register (&idmp_reassembly_table, |
869 | 14 | &addresses_reassembly_table_functions); |
870 | | |
871 | | |
872 | | /* Register our configuration options for IDMP, particularly our port */ |
873 | | |
874 | 14 | idmp_module = prefs_register_protocol_subtree("OSI/X.500", proto_idmp, NULL); |
875 | | |
876 | 14 | prefs_register_bool_preference(idmp_module, "desegment_idmp_messages", |
877 | 14 | "Reassemble IDMP messages spanning multiple TCP segments", |
878 | 14 | "Whether the IDMP dissector should reassemble messages spanning multiple TCP segments." |
879 | 14 | " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.", |
880 | 14 | &idmp_desegment); |
881 | | |
882 | 14 | prefs_register_bool_preference(idmp_module, "reassemble", |
883 | 14 | "Reassemble segmented IDMP datagrams", |
884 | 14 | "Whether segmented IDMP datagrams should be reassembled." |
885 | 14 | " To use this option, you must also enable" |
886 | 14 | " \"Allow subdissectors to reassemble TCP streams\"" |
887 | 14 | " in the TCP protocol settings.", &idmp_reassemble); |
888 | 14 | } |
889 | | |
890 | | |
891 | | /*--- proto_reg_handoff_idm --- */ |
892 | 14 | void proto_reg_handoff_idm(void) { |
893 | 14 | dissector_add_uint_with_preference("tcp.port", IDMP_TCP_PORT, idmp_handle); |
894 | 14 | } |