1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22/* \summary: UDP printer */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include "netdissect-stdinc.h"
29
30#include "netdissect.h"
31#include "addrtoname.h"
32#include "extract.h"
33#include "appletalk.h"
34
35#include "udp.h"
36
37#include "ip.h"
38#include "ip6.h"
39#include "ipproto.h"
40#include "rpc_auth.h"
41#include "rpc_msg.h"
42
43#include "nfs.h"
44
45
46struct rtcphdr {
47	nd_uint16_t rh_flags;	/* T:2 P:1 CNT:5 PT:8 */
48	nd_uint16_t rh_len;	/* length of message (in words) */
49	nd_uint32_t rh_ssrc;	/* synchronization src id */
50};
51
52typedef struct {
53	nd_uint32_t upper;	/* more significant 32 bits */
54	nd_uint32_t lower;	/* less significant 32 bits */
55} ntp64;
56
57/*
58 * Sender report.
59 */
60struct rtcp_sr {
61	ntp64       sr_ntp;	/* 64-bit ntp timestamp */
62	nd_uint32_t sr_ts;	/* reference media timestamp */
63	nd_uint32_t sr_np;	/* no. packets sent */
64	nd_uint32_t sr_nb;	/* no. bytes sent */
65};
66
67/*
68 * Receiver report.
69 * Time stamps are middle 32-bits of ntp timestamp.
70 */
71struct rtcp_rr {
72	nd_uint32_t rr_srcid;	/* sender being reported */
73	nd_uint32_t rr_nl;	/* no. packets lost */
74	nd_uint32_t rr_ls;	/* extended last seq number received */
75	nd_uint32_t rr_dv;	/* jitter (delay variance) */
76	nd_uint32_t rr_lsr;	/* orig. ts from last rr from this src  */
77	nd_uint32_t rr_dlsr;	/* time from recpt of last rr to xmit time */
78};
79
80/*XXX*/
81#define RTCP_PT_SR	200
82#define RTCP_PT_RR	201
83#define RTCP_PT_SDES	202
84#define    RTCP_SDES_CNAME	1
85#define    RTCP_SDES_NAME	2
86#define    RTCP_SDES_EMAIL	3
87#define    RTCP_SDES_PHONE	4
88#define    RTCP_SDES_LOC	5
89#define    RTCP_SDES_TOOL	6
90#define    RTCP_SDES_NOTE	7
91#define    RTCP_SDES_PRIV	8
92#define RTCP_PT_BYE	203
93#define RTCP_PT_APP	204
94
95static void
96vat_print(netdissect_options *ndo, const u_char *hdr, u_int length)
97{
98	/* vat/vt audio */
99	u_int ts;
100
101	ndo->ndo_protocol = "vat";
102	if (length < 2) {
103		ND_PRINT("udp/va/vat, length %u < 2", length);
104		return;
105	}
106	ts = GET_BE_U_2(hdr);
107	if ((ts & 0xf060) != 0) {
108		/* probably vt */
109		ND_PRINT("udp/vt %u %u / %u",
110			     length,
111			     ts & 0x3ff, ts >> 10);
112	} else {
113		/* probably vat */
114		uint32_t i0, i1;
115
116		if (length < 8) {
117			ND_PRINT("udp/vat, length %u < 8", length);
118			return;
119		}
120		i0 = GET_BE_U_4(&((const u_int *)hdr)[0]);
121		i1 = GET_BE_U_4(&((const u_int *)hdr)[1]);
122		ND_PRINT("udp/vat %u c%u %u%s",
123			length - 8,
124			i0 & 0xffff,
125			i1, i0 & 0x800000? "*" : "");
126		/* audio format */
127		if (i0 & 0x1f0000)
128			ND_PRINT(" f%u", (i0 >> 16) & 0x1f);
129		if (i0 & 0x3f000000)
130			ND_PRINT(" s%u", (i0 >> 24) & 0x3f);
131	}
132}
133
134static void
135rtp_print(netdissect_options *ndo, const u_char *hdr, u_int len)
136{
137	/* rtp v1 or v2 */
138	const u_int *ip = (const u_int *)hdr;
139	u_int hasopt, hasext, contype, hasmarker, dlen;
140	uint32_t i0, i1;
141	const char * ptype;
142
143	ndo->ndo_protocol = "rtp";
144	if (len < 8) {
145		ND_PRINT("udp/rtp, length %u < 8", len);
146		return;
147	}
148	i0 = GET_BE_U_4(&((const u_int *)hdr)[0]);
149	i1 = GET_BE_U_4(&((const u_int *)hdr)[1]);
150	dlen = len - 8;
151	ip += 2;
152	len >>= 2;
153	len -= 2;
154	hasopt = 0;
155	hasext = 0;
156	if ((i0 >> 30) == 1) {
157		/* rtp v1 - draft-ietf-avt-rtp-04 */
158		hasopt = i0 & 0x800000;
159		contype = (i0 >> 16) & 0x3f;
160		hasmarker = i0 & 0x400000;
161		ptype = "rtpv1";
162	} else {
163		/* rtp v2 - RFC 3550 */
164		if (dlen < 4) {
165			ND_PRINT("udp/rtp, length %u < 12", dlen + 8);
166			return;
167		}
168		hasext = i0 & 0x10000000;
169		contype = (i0 >> 16) & 0x7f;
170		hasmarker = i0 & 0x800000;
171		dlen -= 4;
172		ptype = "rtp";
173		ip += 1;
174		len -= 1;
175	}
176	ND_PRINT("udp/%s %u c%u %s%s %u %u",
177		ptype,
178		dlen,
179		contype,
180		(hasopt || hasext)? "+" : "",
181		hasmarker? "*" : "",
182		i0 & 0xffff,
183		i1);
184	if (ndo->ndo_vflag) {
185		ND_PRINT(" %u", GET_BE_U_4(&((const u_int *)hdr)[2]));
186		if (hasopt) {
187			u_int i2, optlen;
188			do {
189				i2 = GET_BE_U_4(ip);
190				optlen = (i2 >> 16) & 0xff;
191				if (optlen == 0 || optlen > len) {
192					ND_PRINT(" !opt");
193					return;
194				}
195				ip += optlen;
196				len -= optlen;
197			} while ((int)i2 >= 0);
198		}
199		if (hasext) {
200			u_int i2, extlen;
201			i2 = GET_BE_U_4(ip);
202			extlen = (i2 & 0xffff) + 1;
203			if (extlen > len) {
204				ND_PRINT(" !ext");
205				return;
206			}
207			ip += extlen;
208		}
209		if (contype == 0x1f) /*XXX H.261 */
210			ND_PRINT(" 0x%04x", GET_BE_U_4(ip) >> 16);
211	}
212}
213
214static const u_char *
215rtcp_print(netdissect_options *ndo, const u_char *hdr, const u_char *ep)
216{
217	/* rtp v2 control (rtcp) */
218	const struct rtcp_rr *rr = 0;
219	const struct rtcp_sr *sr;
220	const struct rtcphdr *rh = (const struct rtcphdr *)hdr;
221	u_int len;
222	uint16_t flags;
223	u_int cnt;
224	double ts, dts;
225
226	ndo->ndo_protocol = "rtcp";
227	if ((const u_char *)(rh + 1) > ep)
228		goto trunc;
229	ND_TCHECK_SIZE(rh);
230	len = (GET_BE_U_2(rh->rh_len) + 1) * 4;
231	flags = GET_BE_U_2(rh->rh_flags);
232	cnt = (flags >> 8) & 0x1f;
233	switch (flags & 0xff) {
234	case RTCP_PT_SR:
235		sr = (const struct rtcp_sr *)(rh + 1);
236		ND_PRINT(" sr");
237		if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
238			ND_PRINT(" [%u]", len);
239		if (ndo->ndo_vflag)
240			ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc));
241		if ((const u_char *)(sr + 1) > ep)
242			goto trunc;
243		ND_TCHECK_SIZE(sr);
244		ts = (double)(GET_BE_U_4(sr->sr_ntp.upper)) +
245		    ((double)(GET_BE_U_4(sr->sr_ntp.lower)) /
246		     FMAXINT);
247		ND_PRINT(" @%.2f %u %up %ub", ts, GET_BE_U_4(sr->sr_ts),
248			  GET_BE_U_4(sr->sr_np), GET_BE_U_4(sr->sr_nb));
249		rr = (const struct rtcp_rr *)(sr + 1);
250		break;
251	case RTCP_PT_RR:
252		ND_PRINT(" rr");
253		if (len != cnt * sizeof(*rr) + sizeof(*rh))
254			ND_PRINT(" [%u]", len);
255		rr = (const struct rtcp_rr *)(rh + 1);
256		if (ndo->ndo_vflag)
257			ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc));
258		break;
259	case RTCP_PT_SDES:
260		ND_PRINT(" sdes %u", len);
261		if (ndo->ndo_vflag)
262			ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc));
263		cnt = 0;
264		break;
265	case RTCP_PT_BYE:
266		ND_PRINT(" bye %u", len);
267		if (ndo->ndo_vflag)
268			ND_PRINT(" %u", GET_BE_U_4(rh->rh_ssrc));
269		cnt = 0;
270		break;
271	default:
272		ND_PRINT(" type-0x%x %u", flags & 0xff, len);
273		cnt = 0;
274		break;
275	}
276	if (cnt > 1)
277		ND_PRINT(" c%u", cnt);
278	while (cnt != 0) {
279		if ((const u_char *)(rr + 1) > ep)
280			goto trunc;
281		ND_TCHECK_SIZE(rr);
282		if (ndo->ndo_vflag)
283			ND_PRINT(" %u", GET_BE_U_4(rr->rr_srcid));
284		ts = (double)(GET_BE_U_4(rr->rr_lsr)) / 65536.;
285		dts = (double)(GET_BE_U_4(rr->rr_dlsr)) / 65536.;
286		ND_PRINT(" %ul %us %uj @%.2f+%.2f",
287		    GET_BE_U_4(rr->rr_nl) & 0x00ffffff,
288		    GET_BE_U_4(rr->rr_ls),
289		    GET_BE_U_4(rr->rr_dv), ts, dts);
290		cnt--;
291	}
292	return (hdr + len);
293
294trunc:
295	nd_print_trunc(ndo);
296	return ep;
297}
298
299static uint16_t udp_cksum(netdissect_options *ndo, const struct ip *ip,
300		     const struct udphdr *up,
301		     u_int len)
302{
303	return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)up, len, len,
304				IPPROTO_UDP);
305}
306
307static uint16_t udp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6,
308		      const struct udphdr *up, u_int len)
309{
310	return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)up, len, len,
311				IPPROTO_UDP);
312}
313
314static void
315udpipaddr_print(netdissect_options *ndo, const struct ip *ip, int sport, int dport)
316{
317	const struct ip6_hdr *ip6;
318
319	if (IP_V(ip) == 6)
320		ip6 = (const struct ip6_hdr *)ip;
321	else
322		ip6 = NULL;
323
324	if (ip6) {
325		if (GET_U_1(ip6->ip6_nxt) == IPPROTO_UDP) {
326			if (sport == -1) {
327				ND_PRINT("%s > %s: ",
328					GET_IP6ADDR_STRING(ip6->ip6_src),
329					GET_IP6ADDR_STRING(ip6->ip6_dst));
330			} else {
331				ND_PRINT("%s.%s > %s.%s: ",
332					GET_IP6ADDR_STRING(ip6->ip6_src),
333					udpport_string(ndo, (uint16_t)sport),
334					GET_IP6ADDR_STRING(ip6->ip6_dst),
335					udpport_string(ndo, (uint16_t)dport));
336			}
337		} else {
338			if (sport != -1) {
339				ND_PRINT("%s > %s: ",
340					udpport_string(ndo, (uint16_t)sport),
341					udpport_string(ndo, (uint16_t)dport));
342			}
343		}
344	} else {
345		if (GET_U_1(ip->ip_p) == IPPROTO_UDP) {
346			if (sport == -1) {
347				ND_PRINT("%s > %s: ",
348					GET_IPADDR_STRING(ip->ip_src),
349					GET_IPADDR_STRING(ip->ip_dst));
350			} else {
351				ND_PRINT("%s.%s > %s.%s: ",
352					GET_IPADDR_STRING(ip->ip_src),
353					udpport_string(ndo, (uint16_t)sport),
354					GET_IPADDR_STRING(ip->ip_dst),
355					udpport_string(ndo, (uint16_t)dport));
356			}
357		} else {
358			if (sport != -1) {
359				ND_PRINT("%s > %s: ",
360					udpport_string(ndo, (uint16_t)sport),
361					udpport_string(ndo, (uint16_t)dport));
362			}
363		}
364	}
365}
366
367void
368udp_print(netdissect_options *ndo, const u_char *bp, u_int length,
369	  const u_char *bp2, int fragmented, u_int ttl_hl)
370{
371	const struct udphdr *up;
372	const struct ip *ip;
373	const u_char *cp;
374	const u_char *ep = ndo->ndo_snapend;
375	uint16_t sport, dport;
376	u_int ulen;
377	const struct ip6_hdr *ip6;
378
379	ndo->ndo_protocol = "udp";
380	up = (const struct udphdr *)bp;
381	ip = (const struct ip *)bp2;
382	if (IP_V(ip) == 6)
383		ip6 = (const struct ip6_hdr *)bp2;
384	else
385		ip6 = NULL;
386	if (!ND_TTEST_2(up->uh_dport)) {
387		udpipaddr_print(ndo, ip, -1, -1);
388		goto trunc;
389	}
390
391	sport = GET_BE_U_2(up->uh_sport);
392	dport = GET_BE_U_2(up->uh_dport);
393
394	if (length < sizeof(struct udphdr)) {
395		udpipaddr_print(ndo, ip, sport, dport);
396		ND_PRINT("truncated-udp %u", length);
397		return;
398	}
399	if (!ND_TTEST_2(up->uh_ulen)) {
400		udpipaddr_print(ndo, ip, sport, dport);
401		goto trunc;
402	}
403	ulen = GET_BE_U_2(up->uh_ulen);
404	/*
405	 * IPv6 Jumbo Datagrams; see RFC 2675.
406	 * If the length is zero, and the length provided to us is
407	 * > 65535, use the provided length as the length.
408	 */
409	if (ulen == 0 && length > 65535)
410		ulen = length;
411	if (ulen < sizeof(struct udphdr)) {
412		udpipaddr_print(ndo, ip, sport, dport);
413		ND_PRINT("truncated-udplength %u", ulen);
414		return;
415	}
416	ulen -= sizeof(struct udphdr);
417	length -= sizeof(struct udphdr);
418	if (ulen < length)
419		length = ulen;
420
421	cp = (const u_char *)(up + 1);
422	if (cp > ndo->ndo_snapend) {
423		udpipaddr_print(ndo, ip, sport, dport);
424		goto trunc;
425	}
426
427	if (ndo->ndo_packettype) {
428		const struct sunrpc_msg *rp;
429		enum sunrpc_msg_type direction;
430
431		switch (ndo->ndo_packettype) {
432
433		case PT_VAT:
434			udpipaddr_print(ndo, ip, sport, dport);
435			vat_print(ndo, cp, length);
436			break;
437
438		case PT_WB:
439			udpipaddr_print(ndo, ip, sport, dport);
440			wb_print(ndo, cp, length);
441			break;
442
443		case PT_RPC:
444			rp = (const struct sunrpc_msg *)cp;
445			direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction);
446			if (direction == SUNRPC_CALL)
447				sunrpc_print(ndo, (const u_char *)rp, length,
448				    (const u_char *)ip);
449			else
450				nfsreply_print(ndo, (const u_char *)rp, length,
451				    (const u_char *)ip);			/*XXX*/
452			break;
453
454		case PT_RTP:
455			udpipaddr_print(ndo, ip, sport, dport);
456			rtp_print(ndo, cp, length);
457			break;
458
459		case PT_RTCP:
460			udpipaddr_print(ndo, ip, sport, dport);
461			while (cp < ep)
462				cp = rtcp_print(ndo, cp, ep);
463			break;
464
465		case PT_SNMP:
466			udpipaddr_print(ndo, ip, sport, dport);
467			snmp_print(ndo, cp, length);
468			break;
469
470		case PT_CNFP:
471			udpipaddr_print(ndo, ip, sport, dport);
472			cnfp_print(ndo, cp);
473			break;
474
475		case PT_TFTP:
476			udpipaddr_print(ndo, ip, sport, dport);
477			tftp_print(ndo, cp, length);
478			break;
479
480		case PT_AODV:
481			udpipaddr_print(ndo, ip, sport, dport);
482			aodv_print(ndo, cp, length,
483			    ip6 != NULL);
484			break;
485
486		case PT_RADIUS:
487			udpipaddr_print(ndo, ip, sport, dport);
488			radius_print(ndo, cp, length);
489			break;
490
491		case PT_VXLAN:
492			udpipaddr_print(ndo, ip, sport, dport);
493			vxlan_print(ndo, cp, length);
494			break;
495
496		case PT_PGM:
497		case PT_PGM_ZMTP1:
498			udpipaddr_print(ndo, ip, sport, dport);
499			pgm_print(ndo, cp, length, bp2);
500			break;
501		case PT_LMP:
502			udpipaddr_print(ndo, ip, sport, dport);
503			lmp_print(ndo, cp, length);
504			break;
505		case PT_PTP:
506			udpipaddr_print(ndo, ip, sport, dport);
507			ptp_print(ndo, cp, length);
508			break;
509		case PT_SOMEIP:
510			udpipaddr_print(ndo, ip, sport, dport);
511			someip_print(ndo, cp, length);
512			break;
513		case PT_DOMAIN:
514			udpipaddr_print(ndo, ip, sport, dport);
515			/* over_tcp: FALSE, is_mdns: FALSE */
516			domain_print(ndo, cp, length, FALSE, FALSE);
517			break;
518		}
519		return;
520	}
521
522	udpipaddr_print(ndo, ip, sport, dport);
523	if (!ndo->ndo_qflag) {
524		const struct sunrpc_msg *rp;
525		enum sunrpc_msg_type direction;
526
527		rp = (const struct sunrpc_msg *)cp;
528		if (ND_TTEST_4(rp->rm_direction)) {
529			direction = (enum sunrpc_msg_type) GET_BE_U_4(rp->rm_direction);
530			if (dport == NFS_PORT && direction == SUNRPC_CALL) {
531				ND_PRINT("NFS request xid %u ",
532					 GET_BE_U_4(rp->rm_xid));
533				nfsreq_noaddr_print(ndo, (const u_char *)rp, length,
534				    (const u_char *)ip);
535				return;
536			}
537			if (sport == NFS_PORT && direction == SUNRPC_REPLY) {
538				ND_PRINT("NFS reply xid %u ",
539					 GET_BE_U_4(rp->rm_xid));
540				nfsreply_noaddr_print(ndo, (const u_char *)rp, length,
541				    (const u_char *)ip);
542				return;
543			}
544#ifdef notdef
545			if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) {
546				sunrpc_print((const u_char *)rp, length, (const u_char *)ip);
547				return;
548			}
549#endif
550		}
551	}
552
553	if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) {
554		/* Check the checksum, if possible. */
555		uint16_t sum, udp_sum;
556
557		/*
558		 * XXX - do this even if vflag == 1?
559		 * TCP does, and we do so for UDP-over-IPv6.
560		 */
561		if (IP_V(ip) == 4 && (ndo->ndo_vflag > 1)) {
562			udp_sum = GET_BE_U_2(up->uh_sum);
563			if (udp_sum == 0) {
564				ND_PRINT("[no cksum] ");
565			} else if (ND_TTEST_LEN(cp, length)) {
566				sum = udp_cksum(ndo, ip, up, length + sizeof(struct udphdr));
567
568				if (sum != 0) {
569					ND_PRINT("[bad udp cksum 0x%04x -> 0x%04x!] ",
570					    udp_sum,
571					    in_cksum_shouldbe(udp_sum, sum));
572				} else
573					ND_PRINT("[udp sum ok] ");
574			}
575		}
576		else if (IP_V(ip) == 6) {
577			/* for IPv6, UDP checksum is mandatory */
578			if (ND_TTEST_LEN(cp, length)) {
579				sum = udp6_cksum(ndo, ip6, up, length + sizeof(struct udphdr));
580				udp_sum = GET_BE_U_2(up->uh_sum);
581
582				if (sum != 0) {
583					ND_PRINT("[bad udp cksum 0x%04x -> 0x%04x!] ",
584					    udp_sum,
585					    in_cksum_shouldbe(udp_sum, sum));
586				} else
587					ND_PRINT("[udp sum ok] ");
588			}
589		}
590	}
591
592	if (!ndo->ndo_qflag) {
593		if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))
594			/* over_tcp: FALSE, is_mdns: FALSE */
595			domain_print(ndo, cp, length, FALSE, FALSE);
596		else if (IS_SRC_OR_DST_PORT(MULTICASTDNS_PORT))
597			/* over_tcp: FALSE, is_mdns: TRUE */
598			domain_print(ndo, cp, length, FALSE, TRUE);
599		else if (IS_SRC_OR_DST_PORT(TIMED_PORT))
600			timed_print(ndo, (const u_char *)cp);
601		else if (IS_SRC_OR_DST_PORT(TFTP_PORT))
602			tftp_print(ndo, cp, length);
603		else if (IS_SRC_OR_DST_PORT(BOOTPC_PORT) || IS_SRC_OR_DST_PORT(BOOTPS_PORT))
604			bootp_print(ndo, cp, length);
605		else if (IS_SRC_OR_DST_PORT(RIP_PORT))
606			rip_print(ndo, cp, length);
607		else if (IS_SRC_OR_DST_PORT(AODV_PORT))
608			aodv_print(ndo, cp, length,
609			    ip6 != NULL);
610		else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT))
611			 isakmp_print(ndo, cp, length, bp2);
612		else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_NATT))
613			 isakmp_rfc3948_print(ndo, cp, length, bp2, IP_V(ip), fragmented, ttl_hl);
614		else if (IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER1) || IS_SRC_OR_DST_PORT(ISAKMP_PORT_USER2))
615			isakmp_print(ndo, cp, length, bp2);
616		else if (IS_SRC_OR_DST_PORT(SNMP_PORT) || IS_SRC_OR_DST_PORT(SNMPTRAP_PORT))
617			snmp_print(ndo, cp, length);
618		else if (IS_SRC_OR_DST_PORT(NTP_PORT))
619			ntp_print(ndo, cp, length);
620		else if (IS_SRC_OR_DST_PORT(KERBEROS_PORT) || IS_SRC_OR_DST_PORT(KERBEROS_SEC_PORT))
621			krb_print(ndo, (const u_char *)cp);
622		else if (IS_SRC_OR_DST_PORT(L2TP_PORT))
623			l2tp_print(ndo, cp, length);
624#ifdef ENABLE_SMB
625		else if (IS_SRC_OR_DST_PORT(NETBIOS_NS_PORT))
626			nbt_udp137_print(ndo, cp, length);
627		else if (IS_SRC_OR_DST_PORT(NETBIOS_DGRAM_PORT))
628			nbt_udp138_print(ndo, cp, length);
629#endif
630		else if (dport == VAT_PORT)
631			vat_print(ndo, cp, length);
632		else if (IS_SRC_OR_DST_PORT(ZEPHYR_SRV_PORT) || IS_SRC_OR_DST_PORT(ZEPHYR_CLT_PORT))
633			zephyr_print(ndo, cp, length);
634		/*
635		 * Since there are 10 possible ports to check, I think
636		 * a <> test would be more efficient
637		 */
638		else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) ||
639			 (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH))
640			rx_print(ndo, cp, length, sport, dport,
641				 (const u_char *) ip);
642		else if (IS_SRC_OR_DST_PORT(RIPNG_PORT))
643			ripng_print(ndo, cp, length);
644		else if (IS_SRC_OR_DST_PORT(DHCP6_SERV_PORT) || IS_SRC_OR_DST_PORT(DHCP6_CLI_PORT))
645			dhcp6_print(ndo, cp, length);
646		else if (IS_SRC_OR_DST_PORT(AHCP_PORT))
647			ahcp_print(ndo, cp, length);
648		else if (IS_SRC_OR_DST_PORT(BABEL_PORT) || IS_SRC_OR_DST_PORT(BABEL_PORT_OLD))
649			babel_print(ndo, cp, length);
650		else if (IS_SRC_OR_DST_PORT(HNCP_PORT))
651			hncp_print(ndo, cp, length);
652		/*
653		 * Kludge in test for whiteboard packets.
654		 */
655		else if (dport == WB_PORT)
656			wb_print(ndo, cp, length);
657		else if (IS_SRC_OR_DST_PORT(CISCO_AUTORP_PORT))
658			cisco_autorp_print(ndo, cp, length);
659		else if (IS_SRC_OR_DST_PORT(RADIUS_PORT) ||
660			 IS_SRC_OR_DST_PORT(RADIUS_NEW_PORT) ||
661			 IS_SRC_OR_DST_PORT(RADIUS_ACCOUNTING_PORT) ||
662			 IS_SRC_OR_DST_PORT(RADIUS_NEW_ACCOUNTING_PORT) ||
663			 IS_SRC_OR_DST_PORT(RADIUS_CISCO_COA_PORT) ||
664			 IS_SRC_OR_DST_PORT(RADIUS_COA_PORT) )
665			radius_print(ndo, cp, length);
666		else if (dport == HSRP_PORT)
667			hsrp_print(ndo, cp, length);
668		else if (IS_SRC_OR_DST_PORT(LWRES_PORT))
669			lwres_print(ndo, cp, length);
670		else if (IS_SRC_OR_DST_PORT(LDP_PORT))
671			ldp_print(ndo, cp, length);
672		else if (IS_SRC_OR_DST_PORT(OLSR_PORT))
673			olsr_print(ndo, cp, length,
674					(IP_V(ip) == 6) ? 1 : 0);
675		else if (IS_SRC_OR_DST_PORT(MPLS_LSP_PING_PORT))
676			lspping_print(ndo, cp, length);
677		else if (sport == BCM_LI_PORT)
678			bcm_li_print(ndo, cp, length);
679		else if (dport == BFD_CONTROL_PORT ||
680			 dport == BFD_MULTIHOP_PORT ||
681			 dport == BFD_LAG_PORT ||
682			 dport == BFD_ECHO_PORT )
683			bfd_print(ndo, cp, length, dport);
684		else if (IS_SRC_OR_DST_PORT(LMP_PORT))
685			lmp_print(ndo, cp, length);
686		else if (IS_SRC_OR_DST_PORT(VQP_PORT))
687			vqp_print(ndo, cp, length);
688		else if (IS_SRC_OR_DST_PORT(SFLOW_PORT))
689			sflow_print(ndo, cp, length);
690		else if (dport == LWAPP_CONTROL_PORT)
691			lwapp_control_print(ndo, cp, length, 1);
692		else if (sport == LWAPP_CONTROL_PORT)
693			lwapp_control_print(ndo, cp, length, 0);
694		else if (IS_SRC_OR_DST_PORT(LWAPP_DATA_PORT))
695			lwapp_data_print(ndo, cp, length);
696		else if (IS_SRC_OR_DST_PORT(SIP_PORT))
697			sip_print(ndo, cp, length);
698		else if (IS_SRC_OR_DST_PORT(SYSLOG_PORT))
699			syslog_print(ndo, cp, length);
700		else if (IS_SRC_OR_DST_PORT(OTV_PORT))
701			otv_print(ndo, cp, length);
702		else if (IS_SRC_OR_DST_PORT(VXLAN_PORT))
703			vxlan_print(ndo, cp, length);
704		else if (dport == GENEVE_PORT)
705			geneve_print(ndo, cp, length);
706		else if (IS_SRC_OR_DST_PORT(LISP_CONTROL_PORT))
707			lisp_print(ndo, cp, length);
708		else if (IS_SRC_OR_DST_PORT(VXLAN_GPE_PORT))
709			vxlan_gpe_print(ndo, cp, length);
710		else if (IS_SRC_OR_DST_PORT(ZEP_PORT))
711			zep_print(ndo, cp, length);
712		else if (IS_SRC_OR_DST_PORT(MPLS_PORT))
713			mpls_print(ndo, cp, length);
714		else if (ND_TTEST_1(((const struct LAP *)cp)->type) &&
715			 GET_U_1(((const struct LAP *)cp)->type) == lapDDP &&
716			 (atalk_port(sport) || atalk_port(dport))) {
717			if (ndo->ndo_vflag)
718				ND_PRINT("kip ");
719			llap_print(ndo, cp, length);
720		} else if (IS_SRC_OR_DST_PORT(PTP_EVENT_PORT) ||
721			IS_SRC_OR_DST_PORT(PTP_GENERAL_PORT)) {
722			ptp_print(ndo, cp, length);
723		} else if (IS_SRC_OR_DST_PORT(SOMEIP_PORT))
724			someip_print(ndo, cp, length);
725		else {
726			if (ulen > length && !fragmented)
727				ND_PRINT("UDP, bad length %u > %u",
728				    ulen, length);
729			else
730				ND_PRINT("UDP, length %u", ulen);
731		}
732	} else {
733		if (ulen > length && !fragmented)
734			ND_PRINT("UDP, bad length %u > %u",
735			    ulen, length);
736		else
737			ND_PRINT("UDP, length %u", ulen);
738	}
739	return;
740
741trunc:
742	nd_print_trunc(ndo);
743}
744