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-rtitcp.c
Line
Count
Source
1
/* packet-rtitcp.c
2
 * Dissector for the RTI TCP Transport Protocol.
3
 * Layer on top of TCP used to send Control messages
4
 * to establish and maintain the connections as well as
5
 * send RTPS data.
6
 *
7
 * (c) 2005-2015 Copyright, Real-Time Innovations, Inc.
8
 * Real-Time Innovations, Inc.
9
 * 232 East Java Drive
10
 * Sunnyvale, CA 94089
11
 *
12
 * Wireshark - Network traffic analyzer
13
 * By Gerald Combs <gerald@wireshark.org>
14
 * Copyright 1998 Gerald Combs
15
 *
16
 * SPDX-License-Identifier: GPL-2.0-or-later
17
 */
18
19
#include "config.h"
20
21
#include <epan/packet.h>
22
#include <epan/expert.h>
23
#include <epan/prefs.h>
24
#include <epan/addr_resolv.h>
25
#include <epan/wmem_scopes.h>
26
#include <epan/conversation.h>
27
28
#include <wsutil/ws_padding_to.h>
29
30
#include "packet-tcp.h"
31
32
2.64k
#define RTITCP_MAGIC_NUMBER             0xdd54dd55
33
0
#define RTPS_MAGIC_NUMBER               0x52545053
34
0
#define RTITCP_CONTROL_MAGIC_COOKIE     0x2112A442
35
0
#define RTITCP_CRC_MAGIC_NUMBER         0x43524332
36
37
/* A sample #define of the minimum length (in bytes) of the protocol data.
38
 * If data is received with fewer than this many bytes it is rejected by
39
 * the current dissector. */
40
0
#define RTITCP_MIN_LENGTH 8
41
0
#define NUMBER_2E30 1073741824
42
43
#define IDENTITY_BIND_REQUEST                           (0x0C01)
44
#define IDENTITY_BIND_INDICATION                        (0x0C11)
45
#define IDENTITY_BIND_RESPONSE                          (0x0D01)
46
#define IDENTITY_BIND_ERROR                             (0x0D11)
47
48
#define SERVER_LOGICAL_PORT_REQUEST                     (0x0C02)
49
#define SERVER_LOGICAL_PORT_INDICATION                  (0x0C12)
50
#define SERVER_LOGICAL_PORT_RESPONSE                    (0x0D02)
51
#define SERVER_LOGICAL_PORT_ERROR                       (0x0D12)
52
53
#define CLIENT_LOGICAL_PORT_REQUEST                     (0x0C03)
54
#define CLIENT_LOGICAL_PORT_INDICATION                  (0x0C13)
55
#define CLIENT_LOGICAL_PORT_RESPONSE                    (0x0D03)
56
#define CLIENT_LOGICAL_PORT_ERROR                       (0x0D13)
57
58
#define CONNECTION_BIND_REQUEST                         (0x0C04)
59
#define CONNECTION_BIND_INDICATION                      (0x0C14)
60
#define CONNECTION_BIND_RESPONSE                        (0x0D04)
61
#define CONNECTION_BIND_ERROR                           (0x0D14)
62
63
#define SESSION_ID_REQUEST                              (0x0C05)
64
#define SESSION_ID_INDICATION                           (0x0C15)
65
#define SESSION_ID_RESPONSE                             (0x0D05)
66
#define SESSION_ID_ERROR                                (0x0D15)
67
68
#define LIVELINESS_REQUEST                              (0x0C06)
69
#define LIVELINESS_RESPONSE                             (0x0D06)
70
71
#define FINALIZE_SESSION_REQUEST                        (0x0C0F)
72
#define FINALIZE_SESSION_INDICATION                     (0x0C1F)
73
#define FINALIZE_SESSION_RESPONSE                       (0x0D0F)
74
#define FINALIZE_SESSION_ERRROR                         (0x0D1F)
75
76
0
#define LOCATOR_KIND_IPV4                               (1)
77
0
#define LOCATOR_KIND_IPV6                               (2)
78
79
0
#define RTPS_LOCATOR_ADDRESS_ATTRIBUTE_TYPE             (0x3D01)
80
0
#define RTPS_LOCATOR_PORT_ATTRIBUTE_TYPE                (0x3D02)
81
0
#define CONNECTION_TYPE_ATTRIBUTE_TYPE                  (0x3D03)
82
0
#define CONNECTION_COOKIE_ATTRIBUTE_TYPE                (0x3D04)
83
#define PORT_OPTIONS_ATTRIBUTE_TYPE                     (0x3D05)
84
#define TRANSPORT_PRIORITY_ATTRIBUTE_TYPE               (0x3D06)
85
0
#define SESSION_ID_ATTRIBUTE_TYPE                       (0x3D07)
86
87
#define MAPPED_ADDRESS_ATTRIBUTE_TYPE                   (0x0001)
88
#define XOR_MAPPED_ADDRESS_ATTRIBUTE_TYPE               (0x0020)
89
0
#define ERROR_CODE_ATTRIBUTE_TYPE                       (0x0009)
90
#define UNKNOWN_ATTRIBUTES_ATTRIBUTE_TYPE               (0x000A)
91
92
#define SOFTWARE_ATTRIBUTE_TYPE                         (0x8022)
93
#define ALTERNATE_SERVER_ATTRIBUTE_TYPE                 (0x8023)
94
95
#define CLASS_ID_TCPV4_LAN                              (0x00)
96
#define CLASS_ID_TCPV4_WAN                              (0x40)
97
#define CLASS_ID_TLSV4_LAN                              (0x80)
98
#define CLASS_ID_TLSV4_WAN                              (0xC0)
99
100
101
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_OK                                              0
102
/* client requested a transport class not supported by the server */
103
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_TRANSPORT_CLASS_MISMATCH                  1
104
/* required attribute is missing */
105
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_ATTRIBUTE_MISSING                         2
106
/* no matching receive resource for requested port */
107
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_NO_MATCHING_RECVRESOURCE                  3
108
/* no matching cookie found on server */
109
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_NO_MATCH_COOKIE                           4
110
/* fatal internal processing error (caller is not responsible) */
111
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_INTERNAL                                  5
112
/* the operation should be retried at the first occurrence */
113
#define NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_RETRY                                     6
114
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_BAD_REQUEST_ID                        400
115
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_UNKNOWN_ATTRIBUTE_ID                  420
116
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_ALLOCATION_MISMATCH_ID                437
117
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_UNSUPPORTED_TRANSPORT_PROTOCOL_ID     442
118
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_CONNECTION_ALREADY_EXISTS_ID          446
119
#define NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_SERVER_ERROR_ID                       500
120
121
/* Forward declaration that is needed below if using the
122
 * proto_reg_handoff_rtitcp function as a callback for when protocol
123
 * preferences get changed. For now we don't have preferences but we
124
 * may have them in the future.*/
