Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-tpkt.c
Line
Count
Source
1
/* packet-tpkt.c
2
 *
3
 * Routine to check for RFC 1006 TPKT header and to dissect TPKT header
4
 * Copyright 2000, Philips Electronics N.V.
5
 * Andreas Sikkema <h323@ramdyne.nl>
6
 *
7
 * Routine to dissect RFC 1006 TPKT packet containing OSI TP PDU
8
 * Copyright 2001, Martin Thomas <Martin_A_Thomas@yahoo.com>
9
 *
10
 * Wireshark - Network traffic analyzer
11
 * By Gerald Combs <gerald@wireshark.org>
12
 * Copyright 1998 Gerald Combs
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 */
16
17
#include "config.h"
18
19
#include <epan/packet.h>
20
#include <epan/exceptions.h>
21
#include <epan/prefs.h>
22
#include <epan/show_exception.h>
23
#include <epan/conversation.h>
24
25
#include "packet-tpkt.h"
26
27
void proto_register_tpkt(void);
28
void proto_reg_handoff_tpkt(void);
29
30
static heur_dissector_list_t tpkt_heur_subdissector_list;
31
32
/* TPKT header fields             */
33
static int proto_tpkt;
34
static int proto_tpkt_heur;
35
static protocol_t *proto_tpkt_ptr;
36
static int hf_tpkt_version;
37
static int hf_tpkt_reserved;
38
static int hf_tpkt_length;
39
static int hf_tpkt_continuation_data;
40
41
42
/* TPKT fields defining a sub tree */
43
static int ett_tpkt;
44
45
/* desegmentation of OSI over TPKT over TCP */
46
static bool tpkt_desegment = true;
47
48
14
#define TCP_PORT_TPKT_RANGE       "102"
49
50
/* IANA registered port for RDP (as ms-wbt-server) */
51
14
#define TCP_PORT_RDP 3389
52
53
/* find the dissector for OSI TP (aka COTP) */
54
static dissector_handle_t osi_tp_handle;
55
static dissector_handle_t tpkt_handle;
56
57
#define DEFAULT_TPKT_PORT_RANGE "102"
58
59
/*
60
 * Check whether this could be a TPKT-encapsulated PDU.
61
 * Returns -1 if it's not, and the PDU length from the TPKT header
62
 * if it is.
63
 *
64
 * "min_len" is the minimum length of the PDU; the length field in the
65
 * TPKT header must be at least "4+min_len" in order for this to be a
66
 * valid TPKT PDU for the protocol in question.
67
 */
