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