2 * Routines for X.518 (X.500 Distributed Operations) packet dissection
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/expert.h>
16 #include <epan/prefs.h>
17 #include <epan/oids.h>
18 #include <epan/asn1.h>
19 #include <wsutil/array.h>
21 #include "packet-ber.h"
22 #include "packet-acse.h"
23 #include "packet-ros.h"
25 #include "packet-x509if.h"
26 #include "packet-x509af.h"
27 #include "packet-x509sat.h"
29 #include "packet-dap.h"
30 #include "packet-dsp.h"
33 #define PNAME "X.519 Directory System Protocol"
37 void proto_register_dsp(void);
38 void proto_reg_handoff_dsp(void);
40 /* Initialize the protocol and registered fields */
43 #include "packet-dsp-hf.c"
45 /* Initialize the subtree pointers */
47 #include "packet-dsp-ett.c"
49 static expert_field ei_dsp_unsupported_opcode
;
50 static expert_field ei_dsp_unsupported_errcode
;
51 static expert_field ei_dsp_unsupported_pdu
;
52 static expert_field ei_dsp_zero_pdu
;
54 #include "packet-dsp-fn.c"
56 static dissector_handle_t dsp_handle
;
59 * Dissect X518 PDUs inside a ROS PDUs
62 dissect_dsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data
)
68 struct SESSION_DATA_STRUCTURE
* session
;
69 int (*dsp_dissector
)(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
) = NULL
;
70 const char *dsp_op_name
;
73 /* do we have operation information from the ROS dissector? */
76 session
= (struct SESSION_DATA_STRUCTURE
*)data
;
78 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
80 item
= proto_tree_add_item(parent_tree
, proto_dsp
, tvb
, 0, -1, ENC_NA
);
81 tree
= proto_item_add_subtree(item
, ett_dsp
);
83 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DAP");
84 col_clear(pinfo
->cinfo
, COL_INFO
);
86 asn1_ctx
.private_data
= session
;
88 switch(session
->ros_op
& ROS_OP_MASK
) {
89 case (ROS_OP_BIND
| ROS_OP_ARGUMENT
): /* BindInvoke */
90 dsp_dissector
= dissect_dsp_DSASystemBindArgument
;
91 dsp_op_name
= "System-Bind-Argument";
93 case (ROS_OP_BIND
| ROS_OP_RESULT
): /* BindResult */
94 dsp_dissector
= dissect_dsp_DSASystemBindResult
;
95 dsp_op_name
= "System-Bind-Result";
97 case (ROS_OP_BIND
| ROS_OP_ERROR
): /* BindError */
98 dsp_dissector
= dissect_dsp_DSASystemBindError
;
99 dsp_op_name
= "System-Bind-Error";
101 case (ROS_OP_INVOKE
| ROS_OP_ARGUMENT
): /* Invoke Argument */
102 switch(session
->ros_op
& ROS_OP_OPCODE_MASK
) {
104 dsp_dissector
= dissect_dsp_ChainedReadArgument
;
105 dsp_op_name
= "Chained-Read-Argument";
107 case 2: /* compare */
108 dsp_dissector
= dissect_dsp_ChainedCompareArgument
;
109 dsp_op_name
= "Chained-Compare-Argument";
111 case 3: /* abandon */
112 dsp_dissector
= dissect_dsp_ChainedAbandonArgument
;
113 dsp_op_name
= "Chained-Abandon-Argument";
116 dsp_dissector
= dissect_dsp_ChainedListArgument
;
117 dsp_op_name
= "Chained-List-Argument";
120 dsp_dissector
= dissect_dsp_ChainedSearchArgument
;
121 dsp_op_name
= "Chained-Search-Argument";
123 case 6: /* addEntry */
124 dsp_dissector
= dissect_dsp_ChainedAddEntryArgument
;
125 dsp_op_name
= "Chained-Add-Entry-Argument";
127 case 7: /* removeEntry */
128 dsp_dissector
= dissect_dsp_ChainedRemoveEntryArgument
;
129 dsp_op_name
= "Chained-Remove-Entry-Argument";
131 case 8: /* modifyEntry */
132 dsp_dissector
= dissect_dsp_ChainedModifyEntryArgument
;
133 dsp_op_name
= "ChainedModify-Entry-Argument";
135 case 9: /* modifyDN */
136 dsp_dissector
= dissect_dsp_ChainedModifyDNArgument
;
137 dsp_op_name
= "ChainedModify-DN-Argument";
140 proto_tree_add_expert_format(tree
, pinfo
, &ei_dsp_unsupported_opcode
, tvb
, offset
, -1,
141 "Unsupported DSP opcode (%d)", session
->ros_op
& ROS_OP_OPCODE_MASK
);
145 case (ROS_OP_INVOKE
| ROS_OP_RESULT
): /* Return Result */
146 switch(session
->ros_op
& ROS_OP_OPCODE_MASK
) {
148 dsp_dissector
= dissect_dsp_ChainedReadResult
;
149 dsp_op_name
= "Chained-Read-Result";
151 case 2: /* compare */
152 dsp_dissector
= dissect_dsp_ChainedCompareResult
;
153 dsp_op_name
= "Chained-Compare-Result";
155 case 3: /* abandon */
156 dsp_dissector
= dissect_dsp_ChainedAbandonResult
;
157 dsp_op_name
= "Chained-Abandon-Result";
160 dsp_dissector
= dissect_dsp_ChainedListResult
;
161 dsp_op_name
= "Chained-List-Result";
164 dsp_dissector
= dissect_dsp_ChainedSearchResult
;
165 dsp_op_name
= "Chained-Search-Result";
167 case 6: /* addEntry */
168 dsp_dissector
= dissect_dsp_ChainedAddEntryResult
;
169 dsp_op_name
= "Chained-Add-Entry-Result";
171 case 7: /* removeEntry */
172 dsp_dissector
= dissect_dsp_ChainedRemoveEntryResult
;
173 dsp_op_name
= "Chained-Remove-Entry-Result";
175 case 8: /* modifyEntry */
176 dsp_dissector
= dissect_dsp_ChainedModifyEntryResult
;
177 dsp_op_name
= "Chained-Modify-Entry-Result";
179 case 9: /* modifyDN */
180 dsp_dissector
= dissect_dsp_ChainedModifyDNResult
;
181 dsp_op_name
= "ChainedModify-DN-Result";
184 proto_tree_add_expert(tree
, pinfo
, &ei_dsp_unsupported_opcode
, tvb
, offset
, -1);
188 case (ROS_OP_INVOKE
| ROS_OP_ERROR
): /* Return Error */
189 switch(session
->ros_op
& ROS_OP_OPCODE_MASK
) {
190 case 1: /* attributeError */
191 dsp_dissector
= dissect_dap_AttributeError
;
192 dsp_op_name
= "Attribute-Error";
194 case 2: /* nameError */
195 dsp_dissector
= dissect_dap_NameError
;
196 dsp_op_name
= "Name-Error";
198 case 3: /* serviceError */
199 dsp_dissector
= dissect_dap_ServiceError
;
200 dsp_op_name
= "Service-Error";
202 case 4: /* referral */
203 dsp_dissector
= dissect_dap_Referral
;
204 dsp_op_name
= "Referral";
206 case 5: /* abandoned */
207 dsp_dissector
= dissect_dap_Abandoned
;
208 dsp_op_name
= "Abandoned";
210 case 6: /* securityError */
211 dsp_dissector
= dissect_dap_SecurityError
;
212 dsp_op_name
= "Security-Error";
214 case 7: /* abandonFailed */
215 dsp_dissector
= dissect_dap_AbandonFailedError
;
216 dsp_op_name
= "Abandon-Failed-Error";
218 case 8: /* updateError */
219 dsp_dissector
= dissect_dap_UpdateError
;
220 dsp_op_name
= "Update-Error";
222 case 9: /* DSAReferral */
223 dsp_dissector
= dissect_dsp_DSAReferral
;
224 dsp_op_name
= "DSA-Referral";
227 proto_tree_add_expert(tree
, pinfo
, &ei_dsp_unsupported_errcode
, tvb
, offset
, -1);
232 proto_tree_add_expert(tree
, pinfo
, &ei_dsp_unsupported_pdu
, tvb
, offset
, -1);
233 return tvb_captured_length(tvb
);
237 col_set_str(pinfo
->cinfo
, COL_INFO
, dsp_op_name
);
239 while (tvb_reported_length_remaining(tvb
, offset
) > 0){
241 offset
=(*dsp_dissector
)(false, tvb
, offset
, &asn1_ctx
, tree
, -1);
242 if(offset
== old_offset
){
243 proto_tree_add_expert(tree
, pinfo
, &ei_dsp_zero_pdu
, tvb
, offset
, -1);
249 return tvb_captured_length(tvb
);
253 /*--- proto_register_dsp -------------------------------------------*/
254 void proto_register_dsp(void) {
257 static hf_register_info hf
[] =
259 #include "packet-dsp-hfarr.c"
262 /* List of subtrees */
263 static int *ett
[] = {
265 #include "packet-dsp-ettarr.c"
267 static ei_register_info ei
[] = {
268 { &ei_dsp_unsupported_opcode
, { "dsp.unsupported_opcode", PI_UNDECODED
, PI_WARN
, "Unsupported DSP opcode", EXPFILL
}},
269 { &ei_dsp_unsupported_errcode
, { "dsp.unsupported_errcode", PI_UNDECODED
, PI_WARN
, "Unsupported DSP errcode", EXPFILL
}},
270 { &ei_dsp_unsupported_pdu
, { "dsp.unsupported_pdu", PI_UNDECODED
, PI_WARN
, "Unsupported DSP PDU", EXPFILL
}},
271 { &ei_dsp_zero_pdu
, { "dsp.zero_pdu", PI_PROTOCOL
, PI_ERROR
, "Internal error, zero-byte DSP PDU", EXPFILL
}},
274 module_t
*dsp_module
;
275 expert_module_t
* expert_dsp
;
277 /* Register protocol */
278 proto_dsp
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
280 dsp_handle
= register_dissector("dsp", dissect_dsp
, proto_dsp
);
282 /* Register fields and subtrees */
283 proto_register_field_array(proto_dsp
, hf
, array_length(hf
));
284 proto_register_subtree_array(ett
, array_length(ett
));
285 expert_dsp
= expert_register_protocol(proto_dsp
);
286 expert_register_field_array(expert_dsp
, ei
, array_length(ei
));
288 /* Register our configuration options for DSP, particularly our port */
290 dsp_module
= prefs_register_protocol_subtree("OSI/X.500", proto_dsp
, NULL
);
292 prefs_register_obsolete_preference(dsp_module
, "tcp.port");
294 prefs_register_static_text_preference(dsp_module
, "tcp_port_info",
295 "The TCP ports used by the DSP protocol should be added to the TPKT preference \"TPKT TCP ports\", or by selecting \"TPKT\" as the \"Transport\" protocol in the \"Decode As\" dialog.",
296 "DSP TCP Port preference moved information");
301 /*--- proto_reg_handoff_dsp --- */
302 void proto_reg_handoff_dsp(void) {
303 #include "packet-dsp-dis-tab.c"
305 /* APPLICATION CONTEXT */
307 oid_add_from_string("id-ac-directory-system","2.5.3.2");
309 /* ABSTRACT SYNTAXES */
311 /* Register DSP with ROS (with no use of RTSE) */
312 register_ros_oid_dissector_handle("2.5.9.2", dsp_handle
, 0, "id-as-directory-system", false);