PROFINET: Additional DCP features are added.

Missing DCP features are implemented.
Minor bugs are fixed as well.

Change-Id: I2deb00ca61a09cc290a692eadaea4eaa1a52fb85
Reviewed-on: https://code.wireshark.org/review/32030
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
moguz 2019-02-14 14:22:03 -08:00 committed by Anders Broman
parent 434a95625b
commit d184edbaed
1 changed files with 187 additions and 23 deletions

View File

@ -70,6 +70,7 @@ static int hf_pn_dcp_suboption_ip_block_info = -1;
static int hf_pn_dcp_suboption_ip_ip = -1;
static int hf_pn_dcp_suboption_ip_subnetmask = -1;
static int hf_pn_dcp_suboption_ip_standard_gateway = -1;
static int hf_pn_dcp_suboption_ip_mac_address = -1;
static int hf_pn_dcp_suboption_device = -1;
static int hf_pn_dcp_suboption_device_typeofstation = -1;
@ -84,7 +85,10 @@ static int hf_pn_dcp_suboption_device_oem_ven_id = -1;
static int hf_pn_dcp_suboption_device_oem_dev_id = -1;
static int hf_pn_dcp_suboption_dhcp = -1;
static int hf_pn_dcp_suboption_dhcp_device_id = -1;
static int hf_pn_dcp_suboption_dhcp_parameter_length = -1;
static int hf_pn_dcp_suboption_dhcp_parameter_data = -1;
static int hf_pn_dcp_suboption_dhcp_arbitrary_client_id = -1;
static int hf_pn_dcp_suboption_dhcp_control_parameter_data = -1;
static int hf_pn_dcp_suboption_control = -1;
static int hf_pn_dcp_suboption_control_option = -1;
@ -221,11 +225,13 @@ static const value_string pn_dcp_option[] = {
#define PNDCP_SUBOPTION_IP_MAC 0x01
#define PNDCP_SUBOPTION_IP_IP 0x02
#define PNDCP_SUBOPTION_IP_FULL_IP_SUITE 0x03
static const value_string pn_dcp_suboption_ip[] = {
{ 0x00, "Reserved" },
{ PNDCP_SUBOPTION_IP_MAC, "MAC address" },
{ PNDCP_SUBOPTION_IP_IP, "IP parameter" },
{ PNDCP_SUBOPTION_IP_FULL_IP_SUITE, "Full IP suite" },
/*0x03 - 0xff reserved */
{ 0, NULL }
};
@ -270,21 +276,29 @@ static const value_string pn_dcp_suboption_device[] = {
};
#define PNDCP_SUBOPTION_DHCP_CLIENT_ID 61
#define PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES 255
static const value_string pn_dcp_suboption_dhcp[] = {
{ 12, "Host name" },
{ 43, "Vendor specific" },
{ 54, "Server identifier" },
{ 55, "Parameter request list" },
{ 60, "Class identifier" },
{ PNDCP_SUBOPTION_DHCP_CLIENT_ID, "DHCP client identifier" },
{ 81, "FQDN, Fully Qualified Domain Name" },
{ 97, "UUID/GUID-based Client" },
{ 255, "Control DHCP for address resolution" },
{ 12, "Host name" },
{ 43, "Vendor specific" },
{ 54, "Server identifier" },
{ 55, "Parameter request list" },
{ 60, "Class identifier" },
{ PNDCP_SUBOPTION_DHCP_CLIENT_ID, "DHCP client identifier" },
{ 81, "FQDN, Fully Qualified Domain Name" },
{ 97, "UUID/GUID-based Client" },
{ PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES, "Control DHCP for address resolution" },
/*all others reserved */
{ 0, NULL }
};
static const value_string pn_dcp_suboption_dhcp_control_parameter_data[] = {
{ 0x00, "Don't use DHCP (Default)" },
{ 0x01, "Don't use DHCP, all DHCPOptions set to Reset to Factory value" },
{ 0x02, "Use DHCP with the given set of DHCPOptions" },
{ 0, NULL }
};
#define PNDCP_SUBOPTION_CONTROL_START_TRANS 0x01
#define PNDCP_SUBOPTION_CONTROL_END_TRANS 0x02
#define PNDCP_SUBOPTION_CONTROL_SIGNAL 0x03
@ -402,6 +416,9 @@ dissect_PNDCP_Suboption_IP(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint16 block_length;
guint16 block_info;
guint16 block_qualifier;
gboolean have_block_info = FALSE;
gboolean have_block_qualifier = FALSE;
guint8 mac[6];
guint32 ip;
proto_item *item = NULL;
address addr;
@ -418,23 +435,50 @@ dissect_PNDCP_Suboption_IP(tvbuff_t *tvb, int offset, packet_info *pinfo,
pn_append_info(pinfo, dcp_item, ", MAC");
proto_item_append_text(block_item, "IP/MAC");
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
/* BlockInfo? */
if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
have_block_info = TRUE;
block_length -= 2;
}
/* BlockQualifier? */
if ((service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
have_block_qualifier = TRUE;
block_length -= 2;
}
if (have_block_qualifier) {
proto_item_append_text(block_item, ", BlockQualifier: %s",
val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
}
if (have_block_info) {
proto_item_append_text(block_item, ", BlockInfo: %s",
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
offset = dissect_pn_mac(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_mac_address, mac);
set_address(&addr, AT_ETHER, 6, mac);
proto_item_append_text(block_item, ", MACAddress: %s", address_to_str(wmem_packet_scope(), &addr));
break;
case PNDCP_SUBOPTION_IP_IP:
pn_append_info(pinfo, dcp_item, ", IP");
proto_item_append_text(block_item, "IP/IP");
/* BlockInfo? */
if ( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
block_info = tvb_get_ntohs (tvb, offset);
if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
block_info = tvb_get_ntohs(tvb, offset);
if (tree) {
item = proto_tree_add_uint(tree, hf_pn_dcp_suboption_ip_block_info, tvb, offset, 2, block_info);
}
offset += 2;
proto_item_append_text(block_item, ", BlockInfo: %s",
val_to_str(block_info, pn_dcp_suboption_ip_block_info, "Undecoded"));
val_to_str(block_info, pn_dcp_suboption_ip_block_info, "Undecoded"));
block_length -= 2;
if (block_info & 0x80) {
expert_add_info(pinfo, item, &ei_pn_dcp_ip_conflict);
@ -465,6 +509,70 @@ dissect_PNDCP_Suboption_IP(tvbuff_t *tvb, int offset, packet_info *pinfo,
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", Gateway: %s", address_to_str(wmem_packet_scope(), &addr));
break;
case PNDCP_SUBOPTION_IP_FULL_IP_SUITE:
pn_append_info(pinfo, dcp_item, ", MAC");
proto_item_append_text(block_item, "IP/MAC");
/* BlockInfo? */
if (((service_id == PNDCP_SERVICE_ID_IDENTIFY) && is_response) ||
((service_id == PNDCP_SERVICE_ID_HELLO) && !is_response) ||
((service_id == PNDCP_SERVICE_ID_GET) && is_response)) {
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
block_length -= 2;
}
/* BlockQualifier? */
if ((service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
block_length -= 2;
}
if (have_block_qualifier) {
proto_item_append_text(block_item, ", BlockQualifier: %s",
val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
}
if (have_block_info) {
proto_item_append_text(block_item, ", BlockInfo: %s",
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
/* IPAddress */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", IP: %s", address_to_str(wmem_packet_scope(), &addr));
/* Subnetmask */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", Subnet: %s", address_to_str(wmem_packet_scope(), &addr));
/* StandardGateway */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", Gateway: %s", address_to_str(wmem_packet_scope(), &addr));
/* IPAddress_1 */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_ip, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", DNSServerIP1: %s", address_to_str(wmem_packet_scope(), &addr));
/* IPAddress_2 */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_subnetmask, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", DNSServerIP2: %s", address_to_str(wmem_packet_scope(), &addr));
/* IPAddress_3 */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", DNSServerIP3: %s", address_to_str(wmem_packet_scope(), &addr));
/* IPAddress_4 */
offset = dissect_pn_ipv4(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_ip_standard_gateway, &ip);
set_address(&addr, AT_IPv4, 4, &ip);
proto_item_append_text(block_item, ", DNSServerIP4: %s", address_to_str(wmem_packet_scope(), &addr));
break;
default:
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
@ -759,6 +867,10 @@ dissect_PNDCP_Suboption_DHCP(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint16 block_length;
guint16 block_info = 0;
guint16 block_qualifier = 0;
guint8 dhcpparameterlength = 0;
guint8 dhcpparameterdata = 0;
guint8 dhcpcontrolparameterdata = 0;
char *arbitraryclientID;
gboolean have_block_info = FALSE;
gboolean have_block_qualifier = FALSE;
@ -774,7 +886,6 @@ dissect_PNDCP_Suboption_DHCP(tvbuff_t *tvb, int offset, packet_info *pinfo,
have_block_info=TRUE;
block_length -= 2;
}
/* BlockQualifier? */
if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
@ -794,8 +905,41 @@ dissect_PNDCP_Suboption_DHCP(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_item_append_text(block_item, ", BlockInfo: %s",
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
proto_tree_add_item(tree, hf_pn_dcp_suboption_dhcp_device_id, tvb, offset, block_length, ENC_NA);
offset += block_length;
offset += 1;//SuboptionDHCP
offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_length, &dhcpparameterlength);
offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_data, &dhcpparameterdata);
if (dhcpparameterlength == 1) {
if (dhcpparameterdata == 1) {
proto_item_append_text(block_item, ", Client-ID: MAC Address");
}
else {
proto_item_append_text(block_item, ", Client-ID: Name of Station");
}
}
else {
proto_item_append_text(block_item, ", Client-ID: Arbitrary");
arbitraryclientID = (char *)wmem_alloc(wmem_packet_scope(), dhcpparameterlength);
tvb_memcpy(tvb, (guint8 *)arbitraryclientID, offset, 5);
arbitraryclientID[dhcpparameterlength - 1] = '\0';
proto_tree_add_string(tree, hf_pn_dcp_suboption_dhcp_arbitrary_client_id, tvb, offset, dhcpparameterlength - 1, arbitraryclientID);
offset += dhcpparameterlength;
}
break;
case PNDCP_SUBOPTION_DHCP_CONTROL_FOR_ADDRESS_RES:
pn_append_info(pinfo, dcp_item, ", Control DHCP for address resolution");
proto_item_append_text(block_item, "DHCP/Control DHCP for address resolution");
if (have_block_qualifier) {
proto_item_append_text(block_item, ", BlockQualifier: %s",
val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
}
if (have_block_info) {
proto_item_append_text(block_item, ", BlockInfo: %s",
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
offset += 1;//SuboptionDHCP
offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_parameter_length, &dhcpparameterlength);
offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_dhcp_control_parameter_data, &dhcpcontrolparameterdata);
break;
default:
offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
@ -877,7 +1021,7 @@ dissect_PNDCP_Suboption_Control(tvbuff_t *tvb, int offset, packet_info *pinfo,
pn_append_info(pinfo, dcp_item, ", Reset to Factory");
proto_item_append_text(block_item, "Reset to FactorySettings");
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_blockqualifier, &BlockQualifier);
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_blockqualifier_r2f, &BlockQualifier);
proto_item_append_text(block_item, ", BlockQualifier: %s",
val_to_str(BlockQualifier, pn_dcp_BlockQualifier, "reserved"));
block_length -= 2;
@ -1251,6 +1395,11 @@ proto_register_pn_dcp (void)
FT_UINT16, BASE_DEC, VALS(pn_dcp_suboption_ip_block_info), 0x0,
NULL, HFILL }},
{ &hf_pn_dcp_suboption_ip_mac_address,
{ "MAC Address", "pn_dcp.suboption_ip_mac_address",
FT_ETHER, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
{ &hf_pn_dcp_suboption_ip_ip,
{ "IPaddress", "pn_dcp.subobtion_ip_ip",
FT_IPv4, BASE_NONE, NULL, 0x0,
@ -1326,11 +1475,26 @@ proto_register_pn_dcp (void)
FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_dhcp), 0x0,
NULL, HFILL }},
{ &hf_pn_dcp_suboption_dhcp_device_id,
{ "Device ID", "pn_dcp.suboption_dhcp_device_id",
FT_BYTES, BASE_NONE, NULL, 0x0,
{ &hf_pn_dcp_suboption_dhcp_arbitrary_client_id,
{ "Client ID", "pn_dcp.suboption_dhcp_client_id",
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
{ &hf_pn_dcp_suboption_dhcp_parameter_length,
{ "DHCP Parameter Length", "pn_dcp.suboption_dhcp_parameter_length",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL } },
{ &hf_pn_dcp_suboption_dhcp_parameter_data,
{ "DHCP Parameter Data", "pn_dcp.suboption_dhcp_parameter_data",
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL } },
{ &hf_pn_dcp_suboption_dhcp_control_parameter_data,
{ "DHCP Parameter Data", "pn_dcp.suboption_dhcp_parameter_data",
FT_UINT8, BASE_HEX, VALS(pn_dcp_suboption_dhcp_control_parameter_data), 0x0,
NULL, HFILL } },
{ &hf_pn_dcp_suboption_control,
{ "Suboption", "pn_dcp.suboption_control",
FT_UINT8, BASE_DEC, VALS(pn_dcp_suboption_control), 0x0,