Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-xcsl.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-xcsl.c
2
 *
3
 * Routines for the Xcsl dissection (Call Specification Language)
4
 *
5
 * Copyright 2008, Dick Gooris (gooris@alcatel-lucent.com)
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
#include "config.h"
14
15
#include <stdlib.h>
16
17
#include <epan/packet.h>
18
19
#include <wsutil/strtoi.h>
20
21
/* string array size */
22
#define MAXLEN 4096
23
24
void proto_register_xcsl(void);
25
void proto_reg_handoff_xcsl(void);
26
27
static int proto_xcsl;
28
29
static int hf_xcsl_command;
30
static int hf_xcsl_information;
31
static int hf_xcsl_parameter;
32
static int hf_xcsl_protocol_version;
33
static int hf_xcsl_result;
34
static int hf_xcsl_transaction_id;
35
36
/* Initialize the subtree pointers */
37
static int ett_xcsl;
38
39
/* Xcsl result codes */
40
#define XCSL_SUCCESS      0
41
#define XCSL_UNKNOWN      1
42
#define XCSL_USRUNKN      2
43
#define XCSL_ERROR        3
44
#define XCSL_BUSY         4
45
1
#define XCSL_UNDEFINED    5
46
#define XCSL_MORE         6
47
#define XCSL_MAINT        7
48
#define XCSL_PROTSEQERR   8
49
1
#define XCSL_NONE         9
50
51
/* Result code meanings. */
52
static const value_string xcsl_action_vals[] = {
53
    { XCSL_SUCCESS,    "Success" },
54
    { XCSL_UNKNOWN,    "Unknown" },
55
    { XCSL_USRUNKN,    "User unknown" },
56
    { XCSL_ERROR,      "Error" },
57
    { XCSL_BUSY,       "Busy" },
58
    { XCSL_UNDEFINED,  "Undefined" },
59
    { XCSL_MORE,       "More" },
60
    { XCSL_MAINT,      "Maintenance" },
61
    { XCSL_PROTSEQERR, "Protocol Sequence Error" },
62
    { 0, NULL }
63
};
64
65
/* patterns used for tvb_ws_mempbrk_pattern_uint8 */
66
static ws_mempbrk_pattern pbrk_param_end;
67
68
/* Dissector for xcsl */
69
9
static void dissect_xcsl_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
70
71
9
    unsigned     offset = 0;
72
9
    int          length_remaining;
73
9
    uint8_t      idx;
74
9
    bool         request;
75
9
    uint8_t      par;
76
9
    uint8_t     *str;
77
9
    uint8_t      result;
78
9
    const char *code;
79
9
    unsigned     len;
80
9
    int          next_offset;
81
9
    proto_tree  *xcsl_tree = NULL;
82
83
    /* color support */
84
9
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Xcsl");
85
9
    col_clear(pinfo->cinfo, COL_INFO);
86
87
    /* Create display tree for the xcsl protocol */
88
9
    if (tree) {
89
9
        proto_item  *xcsl_item;
90
9
        xcsl_item = proto_tree_add_item(tree, proto_xcsl, tvb, offset, -1, ENC_NA);
91
9
        xcsl_tree = proto_item_add_subtree(xcsl_item, ett_xcsl);
92
9
    }
93
94
    /* reset idx */
95
9
    idx = 0;
96
97
    /* reset the parameter count */
98
9
    par = 0;
99
100
    /* switch whether it concerns a command or an answer */
101
9
    request = false;
102
103
58
    while ((length_remaining = tvb_reported_length_remaining(tvb, offset)) > 0) {
104
105
        /* get next item */
106
49
        next_offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, length_remaining, &pbrk_param_end, NULL);
107
49
        if (next_offset == -1) {
108
9
            len = length_remaining;
109
9
            next_offset = offset + len;
110
40
        } else {
111
40
            len = next_offset - offset;
112
40
        }
113
114
        /* do not add to the tree when the string is of zero length */
