Remove duplicate transport ports from proto tree summary

Don't display duplicate ports if transport name resolution is not
enabled (for UDP/TCP/DCCP).

Also introduce col_append_port() to handle info column port display
with name resolution in a uniform format.

Change-Id: Icb8ac45f726b7c539b4534c62061473e9b582753
Reviewed-on: https://code.wireshark.org/review/10804
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
João Valverde 2015-10-05 13:51:58 +01:00 committed by Michael Mann
parent b752f97b0b
commit 5823e6e50b
8 changed files with 154 additions and 143 deletions

View File

@ -167,14 +167,6 @@ typedef struct {
} subnet_length_entry_t;
#if 0
typedef struct serv_port {
gchar *udp_name;
gchar *tcp_name;
gchar *sctp_name;
gchar *dccp_name;
} serv_port_t;
#endif
/* hash table used for IPX network lookup */
/* XXX - check goodness of hash function */
@ -620,77 +612,63 @@ wmem_utoa(wmem_allocator_t *allocator, guint port)
return bp;
}
static const gchar *
serv_name_lookup(const guint port, const port_type proto)
_serv_name_lookup(port_type proto, guint port, serv_port_t **value_ret)
{
serv_port_t *serv_port_table;
gchar *name;
serv_port_table = (serv_port_t *)g_hash_table_lookup(serv_port_hashtable, &port);
if (serv_port_table) {
/* Set which table we should look up port in */
switch(proto) {
case PT_UDP:
if (serv_port_table->udp_name) {
return serv_port_table->udp_name;
}
break;
case PT_TCP:
if (serv_port_table->tcp_name) {
return serv_port_table->tcp_name;
}
break;
case PT_SCTP:
if (serv_port_table->sctp_name) {
return serv_port_table->sctp_name;
}
break;
case PT_DCCP:
if (serv_port_table->dccp_name) {
return serv_port_table->dccp_name;
}
break;
default:
/* not yet implemented */
return NULL;
/*NOTREACHED*/
} /* proto */
}
if (value_ret != NULL)
*value_ret = serv_port_table;
/* Use numerical port string */
name = (gchar*)g_malloc(16);
guint32_to_str_buf(port, name, 16);
if (serv_port_table == NULL)
return NULL;
switch (proto) {
case PT_UDP:
return serv_port_table->udp_name;
case PT_TCP:
return serv_port_table->tcp_name;
case PT_SCTP:
return serv_port_table->sctp_name;
case PT_DCCP:
return serv_port_table->dccp_name;
default:
break;
}
return NULL;
}
const gchar *
try_serv_name_lookup(port_type proto, guint port)
{
return _serv_name_lookup(proto, port, NULL);
}
const gchar *
serv_name_lookup(port_type proto, guint port)
{
serv_port_t *serv_port_table = NULL;
const char *name;
guint *key;
name = _serv_name_lookup(proto, port, &serv_port_table);
if (name != NULL)
return name;
if (serv_port_table == NULL) {
int *key;
key = (int *)g_new(int, 1);
key = (guint *)g_new(guint, 1);
*key = port;
serv_port_table = g_new0(serv_port_t,1);
serv_port_table = g_new0(serv_port_t, 1);
g_hash_table_insert(serv_port_hashtable, key, serv_port_table);
}
switch(proto) {
case PT_UDP:
serv_port_table->udp_name = name;
break;
case PT_TCP:
serv_port_table->tcp_name = name;
break;
case PT_SCTP:
serv_port_table->sctp_name = name;
break;
case PT_DCCP:
serv_port_table->dccp_name = name;
break;
default:
return NULL;
/*NOTREACHED*/
if (serv_port_table->numeric == NULL) {
serv_port_table->numeric = g_strdup_printf("%u", port);
}
return name;
} /* serv_name_lookup */
return serv_port_table->numeric;
}
static void
destroy_serv_port(gpointer data)
@ -700,6 +678,7 @@ destroy_serv_port(gpointer data)
g_free(table->tcp_name);
g_free(table->sctp_name);
g_free(table->dccp_name);
g_free(table->numeric);
g_free(table);
}
@ -2958,7 +2937,7 @@ udp_port_to_display(wmem_allocator_t *allocator, guint port)
return wmem_utoa(allocator, port);
}
return wmem_strdup(allocator, serv_name_lookup(port, PT_UDP));
return wmem_strdup(allocator, serv_name_lookup(PT_UDP, port));
} /* udp_port_to_display */
@ -2970,7 +2949,7 @@ dccp_port_to_display(wmem_allocator_t *allocator, guint port)
return wmem_utoa(allocator, port);
}
return wmem_strdup(allocator, serv_name_lookup(port, PT_DCCP));
return wmem_strdup(allocator, serv_name_lookup(PT_DCCP, port));
} /* dccp_port_to_display */
@ -2982,7 +2961,7 @@ tcp_port_to_display(wmem_allocator_t *allocator, guint port)
return wmem_utoa(allocator, port);
}
return wmem_strdup(allocator, serv_name_lookup(port, PT_TCP));
return wmem_strdup(allocator, serv_name_lookup(PT_TCP, port));
} /* tcp_port_to_display */
@ -2994,22 +2973,36 @@ sctp_port_to_display(wmem_allocator_t *allocator, guint port)
return wmem_utoa(allocator, port);
}
return wmem_strdup(allocator, serv_name_lookup(port, PT_SCTP));
return wmem_strdup(allocator, serv_name_lookup(PT_SCTP, port));
} /* sctp_port_to_display */
int
port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type port_typ, guint16 port_num)
gchar *
port_with_resolution_to_str(wmem_allocator_t *scope, port_type proto, guint port)
{
const gchar *port_res_str;
const gchar *port_str;
if (!gbl_resolv_flags.transport_name ||
(port_typ == PT_NONE) ||
((port_res_str = serv_name_lookup(port_num, port_typ)) == NULL)) {
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
/* No name resolution support, just return port string */
return g_snprintf(buf, buf_size, "%u", port_num);
return wmem_strdup_printf(scope, "%u", port);
}
return g_snprintf(buf, buf_size, "%s (%u)", port_res_str, port_num);
port_str = serv_name_lookup(proto, port);
g_assert(port_str);
return wmem_strdup_printf(scope, "%s (%u)", port_str, port);
}
int
port_with_resolution_to_str_buf(gchar *buf, gulong buf_size, port_type proto, guint port)
{
const gchar *port_str;
if (!gbl_resolv_flags.transport_name || (proto == PT_NONE)) {
/* No name resolution support, just return port string */
return g_snprintf(buf, buf_size, "%u", port);
}
port_str = serv_name_lookup(proto, port);
g_assert(port_str);
return g_snprintf(buf, buf_size, "%s (%u)", port_str, port);
}
gchar *

