Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-forces.c
Line
Count
Source
1
/* packet-forces.c
2
 * RFC 5810
3
 * Routines for dissecting IETF ForCES protocol layer messages.Now support the following TML types:TCP+UDP,SCTP.
4
 * Copyright 2009, NDSC & Zhejiang Gongshang University,Fenggen Jia <fgjia@mail.zjgsu.edu.cn or fenggen.jia@gmail.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/prefs.h>
17
#include <epan/expert.h>
18
#include <epan/unit_strings.h>
19
20
void proto_register_forces(void);
21
void proto_reg_handoff_forces(void);
22
23
static dissector_handle_t  forces_handle_tcp, forces_handle;
24
25
static dissector_handle_t ip_handle;
26
27
/* Initialize the ForCES protocol and registered fields */
28
static int proto_forces;
29
30
/*Main header*/
31
static int hf_forces_version;
32
static int hf_forces_rsvd;
33
static int hf_forces_messagetype;
34
static int hf_forces_sid;
35
static int hf_forces_did;
36
static int hf_forces_correlator;
37
static int hf_forces_length;
38
/*Flags*/
39
static int hf_forces_flags;
40
static int hf_forces_flags_ack;
41
static int hf_forces_flags_pri;
42
static int hf_forces_flags_rsrvd;
43
static int hf_forces_flags_em;
44
static int hf_forces_flags_at;
45
static int hf_forces_flags_tp;
46
static int hf_forces_flags_reserved;
47
48
static int hf_forces_tlv_type;
49
static int hf_forces_tlv_length;
50
51
/*Initiation of LFBSelect TLV*/
52
static int hf_forces_lfbselect_tlv_type_lfb_classid;
53
static int hf_forces_lfbselect_tlv_type_lfb_instanceid;
54
55
/*Initiation of Operation TLV*/
56
static int hf_forces_lfbselect_tlv_type_operation_type;
57
static int hf_forces_lfbselect_tlv_type_operation_length;
58
static int hf_forces_lfbselect_tlv_type_operation_path_type;
59
static int hf_forces_lfbselect_tlv_type_operation_path_length;
60
static int hf_forces_lfbselect_tlv_type_operation_path_flags;
61
static int hf_forces_lfbselect_tlv_type_operation_path_flags_selector;
62
static int hf_forces_lfbselect_tlv_type_operation_path_flags_reserved;
63
static int hf_forces_lfbselect_tlv_type_operation_path_IDcount;
64
static int hf_forces_lfbselect_tlv_type_operation_path_IDs;
65
static int hf_forces_lfbselect_tlv_type_operation_path_data;
66
67
/*Initiation of Redirect TLV*/
68
static int hf_forces_redirect_tlv_meta_data_tlv_type;
69
static int hf_forces_redirect_tlv_meta_data_tlv_length;
70
static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv;
71
static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id;
72
static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length;
73
static int hf_forces_redirect_tlv_redirect_data_tlv_type;
74
static int hf_forces_redirect_tlv_redirect_data_tlv_length;
75
76
/*Initiation of ASResult TLV*/
77
static int hf_forces_asresult_association_setup_result;
78
79
/*Initiation of ASTreason TLV*/
80
static int hf_forces_astreason_tlv_teardown_reason;
81
82
/*Main TLV may be unknown*/
83
static int hf_forces_unknown_tlv;
84
85
/*Message Types */
86
#define AssociationSetup            0x01
87
#define AssociationTeardown         0x02
88
#define Config                      0x03
89
#define Query                       0x04
90
#define EventNotification           0x05
91
#define PacketRedirect              0x06
92
#define Heartbeat                   0x0F
93
#define AssociationSetupResponse    0x11
94
#define ConfigResponse              0x13
95
#define QueryResponse               0x14
96
97
/*TLV Types*/
98
#define Reserved            0x0000
99
0
#define REDIRECT_TLV        0x0001
100
0
#define ASResult_TLV        0x0010
101
0
#define ASTreason_TLV       0x0011
102
0
#define LFBselect_TLV       0x1000
103
0
#define PATH_DATA_TLV       0x0110
104
#define KEYINFO_TLV         0x0111
105
#define FULLDATA_TLV        0x0112
106
#define SPARSEDATA_TLV      0x0113
107
#define RESULT_TLV          0x0114
108
#define METADATA_TLV        0x0115
109
#define REDIRECTDATA_TLV    0x0116
110
111
/*Operation Type*/
112
#define Reserved            0x0000
113
#define SET                 0x0001
114
#define SET_PROP            0x0002
115
#define SET_RESPONSE        0x0003
116
#define SET_PROP_RESPONSE   0x0004
117
#define DEL                 0x0005
118
#define DEL_RESPONSE        0x0006
119
#define GET                 0x0007
120
#define GET_PROP            0x0008
121
#define GET_RESPONSE        0x0009
122
#define GET_PROP_RESPONSE   0x000A
123
#define REPORT              0x000B
124
#define COMMIT              0x000C
125
#define COMMIT_RESPONSE     0x000D
126
#define TRCOMP              0x000E
127
128
0
#define FLAG_SELECTOR       0x8000
129
130
0
#define ForCES_HEADER_LENGTH    24
131
0
#define TLV_TL_LENGTH            4 /*Type+length*/
132
0
#define MIN_IP_HEADER_LENGTH    20
133
134
/*For TCP+UDP TML. There are two bytes added to the ForCES PL message, not strictly combine to the ForCES protocol.
135
  For other type TMLs,no need to add these 2 bytes.*/