68
int
69
is_tpkt(tvbuff_t *tvb, int min_len)
70
3.89k
{
71
3.89k
    uint16_t pkt_len;
72
73
    /*
74
     * If TPKT is disabled, don't dissect it, just return -1, meaning
75
     * "this isn't TPKT".
76
     */
77
3.89k
    if (!proto_is_protocol_enabled(proto_tpkt_ptr))
78
0
        return -1;
79
80
    /* There should at least be 4 bytes left in the frame */
81
3.89k
    if (tvb_captured_length(tvb) < 4)
82
141
        return -1;  /* there aren't */
83
84
    /*
85
     * The first octet should be 3 and the second one should be 0
86
     * The H.323 implementers guide suggests that this might not
87
     * always be the case....
88
     */
89
3.75k
    if (!(tvb_get_uint8(tvb, 0) == 3 && tvb_get_uint8(tvb, 1) == 0))
90
3.68k
        return -1;  /* they're not */
91
92
    /*
93
     * Get the length from the TPKT header.  Make sure it's large
94
     * enough.
95
     */
96
62
    pkt_len = tvb_get_ntohs(tvb, 2);
97
62
    if (pkt_len < 4 + min_len)
98
4
        return -1;  /* it's not */
99
100
    /*
101
     * Return the length from the header.
102
     */
103
58
    return pkt_len;
104
62
}
105
uint16_t
106
is_asciitpkt(tvbuff_t *tvb)
107
194
{
108
194
    uint16_t count;
109
        /*
110
         * If TPKT is disabled, don't dissect it, just return -1, meaning
111
         * "this isn't TPKT".
112
         */
113
194
    if (!proto_is_protocol_enabled(proto_tpkt_ptr))
114
0
       return -1;
115
116
          /* There should at least be 8 bytes left in the frame */
117
194
    if (!tvb_bytes_exist(tvb, 0, 8))
118
12
        return -1;      /* there aren't */
119
120
        /*
121
         * The first four  octets should be alphanumeric ASCII
122
         */
123
903
    for (count = 0; count <=7 ; count ++)
124
867
        {
125
867
        if(!g_ascii_isalnum(tvb_get_uint8(tvb,count)))
126
146
          {
127
146
          return 0;
128
146
          }
129
867
        }
130
36
     return 1;
131
132
133
182
}
134
static int
135
parseLengthText ( uint8_t* pTpktData )
136
143
{
137
143
    int value = 0;
138
143
    const uint8_t * pData = pTpktData;
139
143
    int bitvalue = 0, count1 = 3;
140
143
    int count;
141
715
    for (count = 0; count <= 3; count++)
142
572
        {
143
572
        if (('0' <= *(pData + count)) && (*(pData + count) <= '9'))
144
361
            bitvalue = *(pData + count) - 48;
145
211
        else if (('a' <= *(pData + count)) && (*(pData + count) <= 'f' ))
146
9
            bitvalue = *(pData + count) - 87;
147
202
        else if (('A' <= *(pData + count)) && (*(pData + count) <= 'F' ))
148
3
            bitvalue = *(pData + count) - 55;
149
150
572
        value += bitvalue << (4*count1);
151
572
        count1--;
152
572
        }
153
143
    return value;
154
143
}
155
static int
156
parseVersionText ( uint8_t* pTpktData )
157
145
{
158
145
    int value = 0;
159
145
    uint8_t * pData = pTpktData;
160
145
    int bitvalue = 0, count1 = 1;
161
145
    int count;
162
435
    for (count = 0; count <= 1; count++)
163
290
        {
164
290
        if (('0' <= *(pData + count)) && (*(pData + count) <= '9'))
165
272
            bitvalue = *(pData + count) - 48;
166
18
        else if (('a' <= *(pData + count)) && (*(pData + count) <= 'f' ))
167
0
            bitvalue = *(pData + count) - 87;
168
18
        else if (('A' <= *(pData + count)) && (*(pData + count) <= 'F' ))
169
1
            bitvalue = *(pData + count) - 55;
170
171
290
        value += bitvalue << (4*count1);
172
290
        count1--;
173
290
        }
174
175
145
    return value;
176
145
}
177
static int
178
parseReservedText ( uint8_t* pTpktData )
179
145
{
180
145
    int value = 0;
181
145
    uint8_t * pData = pTpktData;
182
145
    int bitvalue = 0, count1 = 1;
183
145
    int count;
184
435
    for (count = 0; count <= 1; count++)
185
290
        {
186
290
        if (('0' <= *(pData + count)) && (*(pData + count) <= '9'))
187
237
            bitvalue = *(pData + count) - 48;
188
53
        else if (('a' <= *(pData + count)) && (*(pData + count) <= 'f' ))
189
4
            bitvalue = *(pData + count) - 87;
190
49
        else if (('A' <= *(pData + count)) && (*(pData + count) <= 'F' ))
191
1
            bitvalue = *(pData + count) - 55;
192
193
290
        value += bitvalue << (4*count1);
194
290
        count1--;
195
290
        }
196
197
145
    return value;
198
145
}
199
200
/*
201
 * Length of the TPKT text-layer header.
202
 */
203
static const int TEXT_LAYER_LENGTH   = 9;
204
205
/*
206
 * Dissect ASCII TPKT-encapsulated data in a TCP stream.
207
 */
208
void
209
dissect_asciitpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
210
          dissector_handle_t subdissector_handle)
211
36
{
212
36
    proto_item *ti = NULL;
213
36
    proto_tree *tpkt_tree = NULL;
214
36
    volatile int offset = 0;
215
36
    int data_len;
216
36
    volatile int mgcp_packet_len = 0;
217
36
    int mgcp_version = 0;
218
36
    int mgcp_reserved = 0;
219
36
    tvbuff_t *volatile next_tvb;
220
36
    const char *saved_proto;
221
36
    uint8_t string[4];
222
223
    /*
224
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
225
     * column, so subdissectors can append information
226
     * without having to worry about emptying the column.
227
     *
228
     * We use "col_add_str()" because the subdissector
229
     * might be appending information to the column, in
230
     * which case we'd have to zero the buffer out explicitly
231
     * anyway.
232
     */
233
36
    if (tpkt_desegment)
234
36
        col_clear(pinfo->cinfo, COL_INFO);
235
236
181
    while (tvb_reported_length_remaining(tvb, offset) != 0) {
237
        /*
238
         * Is the first byte of this putative TPKT header
239
         * a valid TPKT version number, i.e. 3?
240
         */
241
172
        if (tvb_get_uint8(tvb, offset) != 48) {
242
            /*
243
             * No, so don't assume this is a TPKT header;
244
             * we might be in the middle of TPKT data,
245
             * so don't get the length and don't try to
246
             * do reassembly.
247
             */
248
27
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
249
27
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
250
27
            if (tree) {
251
27
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
252
27
                             offset, -1, ENC_NA);
253
27
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
254
255
27
                proto_tree_add_item(tpkt_tree, hf_tpkt_continuation_data, tvb, offset, -1, ENC_NA);
256
27
            }
257
27
            return;
258
27
        }
259
260
        /*
261
         * Get the length from the TPKT header.
262
         */
263
264
145
        tvb_memcpy(tvb, (uint8_t *)string, offset, 2);
265
145
        mgcp_version = parseVersionText(string);
266
145
        tvb_memcpy(tvb, (uint8_t *)string, offset +2, 2);
267
145
        mgcp_reserved = parseReservedText(string);
268
145
        tvb_memcpy(tvb, (uint8_t *)string, offset + 4, 4);
269
145
        mgcp_packet_len = parseLengthText(string);
270
145
        data_len = mgcp_packet_len;
271
272
        /*
273
         * Dissect the TPKT header.
274
         * Save and restore "pinfo->current_proto".
275
         */
276
145
        saved_proto = pinfo->current_proto;
277
145
        pinfo->current_proto = "TPKT";
278
279
145
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
280
        /*
281
         * Don't add the TPKT header information if we're
282
         * reassembling segmented TPKT PDUs or if this
283
         * PDU isn't reassembled.
284
         *
285
         * XXX - the first is so that subdissectors can append
286
         * information without getting TPKT stuff in the middle;
287
         * why the second?
288
         */
289
145
        if (!tpkt_desegment && !pinfo->fragmented) {
290
0
            col_add_fstr(pinfo->cinfo, COL_INFO,
291
0
                     "TPKT Data length = %u", data_len);
292
0
        }
293
294
145
        if (tree) {
295
143
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
296
143
                         offset, 8, ENC_NA);
297
143
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
298
143
            proto_item_set_text(ti, "TPKT");
299
300
            /* Version */
301
143
            proto_tree_add_uint(tpkt_tree, hf_tpkt_version, tvb,
302
143
                        offset, 2, mgcp_version);
303
304
            /* Reserved octet*/
305
143
            proto_tree_add_uint(tpkt_tree, hf_tpkt_reserved, tvb,
306
143
                        offset + 2, 2, mgcp_reserved);
307
308
            /* Length */
309
143
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
310
143
                        offset + 4, 4, mgcp_packet_len);
