Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-csn1.c
Line
Count
Source
1
/* packet-csn1.c
2
 * Routines for CSN1 dissection in wireshark.
3
 * By Vincent Helfre, based on original code by Jari Sassi
4
 * with the gracious authorization of STE
5
 * Copyright (c) 2011 ST-Ericsson
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
#include <epan/packet.h>
17
#include <epan/to_str.h>
18
#include "packet-csn1.h"
19
20
void proto_register_csn1(void);
21
22
static int hf_null_data;
23
24
static expert_field ei_csn1_more_bits_to_unpack;
25
static expert_field ei_csn1_general;
26
static expert_field ei_csn1_not_implemented;
27
static expert_field ei_csn1_union_index;
28
static expert_field ei_csn1_script_error;
29
static expert_field ei_csn1_more32bits;
30
static expert_field ei_csn1_fixed_not_matched;
31
static expert_field ei_csn1_stream_not_supported;
32
33
33.5k
#define pvDATA(_pv, _offset) ((void*) ((unsigned char*)_pv + _offset))
34
27.3k
#define pui8DATA(_pv, _offset) ((uint8_t*) pvDATA(_pv, _offset))
35
689
#define pui16DATA(_pv, _offset) ((uint16_t*) pvDATA(_pv, _offset))
36
304
#define pui32DATA(_pv, _offset) ((uint32_t*) pvDATA(_pv, _offset))
37
38
/* used to tag existence of next element in variable length lists */
39
10.7k
#define STANDARD_TAG 1
40
0
#define REVERSED_TAG 0
41
42
static const unsigned char ixBitsTab[] = {0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5};
43
44
static int proto_csn1;
45
46
/* Returns no_of_bits (up to 8) masked with 0x2B */
47
static uint8_t
48
tvb_get_masked_bits8(tvbuff_t *tvb, int bit_offset,  const int no_of_bits)
49
0
{
50
0
  static const uint8_t maskBits[] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
51
0
  int byte_offset = bit_offset >> 3;          /* divide by 8 */
52
0
  int relative_bit_offset = bit_offset & 0x07;  /* modulo 8 */
53
0
  uint8_t result;
54
0
  int bit_shift = 8 - relative_bit_offset - (int) no_of_bits;
55
56
0
  if (bit_shift >= 0)
57
0
  {
58
0
    result = (0x2B ^ tvb_get_uint8(tvb, byte_offset)) >> bit_shift;
59
0
    result &= maskBits[no_of_bits];
60
0
  }
61
0
  else
62
0
  {
63
0
    uint8_t high_part = (0x2B ^ tvb_get_uint8(tvb, byte_offset)) & maskBits[8 - relative_bit_offset];
64
0
    high_part = (uint8_t) (high_part << (-bit_shift));
65
0
    result =  (0x2B ^ tvb_get_uint8(tvb, byte_offset+1)) >> (8 + bit_shift);
66
0
    result |= high_part;
67
0
  }
68
0
  return result;
69
0
}
70
71
/**
72
 * ================================================================================================
73
 * set initial/start values in help data structure used for packing/unpacking operation
74
 * ================================================================================================
75
 */
76
void
77
csnStreamInit(csnStream_t* ar, int bit_offset, int remaining_bits_len, packet_info* pinfo)
78
9.28k
{
79
9.28k
  ar->remaining_bits_len  = remaining_bits_len;
80
9.28k
  ar->bit_offset          = bit_offset;
81
9.28k
  ar->pinfo               = pinfo;
82
9.28k
}
83
84
static int16_t
85
ProcessError(proto_tree *tree, packet_info* pinfo, tvbuff_t *tvb, int bit_offset, int16_t err, expert_field* err_field, const CSN_DESCR* pDescr)
86
355
{
87
355
  if (err_field != NULL)
88
355
    proto_tree_add_expert_format(tree, pinfo, err_field, tvb, bit_offset>>3, 1, "%s (%s)", expert_get_summary(err_field), pDescr?pDescr->sz:"-");
89
90
355
  return err;
91
355
}
92
93
#if 0
94
static const char* CSN_DESCR_type[]=
95
{
96
  "CSN_END",
97
  "CSN_BIT",
98
  "CSN_UINT",
99
  "CSN_TYPE",
100
  "CSN_CHOICE",
101
  "CSN_UNION",
102
  "CSN_UNION_LH",
103
  "CSN_UINT_ARRAY",
104
  "CSN_TYPE_ARRAY",
105
  "CSN_BITMAP",
106
  "CSN_VARIABLE_BITMAP",
107
  "CSN_VARIABLE_BITMAP_1",
108
  "CSN_LEFT_ALIGNED_VAR_BMP",
109
  "CSN_LEFT_ALIGNED_VAR_BMP_1",
110
  "CSN_VARIABLE_ARRAY",
111
  "CSN_VARIABLE_TARRAY",
112
  "CSN_VARIABLE_TARRAY_OFFSET",
113
  "CSN_RECURSIVE_ARRAY",
114
  "CSN_RECURSIVE_TARRAY",
115
  "CSN_RECURSIVE_TARRAY_1",
116
  "CSN_RECURSIVE_TARRAY_2",
117
  "CSN_EXIST",
118
  "CSN_EXIST_LH",
119
  "CSN_NEXT_EXIST",
120
  "CSN_NEXT_EXIST_LH",
121
  "CSN_NULL",
122
  "CSN_FIXED",
123
  "CSN_CALLBACK",
124
  "CSN_UINT_OFFSET",
125
  "CSN_UINT_LH",
126
  "CSN_SERIALIZE",
127
  "CSN_TRAP_ERROR"
128
  "CSN_???"
129
};
130
#endif
131
132
/**
133
 * ================================================================================================
134
 * Return true if tag in bit stream indicates existence of next list element,
135
 * otherwise return false.
136
 * Will work for tag values equal to both 0 and 1.
137
 * ================================================================================================
138
 */
139
140
static bool
141
existNextElement(tvbuff_t *tvb, int bit_offset, uint8_t Tag)
142
2.37k
{
143
2.37k
  uint8_t res = tvb_get_bits8(tvb, bit_offset, 1);
144
2.37k
  if (Tag == STANDARD_TAG)
145
2.37k
  {
146
2.37k
    return (res > 0);
147
2.37k
  }
148
1
  return (res == 0);
149
2.37k
}
150
151
152
int16_t
153
// NOLINTNEXTLINE(misc-no-recursion)
154
csnStreamDissector(proto_tree *tree, csnStream_t* ar, const CSN_DESCR* pDescr, tvbuff_t *tvb, void* data, int ett_csn1)
155
8.36k
{
156
8.36k
  int   remaining_bits_len = ar->remaining_bits_len;
157
8.36k
  int   bit_offset         = ar->bit_offset;
158
8.36k
  uint8_t*  pui8 = NULL;
159
8.36k
  uint16_t* pui16;
160
8.36k
  uint32_t* pui32;
161
8.36k
  uint8_t Tag = STANDARD_TAG;
162
163
  /* Negative number definitely indicates an error */
164
8.36k
  if (remaining_bits_len < 0)
165
0
  {
166
0
    return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
167
0
  }
168
169
8.36k
  do
170
39.0k
  {
171
39.0k
    switch (pDescr->type)
172
39.0k
    {
173
0
      case CSN_BIT:
174
0
      {
175
0
        if (remaining_bits_len > 0)
176
0
        {
177
0
          pui8  = pui8DATA(data, pDescr->offset);
178
179
0
          *pui8 = tvb_get_bits8(tvb, bit_offset, 1);
180
0
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
181
182
          /* end add the bit value to protocol tree */
183
0
        }
184
0
        else if(pDescr->may_be_null)
185
0
        {
186
0
          pui8  = pui8DATA(data, pDescr->offset);
187
0
          *pui8 = 0;
188
0
          proto_tree_add_none_format(tree, hf_null_data, tvb, 0, 0, "[NULL data]: %s Not Present", proto_registrar_get_name(*(pDescr->hf_ptr)));
189
0
        }
190
0
        else
191
0
        {
192
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
193
0
        }
194
195
0
        pDescr++;
196
0
        remaining_bits_len--;
197
0
        bit_offset++;
198
0
        break;
199
0
      }
200
201
33
      case CSN_NULL:
202
33
      { /* Empty member! */
203
33
        bit_offset += pDescr->i;
204
33
        pDescr++;
205
33
        break;
206
0
      }
207
208
20.1k
      case CSN_UINT:
209
20.1k
      {
210
20.1k
        uint8_t no_of_bits = (uint8_t) pDescr->i;
211
212
20.1k
        if (remaining_bits_len >= no_of_bits)
213
19.7k
        {
214
19.7k
          if (no_of_bits <= 8)
215
19.4k
          {
216
19.4k
            uint8_t ui8 = tvb_get_bits8(tvb, bit_offset, no_of_bits);
217
19.4k
            pui8  = pui8DATA(data, pDescr->offset);
218
19.4k
            *pui8 = ui8;
219
19.4k
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
220
19.4k
          }
221
331
          else if (no_of_bits <= 16)
222
276
          {
223
276
            uint16_t ui16 = tvb_get_bits16(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
224
276
            pui16  = pui16DATA(data, pDescr->offset);
225
276
            memcpy(pui16, &ui16, 2);
226
276
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
227
276
          }
228
55
          else if (no_of_bits <= 32)
229
55
          {
230
55
            uint32_t ui32 = tvb_get_bits32(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
231
55
            pui32  = pui32DATA(data, pDescr->offset);
232
55
            memcpy(pui32, &ui32, 4);
233
55
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
234
55
          }
235
0
          else
236
0
          {
237
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
238
0
          }
239
19.7k
          remaining_bits_len -= no_of_bits;
240
19.7k
          bit_offset += no_of_bits;
241
19.7k
        }
242
368
        else if(pDescr->may_be_null)
243
193
        {
244
193
            if (no_of_bits <= 8)
245
193
            {
246
193
              pui8  = pui8DATA(data, pDescr->offset);
247
193
              *pui8 = 0;
248
193
            }
249
0
            else if (no_of_bits <= 16)
250
0
            {
251
0
              pui16  = pui16DATA(data, pDescr->offset);
252
0
              memset(pui16, 0, 2);
253
0
            }
254
0
            else if (no_of_bits <= 32)
255
0
            {
256
0
              pui32  = pui32DATA(data, pDescr->offset);
257
0
              memset(pui32, 0, 4);
258
0
            }
259
193
            proto_tree_add_none_format(tree, hf_null_data, tvb, 0, 0, "[NULL data]: %s Not Present", proto_registrar_get_name(*(pDescr->hf_ptr)));
260
193
        }
261
175
        else
262
175
        {
263
175
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
264
175
        }
265
266
19.9k
        pDescr++;
267
19.9k
        break;
268
20.1k
      }
269
270
151
      case CSN_UINT_OFFSET:
271
151
      {
272
151
        uint8_t no_of_bits = (uint8_t) pDescr->i;
273
274
151
        if (remaining_bits_len >= no_of_bits)
275
149
        {
276
149
          if (no_of_bits <= 8)
277
149
          {
278
149
            uint8_t ui8 = tvb_get_bits8(tvb, bit_offset, no_of_bits);
279
149
            pui8      = pui8DATA(data, pDescr->offset);
280
149
            *pui8     = ui8 + (uint8_t)pDescr->descr.value;
281
282
149
            proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits,
283
149
                                                  *pui8, ENC_BIG_ENDIAN, "%u (Raw %u + Offset %u)", *pui8, ui8,
284
149
                                                  (uint8_t) pDescr->descr.value);
285
149
          }
286
0
          else if (no_of_bits <= 16)
287
0
          {
288
0
            uint16_t ui16 = tvb_get_bits16(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN) + (uint16_t)pDescr->descr.value;
289
0
            pui16       = pui16DATA(data, pDescr->offset);
290
0
            memcpy(pui16, &ui16, 2);
291
292
0
            proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits,
293
0
                                                  *pui16, ENC_BIG_ENDIAN, "%u (Raw %u + Offset %u)", *pui16, ui16,
294
0
                                                  (uint16_t) pDescr->descr.value);
295
0
          }
296
0
          else if (no_of_bits <= 32)
297
0
          {
298
0
            uint32_t ui32 = tvb_get_bits32(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN) + (uint16_t)pDescr->descr.value;
299
0
            pui32       = pui32DATA(data, pDescr->offset);
300
0
            memcpy(pui32, &ui32, 4);
301
302
0
            proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits,
303
0
                                                  *pui32, ENC_BIG_ENDIAN, "%u (Raw %u + Offset %u)", *pui32, ui32,
304
0
                                                  (uint16_t) pDescr->descr.value);
305
0
          }
306
0
          else
307
0
          {
308
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
309
0
          }
310
149
        }
311
2
        else
312
2
        {
313
2
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
314
2
        }
315
316
149
        remaining_bits_len -= no_of_bits;
317
149
        bit_offset += no_of_bits;
318
149
        pDescr++;
319
149
        break;
320
151
      }
321
322
0
      case CSN_UINT_LH:
323
0
      {
324
0
        uint8_t no_of_bits = (uint8_t) pDescr->i;
325
326
0
        if (remaining_bits_len >= no_of_bits)
327
0
        {
328
0
          if (no_of_bits <= 8)
329
0
          {
330
0
            uint8_t ui8 = tvb_get_masked_bits8(tvb, bit_offset, no_of_bits);
331
0
            pui8      = pui8DATA(data, pDescr->offset);
332
0
            *pui8     = ui8;
333
0
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
334
335
0
          }
336
0
          else
337
0
          {/* Maybe we should support more than 8 bits ? */
338
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
339
0
          }
340
0
        }
341
0
        else
342
0
        {
343
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
344
0
        }
345
346
0
        remaining_bits_len -= no_of_bits;
347
0
        bit_offset += no_of_bits;
348
0
        pDescr++;
349
0
        break;
350
0
      }
351
352
92
        case CSN_SPLIT_BITS:
353
92
        {
354
92
          uint8_t no_of_value_bits = (uint8_t) pDescr->i;
355
92
          uint64_t value;
356
357
92
          proto_tree_add_split_bits_item_ret_val(tree, *pDescr->hf_ptr, tvb, bit_offset, pDescr->descr.crumb_spec, &value);
358
92
          if (no_of_value_bits <= 8)
359
46
          {
360
46
            pui8      = pui8DATA(data, pDescr->offset);
361
46
            *pui8     = (uint8_t)value;
362
46
          }
363
46
          else if (no_of_value_bits <= 16)
364
46
          {
365
46
            uint16_t ui16 = (uint16_t) value;
366
46
            pui16       = pui16DATA(data, pDescr->offset);
367
46
            memcpy(pui16, &ui16, 2);
368
46
          }
369
0
          else if (no_of_value_bits <= 32)
370
0
          {
371
0
            uint32_t ui32 = (uint32_t) value;
372
0
            pui32       = pui32DATA(data, pDescr->offset);
373
0
            memcpy(pui32, &ui32, 4);
374
0
          }
375
0
          else
376
0
          {
377
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
378
0
          }
379
380
92
          pDescr++;
381
92
          break;
382
92
        }
383
384
203
        case CSN_SPLIT_BITS_CRUMB:
385
203
        {
386
203
          if (remaining_bits_len >= pDescr->descr.crumb_spec[pDescr->i].crumb_bit_length)
387
203
          {
388
203
            proto_tree_add_split_bits_crumb(tree, *pDescr->hf_ptr, tvb, bit_offset,
389
203
                                            pDescr->descr.crumb_spec, pDescr->i);
390
391
203
            remaining_bits_len -= pDescr->descr.crumb_spec[pDescr->i].crumb_bit_length;
392
203
            bit_offset += pDescr->descr.crumb_spec[pDescr->i].crumb_bit_length;
393
203
          }
394
0
          else
395
0
          {
396
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
397
0
          }
398
399
203
          pDescr++;
400
203
          break;
401
203
        }
402
403
234
      case CSN_UINT_ARRAY:
404
234
      {
405
234
        uint8_t no_of_bits  = (uint8_t) pDescr->i;
406
234
        uint16_t nCount = (uint16_t)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
407
234
        uint64_t ret_val;
408
234
        proto_item *pi;
409
234
        int i = 0;
410
411
234
        if (pDescr->value != 0)
412
0
        { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
413
0
          memcpy(&nCount, pui16DATA(data, nCount), 2);
414
0
        }
415
416
234
        if (remaining_bits_len >= (no_of_bits * nCount))
417
209
        {
418
209
          remaining_bits_len -= (no_of_bits * nCount);
419
209
          if (no_of_bits <= 8)
420
209
          {
421
209
            pui8 = pui8DATA(data, pDescr->offset);
422
209
            do
423
734
            {
424
734
              pi = proto_tree_add_bits_ret_val(tree, *(pDescr->hf_ptr), tvb,
425
734
                                               bit_offset, no_of_bits,
426
734
                                               &ret_val, ENC_BIG_ENDIAN);
427
734
              proto_item_append_text(pi, " (count %d)", i++);
428
734
              *pui8++ = (uint8_t)ret_val;
429
734
              bit_offset += no_of_bits;
430
734
            } while (--nCount > 0);
431
209
          }
432
0
          else if (no_of_bits <= 16)
433
0
          {
434
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, 999, &ei_csn1_not_implemented, pDescr);
435
0
          }
436
0
          else if (no_of_bits <= 32)
437
0
          {
438
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, 999, &ei_csn1_not_implemented, pDescr);
439
0
          }
440
0
          else
441
0
          {
442
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
443
0
          }
444
209
        }
445
25
        else
446
25
        {
447
25
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
448
25
        }
449
209
        pDescr++;
450
209
        break;
451
234
      }
