From 4e4f6d67fa9e7d529f615abd131feed552b1c76a Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Tue, 4 Oct 2005 13:34:52 +0000 Subject: [PATCH] in svn 15335 the tcp analysis was changed to do its stuff and to populate (prepend to) COL_INFO before callking the subdissectors instead of calling the tcp analysis (and prepend colingo) eitehr after the subdissector returned normally or if an exception caused by a subdissector was rised. this as a sideffect caused tcp analysis data to be overwritten if the subdissector caused any output to the info column. (and made tcp analysis suboptimal) this change adds a new function col_prepend_fence_fstr() that will prepend the info column with the string and also, if there was no fence already defined, create a fence and set it after the prepended col info text. This way, even if the subdissectors generate and rewrite col info, the tcp analysis data will still be displayed on the info column. svn path=/trunk/; revision=16116 --- epan/column-utils.c | 45 ++++++++++++++++++++++++++++++++++++ epan/column-utils.h | 11 +++++++++ epan/dissectors/packet-tcp.c | 28 +++++++++++----------- epan/libethereal.def | 1 + 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/epan/column-utils.c b/epan/column-utils.c index de134a7e03..109ecbdc7f 100644 --- a/epan/column-utils.c +++ b/epan/column-utils.c @@ -380,6 +380,51 @@ col_prepend_fstr(column_info *cinfo, gint el, const gchar *format, ...) } va_end(ap); } +void +col_prepend_fence_fstr(column_info *cinfo, gint el, const gchar *format, ...) +{ + va_list ap; + int i; + char orig_buf[COL_BUF_MAX_LEN]; + const char *orig; + size_t max_len; + + g_assert(cinfo->col_first[el] >= 0); + if (el == COL_INFO) + max_len = COL_MAX_INFO_LEN; + else + max_len = COL_MAX_LEN; + + va_start(ap, format); + for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) { + if (cinfo->fmt_matx[i][el]) { + if (cinfo->col_data[i] != cinfo->col_buf[i]) { + /* This was set with "col_set_str()"; which is effectively const */ + orig = cinfo->col_data[i]; + } else { + strncpy(orig_buf, cinfo->col_buf[i], max_len); + orig_buf[max_len - 1] = '\0'; + orig = orig_buf; + } + g_vsnprintf(cinfo->col_buf[i], max_len, format, ap); + cinfo->col_buf[i][max_len - 1] = '\0'; + + /* + * Move the fence if it exists, else create a new fence at the + * end of the prepended data. + */ + if (cinfo->col_fence[i] > 0) { + cinfo->col_fence[i] += strlen(cinfo->col_buf[i]); + } else { + cinfo->col_fence[i] = strlen(cinfo->col_buf[i]); + } + strncat(cinfo->col_buf[i], orig, max_len); + cinfo->col_buf[i][max_len - 1] = '\0'; + cinfo->col_data[i] = cinfo->col_buf[i]; + } + } + va_end(ap); +} /* Use this if "str" points to something that won't stay around (and must thus be copied). */ diff --git a/epan/column-utils.h b/epan/column-utils.h index f5dda5c560..c80706084d 100644 --- a/epan/column-utils.h +++ b/epan/column-utils.h @@ -168,6 +168,17 @@ extern void col_append_fstr(column_info *cinfo, gint col, const gchar *format, . extern void col_prepend_fstr(column_info *cinfo, gint col, const gchar *format, ...) GNUC_FORMAT_CHECK(printf, 3, 4); +/**Prepend the given text to a column element, the text will be formatted and copied. + * This function is similar to col_prepend_fstr() but this function will + * unconditionally set a fence to the end of the prepended data even if there + * were no fence before. + * The col_prepend_fstr() will only prepend the data before the fence IFF + * there is already a fence created. This function will create a fence in case + * it does not yet exist. + */ +extern void col_prepend_fence_fstr(column_info *cinfo, gint col, const gchar *format, ...) + GNUC_FORMAT_CHECK(printf, 3, 4); + /** Append the given text (prepended by a separator) to a column element. * * Much like col_append_str() but will prepend the given separator if the column isn't empty. diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index b44f085b30..514b651144 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -400,7 +400,7 @@ print_pdu_tracking_data(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tcp_tree, proto_item *item; if (check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", tnp->first_frame); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", tnp->first_frame); } item=proto_tree_add_uint(tcp_tree, hf_tcp_continuation_to, tvb, 0, 0, tnp->first_frame); @@ -1309,7 +1309,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Retransmission (suspected)"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Retransmission] "); } if( ta->rto_ts.secs || ta->rto_ts.nsecs ){ item = proto_tree_add_time(flags_tree, hf_tcp_analysis_rto, @@ -1326,7 +1326,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_retransmission, tvb, 0, 0, "This frame is a (suspected) retransmission"); PROTO_ITEM_SET_GENERATED(flags_item); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Fast Retransmission] "); } } if( ta->flags&TCP_A_OUT_OF_ORDER ){ @@ -1334,7 +1334,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Out-Of-Order segment"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Out-Of-Order] "); } } if( ta->flags&TCP_A_LOST_PACKET ){ @@ -1342,7 +1342,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "Previous segment lost (common at capture start)"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Previous segment lost] "); } } if( ta->flags&TCP_A_ACK_LOST_PACKET ){ @@ -1350,7 +1350,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_WARN, "ACKed lost segment (common at capture start)"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ACKed lost segment] "); } } if( ta->flags&TCP_A_WINDOW_UPDATE ){ @@ -1358,7 +1358,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window update"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Update] "); } } if( ta->flags&TCP_A_WINDOW_FULL ){ @@ -1366,7 +1366,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Window is full"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Window Full] "); } } if( ta->flags&TCP_A_KEEP_ALIVE ){ @@ -1374,7 +1374,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive] "); } } if( ta->flags&TCP_A_KEEP_ALIVE_ACK ){ @@ -1382,7 +1382,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Keep-Alive ACK"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Keep-Alive ACK] "); } } if( ta->dupack_num){ @@ -1390,7 +1390,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree flags_item=proto_tree_add_none_format(flags_tree, hf_tcp_analysis_duplicate_ack, tvb, 0, 0, "This is a TCP duplicate ack"); PROTO_ITEM_SET_GENERATED(flags_item); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP Dup ACK %u#%u] ", ta->dupack_frame, ta->dupack_num); } } flags_item=proto_tree_add_uint(tree, hf_tcp_analysis_duplicate_ack_num, @@ -1407,7 +1407,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window probe"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowProbe] "); } } if( ta->flags&TCP_A_ZERO_WINDOW ){ @@ -1415,7 +1415,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindow] "); } } if( ta->flags&TCP_A_ZERO_WINDOW_VIOLATION ){ @@ -1423,7 +1423,7 @@ tcp_print_sequence_number_analysis(packet_info *pinfo, tvbuff_t *tvb, proto_tree PROTO_ITEM_SET_GENERATED(flags_item); expert_add_info_format(pinfo, flags_item, PI_SEQUENCE, PI_NOTE, "Zero window violation"); if(check_col(pinfo->cinfo, COL_INFO)){ - col_prepend_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowViolation] "); + col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[TCP ZeroWindowViolation] "); } } } diff --git a/epan/libethereal.def b/epan/libethereal.def index 801c3b3b6e..5114395919 100644 --- a/epan/libethereal.def +++ b/epan/libethereal.def @@ -73,6 +73,7 @@ col_format_desc col_format_to_string col_get_writable col_prepend_fstr +col_prepend_fence_fstr col_setup col_set_cls_time col_set_fence