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