epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-mux27010.c
blobbd02e13759d4466c8c3d0944dfa6b93f8048a457
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>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
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.
16 * The assigned DLT value is:
17 * LINKTYPE_MUX27010 236 DLT_MUX27010
19 * A detailed description of the packet structure/LINKTYPE_MUX27010 can be found on:
20 * http://www.tcpdump.org/linktypes/LINKTYPE_MUX27010.html
23 #include "config.h"
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>
31 void proto_register_mux27010(void);
32 void proto_reg_handoff_mux27010(void);
34 #define PROTO_TAG_MUX27010 "MUX27010"
36 /*Extended Header*/
37 #define MUX27010_EXTENDED_HEADER_NOT_ENDED 0x01
39 /*Address flags*/
40 #define MUX27010_DLCI_ADDRESS_FLAG 0xFC
41 #define MUX27010_EA_ADDRESS_FLAG 0x01
42 #define MUX27010_CR_ADDRESS_FLAG 0x02
44 /*Control flags*/
45 #define MUX27010_FRAMETYPE_CONTROL_FLAG 0xEF
46 #define MUX27010_FRAMETYPE_CONTROL_FLAG_SABM 0x2F
47 #define MUX27010_FRAMETYPE_CONTROL_FLAG_UA 0x63
48 #define MUX27010_FRAMETYPE_CONTROL_FLAG_DM 0x0F
49 #define MUX27010_FRAMETYPE_CONTROL_FLAG_DISC 0x43
50 #define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH 0xEF
51 #define MUX27010_PF_CONTROL_FLAG 0x10
52 #define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E 0x00
53 #define MUX27010_FRAMETYPE_CONTROL_FLAG_RR 0x01
54 #define MUX27010_FRAMETYPE_CONTROL_FLAG_RNR 0x05
55 #define MUX27010_FRAMETYPE_CONTROL_FLAG_REJ 0x09
56 #define MUX27010_FRAMETYPE_CONTROL_FLAG_NS 0x0E
57 #define MUX27010_FRAMETYPE_CONTROL_FLAG_NR 0xE0
58 #define MUX27010_FRAMETYPE_CONTROL_FLAG_NOT_GREATER_THEN_7 0x07
61 /*Length*/
62 #define MUX27010_EA_LENGTH_FLAG 0x01
63 #define MUX27010_FRAMESIZE_LENGTH_FLAG 0xFE
64 #define MUX27010_FRAMESIZE_LENGTH_FLAG_EA 0xFFFE
66 /*Control Channel*/
67 #define MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG 0x01
68 #define MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG 0x02
69 #define MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG 0xFC
70 #define MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG 0x01
71 #define MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG 0xFE
72 #define MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION 0xFF
73 #define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE 0x04
74 #define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS 0x08
75 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI 0xFC
76 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC 0x02
77 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC 0x04
78 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR 0x08
79 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING 0x40
80 #define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD 0x80
81 #define MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI 0x3F
82 #define MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE 0x0F
83 #define MUX27010_VALUE_CONTROLCHANNEL_PN_CL 0xF0
84 #define MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO 0x3F
85 #define MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE 0x07
87 /*Command pattern - set C/R bit to 1*/
88 #define MUX27010_COMMAND_MULTIPLEXER_CLOSEDOWN 0xC3 /*11000011*/
89 #define MUX27010_COMMAND_TEST_COMMAND 0x23 /*00100011*/
90 #define MUX27010_COMMAND_POWER_SAVING_CONTROL 0x43 /*01000011*/
91 #define MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE 0x13 /*00010011*/
92 #define MUX27010_COMMAND_MODEM_STATUS_COMMAND 0xE3 /*00010011*/
93 #define MUX27010_COMMAND_PARAMETER_NEGOTIATION 0x83 /*10000011*/
96 /* Wireshark ID of the MUX27010 protocol */
97 static int proto_mux27010;
99 /* Handles of subdissectors */
100 static dissector_handle_t ppp_handle;
102 #if 0
103 static const value_string packettypenames[] = {
104 { 0, "TEXT" },
105 { 1, "SOMETHING_ELSE" },
106 { 0, NULL }
108 #endif
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 }
118 static const value_string detailedvalue_response_vals[] = {
119 { 0, "Failure" },
120 { 1, "Success" },
121 { 0, NULL }
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 }
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 }
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 }
153 /*Control channel*/
154 struct controlchannel_type
156 uint8_t cr;
157 uint8_t command;
158 int number_of_type_frames;
161 struct controlchannel
163 uint8_t length_value;
164 int number_of_length_frames;
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()
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;
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;
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;
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;
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;
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;
269 static expert_field ei_mux27010_message_illogical;
270 static expert_field ei_mux27010_checksum_incorrect;
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;
283 static int ett_msg_fragment;
284 static int ett_msg_fragments;
286 static dissector_handle_t mux27010_handle;
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"
311 static reassembly_table msg_reassembly_table;
315 static int
316 getExtendedHeader(tvbuff_t *tvb, proto_tree *field_tree, int offset, uint8_t* sizeMuxPPPHeader){
317 int i;
319 *sizeMuxPPPHeader = tvb_get_uint8(tvb, offset);
320 proto_tree_add_item(field_tree, hf_mux27010_extended_header_size, tvb, offset, 1, ENC_BIG_ENDIAN);
321 if (*sizeMuxPPPHeader > 0){
322 int tmpOffset = 1;
323 uint16_t tmpStartByte = 0;
324 uint16_t tmpLastByte = 0;
325 for (i=0; i < *sizeMuxPPPHeader/7; i++){
326 switch(i){
327 case(0) :
328 proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
329 tmpOffset+=2;
331 proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
332 tmpOffset+=2;
334 tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
335 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
336 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_I, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
337 tmpOffset+=1;
339 tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
340 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
341 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_I, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
343 tmpOffset+=1;
344 proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
345 if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
346 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 else
348 proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
349 break;
351 case(1) :
352 tmpOffset+=1;
353 proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
354 tmpOffset+=2;
356 proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
357 tmpOffset+=2;
359 tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
360 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
361 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_II, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
362 tmpOffset+=1;
364 tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
365 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
366 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_II, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
368 tmpOffset+=1;
369 proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
370 if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
371 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 else
373 proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
374 break;
376 case(2) :
377 tmpOffset+=1;
378 proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
379 tmpOffset+=2;
381 proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
382 tmpOffset+=2;
384 tmpStartByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
385 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
386 proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_III, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
387 tmpOffset+=1;
389 tmpLastByte = tvb_get_uint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
390 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
391 proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_III, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
393 tmpOffset+=1;
394 proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
395 if ((tvb_get_uint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
396 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 else
398 proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
399 break;
406 return *sizeMuxPPPHeader;
410 /*Get the direction of the actual packet*/
411 static int
412 getFrameDirection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, int offset){
413 uint8_t direction_in_out;
415 /*Direction is coded in the first byte of the frame*/
416 direction_in_out = tvb_get_uint8(tvb, offset);
418 /*If first byte is 0 => Frame source is Application*/
419 /*If first byte is 1 => Frame source is Module*/
420 /*else Error*/
421 proto_tree_add_uint(field_tree, hf_mux27010_direction, tvb, offset, 1, direction_in_out & 3);
422 switch (direction_in_out & 3) {
423 case (0):/*Application >> Module*/
424 col_set_str(pinfo->cinfo, COL_DEF_SRC, "Application DLCI ");
425 col_set_str(pinfo->cinfo, COL_DEF_DST, "Module");
426 break;
427 case (1):/*Module >> Application*/
428 col_set_str(pinfo->cinfo, COL_DEF_SRC, "Module DLCI ");
429 col_set_str(pinfo->cinfo, COL_DEF_DST, "Application");
430 break;
431 default:/*?? >> ??*/
432 col_set_str(pinfo->cinfo, COL_DEF_SRC, "Direction not valid ");
433 col_set_str(pinfo->cinfo, COL_DEF_DST, "Direction not valid ");
434 break;
437 return 1;
442 /*Get the address of the actual frame*/
443 static int
444 getFrameAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree_addr, int offset, uint8_t* dlci_number){
445 uint8_t byte;
447 byte = tvb_get_uint8(tvb, offset);
448 /*Get the DCLI number of the frame >> overwrite other bits (E/A, CR) >> shift*/
449 *dlci_number = (byte & MUX27010_DLCI_ADDRESS_FLAG) >> 2;
451 /*Add text to string for Source column*/
452 col_append_fstr(pinfo->cinfo, COL_DEF_SRC, "%d ", *dlci_number);
454 /*Add items to subtree to display the details*/
455 proto_tree_add_item(field_tree_addr, hf_mux27010_eaaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
456 proto_tree_add_item(field_tree_addr, hf_mux27010_craddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
457 proto_tree_add_item(field_tree_addr, hf_mux27010_dlciaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
459 return 1;
464 /*Get frame data from control field*/
465 static int
466 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 uint8_t known_frame_type = 0;
470 /*Get the type of frame*/
471 *frame_type = tvb_get_uint8(tvb, offset) & MUX27010_FRAMETYPE_CONTROL_FLAG;
473 /*Find out the frame type and write info into column*/
474 switch (*frame_type) {
475 case (MUX27010_FRAMETYPE_CONTROL_FLAG_SABM): /*SABM frame*/
476 case (MUX27010_FRAMETYPE_CONTROL_FLAG_UA): /*UA frame*/
477 case (MUX27010_FRAMETYPE_CONTROL_FLAG_DM): /*DM frame*/
478 case (MUX27010_FRAMETYPE_CONTROL_FLAG_DISC): /*DISC frame*/
479 case (MUX27010_FRAMETYPE_CONTROL_FLAG_UIH): /*UIH frame*/
480 proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type);
481 break;
483 default:
484 /*Got another frame -> probably a UIH_E, RR, RNR or REJ frame from a DLCI channel != 0 ==> Data channel*/
486 /*Check if frame is a UIH_E frame*/
487 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 *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E;
489 /*Add frame type to column*/
490 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 proto_tree_add_item(field_tree, hf_mux27010_controlframetypens, tvb, offset, 1, ENC_BIG_ENDIAN);
493 proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
495 /*Frame type is known*/
496 known_frame_type = 1;
498 /*Check if frame is a RR frame*/
499 if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
500 *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RR;
501 /*Add frame type to column*/
502 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 proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
506 /*Frame type is known*/
507 known_frame_type = 1;
509 if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RNR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
510 *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RNR;
511 /*Add frame type to column*/
512 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 proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
516 /*Frame type is known*/
517 known_frame_type = 1;
519 if ((MUX27010_FRAMETYPE_CONTROL_FLAG_REJ | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
520 *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_REJ;
521 /*Add frame type to column*/
522 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 proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
526 /*Frame type is known*/
527 known_frame_type = 1;
530 /*Unknown frame*/
531 if (known_frame_type == 0) {
532 /*Add frame type to column*/
533 proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type);
537 /*Write information to string for column info*/
538 col_add_fstr(pinfo->cinfo, COL_INFO, "(%s)", val_to_str_const(*frame_type, frame_type_vals, "Unknown"));
540 /*Add Frame type value and PF bit to column*/
541 proto_tree_add_item(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
542 proto_tree_add_item(field_tree, hf_mux27010_pfcontrolflag, tvb, offset, 1, ENC_BIG_ENDIAN);
544 return 1;
550 /*Get frame data from length field*/
551 static int
552 getFrameLength(tvbuff_t *tvb, proto_tree *field_tree, int offset, uint32_t* length_info){
554 /*Get the E/A bit*/
555 uint8_t length_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_LENGTH_FLAG;
556 proto_tree_add_item(field_tree, hf_mux27010_ealengthflag, tvb, offset, 1, ENC_BIG_ENDIAN);
558 /*Get the length of the info field*/
560 /*If E/A = 1 it is the last octet*/
561 if (length_ea == 1) {
563 /*Add the E/A bit and the length value to the subtree*/
564 proto_tree_add_item(field_tree, hf_mux27010_lengthframesize, tvb, offset, 1, ENC_BIG_ENDIAN);
565 *length_info = (tvb_get_uint8(tvb, offset) & MUX27010_FRAMESIZE_LENGTH_FLAG) >> 1; /*Shift because of EA bit*/
566 return 1;
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 proto_tree_add_item_ret_uint(field_tree, hf_mux27010_lengthframesize_ea, tvb, offset, 2, ENC_LITTLE_ENDIAN, length_info);
573 return 2;
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 struct controlchannel_type* cctype){
581 uint8_t controlchannel_type_ea;
583 /*Get the E/A bit*/
584 controlchannel_type_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG;
586 /*Set variable for number of octets for frame type to 0*/
587 cctype->number_of_type_frames = 0;
588 /*If E/A bit = 1, there will be no other frame type octet*/
589 if (controlchannel_type_ea == 1)
590 cctype->number_of_type_frames++;
592 /*If E/A = 0, read all frame type octets*/
593 while (controlchannel_type_ea == 0){
594 cctype->number_of_type_frames++;
595 controlchannel_type_ea = tvb_get_uint8(tvb, offset+cctype->number_of_type_frames) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG;
598 /*Get CR bit*/
599 cctype->cr = (tvb_get_uint8(tvb, offset) & MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG) >> 1;
601 /*Get command info*/
602 cctype->command = tvb_get_uint8(tvb, offset) & MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG;
604 /*Add info to subtree*/
605 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneleaframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
606 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelcrframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
607 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelframetypecommand, tvb, offset, 1, ENC_BIG_ENDIAN);
609 /*Check the control channel frame types and add the name to the subtree Info column*/
610 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(cctype->command>>2, command_vals, "Unknown"));
612 if (cctype->cr == 1) /*Command C/R*/{
613 col_append_str(pinfo->cinfo, COL_INFO, " (Command)");
615 else{ /*Response*/
616 col_append_str(pinfo->cinfo, COL_INFO, " (Response)");
619 return cctype->number_of_type_frames;
623 /*Get length of control channel info field*/
624 static int
625 getControlChannelLength(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset, struct controlchannel* cc) {
626 uint8_t controlchannel_length_ea;
628 /*Get the E/A bit*/
629 controlchannel_length_ea = tvb_get_uint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG;
631 /*Set variable for number of octets for info field to 0*/
632 cc->number_of_length_frames = 0;
633 /*If E/A bit = 1, there will be no other info field length octet*/
634 if (controlchannel_length_ea == 1)
635 cc->number_of_length_frames++;
637 /*If E/A = 0, read all length of info field octets*/
638 while (controlchannel_length_ea == 0){
639 cc->number_of_length_frames++;
640 controlchannel_length_ea = tvb_get_uint8(tvb, offset+cc->number_of_length_frames) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG;
643 /*Get the data from info field*/
644 cc->length_value = (tvb_get_uint8(tvb, offset) & MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG) >> 1;
646 /*Add data to subtree*/
647 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelealength, tvb, offset, 1, ENC_BIG_ENDIAN);
648 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannellengthfield, tvb, offset, 1, ENC_BIG_ENDIAN);
650 return cc->number_of_length_frames;
655 /*Get values of control channel*/
656 static int
657 getControlChannelValues(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset,
658 struct controlchannel* cc, struct controlchannel_type* cctype){
659 uint8_t controlchannel_iei;
660 uint8_t controlchannel_psc;
662 /*Command pattern for Test Command (C/R is set to 1)*/
663 switch (cctype->command | MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG | MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG)
665 case MUX27010_COMMAND_TEST_COMMAND:
666 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluetestcommandversion, tvb, offset, 1, ENC_BIG_ENDIAN);
667 controlchannel_iei = tvb_get_uint8(tvb, offset);
668 if ((controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE) ||
669 (controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS)) {
670 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannel_iei_coding, tvb, offset, 1, ENC_BIG_ENDIAN);
673 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelvalue, tvb, offset+1, cc->length_value-1, ENC_NA|ENC_ASCII);
674 break;
676 /*Command pattern for Power saving control (C/R is set to 1)*/
677 case MUX27010_COMMAND_POWER_SAVING_CONTROL:
678 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN);
679 controlchannel_psc = tvb_get_uint8(tvb, offset);
680 if (cctype->cr == 0 && controlchannel_psc == 0) /*Response Failure*/
681 proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 0);
682 if (cctype->cr == 0 && controlchannel_psc == 1) /*Response Success*/
683 proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 1);
684 break;
686 /*Command pattern for non-supported command response (C/R is set to 1)*/
687 case MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE:
688 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN);
689 break;
691 /*Command pattern for Modem Status Command (C/R is set to 1)*/
692 case MUX27010_COMMAND_MODEM_STATUS_COMMAND:
693 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscdlci, tvb, offset, 1, ENC_BIG_ENDIAN);
695 /*Add bits of Flow Control*/
696 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24fc, tvb, offset+1, 1, ENC_BIG_ENDIAN);
697 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtc, tvb, offset+1, 1, ENC_BIG_ENDIAN);
698 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtr, tvb, offset+1, 1, ENC_BIG_ENDIAN);
699 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24ring, tvb, offset+1, 1, ENC_BIG_ENDIAN);
700 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24dcd, tvb, offset+1, 1, ENC_BIG_ENDIAN);
701 /**/
703 if (cc->length_value == 3) {
704 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscbreak, tvb, offset+2, 1, ENC_BIG_ENDIAN);
706 break;
708 /*Command pattern for Parameter Negotiation (EA + C/R is set to 1)*/
709 case MUX27010_COMMAND_PARAMETER_NEGOTIATION:
710 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepndlci, tvb, offset, 1, ENC_BIG_ENDIAN);
711 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);
712 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepncl, tvb, offset+1, 1, ENC_BIG_ENDIAN);
713 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnprio, tvb, offset+2, 1, ENC_BIG_ENDIAN);
714 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepntimer, tvb, offset+3, 1, ENC_BIG_ENDIAN);
715 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframesize, tvb, offset+4, 2, ENC_BIG_ENDIAN);
716 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnna, tvb, offset+6, 1, ENC_BIG_ENDIAN);
717 proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnwinsize, tvb, offset+7, 1, ENC_BIG_ENDIAN);
718 break;
721 return cc->length_value;
726 /*Get values information field*/
727 static int
728 getFrameInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree,
729 int offset, uint32_t length_info){
731 /*Get the data from information field as string*/
732 char *information_field = tvb_get_string_enc(pinfo->pool, tvb,offset,length_info, ENC_ASCII);
734 /*delete unneeded signs out of info field -> for info column: CR (0x0d) and LF (0x0a)*/
735 information_field = g_strdelimit(information_field, "\r\n", ' ');
737 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", information_field);
739 /*Add info to subtree*/
740 proto_tree_add_string(field_tree, hf_mux27010_information_str, tvb, offset, length_info, information_field);
742 /*Increment offset by the length of chars in info field*/
743 return length_info;
749 static int
750 dissect_mux27010(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
752 proto_item *ti, *tf, *tf_extended_header, *tf_addr, *tf_ctr;
753 proto_tree *mux27010_tree, *field_tree, *field_tree_extended_header, *field_tree_addr, *field_tree_ctr;
754 int offset = 0;
755 uint32_t length_info;
756 bool save_fragmented;
757 /*Address DLCI*/
758 int8_t dlci_number = 0;
759 uint8_t frame_type;
760 /*private MUX frame header (PPP)*/
761 uint8_t sizeMuxPPPHeader;
762 struct controlchannel_type cc_type;
763 struct controlchannel cc;
765 /* Setup columns */
766 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_MUX27010);
767 col_clear(pinfo->cinfo, COL_INFO);
769 /* Set offset to 0 => start to read at the begin of the frame*/
770 offset = 0;
772 ti = proto_tree_add_item(tree, proto_mux27010, tvb, 0, -1, ENC_NA);
773 mux27010_tree = proto_item_add_subtree(ti, ett_mux27010);
775 /*Add a subtree (=item) to the child node => in this subtree the details of extended header will be displayed*/
776 tf_extended_header = proto_tree_add_item(mux27010_tree, hf_mux27010_extended_header, tvb, offset, 1, ENC_BIG_ENDIAN);
777 field_tree_extended_header = proto_item_add_subtree(tf_extended_header, ett_mux27010_extended_header);
779 offset += getExtendedHeader(tvb, field_tree_extended_header, offset, &sizeMuxPPPHeader);
780 offset++;
782 /*Get direction of the frame*/
783 offset += getFrameDirection(tvb, pinfo, mux27010_tree, offset);
785 /*~~~~~~~~Flag~~~~~~~~*/
786 /*(Insert data into the child node)*/
787 /*Create item to show/highlight flag sequence*/
788 proto_tree_add_item(mux27010_tree, hf_mux27010, tvb, offset, 1, ENC_BIG_ENDIAN);
789 offset++;
790 /*~~~~~~~~/Flag~~~~~~~~*/
794 /*~~~~~~~~Address~~~~~~~~*/
795 /*Add a subtree (=item) to the child node => in this subtree the details of address data will be displayed*/
796 tf_addr = proto_tree_add_item(mux27010_tree, hf_mux27010_address, tvb, offset, 1, ENC_BIG_ENDIAN);
797 field_tree_addr = proto_item_add_subtree(tf_addr, ett_mux27010_address);
799 /*Get address data (DLCI, E/A, CR)*/
800 offset += getFrameAddress(tvb, pinfo, field_tree_addr, offset, &dlci_number);
801 /*~~~~~~~~/Address~~~~~~~~*/
805 /*~~~~~~~~Control Data~~~~~~~~*/
806 /*Add a subtree (=item) to the child node => in this subtree the details of control data will be displayed*/
807 tf = proto_tree_add_item(mux27010_tree, hf_mux27010_control, tvb, offset, 1, ENC_BIG_ENDIAN);
808 field_tree = proto_item_add_subtree(tf, ett_mux27010_control);
810 /*Get control data of frame (Frame type)*/
811 offset += getFrameControlData(tvb, pinfo, field_tree, offset, &frame_type);
812 /*~~~~~~~~/Control Data~~~~~~~~*/
817 /*~~~~~~~~Length~~~~~~~~*/
818 /*Set the variable for length of the info field to 0*/
819 length_info = 0;
821 /*Check the frame type because in RR, RNR and REJ are no info and no length fields*/
822 if ((frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RR) && (frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RNR) &&
823 (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 tf = proto_tree_add_item(mux27010_tree, hf_mux27010_length, tvb, offset, 1, ENC_BIG_ENDIAN);
826 field_tree = proto_item_add_subtree(tf, ett_mux27010_length);
828 /*Get frame length data*/
829 offset += getFrameLength(tvb, field_tree, offset, &length_info);
831 /*~~~~~~~~/Length~~~~~~~~*/
835 /*~~~~~~~~Control Channel~~~~~~~~*/
836 /*Control Channel only exists if DLCI = 0*/
837 if (dlci_number == 0) {
839 /*If length field > 0, otherwise the frame has no data*/
840 if (length_info > 0) {
842 /*--------Frame Type--------*/
843 /*Get and display data of frame type*/
845 /*Add a subtree (=item) to the child node => in this subtree the details of control channel will be displayed*/
846 tf = proto_tree_add_item(mux27010_tree, hf_mux27010_controlchannel, tvb, offset, 1, ENC_BIG_ENDIAN);
847 field_tree = proto_item_add_subtree(tf, ett_mux27010_controlchannel);
849 /*Add another subtree to the control channel subtree => in this subtree the details of control channel frame type will be displayed*/
850 tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannelframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
851 field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannelframetype);
853 /*Get data about the type of the frame*/
854 offset += getControlChannelFrameType(tvb, pinfo, field_tree_ctr, offset, &cc_type);
855 proto_item_set_len(tf_ctr, cc_type.number_of_type_frames);
856 /*--------/Frame Type--------*/
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 tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannellength, tvb, offset, 1, ENC_BIG_ENDIAN);
862 field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannellength);
864 /*Get data of length field*/
865 offset += getControlChannelLength(tvb, field_tree_ctr, offset, &cc);
866 proto_item_set_len(tf_ctr, cc.number_of_length_frames);
867 /*--------/Length Field--------*/
870 /*--------Values--------*/
871 /*If frame has data inside the length_value is > 0*/
872 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 field_tree_ctr = proto_tree_add_subtree_format(field_tree, tvb, offset, cc.length_value,
875 ett_mux27010_controlchannelvalue, NULL, "Data: %i Byte(s)", cc.length_value);
877 /*Get data of frame*/
878 offset += getControlChannelValues(tvb, field_tree_ctr, offset, &cc, &cc_type);
879 }/*(controlchannel_length_value > 0)*/
880 /*--------/Values--------*/
882 }/*length_info > 0*/
883 }/*dlci_number == 0*/
888 /*~~~~~~~~Information~~~~~~~~*/
889 /*Display "normal" data/values (not control channel) if exists ==> length_info > 0*/
890 if (dlci_number != 0 && length_info > 0) {
891 /*Add a subtree (=item) to the child node => in this subtree will be the data*/
892 tf = proto_tree_add_item(mux27010_tree, hf_mux27010_information, tvb, offset, 1, ENC_BIG_ENDIAN);
893 field_tree = proto_item_add_subtree(tf, ett_mux27010_information);
895 /*We have at least one PPP packet*/
896 if (sizeMuxPPPHeader > 0){
897 uint16_t tmpOffset = 1;
898 uint16_t tmpOffsetBegin = 1;
899 uint16_t tmpOffsetEnd = 1;
901 uint16_t msg_seqid;
902 uint16_t msg_num;
904 uint8_t msg_start;
905 uint8_t msg_end;
906 uint8_t msg_flag;
908 fragment_head *frag_msg = NULL;
909 tvbuff_t *new_tvb = NULL;
910 tvbuff_t *next_tvb2 = NULL;
912 int i;
914 for (i = 0; i < sizeMuxPPPHeader/7; i++){
916 tmpOffset = 7;
917 tmpOffset = (i * tmpOffset)+1;
919 msg_seqid = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
920 msg_num = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
921 msg_start = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1;
922 msg_end = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1;
923 msg_flag = tvb_get_uint8(tvb, tmpOffset); tmpOffset += 1;
925 if (msg_end <= msg_start) {
926 proto_tree_add_expert(field_tree, pinfo, &ei_mux27010_message_illogical,
927 tvb, tmpOffset-3, 2);
928 continue;
931 tmpOffsetBegin = sizeMuxPPPHeader + 1 + msg_start; /*+ Header_Size, + Direction*/
932 tmpOffsetEnd = sizeMuxPPPHeader + 1 + msg_end;
934 save_fragmented = pinfo->fragmented;
935 pinfo->fragmented = true;
937 frag_msg = fragment_add_seq_check(&msg_reassembly_table,
938 tvb, tmpOffsetBegin,
939 pinfo,
940 msg_seqid, /* ID for fragments belonging together */
941 NULL,
942 msg_num, /* fragment sequence number */
943 (tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length */
944 msg_flag); /* More fragments? */
948 new_tvb = process_reassembled_data(tvb, tmpOffsetBegin, pinfo,
949 "Reassembled Message", frag_msg, &msg_frag_items,
950 NULL, mux27010_tree);
952 if (!frag_msg) { /* Not last packet of reassembled Message */
953 col_append_str(pinfo->cinfo, COL_INFO, " [Split Msg]");
956 if (new_tvb) { /* take it all */
957 next_tvb2 = tvb_new_subset_remaining(new_tvb, 1);
958 call_dissector(ppp_handle, next_tvb2, pinfo, tree);
961 pinfo->fragmented = save_fragmented;
965 /*Get and display information*/
966 offset += getFrameInformation(tvb, pinfo, field_tree, offset, length_info);
969 /*~~~~~~~~/Information~~~~~~~~*/
972 /*~~~~~~~~Checksum~~~~~~~~*/
973 /*Validate checksum of frame*/
974 /*Add a subtree (=item) to the child node => in this subtree will be the checksum*/
975 tf = proto_tree_add_item(mux27010_tree, hf_mux27010_checksum, tvb, offset, 1, ENC_BIG_ENDIAN);
976 field_tree = proto_item_add_subtree(tf, ett_mux27010_checksum);
978 /*Call method check_checksum and validate checksum*/
979 if (check_fcs(tvb,offset-sizeMuxPPPHeader-3-length_info, sizeMuxPPPHeader+3, tvb_get_uint8(tvb, offset))){
980 /*Checksum is correct*/
981 proto_tree_add_boolean(field_tree, hf_mux27010_checksum_correct, tvb, offset, 1, true);
983 else{
984 /*Checksum is incorrect*/
985 expert_add_info(pinfo, tf, &ei_mux27010_checksum_incorrect);
987 /*~~~~~~~~/Checksum~~~~~~~~*/
988 return tvb_captured_length(tvb);
991 /*Register the protocol*/
992 void
993 proto_register_mux27010 (void)
995 /* A header field is something you can search/filter on.
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}}.
1002 static hf_register_info hf[] = {
1004 /*Extended MUX header (for PPP)*/
1006 {&hf_mux27010_extended_header,
1007 { "Extended Header", "mux27010.ext_header",
1008 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1010 {&hf_mux27010_extended_header_size,
1011 { "Header Size", "mux27010.ext_header.size",
1012 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1014 {&hf_mux27010_extended_header_msg_number_I,
1015 { "Message Number I", "mux27010.ext_header.msg_number_I",
1016 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1018 {&hf_mux27010_extended_header_freq_number_I,
1019 { "Frequenz Number I", "mux27010.ext_header.frequenz_number_I",
1020 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1022 {&hf_mux27010_extended_header_start_pos_I,
1023 { "Start Position I", "mux27010.ext_header.start_pos_I",
1024 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1026 {&hf_mux27010_extended_header_start_byte_I,
1027 { "Start Byte I", "mux27010.ext_header.start_byte_I",
1028 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1030 {&hf_mux27010_extended_header_end_pos_I,
1031 { "End Position I", "mux27010.ext_header.end_pos_I",
1032 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1034 {&hf_mux27010_extended_header_end_byte_I,
1035 { "End Byte I", "mux27010.ext_header.end_byte_I",
1036 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1038 {&hf_mux27010_extended_header_flag_ended_I,
1039 { "Flag Ended I", "mux27010.ext_header.flag_ended_I",
1040 FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
1042 {&hf_mux27010_extended_header_msg_number_II,
1043 { "Message Number II", "mux27010.ext_header.msg_number_II",
1044 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1046 {&hf_mux27010_extended_header_freq_number_II,
1047 { "Frequenz Number II", "mux27010.ext_header.frequenz_number_II",
1048 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1050 {&hf_mux27010_extended_header_start_pos_II,
1051 { "Start Position II", "mux27010.ext_header.start_pos_II",
1052 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1054 {&hf_mux27010_extended_header_start_byte_II,
1055 { "Start Byte II", "mux27010.ext_header.start_byte_II",
1056 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1058 {&hf_mux27010_extended_header_end_pos_II,
1059 { "End Position II", "mux27010.ext_header.end_pos_II",
1060 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1062 {&hf_mux27010_extended_header_end_byte_II,
1063 { "End Byte II", "mux27010.ext_header.end_byte_II",
1064 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1066 {&hf_mux27010_extended_header_flag_ended_II,
1067 { "Flag Ended II", "mux27010.ext_header.flag_ended_II",
1068 FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
1070 {&hf_mux27010_extended_header_msg_number_III,
1071 { "Message Number III", "mux27010.ext_header.msg_number_III",
1072 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1074 {&hf_mux27010_extended_header_freq_number_III,
1075 { "Frequenz Number III", "mux27010.ext_header.frequenz_number_III",
1076 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1078 {&hf_mux27010_extended_header_start_pos_III,
1079 { "Start Position III", "mux27010.ext_header.start_pos_III",
1080 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1082 {&hf_mux27010_extended_header_start_byte_III,
1083 { "Start Byte III", "mux27010.ext_header.start_byte_III",
1084 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1086 {&hf_mux27010_extended_header_end_pos_III,
1087 { "End Position III", "mux27010.ext_header.end_pos_III",
1088 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1090 {&hf_mux27010_extended_header_end_byte_III,
1091 { "End Byte III", "mux27010.ext_header.end_byte_III",
1092 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1094 {&hf_mux27010_extended_header_flag_ended_III,
1095 { "Flag Ended III", "mux27010.ext_header.flag_ended_III",
1096 FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
1098 /*Direction*/
1100 {&hf_mux27010_direction,
1101 { "Direction", "mux27010.direction",
1102 FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0, NULL, HFILL }},
1104 /*Flag*/
1106 {&hf_mux27010,
1107 { "Flag", "mux27010.flag",
1108 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1110 /*Address frame*/
1112 { &hf_mux27010_address,
1113 { "Address field", "mux27010.address",
1114 FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }},
1116 { &hf_mux27010_dlciaddressflag,
1117 { "DLCI number (decimal)", "mux27010.address.dlciaddress",
1118 FT_UINT8, BASE_DEC, NULL, MUX27010_DLCI_ADDRESS_FLAG, NULL, HFILL }},
1120 { &hf_mux27010_eaaddressflag,
1121 { "EA Address Flag", "mux27010.address.eaaddress",
1122 FT_BOOLEAN, 8, NULL, MUX27010_EA_ADDRESS_FLAG, NULL, HFILL }},
1124 { &hf_mux27010_craddressflag,
1125 { "C/R Address Flag", "mux27010.address.craddress",
1126 FT_BOOLEAN, 8, NULL, MUX27010_CR_ADDRESS_FLAG, NULL, HFILL }},
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
1134 /*Control frame*/
1136 { &hf_mux27010_control,
1137 { "Control field", "mux27010.control",
1138 FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }},
1140 { &hf_mux27010_controlframetype,
1141 { "Frame Type", "mux27010.control.frametype",
1142 FT_UINT8, BASE_HEX, VALS(frame_type_vals), MUX27010_FRAMETYPE_CONTROL_FLAG, NULL, HFILL }},
1144 { &hf_mux27010_controlframetypens,
1145 { "N(S) Sequence Number", "mux27010.control.frametype.ns",
1146 FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NS, NULL, HFILL }},
1148 { &hf_mux27010_controlframetypenr,
1149 { "N(R) Receive Number", "mux27010.control.frametype.nr",
1150 FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NR, NULL, HFILL }},
1152 { &hf_mux27010_pfcontrolflag,
1153 { "Poll/Final bit", "mux27010.control.pfcontrol",
1154 FT_UINT8, BASE_DEC, NULL, MUX27010_PF_CONTROL_FLAG, NULL, HFILL }},
1156 /*Length frame*/
1158 { &hf_mux27010_length,
1159 { "Length field", "mux27010.length",
1160 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1162 { &hf_mux27010_ealengthflag,
1163 { "E/A Flag", "mux27010.length.ealength",
1164 FT_BOOLEAN, 8, NULL, MUX27010_EA_LENGTH_FLAG, NULL, HFILL }},
1166 { &hf_mux27010_lengthframesize_ea,
1167 { "Info length", "mux27010.length.framesize_ea",
1168 FT_UINT16, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG_EA, NULL, HFILL }},
1171 { &hf_mux27010_lengthframesize,
1172 { "Info length", "mux27010.length.framesize",
1173 FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG, NULL, HFILL }},
1175 /*Control Channel DLCI = 0*/
1177 { &hf_mux27010_controlchannel,
1178 { "Control Channel", "mux27010.controlchannel",
1179 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1181 /*Frame Type*/
1183 { &hf_mux27010_controlchannelframetype,
1184 { "Frame Type", "mux27010.controlchannel.frametype",
1185 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1187 { &hf_mux27010_controlchanneleaframetype,
1188 { "EA Flag", "mux27010.controlchannel.frametype.eatype",
1189 FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
1191 { &hf_mux27010_controlchannelcrframetype,
1192 { "C/R Flag", "mux27010.controlchannel.frametype.crtype",
1193 FT_BOOLEAN, 8, NULL, MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
1195 { &hf_mux27010_controlchannelframetypecommand,
1196 { "Command Type", "mux27010.controlchannel.frametype.command",
1197 FT_UINT8, BASE_HEX, VALS(command_vals), MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
1199 /*Length*/
1201 { &hf_mux27010_controlchannellength,
1202 { "Length", "mux27010.controlchannel.length",
1203 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1205 { &hf_mux27010_controlchannelealength,
1206 { "EA Flag", "mux27010.controlchannel.length.ealength",
1207 FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }},
1209 { &hf_mux27010_controlchannellengthfield,
1210 { "Length field", "mux27010.controlchannel.length.length",
1211 FT_UINT8, BASE_DEC, NULL, MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }},
1213 /*Value*/
1215 { &hf_mux27010_controlchannelvalue,
1216 { "Value (ASCII)", "mux27010.controlchannel.value",
1217 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1219 { &hf_mux27010_controlchannel_iei_coding,
1220 { "IEI coding", "mux27010.controlchannel.value.iei_coding",
1221 FT_UINT8, BASE_HEX, VALS(iei_coding_vals), 0x0, NULL, HFILL }},
1223 { &hf_mux27010_controlchanneldetailedvalue,
1224 { "Detailed Values", "mux27010.controlchannel.value.detailedvalues",
1225 FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }},
1227 { &hf_mux27010_controlchannel_detailedvalue_response,
1228 { "Response", "mux27010.controlchannel.value.detailedvalue.response",
1229 FT_UINT8, BASE_DEC, VALS(detailedvalue_response_vals), 0, NULL, HFILL }},
1231 /*Test Command*/
1233 { &hf_mux27010_controlchanneldetailedvaluetestcommandversion,
1234 { "Version", "mux27010.controlchannel.value.detailedvaluetestcommandversion",
1235 FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION, NULL, HFILL }},
1237 /*Modem Status Command*/
1239 { &hf_mux27010_controlchanneldetailedvaluemscdlci,
1240 { "DLCI number (decimal)", "mux27010.controlchannel.value.detailedvaluemscdlci",
1241 FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI, NULL, HFILL }},
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
1249 { &hf_mux27010_controlchanneldetailedvaluemscv24fc,
1250 { "FC", "mux27010.controlchannel.value.detailedvaluemscv24.fc",
1251 FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC, NULL, HFILL }},
1253 { &hf_mux27010_controlchanneldetailedvaluemscv24rtc,
1254 { "RTC", "mux27010.controlchannel.value.detailedvaluemscv24.rtc",
1255 FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC, NULL, HFILL }},
1257 { &hf_mux27010_controlchanneldetailedvaluemscv24rtr,
1258 { "RTR", "mux27010.controlchannel.value.detailedvaluemscv24.rtr",
1259 FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR, NULL, HFILL }},
1261 { &hf_mux27010_controlchanneldetailedvaluemscv24ring,
1262 { "RING", "mux27010.controlchannel.value.detailedvaluemscv24.ring",
1263 FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING, NULL, HFILL }},
1265 { &hf_mux27010_controlchanneldetailedvaluemscv24dcd,
1266 { "DCD", "mux27010.controlchannel.value.detailedvaluemscv24.dcd",
1267 FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD, NULL, HFILL }},
1269 { &hf_mux27010_controlchanneldetailedvaluemscbreak,
1270 { "Break Signal", "mux27010.controlchannel.value.detailedvaluemscbreak",
1271 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1273 /*Parameter Negotiation*/
1275 { &hf_mux27010_controlchanneldetailedvaluepndlci,
1276 { "DLCI", "mux27010.controlchannel.value.detailedvaluepndlci",
1277 FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI, NULL, HFILL }},
1279 { &hf_mux27010_controlchanneldetailedvaluepnframetype,
1280 { "Frame Type", "mux27010.controlchannel.value.detailedvaluepnframetype",
1281 FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE, NULL, HFILL }},
1283 { &hf_mux27010_controlchanneldetailedvaluepncl,
1284 { "Convergence Layer", "mux27010.controlchannel.value.detailedvaluepncl",
1285 FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_CL, NULL, HFILL }},
1287 { &hf_mux27010_controlchanneldetailedvaluepnprio,
1288 { "Priority", "mux27010.controlchannel.value.detailedvaluepnprio",
1289 FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO, NULL, HFILL }},
1291 { &hf_mux27010_controlchanneldetailedvaluepntimer,
1292 { "Acknowledgment Timer (ms)", "mux27010.controlchannel.value.detailedvaluepntimer",
1293 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1295 { &hf_mux27010_controlchanneldetailedvaluepnframesize,
1296 { "Max. Frame Size", "mux27010.controlchannel.value.detailedvaluepnframesize",
1297 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1299 { &hf_mux27010_controlchanneldetailedvaluepnna,
1300 { "Max. Number of Retransmissions", "mux27010.controlchannel.value.detailedvaluepnna",
1301 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1303 { &hf_mux27010_controlchanneldetailedvaluepnwinsize,
1304 { "Window Size for Error Recovery Mode", "mux27010.controlchannel.value.detailedvaluepnwinsize",
1305 FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE, NULL, HFILL }},
1307 /*Information frame*/
1309 { &hf_mux27010_information,
1310 { "Information field", "mux27010.information",
1311 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1313 { &hf_mux27010_information_str,
1314 { "Information", "mux27010.information_str",
1315 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1317 /*Checksum frame*/
1319 { &hf_mux27010_checksum,
1320 { "Checksum", "mux27010.checksum",
1321 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1323 { &hf_mux27010_checksum_correct,
1324 { "Correct", "mux27010.checksum_correct",
1325 FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1327 {&hf_msg_fragments,
1328 {"Message fragments", "mux27010.fragments",
1329 FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1331 {&hf_msg_fragment,
1332 {"Message fragment", "mux27010.fragment",
1333 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1335 {&hf_msg_fragment_overlap,
1336 {"Message fragment overlap", "mux27010.fragment.overlap",
1337 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1339 {&hf_msg_fragment_overlap_conflicts,
1340 {"Message fragment overlapping with conflicting data",
1341 "mux27010.fragment.overlap.conflicts",
1342 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1344 {&hf_msg_fragment_multiple_tails,
1345 {"Message has multiple tail fragments",
1346 "mux27010.fragment.multiple_tails",
1347 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1349 {&hf_msg_fragment_too_long_fragment,
1350 {"Message fragment too long", "mux27010.fragment.too_long_fragment",
1351 FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1353 {&hf_msg_fragment_error,
1354 {"Message defragmentation error", "mux27010.fragment.error",
1355 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1357 {&hf_msg_fragment_count,
1358 {"Message fragment count", "mux27010.fragment.count",
1359 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
1361 {&hf_msg_reassembled_in,
1362 {"Reassembled in", "mux27010.reassembled.in",
1363 FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
1365 {&hf_msg_reassembled_length,
1366 {"Reassembled length", "mux27010.reassembled.length",
1367 FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
1371 /* Setup protocol subtree array */
1372 static int *ett[] = {
1373 &ett_mux27010_extended_header,
1374 &ett_mux27010,
1375 &ett_mux27010_address,
1376 &ett_mux27010_control,
1377 &ett_mux27010_length,
1378 &ett_mux27010_controlchannel,
1379 &ett_mux27010_controlchannelframetype,
1380 &ett_mux27010_controlchannellength,
1381 &ett_mux27010_controlchannelvalue,
1382 &ett_mux27010_information,
1383 &ett_mux27010_checksum,
1384 &ett_msg_fragment,
1385 &ett_msg_fragments
1388 static ei_register_info ei[] = {
1389 { &ei_mux27010_message_illogical, { "mux27010.message_illogical", PI_MALFORMED, PI_ERROR, "Message start and end are illogical, aborting dissection", EXPFILL }},
1390 { &ei_mux27010_checksum_incorrect, { "mux27010.checksum_incorrect", PI_CHECKSUM, PI_WARN, "Checksum: incorrect", EXPFILL }},
1393 expert_module_t* expert_mux27010;
1395 /*Register protocol*/
1396 proto_mux27010 = proto_register_protocol ("MUX27010 Protocol", "MUX27010", "mux27010");
1398 /*Register arrays*/
1399 proto_register_field_array (proto_mux27010, hf, array_length (hf));
1400 proto_register_subtree_array (ett, array_length (ett));
1402 mux27010_handle = register_dissector("mux27010", dissect_mux27010, proto_mux27010);
1404 expert_mux27010 = expert_register_protocol(proto_mux27010);
1405 expert_register_field_array(expert_mux27010, ei, array_length(ei));
1407 reassembly_table_register(&msg_reassembly_table,
1408 &addresses_reassembly_table_functions);
1411 /*Initialize dissector*/
1412 void
1413 proto_reg_handoff_mux27010(void)
1415 /*Initialization of dissector*/
1416 dissector_add_uint("wtap_encap", WTAP_ENCAP_MUX27010, mux27010_handle);
1418 ppp_handle = find_dissector_add_dependency("ppp", proto_mux27010);
1423 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1425 * Local variables:
1426 * c-basic-offset: 4
1427 * tab-width: 8
1428 * indent-tabs-mode: nil
1429 * End:
1431 * vi: set shiftwidth=4 tabstop=8 expandtab:
1432 * :indentSize=4:tabSize=8:noTabs=true: