summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Valverde <joao.valverde@tecnico.ulisboa.pt>2015-10-05 11:53:07 +0100
committerMichael Mann <mmann78@netscape.net>2015-10-05 18:10:48 +0000
commita459ac72a2c01ec12d186907837aff891e3e223b (patch)
tree01328590650245061ae8d78c02f14c8fbdde0381
parentd52322efb3ab782871312950876803334ec018b9 (diff)
downloadwireshark-a459ac72a2c01ec12d186907837aff891e3e223b.tar.gz
Add BASE_PT_ field display types
Avoid displaying duplicate port numbers with transport name resolution disabled and make some dissector code simpler. Introduces port_with_resolution_to_str_buf() function and amends UDP/TCP/DCCP/SCTP to use the new field display type. Change-Id: Ifb97810b9c669ccbb1a310a2c0ffd6e2b63af210 Reviewed-on: https://code.wireshark.org/review/10625 Petri-Dish: Michael Mann <mmann78@netscape.net> Reviewed-by: João Valverde <j@v6e.pt> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--doc/README.dissector9
-rw-r--r--epan/addr_resolv.c23
-rw-r--r--epan/addr_resolv.h9
-rw-r--r--epan/dissectors/packet-dccp.c59
-rw-r--r--epan/dissectors/packet-sctp.c8
-rw-r--r--epan/dissectors/packet-tcp.c40
-rw-r--r--epan/dissectors/packet-udp.c40
-rw-r--r--epan/proto.c51
-rw-r--r--epan/proto.h33
9 files changed, 149 insertions, 123 deletions
diff --git a/doc/README.dissector b/doc/README.dissector
index addd967d5a..97db00b14f 100644
--- a/doc/README.dissector
+++ b/doc/README.dissector
@@ -115,6 +115,10 @@ FIELDDISPLAY --For FT_UINT{8,16,24,32,40,48,56,64} and
or BASE_CUSTOM, possibly ORed with BASE_RANGE_STRING,
BASE_EXT_STRING or BASE_VAL64_STRING
+ --For FT_UINT16:
+
+ BASE_PT_UDP, BASE_PT_TCP, BASE_PT_DCCP or BASE_PT_SCTP
+
--For FT_ABSOLUTE_TIME:
ABSOLUTE_TIME_LOCAL, ABSOLUTE_TIME_UTC, or
@@ -823,6 +827,11 @@ and the second argument is the value to be formatted.
Both custom_fmt_func_t and custom_fmt_func_64_t are defined in epan/proto.h.
+For FT_UINT16 'display' can be used to select a transport layer protocol using one
+of BASE_PT_UDP, BASE_PT_TCP, BASE_PT_DCCP or BASE_PT_SCTP. If transport name
+resolution is enabled the port field label is displayed in decimal and as a well-known
+service name (if one is available).
+
For FT_BOOLEAN fields that are also bitfields (i.e., 'bitmask' is non-zero),
'display' is used specify a "field-width" (i.e., tell the proto_tree how
wide the parent bitfield is). (If the FT_BOOLEAN 'bitmask' is zero, then
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index 648d6274dc..8aab2bdc9c 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -621,8 +621,8 @@ wmem_utoa(wmem_allocator_t *allocator, guint port)
}
-static gchar
-*serv_name_lookup(const guint port, const port_type proto)
+static const gchar *
+serv_name_lookup(const guint port, const port_type proto)
{
serv_port_t *serv_port_table;
gchar *name;
@@ -659,10 +659,7 @@ static gchar
} /* proto */
}
- /* getservbyport() was used here but it was to expensive, if the functionality is desired
- * it would be better to pre parse etc/services or C:\Windows\System32\drivers\etc at
- * startup
- */
+ /* Use numerical port string */
name = (gchar*)g_malloc(16);
guint32_to_str_buf(port, name, 16);
@@ -3001,6 +2998,20 @@ sctp_port_to_display(wmem_allocator_t *allocator, guint port)
} /* sctp_port_to_display */
+int
+port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type port_typ, guint16 port_num)
+{
+ const gchar *port_res_str;
+
+ if (!gbl_resolv_flags.transport_name ||
+ (port_typ == PT_NONE) ||
+ ((port_res_str = serv_name_lookup(port_num, port_typ)) == NULL)) {
+ /* No name resolution support, just return port string */
+ return g_snprintf(buf, buf_size, "%u", port_num);
+ }
+ return g_snprintf(buf, buf_size, "%s (%u)", port_res_str, port_num);
+}
+
gchar *
get_ether_name(const guint8 *addr)
{
diff --git a/epan/addr_resolv.h b/epan/addr_resolv.h
index b3d1f70297..13e48df667 100644
--- a/epan/addr_resolv.h
+++ b/epan/addr_resolv.h
@@ -53,7 +53,7 @@ extern "C" {
typedef struct _e_addr_resolve {
gboolean mac_name; /**< Whether to resolve Ethernet MAC to manufacturer names */
gboolean network_name; /**< Whether to resolve IPv4, IPv6, and IPX addresses into host names */
- gboolean transport_name; /**< Whether to resolve TCP/UDP ports into service names */
+ gboolean transport_name; /**< Whether to resolve TCP/UDP/DCCP/SCTP ports into service names */
gboolean concurrent_dns; /**< Whether to use concurrent DNS name resolution */
gboolean dns_pkt_addr_resolution; /**< Whether to resolve addresses using captured DNS packets */
gboolean use_external_net_name_resolver; /**< Whether to system's configured DNS server to resolve names */
@@ -141,6 +141,13 @@ extern gchar *dccp_port_to_display(wmem_allocator_t *allocator, guint port);
WS_DLL_PUBLIC gchar *sctp_port_to_display(wmem_allocator_t *allocator, guint port);
/*
+ * port_with_resolution_to_str_buf() prints the "<resolved> (<numerical>)" port
+ * string to 'buf'. Return value is the same as g_snprintf().
+ */
+WS_DLL_PUBLIC int port_with_resolution_to_str_buf(gchar *buf, gulong buf_size,
+ port_type port_typ, guint16 port_num);
+
+/*
* Asynchronous host name lookup initialization, processing, and cleanup
*/
diff --git a/epan/dissectors/packet-dccp.c b/epan/dissectors/packet-dccp.c
index 0caef2e8b6..9e6dd39788 100644
--- a/epan/dissectors/packet-dccp.c
+++ b/epan/dissectors/packet-dccp.c
@@ -56,6 +56,8 @@
#include <epan/expert.h>
#include <epan/conversation.h>
#include <epan/tap.h>
+#include <wsutil/utf8_entities.h>
+
#include "packet-dccp.h"
/*
@@ -607,6 +609,7 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
guint advertised_dccp_header_len = 0;
guint options_len = 0;
e_dccphdr *dccph;
+ gchar *src_port_str, *dst_port_str;
dccph = wmem_new0(wmem_packet_scope(), e_dccphdr);
@@ -618,43 +621,33 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCCP");
col_clear(pinfo->cinfo, COL_INFO);
- dccp_item = proto_tree_add_item(tree, proto_dccp, tvb, offset, -1, ENC_NA);
- dccp_tree = proto_item_add_subtree(dccp_item, ett_dccp);
-
/* Extract generic header */
dccph->sport = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint_format_value(dccp_tree, hf_dccp_srcport, tvb,
- offset, 2, dccph->sport,
- "%s (%u)",
- dccp_port_to_display(wmem_packet_scope(), dccph->sport),
- dccph->sport);
+ dccph->dport = tvb_get_ntohs(tvb, offset);
+
+ src_port_str = dccp_port_to_display(wmem_packet_scope(), dccph->sport);
+ dst_port_str = dccp_port_to_display(wmem_packet_scope(), dccph->dport);
+ col_add_lstr(pinfo->cinfo, COL_INFO,
+ src_port_str,
+ " "UTF8_RIGHTWARDS_ARROW" ",
+ dst_port_str,
+ COL_ADD_LSTR_TERMINATOR);
+
+ dccp_item = proto_tree_add_item(tree, proto_dccp, tvb, offset, -1, ENC_NA);
if (dccp_summary_in_tree) {
- proto_item_append_text(dccp_item, ", Src Port: %s (%u)",
- dccp_port_to_display(wmem_packet_scope(), dccph->sport), dccph->sport);
+ proto_item_append_text(dccp_item, ", Src Port: %s (%u), Dst Port: %s (%u)",
+ src_port_str, dccph->sport,
+ dst_port_str, dccph->dport);
}
- col_add_fstr(pinfo->cinfo, COL_INFO,
- "%s ", dccp_port_to_display(wmem_packet_scope(), dccph->sport));
- hidden_item =
- proto_tree_add_uint(dccp_tree, hf_dccp_port, tvb, offset, 2,
- dccph->sport);
+ dccp_tree = proto_item_add_subtree(dccp_item, ett_dccp);
+
+ proto_tree_add_item(dccp_tree, hf_dccp_srcport, tvb, offset, 2, ENC_BIG_ENDIAN);
+ hidden_item = proto_tree_add_item(dccp_tree, hf_dccp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
offset += 2;
- dccph->dport = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint_format_value(dccp_tree, hf_dccp_dstport, tvb,
- offset, 2, dccph->dport,
- "%s (%u)",
- dccp_port_to_display(wmem_packet_scope(), dccph->dport),
- dccph->dport);
- if (dccp_summary_in_tree) {
- proto_item_append_text(dccp_item, ", Dst Port: %s (%u)",
- dccp_port_to_display(wmem_packet_scope(), dccph->dport), dccph->dport);
- }
- col_append_fstr(pinfo->cinfo, COL_INFO, " > %s",
- dccp_port_to_display(wmem_packet_scope(), dccph->dport));
- hidden_item =
- proto_tree_add_uint(dccp_tree, hf_dccp_port, tvb, offset, 2,
- dccph->dport);
+ proto_tree_add_item(dccp_tree, hf_dccp_dstport, tvb, offset, 2, ENC_BIG_ENDIAN);
+ hidden_item = proto_tree_add_item(dccp_tree, hf_dccp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
offset += 2;
@@ -1054,7 +1047,7 @@ proto_register_dccp(void)
&hf_dccp_srcport,
{
"Source Port", "dccp.srcport",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_PT_DCCP, NULL, 0x0,
NULL, HFILL
}
},
@@ -1062,7 +1055,7 @@ proto_register_dccp(void)
&hf_dccp_dstport,
{
"Destination Port", "dccp.dstport",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_PT_DCCP, NULL, 0x0,
NULL, HFILL
}
},
@@ -1070,7 +1063,7 @@ proto_register_dccp(void)
&hf_dccp_port,
{
"Source or Destination Port", "dccp.port",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_PT_DCCP, NULL, 0x0,
NULL, HFILL
}
},
diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c
index 21720a7183..2cbdddb7ef 100644
--- a/epan/dissectors/packet-sctp.c
+++ b/epan/dissectors/packet-sctp.c
@@ -4736,9 +4736,9 @@ proto_register_sctp(void)
/* Setup list of header fields */
static hf_register_info hf[] = {
- { &hf_source_port, { "Source port", "sctp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
- { &hf_destination_port, { "Destination port", "sctp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
- { &hf_port, { "Port", "sctp.port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_source_port, { "Source port", "sctp.srcport", FT_UINT16, BASE_PT_SCTP, NULL, 0x0, NULL, HFILL } },
+ { &hf_destination_port, { "Destination port", "sctp.dstport", FT_UINT16, BASE_PT_SCTP, NULL, 0x0, NULL, HFILL } },
+ { &hf_port, { "Port", "sctp.port", FT_UINT16, BASE_PT_SCTP, NULL, 0x0, NULL, HFILL } },
{ &hf_verification_tag, { "Verification tag", "sctp.verification_tag", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_checksum, { "Checksum", "sctp.checksum", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
{ &hf_checksum_bad, { "Bad checksum", "sctp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
@@ -4786,7 +4786,7 @@ proto_register_sctp(void)
{ &hf_sack_chunk_gap_block_end_tsn, { "End TSN", "sctp.sack_gap_block_end_tsn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_sack_chunk_number_tsns_gap_acked, { "Number of TSNs in gap acknowledgement blocks", "sctp.sack_number_of_tsns_gap_acked", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_sack_chunk_duplicate_tsn, { "Duplicate TSN", "sctp.sack_duplicate_tsn", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
- { &hf_nr_sack_chunk_ns, { "Nounce sum", "sctp.nr_sack_nounce_sum", FT_UINT8, BASE_DEC, NULL, SCTP_NR_SACK_CHUNK_NS_BIT, NULL, HFILL } },
+ { &hf_nr_sack_chunk_ns, { "Nounce sum", "sctp.nr_sack_nounce_sum", FT_UINT8, BASE_DEC, NULL, SCTP_NR_SACK_CHUNK_NS_BIT, NULL, HFILL } },
{ &hf_nr_sack_chunk_cumulative_tsn_ack, { "Cumulative TSN ACK", "sctp.nr_sack_cumulative_tsn_ack", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_nr_sack_chunk_adv_rec_window_credit, { "Advertised receiver window credit (a_rwnd)", "sctp.nr_sack_a_rwnd", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
{ &hf_nr_sack_chunk_number_of_gap_blocks, { "Number of gap acknowledgement blocks", "sctp.nr_sack_number_of_gap_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index 21011f470c..36c82b701a 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -4388,13 +4388,11 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tcp_tree = proto_item_add_subtree(ti, ett_tcp);
p_add_proto_data(pinfo->pool, pinfo, proto_tcp, pinfo->curr_layer_num, tcp_tree);
- proto_tree_add_uint_format_value(tcp_tree, hf_tcp_srcport, tvb, offset, 2, tcph->th_sport,
- "%s (%u)", src_port_str, tcph->th_sport);
- proto_tree_add_uint_format_value(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, tcph->th_dport,
- "%s (%u)", dst_port_str, tcph->th_dport);
- hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset, 2, tcph->th_sport);
+ proto_tree_add_item(tcp_tree, hf_tcp_srcport, tvb, offset, 2, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+ hidden_item = proto_tree_add_item(tcp_tree, hf_tcp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
- hidden_item = proto_tree_add_uint(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, tcph->th_dport);
+ hidden_item = proto_tree_add_item(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
/* If we're dissecting the headers of a TCP packet in an ICMP packet
@@ -5122,20 +5120,18 @@ tcp_cleanup(void)
void
proto_register_tcp(void)
{
- static value_string tcp_ports[65536+1];
-
static hf_register_info hf[] = {
{ &hf_tcp_srcport,
- { "Source Port", "tcp.srcport", FT_UINT16, BASE_DEC, VALS(tcp_ports), 0x0,
+ { "Source Port", "tcp.srcport", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
NULL, HFILL }},
{ &hf_tcp_dstport,
- { "Destination Port", "tcp.dstport", FT_UINT16, BASE_DEC, VALS(tcp_ports), 0x0,
+ { "Destination Port", "tcp.dstport", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
NULL, HFILL }},
{ &hf_tcp_port,
- { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_DEC, VALS(tcp_ports), 0x0,
+ { "Source or Destination Port", "tcp.port", FT_UINT16, BASE_PT_TCP, NULL, 0x0,
NULL, HFILL }},
{ &hf_tcp_stream,
@@ -5978,28 +5974,6 @@ proto_register_tcp(void)
module_t *tcp_module;
expert_module_t* expert_tcp;
- {
- int i, j;
- gboolean transport_name_old = gbl_resolv_flags.transport_name;
-
- gbl_resolv_flags.transport_name = TRUE;
- for (i = 0, j = 0; i <= 65535; i++) {
- const char *serv = tcp_port_to_display(wmem_epan_scope(), i);
-
- if (serv) {
- value_string *p = &tcp_ports[j++];
-
- p->value = i;
- p->strptr = serv;
- }
- }
- /* NULL terminate */
- tcp_ports[j].value = 0;
- tcp_ports[j].strptr = NULL;
-
- gbl_resolv_flags.transport_name = transport_name_old;
- }
-
proto_tcp = proto_register_protocol("Transmission Control Protocol", "TCP", "tcp");
register_dissector("tcp", dissect_tcp, proto_tcp);
proto_register_field_array(proto_tcp, hf, array_length(hf));
diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c
index d0acf286ad..800f1e8f4b 100644
--- a/epan/dissectors/packet-udp.c
+++ b/epan/dissectors/packet-udp.c
@@ -54,8 +54,6 @@ static dissector_handle_t udplite_handle;
static int udp_tap = -1;
static int udp_follow_tap = -1;
-static value_string udp_ports[65536+1];
-
static header_field_info *hfi_udp = NULL;
static header_field_info *hfi_udplite = NULL;
@@ -63,15 +61,15 @@ static header_field_info *hfi_udplite = NULL;
#define UDPLITE_HFI_INIT HFI_INIT(proto_udplite)
static header_field_info hfi_udp_srcport UDP_HFI_INIT =
-{ "Source Port", "udp.srcport", FT_UINT16, BASE_DEC, VALS(udp_ports), 0x0,
+{ "Source Port", "udp.srcport", FT_UINT16, BASE_PT_UDP, NULL, 0x0,
NULL, HFILL };
static header_field_info hfi_udp_dstport UDP_HFI_INIT =
-{ "Destination Port", "udp.dstport", FT_UINT16, BASE_DEC, VALS(udp_ports), 0x0,
+{ "Destination Port", "udp.dstport", FT_UINT16, BASE_PT_UDP, NULL, 0x0,
NULL, HFILL };
static header_field_info hfi_udp_port UDP_HFI_INIT =
-{ "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC, VALS(udp_ports), 0x0,
+{ "Source or Destination Port", "udp.port", FT_UINT16, BASE_PT_UDP, NULL, 0x0,
NULL, HFILL };
static header_field_info hfi_udp_stream UDP_HFI_INIT =
@@ -733,8 +731,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
udp_tree = proto_item_add_subtree(ti, ett_udp);
p_add_proto_data(pinfo->pool, pinfo, hfi_udp->id, pinfo->curr_layer_num, udp_tree);
- port_item = proto_tree_add_uint_format_value(udp_tree, hfi_udp_srcport.id, tvb, offset, 2, udph->uh_sport,
- "%s (%u)", src_port_str, udph->uh_sport);
+ port_item = proto_tree_add_item(udp_tree, &hfi_udp_srcport, tvb, offset, 2, ENC_BIG_ENDIAN);
/* The beginning port number, 32768 + 666 (33434), is from LBL's traceroute.c source code and this code
* further assumes that 3 attempts are made per hop */
if ((udph->uh_sport > (32768 + 666)) && (udph->uh_sport <= (32768 + 666 + 30)))
@@ -743,17 +740,16 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
((udph->uh_sport - 32768 - 666 - 1) % 3) + 1
);
- port_item = proto_tree_add_uint_format_value(udp_tree, hfi_udp_dstport.id, tvb, offset + 2, 2, udph->uh_dport,
- "%s (%u)", dst_port_str, udph->uh_dport);
+ port_item = proto_tree_add_item(udp_tree, &hfi_udp_dstport, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
if ((udph->uh_dport > (32768 + 666)) && (udph->uh_dport <= (32768 + 666 + 30)))
expert_add_info_format(pinfo, port_item, &ei_udp_possible_traceroute, "Possible traceroute: hop #%u, attempt #%u",
((udph->uh_dport - 32768 - 666 - 1) / 3) + 1,
((udph->uh_dport - 32768 - 666 - 1) % 3) + 1
);
- hidden_item = proto_tree_add_uint(udp_tree, &hfi_udp_port, tvb, offset, 2, udph->uh_sport);
+ hidden_item = proto_tree_add_item(udp_tree, &hfi_udp_port, tvb, offset, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
- hidden_item = proto_tree_add_uint(udp_tree, &hfi_udp_port, tvb, offset+2, 2, udph->uh_dport);
+ hidden_item = proto_tree_add_item(udp_tree, &hfi_udp_port, tvb, offset+2, 2, ENC_BIG_ENDIAN);
PROTO_ITEM_SET_HIDDEN(hidden_item);
}
@@ -1091,27 +1087,7 @@ proto_register_udp(void)
static decode_as_t udp_da = {"udp", "Transport", "udp.port", 3, 2, udp_da_values, "UDP", "port(s) as",
decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
- int proto_udp, proto_udplite, i, j;
- gboolean transport_name_old = gbl_resolv_flags.transport_name;
-
- gbl_resolv_flags.transport_name = TRUE;
- for (i = 0, j = 0; i <= 65535; i++) {
- const char *serv = udp_port_to_display(wmem_epan_scope(), i);
-
- if (serv) {
- value_string *p = &udp_ports[j++];
-
- p->value = i;
- p->strptr = serv;
- }
- }
-
- /* NULL terminate */
- udp_ports[j].value = 0;
- udp_ports[j].strptr = NULL;
-
- gbl_resolv_flags.transport_name = transport_name_old;
-
+ int proto_udp, proto_udplite;
proto_udp = proto_register_protocol("User Datagram Protocol",
"UDP", "udp");
diff --git a/epan/proto.c b/epan/proto.c
index 3bbb04c0fe..5e6b032227 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -5923,8 +5923,30 @@ static const value_string hf_display[] = {
{ ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
{ ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
{ ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
+ { BASE_PT_UDP, "BASE_PT_UDP" },
+ { BASE_PT_TCP, "BASE_PT_TCP" },
+ { BASE_PT_DCCP, "BASE_PT_DCCP" },
+ { BASE_PT_SCTP, "BASE_PT_SCTP" },
{ 0, NULL } };
+static inline port_type
+display_to_port_type(field_display_e e)
+{
+ switch (e) {
+ case BASE_PT_UDP:
+ return PT_UDP;
+ case BASE_PT_TCP:
+ return PT_TCP;
+ case BASE_PT_DCCP:
+ return PT_DCCP;
+ case BASE_PT_SCTP:
+ return PT_SCTP;
+ default:
+ break;
+ }
+ return PT_NONE;
+}
+
/* temporary function containing assert part for easier profiling */
static void
tmp_fld_check_assert(header_field_info *hfinfo)
@@ -6062,6 +6084,26 @@ tmp_fld_check_assert(header_field_info *hfinfo)
case FT_UINT48:
case FT_UINT56:
case FT_UINT64:
+ if (IS_BASE_PORT(hfinfo->display)) {
+ tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
+ if (hfinfo->type != FT_UINT16) {
+ g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
+ hfinfo->name, hfinfo->abbrev,
+ tmp_str, ftype_name(hfinfo->type));
+ }
+ if (hfinfo->strings != NULL) {
+ g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
+ hfinfo->name, hfinfo->abbrev,
+ ftype_name(hfinfo->type), tmp_str);
+ }
+ if (hfinfo->bitmask != 0) {
+ g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
+ hfinfo->name, hfinfo->abbrev,
+ ftype_name(hfinfo->type), tmp_str);
+ }
+ wmem_free(NULL, tmp_str);
+ break;
+ }
/* Require integral types (other than frame number,
* which is always displayed in decimal) to have a
* number base.
@@ -6992,7 +7034,7 @@ 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) { /* Add fill_label_framenum? */
const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
out = hfinfo_number_vals_format(hfinfo, buf, value);
@@ -7001,6 +7043,13 @@ fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
else
label_fill_descr(label_str, 0, hfinfo, val_str, out);
}
+ else if (IS_BASE_PORT(hfinfo->display)) {
+ gchar tmp[ITEM_LABEL_LENGTH];
+
+ port_with_resolution_to_str_buf(tmp, sizeof(tmp),
+ display_to_port_type((field_display_e)hfinfo->display), value);
+ label_fill(label_str, 0, hfinfo, tmp);
+ }
else {
out = hfinfo_number_value_format(hfinfo, buf, value);
diff --git a/epan/proto.h b/epan/proto.h
index 3f0cef278d..0b98ba39e5 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -497,9 +497,8 @@ WS_DLL_PUBLIC WS_MSVC_NORETURN void proto_report_dissector_bug(const char *messa
/* For integral types, the display format is a BASE_* field_display_e value
* possibly ORed with BASE_*_STRING */
-/** FIELD_DISPLAY_E_MASK selects the field_display_e value. Its current
- * value means that we may have at most 16 field_display_e values. */
-#define FIELD_DISPLAY_E_MASK 0x0F
+/** FIELD_DISPLAY_E_MASK selects the field_display_e value. */
+#define FIELD_DISPLAY_E_MASK 0xFF
typedef enum {
/* Integral types */
@@ -514,28 +513,36 @@ typedef enum {
/* String types */
STR_ASCII = BASE_NONE, /**< shows non-printable ASCII characters as C-style escapes */
/* XXX, support for format_text_wsp() ? */
- STR_UNICODE = 7, /**< shows non-printable UNICODE characters as \\uXXXX (XXX for now non-printable characters display depends on UI) */
+ STR_UNICODE = 7, /**< shows non-printable UNICODE characters as \\uXXXX (XXX for now non-printable characters display depends on UI) */
/* Byte types */
- SEP_DOT = 8, /**< hexadecimal bytes with a period (.) between each byte */
- SEP_DASH = 9, /**< hexadecimal bytes with a dash (-) between each byte */
- SEP_COLON = 10, /**< hexadecimal bytes with a colon (:) between each byte */
- SEP_SPACE = 11, /**< hexadecimal bytes with a space between each byte */
+ SEP_DOT = 8, /**< hexadecimal bytes with a period (.) between each byte */
+ SEP_DASH = 9, /**< hexadecimal bytes with a dash (-) between each byte */
+ SEP_COLON = 10, /**< hexadecimal bytes with a colon (:) between each byte */
+ SEP_SPACE = 11, /**< hexadecimal bytes with a space between each byte */
/* Address types */
- BASE_NETMASK = 12 /**< Used for IPv4 address that shouldn't be resolved (like for netmasks) */
+ BASE_NETMASK = 12, /**< Used for IPv4 address that shouldn't be resolved (like for netmasks) */
+/* Port types */
+ BASE_PT_UDP = 13, /**< UDP port */
+ BASE_PT_TCP = 14, /**< TCP port */
+ BASE_PT_DCCP = 15, /**< DCCP port */
+ BASE_PT_SCTP = 16, /**< SCTP port */
} field_display_e;
/* Following constants have to be ORed with a field_display_e when dissector
* want to use specials value-string MACROs for a header_field_info */
-#define BASE_RANGE_STRING 0x10
-#define BASE_EXT_STRING 0x20
-#define BASE_VAL64_STRING 0x40
+#define BASE_RANGE_STRING 0x100
+#define BASE_EXT_STRING 0x200
+#define BASE_VAL64_STRING 0x400
/** BASE_ values that cause the field value to be displayed twice */
#define IS_BASE_DUAL(b) ((b)==BASE_DEC_HEX||(b)==BASE_HEX_DEC)
+/** BASE_PT_ values display decimal and transport port service name */
+#define IS_BASE_PORT(b) (((b)==BASE_PT_UDP||(b)==BASE_PT_TCP||(b)==BASE_PT_DCCP||(b)==BASE_PT_SCTP))
+
/* For FT_ABSOLUTE_TIME, the display format is an absolute_time_display_e
* as per time_fmt.h. */
@@ -554,7 +561,7 @@ struct _header_field_info {
const char *name; /**< [FIELDNAME] full name of this field */
const char *abbrev; /**< [FIELDABBREV] abbreviated name of this field */
enum ftenum type; /**< [FIELDTYPE] field type, one of FT_ (from ftypes.h) */
- int display; /**< [FIELDDISPLAY] one of BASE_, or field bit-width if FT_BOOLEAN and non-zero bitmask */
+ int display; /**< [FIELDDISPLAY] one of BASE_, or field bit-width if FT_BOOLEAN and non-zero bitmask */
const void *strings; /**< [FIELDCONVERT] value_string, val64_string, range_string or true_false_string,
typically converted by VALS(), RVALS() or TFS().
If this is an FT_PROTOCOL then it points to the