View File

@ -77,6 +77,7 @@ typedef struct serv_port {
gchar *tcp_name;
gchar *sctp_name;
gchar *dccp_name;
gchar *numeric;
} serv_port_t;
/*
@ -140,12 +141,31 @@ 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);
/*
* serv_name_lookup() returns the well known service name string, or numeric
* representation if one doesn't exist.
*/
WS_DLL_PUBLIC const gchar *serv_name_lookup(port_type proto, guint port);
/*
* try_serv_name_lookup() returns the well known service name string, or NULL if
* one doesn't exist.
*/
WS_DLL_PUBLIC const gchar *try_serv_name_lookup(port_type proto, guint port);
/*
* port_with_resolution_to_str() prints the "<resolved> (<numerical>)" port
* string.
*/
WS_DLL_PUBLIC gchar *port_with_resolution_to_str(wmem_allocator_t *scope,
port_type proto, 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);
port_type proto, guint port);
/*
* Asynchronous host name lookup initialization, processing, and cleanup

View File

@ -410,7 +410,7 @@ col_append_lstr(column_info *cinfo, const gint el, const gchar *str1, ...)
}
void
col_append_str_uint(column_info *cinfo, const gint col, const gchar *sep, const gchar *abbrev, guint32 val)
col_append_str_uint(column_info *cinfo, const gint col, const gchar *abbrev, guint32 val, const gchar *sep)
{
char buf[16];
@ -418,6 +418,21 @@ col_append_str_uint(column_info *cinfo, const gint col, const gchar *sep, const
col_append_lstr(cinfo, col, sep ? sep : "", abbrev, "=", buf, COL_ADD_LSTR_TERMINATOR);
}
void
col_append_port(column_info *cinfo, const gint col, port_type typ, guint16 val, const gchar *sep)
{
const char *str;
char buf[32];
if (gbl_resolv_flags.transport_name &&
(str = try_serv_name_lookup(typ, val)) != NULL) {
g_snprintf(buf, sizeof(buf), "%s(%u)", str, val);
} else {
g_snprintf(buf, sizeof(buf), "%u", val);
}
col_append_lstr(cinfo, col, sep ? sep : "", buf, COL_ADD_LSTR_TERMINATOR);
}
static void
col_do_append_fstr(column_info *cinfo, const int el, const char *separator, const char *format, va_list ap)
{

View File

@ -273,11 +273,21 @@ WS_DLL_PUBLIC void col_append_str(column_info *cinfo, const gint col, const gcha
*
* @param cinfo the current packet row
* @param col the column to use, e.g. COL_INFO
* @param sep an optional separator to prepend to abbrev
* @param abbrev the string to append
* @param val the value to append
* @param sep an optional separator to _prepend_ to abbrev
*/
WS_DLL_PUBLIC void col_append_str_uint(column_info *cinfo, const gint col, const gchar *sep, const gchar *abbrev, guint32 val);
WS_DLL_PUBLIC void col_append_str_uint(column_info *cinfo, const gint col, const gchar *abbrev, guint32 val, const gchar *sep);
/** Append a transport port to a column element, the text will be copied.
*
* @param cinfo the current packet row
* @param col the column to use, e.g. COL_INFO
* @param typ the port type to resolve
* @param val the port value to append
* @param sep an optional separator to _prepend_ to the port string
*/
WS_DLL_PUBLIC void col_append_port(column_info *cinfo, const gint col, port_type typ, guint16 val, const gchar *sep);
/* Append the given strings (terminated by COL_ADD_LSTR_TERMINATOR) to a column element,
*

View File

@ -598,7 +598,6 @@ dissect_dccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
proto_tree *dccp_options_tree = NULL;
proto_item *dccp_item = NULL;
proto_item *hidden_item, *offset_item;
vec_t cksum_vec[4];
guint32 phdr[2];
guint16 computed_cksum;
@ -609,35 +608,24 @@ 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);
SET_ADDRESS(&dccph->ip_src, pinfo->src.type, pinfo->src.len,
pinfo->src.data);
SET_ADDRESS(&dccph->ip_dst, pinfo->dst.type, pinfo->dst.len,
pinfo->dst.data);
dccph->sport = tvb_get_ntohs(tvb, offset);
dccph->dport = tvb_get_ntohs(tvb, offset + 2);
COPY_ADDRESS_SHALLOW(&dccph->ip_src, &pinfo->src);
COPY_ADDRESS_SHALLOW(&dccph->ip_dst, &pinfo->dst);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCCP");
col_clear(pinfo->cinfo, COL_INFO);
/* Extract generic header */
dccph->sport = tvb_get_ntohs(tvb, offset);
dccph->dport = tvb_get_ntohs(tvb, offset + 2);
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);
col_append_port(pinfo->cinfo, COL_INFO, PT_DCCP, dccph->sport, NULL);
col_append_port(pinfo->cinfo, COL_INFO, PT_DCCP, dccph->dport, UTF8_LONG_RIGHTWARDS_ARROW);
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), Dst Port: %s (%u)",
src_port_str, dccph->sport,
dst_port_str, dccph->dport);
proto_item_append_text(dccp_item, ", Src Port: %s, Dst Port: %s",
port_with_resolution_to_str(wmem_packet_scope(), PT_DCCP, dccph->sport),
port_with_resolution_to_str(wmem_packet_scope(), PT_DCCP, dccph->dport));
}
dccp_tree = proto_item_add_subtree(dccp_item, ett_dccp);

