Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-iuup.c
Line
Count
Source
1
/* packet-iuup.c
2
 * IuUP Protocol 3GPP TS 25.415 V6.2.0 (2005-03)
3
 *
4
 * (c) 2005 Luis E. Garcia Ontanon <luis@ontanon.org>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
14
/*
15
   Patch by Polystar (Peter Vestman, Petter Edblom):
16
      Corrected rfci handling in rate control messages
17
      Added crc6 and crc10 checks for header and payload
18
*/
19
20
#include "config.h"
21
22
#include <epan/packet.h>
23
#include <epan/prefs.h>
24
#include <epan/expert.h>
25
#include <epan/conversation.h>
26
#include <epan/crc10-tvb.h>
27
#include <epan/crc6-tvb.h>
28
#include <wsutil/crc10.h>
29
#include <wsutil/crc6.h>
30
31
#include "packet-rtp.h"
32
#include "packet-iuup.h"
33
34
void proto_reg_handoff_iuup(void);
35
void proto_register_iuup(void);
36
37
static int proto_iuup;
38
39
static int hf_iuup_direction;
40
static int hf_iuup_circuit_id;
41
42
static int hf_iuup_pdu_type;
43
static int hf_iuup_frame_number;
44
static int hf_iuup_fqc;
45
static int hf_iuup_rfci;
46
static int hf_iuup_hdr_crc;
47
static int hf_iuup_payload_crc;
48
49
static int hf_iuup_ack_nack;
50
static int hf_iuup_frame_number_t14;
51
static int hf_iuup_mode_version;
52
static int hf_iuup_procedure_indicator;
53
static int hf_iuup_error_cause_val;
54
55
static int hf_iuup_init_ti;
56
static int hf_iuup_init_subflows_per_rfci;
57
static int hf_iuup_init_chain_ind;
58
59
static int hf_iuup_error_distance;
60
static int hf_iuup_errorevt_cause_val;
61
62
static int hf_iuup_time_align;
63
static int hf_iuup_spare_bytes;
64
static int hf_iuup_spare_03;
65
/* static int hf_iuup_spare_0f; */
66
/* static int hf_iuup_spare_c0; */
67
static int hf_iuup_spare_e0;
68
static int hf_iuup_spare_ff;
69
70
static int hf_iuup_delay;
71
static int hf_iuup_advance;
72
static int hf_iuup_delta;
73
74
static int hf_iuup_mode_versions;
75
static int hf_iuup_mode_versions_a[16];
76
77
78
static int hf_iuup_data_pdu_type;
79
80
static int hf_iuup_num_rfci_ind;
81
82
static int hf_iuup_payload;
83
84
static int hf_iuup_init_rfci_ind;
85
static int hf_iuup_init_rfci[64];
86
87
static int hf_iuup_init_rfci_flow_len[64][8];
88
static int hf_iuup_init_rfci_li[64];
89
static int hf_iuup_init_rfci_lri[64];
90
static int hf_iuup_init_ipti[64];
91
static int hf_iuup_rfci_subflow[64][8];
92
static int hf_iuup_rfci_ratectl[64];
93
94
95
static int ett_iuup;
96
static int ett_rfci;
97
static int ett_ipti;
98
static int ett_support;
99
static int ett_time;
100
static int ett_rfciinds;
101
static int ett_payload;
102
static int ett_payload_subflows;
103
104
static expert_field ei_iuup_hdr_crc_bad;
105
static expert_field ei_iuup_payload_crc_bad;
106
static expert_field ei_iuup_payload_undecoded;
107
static expert_field ei_iuup_error_response;
108
static expert_field ei_iuup_ack_nack;
109
static expert_field ei_iuup_time_align;
110
static expert_field ei_iuup_procedure_indicator;
111
static expert_field ei_iuup_pdu_type;
112
static expert_field ei_iuup_too_many_rfcis;
113
114
static wmem_map_t* circuits;
115
116
static dissector_handle_t iuup_handle;
117
118
static bool dissect_fields;
119
static bool two_byte_pseudoheader;
120
121
static const value_string iuup_pdu_types[] = {
122
    {PDUTYPE_DATA_WITH_CRC,"Data with CRC"},
123
    {PDUTYPE_DATA_NO_CRC,"Data without CRC"},
124
    {PDUTYPE_DATA_CONTROL_PROC,"Control Procedure"},
125
    {0,NULL}
126
};
127
128
static const value_string iuup_colinfo_pdu_types[] = {
129
    {PDUTYPE_DATA_WITH_CRC,"Data (CRC)"},
130
    {PDUTYPE_DATA_NO_CRC,"Data (no CRC)"},
131
    {PDUTYPE_DATA_CONTROL_PROC,""},
132
    {0,NULL}
133
};
134
135
0
#define ACKNACK_ACK 0x4
136
0
#define ACKNACK_NACK 0x8
137
0
#define ACKNACK_RESERVED 0xc
138
0
#define ACKNACK_PROC 0x0
139
140
static const value_string iuup_acknack_vals[] = {
141
    {ACKNACK_PROC >> 2,"Procedure"},
142
    {ACKNACK_ACK >> 2,"ACK"},
143
    {ACKNACK_NACK  >> 2,"NACK"},
144
    {ACKNACK_RESERVED  >> 2,"Reserved"},
145
    {0,NULL}
146
};
147
148
static const value_string iuup_colinfo_acknack_vals[] = {
149
    {ACKNACK_PROC,""},
150
    {ACKNACK_ACK,"ACK "},
151
    {ACKNACK_NACK,"NACK "},
152
    {ACKNACK_RESERVED,"Reserved "},
153
    {0,NULL}
154
};
155
156
0
#define PROC_INIT 0
157
0
#define PROC_RATE 1
158
0
#define PROC_TIME 2
159
0
#define PROC_ERROR 3
160
161
static const value_string iuup_procedures[] = {
162
    {PROC_INIT,"Initialization"},
163
    {PROC_RATE,"Rate Control"},
164
    {PROC_TIME,"Time Alignment"},
165
    {PROC_ERROR,"Error Event"},
166
    {4,"Reserved(4)"},
167
    {5,"Reserved(5)"},
168
    {6,"Reserved(6)"},
169
    {7,"Reserved(7)"},
170
    {8,"Reserved(8)"},
171
    {9,"Reserved(9)"},
172
    {10,"Reserved(10)"},
173
    {11,"Reserved(11)"},
174
    {12,"Reserved(12)"},
175
    {13,"Reserved(13)"},
176
    {14,"Reserved(14)"},
177
    {15,"Reserved(15)"},
178
    {0,NULL}
179
};
180
181
static const value_string iuup_colinfo_procedures[] = {
182
    {PROC_INIT,"Initialization "},
183
    {PROC_RATE,"Rate Control "},
184
    {PROC_TIME,"Time Alignment "},
185
    {PROC_ERROR,"Error Event "},
186
    {0,NULL}
187
};
188
189
190
static const value_string iuup_error_distances[] = {
191
    {0, "Reporting local error"},
192
    {1, "First forwarding of error event report"},
193
    {2, "Second forwarding of error event report"},
194
    {3, "Reserved"},
195
    {0,NULL}
196
};
197
198
static const value_string iuup_error_causes[] = {
199
    {0, "CRC error of frame header"},
200
    {1, "CRC error of frame payload"},
201
    {2, "Unexpected frame number"},
202
    {3, "Frame loss"},
203
    {4, "PDU type unknown"},
204
    {5, "Unknown procedure"},
205
    {6, "Unknown reserved value"},
206
    {7, "Unknown field"},
207
    {8, "Frame too short"},
208
    {9, "Missing fields"},
209
    {16, "Unexpected PDU type"},
210
    {18, "Unexpected procedure"},
211
    {19, "Unexpected RFCI"},
212
    {20, "Unexpected value"},
213
    {42, "Initialisation failure"},
214
    {43, "Initialisation failure (network error, timer expiry)"},
215
    {44, "Initialisation failure (Iu UP function error, repeated NACK)"},
216
    {45, "Rate control failure"},
217
    {46, "Error event failure"},
218
    {47, "Time Alignment not supported"},
219
    {48, "Requested Time Alignment not possible"},
220
    {49, "Iu UP Mode version not supported"},
221
    {0,NULL}
222
};
223
224
static const value_string iuup_rfci_indicator[] = {
225
    {0, "RFCI allowed"},
226
    {1, "RFCI barred"},
227
    {0,NULL}
228
};
229
230
231
static const value_string iuup_ti_vals[] = {
232
    {0, "IPTIs not present"},
233
    {1, "IPTIs present in frame"},
234
    {0,NULL}
235
};
236
237
static const value_string iuup_mode_version_support[] = {
238
    {0, "not supported"},
239
    {1, "supported"},
240
    {0,NULL}
241
};
242
243
static const value_string iuup_init_rfci_li_vals[] = {
244
    {0, "one octet used"},
245
    {1, "two octets used"},
246
    {0,NULL}
247
};
248
249
static const value_string iuup_init_chain_ind_vals[] = {
250
    {0, "this frame is the last frame for the procedure"},
251
    {1, "additional frames will be sent for the procedure"},
252
    {0,NULL}
253
};
254
255
static const value_string iuup_init_lri_vals[] = {
256
    {0, "Not last RFCI"},
257
    {1, "Last RFCI in current frame"},
258
    {0,NULL}
259
};
260
261
static const value_string iuup_payload_pdu_type[] = {
262
    {0, "PDU type 0"},
263
    {1, "PDU type 1"},
264
    {0,NULL}
265
};
266
267
static const value_string iuup_fqcs[] = {
268
    {0, "Frame Good"},
269
    {1, "Frame BAD"},
270
    {2, "Frame bad due to radio"},
271
    {3, "spare"},
272
    {0,NULL}
273
};
274
275
276
static proto_item*
277
0
iuup_proto_tree_add_bits(packet_info *pinfo, proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int bit_offset, unsigned bits, uint8_t** buf) {
278
0
    static const uint8_t masks[] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
279
0
    int len = (bits + bit_offset)/8 + (((bits + bit_offset)%8) ? 0 : 1);
280
0
    uint8_t* shifted_buffer;
281
0
    proto_item* pi;
282
0
    int i;
283
284
0
    DISSECTOR_ASSERT(bit_offset < 8);
285
286
0
    shifted_buffer = (uint8_t *)tvb_memdup(pinfo->pool,tvb,offset,len+1);
287
288
0
    for(i = 0; i < len; i++) {
289
0
        shifted_buffer[i] <<= bit_offset;
290
0
        shifted_buffer[i] |= (shifted_buffer[i+1] & masks[bit_offset]) >> (8 - bit_offset);
291
0
    }
292
293
0
    shifted_buffer[len] <<=  bit_offset;
294
0
    shifted_buffer[len] &= masks[(bits + bit_offset)%8];
295
296
0
    if (buf)
297
0
        *buf = shifted_buffer;
298
299
0
    pi = proto_tree_add_bytes(tree, hf, tvb, offset, len + (((bits + bit_offset)%8) ? 1 : 0) , shifted_buffer);
300
0
    proto_item_append_text(pi, " (%i Bits)", bits);
301
302
0
    return pi;
303
0
}
304
305
static iuup_circuit_t *find_iuup_circuit(packet_info *pinfo)
306
0
{
307
0
    iuup_circuit_t *iuup_circuit;
308
0
    conversation_t *p_conv;
309
310
0
    if (two_byte_pseudoheader) {
311
0
        uint32_t circuit_id = conversation_get_id_from_elements(pinfo, CONVERSATION_IUUP, USE_LAST_ENDPOINT);
312
0
        iuup_circuit = (iuup_circuit_t *)wmem_map_lookup(circuits,GUINT_TO_POINTER(circuit_id));
313
0
        return iuup_circuit;
314
0
    }
315
316
0
    p_conv = find_conversation(pinfo->num,
317
0
                               &pinfo->net_dst, &pinfo->net_src,
318
0
                               CONVERSATION_IUUP,
319
0
                               pinfo->destport, pinfo->srcport, 0);
320
0
    if (!p_conv)
321
0
        return NULL;
322
0
    iuup_circuit = (iuup_circuit_t *)conversation_get_proto_data(p_conv, proto_iuup);
323
0
    return iuup_circuit;
324
0
}
325
326
0
static void dissect_iuup_payload(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned rfci_id, int offset) {
327
0
    iuup_circuit_t *iuup_circuit;
328
0
    iuup_rfci_t *rfci;
329
0
    int last_offset = tvb_reported_length(tvb) - 1;
330
0
    unsigned bit_offset;
331
0
    proto_item* pi;
332
333
0
    if (offset == (int)tvb_reported_length(tvb)) /* NO_DATA */
334
0
      return;
335
336
0
    pi = proto_tree_add_item(tree,hf_iuup_payload,tvb,offset,-1,ENC_NA);
337
338
0
    if (!dissect_fields)
339
0
        return;
340
0
    if (!(iuup_circuit = find_iuup_circuit(pinfo))) {
341
0
        expert_add_info(pinfo, pi, &ei_iuup_payload_undecoded);
342
0
        return;
343
0
    }
344
345
0
    for(rfci = iuup_circuit->rfcis; rfci; rfci = rfci->next)
346
0
        if ( rfci->id == rfci_id )
347
0
            break;
348
349
0
    if (!rfci) {
350
0
        expert_add_info(pinfo, pi, &ei_iuup_payload_undecoded);
351
0
        return;
352
0
    }
353
354
0
    tree = proto_item_add_subtree(pi,ett_payload);
355
356
357
0
    do {
358
0
        unsigned i;
359
0
        unsigned subflows = rfci->num_of_subflows;
360
0
        proto_tree* flow_tree;
361
362
0
        flow_tree = proto_tree_add_subtree(tree,tvb,offset,-1,ett_payload_subflows,NULL,"Payload Frame");
363
364
0
        bit_offset = 0;
365
366
0
        for(i = 0; i < subflows; i++) {
367
368
0
            if (! rfci->subflow[i].len)
369
0
                continue;
370
371
0
            iuup_proto_tree_add_bits(pinfo, flow_tree, hf_iuup_rfci_subflow[rfci->id][i], tvb,
372
0
                                offset + (bit_offset/8),
373
0
                                bit_offset % 8,
374
0
                                rfci->subflow[i].len,
375
0
                                NULL);
376
377
0
            bit_offset += rfci->subflow[i].len;
378
0
        }
379
380
0
        if (bit_offset == 0)
381
0
            break;
382
383
0
        offset += (bit_offset / 8) + ((bit_offset % 8) ? 1 : 0);
384
385
0
    } while (offset <= last_offset);
386
0
}
387
388
0
static unsigned dissect_rfcis(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int* offset, iuup_circuit_t *iuup_circuit) {
389
0
    proto_item* pi;
390
0
    proto_tree* pt;
391
0
    uint8_t oct;
392
0
    unsigned c = 0;
393
0
    unsigned i;
394
395
0
    DISSECTOR_ASSERT(iuup_circuit);
396
0
    do {
397
0
        iuup_rfci_t *rfci = wmem_new0(wmem_file_scope(), iuup_rfci_t);
398
0
        unsigned len = 0;
399
400
0
        if (c >= 64) {
401
0
            expert_add_info(pinfo, tree, &ei_iuup_too_many_rfcis);
402
0
            break;
403
0
        }
404
405
0
        pi = proto_tree_add_item(tree,hf_iuup_init_rfci_ind,tvb,*offset,-1,ENC_NA);
406
0
        pt = proto_item_add_subtree(pi,ett_rfci);
407
408
0
        proto_tree_add_item(pt,hf_iuup_init_rfci_lri[c],tvb,*offset,1,ENC_BIG_ENDIAN);
409
0
        proto_tree_add_item(pt,hf_iuup_init_rfci_li[c],tvb,*offset,1,ENC_BIG_ENDIAN);
410
0
        proto_tree_add_item(pt,hf_iuup_init_rfci[c],tvb,*offset,1,ENC_BIG_ENDIAN);
411
412
0
        oct = tvb_get_uint8(tvb,*offset);
413
0
        rfci->id = oct & 0x3f;
414
0
        rfci->num_of_subflows = iuup_circuit->num_of_subflows;
415
416
0
        len = (oct & 0x40) ? 2 : 1;
417
0
        proto_item_set_text(pi,"RFCI %i Initialization",rfci->id);
418
0
        proto_item_set_len(pi,(len*iuup_circuit->num_of_subflows)+1);
419
420
0
        (*offset)++;
421
422
0
        for(i = 0; i < iuup_circuit->num_of_subflows; i++) {
423
0
            unsigned subflow_len;
424
425
0
            if (len == 2) {
426
0
                subflow_len = tvb_get_ntohs(tvb,*offset);
427
0
            } else {
428
0
                subflow_len = tvb_get_uint8(tvb,*offset);
429
0
            }
430
431
0
            rfci->subflow[i].len = subflow_len;
432
0
            rfci->sum_len += subflow_len;
433
434
0
            proto_tree_add_uint(pt,hf_iuup_init_rfci_flow_len[c][i],tvb,*offset,len,subflow_len);
435
436
0
            (*offset) += len;
437
0
        }
438
439
440
0
        if (iuup_circuit->last_rfci) {
441
0
            iuup_circuit->last_rfci = iuup_circuit->last_rfci->next = rfci;
442
0
        } else {
443
0
            iuup_circuit->last_rfci = iuup_circuit->rfcis = rfci;
444
0
        }
445
446
0
        c++;
447
0
    } while ( ! (oct & 0x80) );
448
449
0
    return c - 1;
450
0
}
451
452
0
static void dissect_iuup_init(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
453
0
    int offset = 4;
454
0
    uint8_t oct = tvb_get_uint8(tvb,offset);
455
0
    unsigned n = (oct & 0x0e) >> 1;
456
0
    bool ti = oct & 0x10;
457
0
    unsigned i;
458
0
    unsigned rfcis;
459
0
    proto_item* pi;
460
0
    proto_tree* support_tree = NULL;
461
0
    proto_tree* iptis_tree;
462
0
    iuup_circuit_t *iuup_circuit = NULL;
463
0
    uint32_t circuit_id = 0;
464
465
0
    if (two_byte_pseudoheader) {
466
0
        iuup_circuit = find_iuup_circuit(pinfo);
467
0
        if (iuup_circuit) {
468
0
            circuit_id = iuup_circuit->id;
469
0
            wmem_map_remove(circuits,GUINT_TO_POINTER(iuup_circuit->id));
470
0
            iuup_circuit = NULL;
471
0
        } else {
472
0
            circuit_id = conversation_get_id_from_elements(pinfo, CONVERSATION_IUUP, USE_LAST_ENDPOINT);
473
0
        }
474
0
    }
475
476
0
    iuup_circuit = wmem_new0(wmem_file_scope(), iuup_circuit_t);
477
0
    iuup_circuit->id = circuit_id;
478
0
    iuup_circuit->num_of_subflows = n;
479
0
    iuup_circuit->rfcis = NULL;
480
0
    iuup_circuit->last_rfci = NULL;
481
482
0
    if (two_byte_pseudoheader) {
483
0
        wmem_map_insert(circuits,GUINT_TO_POINTER(circuit_id),iuup_circuit);
484
0
    } else {
485
0
        conversation_t *p_conv;
486
0
        p_conv = conversation_new(pinfo->num, &pinfo->net_dst, &pinfo->net_src, CONVERSATION_IUUP,
487
0
                                  pinfo->destport, pinfo->srcport, 0);
488
0
        conversation_add_proto_data(p_conv, proto_iuup, iuup_circuit);
489
0
    }
490
491
0
    if (tree) {
492
0
        proto_tree_add_item(tree,hf_iuup_spare_e0,tvb,offset,1,ENC_BIG_ENDIAN);
493
0
        proto_tree_add_item(tree,hf_iuup_init_ti,tvb,offset,1,ENC_BIG_ENDIAN);
494
0
        proto_tree_add_item(tree,hf_iuup_init_subflows_per_rfci,tvb,offset,1,ENC_BIG_ENDIAN);
495
0
        proto_tree_add_item(tree,hf_iuup_init_chain_ind,tvb,offset,1,ENC_BIG_ENDIAN);
496
0
    }
497
498
0
    offset++;
499
500
0
    rfcis = dissect_rfcis(tvb, pinfo, tree, &offset, iuup_circuit);
501
502
0
    if (!tree) return;
503
504
0
    if (ti) {
505
0
        iptis_tree = proto_tree_add_subtree(tree,tvb,offset,(rfcis/2)+(rfcis%2),ett_ipti,NULL,"IPTIs");
506
507
0
        for (i = 0; i <= rfcis; i++) {
508
0
            proto_tree_add_item(iptis_tree,hf_iuup_init_ipti[i],tvb,offset,1,ENC_BIG_ENDIAN);
509
0
            if ((i%2)) {
510
0
                offset++;
511
0
            }
512
0
        }
513
514
0
        if ((i%2)) {
515
0
            offset++;
516
0
        }
517
0
    }
518
519
0
    pi = proto_tree_add_item(tree,hf_iuup_mode_versions,tvb,offset,2,ENC_BIG_ENDIAN);
520
0
    support_tree = proto_item_add_subtree(pi,ett_support);
521
522
0
    for (i = 0; i < 16; i++) {
523
0
        proto_tree_add_item(support_tree,hf_iuup_mode_versions_a[i],tvb,offset,2,ENC_BIG_ENDIAN);
524
0
    }
525
526
0
    offset += 2;
527
528
0
    proto_tree_add_item(tree,hf_iuup_data_pdu_type,tvb,offset,1,ENC_BIG_ENDIAN);
529
530
0
}
531
532
0
static void dissect_iuup_ratectl(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree) {
533
0
    unsigned num = tvb_get_uint8(tvb,4) & 0x3f;
534
0
    unsigned i;
535
0
    proto_item* pi;
536
0
    proto_tree* inds_tree;
537
0
    int offset = 4;
538
539
0
    pi = proto_tree_add_item(tree,hf_iuup_num_rfci_ind,tvb,4,1,ENC_BIG_ENDIAN);
540
0
    inds_tree = proto_item_add_subtree(pi,ett_rfciinds);
541
542
0
    for (i = 0; i < num; i++) {
543
0
        if (! (i % 8) ) offset++;
544
0
        proto_tree_add_item(inds_tree,hf_iuup_rfci_ratectl[i],tvb,offset,1,ENC_BIG_ENDIAN);
545
0
    }
546
547
0
}
548
549
static void add_hdr_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree)
550
0
{
551
0
    proto_tree_add_checksum(iuup_tree, tvb, 2, hf_iuup_hdr_crc, -1, &ei_iuup_hdr_crc_bad,
552
0
                            pinfo, crc6_compute_tvb(tvb, 2), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
553
0
}
554
555
static uint16_t
556
update_crc10_by_bytes_iuup(tvbuff_t *tvb, int offset, int length)
557
0
{
558
0
    uint16_t crc10;
559
0
    uint16_t extra_16bits;
560
0
    uint8_t extra_8bits[2];
561
562
0
    crc10 = update_crc10_by_bytes_tvb(0, tvb, offset + 2, length);
563
0
    extra_16bits = tvb_get_ntohs(tvb, offset) & 0x3FF;
564
0
    extra_8bits[0] = extra_16bits >> 2;
565
0
    extra_8bits[1] = (extra_16bits << 6) & 0xFF;
566
0
    crc10 = update_crc10_by_bytes(crc10, extra_8bits, 2);
567
0
    return crc10;
568
0
}
569
570
static void add_payload_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree)
571
0
{
572
0
    proto_item *crc_item;
573
0
    int length = tvb_reported_length(tvb);
574
0
    uint16_t crccheck = update_crc10_by_bytes_iuup(tvb, 2, length - 4);
575
576
0
    crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,ENC_BIG_ENDIAN);