311
143
        }
312
145
        pinfo->current_proto = saved_proto;
313
314
        /* Skip the TPKT header. */
315
145
        offset += TEXT_LAYER_LENGTH;
316
317
145
        next_tvb = tvb_new_subset_length(tvb, offset, data_len);
318
319
        /*
320
         * Call the subdissector.
321
         *
322
         * If it gets an error that means there's no point in
323
         * dissecting any more TPKT messages, rethrow the
324
         * exception in question.
325
         *
326
         * If it gets any other error, report it and continue, as that
327
         * means that TPKT message got an error, but that doesn't mean
328
         * we should stop dissecting TPKT messages within this frame
329
         * or chunk of reassembled data.
330
         */
331
145
        TRY {
332
142
            call_dissector(subdissector_handle, next_tvb, pinfo,
333
142
                       tree);
334
142
        }
335
145
        CATCH_NONFATAL_ERRORS {
336
337
0
            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
338
0
        }
339
145
        ENDTRY;
340
341
        /*
342
         * Skip the payload.
343
         */
344
145
        offset += data_len;
345
145
    }
346
36
}
347
348
/*
349
 * Dissect TPKT-encapsulated data in a TCP stream.
350
 */
351
void
352
dissect_tpkt_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
353
           bool desegment, dissector_handle_t subdissector_handle)
354
393
{
355
393
    proto_item *ti = NULL;
356
393
    proto_tree *tpkt_tree = NULL;
357
393
    volatile int offset = 0;
358
393
    int length_remaining;
359
393
    volatile int data_len;
360
393
    volatile int length;
361
393
    tvbuff_t *volatile next_tvb;
362
393
    const char *saved_proto;
363
393
    bool save_fragmented;
364
393
    heur_dtbl_entry_t *hdtbl_entry;
365
366
    /*
367
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
368
     * column, so subdissectors can append information
369
     * without having to worry about emptying the column.
370
     *
371
     * We use "col_add_str()" because the subdissector
372
     * might be appending information to the column, in
373
     * which case we'd have to zero the buffer out explicitly
374
     * anyway.
375
     */
376
393
    if (desegment)
377
206
        col_clear(pinfo->cinfo, COL_INFO);
378
379
764
    while (tvb_reported_length_remaining(tvb, offset) != 0) {
380
        /*
381
         * Is the first byte of this putative TPKT header
382
         * a valid TPKT version number, i.e. 3?
383
         */
384
443
        if (tvb_get_uint8(tvb, offset) != 3) {
385
            /*
386
             * No, so don't assume this is a TPKT header;
387
             * we might be in the middle of TPKT data,
388
             * so don't get the length and don't try to
389
             * do reassembly.
390
             */
391
392
64
            if (dissector_try_heuristic(tpkt_heur_subdissector_list, tvb,
393
64
                                        pinfo, proto_tree_get_root(tree),
394
64
                                        &hdtbl_entry, NULL)) {
395
6
                return;
396
6
            }
397
398
58
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
399
58
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
400
58
            if (tree) {
401
57
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
402
57
                    offset, -1, ENC_NA);
403
57
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
404
405
57
                proto_tree_add_item(tpkt_tree, hf_tpkt_continuation_data, tvb, offset, -1, ENC_NA);
406
57
            }
407
58
            return;
408
64
        }
409
410
379
        length_remaining = tvb_captured_length_remaining(tvb, offset);
411
412
        /*
413
         * Can we do reassembly?
414
         */
415
379
        if (desegment && pinfo->can_desegment) {
416
            /*
417
             * Yes - is the TPKT header split across segment
418
             * boundaries?
419
             */
420
0
            if (length_remaining < 4) {
421
                /*
422
                 * Yes.  Tell the TCP dissector where the data
423
                 * for this message starts in the data it
424
                 * handed us and that we need "some more data."
425
                 * Don't tell it exactly how many bytes we need
426
                 * because if/when we ask for even more (after
427
                 * the header) that will break reassembly.
428
                 */
429
0
                pinfo->desegment_offset = offset;
430
0
                pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
431
0
                return;
432
0
            }
433
0
        }
434
435
        /*
436
         * Get the length from the TPKT header.
437
         */
438
379
        data_len = tvb_get_ntohs(tvb, offset + 2);
439
440
379
        if (data_len < 4) {
441
            /*
442
             * The length includes the TPKT header, so this can't be a valid
443
             * TPKT header. We only checked one byte above, so we might be in
444
             * the middle of TPKT data. Call it continuation as above.
445
             */
446
8
            if (dissector_try_heuristic(tpkt_heur_subdissector_list, tvb,
447
8
                                        pinfo, proto_tree_get_root(tree),
448
8
                                        &hdtbl_entry, NULL)) {
449
0
                return;
450
0
            }
451
452
8
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
453
8
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
454
8
            if (tree) {
455
8
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
456
8
                    offset, -1, ENC_NA);
457
8
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
458
459
8
                proto_tree_add_item(tpkt_tree, hf_tpkt_continuation_data, tvb, offset, -1, ENC_NA);
460
8
            }
461
8
            return;
462
8
        }
463
464
        /*
465
         * Can we do reassembly?
466
         */
467
371
        if (desegment && pinfo->can_desegment) {
468
            /*
469
             * Yes - is the payload split across segment
470
             * boundaries?
471
             */
472
0
            if (length_remaining < data_len) {
473
                /*
474
                 * Yes.  Tell the TCP dissector where
475
                 * the data for this message starts in
476
                 * the data it handed us, and how many
477
                 * more bytes we need, and return.
478
                 */
479
0
                pinfo->desegment_offset = offset;
480
0
                pinfo->desegment_len =
481
0
                    data_len - length_remaining;
482
0
                return;
483
0
            }
484
0
        }
485
486
        /*
487
         * Dissect the TPKT header.
488
         * Save and restore "pinfo->current_proto".
489
         */
490
371
        saved_proto = pinfo->current_proto;
491
371
        pinfo->current_proto = "TPKT";
492
493
371
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
494
        /*
495
         * Don't add the TPKT header information if we're
496
         * reassembling segmented TPKT PDUs or if this
497
         * PDU isn't reassembled.
498
         *
499
         * XXX - the first is so that subdissectors can append
500
         * information without getting TPKT stuff in the middle;
501
         * why the second?
502
         */
503
371
        if (!desegment && !pinfo->fragmented) {
504
176
            col_add_fstr(pinfo->cinfo, COL_INFO,
505
176
                "TPKT Data length = %u", data_len);
506
176
        }
507
508
371
        if (tree) {
509
371
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
510
371
                offset, 4, ENC_NA);
511
371
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
512
371
            proto_item_set_text(ti, "TPKT");
513
514
            /* Version */
515
371
            proto_tree_add_item(tpkt_tree, hf_tpkt_version, tvb,
516
371
                offset, 1, ENC_BIG_ENDIAN);
517
371
            proto_item_append_text(ti, ", Version: 3");
518
519
            /* Reserved octet*/
520
371
            proto_tree_add_item(tpkt_tree, hf_tpkt_reserved, tvb,
521
371
                offset + 1, 1, ENC_BIG_ENDIAN);
522
523
            /* Length */
524
371
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
525
371
                offset + 2, 2, data_len);
526
371
            proto_item_append_text(ti, ", Length: %u", data_len);
527
371
        }
528
371
        pinfo->current_proto = saved_proto;
529
530
        /* Skip the TPKT header. */
531
371
        offset += 4;
532
371
        data_len -= 4;
533
534
        /*
535
         * Construct a tvbuff with reported length the amount
536
         * amount of data in this TPKT packet.
537
         *
538
         * If reassembly isn't enabled, and we don't have all the
539
         * payload, mark the packet as fragmented, so that
540
         * FragmentBoundsError is thrown instead of ReportedBoundsError.
541
         */