136
0
#define TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP    2
137
138
/*SCTP TML*/
139
static unsigned forces_alternate_sctp_high_prio_channel_port;
140
static unsigned forces_alternate_sctp_med_prio_channel_port;
141
static unsigned forces_alternate_sctp_low_prio_channel_port;
142
143
/*Initialize the subtree pointers*/
144
static int   ett_forces;
145
static int   ett_forces_main_header;
146
static int   ett_forces_flags;
147
static int   ett_forces_tlv;
148
static int   ett_forces_lfbselect_tlv_type;
149
150
/*Operation TLV subtree*/
151
static int   ett_forces_lfbselect_tlv_type_operation;
152
static int   ett_forces_lfbselect_tlv_type_operation_path;
153
static int   ett_forces_lfbselect_tlv_type_operation_path_data;
154
static int   ett_forces_lfbselect_tlv_type_operation_path_data_path;
155
static int   ett_forces_path_data_tlv;
156
static int   ett_forces_path_data_tlv_flags;
157
158
/*Selector subtree*/
159
static int   ett_forces_lfbselect_tlv_type_operation_path_selector;
160
161
/*Redirect TLV subtree*/
162
static int   ett_forces_redirect_tlv_type;
163
static int   ett_forces_redirect_tlv_meta_data_tlv;
164
static int   ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv;
165
static int   ett_forces_redirect_tlv_redirect_data_tlv;
166
167
/*ASResult TLV subtree*/
168
static int   ett_forces_asresult_tlv;
169
170
/*ASReason subtree*/
171
static int   ett_forces_astreason_tlv;
172
173
/*Main_TLV unknown subtree*/
174
static int   ett_forces_unknown_tlv;
175
176
177
static expert_field ei_forces_length;
178
static expert_field ei_forces_tlv_type;
179
static expert_field ei_forces_tlv_length;
180
static expert_field ei_forces_lfbselect_tlv_type_operation_path_length;
181
static expert_field ei_forces_lfbselect_tlv_type_operation_type;
182
static expert_field ei_forces_redirect_tlv_redirect_data_tlv_length;
183
184
/*ACK values and the strings to be displayed*/
185
static const value_string main_header_flags_ack_vals[] = {
186
    { 0x0, "NoACK" },
187
    { 0x1, "SuccessACK" },
188
    { 0x2, "FailureACK" },
189
    { 0x3, "AlwaysACK" },
190
    { 0, NULL}
191
};
192
193
/*Execution mode(EM) values and the strings to be displayed*/
194
static const value_string main_header_flags_em_vals[] = {
195
    { 0x0, "Reserved" },
196
    { 0x1, "Execute-all-or-none" },
197
    { 0x2, "Execute-until-failure" },
198
    { 0x3, "Continue-execute-on-failure" },
199
    { 0, NULL}
200
};
201
202
/*Transaction Phase values and the strings to be displayed*/
203
static const value_string main_header_flags_tp_vals[] = {
204
    { 0x0, "SOT (Start of Transaction)" },
205
    { 0x1, "MOT (Middle of Transaction)" },
206
    { 0x2, "EOT (End of Transaction)" },
207
    { 0x3, "ABT (Abort)" },
208
    { 0, NULL}
209
};
210
211
/*Atomic Transaction(AT) values and the strings to be displayed*/
212
static const value_string main_header_flags_at_vals[] = {
213
    { 0x0, "Stand-alone Message"},
214
    { 0x1, "2PC Transaction Message"},
215
    { 0, NULL}
216
};
217
218
/*Association Setup Result*/
219
static const value_string association_setup_result_at_vals[] = {
220
    { 0x0, "success"},
221
    { 0x1, "FE ID invalid"},
222
    { 0x2, "permission denied"},
223
    { 0, NULL},
224
};
225
226
/*Teardown Reason*/
227
static const value_string teardown_reason_at_vals[] = {
228
    { 0x0,   "normal-teardown by administrator"},
229
    { 0x1,   "error - loss of heartbeats"},
230
    { 0x2,   "error - out of bandwidth"},
231
    { 0x3,   "error - out of memory"},
232
    { 0x4,   "error - application crash"},
233
    { 0x255, "error - other or unspecified"},
234
    { 0,     NULL},
235
};
236
237
static const value_string message_type_vals[] = {
238
    { AssociationSetup,         "AssociationSetup" },
239
    { AssociationTeardown,      "AssociationTeardown" },
240
    { Config,                   "Config" },
241
    { Query,                    "Query" },
242
    { EventNotification,        "EventNotification" },
243
    { PacketRedirect,           "PacketRedirect" },
244
    { Heartbeat,                "Heartbeat" },
245
    { AssociationSetupResponse, "AssociationSetupResponse" },
246
    { ConfigResponse,           "ConfigResponse" },
247
    { QueryResponse,            "QueryResponse" },
248
    { 0,                        NULL},
249
};
250
251
static const value_string tlv_type_vals[] = {
252
    { REDIRECT_TLV,     "REDIRECT-TLV" },
253
    { ASResult_TLV,     "ASResult-TLV" },
254
    { ASTreason_TLV,    "ASTreason-TLV" },
255
    { LFBselect_TLV,    "LFBselect-TLV" },
256
    { PATH_DATA_TLV,    "PATH DATA-TLV" },
257
    { KEYINFO_TLV,      "KEYINFO-TLV" },
258
    { FULLDATA_TLV,     "FULLDATA-TLV" },
259
    { SPARSEDATA_TLV,   "SPARSEDATA-TLV" },
260
    { RESULT_TLV,       "RESULT-TLV" },
261
    { METADATA_TLV,     "METADATA-TLV" },
262
    { REDIRECTDATA_TLV, "REDIRECTDATA-TLV" },
263
    { 0,                NULL},
264
};
265
266
static const value_string operation_type_vals[] = {
267
    { Reserved,          "Reserved" },
268
    { SET,               "SET" },
269
    { SET_PROP,          "SET-PROP" },
270
    { SET_RESPONSE,      "SET-RESPONSE" },
271
    { SET_PROP_RESPONSE, "SET-PROP-RESPONSE" },
272
    { DEL,               "DEL" },
273
    { DEL_RESPONSE,      "DEL-RESPONSE" },
274
    { GET,               "GET" },
275
    { GET_PROP,          "GET-PROP" },
276
    { GET_RESPONSE,      "GET-RESPONSE" },
277
    { GET_PROP_RESPONSE, "GET-PROP-RESPONSE" },
278
    { REPORT,            "REPORT" },
279
    { COMMIT,            "COMMIT" },
280
    { COMMIT_RESPONSE,   "COMMIT-RESPONSE" },
281
    { TRCOMP,            "TRCOMP" },
282
    { 0,                 NULL},
283
};
284
285
static void
286
dissect_path_data_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
287
0
{
288
0
    proto_item *ti, *flag_item;
289
0
    unsigned    length_TLV, IDcount, i;
290
0
    uint16_t    type, flag;
291
0
    proto_tree *tlv_tree, *path_data_tree, *flag_tree;
292
293
0
    while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
294
0
    {
295
0
        tlv_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH, ett_forces_path_data_tlv, &ti, "TLV");
296
297
0
        proto_tree_add_item_ret_uint16(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_type,
298
0
                                       tvb, offset, 2, ENC_BIG_ENDIAN, &type);
299
0
        length_TLV = tvb_get_ntohs(tvb, offset+2);
300
0
        proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_length,
301
0
                            tvb, offset+2, 2, ENC_BIG_ENDIAN);
302
0
        if (length_TLV < TLV_TL_LENGTH)
303
0
        {
304
0
            expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_path_length, "Bogus TLV length: %u", length_TLV);
305
0
            break;
306
0
        }
307
0
        proto_item_set_len(ti, length_TLV);
308
309
0
        if (type == PATH_DATA_TLV)
310
0
        {
311
0
            path_data_tree = proto_tree_add_subtree(tree, tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH,
312
0
                                    ett_forces_path_data_tlv, NULL, "Path Data TLV");
313
314
0
            flag = tvb_get_ntohs(tvb, offset+TLV_TL_LENGTH);
315
0
            flag_item = proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_flags,
316
0
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
317
0
            flag_tree = proto_item_add_subtree(flag_item, ett_forces_path_data_tlv_flags);
318
0
            proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_selector,
319
0
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
320
0
            proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_reserved,
321
0
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
322
323
0
            IDcount = tvb_get_ntohs(tvb, offset + TLV_TL_LENGTH + 2);
324
0
            proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDcount,
325
0
                                tvb, offset+TLV_TL_LENGTH+2, 2, ENC_BIG_ENDIAN);
326
327
0
            for (i = 0; i < IDcount; i++)
328
0
                proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDs,
329
0
                                    tvb, offset+TLV_TL_LENGTH+2+(i*4), 4, ENC_BIG_ENDIAN);
330
0
        }
331
0
        else
332
0
        {
333
0
            flag = 0;
334
0
            proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_operation_path_data,
335
0
                                tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, ENC_NA);
336
0
        }
337
338
0
        if ((flag & FLAG_SELECTOR) == 0)
339
0
            break;
340
341
0
        offset += length_TLV;
342
0
    }
343
0
}
344
345
static void
346
dissect_operation_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned length_count)
347
0
{
348
0
    proto_item *ti;
349
0
    proto_tree *oper_tree;
350
0
    unsigned    type, length;
351
0
    tvbuff_t   *oper_tvb;
352
353
    /* Dissects exactly one Operation TLV; the caller walks the TLVs. */
354
0
    if (tvb_reported_length_remaining(tvb, offset) < TLV_TL_LENGTH)
355
0
        return;
356
357
0
    oper_tree = proto_tree_add_subtree(tree, tvb, offset, length_count,
358
0
        ett_forces_lfbselect_tlv_type_operation, &ti, "Operation TLV");
359
360
0
    ti = proto_tree_add_item_ret_uint(oper_tree, hf_forces_lfbselect_tlv_type_operation_type,
361
0
                                      tvb, offset, 2, ENC_BIG_ENDIAN, &type);
362
0
    if (try_val_to_str(type, operation_type_vals) == NULL)
363
0
        expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_type,
364
0
            "Bogus: ForCES Operation TLV (Type:0x%04x) is not supported", type);
365
366
0
    ti = proto_tree_add_item_ret_uint(oper_tree, hf_forces_lfbselect_tlv_type_operation_length,
367
0
                               tvb, offset+2, 2, ENC_BIG_ENDIAN, &length);
368
0
    if (length < TLV_TL_LENGTH) {
369
0
        expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_path_length, "Bogus TLV length: %u", length);
370
0
        return;
371
0
    }
372
373
    /* Restrict the path data TLVs to this Operation TLV */
374
0
    oper_tvb = tvb_new_subset_length(tvb, offset, length);
375
0
    dissect_path_data_tlv(oper_tvb, pinfo, oper_tree, TLV_TL_LENGTH);
376
0
}
377
378
static void
379
dissect_lfbselecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length_count)
380
0
{
381
0
    unsigned tlv_length;
382
383
0
    proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_classid,    tvb, offset,   4, ENC_BIG_ENDIAN);
384
0
    proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_instanceid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
385
386
0
    offset += 8;
387
0
    while ((tvb_reported_length_remaining(tvb, offset) > TLV_TL_LENGTH) && (length_count > 12))
388
0
    {
389
0
        tlv_length = tvb_get_ntohs(tvb, offset+2);
390
0
        dissect_operation_tlv(tvb, pinfo, tree, offset, tlv_length);
391
0
        if (tlv_length < TLV_TL_LENGTH)
392
0
            break;
393
0
        offset += tlv_length;
394
0
    }
395
0
}
396
397
static void
398
dissect_redirecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
399
0
{
400
0
    proto_tree *meta_data_tree, *meta_data_ilv_tree, *redirect_data_tree;
401
0
    unsigned    start_offset;
402
0
    unsigned    length_meta, length_ilv, length_redirect;
403
0
    proto_item *ti;
404
0
    address     src_addr, src_net_addr;
405
0
    address     dst_addr, dst_net_addr;
406
407
0
    copy_address_shallow(&src_addr, &pinfo->src);
408
0
    copy_address_shallow(&src_net_addr, &pinfo->net_src);
409
0
    copy_address_shallow(&dst_addr, &pinfo->dst);
410
0
    copy_address_shallow(&dst_net_addr, &pinfo->net_dst);
411
412
0
    meta_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
413
0
        ett_forces_redirect_tlv_meta_data_tlv, &ti, "Meta Data TLV");
414
0
    proto_tree_add_item(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
415
416
0
    length_meta = tvb_get_ntohs(tvb, offset+2);
417
0
    proto_tree_add_uint(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_length, tvb, offset+2, 2, length_meta);
418
0
    proto_item_set_len(ti, length_meta);
419
420
0
    start_offset = offset;
421
0
    while ((tvb_reported_length_remaining(tvb, offset) >= 8) && (start_offset+length_meta > offset))
422
0
    {
423
0
        meta_data_ilv_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
424
0
            ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, &ti, "Meta Data ILV");
425
426
0
        proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
427
0
                                   tvb, offset+8, 4, ENC_BIG_ENDIAN);
428
0
        length_ilv = tvb_get_ntohl(tvb, offset+12);
429
0
        proto_tree_add_uint(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
430
0
                                   tvb, offset+12, 4, length_ilv);
431
0
        offset += 8;
432
0
        if (length_ilv > 0) {
433
0
            proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
434
0
                                   tvb, offset, length_ilv, ENC_NA);
435
436
0
            if (offset + length_ilv > offset) {
437
0
                offset += length_ilv;
438
0
            }
439
0
        }
440
441
0
        proto_item_set_len(ti, length_ilv + 8);
442
0
    }
443
444
0
    if (tvb_reported_length_remaining(tvb, offset) > 0)
445
0
    {
446
0
        redirect_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
447
0
            ett_forces_redirect_tlv_redirect_data_tlv, &ti, "Redirect Data TLV");
448
449
0
        proto_tree_add_item(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_type,
450
0
                            tvb, offset, 2,  ENC_BIG_ENDIAN);
451
0
        length_redirect = tvb_get_ntohs(tvb, offset+2);
452
0
        proto_tree_add_uint(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_length,
453
0
                            tvb, offset+2, 2, length_redirect);
454
455
0
        if (tvb_reported_length_remaining(tvb, offset) < length_redirect)
456
0
        {
457
0
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) is wrong", length_redirect);
458
0
        }
459
0
        else if (length_redirect < TLV_TL_LENGTH + MIN_IP_HEADER_LENGTH)
460
0
        {
461
0
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) not big enough for IP layer", length_redirect);
462
0
        }
463
0
        else
464
0
        {
465
0
            tvbuff_t  *next_tvb;
466
467
0
            next_tvb = tvb_new_subset_length(tvb, offset+4, length_redirect-TLV_TL_LENGTH);
468
0
            call_dissector(ip_handle, next_tvb, pinfo, redirect_data_tree);
469
470
            /* Restore IP info */
471
0
            copy_address_shallow(&pinfo->src, &src_addr);
472
0
            copy_address_shallow(&pinfo->net_src, &src_net_addr);
473
0
            copy_address_shallow(&pinfo->dst, &dst_addr);
474
0
            copy_address_shallow(&pinfo->net_dst, &dst_net_addr);
475
0
        }
476
0
    }
477
0
}
478
479
static void
480
dissect_forces(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset)
481
0
{
482
    /* Set up structures needed to add the protocol subtree and manage it */
483
0
    proto_item *ti, *tlv_item;
484
0
    proto_tree *forces_tree, *forces_flags_tree;
485
0
    proto_tree *forces_main_header_tree, *forces_tlv_tree, *tlv_tree;
486
0
    unsigned    length_count;
487
488
0
    uint8_t     message_type;
489
0
    uint16_t    tlv_type;
490
491
    /* Make entries in Protocol column and Info column on summary display */
492
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ForCES");
493
0
    col_clear(pinfo->cinfo, COL_INFO);
494
495
0
    ti = proto_tree_add_item(tree, proto_forces, tvb, 0, -1, ENC_NA);
496
0
    forces_tree = proto_item_add_subtree(ti, ett_forces);
497
498
0
    forces_main_header_tree = proto_tree_add_subtree(forces_tree, tvb, 0, ForCES_HEADER_LENGTH,
499
0
                ett_forces_main_header, NULL, "Common Header");
500
501
0
    proto_tree_add_item(forces_main_header_tree, hf_forces_version, tvb, 0, 1, ENC_BIG_ENDIAN);
502
0
    proto_tree_add_item(forces_main_header_tree, hf_forces_rsvd,    tvb, 0, 1, ENC_BIG_ENDIAN);
503
504
0
    message_type = tvb_get_uint8(tvb, offset+1);
505
0
    proto_tree_add_item( forces_main_header_tree, hf_forces_messagetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);
506
507
0
    length_count = tvb_get_ntohs(tvb, offset+2) * 4;  /*multiply 4 DWORD*/
508
0
    ti = proto_tree_add_uint_format( forces_main_header_tree, hf_forces_length,
509
0
                                     tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count);
510
0
    if (length_count != tvb_reported_length_remaining(tvb, offset))
511
0
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)",
512
0
            length_count, tvb_reported_length_remaining(tvb, offset));
513
0
    if (length_count < 24)
514
0
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count);
515
516
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type: %s, Total Length:  %u Bytes",
517
0
            val_to_str(pinfo->pool, message_type, message_type_vals, "Unknown messagetype 0x%x"), length_count);
518
519
0
    proto_tree_add_item( forces_main_header_tree, hf_forces_sid,        tvb, offset+4,  4, ENC_BIG_ENDIAN);
520
0
    proto_tree_add_item( forces_main_header_tree, hf_forces_did,        tvb, offset+8,  4, ENC_BIG_ENDIAN);
521
0
    proto_tree_add_item( forces_main_header_tree, hf_forces_correlator, tvb, offset+12, 8, ENC_BIG_ENDIAN);
522
523
    /*Add flags tree*/
524
0
    ti = proto_tree_add_item(forces_main_header_tree, hf_forces_flags, tvb, offset+20, 4, ENC_BIG_ENDIAN);
525
0
    forces_flags_tree = proto_item_add_subtree(ti, ett_forces_flags);
526
527
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_ack,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
528
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_at,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
529
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_em,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
530
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_pri,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
531
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_reserved, tvb, offset+20, 4, ENC_BIG_ENDIAN);
532
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_rsrvd,    tvb, offset+20, 4, ENC_BIG_ENDIAN);
533
0
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_tp,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
534
535
0
    offset += 24;
536
0
    while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
537
0
    {
538
0
        forces_tlv_tree = proto_tree_add_subtree(forces_tree, tvb, offset, TLV_TL_LENGTH, ett_forces_tlv, &ti, "TLV");
539
540
0
        tlv_item = proto_tree_add_item_ret_uint16(forces_tlv_tree, hf_forces_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN, &tlv_type);
541
0
        length_count = tvb_get_ntohs(tvb, offset+2) * 4;
542
0
        proto_item_set_len(ti, length_count);
543
0
        ti = proto_tree_add_uint(forces_tlv_tree, hf_forces_tlv_length,
544
0
                                        tvb, offset+2, 2, length_count);
545
0
        if (tvb_reported_length_remaining(tvb, offset) < length_count)
546
0
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus: Main TLV length (%u bytes) is wrong", length_count);
547
548
0
        if (length_count < TLV_TL_LENGTH)
549
0
        {
550
0
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus TLV length: %u", length_count);
551
0
            break;
552
0
        }
553
554
0
        offset       += TLV_TL_LENGTH;
555
0
        length_count -= TLV_TL_LENGTH;
556
557
0
        switch(tlv_type)
558
0
        {
559
0
        case LFBselect_TLV:
560
0
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
561
0
                    ett_forces_lfbselect_tlv_type, NULL, "LFB select TLV");
562
0
            dissect_lfbselecttlv(tvb, pinfo, tlv_tree, offset, length_count);
563
0
            break;
564
565
0
        case REDIRECT_TLV:
566
0
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
567
0
                            ett_forces_redirect_tlv_type, NULL, "Redirect TLV");
568
0
            dissect_redirecttlv(tvb, pinfo, tlv_tree, offset);
569
0
            break;
570
571
0
        case ASResult_TLV:
572
0
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
573
0
                        ett_forces_asresult_tlv, NULL, "ASResult TLV");
574
0
            proto_tree_add_item(tlv_tree, hf_forces_asresult_association_setup_result, tvb, offset, 4, ENC_BIG_ENDIAN);
575
0
            break;
576
577
0
        case ASTreason_TLV:
578
0
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
579
0
                            ett_forces_astreason_tlv, NULL, "ASTreason TLV");
580
0
            proto_tree_add_item(tlv_tree, hf_forces_astreason_tlv_teardown_reason, tvb, offset, 4, ENC_BIG_ENDIAN);
581
0
            break;
582
583
0
        default:
584
0
            expert_add_info(pinfo, tlv_item, &ei_forces_tlv_type);
585
0
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
586
0
                ett_forces_unknown_tlv, NULL, "Unknown TLV");
587
0
            proto_tree_add_item(tlv_tree, hf_forces_unknown_tlv, tvb, offset, length_count, ENC_NA);
588
0
            break;
