Set the svn:eol-style property on all text files to "native", so that
[obnox/wireshark/wip.git] / packet-udp.c
1 /* packet-udp.c
2  * Routines for UDP packet disassembly
3  *
4  * $Id$
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
10  * Richard Sharpe, 13-Feb-1999, added dispatch table support and
11  *                              support for tftp.
12  *
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.
17  *
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.
22  *
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.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include <epan/resolv.h>
39 #include "ipproto.h"
40 #include "in_cksum.h"
41 #include "prefs.h"
42
43 #include "packet-udp.h"
44
45 #include "packet-ip.h"
46 #include <epan/conversation.h>
47 #include "tap.h"
48
49 static int udp_tap = -1;
50
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;
58
59 static gint ett_udp = -1;
60
61 /* Place UDP summary in proto tree */
62 static gboolean udp_summary_in_tree = TRUE;
63
64 static dissector_table_t udp_dissector_table;
65 static heur_dissector_list_t heur_subdissector_list;
66 static dissector_handle_t data_handle;
67
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    */
71
72 static gboolean try_heuristic_first = FALSE;
73
74 void
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)
77 {
78   tvbuff_t *next_tvb;
79   int low_port, high_port;
80   gint len, reported_len;
81
82   len = tvb_length_remaining(tvb, offset);
83   reported_len = tvb_reported_length_remaining(tvb, offset);
84   if (uh_ulen != -1) {
85     /* This is the length from the UDP header; the payload should be cut
86        off at that length.
87        XXX - what if it's *greater* than the reported length? */
88     if (uh_ulen < len)
89       len = uh_ulen;
90     if (uh_ulen < reported_len)
91       reported_len = uh_ulen;
92   }
93   next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
94
95 /* determine if this packet is part of a conversation and call dissector */
96 /* for the conversation if available */
97
98   if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_UDP,
99                 uh_sport, uh_dport, next_tvb, pinfo, tree))
100     return;
101
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))
105       return;
106   }
107
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:
112
113         1) we pick the same dissector for traffic going in both directions;
114
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);
117
118      although there is, of course, no guarantee that any such strategy
119      will always pick the right port number.
120
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) {
125     low_port = uh_dport;
126     high_port = uh_sport;
127   } else {
128     low_port = uh_sport;
129     high_port = uh_dport;
130   }
131   if (low_port != 0 &&
132       dissector_try_port(udp_dissector_table, low_port, next_tvb, pinfo, tree))
133     return;
134   if (high_port != 0 &&
135       dissector_try_port(udp_dissector_table, high_port, next_tvb, pinfo, tree))
136     return;
137
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))
141       return;
142   }
143
144   call_dissector(data_handle,next_tvb, pinfo, tree);
145 }
146
147
148 static void
149 dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
150 {
151   proto_tree *udp_tree;
152   proto_item *ti;
153   guint      len;
154   guint      reported_len;
155   vec_t      cksum_vec[4];
156   guint32    phdr[2];
157   guint16    computed_cksum;
158   int        offset = 0;
159   static e_udphdr udphstruct[4], *udph;
160   static int udph_count=0;
161
162   udph_count++;
163   if(udph_count>=4){
164      udph_count=0;
165   }
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);
169
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);
174
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);
179
180
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));
184
185   if (tree) {
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);
190     } else {
191       ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE);
192     }
193     udp_tree = proto_item_add_subtree(ti, ett_udp);
194
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);
199
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);
202
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);
207       return;
208     }
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
221          reassembly? */
222
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) {
230
231       case AT_IPv4:
232         phdr[0] = g_htonl((IP_PROTO_UDP<<16) + udph->uh_ulen);
233         cksum_vec[2].len = 4;
234         break;
235
236       case AT_IPv6:
237         phdr[0] = g_htonl(udph->uh_ulen);
238         phdr[1] = g_htonl(IP_PROTO_UDP);
239         cksum_vec[2].len = 8;
240         break;
241
242       default:
243         /* TCP runs only atop IPv4 and IPv6.... */
244         g_assert_not_reached();
245         break;
246       }
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);
253       } else {
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));
260       }
261     } else {
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);
264     }
265   }
266
267   /* Skip over header */
268   offset += 8;
269
270   pinfo->ptype = PT_UDP;
271   pinfo->srcport = udph->uh_sport;
272   pinfo->destport = udph->uh_dport;
273
274   tap_queue_packet(udp_tap, pinfo, udph);
275   /*
276    * Call sub-dissectors.
277    *
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
281    * state based on it.
282    * Also, we probably don't want to run UDP taps on those packets.
283    *
284    * We definitely don't want to do it for an error packet if there's
285    * nothing left in the packet.
286    */
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,
289                      udph->uh_ulen);
290 }
291
292 void
293 proto_register_udp(void)
294 {
295         module_t *udp_module;
296         static hf_register_info hf[] = {
297                 { &hf_udp_srcport,
298                 { "Source Port",        "udp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
299                         "", HFILL }},
300
301                 { &hf_udp_dstport,
302                 { "Destination Port",   "udp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
303                         "", HFILL }},
304
305                 { &hf_udp_port,
306                 { "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC,  NULL, 0x0,
307                         "", HFILL }},
308
309                 { &hf_udp_length,
310                 { "Length",             "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
311                         "", HFILL }},
312
313                 { &hf_udp_checksum_bad,
314                 { "Bad Checksum",       "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
315                         "", HFILL }},
316
317                 { &hf_udp_checksum,
318                 { "Checksum",           "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
319                         "", HFILL }},
320         };
321         static gint *ett[] = {
322                 &ett_udp,
323         };
324
325         proto_udp = proto_register_protocol("User Datagram Protocol",
326             "UDP", "udp");
327         proto_register_field_array(proto_udp, hf, array_length(hf));
328         proto_register_subtree_array(ett, array_length(ett));
329
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);
334
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);
345 }
346
347 void
348 proto_reg_handoff_udp(void)
349 {
350         dissector_handle_t udp_handle;
351
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");
356 }