1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <netinet/in.h>
32 #include <at.h>
33 #include <snoop.h>
34 
35 extern char *src_name, *dst_name;
36 
37 struct socktable {
38 	int	pt_num;
39 	char	*pt_short;
40 };
41 
42 static struct socktable pt_ddp[] = {
43 	{1,	"RTMP"},
44 	{2,	"NIS"},
45 	{4,	"Echoer"},
46 	{6,	"ZIS"},
47 	{0,	NULL},
48 };
49 
50 static struct socktable pt_ddp_types[] = {
51 	{1,	"RTMP Resp"},
52 	{2,	"NBP"},
53 	{3,	"ATP"},
54 	{4,	"AEP"},
55 	{5,	"RTMP Req"},
56 	{6,	"ZIP"},
57 	{7,	"ADSP"},
58 	{0,	NULL},
59 };
60 
61 static char *
apple_ddp_type(struct socktable * p,uint16_t port)62 apple_ddp_type(struct socktable *p, uint16_t port)
63 {
64 	for (; p->pt_num != 0; p++) {
65 		if (port == p->pt_num)
66 			return (p->pt_short);
67 	}
68 	return (NULL);
69 }
70 
71 /*
72  * return the short at p, regardless of alignment
73  */
74 
75 uint16_t
get_short(uint8_t * p)76 get_short(uint8_t *p)
77 {
78 	return (p[0] << 8 | p[1]);
79 }
80 
81 /*
82  * return the long at p, regardless of alignment
83  */
84 uint32_t
get_long(uint8_t * p)85 get_long(uint8_t *p)
86 {
87 	return (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
88 }
89 
90 /*
91  * format a MAC address
92  */
93 
94 char *
print_macaddr(uint8_t * ha,int len)95 print_macaddr(uint8_t *ha, int len)
96 {
97 	static char buf[128];
98 	char *p = buf;
99 
100 	while (len-- != 0) {
101 		p += snprintf(p, sizeof (buf) - (p - buf),
102 		    len > 0 ? "%x:" : "%x", *ha++);
103 	}
104 	return (buf);
105 }
106 
107 /* ARGSUSED */
108 void
interpret_at(int flags,struct ddp_hdr * ddp,int len)109 interpret_at(int flags, struct ddp_hdr *ddp, int len)
110 {
111 	int ddplen;
112 	char *pname;
113 	char buff [32];
114 	static char src_buf[16];
115 	static char dst_buf[16];
116 
117 	if (ddp_pad(ddp) != 0)
118 		return;			/* unknown AppleTalk proto */
119 
120 	ddplen = ddp_len(ddp);
121 
122 	(void) snprintf(src_buf, sizeof (src_buf),
123 	    "%u.%u", ntohs(ddp->ddp_src_net), ddp->ddp_src_id);
124 	src_name = src_buf;
125 
126 	(void) snprintf(dst_buf, sizeof (dst_buf),
127 	    "%u.%u", ntohs(ddp->ddp_dest_net), ddp->ddp_dest_id);
128 	if (ddp->ddp_dest_id == NODE_ID_BROADCAST)
129 		dst_name = "(broadcast)";
130 	else
131 		dst_name = dst_buf;
132 
133 	if (flags & F_SUM) {
134 		(void) snprintf(get_sum_line(), MAXLINE,
135 		    "DDP S=%u.%u:%u D=%u.%u:%u LEN=%d",
136 		    ntohs(ddp->ddp_src_net),
137 		    ddp->ddp_src_id,
138 		    ddp->ddp_src_sock,
139 		    ntohs(ddp->ddp_dest_net),
140 		    ddp->ddp_dest_id,
141 		    ddp->ddp_dest_sock,
142 		    ddp_len(ddp));
143 	}
144 
145 	if (flags & F_DTAIL) {
146 		show_header("DDP:  ", "DDP Header", ddplen - DDPHDR_SIZE);
147 		show_space();
148 		pname = apple_ddp_type(pt_ddp, ddp->ddp_src_sock);
149 		if (pname == NULL) {
150 			pname = "";
151 		} else {
152 			(void) snprintf(buff, sizeof (buff), "(%s)", pname);
153 			pname = buff;
154 		}
155 
156 		(void) snprintf(get_line(0, 0), get_line_remain(),
157 		    "Source = %s, Socket = %u %s",
158 		    src_name, ddp->ddp_src_sock, pname);
159 		pname = apple_ddp_type(pt_ddp, ddp->ddp_dest_sock);
160 		if (pname == NULL) {
161 			pname = "";
162 		} else {
163 			(void) snprintf(buff, sizeof (buff), "(%s)", pname);
164 			pname = buff;
165 		}
166 		(void) snprintf(get_line(0, 0), get_line_remain(),
167 		    "Destination = %s, Socket = %u %s",
168 		    dst_name, ddp->ddp_dest_sock, pname);
169 		(void) snprintf(get_line(0, 0), get_line_remain(),
170 		    "Hop count = %d",
171 		    ddp_hop(ddp));
172 		(void) snprintf(get_line(0, 0), get_line_remain(),
173 		    "Length = %d",
174 		    ddp_len(ddp));
175 		(void) snprintf(get_line(0, 0), get_line_remain(),
176 		    "Checksum = %04x %s",
177 		    ntohs(ddp->ddp_cksum),
178 		    ddp->ddp_cksum == 0 ? "(no checksum)" : "");
179 		(void) snprintf(get_line(0, 0), get_line_remain(),
180 		    "DDP type = %d (%s)",
181 		    ddp->ddp_type,
182 		    apple_ddp_type(pt_ddp_types, ddp->ddp_type));
183 		show_space();
184 	}
185 
186 
187 	/* go to the next protocol layer */
188 
189 	switch (ddp->ddp_type) {
190 	case DDP_TYPE_NBP:
191 		interpret_nbp(flags, (struct nbp_hdr *)ddp, ddplen);
192 		break;
193 	case DDP_TYPE_AEP:
194 		interpret_aecho(flags, ddp, ddplen);
195 		break;
196 	case DDP_TYPE_ATP:
197 		interpret_atp(flags, ddp, ddplen);
198 		break;
199 	case DDP_TYPE_ZIP:
200 		interpret_ddp_zip(flags, (struct zip_hdr *)ddp, ddplen);
201 		break;
202 	case DDP_TYPE_ADSP:
203 		interpret_adsp(flags, (struct ddp_adsphdr *)ddp, ddplen);
204 		break;
205 	case DDP_TYPE_RTMPRQ:
206 	case DDP_TYPE_RTMPRESP:
207 		interpret_rtmp(flags, ddp, ddplen);
208 		break;
209 	}
210 }
211