452
453
1
      case CSN_VARIABLE_TARRAY_OFFSET:
454
93
      case CSN_VARIABLE_TARRAY:
455
96
      case CSN_TYPE_ARRAY:
456
96
      {
457
96
        int16_t     Status;
458
96
        csnStream_t arT    = *ar;
459
96
        int16_t     nCount = pDescr->i;
460
96
        uint16_t     nSize  = (uint16_t)(int32_t)pDescr->value;
461
96
        int i =0;
462
463
96
        pui8 = pui8DATA(data, pDescr->offset);
464
96
        if (pDescr->type == CSN_VARIABLE_TARRAY)
465
92
        { /* Count specified in field */
466
92
          nCount = *pui8DATA(data, pDescr->i);
467
92
        }
468
4
        else if (pDescr->type == CSN_VARIABLE_TARRAY_OFFSET)
469
1
        { /* Count specified in field */
470
1
          nCount = *pui8DATA(data, pDescr->i);
471
          /*  nCount--; the 1 offset is already taken into account in CSN_UINT_OFFSET */
472
1
        }
473
474
1.28k
        while (nCount > 0)
475
1.21k
        { /* resulting array of length 0 is possible
476
           * but no bits shall be read from bitstream
477
           */
478
1.21k
          proto_item   *ti;
479
1.21k
          proto_tree   *test_tree;
480
481
1.21k
          test_tree = proto_tree_add_subtree_format(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, "%s[%d]",pDescr->sz, i++);
482
483
1.21k
          csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
484
1.21k
          increment_dissection_depth(ar->pinfo);
485
1.21k
          Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR*)pDescr->descr.ptr, tvb, pui8, ett_csn1);
486
1.21k
          decrement_dissection_depth(ar->pinfo);
487
1.21k
          if (Status >= 0)
488
1.19k
          {
489
1.19k
            pui8    += nSize;
490
1.19k
            proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
491
1.19k
            remaining_bits_len = arT.remaining_bits_len;
492
1.19k
            bit_offset         = arT.bit_offset;
493
1.19k
          }
494
29
          else
495
29
          {
496
29
            return Status;
497
29
          }
498
1.19k
          nCount--;
499
1.19k
        }
500
501
67
        pDescr++;
502
67
        break;
503
96
      }
504
505
7
      case CSN_BITMAP:
506
7
      { /* bitmap with given length. The result is left aligned! */
507
7
        uint8_t no_of_bits = (uint8_t) pDescr->i; /* length of bitmap */
508
509
7
        if (no_of_bits > 0)
510
7
        {
511
7
          if (no_of_bits > remaining_bits_len)
512
3
          {
513
3
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
514
3
          }
515
516
4
          if (no_of_bits <= 32)
517
0
          {
518
0
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
519
0
          }
520
4
          else if (no_of_bits <= 64)
521
4
          {
522
4
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
523
4
          }
524
0
          else
525
0
          {
526
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, 999, &ei_csn1_not_implemented, pDescr);
527
0
          }
528
529
4
          remaining_bits_len -= no_of_bits;
530
4
          bit_offset += no_of_bits;
531
4
        }
532
        /* bitmap was successfully extracted or it was empty */
533
534
4
        pDescr++;
535
4
        break;
536
7
      }
537
538
3.27k
      case CSN_TYPE:
539
3.27k
      {
540
3.27k
        int16_t     Status;
541
3.27k
        csnStream_t arT = *ar;
542
3.27k
        proto_item   *ti;
543
3.27k
        proto_tree   *test_tree;
544
3.27k
        if (pDescr->may_be_null && remaining_bits_len == 0)
545
0
        {
546
0
          proto_tree_add_none_format(tree, hf_null_data, tvb, 0, 0, "[NULL data]: %s Not Present", pDescr->sz);
547
3.27k
        } else {
548
3.27k
          test_tree = proto_tree_add_subtree_format(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, "%s", pDescr->sz);
549
3.27k
          csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
550
3.27k
          increment_dissection_depth(ar->pinfo);
551
3.27k
          Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR*)pDescr->descr.ptr, tvb, pvDATA(data, pDescr->offset), ett_csn1);
552
3.27k
          decrement_dissection_depth(ar->pinfo);
553
3.27k
          if (Status >= 0)
554
2.99k
          {
555
2.99k
            proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
556
2.99k
            remaining_bits_len  = arT.remaining_bits_len;
557
2.99k
            bit_offset          = arT.bit_offset;
558
2.99k
          }
559
282
          else
560
282
          {
561
            /* Has already been processed: ProcessError("csnStreamDissector", Status, pDescr);  */
562
282
            return Status;
563
282
          }
564
3.27k
        }
565
2.99k
        pDescr++;
566
2.99k
        break;
567
3.27k
      }
568
569
323
      case CSN_CHOICE:
570
323
      {
571
323
        int16_t count = pDescr->i;
572
323
        uint8_t i     = 0;
573
323
        const CSN_ChoiceElement_t* pChoice = (const CSN_ChoiceElement_t*) pDescr->descr.ptr;
574
575
        /* Make sure that the list of choice items is not empty */
576
323
        if (!count)
577
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_IN_SCRIPT, &ei_csn1_script_error, pDescr);
578
579
935
        while (count > 0)
580
920
        {
581
920
          uint8_t no_of_bits = pChoice->bits;
582
920
          uint8_t value = tvb_get_bits8(tvb, bit_offset, no_of_bits);
583
584
920
          if (value == pChoice->value)
585
308
          {
586
308
            CSN_DESCR   descr[2];
587
308
            int16_t     Status;
588
308
            csnStream_t arT = *ar;
589
308
            proto_item   *ti = NULL;
590
308
            proto_tree   *test_tree;
591
592
308
            descr[0]      = pChoice->descr;
593
308
            memset(&descr[1], 0x00, sizeof(CSN_DESCR));
594
308
            descr[1].type = CSN_END;
595
308
            pui8          = pui8DATA(data, pDescr->offset);
596
308
            *pui8         = i;
597
598
308
            if (pDescr->sz)
599
297
            {
600
297
              proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
601
297
            }
602
603
308
            if (!pChoice->keep_bits)
604
297
            {
605
297
              bit_offset += no_of_bits;
606
297
              remaining_bits_len -= no_of_bits;
607
297
            }
608
609
308
            if (pDescr->sz)
610
297
            {
611
297
              test_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, pDescr->sz);
612
297
            } else {
613
11
              test_tree = tree;
614
11
            }
615
616
308
            csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
617
308
            increment_dissection_depth(ar->pinfo);
618
308
            Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR*)descr, tvb, data, ett_csn1);
619
308
            decrement_dissection_depth(ar->pinfo);
620
621
308
            if (Status >= 0)
622
268
            {
623
268
              if (ti)
624
262
                proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
625
268
              remaining_bits_len = arT.remaining_bits_len;
626
268
              bit_offset         = arT.bit_offset;
627
268
            }
628
40
            else
629
40
            {
630
40
              return Status;
631
40
            }
632
268
            break;
633
308
          }
634
635
612
          count--;
636
612
          pChoice++;
637
612
          i++;
638
612
        }
639
640
        /* Neither of the choice items matched => unknown value */
641
283
        if (!count) {
642
15
          return ProcessError(tree, ar->pinfo, tvb, bit_offset,
643
15
                              CSN_ERROR_STREAM_NOT_SUPPORTED,
644
15
                              &ei_csn1_stream_not_supported, pDescr);
645
15
        }
646
647
268
        pDescr++;
648
268
        break;
649
283
      }
650
651
68
      case CSN_SERIALIZE:
652
68
      {
653
68
        StreamSerializeFcn_t serialize = (StreamSerializeFcn_t)pDescr->aux_fn;
654
68
        csnStream_t          arT       = *ar;
655
68
        unsigned length_len = pDescr->i;
656
68
        int16_t              Status = -1;
657
68
        proto_item   *ti;
658
68
        proto_tree   *test_tree;
659
68
        uint8_t length = 0;
660
661
68
        if (length_len)
662
61
        {
663
61
          length = tvb_get_bits8(tvb, bit_offset, length_len);
664
665
61
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, length_len, ENC_BIG_ENDIAN);
666
667
61
          bit_offset += length_len;
668
61
          remaining_bits_len -= length_len;
669
670
61
          test_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, ((bit_offset+length-1)>>3)-(bit_offset>>3) + 1, ett_csn1, &ti, pDescr->sz);
671
61
        } else {
672
7
          test_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, pDescr->sz);
673
7
        }
674
675
68
        csnStreamInit(&arT, bit_offset, length > 0 ? length : remaining_bits_len, ar->pinfo);
676
68
        Status = serialize(test_tree, &arT, tvb, pvDATA(data, pDescr->offset), ett_csn1);
677
678
68
        if (Status >= 0)
679
61
        {
680
61
          if (length > 0) {
681
47
            remaining_bits_len -= length;
682
47
            bit_offset         += length;
683
47
          } else {
684
14
            proto_item_set_len(ti,((arT.bit_offset - bit_offset)>>3)+1);
685
14
            remaining_bits_len = arT.remaining_bits_len;
686
14
            bit_offset         = arT.bit_offset;
687
14
          }
688
61
          pDescr++;
689
61
        }
690
7
        else
691
7
        {
692
          /* Has already been processed: */
693
7
          return Status;
694
7
        }
695
696
61
        break;
697
68
      }
698
699
61
      case CSN_UNION_LH:
700
1.44k
      case CSN_UNION:
701
1.44k
      {
702
1.44k
        int16_t          Bits;
703
1.44k
        uint8_t          t_index;
704
1.44k
        int16_t          count      = pDescr->i;
705
1.44k
        const CSN_DESCR* pDescrNext = pDescr;
706
707
1.44k
        pDescrNext += count + 1; /* now this is next after the union */
708
1.44k
        if ((count <= 0) || (count > 16))
709
0
        {
710
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_INVALID_UNION_INDEX, &ei_csn1_union_index, pDescr);
711
0
        }
712
713
        /* Now get the bits to extract the index */
714
1.44k
        Bits = ixBitsTab[count];
715
1.44k
        proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, Bits, tvb_get_bits8(tvb, bit_offset, Bits), ENC_BIG_ENDIAN, " (Union)");
716
1.44k
        t_index = 0;
717
718
2.98k
        while (Bits > 0)
719
1.54k
        {
720
1.54k
          t_index <<= 1;
721
722
1.54k
          if (CSN_UNION_LH == pDescr->type)
723
0
          {
724
0
            t_index |= tvb_get_masked_bits8(tvb, bit_offset, 1);
725
0
          }
726
1.54k
          else
727
1.54k
          {
728
1.54k
            t_index |= tvb_get_bits8(tvb, bit_offset, 1);
729
1.54k
          }
730
731
1.54k
          remaining_bits_len--;
732
1.54k
          bit_offset++;
733
1.54k
          Bits--;
734
1.54k
        }
735
736
        /* Assign UnionType */
737
1.44k
        pui8  = pui8DATA(data, pDescr->offset);
738
1.44k
        *pui8 = t_index;
739
740
        /* script index to continue on, limited in case we do not have a power of 2 */
741
1.44k
        pDescr += (MIN(t_index + 1, count));
742
743
1.44k
        switch (pDescr->type)
744
1.44k
        { /* get the right element of the union based on computed index */
745
746
0
          case CSN_BIT:
747
0
          {
748
0
            pui8  = pui8DATA(data, pDescr->offset);
749
750
0
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
751
752
0
            *pui8 = 0x00;
753
0
            if (tvb_get_bits8(tvb, bit_offset, 1) > 0)
754
0
            {
755
0
              *pui8 = 0x01;
756
0
            }
757
0
            remaining_bits_len --;
758
0
            bit_offset++;
759
0
            pDescr++;
760
0
            break;
761
0
          }
762
763
0
          case CSN_NULL:
764
0
          { /* Empty member! */
765
0
            bit_offset += pDescr->i;
766
0
            pDescr++;
767
0
            break;
768
0
          }
769
770
932
          case CSN_UINT:
771
932
          {
772
932
            uint8_t no_of_bits = (uint8_t) pDescr->i;
773
932
            if (remaining_bits_len >= no_of_bits)
774
919
            {
775
919
              if (no_of_bits <= 8)
776
303
              {
777
303
                uint8_t ui8 = tvb_get_bits8(tvb, bit_offset, no_of_bits);
778
303
                pui8      = pui8DATA(data, pDescr->offset);
779
303
                *pui8     = ui8;
780
303
                proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
781
782
303
              }
783
616
              else if (no_of_bits <= 16)
784
367
              {
785
367
                uint16_t ui16 = tvb_get_bits16(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
786
367
                pui16       = pui16DATA(data, pDescr->offset);
787
367
                memcpy(pui16, &ui16, 2);
788
367
                proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
789
367
              }
790
249
              else if (no_of_bits <= 32)
791
249
              {
792
249
                uint32_t ui32 = tvb_get_bits32(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
793
249
                pui32       = pui32DATA(data, pDescr->offset);
794
249
                memcpy(pui32, &ui32, 4);
795
249
                proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
796
797
249
              }
798
0
              else
799
0
              {
800
0
                return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
801
0
              }
802
919
            }
803
13
            else
804
13
            {
805
13
              return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
806
13
            }
807
808
919
            remaining_bits_len -= no_of_bits;
809
919
            bit_offset += no_of_bits;
810
919
            pDescr++;
811
919
            break;
812
932
          }
813
814
0
          case CSN_UINT_OFFSET:
815
0
          {
816
0
            uint8_t no_of_bits = (uint8_t) pDescr->i;
817
818
0
            if (remaining_bits_len >= no_of_bits)
819
0
            {
820
0
              if (no_of_bits <= 8)
821
0
              {
822
0
                uint8_t ui8 = tvb_get_bits8(tvb, bit_offset, no_of_bits);
823
0
                pui8      = pui8DATA(data, pDescr->offset);
824
0
                *pui8     = ui8 + (uint8_t)pDescr->descr.value;
825
0
                proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ui8, ENC_BIG_ENDIAN, "%d", ui8);
826
0
              }
827
0
              else if (no_of_bits <= 16)
828
0
              {
829
0
                uint16_t ui16 = tvb_get_bits16(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN) + (uint16_t)pDescr->descr.value;
830
0
                pui16       = pui16DATA(data, pDescr->offset);
831
0
                memcpy(pui16, &ui16, 2);
832
0
                proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ui16, ENC_BIG_ENDIAN, "%d", ui16);
833
0
              }
834
0
              else if (no_of_bits <= 32)
835
0
              {
836
0
                uint32_t ui32 = tvb_get_bits32(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN) + (uint16_t)pDescr->descr.value;
837
0
                pui32       = pui32DATA(data, pDescr->offset);
838
0
                memcpy(pui32, &ui32, 4);
839
0
                proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ui32, ENC_BIG_ENDIAN, "%d", ui32);
840
0
              }
841
0
              else
842
0
              {
843
0
                return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
844
0
              }
845
0
            }
846
0
            else
847
0
            {
848
0
              return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
849
0
            }
850
851
0
            remaining_bits_len -= no_of_bits;
852
0
            bit_offset += no_of_bits;
853
0
            pDescr++;
854
0
            break;
855
0
          }
856
857
0
          case CSN_UINT_LH:
858
0
          {
859
0
            uint8_t no_of_bits = (uint8_t) pDescr->i;
860
861
0
            if (remaining_bits_len >= no_of_bits)
862
0
            {
863
0
              if (no_of_bits <= 8)
864
0
              {
865
0
                uint8_t ui8 = tvb_get_masked_bits8(tvb, bit_offset, no_of_bits);
866
0
                pui8      = pui8DATA(data, pDescr->offset);
867
0
                *pui8     = ui8;
868
0
                proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
869
0
              }
870
0
              else
871
0
              { /* Maybe we should support more than 8 bits ? */
872
0
                ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
873
0
              }
874
0
            }
875
0
            else
876
0
            {
877
0
              return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
878
0
            }
879
880
0
            remaining_bits_len -= no_of_bits;
881
0
            bit_offset += no_of_bits;
882
0
            pDescr++;
883
0
            break;
884
0
          }
