1 /*
2 XXX all this offset>>3 and calculations of bytes in the tvb everytime
3 we put something in the tree is just silly. should be replaced with some
4 proper helper routines
5 */
6 /* packet-per.c
7 * Routines for dissection of ASN.1 Aligned PER
8 * 2003 Ronnie Sahlberg
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 <math.h>
20
21 #include <epan/packet.h>
22 #include <epan/exceptions.h>
23 #include <epan/oids.h>
24 #include <epan/to_str.h>
25 #include <epan/asn1.h>
26 #include <epan/expert.h>
27 #include <wsutil/str_util.h>
28 #include "packet-per.h"
29
30 void proto_register_per(void);
31
32 static int proto_per = -1;
33 static int hf_per_GeneralString_length = -1;
34 static int hf_per_extension_bit = -1;
35 static int hf_per_extension_present_bit = -1;
36 static int hf_per_choice_index = -1;
37 static int hf_per_choice_extension_index = -1;
38 static int hf_per_enum_index = -1;
39 static int hf_per_enum_extension_index = -1;
40 static int hf_per_num_sequence_extensions = -1;
41 static int hf_per_small_number_bit = -1;
42 static int hf_per_optional_field_bit = -1;
43 static int hf_per_sequence_of_length = -1;
44 static int hf_per_object_identifier_length = -1;
45 static int hf_per_open_type_length = -1;
46 static int hf_per_real_length = -1;
47 static int hf_per_octet_string_length = -1;
48 static int hf_per_bit_string_length = -1;
49 static int hf_per_normally_small_nonnegative_whole_number_length = -1;
50 static int hf_per_const_int_len = -1;
51 static int hf_per_direct_reference = -1; /* T_direct_reference */
52 static int hf_per_indirect_reference = -1; /* T_indirect_reference */
53 static int hf_per_data_value_descriptor = -1; /* T_data_value_descriptor */
54 static int hf_per_encoding = -1; /* External_encoding */
55 static int hf_per_single_ASN1_type = -1; /* T_single_ASN1_type */
56 static int hf_per_octet_aligned = -1; /* T_octet_aligned */
57 static int hf_per_arbitrary = -1; /* T_arbitrary */
58 static int hf_per_integer_length = -1; /* Show integer length if "show internal per fields" */
59 /* static int hf_per_debug_pos = -1; */
60 static int hf_per_internal_range = -1;
61 static int hf_per_internal_num_bits = -1;
62 static int hf_per_internal_min = -1;
63 static int hf_per_internal_value = -1;
64
65 static gint ett_per_open_type = -1;
66 static gint ett_per_containing = -1;
67 static gint ett_per_sequence_of_item = -1;
68 static gint ett_per_External = -1;
69 static gint ett_per_External_encoding = -1;
70 static gint ett_per_named_bits = -1;
71
72 static expert_field ei_per_size_constraint_value = EI_INIT;
73 static expert_field ei_per_size_constraint_too_few = EI_INIT;
74 static expert_field ei_per_size_constraint_too_many = EI_INIT;
75 static expert_field ei_per_choice_extension_unknown = EI_INIT;
76 static expert_field ei_per_sequence_extension_unknown = EI_INIT;
77 static expert_field ei_per_encoding_error = EI_INIT;
78 static expert_field ei_per_oid_not_implemented = EI_INIT;
79 static expert_field ei_per_undecoded = EI_INIT;
80 static expert_field ei_per_field_not_integer = EI_INIT;
81 static expert_field ei_per_external_type = EI_INIT;
82 static expert_field ei_per_open_type = EI_INIT;
83 static expert_field ei_per_open_type_len = EI_INIT;
84
85 static dissector_table_t per_oid_dissector_table = NULL;
86
87 /*
88 #define DEBUG_ENTRY(x) \
89 printf("#%u %s tvb:0x%08x\n",actx->pinfo->num,x,(int)tvb);
90 */
91 #define DEBUG_ENTRY(x) \
92 ;
93
94 #define BLEN(old_offset, offset) (((offset)>>3)!=((old_offset)>>3)?((offset)>>3)-((old_offset)>>3):1)
95
96 /* whether the PER helpers should put the internal PER fields into the tree
97 or not.
98 */
99 static gboolean display_internal_per_fields = FALSE;
100
101
102
103 static const true_false_string tfs_extension_bit = {
104 "Extension bit is set",
105 "Extension bit is clear"
106 };
107 static const true_false_string tfs_small_number_bit = {
108 "The number is small, 0-63",
109 "The number is large, >63"
110 };
111
112
113 #define BYTE_ALIGN_OFFSET(offset) if(offset&0x07){offset=(offset&0xfffffff8)+8;}
114
115 #define SEQ_MAX_COMPONENTS 128
116
per_check_value(guint32 value,guint32 min_len,guint32 max_len,asn1_ctx_t * actx,proto_item * item,gboolean is_signed)117 static void per_check_value(guint32 value, guint32 min_len, guint32 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
118 {
119 if ((is_signed == FALSE) && (value > max_len)) {
120 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %u (%u .. %u)", value, min_len, max_len);
121 } else if ((is_signed == TRUE) && ((gint32)value > (gint32)max_len)) {
122 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %d (%d .. %d)", (gint32)value, (gint32)min_len, (gint32)max_len);
123 }
124 }
125
per_check_value64(guint64 value,guint64 min_len,guint64 max_len,asn1_ctx_t * actx,proto_item * item,gboolean is_signed)126 static void per_check_value64(guint64 value, guint64 min_len, guint64 max_len, asn1_ctx_t *actx, proto_item *item, gboolean is_signed)
127 {
128 if ((is_signed == FALSE) && (value > max_len)) {
129 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "u (%" G_GINT64_MODIFIER "u .. %" G_GINT64_MODIFIER "u)", value, min_len, max_len);
130 } else if ((is_signed == TRUE) && ((gint64)value > (gint64)max_len)) {
131 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_value, "Size constraint: value too big: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "d .. %" G_GINT64_MODIFIER "d)", (gint64)value, (gint64)min_len, (gint64)max_len);
132 }
133 }
134
per_check_items(guint32 cnt,int min_len,int max_len,asn1_ctx_t * actx,proto_item * item)135 static void per_check_items(guint32 cnt, int min_len, int max_len, asn1_ctx_t *actx, proto_item *item)
136 {
137 if (min_len != NO_BOUND && cnt < (guint32)min_len) {
138 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_few, "Size constraint: too few items: %d (%d .. %d)", cnt, min_len, max_len);
139 } else if (max_len != NO_BOUND && cnt > (guint32)max_len) {
140 expert_add_info_format(actx->pinfo, item, &ei_per_size_constraint_too_many, "Size constraint: too many items: %d (%d .. %d)", cnt, min_len, max_len);
141 }
142 }
143
144
dissect_per_not_decoded_yet(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,const char * reason)145 void dissect_per_not_decoded_yet(proto_tree* tree, packet_info* pinfo, tvbuff_t *tvb, const char* reason)
146 {
147 proto_tree_add_expert_format(tree, pinfo, &ei_per_undecoded, tvb, 0, 0, "something unknown here [%s]",reason);
148 col_append_fstr(pinfo->cinfo, COL_INFO, "[UNKNOWN PER: %s]", reason);
149 THROW(ReportedBoundsError);
150 }
151
152 /* 10 Encoding procedures -------------------------------------------------- */
153
154 /* 10.2 Open type fields --------------------------------------------------- */
155 static guint32
dissect_per_open_type_internal(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,void * type_cb,asn1_cb_variant variant)156 dissect_per_open_type_internal(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, void* type_cb, asn1_cb_variant variant)
157 {
158 int type_length, start_offset, end_offset, fragmented_length = 0, pdu_length, pdu_offset;
159 tvbuff_t *val_tvb = NULL, *pdu_tvb = NULL;
160 header_field_info *hfi;
161 proto_tree *subtree = tree;
162 gboolean is_fragmented;
163 int captured_pdu_length;
164
165 hfi = (hf_index == -1) ? NULL : proto_registrar_get_nth(hf_index);
166
167 start_offset = offset;
168 do {
169 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length, &is_fragmented);
170 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
171 if (is_fragmented) {
172 if (fragmented_length == 0) {
173 pdu_tvb = tvb_new_composite();
174 }
175 tvb_composite_append(pdu_tvb, tvb_new_octet_aligned(tvb, offset, 8*type_length));
176 offset += 8*type_length;
177 fragmented_length += type_length;
178 }
179 } while (is_fragmented);
180 if (fragmented_length) {
181 if (type_length) {
182 tvb_composite_append(pdu_tvb, tvb_new_octet_aligned(tvb, offset, 8*type_length));
183 fragmented_length += type_length;
184 }
185 tvb_composite_finalize(pdu_tvb);
186 add_new_data_source(actx->pinfo, pdu_tvb, "Fragmented OCTET STRING");
187 pdu_offset = 0;
188 pdu_length = fragmented_length;
189 } else {
190 pdu_tvb = tvb;
191 pdu_offset = offset;
192 pdu_length = type_length;
193 }
194 end_offset = offset + type_length * 8;
195
196 if (variant==CB_NEW_DISSECTOR) {
197 if (fragmented_length) {
198 val_tvb = pdu_tvb;
199 } else {
200 if (!pdu_length) {
201 return end_offset;
202 }
203 /* Check if we have a tvb that holds the whole PDU */
204 captured_pdu_length = tvb_captured_length(pdu_tvb) - (pdu_offset>>3);
205 if(captured_pdu_length < pdu_length){
206 val_tvb = tvb_new_octet_aligned(pdu_tvb, pdu_offset, captured_pdu_length * 8);
207 actx->created_item = proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_open_type_len, tvb, pdu_offset >> 3,
208 captured_pdu_length,"Open type length(%i) > available data(%i)", pdu_length, captured_pdu_length);
209 pdu_length = captured_pdu_length;
210 } else {
211 val_tvb = tvb_new_octet_aligned(pdu_tvb, pdu_offset, pdu_length * 8);
212 }
213 /* Add new data source if the offet was unaligned */
214 if ((pdu_offset & 7) != 0) {
215 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
216 }
217 }
218 if (hfi) {
219 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
220 if (IS_FT_UINT(hfi->type))
221 actx->created_item = proto_tree_add_uint(tree, hf_index, val_tvb, 0, pdu_length, pdu_length);
222 else
223 actx->created_item = proto_tree_add_int(tree, hf_index, val_tvb, 0, pdu_length, pdu_length);
224 proto_item_append_text(actx->created_item, plurality(pdu_length, " octet", " octets"));
225 } else {
226 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, pdu_length, ENC_BIG_ENDIAN);
227 }
228 subtree = proto_item_add_subtree(actx->created_item, ett_per_open_type);
229 }
230 }
231
232 if (type_cb) {
233 switch (variant) {
234 case CB_ASN1_ENC:
235 ((per_type_fn)type_cb)(pdu_tvb, pdu_offset, actx, tree, hf_index);
236 break;
237 case CB_NEW_DISSECTOR:
238 /* Pas actx->private_data as "data" to the called function */
239 ((dissector_t)type_cb)(val_tvb, actx->pinfo, subtree, actx->private_data);
240 break;
241 case CB_DISSECTOR_HANDLE:
242 break;
243 }
244 } else {
245 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_open_type, tvb, start_offset>>3, BLEN(start_offset, end_offset));
246 }
247
248 return end_offset;
249 }
250
251 guint32
dissect_per_open_type(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,per_type_fn type_cb)252 dissect_per_open_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb)
253 {
254 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_ASN1_ENC);
255 }
256
257 guint32
dissect_per_open_type_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,dissector_t type_cb)258 dissect_per_open_type_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, dissector_t type_cb)
259 {
260 return dissect_per_open_type_internal(tvb, offset, actx, tree, hf_index, (void*)type_cb, CB_NEW_DISSECTOR);
261 }
262
263 /* 10.9 General rules for encoding a length determinant --------------------
264
265 NOTE 1 - (Tutorial) The procedures of this subclause are invoked when an explicit length field is needed
266 for some part of the encoding regardless of whether the length count is bounded above
267 (by PER-visible constraints) or not. The part of the encoding to which the length applies may
268 be a bit string (with the length count in bits), an octet string (with the length count in octets),
269 a known-multiplier character string (with the length count in characters), or a list of fields
270 (with the length count in components of a sequence-of or set-of).
271
272 NOTE 2 - (Tutorial) In the case of the ALIGNED variant if the length count is bounded above by an upper bound
273 that is less than 64K, then the constrained whole number encoding is used for the length.
274 For sufficiently small ranges the result is a bit-field, otherwise the unconstrained length ("n" say)
275 is encoded into an octet-aligned bit-field in one of three ways (in order of increasing size):
276 a) ("n" less than 128) a single octet containing "n" with bit 8 set to zero;
277 b) ("n" less than 16K) two octets containing "n" with bit 8 of the first octet set to 1 and bit 7 set to zero;
278 c) (large "n") a single octet containing a count "m" with bit 8 set to 1 and bit 7 set to 1.
279 The count "m" is one to four, and the length indicates that a fragment of the material follows
280 (a multiple "m" of 16K items). For all values of "m", the fragment is then followed by another length encoding
281 for the remainder of the material.
282
283 NOTE 3 - (Tutorial) In the UNALIGNED variant, if the length count is bounded above by an upper bound that is less
284 than 64K, then the constrained whole number encoding is used to encode the length in the minimum number of
285 bits necessary to represent the range. Otherwise, the unconstrained length ("n" say) is encoded into a bit
286 field in the manner described above in Note 2.
287
288 */
289 guint32
dissect_per_length_determinant(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx _U_,proto_tree * tree,int hf_index,guint32 * length,gboolean * is_fragmented)290 dissect_per_length_determinant(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index, guint32 *length, gboolean *is_fragmented)
291 {
292 guint8 byte;
293 guint32 len;
294 proto_item *pi;
295 int num_bits;
296 int i, bit, str_length, str_index;
297 gboolean tmp;
298
299 if(!length){
300 length=&len;
301 }
302 if (is_fragmented) {
303 *is_fragmented = FALSE;
304 }
305
306 /* byte aligned */
307 if (actx->aligned){
308 BYTE_ALIGN_OFFSET(offset);
309 byte=tvb_get_guint8(tvb, offset>>3);
310 offset+=8;
311 }else{
312 char *str;
313 guint32 val;
314
315 val = 0;
316
317 /* prepare the string (max number of bits + quartet separators + prepended space) */
318 str_length = 256+64+1;
319 str=(char *)wmem_alloc(wmem_packet_scope(), str_length+1);
320 str_index = 0;
321
322 str_length = g_snprintf(str, str_length+1, " ");
323 for(bit=0;bit<((int)(offset&0x07));bit++){
324 if(bit&&(!(bit%4))){
325 if (str_index < str_length) str[str_index++] = ' ';
326 }
327 if (str_index < str_length) str[str_index++] = '.';
328 }
329 /* read the bits for the int */
330 num_bits = 8;
331 for(i=0;i<num_bits;i++){
332 if(bit&&(!(bit%4))){
333 if (str_index < str_length) str[str_index++] = ' ';
334 }
335 if(bit&&(!(bit%8))){
336 if (str_index < str_length) str[str_index++] = ' ';
337 }
338 bit++;
339 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
340 val<<=1;
341 if(tmp){
342 val|=1;
343 if (str_index < str_length) str[str_index++] = '1';
344 if (i==0) { /* bit 8 is 1, so not a single byte length */
345 num_bits = 16;
346 }
347 else if (i==1 && val==3) { /* bits 8 and 7 both 1, so unconstrained */
348 if (!is_fragmented) {
349 *length = 0;
350 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained");
351 return offset;
352 } else {
353 num_bits = 8;
354 *is_fragmented = TRUE;
355 }
356 }
357 } else {
358 if (str_index < str_length) str[str_index++] = '0';
359 }
360 }
361 str[str_index] = '\0'; /* Terminate string */
362 if(is_fragmented && *is_fragmented==TRUE){
363 *length = val&0x3f;
364 if (*length>4 || *length==0) {
365 *length = 0;
366 *is_fragmented = FALSE;
367 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
368 return offset;
369 }
370 *length *= 0x4000;
371 if(hf_index!=-1){
372 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
373 if (display_internal_per_fields)
374 proto_item_append_text(pi," %s", str);
375 else
376 proto_item_set_hidden(pi);
377 }
378
379 return offset;
380 }
381 else if((val&0x80)==0 && num_bits==8){
382 *length = val;
383 if(hf_index!=-1){
384 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
385 if (display_internal_per_fields)
386 proto_item_append_text(pi," %s", str);
387 else
388 proto_item_set_hidden(pi);
389 }
390
391 return offset;
392 }
393 else if (num_bits==16) {
394 *length = val&0x3fff;
395 if(hf_index!=-1){
396 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
397 if (display_internal_per_fields)
398 proto_item_append_text(pi," %s", str);
399 else
400 proto_item_set_hidden(pi);
401 }
402
403 return offset;
404 }
405 *length = 0;
406 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unaligned");
407 return offset;
408
409 }
410
411 /* 10.9.3.6 */
412 if((byte&0x80)==0){
413 *length=byte;
414 if(hf_index!=-1){
415 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
416 if (!display_internal_per_fields) proto_item_set_hidden(pi);
417 }
418 return offset;
419 }
420
421 /* 10.9.3.7 */
422 if((byte&0xc0)==0x80){
423 *length=(byte&0x3f);
424 *length=((*length)<<8)+tvb_get_guint8(tvb, offset>>3);
425 offset+=8;
426 if(hf_index!=-1){
427 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-2, 2, *length);
428 if (!display_internal_per_fields) proto_item_set_hidden(pi);
429 }
430 return offset;
431 }
432 /* 10.9.3.8.1 */
433 else if (is_fragmented){
434 *length = byte&0x3f;
435 if (*length>4 || *length==0) {
436 *length = 0;
437 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9 Unconstrained unexpected fragment count");
438 return offset;
439 }
440 *length *= 0x4000;
441 *is_fragmented = TRUE;
442 if(hf_index!=-1){
443 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-1, 1, *length);
444 if (!display_internal_per_fields) proto_item_set_hidden(pi);
445 }
446 return offset;
447 }
448 *length = 0;
449 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "10.9.3.8.1");
450 return offset;
451 }
452
453 /* 10.6 normally small non-negative whole number */
454 static guint32
dissect_per_normally_small_nonnegative_whole_number(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 * length)455 dissect_per_normally_small_nonnegative_whole_number(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 *length)
456 {
457 gboolean small_number, length_bit;
458 guint32 len, length_determinant;
459 proto_item *pi;
460
461 DEBUG_ENTRY("dissect_per_normally_small_nonnegative_whole_number");
462 if(!length){
463 length=&len;
464 }
465
466 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_small_number_bit, &small_number);
467 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
468 if(!small_number){
469 int i;
470 /* 10.6.1 */
471 *length=0;
472 for(i=0;i<6;i++){
473 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &length_bit);
474 *length<<=1;
475 if (length_bit) {
476 *length|=1;
477 }
478 }
479 if(hf_index!=-1){
480 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-6)>>3, (offset%8<6)?2:1, *length);
481 if (!display_internal_per_fields) proto_item_set_hidden(pi);
482 }
483 return offset;
484 }
485
486 /* 10.6.2 */
487 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_normally_small_nonnegative_whole_number_length, &length_determinant, NULL);
488 switch (length_determinant) {
489 case 0:
490 *length = 0;
491 break;
492 case 1:
493 *length = tvb_get_bits8(tvb, offset, 8);
494 offset += 8;
495 break;
496 case 2:
497 *length = tvb_get_bits16(tvb, offset, 16, ENC_BIG_ENDIAN);
498 offset += 16;
499 break;
500 case 3:
501 *length = tvb_get_bits32(tvb, offset, 24, ENC_BIG_ENDIAN);
502 offset += 24;
503 break;
504 case 4:
505 *length = tvb_get_bits32(tvb, offset, 32, ENC_BIG_ENDIAN);
506 offset += 32;
507 break;
508 default:
509 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_normally_small_nonnegative_whole_number)");
510 offset += 8*length_determinant;
511 *length = 0;
512 return offset;
513 }
514 if(hf_index!=-1){
515 pi = proto_tree_add_uint(tree, hf_index, tvb, (offset-(8*length_determinant))>>3, length_determinant, *length);
516 if (!display_internal_per_fields) proto_item_set_hidden(pi);
517 }
518
519 return offset;
520 }
521
522
523
524 /* this function reads a GeneralString */
525 /* currently based on pure guesswork since RFC2833 didn't tell me much
526 i guess that the PER encoding for this is a normally-small-whole-number
527 followed by a ascii string.
528
529 based on pure guesswork. it looks ok in the only capture i have where
530 there is a 1 byte general string encoded
531 */
532 guint32
dissect_per_GeneralString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)533 dissect_per_GeneralString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index)
534 {
535 guint32 length;
536
537 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_GeneralString_length, &length, NULL);
538
539 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length, ENC_BIG_ENDIAN);
540
541 offset+=length*8;
542
543 return offset;
544 }
545
546 /* 17 Encoding the null type */
547 guint32
dissect_per_null(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx _U_,proto_tree * tree,int hf_index)548 dissect_per_null(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index) {
549 proto_item *ti_tmp;
550
551 ti_tmp = proto_tree_add_item(tree, hf_index, tvb, offset>>3, 1, ENC_BIG_ENDIAN);
552 proto_item_append_text(ti_tmp, ": NULL");
553
554 return offset;
555 }
556
557 /* 19 this function dissects a sequence of */
558 static guint32
dissect_per_sequence_of_helper(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,per_type_fn func,int hf_index,guint32 length)559 dissect_per_sequence_of_helper(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, per_type_fn func, int hf_index, guint32 length)
560 {
561 guint32 i;
562
563 DEBUG_ENTRY("dissect_per_sequence_of_helper");
564 for(i=0;i<length;i++){
565 guint32 lold_offset=offset;
566 proto_item *litem;
567 proto_tree *ltree;
568
569 ltree=proto_tree_add_subtree_format(tree, tvb, offset>>3, 0, ett_per_sequence_of_item, &litem, "Item %d", i);
570
571 offset=(*func)(tvb, offset, actx, ltree, hf_index);
572 proto_item_set_len(litem, (offset>>3)!=(lold_offset>>3)?(offset>>3)-(lold_offset>>3):1);
573 }
574
575 return offset;
576 }
577 guint32
dissect_per_sequence_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq)578 dissect_per_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
579 {
580 proto_item *item;
581 proto_tree *tree;
582 guint32 old_offset=offset;
583 guint32 length;
584 header_field_info *hfi;
585
586 DEBUG_ENTRY("dissect_per_sequence_of");
587
588 /* semi-constrained whole number for number of elements */
589 /* each element encoded as 10.9 */
590
591 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
592
593 hfi = proto_registrar_get_nth(hf_index);
594 if (IS_FT_UINT(hfi->type)) {
595 item = proto_tree_add_uint(parent_tree, hf_index, tvb, old_offset>>3, 0, length);
596 proto_item_append_text(item, (length==1)?" item":" items");
597 } else {
598 item=proto_tree_add_item(parent_tree, hf_index, tvb, old_offset>>3, 0, ENC_BIG_ENDIAN);
599 }
600 tree=proto_item_add_subtree(item, ett_index);
601
602 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
603
604
605 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
606 return offset;
607 }
608
609
610 /* XXX we don't do >64k length strings yet */
611 static guint32
dissect_per_restricted_character_string_sorted(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_,guint16 lb _U_,guint16 ub,const char * alphabet,int alphabet_length,tvbuff_t ** value_tvb)612 dissect_per_restricted_character_string_sorted(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_, guint16 lb _U_, guint16 ub, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
613 {
614 guint32 length;
615 gboolean byte_aligned, use_canonical_order;
616 guint8 *buf;
617 guint char_pos;
618 int bits_per_char;
619 guint32 old_offset;
620
621 DEBUG_ENTRY("dissect_per_restricted_character_string");
622
623 /* xx.x if the length is 0 bytes there will be no encoding */
624 if(max_len==0){
625 if (value_tvb) {
626 *value_tvb = tvb_new_child_real_data(tvb, NULL, 0, 0);
627 }
628 return offset;
629 }
630
631
632 if (min_len == NO_BOUND) {
633 min_len=0;
634 }
635
636
637 /* 27.5.2 depending of the alphabet length, find how many bits
638 are used to encode each character */
639 /* unaligned PER */
640 if (actx->aligned){
641
642 if(alphabet_length<=2){
643 bits_per_char=1;
644 } else if(alphabet_length<=4){
645 bits_per_char=2;
646 } else if(alphabet_length<=16){
647 bits_per_char=4;
648 } else {
649 bits_per_char=8;
650 }
651 }else{
652 if(alphabet_length<=2){
653 bits_per_char=1;
654 } else if(alphabet_length<=4){
655 bits_per_char=2;
656 } else if(alphabet_length<=8){
657 bits_per_char=3;
658 } else if(alphabet_length<=16){
659 bits_per_char=4;
660 } else if(alphabet_length<=32){
661 bits_per_char=5;
662 } else if(alphabet_length<=64){
663 bits_per_char=6;
664 } else if(alphabet_length<=128){
665 bits_per_char=7;
666 } else {
667 bits_per_char=8;
668 }
669 }
670 /* 27.4 If the type is extensible for PER encodings (see 9.3.16),
671 * then a bit-field consisting of a single bit shall be added to the field-list.
672 * The single bit shall be set to zero if the value is within the range of the extension root,
673 * and to one otherwise. If the value is outside the range of the extension root,
674 * then the following encoding shall be as if there was no effective size constraint,
675 * and shall have an effective permitted-alphabet constraint that consists of the set of characters
676 * of the unconstrained type.
677 * NOTE - Only the known-multiplier character string types can be extensible for PER encodings.
678 * Extensibility markers on other character string types do not affect the PER encoding.
679 */
680
681 if (has_extension) {
682 gboolean extension_present;
683 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
684 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
685 if(extension_present){
686 min_len = NO_BOUND;
687 max_len = NO_BOUND;
688 }
689 }
690
691 byte_aligned=TRUE;
692 if((min_len==max_len)&&(max_len<=2)){
693 byte_aligned=FALSE;
694 }
695 if ((max_len != NO_BOUND) && (max_len < 2)) {
696 byte_aligned=FALSE;
697 }
698
699 /* xx.x */
700 length=max_len;
701 if (max_len == NO_BOUND) {
702 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_octet_string_length, &length, NULL);
703 /* the unconstrained strings are always byte aligned (27.6.3)*/
704 byte_aligned=TRUE;
705 } else if(min_len!=max_len){
706 offset=dissect_per_constrained_integer(tvb, offset, actx,
707 tree, hf_per_octet_string_length, min_len, max_len,
708 &length, FALSE);
709 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
710 }
711
712 if(!length){
713 /* there is no string at all, so don't do any byte alignment */
714 /* byte_aligned=FALSE; */
715 /* Advance offset to next 'element' */
716 offset = offset + 1; }
717
718 if((byte_aligned)&&(actx->aligned)){
719 BYTE_ALIGN_OFFSET(offset);
720 }
721
722 /* 30.5: if "ub" is less than or equal to 2^b-1, then "v" is the value specified in above , else
723 the characters are placed in the canonical order defined in ITU-T Rec. X.680 | ISO/IEC 8824-1,
724 clause 43. The first is assigned the value zero and the next in canonical order is assigned a value
725 that is one greater than the value assigned to the previous character in the canonical order. These are the values "v" */
726 use_canonical_order = (ub <= ((guint16)(1<<bits_per_char)-1)) ? FALSE : TRUE;
727
728 buf = (guint8 *)wmem_alloc(actx->pinfo->pool, length+1);
729 old_offset=offset;
730 for(char_pos=0;char_pos<length;char_pos++){
731 guchar val;
732 int i;
733 gboolean bit;
734
735 val=0;
736 for(i=0;i<bits_per_char;i++){
737 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
738 val=(val<<1)|bit;
739 }
740 if(use_canonical_order == FALSE){
741 buf[char_pos]=val;
742 } else {
743 if (val < alphabet_length){
744 buf[char_pos]=alphabet[val];
745 } else {
746 buf[char_pos] = '?'; /* XXX - how to mark this? */
747 }
748 }
749 }
750 buf[char_pos]=0;
751 proto_tree_add_string(tree, hf_index, tvb, (old_offset>>3), (offset>>3)-(old_offset>>3), (char*)buf);
752 if (value_tvb) {
753 *value_tvb = tvb_new_child_real_data(tvb, buf, length, length);
754 }
755 return offset;
756 }
757
758 static const char*
sort_alphabet(char * sorted_alphabet,const char * alphabet,int alphabet_length)759 sort_alphabet(char *sorted_alphabet, const char *alphabet, int alphabet_length)
760 {
761 int i, j;
762 guchar c, c_max, c_min;
763 char tmp_buf[256];
764
765 /*
766 * XXX - presumably all members of alphabet will be in the
767 * range 0 to 127.
768 */
769 if (!alphabet_length) return sorted_alphabet;
770 memset(tmp_buf, 0, 256);
771 c_min = c_max = (guchar)alphabet[0];
772 for (i=0; i<alphabet_length; i++) {
773 c = (guchar)alphabet[i];
774 tmp_buf[c] = 1;
775 if (c > c_max) c_max = c;
776 else if (c < c_min) c_min = c;
777 }
778 for (i=c_min,j=0; i<=c_max; i++) {
779 if (tmp_buf[i]) sorted_alphabet[j++] = i;
780 }
781 return sorted_alphabet;
782 }
783
784 guint32
dissect_per_restricted_character_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,const char * alphabet,int alphabet_length,tvbuff_t ** value_tvb)785 dissect_per_restricted_character_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, const char *alphabet, int alphabet_length, tvbuff_t **value_tvb)
786 {
787 const char *alphabet_ptr;
788 char sorted_alphabet[128];
789
790 if (alphabet_length > 127) {
791 alphabet_ptr = alphabet;
792 } else {
793 alphabet_ptr = sort_alphabet(sorted_alphabet, alphabet, alphabet_length);
794 }
795 /* Not a known-multiplier character string: enforce lb and ub to max values */
796 return dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, 0, 65535, alphabet_ptr, alphabet_length, value_tvb);
797 }
798
799 guint32
dissect_per_IA5String(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)800 dissect_per_IA5String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
801 {
802 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
803 0, 127, NULL, 128, NULL);
804
805 return offset;
806 }
807
808 guint32
dissect_per_NumericString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)809 dissect_per_NumericString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
810 {
811 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
812 32, 57, " 0123456789", 11, NULL);
813
814 return offset;
815 }
816 guint32
dissect_per_PrintableString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)817 dissect_per_PrintableString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
818 {
819 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
820 32, 122, " '()+,-.*0123456789:=?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 74, NULL);
821 return offset;
822 }
823 guint32
dissect_per_VisibleString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension)824 dissect_per_VisibleString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension)
825 {
826 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension,
827 32, 126, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 95, NULL);
828 return offset;
829 }
830 guint32
dissect_per_BMPString(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_)831 dissect_per_BMPString(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
832 {
833 guint32 length;
834
835 /* xx.x if the length is 0 bytes there will be no encoding */
836 if(max_len==0){
837 return offset;
838 }
839
840
841 if (min_len == NO_BOUND) {
842 min_len = 0;
843 }
844
845
846 /* xx.x */
847 length=max_len;
848 if(min_len!=max_len){
849 offset=dissect_per_constrained_integer(tvb, offset, actx,
850 tree, hf_per_octet_string_length, min_len, max_len,
851 &length, FALSE);
852 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
853 }
854
855
856 /* align to byte boundary */
857 BYTE_ALIGN_OFFSET(offset);
858
859 if(length>=1024){
860 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "BMPString too long");
861 length=1024;
862 }
863
864 proto_tree_add_item(tree, hf_index, tvb, offset>>3, length*2, ENC_UCS_2|ENC_BIG_ENDIAN);
865
866 offset+=(length<<3)*2;
867
868 return offset;
869 }
870 guint32
dissect_per_UTF8String(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension _U_)871 dissect_per_UTF8String(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension _U_)
872 {
873 offset=dissect_per_restricted_character_string_sorted(tvb, offset, actx, tree,
874 hf_index, min_len, max_len, has_extension, 0, 255, NULL, 256, NULL);
875 return offset;
876 }
877
878 guint32
dissect_per_object_descriptor(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)879 dissect_per_object_descriptor(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
880 {
881 offset=dissect_per_octet_string(tvb, offset, actx, tree, hf_index, -1, -1, FALSE, value_tvb);
882
883 return offset;
884 }
885
886
887 /* this function dissects a constrained sequence of */
888 guint32
dissect_per_constrained_sequence_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq,int min_len,int max_len,gboolean has_extension _U_)889 dissect_per_constrained_sequence_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension _U_)
890 {
891 proto_item *item;
892 proto_tree *tree;
893 guint32 old_offset=offset;
894 guint32 length;
895 header_field_info *hfi;
896
897 DEBUG_ENTRY("dissect_per_constrained_sequence_of");
898
899 /* 19.4 If there is a PER-visible constraint and an extension marker is present in it,
900 * a single bit shall be added to the field-list in a bit-field of length one
901 */
902 if (has_extension) {
903 gboolean extension_present;
904 offset=dissect_per_boolean(tvb, offset, actx, parent_tree, hf_per_extension_present_bit, &extension_present);
905 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
906 if (extension_present){
907 /* 10.9 shall be invoked to add the length determinant as a semi-constrained whole number to the field-list,
908 * followed by the component values
909 */
910 offset = dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
911 goto call_sohelper;
912 }
913 }
914
915 /* 19.5 if min==max and min,max<64k ==> no length determinant */
916 if((min_len==max_len) && (min_len<65536)){
917 length=min_len;
918 goto call_sohelper;
919 }
920
921 /* 19.6 ub>=64k or unset */
922 if ((max_len >= 65536) || (max_len == NO_BOUND)) {
923 /* no constraint, see 10.9.4.2 */
924 offset=dissect_per_length_determinant(tvb, offset, actx, parent_tree, hf_per_sequence_of_length, &length, NULL);
925 goto call_sohelper;
926 }
927
928 /* constrained whole number for number of elements */
929 offset=dissect_per_constrained_integer(tvb, offset, actx,
930 parent_tree, hf_per_sequence_of_length, min_len, max_len,
931 &length, FALSE);
932 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
933
934 call_sohelper:
935 hfi = proto_registrar_get_nth(hf_index);
936 if (IS_FT_UINT(hfi->type)) {
937 item = proto_tree_add_uint(parent_tree, hf_index, tvb, offset>>3, 0, length);
938 proto_item_append_text(item, (length==1)?" item":" items");
939 } else {
940 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
941 }
942 tree=proto_item_add_subtree(item, ett_index);
943 per_check_items(length, min_len, max_len, actx, item);
944
945 old_offset = offset;
946 offset=dissect_per_sequence_of_helper(tvb, offset, actx, tree, seq->func, *seq->p_id, length);
947
948 if (offset == old_offset)
949 length = 0;
950 else if (offset >> 3 == old_offset >> 3)
951 length = 1;
952 else
953 length = (offset >> 3) - (old_offset >> 3);
954
955 proto_item_set_len(item, length);
956 return offset;
957 }
958
959 /* this function dissects a constrained set of */
960 guint32
dissect_per_constrained_set_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq,int min_len,int max_len,gboolean has_extension)961 dissect_per_constrained_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq, int min_len, int max_len, gboolean has_extension)
962 {
963 /* for basic-per a set-of is encoded in the same way as a sequence-of */
964 DEBUG_ENTRY("dissect_per_constrained_set_of");
965 offset=dissect_per_constrained_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq, min_len, max_len, has_extension);
966 return offset;
967 }
968
969
970
971
972
973
974 /* this function dissects a set of */
975 guint32
dissect_per_set_of(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * seq)976 dissect_per_set_of(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *seq)
977 {
978 /* for basic-per a set-of is encoded in the same way as a sequence-of */
979 DEBUG_ENTRY("dissect_per_set_of");
980 offset=dissect_per_sequence_of(tvb, offset, actx, parent_tree, hf_index, ett_index, seq);
981 return offset;
982 }
983
984
985
986
987 /* 23 Encoding the object identifier type */
988 static guint32
dissect_per_any_oid(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb,gboolean is_absolute)989 dissect_per_any_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb,
990 gboolean is_absolute)
991 {
992 guint length;
993 const char *str;
994 tvbuff_t *val_tvb = NULL;
995 header_field_info *hfi;
996
997 DEBUG_ENTRY("dissect_per_any_oid");
998
999 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_object_identifier_length, &length, NULL);
1000 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1001 val_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
1002 /* Add new data source if the offet was unaligned */
1003 if ((offset & 7) != 0) {
1004 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
1005 }
1006
1007 hfi = proto_registrar_get_nth(hf_index);
1008 if ((is_absolute && hfi->type == FT_OID) || (is_absolute && hfi->type == FT_REL_OID)) {
1009 actx->created_item = proto_tree_add_item(tree, hf_index, val_tvb, 0, length, ENC_BIG_ENDIAN);
1010 } else if (IS_FT_STRING(hfi->type)) {
1011 str = oid_encoded2string(wmem_packet_scope(), tvb_get_ptr(val_tvb, 0, length), length);
1012 actx->created_item = proto_tree_add_string(tree, hf_index, val_tvb, 0, length, str);
1013 } else {
1014 DISSECTOR_ASSERT_NOT_REACHED();
1015 }
1016
1017 if (value_tvb) *value_tvb = val_tvb;
1018
1019 offset += 8 * length;
1020
1021 return offset;
1022 }
1023
1024 guint32
dissect_per_object_identifier(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)1025 dissect_per_object_identifier(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
1026 {
1027 return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, TRUE);
1028 }
1029
1030 guint32
dissect_per_relative_oid(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,tvbuff_t ** value_tvb)1031 dissect_per_relative_oid(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, tvbuff_t **value_tvb)
1032 {
1033 return dissect_per_any_oid(tvb, offset, actx, tree, hf_index, value_tvb, FALSE);
1034 }
1035
1036 static guint32
dissect_per_any_oid_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx,gboolean is_absolute)1037 dissect_per_any_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx,
1038 gboolean is_absolute)
1039 {
1040 tvbuff_t *value_tvb = NULL;
1041 guint length;
1042
1043 offset = dissect_per_any_oid(tvb, offset, actx, tree, hf_index, (value_stringx) ? &value_tvb : NULL, is_absolute);
1044
1045 if (value_stringx) {
1046 if (value_tvb && (length = tvb_captured_length(value_tvb))) {
1047 *value_stringx = oid_encoded2string(wmem_packet_scope(), tvb_get_ptr(value_tvb, 0, length), length);
1048 } else {
1049 *value_stringx = "";
1050 }
1051 }
1052
1053 return offset;
1054 }
1055
1056 guint32
dissect_per_object_identifier_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx)1057 dissect_per_object_identifier_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1058 {
1059 return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, TRUE);
1060 }
1061
1062 guint32
dissect_per_relative_oid_str(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,const char ** value_stringx)1063 dissect_per_relative_oid_str(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, const char **value_stringx)
1064 {
1065 return dissect_per_any_oid_str(tvb, offset, actx, tree, hf_index, value_stringx, FALSE);
1066 }
1067
1068
1069 /* this function reads a single bit */
1070 guint32
dissect_per_boolean(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gboolean * bool_val)1071 dissect_per_boolean(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gboolean *bool_val)
1072 {
1073 guint8 ch, mask;
1074 gboolean value;
1075 header_field_info *hfi;
1076
1077 DEBUG_ENTRY("dissect_per_boolean");
1078
1079 ch=tvb_get_guint8(tvb, offset>>3);
1080 mask=1<<(7-(offset&0x07));
1081 if(ch&mask){
1082 value=1;
1083 } else {
1084 value=0;
1085 }
1086 if(hf_index!=-1){
1087 char bits[10];
1088 bits[0] = mask&0x80?'0'+value:'.';
1089 bits[1] = mask&0x40?'0'+value:'.';
1090 bits[2] = mask&0x20?'0'+value:'.';
1091 bits[3] = mask&0x10?'0'+value:'.';
1092 bits[4] = ' ';
1093 bits[5] = mask&0x08?'0'+value:'.';
1094 bits[6] = mask&0x04?'0'+value:'.';
1095 bits[7] = mask&0x02?'0'+value:'.';
1096 bits[8] = mask&0x01?'0'+value:'.';
1097 bits[9] = '\0';
1098
1099 hfi = proto_registrar_get_nth(hf_index);
1100 actx->created_item = proto_tree_add_boolean_format(tree, hf_index, tvb, offset>>3, 1, value,
1101 "%s %s: %s", bits, hfi->name,
1102 value?"True":"False");
1103 } else {
1104 actx->created_item = NULL;
1105 }
1106
1107 if(bool_val){
1108 *bool_val=value;
1109 }
1110 return offset+1;
1111 }
1112
1113
1114
1115
1116 /* we currently only handle integers up to 32 bits in length. */
1117 guint32
dissect_per_integer(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint32 * value)1118 dissect_per_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint32 *value)
1119 {
1120 guint32 i, length;
1121 guint32 val;
1122 tvbuff_t *val_tvb=NULL;
1123 proto_item *it=NULL;
1124 header_field_info *hfi;
1125
1126 /* 12.2.6 b */
1127 offset=dissect_per_length_determinant(tvb, offset, actx, tree,hf_per_integer_length, &length, NULL);
1128 /* gassert here? */
1129 if(length>4){
1130 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer(per_integer)");
1131 length=4;
1132 }
1133
1134 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1135 val_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
1136 val=0;
1137 for(i=0;i<length;i++){
1138 if(i==0){
1139 if(tvb_get_guint8(val_tvb, i)&0x80){
1140 /* negative number */
1141 val=0xffffffff;
1142 } else {
1143 /* positive number */
1144 val=0;
1145 }
1146 }
1147 val=(val<<8)|tvb_get_guint8(val_tvb,i);
1148 }
1149 offset += length * 8;
1150
1151 hfi = proto_registrar_get_nth(hf_index);
1152 if (! hfi)
1153 THROW(ReportedBoundsError);
1154 if (IS_FT_INT(hfi->type)) {
1155 it=proto_tree_add_int(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1156 } else if (IS_FT_UINT(hfi->type)) {
1157 it=proto_tree_add_uint(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1158 } else {
1159 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_field_not_integer, tvb, (offset>>3)-(length+1), length+1,
1160 "Field is not an integer: %s", hfi->abbrev);
1161 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1162 }
1163
1164
1165 actx->created_item = it;
1166
1167 if(value){
1168 *value=val;
1169 }
1170
1171 return offset;
1172 }
1173 /* 64 bits experimental version, internal for now */
1174 static guint32
dissect_per_integer64b(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint64 * value)1175 dissect_per_integer64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint64 *value)
1176 {
1177 guint32 i, length;
1178 guint64 val;
1179 proto_item *it=NULL;
1180 header_field_info *hfi;
1181
1182 /* 12.2.6 b */
1183 offset=dissect_per_length_determinant(tvb, offset, actx, tree, -1, &length, NULL);
1184 /* gassert here? */
1185 if(length>8){
1186 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too long integer (64b)");
1187 length=8;
1188 }
1189
1190 val=0;
1191 for(i=0;i<length;i++){
1192 if(i==0){
1193 if(tvb_get_guint8(tvb, offset>>3)&0x80){
1194 /* negative number */
1195 val=G_GUINT64_CONSTANT(0xffffffffffffffff);
1196 } else {
1197 /* positive number */
1198 val=0;
1199 }
1200 }
1201 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1202 offset+=8;
1203 }
1204
1205 hfi = proto_registrar_get_nth(hf_index);
1206 if (! hfi)
1207 THROW(ReportedBoundsError);
1208 if (IS_FT_INT(hfi->type)) {
1209 it=proto_tree_add_int64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, (gint64)val);
1210 } else if (IS_FT_UINT(hfi->type)) {
1211 it=proto_tree_add_uint64(tree, hf_index, tvb, (offset>>3)-(length+1), length+1, val);
1212 } else {
1213 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_field_not_integer, tvb, (offset>>3)-(length+1), length+1,
1214 "Field is not an integer: %s", hfi->abbrev);
1215 REPORT_DISSECTOR_BUG("PER integer field that's not an FT_INT* or FT_UINT*");
1216 }
1217
1218
1219 actx->created_item = it;
1220
1221 if(value){
1222 *value=(gint64)val;
1223 }
1224
1225 return offset;
1226 }
1227 /* this function reads a constrained integer with or without a
1228 PER visible extension marker present
1229
1230 has_extension==TRUE would map to asn constructs such as:
1231 rfc-number INTEGER (1..32768, ...)
1232 while has_extension==FALSE would map to:
1233 t35CountryCode INTEGER (0..255)
1234
1235 it only handles integers that fit inside a 32 bit integer
1236 10.5.1 info only
1237 10.5.2 info only
1238 10.5.3 range=ub-lb+1
1239 10.5.4 empty range
1240 10.5.5 info only
1241 10.5.6 unaligned version
1242 10.5.7 aligned version
1243 10.5.7.1 decoding of 0-255 1-8 bits
1244 10.5.7.2 decoding og 0-256 8 bits
1245 10.5.7.3 decoding of 0-65535 16 bits
1246 10.5.7.4
1247 */
1248 guint32
dissect_per_constrained_integer(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 min,guint32 max,guint32 * value,gboolean has_extension)1249 dissect_per_constrained_integer(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 min, guint32 max, guint32 *value, gboolean has_extension)
1250 {
1251 proto_item *it=NULL;
1252 guint32 range, val;
1253 gint val_start, val_length;
1254 nstime_t timeval;
1255 header_field_info *hfi;
1256 int num_bits;
1257
1258 DEBUG_ENTRY("dissect_per_constrained_integer");
1259 if(has_extension){
1260 gboolean extension_present;
1261 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1262 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1263 if(extension_present){
1264 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, (gint32*)value);
1265 return offset;
1266 }
1267 }
1268
1269 hfi = proto_registrar_get_nth(hf_index);
1270
1271 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1272 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1273 * d) "range" is greater than 64K (the indefinite length case).
1274 */
1275 if(((max-min)>65536)&&(actx->aligned)){
1276 /* just set range really big so it will fall through
1277 to the bottom of the encoding */
1278 range=1000000;
1279 } else {
1280 /* Really ugly hack.
1281 * We should really use guint64 as parameters for min/max.
1282 * This is to prevent range from being 0 if
1283 * the range for a signed integer spans the entire 32 bit range.
1284 * Special case the 2 common cases when this can happen until
1285 * a real fix is implemented.
1286 */
1287 if( (max==0x7fffffff && min==0x80000000)
1288 || (max==0xffffffff && min==0x00000000) ){
1289 range=0xffffffff;
1290 } else {
1291 range=max-min+1;
1292 }
1293 }
1294
1295 val=0;
1296 timeval.secs=val; timeval.nsecs=0;
1297 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1298
1299 /* something is really wrong if range is 0 */
1300 DISSECTOR_ASSERT(range!=0);
1301
1302 if(range==1){
1303 val_start = offset>>3; val_length = 0;
1304 val = min;
1305 } else if((range<=255)||(!actx->aligned)) {
1306 /* 10.5.7.1
1307 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1308 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1309 * number of bits necessary to represent the range.
1310 */
1311 char *str;
1312 int i, length;
1313 guint32 mask,mask2;
1314 /* We only handle 32 bit integers */
1315 mask = 0x80000000;
1316 mask2 = 0x7fffffff;
1317 i = 32;
1318 while ((range & mask)== 0){
1319 i = i - 1;
1320 mask = mask>>1;
1321 mask2 = mask2>>1;
1322 }
1323 if ((range & mask2) == 0)
1324 i = i-1;
1325
1326 num_bits = i;
1327 length=(num_bits+7)>>3;
1328 if(range<=2){
1329 num_bits=1;
1330 }
1331
1332 val_start = (offset)>>3;
1333 val_length = length;
1334 val = (guint32)tvb_get_bits64(tvb,offset,num_bits,ENC_BIG_ENDIAN);
1335
1336 if (display_internal_per_fields){
1337 str = decode_bits_in_field(actx->pinfo->pool, (offset&0x07),num_bits,val,ENC_BIG_ENDIAN);
1338 proto_tree_add_uint(tree, hf_per_internal_min, tvb, val_start,val_length, min);
1339 proto_tree_add_uint64(tree, hf_per_internal_range, tvb, val_start, val_length, range);
1340 proto_tree_add_uint(tree, hf_per_internal_num_bits, tvb, val_start, val_length, num_bits);
1341 proto_tree_add_uint64_format_value(tree, hf_per_internal_value, tvb, val_start, val_length, val+min, "%s decimal value: %u", str, val+min);
1342 }
1343 /* The actual value */
1344 val+=min;
1345 offset = offset+num_bits;
1346 } else if(range==256){
1347 /* 10.5.7.2 */
1348
1349 /* in the aligned case, align to byte boundary */
1350 BYTE_ALIGN_OFFSET(offset);
1351 val=tvb_get_guint8(tvb, offset>>3);
1352 offset+=8;
1353
1354 val_start = (offset>>3)-1; val_length = 1;
1355 val+=min;
1356 } else if(range<=65536){
1357 /* 10.5.7.3 */
1358
1359 /* in the aligned case, align to byte boundary */
1360 BYTE_ALIGN_OFFSET(offset);
1361 val=tvb_get_guint8(tvb, offset>>3);
1362 val<<=8;
1363 offset+=8;
1364 val|=tvb_get_guint8(tvb, offset>>3);
1365 offset+=8;
1366
1367 val_start = (offset>>3)-2; val_length = 2;
1368 val+=min;
1369 } else {
1370 int i,num_bytes;
1371 gboolean bit;
1372
1373 /* 10.5.7.4 */
1374 /* 12.2.6 */
1375 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1376 num_bytes=bit;
1377 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &bit);
1378 num_bytes=(num_bytes<<1)|bit;
1379
1380 num_bytes++; /* lower bound for length determinant is 1 */
1381 if (display_internal_per_fields)
1382 proto_tree_add_uint(tree, hf_per_const_int_len, tvb, (offset>>3), 1, num_bytes);
1383
1384 /* byte aligned */
1385 BYTE_ALIGN_OFFSET(offset);
1386 val=0;
1387 for(i=0;i<num_bytes;i++){
1388 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1389 offset+=8;
1390 }
1391 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1392 val+=min;
1393 }
1394
1395 timeval.secs = val;
1396 if (IS_FT_UINT(hfi->type)) {
1397 it = proto_tree_add_uint(tree, hf_index, tvb, val_start, val_length, val);
1398 per_check_value(val, min, max, actx, it, FALSE);
1399 } else if (IS_FT_INT(hfi->type)) {
1400 it = proto_tree_add_int(tree, hf_index, tvb, val_start, val_length, val);
1401 per_check_value(val, min, max, actx, it, TRUE);
1402 } else if (IS_FT_TIME(hfi->type)) {
1403 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1404 } else {
1405 THROW(ReportedBoundsError);
1406 }
1407 actx->created_item = it;
1408 if (value) *value = val;
1409 return offset;
1410 }
1411
1412 guint32
dissect_per_constrained_integer_64b(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint64 min,guint64 max,guint64 * value,gboolean has_extension)1413 dissect_per_constrained_integer_64b(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint64 min, guint64 max, guint64 *value, gboolean has_extension)
1414 {
1415 proto_item *it=NULL, *int_item=NULL;
1416 guint64 range, val;
1417 gint val_start, val_length;
1418 nstime_t timeval;
1419 header_field_info *hfi;
1420 int num_bits;
1421 gboolean tmp;
1422
1423 DEBUG_ENTRY("dissect_per_constrained_integer_64b");
1424 if(has_extension){
1425 gboolean extension_present;
1426 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1427 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1428 if(extension_present){
1429 offset = dissect_per_integer64b(tvb, offset, actx, tree, hf_index, (gint64*)value);
1430 return offset;
1431 }
1432 }
1433
1434 hfi = proto_registrar_get_nth(hf_index);
1435
1436 /* 10.5.3 Let "range" be defined as the integer value ("ub" - "lb" 1), and let the value to be encoded be "n".
1437 * 10.5.7 In the case of the ALIGNED variant the encoding depends on whether
1438 * d) "range" is greater than 64K (the indefinite length case).
1439 */
1440 if(((max-min)>65536)&&(actx->aligned)){
1441 /* just set range really big so it will fall through
1442 to the bottom of the encoding */
1443 /* range=1000000; */
1444 range = max-min;
1445 if (range==65536)
1446 range++; /* make it fall trough? */
1447 } else {
1448 /* Copied from the 32 bit version, assuming the same problem occurs
1449 * at 64 bit boundary.
1450 * Really ugly hack.
1451 * We should really use guint64 as parameters for min/max.
1452 * This is to prevent range from being 0 if
1453 * the range for a signed integer spans the entire 32 bit range.
1454 * Special case the 2 common cases when this can happen until
1455 * a real fix is implemented.
1456 */
1457 if( (max==G_GINT64_CONSTANT(0x7fffffffffffffff) && min==G_GINT64_CONSTANT(0x8000000000000000))
1458 || (max==G_GINT64_CONSTANT(0xffffffffffffffff) && min==0) ){
1459 range=G_GINT64_CONSTANT(0xffffffffffffffff);
1460 } else {
1461 range=max-min+1;
1462 }
1463 }
1464
1465 val=0;
1466 timeval.secs=0; timeval.nsecs=0;
1467 /* 10.5.4 If "range" has the value 1, then the result of the encoding shall be an empty bit-field (no bits).*/
1468
1469 /* something is really wrong if range is 0 */
1470 DISSECTOR_ASSERT(range!=0);
1471
1472 if(range==1){
1473 val_start = offset>>3; val_length = 0;
1474 val = min;
1475 } else if((range<=255)||(!actx->aligned)) {
1476 /* 10.5.7.1
1477 * 10.5.6 In the case of the UNALIGNED variant the value ("n" - "lb") shall be encoded
1478 * as a non-negative binary integer in a bit field as specified in 10.3 with the minimum
1479 * number of bits necessary to represent the range.
1480 */
1481 char *str;
1482 int i, bit, length, str_length, str_index = 0;
1483 guint64 mask,mask2;
1484 /* We only handle 64 bit integers */
1485 mask = G_GUINT64_CONSTANT(0x8000000000000000);
1486 mask2 = G_GUINT64_CONSTANT(0x7fffffffffffffff);
1487 i = 64;
1488 while ((range & mask)== 0){
1489 i = i - 1;
1490 mask = mask>>1;
1491 mask2 = mask2>>1;
1492 }
1493 if ((range & mask2) == 0)
1494 i = i-1;
1495
1496 num_bits = i;
1497 length=1;
1498 if(range<=2){
1499 num_bits=1;
1500 }
1501
1502 /* prepare the string (max number of bits + quartet separators) */
1503 str_length = 512+128;
1504 str = (char *)wmem_alloc(wmem_packet_scope(), str_length+1);
1505 for(bit=0;bit<((int)(offset&0x07));bit++){
1506 if(bit&&(!(bit%4))){
1507 if (str_index < str_length) str[str_index++] = ' ';
1508 }
1509 if (str_index < str_length) str[str_index++] = '.';
1510 }
1511 /* read the bits for the int */
1512 for(i=0;i<num_bits;i++){
1513 if(bit&&(!(bit%4))){
1514 if (str_index < str_length) str[str_index++] = ' ';
1515 }
1516 if(bit&&(!(bit%8))){
1517 length+=1;
1518 if (str_index < str_length) str[str_index++] = ' ';
1519 }
1520 bit++;
1521 offset=dissect_per_boolean(tvb, offset, actx, tree, -1, &tmp);
1522 val<<=1;
1523 if(tmp){
1524 val|=1;
1525 if (str_index < str_length) str[str_index++] = '1';
1526 } else {
1527 if (str_index < str_length) str[str_index++] = '0';
1528 }
1529 }
1530 for(;bit%8;bit++){
1531 if(bit&&(!(bit%4))){
1532 if (str_index < str_length) str[str_index++] = ' ';
1533 }
1534 if (str_index < str_length) str[str_index++] = '.';
1535 }
1536 str[str_index] = '\0'; /* Terminate string */
1537 val_start = (offset-num_bits)>>3; val_length = length;
1538 val+=min;
1539 if (display_internal_per_fields) {
1540 proto_tree_add_uint64(tree, hf_per_internal_range, tvb, val_start, val_length, range);
1541 proto_tree_add_uint(tree, hf_per_internal_num_bits, tvb, val_start,val_length, num_bits);
1542 proto_tree_add_uint64_format_value(tree, hf_per_internal_value, tvb, val_start, val_length, val, "%s decimal value: %" G_GINT64_MODIFIER "u", str, val);
1543 }
1544 } else if(range==256){
1545 /* 10.5.7.2 */
1546
1547 /* in the aligned case, align to byte boundary */
1548 BYTE_ALIGN_OFFSET(offset);
1549 val=tvb_get_guint8(tvb, offset>>3);
1550 offset+=8;
1551
1552 val_start = (offset>>3)-1; val_length = 1;
1553 val+=min;
1554 } else if(range<=65536){
1555 /* 10.5.7.3 */
1556
1557 /* in the aligned case, align to byte boundary */
1558 BYTE_ALIGN_OFFSET(offset);
1559 val=tvb_get_guint8(tvb, offset>>3);
1560 val<<=8;
1561 offset+=8;
1562 val|=tvb_get_guint8(tvb, offset>>3);
1563 offset+=8;
1564
1565 val_start = (offset>>3)-2; val_length = 2;
1566 val+=min;
1567 } else {
1568 int i,num_bytes,n_bits;
1569
1570 /* 10.5.7.4 */
1571 /* 12.2.6 */
1572 /* calculate the number of bits to hold the length */
1573 if ((range & G_GINT64_CONSTANT(0xffffffff00000000)) != 0){
1574 n_bits=3;
1575 }else{
1576 n_bits=2;
1577 }
1578 num_bytes =tvb_get_bits8(tvb, offset, n_bits);
1579 num_bytes++; /* lower bound for length determinant is 1 */
1580 if (display_internal_per_fields){
1581 int_item = proto_tree_add_bits_item(tree, hf_per_const_int_len, tvb, offset,n_bits, ENC_BIG_ENDIAN);
1582 proto_item_append_text(int_item,"+1=%u bytes, Range = (%" G_GINT64_MODIFIER "u)",num_bytes, range);
1583 }
1584 offset = offset+n_bits;
1585 /* byte aligned */
1586 BYTE_ALIGN_OFFSET(offset);
1587 val=0;
1588 for(i=0;i<num_bytes;i++){
1589 val=(val<<8)|tvb_get_guint8(tvb,offset>>3);
1590 offset+=8;
1591 }
1592 val_start = (offset>>3)-(num_bytes+1); val_length = num_bytes+1;
1593 val+=min;
1594 }
1595
1596
1597 if (IS_FT_UINT(hfi->type)) {
1598 it = proto_tree_add_uint64(tree, hf_index, tvb, val_start, val_length, val);
1599 per_check_value64(val, min, max, actx, it, FALSE);
1600 } else if (IS_FT_INT(hfi->type)) {
1601 it = proto_tree_add_int64(tree, hf_index, tvb, val_start, val_length, val);
1602 per_check_value64(val, min, max, actx, it, TRUE);
1603 } else if (IS_FT_TIME(hfi->type)) {
1604 timeval.secs = (guint32)val;
1605 it = proto_tree_add_time(tree, hf_index, tvb, val_start, val_length, &timeval);
1606 } else {
1607 THROW(ReportedBoundsError);
1608 }
1609 actx->created_item = it;
1610 if (value) *value = val;
1611 return offset;
1612 }
1613
1614 /* 13 Encoding the enumerated type */
1615 guint32
dissect_per_enumerated(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,guint32 root_num,guint32 * value,gboolean has_extension,guint32 ext_num,guint32 * value_map)1616 dissect_per_enumerated(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, guint32 root_num, guint32 *value, gboolean has_extension, guint32 ext_num, guint32 *value_map)
1617 {
1618
1619 proto_item *it=NULL;
1620 guint32 enum_index, val;
1621 guint32 start_offset = offset;
1622 gboolean extension_present = FALSE;
1623 header_field_info *hfi;
1624
1625 if (has_extension) {
1626 /* Extension bit */
1627 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
1628 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1629 }
1630
1631 if (!extension_present) {
1632 /* 13.2 */
1633 offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_per_enum_index, 0, root_num - 1, &enum_index, FALSE);
1634 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1635 } else {
1636 /* 13.3 ".. and the value shall be added to the field-list as a
1637 * normally small non-negative whole number whose value is the
1638 * enumeration index of the additional enumeration and with "lb" set to 0.."
1639 */
1640 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_enum_extension_index, &enum_index);
1641 enum_index += root_num;
1642 }
1643 val = (value_map && (enum_index<(root_num+ext_num))) ? value_map[enum_index] : enum_index;
1644 hfi = proto_registrar_get_nth(hf_index);
1645 if (IS_FT_UINT(hfi->type)) {
1646 it = proto_tree_add_uint(tree, hf_index, tvb, start_offset>>3, BLEN(start_offset, offset), val);
1647 } else {
1648 THROW(ReportedBoundsError);
1649 }
1650 actx->created_item = it;
1651 if (value) *value = val;
1652 return offset;
1653 }
1654
1655 /* 14 Encoding the real type */
1656 guint32
dissect_per_real(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,double * value)1657 dissect_per_real(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, double *value)
1658 {
1659 guint32 val_length, end_offset;
1660 tvbuff_t *val_tvb;
1661 double val = 0;
1662
1663 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_real_length, &val_length, NULL);
1664 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
1665 val_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
1666 /* Add new data source if the offet was unaligned */
1667 if ((offset & 7) != 0) {
1668 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
1669 }
1670 end_offset = offset + val_length * 8;
1671
1672 val = asn1_get_real(tvb_get_ptr(val_tvb, 0, val_length), val_length);
1673 actx->created_item = proto_tree_add_double(tree, hf_index, val_tvb, 0, val_length, val);
1674
1675 if (value) *value = val;
1676
1677 return end_offset;
1678 }
1679
1680 /* 22 Encoding the choice type */
1681 guint32
dissect_per_choice(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,gint ett_index,const per_choice_t * choice,gint * value)1682 dissect_per_choice(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, gint ett_index, const per_choice_t *choice, gint *value)
1683 {
1684 gboolean /*extension_present,*/ extension_flag;
1685 int extension_root_entries;
1686 int extension_addition_entries;
1687 guint32 choice_index;
1688 int i, idx, cidx;
1689 guint32 ext_length = 0;
1690 guint32 old_offset = offset;
1691 proto_item *choice_item = NULL;
1692 proto_tree *choice_tree = NULL;
1693
1694 DEBUG_ENTRY("dissect_per_choice");
1695
1696 if (value) *value = -1;
1697
1698 /* 22.5 */
1699 if (choice[0].extension == ASN1_NO_EXTENSIONS){
1700 /*extension_present = FALSE; ?? */
1701 extension_flag = FALSE;
1702 } else {
1703 /*extension_present = TRUE; ?? */
1704 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1705 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1706 }
1707
1708 /* count the number of entries in the extension root and extension addition */
1709 extension_root_entries = 0;
1710 extension_addition_entries = 0;
1711 for (i=0; choice[i].p_id; i++) {
1712 switch(choice[i].extension){
1713 case ASN1_NO_EXTENSIONS:
1714 case ASN1_EXTENSION_ROOT:
1715 extension_root_entries++;
1716 break;
1717 case ASN1_NOT_EXTENSION_ROOT:
1718 extension_addition_entries++;
1719 break;
1720 }
1721 }
1722
1723 if (!extension_flag) { /* 22.6, 22.7 */
1724 if (extension_root_entries == 1) { /* 22.5 */
1725 choice_index = 0;
1726 } else {
1727 offset = dissect_per_constrained_integer(tvb, offset, actx,
1728 tree, hf_per_choice_index, 0, extension_root_entries - 1,
1729 &choice_index, FALSE);
1730 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1731 }
1732
1733 idx = -1; cidx = choice_index;
1734 for (i=0; choice[i].p_id; i++) {
1735 if(choice[i].extension != ASN1_NOT_EXTENSION_ROOT){
1736 if (!cidx) { idx = i; break; }
1737 cidx--;
1738 }
1739 }
1740 } else { /* 22.8 */
1741 offset = dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_choice_extension_index, &choice_index);
1742 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &ext_length, NULL);
1743
1744 idx = -1; cidx = choice_index;
1745 for (i=0; choice[i].p_id; i++) {
1746 if(choice[i].extension == ASN1_NOT_EXTENSION_ROOT){
1747 if (!cidx) { idx = i; break; }
1748 cidx--;
1749 }
1750 }
1751 }
1752
1753 if (idx != -1) {
1754 choice_item = proto_tree_add_uint(tree, hf_index, tvb, old_offset>>3, 0, choice[idx].value);
1755 choice_tree = proto_item_add_subtree(choice_item, ett_index);
1756 if (!extension_flag) {
1757 offset = choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1758 } else {
1759 choice[idx].func(tvb, offset, actx, choice_tree, *choice[idx].p_id);
1760 offset += ext_length * 8;
1761 }
1762 proto_item_set_len(choice_item, BLEN(old_offset, offset));
1763 } else {
1764 if (!extension_flag) {
1765 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "unknown extension root index in choice");
1766 } else {
1767 offset += ext_length * 8;
1768 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_choice_extension_unknown,
1769 tvb, old_offset>>3, BLEN(old_offset, offset),
1770 "Choice no. %d in extension", choice_index);
1771 }
1772 }
1773
1774 if (value && (idx != -1))
1775 *value = choice[idx].value;
1776
1777 return offset;
1778 }
1779
1780
1781 static const char *
index_get_optional_name(const per_sequence_t * sequence,int idx)1782 index_get_optional_name(const per_sequence_t *sequence, int idx)
1783 {
1784 int i;
1785 header_field_info *hfi;
1786
1787 for(i=0;sequence[i].p_id;i++){
1788 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1789 if (idx == 0) {
1790 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1791 return (hfi) ? hfi->name : "<unknown filed>";
1792 }
1793 idx--;
1794 }
1795 }
1796 return "<unknown type>";
1797 }
1798
1799 static const char *
index_get_extension_name(const per_sequence_t * sequence,int idx)1800 index_get_extension_name(const per_sequence_t *sequence, int idx)
1801 {
1802 int i;
1803 header_field_info *hfi;
1804
1805 for(i=0;sequence[i].p_id;i++){
1806 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1807 if (idx == 0) {
1808 if (*sequence[i].p_id == -1) return "extension addition group";
1809 hfi = proto_registrar_get_nth(*sequence[i].p_id);
1810 return (hfi) ? hfi->name : "<unknown filed>";
1811 }
1812 idx--;
1813 }
1814 }
1815 return "<unknown type>";
1816 }
1817
1818 static const char *
index_get_field_name(const per_sequence_t * sequence,int idx)1819 index_get_field_name(const per_sequence_t *sequence, int idx)
1820 {
1821 if (sequence) {
1822 header_field_info *hfi = proto_registrar_get_nth(*sequence[idx].p_id);
1823
1824 if (hfi) {
1825 return hfi->name;
1826 }
1827 }
1828 return "<unknown field>";
1829 }
1830
1831 /* this functions decodes a SEQUENCE
1832 it can only handle SEQUENCES with at most 32 DEFAULT or OPTIONAL fields
1833 18.1 extension bit
1834 18.2 optional/default items in root
1835 18.3 we ignore the case where n>64K
1836 18.4 the root sequence
1837 18.5
1838 18.6
1839 18.7
1840 18.8
1841 18.9
1842 */
1843 guint32
dissect_per_sequence(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * parent_tree,int hf_index,gint ett_index,const per_sequence_t * sequence)1844 dissect_per_sequence(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *parent_tree, int hf_index, gint ett_index, const per_sequence_t *sequence)
1845 {
1846 gboolean /*extension_present,*/ extension_flag, optional_field_flag;
1847 proto_item *item;
1848 proto_tree *tree;
1849 guint32 old_offset=offset;
1850 guint32 i, j, num_opts;
1851 guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
1852
1853 DEBUG_ENTRY("dissect_per_sequence");
1854 DISSECTOR_ASSERT(sequence);
1855
1856 item=proto_tree_add_item(parent_tree, hf_index, tvb, offset>>3, 0, ENC_BIG_ENDIAN);
1857 tree=proto_item_add_subtree(item, ett_index);
1858
1859
1860 /* first check if there should be an extension bit for this CHOICE.
1861 we do this by just checking the first choice arm
1862 */
1863 /* 18.1 */
1864 extension_flag=0;
1865 if(sequence[0].extension==ASN1_NO_EXTENSIONS){
1866 /*extension_present=0; ?? */
1867 } else {
1868 /*extension_present=1; ?? */
1869 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_bit, &extension_flag);
1870 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1871 }
1872 /* 18.2 */
1873 num_opts=0;
1874 for(i=0;sequence[i].p_id;i++){
1875 if((sequence[i].extension!=ASN1_NOT_EXTENSION_ROOT)&&(sequence[i].optional==ASN1_OPTIONAL)){
1876 num_opts++;
1877 }
1878 }
1879 if (num_opts > SEQ_MAX_COMPONENTS) {
1880 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
1881 }
1882
1883 memset(optional_mask, 0, sizeof(optional_mask));
1884 for(i=0;i<num_opts;i++){
1885 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
1886 if (tree) {
1887 proto_item_append_text(actx->created_item, " (%s %s present)",
1888 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
1889 }
1890 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1891 if(optional_field_flag){
1892 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
1893 }
1894 }
1895
1896
1897 /* 18.4 */
1898 for(i=0,j=0;sequence[i].p_id;i++){
1899 if( (sequence[i].extension==ASN1_NO_EXTENSIONS)
1900 || (sequence[i].extension==ASN1_EXTENSION_ROOT) ){
1901 if(sequence[i].optional==ASN1_OPTIONAL){
1902 gboolean is_present;
1903 if (num_opts == 0){
1904 continue;
1905 }
1906 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
1907 num_opts--;
1908 j++;
1909 if(!is_present){
1910 continue;
1911 }
1912 }
1913 if(sequence[i].func){
1914 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
1915 } else {
1916 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
1917 }
1918 }
1919 }
1920
1921
1922 if(extension_flag){
1923 gboolean extension_bit;
1924 guint32 num_known_extensions;
1925 guint32 num_extensions;
1926 guint32 extension_mask;
1927
1928 offset=dissect_per_normally_small_nonnegative_whole_number(tvb, offset, actx, tree, hf_per_num_sequence_extensions, &num_extensions);
1929 /* the X.691 standard is VERY unclear here.
1930 there is no mention that the lower bound lb for this
1931 (apparently) semiconstrained value is 1,
1932 apart from the NOTE: comment in 18.8 that this value can
1933 not be 0.
1934 In my book, there is a semantic difference between having
1935 a comment that says that the value can not be zero
1936 and stating that the lb is 1.
1937 I don't know if this is right or not but it makes
1938 some of the very few captures I have decode properly.
1939
1940 It could also be that the captures I have are generated by
1941 a broken implementation.
1942 If this is wrong and you don't report it as a bug
1943 then it won't get fixed!
1944 */
1945 num_extensions+=1;
1946 if (num_extensions > 32) {
1947 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many extensions");
1948 }
1949
1950 extension_mask=0;
1951 for(i=0;i<num_extensions;i++){
1952 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_bit);
1953 if (tree) {
1954 proto_item_append_text(actx->created_item, " (%s %s present)",
1955 index_get_extension_name(sequence, i), extension_bit?"is":"is NOT");
1956 }
1957 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
1958
1959 extension_mask=(extension_mask<<1)|extension_bit;
1960 }
1961
1962 /* find how many extensions we know about */
1963 num_known_extensions=0;
1964 for(i=0;sequence[i].p_id;i++){
1965 if(sequence[i].extension==ASN1_NOT_EXTENSION_ROOT){
1966 num_known_extensions++;
1967 }
1968 }
1969
1970 /* decode the extensions one by one */
1971 for(i=0;i<num_extensions;i++){
1972 guint32 length;
1973 guint32 new_offset;
1974 gint32 difference;
1975 guint32 extension_index;
1976 guint32 k;
1977
1978 if(!((1U<<(num_extensions-1-i))&extension_mask)){
1979 /* this extension is not encoded in this PDU */
1980 continue;
1981 }
1982
1983 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &length, NULL);
1984
1985 if(i>=num_known_extensions){
1986 /* we don't know how to decode this extension */
1987 offset+=length*8;
1988 expert_add_info(actx->pinfo, item, &ei_per_sequence_extension_unknown);
1989 continue;
1990 }
1991
1992 extension_index=0;
1993 for(j=0,k=0;sequence[j].p_id;j++){
1994 if(sequence[j].extension==ASN1_NOT_EXTENSION_ROOT){
1995 if(k==i){
1996 extension_index=j;
1997 break;
1998 }
1999 k++;
2000 }
2001 }
2002
2003 if(sequence[extension_index].func){
2004 new_offset=sequence[extension_index].func(tvb, offset, actx, tree, *sequence[extension_index].p_id);
2005 offset+=length*8;
2006 difference = offset - new_offset;
2007 /* A difference of 7 or less might be byte aligning */
2008 /* Difference could be 8 if open type has no bits and the length is 1 */
2009 if ((length > 1) && (difference > 7)) {
2010 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2011 "Possible encoding error full length not decoded. Open type length %u, decoded %u",length, length - (difference>>3));
2012 }
2013 else if (difference < 0) {
2014 proto_tree_add_expert_format(tree, actx->pinfo, &ei_per_encoding_error, tvb, new_offset>>3, (offset-new_offset)>>3,
2015 "Possible encoding error open type length less than dissected bits. Open type length %u, decoded %u", length, length - (difference>>3));
2016 }
2017 } else {
2018 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, extension_index));
2019 offset+=length*8;
2020 }
2021 }
2022 }
2023
2024 proto_item_set_len(item, (offset>>3)!=(old_offset>>3)?(offset>>3)-(old_offset>>3):1);
2025 actx->created_item = item;
2026 return offset;
2027 }
2028
2029 guint32
dissect_per_sequence_eag(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,const per_sequence_t * sequence)2030 dissect_per_sequence_eag(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, const per_sequence_t *sequence)
2031 {
2032 gboolean optional_field_flag;
2033 guint32 i, j, num_opts;
2034 guint32 optional_mask[SEQ_MAX_COMPONENTS>>5];
2035
2036 DEBUG_ENTRY("dissect_per_sequence_eag");
2037
2038 num_opts=0;
2039 for(i=0;sequence[i].p_id;i++){
2040 if(sequence[i].optional==ASN1_OPTIONAL){
2041 num_opts++;
2042 }
2043 }
2044 if (num_opts > SEQ_MAX_COMPONENTS) {
2045 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, "too many optional/default components");
2046 }
2047
2048 memset(optional_mask, 0, sizeof(optional_mask));
2049 for(i=0;i<num_opts;i++){
2050 offset=dissect_per_boolean(tvb, offset, actx, tree, hf_per_optional_field_bit, &optional_field_flag);
2051 if (tree) {
2052 proto_item_append_text(actx->created_item, " (%s %s present)",
2053 index_get_optional_name(sequence, i), optional_field_flag?"is":"is NOT");
2054 }
2055 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2056 if(optional_field_flag){
2057 optional_mask[i>>5]|=0x80000000>>(i&0x1f);
2058 }
2059 }
2060
2061 for(i=0,j=0;sequence[i].p_id;i++){
2062 if(sequence[i].optional==ASN1_OPTIONAL){
2063 gboolean is_present;
2064 if (num_opts == 0){
2065 continue;
2066 }
2067 is_present=(0x80000000>>(j&0x1f))&optional_mask[j>>5];
2068 num_opts--;
2069 j++;
2070 if(!is_present){
2071 continue;
2072 }
2073 }
2074 if(sequence[i].func){
2075 offset=sequence[i].func(tvb, offset, actx, tree, *sequence[i].p_id);
2076 } else {
2077 dissect_per_not_decoded_yet(tree, actx->pinfo, tvb, index_get_field_name(sequence, i));
2078 }
2079 }
2080
2081 return offset;
2082 }
2083
2084
2085 /* 15 Encoding the bitstring type
2086
2087 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2088
2089 */
2090
dissect_per_bit_string_display(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,header_field_info * hfi,guint32 length,int * const * named_bits,gint num_named_bits _U_)2091 static tvbuff_t *dissect_per_bit_string_display(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, header_field_info *hfi, guint32 length, int * const *named_bits, gint num_named_bits _U_)
2092 {
2093 tvbuff_t *out_tvb = NULL;
2094 guint32 pad_length=0;
2095 guint64 value;
2096
2097 out_tvb = tvb_new_octet_aligned(tvb, offset, length);
2098 add_new_data_source(actx->pinfo, out_tvb, "Bitstring tvb");
2099
2100 if (hfi) {
2101 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, -1, ENC_BIG_ENDIAN);
2102 proto_item_append_text(actx->created_item, " [bit length %u", length);
2103 if (length%8) {
2104 pad_length = 8-(length%8);
2105 proto_item_append_text(actx->created_item, ", %u LSB pad bits", pad_length);
2106 }
2107
2108 if (length<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
2109 if (length<=8) {
2110 value = tvb_get_bits8(out_tvb, 0, length);
2111 }else if (length<=16) {
2112 value = tvb_get_bits16(out_tvb, 0, length, ENC_BIG_ENDIAN);
2113 }else if (length<=24) { /* first read 16 and then the remaining bits */
2114 value = tvb_get_bits16(out_tvb, 0, 16, ENC_BIG_ENDIAN);
2115 value <<= 8 - pad_length;
2116 value |= tvb_get_bits8(out_tvb, 16, length - 16);
2117 }else if (length<=32) {
2118 value = tvb_get_bits32(out_tvb, 0, length, ENC_BIG_ENDIAN);
2119 }else if (length<=40) { /* first read 32 and then the remaining bits */
2120 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2121 value <<= 8 - pad_length;
2122 value |= tvb_get_bits8(out_tvb, 32, length - 32);
2123 }else if (length<=48) { /* first read 32 and then the remaining bits */
2124 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2125 value <<= 16 - pad_length;
2126 value |= tvb_get_bits16(out_tvb, 32, length - 32, ENC_BIG_ENDIAN);
2127 }else if (length<=56) { /* first read 32 and 16 then the remaining bits */
2128 value = tvb_get_bits32(out_tvb, 0, 32, ENC_BIG_ENDIAN);
2129 value <<= 16;
2130 value |= tvb_get_bits16(out_tvb, 32, 16, ENC_BIG_ENDIAN);
2131 value <<= 8 - pad_length;
2132 value |= tvb_get_bits8(out_tvb, 48, length - 48);
2133 }else {
2134 value = tvb_get_bits64(out_tvb, 0, length, ENC_BIG_ENDIAN);
2135 }
2136 proto_item_append_text(actx->created_item, ", %s decimal value %" G_GINT64_MODIFIER "u",
2137 decode_bits_in_field(actx->pinfo->pool, 0, length, value, ENC_BIG_ENDIAN), value);
2138 if (named_bits) {
2139 const guint32 named_bits_bytelen = (num_named_bits + 7) / 8;
2140 proto_tree *subtree = proto_item_add_subtree(actx->created_item, ett_per_named_bits);
2141 for (guint32 i = 0; i < named_bits_bytelen; i++) {
2142 // If less data is available than the number of named bits, then
2143 // the trailing (right) bits are assumed to be 0.
2144 value = 0;
2145 const guint32 bit_offset = 8 * i;
2146 if (bit_offset < length) {
2147 value = tvb_get_guint8(out_tvb, i);
2148 }
2149
2150 // Process 8 bits at a time instead of 64, each field masks a
2151 // single byte.
2152 int* const * section_named_bits = named_bits + bit_offset;
2153 int* flags[9];
2154 if (num_named_bits - bit_offset > 8) {
2155 memcpy(&flags[0], named_bits + bit_offset, 8 * sizeof(int*));
2156 flags[8] = NULL;
2157 section_named_bits = flags;
2158 }
2159
2160 // TODO should non-zero pad bits be masked from the value?
2161 // When trailing zeroes are not present in the data, mark the
2162 // last byte for the lack of a better alternative.
2163 proto_tree_add_bitmask_list_value(subtree, out_tvb, offset + MIN(i, length - 1), 1, section_named_bits, value);
2164 }
2165 }
2166 }
2167 proto_item_append_text(actx->created_item, "]");
2168 }
2169
2170 return out_tvb;
2171 }
2172 guint32
dissect_per_bit_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,int * const * named_bits,gint num_named_bits,tvbuff_t ** value_tvb,int * len)2173 dissect_per_bit_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, int * const *named_bits, gint num_named_bits, tvbuff_t **value_tvb, int *len)
2174 {
2175 /*gint val_start, val_length;*/
2176 guint32 length, fragmented_length = 0;
2177 header_field_info *hfi;
2178 gboolean is_fragmented = FALSE;
2179 tvbuff_t *fragmented_tvb = NULL, *out_tvb = NULL;
2180
2181 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2182
2183 DEBUG_ENTRY("dissect_per_bit_string");
2184 /* 15.8 if the length is 0 bytes there will be no encoding */
2185 if(max_len==0) {
2186 if (value_tvb)
2187 *value_tvb = out_tvb;
2188 if (len)
2189 *len = 0;
2190 return offset;
2191 }
2192
2193 if (min_len == NO_BOUND) {
2194 min_len = 0;
2195 }
2196 /* 15.6 If an extension marker is present in the size constraint specification of the bitstring type,
2197 * a single bit shall be added to the field-list in a bit-field of length one.
2198 * The bit shall be set to 1 if the length of this encoding is not within the range of the extension root,
2199 * and zero otherwise.
2200 */
2201 if (has_extension) {
2202 gboolean extension_present;
2203 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2204 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2205 if(extension_present){
2206 next_fragment1:
2207 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2208 if(length || fragmented_length){
2209 /* align to byte */
2210 if (actx->aligned){
2211 BYTE_ALIGN_OFFSET(offset);
2212 }
2213 if(is_fragmented){
2214 if(fragmented_length==0)
2215 fragmented_tvb = tvb_new_composite();
2216 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2217 offset += length;
2218 fragmented_length += length;
2219 goto next_fragment1;
2220 }
2221 if(fragmented_length){
2222 if(length){
2223 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2224 fragmented_length += length;
2225 }
2226 tvb_composite_finalize(fragmented_tvb);
2227 add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2228 out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2229 fragmented_length, named_bits, num_named_bits);
2230 }
2231 else
2232 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2233 }
2234 /* XXX: ?? */
2235 /*val_start = offset>>3;*/
2236 /*val_length = (length+7)/8;*/
2237 offset+=length;
2238
2239 if (value_tvb)
2240 *value_tvb = out_tvb;
2241 if (len)
2242 *len = fragmented_length ? fragmented_length : length;
2243
2244 return offset;
2245 }
2246 }
2247
2248 /* 15.9 if length is fixed and less than or equal to sixteen bits*/
2249 if ((min_len==max_len) && (max_len<=16)) {
2250 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2251 offset+=min_len;
2252 if (value_tvb)
2253 *value_tvb = out_tvb;
2254 if (len)
2255 *len = min_len;
2256 return offset;
2257 }
2258
2259
2260 /* 15.10 if length is fixed and less than to 64kbits*/
2261 if((min_len==max_len)&&(min_len<65536)){
2262 /* (octet-aligned in the ALIGNED variant)
2263 * align to byte
2264 */
2265 if (actx->aligned){
2266 BYTE_ALIGN_OFFSET(offset);
2267 }
2268 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, min_len, named_bits, num_named_bits);
2269 offset+=min_len;
2270 if (value_tvb)
2271 *value_tvb = out_tvb;
2272 if (len)
2273 *len = min_len;
2274 return offset;
2275 }
2276
2277 /* 15.11 */
2278 if (max_len != NO_BOUND && max_len < 65536) {
2279 offset=dissect_per_constrained_integer(tvb, offset, actx,
2280 tree, hf_per_bit_string_length, min_len, max_len,
2281 &length, FALSE);
2282 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2283 } else {
2284 next_fragment2:
2285 offset=dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_bit_string_length, &length, &is_fragmented);
2286 }
2287 if(length || fragmented_length){
2288 /* align to byte */
2289 if (actx->aligned){
2290 BYTE_ALIGN_OFFSET(offset);
2291 }
2292 if(is_fragmented){
2293 if(fragmented_length==0)
2294 fragmented_tvb = tvb_new_composite();
2295 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2296 offset += length;
2297 fragmented_length += length;
2298 goto next_fragment2;
2299 }
2300 if(fragmented_length){
2301 if(length){
2302 tvb_composite_append(fragmented_tvb, tvb_new_octet_aligned(tvb, offset, length));
2303 fragmented_length += length;
2304 }
2305 tvb_composite_finalize(fragmented_tvb);
2306 add_new_data_source(actx->pinfo, fragmented_tvb, "Fragmented bitstring tvb");
2307 out_tvb = dissect_per_bit_string_display(fragmented_tvb, 0, actx, tree, hf_index, hfi,
2308 fragmented_length, named_bits, num_named_bits);
2309 }
2310 else
2311 out_tvb = dissect_per_bit_string_display(tvb, offset, actx, tree, hf_index, hfi, length, named_bits, num_named_bits);
2312 }
2313 /* XXX: ?? */
2314 /*val_start = offset>>3;*/
2315 /*val_length = (length+7)/8;*/
2316 offset+=length;
2317
2318 if (value_tvb)
2319 *value_tvb = out_tvb;
2320 if (len)
2321 *len = fragmented_length ? fragmented_length : length;
2322
2323 return offset;
2324 }
2325
dissect_per_bit_string_containing_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,dissector_t type_cb)2326 guint32 dissect_per_bit_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2327 {
2328 tvbuff_t *val_tvb = NULL;
2329 proto_tree *subtree = tree;
2330
2331 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, NULL, 0, &val_tvb, NULL);
2332
2333 if (type_cb && val_tvb) {
2334 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2335 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2336 }
2337
2338 return offset;
2339 }
2340
2341 /* this function dissects an OCTET STRING
2342 16.1
2343 16.2
2344 16.3
2345 16.4
2346 16.5
2347 16.6
2348 16.7
2349 16.8
2350
2351 max_len or min_len == NO_BOUND means there is no lower/upper constraint
2352
2353 hf_index can either be a FT_BYTES or an FT_STRING
2354 */
2355 guint32
dissect_per_octet_string(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,tvbuff_t ** value_tvb)2356 dissect_per_octet_string(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, tvbuff_t **value_tvb)
2357 {
2358 gint val_start = 0, val_length;
2359 guint32 length = 0, fragmented_length = 0;;
2360 header_field_info *hfi;
2361 gboolean is_fragmented = FALSE;
2362 tvbuff_t *out_tvb = NULL;
2363
2364 hfi = (hf_index==-1) ? NULL : proto_registrar_get_nth(hf_index);
2365
2366 DEBUG_ENTRY("dissect_per_octet_string");
2367
2368 if (has_extension) { /* 16.3 an extension marker is present */
2369 gboolean extension_present;
2370 offset = dissect_per_boolean(tvb, offset, actx, tree, hf_per_extension_present_bit, &extension_present);
2371 if (!display_internal_per_fields) proto_item_set_hidden(actx->created_item);
2372 if (extension_present) max_len = NO_BOUND; /* skip to 16.8 */
2373 }
2374
2375 if (min_len == NO_BOUND) {
2376 min_len = 0;
2377 }
2378 if (max_len==0) { /* 16.5 if the length is 0 bytes there will be no encoding */
2379 val_start = offset>>3;
2380 val_length = 0;
2381
2382 } else if((min_len==max_len)&&(max_len<=2)) {
2383 /* 16.6 if length is fixed and less than or equal to two bytes*/
2384 val_start = offset>>3;
2385 val_length = min_len;
2386 out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2387 /* Add new data source if the offet was unaligned */
2388 if ((offset & 7) != 0) {
2389 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2390 }
2391 offset+=min_len*8;
2392
2393 } else if ((min_len==max_len)&&(min_len<65536)) {
2394 /* 16.7 if length is fixed and less than to 64k*/
2395
2396 /* align to byte */
2397 if (actx->aligned){
2398 BYTE_ALIGN_OFFSET(offset);
2399 }
2400 val_start = offset>>3;
2401 val_length = min_len;
2402 out_tvb = tvb_new_octet_aligned(tvb, offset, val_length * 8);
2403 if ((offset & 7) != 0) {
2404 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2405 }
2406 offset+=min_len*8;
2407
2408 } else { /* 16.8 */
2409 if(max_len>0) {
2410 offset = dissect_per_constrained_integer(tvb, offset, actx, tree,
2411 hf_per_octet_string_length, min_len, max_len, &length, FALSE);
2412
2413 if (!display_internal_per_fields)
2414 proto_item_set_hidden(actx->created_item);
2415 } else {
2416 next_fragment:
2417 offset = dissect_per_length_determinant(tvb, offset, actx, tree,
2418 hf_per_octet_string_length, &length, &is_fragmented);
2419 }
2420
2421 if(length || fragmented_length){
2422 /* align to byte */
2423 if (actx->aligned){
2424 BYTE_ALIGN_OFFSET(offset);
2425 }
2426 if (is_fragmented) {
2427 if (fragmented_length == 0)
2428 out_tvb = tvb_new_composite();
2429 tvb_composite_append(out_tvb, tvb_new_octet_aligned(tvb, offset, length * 8));
2430 offset += length * 8;
2431 fragmented_length += length;
2432 goto next_fragment;
2433 }
2434 if (fragmented_length) {
2435 if (length) {
2436 tvb_composite_append(out_tvb, tvb_new_octet_aligned(tvb, offset, length * 8));
2437 fragmented_length += length;
2438 }
2439 tvb_composite_finalize(out_tvb);
2440 add_new_data_source(actx->pinfo, out_tvb, "Fragmented OCTET STRING");
2441 } else {
2442 out_tvb = tvb_new_octet_aligned(tvb, offset, length * 8);
2443 if ((offset & 7) != 0) {
2444 add_new_data_source(actx->pinfo, out_tvb, "Unaligned OCTET STRING");
2445 }
2446 }
2447 } else {
2448 val_start = offset>>3;
2449 }
2450 val_length = fragmented_length ? fragmented_length : length;
2451 offset+=length*8;
2452 }
2453
2454 if (hfi) {
2455 if (IS_FT_UINT(hfi->type)||IS_FT_INT(hfi->type)) {
2456 /* If the type has been converted to FT_UINT or FT_INT in the .cnf file
2457 * display the length of this octet string instead of the octetstring itself
2458 */
2459 if (IS_FT_UINT(hfi->type))
2460 actx->created_item = proto_tree_add_uint(tree, hf_index, out_tvb, 0, val_length, val_length);
2461 else
2462 actx->created_item = proto_tree_add_int(tree, hf_index, out_tvb, 0, val_length, val_length);
2463 proto_item_append_text(actx->created_item, plurality(val_length, " octet", " octets"));
2464 } else {
2465 if(out_tvb){
2466 actx->created_item = proto_tree_add_item(tree, hf_index, out_tvb, 0, val_length, ENC_BIG_ENDIAN);
2467 }else{
2468 /* Length = 0 */
2469 actx->created_item = proto_tree_add_item(tree, hf_index, tvb, val_start, val_length, ENC_BIG_ENDIAN);
2470 }
2471 }
2472 }
2473
2474 if (value_tvb)
2475 *value_tvb = (out_tvb) ? out_tvb : tvb_new_subset_length(tvb, val_start, val_length);
2476
2477 return offset;
2478 }
2479
dissect_per_octet_string_containing_pdu_new(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,int min_len,int max_len,gboolean has_extension,dissector_t type_cb)2480 guint32 dissect_per_octet_string_containing_pdu_new(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, int min_len, int max_len, gboolean has_extension, dissector_t type_cb)
2481 {
2482 tvbuff_t *val_tvb = NULL;
2483 proto_tree *subtree = tree;
2484
2485 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, min_len, max_len, has_extension, &val_tvb);
2486
2487 if (type_cb && val_tvb && (tvb_reported_length(val_tvb) > 0)) {
2488 subtree = proto_item_add_subtree(actx->created_item, ett_per_containing);
2489 type_cb(val_tvb, actx->pinfo, subtree, NULL);
2490 }
2491
2492 return offset;
2493 }
2494
dissect_per_size_constrained_type(tvbuff_t * tvb,guint32 offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index,per_type_fn type_cb,const gchar * name,int min_len,int max_len,gboolean has_extension)2495 guint32 dissect_per_size_constrained_type(tvbuff_t *tvb, guint32 offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index, per_type_fn type_cb, const gchar *name, int min_len, int max_len, gboolean has_extension)
2496 {
2497 asn1_stack_frame_push(actx, name);
2498 asn1_param_push_integer(actx, min_len);
2499 asn1_param_push_integer(actx, max_len);
2500 asn1_param_push_boolean(actx, has_extension);
2501
2502 offset = type_cb(tvb, offset, actx, tree, hf_index);
2503
2504 asn1_stack_frame_pop(actx, name);
2505
2506 return offset;
2507 }
2508
get_size_constraint_from_stack(asn1_ctx_t * actx,const gchar * name,int * pmin_len,int * pmax_len,gboolean * phas_extension)2509 gboolean get_size_constraint_from_stack(asn1_ctx_t *actx, const gchar *name, int *pmin_len, int *pmax_len, gboolean *phas_extension)
2510 {
2511 asn1_par_t *par;
2512
2513 if (pmin_len) *pmin_len = NO_BOUND;
2514 if (pmax_len) *pmax_len = NO_BOUND;
2515 if (phas_extension) *phas_extension = FALSE;
2516
2517 if (!actx->stack) return FALSE;
2518 if (strcmp(actx->stack->name, name)) return FALSE;
2519
2520 par = actx->stack->par;
2521 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2522 if (pmin_len) *pmin_len = par->value.v_integer;
2523 par = par->next;
2524 if (!par || (par->ptype != ASN1_PAR_INTEGER)) return FALSE;
2525 if (pmax_len) *pmax_len = par->value.v_integer;
2526 par = par->next;
2527 if (!par || (par->ptype != ASN1_PAR_BOOLEAN)) return FALSE;
2528 if (phas_extension) *phas_extension = par->value.v_boolean;
2529
2530 return TRUE;
2531 }
2532
2533
2534 /* 26 Encoding of a value of the external type */
2535
2536 /* code generated from definition in 26.1 */
2537 /*
2538 [UNIVERSAL 8] IMPLICIT SEQUENCE {
2539 direct-reference OBJECT IDENTIFIER OPTIONAL,
2540 indirect-reference INTEGER OPTIONAL,
2541 data-value-descriptor ObjectDescriptor OPTIONAL,
2542 encoding CHOICE {
2543 single-ASN1-type [0] ABSTRACT-SYNTAX.&Type,
2544 octet-aligned [1] IMPLICIT OCTET STRING,
2545 arbitrary [2] IMPLICIT BIT STRING
2546 }
2547 }
2548 */
2549 /* NOTE: This sequence type differs from that in ITU-T Rec. X.680 | ISO/IEC 8824-1 for historical reasons. */
2550
2551 static int
dissect_per_T_direct_reference(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2552 dissect_per_T_direct_reference(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2553
2554 DISSECTOR_ASSERT(actx);
2555 offset = dissect_per_object_identifier_str(tvb, offset, actx, tree, hf_index, &actx->external.direct_reference);
2556
2557 actx->external.direct_ref_present = TRUE;
2558 return offset;
2559 }
2560
2561
2562
2563 static int
dissect_per_T_indirect_reference(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2564 dissect_per_T_indirect_reference(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2565 offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &actx->external.indirect_reference);
2566
2567 actx->external.indirect_ref_present = TRUE;
2568 return offset;
2569 }
2570
2571
2572
2573 static int
dissect_per_T_data_value_descriptor(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2574 dissect_per_T_data_value_descriptor(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2575 offset = dissect_per_object_descriptor(tvb, offset, actx, tree, hf_index, &actx->external.data_value_descriptor);
2576
2577 actx->external.data_value_descr_present = TRUE;
2578 return offset;
2579 }
2580
2581
2582
2583 static int
dissect_per_T_single_ASN1_type(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2584 dissect_per_T_single_ASN1_type(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2585 offset = dissect_per_open_type(tvb, offset, actx, tree, actx->external.hf_index, actx->external.u.per.type_cb);
2586
2587 return offset;
2588 }
2589
2590
2591
2592 static int
dissect_per_T_octet_aligned(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2593 dissect_per_T_octet_aligned(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2594 offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
2595 NO_BOUND, NO_BOUND, FALSE, &actx->external.octet_aligned);
2596
2597 if (actx->external.octet_aligned) {
2598 if (actx->external.u.per.type_cb) {
2599 actx->external.u.per.type_cb(actx->external.octet_aligned, 0, actx, tree, actx->external.hf_index);
2600 } else {
2601 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.octet_aligned, 0, -1);
2602 }
2603 }
2604 return offset;
2605 }
2606
2607
2608
2609 static int
dissect_per_T_arbitrary(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2610 dissect_per_T_arbitrary(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2611 offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
2612 NO_BOUND, NO_BOUND, FALSE, NULL, 0, &actx->external.arbitrary, NULL);
2613
2614 if (actx->external.arbitrary) {
2615 if (actx->external.u.per.type_cb) {
2616 actx->external.u.per.type_cb(actx->external.arbitrary, 0, actx, tree, actx->external.hf_index);
2617 } else {
2618 actx->created_item = proto_tree_add_expert(tree, actx->pinfo, &ei_per_external_type, actx->external.arbitrary, 0, -1);
2619 }
2620 }
2621 return offset;
2622 }
2623
2624
2625 static const value_string per_External_encoding_vals[] = {
2626 { 0, "single-ASN1-type" },
2627 { 1, "octet-aligned" },
2628 { 2, "arbitrary" },
2629 { 0, NULL }
2630 };
2631
2632 static const per_choice_t External_encoding_choice[] = {
2633 { 0, &hf_per_single_ASN1_type, ASN1_NO_EXTENSIONS , dissect_per_T_single_ASN1_type },
2634 { 1, &hf_per_octet_aligned , ASN1_NO_EXTENSIONS , dissect_per_T_octet_aligned },
2635 { 2, &hf_per_arbitrary , ASN1_NO_EXTENSIONS , dissect_per_T_arbitrary },
2636 { 0, NULL, 0, NULL }
2637 };
2638
2639 static int
dissect_per_External_encoding(tvbuff_t * tvb,int offset,asn1_ctx_t * actx,proto_tree * tree,int hf_index)2640 dissect_per_External_encoding(tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index) {
2641 // This assertion is used to remove clang's warning.
2642 DISSECTOR_ASSERT(actx);
2643 offset = dissect_per_choice(tvb, offset, actx, tree, hf_index,
2644 ett_per_External_encoding, External_encoding_choice,
2645 &actx->external.encoding);
2646
2647 return offset;
2648 }
2649
2650
2651 static const per_sequence_t External_sequence[] = {
2652 { &hf_per_direct_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_direct_reference },
2653 { &hf_per_indirect_reference, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_indirect_reference },
2654 { &hf_per_data_value_descriptor, ASN1_NO_EXTENSIONS , ASN1_OPTIONAL , dissect_per_T_data_value_descriptor },
2655 { &hf_per_encoding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_per_External_encoding },
2656 { NULL, 0, 0, NULL }
2657 };
2658
2659 static int
dissect_per_External(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2660 dissect_per_External(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2661 offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
2662 ett_per_External, External_sequence);
2663
2664 return offset;
2665 }
2666
2667 guint32
dissect_per_external_type(tvbuff_t * tvb _U_,guint32 offset,asn1_ctx_t * actx,proto_tree * tree _U_,int hf_index _U_,per_type_fn type_cb)2668 dissect_per_external_type(tvbuff_t *tvb _U_, guint32 offset, asn1_ctx_t *actx, proto_tree *tree _U_, int hf_index _U_, per_type_fn type_cb)
2669 {
2670 asn1_ctx_clean_external(actx);
2671 actx->external.u.per.type_cb = type_cb;
2672 offset = dissect_per_External(tvb, offset, actx, tree, hf_index);
2673
2674 asn1_ctx_clean_external(actx);
2675 return offset;
2676 }
2677
2678 /*
2679 * Calls the callback defined with register_per_oid_dissector() if found.
2680 * Offset is in bits.
2681 */
2682
2683 int
call_per_oid_callback(const char * oid,tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,asn1_ctx_t * actx,int hf_index)2684 call_per_oid_callback(const char *oid, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, asn1_ctx_t *actx, int hf_index)
2685 {
2686 guint32 type_length, end_offset, start_offset;
2687 tvbuff_t *val_tvb = NULL;
2688
2689 start_offset = offset;
2690 offset = dissect_per_length_determinant(tvb, offset, actx, tree, hf_per_open_type_length, &type_length, NULL);
2691 if (actx->aligned) BYTE_ALIGN_OFFSET(offset);
2692 end_offset = offset + type_length;
2693
2694
2695 val_tvb = tvb_new_octet_aligned(tvb, offset, type_length);
2696 if ((offset & 7) != 0) {
2697 add_new_data_source(actx->pinfo, val_tvb, "Unaligned OCTET STRING");
2698 }
2699
2700 if (oid == NULL ||
2701 (dissector_try_string(per_oid_dissector_table, oid, val_tvb, pinfo, tree, actx)) == 0)
2702 {
2703 proto_tree_add_expert(tree, pinfo, &ei_per_oid_not_implemented, val_tvb, 0, -1);
2704 dissect_per_open_type(tvb, start_offset, actx, tree, hf_index, NULL);
2705 }
2706
2707 return end_offset;
2708 }
2709
2710 void
register_per_oid_dissector(const char * oid,dissector_t dissector,int proto,const char * name)2711 register_per_oid_dissector(const char *oid, dissector_t dissector, int proto, const char *name)
2712 {
2713 dissector_handle_t dissector_handle;
2714
2715 dissector_handle = create_dissector_handle(dissector, proto);
2716 dissector_add_string("per.oid", oid, dissector_handle);
2717 oid_add_from_string(name, oid);
2718 }
2719
2720
2721 void
proto_register_per(void)2722 proto_register_per(void)
2723 {
2724 static hf_register_info hf[] = {
2725 { &hf_per_num_sequence_extensions,
2726 { "Number of Sequence Extensions", "per.num_sequence_extensions", FT_UINT32, BASE_DEC,
2727 NULL, 0, "Number of extensions encoded in this sequence", HFILL }},
2728 { &hf_per_choice_index,
2729 { "Choice Index", "per.choice_index", FT_UINT32, BASE_DEC,
2730 NULL, 0, "Which index of the Choice within extension root is encoded", HFILL }},
2731 { &hf_per_choice_extension_index,
2732 { "Choice Extension Index", "per.choice_extension_index", FT_UINT32, BASE_DEC,
2733 NULL, 0, "Which index of the Choice within extension addition is encoded", HFILL }},
2734 { &hf_per_enum_index,
2735 { "Enumerated Index", "per.enum_index", FT_UINT32, BASE_DEC,
2736 NULL, 0, "Which index of the Enumerated within extension root is encoded", HFILL }},
2737 { &hf_per_enum_extension_index,
2738 { "Enumerated Extension Index", "per.enum_extension_index", FT_UINT32, BASE_DEC,
2739 NULL, 0, "Which index of the Enumerated within extension addition is encoded", HFILL }},
2740 { &hf_per_GeneralString_length,
2741 { "GeneralString Length", "per.generalstring_length", FT_UINT32, BASE_DEC,
2742 NULL, 0, "Length of the GeneralString", HFILL }},
2743 { &hf_per_extension_bit,
2744 { "Extension Bit", "per.extension_bit", FT_BOOLEAN, 8,
2745 TFS(&tfs_extension_bit), 0x01, "The extension bit of an aggregate", HFILL }},
2746 { &hf_per_extension_present_bit,
2747 { "Extension Present Bit", "per.extension_present_bit", FT_BOOLEAN, 8,
2748 NULL, 0x01, "Whether this optional extension is present or not", HFILL }},
2749 { &hf_per_small_number_bit,
2750 { "Small Number Bit", "per.small_number_bit", FT_BOOLEAN, 8,
2751 TFS(&tfs_small_number_bit), 0x01, "The small number bit for a section 10.6 integer", HFILL }},
2752 { &hf_per_optional_field_bit,
2753 { "Optional Field Bit", "per.optional_field_bit", FT_BOOLEAN, 8,
2754 NULL, 0x01, "This bit specifies the presence/absence of an optional field", HFILL }},
2755 { &hf_per_sequence_of_length,
2756 { "Sequence-Of Length", "per.sequence_of_length", FT_UINT32, BASE_DEC,
2757 NULL, 0, "Number of items in the Sequence Of", HFILL }},
2758 { &hf_per_object_identifier_length,
2759 { "Object Identifier Length", "per.object_length", FT_UINT32, BASE_DEC,
2760 NULL, 0, "Length of the object identifier", HFILL }},
2761 { &hf_per_open_type_length,
2762 { "Open Type Length", "per.open_type_length", FT_UINT32, BASE_DEC,
2763 NULL, 0, "Length of an open type encoding", HFILL }},
2764 { &hf_per_real_length,
2765 { "Real Length", "per.real_length", FT_UINT32, BASE_DEC,
2766 NULL, 0, "Length of an real encoding", HFILL }},
2767 { &hf_per_octet_string_length,
2768 { "Octet String Length", "per.octet_string_length", FT_UINT32, BASE_DEC,
2769 NULL, 0, "Number of bytes in the Octet String", HFILL }},
2770 { &hf_per_bit_string_length,
2771 { "Bit String Length", "per.bit_string_length", FT_UINT32, BASE_DEC,
2772 NULL, 0, "Number of bits in the Bit String", HFILL }},
2773 { &hf_per_normally_small_nonnegative_whole_number_length,
2774 { "Normally Small Non-negative Whole Number Length", "per.normally_small_nonnegative_whole_number_length", FT_UINT32, BASE_DEC,
2775 NULL, 0, "Number of bytes in the Normally Small Non-negative Whole Number", HFILL }},
2776 { &hf_per_const_int_len,
2777 { "Constrained Integer Length", "per.const_int_len", FT_UINT32, BASE_DEC,
2778 NULL, 0, "Number of bytes in the Constrained Integer", HFILL }},
2779 { &hf_per_direct_reference,
2780 { "direct-reference", "per.direct_reference",
2781 FT_OID, BASE_NONE, NULL, 0,
2782 "per.T_direct_reference", HFILL }},
2783 { &hf_per_indirect_reference,
2784 { "indirect-reference", "per.indirect_reference",
2785 FT_INT32, BASE_DEC, NULL, 0,
2786 "per.T_indirect_reference", HFILL }},
2787 { &hf_per_data_value_descriptor,
2788 { "data-value-descriptor", "per.data_value_descriptor",
2789 FT_STRING, BASE_NONE, NULL, 0,
2790 "per.T_data_value_descriptor", HFILL }},
2791 { &hf_per_encoding,
2792 { "encoding", "per.encoding",
2793 FT_UINT32, BASE_DEC, VALS(per_External_encoding_vals), 0,
2794 "per.External_encoding", HFILL }},
2795 { &hf_per_single_ASN1_type,
2796 { "single-ASN1-type", "per.single_ASN1_type",
2797 FT_NONE, BASE_NONE, NULL, 0,
2798 "per.T_single_ASN1_type", HFILL }},
2799 { &hf_per_octet_aligned,
2800 { "octet-aligned", "per.octet_aligned",
2801 FT_BYTES, BASE_NONE, NULL, 0,
2802 "per.T_octet_aligned", HFILL }},
2803 { &hf_per_arbitrary,
2804 { "arbitrary", "per.arbitrary",
2805 FT_BYTES, BASE_NONE, NULL, 0,
2806 "per.T_arbitrary", HFILL }},
2807 { &hf_per_integer_length,
2808 { "integer length", "per.integer_length",
2809 FT_UINT32, BASE_DEC, NULL, 0,
2810 NULL, HFILL }},
2811 #if 0
2812 { &hf_per_debug_pos,
2813 { "Current bit offset", "per.debug_pos",
2814 FT_UINT32, BASE_DEC, NULL, 0,
2815 NULL, HFILL }},
2816 #endif
2817 { &hf_per_internal_range,
2818 { "Range", "per.internal.range",
2819 FT_UINT64, BASE_DEC, NULL, 0,
2820 NULL, HFILL }},
2821 { &hf_per_internal_num_bits,
2822 { "Bitfield length", "per.internal.num_bits",
2823 FT_UINT32, BASE_DEC, NULL, 0,
2824 NULL, HFILL }},
2825 { &hf_per_internal_min,
2826 { "Min", "per.internal.min",
2827 FT_UINT32, BASE_DEC, NULL, 0,
2828 NULL, HFILL }},
2829 { &hf_per_internal_value,
2830 { "Bits", "per.internal.value",
2831 FT_UINT64, BASE_DEC, NULL, 0,
2832 NULL, HFILL }},
2833 };
2834
2835 static gint *ett[] = {
2836 &ett_per_open_type,
2837 &ett_per_containing,
2838 &ett_per_sequence_of_item,
2839 &ett_per_External,
2840 &ett_per_External_encoding,
2841 &ett_per_named_bits,
2842 };
2843 static ei_register_info ei[] = {
2844 { &ei_per_size_constraint_value,
2845 { "per.size_constraint.value", PI_PROTOCOL, PI_WARN, "Size constraint: value too big", EXPFILL }},
2846 { &ei_per_size_constraint_too_few,
2847 { "per.size_constraint.too_few", PI_PROTOCOL, PI_WARN, "Size constraint: too few items", EXPFILL }},
2848 { &ei_per_size_constraint_too_many,
2849 { "per.size_constraint.too_many", PI_PROTOCOL, PI_WARN, "Size constraint: too many items", EXPFILL }},
2850 { &ei_per_choice_extension_unknown,
2851 { "per.choice_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown choice extension", EXPFILL }},
2852 { &ei_per_sequence_extension_unknown,
2853 { "per.sequence_extension_unknown", PI_UNDECODED, PI_NOTE, "unknown sequence extension", EXPFILL }},
2854 { &ei_per_encoding_error,
2855 { "per.encoding_error", PI_MALFORMED, PI_WARN, "Encoding error", EXPFILL }},
2856 { &ei_per_oid_not_implemented,
2857 { "per.error.oid_not_implemented", PI_UNDECODED, PI_WARN, "PER: Dissector for OID not implemented. Contact Wireshark developers if you want this supported", EXPFILL }},
2858 { &ei_per_undecoded,
2859 { "per.error.undecoded", PI_UNDECODED, PI_WARN, "PER: Something unknown here", EXPFILL }},
2860 { &ei_per_field_not_integer,
2861 { "per.field_not_integer", PI_PROTOCOL, PI_ERROR, "Field is not an integer", EXPFILL }},
2862 { &ei_per_external_type,
2863 { "per.external_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown EXTERNAL Type", EXPFILL }},
2864 { &ei_per_open_type,
2865 { "per.open_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown Open Type", EXPFILL }},
2866 { &ei_per_open_type_len,
2867 { "per.open_type.len", PI_PROTOCOL, PI_ERROR, "Open Type length > available data(tvb)", EXPFILL }}
2868 };
2869
2870 module_t *per_module;
2871 expert_module_t* expert_per;
2872
2873 proto_per = proto_register_protocol("Packed Encoding Rules (ASN.1 X.691)", "PER", "per");
2874 proto_register_field_array(proto_per, hf, array_length(hf));
2875 proto_register_subtree_array(ett, array_length(ett));
2876 expert_per = expert_register_protocol(proto_per);
2877 expert_register_field_array(expert_per, ei, array_length(ei));
2878
2879 proto_set_cant_toggle(proto_per);
2880
2881 per_module = prefs_register_protocol(proto_per, NULL);
2882 prefs_register_bool_preference(per_module, "display_internal_per_fields",
2883 "Display the internal PER fields in the tree",
2884 "Whether the dissector should put the internal PER data in the tree or if it should hide it",
2885 &display_internal_per_fields);
2886
2887 per_oid_dissector_table = register_dissector_table("per.oid", "PER OID", proto_per, FT_STRING, BASE_NONE);
2888
2889
2890 }
2891
2892 /*
2893 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2894 *
2895 * Local variables:
2896 * c-basic-offset: 8
2897 * tab-width: 8
2898 * indent-tabs-mode: t
2899 * End:
2900 *
2901 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2902 * :indentSize=8:tabSize=8:noTabs=false:
2903 */
2904