diff options
Diffstat (limited to 'epan/dissectors/packet-udp.c')
-rw-r--r-- | epan/dissectors/packet-udp.c | 317 |
1 files changed, 166 insertions, 151 deletions
diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c index 4dc2dff9..8d5b7f29 100644 --- a/epan/dissectors/packet-udp.c +++ b/epan/dissectors/packet-udp.c @@ -43,124 +43,126 @@ static dissector_handle_t udplite_handle; static capture_dissector_handle_t udp_cap_handle; static capture_dissector_handle_t udplite_cap_handle; -static int udp_tap = -1; -static int udp_follow_tap = -1; -static int exported_pdu_tap = -1; - -static int proto_udp = -1; -static int proto_udplite = -1; - -static int hf_udp_checksum = -1; -static int hf_udp_checksum_calculated = -1; -static int hf_udp_checksum_status = -1; -static int hf_udp_dstport = -1; -static int hf_udp_length = -1; -static int hf_udp_payload = -1; -static int hf_udp_pdu_size = -1; -static int hf_udp_port = -1; -static int hf_udp_proc_dst_cmd = -1; -static int hf_udp_proc_dst_pid = -1; -static int hf_udp_proc_dst_uid = -1; -static int hf_udp_proc_dst_uname = -1; -static int hf_udp_proc_src_cmd = -1; -static int hf_udp_proc_src_pid = -1; -static int hf_udp_proc_src_uid = -1; -static int hf_udp_proc_src_uname = -1; -static int hf_udp_srcport = -1; -static int hf_udp_stream = -1; -static int hf_udp_ts_delta = -1; -static int hf_udp_ts_relative = -1; -static int hf_udplite_checksum_coverage = -1; - -static gint ett_udp = -1; -static gint ett_udp_checksum = -1; -static gint ett_udp_process_info = -1; -static gint ett_udp_timestamps = -1; - -static expert_field ei_udp_possible_traceroute = EI_INIT; -static expert_field ei_udp_length_bad = EI_INIT; -static expert_field ei_udplite_checksum_coverage_bad = EI_INIT; -static expert_field ei_udp_checksum_zero = EI_INIT; -static expert_field ei_udp_checksum_partial = EI_INIT; -static expert_field ei_udp_checksum_bad = EI_INIT; -static expert_field ei_udp_length_bad_zero = EI_INIT; +static int udp_tap; +static int udp_follow_tap; +static int exported_pdu_tap; + +static int proto_udp; +static int proto_udplite; + +static int hf_udp_checksum; +static int hf_udp_checksum_calculated; +static int hf_udp_checksum_status; +static int hf_udp_dstport; +static int hf_udp_length; +static int hf_udp_payload; +static int hf_udp_pdu_size; +static int hf_udp_port; +static int hf_udp_proc_dst_cmd; +static int hf_udp_proc_dst_pid; +static int hf_udp_proc_dst_uid; +static int hf_udp_proc_dst_uname; +static int hf_udp_proc_src_cmd; +static int hf_udp_proc_src_pid; +static int hf_udp_proc_src_uid; +static int hf_udp_proc_src_uname; +static int hf_udp_srcport; +static int hf_udp_stream; +static int hf_udp_stream_pnum; +static int hf_udp_ts_delta; +static int hf_udp_ts_relative; +static int hf_udplite_checksum_coverage; + +static int ett_udp; +static int ett_udp_checksum; +static int ett_udp_process_info; +static int ett_udp_timestamps; + +static expert_field ei_udp_possible_traceroute; +static expert_field ei_udp_length_bad; +static expert_field ei_udplite_checksum_coverage_bad; +static expert_field ei_udp_checksum_zero; +static expert_field ei_udp_checksum_partial; +static expert_field ei_udp_checksum_bad; +static expert_field ei_udp_length_bad_zero; /* Preferences */ /* Place UDP summary in proto tree */ -static gboolean udp_summary_in_tree = TRUE; +static bool udp_summary_in_tree = true; /* Check UDP checksums */ -static gboolean udp_check_checksum = FALSE; +static bool udp_check_checksum; /* Ignore zero-value UDP checksums over IPv6 */ -static gboolean udp_ignore_ipv6_zero_checksum = FALSE; +static bool udp_ignore_ipv6_zero_checksum; /* Collect IPFIX process flow information */ -static gboolean udp_process_info = FALSE; +static bool udp_process_info; /* Ignore an invalid checksum coverage field for UDP-Lite */ -static gboolean udplite_ignore_checksum_coverage = TRUE; +static bool udplite_ignore_checksum_coverage = true; /* Check UDP-Lite checksums */ -static gboolean udplite_check_checksum = FALSE; +static bool udplite_check_checksum; static dissector_table_t udp_dissector_table; static heur_dissector_list_t heur_subdissector_list; -static guint32 udp_stream_count; +static uint32_t udp_stream_count; /* Determine if there is a sub-dissector and call it. This has been */ /* separated into a stand alone routine so other protocol dissectors */ /* can call to it, ie. socks */ -static gboolean try_heuristic_first = FALSE; +static bool try_heuristic_first; -static gboolean udp_calculate_ts = TRUE; -static gboolean udplite_calculate_ts = TRUE; +static bool udp_calculate_ts = true; +static bool udplite_calculate_ts = true; /* Per-packet-info for UDP */ typedef struct { heur_dtbl_entry_t *heur_dtbl_entry; nstime_t ts_delta; - gboolean ts_delta_valid; + bool ts_delta_valid; + uint32_t pnum; } udp_p_info_t; static void -udp_src_prompt(packet_info *pinfo, gchar *result) +udp_src_prompt(packet_info *pinfo, char *result) { - guint32 port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, + uint32_t port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_udp_srcport, pinfo->curr_layer_num)); snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "source (%u%s)", port, UTF8_RIGHTWARDS_ARROW); } -static gpointer +static void * udp_src_value(packet_info *pinfo) { return p_get_proto_data(pinfo->pool, pinfo, hf_udp_srcport, pinfo->curr_layer_num); } static void -udp_dst_prompt(packet_info *pinfo, gchar *result) +udp_dst_prompt(packet_info *pinfo, char *result) { - guint32 port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, + uint32_t port = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_udp_dstport, pinfo->curr_layer_num)); snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "destination (%s%u)", UTF8_RIGHTWARDS_ARROW, port); } -static gpointer +static void * udp_dst_value(packet_info *pinfo) { return p_get_proto_data(pinfo->pool, pinfo, hf_udp_dstport, pinfo->curr_layer_num); } static void -udp_both_prompt(packet_info *pinfo, gchar *result) +udp_both_prompt(packet_info *pinfo, char *result) { - guint32 srcport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, + uint32_t srcport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_udp_srcport, pinfo->curr_layer_num)); - guint32 dstport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, + uint32_t dstport = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, hf_udp_dstport, pinfo->curr_layer_num)); snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Both (%u%s%u)", srcport, UTF8_LEFT_RIGHT_ARROW, dstport); } @@ -343,41 +345,26 @@ udpip_endpoint_packet(void *pit, packet_info *pinfo, epan_dissect_t *edt _U_, co /* Take two "add" passes per packet, adding for each direction, ensures that all packets are counted properly (even if address is sending to itself) XXX - this could probably be done more efficiently inside endpoint_table */ - add_endpoint_table_data(hash, &udphdr->ip_src, udphdr->uh_sport, TRUE, 1, pinfo->fd->pkt_len, &udp_endpoint_dissector_info, ENDPOINT_UDP); - add_endpoint_table_data(hash, &udphdr->ip_dst, udphdr->uh_dport, FALSE, 1, pinfo->fd->pkt_len, &udp_endpoint_dissector_info, ENDPOINT_UDP); + add_endpoint_table_data(hash, &udphdr->ip_src, udphdr->uh_sport, true, 1, pinfo->fd->pkt_len, &udp_endpoint_dissector_info, ENDPOINT_UDP); + add_endpoint_table_data(hash, &udphdr->ip_dst, udphdr->uh_dport, false, 1, pinfo->fd->pkt_len, &udp_endpoint_dissector_info, ENDPOINT_UDP); return TAP_PACKET_REDRAW; } -static gboolean +static bool udp_filter_valid(packet_info *pinfo, void *user_data _U_) { return proto_is_frame_protocol(pinfo->layers, "udp"); } -static gchar* -udp_build_filter(packet_info *pinfo, void *user_data _U_) +static char* +udp_build_filter_by_id(packet_info *pinfo, void *user_data _U_) { - if( pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4 ) { - /* UDP over IPv4 */ - return ws_strdup_printf("(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)", - address_to_str(pinfo->pool, &pinfo->net_src), - address_to_str(pinfo->pool, &pinfo->net_dst), - pinfo->srcport, pinfo->destport ); - } - - if( pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6 ) { - /* UDP over IPv6 */ - return ws_strdup_printf("(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)", - address_to_str(pinfo->pool, &pinfo->net_src), - address_to_str(pinfo->pool, &pinfo->net_dst), - pinfo->srcport, pinfo->destport ); - } - - return NULL; + return ws_strdup_printf("udp.stream eq %d", pinfo->stream_id); } -static gchar *udp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream _U_) + +static char *udp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, unsigned *stream, unsigned *sub_stream _U_) { conversation_t *conv; struct udp_analysis *udpd; @@ -388,10 +375,11 @@ static gchar *udp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo * Eventually the endpoint API should support storing multiple * endpoints and UDP should be changed to use the endpoint API. */ + conv = find_conversation_strat(pinfo, CONVERSATION_UDP, 0); if (((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) || (pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6)) && (pinfo->ptype == PT_UDP) && - (conv=find_conversation(pinfo->num, &pinfo->net_src, &pinfo->net_dst, CONVERSATION_UDP, pinfo->srcport, pinfo->destport, 0)) != NULL) + conv != NULL) { /* UDP over IPv4/6 */ udpd=get_udp_conversation_data(conv, pinfo); @@ -405,16 +393,16 @@ static gchar *udp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo return NULL; } -static gchar *udp_follow_index_filter(guint stream, guint sub_stream _U_) +static char *udp_follow_index_filter(unsigned stream, unsigned sub_stream _U_) { return ws_strdup_printf("udp.stream eq %u", stream); } -static gchar *udp_follow_address_filter(address *src_addr, address *dst_addr, int src_port, int dst_port) +static char *udp_follow_address_filter(address *src_addr, address *dst_addr, int src_port, int dst_port) { - const gchar *ip_version = src_addr->type == AT_IPv6 ? "v6" : ""; - gchar src_addr_str[WS_INET6_ADDRSTRLEN]; - gchar dst_addr_str[WS_INET6_ADDRSTRLEN]; + const char *ip_version = src_addr->type == AT_IPv6 ? "v6" : ""; + char src_addr_str[WS_INET6_ADDRSTRLEN]; + char dst_addr_str[WS_INET6_ADDRSTRLEN]; address_to_str_buf(src_addr, src_addr_str, sizeof(src_addr_str)); address_to_str_buf(dst_addr, dst_addr_str, sizeof(dst_addr_str)); @@ -434,9 +422,9 @@ static gchar *udp_follow_address_filter(address *src_addr, address *dst_addr, in /* Attach process info to a flow */ /* XXX - We depend on the UDP dissector finding the conversation first */ void -add_udp_process_info(guint32 frame_num, address *local_addr, address *remote_addr, - guint16 local_port, guint16 remote_port, guint32 uid, guint32 pid, - gchar *username, gchar *command) +add_udp_process_info(uint32_t frame_num, address *local_addr, address *remote_addr, + uint16_t local_port, uint16_t remote_port, uint32_t uid, uint32_t pid, + char *username, char *command) { conversation_t *conv; struct udp_analysis *udpd; @@ -474,13 +462,13 @@ add_udp_process_info(guint32 frame_num, address *local_addr, address *remote_add /* Return the current stream count */ -guint32 get_udp_stream_count(void) +uint32_t get_udp_stream_count(void) { return udp_stream_count; } static void -handle_export_pdu_dissection_table(packet_info *pinfo, tvbuff_t *tvb, guint32 port) +handle_export_pdu_dissection_table(packet_info *pinfo, tvbuff_t *tvb, uint32_t port) { if (have_tap_listener(exported_pdu_tap)) { exp_pdu_data_item_t exp_pdu_data_table_value = {exp_pdu_data_dissector_table_num_value_size, exp_pdu_data_dissector_table_num_value_populate_data, NULL}; @@ -558,14 +546,14 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, { tvbuff_t *next_tvb; int low_port, high_port; - gboolean try_low_port, try_high_port; - gint len, reported_len; + bool try_low_port, try_high_port; + int len, reported_len; udp_p_info_t *udp_p_info; /* Save curr_layer_num as it might be changed by subdissector */ - guint8 curr_layer_num = pinfo->curr_layer_num; + uint8_t curr_layer_num = pinfo->curr_layer_num; heur_dtbl_entry_t *hdtbl_entry; exp_pdu_data_t *exp_pdu_data; - proto_tree* tree = proto_tree_get_root(udp_tree); + proto_tree* tree = proto_tree_get_parent_tree(udp_tree); /* populate per packet data variable */ udp_p_info = (udp_p_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_udp, pinfo->curr_layer_num); @@ -624,7 +612,7 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, high_port = uh_dport; } - try_low_port = FALSE; + try_low_port = false; if (low_port != 0) { if (dissector_is_uint_changed(udp_dissector_table, low_port)) { if (dissector_try_uint(udp_dissector_table, low_port, next_tvb, pinfo, tree)) { @@ -634,11 +622,11 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, } else { /* The default; try it later */ - try_low_port = TRUE; + try_low_port = true; } } - try_high_port = FALSE; + try_high_port = false; if (high_port != 0) { if (dissector_is_uint_changed(udp_dissector_table, high_port)) { if (dissector_try_uint(udp_dissector_table, high_port, next_tvb, pinfo, tree)) { @@ -648,7 +636,7 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, } else { /* The default; try it later */ - try_high_port = TRUE; + try_high_port = true; } } @@ -719,19 +707,19 @@ decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo, int udp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, - guint fixed_len, gboolean (*heuristic_check)(packet_info *, tvbuff_t *, int, void*), - guint (*get_pdu_len)(packet_info *, tvbuff_t *, int, void*), + unsigned fixed_len, bool (*heuristic_check)(packet_info *, tvbuff_t *, int, void*), + unsigned (*get_pdu_len)(packet_info *, tvbuff_t *, int, void*), dissector_t dissect_pdu, void* dissector_data) { volatile int offset = 0; int offset_before; - guint captured_length_remaining; - volatile guint plen; - guint length; + unsigned captured_length_remaining; + volatile unsigned plen; + unsigned length; tvbuff_t *next_tvb; proto_item *item=NULL; const char *saved_proto; - guint8 curr_layer_num; + uint8_t curr_layer_num; wmem_list_frame_t *frame; while (tvb_reported_length_remaining(tvb, offset) > 0) { @@ -752,7 +740,7 @@ udp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * If there is a heuristic function, check it */ if ((heuristic_check != NULL) && - ((*heuristic_check)(pinfo, tvb, offset, dissector_data) == FALSE)) { + ((*heuristic_check)(pinfo, tvb, offset, dissector_data) == false)) { return offset; } @@ -790,7 +778,7 @@ udp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, curr_layer_num = pinfo->curr_layer_num-1; frame = wmem_list_frame_prev(wmem_list_tail(pinfo->layers)); - while (frame && (proto_udp != (gint) GPOINTER_TO_UINT(wmem_list_frame_data(frame)))) { + while (frame && (proto_udp != (int) GPOINTER_TO_UINT(wmem_list_frame_data(frame)))) { frame = wmem_list_frame_prev(frame); curr_layer_num--; } @@ -856,13 +844,13 @@ udp_dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, return offset; } -static gboolean -capture_udp(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_) +static bool +capture_udp(const unsigned char *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_) { - guint16 src_port, dst_port, low_port, high_port; + uint16_t src_port, dst_port, low_port, high_port; if (!BYTES_ARE_IN_FRAME(offset, len, 4)) - return FALSE; + return false; capture_dissector_increment_count(cpinfo, proto_udp); @@ -879,13 +867,13 @@ capture_udp(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_in } if (low_port != 0 && try_capture_dissector("udp.port", low_port, pd, offset+20, len, cpinfo, pseudo_header)) - return TRUE; + return true; if (high_port != 0 && try_capture_dissector("udp.port", high_port, pd, offset+20, len, cpinfo, pseudo_header)) - return TRUE; + return true; /* We've at least identified one type of packet, so this shouldn't be "other" */ - return TRUE; + return true; } /* Calculate the timestamps relative to this conversation */ @@ -903,8 +891,11 @@ udp_compute_timestamps(packet_info *pinfo, struct udp_analysis *udp_data, int pr p_add_proto_data(wmem_file_scope(), pinfo, proto, pinfo->curr_layer_num, udp_per_packet_data); } + /* pre-increment so packet numbers start at 1 */ + udp_per_packet_data->pnum = ++udp_data->pnum; + nstime_delta(&udp_per_packet_data->ts_delta, &pinfo->abs_ts, &udp_data->ts_prev); - udp_per_packet_data->ts_delta_valid = TRUE; + udp_per_packet_data->ts_delta_valid = true; udp_data->ts_prev = pinfo->abs_ts; } @@ -923,6 +914,12 @@ udp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, /* get per packet date for UDP/UDP-Lite based on protocol id */ udp_p_info_t *udp_per_packet_data = (udp_p_info_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto, pinfo->curr_layer_num); + if (udp_per_packet_data) { + item = proto_tree_add_uint(parent_tree, hf_udp_stream_pnum, tvb, 0, 0, + udp_per_packet_data->pnum); + proto_item_set_generated(item); + } + tree = proto_tree_add_subtree(parent_tree, tvb, 0, 0, ett_udp_timestamps, &item, "Timestamps"); proto_item_set_generated(item); @@ -938,7 +935,7 @@ udp_print_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent_tree, } static void -udp_handle_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, struct udp_analysis *udp_data, guint32 ip_proto) +udp_handle_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, struct udp_analysis *udp_data, uint32_t ip_proto) { int proto_id = (ip_proto == IP_PROTO_UDP ? proto_udp : proto_udplite); @@ -954,23 +951,23 @@ udp_handle_timestamps(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, struc } static void -dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) +dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ip_proto) { proto_tree *udp_tree = NULL; proto_item *ti, *item, *hidden_item, *calc_item; proto_item *src_port_item, *dst_port_item, *len_cov_item; - guint len; - guint reported_len; + unsigned len; + unsigned reported_len; vec_t cksum_vec[4]; - guint32 phdr[2]; - guint16 computed_cksum; + uint32_t phdr[2]; + uint16_t computed_cksum; int offset = 0; e_udphdr *udph; proto_tree *checksum_tree; conversation_t *conv = NULL; struct udp_analysis *udpd = NULL; proto_tree *process_tree; - gboolean udp_jumbogram = FALSE; + bool udp_jumbogram = false; udph = wmem_new0(pinfo->pool, e_udphdr); udph->uh_sport = tvb_get_ntohs(tvb, offset); @@ -986,7 +983,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) len = tvb_captured_length(tvb); ti = proto_tree_add_item(tree, (ip_proto == IP_PROTO_UDP) ? proto_udp : proto_udplite, tvb, offset, 8, ENC_NA); - if (udp_summary_in_tree) { + if (udp_summary_in_tree && tree) { proto_item_append_text(ti, ", Src Port: %s, Dst Port: %s", port_with_resolution_to_str(pinfo->pool, PT_UDP, udph->uh_sport), port_with_resolution_to_str(pinfo->pool, PT_UDP, udph->uh_dport)); @@ -1024,7 +1021,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) if (udph->uh_ulen == 0 && pinfo->src.type == AT_IPv6) { /* RFC 2675 (section 4) - UDP Jumbograms */ udph->uh_ulen = udph->uh_sum_cov = reported_len; - udp_jumbogram = TRUE; + udp_jumbogram = true; } if (udph->uh_ulen < 8) { /* Bogus length - it includes the header, so it must be >= 8. */ @@ -1073,8 +1070,10 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) if (udph->uh_sum == 0) { /* No checksum supplied in the packet. */ - gboolean ignore_zero_checksum = (ip_proto == IP_PROTO_UDP) && - ((pinfo->src.type == AT_IPv4) || ((pinfo->src.type == AT_IPv6) && udp_ignore_ipv6_zero_checksum)); + bool ignore_zero_checksum = (ip_proto == IP_PROTO_UDP) && + ((pinfo->src.type == AT_IPv4) || + (pinfo->src.type == AT_NONE) || + ((pinfo->src.type == AT_IPv6) && udp_ignore_ipv6_zero_checksum)); proto_checksum_enum_e checksum_status; item = proto_tree_add_item(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, ENC_BIG_ENDIAN); @@ -1103,8 +1102,8 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) if (((ip_proto == IP_PROTO_UDP) && udp_check_checksum) || ((ip_proto == IP_PROTO_UDPLITE) && udplite_check_checksum)) { /* Set up the fields of the pseudo-header. */ - SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len); - SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len); + SET_CKSUM_VEC_PTR(cksum_vec[0], (const uint8_t *)pinfo->src.data, pinfo->src.len); + SET_CKSUM_VEC_PTR(cksum_vec[1], (const uint8_t *)pinfo->dst.data, pinfo->dst.len); switch (pinfo->src.type) { case AT_IPv4: @@ -1112,7 +1111,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) phdr[0] = g_htonl((ip_proto<<16) | udph->uh_ulen); else phdr[0] = g_htonl((ip_proto<<16) | reported_len); - SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 4); + SET_CKSUM_VEC_PTR(cksum_vec[2], (const uint8_t *)&phdr, 4); break; case AT_IPv6: @@ -1121,7 +1120,7 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) else phdr[0] = g_htonl(reported_len); phdr[1] = g_htonl(ip_proto); - SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8); + SET_CKSUM_VEC_PTR(cksum_vec[2], (const uint8_t *)&phdr, 8); break; default: @@ -1218,8 +1217,12 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) pinfo->srcport = udph->uh_sport; pinfo->destport = udph->uh_dport; - /* find(or create if needed) the conversation for this udp session */ - conv = find_or_create_conversation(pinfo); + /* find (and extend) an existing conversation, or create a new one */ + conv = find_conversation_strat(pinfo, CONVERSATION_UDP, 0); + if(!conv) { + conv=conversation_new_strat(pinfo, CONVERSATION_UDP, 0); + } + udpd = get_udp_conversation_data(conv, pinfo); if (udpd) { item = proto_tree_add_uint(udp_tree, hf_udp_stream, tvb, offset, 0, udpd->stream); @@ -1229,6 +1232,12 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) * to tap listeners. */ udph->uh_stream = udpd->stream; + + /* Copy the stream index into pinfo as well to make it available + * to callback functions (essentially conversation following events in GUI) + */ + pinfo->stream_id = udpd->stream; + } tap_queue_packet(udp_tap, pinfo, udph); @@ -1250,11 +1259,6 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) } } - if (udph->uh_ulen == 8) { - /* Empty UDP payload, nothing left to do. */ - return; - } - /* Do we need to calculate timestamps relative to the udp-stream? */ /* Different boolean preferences have to be checked. */ /* If the protocol is UDP then the UDP preference */ @@ -1265,6 +1269,11 @@ dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto) udp_handle_timestamps(pinfo, tvb, udp_tree, udpd, ip_proto); } + if (udph->uh_ulen == 8) { + /* Empty UDP payload, nothing left to do. */ + return; + } + /* * Call sub-dissectors. * @@ -1325,6 +1334,11 @@ proto_register_udp(void) FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } }, + { &hf_udp_stream_pnum, + { "Stream Packet Number", "udp.stream.pnum", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Relative packet number in this UDP stream", HFILL } + }, { &hf_udp_length, { "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0, @@ -1415,7 +1429,7 @@ proto_register_udp(void) }, }; - static gint *ett[] = { + static int *ett[] = { &ett_udp, &ett_udp_checksum, &ett_udp_process_info, @@ -1459,7 +1473,7 @@ proto_register_udp(void) /* subdissector code */ udp_dissector_table = register_dissector_table("udp.port", "UDP port", proto_udp, FT_UINT16, BASE_DEC); - heur_subdissector_list = register_heur_dissector_list("udp", proto_udp); + heur_subdissector_list = register_heur_dissector_list_with_description("udp", "UDP heuristic", proto_udp); register_capture_dissector_table("udp.port", "UDP"); @@ -1487,8 +1501,8 @@ proto_register_udp(void) "Collect process flow information from IPFIX", &udp_process_info); prefs_register_bool_preference(udp_module, "calculate_timestamps", - "Calculate conversation timestamps", - "Calculate timestamps relative to the first frame and the previous frame in the udp conversation", + "Calculate stream packet number and timestamps", + "Calculate relative packet number and timestamps relative to the first frame and the previous frame in the udp conversation", &udp_calculate_ts); udplite_module = prefs_register_protocol(proto_udplite, NULL); @@ -1501,17 +1515,20 @@ proto_register_udp(void) "Whether to validate the UDP-Lite checksum", &udplite_check_checksum); prefs_register_bool_preference(udplite_module, "calculate_timestamps", - "Calculate conversation timestamps", - "Calculate timestamps relative to the first frame and the previous frame in the udp-lite conversation", + "Calculate stream packet number and timestamps", + "Calculate relative packet number and timestamps relative to the first frame and the previous frame in the udp-lite conversation", &udplite_calculate_ts); register_decode_as(&udp_da); - register_conversation_table(proto_udp, FALSE, udpip_conversation_packet, udpip_endpoint_packet); - register_conversation_filter("udp", "UDP", udp_filter_valid, udp_build_filter, NULL); + register_conversation_table(proto_udp, false, udpip_conversation_packet, udpip_endpoint_packet); + register_conversation_filter("udp", "UDP", udp_filter_valid, udp_build_filter_by_id, NULL); register_follow_stream(proto_udp, "udp_follow", udp_follow_conv_filter, udp_follow_index_filter, udp_follow_address_filter, udp_port_to_display, follow_tvb_tap_listener, get_udp_stream_count, NULL); register_init_routine(udp_init); + + udp_tap = register_tap("udp"); + udp_follow_tap = register_tap("udp_follow"); } void @@ -1524,8 +1541,6 @@ proto_reg_handoff_udp(void) capture_dissector_add_uint("ip.proto", IP_PROTO_UDP, udp_cap_handle); capture_dissector_add_uint("ip.proto", IP_PROTO_UDPLITE, udplite_cap_handle); - udp_tap = register_tap("udp"); - udp_follow_tap = register_tap("udp_follow"); exported_pdu_tap = find_tap_id(EXPORT_PDU_TAP_NAME_LAYER_4); } |