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