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