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-pdu-transport.c
Line
Count
Source
1
/* packet-pdu-transport.c
2
 * PDU Transport dissector for FDN and others.
3
 * By <lars.voelker@technica-engineering.de>
4
 * Copyright 2020-2025 Dr. Lars Völker
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
 /*
14
  * This is a dissector for PDUs transported over UDP or TCP.
15
  * The transported PDUs are typically CAN, FlexRay, LIN, or other protocols.
16
  *
17
  * The format is as follows:
18
  *  ID         (optional) [uint8, uint16, or uint32]
19
  *  Length     (optional) [uint8, uint16, or uint32]
20
  *  Data       uint8[length]
21
  *  (restart with ID, if more data exists and Length field present)
22
  *
23
  * The dissector will try to match in this order:
24
  *  Source and Destination port
25
  *  Destination port and Any for Source port
26
  *  Source port and Any for Destination port
27
  *  Any for both ports
28
  *
29
  *
30
  * One known implementation of this protocol is the AUTOSAR Socket Adaptor:
31
  *  With Header Option turned on: uint32 ID and uint32 Length.
32
  *  With Header Option turned off: no ID and no Length.
33
  *
34
  * See AUTOSAR "Specification of Socket Adaptor" (SWS), Section 7.3 PDU Header option:
35
  * https://www.autosar.org/fileadmin/standards/R24-11/CP/AUTOSAR_CP_SWS_SocketAdaptor.pdf
36
  */
