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.
36 #include <epan/packet.h>
37 #include <epan/emem.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 static int udp_tap = -1;
51 static int udp_follow_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;
64 static int hf_udp_proc_src_uid = -1;
65 static int hf_udp_proc_src_pid = -1;
66 static int hf_udp_proc_src_uname = -1;
67 static int hf_udp_proc_src_cmd = -1;
68 static int hf_udp_proc_dst_uid = -1;
69 static int hf_udp_proc_dst_pid = -1;
70 static int hf_udp_proc_dst_uname = -1;
71 static int hf_udp_proc_dst_cmd = -1;
73 static gint ett_udp = -1;
74 static gint ett_udp_checksum = -1;
75 static gint ett_udp_process_info = -1;
79 /* Place UDP summary in proto tree */
80 static gboolean udp_summary_in_tree = TRUE;
82 /* Check UDP checksums */
83 static gboolean udp_check_checksum = FALSE;
85 /* Collect IPFIX process flow information */
86 static gboolean udp_process_info = FALSE;
88 /* Ignore an invalid checksum coverage field for UDPLite */
89 static gboolean udplite_ignore_checksum_coverage = TRUE;
91 /* Check UDPLite checksums */
92 static gboolean udplite_check_checksum = FALSE;
94 static dissector_table_t udp_dissector_table;
95 static heur_dissector_list_t heur_subdissector_list;
96 static dissector_handle_t data_handle;
98 /* Determine if there is a sub-dissector and call it. This has been */
99 /* separated into a stand alone routine so other protocol dissectors */
100 /* can call to it, ie. socks */
102 static gboolean try_heuristic_first = FALSE;
105 /* Conversation and process code originally copied from packet-tcp.c */
106 static struct udp_analysis *
107 init_udp_conversation_data(void)
109 struct udp_analysis *udpd;
111 /* Initialize the udp protocol data structure to add to the udp conversation */
112 udpd = se_alloc0(sizeof(struct udp_analysis));
114 udpd->flow1.username = NULL;
115 udpd->flow1.command = NULL;
116 udpd->flow2.username = NULL;
117 udpd->flow2.command = NULL;
123 static struct udp_analysis *
124 get_udp_conversation_data(conversation_t *conv, packet_info *pinfo)
127 struct udp_analysis *udpd=NULL;
129 /* Did the caller supply the conversation pointer? */
131 conv = find_or_create_conversation(pinfo);
133 /* Get the data for this conversation */
134 udpd=conversation_get_proto_data(conv, proto_udp);
136 /* If the conversation was just created or it matched a
137 * conversation with template options, udpd will not
138 * have been initialized. So, initialize
139 * a new udpd structure for the conversation.
142 udpd = init_udp_conversation_data();
143 conversation_add_proto_data(conv, proto_udp, udpd);
150 /* check direction and get ua lists */
151 direction=CMP_ADDRESS(&pinfo->src, &pinfo->dst);
152 /* if the addresses are equal, match the ports instead */
154 direction= (pinfo->srcport > pinfo->destport) ? 1 : -1;
157 udpd->fwd=&(udpd->flow1);
158 udpd->rev=&(udpd->flow2);
160 udpd->fwd=&(udpd->flow2);
161 udpd->rev=&(udpd->flow1);
167 /* Attach process info to a flow */
168 /* XXX - We depend on the UDP dissector finding the conversation first */
170 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) {
171 conversation_t *conv;
172 struct udp_analysis *udpd;
173 udp_flow_t *flow = NULL;
175 if (!udp_process_info) {
179 conv = find_conversation(frame_num, local_addr, remote_addr, PT_UDP, local_port, remote_port, 0);
184 udpd = conversation_get_proto_data(conv, proto_udp);
189 if (CMP_ADDRESS(local_addr, &conv->key_ptr->addr1) == 0 && local_port == conv->key_ptr->port1) {
191 } else if (CMP_ADDRESS(remote_addr, &conv->key_ptr->addr1) == 0 && remote_port == conv->key_ptr->port1) {
194 if (!flow || flow->command) {
198 flow->process_uid = uid;
199 flow->process_pid = pid;
200 flow->username = se_strdup(username);
201 flow->command = se_strdup(command);
207 decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
208 proto_tree *tree, int uh_sport, int uh_dport, int uh_ulen)
211 int low_port, high_port;
212 gint len, reported_len;
214 len = tvb_length_remaining(tvb, offset);
215 reported_len = tvb_reported_length_remaining(tvb, offset);
217 /* This is the length from the UDP header; the payload should be cut
218 off at that length. (If our caller passed a value here, they
219 are assumed to have checked that it's >= 8, and hence >= offset.)
221 XXX - what if it's *greater* than the reported length? */
222 if (uh_ulen - offset < reported_len)
223 reported_len = uh_ulen - offset;
224 if (len > reported_len)
228 next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
230 /* If the user has a "Follow UDP Stream" window loading, pass a pointer
231 * to the payload tvb through the tap system. */
232 if(have_tap_listener(udp_follow_tap))
233 tap_queue_packet(udp_follow_tap, pinfo, next_tvb);
235 /* determine if this packet is part of a conversation and call dissector */
236 /* for the conversation if available */
238 if (try_conversation_dissector(&pinfo->dst, &pinfo->src, PT_UDP,
239 uh_dport, uh_sport, next_tvb, pinfo, tree)){
243 if (try_heuristic_first) {
244 /* do lookup with the heuristic subdissector table */
245 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
249 /* Do lookups with the subdissector table.
250 We try the port number with the lower value first, followed by the
251 port number with the higher value. This means that, for packets
252 where a dissector is registered for *both* port numbers:
254 1) we pick the same dissector for traffic going in both directions;
256 2) we prefer the port number that's more likely to be the right
257 one (as that prefers well-known ports to reserved ports);
259 although there is, of course, no guarantee that any such strategy
260 will always pick the right port number.
262 XXX - we ignore port numbers of 0, as some dissectors use a port
263 number of 0 to disable the port, and as RFC 768 says that the source
264 port in UDP datagrams is optional and is 0 if not used. */
265 if (uh_sport > uh_dport) {
267 high_port = uh_sport;
270 high_port = uh_dport;
273 dissector_try_uint(udp_dissector_table, low_port, next_tvb, pinfo, tree))
275 if (high_port != 0 &&
276 dissector_try_uint(udp_dissector_table, high_port, next_tvb, pinfo, tree))
279 if (!try_heuristic_first) {
280 /* do lookup with the heuristic subdissector table */
281 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
285 call_dissector(data_handle,next_tvb, pinfo, tree);
290 dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
292 proto_tree *udp_tree = NULL;
293 proto_item *ti, *hidden_item, *port_item;
298 guint16 computed_cksum;
301 proto_tree *checksum_tree;
303 conversation_t *conv = NULL;
304 struct udp_analysis *udpd = NULL;
305 proto_tree *process_tree;
307 udph=ep_alloc(sizeof(e_udphdr));
308 SET_ADDRESS(&udph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
309 SET_ADDRESS(&udph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
311 col_set_str(pinfo->cinfo, COL_PROTOCOL, (ip_proto == IP_PROTO_UDP) ? "UDP" : "UDPlite");
312 col_clear(pinfo->cinfo, COL_INFO);
314 udph->uh_sport=tvb_get_ntohs(tvb, offset);
315 udph->uh_dport=tvb_get_ntohs(tvb, offset+2);
317 col_add_fstr(pinfo->cinfo, COL_INFO, "Source port: %s Destination port: %s",
318 get_udp_port(udph->uh_sport), get_udp_port(udph->uh_dport));
321 if (udp_summary_in_tree) {
322 if (ip_proto == IP_PROTO_UDP) {
323 ti = proto_tree_add_protocol_format(tree, proto_udp, tvb, offset, 8,
324 "User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
325 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
327 ti = proto_tree_add_protocol_format(tree, proto_udplite, tvb, offset, 8,
328 "Lightweight User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
329 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
332 ti = proto_tree_add_item(tree, (ip_proto == IP_PROTO_UDP) ? proto_udp : proto_udplite, tvb, offset, 8, FALSE);
334 udp_tree = proto_item_add_subtree(ti, ett_udp);
336 port_item = proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, udph->uh_sport,
337 "Source port: %s (%u)", get_udp_port(udph->uh_sport), udph->uh_sport);
338 /* The beginning port number, 32768 + 666 (33434), is from LBL's traceroute.c source code and this code
339 * further assumes that 3 attempts are made per hop */
340 if(udph->uh_sport > 32768 + 666 && udph->uh_sport <= 32768 + 666 + 30)
341 expert_add_info_format(pinfo, port_item, PI_SEQUENCE, PI_CHAT, "Possible traceroute: hop #%u, attempt #%u",
342 ((udph->uh_sport - 32768 - 666 - 1) / 3) + 1,
343 ((udph->uh_sport - 32768 - 666 - 1) % 3) + 1
346 port_item = proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, udph->uh_dport,
347 "Destination port: %s (%u)", get_udp_port(udph->uh_dport), udph->uh_dport);
348 if(udph->uh_dport > 32768 + 666 && udph->uh_dport <= 32768 + 666 + 30)
349 expert_add_info_format(pinfo, port_item, PI_SEQUENCE, PI_CHAT, "Possible traceroute: hop #%u, attempt #%u",
350 ((udph->uh_dport - 32768 - 666 - 1) / 3) + 1,
351 ((udph->uh_dport - 32768 - 666 - 1) % 3) + 1
354 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_port, tvb, offset, 2, udph->uh_sport);
355 PROTO_ITEM_SET_HIDDEN(hidden_item);
356 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_port, tvb, offset+2, 2, udph->uh_dport);
357 PROTO_ITEM_SET_HIDDEN(hidden_item);
360 if (ip_proto == IP_PROTO_UDP) {
361 udph->uh_ulen = udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
362 if (udph->uh_ulen < 8) {
363 /* Bogus length - it includes the header, so it must be >= 8. */
364 /* XXX - should handle IPv6 UDP jumbograms (RFC 2675), where the length is zero */
365 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
366 udph->uh_ulen, "Length: %u (bogus, must be >= 8)", udph->uh_ulen);
367 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u < 8", udph->uh_ulen);
368 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u < 8]", udph->uh_ulen);
371 if ((udph->uh_ulen > tvb_reported_length(tvb)) && ! pinfo->fragmented && ! pinfo->flags.in_error_pkt) {
372 /* Bogus length - it goes past the end of the IP payload */
373 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
374 udph->uh_ulen, "Length: %u (bogus, payload length %u)", udph->uh_ulen, tvb_reported_length(tvb));
375 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u > IP payload length", udph->uh_ulen);
376 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u > IP PAYLOAD LENGTH]", udph->uh_ulen);
379 proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, udph->uh_ulen);
380 /* XXX - why is this here, given that this is UDP, not Lightweight UDP? */
381 hidden_item = proto_tree_add_uint(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4,
382 0, udph->uh_sum_cov);
383 PROTO_ITEM_SET_HIDDEN(hidden_item);
387 udph->uh_ulen = pinfo->iplen - pinfo->iphdrlen;
388 udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
389 if (((udph->uh_sum_cov > 0) && (udph->uh_sum_cov < 8)) || (udph->uh_sum_cov > udph->uh_ulen)) {
390 /* Bogus length - it includes the header, so it must be >= 8, and no larger then the IP payload size. */
392 hidden_item = proto_tree_add_boolean(udp_tree, hf_udplite_checksum_coverage_bad, tvb, offset + 4, 2, TRUE);
393 PROTO_ITEM_SET_HIDDEN(hidden_item);
394 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
395 PROTO_ITEM_SET_HIDDEN(hidden_item);
397 item = proto_tree_add_uint_format(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2,
398 udph->uh_sum_cov, "Checksum coverage: %u (bogus, must be >= 8 and <= %u (ip.len-ip.hdr_len))",
399 udph->uh_sum_cov, udph->uh_ulen);
400 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad checksum coverage length value %u < 8 or > %u",
401 udph->uh_sum_cov, udph->uh_ulen);
402 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD LIGHTWEIGHT UDP CHECKSUM COVERAGE LENGTH %u < 8 or > %u]",
403 udph->uh_sum_cov, udph->uh_ulen);
404 if (!udplite_ignore_checksum_coverage)
408 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
409 PROTO_ITEM_SET_HIDDEN(hidden_item);
410 proto_tree_add_uint(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2, udph->uh_sum_cov);
415 udph->uh_sum_cov = (udph->uh_sum_cov) ? udph->uh_sum_cov : udph->uh_ulen;
416 udph->uh_sum = tvb_get_ntohs(tvb, offset+6);
417 reported_len = tvb_reported_length(tvb);
418 len = tvb_length(tvb);
419 if (udph->uh_sum == 0) {
420 /* No checksum supplied in the packet. */
421 if (ip_proto == IP_PROTO_UDP) {
422 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
423 "Checksum: 0x%04x (none)", 0);
425 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
426 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
427 offset + 6, 2, FALSE);
428 PROTO_ITEM_SET_GENERATED(item);
429 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
430 offset + 6, 2, FALSE);
431 PROTO_ITEM_SET_GENERATED(item);
433 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
434 "Checksum: 0x%04x (Illegal)", 0);
435 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Illegal Checksum value (0)");
436 col_append_fstr(pinfo->cinfo, COL_INFO, " [ILLEGAL CHECKSUM (0)]");
438 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
439 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
440 offset + 6, 2, FALSE);
441 PROTO_ITEM_SET_GENERATED(item);
442 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
443 offset + 6, 2, TRUE);
444 PROTO_ITEM_SET_GENERATED(item);
446 } else if (!pinfo->fragmented && len >= reported_len &&
447 len >= udph->uh_sum_cov && reported_len >= udph->uh_sum_cov &&
448 udph->uh_sum_cov >=8) {
449 /* The packet isn't part of a fragmented datagram and isn't
450 truncated, so we can checksum it.
451 XXX - make a bigger scatter-gather list once we do fragment
454 if (((ip_proto == IP_PROTO_UDP) && (udp_check_checksum)) ||
455 ((ip_proto == IP_PROTO_UDPLITE) && (udplite_check_checksum))) {
456 /* Set up the fields of the pseudo-header. */
457 cksum_vec[0].ptr = pinfo->src.data;
458 cksum_vec[0].len = pinfo->src.len;
459 cksum_vec[1].ptr = pinfo->dst.data;
460 cksum_vec[1].len = pinfo->dst.len;
461 cksum_vec[2].ptr = (const guint8 *)&phdr;
462 switch (pinfo->src.type) {
465 phdr[0] = g_htonl((ip_proto<<16) + reported_len);
466 cksum_vec[2].len = 4;
470 phdr[0] = g_htonl(reported_len);
471 phdr[1] = g_htonl(ip_proto);
472 cksum_vec[2].len = 8;
476 /* UDP runs only atop IPv4 and IPv6.... */
477 DISSECTOR_ASSERT_NOT_REACHED();
480 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_sum_cov);
481 cksum_vec[3].len = udph->uh_sum_cov;
482 computed_cksum = in_cksum(&cksum_vec[0], 4);
483 if (computed_cksum == 0) {
484 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
485 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [correct]", udph->uh_sum);
487 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
488 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
489 offset + 6, 2, TRUE);
490 PROTO_ITEM_SET_GENERATED(item);
491 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
492 offset + 6, 2, FALSE);
493 PROTO_ITEM_SET_GENERATED(item);
495 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
496 offset + 6, 2, udph->uh_sum,
497 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"UDP checksum offload\"?)]", udph->uh_sum,
498 in_cksum_shouldbe(udph->uh_sum, computed_cksum));
500 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
501 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
502 offset + 6, 2, FALSE);
503 PROTO_ITEM_SET_GENERATED(item);
504 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
505 offset + 6, 2, TRUE);
506 PROTO_ITEM_SET_GENERATED(item);
507 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
509 col_append_fstr(pinfo->cinfo, COL_INFO, " [UDP CHECKSUM INCORRECT]");
512 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
513 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [validation disabled]", udph->uh_sum);
514 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
515 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
516 offset + 6, 2, FALSE);
517 PROTO_ITEM_SET_GENERATED(item);
518 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
519 offset + 6, 2, FALSE);
520 PROTO_ITEM_SET_GENERATED(item);
523 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
524 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [unchecked, not all data available]", udph->uh_sum);
526 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
527 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
528 offset + 6, 2, FALSE);
529 PROTO_ITEM_SET_GENERATED(item);
530 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
531 offset + 6, 2, FALSE);
532 PROTO_ITEM_SET_GENERATED(item);
535 /* Skip over header */
538 pinfo->ptype = PT_UDP;
539 pinfo->srcport = udph->uh_sport;
540 pinfo->destport = udph->uh_dport;
542 tap_queue_packet(udp_tap, pinfo, udph);
544 /* find(or create if needed) the conversation for this udp session */
545 if (udp_process_info) {
546 conv=find_or_create_conversation(pinfo);
547 udpd=get_udp_conversation_data(conv,pinfo);
550 if (udpd && ((udpd->fwd && udpd->fwd->command) || (udpd->rev && udpd->rev->command))) {
551 ti = proto_tree_add_text(udp_tree, tvb, offset, 0, "Process Information");
552 PROTO_ITEM_SET_GENERATED(ti);
553 process_tree = proto_item_add_subtree(ti, ett_udp_process_info);
554 if (udpd->fwd && udpd->fwd->command) {
555 proto_tree_add_uint_format_value(process_tree, hf_udp_proc_dst_uid, tvb, 0, 0,
556 udpd->fwd->process_uid, "%u", udpd->fwd->process_uid);
557 proto_tree_add_uint_format_value(process_tree, hf_udp_proc_dst_pid, tvb, 0, 0,
558 udpd->fwd->process_pid, "%u", udpd->fwd->process_pid);
559 proto_tree_add_string_format_value(process_tree, hf_udp_proc_dst_uname, tvb, 0, 0,
560 udpd->fwd->username, "%s", udpd->fwd->username);
561 proto_tree_add_string_format_value(process_tree, hf_udp_proc_dst_cmd, tvb, 0, 0,
562 udpd->fwd->command, "%s", udpd->fwd->command);
564 if (udpd->rev->command) {
565 proto_tree_add_uint_format_value(process_tree, hf_udp_proc_src_uid, tvb, 0, 0,
566 udpd->rev->process_uid, "%u", udpd->rev->process_uid);
567 proto_tree_add_uint_format_value(process_tree, hf_udp_proc_src_pid, tvb, 0, 0,
568 udpd->rev->process_pid, "%u", udpd->rev->process_pid);
569 proto_tree_add_string_format_value(process_tree, hf_udp_proc_src_uname, tvb, 0, 0,
570 udpd->rev->username, "%s", udpd->rev->username);
571 proto_tree_add_string_format_value(process_tree, hf_udp_proc_src_cmd, tvb, 0, 0,
572 udpd->rev->command, "%s", udpd->rev->command);
577 * Call sub-dissectors.
579 * XXX - should we do this if this is included in an error packet?
580 * It might be nice to see the details of the packet that caused the
581 * ICMP error, but it might not be nice to have the dissector update
583 * Also, we probably don't want to run UDP taps on those packets.
585 * We definitely don't want to do it for an error packet if there's
586 * nothing left in the packet.
588 if (!pinfo->flags.in_error_pkt || tvb_length_remaining(tvb, offset) > 0)
589 decode_udp_ports(tvb, offset, pinfo, tree, udph->uh_sport, udph->uh_dport,
594 dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
596 dissect(tvb, pinfo, tree, IP_PROTO_UDP);
600 dissect_udplite(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
602 dissect(tvb, pinfo, tree, IP_PROTO_UDPLITE);
606 proto_register_udp(void)
608 module_t *udp_module;
609 module_t *udplite_module;
611 static hf_register_info hf[] = {
613 { "Source Port", "udp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
617 { "Destination Port", "udp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
621 { "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
625 { "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
629 { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
630 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
632 { &hf_udp_checksum_good,
633 { "Good Checksum", "udp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
634 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
636 { &hf_udp_checksum_bad,
637 { "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
638 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }},
640 { &hf_udp_proc_src_uid,
641 { "Source process user ID", "udp.proc.srcuid", FT_UINT32, BASE_DEC, NULL, 0x0,
644 { &hf_udp_proc_src_pid,
645 { "Source process ID", "udp.proc.srcpid", FT_UINT32, BASE_DEC, NULL, 0x0,
648 { &hf_udp_proc_src_uname,
649 { "Source process user name", "udp.proc.srcuname", FT_STRING, BASE_NONE, NULL, 0x0,
652 { &hf_udp_proc_src_cmd,
653 { "Source process name", "udp.proc.srccmd", FT_STRING, BASE_NONE, NULL, 0x0,
654 "Source process command name", HFILL}},
656 { &hf_udp_proc_dst_uid,
657 { "Destination process user ID", "udp.proc.dstuid", FT_UINT32, BASE_DEC, NULL, 0x0,
660 { &hf_udp_proc_dst_pid,
661 { "Destination process ID", "udp.proc.dstpid", FT_UINT32, BASE_DEC, NULL, 0x0,
664 { &hf_udp_proc_dst_uname,
665 { "Destination process user name", "udp.proc.dstuname", FT_STRING, BASE_NONE, NULL, 0x0,
668 { &hf_udp_proc_dst_cmd,
669 { "Destination process name", "udp.proc.dstcmd", FT_STRING, BASE_NONE, NULL, 0x0,
670 "Destination process command name", HFILL}}
673 static hf_register_info hf_lite[] = {
674 { &hf_udplite_checksum_coverage_bad,
675 { "Bad Checksum coverage", "udp.checksum_coverage_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
678 { &hf_udplite_checksum_coverage,
679 { "Checksum coverage", "udp.checksum_coverage", FT_UINT16, BASE_DEC, NULL, 0x0,
683 static gint *ett[] = {
686 &ett_udp_process_info
689 proto_udp = proto_register_protocol("User Datagram Protocol",
691 register_dissector("udp", dissect_udp, proto_udp);
692 proto_udplite = proto_register_protocol("Lightweight User Datagram Protocol",
693 "UDPlite", "udplite");
694 proto_register_field_array(proto_udp, hf, array_length(hf));
695 proto_register_field_array(proto_udplite, hf_lite, array_length(hf_lite));
696 proto_register_subtree_array(ett, array_length(ett));
698 /* subdissector code */
699 udp_dissector_table = register_dissector_table("udp.port",
700 "UDP port", FT_UINT16, BASE_DEC);
701 register_heur_dissector_list("udp", &heur_subdissector_list);
702 register_heur_dissector_list("udplite", &heur_subdissector_list);
704 /* Register configuration preferences */
705 udp_module = prefs_register_protocol(proto_udp, NULL);
706 prefs_register_bool_preference(udp_module, "summary_in_tree",
707 "Show UDP summary in protocol tree",
708 "Whether the UDP summary line should be shown in the protocol tree",
709 &udp_summary_in_tree);
710 prefs_register_bool_preference(udp_module, "try_heuristic_first",
711 "Try heuristic sub-dissectors first",
712 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
713 &try_heuristic_first);
714 prefs_register_bool_preference(udp_module, "check_checksum",
715 "Validate the UDP checksum if possible",
716 "Whether to validate the UDP checksum",
717 &udp_check_checksum);
718 prefs_register_bool_preference(udp_module, "process_info",
719 "Collect process flow information",
720 "Collect process flow information from IPFIX",
723 udplite_module = prefs_register_protocol(proto_udplite, NULL);
724 prefs_register_bool_preference(udplite_module, "ignore_checksum_coverage",
725 "Ignore UDPlite checksum coverage",
726 "Ignore an invalid checksum coverage field and continue dissection",
727 &udplite_ignore_checksum_coverage);
728 prefs_register_bool_preference(udplite_module, "check_checksum",
729 "Validate the UDPlite checksum if possible",
730 "Whether to validate the UDPlite checksum",
731 &udplite_check_checksum);
735 proto_reg_handoff_udp(void)
737 dissector_handle_t udp_handle;
738 dissector_handle_t udplite_handle;
740 udp_handle = find_dissector("udp");
741 dissector_add_uint("ip.proto", IP_PROTO_UDP, udp_handle);
742 udplite_handle = create_dissector_handle(dissect_udplite, proto_udplite);
743 dissector_add_uint("ip.proto", IP_PROTO_UDPLITE, udplite_handle);
744 data_handle = find_dissector("data");
745 udp_tap = register_tap("udp");
746 udp_follow_tap = register_tap("udp_follow");