542
371
        save_fragmented = pinfo->fragmented;
543
371
        length = length_remaining - 4;
544
371
        if (length > data_len) {
545
50
            pinfo->fragmented = true;
546
50
        }
547
371
        next_tvb = tvb_new_subset_length(tvb, offset, data_len);
548
549
        /*
550
         * Call the subdissector.
551
         *
552
         * If it gets an error that means there's no point in
553
         * dissecting any more TPKT messages, rethrow the
554
         * exception in question.
555
         *
556
         * If it gets any other error, report it and continue,
557
         * as that means that TPKT message got an error, but
558
         * that doesn't mean we should stop dissecting TPKT
559
         * messages within this frame or chunk of reassembled
560
         * data.
561
         */
562
371
        TRY {
563
371
            call_dissector(subdissector_handle, next_tvb, pinfo,
564
371
                tree);
565
371
        }
566
371
        CATCH_NONFATAL_ERRORS {
567
354
            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
568
354
        }
569
371
        ENDTRY;
570
571
371
        pinfo->fragmented = save_fragmented;
572
573
        /*
574
         * Skip the payload.
575
         */
576
371
        offset += data_len;
577
371
    }
578
393
}
579
580
/*
581
 * Dissect RFC 1006 TPKT, which wraps a TPKT header around an OSI TP
582
 * PDU.
583
 */
584
static int
585
dissect_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
586
6
{
587
6
    dissect_tpkt_encap(tvb, pinfo, tree, tpkt_desegment, osi_tp_handle);
588
6
    return tvb_captured_length(tvb);
589
6
}
590
591
/*
592
 * Dissect ASCII TPKT, which wraps a ASCII TPKT header around an OSI TP
593
 * PDU.
594
 */
595
#if 0
596
static int
597
dissect_ascii_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
598
{
599
    dissect_asciitpkt(tvb, pinfo, tree, osi_tp_handle);
600
    return tvb_captured_length(tvb);
601
}
602
#endif
603
604
/* A heuristic dissector for TPKT. This is useful for RDP, where TLS may
605
 * or may not be present depending on the RDP security settings.
606
 */