577
0
    if (crccheck) {
578
0
        proto_item_append_text(crc_item, "%s", " [incorrect]");
579
0
        expert_add_info(pinfo, crc_item, &ei_iuup_payload_crc_bad);
580
0
    }
581
0
}
582
583
static int dissect_iuup_data(tvbuff_t* tvb, packet_info* pinfo,
584
                              proto_tree* iuup_tree, void* data _U_, uint8_t pdutype)
585
0
{
586
0
    proto_item *pi;
587
0
    uint8_t first_octet;
588
0
    uint8_t second_octet;
589
0
    uint8_t payload_offset;
590
591
0
    first_octet = tvb_get_uint8(tvb,0);
592
0
    second_octet = tvb_get_uint8(tvb,1);
593
594
0
    col_append_fstr(pinfo->cinfo, COL_INFO,"FN: %x RFCI: %u", (unsigned)(first_octet & 0x0f), (unsigned)(second_octet & 0x3f));
595
596
0
    proto_tree_add_item(iuup_tree,hf_iuup_frame_number,tvb,0,1,ENC_BIG_ENDIAN);
597
0
    pi = proto_tree_add_item(iuup_tree,hf_iuup_fqc,tvb,1,1,ENC_BIG_ENDIAN);
598
599
0
    if (first_octet & FQC_MASK) {
600
0
        expert_add_info(pinfo, pi, &ei_iuup_error_response);
601
0
    }
602
603
0
    proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,ENC_BIG_ENDIAN);
604
0
    add_hdr_crc(tvb, pinfo, iuup_tree);
605
0
    switch (pdutype) {
606
0
    case PDUTYPE_DATA_WITH_CRC:
607
0
        add_payload_crc(tvb, pinfo, iuup_tree);
608
0
        payload_offset = 4;
609
0
        break;
610
0
    case PDUTYPE_DATA_NO_CRC:
611
0
        payload_offset = 3;
612
0
        break;
613
0
    default:
614
0
        DISSECTOR_ASSERT_NOT_REACHED();
615
0
    }
616
0
    dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f, payload_offset);
617
0
    return tvb_captured_length(tvb);
618
0
}
619
620
static int dissect_iuup_control(tvbuff_t* tvb, packet_info* pinfo,
621
                                 proto_tree* iuup_tree, void* data _U_)
622
0
{
623
0
    proto_item *pi;
624
0
    proto_item *proc_item = NULL;
625
0
    proto_item *ack_item = NULL;
626
0
    uint8_t first_octet;
627
0
    uint8_t second_octet;
628
629
0
    first_octet = tvb_get_uint8(tvb,0);
630
0
    second_octet = tvb_get_uint8(tvb,1);
631
632
0
    if (iuup_tree) {
633
0
        ack_item = proto_tree_add_item(iuup_tree,hf_iuup_ack_nack,tvb,0,1,ENC_BIG_ENDIAN);
634
0
        proto_tree_add_item(iuup_tree,hf_iuup_frame_number_t14,tvb,0,1,ENC_BIG_ENDIAN);
635
0
        proto_tree_add_item(iuup_tree,hf_iuup_mode_version,tvb,1,1,ENC_BIG_ENDIAN);
636
0
        proc_item = proto_tree_add_item(iuup_tree,hf_iuup_procedure_indicator,tvb,1,1,ENC_BIG_ENDIAN);
637
0
        add_hdr_crc(tvb, pinfo, iuup_tree);
638
0
    }
639
640
0
    col_append_str(pinfo->cinfo, COL_INFO,
641
0
                    val_to_str(pinfo->pool, first_octet & ACKNACK_MASK,
642
0
                                iuup_colinfo_acknack_vals, "[action:%u] "));
643
644
0
    col_append_str(pinfo->cinfo, COL_INFO,
645
0
                    val_to_str(pinfo->pool, second_octet & PROCEDURE_MASK,
646
0
                                iuup_colinfo_procedures, "[proc:%u] "));
647
648
0
    switch ( first_octet & ACKNACK_MASK ) {
649
0
        case ACKNACK_ACK:
650
0
            switch(second_octet & PROCEDURE_MASK) {
651
0
                case PROC_INIT:
652
0
                    proto_tree_add_item(iuup_tree,hf_iuup_spare_03,tvb,2,1,ENC_BIG_ENDIAN);
653
0
                    proto_tree_add_item(iuup_tree,hf_iuup_spare_ff,tvb,3,1,ENC_BIG_ENDIAN);
654
0
                    return tvb_captured_length(tvb);
655
0
                case PROC_RATE:
656
0
                    dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
657
0
                    return tvb_captured_length(tvb);
658
0
                case PROC_TIME:
659
0
                case PROC_ERROR:
660
0
                    break;
661
0
                default:
662
0
                    expert_add_info(pinfo, proc_item, &ei_iuup_procedure_indicator);
663
0
                    return tvb_captured_length(tvb);
664
0
            }
665
0
            break;
666
0
        case ACKNACK_NACK:
667
0
            pi = proto_tree_add_item(iuup_tree,hf_iuup_error_cause_val,tvb,4,1,ENC_BIG_ENDIAN);
668
0
            expert_add_info(pinfo, pi, &ei_iuup_error_response);
669
0
            return tvb_captured_length(tvb);
670
0
        case ACKNACK_RESERVED:
671
0
            expert_add_info(pinfo, ack_item, &ei_iuup_ack_nack);
672
0
            return tvb_captured_length(tvb);
673
0
        case ACKNACK_PROC:
674
0
            break;
675
0
    }
676
677
0
    switch( second_octet & PROCEDURE_MASK ) {
678
0
        case PROC_INIT:
679
0
            add_payload_crc(tvb, pinfo, iuup_tree);
680
0
            dissect_iuup_init(tvb,pinfo,iuup_tree);
681
0
            break;
682
0
        case PROC_RATE:
683
0
            add_payload_crc(tvb, pinfo, iuup_tree);
684
0
            dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
685
0
            break;
686
0
        case PROC_TIME:
687
0
        {
688
0
            proto_tree* time_tree;
689
0
            unsigned ta;
690
691
0
            ta = tvb_get_uint8(tvb,4);
692
693
0
            pi = proto_tree_add_item(iuup_tree,hf_iuup_time_align,tvb,4,1,ENC_BIG_ENDIAN);
694
0
            time_tree = proto_item_add_subtree(pi,ett_time);
695
696
0
            if (ta >= 1 && ta <= 80) {
697
0
                pi = proto_tree_add_uint(time_tree,hf_iuup_delay,tvb,4,1,ta * 500);
698
0
                proto_item_set_generated(pi);
699
0
                pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((float)((int)(ta) * 500))/(float)1000000.0);
700
0
                proto_item_set_generated(pi);
701
0
            } else if (ta >= 129 && ta <= 208) {
702
0
                pi = proto_tree_add_uint(time_tree,hf_iuup_advance,tvb,4,1,(ta-128) * 500);
703
0
                proto_item_set_generated(pi);
704
0
                pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((float)((int)(-(((int)ta)-128))) * 500)/(float)1000000.0);
705
0
                proto_item_set_generated(pi);
706
0
            } else {
707
0
                expert_add_info(pinfo, pi, &ei_iuup_time_align);
708
0
            }
709
710
0
            proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,ENC_NA);
711
0
            break;
712
0
        }
713
0
        case PROC_ERROR:
714
0
            col_append_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, tvb_get_uint8(tvb,4) & 0x3f,iuup_error_causes,"Unknown (%u)"));
715
716
0
            proto_tree_add_item(iuup_tree,hf_iuup_error_distance,tvb,4,1,ENC_BIG_ENDIAN);
717
0
            pi = proto_tree_add_item(iuup_tree,hf_iuup_errorevt_cause_val,tvb,4,1,ENC_BIG_ENDIAN);
718
0
            expert_add_info(pinfo, pi, &ei_iuup_error_response);
719
0
            proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,ENC_NA);
720
0
            return tvb_captured_length(tvb);
721
0
        default: /* bad */
722
0
            expert_add_info(pinfo, proc_item, &ei_iuup_procedure_indicator);
723
0
            break;
724
0
    }
725
0
    return tvb_captured_length(tvb);
726
0
}
727
728
0
static int dissect_iuup(tvbuff_t *tvb_in, packet_info *pinfo, proto_tree *tree, void *data) {
729
0
    proto_item* iuup_item = NULL;
730
0
    proto_item* pdutype_item = NULL;
731
0
    proto_tree* iuup_tree = NULL;
732
0
    struct _rtp_info *rtp_info = NULL;
733
0
    uint8_t first_octet;
734
0
    uint8_t pdutype;
735
0
    unsigned phdr = 0;
736
0
    tvbuff_t* tvb = tvb_in;
737
738
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IuUP");
739
740
0
    if (two_byte_pseudoheader) {
741
0
        int len = tvb_reported_length(tvb_in) - 2;
742
743
0
        phdr = tvb_get_ntohs(tvb,0);
744
745
0
        proto_tree_add_item(tree,hf_iuup_direction,tvb,0,2,ENC_BIG_ENDIAN);
746
0
        proto_tree_add_item(tree,hf_iuup_circuit_id,tvb,0,2,ENC_BIG_ENDIAN);
747
748
0
        phdr &= 0x7fff;
749
750
0
        conversation_set_elements_by_id(pinfo, CONVERSATION_IUUP, phdr);
751
752
0
        tvb = tvb_new_subset_length(tvb_in,2,len);
753
0
    } else if (data) {
754
        /* Coming from RTP */
755
0
        rtp_info = (struct _rtp_info*)data;
756
0
        rtp_info->info_is_iuup = true;
757
0
    }
758
759
0
    first_octet = tvb_get_uint8(tvb,0);
760
0
    pdutype = ( first_octet & PDUTYPE_MASK ) >> 4;
761
762
0
    if (tree) {
763
0
        iuup_item = proto_tree_add_item(tree,proto_iuup,tvb,0,-1,ENC_NA);
764
0
        iuup_tree = proto_item_add_subtree(iuup_item,ett_iuup);
765
766
0
        pdutype_item = proto_tree_add_item(iuup_tree,hf_iuup_pdu_type,tvb,0,1,ENC_BIG_ENDIAN);
767
0
    }
768
769
0
    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, pdutype, iuup_colinfo_pdu_types, "Unknown PDU Type(%u) "));
