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