Coverage Report

Created: 2026-07-12 07:10

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