openSAFETY: CRC Maintenance, new CRC, new expert interface implemented. Bug 8847 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8847)

From Roland Knall

svn path=/trunk/; revision=50166
This commit is contained in:
Michael Mann 2013-06-26 12:11:08 +00:00
parent 500d399393
commit 6e1f213fca
3 changed files with 133 additions and 34 deletions

View File

@ -440,6 +440,18 @@ static gint ett_opensafety_sod_mapping = -1;
static gint ett_opensafety_sender = -1;
static gint ett_opensafety_receiver = -1;
static expert_field ei_payload_length_not_positive = EI_INIT;
static expert_field ei_payload_unknown_format = EI_INIT;
static expert_field ei_crc_slimssdo_instead_of_spdo = EI_INIT;
static expert_field ei_crc_frame_1_invalid = EI_INIT;
static expert_field ei_crc_frame_1_valid_frame2_invalid = EI_INIT;
static expert_field ei_message_unknown_type = EI_INIT;
static expert_field ei_message_reassembly_size_differs_from_header = EI_INIT;
static expert_field ei_message_spdo_address_invalid = EI_INIT;
static expert_field ei_scmudid_autodetected = EI_INIT;
static expert_field ei_scmudid_invalid_preference = EI_INIT;
static expert_field ei_scmudid_unknown = EI_INIT;
static int hf_oss_msg = -1;
static int hf_oss_msg_direction = -1;
static int hf_oss_msg_category = -1;
@ -590,21 +602,6 @@ setup_dissector(void)
void proto_register_opensafety(void);
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_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 */
/* This is defined by the specification. The Address field is 10 bits long, and the node with the number
@ -623,10 +620,10 @@ void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, i
PROTO_ITEM_SET_GENERATED(psf_item); \
if ( sdn > 0 ) \
{ \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
} else if ( sdn <= 0 ) { \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn * -1, "0x%04X", sdn * -1); \
opensafety_add_note(pinfo, psf_item, "SCM UDID unknown, assuming 00 as first UDID octet" ); \
expert_add_info(pinfo, psf_item, &ei_scmudid_unknown ); \
} \
PROTO_ITEM_SET_GENERATED(psf_item); \
}
@ -642,10 +639,10 @@ void opensafety_add_expert_note(packet_info *pinfo, proto_item *pi, int group, i
PROTO_ITEM_SET_GENERATED(psf_item); \
if ( sdn > 0 ) \
{ \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn, "0x%04X", sdn); \
} else if ( sdn <= 0 ) { \
psf_item = proto_tree_add_uint_format_value(psf_tree, hf_oss_msg_network, message_tvb, posnet, 2, sdn * -1, "0x%04X", sdn * -1); \
opensafety_add_note(pinfo, psf_item, "SCM UDID unknown, assuming 00 as first UDID octet" ); \
expert_add_info(pinfo, psf_item, &ei_scmudid_unknown ); \
} \
PROTO_ITEM_SET_GENERATED(psf_item); \
}
@ -778,7 +775,7 @@ static guint8 findSafetyFrame ( tvbuff_t * message_tvb, guint u_Offset, gboolean
crcOffset = 1;
if ( crc != 0x00 )
calcCrc = crc16_0x5935( bytes, b_Length + 4, 0 );
calcCrc = crc16_0x755B( bytes, b_Length + 4, 0 );
} else {
if ( crc != 0x00 )
calcCrc = crc8_0x2F ( bytes, b_Length + 4, 0 );
@ -953,7 +950,7 @@ static void dissect_ssdo_payload ( packet_info *pinfo, tvbuff_t *new_tvb, proto_
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!");
expert_add_info ( pinfo, item, &ei_message_reassembly_size_differs_from_header );
}
}
else
@ -1011,7 +1008,7 @@ static void dissect_ssdo_payload ( packet_info *pinfo, tvbuff_t *new_tvb, proto_
sod_idx_names, "Unknown") );
if ( ssdoIndex < 0x1000 || ssdoIndex > 0xE7FF )
opensafety_add_error ( pinfo, item, "Unknown payload format detected!" );
expert_add_info ( pinfo, item, &ei_payload_unknown_format );
sod_tree = proto_item_add_subtree(item, ett_opensafety_ssdo_sodentry);
@ -1295,7 +1292,8 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb , packet_info *pinfo, prot
{
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 );
expert_add_info_format_text(pinfo, item, &ei_payload_length_not_positive,
"Calculation for payload length yielded non-positive result [%d]", (guint) calcDataLength );
}
}
else
@ -1453,7 +1451,7 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
{
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);
expert_add_info_format_text(pinfo, item, &ei_scmudid_autodetected, "Auto detected payload as SCM UDID [%s].", tempString);
}
}
@ -1536,7 +1534,7 @@ dissect_opensafety_snmt_message(tvbuff_t *message_tvb, packet_info *pinfo , prot
}
static gboolean
dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree,
dissect_opensafety_checksum(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *opensafety_tree,
guint16 frameStart1, guint16 frameStart2 )
{
guint16 frame1_crc, frame2_crc;
@ -1565,7 +1563,15 @@ dissect_opensafety_checksum(tvbuff_t *message_tvb, proto_tree *opensafety_tree,
bytes = (guint8*)ep_tvb_memdup(message_tvb, frameStart1, dataLength + 4);
if ( dataLength > OSS_PAYLOAD_MAXSIZE_FOR_CRC8 )
calc1_crc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
{
calc1_crc = crc16_0x755B(&bytes[frameStart1], dataLength + 4, 0);
if ( frame1_crc != calc1_crc )
{
calc1_crc = crc16_0x5935(&bytes[frameStart1], dataLength + 4, 0);
if ( frame1_crc == calc1_crc )
expert_add_info(pinfo, item, &ei_crc_slimssdo_instead_of_spdo );
}
}
else
calc1_crc = crc8_0x2F(&bytes[frameStart1], dataLength + 4, 0);
@ -1652,7 +1658,7 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
item = proto_tree_add_boolean(opensafety_tree, hf_oss_scm_udid_valid, message_tvb, 0, 0, validSCMUDID);
if ( scmUDID->len != 6 )
opensafety_add_warning(pinfo, item, "openSAFETY protocol settings are invalid! SCM UDID first octet will be assumed to be 00" );
expert_add_info(pinfo, item, &ei_scmudid_invalid_preference );
PROTO_ITEM_SET_GENERATED(item);
g_byte_array_free( scmUDID, TRUE);
@ -1676,16 +1682,16 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
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" );
expert_add_info(pinfo, item, &ei_message_unknown_type );
}
else
{
crcValid = dissect_opensafety_checksum ( message_tvb, opensafety_tree, frameStart1, frameStart2 );
crcValid = dissect_opensafety_checksum ( message_tvb, pinfo, opensafety_tree, frameStart1, frameStart2 );
}
if ( ! crcValid )
{
opensafety_add_error(pinfo, opensafety_item, "Frame 1 CRC invalid => possible error in package" );
expert_add_info(pinfo, opensafety_item, &ei_crc_frame_1_invalid );
}
/* with SNMT's we can check if the ID's for the frames match. Rare randomized packages do have
@ -1694,7 +1700,7 @@ dissect_opensafety_message(guint16 frameStart1, guint16 frameStart2, guint8 type
if ( crcValid && type == OPENSAFETY_SNMT_MESSAGE_TYPE )
{
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" );
expert_add_info(pinfo, opensafety_item, &ei_crc_frame_1_valid_frame2_invalid );
}
}
@ -1943,7 +1949,7 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
if ( tree && markAsMalformed )
{
if ( OSS_FRAME_ADDR_T(message_tvb, byte_offset + frameStart1) > 1024 )
opensafety_add_error(pinfo, opensafety_item, "SPDO address is invalid" );
expert_add_info(pinfo, opensafety_item, &ei_message_spdo_address_invalid );
}
handled = TRUE;
}
@ -2141,10 +2147,10 @@ proto_register_opensafety(void)
{ "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,
@ -2396,7 +2402,47 @@ proto_register_opensafety(void)
&ett_opensafety_spdo,
};
static ei_register_info ei[] = {
{ &ei_crc_frame_1_invalid,
{ "opensafety.crc.error.frame1_invalid", PI_MALFORMED, PI_ERROR,
"Frame 1 CRC invalid, Possible error in package", EXPFILL } },
{ &ei_crc_frame_1_valid_frame2_invalid,
{ "opensafety.crc.error.frame1_valid_frame2_invalid", PI_MALFORMED, PI_ERROR,
"Frame 1 is valid, frame 2 id is invalid", EXPFILL } },
{ &ei_crc_slimssdo_instead_of_spdo,
{ "opensafety.crc.warning.wrong_crc_for_spdo", PI_PROTOCOL, PI_WARN,
"Frame 1 SPDO CRC is Slim SSDO CRC16 0x5935", EXPFILL } },
{ &ei_message_reassembly_size_differs_from_header,
{ "opensafety.msg.warning.reassembly_size_fail", PI_PROTOCOL, PI_WARN,
"Reassembled message size differs from size in header", EXPFILL } },
{ &ei_message_unknown_type,
{ "opensafety.msg.error.unknown_type", PI_MALFORMED, PI_ERROR,
"Unknown openSAFETY message type", EXPFILL } },
{ &ei_message_spdo_address_invalid,
{ "opensafety.msg.error.spdo_address_invalid", PI_MALFORMED, PI_ERROR,
"SPDO address is invalid", EXPFILL } },
{ &ei_scmudid_autodetected,
{ "opensafety.scm_udid.note.autodetected", PI_PROTOCOL, PI_NOTE,
"Auto detected payload as SCM UDID", EXPFILL } },
{ &ei_scmudid_invalid_preference,
{ "opensafety.scm_udid.note.invalid_preference", PI_PROTOCOL, PI_WARN,
"openSAFETY protocol settings are invalid! SCM UDID first octet will be assumed to be 00", EXPFILL } },
{ &ei_scmudid_unknown,
{ "opensafety.scm_udid.warning.assuming_first_octet", PI_PROTOCOL, PI_WARN,
"SCM UDID unknown, assuming 00 as first UDID octet", EXPFILL } },
{ &ei_payload_unknown_format,
{ "opensafety.msg.warning.unknown_format", PI_PROTOCOL, PI_WARN,
"Unknown payload format detected", EXPFILL } },
{ &ei_payload_length_not_positive,
{ "opensafety.msg.warning.reassembly_length_not_positive", PI_PROTOCOL, PI_NOTE,
"Calculation for payload length yielded non-positive result", EXPFILL } },
};
module_t *opensafety_module;
expert_module_t *expert_opensafety;
/* Register the protocol name and description */
proto_opensafety = proto_register_protocol("openSAFETY", "openSAFETY", "opensafety");
@ -2406,6 +2452,9 @@ proto_register_opensafety(void)
proto_register_field_array(proto_opensafety, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
expert_opensafety = expert_register_protocol ( proto_opensafety );
expert_register_field_array ( expert_opensafety, ei, array_length (ei ) );
/* register user preferences */
prefs_register_string_preference(opensafety_module, "scm_udid",
"SCM UDID (xx:xx:xx:xx:xx:xx)",

View File

@ -185,6 +185,42 @@ static const guint crc16_precompiled_5935[256] =
0x65AA, 0x3C9F, 0xD7C0, 0x8EF5, 0x584B, 0x017E, 0xEA21, 0xB314
};
/* This table was compiled using the polynom 0x755B */
static const guint crc16_precompiled_755B[] =
{
0x0000, 0x755b, 0xeab6, 0x9fed, 0xa037, 0xd56c, 0x4a81, 0x3fda, /* 0x00 */
0x3535, 0x406e, 0xdf83, 0xaad8, 0x9502, 0xe059, 0x7fb4, 0x0aef, /* 0x08 */
0x6a6a, 0x1f31, 0x80dc, 0xf587, 0xca5d, 0xbf06, 0x20eb, 0x55b0, /* 0x10 */
0x5f5f, 0x2a04, 0xb5e9, 0xc0b2, 0xff68, 0x8a33, 0x15de, 0x6085, /* 0x18 */
0xd4d4, 0xa18f, 0x3e62, 0x4b39, 0x74e3, 0x01b8, 0x9e55, 0xeb0e, /* 0x20 */
0xe1e1, 0x94ba, 0x0b57, 0x7e0c, 0x41d6, 0x348d, 0xab60, 0xde3b, /* 0x28 */
0xbebe, 0xcbe5, 0x5408, 0x2153, 0x1e89, 0x6bd2, 0xf43f, 0x8164, /* 0x30 */
0x8b8b, 0xfed0, 0x613d, 0x1466, 0x2bbc, 0x5ee7, 0xc10a, 0xb451, /* 0x38 */
0xdcf3, 0xa9a8, 0x3645, 0x431e, 0x7cc4, 0x099f, 0x9672, 0xe329, /* 0x40 */
0xe9c6, 0x9c9d, 0x0370, 0x762b, 0x49f1, 0x3caa, 0xa347, 0xd61c, /* 0x48 */
0xb699, 0xc3c2, 0x5c2f, 0x2974, 0x16ae, 0x63f5, 0xfc18, 0x8943, /* 0x50 */
0x83ac, 0xf6f7, 0x691a, 0x1c41, 0x239b, 0x56c0, 0xc92d, 0xbc76, /* 0x58 */
0x0827, 0x7d7c, 0xe291, 0x97ca, 0xa810, 0xdd4b, 0x42a6, 0x37fd, /* 0x60 */
0x3d12, 0x4849, 0xd7a4, 0xa2ff, 0x9d25, 0xe87e, 0x7793, 0x02c8, /* 0x68 */
0x624d, 0x1716, 0x88fb, 0xfda0, 0xc27a, 0xb721, 0x28cc, 0x5d97, /* 0x70 */
0x5778, 0x2223, 0xbdce, 0xc895, 0xf74f, 0x8214, 0x1df9, 0x68a2, /* 0x78 */
0xccbd, 0xb9e6, 0x260b, 0x5350, 0x6c8a, 0x19d1, 0x863c, 0xf367, /* 0x80 */
0xf988, 0x8cd3, 0x133e, 0x6665, 0x59bf, 0x2ce4, 0xb309, 0xc652, /* 0x88 */
0xa6d7, 0xd38c, 0x4c61, 0x393a, 0x06e0, 0x73bb, 0xec56, 0x990d, /* 0x90 */
0x93e2, 0xe6b9, 0x7954, 0x0c0f, 0x33d5, 0x468e, 0xd963, 0xac38, /* 0x98 */
0x1869, 0x6d32, 0xf2df, 0x8784, 0xb85e, 0xcd05, 0x52e8, 0x27b3, /* 0xA0 */
0x2d5c, 0x5807, 0xc7ea, 0xb2b1, 0x8d6b, 0xf830, 0x67dd, 0x1286, /* 0xA8 */
0x7203, 0x0758, 0x98b5, 0xedee, 0xd234, 0xa76f, 0x3882, 0x4dd9, /* 0xB0 */
0x4736, 0x326d, 0xad80, 0xd8db, 0xe701, 0x925a, 0x0db7, 0x78ec, /* 0xB8 */
0x104e, 0x6515, 0xfaf8, 0x8fa3, 0xb079, 0xc522, 0x5acf, 0x2f94, /* 0xC0 */
0x257b, 0x5020, 0xcfcd, 0xba96, 0x854c, 0xf017, 0x6ffa, 0x1aa1, /* 0xC8 */
0x7a24, 0x0f7f, 0x9092, 0xe5c9, 0xda13, 0xaf48, 0x30a5, 0x45fe, /* 0xD0 */
0x4f11, 0x3a4a, 0xa5a7, 0xd0fc, 0xef26, 0x9a7d, 0x0590, 0x70cb, /* 0xD8 */
0xc49a, 0xb1c1, 0x2e2c, 0x5b77, 0x64ad, 0x11f6, 0x8e1b, 0xfb40, /* 0xE0 */
0xf1af, 0x84f4, 0x1b19, 0x6e42, 0x5198, 0x24c3, 0xbb2e, 0xce75, /* 0xE8 */
0xaef0, 0xdbab, 0x4446, 0x311d, 0x0ec7, 0x7b9c, 0xe471, 0x912a, /* 0xF0 */
0x9bc5, 0xee9e, 0x7173, 0x0428, 0x3bf2, 0x4ea9, 0xd144, 0xa41f /* 0xF8 */
};
static const guint16 crc16_ccitt_start = 0xFFFF;
static const guint16 crc16_ccitt_xorout = 0xFFFF;
@ -244,3 +280,8 @@ guint16 crc16_0x5935(const guint8 *buf, guint32 len, guint16 seed)
return crc16_unreflected(buf, len, seed, crc16_precompiled_5935);
}
guint16 crc16_0x755B(const guint8 *buf, guint32 len, guint16 seed)
{
return crc16_unreflected(buf, len, seed, crc16_precompiled_755B);
}

View File

@ -72,6 +72,15 @@ WS_DLL_PUBLIC guint16 crc16_ccitt_seed(const guint8 *buf, guint len, guint16 see
*/
WS_DLL_PUBLIC guint16 crc16_0x5935(const guint8 *buf, guint32 len, guint16 seed);
/** Calculates a CRC16 checksum for the given buffer with the polynom
* 0x755B using a precompiled CRC table
* @param pBuffer a pointer to a buffer of the given length
* @param len the length of the given buffer
* @param seed The seed to use.
* @return the CRC16 checksum for the buffer
*/
WS_DLL_PUBLIC guint16 crc16_0x755B(const guint8 *buf, guint32 len, guint16 seed);
#ifdef __cplusplus
}
#endif /* __cplusplus */