Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-fmtp.c
Line
Count
Source
1
/* packet-fmtp.c
2
 *
3
 * Routines for FMTP version 2 packet dissection.
4
 *
5
 * The specifications of this public protocol can be found on Eurocontrol web site:
6
 * http://www.eurocontrol.int/sites/default/files/publication/files/20070614-fmtp-spec-v2.0.pdf
7
 *
8
 * Copyright 2011, Christophe Paletou <c.paletou@free.fr>
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 "packet-tcp.h"
21
22
void proto_register_fmtp(void);
23
void proto_reg_handoff_fmtp(void);
24
25
static int proto_fmtp;
26
static int hf_fmtp_pdu_version;
27
static int hf_fmtp_pdu_reserved;
28
static int hf_fmtp_pdu_type;
29
static int hf_fmtp_pdu_length;
30
static int ett_fmtp;
31
32
/* #define TCP_PORT_FMTP       8500 */
33
33
#define FMTP_HEADER_LEN     5
34
12
#define FMTP_MAX_DATA_LEN   10240
35
12
#define FMTP_MAX_LEN        FMTP_HEADER_LEN + FMTP_MAX_DATA_LEN
36
37
#define FMTP_TYP_OPERATIONAL    1
38
#define FMTP_TYP_OPERATOR       2
39
0
#define FMTP_TYP_IDENTIFICATION 3
40
0
#define FMTP_TYP_SYSTEM         4
41
42
#define INFO_STR_SIZE        1024
43
44
static const value_string packet_type_names[] = {
45
    { FMTP_TYP_OPERATIONAL,    "Operational message" },
46
    { FMTP_TYP_OPERATOR,       "Operator message" },
47
    { FMTP_TYP_IDENTIFICATION, "Identification message" },
48
    { FMTP_TYP_SYSTEM        , "System message" },
49
    { 0, NULL }
50
};
51
52
static const value_string system_message_names[] = {
53
    { 12337, "Startup" },   /* 0x3031 */
54
    { 12336, "Shutdown" },  /* 0x3030 */
55
    { 12339, "Heartbeat" }, /* 0x3033 */
56
    { 0, NULL }
57
};
58
59
static int
60
dissect_fmtp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
61
7
{
62
7
    uint8_t     packet_type;
63
7
    uint16_t    packet_len;
64
7
    tvbuff_t   *next_tvb;
65
7
    proto_item *ti = NULL;
66
7
    proto_tree *fmtp_tree = NULL;
67
68
7
    packet_type = tvb_get_uint8(tvb, 4);
69
7
    packet_len  = tvb_get_ntohs(tvb, 2);
70
71
7
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FMTP");
72
73
    /* Clear out stuff in the info column */
74
7
    col_clear(pinfo->cinfo, COL_INFO);
75
76
7
    ti = proto_tree_add_item(tree, proto_fmtp, tvb, 0, -1, ENC_NA);
77
7
    proto_item_append_text(ti, ", %s",
78
7
        val_to_str(pinfo->pool, packet_type, packet_type_names, "Unknown (0x%02x)"));
79
80
7
    switch (packet_type) {
81
82
0
        case FMTP_TYP_IDENTIFICATION:
83
0
            proto_item_append_text(ti, " (%s)",
84
0
                tvb_get_string_enc(pinfo->pool, tvb, FMTP_HEADER_LEN, packet_len-FMTP_HEADER_LEN, ENC_ASCII));
85
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%s)",
86
0
                val_to_str(pinfo->pool, packet_type, packet_type_names, "Unknown (0x%02x)"),
87
0
                tvb_get_string_enc(pinfo->pool, tvb, FMTP_HEADER_LEN, packet_len-FMTP_HEADER_LEN, ENC_ASCII));
88
0
            break;
89
90
0
        case FMTP_TYP_SYSTEM:
91
0
            proto_item_append_text(ti, " (%s)",
92
0
                tvb_get_string_enc(pinfo->pool, tvb, FMTP_HEADER_LEN, packet_len-FMTP_HEADER_LEN, ENC_ASCII));
93
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%s)",
94
0
                val_to_str(pinfo->pool, packet_type, packet_type_names, "Unknown (0x%02x)"),
95
0
                val_to_str(pinfo->pool, tvb_get_ntohs(tvb, FMTP_HEADER_LEN), system_message_names, "Unknown (0x%02x)"));
96
0
            break;
97
98
7
        default:
99
7
            col_add_str(pinfo->cinfo, COL_INFO,
100
7
                val_to_str(pinfo->pool, packet_type, packet_type_names, "Unknown (0x%02x)"));
101
7
            break;
102
7
    }
