2 * Routines for UDP packet disassembly
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 #include <epan/packet.h>
38 #include <epan/addr_resolv.h>
40 #include <epan/in_cksum.h>
41 #include <epan/prefs.h>
43 #include "packet-udp.h"
45 #include "packet-ip.h"
46 #include <epan/conversation.h>
49 static int udp_tap = -1;
51 static int proto_udp = -1;
52 static int hf_udp_srcport = -1;
53 static int hf_udp_dstport = -1;
54 static int hf_udp_port = -1;
55 static int hf_udp_length = -1;
56 static int hf_udp_checksum = -1;
57 static int hf_udp_checksum_bad = -1;
59 static gint ett_udp = -1;
61 /* Place UDP summary in proto tree */
62 static gboolean udp_summary_in_tree = TRUE;
64 static dissector_table_t udp_dissector_table;
65 static heur_dissector_list_t heur_subdissector_list;
66 static dissector_handle_t data_handle;
68 /* Determine if there is a sub-dissector and call it. This has been */
69 /* separated into a stand alone routine to other protocol dissectors */
70 /* can call to it, ie. socks */
72 static gboolean try_heuristic_first = FALSE;
75 decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
76 proto_tree *tree, int uh_sport, int uh_dport, int uh_ulen)
79 int low_port, high_port;
80 gint len, reported_len;
82 len = tvb_length_remaining(tvb, offset);
83 reported_len = tvb_reported_length_remaining(tvb, offset);
85 /* This is the length from the UDP header; the payload should be cut
87 XXX - what if it's *greater* than the reported length? */
90 if (uh_ulen < reported_len)
91 reported_len = uh_ulen;
93 next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
95 /* determine if this packet is part of a conversation and call dissector */
96 /* for the conversation if available */
98 if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_UDP,
99 uh_sport, uh_dport, next_tvb, pinfo, tree))
102 if (try_heuristic_first) {
103 /* do lookup with the heuristic subdissector table */
104 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
108 /* Do lookups with the subdissector table.
109 We try the port number with the lower value first, followed by the
110 port number with the higher value. This means that, for packets
111 where a dissector is registered for *both* port numbers:
113 1) we pick the same dissector for traffic going in both directions;
115 2) we prefer the port number that's more likely to be the right
116 one (as that prefers well-known ports to reserved ports);
118 although there is, of course, no guarantee that any such strategy
119 will always pick the right port number.
121 XXX - we ignore port numbers of 0, as some dissectors use a port
122 number of 0 to disable the port, and as RFC 768 says that the source
123 port in UDP datagrams is optional and is 0 if not used. */
124 if (uh_sport > uh_dport) {
126 high_port = uh_sport;
129 high_port = uh_dport;
132 dissector_try_port(udp_dissector_table, low_port, next_tvb, pinfo, tree))
134 if (high_port != 0 &&
135 dissector_try_port(udp_dissector_table, high_port, next_tvb, pinfo, tree))
138 if (!try_heuristic_first) {
139 /* do lookup with the heuristic subdissector table */
140 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
144 call_dissector(data_handle,next_tvb, pinfo, tree);
149 dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
151 proto_tree *udp_tree;
157 guint16 computed_cksum;
159 static e_udphdr udphstruct[4], *udph;
160 static int udph_count=0;
166 udph=&udphstruct[udph_count];
167 SET_ADDRESS(&udph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
168 SET_ADDRESS(&udph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
170 if (check_col(pinfo->cinfo, COL_PROTOCOL))
171 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UDP");
172 if (check_col(pinfo->cinfo, COL_INFO))
173 col_clear(pinfo->cinfo, COL_INFO);
175 udph->uh_sport=tvb_get_ntohs(tvb, offset);
176 udph->uh_dport=tvb_get_ntohs(tvb, offset+2);
177 udph->uh_ulen=tvb_get_ntohs(tvb, offset+4);
178 udph->uh_sum=tvb_get_ntohs(tvb, offset+6);
181 if (check_col(pinfo->cinfo, COL_INFO))
182 col_add_fstr(pinfo->cinfo, COL_INFO, "Source port: %s Destination port: %s",
183 get_udp_port(udph->uh_sport), get_udp_port(udph->uh_dport));
186 if (udp_summary_in_tree) {
187 ti = proto_tree_add_protocol_format(tree, proto_udp, tvb, offset, 8,
188 "User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
189 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
191 ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE);
193 udp_tree = proto_item_add_subtree(ti, ett_udp);
195 proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, udph->uh_sport,
196 "Source port: %s (%u)", get_udp_port(udph->uh_sport), udph->uh_sport);
197 proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, udph->uh_dport,
198 "Destination port: %s (%u)", get_udp_port(udph->uh_dport), udph->uh_dport);
200 proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset, 2, udph->uh_sport);
201 proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset+2, 2, udph->uh_dport);
203 if (udph->uh_ulen < 8) {
204 /* Bogus length - it includes the header, so it must be >= 8. */
205 proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
206 udph->uh_ulen, "Length: %u (bogus, must be >= 8)", udph->uh_ulen);
209 proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, udph->uh_ulen);
210 reported_len = tvb_reported_length(tvb);
211 len = tvb_length(tvb);
212 if (udph->uh_sum == 0) {
213 /* No checksum supplied in the packet. */
214 proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
215 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x (none)", udph->uh_sum);
216 } else if (!pinfo->fragmented && len >= reported_len &&
217 len >= udph->uh_ulen && reported_len >= udph->uh_ulen) {
218 /* The packet isn't part of a fragmented datagram and isn't
219 truncated, so we can checksum it.
220 XXX - make a bigger scatter-gather list once we do fragment
223 /* Set up the fields of the pseudo-header. */
224 cksum_vec[0].ptr = pinfo->src.data;
225 cksum_vec[0].len = pinfo->src.len;
226 cksum_vec[1].ptr = pinfo->dst.data;
227 cksum_vec[1].len = pinfo->dst.len;
228 cksum_vec[2].ptr = (const guint8 *)&phdr;
229 switch (pinfo->src.type) {
232 phdr[0] = g_htonl((IP_PROTO_UDP<<16) + udph->uh_ulen);
233 cksum_vec[2].len = 4;
237 phdr[0] = g_htonl(udph->uh_ulen);
238 phdr[1] = g_htonl(IP_PROTO_UDP);
239 cksum_vec[2].len = 8;
243 /* TCP runs only atop IPv4 and IPv6.... */
244 g_assert_not_reached();
247 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_ulen);
248 cksum_vec[3].len = udph->uh_ulen;
249 computed_cksum = in_cksum(&cksum_vec[0], 4);
250 if (computed_cksum == 0) {
251 proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
252 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x (correct)", udph->uh_sum);
254 proto_tree_add_boolean_hidden(udp_tree, hf_udp_checksum_bad, tvb,
255 offset + 6, 2, TRUE);
256 proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
257 offset + 6, 2, udph->uh_sum,
258 "Checksum: 0x%04x (incorrect, should be 0x%04x)", udph->uh_sum,
259 in_cksum_shouldbe(udph->uh_sum, computed_cksum));
262 proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
263 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x", udph->uh_sum);
267 /* Skip over header */
270 pinfo->ptype = PT_UDP;
271 pinfo->srcport = udph->uh_sport;
272 pinfo->destport = udph->uh_dport;
274 tap_queue_packet(udp_tap, pinfo, udph);
276 * Call sub-dissectors.
278 * XXX - should we do this if this is included in an error packet?
279 * It might be nice to see the details of the packet that caused the
280 * ICMP error, but it might not be nice to have the dissector update
282 * Also, we probably don't want to run UDP taps on those packets.
284 * We definitely don't want to do it for an error packet if there's
285 * nothing left in the packet.
287 if (!pinfo->in_error_pkt || tvb_length_remaining(tvb, offset) > 0)
288 decode_udp_ports(tvb, offset, pinfo, tree, udph->uh_sport, udph->uh_dport,
293 proto_register_udp(void)
295 module_t *udp_module;
296 static hf_register_info hf[] = {
298 { "Source Port", "udp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
302 { "Destination Port", "udp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
306 { "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
310 { "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
313 { &hf_udp_checksum_bad,
314 { "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
318 { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
321 static gint *ett[] = {
325 proto_udp = proto_register_protocol("User Datagram Protocol",
327 proto_register_field_array(proto_udp, hf, array_length(hf));
328 proto_register_subtree_array(ett, array_length(ett));
330 /* subdissector code */
331 udp_dissector_table = register_dissector_table("udp.port",
332 "UDP port", FT_UINT16, BASE_DEC);
333 register_heur_dissector_list("udp", &heur_subdissector_list);
335 /* Register configuration preferences */
336 udp_module = prefs_register_protocol(proto_udp, NULL);
337 prefs_register_bool_preference(udp_module, "summary_in_tree",
338 "Show UDP summary in protocol tree",
339 "Whether the UDP summary line should be shown in the protocol tree",
340 &udp_summary_in_tree);
341 prefs_register_bool_preference(udp_module, "try_heuristic_first",
342 "Try heuristic sub-dissectors first",
343 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
344 &try_heuristic_first);
348 proto_reg_handoff_udp(void)
350 dissector_handle_t udp_handle;
352 udp_handle = create_dissector_handle(dissect_udp, proto_udp);
353 dissector_add("ip.proto", IP_PROTO_UDP, udp_handle);
354 data_handle = find_dissector("data");
355 udp_tap = register_tap("udp");