aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-08-08 08:57:31 -0700
committerGuy Harris <guy@alum.mit.edu>2014-08-08 15:58:06 +0000
commit22ad90cdc8c4487072e2152cbca8112afaeaa59f (patch)
tree868fb343a8dcf01d5ae625f4fa91dc3d3d58c5b1
parent8da72cd43dcd597c9f03754831d55211a17f077c (diff)
Add routines for CRC-16 with a polynomial of 0x3D65.
There are routines that take a buffer and a length and that take a tvbuff, offset, and length; use those routines in the DNP dissector (which no longer needs its own table and loop), and use the tvbuff routine instead of calling tvb_get_ptr(). Change-Id: Ic67b0f3b65b94ea47c0fdc2f3d3b6f88df77f9c6 Reviewed-on: https://code.wireshark.org/review/3505 Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--epan/crc16-tvb.c10
-rw-r--r--epan/crc16-tvb.h12
-rw-r--r--epan/dissectors/packet-dnp.c78
-rw-r--r--wsutil/crc16.c42
-rw-r--r--wsutil/crc16.h9
5 files changed, 85 insertions, 66 deletions
diff --git a/epan/crc16-tvb.c b/epan/crc16-tvb.c
index 2b0479c060..10854c4401 100644
--- a/epan/crc16-tvb.c
+++ b/epan/crc16-tvb.c
@@ -122,3 +122,13 @@ guint16 crc16_0x9949_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, gui
return crc16_0x9949_seed(buf, len, seed);
}
+
+guint16 crc16_0x3D65_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, guint16 seed)
+{
+ const guint8 *buf;
+
+ tvb_ensure_bytes_exist(tvb, offset, len); /* len == -1 not allowed */
+ buf = tvb_get_ptr(tvb, offset, len);
+
+ return crc16_0x3D65_seed(buf, len, seed);
+}
diff --git a/epan/crc16-tvb.h b/epan/crc16-tvb.h
index f85ae8fc8c..eee19f7597 100644
--- a/epan/crc16-tvb.h
+++ b/epan/crc16-tvb.h
@@ -115,6 +115,18 @@ WS_DLL_PUBLIC guint16 crc16_plain_tvb_offset_seed(tvbuff_t *tvb, guint offset, g
@return The CRC16 checksum. */
WS_DLL_PUBLIC guint16 crc16_0x9949_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, guint16 seed);
+/** Compute CRC16 checksum of a tv buffer using the parameters
+ * Width = 16 bits
+ * Poly = 0x3D65
+ * Reflection = true
+ * Algorithm = table-driven
+ @param tvb The tv buffer containing the data.
+ @param offset The offset into the tv buffer.
+ @param len The number of bytes to include in the computation.
+ @param seed The seed to use.
+ @return The CRC16 checksum. */
+WS_DLL_PUBLIC guint16 crc16_0x3D65_tvb_offset_seed(tvbuff_t *tvb, guint offset, guint len, guint16 seed);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/epan/dissectors/packet-dnp.c b/epan/dissectors/packet-dnp.c
index e9dbda5cdf..abf3c4ade9 100644
--- a/epan/dissectors/packet-dnp.c
+++ b/epan/dissectors/packet-dnp.c
@@ -42,6 +42,8 @@
#include <epan/conversation.h>
#include <epan/expert.h>
#include <epan/to_str.h>
+#include <epan/crc16-tvb.h>
+#include <wsutil/crc16.h>
/*
* See
@@ -1344,73 +1346,17 @@ enum QUALITY_TYPE {
COUNTER
};
-/*****************************************************************/
-/* */
-/* CRC LOOKUP TABLE */
-/* ================ */
-/* The following CRC lookup table was generated automagically */
-/* by the Rocksoft^tm Model CRC Algorithm Table Generation */
-/* Program V1.0 using the following model parameters: */
-/* */
-/* Width : 2 bytes. */
-/* Poly : 0x3D65 */
-/* Reverse : TRUE. */
-/* */
-/* For more information on the Rocksoft^tm Model CRC Algorithm, */
-/* see the document titled "A Painless Guide to CRC Error */
-/* Detection Algorithms" by Ross Williams */
-/* (ross@guest.adelaide.edu.au.). This document is likely to be */
-/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
-/* */
-/*****************************************************************/
-
-static guint16 crctable[256] =
-{
- 0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A,
- 0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, 0x4A4D, 0x7C13,
- 0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1,
- 0x4DE2, 0x7BBC, 0x215E, 0x1700, 0x949A, 0xA2C4, 0xF826, 0xCE78,
- 0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35,
- 0xD626, 0xE078, 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC,
- 0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E,
- 0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7,
- 0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, 0xE69A, 0xD0C4,
- 0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D,
- 0xE135, 0xD76B, 0x8D89, 0xBBD7, 0x384D, 0x0E13, 0x54F1, 0x62AF,
- 0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26,
- 0x7AF1, 0x4CAF, 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B,
- 0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2,
- 0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00,
- 0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, 0x82D7, 0xB489,
- 0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526,
- 0x5935, 0x6F6B, 0x3589, 0x03D7, 0x804D, 0xB613, 0xECF1, 0xDAAF,
- 0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D,
- 0xEB5E, 0xDD00, 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4,
- 0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89,
- 0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300,
- 0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, 0x88BC, 0xBEE2,
- 0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B,
- 0xF5E2, 0xC3BC, 0x995E, 0xAF00, 0x2C9A, 0x1AC4, 0x4026, 0x7678,
- 0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1,
- 0x4789, 0x71D7, 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413,
- 0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A,
- 0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7,
- 0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, 0x9600, 0xA05E,
- 0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC,
- 0x91AF, 0xA7F1, 0xFD13, 0xCB4D, 0x48D7, 0x7E89, 0x246B, 0x1235
-};
-
-/*****************************************************************/
-/* End of CRC Lookup Table */
-/*****************************************************************/
-
/* calculates crc given a buffer of characters and a length of buffer */
static guint16
calculateCRC(const void *buf, guint len) {
- guint16 crc = 0;
- const guint8 *p = (const guint8 *)buf;
- while (len-- > 0)
- crc = crctable[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ guint16 crc = crc16_0x3D65_seed(buf, len, 0);
+ return ~crc;
+}
+
+/* calculates crc given a tvbuff, offset, and length */
+static guint16
+calculateCRCtvb(tvbuff_t *tvb, guint offset, guint len) {
+ guint16 crc = crc16_0x3D65_tvb_offset_seed(tvb, offset, len, 0);
return ~crc;
}
@@ -3174,7 +3120,7 @@ dissect_dnp3_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
/* and header CRC */
dl_crc = tvb_get_letohs(tvb, offset);
- calc_dl_crc = calculateCRC(tvb_get_ptr(tvb, 0, DNP_HDR_LEN - 2), DNP_HDR_LEN - 2);
+ calc_dl_crc = calculateCRCtvb(tvb, 0, DNP_HDR_LEN - 2);
if (dl_crc == calc_dl_crc)
proto_tree_add_uint_format_value(dl_tree, hf_dnp_hdr_CRC, tvb, offset, 2,
dl_crc, "0x%04x [correct]", dl_crc);
@@ -3392,7 +3338,7 @@ check_dnp3_header(tvbuff_t *tvb)
/* Calculate the header CRC if the bytes are available */
if (length >= DNP_HDR_LEN) {
- guint16 calc_crc = calculateCRC(tvb_get_ptr(tvb, 0, DNP_HDR_LEN - 2), DNP_HDR_LEN - 2);
+ guint16 calc_crc = calculateCRCtvb(tvb, 0, DNP_HDR_LEN - 2);
goodCRC = (calc_crc == tvb_get_letohs(tvb, 8));
}
diff --git a/wsutil/crc16.c b/wsutil/crc16.c
index 8dcf9f5b8f..cbb257fd39 100644
--- a/wsutil/crc16.c
+++ b/wsutil/crc16.c
@@ -257,6 +257,43 @@ static const guint crc16_precompiled_9949_reverse[] =
0x2D8F, 0x235D, 0x302B, 0x3EF9, 0x16C7, 0x1815, 0x0B63, 0x05B1
};
+/* This table was compiled using the polynom: 0x3D65 */
+static const guint crc16_precompiled_3D65_reverse[] =
+{
+ 0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A,
+ 0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, 0x4A4D, 0x7C13,
+ 0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1,
+ 0x4DE2, 0x7BBC, 0x215E, 0x1700, 0x949A, 0xA2C4, 0xF826, 0xCE78,
+ 0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35,
+ 0xD626, 0xE078, 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC,
+ 0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E,
+ 0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7,
+ 0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, 0xE69A, 0xD0C4,
+ 0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D,
+ 0xE135, 0xD76B, 0x8D89, 0xBBD7, 0x384D, 0x0E13, 0x54F1, 0x62AF,
+ 0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26,
+ 0x7AF1, 0x4CAF, 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B,
+ 0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2,
+ 0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00,
+ 0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, 0x82D7, 0xB489,
+ 0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526,
+ 0x5935, 0x6F6B, 0x3589, 0x03D7, 0x804D, 0xB613, 0xECF1, 0xDAAF,
+ 0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D,
+ 0xEB5E, 0xDD00, 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4,
+ 0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89,
+ 0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300,
+ 0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, 0x88BC, 0xBEE2,
+ 0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B,
+ 0xF5E2, 0xC3BC, 0x995E, 0xAF00, 0x2C9A, 0x1AC4, 0x4026, 0x7678,
+ 0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1,
+ 0x4789, 0x71D7, 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413,
+ 0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A,
+ 0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7,
+ 0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, 0x9600, 0xA05E,
+ 0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC,
+ 0x91AF, 0xA7F1, 0xFD13, 0xCB4D, 0x48D7, 0x7E89, 0x246B, 0x1235
+};
+
static const guint16 crc16_ccitt_start = 0xFFFF;
static const guint16 crc16_ccitt_xorout = 0xFFFF;
@@ -324,3 +361,8 @@ guint16 crc16_0x9949_seed(const guint8 *buf, guint len, guint16 seed)
{
return crc16_reflected(buf, len, seed, crc16_precompiled_9949_reverse);
}
+
+guint16 crc16_0x3D65_seed(const guint8 *buf, guint len, guint16 seed)
+{
+ return crc16_reflected(buf, len, seed, crc16_precompiled_3D65_reverse);
+}
diff --git a/wsutil/crc16.h b/wsutil/crc16.h
index 91dbec0ffb..53a8305e09 100644
--- a/wsutil/crc16.h
+++ b/wsutil/crc16.h
@@ -88,6 +88,15 @@ WS_DLL_PUBLIC guint16 crc16_0x755B(const guint8 *buf, guint32 len, guint16 seed)
*/
WS_DLL_PUBLIC guint16 crc16_0x9949_seed(const guint8 *buf, guint len, guint16 seed);
+/** Computes CRC16 checksum for the given data with the polynom 0x3D65 using
+ * precompiled CRC table
+ * @param buf 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_0x3D65_seed(const guint8 *buf, guint len, guint16 seed);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */