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