View File

@ -2513,7 +2513,7 @@ static void
tcp_info_append_uint(packet_info *pinfo, const char *abbrev, guint32 val)
{
/* fstr(" %s=%u", abbrev, val) */
col_append_str_uint(pinfo->cinfo, COL_INFO, " ", abbrev, val);
col_append_str_uint(pinfo->cinfo, COL_INFO, abbrev, val, " ");
}
static void
@ -4353,37 +4353,25 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
struct tcp_per_packet_data_t *tcppd=NULL;
proto_item *item;
proto_tree *checksum_tree;
gchar *src_port_str, *dst_port_str;
tcph=wmem_new(wmem_packet_scope(), struct tcpheader);
tcph = wmem_new0(wmem_packet_scope(), struct tcpheader);
tcph->th_sport = tvb_get_ntohs(tvb, offset);
tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
COPY_ADDRESS_SHALLOW(&tcph->ip_src, &pinfo->src);
COPY_ADDRESS_SHALLOW(&tcph->ip_dst, &pinfo->dst);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCP");
/* Clear out the Info column. */
col_clear(pinfo->cinfo, COL_INFO);
tcph->th_sport = tvb_get_ntohs(tvb, offset);
tcph->th_dport = tvb_get_ntohs(tvb, offset + 2);
src_port_str = tcp_port_to_display(wmem_packet_scope(), tcph->th_sport);
dst_port_str = tcp_port_to_display(wmem_packet_scope(), tcph->th_dport);
col_add_lstr(pinfo->cinfo, COL_INFO,
src_port_str,
" "UTF8_RIGHTWARDS_ARROW" ",
dst_port_str,
COL_ADD_LSTR_TERMINATOR);
col_append_port(pinfo->cinfo, COL_INFO, PT_TCP, tcph->th_sport, NULL);
col_append_port(pinfo->cinfo, COL_INFO, PT_TCP, tcph->th_dport, UTF8_LONG_RIGHTWARDS_ARROW);
if (tree) {
ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, ENC_NA);
if (tcp_summary_in_tree) {
ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, 0, -1,
"Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
src_port_str, tcph->th_sport,
dst_port_str, tcph->th_dport);
}
else {
ti = proto_tree_add_item(tree, proto_tcp, tvb, 0, -1, ENC_NA);
proto_item_append_text(ti, ", Src Port: %s, Dst Port: %s",
port_with_resolution_to_str(wmem_packet_scope(), PT_TCP, tcph->th_sport),
port_with_resolution_to_str(wmem_packet_scope(), PT_TCP, tcph->th_dport));
}
tcp_tree = proto_item_add_subtree(ti, ett_tcp);
p_add_proto_data(pinfo->pool, pinfo, proto_tcp, pinfo->curr_layer_num, tcp_tree);
@ -4677,13 +4665,14 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if(tcph->th_flags & TH_SYN) {
if(tcph->th_flags & TH_ACK) {
expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_sack, "Connection establish acknowledge (SYN+ACK): server port %s", src_port_str);
expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_sack,
"Connection establish acknowledge (SYN+ACK): server port %u", tcph->th_sport);
/* Save the server port to help determine dissector used */
tcpd->server_port = tcph->th_sport;
}
else {
expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_syn, "Connection establish request (SYN): server port %s",
dst_port_str);
expert_add_info_format(pinfo, tf_syn, &ei_tcp_connection_syn,
"Connection establish request (SYN): server port %u", tcph->th_dport);
/* Save the server port to help determine dissector used */
tcpd->server_port = tcph->th_dport;
tcpd->ts_mru_syn.secs = pinfo->fd->abs_ts.secs;

