2 * IuUP Protocol 3GPP TS 25.415 V6.2.0 (2005-03)
4 * (c) 2005 Luis E. Garcia Ontanon <luis@ontanon.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 Patch by Polystar (Peter Vestman, Petter Edblom):
30 Corrected rfci handling in rate control messages
31 Added crc6 and crc10 checks for header and payload
39 #include <epan/epan.h>
40 #include <epan/packet.h>
41 #include <epan/proto.h>
42 #include <epan/tvbuff.h>
43 #include <epan/prefs.h>
44 #include <epan/emem.h>
45 #include <epan/expert.h>
46 #include <epan/crc10.h>
47 #include <epan/crc6.h>
50 typedef struct _iuup_rfci_t {
53 guint num_of_subflows;
57 struct _iuup_rfci_t* next;
62 guint num_of_subflows;
64 iuup_rfci_t* last_rfci;
67 static int proto_iuup = -1;
69 static int hf_iuup_direction = -1;
70 static int hf_iuup_circuit_id = -1;
72 static int hf_iuup_pdu_type = -1;
73 static int hf_iuup_frame_number = -1;
74 static int hf_iuup_fqc = -1;
75 static int hf_iuup_rfci = -1;
76 static int hf_iuup_hdr_crc = -1;
77 static int hf_iuup_hdr_crc_error = -1;
78 static int hf_iuup_payload_crc = -1;
79 static int hf_iuup_payload_crc_error = -1;
81 static int hf_iuup_ack_nack = -1;
82 static int hf_iuup_frame_number_t14 = -1;
83 static int hf_iuup_mode_version = -1;
84 static int hf_iuup_procedure_indicator = -1;
85 static int hf_iuup_error_cause_val = -1;
87 static int hf_iuup_init_ti = -1;
88 static int hf_iuup_init_subflows_per_rfci = -1;
89 static int hf_iuup_init_chain_ind = -1;
91 static int hf_iuup_error_distance = -1;
92 static int hf_iuup_errorevt_cause_val = -1;
94 static int hf_iuup_time_align = -1;
95 static int hf_iuup_spare_bytes = -1;
96 static int hf_iuup_spare_03 = -1;
97 static int hf_iuup_spare_0f = -1;
98 static int hf_iuup_spare_c0 = -1;
99 static int hf_iuup_spare_e0 = -1;
100 static int hf_iuup_spare_ff = -1;
102 static int hf_iuup_delay = -1;
103 static int hf_iuup_advance = -1;
104 static int hf_iuup_delta = -1;
106 static int hf_iuup_mode_versions = -1;
107 static int hf_iuup_mode_versions_a[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
110 static int hf_iuup_data_pdu_type = -1;
112 static int hf_iuup_num_rfci_ind = -1;
114 static int hf_iuup_payload = -1;
116 static int hf_iuup_init_rfci_ind = -1;
117 static int hf_iuup_init_rfci[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
119 static int hf_iuup_init_rfci_flow_len[64][8] = {
120 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
121 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
122 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
123 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
124 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
125 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
126 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
127 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1}
130 static int hf_iuup_init_rfci_li[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
131 static int hf_iuup_init_rfci_lri[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
132 static int hf_iuup_init_ipti[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
134 static int hf_iuup_rfci_subflow[64][8] = {
135 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
136 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
137 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
138 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
139 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
140 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
141 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},
142 {-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1,-1,-1,-1}
145 static int hf_iuup_rfci_ratectl[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
148 static gint ett_iuup = -1;
149 static gint ett_rfci = -1;
150 static gint ett_ipti = -1;
151 static gint ett_support = -1;
152 static gint ett_time = -1;
153 static gint ett_rfciinds = -1;
154 static gint ett_payload = -1;
155 static gint ett_payload_subflows = -1;
157 static GHashTable* circuits = NULL;
159 static dissector_handle_t data_handle = NULL;
160 static gboolean dissect_fields = FALSE;
161 static gboolean two_byte_pseudoheader = FALSE;
162 static guint global_dynamic_payload_type = 0;
165 #define PDUTYPE_DATA_WITH_CRC 0
166 #define PDUTYPE_DATA_NO_CRC 1
167 #define PDUTYPE_DATA_CONTROL_PROC 14
169 static const value_string iuup_pdu_types[] = {
170 {PDUTYPE_DATA_WITH_CRC,"Data with CRC"},
171 {PDUTYPE_DATA_NO_CRC,"Data without CRC"},
172 {PDUTYPE_DATA_CONTROL_PROC,"Control Procedure"},
176 static const value_string iuup_colinfo_pdu_types[] = {
177 {PDUTYPE_DATA_WITH_CRC,"Data (CRC)"},
178 {PDUTYPE_DATA_NO_CRC,"Data (no CRC)"},
179 {PDUTYPE_DATA_CONTROL_PROC,""},
183 #define ACKNACK_ACK 0x4
184 #define ACKNACK_NACK 0x8
185 #define ACKNACK_RESERVED 0xc
186 #define ACKNACK_PROC 0x0
188 static const value_string iuup_acknack_vals[] = {
189 {ACKNACK_PROC >> 2,"Procedure"},
190 {ACKNACK_ACK >> 2,"ACK"},
191 {ACKNACK_NACK >> 2,"NACK"},
192 {ACKNACK_RESERVED >> 2,"Reserved"},
196 static const value_string iuup_colinfo_acknack_vals[] = {
198 {ACKNACK_ACK,"ACK "},
199 {ACKNACK_NACK,"NACK "},
200 {ACKNACK_RESERVED,"Reserved "},
209 static const value_string iuup_procedures[] = {
210 {PROC_INIT,"Initialization"},
211 {PROC_RATE,"Rate Control"},
212 {PROC_TIME,"Time Alignment"},
213 {PROC_ERROR,"Error Event"},
229 static const value_string iuup_colinfo_procedures[] = {
230 {PROC_INIT,"Initialization "},
231 {PROC_RATE,"Rate Control "},
232 {PROC_TIME,"Time Alignment "},
233 {PROC_ERROR,"Error Event "},
238 static const value_string iuup_error_distances[] = {
239 {0, "Reporting local error"},
240 {1, "First forwarding of error event report"},
241 {2, "Second forwarding of error event report"},
246 static const value_string iuup_error_causes[] = {
247 {0, "CRC error of frame header"},
248 {1, "CRC error of frame payload"},
249 {2, "Unexpected frame number"},
251 {4, "PDU type unknown"},
252 {5, "Unknown procedure"},
253 {6, "Unknown reserved value"},
254 {7, "Unknown field"},
255 {8, "Frame too short"},
256 {9, "Missing fields"},
257 {16, "Unexpected PDU type"},
258 {18, "Unexpected procedure"},
259 {19, "Unexpected RFCI"},
260 {20, "Unexpected value"},
261 {42, "Initialisation failure"},
262 {43, "Initialisation failure (network error, timer expiry)"},
263 {44, "Initialisation failure (Iu UP function error, repeated NACK)"},
264 {45, "Rate control failure"},
265 {46, "Error event failure"},
266 {47, "Time Alignment not supported"},
267 {48, "Requested Time Alignment not possible"},
268 {49, "Iu UP Mode version not supported"},
272 static const value_string iuup_rfci_indicator[] = {
279 static const value_string iuup_ti_vals[] = {
280 {0, "IPTIs not present"},
281 {1, "IPTIs present in frame"},
285 static const value_string iuup_mode_version_support[] = {
286 {0, "not supported"},
291 static const value_string iuup_init_rfci_li_vals[] = {
292 {0, "one octet used"},
293 {1, "two octets used"},
297 static const value_string iuup_init_chain_ind_vals[] = {
298 {0, "this frame is the last frame for the procedure"},
299 {1, "additional frames will be sent for the procedure"},
303 static const value_string iuup_init_lri_vals[] = {
304 {0, "Not last RFCI"},
305 {1, "Last RFCI in current frame"},
309 static const value_string iuup_payload_pdu_type[] = {
315 static const value_string iuup_fqcs[] = {
318 {2, "Frame bad due to radio"},
325 iuup_proto_tree_add_bits(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int bit_offset, guint bits, guint8** buf) {
326 static const guint8 masks[] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
327 int len = (bits + bit_offset)/8 + ((bits + bit_offset)%8 ? 0 : 1);
328 guint8* shifted_buffer;
332 DISSECTOR_ASSERT(bit_offset < 8);
334 shifted_buffer = ep_tvb_memdup(tvb,offset,len+1);
336 for(i = 0; i < len; i++) {
337 shifted_buffer[i] <<= bit_offset;
338 shifted_buffer[i] |= (shifted_buffer[i+1] & masks[bit_offset]) >> (8 - bit_offset);
341 shifted_buffer[len] <<= bit_offset;
342 shifted_buffer[len] &= masks[(bits + bit_offset)%8];
345 *buf = shifted_buffer;
347 pi = proto_tree_add_bytes(tree, hf, tvb, offset, len + ((bits + bit_offset) % 8 ? 1 : 0) , shifted_buffer);
348 proto_item_append_text(pi, " (%i Bits)", bits);
353 static void dissect_iuup_payload(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, guint rfci_id _U_, int offset) {
354 iuup_circuit_t* iuup_circuit;
356 int last_offset = tvb_length(tvb) - 1;
357 guint bit_offset = 0;
360 pi = proto_tree_add_item(tree,hf_iuup_payload,tvb,offset,-1,FALSE);
362 if ( ! dissect_fields ) {
364 } else if ( ! pinfo->circuit_id
365 || ! ( iuup_circuit = g_hash_table_lookup(circuits,GUINT_TO_POINTER(pinfo->circuit_id)) ) ) {
366 proto_item_set_expert_flags(pi, PI_UNDECODED, PI_WARN);
370 for(rfci = iuup_circuit->rfcis; rfci; rfci = rfci->next)
371 if ( rfci->id == rfci_id )
375 proto_item_set_expert_flags(pi, PI_UNDECODED, PI_WARN);
379 tree = proto_item_add_subtree(pi,ett_payload);
384 guint subflows = rfci->num_of_subflows;
385 proto_tree* flow_tree;
387 pi = proto_tree_add_text(tree,tvb,offset,-1,"Payload Frame");
388 flow_tree = proto_item_add_subtree(pi,ett_payload_subflows);
392 for(i = 0; i < subflows; i++) {
394 if (! rfci->subflow[i].len)
397 iuup_proto_tree_add_bits(flow_tree, hf_iuup_rfci_subflow[rfci->id][i], tvb,
398 offset + (bit_offset/8),
400 rfci->subflow[i].len,
403 bit_offset += rfci->subflow[i].len;
406 offset += (bit_offset / 8) + (bit_offset % 8 ? 1 : 0);
408 } while (offset <= last_offset);
411 static guint dissect_rfcis(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, int* offset, iuup_circuit_t* iuup_circuit) {
419 iuup_rfci_t *rfci = se_alloc0(sizeof(iuup_rfci_t));
422 DISSECTOR_ASSERT(c < 64);
424 pi = proto_tree_add_item(tree,hf_iuup_init_rfci_ind,tvb,*offset,-1,FALSE);
425 pt = proto_item_add_subtree(pi,ett_rfci);
427 proto_tree_add_item(pt,hf_iuup_init_rfci_lri[c],tvb,*offset,1,FALSE);
428 proto_tree_add_item(pt,hf_iuup_init_rfci_li[c],tvb,*offset,1,FALSE);
429 proto_tree_add_item(pt,hf_iuup_init_rfci[c],tvb,*offset,1,FALSE);
431 oct = tvb_get_guint8(tvb,*offset);
432 rfci->id = oct & 0x3f;
433 rfci->num_of_subflows = iuup_circuit->num_of_subflows;
435 len = (oct & 0x40) ? 2 : 1;
436 proto_item_set_text(pi,"RFCI %i Initialization",rfci->id);
437 proto_item_set_len(pi,(len*iuup_circuit->num_of_subflows)+1);
441 for(i = 0; i < iuup_circuit->num_of_subflows; i++) {
445 subflow_len = tvb_get_ntohs(tvb,*offset);
447 subflow_len = tvb_get_guint8(tvb,*offset);
450 rfci->subflow[i].len = subflow_len;
451 rfci->sum_len += subflow_len;
453 proto_tree_add_uint(pt,hf_iuup_init_rfci_flow_len[c][i],tvb,*offset,len,subflow_len);
459 if (iuup_circuit->last_rfci) {
460 iuup_circuit->last_rfci = iuup_circuit->last_rfci->next = rfci;
462 iuup_circuit->last_rfci = iuup_circuit->rfcis = rfci;
466 } while ( ! (oct & 0x80) );
471 static void dissect_iuup_init(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
473 guint8 oct = tvb_get_guint8(tvb,offset);
474 guint n = (oct & 0x0e) >> 1;
475 gboolean ti = oct & 0x10;
479 proto_tree* support_tree = NULL;
480 proto_tree* iptis_tree;
481 iuup_circuit_t* iuup_circuit = NULL;
483 if (pinfo->circuit_id) {
484 iuup_circuit = g_hash_table_lookup(circuits,GUINT_TO_POINTER(pinfo->circuit_id));
487 g_hash_table_remove(circuits,GUINT_TO_POINTER(pinfo->circuit_id));
490 iuup_circuit = se_alloc0(sizeof(iuup_circuit_t));
492 iuup_circuit = ep_alloc0(sizeof(iuup_circuit_t));
495 iuup_circuit->id = pinfo->circuit_id;
496 iuup_circuit->num_of_subflows = n;
497 iuup_circuit->rfcis = NULL;
498 iuup_circuit->last_rfci = NULL;
500 if (pinfo->circuit_id) {
501 g_hash_table_insert(circuits,GUINT_TO_POINTER(iuup_circuit->id),iuup_circuit);
505 proto_tree_add_item(tree,hf_iuup_spare_e0,tvb,offset,1,FALSE);
506 proto_tree_add_item(tree,hf_iuup_init_ti,tvb,offset,1,FALSE);
507 proto_tree_add_item(tree,hf_iuup_init_subflows_per_rfci,tvb,offset,1,FALSE);
508 proto_tree_add_item(tree,hf_iuup_init_chain_ind,tvb,offset,1,FALSE);
513 rfcis = dissect_rfcis(tvb, pinfo, tree, &offset, iuup_circuit);
518 pi = proto_tree_add_text(tree,tvb,offset,(rfcis/2)+(rfcis%2),"IPTIs");
519 iptis_tree = proto_item_add_subtree(pi,ett_ipti);
521 for (i = 0; i <= rfcis; i++) {
522 proto_tree_add_item(iptis_tree,hf_iuup_init_ipti[i],tvb,offset,1,FALSE);
534 pi = proto_tree_add_item(tree,hf_iuup_mode_versions,tvb,offset,2,FALSE);
535 support_tree = proto_item_add_subtree(pi,ett_support);
537 for (i = 0; i < 16; i++) {
538 proto_tree_add_item(support_tree,hf_iuup_mode_versions_a[i],tvb,offset,2,FALSE);
545 proto_tree_add_item(tree,hf_iuup_data_pdu_type,tvb,offset,1,FALSE);
549 static void dissect_iuup_ratectl(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree) {
550 guint num = tvb_get_guint8(tvb,4) & 0x3f;
553 proto_tree* inds_tree;
556 pi = proto_tree_add_item(tree,hf_iuup_num_rfci_ind,tvb,4,1,FALSE);
557 inds_tree = proto_item_add_subtree(pi,ett_rfciinds);
559 for (i = 0; i < num; i++) {
560 if (! (i % 8) ) offset++;
561 proto_tree_add_item(inds_tree,hf_iuup_rfci_ratectl[i],tvb,offset,1,FALSE);
566 static proto_item *add_hdr_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree, guint16 crccheck)
568 proto_item *crc_item;
570 crc_item = proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc_error,tvb,2,1,FALSE);
571 expert_add_info_format(pinfo, crc_item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
573 crc_item = proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,FALSE);
578 static proto_item *add_payload_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree)
580 proto_item *crc_item;
581 int length = tvb_length(tvb);
582 guint16 crc10 = tvb_get_ntohs(tvb, 2) & 0x3FF;
583 guint16 crccheck = update_crc10_by_bytes(crc10, tvb_get_ptr(tvb, 4, length - 4), length - 4);
585 crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc_error,tvb,2,2,FALSE);
586 expert_add_info_format(pinfo, crc_item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
588 crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,FALSE);
593 #define ACKNACK_MASK 0x0c
594 #define PROCEDURE_MASK 0x0f
595 #define FQC_MASK 0xc0
596 #define PDUTYPE_MASK 0xf0
597 static void dissect_iuup(tvbuff_t* tvb_in, packet_info* pinfo, proto_tree* tree) {
599 proto_item* iuup_item = NULL;
600 proto_item* pdutype_item = NULL;
601 proto_tree* iuup_tree = NULL;
602 proto_item* proc_item = NULL;
603 proto_item* ack_item = NULL;
610 tvbuff_t* tvb = tvb_in;
612 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IuUP");
614 if (two_byte_pseudoheader) {
615 int len = tvb_length(tvb_in) - 2;
617 phdr = tvb_get_ntohs(tvb,0);
619 proto_tree_add_item(tree,hf_iuup_direction,tvb,0,2,FALSE);
620 proto_tree_add_item(tree,hf_iuup_circuit_id,tvb,0,2,FALSE);
624 pinfo->circuit_id = phdr;
626 tvb = tvb_new_subset(tvb_in,2,len,len);
629 first_octet = tvb_get_guint8(tvb,0);
630 second_octet = tvb_get_guint8(tvb,1);
631 hdrcrc6 = tvb_get_guint8(tvb, 2) >> 2;
632 crccheck = update_crc6_by_bytes(hdrcrc6, first_octet, second_octet);
634 pdutype = ( first_octet & PDUTYPE_MASK ) >> 4;
637 iuup_item = proto_tree_add_item(tree,proto_iuup,tvb,0,-1,FALSE);
638 iuup_tree = proto_item_add_subtree(iuup_item,ett_iuup);
640 pdutype_item = proto_tree_add_item(iuup_tree,hf_iuup_pdu_type,tvb,0,1,FALSE);
643 if (check_col(pinfo->cinfo, COL_INFO)) {
644 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pdutype, iuup_colinfo_pdu_types, "Unknown PDU Type(%u) "));
648 case PDUTYPE_DATA_WITH_CRC:
649 if (check_col(pinfo->cinfo, COL_INFO)) {
650 col_append_fstr(pinfo->cinfo, COL_INFO,"FN: %x RFCI: %u", (guint)(first_octet & 0x0f) ,(guint)(second_octet & 0x3f));
654 proto_tree_add_item(iuup_tree,hf_iuup_frame_number,tvb,0,1,FALSE);
655 pi = proto_tree_add_item(iuup_tree,hf_iuup_fqc,tvb,1,1,FALSE);
657 if (first_octet & FQC_MASK) {
658 proto_item_set_expert_flags(pi, PI_RESPONSE_CODE, PI_WARN);
659 proto_item_set_expert_flags(iuup_item, PI_RESPONSE_CODE, PI_WARN);
662 proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,FALSE);
663 add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
664 add_payload_crc(tvb, pinfo, iuup_tree);
665 dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,4);
667 case PDUTYPE_DATA_NO_CRC:
668 if (check_col(pinfo->cinfo, COL_INFO)) {
669 col_append_fstr(pinfo->cinfo, COL_INFO," RFCI %u", (guint)(second_octet & 0x3f));
672 proto_tree_add_item(iuup_tree,hf_iuup_frame_number,tvb,0,1,FALSE);
673 pi = proto_tree_add_item(iuup_tree,hf_iuup_fqc,tvb,1,1,FALSE);
675 if (first_octet & FQC_MASK) {
676 proto_item_set_expert_flags(pi, PI_RESPONSE_CODE, PI_WARN);
677 proto_item_set_expert_flags(iuup_item, PI_RESPONSE_CODE, PI_WARN);
680 proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,FALSE);
681 add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
682 dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,3);
684 case PDUTYPE_DATA_CONTROL_PROC:
686 ack_item = proto_tree_add_item(iuup_tree,hf_iuup_ack_nack,tvb,0,1,FALSE);
687 proto_tree_add_item(iuup_tree,hf_iuup_frame_number_t14,tvb,0,1,FALSE);
688 proto_tree_add_item(iuup_tree,hf_iuup_mode_version,tvb,1,1,FALSE);
689 proc_item = proto_tree_add_item(iuup_tree,hf_iuup_procedure_indicator,tvb,1,1,FALSE);
690 add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
693 if (check_col(pinfo->cinfo, COL_INFO)) {
694 col_append_str(pinfo->cinfo, COL_INFO,
695 val_to_str(first_octet & ACKNACK_MASK,
696 iuup_colinfo_acknack_vals, "[action:%u] "));
698 col_append_str(pinfo->cinfo, COL_INFO,
699 val_to_str(second_octet & PROCEDURE_MASK,
700 iuup_colinfo_procedures, "[proc:%u] "));
703 switch ( first_octet & ACKNACK_MASK ) {
705 switch(second_octet & PROCEDURE_MASK) {
708 proto_tree_add_item(iuup_tree,hf_iuup_spare_03,tvb,2,1,FALSE);
709 proto_tree_add_item(iuup_tree,hf_iuup_spare_ff,tvb,3,1,FALSE);
713 dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
720 proto_item_set_expert_flags(proc_item, PI_MALFORMED, PI_ERROR);
726 pi = proto_tree_add_item(iuup_tree,hf_iuup_error_cause_val,tvb,4,1,FALSE);
727 proto_item_set_expert_flags(pi, PI_RESPONSE_CODE, PI_ERROR);
729 case ACKNACK_RESERVED:
731 proto_item_set_expert_flags(ack_item, PI_MALFORMED, PI_ERROR);
737 switch( second_octet & PROCEDURE_MASK ) {
739 if (tree) add_payload_crc(tvb, pinfo, iuup_tree);
740 dissect_iuup_init(tvb,pinfo,iuup_tree);
744 add_payload_crc(tvb, pinfo, iuup_tree);
745 dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
749 proto_tree* time_tree;
754 ta = tvb_get_guint8(tvb,4);
756 pi = proto_tree_add_item(iuup_tree,hf_iuup_time_align,tvb,4,1,FALSE);
757 time_tree = proto_item_add_subtree(pi,ett_time);
759 if (ta >= 1 && ta <= 80) {
760 pi = proto_tree_add_uint(time_tree,hf_iuup_delay,tvb,4,1,ta * 500);
761 PROTO_ITEM_SET_GENERATED(pi);
762 pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((gfloat)((gint)(ta) * 500))/(gfloat)1000000.0);
763 PROTO_ITEM_SET_GENERATED(pi);
764 } else if (ta >= 129 && ta <= 208) {
765 pi = proto_tree_add_uint(time_tree,hf_iuup_advance,tvb,4,1,(ta-128) * 500);
766 PROTO_ITEM_SET_GENERATED(pi);
767 pi = proto_tree_add_float(time_tree,hf_iuup_delta,tvb,4,1,((gfloat)((gint)(-(((gint)ta)-128))) * 500)/(gfloat)1000000.0);
768 PROTO_ITEM_SET_GENERATED(pi);
770 proto_item_set_expert_flags(pi, PI_MALFORMED, PI_ERROR);
773 proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,FALSE);
777 if (check_col(pinfo->cinfo, COL_INFO)) {
778 col_append_str(pinfo->cinfo, COL_INFO, val_to_str(tvb_get_guint8(tvb,4) & 0x3f,iuup_error_causes,"Unknown (%u)"));
781 proto_tree_add_item(iuup_tree,hf_iuup_error_distance,tvb,4,1,FALSE);
782 pi = proto_tree_add_item(iuup_tree,hf_iuup_errorevt_cause_val,tvb,4,1,FALSE);
783 proto_item_set_expert_flags(pi, PI_RESPONSE_CODE, PI_ERROR);
784 proto_tree_add_item(iuup_tree,hf_iuup_spare_bytes,tvb,5,-1,FALSE);
788 proto_item_set_expert_flags(proc_item, PI_MALFORMED, PI_ERROR);
793 proto_item_set_expert_flags(pdutype_item, PI_MALFORMED, PI_ERROR);
799 static gboolean dissect_iuup_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
800 int len = tvb_length(tvb);
802 guint8 first_octet = tvb_get_guint8(tvb,0);
803 guint8 second_octet = tvb_get_guint8(tvb,1);
804 guint16 hdrcrc6 = tvb_get_guint8(tvb, 2) >> 2;
806 if (update_crc6_by_bytes(hdrcrc6, first_octet, second_octet)) return FALSE;
808 switch ( first_octet & 0xf0 ) {
810 if (len<7) return FALSE;
811 if (update_crc10_by_bytes((guint16)(tvb_get_ntohs(tvb, 4) & 0x3FF), tvb_get_ptr(tvb, 6, len-4), len-4) ) return FALSE;
815 /* a FALSE positive factory */
816 if (len<5) return FALSE;
819 if (len<5) return FALSE;
820 if( (second_octet & 0x0f) > 3) return FALSE;
825 dissect_iuup(tvb, pinfo, tree);
830 static void find_iuup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
831 int len = tvb_length(tvb);
835 if ( dissect_iuup_heur(tvb_new_subset_remaining(tvb,offset), pinfo, tree) )
842 call_dissector(data_handle, tvb, pinfo, tree);
845 static void init_iuup(void) {
847 g_hash_table_destroy(circuits);
848 circuits = g_hash_table_new(g_direct_hash,g_direct_equal);
852 void proto_reg_handoff_iuup(void) {
853 static gboolean iuup_prefs_initialized = FALSE;
854 static dissector_handle_t iuup_handle;
855 static guint saved_dynamic_payload_type = 0;
857 if (!iuup_prefs_initialized) {
858 iuup_handle = find_dissector("iuup");
859 dissector_add_string("rtp_dyn_payload_type","VND.3GPP.IUFP", iuup_handle);
860 data_handle = find_dissector("data");
861 iuup_prefs_initialized = TRUE;
863 if ( saved_dynamic_payload_type > 95 ) {
864 dissector_delete("rtp.pt", saved_dynamic_payload_type, iuup_handle);
868 saved_dynamic_payload_type = global_dynamic_payload_type;
870 if ( global_dynamic_payload_type > 95 ) {
871 dissector_add("rtp.pt", global_dynamic_payload_type, iuup_handle);
876 #define HFS_RFCI(i) \
877 { &hf_iuup_rfci_ratectl[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, VALS(iuup_rfci_indicator),0x80>>(i%8),NULL,HFILL}}, \
878 { &hf_iuup_init_rfci[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}}, \
879 { &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}}, \
880 { &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}}, \
881 { &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}}, \
882 { &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}}, \
883 { &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}}, \
884 { &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}}, \
885 { &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}}, \
886 { &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}}, \
887 { &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}}, \
888 { &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}}, \
889 { &hf_iuup_rfci_subflow[i][0], { "RFCI " #i " Flow 0", "iuup.rfci."#i".flow.0", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
890 { &hf_iuup_rfci_subflow[i][1], { "RFCI " #i " Flow 1", "iuup.rfci."#i".flow.1", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
891 { &hf_iuup_rfci_subflow[i][2], { "RFCI " #i " Flow 2", "iuup.rfci."#i".flow.2", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
892 { &hf_iuup_rfci_subflow[i][3], { "RFCI " #i " Flow 3", "iuup.rfci."#i".flow.3", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
893 { &hf_iuup_rfci_subflow[i][4], { "RFCI " #i " Flow 4", "iuup.rfci."#i".flow.4", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
894 { &hf_iuup_rfci_subflow[i][5], { "RFCI " #i " Flow 5", "iuup.rfci."#i".flow.5", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
895 { &hf_iuup_rfci_subflow[i][6], { "RFCI " #i " Flow 6", "iuup.rfci."#i".flow.6", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
896 { &hf_iuup_rfci_subflow[i][7], { "RFCI " #i " Flow 7", "iuup.rfci."#i".flow.7", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}}, \
897 { &hf_iuup_init_ipti[i], { "RFCI " #i " IPTI", "iuup.rfci."#i".ipti", FT_UINT8, BASE_HEX, NULL,i%2 ? 0x0F : 0xF0,NULL,HFILL}}
901 void proto_register_iuup(void) {
902 static hf_register_info hf[] = {
903 { &hf_iuup_direction, { "Frame Direction", "iuup.direction", FT_UINT16, BASE_DEC, NULL,0x8000,NULL,HFILL}},
904 { &hf_iuup_circuit_id, { "Circuit ID", "iuup.circuit_id", FT_UINT16, BASE_DEC, NULL,0x7fff,NULL,HFILL}},
905 { &hf_iuup_pdu_type, { "PDU Type", "iuup.pdu_type", FT_UINT8, BASE_DEC, VALS(iuup_pdu_types),0xf0,NULL,HFILL}},
906 { &hf_iuup_frame_number, { "Frame Number", "iuup.framenum", FT_UINT8, BASE_DEC, NULL,0x0F,NULL,HFILL}},
907 { &hf_iuup_fqc, { "FQC", "iuup.fqc", FT_UINT8, BASE_DEC, VALS(iuup_fqcs),0xc0,"Frame Quality Classification",HFILL}},
908 { &hf_iuup_rfci, { "RFCI", "iuup.rfci", FT_UINT8, BASE_HEX, NULL, 0x3f, "RAB sub-Flow Combination Indicator",HFILL}},
909 { &hf_iuup_hdr_crc, { "Header CRC", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,NULL,HFILL}},
910 { &hf_iuup_hdr_crc_error, { "Header CRC [incorrect]", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,NULL,HFILL}},
911 { &hf_iuup_payload_crc, { "Payload CRC", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,NULL,HFILL}},
912 { &hf_iuup_payload_crc_error, { "Payload CRC [incorrect]", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,NULL,HFILL}},
913 { &hf_iuup_ack_nack, { "Ack/Nack", "iuup.ack", FT_UINT8, BASE_DEC, VALS(iuup_acknack_vals),0x0c,NULL,HFILL}},
914 { &hf_iuup_frame_number_t14, { "Frame Number", "iuup.framenum", FT_UINT8, BASE_DEC, NULL,0x03,NULL,HFILL}},
915 { &hf_iuup_mode_version, { "Mode Version", "iuup.mode", FT_UINT8, BASE_HEX, NULL,0xf0,NULL,HFILL}},
916 { &hf_iuup_procedure_indicator, { "Procedure", "iuup.procedure", FT_UINT8, BASE_DEC, VALS(iuup_procedures),0x0f,NULL,HFILL}},
917 { &hf_iuup_error_cause_val, { "Error Cause", "iuup.error_cause", FT_UINT8, BASE_DEC, VALS(iuup_error_causes),0xfc,NULL,HFILL}},
918 { &hf_iuup_error_distance, { "Error DISTANCE", "iuup.error_distance", FT_UINT8, BASE_DEC, VALS(iuup_error_distances),0xc0,NULL,HFILL}},
919 { &hf_iuup_errorevt_cause_val, { "Error Cause", "iuup.error_cause", FT_UINT8, BASE_DEC, NULL,0x3f,NULL,HFILL}},
920 { &hf_iuup_time_align, { "Time Align", "iuup.time_align", FT_UINT8, BASE_HEX, NULL,0x0,NULL,HFILL}},
921 { &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}},
923 { &hf_iuup_spare_03, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x03,NULL,HFILL}},
924 { &hf_iuup_spare_0f, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0x0f,NULL,HFILL}},
925 { &hf_iuup_spare_c0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xc0,NULL,HFILL}},
926 { &hf_iuup_spare_e0, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xe0,NULL,HFILL}},
927 { &hf_iuup_spare_ff, { "Spare", "iuup.spare", FT_UINT8, BASE_HEX, NULL,0xff,NULL,HFILL}},
928 { &hf_iuup_spare_bytes, { "Spare", "iuup.spare", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
930 { &hf_iuup_delay, { "Delay", "iuup.delay", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
931 { &hf_iuup_advance, { "Advance", "iuup.advance", FT_UINT32, BASE_HEX, NULL,0x0,NULL,HFILL}},
932 { &hf_iuup_delta, { "Delta Time", "iuup.delta", FT_FLOAT, BASE_NONE, NULL,0x0,NULL,HFILL}},
934 { &hf_iuup_init_ti, { "TI", "iuup.ti", FT_UINT8, BASE_DEC, VALS(iuup_ti_vals),0x10,"Timing Information",HFILL}},
935 { &hf_iuup_init_subflows_per_rfci, { "Subflows", "iuup.subflows", FT_UINT8, BASE_DEC, NULL,0x0e,"Number of Subflows",HFILL}},
936 { &hf_iuup_init_chain_ind, { "Chain Indicator", "iuup.chain_ind", FT_UINT8, BASE_DEC, VALS(iuup_init_chain_ind_vals),0x01,NULL,HFILL}},
937 { &hf_iuup_payload, { "Payload Data", "iuup.payload_data", FT_BYTES, BASE_NONE, NULL,0x00,NULL,HFILL}},
940 { &hf_iuup_mode_versions, { "Iu UP Mode Versions Supported", "iuup.support_mode", FT_UINT16, BASE_HEX, NULL,0x0,NULL,HFILL}},
942 { &hf_iuup_mode_versions_a[ 0], { "Version 16", "iuup.support_mode.version16", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x8000,NULL,HFILL}},
943 { &hf_iuup_mode_versions_a[ 1], { "Version 15", "iuup.support_mode.version15", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x4000,NULL,HFILL}},
944 { &hf_iuup_mode_versions_a[ 2], { "Version 14", "iuup.support_mode.version14", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x2000,NULL,HFILL}},
945 { &hf_iuup_mode_versions_a[ 3], { "Version 13", "iuup.support_mode.version13", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x1000,NULL,HFILL}},
946 { &hf_iuup_mode_versions_a[ 4], { "Version 12", "iuup.support_mode.version12", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0800,NULL,HFILL}},
947 { &hf_iuup_mode_versions_a[ 5], { "Version 11", "iuup.support_mode.version11", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0400,NULL,HFILL}},
948 { &hf_iuup_mode_versions_a[ 6], { "Version 10", "iuup.support_mode.version10", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0200,NULL,HFILL}},
949 { &hf_iuup_mode_versions_a[ 7], { "Version 9", "iuup.support_mode.version9", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0100,NULL,HFILL}},
950 { &hf_iuup_mode_versions_a[ 8], { "Version 8", "iuup.support_mode.version8", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0080,NULL,HFILL}},
951 { &hf_iuup_mode_versions_a[ 9], { "Version 7", "iuup.support_mode.version7", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0040,NULL,HFILL}},
952 { &hf_iuup_mode_versions_a[10], { "Version 6", "iuup.support_mode.version6", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0020,NULL,HFILL}},
953 { &hf_iuup_mode_versions_a[11], { "Version 5", "iuup.support_mode.version5", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0010,NULL,HFILL}},
954 { &hf_iuup_mode_versions_a[12], { "Version 4", "iuup.support_mode.version4", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0008,NULL,HFILL}},
955 { &hf_iuup_mode_versions_a[13], { "Version 3", "iuup.support_mode.version3", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0004,NULL,HFILL}},
956 { &hf_iuup_mode_versions_a[14], { "Version 2", "iuup.support_mode.version2", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0002,NULL,HFILL}},
957 { &hf_iuup_mode_versions_a[15], { "Version 1", "iuup.support_mode.version1", FT_UINT16, BASE_HEX, VALS(iuup_mode_version_support),0x0001,NULL,HFILL}},
959 { &hf_iuup_num_rfci_ind, { "Number of RFCI Indicators", "iuup.p", FT_UINT8, BASE_HEX, NULL,0x3f,NULL,HFILL}},
960 { &hf_iuup_init_rfci_ind, { "RFCI Initialization", "iuup.rfci.init", FT_BYTES, BASE_NONE, NULL,0x0,NULL,HFILL}},
962 HFS_RFCI(0),HFS_RFCI(1),HFS_RFCI(2),HFS_RFCI(3),HFS_RFCI(4),HFS_RFCI(5),HFS_RFCI(6),HFS_RFCI(7),
963 HFS_RFCI(8),HFS_RFCI(9),HFS_RFCI(10),HFS_RFCI(11),HFS_RFCI(12),HFS_RFCI(13),HFS_RFCI(14),HFS_RFCI(15),
964 HFS_RFCI(16),HFS_RFCI(17),HFS_RFCI(18),HFS_RFCI(19),HFS_RFCI(20),HFS_RFCI(21),HFS_RFCI(22),HFS_RFCI(23),
965 HFS_RFCI(24),HFS_RFCI(25),HFS_RFCI(26),HFS_RFCI(27),HFS_RFCI(28),HFS_RFCI(29),HFS_RFCI(30),HFS_RFCI(31),
966 HFS_RFCI(32),HFS_RFCI(33),HFS_RFCI(34),HFS_RFCI(35),HFS_RFCI(36),HFS_RFCI(37),HFS_RFCI(38),HFS_RFCI(39),
967 HFS_RFCI(40),HFS_RFCI(41),HFS_RFCI(42),HFS_RFCI(43),HFS_RFCI(44),HFS_RFCI(45),HFS_RFCI(46),HFS_RFCI(47),
968 HFS_RFCI(48),HFS_RFCI(49),HFS_RFCI(50),HFS_RFCI(51),HFS_RFCI(52),HFS_RFCI(53),HFS_RFCI(54),HFS_RFCI(55),
969 HFS_RFCI(56),HFS_RFCI(57),HFS_RFCI(58),HFS_RFCI(59),HFS_RFCI(60),HFS_RFCI(61),HFS_RFCI(62),HFS_RFCI(63)
982 &ett_payload_subflows
985 module_t* iuup_module;
988 proto_iuup = proto_register_protocol("IuUP", "IuUP", "iuup");
989 proto_register_field_array(proto_iuup, hf, array_length(hf));
990 proto_register_subtree_array(ett, array_length(ett));
991 register_dissector("iuup", dissect_iuup, proto_iuup);
992 register_dissector("find_iuup", find_iuup, proto_iuup);
994 register_init_routine(&init_iuup);
996 iuup_module = prefs_register_protocol(proto_iuup, proto_reg_handoff_iuup);
998 prefs_register_bool_preference(iuup_module, "dissect_payload",
999 "Dissect IuUP Payload bits",
1000 "Whether IuUP Payload bits should be dissected",
1003 prefs_register_bool_preference(iuup_module, "two_byte_pseudoheader",
1004 "Two byte pseudoheader",
1005 "The payload contains a two byte pseudoheader indicating direction and circuit_id",
1006 &two_byte_pseudoheader);
1008 prefs_register_uint_preference(iuup_module, "dynamic.payload.type",
1009 "IuUP dynamic payload type",
1010 "The dynamic payload type which will be interpreted as IuUP",
1012 &global_dynamic_payload_type);