MSWSP: add parse_CNatLanguageRestriction()
[wireshark-wip.git] / asn1 / acse / packet-acse-template.c
blob506ae4ba09a1e7302c0739aa118294708db45907
1 /*XXX
2 There is a bug in asn2wrs that it can not yet handle tagged assignments such
3 as EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE {
5 This bug is workedaround by some .cnf magic but this should be cleaned up
6 once asn2wrs learns how to deal with tagged assignments
7 */
9 /* packet-acse.c
10 * Routines for ACSE packet dissection
11 * Ronnie Sahlberg 2005
12 * dissect_acse() based original handwritten dissector by Sid
13 * Yuriy Sidelnikov <YSidelnikov@hotmail.com>
16 * $Id$
18 * Wireshark - Network traffic analyzer
19 * By Gerald Combs <gerald@wireshark.org>
20 * Copyright 1998 Gerald Combs
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37 #include "config.h"
39 #include <glib.h>
40 #include <epan/packet.h>
41 #include <epan/exceptions.h>
42 #include <epan/wmem/wmem.h>
43 #include <epan/expert.h>
44 #include <epan/oids.h>
45 #include <epan/asn1.h>
47 #include <string.h>
49 #include "packet-ber.h"
50 #include "packet-acse.h"
51 #include "packet-ses.h"
52 #include "packet-pres.h"
53 #include "packet-x509if.h"
55 #define PNAME "ISO 8650-1 OSI Association Control Service"
56 #define PSNAME "ACSE"
57 #define PFNAME "acse"
59 #define CLPNAME "ISO 10035-1 OSI Connectionless Association Control Service"
60 #define CLPSNAME "CLACSE"
61 #define CLPFNAME "clacse"
64 #define ACSE_APDU_OID "2.2.1.0.1"
66 /* Initialize the protocol and registered fields */
67 int proto_acse = -1;
68 int proto_clacse = -1;
72 #include "packet-acse-hf.c"
74 /* Initialize the subtree pointers */
75 static gint ett_acse = -1;
76 #include "packet-acse-ett.c"
78 static expert_field ei_acse_dissector_not_available = EI_INIT;
80 static const char *object_identifier_id;
81 /* indirect_reference, used to pick up the signalling so we know what
82 kind of data is transferred in SES_DATA_TRANSFER_PDUs */
83 static guint32 indir_ref=0;
85 static proto_tree *top_tree=NULL;
87 #if NOT_NEEDED
88 /* to keep track of presentation context identifiers and protocol-oids */
89 typedef struct _acse_ctx_oid_t {
90 /* XXX here we should keep track of ADDRESS/PORT as well */
91 guint32 ctx_id;
92 char *oid;
93 } acse_ctx_oid_t;
94 static GHashTable *acse_ctx_oid_table = NULL;
96 static guint
97 acse_ctx_oid_hash(gconstpointer k)
99 acse_ctx_oid_t *aco=(acse_ctx_oid_t *)k;
100 return aco->ctx_id;
102 /* XXX this one should be made ADDRESS/PORT aware */
103 static gint
104 acse_ctx_oid_equal(gconstpointer k1, gconstpointer k2)
106 acse_ctx_oid_t *aco1=(acse_ctx_oid_t *)k1;
107 acse_ctx_oid_t *aco2=(acse_ctx_oid_t *)k2;
108 return aco1->ctx_id==aco2->ctx_id;
111 static void
112 acse_init(void)
114 if( acse_ctx_oid_table ){
115 g_hash_table_destroy(acse_ctx_oid_table);
116 acse_ctx_oid_table = NULL;
118 acse_ctx_oid_table = g_hash_table_new(acse_ctx_oid_hash,
119 acse_ctx_oid_equal);
123 static void
124 register_ctx_id_and_oid(packet_info *pinfo _U_, guint32 idx, char *oid)
126 acse_ctx_oid_t *aco, *tmpaco;
127 aco=wmem_new(wmem_file_scope(), acse_ctx_oid_t);
128 aco->ctx_id=idx;
129 aco->oid=wmem_strdup(wmem_file_scope(), oid);
131 /* if this ctx already exists, remove the old one first */
132 tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, aco);
133 if(tmpaco){
134 g_hash_table_remove(acse_ctx_oid_table, tmpaco);
136 g_hash_table_insert(acse_ctx_oid_table, aco, aco);
138 static char *
139 find_oid_by_ctx_id(packet_info *pinfo _U_, guint32 idx)
141 acse_ctx_oid_t aco, *tmpaco;
142 aco.ctx_id=idx;
143 tmpaco=(acse_ctx_oid_t *)g_hash_table_lookup(acse_ctx_oid_table, &aco);
144 if(tmpaco){
145 return tmpaco->oid;
147 return NULL;
150 # endif /* NOT_NEEDED */
152 #include "packet-acse-fn.c"
156 * Dissect ACSE PDUs inside a PPDU.
158 static int
159 dissect_acse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
161 int offset = 0;
162 proto_item *item;
163 proto_tree *tree;
164 char *oid;
165 struct SESSION_DATA_STRUCTURE* session;
166 asn1_ctx_t asn1_ctx;
167 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
170 /* first, try to check length */
171 /* do we have at least 2 bytes */
172 if (!tvb_bytes_exist(tvb, 0, 2)){
173 proto_tree_add_text(parent_tree, tvb, offset,
174 tvb_reported_length_remaining(tvb,offset),
175 "User data");
176 return 0; /* no, it isn't a ACSE PDU */
178 /* do we have spdu type from the session dissector? */
179 if( data == NULL){
180 if(parent_tree){
181 REPORT_DISSECTOR_BUG("Can't get SPDU type from session dissector.");
183 return 0;
186 session = ( (struct SESSION_DATA_STRUCTURE*)data);
187 if(session->spdu_type == 0 ) {
188 if(parent_tree){
189 REPORT_DISSECTOR_BUG(
190 wmem_strdup_printf(wmem_packet_scope(), "Wrong spdu type %x from session dissector.",session->spdu_type));
191 return 0;
195 asn1_ctx.private_data = session;
196 /* save parent_tree so subdissectors can create new top nodes */
197 top_tree=parent_tree;
199 /* ACSE has only AARQ,AARE,RLRQ,RLRE,ABRT type of pdu */
200 /* reject everything else */
201 /* data pdu is not ACSE pdu and has to go directly to app dissector */
202 switch(session->spdu_type){
203 case SES_CONNECTION_REQUEST: /* AARQ */
204 case SES_CONNECTION_ACCEPT: /* AARE */
205 case SES_REFUSE: /* RLRE */
206 case SES_DISCONNECT: /* RLRQ */
207 case SES_FINISH: /* RLRE */
208 case SES_ABORT: /* ABRT */
209 case CLSES_UNIT_DATA: /* AARQ Connetctionless session */
210 break;
211 case SES_DATA_TRANSFER:
212 oid=find_oid_by_pres_ctx_id(pinfo, indir_ref);
213 if(oid){
214 if(strcmp(oid, ACSE_APDU_OID) == 0){
215 proto_tree_add_text(parent_tree, tvb, offset, -1,
216 "Invalid OID: %s", ACSE_APDU_OID);
217 THROW(ReportedBoundsError);
219 call_ber_oid_callback(oid, tvb, offset, pinfo, parent_tree, NULL);
220 } else {
221 proto_tree_add_expert(parent_tree, pinfo, &ei_acse_dissector_not_available,
222 tvb, offset, -1);
224 top_tree = NULL;
225 return 0;
226 default:
227 top_tree = NULL;
228 return 0;
231 if(session->spdu_type == CLSES_UNIT_DATA)
233 /* create display subtree for the connectionless protocol */
234 item = proto_tree_add_item(parent_tree, proto_clacse, tvb, 0, -1, ENC_NA);
235 tree = proto_item_add_subtree(item, ett_acse);
237 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CL-ACSE");
238 col_clear(pinfo->cinfo, COL_INFO);
240 else
242 /* create display subtree for the protocol */
243 item = proto_tree_add_item(parent_tree, proto_acse, tvb, 0, -1, ENC_NA);
244 tree = proto_item_add_subtree(item, ett_acse);
246 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACSE");
247 col_clear(pinfo->cinfo, COL_INFO);
250 /* we can't make any additional checking here */
251 /* postpone it before dissector will have more information */
252 while (tvb_reported_length_remaining(tvb, offset) > 0){
253 int old_offset=offset;
254 offset = dissect_acse_ACSE_apdu(FALSE, tvb, offset, &asn1_ctx, tree, -1);
255 if(offset == old_offset ){
256 proto_tree_add_text(tree, tvb, offset, -1,"Malformed packet");
257 break;
261 top_tree = NULL;
262 return tvb_length(tvb);
265 /*--- proto_register_acse ----------------------------------------------*/
266 void proto_register_acse(void) {
268 /* List of fields */
269 static hf_register_info hf[] = {
270 #include "packet-acse-hfarr.c"
273 /* List of subtrees */
274 static gint *ett[] = {
275 &ett_acse,
276 #include "packet-acse-ettarr.c"
279 static ei_register_info ei[] = {
280 { &ei_acse_dissector_not_available, { "acse.dissector_not_available", PI_UNDECODED, PI_WARN, "Dissector is not available", EXPFILL }},
283 expert_module_t* expert_acse;
285 /* Register protocol */
286 proto_acse = proto_register_protocol(PNAME, PSNAME, PFNAME);
287 new_register_dissector("acse", dissect_acse, proto_acse);
289 /* Register connectionless protocol */
290 proto_clacse = proto_register_protocol(CLPNAME, CLPSNAME, CLPFNAME);
293 /* Register fields and subtrees */
294 proto_register_field_array(proto_acse, hf, array_length(hf));
295 proto_register_subtree_array(ett, array_length(ett));
296 expert_acse = expert_register_protocol(proto_acse);
297 expert_register_field_array(expert_acse, ei, array_length(ei));
301 /*--- proto_reg_handoff_acse -------------------------------------------*/
302 void proto_reg_handoff_acse(void) {
303 /*#include "packet-acse-dis-tab.c"*/
304 dissector_handle_t acse_handle = find_dissector("acse");
306 oid_add_from_string("id-aCSE","2.2.3.1.1");
307 register_ber_oid_dissector_handle(ACSE_APDU_OID, acse_handle, proto_acse, "id-as-acse");