From d7fe514fc05e95e3a99fd211768de5abdc3f6486 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sun, 18 Sep 2016 18:48:50 -0700 Subject: [PATCH] Improve support for single-character fields and filter expressions. Add an FT_CHAR type, which is like FT_UINT8 except that the value is displayed as a C-style character constant. Allow use of C-style character constants in filter expressions; they can be used in comparisons with all integral types, and in "contains" operators. Use that type for some fields that appear (based on the way they're displayed, or on the use of C-style character constants in their value_string tables) to be 1-byte characters rather than 8-bit numbers. Change-Id: I39a9f0dda0bd7f4fa02a9ca8373216206f4d7135 Reviewed-on: https://code.wireshark.org/review/17787 Reviewed-by: Guy Harris --- debian/libwireshark0.symbols | 2 + doc/README.dissector | 22 +- doc/wireshark-filter.pod | 12 +- epan/dfilter/grammar.lemon | 5 + epan/dfilter/scanner.l | 60 +++- epan/dfilter/semcheck.c | 72 ++++- epan/dfilter/sttype-string.c | 9 + epan/dfilter/syntax-tree.h | 1 + epan/dissectors/packet-alljoyn.c | 4 +- epan/dissectors/packet-beep.c | 4 +- epan/dissectors/packet-bzr.c | 8 +- epan/dissectors/packet-dcerpc.c | 20 ++ epan/dissectors/packet-dcerpc.h | 4 + epan/dissectors/packet-eap.c | 12 +- epan/dissectors/packet-gdb.c | 10 +- epan/dissectors/packet-ged125.c | 8 +- epan/dissectors/packet-gopher.c | 4 +- epan/dissectors/packet-gsm_a_dtap.c | 6 +- epan/dissectors/packet-ipx.c | 2 +- epan/dissectors/packet-nasdaq-itch.c | 20 +- epan/dissectors/packet-nasdaq-soup.c | 8 +- epan/dissectors/packet-ouch.c | 340 +++------------------ epan/dissectors/packet-rtpproxy.c | 28 +- epan/dissectors/packet-soupbintcp.c | 47 +-- epan/dissectors/packet-telnet.c | 18 +- epan/dissectors/packet-ucp.c | 62 ++-- epan/dissectors/packet-usb.c | 6 +- epan/dissectors/x11-fields | 4 +- epan/dissectors/x11-glx-render-enum.h | 23 +- epan/dissectors/x11-register-info.h | 4 +- epan/ftypes/ftype-integer.c | 408 +++++++++++++++++++++---- epan/ftypes/ftypes.h | 3 +- epan/proto.c | 404 +++++++++++++++++++++++- epan/to_str.c | 6 + epan/to_str.h | 11 + plugins/profinet/packet-dcerpc-pn-io.c | 4 +- 36 files changed, 1118 insertions(+), 543 deletions(-) diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index 04935f514b..370a9fc8bf 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -287,6 +287,7 @@ libwireshark.so.0 libwireshark0 #MINVER# dissect_ber_set_of@Base 1.9.1 dissect_ber_tagged_type@Base 1.9.1 dissect_dap_SecurityParameters@Base 1.9.1 + dissect_dcerpc_char@Base 2.3.0 dissect_dcerpc_uint16@Base 1.9.1 dissect_dcerpc_uint32@Base 1.9.1 dissect_dcerpc_uint64@Base 1.9.1 @@ -783,6 +784,7 @@ libwireshark.so.0 libwireshark0 #MINVER# guids_get_guid_name@Base 1.9.1 guids_init@Base 1.9.1 guids_resolve_guid_to_str@Base 1.9.1 + guint8_to_hex@Base 2.3.0 h225_RasMessage_vals@Base 1.9.1 h225_ReleaseCompleteReason_vals@Base 1.9.1 h245_set_h223_add_lc_handle@Base 1.9.1 diff --git a/doc/README.dissector b/doc/README.dissector index bd34d416fb..e15ca6e26c 100644 --- a/doc/README.dissector +++ b/doc/README.dissector @@ -103,7 +103,7 @@ PROTOABBREV A name for the protocol for use in filter expressions; FIELDNAME The displayed name for the header field. FIELDABBREV The abbreviated name for the header field; it may contain only letters, digits, hyphens, underscores, and periods. -FIELDTYPE FT_NONE, FT_BOOLEAN, FT_UINT8, FT_UINT16, FT_UINT24, +FIELDTYPE FT_NONE, FT_BOOLEAN, FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, FT_INT8, FT_INT16, FT_INT24, FT_INT32, FT_INT40, FT_INT48, FT_INT56, FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME, @@ -129,6 +129,13 @@ FIELDDISPLAY --For FT_UINT{8,16,24,32,40,48,56,64} and BASE_PT_UDP, BASE_PT_TCP, BASE_PT_DCCP or BASE_PT_SCTP + --For FT_CHAR: + BASE_HEX, BASE_OCT, BASE_CUSTOM, or BASE_NONE, possibly + ORed with BASE_RANGE_STRING, BASE_EXT_STRING or + BASE_VAL64_STRING. + + BASE_NONE can be used in the same way as with FT_UINT8. + --For FT_ABSOLUTE_TIME: ABSOLUTE_TIME_LOCAL, ABSOLUTE_TIME_UTC, or @@ -747,6 +754,9 @@ The type of value this field holds. The current field types are: FT_FRAMENUM A frame number; if this is used, the "Go To Corresponding Frame" menu item can work on that field. + FT_CHAR An 8-bit ASCII character. It's treated similarly to an + FT_UINT8, but is displayed as a C-style character + constant. FT_UINT8 An 8-bit unsigned integer. FT_UINT16 A 16-bit unsigned integer. FT_UINT24 A 24-bit unsigned integer. @@ -880,9 +890,11 @@ For FT_BOOLEAN fields that are also bitfields (i.e., 'bitmask' is non-zero), wide the parent bitfield is). (If the FT_BOOLEAN 'bitmask' is zero, then 'display' must be BASE_NONE). -For integer fields a "field-width" is not needed since the type of integer itself -(FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_UINT40, FT_UINT48, FT_UINT56, -FT_UINT64, etc) tells the proto_tree how wide the parent bitfield is. +For integer fields a "field-width" is not needed since the type of +integer itself (FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_UINT40, +FT_UINT48, FT_UINT56, FT_UINT64, etc) tells the proto_tree how wide the +parent bitfield is. The same is true of FT_CHAR, as it's an 8-bit +character. For FT_ABSOLUTE_TIME fields, 'display' is used to indicate whether the time is to be displayed as a time in the time zone for the machine on @@ -1125,7 +1137,7 @@ for protocols with variable-width header fields. Note that the formats used must all belong to the same group as defined below: - FT_INT8, FT_INT16, FT_INT24 and FT_INT32 -- FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_IPXNET and FT_FRAMENUM +- FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, FT_IPXNET and FT_FRAMENUM - FT_INT40, FT_INT48, FT_INT56 and FT_INT64 - FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64 and FT_EUI64 - FT_ABSOLUTE_TIME and FT_RELATIVE_TIME diff --git a/doc/wireshark-filter.pod b/doc/wireshark-filter.pod index db7ba219ba..6ad3874c04 100644 --- a/doc/wireshark-filter.pod +++ b/doc/wireshark-filter.pod @@ -61,7 +61,8 @@ Additional operators exist expressed only in English, not C-like syntax: The "contains" operator allows a filter to search for a sequence of characters, expressed as a string (quoted or unquoted), or bytes, -expressed as a byte array. For example, to search for a given HTTP +expressed as a byte array, or for a single character, expressed as a +C-style character constant. For example, to search for a given HTTP URL in a capture, the following filter can be used: http contains "https://www.wireshark.org" @@ -120,13 +121,18 @@ Each protocol field is typed. The types are: Signed integer, 1, 2, 3, 4, or 8 bytes Time offset Unsigned integer, 1, 2, 3, 4, or 8 bytes + 1-byte ASCII character -An integer may be expressed in decimal, octal, or hexadecimal notation. -The following three display filters are equivalent: +An integer may be expressed in decimal, octal, or hexadecimal notation, +or as a C-style character constant. The following six display filters +are equivalent: frame.pkt_len > 10 frame.pkt_len > 012 frame.pkt_len > 0xa + frame.pkt_len > '\n' + frame.pkt_len > '\xa' + frame.pkt_len > '\012' Boolean values are either true or false. In a display filter expression testing the value of a Boolean field, "true" is expressed as 1 or any diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index 0ea861d446..703876ebcb 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -88,6 +88,10 @@ any "error" symbols are shifted, if possible. */ dfilter_fail(dfw, "The string \"%s\" was unexpected in this context.", (char *)stnode_data(TOKEN)); break; + case STTYPE_CHARCONST: + dfilter_fail(dfw, "The character constant \"%s\" was unexpected in this context.", + (char *)stnode_data(TOKEN)); + break; case STTYPE_UNPARSED: dfilter_fail(dfw, "\"%s\" was unexpected in this context.", (char *)stnode_data(TOKEN)); @@ -173,6 +177,7 @@ logical_test(T) ::= entity(E). /* Entities, or things that can be compared/tested/checked */ entity(E) ::= FIELD(F). { E = F; } entity(E) ::= STRING(S). { E = S; } +entity(E) ::= CHARCONST(C). { E = C; } entity(E) ::= UNPARSED(U). { E = U; } entity(E) ::= range(R). { E = R; } diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index ce138da8b6..b6c9605243 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -117,6 +117,7 @@ static void mark_lval_deprecated(const char *s); %x RANGE_INT %x RANGE_PUNCT %x DQUOTE +%x SQUOTE %% @@ -214,7 +215,7 @@ static void mark_lval_deprecated(const char *s); } \042 { - /* start quote */ + /* start quote of a quoted string */ /* The example of how to scan for strings was taken from the flex 2.5.4 manual, from the section "Start Conditions". See: @@ -287,6 +288,60 @@ static void mark_lval_deprecated(const char *s); } +\047 { + /* start quote of a quoted character value */ + /* The example of how to scan for strings was taken from + the Flex manual, from the section "Start Conditions". + See: + http://flex.sourceforge.net/manual/Start-Conditions.html#Start-Conditions */ + + BEGIN(SQUOTE); + /* A previous filter that failed to compile due to + a missing end quote will have left quoted_string set + to something. Clear it now that we are starting + a new quoted string. */ + if (yyextra->quoted_string) { + g_string_free(yyextra->quoted_string, TRUE); + /* Don't set quoted_string to NULL, as we + do in other quoted_string-cleanup code, as we're + about to set it in the next line. */ + } + yyextra->quoted_string = g_string_new("'"); +} + +<> { + /* unterminated character value */ + /* The example of how to handle unclosed strings was taken from + the Flex manual, from the section "End-of-file rules". + See: + http://flex.sourceforge.net/manual/EOF.html#EOF.html */ + + dfilter_fail(yyextra->dfw, "The final quote was missing from a character constant."); + return SCAN_FAILED; +} + +\047 { + /* end quote */ + int token; + BEGIN(INITIAL); + g_string_append_c(yyextra->quoted_string, '\''); + token = set_lval(TOKEN_CHARCONST, yyextra->quoted_string->str); + g_string_free(yyextra->quoted_string, TRUE); + yyextra->quoted_string = NULL; + return token; +} + +\\. { + /* escaped character */ + g_string_append(yyextra->quoted_string, yytext); +} + +[^\\\047]+ { + /* non-escaped string */ + g_string_append(yyextra->quoted_string, yytext); +} + + [-[:alnum:]_\.:]*\/[[:digit:]]+ { /* CIDR */ @@ -367,6 +422,9 @@ set_lval(int token, gpointer data) case TOKEN_STRING: type_id = STTYPE_STRING; break; + case TOKEN_CHARCONST: + type_id = STTYPE_CHARCONST; + break; case TOKEN_FIELD: type_id = STTYPE_FIELD; break; diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index de7057451f..8d2840e0a9 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -103,6 +103,7 @@ compatible_ftypes(ftenum_t a, ftenum_t b) case FT_BOOLEAN: case FT_FRAMENUM: + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -114,6 +115,7 @@ compatible_ftypes(ftenum_t a, ftenum_t b) switch (b) { case FT_BOOLEAN: case FT_FRAMENUM: + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -235,6 +237,7 @@ mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, char *s) return NULL; case FT_BOOLEAN: + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -371,6 +374,7 @@ is_bytes_type(enum ftenum type) case FT_STRINGZPAD: case FT_BOOLEAN: case FT_FRAMENUM: + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -413,6 +417,7 @@ check_exists(dfwork_t *dfw, stnode_t *st_arg1) /* This is OK */ break; case STTYPE_STRING: + case STTYPE_CHARCONST: case STTYPE_UNPARSED: dfilter_fail(dfw, "\"%s\" is neither a field nor a protocol name.", (char *)stnode_data(st_arg1)); @@ -607,6 +612,25 @@ check_function(dfwork_t *dfw, stnode_t *st_node) } } +/* Convert a character constant to a 1-byte BYTE_STRING containing the + * character. */ +static fvalue_t * +charconst_to_bytes(dfwork_t *dfw, char *s, gboolean allow_partial_value) +{ + fvalue_t *fvalue; + + fvalue = dfilter_fvalue_from_unparsed(dfw, FT_CHAR, s, allow_partial_value); + if (fvalue) { + char *temp_string; + /* It's valid. Create a 1-byte BYTE_STRING from its value. */ + temp_string = g_strdup_printf("%02x", fvalue->value.uinteger); + FVALUE_FREE(fvalue); + fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, temp_string, allow_partial_value); + g_free(temp_string); + } + return (fvalue); +} + /* If the LHS of a relation test is a FIELD, run some checks * and possibly some modifications of syntax tree nodes. */ static void @@ -657,7 +681,8 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, THROW(TypeError); } } - else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { + else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || + type2 == STTYPE_CHARCONST) { s = (char *)stnode_data(st_arg2); if (strcmp(relation_string, "matches") == 0) { /* Convert to a FT_PCRE */ @@ -676,10 +701,20 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string, if (type2 == STTYPE_STRING) fvalue = dfilter_fvalue_from_string(dfw, ftype1, s); - else + else if (type2 == STTYPE_CHARCONST && + strcmp(relation_string, "contains") == 0) { + /* The RHS should be FT_BYTES, but a character + * is just a one-byte byte string. */ + fvalue = charconst_to_bytes(dfw, s, allow_partial_value); + } else fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value); - if (!fvalue) { + /* + * If this is a character constant, just report the + * error, don't try to treat it as a string from + * a value_string table. + */ + if (!fvalue && type2 != STTYPE_CHARCONST) { /* check value_string */ fvalue = mk_fvalue_from_val_string(dfw, hfinfo1, s); } @@ -801,7 +836,8 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string, sttype_test_set2_args(st_node, new_st, st_arg2); stnode_free(st_arg1); } - else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { + else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || + type2 == STTYPE_CHARCONST) { /* Well now that's silly... */ dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.", (char *)stnode_data(st_arg1), @@ -894,7 +930,8 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string, sttype_test_set2_args(st_node, new_st, st_arg2); stnode_free(st_arg1); } - else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { + else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || + type2 == STTYPE_CHARCONST) { /* Well now that's silly... */ dfilter_fail(dfw, "Neither \"%s\" nor \"%s\" are field or protocol names.", (char *)stnode_data(st_arg1), @@ -1071,6 +1108,26 @@ check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string, sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } + else if (type2 == STTYPE_CHARCONST) { + DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_CHARCONST)\n")); + s = (char*)stnode_data(st_arg2); + len_range = drange_get_total_length(sttype_range_drange(st_arg1)); + if (strcmp(relation_string, "matches") == 0) { + /* Convert to a FT_PCRE */ + fvalue = dfilter_fvalue_from_unparsed(dfw, FT_PCRE, s, FALSE); + } + + /* The RHS should be FT_BYTES, but a character is just a + * one-byte byte string. */ + fvalue = charconst_to_bytes(dfw, s, allow_partial_value); + if (!fvalue) { + DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED): Could not convert from string!\n")); + THROW(TypeError); + } + new_st = stnode_new(STTYPE_FVALUE, fvalue); + sttype_test_set2_args(st_node, st_arg1, new_st); + stnode_free(st_arg2); + } else if (type2 == STTYPE_RANGE) { DebugLog((" 5 check_relation_LHS_RANGE(type2 = STTYPE_RANGE)\n")); check_drange_sanity(dfw, st_arg2); @@ -1114,7 +1171,7 @@ check_param_entity(dfwork_t *dfw, stnode_t *st_node) e_type = stnode_type_id(st_node); /* If there's an unparsed string, change it to an FT_STRING */ - if (e_type == STTYPE_UNPARSED) { + if (e_type == STTYPE_UNPARSED || e_type == STTYPE_CHARCONST) { s = (char*)stnode_data(st_node); fvalue = dfilter_fvalue_from_unparsed(dfw, FT_STRING, s, FALSE); if (!fvalue) { @@ -1197,7 +1254,7 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string, sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } - else if (type2 == STTYPE_UNPARSED) { + else if (type2 == STTYPE_UNPARSED || type2 == STTYPE_CHARCONST) { s = (char*)stnode_data(st_arg2); if (strcmp(relation_string, "matches") == 0) { /* Convert to a FT_PCRE */ @@ -1301,6 +1358,7 @@ header_field_info *hfinfo; allow_partial_value, st_node, st_arg1, st_arg2); break; case STTYPE_UNPARSED: + case STTYPE_CHARCONST: check_relation_LHS_UNPARSED(dfw, relation_string, can_func, allow_partial_value, st_node, st_arg1, st_arg2); break; diff --git a/epan/dfilter/sttype-string.c b/epan/dfilter/sttype-string.c index 8be5f33378..c5cf2c62f6 100644 --- a/epan/dfilter/sttype-string.c +++ b/epan/dfilter/sttype-string.c @@ -51,6 +51,14 @@ sttype_register_string(void) string_dup }; + static sttype_t charconst_type = { + STTYPE_CHARCONST, + "CHARCONST", + string_new, + string_free, + string_dup + }; + static sttype_t unparsed_type = { STTYPE_UNPARSED, "UNPARSED", @@ -60,6 +68,7 @@ sttype_register_string(void) }; sttype_register(&string_type); + sttype_register(&charconst_type); sttype_register(&unparsed_type); } diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h index 5d955c900a..54a4294dae 100644 --- a/epan/dfilter/syntax-tree.h +++ b/epan/dfilter/syntax-tree.h @@ -32,6 +32,7 @@ typedef enum { STTYPE_TEST, STTYPE_UNPARSED, STTYPE_STRING, + STTYPE_CHARCONST, STTYPE_FIELD, STTYPE_FVALUE, STTYPE_INTEGER, diff --git a/epan/dissectors/packet-alljoyn.c b/epan/dissectors/packet-alljoyn.c index 21e76057e9..6dcaf18dd0 100644 --- a/epan/dissectors/packet-alljoyn.c +++ b/epan/dissectors/packet-alljoyn.c @@ -1564,7 +1564,7 @@ handle_message_header_body(tvbuff_t *tvb, header_item = proto_tree_add_item(message_tree, hf_alljoyn_mess_header, tvb, offset, MESSAGE_HEADER_LENGTH, ENC_NA); header_tree = proto_item_add_subtree(header_item, ett_alljoyn_header); - proto_tree_add_item(header_tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_NA); + proto_tree_add_item(header_tree, hf_alljoyn_mess_header_endian, tvb, offset + ENDIANNESS_OFFSET, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(header_tree, hf_alljoyn_mess_header_type, tvb, offset + TYPE_OFFSET, 1, ENC_NA); /* The flags byte. */ @@ -2674,7 +2674,7 @@ proto_register_AllJoyn(void) }, {&hf_alljoyn_mess_header_endian, {"Endianness", "alljoyn.mess_header.endianess", - FT_UINT8, BASE_DEC, VALS(endian_encoding_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(endian_encoding_vals), 0x0, NULL, HFILL} }, {&hf_alljoyn_mess_header_type, diff --git a/epan/dissectors/packet-beep.c b/epan/dissectors/packet-beep.c index ba8a96e810..56bd7883fa 100644 --- a/epan/dissectors/packet-beep.c +++ b/epan/dissectors/packet-beep.c @@ -222,7 +222,7 @@ dissect_beep_more(tvbuff_t *tvb, packet_info *pinfo, int offset, int ret = 0; guint8 more = tvb_get_guint8(tvb, offset); - hidden_item = proto_tree_add_item(tree, hf_beep_more, tvb, offset, 1, ENC_BIG_ENDIAN); + hidden_item = proto_tree_add_item(tree, hf_beep_more, tvb, offset, 1, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_HIDDEN(hidden_item); switch(more) { @@ -916,7 +916,7 @@ proto_register_beep(void) { "Sequence Channel Number", "beep.seq.channel", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_beep_more, - { "More", "beep.more", FT_UINT8, BASE_HEX, VALS(beep_more_vals), 0x0, NULL, HFILL }}, + { "More", "beep.more", FT_CHAR, BASE_HEX, VALS(beep_more_vals), 0x0, NULL, HFILL }}, { &hf_beep_msgno, { "Msgno", "beep.msgno", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, diff --git a/epan/dissectors/packet-bzr.c b/epan/dissectors/packet-bzr.c index 6f8a5111f5..e1ddb62971 100644 --- a/epan/dissectors/packet-bzr.c +++ b/epan/dissectors/packet-bzr.c @@ -176,7 +176,7 @@ dissect_body(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) while (tvb_reported_length_remaining(tvb, offset) > 0) { cmd = tvb_get_guint8(tvb, offset); - proto_tree_add_item(tree, hf_bzr_packet_kind, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_bzr_packet_kind, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; switch (cmd) { @@ -188,7 +188,7 @@ dissect_body(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) break; case 'o': proto_tree_add_item(tree, hf_bzr_result, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; case 'e': @@ -258,7 +258,7 @@ proto_register_bzr(void) { static hf_register_info hf[] = { { &hf_bzr_packet_kind, - { "Packet kind", "bzr.kind", FT_UINT8, BASE_DEC, + { "Packet kind", "bzr.kind", FT_CHAR, BASE_HEX, VALS(message_part_kind), 0x0, NULL, HFILL }, }, { &hf_bzr_packet_protocol_version, @@ -287,7 +287,7 @@ proto_register_bzr(void) NULL, 0x0, NULL, HFILL }, }, { &hf_bzr_result, - { "Result", "bzr.result", FT_UINT8, BASE_HEX, + { "Result", "bzr.result", FT_CHAR, BASE_HEX, VALS(message_results), 0x0, "Command result (success or failure with error message)", HFILL }, diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c index d4c0d11b39..4029904ff4 100644 --- a/epan/dissectors/packet-dcerpc.c +++ b/epan/dissectors/packet-dcerpc.c @@ -2041,6 +2041,26 @@ dcerpcstat_param(register_srt_t* srt, const char* opt_arg, char** err) * Utility functions. Modeled after packet-rpc.c */ +int +dissect_dcerpc_char(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, + proto_tree *tree, guint8 *drep, + int hfindex, guint8 *pdata) +{ + guint8 data; + + /* + * XXX - fix to handle EBCDIC if we ever support EBCDIC FT_CHAR. + */ + data = tvb_get_guint8(tvb, offset); + if (hfindex != -1) { + proto_tree_add_item(tree, hfindex, tvb, offset, 1, ENC_ASCII|DREP_ENC_INTEGER(drep)); + } + if (pdata) + *pdata = data; + tvb_ensure_bytes_exist(tvb, offset, 1); + return offset + 1; +} + int dissect_dcerpc_uint8(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree, guint8 *drep, diff --git a/epan/dissectors/packet-dcerpc.h b/epan/dissectors/packet-dcerpc.h index eb7e7799dc..480ad28c9e 100644 --- a/epan/dissectors/packet-dcerpc.h +++ b/epan/dissectors/packet-dcerpc.h @@ -205,6 +205,10 @@ guint16 dcerpc_tvb_get_ntohs (tvbuff_t *tvb, gint offset, guint8 *drep); guint32 dcerpc_tvb_get_ntohl (tvbuff_t *tvb, gint offset, guint8 *drep); void dcerpc_tvb_get_uuid (tvbuff_t *tvb, gint offset, guint8 *drep, e_guid_t *uuid); WS_DLL_PUBLIC +int dissect_dcerpc_char (tvbuff_t *tvb, gint offset, packet_info *pinfo, + proto_tree *tree, guint8 *drep, + int hfindex, guint8 *pdata); +WS_DLL_PUBLIC int dissect_dcerpc_uint8 (tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree, guint8 *drep, int hfindex, guint8 *pdata); diff --git a/epan/dissectors/packet-eap.c b/epan/dissectors/packet-eap.c index 0cbe057dfe..837bb8cbe4 100644 --- a/epan/dissectors/packet-eap.c +++ b/epan/dissectors/packet-eap.c @@ -660,9 +660,8 @@ dissect_eap_aka(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size) /* * XXX - see previous comment. */ - proto_tree_add_uint_format_value(attr_tree, hf_eap_identity_prefix, - tvb, aoffset+2, 1, eap_identity_prefix, "%s ('%c')", - eap_identity_prefix_str, eap_identity_prefix); + proto_tree_add_uint(attr_tree, hf_eap_identity_prefix, + tvb, aoffset+2, 1, eap_identity_prefix); } proto_tree_add_item(attr_tree, hf_eap_identity, tvb, aoffset + 2, aleft - 2, ENC_ASCII|ENC_NA); } @@ -854,9 +853,8 @@ dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) * of the identity is a value that happens to be a valid * prefix, that doesn't *ipso facto* mean it *is* a prefix. */ - proto_tree_add_uint_format_value(eap_identity_tree, hf_eap_identity_prefix, - tvb, offset, 1, eap_identity_prefix, "%s ('%c')", - eap_identity_prefix_str, eap_identity_prefix); + proto_tree_add_uint(eap_identity_tree, hf_eap_identity_prefix, + tvb, offset, 1, eap_identity_prefix); } } if(!pinfo->fd->flags.visited) { @@ -1313,7 +1311,7 @@ proto_register_eap(void) { &hf_eap_identity_prefix, { "Identity Prefix", "eap.identity.prefix", - FT_UINT8, BASE_HEX, VALS(eap_identity_prefix_vals), 0x0, NULL, HFILL }}, + FT_CHAR, BASE_HEX, VALS(eap_identity_prefix_vals), 0x0, NULL, HFILL }}, { &hf_eap_identity_actual_len, { "Identity Actual Length", "eap.identity.actual_len", diff --git a/epan/dissectors/packet-gdb.c b/epan/dissectors/packet-gdb.c index e5c9187df9..d930708bca 100644 --- a/epan/dissectors/packet-gdb.c +++ b/epan/dissectors/packet-gdb.c @@ -72,7 +72,6 @@ dissect_gdb_token(void *tvbparse_data, const void *wanted_data, tvbparse_elem_t { proto_tree *tree; guint token; - guint8 ack; if (!tok) /* XXX - is this check necessary? */ return; @@ -83,11 +82,8 @@ dissect_gdb_token(void *tvbparse_data, const void *wanted_data, tvbparse_elem_t /* XXX - check that tok->len is what we expect? */ switch (token) { case GDB_TOK_ACK: - ack = tvb_get_guint8(tok->tvb, tok->offset); - proto_tree_add_uint_format(tree, hf_gdb_ack, - tok->tvb, tok->offset, tok->len, ack, - "Acknowledgement: %s (%c)", - val_to_str_const(ack, gdb_ack, "unknown"), ack); + proto_tree_add_item(tree, hf_gdb_ack, + tok->tvb, tok->offset, tok->len, ENC_ASCII|ENC_NA); break; case GDB_TOK_START: proto_tree_add_item(tree, hf_gdb_start, @@ -200,7 +196,7 @@ proto_register_gdb(void) { static hf_register_info hf[] = { { &hf_gdb_ack, - { "Acknowledge", "gdb.ack", FT_UINT8, BASE_HEX, + { "Acknowledge", "gdb.ack", FT_CHAR, BASE_HEX, VALS(gdb_ack), 0, NULL, HFILL } }, { &hf_gdb_start, { "Start character", "gdb.start", FT_STRING, BASE_NONE, diff --git a/epan/dissectors/packet-ged125.c b/epan/dissectors/packet-ged125.c index 9f732f86ae..460958fae9 100644 --- a/epan/dissectors/packet-ged125.c +++ b/epan/dissectors/packet-ged125.c @@ -590,7 +590,7 @@ Media_Specifier_dissect(tvbuff_t* tvb, proto_tree* tree, gint* offset, guint32 l guint8 media_protocol; media_protocol = tvb_get_guint8(tvb, *offset); - proto_tree_add_item(tree, hf_ged125_floating_media_protocol, tvb, *offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_ged125_floating_media_protocol, tvb, *offset, 1, ENC_NA|ENC_ASCII); *offset += 1; switch (media_protocol) @@ -599,7 +599,7 @@ Media_Specifier_dissect(tvbuff_t* tvb, proto_tree* tree, gint* offset, guint32 l case 'S': case 'O': case 'F': - proto_tree_add_item(tree, hf_ged125_floating_library_designator, tvb, *offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_ged125_floating_library_designator, tvb, *offset, 1, ENC_NA|ENC_ASCII); *offset += 1; proto_tree_add_item(tree, hf_ged125_floating_payload_strg, tvb, *offset, length - 2, ENC_NA|ENC_ASCII); break; @@ -1696,12 +1696,12 @@ proto_register_ged125 (void) { &hf_ged125_floating_media_protocol, { "Media Protocol", "ged125.media_protocol", - FT_UINT8, BASE_DEC, VALS(floating_media_protocol_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(floating_media_protocol_vals), 0x0, "Type of media", HFILL }}, { &hf_ged125_floating_library_designator, { "Library Designator", "ged125.library_designator", - FT_UINT8, BASE_DEC, VALS(floating_media_library_designator_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(floating_media_library_designator_vals), 0x0, "System or Application", HFILL }}, { &hf_ged125_Data_Playback_Type, diff --git a/epan/dissectors/packet-gopher.c b/epan/dissectors/packet-gopher.c index 8d0db445ea..f8d0e3e633 100644 --- a/epan/dissectors/packet-gopher.c +++ b/epan/dissectors/packet-gopher.c @@ -175,7 +175,7 @@ dissect_gopher(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ ti = proto_tree_add_string(gopher_tree, hf_gopher_dir_item, tvb, offset, line_len + 1, name); dir_tree = proto_item_add_subtree(ti, ett_dir_item); - proto_tree_add_item(dir_tree, hf_gopher_di_type, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(dir_tree, hf_gopher_di_type, tvb, offset, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(dir_tree, hf_gopher_di_name, tvb, offset + 1, sel_start - offset - 2, ENC_ASCII|ENC_NA); proto_tree_add_item(dir_tree, hf_gopher_di_selector, tvb, sel_start, @@ -238,7 +238,7 @@ proto_register_gopher(void) }, { &hf_gopher_di_type, { "Type", "gopher.directory.type", - FT_UINT8, BASE_HEX, VALS(item_types), 0, + FT_CHAR, BASE_HEX, VALS(item_types), 0, NULL, HFILL } }, { &hf_gopher_di_name, diff --git a/epan/dissectors/packet-gsm_a_dtap.c b/epan/dissectors/packet-gsm_a_dtap.c index 3d5397a139..587affd4d2 100644 --- a/epan/dissectors/packet-gsm_a_dtap.c +++ b/epan/dissectors/packet-gsm_a_dtap.c @@ -2706,8 +2706,8 @@ de_keypad_facility(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 proto_tree_add_bits_item(tree, hf_gsm_a_spare_bits, tvb, curr_offset<<3, 1, ENC_BIG_ENDIAN); - item = proto_tree_add_uint_format_value(tree, hf_gsm_a_dtap_keypad_information, tvb, curr_offset, 1, - keypad_char, "%c", keypad_char); + item = proto_tree_add_uint(tree, hf_gsm_a_dtap_keypad_information, tvb, curr_offset, 1, + keypad_char); if (((keypad_char < '0') || (keypad_char > '9')) && ((keypad_char < 'A') || (keypad_char > 'D')) && @@ -8026,7 +8026,7 @@ proto_register_gsm_a_dtap(void) }, { &hf_gsm_a_dtap_keypad_information, { "Keypad information", "gsm_a.dtap.keypad_information", - FT_UINT8, BASE_DEC, NULL, 0x7f, + FT_CHAR, BASE_HEX, NULL, 0x7f, NULL, HFILL } }, { &hf_gsm_a_dtap_repeat_indicator, diff --git a/epan/dissectors/packet-ipx.c b/epan/dissectors/packet-ipx.c index a0b85871d5..acdbf29a6e 100644 --- a/epan/dissectors/packet-ipx.c +++ b/epan/dissectors/packet-ipx.c @@ -1520,7 +1520,7 @@ proto_register_ipx(void) { &hf_msg_sigchar, { "Signature Char", "ipxmsg.sigchar", - FT_UINT8, BASE_DEC, VALS(ipxmsg_sigchar_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(ipxmsg_sigchar_vals), 0x0, NULL, HFILL }} }; diff --git a/epan/dissectors/packet-nasdaq-itch.c b/epan/dissectors/packet-nasdaq-itch.c index 4e62be271e..3695de10a1 100644 --- a/epan/dissectors/packet-nasdaq-itch.c +++ b/epan/dissectors/packet-nasdaq-itch.c @@ -308,7 +308,7 @@ dissect_nasdaq_itch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d offset = time_stamp (tvb, nasdaq_itch_tree, hf_nasdaq_itch_millisecond, offset, 8); } - proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message_type, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_message_type, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; if (version == 3) { @@ -325,20 +325,20 @@ dissect_nasdaq_itch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* d switch (nasdaq_itch_type) { case 'S': /* system event */ - proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_system_event, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_system_event, tvb, offset, 1, ENC_ASCII|ENC_NA); /*offset += 1;*/ break; case 'R': /* Stock Directory */ offset = stock(tvb, pinfo, nasdaq_itch_tree, offset); - proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_market_category, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_market_category, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; - proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_financial_status, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_financial_status, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lot_size, tvb, offset, 6, ENC_ASCII|ENC_NA); offset += 6; - proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lots_only, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(nasdaq_itch_tree, hf_nasdaq_itch_round_lots_only, tvb, offset, 1, ENC_ASCII|ENC_NA); /*offset += 1;*/ break; @@ -451,7 +451,7 @@ proto_register_nasdaq_itch(void) { &hf_nasdaq_itch_message_type, { "Message Type", "nasdaq-itch.message_type", - FT_UINT8, BASE_DEC, VALS(message_types_val), 0x0, + FT_CHAR, BASE_HEX, VALS(message_types_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_itch_second, @@ -466,17 +466,17 @@ proto_register_nasdaq_itch(void) { &hf_nasdaq_itch_system_event, { "System Event", "nasdaq-itch.system_event", - FT_UINT8, BASE_DEC, VALS(system_event_val), 0x0, + FT_CHAR, BASE_HEX, VALS(system_event_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_itch_market_category, { "Market Category", "nasdaq-itch.market_category", - FT_UINT8, BASE_DEC, VALS(market_category_val), 0x0, + FT_CHAR, BASE_HEX, VALS(market_category_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_itch_financial_status, { "Financial Status Indicator", "nasdaq-itch.financial_status", - FT_UINT8, BASE_DEC, VALS(financial_status_val), 0x0, + FT_CHAR, BASE_HEX, VALS(financial_status_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_itch_stock, @@ -491,7 +491,7 @@ proto_register_nasdaq_itch(void) { &hf_nasdaq_itch_round_lots_only, { "Round Lots Only", "nasdaq-itch.round_lots_only", - FT_UINT8, BASE_DEC, VALS(round_lots_only_val), 0x0, + FT_CHAR, BASE_HEX, VALS(round_lots_only_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_itch_trading_state, diff --git a/epan/dissectors/packet-nasdaq-soup.c b/epan/dissectors/packet-nasdaq-soup.c index 2645ab0d52..84b8260a29 100644 --- a/epan/dissectors/packet-nasdaq-soup.c +++ b/epan/dissectors/packet-nasdaq-soup.c @@ -84,7 +84,7 @@ dissect_nasdaq_soup_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent tvbuff_t *new_tvb = NULL; nasdaq_soup_type = tvb_get_guint8(tvb, offset); - proto_tree_add_item(tree, hf_nasdaq_soup_packet_type, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_nasdaq_soup_packet_type, tvb, offset, 1, ENC_ASCII|ENC_NA); offset++; switch (nasdaq_soup_type) { @@ -100,7 +100,7 @@ dissect_nasdaq_soup_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent offset += 10; break; case 'J': /* login reject */ - proto_tree_add_item(tree, hf_nasdaq_soup_reject_code, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_nasdaq_soup_reject_code, tvb, offset, 1, ENC_ASCII|ENC_NA); offset++; break; @@ -214,12 +214,12 @@ proto_register_nasdaq_soup(void) { &hf_nasdaq_soup_packet_type, { "Packet Type", "nasdaq-soup.packet_type", - FT_UINT8, BASE_DEC, VALS(message_types_val), 0x0, + FT_CHAR, BASE_HEX, VALS(message_types_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_soup_reject_code, { "Login Reject Code", "nasdaq-soup.reject_code", - FT_UINT8, BASE_DEC, VALS(reject_code_val), 0x0, + FT_CHAR, BASE_HEX, VALS(reject_code_val), 0x0, NULL, HFILL }}, { &hf_nasdaq_soup_message, diff --git a/epan/dissectors/packet-ouch.c b/epan/dissectors/packet-ouch.c index 5d6e1dc298..c2eb1641b6 100644 --- a/epan/dissectors/packet-ouch.c +++ b/epan/dissectors/packet-ouch.c @@ -350,201 +350,6 @@ ouch_tree_add_timestamp( proto_tree_add_string(tree, hf, tvb, offset, 8, buf); } -static void -packet_type_format( - gchar *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, pkt_type_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for BBO weight indicator code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_bbo_weight_indicator( - gchar *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, - ouch_bbo_weight_indicator_val, - "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for broken trade reason code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_broken_trade_reason( - gchar *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, - ouch_broken_trade_reason_val, - "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for buy/sell indicator code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_buy_sell_indicator( - gchar *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_buy_sell_indicator_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for cancel reason code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_cancel_reason( - gchar *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_cancel_reason_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the capacity code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_capacity( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_capacity_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the cross type code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_cross_type( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_cross_type_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the customer type code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_customer_type( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_customer_type_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the display code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_display( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_display_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the system event code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_event_code( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_event_code_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the ISO eligibility code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_iso_eligibility( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_iso_eligibility_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for the liquidity flag code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_liquidity_flag( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_liquidity_flag_val, "Unknown"), - value); -} - -/** BASE_CUSTOM formatter for order state code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_order_state( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_order_state_val, "Unknown"), - value); -} - /** BASE_CUSTOM formatter for prices * * OUCH prices are integers, with four implicit decimal places. So we @@ -563,23 +368,6 @@ format_price( } } -/** BASE_CUSTOM formatter for price correction reason code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_price_correction_reason( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, - ouch_price_correction_reason_val, - "Unknown"), - value); -} - /** BASE_CUSTOM formatter for reference price type code * * Displays the code value as a character, not its ASCII value, as @@ -597,21 +385,6 @@ format_reference_price_type( value); } -/** BASE_CUSTOM formatter for the reject reason code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_reject_reason( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, ouch_reject_reason_val, "Unknown"), - value); -} - /** BASE_CUSTOM formatter for the Time In Force (TIF) code * * There are three reserved values for the TIF: 0, 99998 and 99999. @@ -653,23 +426,6 @@ format_tif( } } -/** BASE_CUSTOM formatter for the trade correction reason code - * - * Displays the code value as a character, not its ASCII value, as - * would be done by BASE_DEC and friends. */ -static void -format_trade_correction_reason( - char *buf, - guint32 value) -{ - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", - val_to_str_const(value, - ouch_trade_correction_reason_val, - "Unknown"), - value); -} - static int dissect_ouch( @@ -729,7 +485,7 @@ dissect_ouch( /* Packet type (using the cooked value). */ proto_tree_add_item(ouch_tree, hf_ouch_packet_type, - tvb, offset, 1, ENC_NA); + tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; switch (pkt_type) { @@ -743,7 +499,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_buy_sell_indicator, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -779,19 +535,19 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_display, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_capacity, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_iso_eligible, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -803,14 +559,14 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_cross_type, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; if (reported_len >= 49) { /* Added in 4.1 */ proto_tree_add_item(ouch_tree, hf_ouch_customer_type, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; } break; @@ -866,7 +622,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_display, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -878,13 +634,13 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_capacity, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_iso_eligible, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -896,20 +652,20 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_cross_type, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_order_state, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; if (reported_len >= 66) { /* Added in 4.2 */ proto_tree_add_item(ouch_tree, hf_ouch_bbo_weight_indicator, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; } break; @@ -948,13 +704,13 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_display, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_iso_eligible, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1007,7 +763,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_event_code, tvb, offset, 1, - ENC_ASCII); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1062,7 +818,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_display, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1074,13 +830,13 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_capacity, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_iso_eligible, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1092,13 +848,13 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_cross_type, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, hf_ouch_order_state, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1137,7 +893,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_cancel_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1162,7 +918,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_cancel_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1180,7 +936,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_liquidity_flag, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1211,7 +967,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_liquidity_flag, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1242,7 +998,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_broken_trade_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1273,7 +1029,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_liquidity_flag, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1285,7 +1041,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_trade_correction_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1316,7 +1072,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_liquidity_flag, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1365,7 +1121,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_price_correction_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1384,7 +1140,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_reject_reason, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; break; @@ -1435,7 +1191,7 @@ dissect_ouch( proto_tree_add_item(ouch_tree, hf_ouch_display, tvb, offset, 1, - ENC_BIG_ENDIAN); + ENC_ASCII|ENC_NA); offset += 1; proto_tree_add_item(ouch_tree, @@ -1638,37 +1394,37 @@ proto_register_ouch(void) { &hf_ouch_bbo_weight_indicator, { "BBO Weight Indicator", "ouch.bbo_weight_indicator", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_bbo_weight_indicator), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_bbo_weight_indicator_val), 0x0, NULL, HFILL }}, { &hf_ouch_broken_trade_reason, { "Broken Trade Reason", "ouch.broken_trade_reason", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_broken_trade_reason), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_broken_trade_reason_val), 0x0, NULL, HFILL }}, { &hf_ouch_buy_sell_indicator, { "Buy/Sell Indicator", "ouch.buy_sell_indicator", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_buy_sell_indicator), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_buy_sell_indicator_val), 0x0, NULL, HFILL }}, { &hf_ouch_cancel_reason, { "Cancel Reason", "ouch.cancel_reason", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_cancel_reason), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_cancel_reason_val), 0x0, NULL, HFILL }}, { &hf_ouch_capacity, { "Capacity", "ouch.capacity", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_capacity), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_capacity_val), 0x0, NULL, HFILL }}, { &hf_ouch_cross_type, { "Cross Type", "ouch.cross_type", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_cross_type), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_cross_type_val), 0x0, NULL, HFILL }}, { &hf_ouch_customer_type, { "Customer Type", "ouch.customer_type", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_customer_type), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_customer_type_val), 0x0, NULL, HFILL }}, { &hf_ouch_decrement_shares, @@ -1678,12 +1434,12 @@ proto_register_ouch(void) { &hf_ouch_display, { "Display", "ouch.display", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_display), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_display_val), 0x0, NULL, HFILL }}, { &hf_ouch_event_code, { "Event Code", "ouch.event_code", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_event_code), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_event_code_val), 0x0, NULL, HFILL }}, { &hf_ouch_executed_shares, @@ -1708,12 +1464,12 @@ proto_register_ouch(void) { &hf_ouch_iso_eligible, { "Intermarket Sweep Eligibility", "ouch.iso_eligible", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_iso_eligibility), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_iso_eligibility_val), 0x0, NULL, HFILL }}, { &hf_ouch_liquidity_flag, { "Liquidity Flag", "ouch.liquidity_flag", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_liquidity_flag), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_liquidity_flag_val), 0x0, NULL, HFILL }}, { &hf_ouch_match_number, @@ -1743,7 +1499,7 @@ proto_register_ouch(void) { &hf_ouch_order_state, { "Order State", "ouch.order_state", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_order_state), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_order_state_val), 0x0, NULL, HFILL }}, { &hf_ouch_order_token, @@ -1753,7 +1509,7 @@ proto_register_ouch(void) { &hf_ouch_packet_type, { "Packet Type", "ouch.packet_type", - FT_UINT8, BASE_CUSTOM, CF_FUNC(packet_type_format), 0x0, + FT_CHAR, BASE_HEX, VALS(pkt_type_val), 0x0, NULL, HFILL }}, { &hf_ouch_previous_order_token, @@ -1768,7 +1524,7 @@ proto_register_ouch(void) { &hf_ouch_price_correction_reason, { "Price Correction Reason", "ouch.price_correction_reason", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_price_correction_reason), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_price_correction_reason_val), 0x0, NULL, HFILL }}, { &hf_ouch_quantity_prevented_from_trading, @@ -1789,7 +1545,7 @@ proto_register_ouch(void) { &hf_ouch_reject_reason, { "Reject Reason", "ouch.reject_reason", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_reject_reason), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_reject_reason_val), 0x0, NULL, HFILL }}, { &hf_ouch_replacement_order_token, @@ -1819,7 +1575,7 @@ proto_register_ouch(void) { &hf_ouch_trade_correction_reason, { "Trade Correction Reason", "ouch.trade_correction_reason", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_trade_correction_reason), 0x0, + FT_CHAR, BASE_HEX, VALS(ouch_trade_correction_reason_val), 0x0, NULL, HFILL }} }; diff --git a/epan/dissectors/packet-rtpproxy.c b/epan/dissectors/packet-rtpproxy.c index dafb30aa16..fb4002678f 100644 --- a/epan/dissectors/packet-rtpproxy.c +++ b/epan/dissectors/packet-rtpproxy.c @@ -342,7 +342,7 @@ rtpproxy_add_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_t rawstr = tvb_get_string_enc(wmem_packet_scope(), tvb, begin, realsize, ENC_ASCII); while(offset < realsize){ - ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command_parameter, tvb, begin + offset, 1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command_parameter, tvb, begin + offset, 1, ENC_ASCII | ENC_NA); offset++; /* Skip 1-byte parameter's type */ switch (g_ascii_tolower(tvb_get_guint8(tvb, begin+offset-1))) { @@ -414,7 +414,7 @@ rtpproxy_add_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_t break; case 'p': another_tree = proto_item_add_subtree(ti, ett_rtpproxy_command_parameters_proto); - proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_proto, tvb, begin+offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_proto, tvb, begin+offset, 1, ENC_ASCII | ENC_NA); offset++; break; case 't': @@ -427,7 +427,7 @@ rtpproxy_add_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_t break; case 'u': another_tree = proto_item_add_subtree(ti, ett_rtpproxy_command_parameters_acc); - proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_acc, tvb, begin+offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_acc, tvb, begin+offset, 1, ENC_ASCII | ENC_NA); offset++; break; default: @@ -655,7 +655,7 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data } /* All other commands */ - ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command, tvb, offset, 1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command, tvb, offset, 1, ENC_ASCII | ENC_NA); /* A specific case - handshake/ping */ if (tmp == 'v') @@ -964,8 +964,8 @@ proto_register_rtpproxy(void) { "Ok", "rtpproxy.ok", - FT_UINT8, - BASE_DEC, + FT_CHAR, + BASE_HEX, VALS(oktypenames), 0x0, NULL, @@ -1042,8 +1042,8 @@ proto_register_rtpproxy(void) { "Command", "rtpproxy.command", - FT_UINT8, - BASE_DEC, + FT_CHAR, + BASE_HEX, VALS(commandtypenames), 0x0, NULL, @@ -1068,8 +1068,8 @@ proto_register_rtpproxy(void) { "Parameter", "rtpproxy.command_parameter", - FT_UINT8, - BASE_DEC, + FT_CHAR, + BASE_HEX, VALS(paramtypenames), 0x0, NULL, @@ -1146,8 +1146,8 @@ proto_register_rtpproxy(void) { "RTP tramsission protocol", "rtpproxy.command_parameter_proto", - FT_UINT8, - BASE_DEC, + FT_CHAR, + BASE_HEX, VALS(prototypenames), 0x0, NULL, @@ -1172,8 +1172,8 @@ proto_register_rtpproxy(void) { "Accounting", "rtpproxy.command_parameter_acc", - FT_UINT8, - BASE_DEC, + FT_CHAR, + BASE_HEX, VALS(acctypenames), 0x0, NULL, diff --git a/epan/dissectors/packet-soupbintcp.c b/epan/dissectors/packet-soupbintcp.c index 2e94e3222b..3afb49af7c 100644 --- a/epan/dissectors/packet-soupbintcp.c +++ b/epan/dissectors/packet-soupbintcp.c @@ -133,45 +133,6 @@ static int hf_soupbintcp_req_seq_num = -1; static int hf_soupbintcp_reject_code = -1; -/** Format the display of the packet type code - * - * This function is called via BASE_CUSTOM, and displays the packet - * type code as a character like it is in the specification, rather - * than using BASE_DEC which shows it as an integer value. */ -static void -format_packet_type( - gchar *buf, - guint32 value) -{ - gchar* tmp_str; - - tmp_str = val_to_str_wmem(NULL, value, pkt_type_val, "Unknown packet"); - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", tmp_str, (char)(value & 0xff)); - wmem_free(NULL, tmp_str); -} - - -/** Format the display of the login rejection reason code - * - * This function is called via BASE_CUSTOM, and displays the login - * rejection reason code as a character like it is in the - * specification, rather than using BASE_DEC which show it as an - * integer value. */ -static void -format_reject_code( - gchar *buf, - guint32 value) -{ - gchar* tmp_str; - - tmp_str = val_to_str_wmem(NULL, value, reject_code_val, "Unknown reject code"); - g_snprintf(buf, ITEM_LABEL_LENGTH, - "%s (%c)", tmp_str, (char)(value & 0xff)); - wmem_free(NULL, tmp_str); -} - - /** Dissector for SoupBinTCP messages */ static void dissect_soupbintcp_common( @@ -317,7 +278,7 @@ dissect_soupbintcp_common( /* Type */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_packet_type, - tvb, offset, 1, ENC_BIG_ENDIAN); + tvb, offset, 1, ENC_ASCII|ENC_NA); offset += 1; switch (pkt_type) { @@ -343,7 +304,7 @@ dissect_soupbintcp_common( case 'J': /* Login Reject */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_reject_code, - tvb, offset, 1, ENC_BIG_ENDIAN); + tvb, offset, 1, ENC_ASCII|ENC_NA); break; case 'U': /* Unsequenced Data */ @@ -518,13 +479,13 @@ proto_register_soupbintcp(void) { &hf_soupbintcp_packet_type, { "Packet Type", "soupbintcp.packet_type", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_packet_type), 0x0, + FT_CHAR, BASE_HEX, VALS(pkt_type_val), 0x0, "Message type code", HFILL }}, { &hf_soupbintcp_reject_code, { "Login Reject Code", "soupbintcp.reject_code", - FT_UINT8, BASE_CUSTOM, CF_FUNC(format_reject_code), 0x0, + FT_CHAR, BASE_HEX, VALS(reject_code_val), 0x0, "Login reject reason code", HFILL }}, diff --git a/epan/dissectors/packet-telnet.c b/epan/dissectors/packet-telnet.c index 05ab652c97..8fb6d2a791 100644 --- a/epan/dissectors/packet-telnet.c +++ b/epan/dissectors/packet-telnet.c @@ -488,13 +488,13 @@ dissect_starttls_subopt(packet_info *pinfo _U_, const char *optname _U_, tvbuff_ } static const value_string telnet_outmark_subopt_cmd_vals[] = { - { 6, "ACK" }, - { 21, "NAK" }, - { 'D', "Default" }, - { 'T', "Top" }, - { 'B', "Bottom" }, - { 'L', "Left" }, - { 'R', "Right" }, + { '\x06', "ACK" }, + { '\x15', "NAK" }, + { 'D', "Default" }, + { 'T', "Top" }, + { 'B', "Bottom" }, + { 'L', "Left" }, + { 'R', "Right" }, { 0, NULL } }; @@ -505,7 +505,7 @@ dissect_outmark_subopt(packet_info *pinfo _U_, const char *optname _U_, tvbuff_t int gs_offset, datalen; while (len > 0) { - proto_tree_add_item(tree, hf_telnet_outmark_subopt_cmd, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(tree, hf_telnet_outmark_subopt_cmd, tvb, offset, 1, ENC_ASCII | ENC_NA); offset++; len--; @@ -1985,7 +1985,7 @@ proto_register_telnet(void) NULL, 0, NULL, HFILL } }, { &hf_telnet_outmark_subopt_cmd, - { "Command", "telnet.outmark_subopt.cmd", FT_UINT8, BASE_DEC, + { "Command", "telnet.outmark_subopt.cmd", FT_CHAR, BASE_HEX, VALS(telnet_outmark_subopt_cmd_vals), 0, NULL, HFILL } }, { &hf_telnet_outmark_subopt_banner, diff --git a/epan/dissectors/packet-ucp.c b/epan/dissectors/packet-ucp.c index 05185ff82b..40b8dd6575 100644 --- a/epan/dissectors/packet-ucp.c +++ b/epan/dissectors/packet-ucp.c @@ -2020,7 +2020,7 @@ proto_register_ucp(void) }, { &hf_ucp_hdr_O_R, { "Type", "ucp.hdr.O_R", - FT_UINT8, BASE_DEC, VALS(vals_hdr_O_R), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_hdr_O_R), 0x00, "Your basic 'is a request or response'.", HFILL } @@ -2083,14 +2083,14 @@ proto_register_ucp(void) }, { &hf_ucp_parm_BAS, { "BAS", "ucp.parm.BAS", - FT_UINT8, BASE_DEC, VALS(vals_parm_BAS), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_BAS), 0x00, "Barring status flag.", HFILL } }, { &hf_ucp_parm_LAR, { "LAR", "ucp.parm.LAR", - FT_UINT8, BASE_DEC, VALS(vals_parm_LAR), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_LAR), 0x00, "Leg. code for all calls flag.", HFILL } @@ -2104,7 +2104,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_L1R, { "L1R", "ucp.parm.L1R", - FT_UINT8, BASE_DEC, VALS(vals_parm_L1R), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_L1R), 0x00, "Leg. code for priority 1 flag.", HFILL } @@ -2118,7 +2118,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_L3R, { "L3R", "ucp.parm.L3R", - FT_UINT8, BASE_DEC, VALS(vals_parm_L3R), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_L3R), 0x00, "Leg. code for priority 3 flag.", HFILL } @@ -2132,28 +2132,28 @@ proto_register_ucp(void) }, { &hf_ucp_parm_LCR, { "LCR", "ucp.parm.LCR", - FT_UINT8, BASE_DEC, VALS(vals_parm_LCR), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_LCR), 0x00, "Leg. code for reverse charging flag.", HFILL } }, { &hf_ucp_parm_LUR, { "LUR", "ucp.parm.LUR", - FT_UINT8, BASE_DEC, VALS(vals_parm_LUR), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_LUR), 0x00, "Leg. code for urgent message flag.", HFILL } }, { &hf_ucp_parm_LRR, { "LRR", "ucp.parm.LRR", - FT_UINT8, BASE_DEC, VALS(vals_parm_LRR), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_LRR), 0x00, "Leg. code for repetition flag.", HFILL } }, { &hf_ucp_parm_RT, { "RT", "ucp.parm.RT", - FT_UINT8, BASE_DEC, VALS(vals_parm_RT), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_RT), 0x00, "Receiver type.", HFILL } @@ -2181,7 +2181,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_PNC, { "PNC", "ucp.parm.PNC", - FT_UINT8, BASE_DEC, VALS(vals_parm_PNC), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_PNC), 0x00, "Paging network controller.", HFILL } @@ -2244,7 +2244,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_RP, { "RP", "ucp.parm.RP", - FT_UINT8, BASE_DEC, VALS(vals_parm_RP), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_RP), 0x00, "Repetition requested.", HFILL } @@ -2272,7 +2272,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_UM, { "UM", "ucp.parm.UM", - FT_UINT8, BASE_DEC, VALS(vals_parm_UM), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_UM), 0x00, "Urgent message indicator.", HFILL } @@ -2286,7 +2286,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_RC, { "RC", "ucp.parm.RC", - FT_UINT8, BASE_DEC, VALS(vals_parm_RC), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_RC), 0x00, "Reverse charging request.", HFILL } @@ -2300,7 +2300,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_NRq, { "NRq", "ucp.parm.NRq", - FT_UINT8, BASE_DEC, VALS(vals_parm_NRq), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_NRq), 0x00, "Notification request.", HFILL } @@ -2314,7 +2314,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_A_D, { "A_D", "ucp.parm.A_D", - FT_UINT8, BASE_DEC, VALS(vals_parm_A_D), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_A_D), 0x00, "Add to/delete from fixed subscriber address list record.", HFILL } @@ -2342,7 +2342,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_R_T, { "R_T", "ucp.parm.R_T", - FT_UINT8, BASE_DEC, VALS(vals_parm_R_T), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_R_T), 0x00, "Message number.", HFILL } @@ -2356,7 +2356,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_NT, { "NT", "ucp.parm.NT", - FT_UINT8, BASE_DEC, VALS(vals_parm_NT), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_NT), 0x00, "Notification type.", HFILL } @@ -2370,14 +2370,14 @@ proto_register_ucp(void) }, { &hf_ucp_parm_REQ_OT, { "REQ_OT", "ucp.parm.REQ_OT", - FT_UINT8, BASE_DEC, VALS(vals_parm_REQ_OT), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_REQ_OT), 0x00, "UCP release number supported/accepted.", HFILL } }, { &hf_ucp_parm_SSTAT, { "SSTAT", "ucp.parm.SSTAT", - FT_UINT8, BASE_DEC, VALS(vals_parm_SSTAT), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_SSTAT), 0x00, "Supplementary services for which status is requested.", HFILL } @@ -2405,7 +2405,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_LRq, { "LRq", "ucp.parm.LRq", - FT_UINT8, BASE_DEC, VALS(vals_parm_LRq), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_LRq), 0x00, "Last resort address request.", HFILL } @@ -2426,7 +2426,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_DD, { "DD", "ucp.parm.DD", - FT_UINT8, BASE_DEC, VALS(vals_parm_DD), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_DD), 0x00, "Deferred delivery requested.", HFILL } @@ -2482,7 +2482,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_Dst, { "Dst", "ucp.parm.Dst", - FT_UINT8, BASE_DEC, VALS(vals_parm_Dst), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_Dst), 0x00, "Delivery status.", HFILL } @@ -2503,7 +2503,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_MT, { "MT", "ucp.parm.MT", - FT_UINT8, BASE_DEC, VALS(vals_parm_MT), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_MT), 0x00, "Message type.", HFILL } @@ -2531,21 +2531,21 @@ proto_register_ucp(void) }, { &hf_ucp_parm_DCs, { "DCs", "ucp.parm.DCs", - FT_UINT8, BASE_DEC, VALS(vals_parm_DCs), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_DCs), 0x00, "Data coding scheme (deprecated).", HFILL } }, { &hf_ucp_parm_MCLs, { "MCLs", "ucp.parm.MCLs", - FT_UINT8, BASE_DEC, VALS(vals_parm_MCLs), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_MCLs), 0x00, "Message class.", HFILL } }, { &hf_ucp_parm_RPI, { "RPI", "ucp.parm.RPI", - FT_UINT8, BASE_DEC, VALS(vals_parm_RPI), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_RPI), 0x00, "Reply path.", HFILL } @@ -2601,28 +2601,28 @@ proto_register_ucp(void) }, { &hf_ucp_parm_OTON, { "OTON", "ucp.parm.OTON", - FT_UINT8, BASE_DEC, VALS(vals_parm_OTON), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_OTON), 0x00, "Originator type of number.", HFILL } }, { &hf_ucp_parm_ONPI, { "ONPI", "ucp.parm.ONPI", - FT_UINT8, BASE_DEC, VALS(vals_parm_ONPI), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_ONPI), 0x00, "Originator numbering plan id.", HFILL } }, { &hf_ucp_parm_STYP0, { "STYP0", "ucp.parm.STYP0", - FT_UINT8, BASE_DEC, VALS(vals_parm_STYP0), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_STYP0), 0x00, "Subtype of operation.", HFILL } }, { &hf_ucp_parm_STYP1, { "STYP1", "ucp.parm.STYP1", - FT_UINT8, BASE_DEC, VALS(vals_parm_STYP1), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_STYP1), 0x00, "Subtype of operation.", HFILL } @@ -2692,7 +2692,7 @@ proto_register_ucp(void) }, { &hf_ucp_parm_ACK, { "(N)Ack", "ucp.parm.ACK", - FT_UINT8, BASE_DEC, VALS(vals_parm_ACK), 0x00, + FT_CHAR, BASE_HEX, VALS(vals_parm_ACK), 0x00, "Positive or negative acknowledge of the operation.", HFILL } diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c index 7146da0b18..dd41021226 100644 --- a/epan/dissectors/packet-usb.c +++ b/epan/dissectors/packet-usb.c @@ -3396,9 +3396,7 @@ dissect_linux_usb_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t /* show the urb type of this URB as string and as a character */ urb_type = tvb_get_guint8(tvb, 8); usb_conv_info->is_request = (urb_type==URB_SUBMIT); - proto_tree_add_uint_format_value(tree, hf_usb_linux_urb_type, tvb, 8, 1, - urb_type, "%s ('%c')", val_to_str(urb_type, usb_linux_urb_type_vals, "Unknown %d"), - g_ascii_isprint(urb_type) ? urb_type : '.'); + proto_tree_add_uint(tree, hf_usb_linux_urb_type, tvb, 8, 1, urb_type); proto_tree_add_item(tree, hf_usb_linux_transfer_type, tvb, 9, 1, ENC_LITTLE_ENDIAN); transfer_type = tvb_get_guint8(tvb, 9); @@ -4593,7 +4591,7 @@ proto_register_usb(void) { &hf_usb_linux_urb_type, { "URB type", "usb.urb_type", - FT_UINT8, BASE_DEC, VALS(usb_linux_urb_type_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(usb_linux_urb_type_vals), 0x0, NULL, HFILL }}, { &hf_usb_linux_transfer_type, diff --git a/epan/dissectors/x11-fields b/epan/dissectors/x11-fields index 5b4d6b829e..6b74142e18 100644 --- a/epan/dissectors/x11-fields +++ b/epan/dissectors/x11-fields @@ -74,7 +74,7 @@ border-pixel UINT32 HEX border-pixmap UINT32 HEX VALS border-width UINT16 DEC button UINT8 DEC VALS -byte-order UINT8 HEX VALS +byte-order CHAR HEX VALS childwindow UINT32 HEX cap-style UINT8 DEC VALS @@ -263,7 +263,7 @@ grab-status UINT8 DEC VALS grab-window UINT32 HEX graphics-exposures BOOLEAN NONE height UINT16 DEC -image-byte-order UINT8 HEX VALS +image-byte-order CHAR HEX VALS initial-connection NONE NONE undecoded image-format UINT8 DEC VALS image-pixmap-format UINT8 DEC VALS diff --git a/epan/dissectors/x11-glx-render-enum.h b/epan/dissectors/x11-glx-render-enum.h index 29ebb7e660..1b6ff9a22b 100644 --- a/epan/dissectors/x11-glx-render-enum.h +++ b/epan/dissectors/x11-glx-render-enum.h @@ -1,6 +1,6 @@ /* Do not modify this file. */ /* It was automatically generated by ../../tools/process-x11-xcb.pl - using mesa version 12.0-branchpoint-413-g44e0c0e */ + using mesa version 12.0-branchpoint-2878-g15804c4 */ /* * Copyright 2008, 2009, 2013, 2014 Open Text Corporation * @@ -1330,6 +1330,27 @@ static const value_string mesa_enum[] = { /* OpenGL extension ARB_cull_distance */ { 0x82F9, "MAX_CULL_DISTANCES" }, { 0x82FA, "MAX_COMBINED_CLIP_AND_CULL_DISTANCES" }, +/* OpenGL extension KHR_blend_equation_advanced */ + { 0x9285, "BLEND_ADVANCED_COHERENT_KHR" }, + { 0x9294, "MULTIPLY_KHR" }, + { 0x9295, "SCREEN_KHR" }, + { 0x9296, "OVERLAY_KHR" }, + { 0x9297, "DARKEN_KHR" }, + { 0x9298, "LIGHTEN_KHR" }, + { 0x9299, "COLORDODGE_KHR" }, + { 0x929A, "COLORBURN_KHR" }, + { 0x929B, "HARDLIGHT_KHR" }, + { 0x929C, "SOFTLIGHT_KHR" }, + { 0x929E, "DIFFERENCE_KHR" }, + { 0x92A0, "EXCLUSION_KHR" }, + { 0x92AD, "HSL_HUE_KHR" }, + { 0x92AE, "HSL_SATURATION_KHR" }, + { 0x92AF, "HSL_COLOR_KHR" }, + { 0x92B0, "HSL_LUMINOSITY_KHR" }, +/* OpenGL extension ARB_ES3_2_compatibility */ + { 0x92BE, "PRIMITIVE_BOUNDING_BOX_ARB" }, + { 0x9381, "MULTISAMPLE_LINE_WIDTH_RANGE_ARB" }, + { 0x9382, "MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB" }, /* OpenGL extension GL_EXT_blend_color */ { 0x8001, "CONSTANT_COLOR_EXT" }, { 0x8002, "ONE_MINUS_CONSTANT_COLOR_EXT" }, diff --git a/epan/dissectors/x11-register-info.h b/epan/dissectors/x11-register-info.h index 9ccb81ca7e..171c6e081f 100644 --- a/epan/dissectors/x11-register-info.h +++ b/epan/dissectors/x11-register-info.h @@ -71,7 +71,7 @@ { &hf_x11_border_pixmap, { "border-pixmap", "x11.border-pixmap", FT_UINT32, BASE_HEX, VALS(border_pixmap_vals), 0, NULL, HFILL }}, { &hf_x11_border_width, { "border-width", "x11.border-width", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, { &hf_x11_button, { "button", "x11.button", FT_UINT8, BASE_DEC, VALS(button_vals), 0, NULL, HFILL }}, -{ &hf_x11_byte_order, { "byte-order", "x11.byte-order", FT_UINT8, BASE_HEX, VALS(byte_order_vals), 0, NULL, HFILL }}, +{ &hf_x11_byte_order, { "byte-order", "x11.byte-order", FT_CHAR, BASE_HEX, VALS(byte_order_vals), 0, NULL, HFILL }}, { &hf_x11_childwindow, { "childwindow", "x11.childwindow", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, { &hf_x11_cap_style, { "cap-style", "x11.cap-style", FT_UINT8, BASE_DEC, VALS(cap_style_vals), 0, NULL, HFILL }}, { &hf_x11_change_host_mode, { "change-host-mode", "x11.change-host-mode", FT_UINT8, BASE_DEC, VALS(insert_delete_vals), 0, NULL, HFILL }}, @@ -246,7 +246,7 @@ { &hf_x11_grab_window, { "grab-window", "x11.grab-window", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, { &hf_x11_graphics_exposures, { "graphics-exposures", "x11.graphics-exposures", FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }}, { &hf_x11_height, { "height", "x11.height", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, -{ &hf_x11_image_byte_order, { "image-byte-order", "x11.image-byte-order", FT_UINT8, BASE_HEX, VALS(image_byte_order_vals), 0, NULL, HFILL }}, +{ &hf_x11_image_byte_order, { "image-byte-order", "x11.image-byte-order", FT_CHAR, BASE_HEX, VALS(image_byte_order_vals), 0, NULL, HFILL }}, { &hf_x11_initial_connection, { "initial-connection", "x11.initial-connection", FT_NONE, BASE_NONE, NULL, 0, "undecoded", HFILL }}, { &hf_x11_image_format, { "image-format", "x11.image-format", FT_UINT8, BASE_DEC, VALS(image_format_vals), 0, NULL, HFILL }}, { &hf_x11_image_pixmap_format, { "image-pixmap-format", "x11.image-pixmap-format", FT_UINT8, BASE_DEC, VALS(image_pixmap_format_vals), 0, NULL, HFILL }}, diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index c7aae0403b..d666560915 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -61,6 +61,144 @@ get_sinteger(fvalue_t *fv) } +static gboolean +parse_charconst(const char *s, unsigned long *valuep, gchar **err_msg) +{ + const char *cp; + unsigned long value; + + cp = s + 1; /* skip the leading ' */ + if (*cp == '\\') { + /* + * Escape. + */ + cp++; + switch (*cp) { + + case '\0': + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + + case 'a': + value = '\a'; + break; + + case 'b': + value = '\b'; + break; + + case 'f': + value = '\f'; + break; + + case 'n': + value = '\n'; + break; + + case 'r': + value = '\r'; + break; + + case 't': + value = '\t'; + break; + + case 'v': + value = '\v'; + break; + + case '\'': + value = '\''; + break; + + case '\\': + value = '\\'; + break; + + case '"': + value = '"'; + break; + + case 'x': + cp++; + if (*cp >= '0' && *cp <= '9') + value = *cp - '0'; + else if (*cp >= 'A' && *cp <= 'F') + value = 10 + (*cp - 'A'); + else if (*cp >= 'a' && *cp <= 'f') + value = 10 + (*cp - 'a'); + else { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + } + cp++; + if (*cp != '\'') { + value <<= 4; + if (*cp >= '0' && *cp <= '9') + value |= *cp - '0'; + else if (*cp >= 'A' && *cp <= 'F') + value |= 10 + (*cp - 'A'); + else if (*cp >= 'a' && *cp <= 'f') + value |= 10 + (*cp - 'a'); + else { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + } + } + break; + + default: + if (*cp >= '0' && *cp <= '7') + value = *cp - '0'; + else { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + } + cp++; + if (*cp != '\'') { + value <<= 3; + if (*cp >= '0' && *cp <= '7') + value |= *cp - '0'; + else { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + } + cp++; + if (*cp != '\'') { + value <<= 3; + if (*cp >= '0' && *cp <= '7') + value |= *cp - '0'; + else { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" isn't a valid character constant.", s); + return FALSE; + } + } + } + if (value > 0xFF) { + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" is too large to be a valid character constant.", s); + return FALSE; + } + } + } else { + value = *cp; + cp++; + if (!g_ascii_isprint(value)) { + if (err_msg != NULL) + *err_msg = g_strdup_printf("Non-printable character '\\x%02lx' in character constant.", value); + return FALSE; + } + } + *valuep = value; + return TRUE; +} + static gboolean uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg, guint32 max) @@ -68,40 +206,51 @@ uint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_ unsigned long value; char *endptr; - if (strchr (s, '-') && strtol(s, NULL, 0) < 0) { + if (s[0] == '\'') { /* - * Probably a negative integer, but will be - * "converted in the obvious manner" by strtoul(). + * Represented as a C-style character constant. */ - if (err_msg != NULL) - *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum 0.", s); - return FALSE; - } - - errno = 0; - value = strtoul(s, &endptr, 0); - - if (errno == EINVAL || endptr == s || *endptr != '\0') { - /* This isn't a valid number. */ - if (err_msg != NULL) - *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s); - return FALSE; - } - if (errno == ERANGE) { - if (err_msg != NULL) { - if (value == ULONG_MAX) { - *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", - s); - } - else { - /* - * XXX - can "strtoul()" set errno to - * ERANGE without returning ULONG_MAX? - */ - *err_msg = g_strdup_printf("\"%s\" is not an integer.", s); - } + if (!parse_charconst(s, &value, err_msg)) + return FALSE; + } else { + /* + * Try to parse it as a number. + */ + if (strchr (s, '-') && strtol(s, NULL, 0) < 0) { + /* + * Probably a negative integer, but will be + * "converted in the obvious manner" by strtoul(). + */ + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" too small for this field, minimum 0.", s); + return FALSE; + } + + errno = 0; + value = strtoul(s, &endptr, 0); + + if (errno == EINVAL || endptr == s || *endptr != '\0') { + /* This isn't a valid number. */ + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s); + return FALSE; + } + if (errno == ERANGE) { + if (err_msg != NULL) { + if (value == ULONG_MAX) { + *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", + s); + } + else { + /* + * XXX - can "strtoul()" set errno to + * ERANGE without returning ULONG_MAX? + */ + *err_msg = g_strdup_printf("\"%s\" is not an integer.", s); + } + } + return FALSE; } - return FALSE; } if (value > max) { @@ -145,42 +294,54 @@ sint_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_ long value; char *endptr; - if (!strchr (s, '-') && strtoul(s, NULL, 0) > G_MAXINT32) { + if (s[0] == '\'') { /* - * Probably a positive integer > G_MAXINT32, but will be - * "converted in the obvious manner" by strtol(). + * Represented as a C-style character constant. */ - if (err_msg != NULL) - *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s); - return FALSE; - } - - errno = 0; - value = strtol(s, &endptr, 0); - - if (errno == EINVAL || endptr == s || *endptr != '\0') { - /* This isn't a valid number. */ - if (err_msg != NULL) - *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s); - return FALSE; - } - if (errno == ERANGE) { - if (err_msg != NULL) { - if (value == LONG_MAX) { + if (!parse_charconst(s, &value, err_msg)) + return FALSE; + } else { + /* + * Try to parse it as a number. + */ + if (!strchr (s, '-') && strtoul(s, NULL, 0) > G_MAXINT32) { + /* + * Probably a positive integer > G_MAXINT32, but + * will be "converted in the obvious manner" by + * strtol(). + */ + if (err_msg != NULL) *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s); - } - else if (value == LONG_MIN) { - *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s); - } - else { - /* - * XXX - can "strtol()" set errno to - * ERANGE without returning ULONG_MAX? - */ - *err_msg = g_strdup_printf("\"%s\" is not an integer.", s); - } + return FALSE; + } + + errno = 0; + value = strtol(s, &endptr, 0); + + if (errno == EINVAL || endptr == s || *endptr != '\0') { + /* This isn't a valid number. */ + if (err_msg != NULL) + *err_msg = g_strdup_printf("\"%s\" is not a valid number.", s); + return FALSE; + } + if (errno == ERANGE) { + if (err_msg != NULL) { + if (value == LONG_MAX) { + *err_msg = g_strdup_printf("\"%s\" causes an integer overflow.", s); + } + else if (value == LONG_MIN) { + *err_msg = g_strdup_printf("\"%s\" causes an integer underflow.", s); + } + else { + /* + * XXX - can "strtol()" set errno to + * ERANGE without returning ULONG_MAX? + */ + *err_msg = g_strdup_printf("\"%s\" is not an integer.", s); + } + } + return FALSE; } - return FALSE; } if (value > max) { @@ -249,6 +410,12 @@ uinteger_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_) return 10; /* enough for 2^32-1, in decimal or 0xXXXXXXXX */ } +static int +char_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_, int field_display _U_) +{ + return 7; /* enough for '\OOO' or '\xXX' */ +} + static void uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, unsigned int size) { @@ -267,6 +434,73 @@ uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, } } +static void +char_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display, char *buf, unsigned int size _U_) +{ + /* + * The longest possible strings are "'\OOO'" and "'\xXX'", which + * take 7 bytes, including the terminating '\0'. + */ + *buf++ = '\''; + if (g_ascii_isprint(fv->value.uinteger)) { + /* This perfectly fits into 4 or 5 bytes. */ + if (fv->value.uinteger == '\\' || fv->value.uinteger == '\'') + *buf++ = '\\'; + *buf++ = (char)fv->value.uinteger; + } else { + *buf++ = '\\'; + switch (fv->value.uinteger) { + + case '\0': + *buf++ = '0'; + break; + + case '\a': + *buf++ = 'a'; + break; + + case '\b': + *buf++ = 'b'; + break; + + case '\f': + *buf++ = 'f'; + break; + + case '\n': + *buf++ = 'n'; + break; + + case '\r': + *buf++ = 'r'; + break; + + case '\t': + *buf++ = 't'; + break; + + case '\v': + *buf++ = 'v'; + break; + + default: + if (field_display == BASE_HEX) { + *buf++ = 'x'; + buf = guint8_to_hex(buf, fv->value.uinteger); + } + else + { + *buf++ = ((fv->value.uinteger >> 6) & 0x7) + '0'; + *buf++ = ((fv->value.uinteger >> 3) & 0x7) + '0'; + *buf++ = ((fv->value.uinteger >> 0) & 0x7) + '0'; + } + break; + } + } + *buf++ = '\''; + *buf++ = '\0'; +} + static gboolean ipxnet_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg) { @@ -780,7 +1014,50 @@ eui64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, int field_display _U_, char *buf void ftype_register_integers(void) { + static ftype_t char_type = { + FT_CHAR, /* ftype */ + "FT_CHAR", /* name */ + "Character, 1 byte", /* pretty name */ + 1, /* wire_size */ + int_fvalue_new, /* new_value */ + NULL, /* free_value */ + uint8_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ + char_to_repr, /* val_to_string_repr */ + char_repr_len, /* len_string_repr */ + NULL, /* set_value_byte_array */ + NULL, /* set_value_bytes */ + NULL, /* set_value_guid */ + NULL, /* set_value_time */ + NULL, /* set_value_string */ + NULL, /* set_value_protocol */ + set_uinteger, /* set_value_uinteger */ + NULL, /* set_value_sinteger */ + NULL, /* set_value_uinteger64 */ + NULL, /* set_value_sinteger64 */ + NULL, /* set_value_floating */ + + NULL, /* get_value */ + get_uinteger, /* get_value_uinteger */ + NULL, /* get_value_sinteger */ + NULL, /* get_value_uinteger64 */ + NULL, /* get_value_sinteger64 */ + NULL, /* get_value_floating */ + + cmp_eq, + cmp_ne, + u_cmp_gt, + u_cmp_ge, + u_cmp_lt, + u_cmp_le, + cmp_bitwise_and, + NULL, /* cmp_contains */ + NULL, /* cmp_matches */ + + NULL, /* len */ + NULL, /* slice */ + }; static ftype_t uint8_type = { FT_UINT8, /* ftype */ "FT_UINT8", /* name */ @@ -799,14 +1076,14 @@ ftype_register_integers(void) NULL, /* set_value_time */ NULL, /* set_value_string */ NULL, /* set_value_protocol */ - set_uinteger, /* set_value_uinteger */ + set_uinteger, /* set_value_uinteger */ NULL, /* set_value_sinteger */ NULL, /* set_value_uinteger64 */ NULL, /* set_value_sinteger64 */ NULL, /* set_value_floating */ NULL, /* get_value */ - get_uinteger, /* get_value_uinteger */ + get_uinteger, /* get_value_uinteger */ NULL, /* get_value_sinteger */ NULL, /* get_value_uinteger64 */ NULL, /* get_value_sinteger64 */ @@ -1665,6 +1942,7 @@ ftype_register_integers(void) NULL, }; + ftype_register(FT_CHAR, &char_type); ftype_register(FT_UINT8, &uint8_type); ftype_register(FT_UINT16, &uint16_type); ftype_register(FT_UINT24, &uint24_type); diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index 99153c8fa6..5a44553043 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -37,6 +37,7 @@ enum ftenum { FT_NONE, /* used for text labels with no value */ FT_PROTOCOL, FT_BOOLEAN, /* TRUE and FALSE come from */ + FT_CHAR, /* 1-octet character as 0-255 */ FT_UINT8, FT_UINT16, FT_UINT24, /* really a UINT32, but displayed as 6 hex-digits if FD_HEX*/ @@ -83,7 +84,7 @@ enum ftenum { }; #define IS_FT_INT(ft) ((ft)==FT_INT8||(ft)==FT_INT16||(ft)==FT_INT24||(ft)==FT_INT32||(ft)==FT_INT40||(ft)==FT_INT48||(ft)==FT_INT56||(ft)==FT_INT64) -#define IS_FT_UINT(ft) ((ft)==FT_UINT8||(ft)==FT_UINT16||(ft)==FT_UINT24||(ft)==FT_UINT32||(ft)==FT_UINT40||(ft)==FT_UINT48||(ft)==FT_UINT56||(ft)==FT_UINT64||(ft)==FT_FRAMENUM) +#define IS_FT_UINT(ft) ((ft)==FT_CHAR||(ft)==FT_UINT8||(ft)==FT_UINT16||(ft)==FT_UINT24||(ft)==FT_UINT32||(ft)==FT_UINT40||(ft)==FT_UINT48||(ft)==FT_UINT56||(ft)==FT_UINT64||(ft)==FT_FRAMENUM) #define IS_FT_TIME(ft) ((ft)==FT_ABSOLUTE_TIME||(ft)==FT_RELATIVE_TIME) #define IS_FT_STRING(ft) ((ft)==FT_STRING||(ft)==FT_STRINGZ||(ft)==FT_STRINGZPAD) diff --git a/epan/proto.c b/epan/proto.c index 42689a36ac..fd673faf05 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -178,17 +178,22 @@ static void label_mark_truncated(char *label_str, gsize name_pos); #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0) static void fill_label_boolean(field_info *fi, gchar *label_str); +static void fill_label_bitfield_char(field_info *fi, gchar *label_str); static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed); static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed); +static void fill_label_char(field_info *fi, gchar *label_str); static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed); static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed); +static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value); static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value); static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value); +static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value); static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value); static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value); static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value); static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value); +static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value); static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value); static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value); @@ -1889,6 +1894,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, get_uint64_value(tree, tvb, start, length, encoding)); break; + case FT_CHAR: /* XXX - make these just FT_UINT? */ case FT_UINT8: case FT_UINT16: @@ -2344,6 +2350,7 @@ proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!"); switch (hfinfo->type){ + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -2364,6 +2371,7 @@ proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, REPORT_DISSECTOR_BUG("wrong encoding"); } /* I believe it's ok if this is called with a NULL tree */ + /* XXX - modify if we ever support EBCDIC FT_CHAR */ value = get_uint_value(tree, tvb, start, length, encoding); if (retval) @@ -3924,7 +3932,7 @@ proto_tree_set_double(field_info *fi, double value) fvalue_set_floating(&fi->value, value); } -/* Add FT_UINT{8,16,24,32} to a proto_tree */ +/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */ proto_item * proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length, guint32 value) @@ -3937,6 +3945,7 @@ proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo); switch (hfinfo->type) { + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -4598,6 +4607,7 @@ get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, break; case FT_BOOLEAN: + case FT_CHAR: /* XXX - make these just FT_UINT? */ case FT_UINT8: case FT_UINT16: @@ -5022,6 +5032,44 @@ proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence, number64 ? "1" : "0", size-offset_e); break; + case FT_CHAR: + hf_str_val = NULL; + number = fvalue_get_uinteger(&finfo->value); + + if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) { + gchar tmp[ITEM_LABEL_LENGTH]; + custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings; + + DISSECTOR_ASSERT(fmtfunc); + fmtfunc(tmp, number); + + offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r); + + } else if (hfinfo->strings) { + number_out = hf_str_val = hf_try_val_to_str(number, hfinfo); + + if (!number_out) + number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number); + + offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r); + + } else { + number_out = hfinfo_char_value_format(hfinfo, number_buf, number); + + offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r); + } + + if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) { + g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val); + } else { + number_out = hfinfo_char_value_format(hfinfo, number_buf, number); + + g_strlcpy(expr+offset_e, number_out, size-offset_e); + } + + offset_e = (int)strlen(expr); + break; + /* XXX - make these just FT_NUMBER? */ case FT_INT8: case FT_INT16: @@ -5240,6 +5288,7 @@ proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence, switch (hfinfo->type) { case FT_BOOLEAN: + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -6412,6 +6461,7 @@ tmp_fld_check_assert(header_field_info *hfinfo) * true_false_strings or a protocol_t struct */ if (hfinfo->strings != NULL && !( + (hfinfo->type == FT_CHAR) || (hfinfo->type == FT_UINT8) || (hfinfo->type == FT_UINT16) || (hfinfo->type == FT_UINT24) || @@ -6446,6 +6496,7 @@ tmp_fld_check_assert(header_field_info *hfinfo) !(hfinfo->display & BASE_RANGE_STRING) && !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) && ( + (hfinfo->type == FT_CHAR) || (hfinfo->type == FT_UINT8) || (hfinfo->type == FT_UINT16) || (hfinfo->type == FT_UINT24) || @@ -6491,6 +6542,38 @@ tmp_fld_check_assert(header_field_info *hfinfo) switch (hfinfo->type) { + case FT_CHAR: + /* Require the char type to have BASE_HEX, BASE_OCT, + * BASE_CUSTOM, or BASE_NONE as its base. + * + * If the display value is BASE_NONE and there is a + * strings conversion then the dissector writer is + * telling us that the field's numerical value is + * meaningless; we'll avoid showing the value to the + * user. + */ + switch (hfinfo->display & FIELD_DISPLAY_E_MASK) { + case BASE_HEX: + case BASE_OCT: + case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */ + break; + case BASE_NONE: + if (hfinfo->strings == NULL) + g_error("Field '%s' (%s) is an integral value (%s)" + " but is being displayed as BASE_NONE but" + " without a strings conversion", + hfinfo->name, hfinfo->abbrev, + ftype_name(hfinfo->type)); + break; + default: + tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)"); + g_error("Field '%s' (%s) is a character value (%s)" + " but is being displayed as %s\n", + hfinfo->name, hfinfo->abbrev, + ftype_name(hfinfo->type), tmp_str); + wmem_free(NULL, tmp_str); + } + break; case FT_INT8: case FT_INT16: case FT_INT24: @@ -6716,6 +6799,7 @@ _ftype_common(enum ftenum type) case FT_INT32: return FT_INT32; + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -7097,6 +7181,14 @@ proto_item_fill_label(field_info *fi, gchar *label_str) } break; + case FT_CHAR: + if (hfinfo->bitmask) { + fill_label_bitfield_char(fi, label_str); + } else { + fill_label_char(fi, label_str); + } + break; + /* Four types of integers to take care of: * Bitfield, with val_string * Bitfield, w/o val_string @@ -7427,6 +7519,60 @@ hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const return (str) ? str : unknown_str; } +/* Fills data for bitfield chars with val_strings */ +static void +fill_label_bitfield_char(field_info *fi, gchar *label_str) +{ + char *p; + int bitfield_byte_length, bitwidth; + guint32 unshifted_value; + guint32 value; + + char buf[32]; + const char *out; + + header_field_info *hfinfo = fi->hfinfo; + + /* Figure out the bit width */ + bitwidth = hfinfo_container_bitwidth(hfinfo); + + /* Un-shift bits */ + value = fvalue_get_uinteger(&fi->value); + + unshifted_value = value; + if (hfinfo->bitmask) { + unshifted_value <<= hfinfo_bitshift(hfinfo); + } + + /* Create the bitfield first */ + p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth); + bitfield_byte_length = (int) (p - label_str); + + /* Fill in the textual info using stored (shifted) value */ + if (hfinfo->display == BASE_CUSTOM) { + gchar tmp[ITEM_LABEL_LENGTH]; + const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings; + + DISSECTOR_ASSERT(fmtfunc); + fmtfunc(tmp, value); + label_fill(label_str, bitfield_byte_length, hfinfo, tmp); + } + else if (hfinfo->strings) { + const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown"); + + out = hfinfo_char_vals_format(hfinfo, buf, value); + if (out == NULL) /* BASE_NONE so don't put integer in descr */ + label_fill(label_str, bitfield_byte_length, hfinfo, val_str); + else + label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out); + } + else { + out = hfinfo_char_value_format(hfinfo, buf, value); + + label_fill(label_str, bitfield_byte_length, hfinfo, out); + } +} + /* Fills data for bitfield ints with val_strings */ static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed) @@ -7540,6 +7686,39 @@ fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed) } } +static void +fill_label_char(field_info *fi, gchar *label_str) +{ + header_field_info *hfinfo = fi->hfinfo; + guint32 value; + + char buf[32]; + const char *out; + + value = fvalue_get_uinteger(&fi->value); + + /* Fill in the textual info */ + if (hfinfo->display == BASE_CUSTOM) { + gchar tmp[ITEM_LABEL_LENGTH]; + const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings; + + DISSECTOR_ASSERT(fmtfunc); + fmtfunc(tmp, value); + label_fill(label_str, 0, hfinfo, tmp); + } + else if (hfinfo->strings) { + const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown"); + + out = hfinfo_char_vals_format(hfinfo, buf, value); + label_fill_descr(label_str, 0, hfinfo, val_str, out); + } + else { + out = hfinfo_char_value_format(hfinfo, buf, value); + + label_fill(label_str, 0, hfinfo, out); + } +} + static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed) { @@ -7563,7 +7742,12 @@ fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed) fmtfunc(tmp, value); label_fill(label_str, 0, hfinfo, tmp); } - else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { /* Add fill_label_framenum? */ + else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { + /* + * It makes no sense to have a value-string table for a + * frame-number field - they're just integers giving + * the ordinal frame number. + */ const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown"); out = hfinfo_number_vals_format(hfinfo, buf, value); @@ -7648,6 +7832,7 @@ hfinfo_type_bitwidth(enum ftenum type) int bitwidth = 0; switch (type) { + case FT_CHAR: case FT_UINT8: case FT_INT8: bitwidth = 8; @@ -7721,6 +7906,94 @@ hfinfo_hex_digits(const header_field_info *hfinfo) return (bitwidth + 3) / 4; } +static const char * +hfinfo_char_value_format_display(int display, char buf[7], guint32 value) +{ + char *ptr = &buf[6]; + static const gchar hex_digits[16] = + { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + *ptr = '\0'; + *(--ptr) = '\''; + /* Properly format value */ + if (g_ascii_isprint(value)) { + /* + * Printable, so just show the character, and, if it needs + * to be escaped, escape it. + */ + *(--ptr) = value; + if (value == '\\' || value == '\'') + *(--ptr) = '\\'; + } else { + /* + * Non-printable; show it as an escape sequence. + */ + switch (value) { + + case '\0': + /* + * Show a NUL with only one digit. + */ + *(--ptr) = '0'; + break; + + case '\a': + *(--ptr) = 'a'; + break; + + case '\b': + *(--ptr) = 'b'; + break; + + case '\f': + *(--ptr) = 'f'; + break; + + case '\n': + *(--ptr) = 'n'; + break; + + case '\r': + *(--ptr) = 'r'; + break; + + case '\t': + *(--ptr) = 't'; + break; + + case '\v': + *(--ptr) = 'v'; + break; + + default: + switch (display & FIELD_DISPLAY_E_MASK) { + + case BASE_OCT: + *(--ptr) = (value & 0x7) + '0'; + value >>= 3; + *(--ptr) = (value & 0x7) + '0'; + value >>= 3; + *(--ptr) = (value & 0x7) + '0'; + break; + + case BASE_HEX: + *(--ptr) = hex_digits[value & 0x0F]; + value >>= 4; + *(--ptr) = hex_digits[value & 0x0F]; + *(--ptr) = 'x'; + break; + + default: + g_assert_not_reached(); + } + } + *(--ptr) = '\\'; + } + *(--ptr) = '\''; + return ptr; +} + static const char * hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value) { @@ -7839,6 +8112,15 @@ hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guin return hfinfo_number_value_format_display64(hfinfo, display, buf, value); } +static const char * +hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value) +{ + /* Get the underlying BASE_ value */ + int display = hfinfo->display & FIELD_DISPLAY_E_MASK; + + return hfinfo_char_value_format_display(display, buf, value); +} + static const char * hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value) { @@ -7905,6 +8187,15 @@ hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], gui return hfinfo_number_value_format_display64(hfinfo, display, buf, value); } +static const char * +hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value) +{ + /* Get the underlying BASE_ value */ + int display = hfinfo->display & FIELD_DISPLAY_E_MASK; + + return hfinfo_char_value_format_display(display, buf, value); +} + static const char * hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value) { @@ -8304,7 +8595,8 @@ proto_registrar_dump_values(void) if (hfinfo->strings != NULL) { if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM && - (hfinfo->type == FT_UINT8 || + (hfinfo->type == FT_CHAR || + hfinfo->type == FT_UINT8 || hfinfo->type == FT_UINT16 || hfinfo->type == FT_UINT24 || hfinfo->type == FT_UINT32 || @@ -8354,17 +8646,39 @@ proto_registrar_dump_values(void) vi = 0; while (vals[vi].strptr) { /* Print in the proper base */ - if (hfinfo->display == BASE_HEX) { - ws_debug_printf("V\t%s\t0x%x\t%s\n", - hfinfo->abbrev, - vals[vi].value, - vals[vi].strptr); - } - else { - ws_debug_printf("V\t%s\t%u\t%s\n", - hfinfo->abbrev, - vals[vi].value, - vals[vi].strptr); + if (hfinfo->type == FT_CHAR) { + if (g_ascii_isprint(vals[vi].value)) { + ws_debug_printf("V\t%s\t'%c'\t%s\n", + hfinfo->abbrev, + vals[vi].value, + vals[vi].strptr); + } else { + if (hfinfo->display == BASE_HEX) { + ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n", + hfinfo->abbrev, + vals[vi].value, + vals[vi].strptr); + } + else { + ws_debug_printf("V\t%s\t'\\%03o'\t%s\n", + hfinfo->abbrev, + vals[vi].value, + vals[vi].strptr); + } + } + } else { + if (hfinfo->display == BASE_HEX) { + ws_debug_printf("V\t%s\t0x%x\t%s\n", + hfinfo->abbrev, + vals[vi].value, + vals[vi].strptr); + } + else { + ws_debug_printf("V\t%s\t%u\t%s\n", + hfinfo->abbrev, + vals[vi].value, + vals[vi].strptr); + } } vi++; } @@ -8537,7 +8851,8 @@ proto_registrar_dump_fields(void) enum_name = ftype_name(hfinfo->type); base_name = ""; - if (hfinfo->type == FT_UINT8 || + if (hfinfo->type == FT_CHAR || + hfinfo->type == FT_UINT8 || hfinfo->type == FT_UINT16 || hfinfo->type == FT_UINT24 || hfinfo->type == FT_UINT32 || @@ -8651,6 +8966,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo); break; + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -8690,6 +9006,21 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, */ switch (hfinfo->type) { + case FT_CHAR: + if (filter != NULL) { + guint32 number; + + char buf [48]; + const char *out; + + number = fvalue_get_uinteger(&finfo->value); + + out = hfinfo_char_value_format(hfinfo, buf, number); + + *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out); + } + break; + case FT_INT8: case FT_INT16: case FT_INT24: @@ -8919,6 +9250,7 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, } switch (hf->type) { + case FT_CHAR: case FT_INT8: case FT_UINT8: case FT_INT16: @@ -8956,6 +9288,37 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf); switch (hf->type) { + case FT_CHAR: + if (hf->display == BASE_CUSTOM) { + gchar lbl[ITEM_LABEL_LENGTH]; + const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings; + + DISSECTOR_ASSERT(fmtfunc); + fmtfunc(lbl, (guint32) tmpval); + proto_item_append_text(item, "%s%s: %s", first ? "" : ", ", + hf->name, lbl); + first = FALSE; + } + else if (hf->strings) { + proto_item_append_text(item, "%s%s: %s", first ? "" : ", ", + hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown")); + first = FALSE; + } + else if (!(flags & BMT_NO_INT)) { + char buf[32]; + const char *out; + + if (!first) { + proto_item_append_text(item, ", "); + } + + out = hfinfo_char_value_format(hf, buf, (guint32) tmpval); + proto_item_append_text(item, "%s: %s", hf->name, out); + first = FALSE; + } + + break; + case FT_INT8: case FT_UINT8: case FT_INT16: @@ -9402,6 +9765,11 @@ _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb, (guint64)value ? tfstring->true_string : tfstring->false_string); break; + case FT_CHAR: + pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value); + fill_label_char(PITEM_FINFO(pi), lbl_str); + break; + case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -9572,6 +9940,11 @@ proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbu (guint64)value ? tfstring->true_string : tfstring->false_string); break; + case FT_CHAR: + pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value); + fill_label_char(PITEM_FINFO(pi), lbl_str); + break; + case FT_UINT8: case FT_UINT16: case FT_UINT24: @@ -9712,6 +10085,7 @@ _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex, "%s: %s", str, value_str); break; + case FT_CHAR: case FT_UINT8: case FT_UINT16: case FT_UINT24: diff --git a/epan/to_str.c b/epan/to_str.c index ca4fa907f9..dc5d343e03 100644 --- a/epan/to_str.c +++ b/epan/to_str.c @@ -66,6 +66,12 @@ byte_to_hex(char *out, guint32 dword) return out; } +char * +guint8_to_hex(char *out, guint8 val) +{ + return byte_to_hex(out, val); +} + char * word_to_hex(char *out, guint16 word) { diff --git a/epan/to_str.h b/epan/to_str.h index 2377dde425..8d53ee9141 100644 --- a/epan/to_str.h +++ b/epan/to_str.h @@ -144,6 +144,17 @@ WS_DLL_PUBLIC gchar* tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, */ WS_DLL_PUBLIC gchar* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_type type, const gint offset, int length); +/** + * guint8_to_hex() + * + * Output guint8 hex represetation to 'out', and return pointer after last character (out + 4). + * It always output full representation (padded with 0). + * + * String is not NUL terminated by this routine. + * There needs to be at least 2 bytes in the buffer. + */ +WS_DLL_PUBLIC char *guint8_to_hex(char *out, guint8 val); + /** * word_to_hex() * diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c index 490bb547bf..f1f98d43f4 100644 --- a/plugins/profinet/packet-dcerpc-pn-io.c +++ b/plugins/profinet/packet-dcerpc-pn-io.c @@ -3413,7 +3413,7 @@ dissect_IandM0_block(tvbuff_t *tvb, int offset, offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep, hf_pn_io_im_hardware_revision, &u16IMHardwareRevision); /* c8 SWRevisionPrefix */ - offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, + offset = dissect_dcerpc_char(tvb, offset, pinfo, tree, drep, hf_pn_io_im_revision_prefix, &u8SWRevisionPrefix); /* x8 IM_SWRevision_Functional_Enhancement */ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, tree, drep, @@ -12335,7 +12335,7 @@ proto_register_pn_io (void) /* XXX - better use a simple char here -> vals */ { &hf_pn_io_im_revision_prefix, { "IMRevisionPrefix", "pn_io.im_revision_prefix", - FT_UINT8, BASE_HEX, VALS(pn_io_im_revision_prefix_vals), 0x0, + FT_CHAR, BASE_HEX, VALS(pn_io_im_revision_prefix_vals), 0x0, NULL, HFILL } }, { &hf_pn_io_im_sw_revision_functional_enhancement,