103
7
    if (tree) { /* we are being asked for details */
104
7
        fmtp_tree = proto_item_add_subtree(ti, ett_fmtp);
105
7
        proto_tree_add_item(fmtp_tree, hf_fmtp_pdu_version,  tvb, 0, 1, ENC_BIG_ENDIAN);
106
7
        proto_tree_add_item(fmtp_tree, hf_fmtp_pdu_reserved, tvb, 1, 1, ENC_BIG_ENDIAN);
107
7
        proto_tree_add_item(fmtp_tree, hf_fmtp_pdu_length,   tvb, 2, 2, ENC_BIG_ENDIAN);
108
7
        proto_tree_add_item(fmtp_tree, hf_fmtp_pdu_type,     tvb, 4, 1, ENC_BIG_ENDIAN);
109
110
7
        next_tvb = tvb_new_subset_remaining(tvb, FMTP_HEADER_LEN);
111
7
        call_data_dissector(next_tvb, pinfo, fmtp_tree);
112
7
    }
113
114
7
    return tvb_captured_length(tvb);
115
7
}
116
117
static unsigned
118
get_fmtp_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
119
7
{
120
7
    return (unsigned)tvb_get_ntohs(tvb, offset+2);
121
7
}
122
123
static bool
124
dissect_fmtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
125
1.97k
{
126
1.97k
    uint16_t length;
127
128
1.97k
    if (tvb_captured_length(tvb) < 5)
129
76
        return false;
130
    /*
131
     * Check that packet looks like FMTP before going further
132
     */
133
    /* VERSION must currently be 0x02 */
134
1.90k
    if (tvb_get_uint8(tvb, 0) != 0x02) return false;
135
    /* RESERVED must currently be 0x00 */
136
61
    if (tvb_get_uint8(tvb, 1) != 0x00) return false;
137
12
    length = tvb_get_ntohs(tvb, 2);
138
    /* LENGTH must currently not exceed 5 (header) + 10240 (data) */
139
12
    if ((length > FMTP_MAX_LEN) || (length < FMTP_HEADER_LEN)) return false;
140
    /* TYP must currently be in range 0x01-0x04 */
141
7
    if ((tvb_get_uint8(tvb, 4) < 0x01) || (tvb_get_uint8(tvb, 4) > 0x04))
142
3
        return false;
143
144
4
    tcp_dissect_pdus(tvb, pinfo, tree, true, FMTP_HEADER_LEN,
145
4
                     get_fmtp_message_len, dissect_fmtp_message, data);
146
4
    return true;
147
7
}
148
149
void
150
proto_register_fmtp(void)
151
14
{
152
14
    static hf_register_info hf[] = {
153
14
        { &hf_fmtp_pdu_version,
154
14
            { "Version", "fmtp.version",
155
14
            FT_UINT8, BASE_DEC,
156
14
            NULL, 0x0,
157
14
            NULL, HFILL }
158
14
        },
159
14
        { &hf_fmtp_pdu_reserved,
160
14
            { "Reserved", "fmtp.reserved",
161
14
            FT_UINT8, BASE_DEC,
162
14
            NULL, 0x0,
163
14
            NULL, HFILL }
164
14
        },
165
14
        { &hf_fmtp_pdu_length,
166
14
            { "Length", "fmtp.length",
167
14
            FT_UINT16, BASE_DEC,
168
14
            NULL, 0x0,
169
14
            NULL, HFILL }
170
14
        },
171
14
        { &hf_fmtp_pdu_type,
172
14
            { "Type", "fmtp.type",
173
14
            FT_UINT8, BASE_DEC,
174
14
            VALS(packet_type_names), 0x0,
175
14
            NULL, HFILL }
176
14
        }
177
14
    };
178
179
    /* Setup protocol subtree array */
180
14
    static int *ett[] = {
181
14
        &ett_fmtp
182
14
    };
183
184
14
    proto_fmtp = proto_register_protocol("Flight Message Transfer Protocol (FMTP)", "FMTP", "fmtp");
185
186
14
    proto_register_field_array(proto_fmtp, hf, array_length(hf));
187
14
    proto_register_subtree_array(ett, array_length(ett));
188
14
}
189
190
void
191
proto_reg_handoff_fmtp(void)
192
14
{
193
    /* Register as heuristic dissector for TCP */
194
14
    heur_dissector_add("tcp", dissect_fmtp, "FMTP over TCP", "fmtp_tcp", proto_fmtp, HEURISTIC_ENABLE);
195
14
}
196
197
/*
198
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
199
 *
200
 * Local variables:
201
 * c-basic-offset: 4
202
 * tab-width: 8
203
 * indent-tabs-mode: nil
204
 * End:
205
 *
206
 * vi: set shiftwidth=4 tabstop=8 expandtab:
207
 * :indentSize=4:tabSize=8:noTabs=true:
208
 */
209