View File

@ -688,35 +688,28 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
conversation_t *conv = NULL;
struct udp_analysis *udpd = NULL;
proto_tree *process_tree;
gchar *src_port_str, *dst_port_str;
gboolean udp_jumbogram = FALSE;
udph = wmem_new(wmem_packet_scope(), e_udphdr);
udph = wmem_new0(wmem_packet_scope(), e_udphdr);
udph->uh_sport = tvb_get_ntohs(tvb, offset);
udph->uh_dport = tvb_get_ntohs(tvb, offset + 2);
udph->uh_ulen = udph->uh_sum_cov = tvb_get_ntohs(tvb, offset + 4);
udph->uh_sum = tvb_get_ntohs(tvb, offset + 6);
SET_ADDRESS(&udph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
SET_ADDRESS(&udph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
COPY_ADDRESS_SHALLOW(&udph->ip_src, &pinfo->src);
COPY_ADDRESS_SHALLOW(&udph->ip_dst, &pinfo->dst);
col_set_str(pinfo->cinfo, COL_PROTOCOL, (ip_proto == IP_PROTO_UDP) ? "UDP" : "UDP-Lite");
col_clear(pinfo->cinfo, COL_INFO);
src_port_str = udp_port_to_display(wmem_packet_scope(), udph->uh_sport);
dst_port_str = udp_port_to_display(wmem_packet_scope(), udph->uh_dport);
col_add_lstr(pinfo->cinfo, COL_INFO,
src_port_str,
" "UTF8_RIGHTWARDS_ARROW" ",
dst_port_str,
COL_ADD_LSTR_TERMINATOR);
col_append_port(pinfo->cinfo, COL_INFO, PT_UDP, udph->uh_sport, NULL);
col_append_port(pinfo->cinfo, COL_INFO, PT_UDP, udph->uh_dport, UTF8_LONG_RIGHTWARDS_ARROW);
reported_len = tvb_reported_length(tvb);
len = tvb_captured_length(tvb);
ti = proto_tree_add_item(tree, (ip_proto == IP_PROTO_UDP) ? hfi_udp : hfi_udplite, tvb, offset, 8, ENC_NA);
if (udp_summary_in_tree) {
proto_item_append_text(ti, ", Src Port: %s (%u), Dst Port: %s (%u)",
src_port_str, udph->uh_sport, dst_port_str, udph->uh_dport);
proto_item_append_text(ti, ", Src Port: %s, Dst Port: %s",
port_with_resolution_to_str(wmem_packet_scope(), PT_UDP, udph->uh_sport),
port_with_resolution_to_str(wmem_packet_scope(), PT_UDP, udph->uh_dport));
}
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);
@ -742,6 +735,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
((udph->uh_dport - 32768 - 666 - 1) % 3) + 1);
}
udph->uh_ulen = udph->uh_sum_cov = tvb_get_ntohs(tvb, offset + 4);
if (ip_proto == IP_PROTO_UDP) {
len_cov_item = proto_tree_add_item(udp_tree, &hfi_udp_length, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
if (udph->uh_ulen == 0 && pinfo->src.type == AT_IPv6) {
@ -787,10 +781,11 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
}
}
col_append_str_uint(pinfo->cinfo, COL_INFO, " ", "Len", udph->uh_ulen - 8); /* Payload length */
col_append_str_uint(pinfo->cinfo, COL_INFO, "Len", udph->uh_ulen - 8, " "); /* Payload length */
if (udp_jumbogram)
col_append_str(pinfo->cinfo, COL_INFO, " [Jumbogram]");
udph->uh_sum = tvb_get_ntohs(tvb, offset + 6);
if (udph->uh_sum == 0) {
/* No checksum supplied in the packet. */
if ((ip_proto == IP_PROTO_UDP) && (pinfo->src.type == AT_IPv4)) {

View File

@ -39,6 +39,7 @@
#define UTF8_LEFTWARDS_ARROW "\xe2\x86\x90" /* 8592 / 0x2190 */
#define UTF8_RIGHTWARDS_ARROW "\xe2\x86\x92" /* 8594 / 0x2192 */
#define UTF8_LEFT_RIGHT_ARROW "\xe2\x86\x94" /* 8596 / 0x2194 */
#define UTF8_LONG_RIGHTWARDS_ARROW "\xe2\x9f\xb6" /* 10230 / 0x27f6 */
#define UTF8_PLACE_OF_INTEREST_SIGN "\xe2\x8c\x98" /* 8984 / 0x2318 */