/src/wireshark/epan/dissectors/packet-mux27010.c
Line | Count | Source |
1 | | /* packet-mux27010.c |
2 | | * Dissects a variant of 3GPP TS 27.010 multiplexing protocol |
3 | | * Copyright 2011, Hans-Christoph Schemmel <hans-christoph.schemmel[AT]cinterion.com> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | /* |
13 | | * This dissector analyses a multiplexed communication between a GSM modem and the host, |
14 | | * whereby the multiplexing is based upon a variant of the specification 3G TS 27.010. |
15 | | * |
16 | | * The assigned DLT value is: |
17 | | * LINKTYPE_MUX27010 236 DLT_MUX27010 |
18 | | * |
19 | | * A detailed description of the packet structure/LINKTYPE_MUX27010 can be found on: |
20 | | * http://www.tcpdump.org/linktypes/LINKTYPE_MUX27010.html |
21 | | */ |
22 | | |
23 | | #include "config.h" |
24 | | |
25 | | #include <epan/packet.h> |
26 | | #include <wiretap/wtap.h> |
27 | | #include <epan/reassemble.h> |
28 | | #include <epan/crc8-tvb.h> |
29 | | #include <epan/expert.h> |
30 | | |
31 | | void proto_register_mux27010(void); |
32 | | void proto_reg_handoff_mux27010(void); |
33 | | |
34 | 23 | #define PROTO_TAG_MUX27010 "MUX27010" |
35 | | |
36 | | /*Extended Header*/ |
37 | 109 | #define MUX27010_EXTENDED_HEADER_NOT_ENDED 0x01 |
38 | | |
39 | | /*Address flags*/ |
40 | 34 | #define MUX27010_DLCI_ADDRESS_FLAG 0xFC |
41 | 15 | #define MUX27010_EA_ADDRESS_FLAG 0x01 |
42 | 15 | #define MUX27010_CR_ADDRESS_FLAG 0x02 |
43 | | |
44 | | /*Control flags*/ |
45 | 34 | #define MUX27010_FRAMETYPE_CONTROL_FLAG 0xEF |
46 | 0 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_SABM 0x2F |
47 | 0 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_UA 0x63 |
48 | 0 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_DM 0x0F |
49 | 0 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_DISC 0x43 |
50 | 1 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH 0xEF |
51 | 15 | #define MUX27010_PF_CONTROL_FLAG 0x10 |
52 | 42 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E 0x00 |
53 | 43 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_RR 0x01 |
54 | 38 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_RNR 0x05 |
55 | 35 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_REJ 0x09 |
56 | 51 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_NS 0x0E |
57 | 159 | #define MUX27010_FRAMETYPE_CONTROL_FLAG_NR 0xE0 |
58 | | #define MUX27010_FRAMETYPE_CONTROL_FLAG_NOT_GREATER_THEN_7 0x07 |
59 | | |
60 | | |
61 | | /*Length*/ |
62 | 32 | #define MUX27010_EA_LENGTH_FLAG 0x01 |
63 | 20 | #define MUX27010_FRAMESIZE_LENGTH_FLAG 0xFE |
64 | 15 | #define MUX27010_FRAMESIZE_LENGTH_FLAG_EA 0xFFFE |
65 | | |
66 | | /*Control Channel*/ |
67 | 31 | #define MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG 0x01 |
68 | 31 | #define MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG 0x02 |
69 | 23 | #define MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG 0xFC |
70 | 213 | #define MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG 0x01 |
71 | 23 | #define MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG 0xFE |
72 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION 0xFF |
73 | 0 | #define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE 0x04 |
74 | 0 | #define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS 0x08 |
75 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI 0xFC |
76 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC 0x02 |
77 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC 0x04 |
78 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR 0x08 |
79 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING 0x40 |
80 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD 0x80 |
81 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI 0x3F |
82 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE 0x0F |
83 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_PN_CL 0xF0 |
84 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO 0x3F |
85 | 15 | #define MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE 0x07 |
86 | | |
87 | | /*Command pattern - set C/R bit to 1*/ |
88 | | #define MUX27010_COMMAND_MULTIPLEXER_CLOSEDOWN 0xC3 /*11000011*/ |
89 | 0 | #define MUX27010_COMMAND_TEST_COMMAND 0x23 /*00100011*/ |
90 | 0 | #define MUX27010_COMMAND_POWER_SAVING_CONTROL 0x43 /*01000011*/ |
91 | 0 | #define MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE 0x13 /*00010011*/ |
92 | 0 | #define MUX27010_COMMAND_MODEM_STATUS_COMMAND 0xE3 /*00010011*/ |
93 | 0 | #define MUX27010_COMMAND_PARAMETER_NEGOTIATION 0x83 /*10000011*/ |
94 | | |
95 | | |
96 | | /* Wireshark ID of the MUX27010 protocol */ |
97 | | static int proto_mux27010; |
98 | | |
99 | | /* Handles of subdissectors */ |
100 | | static dissector_handle_t ppp_handle; |
101 | | |
102 | | #if 0 |
103 | | static const value_string packettypenames[] = { |
104 | | { 0, "TEXT" }, |
105 | | { 1, "SOMETHING_ELSE" }, |
106 | | { 0, NULL } |
107 | | }; |
108 | | #endif |
109 | | |
110 | | static const value_string direction_vals[] = { |
111 | | { 0, "Direction: Application => Module" }, |
112 | | { 1, "Module => Application" }, |
113 | | { 2, "Not valid" }, |
114 | | { 3, "Not valid" }, |
115 | | { 0, NULL } |
116 | | }; |
117 | | |
118 | | static const value_string detailedvalue_response_vals[] = { |
119 | | { 0, "Failure" }, |
120 | | { 1, "Success" }, |
121 | | { 0, NULL } |
122 | | }; |
123 | | |
124 | | static const value_string frame_type_vals[] = { |
125 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_SABM, "SABM" }, |
126 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_UA, "UA" }, |
127 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_DM, "DM" }, |
128 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_DISC, "DISC" }, |
129 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_UIH, "UIH" }, |
130 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E, "UIH_E" }, |
131 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_RR, "Receive Ready" }, |
132 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_RNR, "Receive Not Ready" }, |
133 | | { MUX27010_FRAMETYPE_CONTROL_FLAG_REJ, "Reject" }, |
134 | | { 0, NULL } |
135 | | }; |
136 | | |
137 | | static const value_string command_vals[] = { |
138 | | { (MUX27010_COMMAND_MULTIPLEXER_CLOSEDOWN>>2), "Multiplexer Close Down" }, |
139 | | { (MUX27010_COMMAND_TEST_COMMAND>>2), "Test Command" }, |
140 | | { (MUX27010_COMMAND_POWER_SAVING_CONTROL>>2), "Power Saving Control" }, |
141 | | { (MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE>>2), "Non-supported Command Response" }, |
142 | | { (MUX27010_COMMAND_MODEM_STATUS_COMMAND>>2), "Modem Status Command" }, |
143 | | { (MUX27010_COMMAND_PARAMETER_NEGOTIATION>>2), "Parameter Negotiation" }, |
144 | | { 0, NULL } |
145 | | }; |
146 | | |
147 | | static const value_string iei_coding_vals[] = { |
148 | | { MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE, "TEMUX_VERSION" }, |
149 | | { MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS, "MSMUX_VERSION" }, |
150 | | { 0, NULL } |
151 | | }; |
152 | | |
153 | | /*Control channel*/ |
154 | | struct controlchannel_type |
155 | | { |
156 | | uint8_t cr; |
157 | | uint8_t command; |
158 | | int number_of_type_frames; |
159 | | }; |
160 | | |
161 | | struct controlchannel |
162 | | { |
163 | | uint8_t length_value; |
164 | | int number_of_length_frames; |
165 | | }; |
166 | | |
167 | | /* The following hf_* variables are used to hold the Wireshark IDs of |
168 | | * the header fields; they are filled out when call |
169 | | * proto_register_field_array() in proto_register_mux27010() |
170 | | */ |
171 | | |
172 | | static int hf_mux27010_extended_header; |
173 | | static int hf_mux27010_direction; |
174 | | static int hf_mux27010; |
175 | | static int hf_mux27010_address; |
176 | | static int hf_mux27010_control; |
177 | | static int hf_mux27010_length; |
178 | | static int hf_mux27010_controlchannel; |
179 | | |
180 | | /*Extended Header*/ |
181 | | static int hf_mux27010_extended_header_size; |
182 | | static int hf_mux27010_extended_header_msg_number_I; |
183 | | static int hf_mux27010_extended_header_freq_number_I; |
184 | | static int hf_mux27010_extended_header_start_pos_I; |
185 | | static int hf_mux27010_extended_header_start_byte_I; |
186 | | static int hf_mux27010_extended_header_end_pos_I; |
187 | | static int hf_mux27010_extended_header_end_byte_I; |
188 | | static int hf_mux27010_extended_header_flag_ended_I; |
189 | | |
190 | | static int hf_mux27010_extended_header_msg_number_II; |
191 | | static int hf_mux27010_extended_header_freq_number_II; |
192 | | static int hf_mux27010_extended_header_start_pos_II; |
193 | | static int hf_mux27010_extended_header_start_byte_II; |
194 | | static int hf_mux27010_extended_header_end_pos_II; |
195 | | static int hf_mux27010_extended_header_end_byte_II; |
196 | | static int hf_mux27010_extended_header_flag_ended_II; |
197 | | |
198 | | static int hf_mux27010_extended_header_msg_number_III; |
199 | | static int hf_mux27010_extended_header_freq_number_III; |
200 | | static int hf_mux27010_extended_header_start_pos_III; |
201 | | static int hf_mux27010_extended_header_start_byte_III; |
202 | | static int hf_mux27010_extended_header_end_pos_III; |
203 | | static int hf_mux27010_extended_header_end_byte_III; |
204 | | static int hf_mux27010_extended_header_flag_ended_III; |
205 | | |
206 | | /*Address*/ |
207 | | static int hf_mux27010_dlciaddressflag; |
208 | | static int hf_mux27010_eaaddressflag; |
209 | | static int hf_mux27010_craddressflag; |
210 | | /* static int hf_mux27010_addressdirection; */ |
211 | | /*Control*/ |
212 | | static int hf_mux27010_controlframetype; |
213 | | static int hf_mux27010_controlframetypens; |
214 | | static int hf_mux27010_controlframetypenr; |
215 | | static int hf_mux27010_pfcontrolflag; |
216 | | /*Length*/ |
217 | | static int hf_mux27010_ealengthflag; |
218 | | static int hf_mux27010_lengthframesize; |
219 | | static int hf_mux27010_lengthframesize_ea; |
220 | | /*Control channel dlci = 0*/ |
221 | | static int hf_mux27010_controlchannelframetype; |
222 | | static int hf_mux27010_controlchanneleaframetype; |
223 | | static int hf_mux27010_controlchannelcrframetype; |
224 | | static int hf_mux27010_controlchannelframetypecommand; |
225 | | static int hf_mux27010_controlchannellength; |
226 | | static int hf_mux27010_controlchannelealength; |
227 | | static int hf_mux27010_controlchannellengthfield; |
228 | | static int hf_mux27010_controlchannelvalue; |
229 | | static int hf_mux27010_controlchannel_iei_coding; |
230 | | static int hf_mux27010_controlchanneldetailedvalue; |
231 | | static int hf_mux27010_controlchannel_detailedvalue_response; |
232 | | static int hf_mux27010_controlchanneldetailedvaluetestcommandversion; |
233 | | static int hf_mux27010_controlchanneldetailedvaluemscdlci; |
234 | | /* static int hf_mux27010_controlchanneldetailedvaluemscv24; */ |
235 | | static int hf_mux27010_controlchanneldetailedvaluemscv24fc; |
236 | | static int hf_mux27010_controlchanneldetailedvaluemscv24rtc; |
237 | | static int hf_mux27010_controlchanneldetailedvaluemscv24rtr; |
238 | | static int hf_mux27010_controlchanneldetailedvaluemscv24ring; |
239 | | static int hf_mux27010_controlchanneldetailedvaluemscv24dcd; |
240 | | static int hf_mux27010_controlchanneldetailedvaluemscbreak; |
241 | | static int hf_mux27010_controlchanneldetailedvaluepndlci; |
242 | | static int hf_mux27010_controlchanneldetailedvaluepnframetype; |
243 | | static int hf_mux27010_controlchanneldetailedvaluepncl; |
244 | | static int hf_mux27010_controlchanneldetailedvaluepnprio; |
245 | | static int hf_mux27010_controlchanneldetailedvaluepntimer; |
246 | | static int hf_mux27010_controlchanneldetailedvaluepnframesize; |
247 | | static int hf_mux27010_controlchanneldetailedvaluepnna; |
248 | | static int hf_mux27010_controlchanneldetailedvaluepnwinsize; |
249 | | /*Information*/ |
250 | | static int hf_mux27010_information; |
251 | | static int hf_mux27010_information_str; |
252 | | /*Checksum*/ |
253 | | static int hf_mux27010_checksum; |
254 | | static int hf_mux27010_checksum_correct; |
255 | | |
256 | | /* These are the ids of the subtrees that we may be creating */ |
257 | | static int ett_mux27010_extended_header; |
258 | | static int ett_mux27010; |
259 | | static int ett_mux27010_address; |
260 | | static int ett_mux27010_control; |
261 | | static int ett_mux27010_length; |
262 | | static int ett_mux27010_controlchannel; |
263 | | static int ett_mux27010_controlchannelframetype; |
264 | | static int ett_mux27010_controlchannellength; |
265 | | static int ett_mux27010_controlchannelvalue; |
266 | | static int ett_mux27010_information; |
267 | | static int ett_mux27010_checksum; |
268 | | |
269 | | static expert_field ei_mux27010_message_illogical; |
270 | | static expert_field ei_mux27010_checksum_incorrect; |
271 | | |
272 | | static int hf_msg_fragments; |
273 | | static int hf_msg_fragment; |
274 | | static int hf_msg_fragment_overlap; |
275 | | static int hf_msg_fragment_overlap_conflicts; |
276 | | static int hf_msg_fragment_multiple_tails; |
277 | | static int hf_msg_fragment_too_long_fragment; |
278 | | static int hf_msg_fragment_error; |
279 | | static int hf_msg_fragment_count; |
280 | | static int hf_msg_reassembled_in; |
281 | | static int hf_msg_reassembled_length; |
282 | | |
283 | | static int ett_msg_fragment; |
284 | | static int ett_msg_fragments; |
285 | | |
286 | | static dissector_handle_t mux27010_handle; |
287 | | |
288 | | static const fragment_items msg_frag_items = { |
289 | | /* Fragment subtrees */ |
290 | | &ett_msg_fragment, |
291 | | &ett_msg_fragments, |
292 | | /* Fragment fields */ |
293 | | &hf_msg_fragments, |
294 | | &hf_msg_fragment, |
295 | | &hf_msg_fragment_overlap, |
296 | | &hf_msg_fragment_overlap_conflicts, |
297 | | &hf_msg_fragment_multiple_tails, |
298 | | &hf_msg_fragment_too_long_fragment, |
299 | | &hf_msg_fragment_error, |
300 | | &hf_msg_fragment_count, |
301 | | /* Reassembled in field */ |
302 | | &hf_msg_reassembled_in, |
303 | | /* Reassembled length field */ |
304 | | &hf_msg_reassembled_length, |
305 | | /* Reassembled data field */ |
306 | | NULL, |
307 | | /* Tag */ |
308 | | "Message fragments" |
309 | | }; |
310 | | |
311 | | static reassembly_table msg_reassembly_table; |
312 | | |
313 | | |
314 | | |
315 | | static int |
316 | 23 | getExtendedHeader(tvbuff_t *tvb, proto_tree *field_tree, int offset, uint8_t* sizeMuxPPPHeader){ |
317 | 23 | int i; |
318 | | |
319 | 23 | *sizeMuxPPPHeader = tvb_get_uint8(tvb, offset); |
320 | 23 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_size, tvb, offset, 1, ENC_BIG_ENDIAN); |
321 | 23 | if (*sizeMuxPPPHeader > 0){ |
322 | 13 | int tmpOffset = 1; |
323 | 13 | uint16_t tmpStartByte = 0; |
324 | 13 | uint16_t tmpLastByte = 0; |
325 | 119 | for (i=0; i < *sizeMuxPPPHeader/7; i++){ |
326 | 110 | switch(i){ |
327 | 12 | case(0) : |
328 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
329 | 12 | tmpOffset+=2; |
330 | | |
331 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
332 | 12 | tmpOffset+=2; |
333 | | |
334 | 12 | tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
335 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
336 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_I, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN); |
337 | 12 | tmpOffset+=1; |
338 | | |
339 | 12 | tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
340 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
341 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_I, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN); |
342 | | |
343 | 12 | tmpOffset+=1; |
344 | 12 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
345 | 12 | if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED) |
346 | 4 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence"); |
347 | 8 | else |
348 | 8 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence"); |
349 | 12 | break; |
350 | | |
351 | 11 | case(1) : |
352 | 11 | tmpOffset+=1; |
353 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
354 | 11 | tmpOffset+=2; |
355 | | |
356 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
357 | 11 | tmpOffset+=2; |
358 | | |
359 | 11 | tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
360 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
361 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_II, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN); |
362 | 11 | tmpOffset+=1; |
363 | | |
364 | 11 | tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
365 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
366 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_II, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN); |
367 | | |
368 | 11 | tmpOffset+=1; |
369 | 11 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
370 | 11 | if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED) |
371 | 5 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence"); |
372 | 6 | else |
373 | 6 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence"); |
374 | 11 | break; |
375 | | |
376 | 9 | case(2) : |
377 | 9 | tmpOffset+=1; |
378 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
379 | 9 | tmpOffset+=2; |
380 | | |
381 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN); |
382 | 9 | tmpOffset+=2; |
383 | | |
384 | 9 | tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
385 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
386 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_III, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN); |
387 | 9 | tmpOffset+=1; |
388 | | |
389 | 9 | tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1; |
390 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
391 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_III, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN); |
392 | | |
393 | 9 | tmpOffset+=1; |
394 | 9 | proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN); |
395 | 9 | if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED) |
396 | 6 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence"); |
397 | 3 | else |
398 | 3 | proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence"); |
399 | 9 | break; |
400 | 110 | } |
401 | | |
402 | 110 | } |
403 | | |
404 | 13 | } |
405 | | |
406 | 19 | return *sizeMuxPPPHeader; |
407 | 23 | } |
408 | | |
409 | | |
410 | | /*Get the direction of the actual packet*/ |
411 | | static int |
412 | 19 | getFrameDirection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, int offset){ |
413 | 19 | uint8_t direction_in_out; |
414 | | |
415 | | /*Direction is coded in the first byte of the frame*/ |
416 | 19 | direction_in_out = tvb_get_uint8(tvb, offset); |
417 | | |
418 | | /*If first byte is 0 => Frame source is Application*/ |
419 | | /*If first byte is 1 => Frame source is Module*/ |
420 | | /*else Error*/ |
421 | 19 | proto_tree_add_uint(field_tree, hf_mux27010_direction, tvb, offset, 1, direction_in_out & 3); |
422 | 19 | switch (direction_in_out & 3) { |
423 | 10 | case (0):/*Application >> Module*/ |
424 | 10 | col_set_str(pinfo->cinfo, COL_DEF_SRC, "Application DLCI "); |
425 | 10 | col_set_str(pinfo->cinfo, COL_DEF_DST, "Module"); |
426 | 10 | break; |
427 | 5 | case (1):/*Module >> Application*/ |
428 | 5 | col_set_str(pinfo->cinfo, COL_DEF_SRC, "Module DLCI "); |
429 | 5 | col_set_str(pinfo->cinfo, COL_DEF_DST, "Application"); |
430 | 5 | break; |
431 | 4 | default:/*?? >> ??*/ |
432 | 4 | col_set_str(pinfo->cinfo, COL_DEF_SRC, "Direction not valid "); |
433 | 4 | col_set_str(pinfo->cinfo, COL_DEF_DST, "Direction not valid "); |
434 | 4 | break; |
435 | 19 | } |
436 | | |
437 | 19 | return 1; |
438 | 19 | } |
439 | | |
440 | | |
441 | | |
442 | | /*Get the address of the actual frame*/ |
443 | | static int |
444 | 19 | getFrameAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree_addr, int offset, uint8_t* dlci_number){ |
445 | 19 | uint8_t byte; |
446 | | |
447 | 19 | byte = tvb_get_uint8(tvb, offset); |
448 | | /*Get the DCLI number of the frame >> overwrite other bits (E/A, CR) >> shift*/ |
449 | 19 | *dlci_number = (byte & MUX27010_DLCI_ADDRESS_FLAG) >> 2; |
450 | | |
451 | | /*Add text to string for Source column*/ |
452 | 19 | col_append_fstr(pinfo->cinfo, COL_DEF_SRC, "%d ", *dlci_number); |
453 | | |
454 | | /*Add items to subtree to display the details*/ |
455 | 19 | proto_tree_add_item(field_tree_addr, hf_mux27010_eaaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN); |
456 | 19 | proto_tree_add_item(field_tree_addr, hf_mux27010_craddressflag, tvb, offset, 1, ENC_BIG_ENDIAN); |
457 | 19 | proto_tree_add_item(field_tree_addr, hf_mux27010_dlciaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN); |
458 | | |
459 | 19 | return 1; |
460 | 19 | } |
461 | | |
462 | | |
463 | | |
464 | | /*Get frame data from control field*/ |
465 | | static int |
466 | 19 | getFrameControlData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, int offset, uint8_t* frame_type){ |
467 | | /*if the frame type is known -> 1 else 0*/ |
468 | 19 | uint8_t known_frame_type = 0; |
469 | | |
470 | | /*Get the type of frame*/ |
471 | 19 | *frame_type = tvb_get_uint8(tvb, offset) & MUX27010_FRAMETYPE_CONTROL_FLAG; |
472 | | |
473 | | /*Find out the frame type and write info into column*/ |
474 | 19 | switch (*frame_type) { |
475 | 0 | case (MUX27010_FRAMETYPE_CONTROL_FLAG_SABM): /*SABM frame*/ |
476 | 0 | case (MUX27010_FRAMETYPE_CONTROL_FLAG_UA): /*UA frame*/ |
477 | 0 | case (MUX27010_FRAMETYPE_CONTROL_FLAG_DM): /*DM frame*/ |
478 | 0 | case (MUX27010_FRAMETYPE_CONTROL_FLAG_DISC): /*DISC frame*/ |
479 | 1 | case (MUX27010_FRAMETYPE_CONTROL_FLAG_UIH): /*UIH frame*/ |
480 | 1 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type); |
481 | 1 | break; |
482 | | |
483 | 18 | default: |
484 | | /*Got another frame -> probably a UIH_E, RR, RNR or REJ frame from a DLCI channel != 0 ==> Data channel*/ |
485 | | |
486 | | /*Check if frame is a UIH_E frame*/ |
487 | 18 | if ((MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E | MUX27010_FRAMETYPE_CONTROL_FLAG_NS | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NS | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) { |
488 | 12 | *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E; |
489 | | /*Add frame type to column*/ |
490 | 12 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E); |
491 | | /*Add info about sequence numbers to column*/ |
492 | 12 | proto_tree_add_item(field_tree, hf_mux27010_controlframetypens, tvb, offset, 1, ENC_BIG_ENDIAN); |
493 | 12 | proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN); |
494 | | |
495 | | /*Frame type is known*/ |
496 | 12 | known_frame_type = 1; |
497 | 12 | } |
498 | | /*Check if frame is a RR frame*/ |
499 | 18 | if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) { |
500 | 1 | *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RR; |
501 | | /*Add frame type to column*/ |
502 | 1 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_RR); |
503 | | /*Add info about sequence number to column*/ |
504 | 1 | proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN); |
505 | | |
506 | | /*Frame type is known*/ |
507 | 1 | known_frame_type = 1; |
508 | 1 | } |
509 | 18 | if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RNR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) { |
510 | 1 | *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RNR; |
511 | | /*Add frame type to column*/ |
512 | 1 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_RNR); |
513 | | /*Add info about sequence number to column*/ |
514 | 1 | proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN); |
515 | | |
516 | | /*Frame type is known*/ |
517 | 1 | known_frame_type = 1; |
518 | 1 | } |
519 | 18 | if ((MUX27010_FRAMETYPE_CONTROL_FLAG_REJ | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) { |
520 | 0 | *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_REJ; |
521 | | /*Add frame type to column*/ |
522 | 0 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_REJ); |
523 | | /*Add info about sequence number to column*/ |
524 | 0 | proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN); |
525 | | |
526 | | /*Frame type is known*/ |
527 | 0 | known_frame_type = 1; |
528 | 0 | } |
529 | | |
530 | | /*Unknown frame*/ |
531 | 18 | if (known_frame_type == 0) { |
532 | | /*Add frame type to column*/ |
533 | 4 | proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type); |
534 | 4 | } |
535 | 19 | } |
536 | | |
537 | | /*Write information to string for column info*/ |
538 | 19 | col_add_fstr(pinfo->cinfo, COL_INFO, "(%s)", val_to_str_const(*frame_type, frame_type_vals, "Unknown")); |
539 | | |
540 | | /*Add Frame type value and PF bit to column*/ |
541 | 19 | proto_tree_add_item(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, ENC_BIG_ENDIAN); |
542 | 19 | proto_tree_add_item(field_tree, hf_mux27010_pfcontrolflag, tvb, offset, 1, ENC_BIG_ENDIAN); |
543 | | |
544 | 19 | return 1; |
545 | 19 | } |
546 | | |
547 | | |
548 | | |
549 | | |
550 | | /*Get frame data from length field*/ |
551 | | static int |
552 | 17 | getFrameLength(tvbuff_t *tvb, proto_tree *field_tree, int offset, uint32_t* length_info){ |
553 | | |
554 | | /*Get the E/A bit*/ |
555 | 17 | uint8_t length_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_LENGTH_FLAG; |
556 | 17 | proto_tree_add_item(field_tree, hf_mux27010_ealengthflag, tvb, offset, 1, ENC_BIG_ENDIAN); |
557 | | |
558 | | /*Get the length of the info field*/ |
559 | | |
560 | | /*If E/A = 1 it is the last octet*/ |
561 | 17 | if (length_ea == 1) { |
562 | | |
563 | | /*Add the E/A bit and the length value to the subtree*/ |
564 | 5 | proto_tree_add_item(field_tree, hf_mux27010_lengthframesize, tvb, offset, 1, ENC_BIG_ENDIAN); |
565 | 5 | *length_info = (tvb_get_uint8(tvb, offset) & MUX27010_FRAMESIZE_LENGTH_FLAG) >> 1; /*Shift because of EA bit*/ |
566 | 5 | return 1; |
567 | 5 | } |
568 | | |
569 | | /*If E/A = 0 the length of the info field is >127; |
570 | | first octet stores LSB bits, second octet MSB -> LITTLE ENDIAN stuffing*/ |
571 | 12 | proto_tree_add_item_ret_uint(field_tree, hf_mux27010_lengthframesize_ea, tvb, offset, 2, ENC_LITTLE_ENDIAN, length_info); |
572 | | |
573 | 12 | return 2; |
574 | 17 | } |
575 | | |
576 | | |
577 | | /*Get frame type of control channel frame*/ |
578 | | static int |
579 | | getControlChannelFrameType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree_ctr, int offset, |
580 | 8 | struct controlchannel_type* cctype){ |
581 | 8 | uint8_t controlchannel_type_ea; |
582 | | |
583 | | /*Get the E/A bit*/ |
584 | 8 | controlchannel_type_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG; |
585 | | |
586 | | /*Set variable for number of octets for frame type to 0*/ |
587 | 8 | cctype->number_of_type_frames = 0; |
588 | | /*If E/A bit = 1, there will be no other frame type octet*/ |
589 | 8 | if (controlchannel_type_ea == 1) |
590 | 8 | cctype->number_of_type_frames++; |
591 | | |
592 | | /*If E/A = 0, read all frame type octets*/ |
593 | 8 | while (controlchannel_type_ea == 0){ |
594 | 0 | cctype->number_of_type_frames++; |
595 | 0 | controlchannel_type_ea = tvb_get_uint8(tvb, offset+cctype->number_of_type_frames) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG; |
596 | 0 | } |
597 | | |
598 | | /*Get CR bit*/ |
599 | 8 | cctype->cr = (tvb_get_uint8(tvb, offset) & MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG) >> 1; |
600 | | |
601 | | /*Get command info*/ |
602 | 8 | cctype->command = tvb_get_uint8(tvb, offset) & MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG; |
603 | | |
604 | | /*Add info to subtree*/ |
605 | 8 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneleaframetype, tvb, offset, 1, ENC_BIG_ENDIAN); |
606 | 8 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelcrframetype, tvb, offset, 1, ENC_BIG_ENDIAN); |
607 | 8 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelframetypecommand, tvb, offset, 1, ENC_BIG_ENDIAN); |
608 | | |
609 | | /*Check the control channel frame types and add the name to the subtree Info column*/ |
610 | 8 | col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(cctype->command>>2, command_vals, "Unknown")); |
611 | | |
612 | 8 | if (cctype->cr == 1) /*Command C/R*/{ |
613 | 1 | col_append_str(pinfo->cinfo, COL_INFO, " (Command)"); |
614 | 1 | } |
615 | 7 | else{ /*Response*/ |
616 | 7 | col_append_str(pinfo->cinfo, COL_INFO, " (Response)"); |
617 | 7 | } |
618 | | |
619 | 8 | return cctype->number_of_type_frames; |
620 | 8 | } |
621 | | |
622 | | |
623 | | /*Get length of control channel info field*/ |
624 | | static int |
625 | 8 | getControlChannelLength(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset, struct controlchannel* cc) { |
626 | 8 | uint8_t controlchannel_length_ea; |
627 | | |
628 | | /*Get the E/A bit*/ |
629 | 8 | controlchannel_length_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG; |
630 | | |
631 | | /*Set variable for number of octets for info field to 0*/ |
632 | 8 | cc->number_of_length_frames = 0; |
633 | | /*If E/A bit = 1, there will be no other info field length octet*/ |
634 | 8 | if (controlchannel_length_ea == 1) |
635 | 2 | cc->number_of_length_frames++; |
636 | | |
637 | | /*If E/A = 0, read all length of info field octets*/ |
638 | 198 | while (controlchannel_length_ea == 0){ |
639 | 190 | cc->number_of_length_frames++; |
640 | 190 | controlchannel_length_ea = tvb_get_uint8(tvb, offset+cc->number_of_length_frames) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG; |
641 | 190 | } |
642 | | |
643 | | /*Get the data from info field*/ |
644 | 8 | cc->length_value = (tvb_get_uint8(tvb, offset) & MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG) >> 1; |
645 | | |
646 | | /*Add data to subtree*/ |
647 | 8 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelealength, tvb, offset, 1, ENC_BIG_ENDIAN); |
648 | 8 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannellengthfield, tvb, offset, 1, ENC_BIG_ENDIAN); |
649 | | |
650 | 8 | return cc->number_of_length_frames; |
651 | 8 | } |
652 | | |
653 | | |
654 | | |
655 | | /*Get values of control channel*/ |
656 | | static int |
657 | | getControlChannelValues(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset, |
658 | 8 | struct controlchannel* cc, struct controlchannel_type* cctype){ |
659 | 8 | uint8_t controlchannel_iei; |
660 | 8 | uint8_t controlchannel_psc; |
661 | | |
662 | | /*Command pattern for Test Command (C/R is set to 1)*/ |
663 | 8 | switch (cctype->command | MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG | MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG) |
664 | 8 | { |
665 | 0 | case MUX27010_COMMAND_TEST_COMMAND: |
666 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluetestcommandversion, tvb, offset, 1, ENC_BIG_ENDIAN); |
667 | 0 | controlchannel_iei = tvb_get_uint8(tvb, offset); |
668 | 0 | if ((controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE) || |
669 | 0 | (controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS)) { |
670 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannel_iei_coding, tvb, offset, 1, ENC_BIG_ENDIAN); |
671 | 0 | } |
672 | |
|
673 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelvalue, tvb, offset+1, cc->length_value-1, ENC_ASCII); |
674 | 0 | break; |
675 | | |
676 | | /*Command pattern for Power saving control (C/R is set to 1)*/ |
677 | 0 | case MUX27010_COMMAND_POWER_SAVING_CONTROL: |
678 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN); |
679 | 0 | controlchannel_psc = tvb_get_uint8(tvb, offset); |
680 | 0 | if (cctype->cr == 0 && controlchannel_psc == 0) /*Response Failure*/ |
681 | 0 | proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 0); |
682 | 0 | if (cctype->cr == 0 && controlchannel_psc == 1) /*Response Success*/ |
683 | 0 | proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 1); |
684 | 0 | break; |
685 | | |
686 | | /*Command pattern for non-supported command response (C/R is set to 1)*/ |
687 | 0 | case MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE: |
688 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN); |
689 | 0 | break; |
690 | | |
691 | | /*Command pattern for Modem Status Command (C/R is set to 1)*/ |
692 | 0 | case MUX27010_COMMAND_MODEM_STATUS_COMMAND: |
693 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscdlci, tvb, offset, 1, ENC_BIG_ENDIAN); |
694 | | |
695 | | /*Add bits of Flow Control*/ |
696 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24fc, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
697 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtc, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
698 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtr, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
699 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24ring, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
700 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24dcd, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
701 | | /**/ |
702 | |
|
703 | 0 | if (cc->length_value == 3) { |
704 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscbreak, tvb, offset+2, 1, ENC_BIG_ENDIAN); |
705 | 0 | } |
706 | 0 | break; |
707 | | |
708 | | /*Command pattern for Parameter Negotiation (EA + C/R is set to 1)*/ |
709 | 0 | case MUX27010_COMMAND_PARAMETER_NEGOTIATION: |
710 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepndlci, tvb, offset, 1, ENC_BIG_ENDIAN); |
711 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframetype, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
712 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepncl, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
713 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnprio, tvb, offset+2, 1, ENC_BIG_ENDIAN); |
714 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepntimer, tvb, offset+3, 1, ENC_BIG_ENDIAN); |
715 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframesize, tvb, offset+4, 2, ENC_BIG_ENDIAN); |
716 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnna, tvb, offset+6, 1, ENC_BIG_ENDIAN); |
717 | 0 | proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnwinsize, tvb, offset+7, 1, ENC_BIG_ENDIAN); |
718 | 0 | break; |
719 | 8 | } |
720 | | |
721 | 8 | return cc->length_value; |
722 | 8 | } |
723 | | |
724 | | |
725 | | |
726 | | /*Get values information field*/ |
727 | | static int |
728 | | getFrameInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, |
729 | 8 | int offset, uint32_t length_info){ |
730 | | |
731 | | /*Get the data from information field as string*/ |
732 | 8 | char *information_field = (char*)tvb_get_string_enc(pinfo->pool, tvb,offset,length_info, ENC_ASCII); |
733 | | |
734 | | /*delete unneeded signs out of info field -> for info column: CR (0x0d) and LF (0x0a)*/ |
735 | 8 | information_field = g_strdelimit(information_field, "\r\n", ' '); |
736 | | |
737 | 8 | col_append_fstr(pinfo->cinfo, COL_INFO, " %s", information_field); |
738 | | |
739 | | /*Add info to subtree*/ |
740 | 8 | proto_tree_add_string(field_tree, hf_mux27010_information_str, tvb, offset, length_info, information_field); |
741 | | |
742 | | /*Increment offset by the length of chars in info field*/ |
743 | 8 | return length_info; |
744 | 8 | } |
745 | | |
746 | | |
747 | | |
748 | | |
749 | | static int |
750 | | dissect_mux27010(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
751 | 23 | { |
752 | 23 | proto_item *ti, *tf, *tf_extended_header, *tf_addr, *tf_ctr; |
753 | 23 | proto_tree *mux27010_tree, *field_tree, *field_tree_extended_header, *field_tree_addr, *field_tree_ctr; |
754 | 23 | unsigned offset = 0; |
755 | 23 | uint32_t length_info; |
756 | 23 | bool save_fragmented; |
757 | | /*Address DLCI*/ |
758 | 23 | uint8_t dlci_number = 0; |
759 | 23 | uint8_t frame_type; |
760 | | /*private MUX frame header (PPP)*/ |
761 | 23 | uint8_t sizeMuxPPPHeader; |
762 | 23 | struct controlchannel_type cc_type; |
763 | 23 | struct controlchannel cc; |
764 | | |
765 | | /* Setup columns */ |
766 | 23 | col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_MUX27010); |
767 | 23 | col_clear(pinfo->cinfo, COL_INFO); |
768 | | |
769 | | /* Set offset to 0 => start to read at the begin of the frame*/ |
770 | 23 | offset = 0; |
771 | | |
772 | 23 | ti = proto_tree_add_item(tree, proto_mux27010, tvb, 0, -1, ENC_NA); |
773 | 23 | mux27010_tree = proto_item_add_subtree(ti, ett_mux27010); |
774 | | |
775 | | /*Add a subtree (=item) to the child node => in this subtree the details of extended header will be displayed*/ |
776 | 23 | tf_extended_header = proto_tree_add_item(mux27010_tree, hf_mux27010_extended_header, tvb, offset, 1, ENC_BIG_ENDIAN); |
777 | 23 | field_tree_extended_header = proto_item_add_subtree(tf_extended_header, ett_mux27010_extended_header); |
778 | | |
779 | 23 | offset += getExtendedHeader(tvb, field_tree_extended_header, offset, &sizeMuxPPPHeader); |
780 | 23 | offset++; |
781 | | |
782 | | /*Get direction of the frame*/ |
783 | 23 | offset += getFrameDirection(tvb, pinfo, mux27010_tree, offset); |
784 | | |
785 | | /*~~~~~~~~Flag~~~~~~~~*/ |
786 | | /*(Insert data into the child node)*/ |
787 | | /*Create item to show/highlight flag sequence*/ |
788 | 23 | proto_tree_add_item(mux27010_tree, hf_mux27010, tvb, offset, 1, ENC_BIG_ENDIAN); |
789 | 23 | offset++; |
790 | | /*~~~~~~~~/Flag~~~~~~~~*/ |
791 | | |
792 | | |
793 | | |
794 | | /*~~~~~~~~Address~~~~~~~~*/ |
795 | | /*Add a subtree (=item) to the child node => in this subtree the details of address data will be displayed*/ |
796 | 23 | tf_addr = proto_tree_add_item(mux27010_tree, hf_mux27010_address, tvb, offset, 1, ENC_BIG_ENDIAN); |
797 | 23 | field_tree_addr = proto_item_add_subtree(tf_addr, ett_mux27010_address); |
798 | | |
799 | | /*Get address data (DLCI, E/A, CR)*/ |
800 | 23 | offset += getFrameAddress(tvb, pinfo, field_tree_addr, offset, &dlci_number); |
801 | | /*~~~~~~~~/Address~~~~~~~~*/ |
802 | | |
803 | | |
804 | | |
805 | | /*~~~~~~~~Control Data~~~~~~~~*/ |
806 | | /*Add a subtree (=item) to the child node => in this subtree the details of control data will be displayed*/ |
807 | 23 | tf = proto_tree_add_item(mux27010_tree, hf_mux27010_control, tvb, offset, 1, ENC_BIG_ENDIAN); |
808 | 23 | field_tree = proto_item_add_subtree(tf, ett_mux27010_control); |
809 | | |
810 | | /*Get control data of frame (Frame type)*/ |
811 | 23 | offset += getFrameControlData(tvb, pinfo, field_tree, offset, &frame_type); |
812 | | /*~~~~~~~~/Control Data~~~~~~~~*/ |
813 | | |
814 | | |
815 | | |
816 | | |
817 | | /*~~~~~~~~Length~~~~~~~~*/ |
818 | | /*Set the variable for length of the info field to 0*/ |
819 | 23 | length_info = 0; |
820 | | |
821 | | /*Check the frame type because in RR, RNR and REJ are no info and no length fields*/ |
822 | 23 | if ((frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RR) && (frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RNR) && |
823 | 17 | (frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_REJ)){ |
824 | | /*Add a subtree (=item) to the child node => in this subtree will be the details of length field*/ |
825 | 17 | tf = proto_tree_add_item(mux27010_tree, hf_mux27010_length, tvb, offset, 1, ENC_BIG_ENDIAN); |
826 | 17 | field_tree = proto_item_add_subtree(tf, ett_mux27010_length); |
827 | | |
828 | | /*Get frame length data*/ |
829 | 17 | offset += getFrameLength(tvb, field_tree, offset, &length_info); |
830 | 17 | } |
831 | | /*~~~~~~~~/Length~~~~~~~~*/ |
832 | | |
833 | | |
834 | | |
835 | | /*~~~~~~~~Control Channel~~~~~~~~*/ |
836 | | /*Control Channel only exists if DLCI = 0*/ |
837 | 23 | if (dlci_number == 0) { |
838 | | |
839 | | /*If length field > 0, otherwise the frame has no data*/ |
840 | 10 | if (length_info > 0) { |
841 | | |
842 | | /*--------Frame Type--------*/ |
843 | | /*Get and display data of frame type*/ |
844 | | |
845 | | /*Add a subtree (=item) to the child node => in this subtree the details of control channel will be displayed*/ |
846 | 8 | tf = proto_tree_add_item(mux27010_tree, hf_mux27010_controlchannel, tvb, offset, 1, ENC_BIG_ENDIAN); |
847 | 8 | field_tree = proto_item_add_subtree(tf, ett_mux27010_controlchannel); |
848 | | |
849 | | /*Add another subtree to the control channel subtree => in this subtree the details of control channel frame type will be displayed*/ |
850 | 8 | tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannelframetype, tvb, offset, 1, ENC_BIG_ENDIAN); |
851 | 8 | field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannelframetype); |
852 | | |
853 | | /*Get data about the type of the frame*/ |
854 | 8 | offset += getControlChannelFrameType(tvb, pinfo, field_tree_ctr, offset, &cc_type); |
855 | 8 | proto_item_set_len(tf_ctr, cc_type.number_of_type_frames); |
856 | | /*--------/Frame Type--------*/ |
857 | | |
858 | | |
859 | | /*--------Length Field--------*/ |
860 | | /*Add another subtree to the control channel subtree => in this subtree the details of control channel length field will be displayed*/ |
861 | 8 | tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannellength, tvb, offset, 1, ENC_BIG_ENDIAN); |
862 | 8 | field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannellength); |
863 | | |
864 | | /*Get data of length field*/ |
865 | 8 | offset += getControlChannelLength(tvb, field_tree_ctr, offset, &cc); |
866 | 8 | proto_item_set_len(tf_ctr, cc.number_of_length_frames); |
867 | | /*--------/Length Field--------*/ |
868 | | |
869 | | |
870 | | /*--------Values--------*/ |
871 | | /*If frame has data inside the length_value is > 0*/ |
872 | 8 | if (cc.length_value > 0) { |
873 | | /*Add another subtree to the control channel subtree => in this subtree the details of control channel values/data will be displayed*/ |
874 | 8 | field_tree_ctr = proto_tree_add_subtree_format(field_tree, tvb, offset, cc.length_value, |
875 | 8 | ett_mux27010_controlchannelvalue, NULL, "Data: %i Byte(s)", cc.length_value); |
876 | | |
877 | | /*Get data of frame*/ |
878 | 8 | offset += getControlChannelValues(tvb, field_tree_ctr, offset, &cc, &cc_type); |
879 | 8 | }/*(controlchannel_length_value > 0)*/ |
880 | | /*--------/Values--------*/ |
881 | | |
882 | 8 | }/*length_info > 0*/ |
883 | 10 | }/*dlci_number == 0*/ |
884 | | |
885 | | |
886 | | |
887 | | |
888 | | /*~~~~~~~~Information~~~~~~~~*/ |
889 | | /*Display "normal" data/values (not control channel) if exists ==> length_info > 0*/ |
890 | 23 | if (dlci_number != 0 && length_info > 0) { |
891 | | /*Add a subtree (=item) to the child node => in this subtree will be the data*/ |
892 | 8 | tf = proto_tree_add_item(mux27010_tree, hf_mux27010_information, tvb, offset, 1, ENC_BIG_ENDIAN); |
893 | 8 | field_tree = proto_item_add_subtree(tf, ett_mux27010_information); |
894 | | |
895 | | /*We have at least one PPP packet*/ |
896 | 8 | if (sizeMuxPPPHeader > 0){ |
897 | 7 | uint16_t tmpOffset = 1; |
898 | 7 | uint16_t tmpOffsetBegin = 1; |
899 | 7 | uint16_t tmpOffsetEnd = 1; |
900 | | |
901 | 7 | uint16_t msg_seqid; |
902 | 7 | uint16_t msg_num; |
903 | | |
904 | 7 | uint8_t msg_start; |
905 | 7 | uint8_t msg_end; |
906 | 7 | uint8_t msg_flag; |
907 | | |
908 | 7 | fragment_head *frag_msg = NULL; |
909 | 7 | tvbuff_t *new_tvb = NULL; |
910 | 7 | tvbuff_t *next_tvb2 = NULL; |
911 | | |
912 | 7 | int i; |
913 | | |
914 | 105 | for (i = 0; i < sizeMuxPPPHeader/7; i++){ |
915 | | |
916 | 98 | tmpOffset = 7; |
917 | 98 | tmpOffset = (i * tmpOffset)+1; |
918 | | |
919 | 98 | msg_seqid = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2; |
920 | 98 | msg_num = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2; |
921 | 98 | msg_start = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1; |
922 | 98 | msg_end = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1; |
923 | 98 | msg_flag = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1; |
924 | | |
925 | 98 | if (msg_end <= msg_start) { |
926 | 71 | proto_tree_add_expert(field_tree, pinfo, &ei_mux27010_message_illogical, |
927 | 71 | tvb, tmpOffset-3, 2); |
928 | 71 | continue; |
929 | 71 | } |
930 | | |
931 | 27 | tmpOffsetBegin = sizeMuxPPPHeader + 1 + msg_start; /*+ Header_Size, + Direction*/ |
932 | 27 | tmpOffsetEnd = sizeMuxPPPHeader + 1 + msg_end; |
933 | | |
934 | 27 | save_fragmented = pinfo->fragmented; |
935 | 27 | pinfo->fragmented = true; |
936 | | |
937 | 27 | frag_msg = fragment_add_seq_check(&msg_reassembly_table, |
938 | 27 | tvb, tmpOffsetBegin, |
939 | 27 | pinfo, |
940 | 27 | msg_seqid, /* ID for fragments belonging together */ |
941 | 27 | NULL, |
942 | 27 | msg_num, /* fragment sequence number */ |
943 | 27 | (tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length */ |
944 | 27 | msg_flag); /* More fragments? */ |
945 | | |
946 | | |
947 | | |
948 | 27 | new_tvb = process_reassembled_data(tvb, tmpOffsetBegin, pinfo, |
949 | 27 | "Reassembled Message", frag_msg, &msg_frag_items, |
950 | 27 | NULL, mux27010_tree); |
951 | | |
952 | 27 | if (!frag_msg) { /* Not last packet of reassembled Message */ |
953 | 25 | col_append_str(pinfo->cinfo, COL_INFO, " [Split Msg]"); |
954 | 25 | } |
955 | | |
956 | 27 | if (new_tvb) { /* take it all */ |
957 | 2 | next_tvb2 = tvb_new_subset_remaining(new_tvb, 1); |
958 | 2 | call_dissector(ppp_handle, next_tvb2, pinfo, tree); |
959 | 2 | } |
960 | | |
961 | 27 | pinfo->fragmented = save_fragmented; |
962 | 27 | } |
963 | 7 | } |
964 | | |
965 | | /*Get and display information*/ |
966 | 8 | offset += getFrameInformation(tvb, pinfo, field_tree, offset, length_info); |
967 | | |
968 | 8 | } |
969 | | /*~~~~~~~~/Information~~~~~~~~*/ |
970 | | |
971 | | |
972 | | /*~~~~~~~~Checksum~~~~~~~~*/ |
973 | | /*Validate checksum of frame*/ |
974 | | /*Add a subtree (=item) to the child node => in this subtree will be the checksum*/ |
975 | 23 | tf = proto_tree_add_item(mux27010_tree, hf_mux27010_checksum, tvb, offset, 1, ENC_BIG_ENDIAN); |
976 | 23 | field_tree = proto_item_add_subtree(tf, ett_mux27010_checksum); |
977 | | |
978 | | /*Call method check_checksum and validate checksum*/ |
979 | 23 | if (check_fcs(tvb,offset-sizeMuxPPPHeader-3-length_info, sizeMuxPPPHeader+3, tvb_get_uint8(tvb, offset))){ |
980 | | /*Checksum is correct*/ |
981 | 0 | proto_tree_add_boolean(field_tree, hf_mux27010_checksum_correct, tvb, offset, 1, true); |
982 | 0 | } |
983 | 23 | else{ |
984 | | /*Checksum is incorrect*/ |
985 | 23 | expert_add_info(pinfo, tf, &ei_mux27010_checksum_incorrect); |
986 | 23 | } |
987 | | /*~~~~~~~~/Checksum~~~~~~~~*/ |
988 | 23 | return tvb_captured_length(tvb); |
989 | 23 | } |
990 | | |
991 | | /*Register the protocol*/ |
992 | | void |
993 | | proto_register_mux27010 (void) |
994 | 15 | { |
995 | | /* A header field is something you can search/filter on. |
996 | | * |
997 | | * Create a structure to register fields. It consists of an |
998 | | * array of hf_register_info structures, each of which are of the format |
999 | | * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}. |
1000 | | */ |
1001 | | |
1002 | 15 | static hf_register_info hf[] = { |
1003 | | |
1004 | | /*Extended MUX header (for PPP)*/ |
1005 | | |
1006 | 15 | {&hf_mux27010_extended_header, |
1007 | 15 | { "Extended Header", "mux27010.ext_header", |
1008 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1009 | | |
1010 | 15 | {&hf_mux27010_extended_header_size, |
1011 | 15 | { "Header Size", "mux27010.ext_header.size", |
1012 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1013 | | |
1014 | 15 | {&hf_mux27010_extended_header_msg_number_I, |
1015 | 15 | { "Message Number I", "mux27010.ext_header.msg_number_I", |
1016 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1017 | | |
1018 | 15 | {&hf_mux27010_extended_header_freq_number_I, |
1019 | 15 | { "Frequenz Number I", "mux27010.ext_header.frequenz_number_I", |
1020 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1021 | | |
1022 | 15 | {&hf_mux27010_extended_header_start_pos_I, |
1023 | 15 | { "Start Position I", "mux27010.ext_header.start_pos_I", |
1024 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1025 | | |
1026 | 15 | {&hf_mux27010_extended_header_start_byte_I, |
1027 | 15 | { "Start Byte I", "mux27010.ext_header.start_byte_I", |
1028 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1029 | | |
1030 | 15 | {&hf_mux27010_extended_header_end_pos_I, |
1031 | 15 | { "End Position I", "mux27010.ext_header.end_pos_I", |
1032 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1033 | | |
1034 | 15 | {&hf_mux27010_extended_header_end_byte_I, |
1035 | 15 | { "End Byte I", "mux27010.ext_header.end_byte_I", |
1036 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1037 | | |
1038 | 15 | {&hf_mux27010_extended_header_flag_ended_I, |
1039 | 15 | { "Flag Ended I", "mux27010.ext_header.flag_ended_I", |
1040 | 15 | FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }}, |
1041 | | |
1042 | 15 | {&hf_mux27010_extended_header_msg_number_II, |
1043 | 15 | { "Message Number II", "mux27010.ext_header.msg_number_II", |
1044 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1045 | | |
1046 | 15 | {&hf_mux27010_extended_header_freq_number_II, |
1047 | 15 | { "Frequenz Number II", "mux27010.ext_header.frequenz_number_II", |
1048 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1049 | | |
1050 | 15 | {&hf_mux27010_extended_header_start_pos_II, |
1051 | 15 | { "Start Position II", "mux27010.ext_header.start_pos_II", |
1052 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1053 | | |
1054 | 15 | {&hf_mux27010_extended_header_start_byte_II, |
1055 | 15 | { "Start Byte II", "mux27010.ext_header.start_byte_II", |
1056 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1057 | | |
1058 | 15 | {&hf_mux27010_extended_header_end_pos_II, |
1059 | 15 | { "End Position II", "mux27010.ext_header.end_pos_II", |
1060 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1061 | | |
1062 | 15 | {&hf_mux27010_extended_header_end_byte_II, |
1063 | 15 | { "End Byte II", "mux27010.ext_header.end_byte_II", |
1064 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1065 | | |
1066 | 15 | {&hf_mux27010_extended_header_flag_ended_II, |
1067 | 15 | { "Flag Ended II", "mux27010.ext_header.flag_ended_II", |
1068 | 15 | FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }}, |
1069 | | |
1070 | 15 | {&hf_mux27010_extended_header_msg_number_III, |
1071 | 15 | { "Message Number III", "mux27010.ext_header.msg_number_III", |
1072 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1073 | | |
1074 | 15 | {&hf_mux27010_extended_header_freq_number_III, |
1075 | 15 | { "Frequenz Number III", "mux27010.ext_header.frequenz_number_III", |
1076 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1077 | | |
1078 | 15 | {&hf_mux27010_extended_header_start_pos_III, |
1079 | 15 | { "Start Position III", "mux27010.ext_header.start_pos_III", |
1080 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1081 | | |
1082 | 15 | {&hf_mux27010_extended_header_start_byte_III, |
1083 | 15 | { "Start Byte III", "mux27010.ext_header.start_byte_III", |
1084 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1085 | | |
1086 | 15 | {&hf_mux27010_extended_header_end_pos_III, |
1087 | 15 | { "End Position III", "mux27010.ext_header.end_pos_III", |
1088 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1089 | | |
1090 | 15 | {&hf_mux27010_extended_header_end_byte_III, |
1091 | 15 | { "End Byte III", "mux27010.ext_header.end_byte_III", |
1092 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1093 | | |
1094 | 15 | {&hf_mux27010_extended_header_flag_ended_III, |
1095 | 15 | { "Flag Ended III", "mux27010.ext_header.flag_ended_III", |
1096 | 15 | FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }}, |
1097 | | |
1098 | | /*Direction*/ |
1099 | | |
1100 | 15 | {&hf_mux27010_direction, |
1101 | 15 | { "Direction", "mux27010.direction", |
1102 | 15 | FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0, NULL, HFILL }}, |
1103 | | |
1104 | | /*Flag*/ |
1105 | | |
1106 | 15 | {&hf_mux27010, |
1107 | 15 | { "Flag", "mux27010.flag", |
1108 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1109 | | |
1110 | | /*Address frame*/ |
1111 | | |
1112 | 15 | { &hf_mux27010_address, |
1113 | 15 | { "Address field", "mux27010.address", |
1114 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }}, |
1115 | | |
1116 | 15 | { &hf_mux27010_dlciaddressflag, |
1117 | 15 | { "DLCI number (decimal)", "mux27010.address.dlciaddress", |
1118 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_DLCI_ADDRESS_FLAG, NULL, HFILL }}, |
1119 | | |
1120 | 15 | { &hf_mux27010_eaaddressflag, |
1121 | 15 | { "EA Address Flag", "mux27010.address.eaaddress", |
1122 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_EA_ADDRESS_FLAG, NULL, HFILL }}, |
1123 | | |
1124 | 15 | { &hf_mux27010_craddressflag, |
1125 | 15 | { "C/R Address Flag", "mux27010.address.craddress", |
1126 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_CR_ADDRESS_FLAG, NULL, HFILL }}, |
1127 | | |
1128 | | #if 0 |
1129 | | { &hf_mux27010_addressdirection, |
1130 | | { "Direction", "mux27010.address.direction", |
1131 | | FT_UINT8, BASE_HEX, NULL, MUX27010_CR_ADDRESS_FLAG, NULL, HFILL }}, |
1132 | | #endif |
1133 | | |
1134 | | /*Control frame*/ |
1135 | | |
1136 | 15 | { &hf_mux27010_control, |
1137 | 15 | { "Control field", "mux27010.control", |
1138 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }}, |
1139 | | |
1140 | 15 | { &hf_mux27010_controlframetype, |
1141 | 15 | { "Frame Type", "mux27010.control.frametype", |
1142 | 15 | FT_UINT8, BASE_HEX, VALS(frame_type_vals), MUX27010_FRAMETYPE_CONTROL_FLAG, NULL, HFILL }}, |
1143 | | |
1144 | 15 | { &hf_mux27010_controlframetypens, |
1145 | 15 | { "N(S) Sequence Number", "mux27010.control.frametype.ns", |
1146 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NS, NULL, HFILL }}, |
1147 | | |
1148 | 15 | { &hf_mux27010_controlframetypenr, |
1149 | 15 | { "N(R) Receive Number", "mux27010.control.frametype.nr", |
1150 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NR, NULL, HFILL }}, |
1151 | | |
1152 | 15 | { &hf_mux27010_pfcontrolflag, |
1153 | 15 | { "Poll/Final bit", "mux27010.control.pfcontrol", |
1154 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_PF_CONTROL_FLAG, NULL, HFILL }}, |
1155 | | |
1156 | | /*Length frame*/ |
1157 | | |
1158 | 15 | { &hf_mux27010_length, |
1159 | 15 | { "Length field", "mux27010.length", |
1160 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1161 | | |
1162 | 15 | { &hf_mux27010_ealengthflag, |
1163 | 15 | { "E/A Flag", "mux27010.length.ealength", |
1164 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_EA_LENGTH_FLAG, NULL, HFILL }}, |
1165 | | |
1166 | 15 | { &hf_mux27010_lengthframesize_ea, |
1167 | 15 | { "Info length", "mux27010.length.framesize_ea", |
1168 | 15 | FT_UINT16, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG_EA, NULL, HFILL }}, |
1169 | | |
1170 | | |
1171 | 15 | { &hf_mux27010_lengthframesize, |
1172 | 15 | { "Info length", "mux27010.length.framesize", |
1173 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG, NULL, HFILL }}, |
1174 | | |
1175 | | /*Control Channel DLCI = 0*/ |
1176 | | |
1177 | 15 | { &hf_mux27010_controlchannel, |
1178 | 15 | { "Control Channel", "mux27010.controlchannel", |
1179 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1180 | | |
1181 | | /*Frame Type*/ |
1182 | | |
1183 | 15 | { &hf_mux27010_controlchannelframetype, |
1184 | 15 | { "Frame Type", "mux27010.controlchannel.frametype", |
1185 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1186 | | |
1187 | 15 | { &hf_mux27010_controlchanneleaframetype, |
1188 | 15 | { "EA Flag", "mux27010.controlchannel.frametype.eatype", |
1189 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }}, |
1190 | | |
1191 | 15 | { &hf_mux27010_controlchannelcrframetype, |
1192 | 15 | { "C/R Flag", "mux27010.controlchannel.frametype.crtype", |
1193 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }}, |
1194 | | |
1195 | 15 | { &hf_mux27010_controlchannelframetypecommand, |
1196 | 15 | { "Command Type", "mux27010.controlchannel.frametype.command", |
1197 | 15 | FT_UINT8, BASE_HEX, VALS(command_vals), MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }}, |
1198 | | |
1199 | | /*Length*/ |
1200 | | |
1201 | 15 | { &hf_mux27010_controlchannellength, |
1202 | 15 | { "Length", "mux27010.controlchannel.length", |
1203 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1204 | | |
1205 | 15 | { &hf_mux27010_controlchannelealength, |
1206 | 15 | { "EA Flag", "mux27010.controlchannel.length.ealength", |
1207 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }}, |
1208 | | |
1209 | 15 | { &hf_mux27010_controlchannellengthfield, |
1210 | 15 | { "Length field", "mux27010.controlchannel.length.length", |
1211 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }}, |
1212 | | |
1213 | | /*Value*/ |
1214 | | |
1215 | 15 | { &hf_mux27010_controlchannelvalue, |
1216 | 15 | { "Value (ASCII)", "mux27010.controlchannel.value", |
1217 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
1218 | | |
1219 | 15 | { &hf_mux27010_controlchannel_iei_coding, |
1220 | 15 | { "IEI coding", "mux27010.controlchannel.value.iei_coding", |
1221 | 15 | FT_UINT8, BASE_HEX, VALS(iei_coding_vals), 0x0, NULL, HFILL }}, |
1222 | | |
1223 | 15 | { &hf_mux27010_controlchanneldetailedvalue, |
1224 | 15 | { "Detailed Values", "mux27010.controlchannel.value.detailedvalues", |
1225 | 15 | FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }}, |
1226 | | |
1227 | 15 | { &hf_mux27010_controlchannel_detailedvalue_response, |
1228 | 15 | { "Response", "mux27010.controlchannel.value.detailedvalue.response", |
1229 | 15 | FT_UINT8, BASE_DEC, VALS(detailedvalue_response_vals), 0, NULL, HFILL }}, |
1230 | | |
1231 | | /*Test Command*/ |
1232 | | |
1233 | 15 | { &hf_mux27010_controlchanneldetailedvaluetestcommandversion, |
1234 | 15 | { "Version", "mux27010.controlchannel.value.detailedvaluetestcommandversion", |
1235 | 15 | FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION, NULL, HFILL }}, |
1236 | | |
1237 | | /*Modem Status Command*/ |
1238 | | |
1239 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscdlci, |
1240 | 15 | { "DLCI number (decimal)", "mux27010.controlchannel.value.detailedvaluemscdlci", |
1241 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI, NULL, HFILL }}, |
1242 | | |
1243 | | #if 0 |
1244 | | { &hf_mux27010_controlchanneldetailedvaluemscv24, |
1245 | | { "V.24 Signal", "mux27010.controlchannel.value.detailedvaluemscv24", |
1246 | | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1247 | | #endif |
1248 | | |
1249 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscv24fc, |
1250 | 15 | { "FC", "mux27010.controlchannel.value.detailedvaluemscv24.fc", |
1251 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC, NULL, HFILL }}, |
1252 | | |
1253 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscv24rtc, |
1254 | 15 | { "RTC", "mux27010.controlchannel.value.detailedvaluemscv24.rtc", |
1255 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC, NULL, HFILL }}, |
1256 | | |
1257 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscv24rtr, |
1258 | 15 | { "RTR", "mux27010.controlchannel.value.detailedvaluemscv24.rtr", |
1259 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR, NULL, HFILL }}, |
1260 | | |
1261 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscv24ring, |
1262 | 15 | { "RING", "mux27010.controlchannel.value.detailedvaluemscv24.ring", |
1263 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING, NULL, HFILL }}, |
1264 | | |
1265 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscv24dcd, |
1266 | 15 | { "DCD", "mux27010.controlchannel.value.detailedvaluemscv24.dcd", |
1267 | 15 | FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD, NULL, HFILL }}, |
1268 | | |
1269 | 15 | { &hf_mux27010_controlchanneldetailedvaluemscbreak, |
1270 | 15 | { "Break Signal", "mux27010.controlchannel.value.detailedvaluemscbreak", |
1271 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1272 | | |
1273 | | /*Parameter Negotiation*/ |
1274 | | |
1275 | 15 | { &hf_mux27010_controlchanneldetailedvaluepndlci, |
1276 | 15 | { "DLCI", "mux27010.controlchannel.value.detailedvaluepndlci", |
1277 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI, NULL, HFILL }}, |
1278 | | |
1279 | 15 | { &hf_mux27010_controlchanneldetailedvaluepnframetype, |
1280 | 15 | { "Frame Type", "mux27010.controlchannel.value.detailedvaluepnframetype", |
1281 | 15 | FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE, NULL, HFILL }}, |
1282 | | |
1283 | 15 | { &hf_mux27010_controlchanneldetailedvaluepncl, |
1284 | 15 | { "Convergence Layer", "mux27010.controlchannel.value.detailedvaluepncl", |
1285 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_CL, NULL, HFILL }}, |
1286 | | |
1287 | 15 | { &hf_mux27010_controlchanneldetailedvaluepnprio, |
1288 | 15 | { "Priority", "mux27010.controlchannel.value.detailedvaluepnprio", |
1289 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO, NULL, HFILL }}, |
1290 | | |
1291 | 15 | { &hf_mux27010_controlchanneldetailedvaluepntimer, |
1292 | 15 | { "Acknowledgment Timer (ms)", "mux27010.controlchannel.value.detailedvaluepntimer", |
1293 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1294 | | |
1295 | 15 | { &hf_mux27010_controlchanneldetailedvaluepnframesize, |
1296 | 15 | { "Max. Frame Size", "mux27010.controlchannel.value.detailedvaluepnframesize", |
1297 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1298 | | |
1299 | 15 | { &hf_mux27010_controlchanneldetailedvaluepnna, |
1300 | 15 | { "Max. Number of Retransmissions", "mux27010.controlchannel.value.detailedvaluepnna", |
1301 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
1302 | | |
1303 | 15 | { &hf_mux27010_controlchanneldetailedvaluepnwinsize, |
1304 | 15 | { "Window Size for Error Recovery Mode", "mux27010.controlchannel.value.detailedvaluepnwinsize", |
1305 | 15 | FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE, NULL, HFILL }}, |
1306 | | |
1307 | | /*Information frame*/ |
1308 | | |
1309 | 15 | { &hf_mux27010_information, |
1310 | 15 | { "Information field", "mux27010.information", |
1311 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1312 | | |
1313 | 15 | { &hf_mux27010_information_str, |
1314 | 15 | { "Information", "mux27010.information_str", |
1315 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
1316 | | |
1317 | | /*Checksum frame*/ |
1318 | | |
1319 | 15 | { &hf_mux27010_checksum, |
1320 | 15 | { "Checksum", "mux27010.checksum", |
1321 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
1322 | | |
1323 | 15 | { &hf_mux27010_checksum_correct, |
1324 | 15 | { "Correct", "mux27010.checksum_correct", |
1325 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
1326 | | |
1327 | 15 | {&hf_msg_fragments, |
1328 | 15 | {"Message fragments", "mux27010.fragments", |
1329 | 15 | FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1330 | | |
1331 | 15 | {&hf_msg_fragment, |
1332 | 15 | {"Message fragment", "mux27010.fragment", |
1333 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1334 | | |
1335 | 15 | {&hf_msg_fragment_overlap, |
1336 | 15 | {"Message fragment overlap", "mux27010.fragment.overlap", |
1337 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1338 | | |
1339 | 15 | {&hf_msg_fragment_overlap_conflicts, |
1340 | 15 | {"Message fragment overlapping with conflicting data", |
1341 | 15 | "mux27010.fragment.overlap.conflicts", |
1342 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1343 | | |
1344 | 15 | {&hf_msg_fragment_multiple_tails, |
1345 | 15 | {"Message has multiple tail fragments", |
1346 | 15 | "mux27010.fragment.multiple_tails", |
1347 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1348 | | |
1349 | 15 | {&hf_msg_fragment_too_long_fragment, |
1350 | 15 | {"Message fragment too long", "mux27010.fragment.too_long_fragment", |
1351 | 15 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1352 | | |
1353 | 15 | {&hf_msg_fragment_error, |
1354 | 15 | {"Message defragmentation error", "mux27010.fragment.error", |
1355 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1356 | | |
1357 | 15 | {&hf_msg_fragment_count, |
1358 | 15 | {"Message fragment count", "mux27010.fragment.count", |
1359 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
1360 | | |
1361 | 15 | {&hf_msg_reassembled_in, |
1362 | 15 | {"Reassembled in", "mux27010.reassembled.in", |
1363 | 15 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
1364 | | |
1365 | 15 | {&hf_msg_reassembled_length, |
1366 | 15 | {"Reassembled length", "mux27010.reassembled.length", |
1367 | 15 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
1368 | 15 | }; |
1369 | | |
1370 | | |
1371 | | /* Setup protocol subtree array */ |
1372 | 15 | static int *ett[] = { |
1373 | 15 | &ett_mux27010_extended_header, |
1374 | 15 | &ett_mux27010, |
1375 | 15 | &ett_mux27010_address, |
1376 | 15 | &ett_mux27010_control, |
1377 | 15 | &ett_mux27010_length, |
1378 | 15 | &ett_mux27010_controlchannel, |
1379 | 15 | &ett_mux27010_controlchannelframetype, |
1380 | 15 | &ett_mux27010_controlchannellength, |
1381 | 15 | &ett_mux27010_controlchannelvalue, |
1382 | 15 | &ett_mux27010_information, |
1383 | 15 | &ett_mux27010_checksum, |
1384 | 15 | &ett_msg_fragment, |
1385 | 15 | &ett_msg_fragments |
1386 | 15 | }; |
1387 | | |
1388 | 15 | static ei_register_info ei[] = { |
1389 | 15 | { &ei_mux27010_message_illogical, { "mux27010.message_illogical", PI_MALFORMED, PI_ERROR, "Message start and end are illogical, aborting dissection", EXPFILL }}, |
1390 | 15 | { &ei_mux27010_checksum_incorrect, { "mux27010.checksum_incorrect", PI_CHECKSUM, PI_WARN, "Checksum: incorrect", EXPFILL }}, |
1391 | 15 | }; |
1392 | | |
1393 | 15 | expert_module_t* expert_mux27010; |
1394 | | |
1395 | | /*Register protocol*/ |
1396 | 15 | proto_mux27010 = proto_register_protocol ("MUX27010 Protocol", "MUX27010", "mux27010"); |
1397 | | |
1398 | | /*Register arrays*/ |
1399 | 15 | proto_register_field_array (proto_mux27010, hf, array_length (hf)); |
1400 | 15 | proto_register_subtree_array (ett, array_length (ett)); |
1401 | | |
1402 | 15 | mux27010_handle = register_dissector("mux27010", dissect_mux27010, proto_mux27010); |
1403 | | |
1404 | 15 | expert_mux27010 = expert_register_protocol(proto_mux27010); |
1405 | 15 | expert_register_field_array(expert_mux27010, ei, array_length(ei)); |
1406 | | |
1407 | 15 | reassembly_table_register(&msg_reassembly_table, |
1408 | 15 | &addresses_reassembly_table_functions); |
1409 | 15 | } |
1410 | | |
1411 | | /*Initialize dissector*/ |
1412 | | void |
1413 | | proto_reg_handoff_mux27010(void) |
1414 | 15 | { |
1415 | | /*Initialization of dissector*/ |
1416 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_MUX27010, mux27010_handle); |
1417 | | |
1418 | 15 | ppp_handle = find_dissector_add_dependency("ppp", proto_mux27010); |
1419 | | |
1420 | 15 | } |
1421 | | |
1422 | | /* |
1423 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1424 | | * |
1425 | | * Local variables: |
1426 | | * c-basic-offset: 4 |
1427 | | * tab-width: 8 |
1428 | | * indent-tabs-mode: nil |
1429 | | * End: |
1430 | | * |
1431 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1432 | | * :indentSize=4:tabSize=8:noTabs=true: |
1433 | | */ |