115
49
        if ( len == 0 ) {
116
14
            offset = next_offset + 1;
117
14
            continue;
118
14
        }
119
120
35
        str = tvb_get_string_enc(pinfo->pool, tvb, offset, len, ENC_ASCII);
121
122
        /* Xcsl (Call Specification Language) protocol in brief :
123
         *
124
         * Request :
125
         *
126
         *    <xcsl-version>;<transaction-id>;<command>;[parameter1;parameter2;parameter3;....]
127
         *
128
         * Reply :
129
         *
130
         *    <xcsl-version>;transaction-id;<result>;[answer data;answer data];...
131
         *
132
         * If result is one or more digits, this is determined as a Reply.
133
         *
134
         * Example :
135
         *
136
         * -->      xcsl-1.0;1000;offhook;+31356871234
137
         * <--      xcsl-1.0;1000;0                              <- success
138
         *
139
         * -->      xcsl-1.0;1001;dial;+31356871234;+31356875678
140
         * <--      xcsl-1.0;1001;0                              <- success
141
         *
142
         *
143
         * index :  0        1    2    3            4
144
         *
145
         * Index 2 represents the return code (see the xcsl_action_vals[] definitions)
146
         *
147
         */
148
149
        /* One by one go through each item ';' separated */
150
35
        switch (idx) {
151
152
            /* This is the protocol item */
153
9
            case 0:
154
9
                proto_tree_add_item(xcsl_tree, hf_xcsl_protocol_version, tvb, offset, len, ENC_ASCII);
155
9
                break;
156
157
                /* This should be the transaction ID, if non-digit, it is treated as info */
158
8
            case 1:
159
8
                if ( g_ascii_isdigit(str[0]) ) {
160
0
                    proto_tree_add_item(xcsl_tree, hf_xcsl_transaction_id, tvb, offset, len, ENC_ASCII);
161
8
                } else {
162
8
                    proto_tree_add_item(xcsl_tree, hf_xcsl_information, tvb, offset, len, ENC_ASCII);
163
8
                }
164
8
                col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",str);
165
8
                break;
166
167
                /* Starting with non-digit -> Command, if it starts with a digit -> reply */
168
7
            case 2:
169
7
                if ( g_ascii_isdigit(str[0]) ) {
170
1
                    proto_item *xcsl_item;
171
172
1
                    request = false;
173
1
                    result = XCSL_UNDEFINED;
174
1
                    ws_strtou8(str, NULL, &result);
175
1
                    if ( result >= XCSL_NONE ) {
176
0
                        result = XCSL_UNDEFINED;
177
0
                    }
178
1
                    code = val_to_str(result, xcsl_action_vals, "Unknown: %d");
179
180
                    /* Print result code and description */
181
1
                    xcsl_item = proto_tree_add_item(xcsl_tree, hf_xcsl_result, tvb, offset, len, ENC_ASCII);
182
1
                    proto_item_append_text(xcsl_item, " (%s)", code);
183
184
1
                    if (result != 0)
185
1
                        col_append_fstr(pinfo->cinfo, COL_INFO, "[%s] ", code);
186
187
6
                } else {
188
189
6
                    request = true;
190
6
                    proto_tree_add_item(xcsl_tree, hf_xcsl_command, tvb, offset, len, ENC_ASCII);
191
192
6
                    col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", str);
193
194
6
                }
195
7
                break;
196
197
                /* This is a command parameter */
198
11
            default:
199
11
                proto_tree_add_item(xcsl_tree, hf_xcsl_parameter, tvb, offset, len, ENC_ASCII);
200
201
11
                if ( request == true ) {
202
9
                    col_append_fstr(pinfo->cinfo, COL_INFO, ": %s ",str);
203
9
                } else {
204
2
                    if (par == 0) {
205
1
                        col_append_fstr(pinfo->cinfo, COL_INFO, "reply: %s ",str);
206
1
                    } else {
207
1
                        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s ",str);
208
1
                    }
209
2
                }
210
211
                /* increment the parameter count */
212
11
                par++;
213
214
11
                break;
215
35
        }
216
217
35
        offset = next_offset + 1;
218
35
        idx++;
219
220
35
    }
221
222
223
9
    return;
224
9
}
225
226
227
/* This function determines whether the first 4 octets equals to xcsl and the fifth is an ; or - */
228
2.22k
static bool dissect_xcsl_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
229
230
2.22k
    uint8_t *protocol;
231
232
2.22k
    if (tvb_captured_length (tvb) >= 5) {
233
2.13k
        protocol = tvb_get_string_enc(pinfo->pool, tvb, 0, 5, ENC_ASCII);
234
235
2.13k
        if (strncmp(protocol,"xcsl",4) == 0 && (protocol[4] == ';' || protocol[4] == '-')) {
236
237
            /* Disssect it as being an xcsl message */
238
9
            dissect_xcsl_tcp(tvb, pinfo, tree);
239
240
9
            return true;
241
9
        }
242
2.13k
    }
243
244
2.21k
    return false;
245
2.22k
}
246
247
248
/* register the various xcsl protocol filters */
249
14
void proto_register_xcsl(void) {
250
14
    static hf_register_info hf[] = {
251
14
        { &hf_xcsl_protocol_version,
252
14
            { "Protocol Version", "xcsl.protocol_version",
253
14
              FT_STRING, BASE_NONE, NULL, 0x0,
254
14
              NULL, HFILL }
255
14
        },
256
14
        { &hf_xcsl_transaction_id,
257
14
            { "Transaction ID", "xcsl.transaction_id",
258
14
              FT_STRING, BASE_NONE, NULL, 0x0,
259
14
              NULL, HFILL }
260
14
        },
261
14
        { &hf_xcsl_command,
262
14
            { "Command", "xcsl.command",
263
14
              FT_STRING, BASE_NONE, NULL, 0x0,
264
14
              NULL, HFILL }
265
14
        },
266
14
        { &hf_xcsl_result,
267
14
            { "Result", "xcsl.result",
268
14
              FT_STRING, BASE_NONE, NULL, 0x0,
269
14
              NULL, HFILL }
270
14
        },
271
14
        { &hf_xcsl_information,
272
14
            { "Information", "xcsl.information",
273
14
              FT_STRING, BASE_NONE, NULL, 0x0,
274
14
              NULL, HFILL }
275
14
        },
276
14
        { &hf_xcsl_parameter,
277
14
            { "Parameter", "xcsl.parameter",
278
14
              FT_STRING, BASE_NONE, NULL, 0x0,
279
14
              NULL, HFILL }
280
14
        },
281
14
    };
282
283
    /* Setup protocol subtree array */
284
14
    static int *ett[] = {
285
14
        &ett_xcsl
286
14
    };
287
288
    /* Register the protocol name and description */
289
14
    proto_xcsl = proto_register_protocol("Call Specification Language (Xcsl)", "XCSL", "xcsl");
290
14
    proto_register_field_array(proto_xcsl, hf, array_length(hf));
291
14
    proto_register_subtree_array(ett, array_length(ett));
292
293
    /* compile patterns */
294
14
    ws_mempbrk_compile(&pbrk_param_end, ";\r\n");
295
14
}
296
297
/* In case it concerns TCP, try to match on the xcsl header */
298
14
void proto_reg_handoff_xcsl(void) {
299
14
    heur_dissector_add("tcp", dissect_xcsl_tcp_heur, "XCSL over TCP", "xcsl_tcp", proto_xcsl, HEURISTIC_ENABLE);
300
14
}
301
302
/*
303
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
304
 *
305
 * Local variables:
306
 * c-basic-offset: 4
307
 * tab-width: 8
308
 * indent-tabs-mode: nil
309
 * End:
310
 *
311
 * vi: set shiftwidth=4 tabstop=8 expandtab:
312
 * :indentSize=4:tabSize=8:noTabs=true:
313
 */