aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2006-04-16 22:03:04 +0000
committerJaap Keuter <jaap.keuter@xs4all.nl>2006-04-16 22:03:04 +0000
commit12de0d5145a7e2d7db18603d5f01d173f3975ae1 (patch)
tree9b3c9f9ef56111a2027c6fb96b477075ceaf0693 /epan/dissectors
parentf45378f3bca36cc98d288fc68141f8dfc654ef52 (diff)
From Steve Karg:
1) BACnet signed values were being decoded incorrectly for negative values since BACnet tries to be clever and minimizes the number of bytes sent on the wire and drops the leading FF on negative values. For example, -200 is passed as FF 38 on the wire, but would display as 65336. 2) Since the BACnet unsigned values were decoded using a 64-bit entity, I changed the decoding such that allows all 8 bytes to be decoded. The function can now decode 5, 6, and 7 byte values. 3) Corrected warning about signed/unsigned in a pointer parameter. svn path=/trunk/; revision=17877
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-bacapp.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/epan/dissectors/packet-bacapp.c b/epan/dissectors/packet-bacapp.c
index 5732829567..78303c0aab 100644
--- a/epan/dissectors/packet-bacapp.c
+++ b/epan/dissectors/packet-bacapp.c
@@ -1339,32 +1339,52 @@ fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
static gboolean
fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
{
- gboolean valid = TRUE;
+ gboolean valid = FALSE;
+ gint64 value = 0;
+ guint8 data, i;
- switch (lvt) {
- case 1:
- *val = tvb_get_guint8(tvb, offset);
- break;
- case 2:
- *val = tvb_get_ntohs(tvb, offset);
- break;
- case 3:
- *val = tvb_get_ntoh24(tvb, offset);
- break;
- case 4:
- *val = tvb_get_ntohl(tvb, offset);
- break;
- case 8:
- *val = tvb_get_ntoh64(tvb, offset);
- break;
- default:
- valid = FALSE;
- break;
+ if (lvt && (lvt <= 8)) {
+ valid = TRUE;
+ data = tvb_get_guint8(tvb, offset);
+ for (i = 0; i < lvt; i++) {
+ data = tvb_get_guint8(tvb, offset+i);
+ value = (value << 8) + data;
+ }
+ *val = value;
}
return valid;
}
+/* BACnet Signed Value uses 2's compliment notation, but with a twist:
+ All signed integers shall be encoded in the smallest number of octets
+ possible. That is, the first octet of any multi-octet encoded value
+ shall not be X'00' if the most significant bit (bit 7) of the second
+ octet is 0, and the first octet shall not be X'FF' if the most
+ significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
+static gboolean
+fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
+{
+ gboolean valid = FALSE;
+ gint64 value = 0;
+ guint8 data, i;
+
+ /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
+ if (lvt && (lvt <= 7)) {
+ valid = TRUE;
+ data = tvb_get_guint8(tvb, offset);
+ if ((data & 0x80) != 0)
+ value = (-1 << 8) | data;
+ for (i = 1; i < lvt; i++) {
+ data = tvb_get_guint8(tvb, offset+i);
+ value = (value << 8) + data;
+ }
+ *val = value;
+ }
+
+ return valid;
+}
+
static guint
fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
guint8 *tag_no, guint8* tag_info, guint32 *lvt)
@@ -1574,7 +1594,7 @@ fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *labe
static guint
fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
{
- guint64 val = 0;
+ gint64 val = 0;
guint8 tag_no, tag_info;
guint32 lvt;
guint tag_len;
@@ -1582,9 +1602,9 @@ fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
proto_tree *subtree;
tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
- if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
+ if (fSigned64 (tvb, offset + tag_len, lvt, &val))
ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
- "%s(Signed) %" PRId64, label, (gint64) val);
+ "%s(Signed) %" PRId64, label, val);
else
ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
"%s - %u octets (Signed)", label, lvt);
@@ -2136,7 +2156,7 @@ fPropertyIdentifier (tvbuff_t *tvb, proto_tree *tree, guint offset)
propertyIdentifier = 0; /* global Variable */
tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
- if (fUnsigned32 (tvb, offset+tag_len, lvt, &propertyIdentifier))
+ if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier))
ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
"property Identifier: %s",
val_to_split_str(propertyIdentifier, 512,