589
0
        }
590
591
0
        offset += length_count;
592
0
    }
593
0
}
594
595
/* Code to actually dissect the TCP packets */
596
static int
597
dissect_forces_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
598
0
{
599
0
    dissect_forces(tvb, pinfo, tree, TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP);
600
0
    return tvb_captured_length(tvb);
601
0
}
602
603
/* Code to actually dissect the ForCES protocol layer packets,like UDP,SCTP and others */
604
static int
605
dissect_forces_not_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
606
0
{
607
0
    dissect_forces(tvb, pinfo, tree, 0);
608
0
    return tvb_captured_length(tvb);
609
0
}
610
611
void
612
proto_register_forces(void)
613
16
{
614
16
    module_t *forces_module;
615
16
    expert_module_t* expert_forces;
616
617
    /* Setup list of header fields  See Section 1.6.1 for details*/
618
16
    static hf_register_info hf[] = {
619
16
        { &hf_forces_version,
620
16
            { "Version", "forces.flags.version",
621
16
            FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
622
16
        },
623
16
        { &hf_forces_rsvd,
624
16
            { "Rsvd", "forces.flags.rsvd",
625
16
            FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
626
16
        },
627
16
        { &hf_forces_messagetype,
628
16
            { "Message Type", "forces.messagetype",
629
16
            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
630
16
        },
631
16
        { &hf_forces_length,
632
16
            { "Header Length", "forces.length",
633
16
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
634
16
        },
635
16
        { &hf_forces_sid,
636
16
            { "Source ID", "forces.sid",
637
16
            FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
638
16
        },
639
16
        { &hf_forces_did,
640
16
            { "Destination ID", "forces.did",
641
16
            FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
642
16
        },
643
16
        { &hf_forces_correlator,
644
16
            { "Correlator", "forces.correlator",
645
16
            FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
646
16
        },
647
16
        { &hf_forces_tlv_type,
648
16
            { "Type", "forces.tlv.type",
649
16
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
650
16
        },
651
16
        { &hf_forces_tlv_length,
652
16
            { "Length", "forces.tlv.length",
653
16
            FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
654
16
        },
655
        /*flags*/
656
16
        { &hf_forces_flags,
657
16
            { "Flags", "forces.Flags",
658
16
            FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
659
16
        },
660
16
        { &hf_forces_flags_ack,
661
16
            { "ACK indicator", "forces.flags.ack",
662
16
            FT_UINT32, BASE_DEC, VALS(main_header_flags_ack_vals), 0xC0000000, NULL, HFILL }
663
16
        },
664
16
        { &hf_forces_flags_pri,
665
16
            { "Priority", "forces.flags.pri",
666
16
            FT_UINT32, BASE_DEC, NULL, 0x38000000, NULL, HFILL }
667
16
        },
668
16
        { &hf_forces_flags_rsrvd,
669
16
            { "Rsrvd", "forces.flags.rsrvd",
670
16
            FT_UINT32, BASE_DEC,NULL, 0x07000000, NULL, HFILL }
671
16
        },
672
16
        { &hf_forces_flags_em,
673
16
            { "Execution mode", "forces.flags.em",
674
16
            FT_UINT32, BASE_DEC, VALS(main_header_flags_em_vals), 0x00C00000, NULL, HFILL }
675
16
        },
676
16
        { &hf_forces_flags_at,
677
16
            { "Atomic Transaction", "forces.flags.at",
678
16
            FT_UINT32, BASE_DEC, VALS(main_header_flags_at_vals), 0x00200000, NULL, HFILL }
679
16
        },
680
16
        { &hf_forces_flags_tp,
681
16
            { "Transaction phase", "forces.flags.tp",
682
16
            FT_UINT32, BASE_DEC, VALS(main_header_flags_tp_vals), 0x00180000, NULL, HFILL }
683
16
        },
684
16
        { &hf_forces_flags_reserved,
685
16
            { "Reserved", "forces.flags.reserved",
686
16
            FT_UINT32, BASE_DEC,NULL, 0x0007ffff, NULL, HFILL }
687
16
        },
688
        /*LFBSelectTLV*/
689
16
        { &hf_forces_lfbselect_tlv_type_lfb_classid,
690
16
            { "Class ID", "forces.lfbselect.tlv.type.lfb.classid",
691
16
            FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
692
16
        },
693
16
        { &hf_forces_lfbselect_tlv_type_lfb_instanceid,
694
16
            { "Instance ID", "forces.fbselect.tlv.type.lfb.instanceid",
695
16
            FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
696
16
        },
697
        /*Operation TLV*/
698
16
        { &hf_forces_lfbselect_tlv_type_operation_type,
699
16
            { "Type", "forces.lfbselect.tlv.type.operation.type",
700
16
            FT_UINT16, BASE_DEC, VALS(operation_type_vals), 0x0, NULL, HFILL }
701
16
        },
702
16
        { &hf_forces_lfbselect_tlv_type_operation_length,
703
16
            { "Length", "forces.lfbselect.tlv.type.operation.length",
704
16
            FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
705
16
        },
706
16
        { &hf_forces_lfbselect_tlv_type_operation_path_type,
707
16
            { "Type", "forces.lfbselect.tlv.type.operation.path.type",
708
16
            FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL }
709
16
        },
710
16
        { &hf_forces_lfbselect_tlv_type_operation_path_length,
711
16
            { "Length", "forces.lfbselect.tlv.type.operation.path.length",
712
16
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
713
16
        },
714
16
        { &hf_forces_lfbselect_tlv_type_operation_path_data,
715
16
            { "Data", "forces.lfbselect.tlv.type.operation.path.data",
716
16
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
717
16
        },
718
16
        { &hf_forces_lfbselect_tlv_type_operation_path_flags,
719
16
            {"Path Data Flags", "forces.lfbselect.tlv.type.operation.path.data.flags",
720
16
            FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
721
16
        },
722
16
        { &hf_forces_lfbselect_tlv_type_operation_path_flags_selector,
723
16
            {"Selector", "forces.lfbselect.tlv.type.operation.path.data.flags.selector",
724
16
            FT_UINT16, BASE_HEX, NULL, 0x80, NULL, HFILL }
725
16
        },
726
16
        { &hf_forces_lfbselect_tlv_type_operation_path_flags_reserved,
727
16
            {"Reserved", "forces.lfbselect.tlv.type.operation.path.data.flags.reserved",
728
16
            FT_UINT16, BASE_HEX, NULL, 0x7F, NULL, HFILL }
729
16
        },
730
16
        { &hf_forces_lfbselect_tlv_type_operation_path_IDcount,
731
16
            { "Path Data IDcount", "forces.lfbselect.tlv.type.operation.path.data.IDcount",
732
16
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
733
16
        },
734
16
        { &hf_forces_lfbselect_tlv_type_operation_path_IDs,
735
16
            { "Path Data IDs", "forces.lfbselect.tlv.type.operation.path.data.IDs",
736
16
            FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
737
16
        },
738
        /*Meta data TLV*/
739
16
        {&hf_forces_redirect_tlv_meta_data_tlv_type,
740
16
            { "Type", "forces.redirect.tlv.meta.data.tlv.type",
741
16
            FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
742
16
        },
743
16
        { &hf_forces_redirect_tlv_meta_data_tlv_length,
744
16
            { "Length", "forces.redirect.tlv.meta.data.tlv.length",
745
16
            FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
746
16
        },
747
16
        { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
748
16
            { "Meta Data ILV", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv",
749
16
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
750
16
        },
751
16
        { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
752
16
            { "ID", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.id",
753
16
            FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }
754
16
        },
755
16
        { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
756
16
            { "Length", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.length",
757
16
            FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
758
16
        },
759
16
        { &hf_forces_redirect_tlv_redirect_data_tlv_type,
760
16
            { "Type", "forces.redirect.tlv.redirect.data.tlv.type",
761
16
            FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL }
762
16
        },
763
16
        { &hf_forces_redirect_tlv_redirect_data_tlv_length,
764
16
            { "Length", "forces.redirect.tlv.redirect.data.tlv.length",
765
16
            FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }
766
16
        },
767
16
        { &hf_forces_asresult_association_setup_result,
768
16
            { "Association Setup Result", "forces.teardown.reason",
769
16
            FT_UINT32, BASE_DEC, VALS(association_setup_result_at_vals), 0x0, NULL, HFILL }
770
16
        },
771
16
        { &hf_forces_astreason_tlv_teardown_reason,
772
16
            { "AStreason TLV TearDown Reason", "forces.astreason.tlv.teardown.reason",
773
16
            FT_UINT32, BASE_DEC, VALS(teardown_reason_at_vals), 0x0, NULL, HFILL }
774
16
        },
775
16
        { &hf_forces_unknown_tlv,
776
16
            { "Data", "forces.unknown.tlv",
777
16
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
778
16
        }
779
16
    };
780
781
    /* Setup protocol subtree array */
782
16
    static int *ett[] = {
783
16
        &ett_forces,
784
16
        &ett_forces_main_header,
785
16
        &ett_forces_flags,
786
16
        &ett_forces_tlv,
787
16
        &ett_forces_lfbselect_tlv_type,
788
16
        &ett_forces_lfbselect_tlv_type_operation,
789
16
        &ett_forces_lfbselect_tlv_type_operation_path,
790
16
        &ett_forces_lfbselect_tlv_type_operation_path_data,
791
16
        &ett_forces_lfbselect_tlv_type_operation_path_data_path,
792
16
        &ett_forces_lfbselect_tlv_type_operation_path_selector,
793
16
        &ett_forces_path_data_tlv,
794
16
        &ett_forces_path_data_tlv_flags,
795
16
        &ett_forces_redirect_tlv_type,
796
16
        &ett_forces_redirect_tlv_meta_data_tlv,
797
16
        &ett_forces_redirect_tlv_redirect_data_tlv,
798
16
        &ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
799
16
        &ett_forces_asresult_tlv,
800
16
        &ett_forces_astreason_tlv,
801
16
        &ett_forces_unknown_tlv
802
16
    };
803
804
16
    static ei_register_info ei[] = {
805
16
        { &ei_forces_length, { "forces.length.bad", PI_PROTOCOL, PI_WARN, "ForCES Header length is wrong", EXPFILL }},
806
16
        { &ei_forces_tlv_type, { "forces.tlv.type.unknown", PI_PROTOCOL, PI_WARN, "Bogus: The Main_TLV type is unknown", EXPFILL }},
807
16
        { &ei_forces_tlv_length, { "forces.tlv.length.bad", PI_PROTOCOL, PI_WARN, "Bogus TLV length", EXPFILL }},
808
16
        { &ei_forces_lfbselect_tlv_type_operation_path_length, { "forces.lfbselect.tlv.type.operation.path.length.bad", PI_PROTOCOL, PI_WARN, "Bogus TLV length", EXPFILL }},
809
16
        { &ei_forces_lfbselect_tlv_type_operation_type, { "forces.lfbselect.tlv.type.operation.type.unsupported", PI_PROTOCOL, PI_WARN, "ForCES Operation TLV is not supported", EXPFILL }},
810
16
        { &ei_forces_redirect_tlv_redirect_data_tlv_length, { "forces.redirect.tlv.redirect.data.tlv.length.bad", PI_PROTOCOL, PI_WARN, "Redirect Data TLV length is wrong", EXPFILL }},
811
16
    };
812
813
    /* Register the protocol name and description */
814
16
    proto_forces = proto_register_protocol("Forwarding and Control Element Separation Protocol", "ForCES", "forces");
815
816
    /* Required function calls to register the header fields and subtrees used */
817
16
    proto_register_field_array(proto_forces, hf, array_length(hf));
818
16
    proto_register_subtree_array(ett, array_length(ett));
819
16
    expert_forces = expert_register_protocol(proto_forces);
820
16
    expert_register_field_array(expert_forces, ei, array_length(ei));
821
822
16
    forces_handle_tcp = register_dissector("forces.tcp", dissect_forces_tcp,     proto_forces);
823
16
    forces_handle     = register_dissector("forces",     dissect_forces_not_tcp, proto_forces);
824
825
16
    forces_module = prefs_register_protocol(proto_forces,proto_reg_handoff_forces);
826
827
16
    prefs_register_uint_preference(forces_module, "sctp_high_prio_port",
828
16
                                   "SCTP High Priority channel port",
829
16
                                   "Decode packets on this sctp port as ForCES",
830
16
                                   10, &forces_alternate_sctp_high_prio_channel_port);
831
832
16
    prefs_register_uint_preference(forces_module, "sctp_med_prio_port",
833
16
                                   "SCTP Medium Priority channel port",
834
16
                                   "Decode packets on this sctp port as ForCES",
835
16
                                   10, &forces_alternate_sctp_med_prio_channel_port);
836
837
16
    prefs_register_uint_preference(forces_module, "sctp_low_prio_port",
838
16
                                   "SCTP Low Priority channel port",
839
16
                                   "Decode packets on this sctp port as ForCES",
840
16
                                   10, &forces_alternate_sctp_low_prio_channel_port);
841
16
}
842
843
void
844
proto_reg_handoff_forces(void)
845
16
{
846
16
    static bool inited = false;
847
848
16
    static unsigned alternate_sctp_high_prio_channel_port = 0; /* 6700 */
849
16
    static unsigned alternate_sctp_med_prio_channel_port  = 0;
850
16
    static unsigned alternate_sctp_low_prio_channel_port  = 0;
851
852
16
    if (!inited) {
853
16
        ip_handle = find_dissector_add_dependency("ip", proto_forces);
854
        /* Register TCP port for dissection */
855
16
        dissector_add_for_decode_as_with_preference("tcp.port", forces_handle_tcp);
856
        /* Register UDP port for dissection */
857
16
        dissector_add_for_decode_as_with_preference("udp.port", forces_handle);
858
859
16
        inited = true;
860
16
    }
861
862
    /* Register SCTP port for high priority dissection */
863
16
    if ((alternate_sctp_high_prio_channel_port != 0) &&
864
0
        (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port))
865
0
        dissector_delete_uint("sctp.port", alternate_sctp_high_prio_channel_port, forces_handle);
866
16
    if ((forces_alternate_sctp_high_prio_channel_port != 0) &&
867
0
        (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port))
868
0
        dissector_add_uint("sctp.port", forces_alternate_sctp_high_prio_channel_port, forces_handle);
869
16
    alternate_sctp_high_prio_channel_port = forces_alternate_sctp_high_prio_channel_port;
870
871
    /* Register SCTP port for medium priority dissection */
872
16
    if ((alternate_sctp_med_prio_channel_port != 0) &&
873
0
        (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port))
874
0
        dissector_delete_uint("sctp.port", alternate_sctp_med_prio_channel_port, forces_handle);
875
16
    if ((forces_alternate_sctp_med_prio_channel_port != 0) &&
876
0
        (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port))
877
0
        dissector_add_uint("sctp.port", forces_alternate_sctp_med_prio_channel_port, forces_handle);
878
16
    alternate_sctp_med_prio_channel_port = forces_alternate_sctp_med_prio_channel_port;
879
880
    /* Register SCTP port for low priority dissection */
881
16
    if ((alternate_sctp_low_prio_channel_port != 0) &&
882
0
        (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port))
883
0
        dissector_delete_uint("sctp.port", alternate_sctp_low_prio_channel_port, forces_handle);
884
16
    if ((forces_alternate_sctp_low_prio_channel_port != 0) &&
885
0
        (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port))
886
0
        dissector_add_uint("sctp.port", forces_alternate_sctp_low_prio_channel_port, forces_handle);
887
16
    alternate_sctp_low_prio_channel_port = forces_alternate_sctp_low_prio_channel_port;
888
16
}
889
890
/*
891
* Editor modelines - https://www.wireshark.org/tools/modelines.html
892
*
893
* Local variables:
894
* c-basic-offset: 4
895
* tab-width: 8
896
* indent-tabs-mode: nil
897
* End:
898
*
899
* vi: set shiftwidth=4 tabstop=8 expandtab:
900
* :indentSize=4:tabSize=8:noTabs=true:
901
*/