Coverage Report

Created: 2025-08-04 07:15

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