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;
52 static int udp_follow_tap = -1;
54 static int proto_udp = -1;
55 static int proto_udplite = -1;
56 static int hf_udp_srcport = -1;
57 static int hf_udp_dstport = -1;
58 static int hf_udp_port = -1;
59 static int hf_udp_length = -1;
60 static int hf_udplite_checksum_coverage = -1;
61 static int hf_udplite_checksum_coverage_bad = -1;
62 static int hf_udp_checksum = -1;
63 static int hf_udp_checksum_good = -1;
64 static int hf_udp_checksum_bad = -1;
66 static gint ett_udp = -1;
67 static gint ett_udp_checksum = -1;
71 /* Place UDP summary in proto tree */
72 static gboolean udp_summary_in_tree = TRUE;
74 /* Check UDP checksums */
75 static gboolean udp_check_checksum = FALSE;
77 /* Ignore an invalid checksum coverage field for UDPLite */
78 static gboolean udplite_ignore_checksum_coverage = TRUE;
80 /* Check UDPLite checksums */
81 static gboolean udplite_check_checksum = FALSE;
83 static dissector_table_t udp_dissector_table;
84 static heur_dissector_list_t heur_subdissector_list;
85 static dissector_handle_t data_handle;
87 /* Determine if there is a sub-dissector and call it. This has been */
88 /* separated into a stand alone routine so other protocol dissectors */
89 /* can call to it, ie. socks */
91 static gboolean try_heuristic_first = FALSE;
94 decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
95 proto_tree *tree, int uh_sport, int uh_dport, int uh_ulen)
98 int low_port, high_port;
99 gint len, reported_len;
101 len = tvb_length_remaining(tvb, offset);
102 reported_len = tvb_reported_length_remaining(tvb, offset);
104 /* This is the length from the UDP header; the payload should be cut
105 off at that length. (If our caller passed a value here, they
106 are assumed to have checked that it's >= 8, and hence >= offset.)
108 XXX - what if it's *greater* than the reported length? */
109 if (uh_ulen - offset < reported_len)
110 reported_len = uh_ulen - offset;
111 if (len > reported_len)
115 next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
117 /* If the user has a "Follow UDP Stream" window loading, pass a pointer
118 * to the payload tvb through the tap system. */
119 if(have_tap_listener(udp_follow_tap))
120 tap_queue_packet(udp_follow_tap, pinfo, next_tvb);
122 /* determine if this packet is part of a conversation and call dissector */
123 /* for the conversation if available */
125 if (try_conversation_dissector(&pinfo->dst, &pinfo->src, PT_UDP,
126 uh_dport, uh_sport, next_tvb, pinfo, tree)){
130 if (try_heuristic_first) {
131 /* do lookup with the heuristic subdissector table */
132 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
136 /* Do lookups with the subdissector table.
137 We try the port number with the lower value first, followed by the
138 port number with the higher value. This means that, for packets
139 where a dissector is registered for *both* port numbers:
141 1) we pick the same dissector for traffic going in both directions;
143 2) we prefer the port number that's more likely to be the right
144 one (as that prefers well-known ports to reserved ports);
146 although there is, of course, no guarantee that any such strategy
147 will always pick the right port number.
149 XXX - we ignore port numbers of 0, as some dissectors use a port
150 number of 0 to disable the port, and as RFC 768 says that the source
151 port in UDP datagrams is optional and is 0 if not used. */
152 if (uh_sport > uh_dport) {
154 high_port = uh_sport;
157 high_port = uh_dport;
160 dissector_try_port(udp_dissector_table, low_port, next_tvb, pinfo, tree))
162 if (high_port != 0 &&
163 dissector_try_port(udp_dissector_table, high_port, next_tvb, pinfo, tree))
166 if (!try_heuristic_first) {
167 /* do lookup with the heuristic subdissector table */
168 if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
172 call_dissector(data_handle,next_tvb, pinfo, tree);
177 dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 ip_proto)
179 proto_tree *udp_tree = NULL;
180 proto_item *ti, *hidden_item;
185 guint16 computed_cksum;
188 proto_tree *checksum_tree;
191 udph=ep_alloc(sizeof(e_udphdr));
192 SET_ADDRESS(&udph->ip_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
193 SET_ADDRESS(&udph->ip_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
195 if (check_col(pinfo->cinfo, COL_PROTOCOL))
196 col_set_str(pinfo->cinfo, COL_PROTOCOL, (ip_proto == IP_PROTO_UDP) ? "UDP" : "UDPlite");
197 if (check_col(pinfo->cinfo, COL_INFO))
198 col_clear(pinfo->cinfo, COL_INFO);
200 udph->uh_sport=tvb_get_ntohs(tvb, offset);
201 udph->uh_dport=tvb_get_ntohs(tvb, offset+2);
203 if (check_col(pinfo->cinfo, COL_INFO))
204 col_add_fstr(pinfo->cinfo, COL_INFO, "Source port: %s Destination port: %s",
205 get_udp_port(udph->uh_sport), get_udp_port(udph->uh_dport));
208 if (udp_summary_in_tree) {
209 if (ip_proto == IP_PROTO_UDP) {
210 ti = proto_tree_add_protocol_format(tree, proto_udp, tvb, offset, 8,
211 "User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
212 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
214 ti = proto_tree_add_protocol_format(tree, proto_udplite, tvb, offset, 8,
215 "Lightweight User Datagram Protocol, Src Port: %s (%u), Dst Port: %s (%u)",
216 get_udp_port(udph->uh_sport), udph->uh_sport, get_udp_port(udph->uh_dport), udph->uh_dport);
219 ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE);
221 udp_tree = proto_item_add_subtree(ti, ett_udp);
223 proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, udph->uh_sport,
224 "Source port: %s (%u)", get_udp_port(udph->uh_sport), udph->uh_sport);
225 proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, udph->uh_dport,
226 "Destination port: %s (%u)", get_udp_port(udph->uh_dport), udph->uh_dport);
228 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_port, tvb, offset, 2, udph->uh_sport);
229 PROTO_ITEM_SET_HIDDEN(hidden_item);
230 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_port, tvb, offset+2, 2, udph->uh_dport);
231 PROTO_ITEM_SET_HIDDEN(hidden_item);
234 if (ip_proto == IP_PROTO_UDP) {
235 udph->uh_ulen = udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
236 if (udph->uh_ulen < 8) {
237 /* Bogus length - it includes the header, so it must be >= 8. */
238 /* XXX - should handle IPv6 UDP jumbograms (RFC 2675), where the length is zero */
239 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
240 udph->uh_ulen, "Length: %u (bogus, must be >= 8)", udph->uh_ulen);
241 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u < 8", udph->uh_ulen);
242 if (check_col(pinfo->cinfo, COL_INFO))
243 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u < 8]", udph->uh_ulen);
246 if ((udph->uh_ulen > tvb_reported_length(tvb)) && ! pinfo->fragmented && ! pinfo->in_error_pkt) {
247 /* Bogus length - it goes past the end of the IP payload */
248 item = proto_tree_add_uint_format(udp_tree, hf_udp_length, tvb, offset + 4, 2,
249 udph->uh_ulen, "Length: %u (bogus, payload length %u)", udph->uh_ulen, tvb_reported_length(tvb));
250 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad length value %u > IP payload length", udph->uh_ulen);
251 if (check_col(pinfo->cinfo, COL_INFO))
252 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD UDP LENGTH %u > IP PAYLOAD LENGTH]", udph->uh_ulen);
255 proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2, udph->uh_ulen);
256 /* XXX - why is this here, given that this is UDP, not Lightweight UDP? */
257 hidden_item = proto_tree_add_uint(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4,
258 0, udph->uh_sum_cov);
259 PROTO_ITEM_SET_HIDDEN(hidden_item);
263 udph->uh_ulen = pinfo->iplen - pinfo->iphdrlen;
264 udph->uh_sum_cov = tvb_get_ntohs(tvb, offset+4);
265 if (((udph->uh_sum_cov > 0) && (udph->uh_sum_cov < 8)) || (udph->uh_sum_cov > udph->uh_ulen)) {
266 /* Bogus length - it includes the header, so it must be >= 8, and no larger then the IP payload size. */
268 hidden_item = proto_tree_add_boolean(udp_tree, hf_udplite_checksum_coverage_bad, tvb, offset + 4, 2, TRUE);
269 PROTO_ITEM_SET_HIDDEN(hidden_item);
270 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
271 PROTO_ITEM_SET_HIDDEN(hidden_item);
273 item = proto_tree_add_uint_format(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2,
274 udph->uh_sum_cov, "Checksum coverage: %u (bogus, must be >= 8 and <= %u (ip.len-ip.hdr_len))",
275 udph->uh_sum_cov, udph->uh_ulen);
276 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Bad checksum coverage length value %u < 8 or > %u",
277 udph->uh_sum_cov, udph->uh_ulen);
278 if (check_col(pinfo->cinfo, COL_INFO))
279 col_append_fstr(pinfo->cinfo, COL_INFO, " [BAD LIGHTWEIGHT UDP CHECKSUM COVERAGE LENGTH %u < 8 or > %u]",
280 udph->uh_sum_cov, udph->uh_ulen);
281 if (!udplite_ignore_checksum_coverage)
285 hidden_item = proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 0, udph->uh_ulen);
286 PROTO_ITEM_SET_HIDDEN(hidden_item);
287 proto_tree_add_uint(udp_tree, hf_udplite_checksum_coverage, tvb, offset + 4, 2, udph->uh_sum_cov);
292 udph->uh_sum_cov = (udph->uh_sum_cov) ? udph->uh_sum_cov : udph->uh_ulen;
293 udph->uh_sum = tvb_get_ntohs(tvb, offset+6);
294 reported_len = tvb_reported_length(tvb);
295 len = tvb_length(tvb);
296 if (udph->uh_sum == 0) {
297 /* No checksum supplied in the packet. */
298 if (ip_proto == IP_PROTO_UDP) {
299 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
300 "Checksum: 0x%04x (none)", 0);
302 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
303 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
304 offset + 6, 2, FALSE);
305 proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
306 offset + 6, 2, FALSE);
308 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, 0,
309 "Checksum: 0x%04x (Illegal)", 0);
310 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Illegal Checksum value (0)");
311 if (check_col(pinfo->cinfo, COL_INFO))
312 col_append_fstr(pinfo->cinfo, COL_INFO, " [ILLEGAL CHECKSUM (0)]");
314 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
315 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
316 offset + 6, 2, FALSE);
317 PROTO_ITEM_SET_GENERATED(item);
318 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
319 offset + 6, 2, TRUE);
320 PROTO_ITEM_SET_GENERATED(item);
322 } else if (!pinfo->fragmented && len >= reported_len &&
323 len >= udph->uh_sum_cov && reported_len >= udph->uh_sum_cov &&
324 udph->uh_sum_cov >=8) {
325 /* The packet isn't part of a fragmented datagram and isn't
326 truncated, so we can checksum it.
327 XXX - make a bigger scatter-gather list once we do fragment
330 if (((ip_proto == IP_PROTO_UDP) && (udp_check_checksum)) ||
331 ((ip_proto == IP_PROTO_UDPLITE) && (udplite_check_checksum))) {
332 /* Set up the fields of the pseudo-header. */
333 cksum_vec[0].ptr = pinfo->src.data;
334 cksum_vec[0].len = pinfo->src.len;
335 cksum_vec[1].ptr = pinfo->dst.data;
336 cksum_vec[1].len = pinfo->dst.len;
337 cksum_vec[2].ptr = (const guint8 *)&phdr;
338 switch (pinfo->src.type) {
341 phdr[0] = g_htonl((ip_proto<<16) + reported_len);
342 cksum_vec[2].len = 4;
346 phdr[0] = g_htonl(reported_len);
347 phdr[1] = g_htonl(ip_proto);
348 cksum_vec[2].len = 8;
352 /* UDP runs only atop IPv4 and IPv6.... */
353 DISSECTOR_ASSERT_NOT_REACHED();
356 cksum_vec[3].ptr = tvb_get_ptr(tvb, offset, udph->uh_sum_cov);
357 cksum_vec[3].len = udph->uh_sum_cov;
358 computed_cksum = in_cksum(&cksum_vec[0], 4);
359 if (computed_cksum == 0) {
360 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
361 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [correct]", udph->uh_sum);
363 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
364 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
365 offset + 6, 2, TRUE);
366 PROTO_ITEM_SET_GENERATED(item);
367 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
368 offset + 6, 2, FALSE);
369 PROTO_ITEM_SET_GENERATED(item);
371 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
372 offset + 6, 2, udph->uh_sum,
373 "Checksum: 0x%04x [incorrect, should be 0x%04x (maybe caused by \"UDP checksum offload\"?)]", udph->uh_sum,
374 in_cksum_shouldbe(udph->uh_sum, computed_cksum));
376 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
377 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
378 offset + 6, 2, FALSE);
379 PROTO_ITEM_SET_GENERATED(item);
380 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
381 offset + 6, 2, TRUE);
382 PROTO_ITEM_SET_GENERATED(item);
383 expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
385 if (check_col(pinfo->cinfo, COL_INFO))
386 col_append_fstr(pinfo->cinfo, COL_INFO, " [UDP CHECKSUM INCORRECT]");
389 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
390 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x [validation disabled]", udph->uh_sum);
391 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
392 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
393 offset + 6, 2, FALSE);
394 PROTO_ITEM_SET_GENERATED(item);
395 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
396 offset + 6, 2, FALSE);
397 PROTO_ITEM_SET_GENERATED(item);
400 item = proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb,
401 offset + 6, 2, udph->uh_sum, "Checksum: 0x%04x", udph->uh_sum);
403 checksum_tree = proto_item_add_subtree(item, ett_udp_checksum);
404 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_good, tvb,
405 offset + 6, 2, FALSE);
406 PROTO_ITEM_SET_GENERATED(item);
407 item = proto_tree_add_boolean(checksum_tree, hf_udp_checksum_bad, tvb,
408 offset + 6, 2, FALSE);
409 PROTO_ITEM_SET_GENERATED(item);
412 /* Skip over header */
415 pinfo->ptype = PT_UDP;
416 pinfo->srcport = udph->uh_sport;
417 pinfo->destport = udph->uh_dport;
419 tap_queue_packet(udp_tap, pinfo, udph);
421 * Call sub-dissectors.
423 * XXX - should we do this if this is included in an error packet?
424 * It might be nice to see the details of the packet that caused the
425 * ICMP error, but it might not be nice to have the dissector update
427 * Also, we probably don't want to run UDP taps on those packets.
429 * We definitely don't want to do it for an error packet if there's
430 * nothing left in the packet.
432 if (!pinfo->in_error_pkt || tvb_length_remaining(tvb, offset) > 0)
433 decode_udp_ports(tvb, offset, pinfo, tree, udph->uh_sport, udph->uh_dport,
438 dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
440 dissect(tvb, pinfo, tree, IP_PROTO_UDP);
444 dissect_udplite(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
446 dissect(tvb, pinfo, tree, IP_PROTO_UDPLITE);
450 proto_register_udp(void)
452 module_t *udp_module;
453 module_t *udplite_module;
455 static hf_register_info hf[] = {
457 { "Source Port", "udp.srcport", FT_UINT16, BASE_DEC, NULL, 0x0,
461 { "Destination Port", "udp.dstport", FT_UINT16, BASE_DEC, NULL, 0x0,
465 { "Source or Destination Port", "udp.port", FT_UINT16, BASE_DEC, NULL, 0x0,
469 { "Length", "udp.length", FT_UINT16, BASE_DEC, NULL, 0x0,
473 { "Checksum", "udp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
474 "Details at: http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html", HFILL }},
476 { &hf_udp_checksum_good,
477 { "Good Checksum", "udp.checksum_good", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
478 "True: checksum matches packet content; False: doesn't match content or not checked", HFILL }},
480 { &hf_udp_checksum_bad,
481 { "Bad Checksum", "udp.checksum_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
482 "True: checksum doesn't match packet content; False: matches content or not checked", HFILL }}
485 static hf_register_info hf_lite[] = {
486 { &hf_udplite_checksum_coverage_bad,
487 { "Bad Checksum coverage", "udp.checksum_coverage_bad", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
490 { &hf_udplite_checksum_coverage,
491 { "Checksum coverage", "udp.checksum_coverage", FT_UINT16, BASE_DEC, NULL, 0x0,
495 static gint *ett[] = {
500 proto_udp = proto_register_protocol("User Datagram Protocol",
502 register_dissector("udp", dissect_udp, proto_udp);
503 proto_udplite = proto_register_protocol("Lightweight User Datagram Protocol",
504 "UDPlite", "udplite");
505 proto_register_field_array(proto_udp, hf, array_length(hf));
506 proto_register_field_array(proto_udplite, hf_lite, array_length(hf_lite));
507 proto_register_subtree_array(ett, array_length(ett));
509 /* subdissector code */
510 udp_dissector_table = register_dissector_table("udp.port",
511 "UDP port", FT_UINT16, BASE_DEC);
512 register_heur_dissector_list("udp", &heur_subdissector_list);
513 register_heur_dissector_list("udplite", &heur_subdissector_list);
515 /* Register configuration preferences */
516 udp_module = prefs_register_protocol(proto_udp, NULL);
517 prefs_register_bool_preference(udp_module, "summary_in_tree",
518 "Show UDP summary in protocol tree",
519 "Whether the UDP summary line should be shown in the protocol tree",
520 &udp_summary_in_tree);
521 prefs_register_bool_preference(udp_module, "try_heuristic_first",
522 "Try heuristic sub-dissectors first",
523 "Try to decode a packet using an heuristic sub-dissector before using a sub-dissector registered to a specific port",
524 &try_heuristic_first);
525 prefs_register_bool_preference(udp_module, "check_checksum",
526 "Validate the UDP checksum if possible",
527 "Whether to validate the UDP checksum",
528 &udp_check_checksum);
530 udplite_module = prefs_register_protocol(proto_udplite, NULL);
531 prefs_register_bool_preference(udplite_module, "ignore_checksum_coverage",
532 "Ignore UDPlite checksum coverage",
533 "Ignore an invalid checksum coverage field and continue dissection",
534 &udplite_ignore_checksum_coverage);
535 prefs_register_bool_preference(udplite_module, "check_checksum",
536 "Validate the UDPlite checksum if possible",
537 "Whether to validate the UDPlite checksum",
538 &udplite_check_checksum);
542 proto_reg_handoff_udp(void)
544 dissector_handle_t udp_handle;
545 dissector_handle_t udplite_handle;
547 udp_handle = find_dissector("udp");
548 dissector_add("ip.proto", IP_PROTO_UDP, udp_handle);
549 udplite_handle = create_dissector_handle(dissect_udplite, proto_udplite);
550 dissector_add("ip.proto", IP_PROTO_UDPLITE, udplite_handle);
551 data_handle = find_dissector("data");
552 udp_tap = register_tap("udp");
553 udp_follow_tap = register_tap("udp_follow");