37
38
#include <config.h>
39
40
#include <epan/packet.h>
41
#include <epan/prefs.h>
42
#include <epan/expert.h>
43
#include <epan/uat.h>
44
#include "packet-tcp.h"
45
#include <epan/reassemble.h>
46
#include "packet-udp.h"
47
#include "packet-pdu-transport.h"
48
#include <epan/decode_as.h>
49
#include <epan/proto_data.h>
50
51
void proto_register_pdu_transport(void);
52
void proto_reg_handoff_pdu_transport(void);
53
54
static int proto_pdu_transport;
55
static dissector_handle_t pdu_transport_handle_udp;
56
static dissector_handle_t pdu_transport_handle_tcp;
57
58
static dissector_table_t subdissector_table;
59
60
0
#define PDU_TRANSPORT_HDR_LEN 8
61
62
/* header field */
63
static int hf_pdu_transport_id;
64
static int hf_pdu_transport_name;
65
static int hf_pdu_transport_impl_id;
66
static int hf_pdu_transport_length;
67
static int hf_pdu_transport_payload;
68
69
/* protocol tree items */
70
static int ett_pdu_transport;
71
72
/* expert info items */
73
static expert_field ei_pdu_transport_message_truncated;
74
75
/********* UATs *********/
76
77
typedef struct _generic_one_id_string {
78
    unsigned   id;
79
    char   *name;
80
} generic_one_id_string_t;
81
82
/* ID -> Name */
83
static void *
84
0
copy_generic_one_id_string_cb(void *n, const void *o, size_t size _U_) {
85
0
    generic_one_id_string_t *new_rec = (generic_one_id_string_t *)n;
86
0
    const generic_one_id_string_t *old_rec = (const generic_one_id_string_t *)o;
87
88
0
    new_rec->name = g_strdup(old_rec->name);
89
0
    new_rec->id = old_rec->id;
90
0
    return new_rec;
91
0
}
92
93
static bool
94
0
update_generic_one_identifier_32bit(void *r, char **err) {
95
0
    generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
96
97
0
    if (rec->name == NULL || rec->name[0] == 0) {
98
0
        *err = g_strdup("Name cannot be empty");
99
0
        return false;
100
0
    }
101
102
0
    return true;
103
0
}
104
105
static void
106
0
free_generic_one_id_string_cb(void *r) {
107
0
    generic_one_id_string_t *rec = (generic_one_id_string_t *)r;
108
    /* freeing result of g_strdup */
109
0
    g_free(rec->name);
110
0
    rec->name = NULL;
111
0
}
112
113
/*** UAT PDU Transport PDUs - ID to Name lookup ***/
114
15
#define DATAFILE_PDU_IDS                "PDU_Transport_identifiers"
115
116
static GHashTable *data_pdu_transport_pdus;
117
static generic_one_id_string_t *pdu_transport_pdus;
118
static unsigned pdu_transport_pdus_num;
119
120
0
UAT_HEX_CB_DEF(pdu_transport_pdus, id, generic_one_id_string_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_pdus_id_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_pdus_id_tostr_cb
121
0
UAT_CSTRING_CB_DEF(pdu_transport_pdus, name, generic_one_id_string_t)
122
123
static void
124
15
post_update_pdu_transport_pdus_cb(void) {
125
    /* destroy old hash table, if it exists */
126
15
    if (data_pdu_transport_pdus) {
127
0
        g_hash_table_destroy(data_pdu_transport_pdus);
128
0
    }
129
130
    /* create new hash table */
131
15
    data_pdu_transport_pdus = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
132
133
15
    for (unsigned i = 0; i < pdu_transport_pdus_num; i++) {
134
0
        g_hash_table_insert(data_pdu_transport_pdus, GUINT_TO_POINTER(pdu_transport_pdus[i].id), pdu_transport_pdus[i].name);
135
0
    }
136
15
}
137
138
static void
139
0
reset_pdu_transport_pdus_cb(void) {
140
    /* destroy hash table, if it exists */
141
0
    if (data_pdu_transport_pdus) {
142
0
        g_hash_table_destroy(data_pdu_transport_pdus);
143
0
        data_pdu_transport_pdus = NULL;
144
0
    }
145
0
}
146
147
static char *
148
0
lookup_pdu_name(uint32_t identifier) {
149
0
    if (data_pdu_transport_pdus == NULL) {
150
0
        return NULL;
151
0
    }
152
153
0
    return (char *)g_hash_table_lookup(data_pdu_transport_pdus, GUINT_TO_POINTER(identifier));
154
0
}
155
156
157
/*** UAT pdu_transport_extended_config ***/
158
15
#define DATAFILE_EXT_CFG                "PDU_Transport_extended_config"
159
0
#define PORT_ANY                        65536
160
161
typedef struct _pdu_transport_ext_cfg {
162
    bool        tcp;
163
    uint32_t    source_port;
164
    uint32_t    destination_port;
165
    uint32_t    size_of_id_field;
166
    uint32_t    size_of_length_field;
167
    uint32_t    default_id;
168
} pdu_transport_ext_cfg_t;
169
170
171
static GHashTable *data_pdu_transport_ext_cfg = NULL;
172
static pdu_transport_ext_cfg_t *pdu_transport_ext_cfg;
173
static unsigned pdu_transport_ext_cfg_num;
174
175
0
UAT_BOOL_CB_DEF(pdu_transport_ext_cfg, tcp, pdu_transport_ext_cfg_t)
176
0
UAT_DEC_CB_DEF(pdu_transport_ext_cfg, source_port, pdu_transport_ext_cfg_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_source_port_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_source_port_tostr_cb
177
0
UAT_DEC_CB_DEF(pdu_transport_ext_cfg, destination_port, pdu_transport_ext_cfg_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_destination_port_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_destination_port_tostr_cb
178
0
UAT_DEC_CB_DEF(pdu_transport_ext_cfg, size_of_id_field, pdu_transport_ext_cfg_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_size_of_id_field_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_size_of_id_field_tostr_cb
179
0
UAT_DEC_CB_DEF(pdu_transport_ext_cfg, size_of_length_field, pdu_transport_ext_cfg_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_size_of_length_field_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_size_of_length_field_tostr_cb
180
0
UAT_HEX_CB_DEF(pdu_transport_ext_cfg, default_id, pdu_transport_ext_cfg_t)
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_default_id_set_cb
Unexecuted instantiation: packet-pdu-transport.c:pdu_transport_ext_cfg_default_id_tostr_cb
181
182
static void *
183
0
copy_pdu_transport_ext_cfg_cb(void *n, const void *o, size_t size _U_) {
184
0
    pdu_transport_ext_cfg_t *new_rec = (pdu_transport_ext_cfg_t *)n;
185
0
    const pdu_transport_ext_cfg_t *old_rec = (const pdu_transport_ext_cfg_t *)o;
186
187
0
    new_rec->tcp = old_rec->tcp;
188
0
    new_rec->source_port = old_rec->source_port;
189
0
    new_rec->destination_port = old_rec->destination_port;
190
0
    new_rec->size_of_id_field = old_rec->size_of_id_field;
191
0
    new_rec->size_of_length_field = old_rec->size_of_length_field;
192
0
    new_rec->default_id = old_rec->default_id;
193
0
    return new_rec;
194
0
}
195
196
static bool
197
0
update_pdu_transport_ext_cfg_cb(void *r, char **err) {
198
0
    pdu_transport_ext_cfg_t *rec = (pdu_transport_ext_cfg_t *)r;
199
200
0
    if (rec->source_port > UINT16_MAX && rec->source_port != PORT_ANY) {
201
0
        *err = g_strdup("Source Port can only be up to 65535 or Any (65536)!");
202
0
        return false;
203
0
    }
204
205
0
    if (rec->destination_port > UINT16_MAX && rec->destination_port != PORT_ANY) {
206
0
        *err = g_strdup("Destination Port can only be up to 65535 or Any (65536)!");
207
0
        return false;
208
0
    }
209
210
0
    if (rec->size_of_id_field != 0 && rec->size_of_id_field != 8 && rec->size_of_id_field != 16 && rec->size_of_id_field != 32) {
211
0
        *err = g_strdup("Size of the ID field can only be 0, 8, 16, or 32 bit!");
212
0
        return false;
213
0
    }
214
215
0
    if (rec->size_of_length_field != 0 && rec->size_of_length_field != 8 && rec->size_of_length_field != 16 && rec->size_of_length_field != 32) {
216
0
        *err = g_strdup("Size of the Length field can only be 0, 8, 16, or 32 bit!");
217
0
        return false;
218
0
    }
219
220
0
    return true;
221
0
}
222
223
224
static void
225
15
reset_pdu_transport_ext_cfg_cb(void) {
226
    /* destroy hash table, if it exists */
227
15
    if (data_pdu_transport_ext_cfg) {
228
0
        g_hash_table_destroy(data_pdu_transport_ext_cfg);
229
0
        data_pdu_transport_ext_cfg = NULL;
230
0
    }
231
15
}
232
233
static void
234
15
post_update_pdu_transport_ext_cfg_cb(void) {
235
15
    reset_pdu_transport_ext_cfg_cb();
236
237
    /* create new hash table */
238
15
    data_pdu_transport_ext_cfg = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
239
240
15
    for (unsigned i = 0; i < pdu_transport_ext_cfg_num; i++) {
241
0
        uint32_t key = 0;
242
0
        if (pdu_transport_ext_cfg[i].destination_port != PORT_ANY) {
243
0
            key |= pdu_transport_ext_cfg[i].destination_port;
244
0
        }
245
246
0
        if (pdu_transport_ext_cfg[i].source_port != PORT_ANY) {
247
0
            key |= (pdu_transport_ext_cfg[i].source_port << 16);
248
0
        }
249
250
0
        g_hash_table_insert(data_pdu_transport_ext_cfg, GUINT_TO_POINTER(key), &(pdu_transport_ext_cfg[i]));
251
0
    }
252
15
}
253
254
static void
255
0
lookup_extended_config(packet_info *pinfo _U_, unsigned *size_of_id, unsigned *size_of_len, uint32_t *default_id) {
256
    /* Set backward compatible defaults, in case we find no entry */
257
0
    *size_of_id = 4;
258
0
    *size_of_len = 4;
259
260
0
    if (data_pdu_transport_ext_cfg == NULL) {
261
0
        return;
262
0
    }
263
264
0
    if (pinfo->ptype != PT_TCP && pinfo->ptype != PT_UDP) {
265
0
        return;
266
0
    }
267
268
0
    bool tcp = (pinfo->ptype == PT_TCP);
269
0
    pdu_transport_ext_cfg_t *entry = NULL;
270
271
    /* Try Source-Port / Dest-Port */
272
0
    uint32_t key = pinfo->srcport << 16 | pinfo->destport;
273
0
    entry = (pdu_transport_ext_cfg_t *)g_hash_table_lookup(data_pdu_transport_ext_cfg, GUINT_TO_POINTER(key));
274
275
    /* If not found, try Any / Dest-Port */
276
0
    if (entry == NULL || entry->tcp != tcp) {
277
0
        key = pinfo->destport;
278
0
        entry = (pdu_transport_ext_cfg_t *)g_hash_table_lookup(data_pdu_transport_ext_cfg, GUINT_TO_POINTER(key));
279
0
    }
280
281
    /* If not found, try Source-Port / Any */
282
0
    if (entry == NULL || entry->tcp != tcp) {
283
0
        key = pinfo->srcport << 16;
284
0
        entry = (pdu_transport_ext_cfg_t *)g_hash_table_lookup(data_pdu_transport_ext_cfg, GUINT_TO_POINTER(key));
285
0
    }
286
287
    /* If not found, try Any / Any */
288
0
    if (entry == NULL || entry->tcp != tcp) {
289
0
        key = 0;
290
0
        entry = (pdu_transport_ext_cfg_t *)g_hash_table_lookup(data_pdu_transport_ext_cfg, GUINT_TO_POINTER(key));
291
0
    }
292
293
0
    if (entry != NULL && entry->tcp == tcp) {
294
0
        *size_of_id = entry->size_of_id_field / 8;
295
0
        *size_of_len = entry->size_of_length_field / 8;
296
0
        *default_id = entry->default_id;
297
0
    }
298
0
}
299
300
301
static int
302
0
dissect_pdu_transport(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
303
0
    proto_item         *ti = NULL;
304
0
    unsigned            offset = 0;
305
306
0
    if (p_get_proto_data(pinfo->pool, pinfo, proto_pdu_transport, pinfo->curr_proto_layer_num) != NULL) {
307
0
        col_append_str(pinfo->cinfo, COL_INFO, ", ");
308
0
        col_set_fence(pinfo->cinfo, COL_INFO);
309
0
    }
310
311
0
    col_set_str(pinfo->cinfo, COL_INFO, "PDU");
312
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDU Transport");
313
0
    proto_item *ti_top = proto_tree_add_item(tree, proto_pdu_transport, tvb, 0, -1, ENC_NA);
314
0
    proto_tree *pdu_transport_tree = proto_item_add_subtree(ti_top, ett_pdu_transport);
315
316
0
    unsigned size_of_id_field;
317
0
    unsigned size_of_len_field;
318
0
    uint32_t default_id;
319
320
0
    lookup_extended_config(pinfo, &size_of_id_field, &size_of_len_field, &default_id);
321
322
0
    if (tvb_captured_length_remaining(tvb, offset) < size_of_id_field + size_of_len_field) {
323
0
        expert_add_info(pinfo, ti_top, &ei_pdu_transport_message_truncated);
324
0
    }
325
326
    /* taken from packet-ip.c
327
     * if pdu_transport is not referenced from any filters we don't need to worry about
328
     * generating any tree items.  We must do this after we created the actual
329
     * protocol above so that proto hier stat still works though.
330
     * XXX: Note that because of the following optimization expert items must
331
     *      not be generated inside of an 'if (tree) ...'
332
     *      so that Analyze ! Expert ...  will work.
333
     */
334
335
0
    if (!proto_field_is_referenced(tree, proto_pdu_transport)) {
336
0
        pdu_transport_tree = NULL;
337
0
    }
338
339
0
    uint32_t pdu_id;
340
0
    if (size_of_id_field > 0) {
341
0
        proto_tree_add_item_ret_uint(pdu_transport_tree, hf_pdu_transport_id, tvb, offset, size_of_id_field, ENC_BIG_ENDIAN, &pdu_id);
342
0
    } else {
343
0
        ti = proto_tree_add_uint(pdu_transport_tree, hf_pdu_transport_impl_id, tvb, 0, 0, default_id);
344
0
        proto_item_set_generated(ti);
345
0
        pdu_id = default_id;
346
0
    }
347
0
    const char *descr = lookup_pdu_name(pdu_id);
348
349
0
    if (descr != NULL) {
350
0
        ti = proto_tree_add_string(pdu_transport_tree, hf_pdu_transport_name, tvb, offset, 4, descr);
351
0
        proto_item_set_generated(ti);
352
0
    }
353
0
    offset += size_of_id_field;
354
355
0
    uint32_t length;
356
0
    if (size_of_len_field > 0) {
357
0
        proto_tree_add_item_ret_uint(pdu_transport_tree, hf_pdu_transport_length, tvb, offset, size_of_len_field, ENC_BIG_ENDIAN, &length);
358
0
        offset += size_of_len_field;
359
0
    } else {
360
0
        length = tvb_captured_length_remaining(tvb, offset);
361
0
    }
362
363
0
    if (descr != NULL) {
364
0
        proto_item_append_text(ti_top, ", ID 0x%x (%s), Length: %d", pdu_id, descr, length);
365
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " (ID: 0x%x, %s)", pdu_id, descr);
366
0
    } else {
367
0
        proto_item_append_text(ti_top, ", ID 0x%x, Length: %d", pdu_id, length);
368
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " (ID: 0x%x)", pdu_id);
369
0
    }
370
371
0
    p_add_proto_data(pinfo->pool, pinfo, proto_pdu_transport, pinfo->curr_proto_layer_num, GUINT_TO_POINTER(pdu_id));
372
373
0
    int tmp = tvb_captured_length_remaining(tvb, offset);
374
0
    tvbuff_t *subtvb = NULL;
375
0
    if ((int)length <= tmp) {
376
0
        proto_tree_add_item(pdu_transport_tree, hf_pdu_transport_payload, tvb, offset, length, ENC_NA);
377
0
    } else {
378
0
        proto_tree_add_item(pdu_transport_tree, hf_pdu_transport_payload, tvb, offset, tmp, ENC_NA);
379
0
        expert_add_info(pinfo, ti_top, &ei_pdu_transport_message_truncated);
380
0
    }
381
0
    subtvb = tvb_new_subset_length(tvb, offset, length);
382
0
    if (subtvb != NULL) {
383
0
        pdu_transport_info_t pdu_t_info;
384
0
        pdu_t_info.id = pdu_id;
385
0
        dissector_try_uint_with_data(subdissector_table, pdu_id, subtvb, pinfo, tree, false, (void *)(&pdu_t_info));
386
0
    }
387
0
    offset += (int)length;
388
389
0
    col_set_fence(pinfo->cinfo, COL_INFO);
390
0
    return offset;
391
0
}
392
393
static unsigned
394
0
get_pdu_transport_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_) {
395
0
    return PDU_TRANSPORT_HDR_LEN + (unsigned)tvb_get_ntohl(tvb, offset + 4);
396
0
}
397
398
static int
399
0
dissect_pdu_transport_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
400
0
    tcp_dissect_pdus(tvb, pinfo, tree, true, PDU_TRANSPORT_HDR_LEN, get_pdu_transport_message_len, dissect_pdu_transport, data);
401
0
    return tvb_reported_length(tvb);
402
0
}
403
404
static int
405
0
dissect_pdu_transport_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) {
406
0
    return udp_dissect_pdus(tvb, pinfo, tree, PDU_TRANSPORT_HDR_LEN, NULL, get_pdu_transport_message_len, dissect_pdu_transport, data);
407
0
}
408
409
410
static void
411
0
pdu_transport_id_prompt(packet_info *pinfo, char *result) {
412
0
    snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "PDU Transport ID 0x%08x as",
413
0
             GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_pdu_transport, pinfo->curr_proto_layer_num)));
414
0
}
415
416
static void *
417
0
pdu_transport_id_value(packet_info *pinfo) {
418
    /* Limitation: This only returns the last proto_data, since udp_dissect_pdus gives us the same layer for all. */
419
0
    return p_get_proto_data(pinfo->pool, pinfo, proto_pdu_transport, pinfo->curr_proto_layer_num);
420
0
}
421
422
void
423
15
proto_register_pdu_transport(void) {
424
15
    module_t *pdu_transport_module = NULL;
425
15
    expert_module_t *expert_module_pdu_transport = NULL;
426
427
15
    static hf_register_info hf[] = {
428
15
        { &hf_pdu_transport_id,
429
15
            { "ID", "pdu_transport.id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
430
15
        { &hf_pdu_transport_impl_id,
431
15
            { "ID (Implicit)", "pdu_transport.implicit_id", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
432
15
        { &hf_pdu_transport_name,
433
15
            { "Name", "pdu_transport.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
434
15
        { &hf_pdu_transport_length,
435
15
            { "Length", "pdu_transport.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
436
15
        { &hf_pdu_transport_payload,
437
15
            { "Payload", "pdu_transport.payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
438
15
    };
439
440
15
    static int *ett[] = {
441
15
        &ett_pdu_transport,
442
15
    };
443
444
15
    static ei_register_info ei[] = {
445
15
    { &ei_pdu_transport_message_truncated,{ "pdu_transport.message_truncated",
446
15
      PI_MALFORMED, PI_ERROR, "PDU Transport Truncated message!", EXPFILL } },
447
15
    };
448
449
    /* Decode As handling */
450
15
    static build_valid_func  pdu_transport_da_build_value[1] = {pdu_transport_id_value};
451
15
    static decode_as_value_t pdu_transport_da_values = {pdu_transport_id_prompt, 1, pdu_transport_da_build_value};
452
453
15
    static decode_as_t pdu_transport_da = { "pdu_transport", "pdu_transport.id", 1, 0, &pdu_transport_da_values,
454
15
                                            NULL, NULL, decode_as_default_populate_list,
455
15
                                            decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL };
456
457
15
    proto_pdu_transport = proto_register_protocol("PDU Transport Protocol", "PDU Transport", "pdu_transport");
458
459
15
    proto_register_field_array(proto_pdu_transport, hf, array_length(hf));
460
15
    proto_register_subtree_array(ett, array_length(ett));
461
462
15
    pdu_transport_module = prefs_register_protocol(proto_pdu_transport, NULL);
463
15
    expert_module_pdu_transport = expert_register_protocol(proto_pdu_transport);
464
15
    expert_register_field_array(expert_module_pdu_transport, ei, array_length(ei));
465
466
467
    /* UAT PDU-Transport PDUs */
468
469
15
    static uat_field_t pdu_transport_pdus_uat_fields[] = {
470
15
        UAT_FLD_HEX(pdu_transport_pdus, id, "ID", "ID  (hex uint32)"),
471
15
        UAT_FLD_CSTRING(pdu_transport_pdus, name, "Name", "Name of the PDU (string)"),
472
15
        UAT_END_FIELDS
473
15
    };
474
475
476
15
    uat_t *pdu_transport_pduid_uat  = uat_new("PDU Transport PDUs",
477
15
        sizeof(generic_one_id_string_t),        /* record size           */
478
15
        DATAFILE_PDU_IDS,                       /* filename              */
479
15
        true,                                   /* from profile          */
480
15
        (void**)&pdu_transport_pdus,            /* data_ptr              */
481
15
        &pdu_transport_pdus_num,                /* numitems_ptr          */
482
15
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
483
15
        NULL,                                   /* help                  */
484
15
        copy_generic_one_id_string_cb,          /* copy callback         */
485
15
        update_generic_one_identifier_32bit,    /* update callback       */
486
15
        free_generic_one_id_string_cb,          /* free callback         */
487
15
        post_update_pdu_transport_pdus_cb,      /* post update callback  */
488
15
        reset_pdu_transport_pdus_cb,            /* reset callback        */
489
15
        pdu_transport_pdus_uat_fields           /* UAT field definitions */
490
15
    );
491
492
15
    prefs_register_uat_preference(pdu_transport_module, "_udf_pdu_transport_pdus", "PDUs",
493
15
        "A table to define names and IDs of PDUs", pdu_transport_pduid_uat);
494
495
496
    /* UAT PDU-Transport Extended Config */
497
498
15
    static uat_field_t pdu_transport_ext_cfg_uat_fields[] = {
499
15
    UAT_FLD_BOOL(pdu_transport_ext_cfg, tcp, "TCP?", "TCP (true) / UDP (false)"),
500
15
    UAT_FLD_DEC(pdu_transport_ext_cfg, source_port, "Source Port", "Source Port  (Dec 0..65535, 65536 means any)"),
501
15
    UAT_FLD_DEC(pdu_transport_ext_cfg, destination_port, "Destination Port", "Destination Port  (Dec 0..65535, 65536 means any)"),
502
15
    UAT_FLD_DEC(pdu_transport_ext_cfg, size_of_id_field, "Size of ID", "Size of ID  (0, 8, 16, 32 bit. 32 bit is default)"),
503
15
    UAT_FLD_DEC(pdu_transport_ext_cfg, size_of_length_field, "Size of Length", "Size of Length  (0, 8, 16, 32 bit. 32 bit is default)"),
504
15
    UAT_FLD_HEX(pdu_transport_ext_cfg, default_id, "Default ID", "Default ID. Used, when no ID present in packet."),
505
15
    UAT_END_FIELDS
506
15
    };
507
508
15
    uat_t *pdu_transport_ext_cfg_uat = uat_new("PDU Transport Extended Config",
509
15
        sizeof(pdu_transport_ext_cfg_t),        /* record size           */
510
15
        DATAFILE_EXT_CFG,                       /* filename              */
511
15
        true,                                   /* from profile          */
512
15
        (void**)&pdu_transport_ext_cfg,         /* data_ptr              */
513
15
        &pdu_transport_ext_cfg_num,             /* numitems_ptr          */
514
15
        UAT_AFFECTS_DISSECTION,                 /* but not fields        */
515
15
        NULL,                                   /* help                  */
516
15
        copy_pdu_transport_ext_cfg_cb,          /* copy callback         */
517
15
        update_pdu_transport_ext_cfg_cb,        /* update callback       */
518
15
        NULL,                                   /* free callback         */
519
15
        post_update_pdu_transport_ext_cfg_cb,   /* post update callback  */
520
15
        reset_pdu_transport_ext_cfg_cb,         /* reset callback        */
521
15
        pdu_transport_ext_cfg_uat_fields        /* UAT field definitions */
522
15
    );
523
524
15
    prefs_register_uat_preference(pdu_transport_module, "_udf_pdu_transport_ext_cfg", "Extended Config",
525
15
        "A table to define the extended configuration", pdu_transport_ext_cfg_uat);
526
527
528
15
    subdissector_table = register_dissector_table("pdu_transport.id", "PDU Transport ID", proto_pdu_transport, FT_UINT32, BASE_HEX);
529
15
    register_decode_as(&pdu_transport_da);
530
15
}
531
532
void
533
15
proto_reg_handoff_pdu_transport(void) {
534
15
    pdu_transport_handle_udp = register_dissector("pdu_transport_over_udp", dissect_pdu_transport_udp, proto_pdu_transport);
535
15
    pdu_transport_handle_tcp = register_dissector("pdu_transport_over_tcp", dissect_pdu_transport_tcp, proto_pdu_transport);
536
537
15
    dissector_add_uint_range_with_preference("udp.port", "", pdu_transport_handle_udp);
538
15
    dissector_add_uint_range_with_preference("tcp.port", "", pdu_transport_handle_tcp);
539
15
}
540
541
/*
542
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
543
 *
544
 * Local variables:
545
 * c-basic-offset: 4
546
 * tab-width: 8
547
 * indent-tabs-mode: nil
548
 * End:
549
 *
550
 * vi: set shiftwidth=4 tabstop=8 expandtab:
551
 * :indentSize=4:tabSize=8:noTabs=true:
552
 */