770
771
0
    switch(pdutype) {
772
0
        case PDUTYPE_DATA_WITH_CRC:
773
0
        case PDUTYPE_DATA_NO_CRC:
774
0
            return dissect_iuup_data(tvb, pinfo, iuup_tree, data, pdutype);
775
0
        case PDUTYPE_DATA_CONTROL_PROC:
776
0
            return dissect_iuup_control(tvb, pinfo, iuup_tree, data);
777
0
        default:
778
0
            expert_add_info(pinfo, pdutype_item, &ei_iuup_pdu_type);
779
0
            break;
780
0
    }
781
0
    return tvb_captured_length(tvb);
782
0
}
783
784
785
0
static bool dissect_iuup_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) {
786
0
    int len = tvb_captured_length(tvb);
787
788
0
    if (len < 3) return false;
789
790
0
    uint8_t first_octet =  tvb_get_uint8(tvb,0);
791
0
    uint8_t second_octet =  tvb_get_uint8(tvb,1);
792
0
    const uint8_t octet_array[] = {first_octet, second_octet};
793
0
    uint16_t hdrcrc6 = tvb_get_uint8(tvb, 2) >> 2;
794
795
0
    if (crc6_0X6F(hdrcrc6, octet_array, 2)) return false;
796
797
0
    switch ( first_octet & 0xf0 ) {
798
0
        case 0x00: {
799
0
            if (len<7) return false;
800
0
            if (update_crc10_by_bytes_iuup(tvb, 2, len-4) ) return false;
801
0
            break;
802
0
        }
803
0
        case 0x10:
804
            /* a false positive factory */
805
0
            if (len<5) return false;
806
0
            break;
807
0
        case 0xe0:
808
0
            if (len<5) return false;
809
0
            if( (second_octet & 0x0f) > 3) return false;
810
0
            break;
811
0
        default:
812
0
            return false;
813
0
    }
814
815
0
    dissect_iuup(tvb, pinfo, tree, data);
816
0
    return true;
817
0
}
818
819
820
0
static int find_iuup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
821
0
    int len = tvb_captured_length(tvb);
