2 * Routines for UDP/UDPLite packet disassembly
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Richard Sharpe, 13-Feb-1999, added dispatch table support and
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #define NEW_PROTO_TREE_API
36 #include <epan/packet.h>
37 #include <epan/wmem/wmem.h>
38 #include <epan/addr_resolv.h>
39 #include <epan/ipproto.h>
40 #include <epan/in_cksum.h>
41 #include <epan/prefs.h>
42 #include <epan/expert.h>
44 #include "packet-udp.h"
46 #include "packet-ip.h"
47 #include <epan/conversation.h>
50 void proto_register_udp(void);
51 void proto_reg_handoff_udp(void);
53 static dissector_handle_t udp_handle
;
54 static dissector_handle_t udplite_handle
;
56 static int udp_tap
= -1;
57 static int udp_follow_tap
= -1;
59 static header_field_info
*hfi_udp
= NULL
;
60 static header_field_info
*hfi_udplite
= NULL
;
62 #define UDP_HFI_INIT HFI_INIT(proto_udp)
63 #define UDPLITE_HFI_INIT HFI_INIT(proto_udplite)
65 static header_field_info hfi_udp_srcport UDP_HFI_INIT
=
66 { "Source Port", "udp.srcport", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
69 static header_field_info hfi_udp_dstport UDP_HFI_INIT
=
70 { "Destination Port", "udp.dstport", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
73 static header_field_info hfi_udp_port UDP_HFI_INIT
=
74 { "Source or Destination Port", "udp.port", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
77 static header_field_info hfi_udp_length UDP_HFI_INIT
=
78 { "Length", "udp.length", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
81 static header_field_info hfi_udp_checksum UDP_HFI_INIT
=
82 { "Checksum", "udp.checksum", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
83 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL
};
85 static header_field_info hfi_udp_checksum_good UDP_HFI_INIT
=
86 { "Good Checksum", "udp.checksum_good", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
87 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL
};
89 static header_field_info hfi_udp_checksum_bad UDP_HFI_INIT
=
90 { "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
91 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL
};
93 static header_field_info hfi_udp_proc_src_uid UDP_HFI_INIT
=
94 { "Source process user ID", "udp.proc.srcuid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
97 static header_field_info hfi_udp_proc_src_pid UDP_HFI_INIT
=
98 { "Source process ID", "udp.proc.srcpid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
101 static header_field_info hfi_udp_proc_src_uname UDP_HFI_INIT
=
102 { "Source process user name", "udp.proc.srcuname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
105 static header_field_info hfi_udp_proc_src_cmd UDP_HFI_INIT
=
106 { "Source process name", "udp.proc.srccmd", FT_STRING
, BASE_NONE
, NULL
, 0x0,
107 "Source process command name", HFILL
};
109 static header_field_info hfi_udp_proc_dst_uid UDP_HFI_INIT
=
110 { "Destination process user ID", "udp.proc.dstuid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
113 static header_field_info hfi_udp_proc_dst_pid UDP_HFI_INIT
=
114 { "Destination process ID", "udp.proc.dstpid", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
117 static header_field_info hfi_udp_proc_dst_uname UDP_HFI_INIT
=
118 { "Destination process user name", "udp.proc.dstuname", FT_STRING
, BASE_NONE
, NULL
, 0x0,
121 static header_field_info hfi_udp_proc_dst_cmd UDP_HFI_INIT
=
122 { "Destination process name", "udp.proc.dstcmd", FT_STRING
, BASE_NONE
, NULL
, 0x0,
123 "Destination process command name", HFILL
};
125 static header_field_info hfi_udplite_checksum_coverage UDPLITE_HFI_INIT
=
126 { "Checksum coverage", "udp.checksum_coverage", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
129 static header_field_info hfi_udplite_checksum_coverage_bad UDPLITE_HFI_INIT
=
130 { "Bad Checksum coverage", "udp.checksum_coverage_bad", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
133 static gint ett_udp
= -1;
134 static gint ett_udp_checksum
= -1;
135 static gint ett_udp_process_info
= -1;
137 static expert_field ei_udp_possible_traceroute
= EI_INIT
;
138 static expert_field ei_udp_length
= EI_INIT
;
139 static expert_field ei_udplite_checksum_coverage
= EI_INIT
;
140 static expert_field ei_udp_checksum_zero
= EI_INIT
;
141 static expert_field ei_udp_checksum_bad
= EI_INIT
;
145 /* Place UDP summary in proto tree */
146 static gboolean udp_summary_in_tree
= TRUE
;
148 /* Check UDP checksums */
149 static gboolean udp_check_checksum
= FALSE
;
151 /* Collect IPFIX process flow information */
152 static gboolean udp_process_info
= FALSE
;
154 /* Ignore an invalid checksum coverage field for UDPLite */
155 static gboolean udplite_ignore_checksum_coverage
= TRUE
;
157 /* Check UDPLite checksums */
158 static gboolean udplite_check_checksum
= FALSE
;
160 static dissector_table_t udp_dissector_table
;
161 static heur_dissector_list_t heur_subdissector_list
;
162 static dissector_handle_t data_handle
;
164 /* Determine if there is a sub-dissector and call it. This has been */
165 /* separated into a stand alone routine so other protocol dissectors */
166 /* can call to it, ie. socks */
168 static gboolean try_heuristic_first
= FALSE
;
170 /* Per-packet-info for UDP */
173 gboolean found_heuristic
;
178 /* Conversation and process code originally copied from packet-tcp.c */
179 static struct udp_analysis
*
180 init_udp_conversation_data(void)
182 struct udp_analysis
*udpd
;
184 /* Initialize the udp protocol data structure to add to the udp conversation */
185 udpd
= wmem_new0(wmem_file_scope(), struct udp_analysis
);
187 udpd->flow1.username = NULL;
188 udpd->flow1.command = NULL;
189 udpd->flow2.username = NULL;
190 udpd->flow2.command = NULL;
196 static struct udp_analysis
*
197 get_udp_conversation_data(conversation_t
*conv
, packet_info
*pinfo
)
200 struct udp_analysis
*udpd
=NULL
;
202 /* Did the caller supply the conversation pointer? */
204 conv
= find_or_create_conversation(pinfo
);
206 /* Get the data for this conversation */
207 udpd
=(struct udp_analysis
*)conversation_get_proto_data(conv
, hfi_udp
->id
);
209 /* If the conversation was just created or it matched a
210 * conversation with template options, udpd will not
211 * have been initialized. So, initialize
212 * a new udpd structure for the conversation.
215 udpd
= init_udp_conversation_data();
216 conversation_add_proto_data(conv
, hfi_udp
->id
, udpd
);
223 /* check direction and get ua lists */
224 direction
=CMP_ADDRESS(&pinfo
->src
, &pinfo
->dst
);
225 /* if the addresses are equal, match the ports instead */
226 if (direction
== 0) {
227 direction
= (pinfo
->srcport
> pinfo
->destport
) ? 1 : -1;
229 if (direction
>= 0) {
230 udpd
->fwd
=&(udpd
->flow1
);
231 udpd
->rev
=&(udpd
->flow2
);
233 udpd
->fwd
=&(udpd
->flow2
);
234 udpd
->rev
=&(udpd
->flow1
);
240 /* Attach process info to a flow */
241 /* XXX - We depend on the UDP dissector finding the conversation first */
243 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
) {
244 conversation_t
*conv
;
245 struct udp_analysis
*udpd
;
246 udp_flow_t
*flow
= NULL
;
248 if (!udp_process_info
) {
252 conv
= find_conversation(frame_num
, local_addr
, remote_addr
, PT_UDP
, local_port
, remote_port
, 0);
257 udpd
= (struct udp_analysis
*)conversation_get_proto_data(conv
, hfi_udp
->id
);
262 if ((CMP_ADDRESS(local_addr
, &conv
->key_ptr
->addr1
) == 0) && (local_port
== conv
->key_ptr
->port1
)) {
264 } else if ((CMP_ADDRESS(remote_addr
, &conv
->key_ptr
->addr1
) == 0) && (remote_port
== conv
->key_ptr
->port1
)) {
267 if (!flow
|| flow
->command
) {
271 flow
->process_uid
= uid
;
272 flow
->process_pid
= pid
;
273 flow
->username
= wmem_strdup(wmem_file_scope(), username
);
274 flow
->command
= wmem_strdup(wmem_file_scope(), command
);
280 decode_udp_ports(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
281 proto_tree
*tree
, int uh_sport
, int uh_dport
, int uh_ulen
)
284 int low_port
, high_port
;
285 gint len
, reported_len
;
286 udp_p_info_t
*udp_p_info
= NULL
;
287 gboolean prev_heur_found
= FALSE
;
289 if (pinfo
->fd
->flags
.visited
) {
290 udp_p_info
= (udp_p_info_t
*)p_get_proto_data(pinfo
->fd
, hfi_udp
->id
, pinfo
->curr_layer_num
);
292 prev_heur_found
= udp_p_info
->found_heuristic
;
295 /* Force heuristic check on first pass */
296 prev_heur_found
= TRUE
;
299 len
= tvb_length_remaining(tvb
, offset
);
300 reported_len
= tvb_reported_length_remaining(tvb
, offset
);
302 /* This is the length from the UDP header; the payload should be cut
303 off at that length. (If our caller passed a value here, they
304 are assumed to have checked that it's >= 8, and hence >= offset.)
306 XXX - what if it's *greater* than the reported length? */
307 if ((uh_ulen
- offset
) < reported_len
)
308 reported_len
= uh_ulen
- offset
;
309 if (len
> reported_len
)
313 next_tvb
= tvb_new_subset(tvb
, offset
, len
, reported_len
);
315 /* If the user has a "Follow UDP Stream" window loading, pass a pointer
316 * to the payload tvb through the tap system. */
317 if (have_tap_listener(udp_follow_tap
))
318 tap_queue_packet(udp_follow_tap
, pinfo
, next_tvb
);
320 /* determine if this packet is part of a conversation and call dissector */
321 /* for the conversation if available */
323 if (try_conversation_dissector(&pinfo
->dst
, &pinfo
->src
, PT_UDP
,
324 uh_dport
, uh_sport
, next_tvb
, pinfo
, tree
, NULL
)) {
328 if (try_heuristic_first
&& prev_heur_found
) {
329 /* Do lookup with the heuristic subdissector table */
330 /* Save curr_layer_num as it might be changed by subdissector */
331 guint8 curr_layer_num
= pinfo
->curr_layer_num
;
332 if (dissector_try_heuristic(heur_subdissector_list
, next_tvb
, pinfo
, tree
, NULL
)) {
334 udp_p_info
= wmem_new0(wmem_file_scope(), udp_p_info_t
);
335 udp_p_info
->found_heuristic
= TRUE
;
336 p_add_proto_data(pinfo
->fd
, hfi_udp
->id
, curr_layer_num
, udp_p_info
);
342 /* Do lookups with the subdissector table.
343 We try the port number with the lower value first, followed by the
344 port number with the higher value. This means that, for packets
345 where a dissector is registered for *both* port numbers:
347 1) we pick the same dissector for traffic going in both directions;
349 2) we prefer the port number that's more likely to be the right
350 one (as that prefers well-known ports to reserved ports);
352 although there is, of course, no guarantee that any such strategy
353 will always pick the right port number.
355 XXX - we ignore port numbers of 0, as some dissectors use a port
356 number of 0 to disable the port, and as RFC 768 says that the source
357 port in UDP datagrams is optional and is 0 if not used. */
358 if (uh_sport
> uh_dport
) {
360 high_port
= uh_sport
;
363 high_port
= uh_dport
;
365 if ((low_port
!= 0) &&
366 dissector_try_uint(udp_dissector_table
, low_port
, next_tvb
, pinfo
, tree
))
368 if ((high_port
!= 0) &&
369 dissector_try_uint(udp_dissector_table
, high_port
, next_tvb
, pinfo
, tree
))
372 if (!try_heuristic_first
&& prev_heur_found
) {
373 /* Do lookup with the heuristic subdissector table */
374 /* Save curr_layer_num as it might be changed by subdissector */
375 guint8 curr_layer_num
= pinfo
->curr_layer_num
;
376 if (dissector_try_heuristic(heur_subdissector_list
, next_tvb
, pinfo
, tree
, NULL
)) {
378 udp_p_info
= wmem_new0(wmem_file_scope(), udp_p_info_t
);
379 udp_p_info
->found_heuristic
= TRUE
;
380 p_add_proto_data(pinfo
->fd
, hfi_udp
->id
, curr_layer_num
, udp_p_info
);
386 call_dissector(data_handle
,next_tvb
, pinfo
, tree
);
391 dissect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint32 ip_proto
)
393 proto_tree
*udp_tree
= NULL
;
394 proto_item
*ti
, *hidden_item
, *port_item
;
399 guint16 computed_cksum
;
402 proto_tree
*checksum_tree
;
404 conversation_t
*conv
= NULL
;
405 struct udp_analysis
*udpd
= NULL
;
406 proto_tree
*process_tree
;
408 udph
=wmem_new(wmem_packet_scope(), e_udphdr
);
409 SET_ADDRESS(&udph
->ip_src
, pinfo
->src
.type
, pinfo
->src
.len
, pinfo
->src
.data
);
410 SET_ADDRESS(&udph
->ip_dst
, pinfo
->dst
.type
, pinfo
->dst
.len
, pinfo
->dst
.data
);
412 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, (ip_proto
== IP_PROTO_UDP
) ? "UDP" : "UDPlite");
413 col_clear(pinfo
->cinfo
, COL_INFO
);
415 udph
->uh_sport
=tvb_get_ntohs(tvb
, offset
);
416 udph
->uh_dport
=tvb_get_ntohs(tvb
, offset
+2);
418 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Source port: %s Destination port: %s",
419 get_udp_port(udph
->uh_sport
), get_udp_port(udph
->uh_dport
));
422 if (udp_summary_in_tree
) {
423 if (ip_proto
== IP_PROTO_UDP
) {
424 ti
= proto_tree_add_protocol_format(tree
, hfi_udp
->id
, tvb
, offset
, 8,
425 "User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
426 get_udp_port(udph
->uh_sport
), udph
->uh_sport
, get_udp_port(udph
->uh_dport
), udph
->uh_dport
);
428 ti
= proto_tree_add_protocol_format(tree
, hfi_udplite
->id
, tvb
, offset
, 8,
429 "Lightweight User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
430 get_udp_port(udph
->uh_sport
), udph
->uh_sport
, get_udp_port(udph
->uh_dport
), udph
->uh_dport
);
433 ti
= proto_tree_add_item(tree
, (ip_proto
== IP_PROTO_UDP
) ? hfi_udp
: hfi_udplite
, tvb
, offset
, 8, ENC_NA
);
435 udp_tree
= proto_item_add_subtree(ti
, ett_udp
);
437 port_item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_srcport
.id
, tvb
, offset
, 2, udph
->uh_sport
,
438 "%s (%u)", get_udp_port(udph
->uh_sport
), udph
->uh_sport
);
439 /* The beginning port number, 32768 + 666 (33434), is from LBL's traceroute.c source code and this code
440 * further assumes that 3 attempts are made per hop */
441 if ((udph
->uh_sport
> (32768 + 666)) && (udph
->uh_sport
<= (32768 + 666 + 30)))
442 expert_add_info_format(pinfo
, port_item
, &ei_udp_possible_traceroute
, "Possible traceroute: hop #%u, attempt #%u",
443 ((udph
->uh_sport
- 32768 - 666 - 1) / 3) + 1,
444 ((udph
->uh_sport
- 32768 - 666 - 1) % 3) + 1
447 port_item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_dstport
.id
, tvb
, offset
+ 2, 2, udph
->uh_dport
,
448 "%s (%u)", get_udp_port(udph
->uh_dport
), udph
->uh_dport
);
449 if ((udph
->uh_dport
> (32768 + 666)) && (udph
->uh_dport
<= (32768 + 666 + 30)))
450 expert_add_info_format(pinfo
, port_item
, &ei_udp_possible_traceroute
, "Possible traceroute: hop #%u, attempt #%u",
451 ((udph
->uh_dport
- 32768 - 666 - 1) / 3) + 1,
452 ((udph
->uh_dport
- 32768 - 666 - 1) % 3) + 1
455 hidden_item
= proto_tree_add_uint(udp_tree
, &hfi_udp_port
, tvb
, offset
, 2, udph
->uh_sport
);
456 PROTO_ITEM_SET_HIDDEN(hidden_item
);
457 hidden_item
= proto_tree_add_uint(udp_tree
, &hfi_udp_port
, tvb
, offset
+2, 2, udph
->uh_dport
);
458 PROTO_ITEM_SET_HIDDEN(hidden_item
);
461 if (ip_proto
== IP_PROTO_UDP
) {
462 udph
->uh_ulen
= udph
->uh_sum_cov
= tvb_get_ntohs(tvb
, offset
+4);
463 if (udph
->uh_ulen
< 8) {
464 /* Bogus length - it includes the header, so it must be >= 8. */
465 /* XXX - should handle IPv6 UDP jumbograms (RFC 2675), where the length is zero */
466 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_length
.id
, tvb
, offset
+ 4, 2,
467 udph
->uh_ulen
, "%u (bogus, must be >= 8)", udph
->uh_ulen
);
468 expert_add_info_format(pinfo
, item
, &ei_udp_length
, "Bad length value %u < 8", udph
->uh_ulen
);
469 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [BAD UDP LENGTH %u < 8]", udph
->uh_ulen
);
472 if ((udph
->uh_ulen
> tvb_reported_length(tvb
)) && ! pinfo
->fragmented
&& ! pinfo
->flags
.in_error_pkt
) {
473 /* Bogus length - it goes past the end of the IP payload */
474 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_length
.id
, tvb
, offset
+ 4, 2,
475 udph
->uh_ulen
, "%u (bogus, payload length %u)", udph
->uh_ulen
, tvb_reported_length(tvb
));
476 expert_add_info_format(pinfo
, item
, &ei_udp_length
, "Bad length value %u > IP payload length", udph
->uh_ulen
);
477 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [BAD UDP LENGTH %u > IP PAYLOAD LENGTH]", udph
->uh_ulen
);
480 proto_tree_add_uint(udp_tree
, &hfi_udp_length
, tvb
, offset
+ 4, 2, udph
->uh_ulen
);
481 /* XXX - why is this here, given that this is UDP, not Lightweight UDP? */
482 hidden_item
= proto_tree_add_uint(udp_tree
, &hfi_udplite_checksum_coverage
, tvb
, offset
+ 4,
483 0, udph
->uh_sum_cov
);
484 PROTO_ITEM_SET_HIDDEN(hidden_item
);
488 udph
->uh_ulen
= tvb_reported_length(tvb
);
489 udph
->uh_sum_cov
= tvb_get_ntohs(tvb
, offset
+4);
490 if (((udph
->uh_sum_cov
> 0) && (udph
->uh_sum_cov
< 8)) || (udph
->uh_sum_cov
> udph
->uh_ulen
)) {
491 /* Bogus length - it includes the header, so it must be >= 8, and no larger then the IP payload size. */
493 hidden_item
= proto_tree_add_boolean(udp_tree
, &hfi_udplite_checksum_coverage_bad
, tvb
, offset
+ 4, 2, TRUE
);
494 PROTO_ITEM_SET_HIDDEN(hidden_item
);
495 hidden_item
= proto_tree_add_uint(udp_tree
, &hfi_udp_length
, tvb
, offset
+ 4, 0, udph
->uh_ulen
);
496 PROTO_ITEM_SET_HIDDEN(hidden_item
);
498 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udplite_checksum_coverage
.id
, tvb
, offset
+ 4, 2,
499 udph
->uh_sum_cov
, "%u (bogus, must be >= 8 and <= %u (ip.len-ip.hdr_len))",
500 udph
->uh_sum_cov
, udph
->uh_ulen
);
501 expert_add_info_format(pinfo
, item
, &ei_udplite_checksum_coverage
, "Bad checksum coverage length value %u < 8 or > %u",
502 udph
->uh_sum_cov
, udph
->uh_ulen
);
503 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [BAD LIGHTWEIGHT UDP CHECKSUM COVERAGE LENGTH %u < 8 or > %u]",
504 udph
->uh_sum_cov
, udph
->uh_ulen
);
505 if (!udplite_ignore_checksum_coverage
)
509 hidden_item
= proto_tree_add_uint(udp_tree
, &hfi_udp_length
, tvb
, offset
+ 4, 0, udph
->uh_ulen
);
510 PROTO_ITEM_SET_HIDDEN(hidden_item
);
511 proto_tree_add_uint(udp_tree
, &hfi_udplite_checksum_coverage
, tvb
, offset
+ 4, 2, udph
->uh_sum_cov
);
516 udph
->uh_sum_cov
= (udph
->uh_sum_cov
) ? udph
->uh_sum_cov
: udph
->uh_ulen
;
517 udph
->uh_sum
= tvb_get_ntohs(tvb
, offset
+6);
518 reported_len
= tvb_reported_length(tvb
);
519 len
= tvb_length(tvb
);
520 if (udph
->uh_sum
== 0) {
521 /* No checksum supplied in the packet. */
522 if ((ip_proto
== IP_PROTO_UDP
) && (pinfo
->src
.type
== AT_IPv4
)) {
523 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
, offset
+ 6, 2, 0,
526 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
527 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
528 offset
+ 6, 2, FALSE
);
529 PROTO_ITEM_SET_GENERATED(item
);
530 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
531 offset
+ 6, 2, FALSE
);
532 PROTO_ITEM_SET_GENERATED(item
);
534 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
, offset
+ 6, 2, 0,
535 "0x%04x (Illegal)", 0);
536 expert_add_info(pinfo
, item
, &ei_udp_checksum_zero
);
537 col_append_str(pinfo
->cinfo
, COL_INFO
, " [ILLEGAL CHECKSUM (0)]");
539 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
540 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
541 offset
+ 6, 2, FALSE
);
542 PROTO_ITEM_SET_GENERATED(item
);
543 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
544 offset
+ 6, 2, TRUE
);
545 PROTO_ITEM_SET_GENERATED(item
);
547 } else if (!pinfo
->fragmented
&& (len
>= reported_len
) &&
548 (len
>= udph
->uh_sum_cov
) && (reported_len
>= udph
->uh_sum_cov
) &&
549 (udph
->uh_sum_cov
>= 8)) {
550 /* The packet isn't part of a fragmented datagram and isn't
551 truncated, so we can checksum it.
552 XXX - make a bigger scatter-gather list once we do fragment
555 if (((ip_proto
== IP_PROTO_UDP
) && udp_check_checksum
) ||
556 ((ip_proto
== IP_PROTO_UDPLITE
) && udplite_check_checksum
)) {
557 /* Set up the fields of the pseudo-header. */
558 cksum_vec
[0].ptr
= (const guint8
*)pinfo
->src
.data
;
559 cksum_vec
[0].len
= pinfo
->src
.len
;
560 cksum_vec
[1].ptr
= (const guint8
*)pinfo
->dst
.data
;
561 cksum_vec
[1].len
= pinfo
->dst
.len
;
562 cksum_vec
[2].ptr
= (const guint8
*)&phdr
;
563 switch (pinfo
->src
.type
) {
566 if (ip_proto
== IP_PROTO_UDP
)
567 phdr
[0] = g_htonl((ip_proto
<<16) | udph
->uh_ulen
);
569 phdr
[0] = g_htonl((ip_proto
<<16) | reported_len
);
570 cksum_vec
[2].len
= 4;
574 if (ip_proto
== IP_PROTO_UDP
)
575 phdr
[0] = g_htonl(udph
->uh_ulen
);
577 phdr
[0] = g_htonl(reported_len
);
578 phdr
[1] = g_htonl(ip_proto
);
579 cksum_vec
[2].len
= 8;
583 /* UDP runs only atop IPv4 and IPv6.... */
584 DISSECTOR_ASSERT_NOT_REACHED();
587 cksum_vec
[3].ptr
= tvb_get_ptr(tvb
, offset
, udph
->uh_sum_cov
);
588 cksum_vec
[3].len
= udph
->uh_sum_cov
;
589 computed_cksum
= in_cksum(&cksum_vec
[0], 4);
590 if (computed_cksum
== 0) {
591 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
,
592 offset
+ 6, 2, udph
->uh_sum
, "0x%04x [correct]", udph
->uh_sum
);
594 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
595 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
596 offset
+ 6, 2, TRUE
);
597 PROTO_ITEM_SET_GENERATED(item
);
598 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
599 offset
+ 6, 2, FALSE
);
600 PROTO_ITEM_SET_GENERATED(item
);
602 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
,
603 offset
+ 6, 2, udph
->uh_sum
,
604 "0x%04x [incorrect, should be 0x%04x (maybe caused by \"UDP checksum offload\"?)]", udph
->uh_sum
,
605 in_cksum_shouldbe(udph
->uh_sum
, computed_cksum
));
607 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
608 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
609 offset
+ 6, 2, FALSE
);
610 PROTO_ITEM_SET_GENERATED(item
);
611 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
612 offset
+ 6, 2, TRUE
);
613 PROTO_ITEM_SET_GENERATED(item
);
614 expert_add_info(pinfo
, item
, &ei_udp_checksum_bad
);
616 col_append_str(pinfo
->cinfo
, COL_INFO
, " [UDP CHECKSUM INCORRECT]");
619 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
,
620 offset
+ 6, 2, udph
->uh_sum
, "0x%04x [validation disabled]", udph
->uh_sum
);
621 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
622 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
623 offset
+ 6, 2, FALSE
);
624 PROTO_ITEM_SET_GENERATED(item
);
625 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
626 offset
+ 6, 2, FALSE
);
627 PROTO_ITEM_SET_GENERATED(item
);
630 item
= proto_tree_add_uint_format_value(udp_tree
, hfi_udp_checksum
.id
, tvb
,
631 offset
+ 6, 2, udph
->uh_sum
, "0x%04x [unchecked, not all data available]", udph
->uh_sum
);
633 checksum_tree
= proto_item_add_subtree(item
, ett_udp_checksum
);
634 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_good
, tvb
,
635 offset
+ 6, 2, FALSE
);
636 PROTO_ITEM_SET_GENERATED(item
);
637 item
= proto_tree_add_boolean(checksum_tree
, &hfi_udp_checksum_bad
, tvb
,
638 offset
+ 6, 2, FALSE
);
639 PROTO_ITEM_SET_GENERATED(item
);
642 /* Skip over header */
645 pinfo
->ptype
= PT_UDP
;
646 pinfo
->srcport
= udph
->uh_sport
;
647 pinfo
->destport
= udph
->uh_dport
;
649 tap_queue_packet(udp_tap
, pinfo
, udph
);
651 /* find(or create if needed) the conversation for this udp session */
652 if (udp_process_info
) {
653 conv
=find_or_create_conversation(pinfo
);
654 udpd
=get_udp_conversation_data(conv
,pinfo
);
657 if (udpd
&& ((udpd
->fwd
&& udpd
->fwd
->command
) || (udpd
->rev
&& udpd
->rev
->command
))) {
658 ti
= proto_tree_add_text(udp_tree
, tvb
, offset
, 0, "Process Information");
659 PROTO_ITEM_SET_GENERATED(ti
);
660 process_tree
= proto_item_add_subtree(ti
, ett_udp_process_info
);
661 if (udpd
->fwd
&& udpd
->fwd
->command
) {
662 proto_tree_add_uint_format_value(process_tree
, hfi_udp_proc_dst_uid
.id
, tvb
, 0, 0,
663 udpd
->fwd
->process_uid
, "%u", udpd
->fwd
->process_uid
);
664 proto_tree_add_uint_format_value(process_tree
, hfi_udp_proc_dst_pid
.id
, tvb
, 0, 0,
665 udpd
->fwd
->process_pid
, "%u", udpd
->fwd
->process_pid
);
666 proto_tree_add_string_format_value(process_tree
, hfi_udp_proc_dst_uname
.id
, tvb
, 0, 0,
667 udpd
->fwd
->username
, "%s", udpd
->fwd
->username
);
668 proto_tree_add_string_format_value(process_tree
, hfi_udp_proc_dst_cmd
.id
, tvb
, 0, 0,
669 udpd
->fwd
->command
, "%s", udpd
->fwd
->command
);
671 if (udpd
->rev
->command
) {
672 proto_tree_add_uint_format_value(process_tree
, hfi_udp_proc_src_uid
.id
, tvb
, 0, 0,
673 udpd
->rev
->process_uid
, "%u", udpd
->rev
->process_uid
);
674 proto_tree_add_uint_format_value(process_tree
, hfi_udp_proc_src_pid
.id
, tvb
, 0, 0,
675 udpd
->rev
->process_pid
, "%u", udpd
->rev
->process_pid
);
676 proto_tree_add_string_format_value(process_tree
, hfi_udp_proc_src_uname
.id
, tvb
, 0, 0,
677 udpd
->rev
->username
, "%s", udpd
->rev
->username
);
678 proto_tree_add_string_format_value(process_tree
, hfi_udp_proc_src_cmd
.id
, tvb
, 0, 0,
679 udpd
->rev
->command
, "%s", udpd
->rev
->command
);
684 * Call sub-dissectors.
686 * XXX - should we do this if this is included in an error packet?
687 * It might be nice to see the details of the packet that caused the
688 * ICMP error, but it might not be nice to have the dissector update
690 * Also, we probably don't want to run UDP taps on those packets.
692 * We definitely don't want to do it for an error packet if there's
693 * nothing left in the packet.
695 if (!pinfo
->flags
.in_error_pkt
|| (tvb_length_remaining(tvb
, offset
) > 0))
696 decode_udp_ports(tvb
, offset
, pinfo
, tree
, udph
->uh_sport
, udph
->uh_dport
,
701 dissect_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
703 dissect(tvb
, pinfo
, tree
, IP_PROTO_UDP
);
707 dissect_udplite(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
709 dissect(tvb
, pinfo
, tree
, IP_PROTO_UDPLITE
);
713 proto_register_udp(void)
715 module_t
*udp_module
;
716 module_t
*udplite_module
;
717 expert_module_t
* expert_udp
;
719 #ifndef HAVE_HFI_SECTION_INIT
720 static header_field_info
*hfi
[] = {
726 &hfi_udp_checksum_good
,
727 &hfi_udp_checksum_bad
,
728 &hfi_udp_proc_src_uid
,
729 &hfi_udp_proc_src_pid
,
730 &hfi_udp_proc_src_uname
,
731 &hfi_udp_proc_src_cmd
,
732 &hfi_udp_proc_dst_uid
,
733 &hfi_udp_proc_dst_pid
,
734 &hfi_udp_proc_dst_uname
,
735 &hfi_udp_proc_dst_cmd
,
738 static header_field_info
*hfi_lite
[] = {
739 &hfi_udplite_checksum_coverage_bad
,
740 &hfi_udplite_checksum_coverage
,
744 static gint
*ett
[] = {
747 &ett_udp_process_info
750 static ei_register_info ei
[] = {
751 { &ei_udp_possible_traceroute
, { "udp.possible_traceroute", PI_SEQUENCE
, PI_CHAT
, "Possible traceroute", EXPFILL
}},
752 { &ei_udp_length
, { "udp.length.bad", PI_MALFORMED
, PI_ERROR
, "Bad length value", EXPFILL
}},
753 { &ei_udplite_checksum_coverage
, { "udp.checksum_coverage.expert", PI_MALFORMED
, PI_ERROR
, "Bad checksum coverage length value", EXPFILL
}},
754 { &ei_udp_checksum_zero
, { "udp.checksum.zero", PI_CHECKSUM
, PI_ERROR
, "Illegal Checksum value (0)", EXPFILL
}},
755 { &ei_udp_checksum_bad
, { "udp.checksum_bad.expert", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
758 int proto_udp
, proto_udplite
;
760 proto_udp
= proto_register_protocol("User Datagram Protocol",
762 hfi_udp
= proto_registrar_get_nth(proto_udp
);
763 udp_handle
= register_dissector("udp", dissect_udp
, proto_udp
);
764 expert_udp
= expert_register_protocol(proto_udp
);
765 proto_register_fields(proto_udp
, hfi
, array_length(hfi
));
767 proto_udplite
= proto_register_protocol("Lightweight User Datagram Protocol",
768 "UDPlite", "udplite");
769 udplite_handle
= create_dissector_handle(dissect_udplite
, proto_udplite
);
770 hfi_udplite
= proto_registrar_get_nth(proto_udplite
);
771 proto_register_fields(proto_udplite
, hfi_lite
, array_length(hfi_lite
));
773 proto_register_subtree_array(ett
, array_length(ett
));
774 expert_register_field_array(expert_udp
, ei
, array_length(ei
));
776 /* subdissector code */
777 udp_dissector_table
= register_dissector_table("udp.port",
778 "UDP port", FT_UINT16
, BASE_DEC
);
779 register_heur_dissector_list("udp", &heur_subdissector_list
);
780 register_heur_dissector_list("udplite", &heur_subdissector_list
);
782 /* Register configuration preferences */
783 udp_module
= prefs_register_protocol(proto_udp
, NULL
);
784 prefs_register_bool_preference(udp_module
, "summary_in_tree",
785 "Show UDP summary in protocol tree",
786 "Whether the UDP summary line should be shown in the protocol tree",
787 &udp_summary_in_tree
);
788 prefs_register_bool_preference(udp_module
, "try_heuristic_first",
789 "Try heuristic sub-dissectors first",
790 "Try to decode a packet using an heuristic sub-dissector"
791 " before using a sub-dissector registered to a specific port",
792 &try_heuristic_first
);
793 prefs_register_bool_preference(udp_module
, "check_checksum",
794 "Validate the UDP checksum if possible",
795 "Whether to validate the UDP checksum",
796 &udp_check_checksum
);
797 prefs_register_bool_preference(udp_module
, "process_info",
798 "Collect process flow information",
799 "Collect process flow information from IPFIX",
802 udplite_module
= prefs_register_protocol(proto_udplite
, NULL
);
803 prefs_register_bool_preference(udplite_module
, "ignore_checksum_coverage",
804 "Ignore UDPlite checksum coverage",
805 "Ignore an invalid checksum coverage field and continue dissection",
806 &udplite_ignore_checksum_coverage
);
807 prefs_register_bool_preference(udplite_module
, "check_checksum",
808 "Validate the UDPlite checksum if possible",
809 "Whether to validate the UDPlite checksum",
810 &udplite_check_checksum
);
814 proto_reg_handoff_udp(void)
816 dissector_add_uint("ip.proto", IP_PROTO_UDP
, udp_handle
);
817 dissector_add_uint("ip.proto", IP_PROTO_UDPLITE
, udplite_handle
);
818 data_handle
= find_dissector("data");
819 udp_tap
= register_tap("udp");
820 udp_follow_tap
= register_tap("udp_follow");
824 * Editor modelines - http://www.wireshark.org/tools/modelines.html
829 * indent-tabs-mode: nil
832 * vi: set shiftwidth=2 tabstop=8 expandtab:
833 * :indentSize=2:tabSize=8:noTabs=true: