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.
37 #include <epan/packet.h>
38 #include <epan/emem.h>
39 #include <epan/addr_resolv.h>
40 #include <epan/ipproto.h>
41 #include <epan/in_cksum.h>
42 #include <epan/prefs.h>
43 #include <epan/expert.h>
45 #include "packet-udp.h"
47 #include "packet-ip.h"
48 #include <epan/conversation.h>
51 static int udp_tap = -1;
53 static int proto_udp = -1;
54 static int proto_udplite = -1;
55 static int hf_udp_srcport = -1;
56 static int hf_udp_dstport = -1;
57 static int hf_udp_port = -1;
58 static int hf_udp_length = -1;
59 static int hf_udplite_checksum_coverage = -1;
60 static int hf_udplite_checksum_coverage_bad = -1;
61 static int hf_udp_checksum = -1;
62 static int hf_udp_checksum_good = -1;
63 static int hf_udp_checksum_bad = -1;
65 static gint ett_udp = -1;
66 static gint ett_udp_checksum = -1;
70 /* Place UDP summary in proto tree */
71 static gboolean udp_summary_in_tree = TRUE;
73 /* Check UDP checksums */
74 static gboolean udp_check_checksum = TRUE;
76 /* Ignore an invalid checksum coverage field for UDPLite */
77 static gboolean udplite_ignore_checksum_coverage = TRUE;
79 /* Check UDPLite checksums */
80 static gboolean udplite_check_checksum = TRUE;
82 static dissector_table_t udp_dissector_table;
83 static heur_dissector_list_t heur_subdissector_list;
84 static dissector_handle_t data_handle;
86 /* Determine if there is a sub-dissector and call it. This has been */
87 /* separated into a stand alone routine so other protocol dissectors */
88 /* can call to it, ie. socks */
90 static gboolean try_heuristic_first = FALSE;
93 decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
94 proto_tree *tree, int uh_sport, int uh_dport, int uh_ulen)
97 int low_port, high_port;
98 gint len, reported_len;
100 len = tvb_length_remaining(tvb, offset);
101 reported_len = tvb_reported_length_remaining(tvb, offset);
103 /* This is the length from the UDP header; the payload should be cut
104 off at that length. (If our caller passed a value here, they
105 are assumed to have checked that it's >= 8, and hence >= offset.)
107 XXX - what if it's *greater* than the reported length? */
108 if (uh_ulen - offset < reported_len)
109 reported_len = uh_ulen - offset;
110 if (len > reported_len)
113 next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
115 /* determine if this packet is part of a conversation and call dissector */
116 /* for the conversation if available */
118 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_UDP,
119 uh_sport, uh_dport, next_tvb, pinfo, tree)){
123 if (try_heuristic_first) {
124 /* do lookup with the heuristic subdissector table */
125 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
129 /* Do lookups with the subdissector table.
130 We try the port number with the lower value first, followed by the
131 port number with the higher value. This means that, for packets
132 where a dissector is registered for *both* port numbers:
134 1) we pick the same dissector for traffic going in both directions;
136 2) we prefer the port number that's more likely to be the right
137 one (as that prefers well-known ports to reserved ports);
139 although there is, of course, no guarantee that any such strategy
140 will always pick the right port number.
142 XXX - we ignore port numbers of 0, as some dissectors use a port
143 number of 0 to disable the port, and as RFC 768 says that the source
144 port in UDP datagrams is optional and is 0 if not used. */
145 if (uh_sport > uh_dport) {
147 high_port = uh_sport;
150 high_port = uh_dport;
153 dissector_try_port(udp_dissector_table, low_port, next_tvb, pinfo, tree))
155 if (high_port != 0 &&
156 dissector_try_port(udp_dissector_table, high_port, next_tvb, pinfo, tree))
159 if (!try_heuristic_first) {
160 /* do lookup with the heuristic subdissector table */
161 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
165 call_dissector(data_handle,next_tvb, pinfo, tree);
170 dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
172 proto_tree *udp_tree = NULL;
178 guint16 computed_cksum;
181 proto_tree *checksum_tree;
184 udph=ep_alloc(sizeof(e_udphdr));
185 SET_ADDRESS(&udph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
186 SET_ADDRESS(&udph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
188 if (check_col(pinfo->cinfo, COL_PROTOCOL))
189 col_set_str(pinfo->cinfo, COL_PROTOCOL, (ip_proto == IP_PROTO_UDP) ? "UDP" : "UDPlite");
190 if (check_col(pinfo->cinfo, COL_INFO))
191 col_clear(pinfo->cinfo, COL_INFO);
193 udph->uh_sport=tvb_get_ntohs(tvb, offset);
194 udph->uh_dport=tvb_get_ntohs(tvb, offset+2);
196 if (check_col(pinfo->cinfo, COL_INFO))
197 col_add_fstr(pinfo->cinfo, COL_INFO, "Source port: %s Destination port: %s",
198 get_udp_port(udph->uh_sport), get_udp_port(udph->uh_dport));
201 if (udp_summary_in_tree) {
202 if (ip_proto == IP_PROTO_UDP) {
203 ti = proto_tree_add_protocol_format(tree, proto_udp, tvb, offset, 8,
204 "User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
205 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
207 ti = proto_tree_add_protocol_format(tree, proto_udplite, tvb, offset, 8,
208 "Lightweight User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
209 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
212 ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE);
214 udp_tree = proto_item_add_subtree(ti, ett_udp);
216 proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, udph->uh_sport,
217 "Source port: %s (%u)", get_udp_port(udph->uh_sport), udph->uh_sport);
218 proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, udph->uh_dport,
219 "Destination port: %s (%u)", get_udp_port(udph->uh_dport), udph->uh_dport);
221 proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset, 2, udph->uh_sport);
222 proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset+2, 2, udph->uh_dport);
225 if (ip_proto == IP_PROTO_UDP) {
226 udph->uh_ulen = udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
227 if (udph->uh_ulen < 8) {
228 /* Bogus length - it includes the header, so it must be >= 8. */
229 /* XXX - should handle IPv6 UDP jumbograms (RFC 2675), where the length is zero */
230 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
231 udph->uh_ulen, "Length: %u (bogus, must be >= 8)", udph->uh_ulen);
232 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u < 8", udph->uh_ulen);
233 if (check_col(pinfo->cinfo, COL_INFO))
234 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u < 8]", udph->uh_ulen);
237 if ((udph->uh_ulen > tvb_reported_length(tvb)) && ! pinfo->fragmented) {
238 /* Bogus length - it goes past the end of the IP payload */
239 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
240 udph->uh_ulen, "Length: %u (bogus, payload length %u)", udph->uh_ulen, tvb_reported_length(tvb));
241 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u > IP payload length", udph->uh_ulen);
242 if (check_col(pinfo->cinfo, COL_INFO))
243 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u > IP PAYLOAD LENGTH]", udph->uh_ulen);
246 proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, udph->uh_ulen);
247 /* XXX - why is this here, given that this is UDP, not Lightweight UDP? */
248 proto_tree_add_uint_hidden(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4,
249 0, udph->uh_sum_cov);
253 udph->uh_ulen = pinfo->iplen - pinfo->iphdrlen;
254 udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
255 if (((udph->uh_sum_cov > 0) && (udph->uh_sum_cov < 8)) || (udph->uh_sum_cov > udph->uh_ulen)) {
256 /* Bogus length - it includes the header, so it must be >= 8, and no larger then the IP payload size. */
258 proto_tree_add_boolean_hidden(udp_tree, hf_udplite_checksum_coverage_bad, tvb, offset + 4, 2, TRUE);
259 proto_tree_add_uint_hidden(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
261 item = proto_tree_add_uint_format(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2,
262 udph->uh_sum_cov, "Checksum coverage: %u (bogus, must be >= 8 and <= %u (ip.len-ip.hdr_len))",
263 udph->uh_sum_cov, udph->uh_ulen);
264 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad checksum coverage length value %u < 8 or > %u",
265 udph->uh_sum_cov, udph->uh_ulen);
266 if (check_col(pinfo->cinfo, COL_INFO))
267 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD LIGHTWEIGHT UDP CHECKSUM COVERAGE LENGTH %u < 8 or > %u]",
268 udph->uh_sum_cov, udph->uh_ulen);
269 if (!udplite_ignore_checksum_coverage)
273 proto_tree_add_uint_hidden(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
274 proto_tree_add_uint(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2, udph->uh_sum_cov);
279 udph->uh_sum_cov = (udph->uh_sum_cov) ? udph->uh_sum_cov : udph->uh_ulen;
280 udph->uh_sum = tvb_get_ntohs(tvb, offset+6);
281 reported_len = tvb_reported_length(tvb);
282 len = tvb_length(tvb);
283 if (udph->uh_sum == 0) {
284 /* No checksum supplied in the packet. */
285 if (ip_proto == IP_PROTO_UDP) {
286 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
287 "Checksum: 0x%04x (none)", 0);
289 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
290 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
291 offset + 6, 2, FALSE);
292 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
293 offset + 6, 2, FALSE);
295 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
296 "Checksum: 0x%04x (Illegal)", 0);
298 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
299 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
300 offset + 6, 2, FALSE);
301 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
302 offset + 6, 2, TRUE);
304 } else if (!pinfo->fragmented && len >= reported_len &&
305 len >= udph->uh_sum_cov && reported_len >= udph->uh_sum_cov &&
306 udph->uh_sum_cov >=8) {
307 /* The packet isn't part of a fragmented datagram and isn't
308 truncated, so we can checksum it.
309 XXX - make a bigger scatter-gather list once we do fragment
312 if (((ip_proto == IP_PROTO_UDP) && (udp_check_checksum)) ||
313 ((ip_proto == IP_PROTO_UDPLITE) && (udplite_check_checksum))) {
314 /* Set up the fields of the pseudo-header. */
315 cksum_vec[0].ptr = pinfo->src.data;
316 cksum_vec[0].len = pinfo->src.len;
317 cksum_vec[1].ptr = pinfo->dst.data;
318 cksum_vec[1].len = pinfo->dst.len;
319 cksum_vec[2].ptr = (const guint8 *)&phdr;
320 switch (pinfo->src.type) {
323 phdr[0] = g_htonl((ip_proto<<16) + reported_len);
324 cksum_vec[2].len = 4;
328 phdr[0] = g_htonl(reported_len);
329 phdr[1] = g_htonl(ip_proto);
330 cksum_vec[2].len = 8;
334 /* UDP runs only atop IPv4 and IPv6.... */
335 DISSECTOR_ASSERT_NOT_REACHED();
338 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_sum_cov);
339 cksum_vec[3].len = udph->uh_sum_cov;
340 computed_cksum = in_cksum(&cksum_vec[0], 4);
341 if (computed_cksum == 0) {
342 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
343 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [correct]", udph->uh_sum);
345 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
346 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
347 offset + 6, 2, TRUE);
348 PROTO_ITEM_SET_GENERATED(item);
349 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
350 offset + 6, 2, FALSE);
351 PROTO_ITEM_SET_GENERATED(item);
353 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
354 offset + 6, 2, udph->uh_sum,
355 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"UDP checksum offload\"?)]", udph->uh_sum,
356 in_cksum_shouldbe(udph->uh_sum, computed_cksum));
358 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
359 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
360 offset + 6, 2, FALSE);
361 PROTO_ITEM_SET_GENERATED(item);
362 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
363 offset + 6, 2, TRUE);
364 PROTO_ITEM_SET_GENERATED(item);
365 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
367 if (check_col(pinfo->cinfo, COL_INFO))
368 col_append_fstr(pinfo->cinfo, COL_INFO, " [UDP CHECKSUM INCORRECT]");
371 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
372 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [validation disabled]", udph->uh_sum);
373 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
374 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
375 offset + 6, 2, FALSE);
376 PROTO_ITEM_SET_GENERATED(item);
377 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
378 offset + 6, 2, FALSE);
379 PROTO_ITEM_SET_GENERATED(item);
382 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
383 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x", udph->uh_sum);
385 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
386 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
387 offset + 6, 2, FALSE);
388 PROTO_ITEM_SET_GENERATED(item);
389 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
390 offset + 6, 2, FALSE);
391 PROTO_ITEM_SET_GENERATED(item);
394 /* Skip over header */
397 pinfo->ptype = PT_UDP;
398 pinfo->srcport = udph->uh_sport;
399 pinfo->destport = udph->uh_dport;
401 tap_queue_packet(udp_tap, pinfo, udph);
403 * Call sub-dissectors.
405 * XXX - should we do this if this is included in an error packet?
406 * It might be nice to see the details of the packet that caused the
407 * ICMP error, but it might not be nice to have the dissector update
409 * Also, we probably don't want to run UDP taps on those packets.
411 * We definitely don't want to do it for an error packet if there's
412 * nothing left in the packet.
414 if (!pinfo->in_error_pkt || tvb_length_remaining(tvb, offset) > 0)
415 decode_udp_ports(tvb, offset, pinfo, tree, udph->uh_sport, udph->uh_dport,
420 dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
422 dissect(tvb, pinfo, tree, IP_PROTO_UDP);
426 dissect_udplite(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
428 dissect(tvb, pinfo, tree, IP_PROTO_UDPLITE);
432 proto_register_udp(void)
434 module_t *udp_module;
435 module_t *udplite_module;
437 static hf_register_info hf[] = {
439 { "Source Port", "udp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
443 { "Destination Port", "udp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
447 { "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
451 { "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
455 { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
456 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
458 { &hf_udp_checksum_good,
459 { "Good Checksum", "udp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
460 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
462 { &hf_udp_checksum_bad,
463 { "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
464 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }}
467 static hf_register_info hf_lite[] = {
468 { &hf_udplite_checksum_coverage_bad,
469 { "Bad Checksum coverage", "udp.checksum_coverage_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
472 { &hf_udplite_checksum_coverage,
473 { "Checksum coverage", "udp.checksum_coverage", FT_UINT16, BASE_DEC, NULL, 0x0,
477 static gint *ett[] = {
482 proto_udp = proto_register_protocol("User Datagram Protocol",
484 register_dissector("udp", dissect_udp, proto_udp);
485 proto_udplite = proto_register_protocol("Lightweight User Datagram Protocol",
486 "UDPlite", "udplite");
487 proto_register_field_array(proto_udp, hf, array_length(hf));
488 proto_register_field_array(proto_udplite, hf_lite, array_length(hf_lite));
489 proto_register_subtree_array(ett, array_length(ett));
491 /* subdissector code */
492 udp_dissector_table = register_dissector_table("udp.port",
493 "UDP port", FT_UINT16, BASE_DEC);
494 register_heur_dissector_list("udp", &heur_subdissector_list);
495 register_heur_dissector_list("udplite", &heur_subdissector_list);
497 /* Register configuration preferences */
498 udp_module = prefs_register_protocol(proto_udp, NULL);
499 prefs_register_bool_preference(udp_module, "summary_in_tree",
500 "Show UDP summary in protocol tree",
501 "Whether the UDP summary line should be shown in the protocol tree",
502 &udp_summary_in_tree);
503 prefs_register_bool_preference(udp_module, "try_heuristic_first",
504 "Try heuristic sub-dissectors first",
505 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
506 &try_heuristic_first);
507 prefs_register_bool_preference(udp_module, "check_checksum",
508 "Validate the UDP checksum if possible",
509 "Whether to validate the UDP checksum",
510 &udp_check_checksum);
512 udplite_module = prefs_register_protocol(proto_udplite, NULL);
513 prefs_register_bool_preference(udplite_module, "ignore_checksum_coverage",
514 "Ignore UDPlite checksum coverage",
515 "Ignore an invalid checksum coverage field and continue dissection",
516 &udplite_ignore_checksum_coverage);
517 prefs_register_bool_preference(udplite_module, "check_checksum",
518 "Validate the UDPlite checksum if possible",
519 "Whether to validate the UDPlite checksum",
520 &udplite_check_checksum);
524 proto_reg_handoff_udp(void)
526 dissector_handle_t udp_handle;
527 dissector_handle_t udplite_handle;
529 udp_handle = create_dissector_handle(dissect_udp, proto_udp);
530 dissector_add("ip.proto", IP_PROTO_UDP, udp_handle);
531 udplite_handle = create_dissector_handle(dissect_udplite, proto_udplite);
532 dissector_add("ip.proto", IP_PROTO_UDPLITE, udplite_handle);
533 data_handle = find_dissector("data");
534 udp_tap = register_tap("udp");