10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*410Skcpoon * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*410Skcpoon * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdio.h>
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <netinet/in.h>
320Sstevel@tonic-gate #include <at.h>
330Sstevel@tonic-gate #include <snoop.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate extern char *src_name, *dst_name;
360Sstevel@tonic-gate
37*410Skcpoon struct socktable {
380Sstevel@tonic-gate int pt_num;
390Sstevel@tonic-gate char *pt_short;
400Sstevel@tonic-gate };
410Sstevel@tonic-gate
420Sstevel@tonic-gate static struct socktable pt_ddp[] = {
430Sstevel@tonic-gate {1, "RTMP"},
440Sstevel@tonic-gate {2, "NIS"},
450Sstevel@tonic-gate {4, "Echoer"},
460Sstevel@tonic-gate {6, "ZIS"},
470Sstevel@tonic-gate {0, NULL},
480Sstevel@tonic-gate };
490Sstevel@tonic-gate
500Sstevel@tonic-gate static struct socktable pt_ddp_types[] = {
510Sstevel@tonic-gate {1, "RTMP Resp"},
520Sstevel@tonic-gate {2, "NBP"},
530Sstevel@tonic-gate {3, "ATP"},
540Sstevel@tonic-gate {4, "AEP"},
550Sstevel@tonic-gate {5, "RTMP Req"},
560Sstevel@tonic-gate {6, "ZIP"},
570Sstevel@tonic-gate {7, "ADSP"},
580Sstevel@tonic-gate {0, NULL},
590Sstevel@tonic-gate };
600Sstevel@tonic-gate
610Sstevel@tonic-gate static char *
apple_ddp_type(struct socktable * p,uint16_t port)620Sstevel@tonic-gate apple_ddp_type(struct socktable *p, uint16_t port)
630Sstevel@tonic-gate {
640Sstevel@tonic-gate for (; p->pt_num != 0; p++) {
650Sstevel@tonic-gate if (port == p->pt_num)
660Sstevel@tonic-gate return (p->pt_short);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate return (NULL);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate
710Sstevel@tonic-gate /*
720Sstevel@tonic-gate * return the short at p, regardless of alignment
730Sstevel@tonic-gate */
740Sstevel@tonic-gate
750Sstevel@tonic-gate uint16_t
get_short(uint8_t * p)760Sstevel@tonic-gate get_short(uint8_t *p)
770Sstevel@tonic-gate {
780Sstevel@tonic-gate return (p[0] << 8 | p[1]);
790Sstevel@tonic-gate }
800Sstevel@tonic-gate
810Sstevel@tonic-gate /*
820Sstevel@tonic-gate * return the long at p, regardless of alignment
830Sstevel@tonic-gate */
840Sstevel@tonic-gate uint32_t
get_long(uint8_t * p)850Sstevel@tonic-gate get_long(uint8_t *p)
860Sstevel@tonic-gate {
870Sstevel@tonic-gate return (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate /*
910Sstevel@tonic-gate * format a MAC address
920Sstevel@tonic-gate */
930Sstevel@tonic-gate
940Sstevel@tonic-gate char *
print_macaddr(uint8_t * ha,int len)950Sstevel@tonic-gate print_macaddr(uint8_t *ha, int len)
960Sstevel@tonic-gate {
970Sstevel@tonic-gate static char buf[128];
980Sstevel@tonic-gate char *p = buf;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate while (len-- != 0) {
1010Sstevel@tonic-gate p += snprintf(p, sizeof (buf) - (p - buf),
1020Sstevel@tonic-gate len > 0 ? "%x:" : "%x", *ha++);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate return (buf);
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate /* ARGSUSED */
1080Sstevel@tonic-gate void
interpret_at(int flags,struct ddp_hdr * ddp,int len)1090Sstevel@tonic-gate interpret_at(int flags, struct ddp_hdr *ddp, int len)
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate int ddplen;
1120Sstevel@tonic-gate char *pname;
1130Sstevel@tonic-gate char buff [32];
1140Sstevel@tonic-gate static char src_buf[16];
1150Sstevel@tonic-gate static char dst_buf[16];
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate if (ddp_pad(ddp) != 0)
1180Sstevel@tonic-gate return; /* unknown AppleTalk proto */
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate ddplen = ddp_len(ddp);
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate (void) snprintf(src_buf, sizeof (src_buf),
1230Sstevel@tonic-gate "%u.%u", ntohs(ddp->ddp_src_net), ddp->ddp_src_id);
1240Sstevel@tonic-gate src_name = src_buf;
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate (void) snprintf(dst_buf, sizeof (dst_buf),
1270Sstevel@tonic-gate "%u.%u", ntohs(ddp->ddp_dest_net), ddp->ddp_dest_id);
1280Sstevel@tonic-gate if (ddp->ddp_dest_id == NODE_ID_BROADCAST)
1290Sstevel@tonic-gate dst_name = "(broadcast)";
1300Sstevel@tonic-gate else
1310Sstevel@tonic-gate dst_name = dst_buf;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate if (flags & F_SUM) {
1340Sstevel@tonic-gate (void) snprintf(get_sum_line(), MAXLINE,
1350Sstevel@tonic-gate "DDP S=%u.%u:%u D=%u.%u:%u LEN=%d",
1360Sstevel@tonic-gate ntohs(ddp->ddp_src_net),
1370Sstevel@tonic-gate ddp->ddp_src_id,
1380Sstevel@tonic-gate ddp->ddp_src_sock,
1390Sstevel@tonic-gate ntohs(ddp->ddp_dest_net),
1400Sstevel@tonic-gate ddp->ddp_dest_id,
1410Sstevel@tonic-gate ddp->ddp_dest_sock,
1420Sstevel@tonic-gate ddp_len(ddp));
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate if (flags & F_DTAIL) {
1460Sstevel@tonic-gate show_header("DDP: ", "DDP Header", ddplen - DDPHDR_SIZE);
1470Sstevel@tonic-gate show_space();
1480Sstevel@tonic-gate pname = apple_ddp_type(pt_ddp, ddp->ddp_src_sock);
1490Sstevel@tonic-gate if (pname == NULL) {
1500Sstevel@tonic-gate pname = "";
1510Sstevel@tonic-gate } else {
1520Sstevel@tonic-gate (void) snprintf(buff, sizeof (buff), "(%s)", pname);
1530Sstevel@tonic-gate pname = buff;
1540Sstevel@tonic-gate }
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1570Sstevel@tonic-gate "Source = %s, Socket = %u %s",
1580Sstevel@tonic-gate src_name, ddp->ddp_src_sock, pname);
1590Sstevel@tonic-gate pname = apple_ddp_type(pt_ddp, ddp->ddp_dest_sock);
1600Sstevel@tonic-gate if (pname == NULL) {
1610Sstevel@tonic-gate pname = "";
1620Sstevel@tonic-gate } else {
1630Sstevel@tonic-gate (void) snprintf(buff, sizeof (buff), "(%s)", pname);
1640Sstevel@tonic-gate pname = buff;
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1670Sstevel@tonic-gate "Destination = %s, Socket = %u %s",
1680Sstevel@tonic-gate dst_name, ddp->ddp_dest_sock, pname);
1690Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1700Sstevel@tonic-gate "Hop count = %d",
1710Sstevel@tonic-gate ddp_hop(ddp));
1720Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1730Sstevel@tonic-gate "Length = %d",
1740Sstevel@tonic-gate ddp_len(ddp));
1750Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1760Sstevel@tonic-gate "Checksum = %04x %s",
1770Sstevel@tonic-gate ntohs(ddp->ddp_cksum),
1780Sstevel@tonic-gate ddp->ddp_cksum == 0 ? "(no checksum)" : "");
1790Sstevel@tonic-gate (void) snprintf(get_line(0, 0), get_line_remain(),
1800Sstevel@tonic-gate "DDP type = %d (%s)",
1810Sstevel@tonic-gate ddp->ddp_type,
1820Sstevel@tonic-gate apple_ddp_type(pt_ddp_types, ddp->ddp_type));
1830Sstevel@tonic-gate show_space();
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate /* go to the next protocol layer */
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate switch (ddp->ddp_type) {
1900Sstevel@tonic-gate case DDP_TYPE_NBP:
1910Sstevel@tonic-gate interpret_nbp(flags, (struct nbp_hdr *)ddp, ddplen);
1920Sstevel@tonic-gate break;
1930Sstevel@tonic-gate case DDP_TYPE_AEP:
1940Sstevel@tonic-gate interpret_aecho(flags, ddp, ddplen);
1950Sstevel@tonic-gate break;
1960Sstevel@tonic-gate case DDP_TYPE_ATP:
1970Sstevel@tonic-gate interpret_atp(flags, ddp, ddplen);
1980Sstevel@tonic-gate break;
1990Sstevel@tonic-gate case DDP_TYPE_ZIP:
2000Sstevel@tonic-gate interpret_ddp_zip(flags, (struct zip_hdr *)ddp, ddplen);
2010Sstevel@tonic-gate break;
2020Sstevel@tonic-gate case DDP_TYPE_ADSP:
2030Sstevel@tonic-gate interpret_adsp(flags, (struct ddp_adsphdr *)ddp, ddplen);
2040Sstevel@tonic-gate break;
2050Sstevel@tonic-gate case DDP_TYPE_RTMPRQ:
2060Sstevel@tonic-gate case DDP_TYPE_RTMPRESP:
2070Sstevel@tonic-gate interpret_rtmp(flags, ddp, ddplen);
2080Sstevel@tonic-gate break;
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate }
211