607
static int
608
dissect_tpkt_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
609
4
{
610
4
    if (is_tpkt(tvb, 0) == -1) {
611
        /* Doesn't look like TPKT directly. Might be over TLS, so reject
612
         * and let the TLS heuristic dissector take a look
613
         */
614
4
        return 0;
615
4
    }
616
617
0
    return dissect_tpkt(tvb, pinfo, tree, data);
618
4
}
619
620
static bool
621
dissect_tpkt_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
622
0
{
623
0
    return dissect_tpkt_tcp(tvb, pinfo, tree, data) > 0;
624
0
}
625
626
void
627
proto_register_tpkt(void)
628
14
{
629
14
    static hf_register_info hf[] = {
630
14
        {
631
14
            &hf_tpkt_version,
632
14
            {
633
14
                "Version",
634
14
                "tpkt.version",
635
14
                FT_UINT16,
636
14
                BASE_DEC,
637
14
                NULL,
638
14
                0x0,
639
14
                "Version, only version 3 is defined", HFILL
640
14
            }
641
14
        },
642
14
        {
643
14
            &hf_tpkt_reserved,
644
14
            {
645
14
                "Reserved",
646
14
                "tpkt.reserved",
647
14
                FT_UINT8,
648
14
                BASE_DEC,
649
14
                NULL,
650
14
                0x0,
651
14
                "Reserved, should be 0", HFILL
652
14
            }
653
14
        },
654
14
        {
655
14
            &hf_tpkt_length,
656
14
            {
657
14
                "Length",
658
14
                "tpkt.length",
659
14
                FT_UINT16,
660
14
                BASE_DEC,
661
14
                NULL,
662
14
                0x0,
663
14
                "Length of data unit, including this header", HFILL
664
14
            }
665
14
        },
666
14
        {
667
14
            &hf_tpkt_continuation_data,
668
14
            {
669
14
                "Continuation data",
670
14
                "tpkt.continuation_data",
671
14
                FT_BYTES,
672
14
                BASE_NONE,
673
14
                NULL,
674
14
                0x0,
675
14
                NULL, HFILL
676
14
            }
677
14
        },
678
14
    };
679
680
14
    static int *ett[] =
681
14
    {
682
14
        &ett_tpkt,
683
14
    };
684
14
    module_t *tpkt_module;
685
686
14
    proto_tpkt = proto_register_protocol("TPKT - ISO on TCP - RFC1006", "TPKT", "tpkt");
687
14
    proto_tpkt_ptr = find_protocol_by_id(proto_tpkt);
688
14
    proto_register_field_array(proto_tpkt, hf, array_length(hf));
689
14
    proto_register_subtree_array(ett, array_length(ett));
690
14
    tpkt_handle = register_dissector("tpkt", dissect_tpkt, proto_tpkt);
691
692
14
    tpkt_module = prefs_register_protocol(proto_tpkt, NULL);
693
14
    prefs_register_bool_preference(tpkt_module, "desegment",
694
14
        "Reassemble TPKT messages spanning multiple TCP segments",
695
14
        "Whether the TPKT dissector should reassemble messages spanning multiple TCP segments. "
696
14
        "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
697
14
        &tpkt_desegment);
698
699
    /* heuristic dissectors for preamble CredSSP before RDP and Fast-Path RDP packets */
700
14
    tpkt_heur_subdissector_list = register_heur_dissector_list_with_description("tpkt", "TPKT fragment", proto_tpkt);
701
702
14
    proto_tpkt_heur = proto_register_protocol_in_name_only("TPKT Heuristic (for RDP)", "TPKT Heuristic (for RDP)", "tpkt", proto_tpkt, FT_PROTOCOL);
703
14
}
704
705
void
706
proto_reg_handoff_tpkt(void)
707
14
{
708
14
    osi_tp_handle = find_dissector("ositp");
709
14
    dissector_add_uint_range_with_preference("tcp.port", TCP_PORT_TPKT_RANGE, tpkt_handle);
710
711
    /* ssl_dissector_add registers TLS as the dissector for TCP for the
712
     * given port. We can't use it, since on port 3389 TPKT (for RDP) can be
713
     * over TLS or directly over TCP, depending on the RDP security settings.
714
     * TPKT heuristics are also too weak to enable in general. Instead,
715
     * use the heuristic dissector by default just on the RDP port, and
716
     * if rejected the TLS heuristic dissector will be tried.
717
     */
718
14
    dissector_add_uint("tcp.port", TCP_PORT_RDP, create_dissector_handle(dissect_tpkt_tcp, proto_tpkt_heur));
719
14
    heur_dissector_add("tcp", dissect_tpkt_heur, "TPKT over TCP", "tpkt_tcp", proto_tpkt, HEURISTIC_DISABLE);
720
14
    heur_dissector_add("tls", dissect_tpkt_heur, "TPKT over TLS", "tpkt_tls", proto_tpkt, HEURISTIC_ENABLE);
721
722
    /*
723
    tpkt_ascii_handle = create_dissector_handle(dissect_ascii_tpkt, proto_tpkt);
724
    dissector_add_uint("tcp.port", TCP_PORT_TPKT, tpkt_ascii_handle);
725
    */
726
727
14
}
728
729
/*
730
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
731
 *
732
 * Local variables:
733
 * c-basic-offset: 4
734
 * tab-width: 8
735
 * indent-tabs-mode: nil
736
 * End:
737
 *
738
 * vi: set shiftwidth=4 tabstop=8 expandtab:
739
 * :indentSize=4:tabSize=8:noTabs=true:
740
 */