forked from osmocom/wireshark
971 lines
40 KiB
C
971 lines
40 KiB
C
/* packet-someip-sd.c
|
|
* SOME/IP-SD dissector.
|
|
* By Dr. Lars Voelker <lars.voelker@technica-engineering.de> / <lars.voelker@bmw.de>
|
|
* Copyright 2012-2020 Dr. Lars Voelker
|
|
* Copyright 2020 Ayoub Kaanich
|
|
* Copyright 2019 Ana Pantar
|
|
* Copyright 2019 Guenter Ebermann
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/to_str.h>
|
|
#include <epan/uat.h>
|
|
#include "packet-udp.h"
|
|
#include "packet-someip.h"
|
|
|
|
/*
|
|
* Dissector for SOME/IP Service Discovery (SOME/IP-SD).
|
|
*
|
|
* See
|
|
* http://www.some-ip.com
|
|
*/
|
|
|
|
#define SOMEIP_SD_NAME "SOME/IP-SD"
|
|
#define SOMEIP_SD_NAME_LONG "SOME/IP Service Discovery Protocol"
|
|
#define SOMEIP_SD_NAME_FILTER "someipsd"
|
|
|
|
#define SOMEIP_SD_MESSAGEID 0xffff8100
|
|
|
|
/* Header */
|
|
#define SOMEIP_SD_REBOOT_FLAG 0x80
|
|
#define SOMEIP_SD_UNICAST_FLAG 0x40
|
|
#define SOMEIP_SD_EXPL_INIT_EVENT_REQ_FLAG 0x20
|
|
#define SOMEIP_SD_MIN_LENGTH 12
|
|
|
|
/* Entries */
|
|
#define SD_ENTRY_LENGTH 16
|
|
|
|
#define SD_ENTRY_UNKNOWN 0x00
|
|
#define SD_ENTRY_SERVICE 0x01
|
|
#define SD_ENTRY_EVENTGROUP 0x02
|
|
/* TTL>0 */
|
|
#define SD_ENTRY_FIND_SERVICE 0x00
|
|
#define SD_ENTRY_OFFER_SERVICE 0x01
|
|
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP 0x06
|
|
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK 0x07
|
|
/* TTL=0 */
|
|
#define SD_ENTRY_STOP_OFFER_SERVICE 0x01
|
|
#define SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP 0x06
|
|
#define SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK 0x07
|
|
|
|
#define SD_EVENTGROUP_ENTRY_COUNTER_MASK 0x0f
|
|
#define SD_EVENTGROUP_ENTRY_RES2_MASK 0x70
|
|
#define SD_ENTRY_INIT_EVENT_REQ_MASK 0x80
|
|
|
|
/* Options */
|
|
#define SD_OPTION_MINLENGTH 3
|
|
#define SD_OPTION_IPV4_LENGTH 12
|
|
#define SD_OPTION_IPV6_LENGTH 24
|
|
|
|
#define SD_OPTION_UNKNOWN 0x00
|
|
#define SD_OPTION_CONFIGURATION 0x01
|
|
#define SD_OPTION_LOADBALANCING 0x02
|
|
#define SD_OPTION_IPV4_ENDPOINT 0x04
|
|
#define SD_OPTION_IPV6_ENDPOINT 0x06
|
|
#define SD_OPTION_IPV4_MULTICAST 0x14
|
|
#define SD_OPTION_IPV6_MULTICAST 0x16
|
|
#define SD_OPTION_IPV4_SD_ENDPOINT 0x24
|
|
#define SD_OPTION_IPV6_SD_ENDPOINT 0x26
|
|
|
|
#define SD_OPTION_L4PROTO_TCP 6
|
|
#define SD_OPTION_L4PROTO_UDP 17
|
|
|
|
/* ID wireshark identifies the dissector by */
|
|
static int proto_someip_sd = -1;
|
|
|
|
/* header field */
|
|
static int hf_someip_sd_flags = -1;
|
|
static int hf_someip_sd_rebootflag = -1;
|
|
static int hf_someip_sd_unicastflag = -1;
|
|
static int hf_someip_sd_explicitiniteventflag = -1;
|
|
static int hf_someip_sd_reserved = -1;
|
|
|
|
static int hf_someip_sd_length_entriesarray = -1;
|
|
static int hf_someip_sd_entries = -1;
|
|
|
|
static int hf_someip_sd_entry = -1;
|
|
static int hf_someip_sd_entry_type = -1;
|
|
static int hf_someip_sd_entry_type_offerservice = -1;
|
|
static int hf_someip_sd_entry_type_stopofferservice = -1;
|
|
static int hf_someip_sd_entry_type_findservice = -1;
|
|
static int hf_someip_sd_entry_type_subscribeeventgroup = -1;
|
|
static int hf_someip_sd_entry_type_stopsubscribeeventgroup = -1;
|
|
static int hf_someip_sd_entry_type_subscribeeventgroupack = -1;
|
|
static int hf_someip_sd_entry_type_subscribeeventgroupnack = -1;
|
|
static int hf_someip_sd_entry_index1 = -1;
|
|
static int hf_someip_sd_entry_index2 = -1;
|
|
static int hf_someip_sd_entry_numopt1 = -1;
|
|
static int hf_someip_sd_entry_numopt2 = -1;
|
|
static int hf_someip_sd_entry_serviceid = -1;
|
|
static int hf_someip_sd_entry_instanceid = -1;
|
|
static int hf_someip_sd_entry_majorver = -1;
|
|
static int hf_someip_sd_entry_ttl = -1;
|
|
static int hf_someip_sd_entry_minorver = -1;
|
|
static int hf_someip_sd_entry_eventgroupid = -1;
|
|
static int hf_someip_sd_entry_reserved = -1;
|
|
static int hf_someip_sd_entry_counter = -1;
|
|
static int hf_someip_sd_entry_intial_event_flag = -1;
|
|
static int hf_someip_sd_entry_reserved2 = -1;
|
|
|
|
static int hf_someip_sd_length_optionsarray = -1;
|
|
static int hf_someip_sd_options = -1;
|
|
|
|
static int hf_someip_sd_option_type = -1;
|
|
static int hf_someip_sd_option_length = -1;
|
|
static int hf_someip_sd_option_reserved = -1;
|
|
static int hf_someip_sd_option_ipv4 = -1;
|
|
static int hf_someip_sd_option_ipv6 = -1;
|
|
static int hf_someip_sd_option_port = -1;
|
|
static int hf_someip_sd_option_proto = -1;
|
|
static int hf_someip_sd_option_reserved2 = -1;
|
|
static int hf_someip_sd_option_data = -1;
|
|
static int hf_someip_sd_option_config_string = -1;
|
|
static int hf_someip_sd_option_lb_priority = -1;
|
|
static int hf_someip_sd_option_lb_weight = -1;
|
|
|
|
/* protocol tree items */
|
|
static gint ett_someip_sd = -1;
|
|
static gint ett_someip_sd_flags = -1;
|
|
static gint ett_someip_sd_entries = -1;
|
|
static gint ett_someip_sd_entry = -1;
|
|
static gint ett_someip_sd_options = -1;
|
|
static gint ett_someip_sd_option = -1;
|
|
|
|
/*** Preferences ***/
|
|
static range_t *someip_ignore_ports_udp = NULL;
|
|
static range_t *someip_ignore_ports_tcp = NULL;
|
|
|
|
/* SOME/IP-SD Entry Names for TTL>0 */
|
|
static const value_string sd_entry_type_positive[] = {
|
|
{SD_ENTRY_FIND_SERVICE, "Find Service"},
|
|
{SD_ENTRY_OFFER_SERVICE, "Offer Service"},
|
|
{SD_ENTRY_SUBSCRIBE_EVENTGROUP, "Subscribe Eventgroup"},
|
|
{SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK, "Subscribe Eventgroup Ack"},
|
|
{0, NULL}
|
|
};
|
|
|
|
/* SOME/IP-SD Entry Names for TTL=0 */
|
|
static const value_string sd_entry_type_negative[] = {
|
|
{SD_ENTRY_STOP_OFFER_SERVICE, "Stop Offer Service"},
|
|
{SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP, "Stop Subscribe Eventgroup"},
|
|
{SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK, "Subscribe Eventgroup Negative Ack"},
|
|
{0, NULL}
|
|
};
|
|
|
|
/* SOME/IP-SD Option Names */
|
|
static const value_string sd_option_type[] = {
|
|
{SD_OPTION_UNKNOWN, "Unknown"},
|
|
{SD_OPTION_CONFIGURATION, "Configuration"},
|
|
{SD_OPTION_LOADBALANCING, "Load Balancing"},
|
|
{SD_OPTION_IPV4_ENDPOINT, "IPv4 Endpoint"},
|
|
{SD_OPTION_IPV6_ENDPOINT, "IPv6 Endpoint"},
|
|
{SD_OPTION_IPV4_MULTICAST, "IPv4 Multicast"},
|
|
{SD_OPTION_IPV6_MULTICAST, "IPv6 Multicast"},
|
|
{SD_OPTION_IPV4_SD_ENDPOINT, "IPv4 SD Endpoint"},
|
|
{SD_OPTION_IPV6_SD_ENDPOINT, "IPv6 SD Endpoint"},
|
|
{0, NULL}
|
|
};
|
|
|
|
/* L4 Protocol Names for SOME/IP-SD Endpoints */
|
|
static const value_string sd_option_l4protos[] = {
|
|
{SD_OPTION_L4PROTO_TCP, "TCP"},
|
|
{SD_OPTION_L4PROTO_UDP, "UDP"},
|
|
{0, NULL}
|
|
};
|
|
|
|
static const true_false_string sd_reboot_flag = {
|
|
"Session ID did not roll over since last reboot",
|
|
"Session ID rolled over since last reboot"
|
|
};
|
|
|
|
static const true_false_string sd_unicast_flag = {
|
|
"Unicast messages support",
|
|
"Unicast messages not supported (deprecated)"
|
|
};
|
|
|
|
static const true_false_string sd_eiec_flag = {
|
|
"Explicit Initial Event control supported",
|
|
"Explicit Initial Event control not supported"
|
|
};
|
|
|
|
/*** expert info items ***/
|
|
static expert_field ef_someipsd_message_truncated = EI_INIT;
|
|
static expert_field ef_someipsd_entry_array_malformed = EI_INIT;
|
|
static expert_field ef_someipsd_entry_array_empty = EI_INIT;
|
|
static expert_field ef_someipsd_entry_unknown = EI_INIT;
|
|
static expert_field ef_someipsd_option_array_truncated = EI_INIT;
|
|
static expert_field ef_someipsd_option_array_bytes_left = EI_INIT;
|
|
static expert_field ef_someipsd_option_unknown = EI_INIT;
|
|
static expert_field ef_someipsd_option_wrong_length = EI_INIT;
|
|
static expert_field ef_someipsd_L4_protocol_unsupported = EI_INIT;
|
|
|
|
/*** prototypes ***/
|
|
void proto_register_someip_sd(void);
|
|
void proto_reg_handoff_someip_sd(void);
|
|
|
|
/**************************************
|
|
******** SOME/IP-SD Dissector ********
|
|
*************************************/
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_option_configuration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
|
|
guint32 offset_orig = offset;
|
|
|
|
tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, NULL, "%d: Configuration Option", optionnum);
|
|
|
|
/* Add common fields */
|
|
proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_config_string, tvb, offset, length - offset + offset_orig, ENC_ASCII|ENC_NA);
|
|
|
|
/* TODO: splitting the config string would be nice... does DNS have code for this? */
|
|
}
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_option_loadbalancing(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
|
|
tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, NULL, "%d: Load Balancing Option", optionnum);
|
|
|
|
/* Add common fields */
|
|
proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_lb_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_lb_weight, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
}
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_option_ipv4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
|
|
guint8 type = 255;
|
|
const gchar *description = NULL;
|
|
guint32 l4port = 0;
|
|
guint32 l4proto = 0;
|
|
const gchar *l4protoname = NULL;
|
|
const gchar *ipstring = NULL;
|
|
|
|
proto_item *ti = NULL;
|
|
proto_item *ti_top = NULL;
|
|
|
|
type = tvb_get_guint8(tvb, offset + 2);
|
|
description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
|
|
tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
|
|
|
|
if (length != SD_OPTION_IPV4_LENGTH) {
|
|
expert_add_info(pinfo, ti_top, &ef_someipsd_option_wrong_length);
|
|
return;
|
|
}
|
|
|
|
/* Add common fields */
|
|
proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_ipv4, tvb, offset, 4, ENC_NA);
|
|
ipstring = tvb_ip_to_str(tvb, offset);
|
|
offset += 4;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved2, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_proto, tvb, offset, 1, ENC_NA, &l4proto);
|
|
l4protoname = val_to_str(l4proto, sd_option_l4protos, "Unknown Transport Protocol: %d");
|
|
proto_item_append_text(ti, " (%s)", l4protoname);
|
|
|
|
if (type != SD_OPTION_IPV4_ENDPOINT && l4proto == SD_OPTION_L4PROTO_TCP) {
|
|
expert_add_info(pinfo, ti_top, &ef_someipsd_L4_protocol_unsupported);
|
|
}
|
|
offset += 1;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_port, tvb, offset, 2, ENC_BIG_ENDIAN, &l4port);
|
|
|
|
proto_item_append_text(ti_top, " (%s:%d (%s))", ipstring, l4port, l4protoname);
|
|
|
|
if (l4proto == SD_OPTION_L4PROTO_UDP && !value_is_in_range(someip_ignore_ports_udp, l4port)) {
|
|
register_someip_port_udp(l4port);
|
|
}
|
|
if (l4proto == SD_OPTION_L4PROTO_TCP && !value_is_in_range(someip_ignore_ports_tcp, l4port)) {
|
|
register_someip_port_tcp(l4port);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_option_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
|
|
guint8 type = 255;
|
|
const gchar *description = NULL;
|
|
guint32 l4port = 0;
|
|
guint32 l4proto = 0;
|
|
const gchar *l4protoname = NULL;
|
|
proto_item *ti = NULL;
|
|
proto_item *ti_top = NULL;
|
|
|
|
type = tvb_get_guint8(tvb, offset + 2);
|
|
description = val_to_str(type, sd_option_type, "(Unknown Option: %d)");
|
|
|
|
tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti_top, "%d: %s Option", optionnum, description);
|
|
|
|
if (length != SD_OPTION_IPV6_LENGTH) {
|
|
expert_add_info(pinfo, ti_top, &ef_someipsd_option_wrong_length);
|
|
return;
|
|
}
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_ipv6, tvb, offset, 16, ENC_NA);
|
|
offset += 16;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved2, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_proto, tvb, offset, 1, ENC_NA, &l4proto);
|
|
l4protoname = val_to_str(l4proto, sd_option_l4protos, "(Unknown Transport Protocol: %d)");
|
|
proto_item_append_text(ti, " (%s)", l4protoname);
|
|
|
|
if (type != SD_OPTION_IPV6_ENDPOINT && l4proto == SD_OPTION_L4PROTO_TCP) {
|
|
expert_add_info(pinfo, ti_top, &ef_someipsd_L4_protocol_unsupported);
|
|
}
|
|
offset += 1;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_port, tvb, offset, 2, ENC_BIG_ENDIAN, &l4port);
|
|
|
|
proto_item_append_text(ti_top, " (%s)", l4protoname);
|
|
|
|
if (l4proto == SD_OPTION_L4PROTO_UDP && !value_is_in_range(someip_ignore_ports_udp, l4port)) {
|
|
register_someip_port_udp(l4port);
|
|
}
|
|
if (l4proto == SD_OPTION_L4PROTO_TCP && !value_is_in_range(someip_ignore_ports_tcp, l4port)) {
|
|
register_someip_port_tcp(l4port);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_option_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length, int optionnum) {
|
|
guint32 len = 0;
|
|
proto_item *ti;
|
|
|
|
tree = proto_tree_add_subtree_format(tree, tvb, offset, length, ett_someip_sd_option, &ti, "%d: %s Option", optionnum,
|
|
val_to_str_const(tvb_get_guint8(tvb, offset + 2), sd_option_type, "Unknown"));
|
|
|
|
expert_add_info(pinfo, ti, &ef_someipsd_option_unknown);
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_option_length, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_option_type, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
if (length > 3) {
|
|
proto_tree_add_item(tree, hf_someip_sd_option_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
if (length > 4) {
|
|
proto_tree_add_item(tree, hf_someip_sd_option_data, tvb, offset, length - 4, ENC_NA);
|
|
}
|
|
}
|
|
}
|
|
|
|
static int
|
|
dissect_someip_sd_pdu_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint32 offset, guint32 length) {
|
|
guint16 real_length = 0;
|
|
guint8 option_type = 0;
|
|
int optionnum = 0;
|
|
tvbuff_t *subtvb = NULL;
|
|
|
|
if (!tvb_bytes_exist(tvb, offset, SD_OPTION_MINLENGTH) || !tvb_bytes_exist(tvb, offset, length)) {
|
|
expert_add_info(pinfo, ti, &ef_someipsd_option_array_truncated);
|
|
return offset;
|
|
}
|
|
|
|
while (tvb_bytes_exist(tvb, offset, SD_OPTION_MINLENGTH)) {
|
|
real_length = tvb_get_ntohs(tvb, offset) + 3;
|
|
option_type = tvb_get_guint8(tvb, offset + 2);
|
|
|
|
if (!tvb_bytes_exist(tvb, offset, (gint)real_length)) {
|
|
expert_add_info(pinfo, ti, &ef_someipsd_option_array_truncated);
|
|
return offset;
|
|
}
|
|
|
|
subtvb = tvb_new_subset_length(tvb, offset, (gint)real_length);
|
|
|
|
switch (option_type) {
|
|
case SD_OPTION_CONFIGURATION:
|
|
dissect_someip_sd_pdu_option_configuration(subtvb, pinfo, tree, 0, real_length, optionnum);
|
|
break;
|
|
case SD_OPTION_LOADBALANCING:
|
|
dissect_someip_sd_pdu_option_loadbalancing(subtvb, pinfo, tree, 0, real_length, optionnum);
|
|
break;
|
|
case SD_OPTION_IPV4_ENDPOINT:
|
|
case SD_OPTION_IPV4_MULTICAST:
|
|
case SD_OPTION_IPV4_SD_ENDPOINT:
|
|
dissect_someip_sd_pdu_option_ipv4(subtvb, pinfo, tree, 0, real_length, optionnum);
|
|
break;
|
|
|
|
case SD_OPTION_IPV6_ENDPOINT:
|
|
case SD_OPTION_IPV6_MULTICAST:
|
|
case SD_OPTION_IPV6_SD_ENDPOINT:
|
|
dissect_someip_sd_pdu_option_ipv6(subtvb, pinfo, tree, 0, real_length, optionnum);
|
|
break;
|
|
|
|
default:
|
|
dissect_someip_sd_pdu_option_unknown(subtvb, pinfo, tree, 0, real_length, optionnum);
|
|
break;
|
|
}
|
|
optionnum++;
|
|
offset += real_length;
|
|
}
|
|
|
|
return offset;
|
|
}
|
|
|
|
static void
|
|
dissect_someip_sd_pdu_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset, guint32 length _U_, guint32 *entry_flags, guint32 *stop_entry_flags) {
|
|
guint8 type = 255;
|
|
guint32 serviceid = 0;
|
|
guint32 instanceid = 0;
|
|
guint32 eventgroupid = 0;
|
|
guint32 majorver = 0;
|
|
guint32 minorver = 0;
|
|
guint32 ttl = 0;
|
|
|
|
guint64 uniqueid = 0;
|
|
guint8 category = SD_ENTRY_UNKNOWN;
|
|
|
|
const gchar *description = NULL;
|
|
|
|
proto_item *ti;
|
|
proto_item *ti_top;
|
|
|
|
if (length < SD_ENTRY_LENGTH || !tvb_bytes_exist(tvb, offset, length)) {
|
|
return;
|
|
}
|
|
|
|
/* lets look ahead and find out the type and ttl */
|
|
type = tvb_get_guint8(tvb, offset);
|
|
ttl = tvb_get_ntoh24(tvb, offset + 9);
|
|
|
|
if (type < 4) {
|
|
category = SD_ENTRY_SERVICE;
|
|
} else if (type >= 4 && type < 8) {
|
|
category = SD_ENTRY_EVENTGROUP;
|
|
} else {
|
|
ti_top = proto_tree_add_none_format(tree, hf_someip_sd_entry, tvb, offset, SD_ENTRY_LENGTH, "Unknown Entry (Type: %d)", type);
|
|
expert_add_info(pinfo, ti_top, &ef_someipsd_entry_unknown);
|
|
return;
|
|
}
|
|
|
|
if (ttl == 0) {
|
|
description = val_to_str(type, sd_entry_type_negative, "(Unknown Entry: %d)");
|
|
} else {
|
|
description = val_to_str(type, sd_entry_type_positive, "(Unknown Entry: %d)");
|
|
}
|
|
|
|
ti_top = proto_tree_add_none_format(tree, hf_someip_sd_entry, tvb, offset, SD_ENTRY_LENGTH, "%s Entry", description);
|
|
tree = proto_item_add_subtree(ti_top, ett_someip_sd_entry);
|
|
|
|
proto_tree_add_uint_format_value(tree, hf_someip_sd_entry_type, tvb, offset, 1, type, "0x%02x (%s)", type, description);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_index1, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_index2, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_numopt1, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_numopt2, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_serviceid, tvb, offset, 2, ENC_BIG_ENDIAN, &serviceid);
|
|
description = someip_lookup_service_name((guint16)serviceid);
|
|
if (description != NULL) {
|
|
proto_item_append_text(ti, " (%s)", description);
|
|
}
|
|
offset += 2;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_instanceid, tvb, offset, 2, ENC_BIG_ENDIAN, &instanceid);
|
|
offset += 2;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_majorver, tvb, offset, 1, ENC_BIG_ENDIAN, &majorver);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_ttl, tvb, offset, 3, ENC_BIG_ENDIAN);
|
|
offset += 3;
|
|
|
|
/* Add specific fields - i.e. the last line */
|
|
if (category == SD_ENTRY_SERVICE) {
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_minorver, tvb, offset, 4, ENC_BIG_ENDIAN, &minorver);
|
|
offset += 4;
|
|
|
|
proto_item_append_text(ti_top, " (Service ID 0x%04x, Instance ID 0x%04x, Version %u.%u)", serviceid, instanceid, majorver, minorver);
|
|
} else if (category == SD_ENTRY_EVENTGROUP) {
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_reserved, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_intial_event_flag, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_reserved2, tvb, offset, 1, ENC_NA);
|
|
proto_tree_add_item(tree, hf_someip_sd_entry_counter, tvb, offset, 1, ENC_NA);
|
|
offset += 1;
|
|
|
|
ti = proto_tree_add_item_ret_uint(tree, hf_someip_sd_entry_eventgroupid, tvb, offset, 2, ENC_BIG_ENDIAN, &eventgroupid);
|
|
description = someip_lookup_eventgroup_name((guint16)serviceid, (guint16)eventgroupid);
|
|
if (description != NULL) {
|
|
proto_item_append_text(ti, " (%s)", description);
|
|
}
|
|
offset += 2;
|
|
|
|
proto_item_append_text(ti_top, " (Service ID 0x%04x, Instance ID 0x%04x, Eventgroup ID 0x%04x, Version %u)", serviceid, instanceid, eventgroupid, majorver);
|
|
}
|
|
|
|
/* mark for attaching to info column */
|
|
if (type < 32) {
|
|
if (ttl == 0) {
|
|
*stop_entry_flags = *stop_entry_flags | (1 << type);
|
|
} else {
|
|
*entry_flags = *entry_flags | (1 << type);
|
|
}
|
|
}
|
|
|
|
/* lets add some combined filtering term */
|
|
uniqueid = (((guint64)serviceid) << 32) | instanceid << 16 | eventgroupid;
|
|
|
|
ti = NULL;
|
|
if (ttl > 0) {
|
|
switch (type) {
|
|
case SD_ENTRY_FIND_SERVICE:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_findservice, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
case SD_ENTRY_OFFER_SERVICE:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_offerservice, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
case SD_ENTRY_SUBSCRIBE_EVENTGROUP:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroup, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
case SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroupack, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
}
|
|
} else {
|
|
switch (type) {
|
|
case SD_ENTRY_STOP_OFFER_SERVICE:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_stopofferservice, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
case SD_ENTRY_STOP_SUBSCRIBE_EVENTGROUP:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_stopsubscribeeventgroup, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
case SD_ENTRY_SUBSCRIBE_EVENTGROUP_NACK:
|
|
ti = proto_tree_add_uint64_format_value(tree, hf_someip_sd_entry_type_subscribeeventgroupnack, tvb, offset, SD_ENTRY_LENGTH, uniqueid, "on 0x%012" G_GINT64_MODIFIER "x", uniqueid);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ti != NULL) {
|
|
PROTO_ITEM_SET_HIDDEN(ti);
|
|
}
|
|
}
|
|
|
|
static int
|
|
dissect_someip_sd_pdu_entries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint32 offset, guint32 length) {
|
|
guint32 entry_flags = 0;
|
|
guint32 stop_entry_flags = 0;
|
|
|
|
while (length >= SD_ENTRY_LENGTH) {
|
|
dissect_someip_sd_pdu_entry(tvb, pinfo, tree, offset, SD_ENTRY_LENGTH, &entry_flags, &stop_entry_flags);
|
|
offset += SD_ENTRY_LENGTH;
|
|
length -= SD_ENTRY_LENGTH;
|
|
}
|
|
|
|
/* Add entry flags */
|
|
if (stop_entry_flags != 0 || entry_flags != 0) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, " ");
|
|
}
|
|
|
|
if (entry_flags & (1 << SD_ENTRY_FIND_SERVICE)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[Find]");
|
|
}
|
|
|
|
if (stop_entry_flags & (1 << SD_ENTRY_OFFER_SERVICE)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[StopOffer]");
|
|
}
|
|
|
|
if (entry_flags & (1 << SD_ENTRY_OFFER_SERVICE)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[Offer]");
|
|
}
|
|
|
|
if (stop_entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[StopSubscribe]");
|
|
}
|
|
|
|
if (entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[Subscribe]");
|
|
}
|
|
|
|
if (stop_entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[SubscribeNack]");
|
|
}
|
|
|
|
if (entry_flags & (1 << SD_ENTRY_SUBSCRIBE_EVENTGROUP_ACK)) {
|
|
col_append_str(pinfo->cinfo, COL_INFO, "[SubscribeAck]");
|
|
}
|
|
|
|
if (length != 0) {
|
|
expert_add_info(pinfo, ti, &ef_someipsd_entry_array_malformed);
|
|
}
|
|
|
|
return length;
|
|
}
|
|
|
|
static int
|
|
dissect_someip_sd_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) {
|
|
guint32 offset = 0;
|
|
guint32 length_entriesarray = 0;
|
|
guint32 length_optionsarray = 0;
|
|
|
|
proto_item *ti = NULL;
|
|
proto_item *ti_sd_entries = NULL;
|
|
|
|
proto_tree *someip_sd_entries_tree = NULL;
|
|
proto_tree *someip_sd_options_tree = NULL;
|
|
gboolean stop_parsing_after_entries = FALSE;
|
|
guint32 offset_entriesarray;
|
|
|
|
static int * const someipsd_flags[] = {
|
|
&hf_someip_sd_rebootflag,
|
|
&hf_someip_sd_unicastflag,
|
|
&hf_someip_sd_explicitiniteventflag,
|
|
NULL
|
|
};
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, SOMEIP_SD_NAME);
|
|
col_set_str(pinfo->cinfo, COL_INFO, SOMEIP_SD_NAME_LONG);
|
|
|
|
ti = proto_tree_add_item(tree, proto_someip_sd, tvb, offset, -1, ENC_NA);
|
|
tree = proto_item_add_subtree(ti, ett_someip_sd);
|
|
|
|
if (!tvb_bytes_exist(tvb, offset, SOMEIP_SD_MIN_LENGTH)) {
|
|
expert_add_info(pinfo, ti, &ef_someipsd_message_truncated);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
/* add flags */
|
|
proto_tree_add_bitmask(tree, tvb, offset, hf_someip_sd_flags, ett_someip_sd_flags, someipsd_flags, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
|
|
/* add reserved */
|
|
proto_tree_add_item(tree, hf_someip_sd_reserved, tvb, offset, 3, ENC_BIG_ENDIAN);
|
|
offset += 3;
|
|
|
|
/* add length of entries */
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_length_entriesarray, tvb, offset, 4, ENC_BIG_ENDIAN, &length_entriesarray);
|
|
offset += 4;
|
|
|
|
if (!tvb_bytes_exist(tvb, offset, length_entriesarray)) {
|
|
expert_add_info(pinfo, ti , &ef_someipsd_message_truncated);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
if (!tvb_bytes_exist(tvb, offset, length_entriesarray)) {
|
|
/* truncated SD message - need to shorten buffer */
|
|
length_entriesarray = tvb_captured_length_remaining(tvb, offset);
|
|
expert_add_info(pinfo, ti, &ef_someipsd_message_truncated);
|
|
stop_parsing_after_entries = TRUE;
|
|
}
|
|
|
|
/* preparing entries array but not parsing it yet */
|
|
ti_sd_entries = proto_tree_add_item(tree, hf_someip_sd_entries, tvb, offset, length_entriesarray, ENC_NA);
|
|
someip_sd_entries_tree = proto_item_add_subtree(ti_sd_entries, ett_someip_sd_entries);
|
|
/* save offset to parse entries later since we need to parse options first */
|
|
offset_entriesarray = offset;
|
|
offset += length_entriesarray;
|
|
|
|
if (!stop_parsing_after_entries) {
|
|
/* make sure we have a length field */
|
|
if (tvb_bytes_exist(tvb, offset, 4)) {
|
|
|
|
/* add options length */
|
|
proto_tree_add_item_ret_uint(tree, hf_someip_sd_length_optionsarray, tvb, offset, 4, ENC_BIG_ENDIAN, &length_optionsarray);
|
|
offset += 4;
|
|
|
|
if (length_optionsarray > 0) {
|
|
if (tvb_bytes_exist(tvb, offset, 1)) {
|
|
ti = proto_tree_add_item(tree, hf_someip_sd_options, tvb, offset, -1, ENC_NA);
|
|
someip_sd_options_tree = proto_item_add_subtree(ti, ett_someip_sd_options);
|
|
|
|
/* check, if enough bytes are left for optionsarray */
|
|
if (!tvb_bytes_exist(tvb, offset, length_optionsarray)) {
|
|
length_optionsarray = tvb_captured_length_remaining(tvb, offset);
|
|
expert_add_info(pinfo, ti, &ef_someipsd_message_truncated);
|
|
proto_item_append_text(ti, " (truncated!)");
|
|
}
|
|
|
|
/* updating to length we will work with */
|
|
if (length_optionsarray > 0) {
|
|
proto_item_set_len(ti, length_optionsarray);
|
|
}
|
|
|
|
dissect_someip_sd_pdu_options(tvb, pinfo, someip_sd_options_tree, ti, offset, length_optionsarray);
|
|
offset += length_optionsarray;
|
|
} else {
|
|
expert_add_info(pinfo, ti, &ef_someipsd_message_truncated);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Possible improvement: it would be nice, if entries referenced options. */
|
|
if (length_entriesarray >= SD_ENTRY_LENGTH) {
|
|
offset += dissect_someip_sd_pdu_entries(tvb, pinfo, someip_sd_entries_tree, ti_sd_entries, offset_entriesarray, length_entriesarray);
|
|
} else {
|
|
expert_add_info(pinfo, ti_sd_entries, &ef_someipsd_entry_array_empty);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
void
|
|
proto_register_someip_sd(void) {
|
|
module_t *someipsd_module;
|
|
|
|
expert_module_t *expert_module_someip_sd;
|
|
|
|
/* data fields */
|
|
static hf_register_info hf_sd[] = {
|
|
{ &hf_someip_sd_flags,
|
|
{ "Flags", "someipsd.flags",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_rebootflag,
|
|
{ "Reboot Flag", "someipsd.flags.reboot",
|
|
FT_BOOLEAN, 8, TFS(&sd_reboot_flag), SOMEIP_SD_REBOOT_FLAG, NULL, HFILL }},
|
|
{ &hf_someip_sd_unicastflag,
|
|
{ "Unicast Flag", "someipsd.flags.unicast",
|
|
FT_BOOLEAN, 8, TFS(&sd_unicast_flag), SOMEIP_SD_UNICAST_FLAG, NULL, HFILL }},
|
|
{ &hf_someip_sd_explicitiniteventflag,
|
|
{ "Explicit Initial Events Flag", "someipsd.flags.exp_init_events",
|
|
FT_BOOLEAN, 8, TFS(&sd_eiec_flag), SOMEIP_SD_EXPL_INIT_EVENT_REQ_FLAG, NULL, HFILL }},
|
|
{ &hf_someip_sd_reserved,
|
|
{ "Reserved", "someipsd.reserved",
|
|
FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_someip_sd_length_entriesarray,
|
|
{ "Length of Entries Array", "someipsd.length_entriesarray",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entries,
|
|
{ "Entries Array", "someipsd.entries",
|
|
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry,
|
|
{ "Entry", "someipsd.entry",
|
|
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_type,
|
|
{ "Type", "someipsd.entry.type",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_index1,
|
|
{ "Index 1", "someipsd.entry.index1",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_index2,
|
|
{ "Index 2", "someipsd.entry.index2",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_numopt1,
|
|
{ "Number of Opts 1", "someipsd.entry.numopt1",
|
|
FT_UINT8, BASE_HEX, NULL, 0xf0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_numopt2,
|
|
{ "Number of Opts 2", "someipsd.entry.numopt2",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }},
|
|
|
|
{ &hf_someip_sd_entry_serviceid,
|
|
{ "Service ID", "someipsd.entry.serviceid",
|
|
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_instanceid,
|
|
{ "Instance ID", "someipsd.entry.instanceid",
|
|
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_majorver,
|
|
{ "Major Version", "someipsd.entry.majorver",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_ttl,
|
|
{ "TTL", "someipsd.entry.ttl",
|
|
FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_minorver,
|
|
{ "Minor Version", "someipsd.entry.minorver",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_eventgroupid,
|
|
{ "Eventgroup ID", "someipsd.entry.eventgroupid",
|
|
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_reserved,
|
|
{ "Reserved", "someipsd.entry.reserved",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_entry_counter,
|
|
{ "Counter", "someipsd.entry.counter",
|
|
FT_UINT8, BASE_HEX, NULL, SD_EVENTGROUP_ENTRY_COUNTER_MASK, NULL, HFILL } },
|
|
{ &hf_someip_sd_entry_reserved2,
|
|
{ "Reserved", "someipsd.entry.reserved2",
|
|
FT_UINT8, BASE_HEX, NULL, SD_EVENTGROUP_ENTRY_RES2_MASK, NULL, HFILL } },
|
|
{ &hf_someip_sd_entry_intial_event_flag,
|
|
{ "Initial Event Request", "someipsd.entry.initialevents",
|
|
FT_BOOLEAN, 8, NULL, SD_ENTRY_INIT_EVENT_REQ_MASK, NULL, HFILL } },
|
|
|
|
{ &hf_someip_sd_length_optionsarray,
|
|
{ "Length of Options Array", "someipsd.length_optionsarray",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_options,
|
|
{ "Options Array", "someipsd.options",
|
|
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_someip_sd_option_type,
|
|
{ "Type", "someipsd.option.type",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_length,
|
|
{ "Length", "someipsd.option.length",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_reserved,
|
|
{ "Reserved", "someipsd.option.reserved",
|
|
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_ipv4,
|
|
{ "IPv4 Address", "someipsd.option.ipv4address",
|
|
FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_ipv6,
|
|
{ "IPv6 Address", "someipsd.option.ipv6address",
|
|
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_port,
|
|
{ "Port", "someipsd.option.port",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_proto,
|
|
{ "Protocol", "someipsd.option.proto",
|
|
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_option_reserved2,
|
|
{ "Reserved 2", "someipsd.option.reserved2",
|
|
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_option_data,
|
|
{ "Unknown Data", "someipsd.option.unknown_data",
|
|
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_option_config_string,
|
|
{ "Configuration String", "someipsd.option.config_string",
|
|
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_option_lb_priority,
|
|
{ "Priority", "someipsd.option.priority",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_option_lb_weight,
|
|
{ "Weight", "someipsd.option.weight",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
|
|
{ &hf_someip_sd_entry_type_offerservice,
|
|
{ "Offer Service", "someipsd.entry.offerservice",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_type_stopofferservice,
|
|
{ "Stop Offer Service", "someipsd.entry.stopofferservice",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_type_findservice,
|
|
{ "Find Service", "someipsd.entry.findservice",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_someip_sd_entry_type_subscribeeventgroup,
|
|
{ "Subscribe Eventgroup", "someipsd.entry.subscribeeventgroup",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_type_stopsubscribeeventgroup,
|
|
{ "Stop Subscribe Eventgroup", "someipsd.entry.stopsubscribeeventgroup",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
|
|
{ &hf_someip_sd_entry_type_subscribeeventgroupack,
|
|
{ "Subscribe Eventgroup ACK", "someipsd.entry.subscribeeventgroupack",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_someip_sd_entry_type_subscribeeventgroupnack,
|
|
{ "Subscribe Eventgroup NACK", "someipsd.entry.subscribeeventgroupnack",
|
|
FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
|
};
|
|
|
|
static gint *ett_sd[] = {
|
|
&ett_someip_sd,
|
|
&ett_someip_sd_flags,
|
|
&ett_someip_sd_entries,
|
|
&ett_someip_sd_entry,
|
|
&ett_someip_sd_options,
|
|
&ett_someip_sd_option,
|
|
};
|
|
|
|
static ei_register_info ei_sd[] = {
|
|
{ &ef_someipsd_message_truncated,{ "someipsd.message_truncated", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Truncated message!", EXPFILL } },
|
|
{ &ef_someipsd_entry_array_malformed,{ "someipsd.entry_array_malformed", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Entry Array length not multiple of 16 bytes!", EXPFILL } },
|
|
{ &ef_someipsd_entry_array_empty,{ "someipsd.entry_array_empty", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Empty Entry Array!", EXPFILL } },
|
|
{ &ef_someipsd_entry_unknown,{ "someipsd.entry_unknown", PI_MALFORMED, PI_WARN, "SOME/IP-SD Unknown Entry!", EXPFILL } },
|
|
{ &ef_someipsd_option_array_truncated,{ "someipsd.option_array_truncated", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Option Array truncated!", EXPFILL } },
|
|
{ &ef_someipsd_option_array_bytes_left,{ "someipsd.option_array_bytes_left", PI_MALFORMED, PI_WARN, "SOME/IP-SD Option Array bytes left after parsing options!", EXPFILL } },
|
|
{ &ef_someipsd_option_unknown,{ "someipsd.option_unknown", PI_MALFORMED, PI_WARN, "SOME/IP-SD Unknown Option!", EXPFILL } },
|
|
{ &ef_someipsd_option_wrong_length,{ "someipsd.option_wrong_length", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Option length is incorrect!", EXPFILL } },
|
|
{ &ef_someipsd_L4_protocol_unsupported,{ "someipsd.L4_protocol_unsupported", PI_MALFORMED, PI_ERROR, "SOME/IP-SD Unsupported Layer 4 Protocol!", EXPFILL } },
|
|
};
|
|
|
|
/* Register ETTs */
|
|
proto_someip_sd = proto_register_protocol(SOMEIP_SD_NAME_LONG, SOMEIP_SD_NAME, SOMEIP_SD_NAME_FILTER);
|
|
proto_register_field_array(proto_someip_sd, hf_sd, array_length(hf_sd));
|
|
proto_register_subtree_array(ett_sd, array_length(ett_sd));
|
|
expert_module_someip_sd = expert_register_protocol(proto_someip_sd);
|
|
expert_register_field_array(expert_module_someip_sd, ei_sd, array_length(ei_sd));
|
|
|
|
/* Register preferences */
|
|
someipsd_module = prefs_register_protocol(proto_someip_sd, &proto_reg_handoff_someip_sd);
|
|
|
|
range_convert_str(wmem_epan_scope(), &someip_ignore_ports_udp, "", 65535);
|
|
prefs_register_range_preference(someipsd_module, "ports.udp.ignore", "UDP Ports ignored",
|
|
"SOME/IP Ignore Port Ranges UDP. These ports are not automatically added by the SOME/IP-SD.",
|
|
&someip_ignore_ports_udp, 65535);
|
|
|
|
range_convert_str(wmem_epan_scope(), &someip_ignore_ports_tcp, "", 65535);
|
|
prefs_register_range_preference(someipsd_module, "ports.tcp.ignore", "TCP Ports ignored",
|
|
"SOME/IP Ignore Port Ranges TCP. These ports are not automatically added by the SOME/IP-SD.",
|
|
&someip_ignore_ports_tcp, 65535);
|
|
}
|
|
|
|
void
|
|
proto_reg_handoff_someip_sd(void) {
|
|
static gboolean initialized = FALSE;
|
|
static dissector_handle_t someip_sd_handle = NULL;
|
|
|
|
if (!initialized) {
|
|
someip_sd_handle = create_dissector_handle(dissect_someip_sd_pdu, proto_someip_sd);
|
|
dissector_add_uint("someip.messageid", SOMEIP_SD_MESSAGEID, someip_sd_handle);
|
|
initialized = TRUE;
|
|
}
|
|
|
|
/* nothing to do here right now */
|
|
}
|
|
|
|
/*
|
|
* Editor modelines
|
|
*
|
|
* Local Variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|