885
886
22
          case CSN_UINT_ARRAY:
887
22
          {
888
22
            uint8_t no_of_bits  = (uint8_t) pDescr->i;
889
22
            uint16_t nCount = (uint16_t)pDescr->descr.value; /* nCount supplied by value i.e. M_UINT_ARRAY(...) */
890
22
            uint64_t ret_val;
891
22
            proto_item *pi;
892
22
            int i = 0;
893
894
22
            if (pDescr->value != 0)
895
0
            { /* nCount specified by a reference to field holding value i.e. M_VAR_UINT_ARRAY(...) */
896
0
              memcpy(&nCount, pui16DATA(data, nCount), 2);
897
0
            }
898
899
22
            if (remaining_bits_len >= (no_of_bits * nCount))
900
18
            {
901
18
              remaining_bits_len -= (no_of_bits * nCount);
902
18
              if (no_of_bits <= 8)
903
18
              {
904
18
                pui8 = pui8DATA(data, pDescr->offset);
905
906
90
                while (nCount > 0)
907
72
                {
908
72
                  pi = proto_tree_add_bits_ret_val(tree, *(pDescr->hf_ptr), tvb,
909
72
                                                   bit_offset, no_of_bits,
910
72
                                                   &ret_val, ENC_BIG_ENDIAN);
911
72
                  proto_item_append_text(pi, " (count %d)", i++);
912
72
                  *pui8++ = (uint8_t)ret_val;
913
72
                  bit_offset += no_of_bits;
914
72
                  nCount--;
915
72
                }
916
18
              }
917
0
              else if (no_of_bits <= 16)
918
0
              {
919
0
                pui16 = pui16DATA(data, pDescr->offset);
920
921
0
                while (nCount > 0)
922
0
                {
923
0
                  pi = proto_tree_add_bits_ret_val(tree, *(pDescr->hf_ptr), tvb,
924
0
                                                   bit_offset, no_of_bits,
925
0
                                                   &ret_val, ENC_BIG_ENDIAN);
926
0
                  proto_item_append_text(pi, " (count %d)", i++);
927
0
                  *pui16++ = (uint16_t)ret_val;
928
0
                  bit_offset += no_of_bits;
929
0
                  nCount--;
930
0
                }
931
0
              }
932
0
              else if (no_of_bits <= 32)
933
0
              { /* not supported */
934
0
                return ProcessError(tree, ar->pinfo, tvb, bit_offset, 999, &ei_csn1_not_implemented, pDescr);
935
0
              }
936
0
              else
937
0
              {
938
0
                return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_GENERAL, &ei_csn1_general, pDescr);
939
0
              }
940
18
            }
941
4
            else
942
4
            {
943
4
              return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
944
4
            }
945
946
18
            pDescr++;
947
18
            break;
948
22
          }
949
950
0
          case CSN_VARIABLE_TARRAY_OFFSET:
951
0
          case CSN_VARIABLE_TARRAY:
952
6
          case CSN_TYPE_ARRAY:
953
6
          {
954
6
            int16_t     Status;
955
6
            csnStream_t arT    = *ar;
956
6
            uint16_t     nCount = (uint16_t) pDescr->i;
957
6
            uint16_t     nSize  = (uint16_t)(uint32_t)pDescr->value;
958
6
            int i = 0;
959
960
6
            pui8  = pui8DATA(data, pDescr->offset);
961
962
6
            if (CSN_VARIABLE_TARRAY == pDescr->type)
963
0
            { /* Count specified in field */
964
0
              nCount = *pui8DATA(data, pDescr->i);
965
0
            }
966
6
            else if (CSN_VARIABLE_TARRAY_OFFSET == pDescr->type)
967
0
            { /* Count specified in field */
968
0
              nCount = *pui8DATA(data, pDescr->i);
969
0
              nCount--; /* Offset 1 */
970
0
            }
971
972
32
            while (nCount--)    /* Changed to handle length = 0.  */
973
30
            {
974
30
              proto_item   *ti;
975
30
              proto_tree   *test_tree;
976
977
30
              test_tree = proto_tree_add_subtree_format(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, "%s[%d]",pDescr->sz, i++);
978
979
30
              csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
980
30
              increment_dissection_depth(ar->pinfo);
981
30
              Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR *)pDescr->descr.ptr, tvb, pui8, ett_csn1);
982
30
              decrement_dissection_depth(ar->pinfo);
983
30
              if (Status >= 0)
984
26
              {
985
26
                pui8    += nSize;
986
26
                proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
987
26
                remaining_bits_len = arT.remaining_bits_len;
988
26
                bit_offset         = arT.bit_offset;
989
26
              }
990
4
              else
991
4
              {
992
4
                return Status;
993
4
              }
994
30
            }
995
996
2
            pDescr++;
997
2
            break;
998
6
          }
999
1000
0
          case CSN_BITMAP:
1001
0
          { /* bitmap with given length. The result is left aligned! */
1002
0
            uint8_t no_of_bits = (uint8_t) pDescr->i; /* length of bitmap */
1003
1004
0
            if (no_of_bits > 0)
1005
0
            { /* a non empty bitmap */
1006
0
              proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1007
0
              remaining_bits_len -= no_of_bits;
1008
0
              bit_offset += no_of_bits;
1009
1010
0
              if (remaining_bits_len < 0)
1011
0
              {
1012
0
                return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1013
0
              }
1014
1015
0
            }
1016
            /* bitmap was successfully extracted or it was empty */
1017
1018
0
            pDescr++;
1019
0
            break;
1020
0
          }
1021
1022
468
          case CSN_TYPE:
1023
468
          {
1024
468
            int16_t     Status;
1025
468
            csnStream_t arT = *ar;
1026
468
            proto_item   *ti;
1027
468
            proto_tree   *test_tree;
1028
1029
468
            if (pDescr->may_be_null && remaining_bits_len == 0)
1030
0
            {
1031
0
              proto_tree_add_none_format(tree, hf_null_data, tvb, 0, 0, "[NULL data]: %s Not Present", pDescr->sz);
1032
468
            } else {
1033
468
              test_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, pDescr->sz);
1034
468
              csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
1035
468
              increment_dissection_depth(ar->pinfo);
1036
468
              Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR *)pDescr->descr.ptr, tvb, pvDATA(data, pDescr->offset), ett_csn1);
1037
468
              decrement_dissection_depth(ar->pinfo);
1038
468
              if (Status >= 0)
1039
303
              {
1040
303
                proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
1041
303
                remaining_bits_len = arT.remaining_bits_len;
1042
303
                bit_offset         = arT.bit_offset;
1043
303
              }
1044
165
              else
1045
165
              { /* return error code Has already been processed:  */
1046
165
                return Status;
1047
165
              }
1048
468
            }
1049
303
            pDescr++;
1050
303
            break;
1051
468
          }
1052
1053
15
          default:
1054
15
          { /* descriptions of union elements other than above are illegal */
1055
15
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_IN_SCRIPT, &ei_csn1_script_error, pDescr);
1056
468
          }
1057
1.44k
        }
1058
1059
1.24k
        pDescr = pDescrNext;
1060
1.24k
        break;
1061
1.44k
      }
1062
1063
0
      case CSN_EXIST:
1064
0
      case CSN_EXIST_LH:
1065
0
      {
1066
0
        uint8_t fExist;
1067
1068
0
        pui8  = pui8DATA(data, pDescr->offset);
1069
1070
0
        if (CSN_EXIST_LH == pDescr->type)
1071
0
        {
1072
0
          fExist = tvb_get_masked_bits8(tvb, bit_offset, 1);
1073
0
          proto_tree_add_uint(tree, *(pDescr->hf_ptr), tvb, bit_offset>>3, 1, fExist);
1074
0
        }
1075
0
        else
1076
0
        {
1077
0
          fExist = tvb_get_bits8(tvb, bit_offset, 1);
1078
0
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1079
0
        }
1080
1081
0
        *pui8 = fExist;
1082
0
        remaining_bits_len --;
1083
0
        bit_offset++;
1084
0
        pDescr++;
1085
1086
0
        if (!fExist)
1087
0
        {
1088
0
          ar->remaining_bits_len  = remaining_bits_len;
1089
0
          ar->bit_offset          = bit_offset;
1090
0
          return remaining_bits_len;
1091
0
        }
1092
1093
0
        break;
1094
0
      }
