117680Spst/*
239300Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056896Sfenner *
2156896Sfenner * $FreeBSD$
2217680Spst */
2317680Spst
2417680Spst#ifndef lint
25127675Sbmsstatic const char rcsid[] _U_ =
26190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.142 2007-08-08 17:20:58 hannes Exp $ (LBL)";
2717680Spst#endif
2817680Spst
2956896Sfenner#ifdef HAVE_CONFIG_H
3056896Sfenner#include "config.h"
3156896Sfenner#endif
3256896Sfenner
33127675Sbms#include <tcpdump-stdinc.h>
3417680Spst
3539300Sfenner#ifdef SEGSIZE
3639300Sfenner#undef SEGSIZE
3739300Sfenner#endif
3817680Spst
3917680Spst#include <stdio.h>
4075118Sfenner#include <string.h>
4117680Spst
4217680Spst#include "interface.h"
4317680Spst#include "addrtoname.h"
44127675Sbms#include "extract.h"
4517680Spst#include "appletalk.h"
4617680Spst
4775118Sfenner#include "udp.h"
4875118Sfenner
4975118Sfenner#include "ip.h"
5075118Sfenner#ifdef INET6
5175118Sfenner#include "ip6.h"
5275118Sfenner#endif
53127675Sbms#include "ipproto.h"
54146778Ssam#include "rpc_auth.h"
55146778Ssam#include "rpc_msg.h"
5675118Sfenner
5775118Sfenner#include "nameser.h"
5819001Spst#include "nfs.h"
5917680Spst#include "bootp.h"
6017680Spst
6117680Spststruct rtcphdr {
6275118Sfenner	u_int16_t rh_flags;	/* T:2 P:1 CNT:5 PT:8 */
6375118Sfenner	u_int16_t rh_len;	/* length of message (in words) */
6475118Sfenner	u_int32_t rh_ssrc;	/* synchronization src id */
6517680Spst};
6617680Spst
6717680Spsttypedef struct {
6875118Sfenner	u_int32_t upper;	/* more significant 32 bits */
6975118Sfenner	u_int32_t lower;	/* less significant 32 bits */
7017680Spst} ntp64;
7117680Spst
7217680Spst/*
7317680Spst * Sender report.
7417680Spst */
7517680Spststruct rtcp_sr {
7617680Spst	ntp64 sr_ntp;		/* 64-bit ntp timestamp */
7775118Sfenner	u_int32_t sr_ts;	/* reference media timestamp */
7875118Sfenner	u_int32_t sr_np;	/* no. packets sent */
7975118Sfenner	u_int32_t sr_nb;	/* no. bytes sent */
8017680Spst};
8117680Spst
8217680Spst/*
8317680Spst * Receiver report.
8417680Spst * Time stamps are middle 32-bits of ntp timestamp.
8517680Spst */
8617680Spststruct rtcp_rr {
8775118Sfenner	u_int32_t rr_srcid;	/* sender being reported */
8875118Sfenner	u_int32_t rr_nl;	/* no. packets lost */
8975118Sfenner	u_int32_t rr_ls;	/* extended last seq number received */
9075118Sfenner	u_int32_t rr_dv;	/* jitter (delay variance) */
9175118Sfenner	u_int32_t rr_lsr;	/* orig. ts from last rr from this src  */
9275118Sfenner	u_int32_t rr_dlsr;	/* time from recpt of last rr to xmit time */
9317680Spst};
9417680Spst
9517680Spst/*XXX*/
9626183Sfenner#define RTCP_PT_SR	200
9726183Sfenner#define RTCP_PT_RR	201
9826183Sfenner#define RTCP_PT_SDES	202
9917680Spst#define 	RTCP_SDES_CNAME	1
10017680Spst#define 	RTCP_SDES_NAME	2
10117680Spst#define 	RTCP_SDES_EMAIL	3
10217680Spst#define 	RTCP_SDES_PHONE	4
10317680Spst#define 	RTCP_SDES_LOC	5
10417680Spst#define 	RTCP_SDES_TOOL	6
10526183Sfenner#define 	RTCP_SDES_NOTE	7
10626183Sfenner#define 	RTCP_SDES_PRIV	8
10726183Sfenner#define RTCP_PT_BYE	203
10826183Sfenner#define RTCP_PT_APP	204
10917680Spst
11017680Spststatic void
111127675Sbmsvat_print(const void *hdr, register const struct udphdr *up)
11217680Spst{
11317680Spst	/* vat/vt audio */
11475118Sfenner	u_int ts = *(u_int16_t *)hdr;
11517680Spst	if ((ts & 0xf060) != 0) {
11617680Spst		/* probably vt */
11798527Sfenner		(void)printf("udp/vt %u %d / %d",
118127675Sbms			     (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)),
11917680Spst			     ts & 0x3ff, ts >> 10);
12017680Spst	} else {
12117680Spst		/* probably vat */
122127675Sbms		u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
123127675Sbms		u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
12498527Sfenner		printf("udp/vat %u c%d %u%s",
125127675Sbms			(u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8),
12617680Spst			i0 & 0xffff,
12717680Spst			i1, i0 & 0x800000? "*" : "");
12817680Spst		/* audio format */
12917680Spst		if (i0 & 0x1f0000)
13017680Spst			printf(" f%d", (i0 >> 16) & 0x1f);
13117680Spst		if (i0 & 0x3f000000)
13217680Spst			printf(" s%d", (i0 >> 24) & 0x3f);
13317680Spst	}
13417680Spst}
13517680Spst
13617680Spststatic void
13717680Spstrtp_print(const void *hdr, u_int len, register const struct udphdr *up)
13817680Spst{
13917680Spst	/* rtp v1 or v2 */
14017680Spst	u_int *ip = (u_int *)hdr;
14126183Sfenner	u_int hasopt, hasext, contype, hasmarker;
142127675Sbms	u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
143127675Sbms	u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
144127675Sbms	u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8;
14526183Sfenner	const char * ptype;
14617680Spst
14717680Spst	ip += 2;
14817680Spst	len >>= 2;
14917680Spst	len -= 2;
15026183Sfenner	hasopt = 0;
15126183Sfenner	hasext = 0;
15217680Spst	if ((i0 >> 30) == 1) {
15317680Spst		/* rtp v1 */
15417680Spst		hasopt = i0 & 0x800000;
15517680Spst		contype = (i0 >> 16) & 0x3f;
15617680Spst		hasmarker = i0 & 0x400000;
15717680Spst		ptype = "rtpv1";
15826183Sfenner	} else {
15917680Spst		/* rtp v2 */
16026183Sfenner		hasext = i0 & 0x10000000;
16117680Spst		contype = (i0 >> 16) & 0x7f;
16217680Spst		hasmarker = i0 & 0x800000;
16317680Spst		dlen -= 4;
16417680Spst		ptype = "rtp";
16517680Spst		ip += 1;
16617680Spst		len -= 1;
16717680Spst	}
16898527Sfenner	printf("udp/%s %d c%d %s%s %d %u",
16917680Spst		ptype,
17017680Spst		dlen,
17117680Spst		contype,
17226183Sfenner		(hasopt || hasext)? "+" : "",
17317680Spst		hasmarker? "*" : "",
17426183Sfenner		i0 & 0xffff,
17526183Sfenner		i1);
17617680Spst	if (vflag) {
177127675Sbms		printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2]));
17817680Spst		if (hasopt) {
17917680Spst			u_int i2, optlen;
18017680Spst			do {
18117680Spst				i2 = ip[0];
18217680Spst				optlen = (i2 >> 16) & 0xff;
18317680Spst				if (optlen == 0 || optlen > len) {
18417680Spst					printf(" !opt");
18517680Spst					return;
18617680Spst				}
18717680Spst				ip += optlen;
18826183Sfenner				len -= optlen;
18917680Spst			} while ((int)i2 >= 0);
19017680Spst		}
19126183Sfenner		if (hasext) {
19226183Sfenner			u_int i2, extlen;
19326183Sfenner			i2 = ip[0];
19426183Sfenner			extlen = (i2 & 0xffff) + 1;
19526183Sfenner			if (extlen > len) {
19626183Sfenner				printf(" !ext");
19726183Sfenner				return;
19826183Sfenner			}
19926183Sfenner			ip += extlen;
20026183Sfenner		}
20126183Sfenner		if (contype == 0x1f) /*XXX H.261 */
20217680Spst			printf(" 0x%04x", ip[0] >> 16);
20317680Spst	}
20417680Spst}
20517680Spst
20626183Sfennerstatic const u_char *
20726183Sfennerrtcp_print(const u_char *hdr, const u_char *ep)
20817680Spst{
20917680Spst	/* rtp v2 control (rtcp) */
21026183Sfenner	struct rtcp_rr *rr = 0;
21126183Sfenner	struct rtcp_sr *sr;
21226183Sfenner	struct rtcphdr *rh = (struct rtcphdr *)hdr;
21326183Sfenner	u_int len;
21475118Sfenner	u_int16_t flags;
21526183Sfenner	int cnt;
21626183Sfenner	double ts, dts;
21726183Sfenner	if ((u_char *)(rh + 1) > ep) {
21826183Sfenner		printf(" [|rtcp]");
21926183Sfenner		return (ep);
22026183Sfenner	}
221127675Sbms	len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4;
222127675Sbms	flags = EXTRACT_16BITS(&rh->rh_flags);
22326183Sfenner	cnt = (flags >> 8) & 0x1f;
22417680Spst	switch (flags & 0xff) {
22517680Spst	case RTCP_PT_SR:
22626183Sfenner		sr = (struct rtcp_sr *)(rh + 1);
22717680Spst		printf(" sr");
22817680Spst		if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
22917680Spst			printf(" [%d]", len);
23026183Sfenner		if (vflag)
231127675Sbms			printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
23226183Sfenner		if ((u_char *)(sr + 1) > ep) {
23326183Sfenner			printf(" [|rtcp]");
23426183Sfenner			return (ep);
23526183Sfenner		}
236127675Sbms		ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) +
237127675Sbms		    ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) /
23826183Sfenner		    4294967296.0);
239127675Sbms		printf(" @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts),
240127675Sbms		    EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb));
24126183Sfenner		rr = (struct rtcp_rr *)(sr + 1);
24217680Spst		break;
24317680Spst	case RTCP_PT_RR:
24417680Spst		printf(" rr");
24517680Spst		if (len != cnt * sizeof(*rr) + sizeof(*rh))
24617680Spst			printf(" [%d]", len);
24726183Sfenner		rr = (struct rtcp_rr *)(rh + 1);
24826183Sfenner		if (vflag)
249127675Sbms			printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
25017680Spst		break;
25117680Spst	case RTCP_PT_SDES:
25217680Spst		printf(" sdes %d", len);
25326183Sfenner		if (vflag)
254127675Sbms			printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
25517680Spst		cnt = 0;
25617680Spst		break;
25717680Spst	case RTCP_PT_BYE:
25817680Spst		printf(" bye %d", len);
25926183Sfenner		if (vflag)
260127675Sbms			printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
26117680Spst		cnt = 0;
26217680Spst		break;
26317680Spst	default:
26417680Spst		printf(" type-0x%x %d", flags & 0xff, len);
26517680Spst		cnt = 0;
26617680Spst		break;
26717680Spst	}
26817680Spst	if (cnt > 1)
26917680Spst		printf(" c%d", cnt);
27017680Spst	while (--cnt >= 0) {
27126183Sfenner		if ((u_char *)(rr + 1) > ep) {
27217680Spst			printf(" [|rtcp]");
27326183Sfenner			return (ep);
27417680Spst		}
27517680Spst		if (vflag)
276127675Sbms			printf(" %u", EXTRACT_32BITS(&rr->rr_srcid));
277127675Sbms		ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.;
278127675Sbms		dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.;
27926183Sfenner		printf(" %ul %us %uj @%.2f+%.2f",
280127675Sbms		    EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff,
281127675Sbms		    EXTRACT_32BITS(&rr->rr_ls),
282127675Sbms		    EXTRACT_32BITS(&rr->rr_dv), ts, dts);
28317680Spst	}
28417680Spst	return (hdr + len);
28517680Spst}
28617680Spst
28775118Sfennerstatic int udp_cksum(register const struct ip *ip,
28875118Sfenner		     register const struct udphdr *up,
289127675Sbms		     register u_int len)
29075118Sfenner{
291235530Sdelphij	return (nextproto4_cksum(ip, (const u_int8_t *)(void *)up, len,
292235530Sdelphij	    IPPROTO_UDP));
29375118Sfenner}
29475118Sfenner
29575118Sfenner#ifdef INET6
29675118Sfennerstatic int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
297127675Sbms	u_int len)
29875118Sfenner{
299235530Sdelphij	return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len,
300235530Sdelphij	    IPPROTO_UDP));
30175118Sfenner}
30275118Sfenner#endif
30375118Sfenner
304127675Sbmsstatic void
305127675Sbmsudpipaddr_print(const struct ip *ip, int sport, int dport)
306127675Sbms{
307127675Sbms#ifdef INET6
308127675Sbms	const struct ip6_hdr *ip6;
30975118Sfenner
310127675Sbms	if (IP_V(ip) == 6)
311127675Sbms		ip6 = (const struct ip6_hdr *)ip;
312127675Sbms	else
313127675Sbms		ip6 = NULL;
31417680Spst
315127675Sbms	if (ip6) {
316127675Sbms		if (ip6->ip6_nxt == IPPROTO_UDP) {
317127675Sbms			if (sport == -1) {
318127675Sbms				(void)printf("%s > %s: ",
319127675Sbms					ip6addr_string(&ip6->ip6_src),
320127675Sbms					ip6addr_string(&ip6->ip6_dst));
321127675Sbms			} else {
322127675Sbms				(void)printf("%s.%s > %s.%s: ",
323127675Sbms					ip6addr_string(&ip6->ip6_src),
324127675Sbms					udpport_string(sport),
325127675Sbms					ip6addr_string(&ip6->ip6_dst),
326127675Sbms					udpport_string(dport));
327127675Sbms			}
328127675Sbms		} else {
329127675Sbms			if (sport != -1) {
330127675Sbms				(void)printf("%s > %s: ",
331127675Sbms					udpport_string(sport),
332127675Sbms					udpport_string(dport));
333127675Sbms			}
334127675Sbms		}
335127675Sbms	} else
336127675Sbms#endif /*INET6*/
337127675Sbms	{
338127675Sbms		if (ip->ip_p == IPPROTO_UDP) {
339127675Sbms			if (sport == -1) {
340127675Sbms				(void)printf("%s > %s: ",
341127675Sbms					ipaddr_string(&ip->ip_src),
342127675Sbms					ipaddr_string(&ip->ip_dst));
343127675Sbms			} else {
344127675Sbms				(void)printf("%s.%s > %s.%s: ",
345127675Sbms					ipaddr_string(&ip->ip_src),
346127675Sbms					udpport_string(sport),
347127675Sbms					ipaddr_string(&ip->ip_dst),
348127675Sbms					udpport_string(dport));
349127675Sbms			}
350127675Sbms		} else {
351127675Sbms			if (sport != -1) {
352127675Sbms				(void)printf("%s > %s: ",
353127675Sbms					udpport_string(sport),
354127675Sbms					udpport_string(dport));
355127675Sbms			}
356127675Sbms		}
357127675Sbms	}
358127675Sbms}
35956896Sfenner
36017680Spstvoid
36175118Sfennerudp_print(register const u_char *bp, u_int length,
36275118Sfenner	  register const u_char *bp2, int fragmented)
36317680Spst{
36417680Spst	register const struct udphdr *up;
36517680Spst	register const struct ip *ip;
36617680Spst	register const u_char *cp;
36726183Sfenner	register const u_char *ep = bp + length;
36875118Sfenner	u_int16_t sport, dport, ulen;
36956896Sfenner#ifdef INET6
37056896Sfenner	register const struct ip6_hdr *ip6;
37156896Sfenner#endif
37217680Spst
37326183Sfenner	if (ep > snapend)
37426183Sfenner		ep = snapend;
37517680Spst	up = (struct udphdr *)bp;
37617680Spst	ip = (struct ip *)bp2;
37756896Sfenner#ifdef INET6
37875118Sfenner	if (IP_V(ip) == 6)
37956896Sfenner		ip6 = (struct ip6_hdr *)bp2;
38056896Sfenner	else
38156896Sfenner		ip6 = NULL;
38256896Sfenner#endif /*INET6*/
38317680Spst	cp = (u_char *)(up + 1);
384127675Sbms	if (!TTEST(up->uh_dport)) {
385127675Sbms		udpipaddr_print(ip, -1, -1);
386127675Sbms		(void)printf("[|udp]");
38717680Spst		return;
38817680Spst	}
389127675Sbms
390127675Sbms	sport = EXTRACT_16BITS(&up->uh_sport);
391127675Sbms	dport = EXTRACT_16BITS(&up->uh_dport);
392127675Sbms
39317680Spst	if (length < sizeof(struct udphdr)) {
394127675Sbms		udpipaddr_print(ip, sport, dport);
395127675Sbms		(void)printf("truncated-udp %d", length);
39617680Spst		return;
39717680Spst	}
39817680Spst	length -= sizeof(struct udphdr);
39917680Spst
400127675Sbms	if (cp > snapend) {
401127675Sbms		udpipaddr_print(ip, sport, dport);
402127675Sbms		(void)printf("[|udp]");
403127675Sbms		return;
404127675Sbms	}
405127675Sbms
406127675Sbms	ulen = EXTRACT_16BITS(&up->uh_ulen);
40775118Sfenner	if (ulen < 8) {
408127675Sbms		udpipaddr_print(ip, sport, dport);
409127675Sbms		(void)printf("truncated-udplength %d", ulen);
41075118Sfenner		return;
41175118Sfenner	}
41217680Spst	if (packettype) {
413146778Ssam		register struct sunrpc_msg *rp;
414146778Ssam		enum sunrpc_msg_type direction;
41517680Spst
41617680Spst		switch (packettype) {
41717680Spst
41817680Spst		case PT_VAT:
419127675Sbms			udpipaddr_print(ip, sport, dport);
420127675Sbms			vat_print((void *)(up + 1), up);
42117680Spst			break;
42217680Spst
42317680Spst		case PT_WB:
424127675Sbms			udpipaddr_print(ip, sport, dport);
42517680Spst			wb_print((void *)(up + 1), length);
42617680Spst			break;
42717680Spst
42817680Spst		case PT_RPC:
429146778Ssam			rp = (struct sunrpc_msg *)(up + 1);
430146778Ssam			direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
431146778Ssam			if (direction == SUNRPC_CALL)
43217680Spst				sunrpcrequest_print((u_char *)rp, length,
43317680Spst				    (u_char *)ip);
43417680Spst			else
43517680Spst				nfsreply_print((u_char *)rp, length,
43617680Spst				    (u_char *)ip);			/*XXX*/
43717680Spst			break;
43817680Spst
43917680Spst		case PT_RTP:
440127675Sbms			udpipaddr_print(ip, sport, dport);
44117680Spst			rtp_print((void *)(up + 1), length, up);
44217680Spst			break;
44317680Spst
44417680Spst		case PT_RTCP:
445127675Sbms			udpipaddr_print(ip, sport, dport);
44626183Sfenner			while (cp < ep)
44726183Sfenner				cp = rtcp_print(cp, ep);
44817680Spst			break;
44956896Sfenner
45056896Sfenner		case PT_SNMP:
451127675Sbms			udpipaddr_print(ip, sport, dport);
45256896Sfenner			snmp_print((const u_char *)(up + 1), length);
45356896Sfenner			break;
45475118Sfenner
45575118Sfenner		case PT_CNFP:
456127675Sbms			udpipaddr_print(ip, sport, dport);
457127675Sbms			cnfp_print(cp, (const u_char *)ip);
45875118Sfenner			break;
459127675Sbms
460127675Sbms		case PT_TFTP:
461127675Sbms			udpipaddr_print(ip, sport, dport);
462127675Sbms			tftp_print(cp, length);
463127675Sbms			break;
464127675Sbms
465127675Sbms		case PT_AODV:
466127675Sbms			udpipaddr_print(ip, sport, dport);
467127675Sbms			aodv_print((const u_char *)(up + 1), length,
468127675Sbms#ifdef INET6
469127675Sbms			    ip6 != NULL);
470127675Sbms#else
471146778Ssam			    0);
472127675Sbms#endif
473127675Sbms			break;
474251158Sdelphij
475251158Sdelphij		case PT_RADIUS:
476251158Sdelphij			udpipaddr_print(ip, sport, dport);
477251158Sdelphij			radius_print(cp, length);
478251158Sdelphij			break;
479251158Sdelphij
480251158Sdelphij		case PT_VXLAN:
481251158Sdelphij			udpipaddr_print(ip, sport, dport);
482251158Sdelphij			vxlan_print((const u_char *)(up + 1), length);
483251158Sdelphij			break;
48417680Spst		}
48517680Spst		return;
48617680Spst	}
48717680Spst
48826183Sfenner	if (!qflag) {
489146778Ssam		register struct sunrpc_msg *rp;
490146778Ssam		enum sunrpc_msg_type direction;
49117680Spst
492146778Ssam		rp = (struct sunrpc_msg *)(up + 1);
49326183Sfenner		if (TTEST(rp->rm_direction)) {
494146778Ssam			direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
495146778Ssam			if (dport == NFS_PORT && direction == SUNRPC_CALL) {
49626183Sfenner				nfsreq_print((u_char *)rp, length,
49726183Sfenner				    (u_char *)ip);
49826183Sfenner				return;
49926183Sfenner			}
500146778Ssam			if (sport == NFS_PORT && direction == SUNRPC_REPLY) {
50126183Sfenner				nfsreply_print((u_char *)rp, length,
50226183Sfenner				    (u_char *)ip);
50326183Sfenner				return;
50426183Sfenner			}
50517680Spst#ifdef notdef
506146778Ssam			if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) {
50726183Sfenner				sunrpcrequest_print((u_char *)rp, length, (u_char *)ip);
50817680Spst				return;
50917680Spst			}
51026183Sfenner#endif
51117680Spst		}
51226183Sfenner		if (TTEST(((struct LAP *)cp)->type) &&
51326183Sfenner		    ((struct LAP *)cp)->type == lapDDP &&
51426183Sfenner		    (atalk_port(sport) || atalk_port(dport))) {
51526183Sfenner			if (vflag)
51626183Sfenner				fputs("kip ", stdout);
51775118Sfenner			llap_print(cp, length);
51826183Sfenner			return;
51926183Sfenner		}
52017680Spst	}
521127675Sbms	udpipaddr_print(ip, sport, dport);
52217680Spst
523235530Sdelphij	if (vflag && !Kflag && !fragmented) {
524235530Sdelphij                /* Check the checksum, if possible. */
525235530Sdelphij                u_int16_t sum, udp_sum;
526235530Sdelphij
527235530Sdelphij		/*
528235530Sdelphij		 * XXX - do this even if vflag == 1?
529235530Sdelphij		 * TCP does, and we do so for UDP-over-IPv6.
530235530Sdelphij		 */
531235530Sdelphij	        if (IP_V(ip) == 4 && (vflag > 1)) {
532235530Sdelphij			udp_sum = EXTRACT_16BITS(&up->uh_sum);
533235530Sdelphij			if (udp_sum == 0) {
534235530Sdelphij				(void)printf("[no cksum] ");
535235530Sdelphij			} else if (TTEST2(cp[0], length)) {
536235530Sdelphij				sum = udp_cksum(ip, up, length + sizeof(struct udphdr));
537235530Sdelphij
538235530Sdelphij	                        if (sum != 0) {
539235530Sdelphij        	                        (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ",
540235530Sdelphij					    udp_sum,
541235530Sdelphij					    in_cksum_shouldbe(udp_sum, sum));
542235530Sdelphij				} else
543235530Sdelphij					(void)printf("[udp sum ok] ");
544235530Sdelphij			}
54575118Sfenner		}
54675118Sfenner#ifdef INET6
547235530Sdelphij		else if (IP_V(ip) == 6 && ip6->ip6_plen) {
548235530Sdelphij			/* for IPv6, UDP checksum is mandatory */
549235530Sdelphij			if (TTEST2(cp[0], length)) {
550235530Sdelphij				sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr));
551235530Sdelphij				udp_sum = EXTRACT_16BITS(&up->uh_sum);
552235530Sdelphij
553235530Sdelphij	                        if (sum != 0) {
554235530Sdelphij        	                        (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ",
555235530Sdelphij					    udp_sum,
556235530Sdelphij					    in_cksum_shouldbe(udp_sum, sum));
557235530Sdelphij				} else
558235530Sdelphij					(void)printf("[udp sum ok] ");
559235530Sdelphij			}
56075118Sfenner		}
561235530Sdelphij#endif
56275118Sfenner	}
56375118Sfenner
56417680Spst	if (!qflag) {
56517680Spst#define ISPORT(p) (dport == (p) || sport == (p))
56617680Spst		if (ISPORT(NAMESERVER_PORT))
567127675Sbms			ns_print((const u_char *)(up + 1), length, 0);
568127675Sbms		else if (ISPORT(MULTICASTDNS_PORT))
569127675Sbms			ns_print((const u_char *)(up + 1), length, 1);
57075118Sfenner		else if (ISPORT(TIMED_PORT))
571127675Sbms			timed_print((const u_char *)(up + 1));
57217680Spst		else if (ISPORT(TFTP_PORT))
57317680Spst			tftp_print((const u_char *)(up + 1), length);
57417680Spst		else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
575127675Sbms			bootp_print((const u_char *)(up + 1), length);
57617680Spst		else if (ISPORT(RIP_PORT))
57717680Spst			rip_print((const u_char *)(up + 1), length);
578127675Sbms		else if (ISPORT(AODV_PORT))
579127675Sbms			aodv_print((const u_char *)(up + 1), length,
580127675Sbms#ifdef INET6
581127675Sbms			    ip6 != NULL);
582127675Sbms#else
583146778Ssam			    0);
584127675Sbms#endif
585146778Ssam	        else if (ISPORT(ISAKMP_PORT))
586146778Ssam			 isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
587146778Ssam  	        else if (ISPORT(ISAKMP_PORT_NATT))
588146778Ssam			 isakmp_rfc3948_print(gndo, (const u_char *)(up + 1), length, bp2);
58956896Sfenner#if 1 /*???*/
590146778Ssam   	        else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2))
591146778Ssam			isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
59256896Sfenner#endif
59317680Spst		else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
59417680Spst			snmp_print((const u_char *)(up + 1), length);
59517680Spst		else if (ISPORT(NTP_PORT))
59617680Spst			ntp_print((const u_char *)(up + 1), length);
59717680Spst		else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
598127675Sbms			krb_print((const void *)(up + 1));
59956896Sfenner		else if (ISPORT(L2TP_PORT))
60056896Sfenner			l2tp_print((const u_char *)(up + 1), length);
60198527Sfenner#ifdef TCPDUMP_DO_SMB
602127675Sbms		else if (ISPORT(NETBIOS_NS_PORT))
60356896Sfenner			nbt_udp137_print((const u_char *)(up + 1), length);
604127675Sbms		else if (ISPORT(NETBIOS_DGRAM_PORT))
605127675Sbms			nbt_udp138_print((const u_char *)(up + 1), length);
60698527Sfenner#endif
60717680Spst		else if (dport == 3456)
608127675Sbms			vat_print((const void *)(up + 1), up);
60998527Sfenner		else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT))
61098527Sfenner			zephyr_print((const void *)(up + 1), length);
611127675Sbms		/*
612127675Sbms		 * Since there are 10 possible ports to check, I think
613127675Sbms		 * a <> test would be more efficient
614127675Sbms		 */
615127675Sbms		else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) ||
616127675Sbms			 (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH))
617127675Sbms			rx_print((const void *)(up + 1), length, sport, dport,
618127675Sbms				 (u_char *) ip);
61956896Sfenner#ifdef INET6
62056896Sfenner		else if (ISPORT(RIPNG_PORT))
62156896Sfenner			ripng_print((const u_char *)(up + 1), length);
622235530Sdelphij		else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
623127675Sbms			dhcp6_print((const u_char *)(up + 1), length);
624235530Sdelphij		else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD))
625235530Sdelphij			babel_print((const u_char *)(up + 1), length);
62656896Sfenner#endif /*INET6*/
62717680Spst		/*
62817680Spst		 * Kludge in test for whiteboard packets.
62917680Spst		 */
63017680Spst		else if (dport == 4567)
63117680Spst			wb_print((const void *)(up + 1), length);
63256896Sfenner		else if (ISPORT(CISCO_AUTORP_PORT))
63356896Sfenner			cisco_autorp_print((const void *)(up + 1), length);
63475118Sfenner		else if (ISPORT(RADIUS_PORT) ||
63598527Sfenner			 ISPORT(RADIUS_NEW_PORT) ||
636127675Sbms			 ISPORT(RADIUS_ACCOUNTING_PORT) ||
63798527Sfenner			 ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
63898527Sfenner			radius_print((const u_char *)(up+1), length);
63998527Sfenner		else if (dport == HSRP_PORT)
640127675Sbms			hsrp_print((const u_char *)(up + 1), length);
64198527Sfenner		else if (ISPORT(LWRES_PORT))
64298527Sfenner			lwres_print((const u_char *)(up + 1), length);
643214478Srpaulo		else if (ISPORT(LDP_PORT))
644127675Sbms			ldp_print((const u_char *)(up + 1), length);
645214478Srpaulo		else if (ISPORT(OLSR_PORT))
646214478Srpaulo			olsr_print((const u_char *)(up + 1), length,
647214478Srpaulo#if INET6
648214478Srpaulo					(IP_V(ip) == 6) ? 1 : 0);
649214478Srpaulo#else
650214478Srpaulo					0);
651214478Srpaulo#endif
652214478Srpaulo		else if (ISPORT(MPLS_LSP_PING_PORT))
653146778Ssam			lspping_print((const u_char *)(up + 1), length);
654127675Sbms		else if (dport == BFD_CONTROL_PORT ||
655127675Sbms			 dport == BFD_ECHO_PORT )
656127675Sbms			bfd_print((const u_char *)(up+1), length, dport);
657146778Ssam                else if (ISPORT(LMP_PORT))
658146778Ssam			lmp_print((const u_char *)(up + 1), length);
659190207Srpaulo		else if (ISPORT(VQP_PORT))
660190207Srpaulo			vqp_print((const u_char *)(up + 1), length);
661190207Srpaulo                else if (ISPORT(SFLOW_PORT))
662190207Srpaulo                        sflow_print((const u_char *)(up + 1), length);
663190207Srpaulo	        else if (dport == LWAPP_CONTROL_PORT)
664190207Srpaulo			lwapp_control_print((const u_char *)(up + 1), length, 1);
665190207Srpaulo                else if (sport == LWAPP_CONTROL_PORT)
666190207Srpaulo                        lwapp_control_print((const u_char *)(up + 1), length, 0);
667190207Srpaulo                else if (ISPORT(LWAPP_DATA_PORT))
668190207Srpaulo                        lwapp_data_print((const u_char *)(up + 1), length);
669146778Ssam                else if (ISPORT(SIP_PORT))
670146778Ssam			sip_print((const u_char *)(up + 1), length);
671146778Ssam                else if (ISPORT(SYSLOG_PORT))
672146778Ssam			syslog_print((const u_char *)(up + 1), length);
673251158Sdelphij                else if (ISPORT(OTV_PORT))
674251158Sdelphij			otv_print((const u_char *)(up + 1), length);
67517680Spst		else
676146778Ssam			(void)printf("UDP, length %u",
67717680Spst			    (u_int32_t)(ulen - sizeof(*up)));
67817680Spst#undef ISPORT
67917680Spst	} else
680146778Ssam		(void)printf("UDP, length %u", (u_int32_t)(ulen - sizeof(*up)));
68117680Spst}
682146778Ssam
683146778Ssam
684146778Ssam/*
685146778Ssam * Local Variables:
686146778Ssam * c-style: whitesmith
687146778Ssam * c-basic-offset: 8
688146778Ssam * End:
689146778Ssam */
690146778Ssam
691