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 #include <stdio.h>
28 #include <sys/types.h>
29 #include <netinet/in.h>
30 #include <at.h>
31 #include <snoop.h>
32
33 extern char *src_name, *dst_name;
34
35 struct socktable {
36 int pt_num;
37 char *pt_short;
38 };
39
40 static struct socktable pt_ddp[] = {
41 {1, "RTMP"},
42 {2, "NIS"},
43 {4, "Echoer"},
44 {6, "ZIS"},
45 {0, NULL},
46 };
47
48 static struct socktable pt_ddp_types[] = {
49 {1, "RTMP Resp"},
50 {2, "NBP"},
51 {3, "ATP"},
52 {4, "AEP"},
53 {5, "RTMP Req"},
54 {6, "ZIP"},
55 {7, "ADSP"},
56 {0, NULL},
57 };
58
59 static char *
apple_ddp_type(struct socktable * p,uint16_t port)60 apple_ddp_type(struct socktable *p, uint16_t port)
61 {
62 for (; p->pt_num != 0; p++) {
63 if (port == p->pt_num)
64 return (p->pt_short);
65 }
66 return (NULL);
67 }
68
69 /*
70 * return the short at p, regardless of alignment
71 */
72
73 uint16_t
get_short(uint8_t * p)74 get_short(uint8_t *p)
75 {
76 return (p[0] << 8 | p[1]);
77 }
78
79 /*
80 * return the long at p, regardless of alignment
81 */
82 uint32_t
get_long(uint8_t * p)83 get_long(uint8_t *p)
84 {
85 return (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
86 }
87
88 /*
89 * format a MAC address
90 */
91
92 char *
print_macaddr(uint8_t * ha,int len)93 print_macaddr(uint8_t *ha, int len)
94 {
95 static char buf[128];
96 char *p = buf;
97
98 while (len-- != 0) {
99 p += snprintf(p, sizeof (buf) - (p - buf),
100 len > 0 ? "%x:" : "%x", *ha++);
101 }
102 return (buf);
103 }
104
105 /* ARGSUSED */
106 void
interpret_at(int flags,struct ddp_hdr * ddp,int len)107 interpret_at(int flags, struct ddp_hdr *ddp, int len)
108 {
109 int ddplen;
110 char *pname;
111 char buff [32];
112 static char src_buf[16];
113 static char dst_buf[16];
114
115 if (ddp_pad(ddp) != 0)
116 return; /* unknown AppleTalk proto */
117
118 ddplen = ddp_len(ddp);
119
120 (void) snprintf(src_buf, sizeof (src_buf),
121 "%u.%u", ntohs(ddp->ddp_src_net), ddp->ddp_src_id);
122 src_name = src_buf;
123
124 (void) snprintf(dst_buf, sizeof (dst_buf),
125 "%u.%u", ntohs(ddp->ddp_dest_net), ddp->ddp_dest_id);
126 if (ddp->ddp_dest_id == NODE_ID_BROADCAST)
127 dst_name = "(broadcast)";
128 else
129 dst_name = dst_buf;
130
131 if (flags & F_SUM) {
132 (void) snprintf(get_sum_line(), MAXLINE,
133 "DDP S=%u.%u:%u D=%u.%u:%u LEN=%d",
134 ntohs(ddp->ddp_src_net),
135 ddp->ddp_src_id,
136 ddp->ddp_src_sock,
137 ntohs(ddp->ddp_dest_net),
138 ddp->ddp_dest_id,
139 ddp->ddp_dest_sock,
140 ddp_len(ddp));
141 }
142
143 if (flags & F_DTAIL) {
144 show_header("DDP: ", "DDP Header", ddplen - DDPHDR_SIZE);
145 show_space();
146 pname = apple_ddp_type(pt_ddp, ddp->ddp_src_sock);
147 if (pname == NULL) {
148 pname = "";
149 } else {
150 (void) snprintf(buff, sizeof (buff), "(%s)", pname);
151 pname = buff;
152 }
153
154 (void) snprintf(get_line(0, 0), get_line_remain(),
155 "Source = %s, Socket = %u %s",
156 src_name, ddp->ddp_src_sock, pname);
157 pname = apple_ddp_type(pt_ddp, ddp->ddp_dest_sock);
158 if (pname == NULL) {
159 pname = "";
160 } else {
161 (void) snprintf(buff, sizeof (buff), "(%s)", pname);
162 pname = buff;
163 }
164 (void) snprintf(get_line(0, 0), get_line_remain(),
165 "Destination = %s, Socket = %u %s",
166 dst_name, ddp->ddp_dest_sock, pname);
167 (void) snprintf(get_line(0, 0), get_line_remain(),
168 "Hop count = %d",
169 ddp_hop(ddp));
170 (void) snprintf(get_line(0, 0), get_line_remain(),
171 "Length = %d",
172 ddp_len(ddp));
173 (void) snprintf(get_line(0, 0), get_line_remain(),
174 "Checksum = %04x %s",
175 ntohs(ddp->ddp_cksum),
176 ddp->ddp_cksum == 0 ? "(no checksum)" : "");
177 (void) snprintf(get_line(0, 0), get_line_remain(),
178 "DDP type = %d (%s)",
179 ddp->ddp_type,
180 apple_ddp_type(pt_ddp_types, ddp->ddp_type));
181 show_space();
182 }
183
184
185 /* go to the next protocol layer */
186
187 switch (ddp->ddp_type) {
188 case DDP_TYPE_NBP:
189 interpret_nbp(flags, (struct nbp_hdr *)ddp, ddplen);
190 break;
191 case DDP_TYPE_AEP:
192 interpret_aecho(flags, ddp, ddplen);
193 break;
194 case DDP_TYPE_ATP:
195 interpret_atp(flags, ddp, ddplen);
196 break;
197 case DDP_TYPE_ZIP:
198 interpret_ddp_zip(flags, (struct zip_hdr *)ddp, ddplen);
199 break;
200 case DDP_TYPE_ADSP:
201 interpret_adsp(flags, (struct ddp_adsphdr *)ddp, ddplen);
202 break;
203 case DDP_TYPE_RTMPRQ:
204 case DDP_TYPE_RTMPRESP:
205 interpret_rtmp(flags, ddp, ddplen);
206 break;
207 }
208 }
209