1095
1096
3.28k
      case CSN_NEXT_EXIST:
1097
3.28k
      {
1098
3.28k
        uint8_t isnull;
1099
1100
3.28k
        pui8  = pui8DATA(data, pDescr->offset);
1101
1102
        /* this if-statement represents the M_NEXT_EXIST_OR_NULL description element */
1103
3.28k
        if ((pDescr->may_be_null) && (remaining_bits_len == 0))
1104
45
        { /* no more bits to decode is fine here - end of message detected and allowed */
1105
1106
          /* Skip i entries + this entry */
1107
45
          pDescr += pDescr->i + 1;
1108
1109
          /* Set the data member to "not exist" */
1110
45
          *pui8 = 0;
1111
45
          break;
1112
45
        }
1113
1114
        /* the "regular" M_NEXT_EXIST description element */
1115
3.23k
        proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1116
1117
3.23k
        isnull = 1;
1118
3.23k
        if (tvb_get_bits8(tvb, bit_offset, 1))
1119
1.75k
        {
1120
1.75k
          if (remaining_bits_len == 1)
1121
9
          {
1122
             /* If { 1 < end > } and all next items may be null, store it as { 0 } */
1123
9
            const CSN_DESCR* pDescrNext = pDescr + 1;
1124
9
            uint8_t i;
1125
23
            for (i = 0; i < pDescr->i; i++, pDescrNext++)
1126
14
            {
1127
14
              if (!pDescrNext->may_be_null)
1128
14
                isnull = 0;
1129
14
            }
1130
1.74k
          } else {
1131
1.74k
            isnull = 0;
1132
1.74k
          }
1133
1.75k
        }
1134
1135
3.23k
        *pui8     = isnull ? 0 : 1;
1136
1137
3.23k
        remaining_bits_len --;
1138
3.23k
        bit_offset++;
1139
1140
3.23k
        if (isnull)
1141
1.47k
        { /* Skip 'i' entries */
1142
1.47k
          pDescr += pDescr->i;
1143
1.47k
        }
1144
1145
3.23k
        pDescr++;
1146
3.23k
        break;
1147
3.28k
      }
1148
1149
0
      case CSN_NEXT_EXIST_LH:
1150
0
      {
1151
0
        uint8_t isnull;
1152
0
        pui8  = pui8DATA(data, pDescr->offset);
1153
1154
        /* this if-statement represents the M_NEXT_EXIST_OR_NULL_LH description element */
1155
0
        if ((pDescr->descr.ptr != NULL) && (remaining_bits_len == 0))
1156
0
        { /* no more bits to decode is fine here - end of message detected and allowed */
1157
1158
          /* skip 'i' entries + this entry */
1159
0
          pDescr += pDescr->i + 1;
1160
1161
          /* set the data member to "not exist" */
1162
0
          *pui8 = 0;
1163
0
          break;
1164
0
        }
1165
1166
        /* the "regular" M_NEXT_EXIST_LH description element */
1167
0
        proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1168
1169
0
        isnull = 1;
1170
0
        if (tvb_get_masked_bits8(tvb, bit_offset, 1))
1171
0
        {
1172
0
          if (remaining_bits_len == 1) {
1173
             /* If { 1 < end > } and all next items may be null, store it as { 0 } */
1174
0
            const CSN_DESCR* pDescrNext = pDescr + 1;
1175
0
            uint8_t i;
1176
0
            for (i = 0; i < pDescr->i; i++, pDescrNext++)
1177
0
            {
1178
0
              if (!pDescrNext->may_be_null)
1179
0
                isnull = 0;
1180
0
            }
1181
0
          } else {
1182
0
            isnull = 0;
1183
0
          }
1184
0
        }
1185
1186
0
        *pui8++   = isnull ? 0 : 1;
1187
1188
0
        remaining_bits_len --;
1189
0
        bit_offset++;
1190
1191
0
        if (isnull)
1192
0
        { /* Skip 'i' entries */
1193
0
          pDescr += pDescr->i;
1194
0
        }
1195
0
        pDescr++;
1196
1197
0
        break;
1198
0
      }
1199
1200
0
      case CSN_VARIABLE_BITMAP_1:
1201
0
      { /* Bitmap from here and to the end of message */
1202
1203
0
        *pui8DATA(data, (int16_t)pDescr->descr.value) = (uint8_t) remaining_bits_len; /* length of bitmap == remaining bits */
1204
1205
        /*no break -
1206
         * with a length set we have a regular variable length bitmap so we continue */
1207
0
      }
1208
      /* FALL THROUGH */
1209
405
      case CSN_VARIABLE_BITMAP:
1210
405
      { /* {CSN_VARIABLE_BITMAP, 0, offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1211
         * <N: bit (5)> <bitmap: bit(N + offset)>
1212
         * Bit array with length (in bits) specified in parameter (pDescr->descr)
1213
         * The result is right aligned!
1214
         */
1215
405
        int16_t no_of_bits = *pui8DATA(data, (int16_t)pDescr->descr.value);
1216
1217
405
        no_of_bits += pDescr->i; /* adjusted by offset */
1218
1219
2.49k
        while (no_of_bits > 0)
1220
2.08k
        {
1221
2.08k
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1222
2.08k
          bit_offset++;
1223
2.08k
          no_of_bits--;
1224
2.08k
          remaining_bits_len--;
1225
1226
2.08k
          if (remaining_bits_len < 0)
1227
0
          {
1228
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1229
0
          }
1230
2.08k
        }
1231
405
        pDescr++;
1232
405
        break;
1233
405
      }
1234
1235
8
      case CSN_LEFT_ALIGNED_VAR_BMP_1:
1236
8
      { /* Bitmap from here and to the end of message */
1237
1238
8
        *pui8DATA(data, (int16_t)pDescr->descr.value) = (uint8_t) remaining_bits_len; /* length of bitmap == remaining bits */
1239
1240
        /* no break -
1241
         * with a length set we have a regular left aligned variable length bitmap so we continue
1242
         */
1243
8
      }
1244
      /* FALL THROUGH */
1245
39
      case CSN_LEFT_ALIGNED_VAR_BMP:
1246
39
      { /* {CSN_LEFT_ALIGNED_VAR_BMP, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1247
         * <N: bit (5)> <bitmap: bit(N + offset)>
1248
         * bit array with length (in bits) specified in parameter (pDescr->descr)
1249
         */
1250
39
        int16_t no_of_bits = *pui8DATA(data, (int16_t)pDescr->descr.value);/* Size of bitmap */
1251
1252
39
        no_of_bits += pDescr->i;/* size adjusted by offset */
1253
1254
39
        if (no_of_bits > 0)
1255
36
        {
1256
36
          if (no_of_bits <= 32)
1257
11
          {
1258
11
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1259
11
          }
1260
25
          else if (no_of_bits <= 64)
1261
18
          {
1262
18
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1263
18
          }
1264
7
          else
1265
7
          {
1266
7
            proto_tree_add_uint64_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset>>3, ((bit_offset+no_of_bits-1)>>3)-(bit_offset>>3)+1, no_of_bits, "%u bits",
1267
7
                                     no_of_bits);
1268
7
          }
1269
36
          bit_offset += no_of_bits;
1270
36
          remaining_bits_len -= no_of_bits;
1271
1272
36
          if (remaining_bits_len < 0)
1273
1
          {
1274
1
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1275
1
          }
1276
36
        }
1277
1278
        /* bitmap was successfully extracted or it was empty */
1279
38
        pDescr++;
1280
38
        break;
1281
39
      }
1282
1283
1284
298
      case CSN_PADDING_BITS:
1285
298
      { /* Padding from here and to the end of message */
1286
1287
298
        if (remaining_bits_len > 0)
1288
287
        {
1289
287
          proto_tree *padding_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, -1, ett_csn1, NULL, "Padding Bits");
1290
1.72k
          while (remaining_bits_len > 0)
1291
1.43k
          {
1292
1.43k
            int bits_to_handle = remaining_bits_len + (bit_offset%8);
1293
1.43k
            if (bits_to_handle > 32)
1294
1.14k
            {
1295
1.14k
               bits_to_handle = 32 - (bit_offset%8);
1296
1.14k
            }
1297
287
            else
1298
287
            {
1299
287
               bits_to_handle -= (bit_offset%8);
1300
287
            }
1301
1.43k
            proto_tree_add_bits_item(padding_tree, *(pDescr->hf_ptr), tvb, bit_offset, bits_to_handle, ENC_BIG_ENDIAN);
1302
1.43k
            bit_offset += bits_to_handle;
1303
1.43k
            remaining_bits_len -= bits_to_handle;
1304
1.43k
          }
1305
287
        }