125
126
void proto_reg_handoff_rtitcp(void);
127
void proto_register_rtitcp(void);
128
129
/* Initialize the protocol and registered fields */
130
static int proto_rtitcp;
131
static int hf_rtitcp_header_control_byte;
132
static int hf_rtitcp_header_magic_number;
133
static int hf_rtitcp_header_message_length;
134
static int hf_rtitcp_control_transaction_id;
135
static int hf_rtitcp_control_kind;
136
static int hf_rtitcp_control_attribute_type;
137
static int hf_rtitcp_control_attribute_length;
138
static int hf_rtitcp_control_attribute_port;
139
static int hf_rtitcp_attributes_list_length;
140
static int hf_rtitcp_control_magic_cookie;
141
static int hf_rtitcp_control_attribute_connection_cookie;
142
static int hf_rtitcp_control_attribute_connection_type;
143
static int hf_rtitcp_control_attribute_session_id;
144
static int hf_rtitcp_control_attribute_error_code_value;
145
static int hf_rtitcp_control_attribute_error_code_description;
146
static int hf_rtitcp_locator_ipv4;
147
static int hf_rtitcp_locator_port;
148
static int hf_rtitcp_locator_ipv6;
149
static int hf_rtitcp_locator_kind;
150
static int hf_rtitcp_crc_magic_cookie;
151
static int hf_rtitcp_control_crc_value;
152
153
static int hf_rtitcp_response_in;
154
static int hf_rtitcp_response_to;
155
static int hf_rtitcp_response_time;
156
157
0
#define RTITCP_FLAG_NOT_REQUEST 0x0100
158
159
typedef struct _rtitcp_transaction_t {
160
    uint32_t req_frame;
161
    uint32_t rep_frame;
162
    nstime_t req_time;
163
} rtitcp_transaction_t;
164
165
typedef struct _rtitcp_conv_info_t {
166
    wmem_map_t *pdus;
167
} rtitcp_conv_info_t;
168
169
/* Subtree pointers */
170
static int ett_rtitcp;
171
static int ett_rtitcp_signalling_protocol;
172
static int ett_rtitcp_message;
173
static int ett_rtitcp_attributes_list;
174
static int ett_rtitcp_attribute;
175
176
static header_field_info *hfi_rtitcp;
177
static heur_dissector_list_t heur_subdissector_list;
178
179
static const value_string ctrl_message_types_vals[] = {
180
    { IDENTITY_BIND_REQUEST,                    "Identity Bind Request" },
181
    { IDENTITY_BIND_INDICATION,                 "Identity Bind Indication" },
182
    { IDENTITY_BIND_RESPONSE,                   "Identity Bind Response" },
183
    { IDENTITY_BIND_ERROR,                      "Identity Bind Error" },
184
    { SERVER_LOGICAL_PORT_REQUEST,              "Server Logical Port Request" },
185
    { SERVER_LOGICAL_PORT_RESPONSE,             "Server Logical Port Response" },
186
    { SERVER_LOGICAL_PORT_ERROR,                "Server Logical Port Error" },
187
    { CLIENT_LOGICAL_PORT_REQUEST,              "Client Logical Port Request" },
188
    { CLIENT_LOGICAL_PORT_RESPONSE,             "Client Logical Port Response" },
189
    { CLIENT_LOGICAL_PORT_ERROR,                "Client Logical Port Error" },
190
    { CONNECTION_BIND_REQUEST,                  "Connection Bind Request" },
191
    { CONNECTION_BIND_RESPONSE,                 "Connection Bind Response" },
192
    { CONNECTION_BIND_ERROR,                    "Connection Bind Error" },
193
    { SESSION_ID_REQUEST,                       "Session ID Request" },
194
    { SESSION_ID_INDICATION,                    "Session ID Indication" },
195
    { SESSION_ID_RESPONSE,                      "Session ID Response" },
196
    { SESSION_ID_ERROR,                         "Session ID Error" },
197
    { LIVELINESS_REQUEST,                       "Liveliness Request" },
198
    { LIVELINESS_RESPONSE,                      "Liveliness Response" },
199
    { FINALIZE_SESSION_INDICATION,              "Finalize Session Indication" },
200
    { 0, NULL }
201
};
202
203
static const value_string attribute_types_vals[] = {
204
    { RTPS_LOCATOR_ADDRESS_ATTRIBUTE_TYPE,    "Locator Address" },
205
    { RTPS_LOCATOR_PORT_ATTRIBUTE_TYPE,       "Locator Port" },
206
    { CONNECTION_TYPE_ATTRIBUTE_TYPE,         "Connection Type" },
207
    { CONNECTION_COOKIE_ATTRIBUTE_TYPE,       "Connection Cookie" },
208
    { PORT_OPTIONS_ATTRIBUTE_TYPE,            "Port options" },
209
    { TRANSPORT_PRIORITY_ATTRIBUTE_TYPE,      "Transport priority" },
210
    { SESSION_ID_ATTRIBUTE_TYPE,              "Session ID" },
211
    { MAPPED_ADDRESS_ATTRIBUTE_TYPE,          "Mapped Address" },
212
    { XOR_MAPPED_ADDRESS_ATTRIBUTE_TYPE,      "XOR Mapped Address" },
213
    { ERROR_CODE_ATTRIBUTE_TYPE,              "Error Code" },
214
    { UNKNOWN_ATTRIBUTES_ATTRIBUTE_TYPE,      "Unknown attribute" },
215
    { SOFTWARE_ATTRIBUTE_TYPE,                "Software" },
216
    { ALTERNATE_SERVER_ATTRIBUTE_TYPE,        "Alternate Server" },
217
    { 0, NULL }
218
};
219
220
static const value_string error_code_kind_vals[] = {
221
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_OK,
222
      "PROTOCOL_OK" },
223
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_TRANSPORT_CLASS_MISMATCH,
224
      "PROTOCOL_ERROR_TRANSPORT_CLASS_MISMATCH" },
225
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_ATTRIBUTE_MISSING,
226
      "PROTOCOL_ERROR_ATTRIBUTE_MISSING" },
227
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_NO_MATCHING_RECVRESOURCE,
228
      "PROTOCOL_ERROR_NO_MATCHING_RECVRESOURCE" },
229
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_NO_MATCH_COOKIE,
230
      "PROTOCOL_ERROR_NO_MATCH_COOKIE" },
231
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_INTERNAL,
232
      "PROTOCOL_ERROR_INTERNAL" },
