diff options
author | Guy Harris <guy@alum.mit.edu> | 2020-04-26 16:33:20 -0700 |
---|---|---|
committer | Guy Harris <gharris@sonic.net> | 2020-04-27 01:53:09 +0000 |
commit | 524baee94fd8fab0ce4ba212ef35f39e81a386c0 (patch) | |
tree | b024d4b5d739ad69a84c6fd6f9ac8d951263ad08 /epan/tvbuff.c | |
parent | 94556ca7a2502f820e2884550b153d06997b9384 (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.c | 131 |
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); } /* |