1306
298
        if (remaining_bits_len < 0)
1307
0
        {
1308
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1309
0
        }
1310
1311
        /* Padding was successfully extracted or it was empty */
1312
298
        pDescr++;
1313
298
        break;
1314
298
      }
1315
1316
47
      case CSN_VARIABLE_ARRAY:
1317
47
      { /* {int type; int i; void* descr; int offset; const char* sz; } CSN_DESCR;
1318
         * {CSN_VARIABLE_ARRAY, _OFFSET, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1319
         * Array with length specified in parameter:
1320
         *  <count: bit (x)>
1321
         *  <list: octet(count + offset)>
1322
         */
1323
47
        int16_t count = *pui8DATA(data, (int16_t)pDescr->descr.value);
1324
1325
47
        count += pDescr->i; /* Adjusted by offset */
1326
1327
47
        if (count > 0)
1328
47
        {
1329
47
          pui8 = pui8DATA(data, pDescr->offset);
1330
1331
494
          while (count > 0)
1332
447
          {
1333
447
            proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 8, ENC_BIG_ENDIAN);
1334
447
            *pui8++ = tvb_get_bits8(tvb, bit_offset, 8);
1335
447
            bit_offset += 8;
1336
447
            count--;
1337
447
            remaining_bits_len -= 8;
1338
447
            if (remaining_bits_len < 0)
1339
0
            {
1340
0
              return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1341
0
            }
1342
447
          }
1343
47
        }
1344
1345
47
        pDescr++;
1346
47
        break;
1347
47
      }
1348
1349
173
      case CSN_RECURSIVE_ARRAY:
1350
173
      { /* Recursive way to specify an array: <list> ::= {1 <number: bit (4)> <list> | 0}
1351
         *  or more generally:                <list> ::= { <tag> <element> <list> | <EndTag> }
1352
         *  where <element> ::= bit(value)
1353
         *        <tag>     ::= 0 | 1
1354
         *        <EndTag>  ::= reversed tag i.e. tag == 1 -> EndTag == 0 and vice versa
1355
         * {CSN_RECURSIVE_ARRAY, _BITS, (void*)offsetof(_STRUCT, _ElementCountField), offsetof(_STRUCT, _MEMBER), #_MEMBER}
1356
         * REMARK: recursive way to specify an array but an iterative implementation!
1357
         */
1358
173
        int16_t no_of_bits        = pDescr->i;
1359
173
        uint8_t ElementCount = 0;
1360
1361
173
        pui8  = pui8DATA(data, pDescr->offset);
1362
1363
471
        while (existNextElement(tvb, bit_offset, Tag))
1364
298
        { /* tag control shows existence of next list elements */
1365
298
          proto_tree_add_bits_item(tree, *(pDescr->hf_exist_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1366
298
          bit_offset++;
1367
298
          remaining_bits_len--;
1368
1369
          /* extract and store no_of_bits long element from bitstream */
1370
298
          *pui8++   = tvb_get_bits8(tvb, bit_offset, no_of_bits);
1371
298
          ElementCount++;
1372
1373
298
          if (remaining_bits_len < 0)
1374
0
          {
1375
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1376
0
          }
1377
1378
298
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1379
298
          bit_offset += no_of_bits;
1380
298
          remaining_bits_len -= no_of_bits;
1381
298
        }
1382
1383
173
        proto_tree_add_bits_item(tree, *(pDescr->hf_exist_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1384
1385
        /* existNextElement() returned false, 1 bit consumed */
1386
173
        bit_offset++;
1387
173
        remaining_bits_len--;
1388
1389
        /* Store the counted number of elements of the array */
1390
173
        *pui8DATA(data, (int16_t)pDescr->descr.value) = ElementCount;
1391
1392
173
        pDescr++;
1393
173
        break;
1394
173
      }
1395
1396
921
      case CSN_RECURSIVE_TARRAY:
1397
921
      { /* Recursive way to specify an array of type: <lists> ::= { 1 <type> } ** 0 ;
1398
         *  M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1399
         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), NULL, NULL, (void_fn_t)array_length(((_STRUCT*)0)->_MEMBER)}
1400
         */
1401
921
        int16_t nSizeElement = (int16_t)(int32_t)pDescr->value;
1402
921
        uint32_t nSizeArray = (uint32_t)((uintptr_t)pDescr->aux_fn);
1403
921
        uint8_t ElementCount = 0;
1404
1405
1.80k
        while (existNextElement(tvb, bit_offset, Tag))
1406
945
        { /* tag control shows existence of next list elements */
1407
945
          proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, ENC_BIG_ENDIAN);
1408
1409
          /* existNextElement() returned true, 1 bit consumed */
1410
945
          bit_offset++;
1411
945
          remaining_bits_len--;
1412
945
          ElementCount++;
1413
1414
945
          if (ElementCount > nSizeArray)
1415
8
          {
1416
            /* error: too many elements in recursive array. Increase its size! */
1417
8
            return ProcessError(tree , ar->pinfo, tvb, bit_offset, CSN_ERROR_STREAM_NOT_SUPPORTED, &ei_csn1_stream_not_supported, pDescr);
1418
8
          }
1419
1420
937
          { /* unpack the following data structure */
1421
937
            csnStream_t arT = *ar;
1422
937
            int16_t     Status;
1423
937
            proto_item   *ti;
1424
937
            proto_tree   *test_tree;
1425
1426
937
            test_tree = proto_tree_add_subtree(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, pDescr->sz);
1427
1428
937
            csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
1429
937
            increment_dissection_depth(ar->pinfo);
1430
937
            Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR *)pDescr->descr.ptr, tvb, pvDATA(data, pDescr->offset), ett_csn1);
1431
937
            decrement_dissection_depth(ar->pinfo);
1432
1433
937
            if (Status >= 0)
1434
881
            { /* successful completion */
1435
881
              pui8    += nSizeElement;  /* -> to next data element */
1436
881
              proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
1437
881
              remaining_bits_len = arT.remaining_bits_len;
1438
881
              bit_offset         = arT.bit_offset;
1439
881
            }
1440
56
            else
1441
56
            { /* something went awry */
1442
56
              return Status;
1443
56
            }
1444
937
          }
1445
1446
881
          if (remaining_bits_len < 0)
1447
0
          {
1448
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1449
0
          }
1450
881
        }
1451
1452
        /* existNextElement() returned false, 1 bit consumed */
1453
857
        bit_offset++;
1454
857
        remaining_bits_len --;
1455
1456
        /* Store the counted number of elements of the array */
1457
857
        *pui8DATA(data, (int16_t)(int32_t)pDescr->i) = ElementCount;
1458
1459
857
        pDescr++;
1460
857
        break;
1461
921
      }
1462
1463
0
      case CSN_RECURSIVE_TARRAY_2:
1464
0
      { /* Recursive way to specify an array of type: <list> ::= <type> { 0 <type> } ** 1 ; */
1465
1466
0
        Tag = REVERSED_TAG;
1467
1468
        /* NO break -
1469
         * handling is exactly the same as for CSN_RECURSIVE_TARRAY_1 so we continue
1470
         */
1471
0
      }
1472
      /* FALL THROUGH */
1473
77
      case CSN_RECURSIVE_TARRAY_1:
1474
77
      { /* Recursive way to specify an array of type: <lists> ::= <type> { 1 <type> } ** 0 ;
1475
         * M_REC_TARRAY(_STRUCT, _MEMBER, _MEMBER_TYPE, _ElementCountField)
1476
         * {t, offsetof(_STRUCT, _ElementCountField), (void*)CSNDESCR_##_MEMBER_TYPE, offsetof(_STRUCT, _MEMBER), #_MEMBER, (StreamSerializeFcn_t)sizeof(_MEMBER_TYPE), NULL, NULL, (void_fn_t)array_length(((_STRUCT*)0)->_MEMBER)}
1477
         */
1478
77
        int16_t     nSizeElement = (int16_t)(int32_t)pDescr->value;
1479
77
        uint32_t    nSizeArray = (uint32_t)((uintptr_t)pDescr->aux_fn);
1480
77
        uint8_t      ElementCount = 0;
1481
77
        csnStream_t arT          = *ar;
1482
77
        bool         EndOfList    = false;
1483
77
        int16_t     Status;
1484
77
        proto_item   *ti;
1485
77
        proto_tree   *test_tree;
1486
1487
77
        do
1488
150
        { /* get data element */
1489
150
          ElementCount++;
1490
1491
150
        if (ElementCount >= nSizeArray)
1492
4
        {
1493
          /* error: too many elements in recursive array. Increase its size! */
1494
4
          return ProcessError(tree , ar->pinfo, tvb, bit_offset, CSN_ERROR_STREAM_NOT_SUPPORTED, &ei_csn1_stream_not_supported, pDescr);
1495
4
        }
1496
1497
146
          test_tree = proto_tree_add_subtree_format(tree, tvb, bit_offset>>3, 1, ett_csn1, &ti, "%s[%d]", pDescr->sz, ElementCount-1);
1498
1499
146
          csnStreamInit(&arT, bit_offset, remaining_bits_len, ar->pinfo);
1500
146
          increment_dissection_depth(ar->pinfo);
1501
146
          Status = csnStreamDissector(test_tree, &arT, (const CSN_DESCR *)pDescr->descr.ptr, tvb, pvDATA(data, pDescr->offset), ett_csn1);
1502
146
          decrement_dissection_depth(ar->pinfo);
1503
1504
146
          if (Status >= 0)
1505
106
          { /* successful completion */
1506
106
            pui8    += nSizeElement;  /* -> to next */
1507
106
            proto_item_set_len(ti,((arT.bit_offset-1)>>3) - (bit_offset>>3)+1);
1508
106
            remaining_bits_len = arT.remaining_bits_len;
1509
106
            bit_offset         = arT.bit_offset;
1510
106
          }
1511
40
          else
1512
40
          { /* something went awry */
1513
40
            return Status;
1514
40
          }
1515
1516
106
          if (remaining_bits_len < 0)
1517
0
          {
1518
0
            return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1519
0
          }
1520
1521
          /* control of next element's tag */
1522
106
          proto_tree_add_uint_bits_format_value(tree, *(pDescr->hf_ptr), tvb, bit_offset, 1, tvb_get_bits8(tvb, bit_offset, 1), ENC_BIG_ENDIAN, "%s[%d]",
1523
106
                                     proto_registrar_get_name(*(pDescr->hf_ptr)), ElementCount);
1524
106
          EndOfList         = !(existNextElement(tvb, bit_offset, Tag));
1525
1526
106
          bit_offset++;
1527
106
          remaining_bits_len--; /* 1 bit consumed (tag) */
1528
106
        } while (!EndOfList);
1529
1530
1531
        /* Store the count of the array */
1532
33
        *pui8DATA(data, pDescr->i) = ElementCount;
1533
33
        Tag = STANDARD_TAG; /* in case it was set to "reversed" */
1534
33
        pDescr++;
1535
33
        break;
1536
77
      }
1537
1538
317
      case CSN_FIXED:
1539
317
      { /* Verify the fixed bits */
1540
317
        uint8_t no_of_bits = (uint8_t) pDescr->i;
1541
317
        uint32_t ui32;
1542
1543
317
        if (no_of_bits <= 8)
1544
317
        {
1545
317
          ui32 = tvb_get_bits8(tvb, bit_offset, no_of_bits);
1546
317
        }
1547
0
        else if (no_of_bits <= 16)
1548
0
        {
1549
0
          ui32 = tvb_get_bits16(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1550
0
        }
1551
0
        else if (no_of_bits <= 32)
1552
0
        {
1553
0
          ui32  = tvb_get_bits32(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1554
0
        }
1555
0
        else
1556
0
        {
1557
0
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, -1, &ei_csn1_more32bits, pDescr);
1558
0
        }
1559
317
        if (ui32 != (unsigned)(int32_t)pDescr->offset)
1560
80
        {
1561
80
          return ProcessError(tree, ar->pinfo, tvb, bit_offset, -1, &ei_csn1_fixed_not_matched, pDescr);
1562
80
        }
1563
237
        proto_tree_add_bits_item(tree, *(pDescr->hf_ptr), tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
1564
1565
237
        remaining_bits_len   -= no_of_bits;
1566
237
        bit_offset += no_of_bits;
1567
237
        pDescr++;
1568
237
        break;
1569
317
      }
1570
1571
172
      case CSN_CALLBACK:
1572
172
      {
1573
172
        uint16_t no_of_bits;
1574
172
        DissectorCallbackFcn_t callback = (DissectorCallbackFcn_t)pDescr->aux_fn;
1575
1576
172
        no_of_bits = callback(tree, tvb, pvDATA(data, pDescr->i), pvDATA(data, pDescr->offset), bit_offset, ett_csn1, ar->pinfo);
1577
172
        bit_offset += no_of_bits;
1578
172
        remaining_bits_len -= no_of_bits;
1579
1580
172
        pDescr++;
1581
172
        break;
1582
317
      }
1583
1584
6
      case CSN_TRAP_ERROR:
1585
6
      {
1586
6
        return ProcessError(tree, ar->pinfo, tvb, bit_offset, -1, pDescr->error, pDescr);
1587
317
      }
1588
1589
7.31k
      case CSN_END:
1590
7.31k
      {
1591
7.31k
        ar->remaining_bits_len  = remaining_bits_len;
1592
7.31k
        ar->bit_offset = bit_offset;
1593
7.31k
        return remaining_bits_len;
1594
317
      }
1595
1596
0
      default:
1597
0
      {
1598
0
        DISSECTOR_ASSERT(0);
1599
0
      }
1600
1601
39.0k
    }
1602
1603
39.0k
  } while (remaining_bits_len >= 0);
1604
1605
4
  return ProcessError(tree, ar->pinfo, tvb, bit_offset, CSN_ERROR_NEED_MORE_BITS_TO_UNPACK, &ei_csn1_more_bits_to_unpack, pDescr);
1606
8.36k
}
1607
1608
void
1609
proto_register_csn1(void)
1610
16
{
1611
16
    static hf_register_info hf[] = {
1612
16
        { &hf_null_data,
1613
16
            { "NULL data", "csn1.null_data",
1614
16
            FT_NONE, BASE_NONE, NULL, 0x00,
1615
16
            NULL, HFILL }
1616
16
        },
1617
16
    };
1618
1619
16
    static ei_register_info ei[] = {
1620
16
        { &ei_csn1_more_bits_to_unpack, { "csn1.more_bits_to_unpack", PI_MALFORMED, PI_ERROR, "NEED_MORE BITS TO UNPACK", EXPFILL }},
1621
16
        { &ei_csn1_general, { "csn1.general_error", PI_PROTOCOL, PI_WARN, "General -1", EXPFILL }},
1622
16
        { &ei_csn1_not_implemented, { "csn1.not_implemented", PI_UNDECODED, PI_WARN, "NOT IMPLEMENTED", EXPFILL }},
1623
16
        { &ei_csn1_union_index, { "csn1.union_index_invalid", PI_PROTOCOL, PI_WARN, "INVALID UNION INDEX", EXPFILL }},
1624
16
        { &ei_csn1_script_error, { "csn1.script_error", PI_MALFORMED, PI_ERROR, "ERROR IN SCRIPT", EXPFILL }},
1625
16
        { &ei_csn1_more32bits, { "csn1.more32bits", PI_PROTOCOL, PI_WARN, "no_of_bits > 32", EXPFILL }},
1626
16
        { &ei_csn1_fixed_not_matched, { "csn1.fixed_not_matched", PI_PROTOCOL, PI_WARN, "FIXED value does not match", EXPFILL }},
1627
16
        { &ei_csn1_stream_not_supported, { "csn1.stream_not_supported", PI_PROTOCOL, PI_WARN, "STREAM NOT SUPPORTED", EXPFILL }},
1628
16
    };
1629
1630
16
    expert_module_t* expert_csn1;
1631
1632
16
    proto_csn1 = proto_register_protocol("CSN.1", "CSN1", "csn1");
1633
1634
16
  proto_register_field_array(proto_csn1, hf, array_length(hf));
1635
16
    expert_csn1 = expert_register_protocol(proto_csn1);
1636
16
    expert_register_field_array(expert_csn1, ei, array_length(ei));
1637
1638
16
    proto_set_cant_toggle(proto_csn1);
1639
16
}
1640
1641
/*
1642
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1643
 *
1644
 * Local Variables:
1645
 * c-basic-offset: 2
1646
 * tab-width: 8
1647
 * indent-tabs-mode: nil
1648
 * End:
1649
 *
1650
 * ex: set shiftwidth=2 tabstop=8 expandtab:
1651
 * :indentSize=2:tabSize=8:noTabs=true:
1652
 */