Cyclic PROFINET PROFIsafe RTC1 data dissection

New implemented functions for profinet plug-in to read cyclic RTC1 data
frames more detailed and further to dissect PROFIsafe on PROFINET frames.

New functions include:
- Reading the PROFINET "Ident OK" Frame for detailed module information,
  as ModuleIdentNr., SubModuleIdentNr., etc. total dynamically
- Improved the existing dissection of fParameter with usage of GSDML-files,
  as the indexnumber for those parameters can change
- Reading a GSDML-file for further module-information, such as PROFIsafe
  Module, etc.
- Aded new pnio protocol preferences, in which the user can define its own
  network path to his GSDML-files, so that Wireshark is able to read those
  files for detailed information output.
- Added new filter functions for PROFINET and PROFIsafe
- All gained and saved information will be used to dissect the cyclic
  PROFINET frames

Bug: 12216
Change-Id: I379da1d349fa099047953042f1aa30450bee5b30
Reviewed-on: https://code.wireshark.org/review/14119
Petri-Dish: Jim Young <jim.young.ws@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Birol Capa <birol.capa@siemens.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
T. Scholz 2016-05-19 13:27:17 -04:00 committed by Michael Mann
parent 32c1a2a315
commit c0e679e0a9
8 changed files with 2045 additions and 116 deletions

View File

@ -1,3 +1,3 @@
Author :
Ulf Lamping <ulf.lamping@web.de>
Tobias Scholz <scholzt234@googlemail.com>

View File