822
0
    unsigned offset = 0;
823
824
0
    while (len > 3) {
825
0
        if ( dissect_iuup_heur(tvb_new_subset_remaining(tvb,offset), pinfo, tree, data) )
826
0
            return tvb_captured_length(tvb);
827
828
0
        offset++;
829
0
        len--;
830
0
    }
831
832
0
    call_data_dissector(tvb, pinfo, tree);
833
0
    return tvb_captured_length(tvb);
834
0
}
835
836
837
16
void proto_reg_handoff_iuup(void) {
838
16
    dissector_add_string("rtp_dyn_payload_type","VND.3GPP.IUFP", iuup_handle);
839
840
16
    dissector_add_uint_range_with_preference("rtp.pt", "", iuup_handle);
841
16
}
842
843
844
1.02k
#define HFS_RFCI(i) \
845
1.02k
{ &hf_iuup_rfci_ratectl[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, VALS(iuup_rfci_indicator),0x80>>(i%8),NULL,HFILL}}, \
846
1.02k
{ &hf_iuup_init_rfci[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}}, \
847
1.02k
{ &hf_iuup_init_rfci_flow_len[i][0], { "RFCI " #i " Flow 0 Len", "iuup.rfci."#i".flow.0.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
848
1.02k
{ &hf_iuup_init_rfci_flow_len[i][1], { "RFCI " #i " Flow 1 Len", "iuup.rfci."#i".flow.1.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
849
1.02k
{ &hf_iuup_init_rfci_flow_len[i][2], { "RFCI " #i " Flow 2 Len", "iuup.rfci."#i".flow.2.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
850
1.02k
{ &hf_iuup_init_rfci_flow_len[i][3], { "RFCI " #i " Flow 3 Len", "iuup.rfci."#i".flow.3.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
851
1.02k
{ &hf_iuup_init_rfci_flow_len[i][4], { "RFCI " #i " Flow 4 Len", "iuup.rfci."#i".flow.4.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
852
1.02k
{ &hf_iuup_init_rfci_flow_len[i][5], { "RFCI " #i " Flow 5 Len", "iuup.rfci."#i".flow.5.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
853
1.02k
{ &hf_iuup_init_rfci_flow_len[i][6], { "RFCI " #i " Flow 6 Len", "iuup.rfci."#i".flow.6.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
854
1.02k
{ &hf_iuup_init_rfci_flow_len[i][7], { "RFCI " #i " Flow 7 Len", "iuup.rfci."#i".flow.7.len", FT_UINT16, BASE_DEC, NULL,0x0,NULL,HFILL}}, \
855
1.02k
{ &hf_iuup_init_rfci_li[i], { "RFCI " #i " LI", "iuup.rfci."#i".li", FT_UINT8, BASE_HEX, VALS(iuup_init_rfci_li_vals),0x40,"Length Indicator",HFILL}}, \
856
1.02k
{ &hf_iuup_init_rfci_lri[i], { "RFCI " #i " LRI", "iuup.rfci."#i".lri", FT_UINT8, BASE_HEX, VALS(iuup_init_lri_vals),0x80,"Last Record Indicator",HFILL}}, \
857
1.02k
{ &hf_iuup_rfci_subflow[i][0], { "RFCI " #i " Flow 0", "iuup.rfci."#i".flow.0", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
858
1.02k
{ &hf_iuup_rfci_subflow[i][1], { "RFCI " #i " Flow 1", "iuup.rfci."#i".flow.1", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
859
1.02k
{ &hf_iuup_rfci_subflow[i][2], { "RFCI " #i " Flow 2", "iuup.rfci."#i".flow.2", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
860
1.02k
{ &hf_iuup_rfci_subflow[i][3], { "RFCI " #i " Flow 3", "iuup.rfci."#i".flow.3", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
861
1.02k
{ &hf_iuup_rfci_subflow[i][4], { "RFCI " #i " Flow 4", "iuup.rfci."#i".flow.4", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
862
1.02k
{ &hf_iuup_rfci_subflow[i][5], { "RFCI " #i " Flow 5", "iuup.rfci."#i".flow.5", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
863
1.02k
{ &hf_iuup_rfci_subflow[i][6], { "RFCI " #i " Flow 6", "iuup.rfci."#i".flow.6", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
864
1.02k
{ &hf_iuup_rfci_subflow[i][7], { "RFCI " #i " Flow 7", "iuup.rfci."#i".flow.7", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
865
1.02k
{ &hf_iuup_init_ipti[i], { "RFCI " #i " IPTI", "iuup.rfci."#i".ipti", FT_UINT8, BASE_HEX, NULL,i%2 ? 0x0F : 0xF0,NULL,HFILL}}
866
867
868
869
16
void proto_register_iuup(void) {
870
16
    static hf_register_info hf[] = {
871
16
        { &hf_iuup_direction, { "Frame Direction", "iuup.direction", FT_UINT16, BASE_DEC, NULL,0x8000,NULL,HFILL}},
872
16
        { &hf_iuup_circuit_id, { "Circuit ID", "iuup.circuit_id", FT_UINT16, BASE_DEC, NULL,0x7fff,NULL,HFILL}},
873
16
        { &hf_iuup_pdu_type, { "PDU Type", "iuup.pdu_type", FT_UINT8, BASE_DEC, VALS(iuup_pdu_types),0xf0,NULL,HFILL}},
874
16
        { &hf_iuup_frame_number, { "Frame Number", "iuup.framenum", FT_UINT8, BASE_DEC, NULL,0x0F,NULL,HFILL}},
875
16
        { &hf_iuup_fqc, { "FQC", "iuup.fqc", FT_UINT8, BASE_DEC, VALS(iuup_fqcs),0xc0,"Frame Quality Classification",HFILL}},
876
16
        { &hf_iuup_rfci, { "RFCI", "iuup.rfci", FT_UINT8, BASE_HEX, NULL, 0x3f, "RAB sub-Flow Combination Indicator",HFILL}},
877
16
        { &hf_iuup_hdr_crc, { "Header CRC", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,NULL,HFILL}},
878
16
        { &hf_iuup_payload_crc, { "Payload CRC", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,NULL,HFILL}},
879
16
        { &hf_iuup_ack_nack, { "Ack/Nack", "iuup.ack", FT_UINT8, BASE_DEC, VALS(iuup_acknack_vals),0x0c,NULL,HFILL}},
880
16
        { &hf_iuup_frame_number_t14, { "Frame Number", "iuup.framenum_t14", FT_UINT8, BASE_DEC, NULL,0x03,NULL,HFILL}},
881
16
        { &hf_iuup_mode_version, { "Mode Version", "iuup.mode", FT_UINT8, BASE_HEX, NULL,0xf0,NULL,HFILL}},
882
16
        { &hf_iuup_procedure_indicator, { "Procedure", "iuup.procedure", FT_UINT8, BASE_DEC, VALS(iuup_procedures),0x0f,NULL,HFILL}},
883
16
        { &hf_iuup_error_cause_val, { "Error Cause", "iuup.error_cause", FT_UINT8, BASE_DEC, VALS(iuup_error_causes),0xfc,NULL,HFILL}},
884
16
        { &hf_iuup_error_distance, { "Error DISTANCE", "iuup.error_distance", FT_UINT8, BASE_DEC, VALS(iuup_error_distances),0xc0,NULL,HFILL}},
885
16
        { &hf_iuup_errorevt_cause_val, { "Error Cause", "iuup.errorevt_cause", FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}},
886
16
        { &hf_iuup_time_align, { "Time Align", "iuup.time_align", FT_UINT8, BASE_HEX, NULL,0x0,NULL,HFILL}},
887
16
        { &hf_iuup_data_pdu_type, { "RFCI Data Pdu Type", "iuup.data_pdu_type", FT_UINT8, BASE_HEX, VALS(iuup_payload_pdu_type),0xF0,NULL,HFILL}},
888
889
16
        { &hf_iuup_spare_03, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x03,NULL,HFILL}},
890
#if 0
891
        { &hf_iuup_spare_0f, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x0f,NULL,HFILL}},
892
#endif
893
#if 0
894
        { &hf_iuup_spare_c0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xc0,NULL,HFILL}},
895
#endif
896
16
        { &hf_iuup_spare_e0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xe0,NULL,HFILL}},
897
16
        { &hf_iuup_spare_ff, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xff,NULL,HFILL}},
898
16
        { &hf_iuup_spare_bytes, { "Spare", "iuup.spare_bytes", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
899
900
16
        { &hf_iuup_delay, { "Delay", "iuup.delay", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
901
16
        { &hf_iuup_advance, { "Advance", "iuup.advance", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
902
16
        { &hf_iuup_delta, { "Delta Time", "iuup.delta", FT_FLOAT, BASE_NONE, NULL,0x0,NULL,HFILL}},
903
904
16
        { &hf_iuup_init_ti, { "TI", "iuup.ti", FT_UINT8, BASE_DEC, VALS(iuup_ti_vals),0x10,"Timing Information",HFILL}},
905
16
        { &hf_iuup_init_subflows_per_rfci, { "Subflows", "iuup.subflows", FT_UINT8, BASE_DEC, NULL,0x0e,"Number of Subflows",HFILL}},
906
16
        { &hf_iuup_init_chain_ind, { "Chain Indicator", "iuup.chain_ind", FT_UINT8, BASE_DEC, VALS(iuup_init_chain_ind_vals),0x01,NULL,HFILL}},
907
16
        { &hf_iuup_payload, { "Payload Data", "iuup.payload_data", FT_BYTES, BASE_NONE, NULL,0x00,NULL,HFILL}},
908
909
910
16
        { &hf_iuup_mode_versions, { "Iu UP Mode Versions Supported", "iuup.support_mode", FT_UINT16, BASE_HEX, NULL,0x0,NULL,HFILL}},
911
912
16
        { &hf_iuup_mode_versions_a[ 0], { "Version 16", "iuup.support_mode.version16", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x8000,NULL,HFILL}},
913
16
        { &hf_iuup_mode_versions_a[ 1], { "Version 15", "iuup.support_mode.version15", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x4000,NULL,HFILL}},
914
16
        { &hf_iuup_mode_versions_a[ 2], { "Version 14", "iuup.support_mode.version14", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x2000,NULL,HFILL}},
915
16
        { &hf_iuup_mode_versions_a[ 3], { "Version 13", "iuup.support_mode.version13", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x1000,NULL,HFILL}},
916
16
        { &hf_iuup_mode_versions_a[ 4], { "Version 12", "iuup.support_mode.version12", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0800,NULL,HFILL}},
917
16
        { &hf_iuup_mode_versions_a[ 5], { "Version 11", "iuup.support_mode.version11", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0400,NULL,HFILL}},
918
16
        { &hf_iuup_mode_versions_a[ 6], { "Version 10", "iuup.support_mode.version10", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0200,NULL,HFILL}},
919
16
        { &hf_iuup_mode_versions_a[ 7], { "Version  9", "iuup.support_mode.version9", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0100,NULL,HFILL}},
920
16
        { &hf_iuup_mode_versions_a[ 8], { "Version  8", "iuup.support_mode.version8", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0080,NULL,HFILL}},
921
16
        { &hf_iuup_mode_versions_a[ 9], { "Version  7", "iuup.support_mode.version7", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0040,NULL,HFILL}},
922
16
        { &hf_iuup_mode_versions_a[10], { "Version  6", "iuup.support_mode.version6", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0020,NULL,HFILL}},
923
16
        { &hf_iuup_mode_versions_a[11], { "Version  5", "iuup.support_mode.version5", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0010,NULL,HFILL}},
924
16
        { &hf_iuup_mode_versions_a[12], { "Version  4", "iuup.support_mode.version4", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0008,NULL,HFILL}},
925
16
        { &hf_iuup_mode_versions_a[13], { "Version  3", "iuup.support_mode.version3", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0004,NULL,HFILL}},
926
16
        { &hf_iuup_mode_versions_a[14], { "Version  2", "iuup.support_mode.version2", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0002,NULL,HFILL}},
927
16
        { &hf_iuup_mode_versions_a[15], { "Version  1", "iuup.support_mode.version1", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0001,NULL,HFILL}},
928
929
16
        { &hf_iuup_num_rfci_ind, { "Number of RFCI Indicators", "iuup.p", FT_UINT8, BASE_HEX, NULL,0x3f,NULL,HFILL}},
930
16
        { &hf_iuup_init_rfci_ind, { "RFCI Initialization", "iuup.rfci.init", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
931
932
16
        HFS_RFCI(0),HFS_RFCI(1),HFS_RFCI(2),HFS_RFCI(3),HFS_RFCI(4),HFS_RFCI(5),HFS_RFCI(6),HFS_RFCI(7),
933
16
        HFS_RFCI(8),HFS_RFCI(9),HFS_RFCI(10),HFS_RFCI(11),HFS_RFCI(12),HFS_RFCI(13),HFS_RFCI(14),HFS_RFCI(15),
934
16
        HFS_RFCI(16),HFS_RFCI(17),HFS_RFCI(18),HFS_RFCI(19),HFS_RFCI(20),HFS_RFCI(21),HFS_RFCI(22),HFS_RFCI(23),
935
16
        HFS_RFCI(24),HFS_RFCI(25),HFS_RFCI(26),HFS_RFCI(27),HFS_RFCI(28),HFS_RFCI(29),HFS_RFCI(30),HFS_RFCI(31),
936
16
        HFS_RFCI(32),HFS_RFCI(33),HFS_RFCI(34),HFS_RFCI(35),HFS_RFCI(36),HFS_RFCI(37),HFS_RFCI(38),HFS_RFCI(39),
937
16
        HFS_RFCI(40),HFS_RFCI(41),HFS_RFCI(42),HFS_RFCI(43),HFS_RFCI(44),HFS_RFCI(45),HFS_RFCI(46),HFS_RFCI(47),
938
16
        HFS_RFCI(48),HFS_RFCI(49),HFS_RFCI(50),HFS_RFCI(51),HFS_RFCI(52),HFS_RFCI(53),HFS_RFCI(54),HFS_RFCI(55),
939
16
        HFS_RFCI(56),HFS_RFCI(57),HFS_RFCI(58),HFS_RFCI(59),HFS_RFCI(60),HFS_RFCI(61),HFS_RFCI(62),HFS_RFCI(63)
940
941
16
    };
942
943
944
16
    int* ett[] = {
945
16
        &ett_iuup,
946
16
        &ett_rfci,
947
16
        &ett_ipti,
948
16
        &ett_support,
949
16
        &ett_time,
950
16
        &ett_rfciinds,
951
16
        &ett_payload,
952
16
        &ett_payload_subflows
953
16
    };
954
955
16
    static ei_register_info ei[] = {
956
16
        { &ei_iuup_hdr_crc_bad, { "iuup.hdr.crc.bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
957
16
        { &ei_iuup_payload_crc_bad, { "iuup.payload.crc.bad", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
958
16
        { &ei_iuup_payload_undecoded, { "iuup.payload.undecoded", PI_UNDECODED, PI_WARN, "Undecoded payload", EXPFILL }},
959
16
        { &ei_iuup_error_response, { "iuup.error_response", PI_RESPONSE_CODE, PI_ERROR, "Error response", EXPFILL }},
960
16
        { &ei_iuup_ack_nack, { "iuup.ack.malformed", PI_MALFORMED, PI_ERROR, "Malformed Ack/Nack", EXPFILL }},
961
16
        { &ei_iuup_time_align, { "iuup.time_align.malformed", PI_MALFORMED, PI_ERROR, "Malformed Time Align", EXPFILL }},
962
16
        { &ei_iuup_procedure_indicator, { "iuup.procedure.malformed", PI_MALFORMED, PI_ERROR, "Malformed Procedure", EXPFILL }},
963
16
        { &ei_iuup_too_many_rfcis, { "iuup.rfci.too_many", PI_MALFORMED, PI_ERROR, "Too many RFCIs (more than 64)", EXPFILL }},
964
16
        { &ei_iuup_pdu_type, { "iuup.pdu_type.malformed", PI_MALFORMED, PI_ERROR, "Malformed PDU Type", EXPFILL }},
965
16
    };
966
967
16
    module_t *iuup_module;
968
16
    expert_module_t* expert_iuup;
969
970
16
    proto_iuup = proto_register_protocol("IuUP", "IuUP", "iuup");
971
16
    proto_register_field_array(proto_iuup, hf, array_length(hf));
972
16
    proto_register_subtree_array(ett, array_length(ett));
973
16
    expert_iuup = expert_register_protocol(proto_iuup);
974
16
    expert_register_field_array(expert_iuup, ei, array_length(ei));
975
16
    iuup_handle = register_dissector("iuup", dissect_iuup, proto_iuup);
976
16
    register_dissector("find_iuup", find_iuup, proto_iuup);
977
978
16
    circuits = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), g_direct_hash, g_direct_equal);
979
980
16
    iuup_module = prefs_register_protocol(proto_iuup, NULL);
981
982
16
    prefs_register_bool_preference(iuup_module, "dissect_payload",
983
16
                                   "Dissect IuUP Payload bits",
984
16
                                   "Whether IuUP Payload bits should be dissected",
985
16
                                   &dissect_fields);
986
987
16
    prefs_register_bool_preference(iuup_module, "two_byte_pseudoheader",
988
16
                                   "Two byte pseudoheader",
989
16
                                   "The payload contains a two byte pseudoheader indicating direction and circuit_id",
990
16
                                   &two_byte_pseudoheader);
991
992
16
    prefs_register_obsolete_preference(iuup_module, "dynamic.payload.type");
993
16
}
994
995
/*
996
 * Editor modelines
997
 *
998
 * Local Variables:
999
 * c-basic-offset: 4
1000
 * tab-width: 8
1001
 * indent-tabs-mode: nil
1002
 * End:
1003
 *
1004
 * ex: set shiftwidth=4 tabstop=8 expandtab:
1005
 * :indentSize=4:tabSize=8:noTabs=true:
1006
 */