aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-04-11 15:50:43 +0000
committerEvan Huus <eapache@gmail.com>2013-04-11 15:50:43 +0000
commit4a5b3a62fe30325cb00d1fefbb73774a96818c6f (patch)
tree686b615ac382a13036f4b5770a58b75ae1baddd8 /epan
parent7eda94d5b0db18dacbc4b4ede3c3522a15958a3a (diff)
From Roland Knall via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8505
Numerous improvements and fixes for the OpenSafety dissector (too many to usefully list here; see the bug). As noted by Pascal, also fix a copy-paste error in the preferences registration. svn path=/trunk/; revision=48817
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-opensafety.c1312
1 files changed, 904 insertions, 408 deletions
diff --git a/epan/dissectors/packet-opensafety.c b/epan/dissectors/packet-opensafety.c
index 10c9fdefb6..8d215e2db1 100644
--- a/epan/dissectors/packet-opensafety.c
+++ b/epan/dissectors/packet-opensafety.c
@@ -46,6 +46,7 @@
#include <epan/etypes.h>
#include <epan/emem.h>
#include <epan/expert.h>
+#include <epan/reassemble.h>
#include <epan/strutil.h>
#include <epan/dissectors/packet-udp.h>
#include <epan/dissectors/packet-frame.h>
@@ -186,6 +187,7 @@ static const value_string sn_fail_error_group[] = {
{ 2, "Parameter" },
{ 3, "Vendor specific" },
{ 4, "openSAFETY Stack" },
+ { 5, "Additional parameter needed" },
{ 0, NULL }
};
@@ -252,23 +254,105 @@ static const true_false_string opensafety_sacmd_blk = { "Block Transfer", "Norm
#define OPENSAFETY_SPDO_CONNECTION_VALID 0x04
+#define OPENSAFETY_SOD_DVI 0x1018
+#define OPENSAFETY_SOD_RXMAP 0x1800
+#define OPENSAFETY_SOD_TXMAP 0xC000
+
static const value_string sod_idx_names[] = {
- /* SSDO dictionary names, only names that are in common use are presented */
-
- { 0x10180000, "Device Vendor Information" },
- { 0x10180001, "VendorID" },
- { 0x10180002, "ProductCode" },
- { 0x10180003, "RevisionNumber" },
- { 0x10180004, "SerialNumber" },
- { 0x10180005, "FirmWareChecksum" },
- { 0x10180006, "Parameter Checksum" },
- { 0x10180007, "Parameter Timestamp" },
-
- { 0x10190000, "Unique Device ID" },
- { 0x101A0000, "Parameter Download" },
- { 0x101B0000, "SCM Parameters" },
-
- { 0, NULL }
+ /* SSDO dictionary names, only names that are in common use are presented */
+ { 0x100C0000, "Life Guarding" },
+ { 0x100C0001, "Guard Time" },
+ { 0x100C0002, "LifeTimeFactor" },
+
+ { 0x100D0000, "Number of Retries for Reset Guarding" },
+
+ { 0x10180000 , "Device Vendor Information" },
+ { 0x10180001, "VendorID" },
+ { 0x10180002, "ProductCode" },
+ { 0x10180003, "RevisionNumber" },
+ { 0x10180004, "SerialNumber" },
+ { 0x10180005, "FirmWareChecksum" },
+ { 0x10180006, "Parameter Checksum" },
+ { 0x10180007, "Parameter Timestamp" },
+
+ { 0x10190000, "Unique Device ID" },
+ { 0x101A0000, "Parameter Download" },
+ { 0x101B0000, "SCM Parameters" },
+
+ { 0x12000000, "Common Communication Parameters" },
+ { 0x12000001, "Safety Domain Number" },
+ { 0x12000002, "SADR" },
+ { 0x12000003, "Consecutive Timebase" },
+ { 0x12000004, "UDID of SCM" },
+
+ { 0x14000000, "RxSPDO Communication Parameters" },
+ { 0x14000001, "SADR" },
+ { 0x14000002, "SCT" },
+ { 0x14000003, "Number of consecutive TReq" },
+ { 0x14000004, "Time delay TReq" },
+ { 0x14000005, "Time delay Sync" },
+ { 0x14000006, "Min TSync Propagation Delay" },
+ { 0x14000007, "Max TSync Propagation Delay" },
+ { 0x14000008, "Min SPDO Propagation Delay" },
+ { 0x14000009, "Max SPDO Propagation Delay" },
+ { 0x1400000A, "Best case TRes Delay" },
+ { 0x1400000B, "Time Request Cycle" },
+ { 0x1400000C, "TxSPDO No" },
+
+ { 0x18000000, "RxSPDO Mapping Parameters" },
+
+ { 0x1C000000, "TxSPDO Communication Parameters" },
+ { 0x1C000001, "SADR for broadcast" },
+ { 0x1C000002, "Refresh Prescale" },
+ { 0x1C000003, "Number of TRes" },
+
+ { 0x20000000, "Manufacturer Parameters" },
+ { 0x20010000, "Used Channels" },
+
+ { 0x21000000, "Safe Machine Options" },
+
+ { 0x21010000, "SDG CRC Configuration" },
+ { 0x21010001, "SDG CRC #1" },
+ { 0x21010002, "SDG CRC #2" },
+ { 0x21010003, "SDG CRC #3" },
+ { 0x21010004, "SDG CRC #4" },
+ { 0x21010005, "SDG CRC #5" },
+ { 0x21010006, "SDG CRC #6" },
+ { 0x21010007, "SDG CRC #7" },
+ { 0x21010008, "SDG CRC #8" },
+ { 0x21010009, "SDG CRC #9" },
+ { 0x2101000A, "SDG CRC #10" },
+
+ { 0x21120000, "Manufacturer - Module specific" },
+ { 0x21120002, "PDOmapRx" },
+ { 0x21120003, "PDOmapTx" },
+ { 0x21120004, "CycleTime min [us]" },
+ { 0x21120005, "CycleTime max [us]" },
+ { 0x21120006, "Used Channels (same as 0x2001)" },
+ { 0x21120007, "External Machine Options" },
+ { 0x21120008, "Parameter for SafeMC" },
+
+ { 0xC0000000, "TxSPDO Mapping Parameters" },
+
+ { 0xD0000000, "SCM Module Flags" },
+ { 0xD0000001, "BCM" },
+ { 0xD0000002, "Optional" },
+ { 0xD0000003, "Startup" },
+ { 0xD0000004, "EMOs" },
+ { 0xD0000005, "ext. Startup-Flags allowed" },
+ { 0xD0000006, "Remote-Ctrl allowed" },
+ { 0xD0000007, "Scans at startup" },
+ { 0xD0000008, "Not Present" },
+ { 0xD0000009, "Use Remanent Data" },
+ { 0xD000000A, "SCM-AR specific" },
+
+ { 0xD0100000, "Remanent Data" },
+ { 0xD0100001, "DINT" },
+
+ { 0xD0110000, "Remanent Data" },
+ { 0xD0110001, "DUINT" },
+
+ { 0, NULL }
};
static const value_string abort_codes[] = {
@@ -332,10 +416,14 @@ static const true_false_string opensafety_message_direction = { "Request", "Resp
#define OSS_MINIMUM_LENGTH 0x0b /* 11 */
#define OSS_FRAME_ADDR(f, offset) (f[OSS_FRAME_POS_ADDR + offset] + ((guint8)((f[OSS_FRAME_POS_ADDR + offset + 1]) << 6) << 2))
-#define OSS_FRAME_ID(f, offset) ((f[OSS_FRAME_POS_ID + offset] >> 2 ) << 2)
+#define OSS_FRAME_ID(f, offset) (f[OSS_FRAME_POS_ID + offset] & 0xFC )
#define OSS_FRAME_LENGTH(f, offset) (f[OSS_FRAME_POS_LEN + offset])
#define OSS_FRAME_FIELD(f, position) (f[position])
+#define OSS_FRAME_ADDR_T(f, offset) (tvb_get_guint8(f, OSS_FRAME_POS_ADDR + offset) + ((guint8)((tvb_get_guint8( f, OSS_FRAME_POS_ADDR + offset + 1)) << 6) << 2))
+#define OSS_FRAME_ADDR_T2(f, offset, su1, su2) (( tvb_get_guint8(f, OSS_FRAME_POS_ADDR + offset) ^ su1) + ((guint8)(((tvb_get_guint8( f, OSS_FRAME_POS_ADDR + offset + 1) ^ su2)) << 6) << 2))
+#define OSS_FRAME_ID_T(f, offset) (tvb_get_guint8(f, OSS_FRAME_POS_ID + offset) & 0xFC)
+#define OSS_FRAME_LENGTH_T(f, offset) (tvb_get_guint8(f, OSS_FRAME_POS_LEN + offset))
static int proto_opensafety = -1;
@@ -345,6 +433,10 @@ static gint ett_opensafety_snmt = -1;
static gint ett_opensafety_ssdo = -1;
static gint ett_opensafety_spdo = -1;
static gint ett_opensafety_ssdo_sacmd = -1;
+static gint ett_opensafety_ssdo_payload = -1;
+static gint ett_opensafety_ssdo_sodentry = -1;
+static gint ett_opensafety_ssdo_extpar = -1;
+static gint ett_opensafety_sod_mapping = -1;
static gint ett_opensafety_sender = -1;
static gint ett_opensafety_receiver = -1;
@@ -356,7 +448,6 @@ static int hf_oss_msg_network = -1;
static int hf_oss_msg_sender = -1;
static int hf_oss_msg_receiver = -1;
static int hf_oss_length= -1;
-/* static int hf_oss_data = -1; */
static int hf_oss_crc = -1;
static int hf_oss_crc_valid = -1;
@@ -367,23 +458,28 @@ static int hf_oss_snmt_master = -1;
static int hf_oss_snmt_udid = -1;
static int hf_oss_snmt_scm = -1;
static int hf_oss_snmt_tool = -1;
-static int hf_oss_snmt_timestamp = -1;
static int hf_oss_snmt_service_id = -1;
static int hf_oss_snmt_error_group = -1;
static int hf_oss_snmt_error_code = -1;
static int hf_oss_ssdo_server = -1;
static int hf_oss_ssdo_client = -1;
-/* static int hf_oss_ssdo_sano = -1; */
+static int hf_oss_ssdo_sano = -1;
static int hf_oss_ssdo_sacmd = -1;
static int hf_oss_ssdo_sod_index = -1;
static int hf_oss_ssdo_sod_subindex = -1;
static int hf_oss_ssdo_payload = -1;
static int hf_oss_ssdo_payload_size = -1;
-/* static int hf_oss_ssdo_segment_size = -1; */
+static int hf_oss_ssdo_sodentry_size = -1;
+static int hf_oss_ssdo_sodentry_data = -1;
/* static int hf_oss_ssdo_inhibit_time = -1; */
static int hf_oss_ssdo_abort_code = -1;
+static int hf_oss_sod_par_timestamp = -1;
+static int hf_oss_sod_par_checksum = -1;
+static int hf_oss_ssdo_sodmapping = -1;
+static int hf_oss_ssdo_sodmapping_bits = -1;
+
static int hf_oss_ssdo_sacmd_access_type = -1;
/* static int hf_oss_ssdo_sacmd_reserved = -1; */
static int hf_oss_ssdo_sacmd_abort_transfer = -1;
@@ -393,6 +489,15 @@ static int hf_oss_ssdo_sacmd_initiate = -1;
static int hf_oss_ssdo_sacmd_end_segment = -1;
static int hf_oss_ssdo_sacmd_block_transfer = -1;
+static int hf_oss_ssdo_extpar_parset = -1;
+static int hf_oss_ssdo_extpar_version = -1;
+static int hf_oss_ssdo_extpar_saddr = -1;
+static int hf_oss_ssdo_extpar_length = -1;
+static int hf_oss_ssdo_extpar_crc = -1;
+static int hf_oss_ssdo_extpar_tstamp = -1;
+static int hf_oss_ssdo_extpar_data = -1;
+static int hf_oss_ssdo_extpar = -1;
+
static int hf_oss_scm_udid = -1;
static int hf_oss_scm_udid_auto = -1;
static int hf_oss_scm_udid_valid = -1;
@@ -406,9 +511,48 @@ static int hf_oss_spdo_time_request = -1;
static int hf_oss_spdo_time_request_to = -1;
static int hf_oss_spdo_time_request_from = -1;
+static int hf_oss_fragments = -1;
+static int hf_oss_fragment = -1;
+static int hf_oss_fragment_overlap = -1;
+static int hf_oss_fragment_overlap_conflicts = -1;
+static int hf_oss_fragment_multiple_tails = -1;
+static int hf_oss_fragment_too_long_fragment = -1;
+static int hf_oss_fragment_error = -1;
+static int hf_oss_fragment_count = -1;
+static int hf_oss_reassembled_in = -1;
+static int hf_oss_reassembled_length = -1;
+static int hf_oss_reassembled_data = -1;
+
+static gint ett_opensafety_ssdo_fragment = -1;
+static gint ett_opensafety_ssdo_fragments = -1;
+
+static const fragment_items oss_frag_items = {
+ /* Fragment subtrees */
+ &ett_opensafety_ssdo_fragment,
+ &ett_opensafety_ssdo_fragments,
+ /* Fragment fields */
+ &hf_oss_fragments,
+ &hf_oss_fragment,
+ &hf_oss_fragment_overlap,
+ &hf_oss_fragment_overlap_conflicts,
+ &hf_oss_fragment_multiple_tails,
+ &hf_oss_fragment_too_long_fragment,
+ &hf_oss_fragment_error,
+ &hf_oss_fragment_count,
+ /* Reassembled in field */
+ &hf_oss_reassembled_in,
+ /* Reassembled length field */
+ &hf_oss_reassembled_length,
+ /* Reassembled data */
+ &hf_oss_reassembled_data,
+ /* Tag */
+ "Message fragments"
+};
+
static const char *global_scm_udid = "00:00:00:00:00:00";
static gboolean global_scm_udid_autoset = TRUE;
static gboolean global_udp_frame2_first = FALSE;
+static gboolean global_siii_udp_frame2_first = FALSE;
static gboolean global_mbtcp_big_endian = FALSE;
static guint global_network_udp_port = UDP_PORT_OPENSAFETY;
static guint global_network_udp_port_sercosiii = UDP_PORT_SIII;
@@ -425,6 +569,8 @@ static gboolean bDissector_Called_Once_Before = FALSE;
* enable automatic detection of scm udid */
static char *local_scm_udid = NULL;
+static reassembly_table os_reassembly_table;
+
/* Resets the dissector in case the dissection is malformed and the dissector crashes */
static void
reset_dissector(void)
@@ -437,6 +583,8 @@ setup_dissector(void)
{
if ( local_scm_udid != NULL )
local_scm_udid = NULL;
+
+ reassembly_table_init(&os_reassembly_table, &addresses_reassembly_table_functions);
}
void proto_register_opensafety(void);
@@ -444,16 +592,17 @@ void proto_reg_handoff_opensafety(void);
void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, int severity, const char *format, ...)
{
- va_list ap;
+ va_list ap;
- va_start(ap, format);
- expert_add_info_format(pinfo, pi, group, severity, format, ap);
- va_end(ap);
+ va_start(ap, format);
+ expert_add_info_format(pinfo, pi, group, severity, format, ap);
+ va_end(ap);
}
#define opensafety_add_warning(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_PROTOCOL, PI_WARN, fmt)
#define opensafety_add_warning1(pinf, pi, fmt, arg1) opensafety_add_expert_note (pinf, pi, PI_PROTOCOL, PI_WARN, fmt, arg1)
#define opensafety_add_error(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_MALFORMED, PI_ERROR, fmt)
+#define opensafety_add_error1(pinf, pi, fmt, arg1, arg2, arg3) opensafety_add_expert_note (pinf, pi, PI_MALFORMED, PI_ERROR, fmt, arg1)
#define opensafety_add_note(pinf, pi, fmt) opensafety_add_expert_note (pinf, pi, PI_UNDECODED, PI_NOTE, fmt)
/* Conversation functions */
@@ -509,12 +658,13 @@ void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, i
}
static guint16
-findFrame1Position ( guint8 byteStream[], guint8 dataLength, gboolean checkIfSlimMistake )
+findFrame1Position ( tvbuff_t *message_tvb, guint16 byte_offset, guint8 dataLength, gboolean checkIfSlimMistake )
{
guint16 i_wFrame1Position = 0;
guint16 i_payloadLength, i_calculatedLength = 0;
guint16 i_offset = 0, calcCRC = 0, frameCRC = 0;
guint8 b_tempByte = 0;
+ guint8 *bytes = NULL;
/*
* First, a normal package get's assumed. Calculation of frame 1 position is
@@ -522,7 +672,7 @@ findFrame1Position ( guint8 byteStream[], guint8 dataLength, gboolean checkIfSli
* results in frame 1 start at (6 + n + o), which is length / 2 + 1
*/
i_wFrame1Position = dataLength / 2 + 1;
- i_payloadLength = byteStream [ i_wFrame1Position + 2 ];
+ i_payloadLength = tvb_get_guint8(message_tvb, byte_offset + i_wFrame1Position + 2 );
/* Calculating the assumed frame length, taking CRC8/CRC16 into account */
i_calculatedLength = i_payloadLength * 2 + 11 + 2 * (i_payloadLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 ? 1 : 0);
@@ -531,14 +681,16 @@ findFrame1Position ( guint8 byteStream[], guint8 dataLength, gboolean checkIfSli
* is somewhat time consuming, so it will only run if the normal check led to a mistake detected along the line */
if ( checkIfSlimMistake && i_calculatedLength == dataLength )
{
+ bytes = (guint8*)ep_tvb_memdup(message_tvb, byte_offset + i_wFrame1Position, dataLength + 4);
if ( dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 )
- calcCRC = crc16_0x5935(&byteStream[i_wFrame1Position], dataLength + 4, 0);
+ calcCRC = crc16_0x5935(bytes, dataLength + 4, 0);
else
- calcCRC = crc8_0x2F(&byteStream[i_wFrame1Position], dataLength + 4, 0);
+ calcCRC = crc8_0x2F(bytes, dataLength + 4, 0);
- frameCRC = byteStream[i_wFrame1Position + dataLength + OSS_FRAME_POS_DATA];
if (dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8)
- frameCRC += (byteStream[i_wFrame1Position + dataLength + OSS_FRAME_POS_DATA + 1] << 8);
+ frameCRC = tvb_get_letohs(message_tvb, byte_offset + i_wFrame1Position + dataLength + OSS_FRAME_POS_DATA);
+ else
+ frameCRC = tvb_get_guint8(message_tvb, byte_offset + i_wFrame1Position + dataLength + OSS_FRAME_POS_DATA);
/* if the calculated crc does not match the detected, the package is not a normal openSAFETY package */
if ( frameCRC != calcCRC )
@@ -556,7 +708,7 @@ findFrame1Position ( guint8 byteStream[], guint8 dataLength, gboolean checkIfSli
*/
i_offset = OSS_SLIM_FRAME2_WITH_CRC8 + ( dataLength < (OSS_SLIM_FRAME_WITH_CRC8_MAXSIZE + 1) ? 0 : 1 );
/* Last 2 digits belong to addr, therefore have to be cleared */
- b_tempByte = ( ( byteStream [ i_offset + 1 ] ) >> 2 ) << 2;
+ b_tempByte = ( tvb_get_guint8 ( message_tvb, byte_offset + i_offset + 1 ) ) & 0xFC;
/* If the id byte xor 0xE8 is 0, we have a slim package */
if ( ( ( b_tempByte ^ OPENSAFETY_MSG_SSDO_SLIM_SERVICE_REQUEST ) == 0 ) ||
@@ -570,108 +722,107 @@ findFrame1Position ( guint8 byteStream[], guint8 dataLength, gboolean checkIfSli
return i_wFrame1Position;
}
-/*
- * This function applies the given UDID to the bytestream, considering the start of frame 2
- */
-static guint8 *unxorFrame(guint dataLength, guint8 byteStream[], guint16 frameStart1, guint16 frameStart2, guint8 scmUDID[])
-{
- guint8 * pb_sendMemBlock;
- guint k;
- guint8 frame1Size;
-
- frame1Size = ( frameStart2 > frameStart1 ? frameStart2 : dataLength - frameStart1 );
- frame1Size = MIN(frame1Size, dataLength);
-
- pb_sendMemBlock = (guint8*) ep_alloc0( sizeof(guint8) * dataLength);
-
- memcpy ( &pb_sendMemBlock[frameStart1], &byteStream[frameStart1], frame1Size );
-
- for ( k = 0; k < (guint)(dataLength - frame1Size); k++)
- pb_sendMemBlock [ k + frameStart2 ] = byteStream [ k + frameStart2 ] ^ scmUDID[ ( k % 6 ) ];
-
- return pb_sendMemBlock;
-}
-
-static guint8 findSafetyFrame ( guint8 *pBuffer, guint32 length, guint u_Offset, gboolean b_frame2first, guint *u_frameOffset, guint *u_frameLength )
+static guint8 findSafetyFrame ( tvbuff_t * message_tvb, guint u_Offset, gboolean b_frame2first, guint *u_frameOffset, guint *u_frameLength )
{
- guint n;
+ guint ctr, rem_length;
guint16 crc, calcCrc;
- guint8 b_ID, b_Length, crcOffset, leftShifted;
+ guint8 b_Length, crcOffset;
+ guint8 *bytes;
+ guint b_ID;
gboolean found;
found = 0;
- for ( n = u_Offset; n < ( u_Offset + length ); n++)
+ ctr = u_Offset;
+ rem_length = tvb_reported_length_remaining (message_tvb, ctr);
+
+ while ( rem_length >= OSS_MINIMUM_LENGTH)
{
/* The ID byte must ALWAYS be the second byte, therefore 0 is invalid */
- if ( n == 0 )
- continue;
-
- *u_frameLength = 0;
- *u_frameOffset = 0;
-
- crcOffset = 0;
- b_ID = pBuffer [ n ];
- b_Length = pBuffer [ n + 1 ];
-
- /* 0xFF is often used, but always false, otherwise start detection, if the highest
- * bit is set */
- if ( ( b_ID != 0xFF ) && ( b_ID & 0x80 ) )
+ if ( ctr != 0 )
{
- /* If the determined size could be bigger then the data to be dissected,
- * we have an error, return */
- if ( ( b_Length + n ) > ( u_Offset + length ) )
- continue;
-
- leftShifted = b_ID >> 4;
- /* An openSAFETY command has to have a high-byte range between 0x0A and 0x0E
- * b_ID 0x80 took care of everything underneath, we check for 0x09 and 0x0F,
- * as they remain the only values left, which are not valid */
- if ( ( leftShifted == 0x09 ) || ( leftShifted == 0x0F ) )
- continue;
+ *u_frameLength = 0;
+ *u_frameOffset = 0;
- /* Find CRC position and calculate checksum */
- calcCrc = 0;
- crc = pBuffer [ n + 3 + b_Length ];
- if ( b_Length > 8 ) {
- crc += ( ( pBuffer [ n + 4 + b_Length ] ) << 8 );
- crcOffset = 1;
- if ( crc != 0x00 )
- calcCrc = crc16_0x5935( &pBuffer [ n - 1 ], b_Length + 4, 0 );
- } else {
- if ( crc != 0x00 )
- calcCrc = crc8_0x2F ( &pBuffer [ n - 1 ], b_Length + 4, 0 );
- }
+ crcOffset = 0;
+ b_ID = tvb_get_guint8(message_tvb, ctr );
- if ( ( crc != 0x00 ) && ( crc ^ calcCrc ) == 0 )
+ if ( b_ID != 0x0 )
{
- /* We have found a Slim frame. Those are not correctly identified yet */
- if ( ( b_ID >> 3 ) == ( OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE >> 3 ) )
- {
- *u_frameOffset = ( n - 1 );
- *u_frameLength = b_Length + 2 * crcOffset + 11;
- found = 1;
- break;
- }
- else
- {
- *u_frameLength = 2 * b_Length + 2 * crcOffset + 11;
- *u_frameOffset = ( n - 1 );
- /* EPL SoC messages can be falsely detected as openSAFETY frames,
- * so we check if both checksums have no lower byte of 0x00. This
- * check remains, although SoC and SoA messages get sorted out in
- * the dissector */
- if ( pBuffer [ *u_frameOffset + *u_frameLength - 2 ] == 0x00 &&
- pBuffer [ *u_frameOffset + *u_frameLength - 1 ] == 0x00 )
- continue;
+ b_Length = tvb_get_guint8(message_tvb, ctr + 1 );
- found = 1;
- break;
+ /* 0xFF is often used, but always false, otherwise start detection, if the highest
+ * bit is set */
+ if ( ( b_ID != 0xFF ) && ( b_ID & 0x80 ) )
+ {
+ /* The calculated length must fit, but for the CRC16 check, also the calculated length
+ * plus the CRC16 end position must fit in the remaining length */
+ if ( ( b_Length <= (guint) 8 && ( b_Length <= rem_length ) ) ||
+ ( b_Length > (guint) 8 && ( ( b_Length + (guint) 5 ) <= rem_length ) ) )
+ {
+ /* Ensure, that the correct length for CRC calculation
+ * still exists in byte stream, so that we can calculate the crc */
+ if ( tvb_bytes_exist(message_tvb, ctr - 1, b_Length + 5) )
+ {
+ /* An openSAFETY command has to have a high-byte range between 0x0A and 0x0E
+ * b_ID 0x80 took care of everything underneath, we check for 0x09 and 0x0F,
+ * as they remain the only values left, which are not valid */
+ if ( ( ( b_ID >> 4 ) != 0x09 ) && ( ( b_ID >> 4 ) != 0x0F ) )
+ {
+ /* Find CRC position and calculate checksum */
+ calcCrc = 0;
+ crc = tvb_get_guint8(message_tvb, ctr + 3 + b_Length );
+
+ bytes = (guint8 *)ep_tvb_memdup(message_tvb, ctr - 1, b_Length + 5 );
+ if ( b_Length > 8 ) {
+ crc = tvb_get_letohs ( message_tvb, ctr + 3 + b_Length );
+ crcOffset = 1;
+
+ if ( crc != 0x00 )
+ calcCrc = crc16_0x5935( bytes, b_Length + 4, 0 );
+ } else {
+ if ( crc != 0x00 )
+ calcCrc = crc8_0x2F ( bytes, b_Length + 4, 0 );
+ }
+
+ if ( ( crc != 0x00 ) && ( crc ^ calcCrc ) == 0 )
+ {
+ /* We have found a Slim frame. Those are not correctly identified yet */
+ if ( ( b_ID >> 3 ) == ( OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE >> 3 ) )
+ {
+ *u_frameOffset = ( ctr - 1 );
+ *u_frameLength = b_Length + 2 * crcOffset + 11;
+ found = 1;
+ break;
+ }
+ else
+ {
+ *u_frameLength = 2 * b_Length + 2 * crcOffset + 11;
+ *u_frameOffset = ( ctr - 1 );
+ /* EPL SoC messages can be falsely detected as openSAFETY frames,
+ * so we check if both checksums have no lower byte of 0x00. This
+ * check remains, although SoC and SoA messages get sorted out in
+ * the dissector */
+ if ( tvb_get_guint8(message_tvb, *u_frameOffset + *u_frameLength - 2 ) != 0x00 ||
+ tvb_get_guint8(message_tvb, *u_frameOffset + *u_frameLength - 1 ) != 0x00 )
+ {
+ found = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
}
}
}
+
+ ctr++;
+ rem_length = tvb_reported_length_remaining(message_tvb, ctr);
+
}
- /** Seem redundant if b_frame2First is false. But in this case, the function is needed for the
+ /* Seem redundant if b_frame2First is false. But in this case, the function is needed for the
* simple detection of a possible openSAFETY frame. */
if ( b_frame2first && found )
*u_frameOffset = u_Offset;
@@ -681,7 +832,7 @@ static guint8 findSafetyFrame ( guint8 *pBuffer, guint32 length, guint u_Offset,
static void
dissect_opensafety_spdo_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *opensafety_tree,
- guint8 *bytes, guint16 frameStart1, guint16 frameStart2 , gboolean validSCMUDID)
+ guint16 frameStart1, guint16 frameStart2 , gboolean validSCMUDID, guint8 scm_udid[6])
{
proto_item *item;
proto_tree *spdo_tree;
@@ -691,20 +842,21 @@ dissect_opensafety_spdo_message(tvbuff_t *message_tvb, packet_info *pinfo, proto
guint8 tr, b_ID, conn_Valid;
dataLength = tvb_get_guint8(message_tvb, OSS_FRAME_POS_LEN + frameStart1);
- b_ID = ( bytes[frameStart1 + 1] >> 3 ) << 3;
- conn_Valid = ( (bytes[frameStart1 + 1] & 0x04) == 0x04);
+ b_ID = tvb_get_guint8(message_tvb, frameStart1 + 1) & 0xF8;
+ conn_Valid = ( (tvb_get_guint8(message_tvb, frameStart1 + 1) & 0x04) == 0x04);
- ct = bytes[frameStart1 + 2];
+ ct = tvb_get_guint8(message_tvb, frameStart1 + 3);
if ( validSCMUDID )
- ct = (guint16)(bytes[frameStart2 + 2] << 8) + (bytes[frameStart1 + 2]);
+ ct = (guint16)((tvb_get_guint8(message_tvb, frameStart2 + 2) ^ scm_udid[2]) << 8) +
+ (tvb_get_guint8(message_tvb, frameStart1 + 3));
/* Network address is xor'ed into the start of the second frame, but only legible, if the scm given is valid */
- taddr = ( ( OSS_FRAME_ADDR(bytes, frameStart1) ) ^ ( OSS_FRAME_ADDR(bytes, frameStart2) ) );
+ taddr = ( ( OSS_FRAME_ADDR_T(message_tvb, frameStart1) ) ^ ( OSS_FRAME_ADDR_T2(message_tvb, frameStart2, scm_udid[0], scm_udid[1]) ) );
if ( ! validSCMUDID )
taddr = ( -1 * taddr );
/* An SPDO get's always send by the producer, to everybody else */
- PACKET_SENDER( pinfo, OSS_FRAME_ADDR(bytes, frameStart1), OSS_FRAME_POS_ADDR + frameStart1, frameStart2, taddr );
+ PACKET_SENDER( pinfo, OSS_FRAME_ADDR_T(message_tvb, frameStart1), OSS_FRAME_POS_ADDR + frameStart1, frameStart2, taddr );
item = proto_tree_add_uint_format_value(opensafety_tree, hf_oss_msg_category, message_tvb,
OSS_FRAME_POS_ID + frameStart1, 1, OPENSAFETY_SPDO_MESSAGE_TYPE,
@@ -724,13 +876,13 @@ dissect_opensafety_spdo_message(tvbuff_t *message_tvb, packet_info *pinfo, proto
b_ID, "%s", val_to_str_const(b_ID, message_type_values, "Unknown") );
proto_tree_add_uint(spdo_tree, hf_oss_spdo_producer, message_tvb,
- OSS_FRAME_POS_ADDR + frameStart1, 2, OSS_FRAME_ADDR(bytes, frameStart1));
+ OSS_FRAME_POS_ADDR + frameStart1, 2, OSS_FRAME_ADDR_T(message_tvb, frameStart1));
proto_tree_add_boolean(spdo_tree, hf_oss_spdo_connection_valid, message_tvb,
OSS_FRAME_POS_ID + frameStart1, 1, conn_Valid);
/* taddr is the 4th octet in the second frame */
- taddr = OSS_FRAME_ADDR(bytes, frameStart2 + 3);
- tr = ( bytes[frameStart2 + 4] << 2 ) >> 2;
+ taddr = OSS_FRAME_ADDR_T2(message_tvb, frameStart2 + 3, scm_udid[3], scm_udid[4]);
+ tr = ( tvb_get_guint8(message_tvb, frameStart2 + 4) ^ scm_udid[4] ) & 0xFC;
if ( b_ID == OPENSAFETY_MSG_SPDO_DATA_WITH_TIME_REQUEST )
{
@@ -758,62 +910,188 @@ dissect_opensafety_spdo_message(tvbuff_t *message_tvb, packet_info *pinfo, proto
}
if ( dataLength > 0 )
+ proto_tree_add_item(spdo_tree, hf_oss_spdo_payload, message_tvb, OSS_FRAME_POS_ID + 3, dataLength, ENC_NA);
+}
+
+static void dissect_ssdo_payload ( packet_info *pinfo, tvbuff_t *new_tvb, proto_tree *ssdo_payload )
+{
+ guint dataLength = 0, ctr = 0, n = 0;
+ guint8 ssdoSubIndex = 0;
+ guint16 ssdoIndex = 0, dispSSDOIndex = 0;
+ guint32 sodLength = 0, entry = 0;
+ proto_item *item;
+ proto_tree *sod_tree, *ext_tree;
+
+ dataLength = tvb_length(new_tvb);
+
+ ssdoIndex = tvb_get_letohs(new_tvb, 0);
+
+ sodLength = tvb_get_letohl(new_tvb, 4);
+
+ /* first check for extended parameter */
+ if ( dataLength == 16 || sodLength == ( dataLength - 16 ) || ssdoIndex == 0x0101 )
{
- proto_tree_add_bytes(spdo_tree, hf_oss_spdo_payload, message_tvb, OSS_FRAME_POS_ID + 3,
- dataLength, &bytes[frameStart1 + 4]);
+ /* extended parameter header & data */
+ item = proto_tree_add_string_format(ssdo_payload, hf_oss_ssdo_extpar,
+ new_tvb, 0, dataLength, "", "Extended Parameter Set: %s",
+ (dataLength == 16 ? "Header only" : "Header & Data") );
+ ext_tree = proto_item_add_subtree(item, ett_opensafety_ssdo_extpar);
+
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_parset, new_tvb, 0, 1, ENC_BIG_ENDIAN );
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_version, new_tvb, 1, 1, ENC_BIG_ENDIAN );
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_saddr, new_tvb, 2, 2, ENC_LITTLE_ENDIAN );
+
+ proto_tree_add_uint_format_value(ext_tree, hf_oss_ssdo_extpar_length,
+ new_tvb, 4, 4, sodLength, "0x%04X (%d octets)",
+ sodLength, sodLength );
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_crc, new_tvb, 8, 4, ENC_LITTLE_ENDIAN );
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_tstamp, new_tvb, 12, 4, ENC_LITTLE_ENDIAN );
+
+ if ( dataLength != 16 )
+ {
+ item = proto_tree_add_item(ext_tree, hf_oss_ssdo_extpar_data, new_tvb, 16, dataLength - 16, ENC_NA );
+
+ if ( ( dataLength - sodLength ) != 16 )
+ opensafety_add_error ( pinfo, item, "Reassembled message size differs from size in header!");
+ }
+ }
+ else
+ {
+ /* normal parameter set */
+ for ( ctr = 0; ctr < dataLength; ctr++ )
+ {
+ ssdoIndex = tvb_get_letohs(new_tvb, ctr);
+ ssdoSubIndex = tvb_get_guint8(new_tvb, ctr + 2);
+ dispSSDOIndex = ssdoIndex;
+
+ if ( ssdoIndex >= 0x1400 && ssdoIndex <= 0x17FE )
+ dispSSDOIndex = 0x1400;
+ else if ( ssdoIndex >= 0x1800 && ssdoIndex <= 0x1BFE )
+ dispSSDOIndex = 0x1800;
+ else if ( ssdoIndex >= 0x1C00 && ssdoIndex <= 0x1FFE )
+ dispSSDOIndex = 0x1C00;
+ else if ( ssdoIndex >= 0xC000 && ssdoIndex <= 0xC3FE )
+ dispSSDOIndex = 0xC000;
+
+ item = proto_tree_add_uint_format_value(ssdo_payload, hf_oss_ssdo_sod_index, new_tvb,
+ ctr, 2, ssdoIndex, "0x%04X (%s)", ssdoIndex,
+ val_to_str_const( ((guint32) (dispSSDOIndex << 16) ),
+ sod_idx_names, "Unknown") );
+
+ if ( ssdoIndex < 0x1000 || ssdoIndex > 0xE7FF )
+ opensafety_add_error ( pinfo, item, "Unknown payload format detected!" );
+
+ sod_tree = proto_item_add_subtree(item, ett_opensafety_ssdo_sodentry);
+
+ if ( ssdoSubIndex != 0 )
+ proto_tree_add_uint_format_value(sod_tree, hf_oss_ssdo_sod_subindex, new_tvb, ctr + 2, 1,
+ ssdoSubIndex, "0x%02X (%s)", ssdoSubIndex,
+ val_to_str_const(((guint32) (ssdoIndex << 16) + ssdoSubIndex),
+ sod_idx_names, "Unknown") );
+ else
+ proto_tree_add_uint_format_value(sod_tree, hf_oss_ssdo_sod_subindex, new_tvb, ctr + 2, 1,
+ ssdoSubIndex, "0x%02X",ssdoSubIndex );
+ ctr += 2;
+
+ /* reading real size */
+ sodLength = tvb_get_letohl ( new_tvb, ctr + 1 );
+ if ( sodLength > (dataLength - ctr) )
+ sodLength = 0;
+
+ if ( ( sodLength + 4 + ctr ) > dataLength )
+ break;
+
+ if ( ssdoIndex == OPENSAFETY_SOD_DVI && ssdoSubIndex == 0x06 )
+ {
+ entry = tvb_get_letohl ( new_tvb, ctr + 5 );
+ proto_tree_add_uint_format_value ( sod_tree, hf_oss_sod_par_timestamp, new_tvb, ctr + 5,
+ 4, entry, "0x%08X", entry );
+ for ( n = 4; n < sodLength; n+=4 )
+ {
+ entry = tvb_get_letohl ( new_tvb, ctr + 5 + n );
+ proto_tree_add_uint_format_value ( sod_tree, hf_oss_sod_par_checksum, new_tvb, (ctr + 5 + n ),
+ 4, entry, "[#%d] 0x%08X", ( n / 4 ), entry );
+ }
+ } else if ( ssdoIndex == OPENSAFETY_SOD_DVI && ssdoSubIndex == 0x07 ) {
+ entry = tvb_get_letohl ( new_tvb, ctr + 5 );
+ proto_tree_add_uint_format_value ( sod_tree, hf_oss_sod_par_timestamp, new_tvb, ctr + 5,
+ 4, entry, "0x%08X", entry );
+ } else if ( ( dispSSDOIndex == OPENSAFETY_SOD_RXMAP || dispSSDOIndex == OPENSAFETY_SOD_TXMAP ) && ssdoSubIndex != 0x0 ) {
+ proto_tree_add_uint(sod_tree, hf_oss_ssdo_sodentry_size, new_tvb, ctr + 1, 4, sodLength );
+ item = proto_tree_add_item(sod_tree, hf_oss_ssdo_sodmapping, new_tvb, ctr + 5, sodLength, ENC_NA );
+ ext_tree = proto_item_add_subtree(item, ett_opensafety_sod_mapping);
+
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_sodmapping_bits, new_tvb, ctr + 5, 1, ENC_NA);
+
+ entry = tvb_get_letohl ( new_tvb, ctr + 7 );
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_sod_index, new_tvb, ctr + 7, 2, entry);
+ proto_tree_add_item(ext_tree, hf_oss_ssdo_sod_subindex, new_tvb, ctr + 6, 1, ENC_NA);
+
+ } else {
+ proto_tree_add_uint(sod_tree, hf_oss_ssdo_sodentry_size, new_tvb, ctr + 1, 4, sodLength );
+ if ( sodLength > 0 )
+ proto_tree_add_item(sod_tree, hf_oss_ssdo_sodentry_data, new_tvb, ctr + 5, sodLength, ENC_LITTLE_ENDIAN );
+ }
+ ctr += sodLength + 4;
+ }
}
-}
+}
+
static void
dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, proto_tree *opensafety_tree ,
- guint8 *bytes, guint16 frameStart1, guint16 frameStart2 , gboolean validSCMUDID)
+ guint16 frameStart1, guint16 frameStart2 , gboolean validSCMUDID, guint8 scm_udid[6])
{
proto_item *item;
- proto_tree *ssdo_tree, *ssdo_sacmd_tree;
- guint16 taddr = 0, sdn = 0;
- guint32 abortcode, ssdoIndex, ssdoSubIndex;
- guint8 db0Offset, db0, sacmd, payloadOffset, payloadSize, n;
+ proto_tree *ssdo_tree, *ssdo_payload, *ssdo_sacmd_tree;
+ guint16 taddr = 0, sdn = 0, server = 0, client = 0, n = 0, ct = 0;
+ guint32 abortcode, ssdoIndex = 0, ssdoSubIndex = 0, payloadSize, fragmentId = 0, entry = 0;
+ guint8 db0Offset, db0, sacmd, payloadOffset;
guint dataLength;
gint calcDataLength;
- gboolean isResponse, decodePayload;
- guint8 *payload;
+ gboolean isResponse, decodePayload, isEndSegment, isSegmented, saveFragmented;
+ tvbuff_t* new_tvb = NULL;
+ fragment_data *frag_msg = NULL;
dataLength = tvb_get_guint8(message_tvb, OSS_FRAME_POS_LEN + frameStart1);
decodePayload = FALSE;
db0Offset = frameStart1 + OSS_FRAME_POS_DATA;
- db0 = bytes[db0Offset];
+ db0 = tvb_get_guint8(message_tvb, db0Offset);
sacmd = db0;
+ ssdoIndex = 0;
+ ssdoSubIndex = 0;
if ( ( sacmd & OPENSAFETY_SSDO_SACMD_TGL ) == OPENSAFETY_SSDO_SACMD_TGL )
sacmd = sacmd & ( ~OPENSAFETY_SSDO_SACMD_TGL );
- isResponse = ( ( OSS_FRAME_ID(bytes, frameStart1) & 0x04 ) == 0x04 );
+ isResponse = ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) & 0x04 ) == 0x04 );
if ( validSCMUDID )
{
/* taddr is the 4th octet in the second frame */
- taddr = OSS_FRAME_ADDR(bytes, frameStart2 + 3);
- sdn = ( OSS_FRAME_ADDR(bytes, frameStart1) ^ OSS_FRAME_ADDR(bytes, frameStart2) );
+ taddr = OSS_FRAME_ADDR_T2(message_tvb, frameStart2 + 3, scm_udid[3], scm_udid[4]);
+ sdn = ( OSS_FRAME_ADDR_T(message_tvb, frameStart1) ^
+ ( OSS_FRAME_ADDR_T2(message_tvb, frameStart2, scm_udid[0], scm_udid[1]) ) );
- PACKET_SENDER_RECEIVER ( pinfo, OSS_FRAME_ADDR(bytes, frameStart1), frameStart1, taddr,
- frameStart2 + 3, frameStart2, sdn );
+ PACKET_SENDER_RECEIVER ( pinfo, taddr, frameStart2 + 3, OSS_FRAME_ADDR_T(message_tvb, frameStart1),
+ frameStart1, frameStart2, sdn );
}
else if ( ! isResponse )
{
- PACKET_RECEIVER(pinfo, OSS_FRAME_ADDR(bytes, frameStart1), frameStart1, frameStart2,
- -1 * ( ( OSS_FRAME_ADDR(bytes, frameStart1) ) ^ ( OSS_FRAME_ADDR(bytes, frameStart2) ) ) );
+ PACKET_SENDER(pinfo, OSS_FRAME_ADDR_T(message_tvb, frameStart1), frameStart1, frameStart2,
+ -1 * ( ( OSS_FRAME_ADDR_T(message_tvb, frameStart1) ) ^ ( OSS_FRAME_ADDR_T2(message_tvb, frameStart2, scm_udid[0], scm_udid[1]) ) ) );
}
else if ( isResponse )
{
- PACKET_SENDER(pinfo, OSS_FRAME_ADDR(bytes, frameStart1), frameStart1, frameStart2,
- -1 * ( ( OSS_FRAME_ADDR(bytes, frameStart1) ) ^ ( OSS_FRAME_ADDR(bytes, frameStart2) ) ) );
+ PACKET_RECEIVER(pinfo, OSS_FRAME_ADDR_T(message_tvb, frameStart1), frameStart1, frameStart2,
+ -1 * ( ( OSS_FRAME_ADDR_T(message_tvb, frameStart1) ) ^ ( OSS_FRAME_ADDR_T2(message_tvb, frameStart2, scm_udid[0], scm_udid[1]) ) ) );
}
- if ( ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_REQUEST ) ||
- ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_RESPONSE ) )
+ if ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_REQUEST ) ||
+ ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_RESPONSE ) )
item = proto_tree_add_uint_format_value(opensafety_tree, hf_oss_msg_category, message_tvb,
OSS_FRAME_POS_ID + frameStart1, 1,
OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE,
@@ -826,39 +1104,45 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
ssdo_tree = proto_item_add_subtree(item, ett_opensafety_ssdo);
- if ( ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SSDO_SERVICE_RESPONSE ) ||
- ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_RESPONSE ) )
+ if ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SSDO_SERVICE_RESPONSE ) ||
+ ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SSDO_SLIM_SERVICE_RESPONSE ) )
proto_tree_add_boolean(ssdo_tree, hf_oss_msg_direction, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1, OPENSAFETY_RESPONSE);
else
proto_tree_add_boolean(ssdo_tree, hf_oss_msg_direction, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1, OPENSAFETY_REQUEST);
proto_tree_add_uint_format_value(ssdo_tree, hf_oss_msg, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1,
- OSS_FRAME_ID(bytes, frameStart1),
- "%s", val_to_str_const(OSS_FRAME_ID(bytes, frameStart1), message_type_values, "Unknown") );
+ OSS_FRAME_ID_T(message_tvb, frameStart1),
+ "%s", val_to_str_const(OSS_FRAME_ID_T(message_tvb, frameStart1), message_type_values, "Unknown") );
if ( isResponse )
{
if ( validSCMUDID )
{
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart1, 2, OSS_FRAME_ADDR(bytes, frameStart1));
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart1, 2, OSS_FRAME_ADDR_T(message_tvb, frameStart1));
+ client = OSS_FRAME_ADDR_T(message_tvb, frameStart1);
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart2 + 3, 2, taddr);
+ server = taddr;
}
else
{
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart1, 2, OSS_FRAME_ADDR(bytes, frameStart1));
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart1, 2, OSS_FRAME_ADDR_T(message_tvb, frameStart1));
+ client = OSS_FRAME_ADDR_T(message_tvb, frameStart1);
}
}
else if ( ! isResponse )
{
if ( validSCMUDID )
{
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart1, 2, OSS_FRAME_ADDR(bytes, frameStart1));
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart1, 2, OSS_FRAME_ADDR_T(message_tvb, frameStart1));
+ server = OSS_FRAME_ADDR_T(message_tvb, frameStart1);
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart2 + 3, 2, taddr);
+ client = taddr;
}
else
{
- proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_client, message_tvb, frameStart1, 2, OSS_FRAME_ADDR(bytes, frameStart1));
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_server, message_tvb, frameStart1, 2, OSS_FRAME_ADDR_T(message_tvb, frameStart1));
+ server = OSS_FRAME_ADDR_T(message_tvb, frameStart1);
}
}
@@ -875,6 +1159,13 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
proto_tree_add_boolean(ssdo_sacmd_tree, hf_oss_ssdo_sacmd_access_type, message_tvb, db0Offset, 1, db0);
payloadOffset = db0Offset + 1;
+
+ ct = tvb_get_guint8(message_tvb, frameStart1 + 3);
+ if ( validSCMUDID )
+ ct = (guint16)((tvb_get_guint8(message_tvb, frameStart2 + 2) ^ scm_udid[2]) << 8) + (tvb_get_guint8(message_tvb, frameStart1 + 3));
+
+ proto_tree_add_uint(ssdo_tree, hf_oss_ssdo_sano, message_tvb, frameStart1 + 3, 1, ct );
+
/* When the following clause is met, DB1,2 contain the SOD index, and DB3 the SOD subindex */
if ( ( ( sacmd & OPENSAFETY_SSDO_SACMD_INI ) == OPENSAFETY_SSDO_SACMD_INI ) ||
( sacmd == OPENSAFETY_MSG_SSDO_UPLOAD_SEGMENT_MIDDLE ) ||
@@ -882,8 +1173,8 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
( sacmd == OPENSAFETY_MSG_SSDO_ABORT )
)
{
- ssdoIndex = ((guint16)(bytes[db0Offset + 2] << 8) + bytes[db0Offset + 1]);
- ssdoSubIndex = bytes[db0Offset + 3];
+ ssdoIndex = tvb_get_letohs(message_tvb, db0Offset + 1);
+ ssdoSubIndex = tvb_get_guint8(message_tvb, db0Offset + 3);
proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_sod_index, message_tvb, db0Offset + 1, 2,
ssdoIndex, "0x%04X (%s)", ssdoIndex,
@@ -905,9 +1196,7 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
if ( sacmd == OPENSAFETY_MSG_SSDO_ABORT )
{
- abortcode = 0;
- for ( n = 0; n < 4; n++ )
- abortcode += ( bytes[frameStart1 + OSS_FRAME_POS_DATA + 4 + n] ) << (8 * n);
+ abortcode = tvb_get_ntohl(message_tvb, frameStart1 + OSS_FRAME_POS_DATA + 4);
proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_abort_code, message_tvb, payloadOffset, 4, abortcode,
"0x%04X %04X - %s", (guint16)(abortcode >> 16), (guint16)(abortcode),
@@ -933,86 +1222,153 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
if ( decodePayload )
{
+ saveFragmented = pinfo->fragmented;
+ if ( server != 0 && client != 0 )
+ fragmentId = (guint32)((((guint32)client) << 16 ) + server );
- /* If payload data has to be calculated, either a total size is given, or not */
+ isSegmented = ( ( db0 & OPENSAFETY_SSDO_SACMD_SEG ) == OPENSAFETY_SSDO_SACMD_SEG );
+
+ /* If payload data has to be calculated, either a total size is given, or not */
if ( ( sacmd == OPENSAFETY_MSG_SSDO_DOWNLOAD_INITIATE_SEGMENTED ) ||
( sacmd == OPENSAFETY_MSG_SSDO_UPLOAD_INITIATE_SEGMENTED )
)
{
+
payloadOffset += 4;
- /* using payloadSize as helper var for for-loop */
- payloadSize = dataLength - (payloadOffset - db0Offset);
- payload = (guint8*)ep_alloc(sizeof(guint8)*payloadSize);
- for ( n = 0; n < payloadSize; n++)
- payload[payloadSize - n - 1] = bytes[frameStart1 + OSS_FRAME_POS_DATA + (payloadOffset - db0Offset) + n];
/* reading real size */
- payloadSize = 0;
- for ( n = 0; n < 4; n++ )
- {
- payloadSize += ( bytes[frameStart1 + OSS_FRAME_POS_DATA + 4 + n] ) << (8 * n);
- }
+ payloadSize = tvb_get_letohl(message_tvb, payloadOffset - 4);
calcDataLength = dataLength - (payloadOffset - db0Offset);
item = proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_payload_size, message_tvb, payloadOffset - 4, 4,
payloadSize, "%d octets total (%d octets in this frame)", payloadSize, calcDataLength);
+
+ if ( fragmentId != 0 && isSegmented )
+ {
+ pinfo->fragmented = TRUE;
+ frag_msg = fragment_add_seq_check(&os_reassembly_table, message_tvb, payloadOffset, pinfo,
+ fragmentId, NULL, 0, calcDataLength, TRUE );
+ fragment_add_seq_offset ( &os_reassembly_table, pinfo, fragmentId, NULL, ct );
+
+ if ( frag_msg != NULL )
+ {
+ item = proto_tree_add_bytes_format_value(ssdo_tree, hf_oss_ssdo_payload, message_tvb, 0, 0, NULL, "Reassembled" );
+ PROTO_ITEM_SET_GENERATED(item);
+
+ ssdo_payload = proto_item_add_subtree(item, ett_opensafety_ssdo_payload);
+ process_reassembled_data(message_tvb, 0, pinfo, "Reassembled Message", frag_msg, &oss_frag_items, NULL, ssdo_payload );
+ }
+ }
+
if ( (gint) calcDataLength > (gint) 0 )
{
- proto_tree_add_bytes(ssdo_tree, hf_oss_ssdo_payload, message_tvb, payloadOffset, calcDataLength, payload );
+ proto_tree_add_item(ssdo_tree, hf_oss_ssdo_payload, message_tvb, payloadOffset, calcDataLength, ENC_NA );
} else {
opensafety_add_warning1(pinfo, item, "Calculation for payload length yielded non-positive result [%d]", (guint) calcDataLength );
}
}
else
{
+ isEndSegment = FALSE;
+ if ( ( sacmd == OPENSAFETY_MSG_SSDO_DOWNLOAD_SEGMENT_END ) || ( sacmd == OPENSAFETY_MSG_SSDO_UPLOAD_SEGMENT_END ) )
+ isEndSegment = TRUE;
+
payloadSize = dataLength - (payloadOffset - db0Offset);
- payload = (guint8*)ep_alloc(sizeof(guint8)*payloadSize);
- for ( n = 0; n < payloadSize; n++)
- payload[payloadSize - n - 1] = bytes[frameStart1 + OSS_FRAME_POS_DATA + (payloadOffset - db0Offset) + n];
- item = proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_payload_size, message_tvb, 0, 0, payloadSize,
- "%d octets", payloadSize);
- PROTO_ITEM_SET_GENERATED(item);
- proto_tree_add_bytes(ssdo_tree, hf_oss_ssdo_payload, message_tvb, payloadOffset, payloadSize, payload );
+ if ( fragmentId != 0 && isSegmented )
+ {
+ pinfo->fragmented = TRUE;
+
+ frag_msg = fragment_add_seq_check(&os_reassembly_table, message_tvb, payloadOffset, pinfo,
+ fragmentId, NULL,ct,
+ payloadSize, isEndSegment ? FALSE : TRUE );
+ }
+
+ if ( frag_msg )
+ {
+ item = proto_tree_add_bytes_format_value(ssdo_tree, hf_oss_ssdo_payload, message_tvb,
+ 0, 0, NULL, "Reassembled" );
+ PROTO_ITEM_SET_GENERATED(item);
+ ssdo_payload = proto_item_add_subtree(item, ett_opensafety_ssdo_payload);
+
+ new_tvb = process_reassembled_data(message_tvb, 0, pinfo, "Reassembled Message", frag_msg,
+ &oss_frag_items, NULL, ssdo_payload );
+ if ( isEndSegment && new_tvb )
+ {
+ item = proto_tree_add_uint_format_value(ssdo_payload, hf_oss_ssdo_payload_size, message_tvb, 0, 0,
+ payloadSize, "%d octets (over all fragments)", frag_msg->len);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)" );
+ dissect_ssdo_payload ( pinfo, new_tvb, ssdo_payload );
+ }
+ }
+ else
+ {
+ item = proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_payload_size, message_tvb, 0, 0, payloadSize,
+ "%d octets", payloadSize);
+ PROTO_ITEM_SET_GENERATED(item);
+
+ if ( ssdoIndex == OPENSAFETY_SOD_DVI && ssdoSubIndex == 0x06 )
+ {
+ entry = tvb_get_letohl ( message_tvb, payloadOffset );
+ proto_tree_add_uint_format_value ( ssdo_tree, hf_oss_sod_par_timestamp, message_tvb, payloadOffset,
+ 4, entry, "0x%08X", entry );
+ for ( n = 4; n < payloadSize; n+=4 )
+ {
+ entry = tvb_get_letohl ( message_tvb, payloadOffset + n );
+ proto_tree_add_uint_format_value ( ssdo_tree, hf_oss_sod_par_checksum, message_tvb, (payloadOffset + n ),
+ 4, entry, "[#%d] 0x%08X", ( n / 4 ), entry );
+ }
+ } else if ( ssdoIndex == OPENSAFETY_SOD_DVI && ssdoSubIndex == 0x07 ) {
+ entry = tvb_get_letohl ( message_tvb, payloadOffset );
+ proto_tree_add_uint_format_value ( ssdo_tree, hf_oss_sod_par_timestamp, message_tvb, payloadOffset,
+ 4, entry, "0x%08X", entry );
+ } else
+ proto_tree_add_item(ssdo_tree, hf_oss_ssdo_payload, message_tvb, payloadOffset, payloadSize, ENC_NA );
+ }
}
+
+ pinfo->fragmented = saveFragmented;
}
}
}
static void
dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , proto_tree *opensafety_tree,
- guint8 *bytes, guint16 frameStart1, guint16 frameStart2 )
+ guint16 frameStart1, guint16 frameStart2 )
{
proto_item *item;
proto_tree *snmt_tree;
+ guint32 entry = 0;
guint16 addr, taddr, sdn;
guint8 db0, byte;
guint dataLength;
char *tempString;
- dataLength = OSS_FRAME_LENGTH(bytes, frameStart1);
+ dataLength = OSS_FRAME_LENGTH_T(message_tvb, frameStart1);
/* addr is the first field, as well as the recipient of the message */
- addr = OSS_FRAME_ADDR(bytes, frameStart1);
+ addr = OSS_FRAME_ADDR_T(message_tvb, frameStart1);
/* taddr is the 4th octet in the second frame */
- taddr = OSS_FRAME_ADDR(bytes, frameStart2 + 3);
+ taddr = OSS_FRAME_ADDR_T(message_tvb, frameStart2 + 3);
/* domain is xor'ed on the first field in the second frame. As this is also addr, it is easy to obtain */
- sdn = OSS_FRAME_ADDR(bytes, frameStart2) ^ addr;
+ sdn = OSS_FRAME_ADDR_T(message_tvb, frameStart2) ^ addr;
db0 = -1;
if (dataLength > 0)
- db0 = bytes[OSS_FRAME_POS_DATA];
+ db0 = tvb_get_guint8(message_tvb, frameStart1 + OSS_FRAME_POS_DATA);
- if ( ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE) == 0 ) &&
+ if ( ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE) == 0 ) &&
( (db0 ^ OPENSAFETY_MSG_SNMT_EXT_SCM_SET_TO_STOP) == 0 || (db0 ^ OPENSAFETY_MSG_SNMT_EXT_SCM_SET_TO_OP) == 0 ) )
{
PACKET_RECEIVER( pinfo, addr, OSS_FRAME_POS_ADDR + frameStart1, frameStart2, sdn );
}
else
{
- PACKET_SENDER_RECEIVER ( pinfo, taddr, OSS_FRAME_POS_ADDR + frameStart1, frameStart2 + 3, addr,
- frameStart2, sdn );
+ PACKET_SENDER_RECEIVER ( pinfo, taddr, OSS_FRAME_POS_ADDR + frameStart1, addr, frameStart2 + 3,
+ frameStart2, sdn );
}
item = proto_tree_add_uint_format_value(opensafety_tree, hf_oss_msg_category, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1,
@@ -1022,23 +1378,23 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
snmt_tree = proto_item_add_subtree(item, ett_opensafety_snmt);
- if ( ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SNMT_RESPONSE_UDID ) ||
- ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SNMT_SADR_ASSIGNED ) ||
- ( OSS_FRAME_ID(bytes, frameStart1) == OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE ) )
+ if ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SNMT_RESPONSE_UDID ) ||
+ ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SNMT_SADR_ASSIGNED ) ||
+ ( OSS_FRAME_ID_T(message_tvb, frameStart1) == OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE ) )
proto_tree_add_boolean(snmt_tree, hf_oss_msg_direction, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1, OPENSAFETY_RESPONSE);
else
proto_tree_add_boolean(snmt_tree, hf_oss_msg_direction, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1, OPENSAFETY_REQUEST);
proto_tree_add_uint_format_value(snmt_tree, hf_oss_msg, message_tvb, OSS_FRAME_POS_ID + frameStart1, 1,
- OSS_FRAME_ID(bytes, frameStart1),
- "%s", val_to_str_const(OSS_FRAME_ID(bytes, frameStart1), message_type_values, "Unknown") );
+ OSS_FRAME_ID_T(message_tvb, frameStart1),
+ "%s", val_to_str_const(OSS_FRAME_ID_T(message_tvb, frameStart1), message_type_values, "Unknown") );
- if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_SN_RESET_GUARDING_SCM) == 0 )
+ if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_SN_RESET_GUARDING_SCM) == 0 )
{
proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, frameStart2 + 3, 2, taddr);
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_RESPONSE) == 0 )
{
proto_tree_add_uint(snmt_tree, hf_oss_snmt_service_id, message_tvb, OSS_FRAME_POS_DATA + frameStart1, 1, db0);
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(db0, message_service_type, "Unknown"));
@@ -1047,15 +1403,13 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, frameStart2 + 3, 2, taddr);
if ( (db0 ^ OPENSAFETY_MSG_SNMT_EXT_SN_FAIL) == 0 )
{
- byte = bytes[OSS_FRAME_POS_DATA + frameStart1 + 1];
- proto_tree_add_uint_format(snmt_tree, hf_oss_snmt_error_group, message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 1, 1,
- byte, "%s",
- ( byte == 0 ? "Device" : val_to_str(byte, sn_fail_error_group, "Reserved [%d]" ) ) );
-
- byte = bytes[OSS_FRAME_POS_DATA + frameStart1 + 2];
- proto_tree_add_uint_format(snmt_tree, hf_oss_snmt_error_code, message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 2, 1,
- byte, "%s [%d]",
- ( byte == 0 ? "Default" : "Vendor Specific" ), byte );
+ byte = tvb_get_guint8(message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 1);
+ proto_tree_add_uint_format(snmt_tree, hf_oss_snmt_error_group, message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 1, 1,
+ byte, "%s", ( byte == 0 ? "Device" : val_to_str(byte, sn_fail_error_group, "Reserved [%d]" ) ) );
+
+ byte = tvb_get_guint8(message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 2);
+ proto_tree_add_uint_format(snmt_tree, hf_oss_snmt_error_code, message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 2, 1,
+ byte, "%s [%d]", ( byte == 0 ? "Default" : "Vendor Specific" ), byte );
}
else if ( (db0 ^ OPENSAFETY_MSG_SNMT_EXT_SN_ASSIGNED_UDID_SCM) == 0 )
{
@@ -1067,16 +1421,16 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
g_snprintf ( tempString, 18, "%s", tvb_bytes_to_str_punct(message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 1, 6, ':' ) );
if ( memcmp ( global_scm_udid, tempString, 17 ) != 0 )
{
- local_scm_udid = (char *)se_alloc0(18 * sizeof(char));
- g_snprintf(local_scm_udid, 18, "%s", tempString );
- expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_NOTE, "Auto detected payload as SCM UDID [%s].", tempString);
+ local_scm_udid = (char *)se_alloc0(18 * sizeof(char));
+ g_snprintf(local_scm_udid, 18, "%s", tempString );
+ expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_NOTE, "Auto detected payload as SCM UDID [%s].", tempString);
}
}
}
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_REQUEST) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_SERVICE_REQUEST) == 0 )
{
proto_tree_add_uint(snmt_tree, hf_oss_snmt_service_id, message_tvb, OSS_FRAME_POS_DATA + frameStart1, 1, db0);
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(db0, message_service_type, "Unknown"));
@@ -1107,16 +1461,18 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
}
else
{
- proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
- proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
+
if ( (db0 ^ OPENSAFETY_MSG_SNMT_EXT_SN_SET_TO_OP) == 0 )
{
- proto_tree_add_bytes(snmt_tree, hf_oss_snmt_timestamp, message_tvb, OSS_FRAME_POS_DATA + frameStart1 + 1, 4,
- (bytes + frameStart1 + OSS_FRAME_POS_DATA + 1));
+ entry = tvb_get_letohl ( message_tvb, frameStart1 + OSS_FRAME_POS_DATA + 1 );
+ proto_tree_add_uint_format_value ( snmt_tree, hf_oss_sod_par_timestamp, message_tvb,
+ OSS_FRAME_POS_DATA + frameStart1 + 1, 4, entry, "0x%08X", entry );
}
}
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_SADR_ASSIGNED) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_SADR_ASSIGNED) == 0 )
{
proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, frameStart2 + 3, 2, taddr);
@@ -1124,16 +1480,16 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
if (dataLength > 0)
proto_tree_add_item(snmt_tree, hf_oss_snmt_udid, message_tvb, OSS_FRAME_POS_DATA + frameStart1, 6, ENC_NA);
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_ASSIGN_SADR) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_ASSIGN_SADR) == 0 )
{
- proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
if (dataLength > 0)
proto_tree_add_item(snmt_tree, hf_oss_snmt_udid, message_tvb, OSS_FRAME_POS_DATA + frameStart1, 6, ENC_NA);
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_RESPONSE_UDID) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_RESPONSE_UDID) == 0 )
{
proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, frameStart2 + 3, 2, taddr);
@@ -1142,48 +1498,68 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
proto_tree_add_item(snmt_tree, hf_oss_snmt_udid, message_tvb, OSS_FRAME_POS_DATA + frameStart1, 6, ENC_NA);
}
- else if ( (OSS_FRAME_ID(bytes, frameStart1) ^ OPENSAFETY_MSG_SNMT_REQUEST_UDID) == 0 )
+ else if ( (OSS_FRAME_ID_T(message_tvb, frameStart1) ^ OPENSAFETY_MSG_SNMT_REQUEST_UDID) == 0 )
{
- proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
proto_tree_add_uint(snmt_tree, hf_oss_snmt_master, message_tvb, frameStart2 + 3, 2, taddr);
+ proto_tree_add_uint(snmt_tree, hf_oss_snmt_slave, message_tvb, OSS_FRAME_POS_ADDR + frameStart1, 2, addr);
}
}
static gboolean
-dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree, guint8 *bytes, guint16 frameStart1 )
+dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree,
+ guint16 frameStart1, guint16 frameStart2 )
{
- guint16 frameCrc;
- guint16 calcCrc;
+ guint16 frame1_crc, frame2_crc;
+ guint16 calc1_crc;
guint dataLength;
+ guint8 *bytes;
proto_item *item;
proto_tree *checksum_tree;
gint start;
gint length;
+ gboolean isSlim = FALSE;
- dataLength = OSS_FRAME_LENGTH(bytes, frameStart1);
- start = OSS_FRAME_POS_DATA + dataLength + frameStart1;
- frameCrc = bytes[start];
+ dataLength = OSS_FRAME_LENGTH_T(message_tvb, frameStart1);
+ start = OSS_FRAME_POS_DATA + dataLength + frameStart1;
- if (OSS_FRAME_LENGTH(bytes, frameStart1) > OSS_PAYLOAD_MAXSIZE_FOR_CRC8)
- frameCrc += (bytes[start + 1] << 8);
+ if (OSS_FRAME_LENGTH_T(message_tvb, frameStart1) > OSS_PAYLOAD_MAXSIZE_FOR_CRC8)
+ frame1_crc = tvb_get_letohs(message_tvb, start);
+ else
+ frame1_crc = tvb_get_guint8(message_tvb, start);
length = (dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 ? OPENSAFETY_CHECKSUM_CRC16 : OPENSAFETY_CHECKSUM_CRC8);
- item = proto_tree_add_uint(opensafety_tree, hf_oss_crc, message_tvb, start, length, frameCrc);
+ item = proto_tree_add_uint_format(opensafety_tree, hf_oss_crc, message_tvb, start, length, frame1_crc,
+ "CRC for subframe #1: 0x%04X", frame1_crc);
checksum_tree = proto_item_add_subtree(item, ett_opensafety_checksum);
+ bytes = (guint8*)ep_tvb_memdup(message_tvb, frameStart1, dataLength + 4);
if ( dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 )
- calcCrc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
+ calc1_crc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
else
- calcCrc = crc8_0x2F(&bytes[frameStart1], dataLength + 4, 0);
+ calc1_crc = crc8_0x2F(&bytes[frameStart1], dataLength + 4, 0);
- item = proto_tree_add_boolean(checksum_tree, hf_oss_crc_valid, message_tvb, start, length, (frameCrc == calcCrc));
+ item = proto_tree_add_boolean(checksum_tree, hf_oss_crc_valid, message_tvb, start, length, (frame1_crc == calc1_crc));
PROTO_ITEM_SET_GENERATED(item);
/* using the defines, as the values can change */
proto_tree_add_uint(checksum_tree, hf_oss_crc_type, message_tvb, start, length,
( dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 ? OPENSAFETY_CHECKSUM_CRC16 : OPENSAFETY_CHECKSUM_CRC8 ) );
- return (gboolean) (frameCrc == calcCrc);
+ if ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) & OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
+ isSlim = TRUE;
+
+ start = frameStart2 + (isSlim ? 5 : dataLength + OSS_FRAME_POS_DATA + 1 );
+ if (OSS_FRAME_LENGTH_T(message_tvb, frameStart1) > OSS_PAYLOAD_MAXSIZE_FOR_CRC8)
+ frame2_crc = tvb_get_letohs(message_tvb, start);
+ else
+ frame2_crc = tvb_get_guint8(message_tvb, start);
+
+ proto_tree_add_uint_format(opensafety_tree, hf_oss_crc, message_tvb, start, length, frame2_crc,
+ "CRC for subframe #2: 0x%04X", frame2_crc);
+ /* For a correct calculation of the second crc we need to know the scm udid as well
+ * as the sdn. We might have the scm udid, but never the sdn, therefore a calculation
+ * must allways fail. */
+ return (gboolean) (frame1_crc == calc1_crc);
}
static gboolean
@@ -1191,32 +1567,30 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
tvbuff_t *message_tvb, packet_info *pinfo,
proto_item *opensafety_item, proto_tree *opensafety_tree, guint8 u_nrInPackage)
{
- guint8 b_ID;
- guint length;
- guint8 *bytes;
+ guint8 b_ID, ctr;
+ guint8 scm_udid[6];
GByteArray *scmUDID = NULL;
gboolean validSCMUDID;
proto_item *item;
gboolean messageTypeUnknown, crcValid;
messageTypeUnknown = FALSE;
- length = tvb_length(message_tvb);
- bytes = (guint8 *)ep_tvb_memdup(message_tvb, 0, length);
+ for ( ctr = 0; ctr < 6; ctr++ )
+ scm_udid[ctr] = 0;
- b_ID = OSS_FRAME_ID(bytes, frameStart1);
+ b_ID = OSS_FRAME_ID_T(message_tvb, frameStart1);
/* Clearing connection valid bit */
if ( type == OPENSAFETY_SPDO_MESSAGE_TYPE )
- b_ID = ( b_ID >> 3 ) << 3;
+ b_ID = b_ID & 0xF8;
col_append_fstr(pinfo->cinfo, COL_INFO, (u_nrInPackage > 1 ? " | %s" : "%s" ),
val_to_str(b_ID, message_type_values, "Unknown Message (0x%02X) "));
- if (opensafety_tree)
{
if ( type == OPENSAFETY_SNMT_MESSAGE_TYPE )
{
- dissect_opensafety_snmt_message ( message_tvb, pinfo, opensafety_tree, bytes, frameStart1, frameStart2 );
+ dissect_opensafety_snmt_message ( message_tvb, pinfo, opensafety_tree, frameStart1, frameStart2 );
}
else
{
@@ -1226,25 +1600,24 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
if ( hex_str_to_bytes((local_scm_udid != NULL ? local_scm_udid : global_scm_udid), scmUDID, TRUE) && scmUDID->len == 6 )
{
validSCMUDID = TRUE;
- bytes = unxorFrame(length, bytes, frameStart1, frameStart2, scmUDID->data);
- /* Now confirm, that the xor operation was successful
- * The ID fields of both frames have to be the same, otherwise
- * perform the xor again to revert the change
- */
- if ( ( OSS_FRAME_ID(bytes, frameStart1) ^ OSS_FRAME_ID(bytes, frameStart2 ) ) != 0 )
- {
+
+ /* Now confirm, that the xor operation was successful. The ID fields of both frames have to be the same */
+ b_ID = OSS_FRAME_ID_T(message_tvb, frameStart2) ^ (guint8)(scmUDID->data[OSS_FRAME_POS_ID]);
+
+ if ( ( OSS_FRAME_ID_T(message_tvb, frameStart1) ^ b_ID ) != 0 )
validSCMUDID = FALSE;
- bytes = unxorFrame(length, bytes, frameStart1, frameStart2, scmUDID->data);
- }
+ else
+ for ( ctr = 0; ctr < 6; ctr++ )
+ scm_udid[ctr] = scmUDID->data[ctr];
}
if ( strlen ( (local_scm_udid != NULL ? local_scm_udid : global_scm_udid) ) > 0 && scmUDID->len == 6 )
{
- if ( local_scm_udid != NULL )
- item = proto_tree_add_string(opensafety_tree, hf_oss_scm_udid_auto, message_tvb, 0, 0, local_scm_udid);
- else
- item = proto_tree_add_string(opensafety_tree, hf_oss_scm_udid, message_tvb, 0, 0, global_scm_udid);
- PROTO_ITEM_SET_GENERATED(item);
+ if ( local_scm_udid != NULL )
+ item = proto_tree_add_string(opensafety_tree, hf_oss_scm_udid_auto, message_tvb, 0, 0, local_scm_udid);
+ else
+ item = proto_tree_add_string(opensafety_tree, hf_oss_scm_udid, message_tvb, 0, 0, global_scm_udid);
+ PROTO_ITEM_SET_GENERATED(item);
}
item = proto_tree_add_boolean(opensafety_tree, hf_oss_scm_udid_valid, message_tvb, 0, 0, validSCMUDID);
@@ -1256,11 +1629,11 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
if ( type == OPENSAFETY_SSDO_MESSAGE_TYPE || type == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
{
- dissect_opensafety_ssdo_message ( message_tvb, pinfo, opensafety_tree, bytes, frameStart1, frameStart2, validSCMUDID );
+ dissect_opensafety_ssdo_message ( message_tvb, pinfo, opensafety_tree, frameStart1, frameStart2, validSCMUDID, scm_udid );
}
else if ( type == OPENSAFETY_SPDO_MESSAGE_TYPE )
{
- dissect_opensafety_spdo_message ( message_tvb, pinfo, opensafety_tree, bytes, frameStart1, frameStart2, validSCMUDID );
+ dissect_opensafety_spdo_message ( message_tvb, pinfo, opensafety_tree, frameStart1, frameStart2, validSCMUDID, scm_udid );
}
else
{
@@ -1270,14 +1643,14 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
crcValid = FALSE;
item = proto_tree_add_uint(opensafety_tree, hf_oss_length,
- message_tvb, OSS_FRAME_POS_LEN + frameStart1, 1, OSS_FRAME_LENGTH(bytes, frameStart1));
+ message_tvb, OSS_FRAME_POS_LEN + frameStart1, 1, OSS_FRAME_LENGTH_T(message_tvb, frameStart1));
if ( messageTypeUnknown )
{
opensafety_add_error(pinfo, item, "Unknown openSAFETY message type" );
}
else
{
- crcValid = dissect_opensafety_checksum ( message_tvb, opensafety_tree, bytes, frameStart1 );
+ crcValid = dissect_opensafety_checksum ( message_tvb, opensafety_tree, frameStart1, frameStart2 );
}
if ( ! crcValid )
@@ -1290,10 +1663,8 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
* the addresses, but addresses won't be checked yet, as there are issues with SDN xored on it */
if ( crcValid && type == OPENSAFETY_SNMT_MESSAGE_TYPE )
{
- if ( OSS_FRAME_ID(bytes, frameStart1) != OSS_FRAME_ID(bytes, frameStart2) )
- {
+ if ( OSS_FRAME_ID_T(message_tvb, frameStart1) != OSS_FRAME_ID_T(message_tvb, frameStart2) )
opensafety_add_error(pinfo, opensafety_item, "Frame 1 is valid, frame 2 id is invalid => error in openSAFETY frame" );
- }
}
}
@@ -1303,14 +1674,14 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
static gboolean
opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_handle,
gboolean b_frame2First, gboolean do_byte_swap, guint8 force_nr_in_package,
- tvbuff_t *message_tvb , packet_info *pinfo , proto_tree *tree )
+ tvbuff_t *given_tvb , packet_info *pinfo , proto_tree *tree )
{
- tvbuff_t *next_tvb;
+ tvbuff_t *next_tvb, *message_tvb = NULL;
guint length, len, frameOffset, frameLength, nodeAddress;
- guint8 *bytes, *bytesOffset;
+ guint8 *bytes;
gboolean handled, dissectorCalled, call_sub_dissector, markAsMalformed;
guint8 type, found, packageCounter, i, tempByte;
- guint16 frameStart1, frameStart2;
+ guint16 frameStart1, frameStart2, byte_offset;
gint reported_len;
dissector_handle_t protocol_dissector = NULL;
proto_item *opensafety_item;
@@ -1325,9 +1696,9 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
* further dissector calls (see bug #6950) */
register_frame_end_routine(pinfo, reset_dissector);
- length = tvb_length(message_tvb);
+ length = tvb_reported_length(given_tvb);
/* Minimum package length is 11 */
- if ( length < 11 )
+ if ( length < OSS_MINIMUM_LENGTH )
return FALSE;
if ( strlen( sub_diss_handle ) > 0 )
@@ -1338,8 +1709,8 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
protocol_dissector = find_dissector ( "data" );
}
- reported_len = tvb_reported_length_remaining(message_tvb, 0);
- bytes = (guint8 *) ep_tvb_memdup(message_tvb, 0, length);
+ reported_len = tvb_reported_length_remaining(given_tvb, 0);
+ bytes = (guint8 *) ep_tvb_memdup(given_tvb, 0, length);
if ( do_byte_swap == TRUE && global_mbtcp_big_endian == TRUE )
{
@@ -1350,6 +1721,10 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
{
tempByte = bytes [ 2 * i ]; bytes [ 2 * i ] = bytes [ 2 * i + 1 ]; bytes [ 2 * i + 1 ] = tempByte;
}
+
+ message_tvb = tvb_new_real_data(bytes, length, reported_len);
+ } else {
+ message_tvb = given_tvb;
}
frameOffset = 0;
@@ -1359,44 +1734,32 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
while ( frameOffset < length )
{
- if ( ( length - frameOffset ) <= 0 )
+ /* Smallest possible frame size is 11 */
+ if ( tvb_length_remaining(message_tvb, frameOffset ) < OSS_MINIMUM_LENGTH )
break;
- /** Finding the start of the first possible safety frame */
- if ( findSafetyFrame(bytes, length - frameOffset, frameOffset, b_frame2First, &frameOffset, &frameLength) )
+ /* Finding the start of the first possible safety frame */
+ if ( findSafetyFrame(message_tvb, frameOffset, b_frame2First, &frameOffset, &frameLength) )
{
- /** frameLength is calculated/read directly from the dissected data. If frameLenght and frameOffset together
+ /* frameLength is calculated/read directly from the dissected data. If frameLenght and frameOffset together
* are bigger than the reported length, the package is not really an openSAFETY package */
if ( ( frameOffset + frameLength ) > (guint)reported_len )
break;
- found++;
- /* Freeing memory before dissector, as otherwise we would waste it */
- if ( do_byte_swap == TRUE && global_mbtcp_big_endian == TRUE )
- {
- next_tvb = tvb_new_child_real_data(message_tvb, &bytes[frameOffset], (frameLength), reported_len);
- /* Adding a visual aid to the dissector tree */
- add_new_data_source(pinfo, next_tvb, "openSAFETY Frame (Swapped)");
- }
- else
- {
- next_tvb = tvb_new_subset(message_tvb, frameOffset, frameLength, reported_len);
- /* Adding a visual aid to the dissector tree */
- add_new_data_source(pinfo, next_tvb, "openSAFETY Frame");
- }
+ found++;
- bytesOffset = &bytes[( b_frame2First ? 0 : frameOffset )];
+ byte_offset = ( b_frame2First ? 0 : frameOffset );
/* We determine a possible position for frame 1 and frame 2 */
if ( b_frame2First )
{
- frameStart1 = findFrame1Position (bytesOffset, frameLength, FALSE );
+ frameStart1 = findFrame1Position (message_tvb, byte_offset, frameLength, FALSE );
frameStart2 = 0;
}
else
{
frameStart1 = 0;
- frameStart2 = ((OSS_FRAME_LENGTH(bytesOffset, frameStart1) - 1) +
- (OSS_FRAME_LENGTH(bytesOffset, frameStart1) > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 ? OSS_SLIM_FRAME2_WITH_CRC16 : OSS_SLIM_FRAME2_WITH_CRC8));
+ frameStart2 = ((OSS_FRAME_LENGTH_T(message_tvb, byte_offset + frameStart1) - 1) +
+ (OSS_FRAME_LENGTH_T(message_tvb, byte_offset + frameStart1) > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 ? OSS_SLIM_FRAME2_WITH_CRC16 : OSS_SLIM_FRAME2_WITH_CRC8));
}
/* If both frame starts are equal, something went wrong. In which case, we retract the found entry, and
@@ -1409,13 +1772,13 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
}
/* We determine the possible type, and return false, if there could not be one */
- if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
+ if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
type = OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SSDO_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SSDO_MESSAGE_TYPE )
type = OPENSAFETY_SSDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SPDO_MESSAGE_TYPE ) == OPENSAFETY_SPDO_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SPDO_MESSAGE_TYPE ) == OPENSAFETY_SPDO_MESSAGE_TYPE )
type = OPENSAFETY_SPDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SNMT_MESSAGE_TYPE ) == OPENSAFETY_SNMT_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SNMT_MESSAGE_TYPE ) == OPENSAFETY_SNMT_MESSAGE_TYPE )
type = OPENSAFETY_SNMT_MESSAGE_TYPE;
else
{
@@ -1425,37 +1788,67 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
if ( b_frame2First )
{
/* Now let's check again, but this time calculate the CRC */
- frameStart1 = findFrame1Position(bytesOffset, frameLength, TRUE );
+ frameStart1 = findFrame1Position(message_tvb, ( b_frame2First ? 0 : frameOffset ), frameLength, TRUE );
frameStart2 = 0;
- if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
+ if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE )
type = OPENSAFETY_SLIM_SSDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SSDO_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SSDO_MESSAGE_TYPE ) == OPENSAFETY_SSDO_MESSAGE_TYPE )
type = OPENSAFETY_SSDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SPDO_MESSAGE_TYPE ) == OPENSAFETY_SPDO_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SPDO_MESSAGE_TYPE ) == OPENSAFETY_SPDO_MESSAGE_TYPE )
type = OPENSAFETY_SPDO_MESSAGE_TYPE;
- else if ( ( OSS_FRAME_ID(bytesOffset, frameStart1) & OPENSAFETY_SNMT_MESSAGE_TYPE ) == OPENSAFETY_SNMT_MESSAGE_TYPE )
+ else if ( ( OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) & OPENSAFETY_SNMT_MESSAGE_TYPE ) == OPENSAFETY_SNMT_MESSAGE_TYPE )
type = OPENSAFETY_SNMT_MESSAGE_TYPE;
else {
/* Skip this frame. We cannot continue without
advancing frameOffset - just doing a continue
- will result in an infinite loop. */
- frameOffset += frameLength;
+ will result in an infinite loop. Advancing with 1 will
+ lead to infinite loop, advancing with frameLength might miss
+ some packages*/
+ frameOffset += 2;
+ found--;
continue;
}
} else {
/* As stated above, you cannot just continue
- without advancing frameOffset. */
- frameOffset += frameLength;
+ without advancing frameOffset. Advancing with 1 will
+ lead to infinite loop, advancing with frameLength might miss
+ some packages*/
+ frameOffset += 2;
+ found--;
+ continue;
+ }
+ }
+
+ /* Some faulty packages do indeed have a valid first frame, but the second is
+ * invalid. These checks should prevent most faulty detections */
+ if ( type != OPENSAFETY_SPDO_MESSAGE_TYPE )
+ {
+ /* Is the given type at least known? */
+ gint idx = -1;
+ try_val_to_str_idx(OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1), message_type_values, &idx );
+ /* Unknown Frame Type */
+ if ( idx < 0 )
+ {
+ frameOffset += 2;
+ found--;
+ continue;
+ }
+ /* Frame IDs do not match */
+ else if ( type == OPENSAFETY_SNMT_MESSAGE_TYPE &&
+ (OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart1) != OSS_FRAME_ID_T(message_tvb, byte_offset + frameStart2)) )
+ {
+ frameOffset += 2;
+ found--;
continue;
}
}
- /** Checking if the producer for a SPDO message is valid, otherwise the opensafety package
+ /* Checking if the producer for a SPDO message is valid, otherwise the opensafety package
* is malformed. Instead of declining dissection, the package get's marked as malformed */
if ( type == OPENSAFETY_SPDO_MESSAGE_TYPE )
{
- nodeAddress = OSS_FRAME_ADDR(bytesOffset, frameStart1);
+ nodeAddress = OSS_FRAME_ADDR_T(message_tvb, byte_offset + frameStart1);
if ( nodeAddress > 1024 ) {
markAsMalformed = TRUE;
}
@@ -1468,6 +1861,20 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
if ( ( (gint)frameLength - (gint)( frameStart2 > frameStart1 ? frameStart2 : frameLength - frameStart1 ) ) < 0 )
return FALSE;
+ /* From here on, the package should be correct, therefore adding second frame */
+ if ( do_byte_swap == TRUE && global_mbtcp_big_endian == TRUE )
+ {
+ next_tvb = tvb_new_child_real_data(message_tvb, &bytes[frameOffset], (frameLength), reported_len);
+ /* Adding a visual aid to the dissector tree */
+ add_new_data_source(pinfo, next_tvb, "openSAFETY Frame (Swapped)");
+ }
+ else
+ {
+ next_tvb = tvb_new_subset(message_tvb, frameOffset, frameLength, reported_len);
+ /* Adding a visual aid to the dissector tree */
+ add_new_data_source(pinfo, next_tvb, "openSAFETY Frame");
+ }
+
/* A new subtype for package dissection will need to set the actual nr. for the whole dissected package */
if ( force_nr_in_package > 0 )
{
@@ -1505,7 +1912,7 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
if ( tree && markAsMalformed )
{
- if ( OSS_FRAME_ADDR(bytesOffset, frameStart1) > 1024 )
+ if ( OSS_FRAME_ADDR_T(message_tvb, byte_offset + frameStart1) > 1024 )
opensafety_add_error(pinfo, opensafety_item, "SPDO address is invalid" );
}
handled = TRUE;
@@ -1525,6 +1932,7 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
call_dissector(protocol_dissector, message_tvb, pinfo, tree);
handled = TRUE;
}
+
return ( handled ? TRUE : FALSE );
}
@@ -1535,7 +1943,7 @@ dissect_opensafety_epl(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree *
guint8 firstByte;
if ( ! global_enable_plk )
- return result;
+ return result;
/* We will call the epl dissector by using call_dissector(). The epl dissector will then call
* the heuristic openSAFETY dissector again. By setting this information, we prevent a dissector
@@ -1567,7 +1975,7 @@ dissect_opensafety_siii(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree
guint8 firstByte;
if ( ! global_enable_siii )
- return result;
+ return result;
if ( pinfo->ipproto == IPPROTO_UDP )
{
@@ -1602,7 +2010,7 @@ dissect_opensafety_pn_io(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree
gboolean result = FALSE;
if ( ! global_enable_pnio )
- return result;
+ return result;
/* We will call the pn_io dissector by using call_dissector(). The epl dissector will then call
* the heuristic openSAFETY dissector again. By setting this information, we prevent a dissector
@@ -1621,8 +2029,8 @@ dissect_opensafety_pn_io(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree
static gboolean
dissect_opensafety_mbtcp(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree *tree, void *data _U_ )
{
- if ( ! global_enable_mbtcp )
- return FALSE;
+ if ( ! global_enable_mbtcp )
+ return FALSE;
/* When Modbus/TCP get's dissected, openSAFETY would be sorted as a child protocol. Although,
* this behaviour is technically correct, it differs from other implemented IEM protocol handlers.
@@ -1634,32 +2042,33 @@ dissect_opensafety_mbtcp(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree
static gboolean
dissect_opensafety_udpdata(tvbuff_t *message_tvb , packet_info *pinfo , proto_tree *tree , void *data _U_ )
{
- gboolean result = FALSE;
- static guint32 frameNum = 0;
- static guint32 frameIdx = 0;
+ gboolean result = FALSE;
+ static guint32 frameNum = 0;
+ static guint32 frameIdx = 0;
- if ( ! global_enable_udp )
- return result;
+ if ( ! global_enable_udp )
+ return result;
- /* An openSAFETY frame has at least OSS_MINIMUM_LENGTH bytes */
- if ( tvb_length ( message_tvb ) < OSS_MINIMUM_LENGTH )
- return result;
+ /* An openSAFETY frame has at least OSS_MINIMUM_LENGTH bytes */
+ if ( tvb_length ( message_tvb ) < OSS_MINIMUM_LENGTH )
+ return result;
- /* More than one openSAFETY package could be transported in the same frame,
- * in such a case, we need to establish the number of packages inside the frame */
- if ( pinfo->fd->num != frameNum )
- {
- frameIdx = 0;
- frameNum = pinfo->fd->num;
- }
+ /* More than one openSAFETY package could be transported in the same frame,
+ * in such a case, we need to establish the number of packages inside the frame */
+ if ( pinfo->fd->num != frameNum )
+ {
+ frameIdx = 0;
+ frameNum = pinfo->fd->num;
+ }
- result = opensafety_package_dissector((pinfo->destport == UDP_PORT_SIII ? "openSAFETY/SercosIII" : "openSAFETY/UDP" ),
- "", global_udp_frame2_first, FALSE, frameIdx, message_tvb, pinfo, tree);
+ result = opensafety_package_dissector((pinfo->destport == UDP_PORT_SIII ? "openSAFETY/SercosIII" : "openSAFETY/UDP" ),
+ "", pinfo->destport == UDP_PORT_SIII ? global_siii_udp_frame2_first : global_udp_frame2_first,
+ FALSE, frameIdx, message_tvb, pinfo, tree);
- if ( result )
- frameIdx++;
+ if ( result )
+ frameIdx++;
- return result;
+ return result;
}
static void
@@ -1698,126 +2107,190 @@ proto_register_opensafety(void)
{
/* Setup list of header fields */
static hf_register_info hf[] = {
- /* General fields for subframe 1 */
-
{ &hf_oss_scm_udid,
- { "SCM UDID Configured", "opensafety.scm_udid",
+ { "SCM UDID Configured", "opensafety.scm_udid",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_scm_udid_auto,
- { "SCM UDID Auto Detect", "opensafety.scm_udid_auto",
+ { "SCM UDID Auto Detect", "opensafety.scm_udid_auto",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_scm_udid_valid,
- { "SCM UDID Valid", "opensafety.scm_udid_valid",
+ { "SCM UDID Valid", "opensafety.scm_udid_valid",
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_msg,
- { "Message", "opensafety.msg.id",
+ { "Message", "opensafety.msg.id",
FT_UINT8, BASE_HEX, VALS(message_type_values), 0x0, NULL, HFILL } },
{ &hf_oss_msg_category,
- { "Type", "opensafety.msg.type",
+ { "Type", "opensafety.msg.type",
FT_UINT16, BASE_HEX, VALS(message_id_values), 0x0, NULL, HFILL } },
{ &hf_oss_msg_direction,
- { "Direction", "opensafety.msg.direction",
+ { "Direction", "opensafety.msg.direction",
FT_BOOLEAN, BASE_NONE, TFS(&opensafety_message_direction), 0x0, NULL, HFILL } },
{ &hf_oss_msg_node,
- { "Safety Node", "opensafety.msg.node",
+ { "Safety Node", "opensafety.msg.node",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_msg_network,
- { "Safety Domain", "opensafety.msg.network",
+ { "Safety Domain", "opensafety.msg.network",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_msg_sender,
- { "Sender", "opensafety.msg.sender",
+ { "Sender", "opensafety.msg.sender",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_msg_receiver,
- { "Receiver", "opensafety.msg.receiver",
+ { "Receiver", "opensafety.msg.receiver",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_length,
- { "Length", "opensafety.length",
+ { "Length", "opensafety.length",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
-#if 0
- { &hf_oss_data,
- { "Data", "opensafety.data",
- FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
-#endif
{ &hf_oss_crc,
- { "CRC", "opensafety.crc.data",
+ { "CRC", "opensafety.crc.data",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_crc_valid,
- { "Is Valid", "opensafety.crc.valid",
+ { "Is Valid", "opensafety.crc.valid",
FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_crc_type,
- { "CRC Type", "opensafety.crc.type",
+ { "CRC Type", "opensafety.crc.type",
FT_UINT8, BASE_DEC, VALS(message_crc_type), 0x0, NULL, HFILL } },
/* SNMT Specific fields */
{ &hf_oss_snmt_slave,
- { "SNMT Slave", "opensafety.snmt.slave",
+ { "SNMT Slave", "opensafety.snmt.slave",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_master,
- { "SNMT Master", "opensafety.snmt.master",
+ { "SNMT Master", "opensafety.snmt.master",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_scm,
- { "SCM", "opensafety.snmt.scm",
+ { "SCM", "opensafety.snmt.scm",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_tool,
- { "Tool ID", "opensafety.snmt.tool_id",
+ { "Tool ID", "opensafety.snmt.tool_id",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_udid,
- { "UDID for SN", "opensafety.snmt.udid",
+ { "UDID for SN", "opensafety.snmt.udid",
FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } },
- { &hf_oss_snmt_timestamp,
- { "Parameter Timestamp", "opensafety.snmt.timestamp",
- FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_service_id,
- { "Extended Service ID", "opensafety.snmt.service_id",
+ { "Extended Service ID", "opensafety.snmt.service_id",
FT_UINT8, BASE_HEX, VALS(message_service_type), 0x0, NULL, HFILL } },
{ &hf_oss_snmt_error_group,
- { "Error Group", "opensafety.snmt.error_group",
+ { "Error Group", "opensafety.snmt.error_group",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_snmt_error_code,
- { "Error Code", "opensafety.snmt.error_code",
+ { "Error Code", "opensafety.snmt.error_code",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
/* SSDO Specific fields */
{ &hf_oss_ssdo_server,
- { "SSDO Server", "opensafety.ssdo.master",
+ { "SSDO Server", "opensafety.ssdo.master",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_client,
- { "SSDO Client", "opensafety.ssdo.client",
+ { "SSDO Client", "opensafety.ssdo.client",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
-#if 0
{ &hf_oss_ssdo_sano,
- { "SOD Access Request Number", "opensafety.ssdo.sano",
- FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
-#endif
+ { "SOD Access Request Number", "opensafety.ssdo.sano",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_sacmd,
- { "SOD Access Command", "opensafety.ssdo.sacmd",
+ { "SOD Access Command", "opensafety.ssdo.sacmd",
FT_UINT8, BASE_HEX, VALS(ssdo_sacmd_values), 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_sod_index,
- { "SOD Index", "opensafety.ssdo.sod_index",
+ { "SOD Index", "opensafety.ssdo.sodentry.index",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_sod_subindex,
- { "SOD Sub Index", "opensafety.ssdo.sod_subindex",
+ { "SOD Sub Index", "opensafety.ssdo.sodentry.subindex",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_payload,
- { "SOD Payload", "opensafety.ssdo.payload",
+ { "SOD Payload", "opensafety.ssdo.payload",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_oss_ssdo_payload_size,
- { "SOD Payload Size", "opensafety.ssdo.payloadsize",
+ { "SOD Payload Size", "opensafety.ssdo.payloadsize",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
-#if 0
- { &hf_oss_ssdo_segment_size,
- { "SOD Segment Size", "opensafety.ssdo.segmentsize",
- FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
-#endif
+ { &hf_oss_ssdo_sodentry_size,
+ { "SOD Entry Size", "opensafety.ssdo.sodentry.size",
+ FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_sodentry_data,
+ { "SOD Data", "opensafety.ssdo.sodentry.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_sod_par_timestamp,
+ { "Parameter Timestamp", "opensafety.sod.parameter.timestamp",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_sod_par_checksum,
+ { "Parameter Checksum", "opensafety.sod.parameter.checksum",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+
+ { &hf_oss_ssdo_sodmapping,
+ { "Mapping entry", "opensafety.sod.mapping",
+ FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_sodmapping_bits,
+ { "Mapping size", "opensafety.sod.mapping.bits",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+
+ { &hf_oss_ssdo_extpar_parset,
+ { "Set Nr", "opensafety.ssdo.extpar.setnr",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_version,
+ { "Version", "opensafety.ssdo.extpar.version",
+ FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_saddr,
+ { "SADDR", "opensafety.ssdo.extpar.saddr",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_length,
+ { "Set Length", "opensafety.ssdo.extpar.length",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_crc,
+ { "Set CRC", "opensafety.ssdo.extpar.crc",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_tstamp,
+ { "Timestamp", "opensafety.ssdo.extpar.timestamp",
+ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar_data,
+ { "Ext. Parameter Data", "opensafety.ssdo.extpar.data",
+ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_oss_ssdo_extpar,
+ { "Ext. Parameter", "opensafety.ssdo.extpar",
+ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+
+ {&hf_oss_fragments,
+ {"Message fragments", "opensafety.ssdo.fragments",
+ FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment,
+ {"Message fragment", "opensafety.ssdo.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_overlap,
+ {"Message fragment overlap", "opensafety.ssdo.fragment.overlap",
+ FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_overlap_conflicts,
+ {"Message fragment overlapping with conflicting data",
+ "opensafety.ssdo.fragment.overlap.conflicts",
+ FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_multiple_tails,
+ {"Message has multiple tail fragments", "opensafety.ssdo.fragment.multiple_tails",
+ FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_too_long_fragment,
+ {"Message fragment too long", "opensafety.ssdo.fragment.too_long_fragment",
+ FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_error,
+ {"Message defragmentation error", "opensafety.ssdo.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_fragment_count,
+ {"Message fragment count", "opensafety.ssdo.fragment.count",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_reassembled_in,
+ {"Reassembled in", "opensafety.ssdo.reassembled.in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_reassembled_length,
+ {"Reassembled length", "opensafety.ssdo.reassembled.length",
+ FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
+ {&hf_oss_reassembled_data,
+ {"Reassembled Data", "opensafety.ssdo.reassembled.data",
+ FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } },
+
#if 0
{ &hf_oss_ssdo_inhibit_time,
{ "Inhibit Time", "opensafety.ssdo.inhibittime",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
#endif
{ &hf_oss_ssdo_abort_code,
- { "Abort Code", "opensafety.ssdo.abortcode", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+ { "Abort Code", "opensafety.ssdo.abortcode",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
/* SSDO SACmd specific fields */
{ &hf_oss_ssdo_sacmd_access_type,
@@ -1877,14 +2350,20 @@ proto_register_opensafety(void)
/* Setup protocol subtree array */
static gint *ett[] = {
- &ett_opensafety,
- &ett_opensafety_sender,
- &ett_opensafety_receiver,
- &ett_opensafety_checksum,
- &ett_opensafety_snmt,
- &ett_opensafety_ssdo,
- &ett_opensafety_spdo,
- &ett_opensafety_ssdo_sacmd,
+ &ett_opensafety,
+ &ett_opensafety_sender,
+ &ett_opensafety_receiver,
+ &ett_opensafety_checksum,
+ &ett_opensafety_snmt,
+ &ett_opensafety_ssdo,
+ &ett_opensafety_ssdo_sacmd,
+ &ett_opensafety_ssdo_fragment,
+ &ett_opensafety_ssdo_fragments,
+ &ett_opensafety_ssdo_payload,
+ &ett_opensafety_ssdo_sodentry,
+ &ett_opensafety_sod_mapping,
+ &ett_opensafety_ssdo_extpar,
+ &ett_opensafety_spdo,
};
module_t *opensafety_module;
@@ -1914,33 +2393,37 @@ proto_register_opensafety(void)
"Port used for SercosIII/UDP",
"UDP port used by SercosIII to transport data", 10,
&global_network_udp_port_sercosiii);
+ prefs_register_bool_preference(opensafety_module, "network_udp_frame_first_sercosiii",
+ "openSAFETY frame 2 before frame 1 (SercosIII/UDP only)",
+ "In an SercosIII/UDP transport stream, openSAFETY frame 2 will be expected before frame 1",
+ &global_siii_udp_frame2_first );
prefs_register_bool_preference(opensafety_module, "network_udp_frame_first",
- "openSAFETY frame 2 before frame 1 (UDP only)",
- "In the transport stream, openSAFETY frame 2 will be expected before frame 1",
- &global_udp_frame2_first );
+ "openSAFETY frame 2 before frame 1 (UDP only)",
+ "In the transport stream, openSAFETY frame 2 will be expected before frame 1",
+ &global_udp_frame2_first );
prefs_register_bool_preference(opensafety_module, "mbtcp_big_endian",
"Big Endian Word Coding (Modbus/TCP only)",
"Modbus/TCP words can be transcoded either big- or little endian. Default will be little endian",
&global_mbtcp_big_endian);
prefs_register_bool_preference(opensafety_module, "enable_plk",
- "Enable heuristic dissection for Ethernet POWERLINK", "Enable heuristic dissection for Ethernet POWERLINK",
- &global_enable_plk);
+ "Enable heuristic dissection for Ethernet POWERLINK", "Enable heuristic dissection for Ethernet POWERLINK",
+ &global_enable_plk);
prefs_register_bool_preference(opensafety_module, "enable_udp",
- "Enable heuristic dissection for openSAFETY over UDP encoded traffic", "Enable heuristic dissection for openSAFETY over UDP encoded traffic",
- &global_enable_udp);
+ "Enable heuristic dissection for openSAFETY over UDP encoded traffic", "Enable heuristic dissection for openSAFETY over UDP encoded traffic",
+ &global_enable_udp);
prefs_register_bool_preference(opensafety_module, "enable_genudp",
- "Enable heuristic dissection for generic UDP encoded traffic", "Enable heuristic dissection for generic UDP encoded traffic",
- &global_enable_genudp);
+ "Enable heuristic dissection for generic UDP encoded traffic", "Enable heuristic dissection for generic UDP encoded traffic",
+ &global_enable_genudp);
prefs_register_bool_preference(opensafety_module, "enable_siii",
- "Enable heuristic dissection for SercosIII", "Enable heuristic dissection for SercosIII",
- &global_enable_siii);
+ "Enable heuristic dissection for SercosIII", "Enable heuristic dissection for SercosIII",
+ &global_enable_siii);
prefs_register_bool_preference(opensafety_module, "enable_pnio",
- "Enable heuristic dissection for Profinet IO", "Enable heuristic dissection for Profinet IO",
- &global_enable_pnio);
+ "Enable heuristic dissection for Profinet IO", "Enable heuristic dissection for Profinet IO",
+ &global_enable_pnio);
prefs_register_bool_preference(opensafety_module, "enable_mbtcp",
- "Enable heuristic dissection for Modbus/TCP", "Enable heuristic dissection for Modbus/TCP",
- &global_enable_mbtcp);
+ "Enable heuristic dissection for Modbus/TCP", "Enable heuristic dissection for Modbus/TCP",
+ &global_enable_mbtcp);
/* Registering default and ModBus/TCP dissector */
new_register_dissector("opensafety_udpdata", dissect_opensafety_udpdata, proto_opensafety );
@@ -1993,3 +2476,16 @@ proto_reg_handoff_opensafety(void)
}
}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */