aboutsummaryrefslogtreecommitdiffstats
path: root/epan/tvbuff.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2020-04-26 16:33:20 -0700
committerGuy Harris <gharris@sonic.net>2020-04-27 01:53:09 +0000
commit524baee94fd8fab0ce4ba212ef35f39e81a386c0 (patch)
treeb024d4b5d739ad69a84c6fd6f9ac8d951263ad08 /epan/tvbuff.c
parent94556ca7a2502f820e2884550b153d06997b9384 (diff)
Add string encoding values for various BCD encodings, and use them.
Add some ENC_ values for various flavors of packed BCD, and use that instead of explicitly calling tvb_bcd_dig_to_wmem_packet_str() and adding the result. Change-Id: I07511d9d09c9231b610c121cd6ffb3b16fb017a9 Reviewed-on: https://code.wireshark.org/review/36952 Reviewed-by: Guy Harris <gharris@sonic.net>
Diffstat (limited to 'epan/tvbuff.c')
-rw-r--r--epan/tvbuff.c131
1 files changed, 95 insertions, 36 deletions
diff --git a/epan/tvbuff.c b/epan/tvbuff.c
index a5a8d24503..3aa4397616 100644
--- a/epan/tvbuff.c
+++ b/epan/tvbuff.c
@@ -2739,6 +2739,30 @@ tvb_get_t61_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint len
}
/*
+ * Encoding tables for BCD strings.
+ */
+static const dgt_set_t Dgt0_9_bcd = {
+ {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
+ }
+};
+
+static const dgt_set_t Dgt_keypad_abc_tbcd = {
+ {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c','?'
+ }
+};
+
+static const dgt_set_t Dgt_ansi_tbcd = {
+ {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#','?'
+ }
+};
+
+/*
* Given a tvbuff, an offset, a length, and an encoding, allocate a
* buffer big enough to hold a non-null-terminated string of that length
* at that offset, plus a trailing '\0', copy into the buffer the
@@ -2931,6 +2955,29 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
case ENC_T61:
strptr = tvb_get_t61_string(scope, tvb, offset, length);
break;
+
+ case ENC_BCD_DIGITS_0_9:
+ /*
+ * Packed BCD, with digits 0-9.
+ */
+ strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt0_9_bcd, FALSE);
+ break;
+
+ case ENC_KEYPAD_ABC_TBCD:
+ /*
+ * Keypad-with-a/b/c "telephony BCD" - packed BCD, with
+ * digits 0-9 and symbols *, #, a, b, and c.
+ */
+ strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_keypad_abc_tbcd, FALSE);
+ break;
+
+ case ENC_KEYPAD_BC_TBCD:
+ /*
+ * Keypad-with-B/C "telephony BCD" - packed BCD, with
+ * digits 0-9 and symbols B, C, *, and #.
+ */
+ strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_ansi_tbcd, FALSE);
+ break;
}
return strptr;
}
@@ -3928,50 +3975,53 @@ tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset
return bytestring_to_str(scope, ensure_contiguous(tvb, offset, len), len, punct);
}
-
/*
- * Given a tvbuff, an offset into the tvbuff, and a length that starts
- * at that offset (which may be -1 for "all the way to the end of the
- * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
- * the low or high half byte, formating the digits according to an input digit set,
- * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
- * A pointer to the packet scope allocated string will be returned.
- * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
+ * Given a wmem scope, a tvbuff, an offset, a length, an input digit
+ * set, and a boolean indicator, fetch BCD-encoded digits from a
+ * tvbuff starting from either the low or high half byte of the
+ * first byte depending on the boolean indicator (TRUE means "start
+ * with the high half byte, ignoring the low half byte", and FALSE
+ * means "start with the low half byte and proceed to the high half
+ * byte), formating the digits into characters according to the
+ * input digit set, and return a pointer to a UTF-8 string, allocated
+ * using the wmem scope. A high-order nibble of 0xf is considered a
+ * 'filler' and will end the conversion.
*/
-static const dgt_set_t Dgt1_9_bcd = {
- {
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/
- '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
- }
-};
-const gchar *
-tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first)
+gchar *
+tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint len, const dgt_set_t *dgt, gboolean skip_first)
{
- int length;
- guint8 octet;
- int i = 0;
- char *digit_str;
- gint t_offset = offset;
+ const guint8 *ptr;
+ int i = 0;
+ char *digit_str;
+ guint8 octet;
DISSECTOR_ASSERT(tvb && tvb->initialized);
- if (!dgt)
- dgt = &Dgt1_9_bcd;
-
if (len == -1) {
+ /*
+ * Run to the end of the captured data.
+ *
+ * XXX - captured, or total?
+ */
/*length = tvb_captured_length(tvb);*/
- length = tvb->length;
- if (length < offset) {
- return "";
+ len = tvb->length;
+ if (len < offset) {
+ return (char *)"";
}
- } else {
- length = offset + len;
+ len -= offset;
}
- digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
- while (t_offset < length) {
+ ptr = ensure_contiguous(tvb, offset, len);
+
+ /*
+ * XXX - map illegal digits (digits that map to 0) to REPLACEMENT
+ * CHARACTER, and have all the tables in epan/tvbuff.c use 0 rather
+ * than '?'?
+ */
+ digit_str = (char *)wmem_alloc(scope, len*2 + 1);
- octet = tvb_get_guint8(tvb,t_offset);
+ while (len > 0) {
+ octet = *ptr;
if (!skip_first) {
digit_str[i] = dgt->out[octet & 0x0f];
i++;
@@ -3983,9 +4033,9 @@ tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len,
*/
octet = octet >> 4;
- if (t_offset == length - 1 && octet == 0x0f) {
+ if (len == 1 && octet == 0x0f) {
/*
- * This is the last octet, and the low-order
+ * This is the last octet, and the high-order
* nibble is 0xf, so we have an odd number of
* digits, and this is a filler digit. Ignore
* it.
@@ -3995,12 +4045,21 @@ tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len,
digit_str[i] = dgt->out[octet & 0x0f];
i++;
- t_offset++;
+ ptr++;
+ len--;
}
- digit_str[i]= '\0';
+ digit_str[i] = '\0';
return digit_str;
+}
+
+const gchar *
+tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first)
+{
+ if (!dgt)
+ dgt = &Dgt0_9_bcd;
+ return tvb_get_bcd_string(wmem_packet_scope(), tvb, offset, len, dgt, skip_first);
}
/*