@ -33,6 +33,7 @@ set(DISSECTOR_SRC
packet-pn-mrrt.c
packet-pn-ptcp.c
packet-pn-rt.c
packet-pn-rtc-one.c
)
set(DISSECTOR_SUPPORT_SRC

View File

@ -33,7 +33,8 @@ NONGENERATED_REGISTER_C_FILES = \
packet-pn-mrp.c \
packet-pn-mrrt.c \
packet-pn-ptcp.c \
packet-pn-rt.c
packet-pn-rt.c \
packet-pn-rtc-one.c
# Non-generated sources
NONGENERATED_C_FILES = \

File diff suppressed because it is too large Load Diff

View File

@ -21,22 +21,42 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Cyclic PNIO RTC1 Data Dissection:
*
* Added new functions to packet-pn-dcp.c. The profinet plug-in will now save
* the information (Stationname, -type, -id) of "Ident OK" frames. Those
* informations will later be used for detailled dissection of cyclic PNIO RTC1
* dataframes.
*
* The declaration of the new added structures are within packet-pn.h to
* use the information within packet-pn-rtc-one.c
*
* Overview for cyclic PNIO RTC1 data dissection functions:
* -> dissect_PNDCP_Suboption_Device (Save Stationname, -type, -id)
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/to_str.h>
#include <epan/wmem/wmem.h>
#include <epan/expert.h>
#include <epan/dissectors/packet-dcerpc.h>
#include <epan/conversation.h>
#include "packet-pn.h"
void proto_register_pn_dcp(void);
void proto_reg_handoff_pn_dcp(void);
static int proto_pn_dcp = -1;
int proto_pn_dcp = -1;
static int hf_pn_dcp_service_id = -1;
static int hf_pn_dcp_service_type = -1;
@ -95,7 +115,6 @@ static gint ett_pn_dcp_block = -1;
static expert_field ei_pn_dcp_block_error_unknown = EI_INIT;
static expert_field ei_pn_dcp_ip_conflict = EI_INIT;
#define PNDCP_SERVICE_ID_GET 0x03
#define PNDCP_SERVICE_ID_SET 0x04
#define PNDCP_SERVICE_ID_IDENTIFY 0x05
@ -483,7 +502,8 @@ dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint8 device_instance_low;
guint16 oem_vendor_id;
guint16 oem_device_id;
conversation_t *conversation;
stationInfo *station_info;
/* SuboptionDevice... */
offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device, &suboption);
@ -523,8 +543,28 @@ dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo,
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
proto_item_append_text(block_item, ", DeviceVendorValue: \"%s\"", typeofstation);
if (pinfo->fd->flags.visited == FALSE) {
/* Create a conversation between the MAC addresses */
conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
if (conversation == NULL) {
conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
}
station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
if (station_info == NULL) {
station_info = wmem_new0(wmem_file_scope(), stationInfo);
init_pnio_rtc1_station(station_info);
conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
}
station_info->typeofstation = wmem_strdup(wmem_file_scope(), typeofstation);
}
offset += block_length;
break;
case PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION:
nameofstation = (char *)wmem_alloc(wmem_packet_scope(), block_length+1);
tvb_memcpy(tvb, (guint8 *) nameofstation, offset, block_length);
@ -541,11 +581,51 @@ dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo,
val_to_str(block_info, pn_dcp_block_info, "Unknown"));
}
proto_item_append_text(block_item, ", \"%s\"", nameofstation);
if (pinfo->fd->flags.visited == FALSE) {
/* Create a conversation between the MAC addresses */
conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
if (conversation == NULL) {
conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
}
station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
if (station_info == NULL) {
station_info = wmem_new0(wmem_file_scope(), stationInfo);
init_pnio_rtc1_station(station_info);
conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
}
station_info->nameofstation = wmem_strdup(wmem_file_scope(), nameofstation);
}
offset += block_length;
break;
case PNDCP_SUBOPTION_DEVICE_DEV_ID:
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_vendor_id, &vendor_id);
offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_id, &device_id);
if (pinfo->fd->flags.visited == FALSE) {
/* Create a conversation between the MAC addresses */
conversation = find_conversation(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
if (conversation == NULL) {
conversation = conversation_new(pinfo->num, &pinfo->dl_src, &pinfo->dl_dst, PT_NONE, 0, 0, 0);
}
station_info = (stationInfo*)conversation_get_proto_data(conversation, proto_pn_dcp);
if (station_info == NULL) {
station_info = wmem_new0(wmem_file_scope(), stationInfo);
init_pnio_rtc1_station(station_info);
conversation_add_proto_data(conversation, proto_pn_dcp, station_info);
}
station_info->u16Vendor_id = vendor_id;
station_info->u16Device_id = device_id;
}
pn_append_info(pinfo, dcp_item, ", Dev-ID");
proto_item_append_text(block_item, "Device/Device ID");
if (have_block_qualifier) {

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/wmem/wmem.h>
#include <epan/dissectors/packet-dcerpc.h>
#include "packet-pn.h"
@ -42,6 +43,16 @@ static int hf_pn_malformed = -1;
static expert_field ei_pn_undecoded_data = EI_INIT;
/* Initialize PNIO RTC1 stationInfo memory */
void
init_pnio_rtc1_station(stationInfo *station_info) {
station_info->iocs_data_in = wmem_list_new(wmem_file_scope());
station_info->iocs_data_out = wmem_list_new(wmem_file_scope());
station_info->ioobject_data_in = wmem_list_new(wmem_file_scope());
station_info->ioobject_data_out = wmem_list_new(wmem_file_scope());
station_info->diff_module = wmem_list_new(wmem_file_scope());
}
/* dissect an 8 bit unsigned integer */
int
dissect_pn_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,

View File

@ -20,13 +20,94 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Cyclic PNIO RTC1 Data Dissection:
*
* Added new structures to packet-pn.h to transfer the gained data of
* packet-pn-dcp.c and packet-dcerpc-pn-io.c to packet-pn-rtc-one.c for
* detailled dissection of cyclic PNIO RTC1 dataframes.
*
*/
#define FRAME_ID_DCP_HELLO 0xfefc
#define FRAME_ID_DCP_GETORSET 0xfefd
#define FRAME_ID_DCP_IDENT_REQ 0xfefe
#define FRAME_ID_DCP_IDENT_RES 0xfeff
/* ---- Structures for pnio_rtc1 ---- */
extern int proto_pn_dcp;
extern gboolean pnio_ps_selection; /* given by pnio preferences */
/* Structure for general station information */
typedef struct tagStationInfo {
/* general information */
gchar *typeofstation;
gchar *nameofstation;
guint16 u16Vendor_id;
guint16 u16Device_id;
/* frame structure */
guint16 ioDataObjectNr;
guint16 iocsNr;
/* GSDfile station information */
gboolean gsdFound;
gboolean gsdPathLength;
gchar *gsdLocation;
/* IOCS object data */
wmem_list_t *iocs_data_in;
wmem_list_t *iocs_data_out;
/* IOData object data */
wmem_list_t *ioobject_data_in;
wmem_list_t *ioobject_data_out;
/* Different ModuleIdentnumber */
wmem_list_t *diff_module;
} stationInfo;
/* Structure for IOCS Frames */
typedef struct tagIocsObject {
guint16 slotNr;
guint16 subSlotNr;
guint16 frameOffset;
} iocsObject;
/* Structure for IO Data Objects */
typedef struct tagIoDataObject {
guint16 slotNr;
guint16 subSlotNr;
guint32 moduleIdentNr;
guint32 subModuleIdentNr;
guint16 frameOffset;
guint16 length;
guint16 amountInGSDML;
guint32 fParameterIndexNr;
guint16 f_par_crc1;
guint16 f_src_adr;
guint16 f_dest_adr;
gboolean f_crc_seed;
guint8 f_crc_len;
address srcAddr;
address dstAddr;
gboolean profisafeSupported;
gboolean discardIOXS;
gchar *moduleNameStr;
tvbuff_t *tvb_slot;
tvbuff_t *tvb_subslot;
/* Status- or Controlbyte data*/
guint8 last_sb_cb;
guint8 lastToggleBit;
} ioDataObject;
/* Structure for Modules with different ModuleIdentnumber */
typedef struct tagModuleDiffInfo {
guint16 slotNr;
guint32 modulID;
} moduleDiffInfo;
extern void init_pn(int proto);
extern void init_pn_io_rtc1(int proto);
extern void init_pnio_rtc1_station(stationInfo *station_info);
extern int dissect_pn_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo,
proto_tree *tree, int hfindex, guint8 *pdata);
@ -77,6 +158,9 @@ extern int dissect_pn_padding(tvbuff_t *tvb, int offset, packet_info *pinfo,
extern int dissect_pn_align4(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
extern int dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, packet_info *pinfo,
proto_tree *tree, guint8 *drep _U_);
extern void pn_append_info(packet_info *pinfo, proto_item *dcp_item, const char *text);
extern gboolean dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);