233
    { NDDS_TRANSPORT_TCPV4_CONTROL_PROTOCOL_ERROR_RETRY,
234
      "PROTOCOL_ERROR_RETRY" },
235
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_BAD_REQUEST_ID,
236
      "ERROR_CODE_ATTRIBUTE_BAD_REQUEST_ID" },
237
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_UNKNOWN_ATTRIBUTE_ID,
238
      "ERROR_CODE_ATTRIBUTE_UNKNOWN_ATTRIBUTE_ID" },
239
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_ALLOCATION_MISMATCH_ID,
240
      "ERROR_CODE_ATTRIBUTE_ALLOCATION_MISMATCH_ID" },
241
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_UNSUPPORTED_TRANSPORT_PROTOCOL_ID,
242
      "ERROR_CODE_ATTRIBUTE_UNSUPPORTED_TRANSPORT_PROTOCOL_ID" },
243
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_CONNECTION_ALREADY_EXISTS_ID,
244
      "ERROR_CODE_ATTRIBUTE_CONNECTION_ALREADY_EXISTS_ID" },
245
    { NDDS_TRANSPORT_TCP_CONTROL_ERROR_CODE_ATTRIBUTE_SERVER_ERROR_ID,
246
      "ERROR_CODE_ATTRIBUTE_SERVER_ERROR_ID" },
247
    { 0, NULL }
248
};
249
250
static const value_string rtitcp_locator_kind_vals[] = {
251
    { LOCATOR_KIND_IPV4,        "IPV4" },
252
    { LOCATOR_KIND_IPV6,        "Unreachable peer" },
253
    { 0, NULL }
254
};
255
256
static const value_string rtitcp_attribute_connection_type_vals[] = {
257
    { CLASS_ID_TCPV4_LAN,        "TCPV4_LAN" },
258
    { CLASS_ID_TCPV4_WAN,        "TCPV4_WAN" },
259
    { CLASS_ID_TLSV4_LAN,        "TLSV4_LAN" },
260
    { CLASS_ID_TLSV4_WAN,        "TLSV4_WAN" },
261
    { 0, NULL }
262
};
263
264
static void rtitcp_util_add_error_attribute(proto_tree *attribute, tvbuff_t* tvb,
265
0
                             int offset, unsigned size) {
266
0
    proto_tree_add_item(attribute, hf_rtitcp_control_attribute_error_code_value, tvb, offset, 4, ENC_BIG_ENDIAN);
267
0
    proto_tree_add_item(attribute, hf_rtitcp_control_attribute_error_code_description, tvb, offset + 4,
268
0
            size - 4, ENC_ASCII);
269
0
}
270
271
static void rtitcp_util_add_locator_t(proto_tree *tree, packet_info *pinfo _U_, tvbuff_t * tvb,
272
                             int offset, bool little_endian,
273
0
                             proto_item * rtitcp_message, bool * first_attribute) {
274
0
    int32_t kind;
275
0
    uint16_t port;
276
0
    kind = tvb_get_uint16(tvb, offset+8, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
277
278
0
    if (kind == 0xFFFF) {
279
0
        kind = LOCATOR_KIND_IPV4;
280
0
    } else {
281
0
        kind = LOCATOR_KIND_IPV6;
282
0
    }
283
0
    proto_tree_add_uint(tree, hf_rtitcp_locator_kind, tvb, offset+8, 2, kind);
284
285
0
    if (kind == LOCATOR_KIND_IPV4) {
286
0
        proto_tree_add_item(tree, hf_rtitcp_locator_port, tvb, offset+10, 2, ENC_BIG_ENDIAN);
287
0
        proto_tree_add_item(tree, hf_rtitcp_locator_ipv4, tvb, offset+12, 4, ENC_BIG_ENDIAN);
288
289
0
        port = tvb_get_uint16(tvb, offset+10, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
290
0
        if (*first_attribute) {
291
0
            proto_item_append_text(rtitcp_message," (");
292
0
            col_append_str(pinfo->cinfo, COL_INFO, " (");
293
0
        }
294
0
        proto_item_append_text(rtitcp_message, "%s%s:%u",
295
0
            *first_attribute ? "" : ", ", tvb_ip_to_str(pinfo->pool, tvb, offset + 12), port);
296
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s:%u",
297
0
                *first_attribute ? "" : ", ", tvb_ip_to_str(pinfo->pool, tvb, offset + 12), port);
298
0
    } else {
299
0
        proto_tree_add_item(tree, hf_rtitcp_locator_ipv6, tvb, offset, 16, ENC_NA);
300
0
        if (*first_attribute) {
301
0
            proto_item_append_text(rtitcp_message," (");
302
0
            col_append_str(pinfo->cinfo, COL_INFO, " (");
303
0
        }
304
0
        proto_item_append_text(rtitcp_message, "%s%s",
305
0
            *first_attribute ? "" : ", ", tvb_ip6_to_str(pinfo->pool, tvb, offset));
306
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
307
0
                *first_attribute ? "" : ", ", tvb_ip6_to_str(pinfo->pool, tvb, offset));
308
0
    }
309
0
}
310
311
static unsigned dissect_attribute(tvbuff_t *tvb, packet_info *pinfo,
312
        proto_tree *attributes_list, unsigned offset, unsigned attributes_list_offset,
313
0
        proto_item * rtitcp_message, bool * first_attribute) {
314
315
0
    uint16_t attribute_length, attribute_type;
316
0
    unsigned padding;
317
0
    proto_item *attribute;
318
319
0
    attribute_type = tvb_get_uint16(tvb, attributes_list_offset+offset, ENC_BIG_ENDIAN);
320
0
    attribute_length = tvb_get_uint16(tvb, attributes_list_offset+offset+2, ENC_BIG_ENDIAN);
321
322
0
    attribute = proto_tree_add_subtree_format(attributes_list, tvb,
323
0
            attributes_list_offset+offset, attribute_length+4,
324
0
            ett_rtitcp_attribute, NULL, "Unknown Attribute");
325
326
0
    proto_tree_add_item(attribute, hf_rtitcp_control_attribute_type, tvb,
327
0
            attributes_list_offset+offset, 2, ENC_BIG_ENDIAN);
328
0
    proto_tree_add_item(attribute, hf_rtitcp_control_attribute_length, tvb,
329
0
            attributes_list_offset+offset+2, 2, ENC_BIG_ENDIAN);
330
0
    proto_item_set_text(attribute,"%s", val_to_str_const(attribute_type, attribute_types_vals, "Unknown attribute"));
331
332
0
    switch (attribute_type) {
333
0
        case RTPS_LOCATOR_PORT_ATTRIBUTE_TYPE: {
334
0
            uint32_t port;
335
0
            port = tvb_get_uint32(tvb, attributes_list_offset+offset+4, ENC_BIG_ENDIAN);
336
0
            if (*first_attribute) {
337
0
                proto_item_append_text(rtitcp_message," (");
338
0
                col_append_str(pinfo->cinfo, COL_INFO, " (");
339
0
            }
340
0
            proto_item_append_text(rtitcp_message, "%s%u",
341
0
                    *first_attribute ? "" : ", ", port);
342
0
            col_append_fstr(pinfo->cinfo, COL_INFO, "%s%u",
343
0
                    *first_attribute ? "" : ", ", port);
344
0
            (*first_attribute) = false;
345
0
            proto_item_append_text(attribute, " (Port = %u)", port);
346
0
            proto_tree_add_item(attribute, hf_rtitcp_control_attribute_port, tvb,
347
0
                    attributes_list_offset+offset+4, attribute_length, ENC_BIG_ENDIAN);
348
0
            break;
349
0
        }
350
0
        case RTPS_LOCATOR_ADDRESS_ATTRIBUTE_TYPE: {
351
0
            rtitcp_util_add_locator_t(attribute, pinfo, tvb, attributes_list_offset+offset+4,
352
0
                                ENC_BIG_ENDIAN, rtitcp_message, first_attribute);
353
0
            (*first_attribute) = false;
354
0
            break;
355
0
        }
356
357
0
        case CONNECTION_COOKIE_ATTRIBUTE_TYPE: {
358
0
            proto_tree_add_item(attribute, hf_rtitcp_control_attribute_connection_cookie,
359
0
                    tvb, attributes_list_offset+offset+4, attribute_length, ENC_NA);
360
0
            if (*first_attribute) {
361
0
                proto_item_append_text(rtitcp_message," (");
362
0
                col_append_str(pinfo->cinfo, COL_INFO, " (");
363
0
            }
364
0
            proto_item_append_text(rtitcp_message, "%s%s",
365
0
                (*first_attribute) ? "" : ", ",
366
0
                tvb_bytes_to_str(pinfo->pool, tvb, attributes_list_offset+offset+4, 16));
367
0
            col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
368
0
                (*first_attribute) ? "" : ", ",
369
0
                tvb_bytes_to_str(pinfo->pool, tvb, attributes_list_offset+offset+4, 16));
370
0
            (*first_attribute) = false;
371
0
            break;
372
0
        }
373
0
        case CONNECTION_TYPE_ATTRIBUTE_TYPE: {
374
0
            uint8_t attribute_connection_type = tvb_get_uint8(tvb, attributes_list_offset+offset+4);
375
0
            proto_tree_add_item(attribute, hf_rtitcp_control_attribute_connection_type, tvb,
376
0
                    attributes_list_offset+offset+4, attribute_length, ENC_BIG_ENDIAN);
377
0
            if (*first_attribute) {
378
0
                proto_item_append_text(rtitcp_message," (");
379
0
                col_append_str(pinfo->cinfo, COL_INFO, " (");
380
0
            }
381
0
            proto_item_append_text(rtitcp_message, "%s%s",
382
0
                (*first_attribute) ? "" : ", ",
383
0
                val_to_str_const(attribute_connection_type, rtitcp_attribute_connection_type_vals, "Unknown attribute"));
384
0
            col_append_fstr(pinfo->cinfo, COL_INFO, "%s%s",
385
0
                (*first_attribute) ? "" : ", ",
386
0
                val_to_str_const(attribute_connection_type, rtitcp_attribute_connection_type_vals, "Unknown attribute"));
387
0
            (*first_attribute) = false;
388
0
            break;
389
0
        }
390
0
        case SESSION_ID_ATTRIBUTE_TYPE: {
391
0
            proto_tree_add_item(attribute, hf_rtitcp_control_attribute_session_id, tvb,
392
0
                    attributes_list_offset+offset+4, attribute_length, ENC_NA);
393
0
            break;
394
0
        }
395
0
        case ERROR_CODE_ATTRIBUTE_TYPE: {
396
0
            rtitcp_util_add_error_attribute(attribute, tvb, attributes_list_offset+offset+4, attribute_length);
397
0
            break;
398
0
        }
399
0
        default:
400
0
            break;
401
0
    }
402
403
0
    padding = WS_PADDING_TO_4(attribute_length);
404
0
    return (attribute_length+padding+4);
405
0
}
406
static proto_tree* print_header(proto_tree *tree, proto_tree *rtitcp_message, tvbuff_t *tvb, unsigned offset,
407
0
                                    uint16_t msg_length, bool printCRC, bool is_data) {
408
0
    proto_item *ti;
409
410
0
    if (is_data) {
411
0
        rtitcp_message = proto_tree_add_subtree_format(tree, tvb, offset, msg_length,
412
0
            ett_rtitcp_message, NULL, "RTI TCP Data Message");
413
0
    } else {
414
0
        rtitcp_message = proto_tree_add_subtree_format(tree, tvb, offset, msg_length,
415
0
            ett_rtitcp_message, NULL, "RTI TCP Control Message");
416
0
    }
417
0
    if (is_data) {
418
0
        uint32_t msg_length32;
419
0
        proto_tree_add_item(rtitcp_message, hf_rtitcp_header_control_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
420
0
        ti = proto_tree_add_item(rtitcp_message, hf_rtitcp_header_message_length,
421
0
                tvb, offset+1, 3, ENC_BIG_ENDIAN);
422
0
        msg_length32 = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
423
0
        msg_length32 = msg_length32 % NUMBER_2E30;
424
0
        proto_item_set_text(ti,"RTI TCP Message Length: %d", msg_length32);
425
0
    } else {
426
0
        proto_tree_add_item(rtitcp_message, hf_rtitcp_header_control_byte, tvb, offset, 2, ENC_BIG_ENDIAN);
427
0
        proto_tree_add_item(rtitcp_message, hf_rtitcp_header_message_length, tvb, offset+2, 2, ENC_BIG_ENDIAN);
428
0
    }
429
0
    proto_tree_add_item(rtitcp_message, hf_rtitcp_header_magic_number, tvb, offset+4, 4, ENC_BIG_ENDIAN);
430
0
    if (printCRC) {
431
0
        proto_tree_add_item(rtitcp_message, hf_rtitcp_crc_magic_cookie, tvb, offset+8, 4, ENC_BIG_ENDIAN);
432
0
        proto_tree_add_item(rtitcp_message, hf_rtitcp_control_crc_value, tvb, offset+12, 4, ENC_BIG_ENDIAN);
433
0
    }
434
435
0
    return rtitcp_message;
436
0
}
437
static uint16_t dissect_control_message(proto_tree *rtitcp_tree, tvbuff_t *tvb, packet_info *pinfo,
438
0
                                  unsigned offset) {
439
440
   /* 0...2...........7...............15.............23...............31
441
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
442
   * |            Not Used           |           msg_length          |
443
   * +---------------+---------------+---------------+---------------+
444
   * |                      RTITCP_MAGIC_NUMBER                      |
445
   * +---------------+---------------+---------------+---------------+
446
   * |      control_message_kind     |    attributes_list_length     |
447
   * +---------------+---------------+---------------+---------------+
448
   * |                   RTITCP_CONTROL_MAGIC_COOKIE                 |
449
   * +---------------+---------------+---------------+---------------+
450
   * |                                                               |
451
   * |-                                                             -|
452
   * |                         TRANSACTION_ID                        |
453
   * |-                                                             -|
454
   * |                                                               |
455
   * +---------------+---------------+---------------+---------------+   ---------------------------------
456
   * |       attribute_type          |       attribute_length ..         Repeat                          |
457
   * +---------------+---------------+---------------+---------------+   until                           |
458
   * |                       ATTRIBUTE (length)                      |   attributes_list_length expires  |
459
   * +---------------+---------------+---------------+---------------+   --------------------------------*/
460
461
0
    proto_tree  *attributes_list, *rtitcp_message = NULL;
462
0
    uint16_t msg_length, control_message_kind, attributes_list_length, header_length;
463
0
    unsigned attributes_list_offset, attribute_offset, offset_header = offset;
464
0
    unsigned attributes_count;
465
0
    bool is_data = false, printCRC = false, first_attribute;
466
0
    char * transaction_id_str;
467
0
    uint64_t seq_num;
468
0
    conversation_t *conversation;
469
0
    rtitcp_conv_info_t *rtitcp_info;
470
0
    rtitcp_transaction_t *rtitcp_trans;
471
0
    uint64_t * conversation_info_key = NULL;
472
473
    /* The header length is 8 if it doesn't contain optional fields */
474
0
    header_length = 8;
475
476
0
    msg_length = tvb_get_uint16(tvb, offset+2, ENC_BIG_ENDIAN);
477
0
    offset += 8;
478
479
    /* Check if CRC is present */
480
0
    if (tvb_get_ntohl(tvb, offset) == RTITCP_CRC_MAGIC_NUMBER) {
481
0
        printCRC = true;
482
0
        header_length += 8;
483
0
        offset += 8; /* Because of 0xCRC32 + actual CRC (4 bytes) */
484
0
    }
485
486
    /* Time to print the header */
487
0
    rtitcp_message = print_header(rtitcp_tree, rtitcp_message, tvb, offset_header, msg_length + header_length, printCRC, is_data);
488
489
    /* Check the control message kind */
490
0
    control_message_kind = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
491
0
    col_append_sep_str(pinfo->cinfo, COL_INFO, ", ",
492
0
                val_to_str_const(control_message_kind,ctrl_message_types_vals, "Unknown control message"));
493
0
    proto_tree_add_uint(rtitcp_message, hf_rtitcp_control_kind, tvb, offset, 2, control_message_kind);
494
0
    proto_item_set_text(rtitcp_message,"RTI TCP Control Message , Kind: %s",
495
0
            val_to_str_const(control_message_kind,ctrl_message_types_vals, "Unknown control message"));
496
0
    offset += 2;
497
498
    /* Take the length in bytes of the attributes list */
499
0
    attributes_list_length = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
500
0
    proto_tree_add_item(rtitcp_message, hf_rtitcp_attributes_list_length, tvb, offset, 2, ENC_BIG_ENDIAN);
501
0
    offset += 2;
502
503
    /* We expect now the RTI TCP Control Magic Cookie */
504
0
    if (tvb_get_ntohl(tvb, offset) != RTITCP_CONTROL_MAGIC_COOKIE) {
505
0
        return msg_length + header_length;
506
0
    }
507
0
    proto_tree_add_item(rtitcp_message, hf_rtitcp_control_magic_cookie, tvb, offset, 4, ENC_BIG_ENDIAN);
508
0
    offset += 4;
509
510
    /* Now we dissect the transaction id */
511
0
    proto_tree_add_item(rtitcp_message, hf_rtitcp_control_transaction_id, tvb, offset, 12, ENC_NA);
512
0
    transaction_id_str = tvb_bytes_to_str(pinfo->pool, tvb, offset, 12);
513
514
    /* Get the transaction identifier. Not the whole transaction but the middle part, which
515
     * shouldn't coincide */
516
0
    seq_num = tvb_get_ntoh64(tvb, offset);
517
518
    /*
519
     * We need to track some state for this protocol on a per conversation
520
     * basis so we can do neat things like request/response tracking
521
     */
522
0
    conversation = find_or_create_conversation(pinfo);
523
524
0
    rtitcp_info = (rtitcp_conv_info_t *)conversation_get_proto_data(conversation, proto_rtitcp);
525
0
    if (!rtitcp_info) {
526
        /*
527
         * No.  Attach that information to the conversation, and add
528
         * it to the list of information structures.
529
         */
530
0
        rtitcp_info = wmem_new(wmem_file_scope(), rtitcp_conv_info_t);
531
0
        rtitcp_info->pdus=wmem_map_new(wmem_file_scope(), g_int64_hash, g_int64_equal);
532
533
0
        conversation_add_proto_data(conversation, proto_rtitcp, rtitcp_info);
534
0
    }
535
0
    if (!pinfo->fd->visited) {
536
0
        if (!(control_message_kind & RTITCP_FLAG_NOT_REQUEST)) {
537
            /* This is a request */
538
0
            rtitcp_trans=wmem_new(wmem_file_scope(), rtitcp_transaction_t);
539
0
            rtitcp_trans->req_frame = pinfo->num;
540
0
            rtitcp_trans->rep_frame = 0;
541
0
            rtitcp_trans->req_time = pinfo->abs_ts;
542
0
            conversation_info_key = wmem_new0(wmem_file_scope(), uint64_t);
543
0
            *conversation_info_key = seq_num;
544
0
            wmem_map_insert(rtitcp_info->pdus, conversation_info_key, (void *)rtitcp_trans);
545
0
        } else {
546
0
            conversation_info_key = &seq_num;
547
0
            rtitcp_trans=(rtitcp_transaction_t *)wmem_map_lookup(rtitcp_info->pdus, conversation_info_key);
548
0
            if (rtitcp_trans) {
549
0
                rtitcp_trans->rep_frame = pinfo->num;
550
0
            }
551
0
        }
552
0
    } else {
553
0
        conversation_info_key = &seq_num;
554
0
        rtitcp_trans=(rtitcp_transaction_t *)wmem_map_lookup(rtitcp_info->pdus, conversation_info_key);
555
0
    }
556
0
    if (!rtitcp_trans) {
557
            /* create a "fake" rtitcp_trans structure */
558
0
            rtitcp_trans=wmem_new(pinfo->pool, rtitcp_transaction_t);
559
0
            rtitcp_trans->req_frame = 0;
560
0
            rtitcp_trans->rep_frame = 0;
561
0
            rtitcp_trans->req_time = pinfo->abs_ts;
562
0
    }
563
564
    /* print state tracking in the tree */
565
0
    if (!(control_message_kind & RTITCP_FLAG_NOT_REQUEST)) {
566
        /* This is a request */
567
0
        if (rtitcp_trans->rep_frame) {
568
0
            proto_item *it;
569
0
            it = proto_tree_add_uint(rtitcp_message, hf_rtitcp_response_in,
570
0
                            tvb, 0, 0, rtitcp_trans->rep_frame);
571
0
            proto_item_set_generated(it);
572
0
        }
573
0
    } else {
574
        /* This is a reply */
575
0
        if (rtitcp_trans->req_frame) {
576
0
            proto_item *it;
577
0
            nstime_t ns;
578
0
            it = proto_tree_add_uint(rtitcp_message, hf_rtitcp_response_to,
579
0
                            tvb, 0, 0, rtitcp_trans->req_frame);
580
0
            proto_item_set_generated(it);
581
582
0
            nstime_delta(&ns, &pinfo->abs_ts, &rtitcp_trans->req_time);
583
0
            it = proto_tree_add_time(rtitcp_message, hf_rtitcp_response_time, tvb, 0, 0, &ns);
584
0
            proto_item_set_generated(it);
585
0
        }
586
0
    }
587
588
    /* End of feature */
589
0
    offset += 12;
590
591
    /* Finally, dissect the list of attributes */
592
0
    attributes_list_offset = 0;
593
0
    attributes_list = proto_tree_add_subtree_format(rtitcp_message, tvb,
594
0
            attributes_list_offset+offset, attributes_list_length,
595
0
            ett_rtitcp_attributes_list, NULL, "Attributes List");
596
597
0
    attributes_count = 0;
598
0
    first_attribute = true;
599
0
    while (attributes_list_offset < attributes_list_length) {
600
0
        ++attributes_count;
601
0
        attribute_offset = dissect_attribute(tvb, pinfo, attributes_list,
602
0
          offset, attributes_list_offset, rtitcp_message, &first_attribute);
603
0
        attributes_list_offset += attribute_offset;
604
0
    }
605
0
    if (!first_attribute) {
606
0
        proto_item_append_text(rtitcp_message,")");
607
0
        col_append_str(pinfo->cinfo, COL_INFO, ")");
608
0
    }
609
    /* Now that we have the number of attributes, update the text to show it */
610
0
    proto_item_set_text(attributes_list, "Attributes list [%d attribute%s",
611
0
        attributes_count, attributes_count > 1 ? "s]" : "]");
612
613
0
    proto_item_append_text(rtitcp_message,", Transaction ID: %s, Len: %d",
614
0
            transaction_id_str, msg_length);
615
616
0
    return msg_length + header_length;
617
0
}
618
619
/* This function dissects all the control messages found */
620
0
static unsigned dissect_rtitcp_control_protocol(proto_tree *rtitcp_tree, tvbuff_t *tvb, packet_info *pinfo) {
621
0
    unsigned offset;
622
0
    uint16_t msg_length;
623
0
    uint32_t tvb_len;
624
625
0
    offset = 0;
626
0
    tvb_len = tvb_reported_length(tvb);
627
628
0
    while (offset < tvb_len) {
629
0
        msg_length = dissect_control_message(rtitcp_tree, tvb, pinfo, offset);
630
0
        offset += msg_length;
631
0
    }
632
633
0
    return offset;
634
0
}
635
636
static int dissect_rtitcp_common(tvbuff_t *tvb, packet_info *pinfo,
637
0
                            proto_tree *tree, void *data _U_) {
638
639
   /*                   FORMAT OF THE CONTROL MESSAGE
640
641
     0...2...........7...............15.............23...............31
642
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
643
   * |         control bytes         |    RTI TCP message length     |
644
   * +---------------+---------------+---------------+---------------+
645
   * |                     RTITCP_MAGIC_NUMBER                       |
646
   * +---------------+---------------+---------------+---------------+
647
   * |      control_message_kind     |    attributes_list_length     |
648
   * +---------------+---------------+---------------+---------------+
649
   * |                    RTITCP_CONTROL_MAGIC_COOKIE                |
650
   * +---------------+---------------+---------------+---------------+
651
   * |                                                               |
652
   * |-                                                             -|
653
   * |                         TRANSACTION_ID                        |
654
   * |-                                                             -|
655
   * |                                                               |
656
   * +---------------+---------------+---------------+---------------+   ---------------------------------
657
   * |       attribute_type          |       attribute_length ..         Repeat                          |
658
   * +---------------+---------------+---------------+---------------+   until                           |
659
   * |                       ATTRIBUTE (length)                      |   attributes_list_length expires  |
660
   * +---------------+---------------+---------------+---------------+   --------------------------------*/
661
662
0
    proto_item   *ti;
663
0
    proto_tree   *rtitcp_tree, *rtitcp_message = NULL;
664
0
    unsigned offset, offset_header;
665
0
    uint16_t rtitcp_msg_length, header_length;
666
0
    uint32_t tvb_len, rtitcp_rtps_msg_length;
667
0
    bool printCRC = false, is_data = false;
668
0
    tvbuff_t *next_tvb;
669
0
    heur_dtbl_entry_t *hdtbl_entry;
670
671
0
    offset = 0;
672
0
    tvb_len = tvb_reported_length(tvb);
673
674
    /* From this point, we can consider that this is a RTI TCP message */
675
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTI-TCP");
676
677
0
    rtitcp_msg_length = tvb_get_uint16(tvb, offset+2, ENC_BIG_ENDIAN);
678
679
0
    ti = proto_tree_add_item(tree, proto_rtitcp, tvb, offset, -1, ENC_NA);
680
0
    rtitcp_tree = proto_item_add_subtree(ti, ett_rtitcp);
681
682
0
    offset_header = 0; /* Remember the offset that delimits the header */
683
0
    header_length = 8; /* the header is 8 bytes length + 8 optional (CRC) */
684
0
    offset += 2; /* First two bytes are CTRL bytes */
685
0
    offset += 2; /* rtitcp_msg_length */
686
0
    offset += 4; /* RTITCP_MAGIC_NUMBER has already been checked */
687
688
    /* if bytes 8 to 12 are RTITCP_CRC_MAGIC_NUMBER, we got a CRC */
689
0
    if (tvb_get_ntohl(tvb, offset) == RTITCP_CRC_MAGIC_NUMBER) {
690
0
        printCRC = true; /* To specify later that CRC must be printed */
691
0
        header_length += 8; /* header increases in 8 bytes */
692
0
        offset += 8; /* Because of 0xCRC32 + actual CRC (4 bytes) */
693
0
    }
694
0
    proto_item_set_len(ti, rtitcp_msg_length + header_length);
695
696
    /* At this point, offset is 8 or 16 bytes and we have now data.
697
       This data can be RTPS or RTI TCP Signaling messages */
698
0
    if (tvb_get_ntohl(tvb, offset) == RTPS_MAGIC_NUMBER) {
699
700
        /* IMPORTANT NOTE: We assume always one RTPS message per RTITCP message */
701
        /* If the TCP layer has provided us with garbage at the end of the buffer,
702
           process only the length specified by rtitcp_msg_length */
703
0
        if (tvb_len > (uint32_t)(rtitcp_msg_length + header_length)) {
704
0
            tvb_set_reported_length(tvb, (rtitcp_msg_length + header_length));
705
0
        }
706
707
        /* When we encapsulate RTPS, packet length is given by the 30 less
708
           significant bits of the first four bytes */
709
0
        rtitcp_rtps_msg_length = tvb_get_uint32(tvb, 0, ENC_BIG_ENDIAN);
710
0
        rtitcp_rtps_msg_length = rtitcp_rtps_msg_length % NUMBER_2E30;
711
        /* Add RTI TCP Data Message subtree and print header */
712
0
        is_data = true;
713
0
        rtitcp_message = print_header(rtitcp_tree, rtitcp_message, tvb, offset_header,
714
0
                                        rtitcp_rtps_msg_length + header_length, printCRC, is_data);
715
716
0
        proto_item_set_text(rtitcp_message,"RTI TCP Data Message, Len: %d",
717
0
                                rtitcp_rtps_msg_length);
718
719
        /* Take the payload and call the registered sub-dissectors. So far, RTPS */
720
0
        next_tvb = tvb_new_subset_remaining(tvb, offset);
721
0
        dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, NULL);
722
0
        return tvb_captured_length(tvb);
723
724
0
    } else {
725
0
        return dissect_rtitcp_control_protocol(rtitcp_tree, tvb, pinfo);
726
0
    }
727
0
}
728
729
static unsigned get_rtitcp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
730
0
        int offset, void * data _U_) {
731
0
    uint16_t plen;
732
0
    uint16_t header_length = 8;
733
    /*
734
    * Get the length of the RTITCP packet.
735
    */
736
0
    plen = tvb_get_uint16(tvb, offset+2, ENC_BIG_ENDIAN);
737
    /*
738
    * That length doesn't include the header field itself; add that in.
739
    */
740
0
    if (tvb_get_ntohl(tvb, offset+8) == RTITCP_CRC_MAGIC_NUMBER)
741
0
        header_length += 8;
742
    /* We don't expect plen to be greater than 0xfff8 since adding the header
743
     * exceeds the size */
744
0
    if (plen >= 0xfff8)
745
0
        return 1;
746
747
0
    return plen + header_length;
748
0
}
749
static int dissect_rtitcp(tvbuff_t *tvb, packet_info *pinfo,
750
2.94k
                            proto_tree *tree, void *data _U_) {
751
752
2.94k
    bool desegmentation = true;
753
754
2.94k
    if (tvb_captured_length(tvb) < 8)
755
306
        return 0;
756
757
    /* Check if the RTITCP_MAGIC_NUMBER is here */
758
2.64k
    if (tvb_get_ntohl(tvb, 4) != RTITCP_MAGIC_NUMBER)
759
2.64k
        return 0;
760
761
0
    col_clear(pinfo->cinfo, COL_INFO);
762
763
0
    tcp_dissect_pdus(tvb, pinfo, tree, desegmentation, RTITCP_MIN_LENGTH,
764
0
            get_rtitcp_pdu_len, dissect_rtitcp_common, data);
765
766
0
    return tvb_captured_length(tvb);
767
768
2.64k
}
769
770
static bool
771
dissect_rtitcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
772
2.94k
{
773
2.94k
    return dissect_rtitcp(tvb, pinfo, tree, data) > 0;
774
2.94k
}
775
776
/* Register the protocol with Wireshark.
777
 *
778
 * This format is required because a script is used to build the C function that
779
 * calls all the protocol registration.
780
 */
781
void
782
proto_register_rtitcp(void)
783
14
{
784
    /* module_t *rtitcp_module; */
785
    /* expert_module_t* expert_rtitcp; */
786
787
14
    static hf_register_info hf[] = {
788
789
14
        { &hf_rtitcp_header_control_byte, {
790
14
            "Control Byte", "rtitcp.header.control_byte",
791
14
            FT_UINT16, BASE_HEX, NULL, 0,
792
14
            NULL, HFILL }
793
14
        },
794
795
14
        { &hf_rtitcp_header_message_length, {
796
14
            "Message Length", "rtitcp.header.message_length",
797
14
            FT_UINT24, BASE_DEC, NULL, 0,
798
14
            NULL, HFILL }
799
14
        },
800
801
14
        { &hf_rtitcp_header_magic_number, {
802
14
            "Magic Cookie", "rtitcp.header.magic_cookie",
803
14
            FT_UINT32, BASE_HEX, NULL, 0,
804
14
            NULL, HFILL }
805
14
        },
806
807
14
        { &hf_rtitcp_crc_magic_cookie, {
808
14
            "CRC Magic Cookie", "rtitcp.header.crc_magic_cookie",
809
14
            FT_UINT32, BASE_HEX, NULL, 0,
810
14
            NULL, HFILL }
811
14
        },
812
813
14
        { &hf_rtitcp_control_kind,
814
14
          { "Kind", "rtitcp.control.kind",
815
14
            FT_UINT16, BASE_HEX, VALS(ctrl_message_types_vals), 0,
816
14
            NULL, HFILL }
817
14
        },
818
819
14
        { &hf_rtitcp_control_magic_cookie, {
820
14
            "Control Magic Cookie", "rtitcp.control.magic_cookie",
821
14
            FT_UINT32, BASE_HEX, NULL, 0,
822
14
            NULL, HFILL }
823
14
        },
824
825
14
        { &hf_rtitcp_control_transaction_id, {
826
14
            "Transaction ID", "rtitcp.control.transaction_id",
827
14
            FT_BYTES, BASE_NONE, NULL, 0,
828
14
            NULL, HFILL }
829
14
        },
830
831
14
        { &hf_rtitcp_control_attribute_session_id, {
832
14
            "Session ID", "rtitcp.control.attribute.session_id",
833
14
            FT_BYTES, BASE_NONE, NULL, 0,
834
14
            NULL, HFILL }
835
14
        },
836
837
14
        { &hf_rtitcp_control_attribute_type,
838
14
          { "Attribute Type", "rtitcp.control.attribute_type",
839
14
            FT_UINT16, BASE_HEX, VALS(attribute_types_vals), 0,
840
14
            NULL, HFILL }
841
14
        },
842
843
14
        { &hf_rtitcp_control_attribute_error_code_value,
844
14
          { "Kind", "rtitcp.control.attribute.error_code",
845
14
            FT_UINT32, BASE_HEX, VALS(error_code_kind_vals), 0,
846
14
            NULL, HFILL }
847
14
        },
848
849
14
        { &hf_rtitcp_control_attribute_error_code_description, {
850
14
            "Description", "rtitcp.control.attribute.error_code.description",
851
14
            FT_STRING, BASE_NONE, NULL, 0,
852
14
            NULL, HFILL }
853
14
        },
854
855
14
        { &hf_rtitcp_control_attribute_connection_cookie, {
856
14
            "Connection Cookie", "rtitcp.control.attribute.connection_cookie",
857
14
            FT_BYTES, BASE_NONE, NULL, 0,
858
14
            NULL, HFILL }
859
14
        },
860
861
14
        { &hf_rtitcp_control_attribute_connection_type, {
862
14
            "Class ID", "rtitcp.control_attribute.connection_type",
863
14
            FT_UINT8, BASE_HEX, VALS(rtitcp_attribute_connection_type_vals), 0,
864
14
            NULL, HFILL }
865
14
        },
866
867
14
        { &hf_rtitcp_attributes_list_length, {
868
14
            "Attributes list length", "rtitcp.attributes_list_length",
869
14
            FT_UINT16, BASE_DEC, NULL, 0,
870
14
            NULL, HFILL }
871
14
        },
872
873
14
        { &hf_rtitcp_control_attribute_length, {
874
14
            "Attribute Length", "rtitcp.control.attribute.length",
875
14
            FT_UINT16, BASE_DEC, NULL, 0,
876
14
            NULL, HFILL }
877
14
        },
878
879
14
        { &hf_rtitcp_control_attribute_port, {
880
14
            "Port", "rtitcp.control.attribute_port",
881
14
            FT_UINT32, BASE_DEC, NULL, 0,
882
14
            NULL, HFILL }
883
14
        },
884
885
14
        { &hf_rtitcp_locator_kind,
886
14
          { "Kind", "rtitcp.locator.kind",
887
14
            FT_UINT16, BASE_DEC, VALS(rtitcp_locator_kind_vals), 0,
888
14
            NULL, HFILL }
889
14
        },
890
891
14
        { &hf_rtitcp_locator_ipv4,
892
14
          { "Address", "rtitcp.locator.ipv4",
893
14
            FT_IPv4, BASE_NONE, NULL, 0,
894
14
            NULL, HFILL }
895
14
        },
896
897
14
        { &hf_rtitcp_locator_port,
898
14
          { "Port", "rtitcp.locator.port",
899
14
            FT_UINT16, BASE_DEC, NULL, 0,
900
14
            NULL, HFILL }
901
14
        },
902
903
14
        { &hf_rtitcp_locator_ipv6,
904
14
          { "Address", "rtitcp.locator.ipv6",
905
14
            FT_IPv6, BASE_NONE, NULL, 0,
906
14
            NULL, HFILL }
907
14
        },
908
909
14
        { &hf_rtitcp_control_crc_value,
910
14
          { "CRC", "rtitcp.control.crc",
911
14
            FT_UINT32, BASE_HEX, NULL, 0,
912
14
            NULL, HFILL }
913
14
        },
914
915
14
        { &hf_rtitcp_response_in,
916
14
          { "Response In", "rtitcp.response_in",
917
14
            FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
918
14
            "The response to this RTITCP request is in this frame", HFILL }
919
14
        },
920
921
14
        { &hf_rtitcp_response_to,
922
14
          { "Request In", "rtitcp.response_to",
923
14
            FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
924
14
            "This is a response to the RTITCP request in this frame", HFILL }
925
14
        },
926
927
14
        { &hf_rtitcp_response_time,
928
14
          { "Response Time", "rtitcp.response_time",
929
14
            FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
930
14
            "The time between the Request and the Reply", HFILL }
931
14
        }
932
14
    };
933
934
14
    static int *ett[] = {
935
14
        &ett_rtitcp,
936
14
        &ett_rtitcp_signalling_protocol,
937
14
        &ett_rtitcp_message,
938
14
        &ett_rtitcp_attributes_list,
939
14
        &ett_rtitcp_attribute
940
14
    };
941
942
    /* Setup protocol expert items */
943
    /* static ei_register_info ei[] = {}; */
944
945
    /* Register the protocol name and description */
946
14
    proto_rtitcp = proto_register_protocol("RTI TCP Transport Protocol",
947
14
            "RTITCP", "rtitcp");
948
949
14
    hfi_rtitcp = proto_registrar_get_nth(proto_rtitcp);
950
    /* Required function calls to register the header fields and subtrees */
951
14
    proto_register_field_array(proto_rtitcp, hf, array_length(hf));
952
14
    proto_register_subtree_array(ett, array_length(ett));
953
954
    /* Required function calls to register expert items */
955
    /* expert_rtitcp = expert_register_protocol(proto_rtitcp);
956
     expert_register_field_array(expert_rtitcp, ei, array_length(ei)); */
957
958
14
    register_dissector("rtitcp", dissect_rtitcp, proto_rtitcp);
959
14
    heur_subdissector_list = register_heur_dissector_list_with_description("rtitcp", "RTI TCP signalling message", proto_rtitcp);
960
961
14
}
962
963
/* Simpler form of proto_reg_handoff_rtitcp which can be used if there are
964
 * no prefs-dependent registration function calls. */
965
void
966
proto_reg_handoff_rtitcp(void)
967
14
{
968
14
    heur_dissector_add("tcp", dissect_rtitcp_heur, "RTI TCP Layer" , "rtitcp", proto_rtitcp, HEURISTIC_ENABLE);
969
14
}
970
971
/*
972
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
973
 *
974
 * Local variables:
975
 * c-basic-offset: 4
976
 * tab-width: 8
977
 * indent-tabs-mode: nil
978
 * End:
979
 *
980
 * vi: set shiftwidth=4 tabstop=8 expandtab:
981
 * :indentSize=4:tabSize=8:noTabs=true:
982
 */