summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mux27010.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-mux27010.c')
-rw-r--r--epan/dissectors/packet-mux27010.c1433
1 files changed, 1433 insertions, 0 deletions
diff --git a/epan/dissectors/packet-mux27010.c b/epan/dissectors/packet-mux27010.c
new file mode 100644
index 00000000..2f61a9c1
--- /dev/null
+++ b/epan/dissectors/packet-mux27010.c
@@ -0,0 +1,1433 @@
+/* packet-mux27010.c
+ * Dissects a variant of 3GPP TS 27.010 multiplexing protocol
+ * Copyright 2011, Hans-Christoph Schemmel <hans-christoph.schemmel[AT]cinterion.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * This dissector analyses a multiplexed communication between a GSM modem and the host,
+ * whereby the multiplexing is based upon a variant of the specification 3G TS 27.010.
+ *
+ * The assigned DLT value is:
+ * LINKTYPE_MUX27010 236 DLT_MUX27010
+ *
+ * A detailed description of the packet structure/LINKTYPE_MUX27010 can be found on:
+ * http://www.tcpdump.org/linktypes/LINKTYPE_MUX27010.html
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <wiretap/wtap.h>
+#include <epan/reassemble.h>
+#include <epan/crc8-tvb.h>
+#include <epan/expert.h>
+
+void proto_register_mux27010(void);
+void proto_reg_handoff_mux27010(void);
+
+#define PROTO_TAG_MUX27010 "MUX27010"
+
+/*Extended Header*/
+#define MUX27010_EXTENDED_HEADER_NOT_ENDED 0x01
+
+/*Address flags*/
+#define MUX27010_DLCI_ADDRESS_FLAG 0xFC
+#define MUX27010_EA_ADDRESS_FLAG 0x01
+#define MUX27010_CR_ADDRESS_FLAG 0x02
+
+/*Control flags*/
+#define MUX27010_FRAMETYPE_CONTROL_FLAG 0xEF
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_SABM 0x2F
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_UA 0x63
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_DM 0x0F
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_DISC 0x43
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH 0xEF
+#define MUX27010_PF_CONTROL_FLAG 0x10
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E 0x00
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_RR 0x01
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_RNR 0x05
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_REJ 0x09
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_NS 0x0E
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_NR 0xE0
+#define MUX27010_FRAMETYPE_CONTROL_FLAG_NOT_GREATER_THEN_7 0x07
+
+
+/*Length*/
+#define MUX27010_EA_LENGTH_FLAG 0x01
+#define MUX27010_FRAMESIZE_LENGTH_FLAG 0xFE
+#define MUX27010_FRAMESIZE_LENGTH_FLAG_EA 0xFFFE
+
+/*Control Channel*/
+#define MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG 0x01
+#define MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG 0x02
+#define MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG 0xFC
+#define MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG 0x01
+#define MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG 0xFE
+#define MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION 0xFF
+#define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE 0x04
+#define MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS 0x08
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI 0xFC
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC 0x02
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC 0x04
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR 0x08
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING 0x40
+#define MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD 0x80
+#define MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI 0x3F
+#define MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE 0x0F
+#define MUX27010_VALUE_CONTROLCHANNEL_PN_CL 0xF0
+#define MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO 0x3F
+#define MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE 0x07
+
+/*Command pattern - set C/R bit to 1*/
+#define MUX27010_COMMAND_MULTIPLEXER_CLOSEDOWN 0xC3 /*11000011*/
+#define MUX27010_COMMAND_TEST_COMMAND 0x23 /*00100011*/
+#define MUX27010_COMMAND_POWER_SAVING_CONTROL 0x43 /*01000011*/
+#define MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE 0x13 /*00010011*/
+#define MUX27010_COMMAND_MODEM_STATUS_COMMAND 0xE3 /*00010011*/
+#define MUX27010_COMMAND_PARAMETER_NEGOTIATION 0x83 /*10000011*/
+
+
+/* Wireshark ID of the MUX27010 protocol */
+static int proto_mux27010 = -1;
+
+/* Handles of subdissectors */
+static dissector_handle_t ppp_handle;
+
+#if 0
+static const value_string packettypenames[] = {
+ { 0, "TEXT" },
+ { 1, "SOMETHING_ELSE" },
+ { 0, NULL }
+};
+#endif
+
+static const value_string direction_vals[] = {
+ { 0, "Direction: Application => Module" },
+ { 1, "Module => Application" },
+ { 2, "Not valid" },
+ { 3, "Not valid" },
+ { 0, NULL }
+};
+
+static const value_string detailedvalue_response_vals[] = {
+ { 0, "Failure" },
+ { 1, "Success" },
+ { 0, NULL }
+};
+
+static const value_string frame_type_vals[] = {
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_SABM, "SABM" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_UA, "UA" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_DM, "DM" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_DISC, "DISC" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_UIH, "UIH" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E, "UIH_E" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_RR, "Receive Ready" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_RNR, "Receive Not Ready" },
+ { MUX27010_FRAMETYPE_CONTROL_FLAG_REJ, "Reject" },
+ { 0, NULL }
+};
+
+static const value_string command_vals[] = {
+ { (MUX27010_COMMAND_MULTIPLEXER_CLOSEDOWN>>2), "Multiplexer Close Down" },
+ { (MUX27010_COMMAND_TEST_COMMAND>>2), "Test Command" },
+ { (MUX27010_COMMAND_POWER_SAVING_CONTROL>>2), "Power Saving Control" },
+ { (MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE>>2), "Non-supported Command Response" },
+ { (MUX27010_COMMAND_MODEM_STATUS_COMMAND>>2), "Modem Status Command" },
+ { (MUX27010_COMMAND_PARAMETER_NEGOTIATION>>2), "Parameter Negotiation" },
+ { 0, NULL }
+};
+
+static const value_string iei_coding_vals[] = {
+ { MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE, "TEMUX_VERSION" },
+ { MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS, "MSMUX_VERSION" },
+ { 0, NULL }
+};
+
+/*Control channel*/
+struct controlchannel_type
+{
+ guint8 cr;
+ guint8 command;
+ gint number_of_type_frames;
+};
+
+struct controlchannel
+{
+ guint8 length_value;
+ gint number_of_length_frames;
+};
+
+/* The following hf_* variables are used to hold the Wireshark IDs of
+* the header fields; they are filled out when call
+* proto_register_field_array() in proto_register_mux27010()
+*/
+
+static gint hf_mux27010_extended_header = -1;
+static gint hf_mux27010_direction = -1;
+static gint hf_mux27010 = -1;
+static gint hf_mux27010_address = -1;
+static gint hf_mux27010_control = -1;
+static gint hf_mux27010_length = -1;
+static gint hf_mux27010_controlchannel = -1;
+
+/*Extended Header*/
+static int hf_mux27010_extended_header_size = -1;
+static int hf_mux27010_extended_header_msg_number_I = -1;
+static int hf_mux27010_extended_header_freq_number_I = -1;
+static int hf_mux27010_extended_header_start_pos_I = -1;
+static int hf_mux27010_extended_header_start_byte_I = -1;
+static int hf_mux27010_extended_header_end_pos_I = -1;
+static int hf_mux27010_extended_header_end_byte_I = -1;
+static int hf_mux27010_extended_header_flag_ended_I = -1;
+
+static int hf_mux27010_extended_header_msg_number_II = -1;
+static int hf_mux27010_extended_header_freq_number_II = -1;
+static int hf_mux27010_extended_header_start_pos_II = -1;
+static int hf_mux27010_extended_header_start_byte_II = -1;
+static int hf_mux27010_extended_header_end_pos_II = -1;
+static int hf_mux27010_extended_header_end_byte_II = -1;
+static int hf_mux27010_extended_header_flag_ended_II = -1;
+
+static int hf_mux27010_extended_header_msg_number_III = -1;
+static int hf_mux27010_extended_header_freq_number_III = -1;
+static int hf_mux27010_extended_header_start_pos_III = -1;
+static int hf_mux27010_extended_header_start_byte_III = -1;
+static int hf_mux27010_extended_header_end_pos_III = -1;
+static int hf_mux27010_extended_header_end_byte_III = -1;
+static int hf_mux27010_extended_header_flag_ended_III = -1;
+
+/*Address*/
+static int hf_mux27010_dlciaddressflag = -1;
+static int hf_mux27010_eaaddressflag = -1;
+static int hf_mux27010_craddressflag = -1;
+/* static int hf_mux27010_addressdirection = -1; */
+/*Control*/
+static int hf_mux27010_controlframetype = -1;
+static int hf_mux27010_controlframetypens = -1;
+static int hf_mux27010_controlframetypenr = -1;
+static int hf_mux27010_pfcontrolflag = -1;
+/*Length*/
+static int hf_mux27010_ealengthflag = -1;
+static int hf_mux27010_lengthframesize = -1;
+static int hf_mux27010_lengthframesize_ea = -1;
+/*Control channel dlci = 0*/
+static int hf_mux27010_controlchannelframetype = -1;
+static int hf_mux27010_controlchanneleaframetype = -1;
+static int hf_mux27010_controlchannelcrframetype = -1;
+static int hf_mux27010_controlchannelframetypecommand = -1;
+static int hf_mux27010_controlchannellength = -1;
+static int hf_mux27010_controlchannelealength = -1;
+static int hf_mux27010_controlchannellengthfield = -1;
+static int hf_mux27010_controlchannelvalue = -1;
+static int hf_mux27010_controlchannel_iei_coding = -1;
+static int hf_mux27010_controlchanneldetailedvalue = -1;
+static int hf_mux27010_controlchannel_detailedvalue_response = -1;
+static int hf_mux27010_controlchanneldetailedvaluetestcommandversion = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscdlci = -1;
+/* static int hf_mux27010_controlchanneldetailedvaluemscv24 = -1; */
+static int hf_mux27010_controlchanneldetailedvaluemscv24fc = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscv24rtc = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscv24rtr = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscv24ring = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscv24dcd = -1;
+static int hf_mux27010_controlchanneldetailedvaluemscbreak = -1;
+static int hf_mux27010_controlchanneldetailedvaluepndlci = -1;
+static int hf_mux27010_controlchanneldetailedvaluepnframetype = -1;
+static int hf_mux27010_controlchanneldetailedvaluepncl = -1;
+static int hf_mux27010_controlchanneldetailedvaluepnprio = -1;
+static int hf_mux27010_controlchanneldetailedvaluepntimer = -1;
+static int hf_mux27010_controlchanneldetailedvaluepnframesize = -1;
+static int hf_mux27010_controlchanneldetailedvaluepnna = -1;
+static int hf_mux27010_controlchanneldetailedvaluepnwinsize = -1;
+/*Information*/
+static int hf_mux27010_information = -1;
+static int hf_mux27010_information_str = -1;
+/*Checksum*/
+static int hf_mux27010_checksum = -1;
+static int hf_mux27010_checksum_correct = -1;
+
+/* These are the ids of the subtrees that we may be creating */
+static gint ett_mux27010_extended_header = -1;
+static gint ett_mux27010 = -1;
+static gint ett_mux27010_address = -1;
+static gint ett_mux27010_control = -1;
+static gint ett_mux27010_length = -1;
+static gint ett_mux27010_controlchannel = -1;
+static gint ett_mux27010_controlchannelframetype = -1;
+static gint ett_mux27010_controlchannellength = -1;
+static gint ett_mux27010_controlchannelvalue = -1;
+static gint ett_mux27010_information = -1;
+static gint ett_mux27010_checksum = -1;
+
+static expert_field ei_mux27010_message_illogical = EI_INIT;
+static expert_field ei_mux27010_checksum_incorrect = EI_INIT;
+
+static int hf_msg_fragments = -1;
+static int hf_msg_fragment = -1;
+static int hf_msg_fragment_overlap = -1;
+static int hf_msg_fragment_overlap_conflicts = -1;
+static int hf_msg_fragment_multiple_tails = -1;
+static int hf_msg_fragment_too_long_fragment = -1;
+static int hf_msg_fragment_error = -1;
+static int hf_msg_fragment_count = -1;
+static int hf_msg_reassembled_in = -1;
+static int hf_msg_reassembled_length = -1;
+
+static gint ett_msg_fragment = -1;
+static gint ett_msg_fragments = -1;
+
+static dissector_handle_t mux27010_handle;
+
+static const fragment_items msg_frag_items = {
+ /* Fragment subtrees */
+ &ett_msg_fragment,
+ &ett_msg_fragments,
+ /* Fragment fields */
+ &hf_msg_fragments,
+ &hf_msg_fragment,
+ &hf_msg_fragment_overlap,
+ &hf_msg_fragment_overlap_conflicts,
+ &hf_msg_fragment_multiple_tails,
+ &hf_msg_fragment_too_long_fragment,
+ &hf_msg_fragment_error,
+ &hf_msg_fragment_count,
+ /* Reassembled in field */
+ &hf_msg_reassembled_in,
+ /* Reassembled length field */
+ &hf_msg_reassembled_length,
+ /* Reassembled data field */
+ NULL,
+ /* Tag */
+ "Message fragments"
+ };
+
+static reassembly_table msg_reassembly_table;
+
+
+
+static int
+getExtendedHeader(tvbuff_t *tvb, proto_tree *field_tree, int offset, guint8* sizeMuxPPPHeader){
+ int i;
+
+ *sizeMuxPPPHeader = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_size, tvb, offset, 1, ENC_BIG_ENDIAN);
+ if (*sizeMuxPPPHeader > 0){
+ int tmpOffset = 1;
+ guint16 tmpStartByte = 0;
+ guint16 tmpLastByte = 0;
+ for (i=0; i < *sizeMuxPPPHeader/7; i++){
+ switch(i){
+ case(0) :
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_I, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ tmpStartByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_I, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
+ tmpOffset+=1;
+
+ tmpLastByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_I, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
+
+ tmpOffset+=1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ if ((tvb_get_guint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence");
+ else
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_I, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
+ break;
+
+ case(1) :
+ tmpOffset+=1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_II, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ tmpStartByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_II, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
+ tmpOffset+=1;
+
+ tmpLastByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_II, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
+
+ tmpOffset+=1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ if ((tvb_get_guint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence");
+ else
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_II, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
+ break;
+
+ case(2) :
+ tmpOffset+=1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_msg_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_freq_number_III, tvb, offset+tmpOffset, 2, ENC_BIG_ENDIAN);
+ tmpOffset+=2;
+
+ tmpStartByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_start_byte_III, tvb, tmpStartByte, 1, ENC_BIG_ENDIAN);
+ tmpOffset+=1;
+
+ tmpLastByte = tvb_get_guint8(tvb, tmpOffset) + *sizeMuxPPPHeader + 1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_pos_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_end_byte_III, tvb, tmpLastByte, 1, ENC_BIG_ENDIAN);
+
+ tmpOffset+=1;
+ proto_tree_add_item(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, ENC_BIG_ENDIAN);
+ if ((tvb_get_guint8(tvb, tmpOffset) & MUX27010_EXTENDED_HEADER_NOT_ENDED) == MUX27010_EXTENDED_HEADER_NOT_ENDED)
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, 1, "Not Last Packet in Frequence");
+ else
+ proto_tree_add_uint_format(field_tree, hf_mux27010_extended_header_flag_ended_III, tvb, offset+tmpOffset, 1, 1, "Last Packet in Frequence");
+ break;
+ }
+
+ }
+
+ }
+
+ return *sizeMuxPPPHeader;
+}
+
+
+/*Get the direction of the actual packet*/
+static int
+getFrameDirection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, int offset){
+ guint8 direction_in_out;
+
+ /*Direction is coded in the first byte of the frame*/
+ direction_in_out = tvb_get_guint8(tvb, offset);
+
+ /*If first byte is 0 => Frame source is Application*/
+ /*If first byte is 1 => Frame source is Module*/
+ /*else Error*/
+ proto_tree_add_uint(field_tree, hf_mux27010_direction, tvb, offset, 1, direction_in_out & 3);
+ switch (direction_in_out & 3) {
+ case (0):/*Application >> Module*/
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, "Application DLCI ");
+ col_set_str(pinfo->cinfo, COL_DEF_DST, "Module");
+ break;
+ case (1):/*Module >> Application*/
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, "Module DLCI ");
+ col_set_str(pinfo->cinfo, COL_DEF_DST, "Application");
+ break;
+ default:/*?? >> ??*/
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, "Direction not valid ");
+ col_set_str(pinfo->cinfo, COL_DEF_DST, "Direction not valid ");
+ break;
+ }
+
+ return 1;
+}
+
+
+
+/*Get the address of the actual frame*/
+static int
+getFrameAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree_addr, int offset, guint8* dlci_number){
+ guint8 byte;
+
+ byte = tvb_get_guint8(tvb, offset);
+ /*Get the DCLI number of the frame >> overwrite other bits (E/A, CR) >> shift*/
+ *dlci_number = (byte & MUX27010_DLCI_ADDRESS_FLAG) >> 2;
+
+ /*Add text to string for Source column*/
+ col_append_fstr(pinfo->cinfo, COL_DEF_SRC, "%d ", *dlci_number);
+
+ /*Add items to subtree to display the details*/
+ proto_tree_add_item(field_tree_addr, hf_mux27010_eaaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_addr, hf_mux27010_craddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_addr, hf_mux27010_dlciaddressflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ return 1;
+}
+
+
+
+/*Get frame data from control field*/
+static int
+getFrameControlData(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree, int offset, guint8* frame_type){
+ /*if the frame type is known -> 1 else 0*/
+ guint8 known_frame_type = 0;
+
+ /*Get the type of frame*/
+ *frame_type = tvb_get_guint8(tvb, offset) & MUX27010_FRAMETYPE_CONTROL_FLAG;
+
+ /*Find out the frame type and write info into column*/
+ switch (*frame_type) {
+ case (MUX27010_FRAMETYPE_CONTROL_FLAG_SABM): /*SABM frame*/
+ case (MUX27010_FRAMETYPE_CONTROL_FLAG_UA): /*UA frame*/
+ case (MUX27010_FRAMETYPE_CONTROL_FLAG_DM): /*DM frame*/
+ case (MUX27010_FRAMETYPE_CONTROL_FLAG_DISC): /*DISC frame*/
+ case (MUX27010_FRAMETYPE_CONTROL_FLAG_UIH): /*UIH frame*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type);
+ break;
+
+ default:
+ /*Got another frame -> probably a UIH_E, RR, RNR or REJ frame from a DLCI channel != 0 ==> Data channel*/
+
+ /*Check if frame is a UIH_E frame*/
+ 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)) {
+ *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E;
+ /*Add frame type to column*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_UIH_E);
+ /*Add info about sequence numbers to column*/
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetypens, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Frame type is known*/
+ known_frame_type = 1;
+ }
+ /*Check if frame is a RR frame*/
+ if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
+ *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RR;
+ /*Add frame type to column*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_RR);
+ /*Add info about sequence number to column*/
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Frame type is known*/
+ known_frame_type = 1;
+ }
+ if ((MUX27010_FRAMETYPE_CONTROL_FLAG_RNR | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
+ *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_RNR;
+ /*Add frame type to column*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_RNR);
+ /*Add info about sequence number to column*/
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Frame type is known*/
+ known_frame_type = 1;
+ }
+ if ((MUX27010_FRAMETYPE_CONTROL_FLAG_REJ | MUX27010_FRAMETYPE_CONTROL_FLAG_NR) == (*frame_type | MUX27010_FRAMETYPE_CONTROL_FLAG_NR)) {
+ *frame_type = MUX27010_FRAMETYPE_CONTROL_FLAG_REJ;
+ /*Add frame type to column*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, MUX27010_FRAMETYPE_CONTROL_FLAG_REJ);
+ /*Add info about sequence number to column*/
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetypenr, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Frame type is known*/
+ known_frame_type = 1;
+ }
+
+ /*Unknown frame*/
+ if (known_frame_type == 0) {
+ /*Add frame type to column*/
+ proto_tree_add_uint(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, *frame_type);
+ }
+ }
+
+ /*Write information to string for column info*/
+ col_add_fstr(pinfo->cinfo, COL_INFO, "(%s)", val_to_str_const(*frame_type, frame_type_vals, "Unknown"));
+
+ /*Add Frame type value and PF bit to column*/
+ proto_tree_add_item(field_tree, hf_mux27010_controlframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree, hf_mux27010_pfcontrolflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ return 1;
+}
+
+
+
+
+/*Get frame data from length field*/
+static int
+getFrameLength(tvbuff_t *tvb, proto_tree *field_tree, int offset, guint32* length_info){
+
+ /*Get the E/A bit*/
+ guint8 length_ea = tvb_get_guint8(tvb, offset) & MUX27010_EA_LENGTH_FLAG;
+ proto_tree_add_item(field_tree, hf_mux27010_ealengthflag, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Get the length of the info field*/
+
+ /*If E/A = 1 it is the last octet*/
+ if (length_ea == 1) {
+
+ /*Add the E/A bit and the length value to the subtree*/
+ proto_tree_add_item(field_tree, hf_mux27010_lengthframesize, tvb, offset, 1, ENC_BIG_ENDIAN);
+ *length_info = (tvb_get_guint8(tvb, offset) & MUX27010_FRAMESIZE_LENGTH_FLAG) >> 1; /*Shift because of EA bit*/
+ return 1;
+ }
+
+ /*If E/A = 0 the length of the info field is >127;
+ first octet stores LSB bits, second octet MSB -> LITTLE ENDIAN stuffing*/
+ proto_tree_add_item_ret_uint(field_tree, hf_mux27010_lengthframesize_ea, tvb, offset, 2, ENC_LITTLE_ENDIAN, length_info);
+
+ return 2;
+}
+
+
+/*Get frame type of control channel frame*/
+static int
+getControlChannelFrameType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree_ctr, int offset,
+ struct controlchannel_type* cctype){
+ guint8 controlchannel_type_ea;
+
+ /*Get the E/A bit*/
+ controlchannel_type_ea = tvb_get_guint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG;
+
+ /*Set variable for number of octets for frame type to 0*/
+ cctype->number_of_type_frames = 0;
+ /*If E/A bit = 1, there will be no other frame type octet*/
+ if (controlchannel_type_ea == 1)
+ cctype->number_of_type_frames++;
+
+ /*If E/A = 0, read all frame type octets*/
+ while (controlchannel_type_ea == 0){
+ cctype->number_of_type_frames++;
+ controlchannel_type_ea = tvb_get_guint8(tvb, offset+cctype->number_of_type_frames) & MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG;
+ }
+
+ /*Get CR bit*/
+ cctype->cr = (tvb_get_guint8(tvb, offset) & MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG) >> 1;
+
+ /*Get command info*/
+ cctype->command = tvb_get_guint8(tvb, offset) & MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG;
+
+ /*Add info to subtree*/
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneleaframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelcrframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelframetypecommand, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Check the control channel frame types and add the name to the subtree and strcat the name to the info column*/
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", val_to_str_const(cctype->command>>2, command_vals, "Unknown"));
+
+ if (cctype->cr == 1) /*Command C/R*/{
+ col_append_str(pinfo->cinfo, COL_INFO, " (Command)");
+ }
+ else{ /*Response*/
+ col_append_str(pinfo->cinfo, COL_INFO, " (Response)");
+ }
+
+ return cctype->number_of_type_frames;
+}
+
+
+/*Get length of control channel info field*/
+static int
+getControlChannelLength(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset, struct controlchannel* cc) {
+ guint8 controlchannel_length_ea;
+
+ /*Get the E/A bit*/
+ controlchannel_length_ea = tvb_get_guint8(tvb, offset) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG;
+
+ /*Set variable for number of octets for info field to 0*/
+ cc->number_of_length_frames = 0;
+ /*If E/A bit = 1, there will be no other info field length octet*/
+ if (controlchannel_length_ea == 1)
+ cc->number_of_length_frames++;
+
+ /*If E/A = 0, read all length of info field octets*/
+ while (controlchannel_length_ea == 0){
+ cc->number_of_length_frames++;
+ controlchannel_length_ea = tvb_get_guint8(tvb, offset+cc->number_of_length_frames) & MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG;
+ }
+
+ /*Get the data from info field*/
+ cc->length_value = (tvb_get_guint8(tvb, offset) & MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG) >> 1;
+
+ /*Add data to subtree*/
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelealength, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannellengthfield, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ return cc->number_of_length_frames;
+}
+
+
+
+/*Get values of control channel*/
+static int
+getControlChannelValues(tvbuff_t *tvb, proto_tree *field_tree_ctr, int offset,
+ struct controlchannel* cc, struct controlchannel_type* cctype){
+ guint8 controlchannel_iei;
+ guint8 controlchannel_psc;
+
+ /*Command pattern for Test Command (C/R is set to 1)*/
+ switch (cctype->command | MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG | MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG)
+ {
+ case MUX27010_COMMAND_TEST_COMMAND:
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluetestcommandversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ controlchannel_iei = tvb_get_guint8(tvb, offset);
+ if ((controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_TE) ||
+ (controlchannel_iei == MUX27010_VALUE_CONTROLCHANNEL_TEST_IEI_MS)) {
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannel_iei_coding, tvb, offset, 1, ENC_BIG_ENDIAN);
+ }
+
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchannelvalue, tvb, offset+1, cc->length_value-1, ENC_NA|ENC_ASCII);
+ break;
+
+ /*Command pattern for Power saving control (C/R is set to 1)*/
+ case MUX27010_COMMAND_POWER_SAVING_CONTROL:
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN);
+ controlchannel_psc = tvb_get_guint8(tvb, offset);
+ if (cctype->cr == 0 && controlchannel_psc == 0) /*Response Failure*/
+ proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 0);
+ if (cctype->cr == 0 && controlchannel_psc == 1) /*Response Success*/
+ proto_tree_add_uint(field_tree_ctr, hf_mux27010_controlchannel_detailedvalue_response, tvb, offset, cc->length_value, 1);
+ break;
+
+ /*Command pattern for non-supported command response (C/R is set to 1)*/
+ case MUX27010_COMMAND_NON_SUPPORTED_COMMAND_RESPONSE:
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvalue, tvb, offset, 1, ENC_BIG_ENDIAN);
+ break;
+
+ /*Command pattern for Modem Status Command (C/R is set to 1)*/
+ case MUX27010_COMMAND_MODEM_STATUS_COMMAND:
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscdlci, tvb, offset, 1, ENC_BIG_ENDIAN);
+
+ /*Add bits of Flow Control*/
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24fc, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtc, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24rtr, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24ring, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscv24dcd, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ /**/
+
+ if (cc->length_value == 3) {
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluemscbreak, tvb, offset+2, 1, ENC_BIG_ENDIAN);
+ }
+ break;
+
+ /*Command pattern for Parameter Negotiation (EA + C/R is set to 1)*/
+ case MUX27010_COMMAND_PARAMETER_NEGOTIATION:
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepndlci, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepncl, tvb, offset+1, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnprio, tvb, offset+2, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepntimer, tvb, offset+3, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnframesize, tvb, offset+4, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnna, tvb, offset+6, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(field_tree_ctr, hf_mux27010_controlchanneldetailedvaluepnwinsize, tvb, offset+7, 1, ENC_BIG_ENDIAN);
+ break;
+ }
+
+ return cc->length_value;
+}
+
+
+
+/*Get values information field*/
+static int
+getFrameInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *field_tree,
+ int offset, guint32 length_info){
+
+ /*Get the data from information field as string*/
+ char *information_field = tvb_get_string_enc(pinfo->pool, tvb,offset,length_info, ENC_ASCII);
+
+ /*delete unneeded signs out of info field -> for info column: CR (0x0d) and LF (0x0a)*/
+ information_field = g_strdelimit(information_field, "\r\n", ' ');
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " %s", information_field);
+
+ /*Add info to subtree*/
+ proto_tree_add_string(field_tree, hf_mux27010_information_str, tvb, offset, length_info, information_field);
+
+ /*Increment offset by the length of chars in info field*/
+ return length_info;
+}
+
+
+
+
+static int
+dissect_mux27010(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ proto_item *ti, *tf, *tf_extended_header, *tf_addr, *tf_ctr;
+ proto_tree *mux27010_tree, *field_tree, *field_tree_extended_header, *field_tree_addr, *field_tree_ctr;
+ int offset = 0;
+ guint32 length_info;
+ gboolean save_fragmented;
+ /*Address DLCI*/
+ gint8 dlci_number = 0;
+ guint8 frame_type;
+ /*private MUX frame header (PPP)*/
+ guint8 sizeMuxPPPHeader;
+ struct controlchannel_type cc_type;
+ struct controlchannel cc;
+
+ /* Setup columns */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_MUX27010);
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* Set offset to 0 => start to read at the begin of the frame*/
+ offset = 0;
+
+ ti = proto_tree_add_item(tree, proto_mux27010, tvb, 0, -1, ENC_NA);
+ mux27010_tree = proto_item_add_subtree(ti, ett_mux27010);
+
+ /*Add a subtree (=item) to the child node => in this subtree the details of extended header will be displayed*/
+ tf_extended_header = proto_tree_add_item(mux27010_tree, hf_mux27010_extended_header, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree_extended_header = proto_item_add_subtree(tf_extended_header, ett_mux27010_extended_header);
+
+ offset += getExtendedHeader(tvb, field_tree_extended_header, offset, &sizeMuxPPPHeader);
+ offset++;
+
+ /*Get direction of the frame*/
+ offset += getFrameDirection(tvb, pinfo, mux27010_tree, offset);
+
+ /*~~~~~~~~Flag~~~~~~~~*/
+ /*(Insert data into the child node)*/
+ /*Create item to show/highlight flag sequence*/
+ proto_tree_add_item(mux27010_tree, hf_mux27010, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ /*~~~~~~~~/Flag~~~~~~~~*/
+
+
+
+ /*~~~~~~~~Address~~~~~~~~*/
+ /*Add a subtree (=item) to the child node => in this subtree the details of address data will be displayed*/
+ tf_addr = proto_tree_add_item(mux27010_tree, hf_mux27010_address, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree_addr = proto_item_add_subtree(tf_addr, ett_mux27010_address);
+
+ /*Get address data (DLCI, E/A, CR)*/
+ offset += getFrameAddress(tvb, pinfo, field_tree_addr, offset, &dlci_number);
+ /*~~~~~~~~/Address~~~~~~~~*/
+
+
+
+ /*~~~~~~~~Control Data~~~~~~~~*/
+ /*Add a subtree (=item) to the child node => in this subtree the details of control data will be displayed*/
+ tf = proto_tree_add_item(mux27010_tree, hf_mux27010_control, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(tf, ett_mux27010_control);
+
+ /*Get control data of frame (Frame type)*/
+ offset += getFrameControlData(tvb, pinfo, field_tree, offset, &frame_type);
+ /*~~~~~~~~/Control Data~~~~~~~~*/
+
+
+
+
+ /*~~~~~~~~Length~~~~~~~~*/
+ /*Set the variable for length of the info field to 0*/
+ length_info = 0;
+
+ /*Check the frame type because in RR, RNR and REJ are no info and no length fields*/
+ if ((frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RR) && (frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_RNR) &&
+ (frame_type != MUX27010_FRAMETYPE_CONTROL_FLAG_REJ)){
+ /*Add a subtree (=item) to the child node => in this subtree will be the details of length field*/
+ tf = proto_tree_add_item(mux27010_tree, hf_mux27010_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(tf, ett_mux27010_length);
+
+ /*Get frame length data*/
+ offset += getFrameLength(tvb, field_tree, offset, &length_info);
+ }
+ /*~~~~~~~~/Length~~~~~~~~*/
+
+
+
+ /*~~~~~~~~Control Channel~~~~~~~~*/
+ /*Control Channel only exists if DLCI = 0*/
+ if (dlci_number == 0) {
+
+ /*If length field > 0, otherwise the frame has no data*/
+ if (length_info > 0) {
+
+ /*--------Frame Type--------*/
+ /*Get and display data of frame type*/
+
+ /*Add a subtree (=item) to the child node => in this subtree the details of control channel will be displayed*/
+ tf = proto_tree_add_item(mux27010_tree, hf_mux27010_controlchannel, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(tf, ett_mux27010_controlchannel);
+
+ /*Add another subtree to the control channel subtree => in this subtree the details of control channel frame type will be displayed*/
+ tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannelframetype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannelframetype);
+
+ /*Get data about the type of the frame*/
+ offset += getControlChannelFrameType(tvb, pinfo, field_tree_ctr, offset, &cc_type);
+ proto_item_set_len(tf_ctr, cc_type.number_of_type_frames);
+ /*--------/Frame Type--------*/
+
+
+ /*--------Length Field--------*/
+ /*Add another subtree to the control channel subtree => in this subtree the details of control channel length field will be displayed*/
+ tf_ctr = proto_tree_add_item(field_tree, hf_mux27010_controlchannellength, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree_ctr = proto_item_add_subtree(tf_ctr, ett_mux27010_controlchannellength);
+
+ /*Get data of length field*/
+ offset += getControlChannelLength(tvb, field_tree_ctr, offset, &cc);
+ proto_item_set_len(tf_ctr, cc.number_of_length_frames);
+ /*--------/Length Field--------*/
+
+
+ /*--------Values--------*/
+ /*If frame has data inside the length_value is > 0*/
+ if (cc.length_value > 0) {
+ /*Add another subtree to the control channel subtree => in this subtree the details of control channel values/data will be displayed*/
+ field_tree_ctr = proto_tree_add_subtree_format(field_tree, tvb, offset, cc.length_value,
+ ett_mux27010_controlchannelvalue, NULL, "Data: %i Byte(s)", cc.length_value);
+
+ /*Get data of frame*/
+ offset += getControlChannelValues(tvb, field_tree_ctr, offset, &cc, &cc_type);
+ }/*(controlchannel_length_value > 0)*/
+ /*--------/Values--------*/
+
+ }/*length_info > 0*/
+ }/*dlci_number == 0*/
+
+
+
+
+ /*~~~~~~~~Information~~~~~~~~*/
+ /*Display "normal" data/values (not control channel) if exists ==> length_info > 0*/
+ if (dlci_number != 0 && length_info > 0) {
+ /*Add a subtree (=item) to the child node => in this subtree will be the data*/
+ tf = proto_tree_add_item(mux27010_tree, hf_mux27010_information, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(tf, ett_mux27010_information);
+
+ /*We have at least one PPP packet*/
+ if (sizeMuxPPPHeader > 0){
+ guint16 tmpOffset = 1;
+ guint16 tmpOffsetBegin = 1;
+ guint16 tmpOffsetEnd = 1;
+
+ guint16 msg_seqid;
+ guint16 msg_num;
+
+ guint8 msg_start;
+ guint8 msg_end;
+ guint8 msg_flag;
+
+ fragment_head *frag_msg = NULL;
+ tvbuff_t *new_tvb = NULL;
+ tvbuff_t *next_tvb2 = NULL;
+
+ int i;
+
+ for (i = 0; i < sizeMuxPPPHeader/7; i++){
+
+ tmpOffset = 7;
+ tmpOffset = (i * tmpOffset)+1;
+
+ msg_seqid = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
+ msg_num = tvb_get_ntohs(tvb, tmpOffset); tmpOffset += 2;
+ msg_start = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
+ msg_end = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
+ msg_flag = tvb_get_guint8(tvb, tmpOffset); tmpOffset += 1;
+
+ if (msg_end <= msg_start) {
+ proto_tree_add_expert(field_tree, pinfo, &ei_mux27010_message_illogical,
+ tvb, tmpOffset-3, 2);
+ continue;
+ }
+
+ tmpOffsetBegin = sizeMuxPPPHeader + 1 + msg_start; /*+ Header_Size, + Direction*/
+ tmpOffsetEnd = sizeMuxPPPHeader + 1 + msg_end;
+
+ save_fragmented = pinfo->fragmented;
+ pinfo->fragmented = TRUE;
+
+ frag_msg = fragment_add_seq_check(&msg_reassembly_table,
+ tvb, tmpOffsetBegin,
+ pinfo,
+ msg_seqid, /* ID for fragments belonging together */
+ NULL,
+ msg_num, /* fragment sequence number */
+ (tmpOffsetEnd-tmpOffsetBegin)+1, /* fragment length */
+ msg_flag); /* More fragments? */
+
+
+
+ new_tvb = process_reassembled_data(tvb, tmpOffsetBegin, pinfo,
+ "Reassembled Message", frag_msg, &msg_frag_items,
+ NULL, mux27010_tree);
+
+ if (!frag_msg) { /* Not last packet of reassembled Message */
+ col_append_str(pinfo->cinfo, COL_INFO, " [Split Msg]");
+ }
+
+ if (new_tvb) { /* take it all */
+ next_tvb2 = tvb_new_subset_remaining(new_tvb, 1);
+ call_dissector(ppp_handle, next_tvb2, pinfo, tree);
+ }
+
+ pinfo->fragmented = save_fragmented;
+ }
+ }
+
+ /*Get and display information*/
+ offset += getFrameInformation(tvb, pinfo, field_tree, offset, length_info);
+
+ }
+ /*~~~~~~~~/Information~~~~~~~~*/
+
+
+ /*~~~~~~~~Checksum~~~~~~~~*/
+ /*Validate checksum of frame*/
+ /*Add a subtree (=item) to the child node => in this subtree will be the checksum*/
+ tf = proto_tree_add_item(mux27010_tree, hf_mux27010_checksum, tvb, offset, 1, ENC_BIG_ENDIAN);
+ field_tree = proto_item_add_subtree(tf, ett_mux27010_checksum);
+
+ /*Call method check_checksum and validate checksum*/
+ if (check_fcs(tvb,offset-sizeMuxPPPHeader-3-length_info, sizeMuxPPPHeader+3, tvb_get_guint8(tvb, offset))){
+ /*Checksum is correct*/
+ proto_tree_add_boolean(field_tree, hf_mux27010_checksum_correct, tvb, offset, 1, TRUE);
+ }
+ else{
+ /*Checksum is incorrect*/
+ expert_add_info(pinfo, tf, &ei_mux27010_checksum_incorrect);
+ }
+ /*~~~~~~~~/Checksum~~~~~~~~*/
+ return tvb_captured_length(tvb);
+}
+
+/*Register the protocol*/
+void
+proto_register_mux27010 (void)
+{
+ /* A header field is something you can search/filter on.
+ *
+ * Create a structure to register fields. It consists of an
+ * array of hf_register_info structures, each of which are of the format
+ * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
+ */
+
+ static hf_register_info hf[] = {
+
+ /*Extended MUX header (for PPP)*/
+
+ {&hf_mux27010_extended_header,
+ { "Extended Header", "mux27010.ext_header",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_size,
+ { "Header Size", "mux27010.ext_header.size",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_msg_number_I,
+ { "Message Number I", "mux27010.ext_header.msg_number_I",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_freq_number_I,
+ { "Frequenz Number I", "mux27010.ext_header.frequenz_number_I",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_pos_I,
+ { "Start Position I", "mux27010.ext_header.start_pos_I",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_byte_I,
+ { "Start Byte I", "mux27010.ext_header.start_byte_I",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_pos_I,
+ { "End Position I", "mux27010.ext_header.end_pos_I",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_byte_I,
+ { "End Byte I", "mux27010.ext_header.end_byte_I",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_flag_ended_I,
+ { "Flag Ended I", "mux27010.ext_header.flag_ended_I",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_msg_number_II,
+ { "Message Number II", "mux27010.ext_header.msg_number_II",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_freq_number_II,
+ { "Frequenz Number II", "mux27010.ext_header.frequenz_number_II",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_pos_II,
+ { "Start Position II", "mux27010.ext_header.start_pos_II",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_byte_II,
+ { "Start Byte II", "mux27010.ext_header.start_byte_II",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_pos_II,
+ { "End Position II", "mux27010.ext_header.end_pos_II",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_byte_II,
+ { "End Byte II", "mux27010.ext_header.end_byte_II",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_flag_ended_II,
+ { "Flag Ended II", "mux27010.ext_header.flag_ended_II",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_msg_number_III,
+ { "Message Number III", "mux27010.ext_header.msg_number_III",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_freq_number_III,
+ { "Frequenz Number III", "mux27010.ext_header.frequenz_number_III",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_pos_III,
+ { "Start Position III", "mux27010.ext_header.start_pos_III",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_start_byte_III,
+ { "Start Byte III", "mux27010.ext_header.start_byte_III",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_pos_III,
+ { "End Position III", "mux27010.ext_header.end_pos_III",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_end_byte_III,
+ { "End Byte III", "mux27010.ext_header.end_byte_III",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_mux27010_extended_header_flag_ended_III,
+ { "Flag Ended III", "mux27010.ext_header.flag_ended_III",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_EXTENDED_HEADER_NOT_ENDED, NULL, HFILL }},
+
+ /*Direction*/
+
+ {&hf_mux27010_direction,
+ { "Direction", "mux27010.direction",
+ FT_UINT8, BASE_HEX, VALS(direction_vals), 0x0, NULL, HFILL }},
+
+ /*Flag*/
+
+ {&hf_mux27010,
+ { "Flag", "mux27010.flag",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ /*Address frame*/
+
+ { &hf_mux27010_address,
+ { "Address field", "mux27010.address",
+ FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }},
+
+ { &hf_mux27010_dlciaddressflag,
+ { "DLCI number (decimal)", "mux27010.address.dlciaddress",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_DLCI_ADDRESS_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_eaaddressflag,
+ { "EA Address Flag", "mux27010.address.eaaddress",
+ FT_BOOLEAN, 8, NULL, MUX27010_EA_ADDRESS_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_craddressflag,
+ { "C/R Address Flag", "mux27010.address.craddress",
+ FT_BOOLEAN, 8, NULL, MUX27010_CR_ADDRESS_FLAG, NULL, HFILL }},
+
+#if 0
+ { &hf_mux27010_addressdirection,
+ { "Direction", "mux27010.address.direction",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_CR_ADDRESS_FLAG, NULL, HFILL }},
+#endif
+
+ /*Control frame*/
+
+ { &hf_mux27010_control,
+ { "Control field", "mux27010.control",
+ FT_UINT8, BASE_HEX, NULL, 0x0,NULL, HFILL }},
+
+ { &hf_mux27010_controlframetype,
+ { "Frame Type", "mux27010.control.frametype",
+ FT_UINT8, BASE_HEX, VALS(frame_type_vals), MUX27010_FRAMETYPE_CONTROL_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_controlframetypens,
+ { "N(S) Sequence Number", "mux27010.control.frametype.ns",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NS, NULL, HFILL }},
+
+ { &hf_mux27010_controlframetypenr,
+ { "N(R) Receive Number", "mux27010.control.frametype.nr",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMETYPE_CONTROL_FLAG_NR, NULL, HFILL }},
+
+ { &hf_mux27010_pfcontrolflag,
+ { "Poll/Final bit", "mux27010.control.pfcontrol",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_PF_CONTROL_FLAG, NULL, HFILL }},
+
+ /*Length frame*/
+
+ { &hf_mux27010_length,
+ { "Length field", "mux27010.length",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_ealengthflag,
+ { "E/A Flag", "mux27010.length.ealength",
+ FT_BOOLEAN, 8, NULL, MUX27010_EA_LENGTH_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_lengthframesize_ea,
+ { "Info length", "mux27010.length.framesize_ea",
+ FT_UINT16, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG_EA, NULL, HFILL }},
+
+
+ { &hf_mux27010_lengthframesize,
+ { "Info length", "mux27010.length.framesize",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_FRAMESIZE_LENGTH_FLAG, NULL, HFILL }},
+
+ /*Control Channel DLCI = 0*/
+
+ { &hf_mux27010_controlchannel,
+ { "Control Channel", "mux27010.controlchannel",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ /*Frame Type*/
+
+ { &hf_mux27010_controlchannelframetype,
+ { "Frame Type", "mux27010.controlchannel.frametype",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneleaframetype,
+ { "EA Flag", "mux27010.controlchannel.frametype.eatype",
+ FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannelcrframetype,
+ { "C/R Flag", "mux27010.controlchannel.frametype.crtype",
+ FT_BOOLEAN, 8, NULL, MUX27010_CR_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannelframetypecommand,
+ { "Command Type", "mux27010.controlchannel.frametype.command",
+ FT_UINT8, BASE_HEX, VALS(command_vals), MUX27010_COMMAND_CONTROLCHANNEL_FRAMETYPE_FLAG, NULL, HFILL }},
+
+ /*Length*/
+
+ { &hf_mux27010_controlchannellength,
+ { "Length", "mux27010.controlchannel.length",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannelealength,
+ { "EA Flag", "mux27010.controlchannel.length.ealength",
+ FT_BOOLEAN, 8, NULL, MUX27010_EA_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannellengthfield,
+ { "Length field", "mux27010.controlchannel.length.length",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_LENGTHFIELD_CONTROLCHANNEL_LENGTH_FLAG, NULL, HFILL }},
+
+ /*Value*/
+
+ { &hf_mux27010_controlchannelvalue,
+ { "Value (ASCII)", "mux27010.controlchannel.value",
+ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannel_iei_coding,
+ { "IEI coding", "mux27010.controlchannel.value.iei_coding",
+ FT_UINT8, BASE_HEX, VALS(iei_coding_vals), 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvalue,
+ { "Detailed Values", "mux27010.controlchannel.value.detailedvalues",
+ FT_UINT8, BASE_HEX, NULL, 0xFF, NULL, HFILL }},
+
+ { &hf_mux27010_controlchannel_detailedvalue_response,
+ { "Response", "mux27010.controlchannel.value.detailedvalue.response",
+ FT_UINT8, BASE_DEC, VALS(detailedvalue_response_vals), 0, NULL, HFILL }},
+
+ /*Test Command*/
+
+ { &hf_mux27010_controlchanneldetailedvaluetestcommandversion,
+ { "Version", "mux27010.controlchannel.value.detailedvaluetestcommandversion",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_TEST_VERSION, NULL, HFILL }},
+
+ /*Modem Status Command*/
+
+ { &hf_mux27010_controlchanneldetailedvaluemscdlci,
+ { "DLCI number (decimal)", "mux27010.controlchannel.value.detailedvaluemscdlci",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_DCLI, NULL, HFILL }},
+
+#if 0
+ { &hf_mux27010_controlchanneldetailedvaluemscv24,
+ { "V.24 Signal", "mux27010.controlchannel.value.detailedvaluemscv24",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+#endif
+
+ { &hf_mux27010_controlchanneldetailedvaluemscv24fc,
+ { "FC", "mux27010.controlchannel.value.detailedvaluemscv24.fc",
+ FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_FC, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluemscv24rtc,
+ { "RTC", "mux27010.controlchannel.value.detailedvaluemscv24.rtc",
+ FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTC, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluemscv24rtr,
+ { "RTR", "mux27010.controlchannel.value.detailedvaluemscv24.rtr",
+ FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RTR, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluemscv24ring,
+ { "RING", "mux27010.controlchannel.value.detailedvaluemscv24.ring",
+ FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_RING, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluemscv24dcd,
+ { "DCD", "mux27010.controlchannel.value.detailedvaluemscv24.dcd",
+ FT_BOOLEAN, 8, NULL, MUX27010_VALUE_CONTROLCHANNEL_MSC_V24_DCD, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluemscbreak,
+ { "Break Signal", "mux27010.controlchannel.value.detailedvaluemscbreak",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ /*Parameter Negotiation*/
+
+ { &hf_mux27010_controlchanneldetailedvaluepndlci,
+ { "DLCI", "mux27010.controlchannel.value.detailedvaluepndlci",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_DLCI, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepnframetype,
+ { "Frame Type", "mux27010.controlchannel.value.detailedvaluepnframetype",
+ FT_UINT8, BASE_HEX, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_FRAMETYPE, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepncl,
+ { "Convergence Layer", "mux27010.controlchannel.value.detailedvaluepncl",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_CL, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepnprio,
+ { "Priority", "mux27010.controlchannel.value.detailedvaluepnprio",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_PRIO, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepntimer,
+ { "Acknowledgment Timer (ms)", "mux27010.controlchannel.value.detailedvaluepntimer",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepnframesize,
+ { "Max. Frame Size", "mux27010.controlchannel.value.detailedvaluepnframesize",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepnna,
+ { "Max. Number of Retransmissions", "mux27010.controlchannel.value.detailedvaluepnna",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_controlchanneldetailedvaluepnwinsize,
+ { "Window Size for Error Recovery Mode", "mux27010.controlchannel.value.detailedvaluepnwinsize",
+ FT_UINT8, BASE_DEC, NULL, MUX27010_VALUE_CONTROLCHANNEL_PN_WINSIZE, NULL, HFILL }},
+
+ /*Information frame*/
+
+ { &hf_mux27010_information,
+ { "Information field", "mux27010.information",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_information_str,
+ { "Information", "mux27010.information_str",
+ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ /*Checksum frame*/
+
+ { &hf_mux27010_checksum,
+ { "Checksum", "mux27010.checksum",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+
+ { &hf_mux27010_checksum_correct,
+ { "Correct", "mux27010.checksum_correct",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+
+ {&hf_msg_fragments,
+ {"Message fragments", "mux27010.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment,
+ {"Message fragment", "mux27010.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_overlap,
+ {"Message fragment overlap", "mux27010.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_overlap_conflicts,
+ {"Message fragment overlapping with conflicting data",
+ "mux27010.fragment.overlap.conflicts",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_multiple_tails,
+ {"Message has multiple tail fragments",
+ "mux27010.fragment.multiple_tails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_too_long_fragment,
+ {"Message fragment too long", "mux27010.fragment.too_long_fragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_error,
+ {"Message defragmentation error", "mux27010.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_fragment_count,
+ {"Message fragment count", "mux27010.fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_reassembled_in,
+ {"Reassembled in", "mux27010.reassembled.in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
+ {&hf_msg_reassembled_length,
+ {"Reassembled length", "mux27010.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
+ };
+
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_mux27010_extended_header,
+ &ett_mux27010,
+ &ett_mux27010_address,
+ &ett_mux27010_control,
+ &ett_mux27010_length,
+ &ett_mux27010_controlchannel,
+ &ett_mux27010_controlchannelframetype,
+ &ett_mux27010_controlchannellength,
+ &ett_mux27010_controlchannelvalue,
+ &ett_mux27010_information,
+ &ett_mux27010_checksum,
+ &ett_msg_fragment,
+ &ett_msg_fragments
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_mux27010_message_illogical, { "mux27010.message_illogical", PI_MALFORMED, PI_ERROR, "Message start and end are illogical, aborting dissection", EXPFILL }},
+ { &ei_mux27010_checksum_incorrect, { "mux27010.checksum_incorrect", PI_CHECKSUM, PI_WARN, "Checksum: incorrect", EXPFILL }},
+ };
+
+ expert_module_t* expert_mux27010;
+
+ /*Register protocol*/
+ proto_mux27010 = proto_register_protocol ("MUX27010 Protocol", "MUX27010", "mux27010");
+
+ /*Register arrays*/
+ proto_register_field_array (proto_mux27010, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+
+ mux27010_handle = register_dissector("mux27010", dissect_mux27010, proto_mux27010);
+
+ expert_mux27010 = expert_register_protocol(proto_mux27010);
+ expert_register_field_array(expert_mux27010, ei, array_length(ei));
+
+ reassembly_table_register(&msg_reassembly_table,
+ &addresses_reassembly_table_functions);
+}
+
+/*Initialize dissector*/
+void
+proto_reg_handoff_mux27010(void)
+{
+ /*Initialization of dissector*/
+ dissector_add_uint("wtap_encap", WTAP_ENCAP_MUX27010, mux27010_handle);
+
+ ppp_handle = find_dissector_add_dependency("ppp", proto_mux27010);
+
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */