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 (c) 2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <stdio.h>
30 #include <sys/types.h>
31
32 #include <at.h>
33 #include <snoop.h>
34
35 char *print_macaddr(uint8_t *, int);
36
37 static char *zip_flags(char);
38 static char *zip_flags_long(char);
39
40 void
interpret_ddp_zip(int flags,struct zip_hdr * zip,int len)41 interpret_ddp_zip(int flags, struct zip_hdr *zip, int len)
42 {
43 int cnt;
44 uint16_t net;
45 uint16_t range;
46 uint8_t *p;
47 char zone[33];
48 char defzone[60] = "";
49 char mcast[50] = "";
50 uint8_t gniflags;
51 uint8_t *tail = (uint8_t *)zip + len;
52
53 if (flags & F_SUM) {
54 if (len < sizeof (struct zip_hdr))
55 goto out;
56
57 switch (zip->zip_func) {
58 case ZIP_QUERY:
59 cnt = zip->zip_netcnt;
60 (void) snprintf(get_sum_line(), MAXLINE,
61 "ZIP Query CNT = %d", cnt);
62 break;
63 case ZIP_REPLY:
64 case ZIP_EXT_REPLY:
65 cnt = zip->zip_netcnt;
66 (void) snprintf(get_sum_line(), MAXLINE,
67 "ZIP Reply CNT = %d", cnt);
68 break;
69 case ZIP_GET_NET_INFO:
70 p = &zip->zip_func;
71
72 if ((p+6 > tail) || (p+7+p[6] > tail))
73 goto out;
74
75 (void) snprintf(get_sum_line(), MAXLINE,
76 "ZIP GNI Zone = \"%.*s\"", p[6], &p[7]);
77 break;
78 case ZIP_GET_NET_INFO_REPLY:
79 p = &zip->zip_func;
80
81 gniflags = p[1];
82 (void) snprintf(get_sum_line(), MAXLINE,
83 "ZIP GNI Rep Flags 0x%x (%s)",
84 gniflags, zip_flags(gniflags));
85 break;
86 default:
87 (void) snprintf(get_sum_line(), MAXLINE,
88 "ZIP CMD = %d", zip->zip_func);
89 break;
90 }
91 }
92
93 if (flags & F_DTAIL) {
94 show_header("ZIP: ", "ZIP Header", len);
95 show_space();
96
97 (void) snprintf(get_line(0, 0), get_line_remain(),
98 "Length = %d", len);
99
100 if (len < sizeof (struct zip_hdr))
101 goto out;
102
103 switch (zip->zip_func) {
104 case ZIP_QUERY:
105 (void) snprintf(get_line(0, 0), get_line_remain(),
106 "Query, Network count = %d", zip->zip_netcnt);
107 cnt = zip->zip_netcnt;
108 p = (uint8_t *)(zip + 1);
109 while (cnt--) {
110 if (p+2 > tail)
111 goto out;
112 net = get_short(p);
113 p += 2;
114 (void) snprintf(get_line(0, 0),
115 get_line_remain(), "Net = %d", net);
116 }
117 break;
118 case ZIP_REPLY:
119 case ZIP_EXT_REPLY:
120 cnt = zip->zip_netcnt;
121 (void) snprintf(get_line(0, 0), get_line_remain(),
122 "Reply, Network count = %d", cnt);
123
124 p = (uint8_t *)(zip + 1);
125 while (cnt--) {
126 if (p+2 > tail)
127 goto out;
128 net = get_short(p);
129 p += 2;
130 if (p+1 > tail || (&p[1] + p[0]) > tail)
131 goto out;
132 (void) snprintf(get_line(0, 0),
133 get_line_remain(),
134 "Network = %d, Zone = \"%.*s\"",
135 net, p[0], &p[1]);
136 p += p[0] + 1;
137 }
138 break;
139 case ZIP_GET_NET_INFO:
140 p = &zip->zip_func;
141 if (p+1 > tail || (&p[1] + p[0]) > tail)
142 goto out;
143 (void) snprintf(get_line(0, 0), get_line_remain(),
144 "GetNetInfo Zone = \"%.*s\"", p[0], &p[1]);
145 break;
146 case ZIP_GET_NET_INFO_REPLY:
147 p = &zip->zip_func;
148 if (p+5 > tail)
149 goto out;
150 gniflags = p[1];
151 net = get_short(&p[2]);
152 range = get_short(&p[4]);
153
154 if (p+7 > tail || (&p[7] + p[6]) > tail)
155 goto out;
156 (void) snprintf(zone, sizeof (zone),
157 "%.*s", p[6], &p[7]);
158 p = &p[7] + p[6];
159
160 if ((gniflags & ZIP_FLG_USEBRC) == 0) {
161 if (p+1 > tail || (&p[1] + p[0]) > tail)
162 goto out;
163 (void) snprintf(mcast, sizeof (mcast),
164 "Multicast address = %s",
165 print_macaddr(&p[1], p[0]));
166 }
167
168 if (gniflags & ZIP_FLG_ZINV) {
169 p = &p[1] + p[0];
170 if (p+1 > tail || (&p[1] + p[0]) > tail)
171 goto out;
172 (void) snprintf(defzone, sizeof (defzone),
173 "Default Zone = \"%.*s\"",
174 p[0], &p[1]);
175 }
176 (void) snprintf(get_line(0, 0), get_line_remain(),
177 "GetNetInfo Reply, Flags 0x%x (%s)",
178 gniflags, zip_flags_long(gniflags));
179
180 (void) snprintf(get_line(0, 0), get_line_remain(),
181 "Network number = %d-%d", net, range);
182
183 (void) snprintf(get_line(0, 0), get_line_remain(),
184 "Zone = \"%s\"", zone);
185
186 if (mcast[0])
187 (void) snprintf(get_line(0, 0),
188 get_line_remain(),
189 "%s", mcast);
190
191 if (defzone[0])
192 (void) snprintf(get_line(0, 0),
193 get_line_remain(),
194 "%s", defzone);
195
196 break;
197 case ZIP_NOTIFY:
198 p = &zip->zip_func;
199 if (p+5 > tail)
200 goto out;
201
202 gniflags = p[1];
203 net = get_short(&p[2]);
204 range = get_short(&p[4]);
205
206 if (p+7 > tail || (&p[7] + p[6]) > tail)
207 goto out;
208 (void) snprintf(zone, sizeof (zone),
209 "%.*s", p[6], &p[7]);
210 p = &p[7] + p[6];
211
212 if ((gniflags & ZIP_FLG_USEBRC) == 0) {
213 if (p+1 > tail || (&p[1] + p[0]) > tail)
214 goto out;
215 (void) snprintf(mcast, sizeof (mcast),
216 "New Multicast address = %s",
217 print_macaddr(&p[1], p[0]));
218 }
219
220 if (p+1 > tail || (&p[1] + p[0]) > tail)
221 goto out;
222
223 p = &p[1] + p[0];
224
225 if (p+1 > tail || (&p[1] + p[0]) > tail)
226 goto out;
227
228 (void) snprintf(defzone, sizeof (defzone),
229 "New Default Zone = \"%.*s\"",
230 p[0], &p[1]);
231
232 (void) snprintf(get_line(0, 0), get_line_remain(),
233 "Notify, Flags 0x%x (%s)",
234 gniflags, zip_flags_long(gniflags));
235
236 (void) snprintf(get_line(0, 0), get_line_remain(),
237 "Old Zone = \"%s\"", zone);
238
239 if (mcast[0])
240 (void) snprintf(get_line(0, 0),
241 get_line_remain(), "%s", mcast);
242
243 if (defzone[0])
244 (void) snprintf(get_line(0, 0),
245 get_line_remain(), "%s", defzone);
246
247 break;
248 default:
249 (void) snprintf(get_line(0, 0), get_line_remain(),
250 "Op = %d", zip->zip_func);
251 break;
252 }
253 }
254 return;
255 out:
256 if (flags & F_SUM)
257 (void) snprintf(get_sum_line(), MAXLINE,
258 "ZIP (short packet)");
259 if (flags & F_DTAIL)
260 (void) snprintf(get_line(0, 0), get_line_remain(),
261 "ZIP (short packet)");
262 }
263
264 static char *
zip_flags(char flags)265 zip_flags(char flags)
266 {
267 static char buf[50];
268 char *p = buf;
269 char *tail = &buf[sizeof (buf)];
270
271 buf[0] = '\0';
272
273 if (flags & ZIP_FLG_ZINV)
274 p += snprintf(p, tail-p, "IZ");
275
276 if (flags & ZIP_FLG_USEBRC)
277 p += snprintf(p, tail-p, p == buf ? "UB" : " UB");
278
279 if (flags & ZIP_FLG_ONEZ)
280 (void) snprintf(p, tail-p, p == buf ? "OOZ" : " OOZ");
281
282 return (buf);
283 }
284
285 static char *
zip_flags_long(char flags)286 zip_flags_long(char flags)
287 {
288 static char buf[50];
289 char *p = buf;
290 char *tail = &buf[sizeof (buf)];
291
292 buf[0] = '\0';
293
294 if (flags & ZIP_FLG_ZINV)
295 p += snprintf(p, tail-p, "ZoneInvalid");
296
297 if (flags & ZIP_FLG_USEBRC)
298 p += snprintf(p, tail-p,
299 p == buf ? "UseBroadcast" : " UseBroadcast");
300
301 if (flags & ZIP_FLG_ONEZ)
302 (void) snprintf(p, tail-p,
303 p == buf ? "OnlyOneZone" : " OnlyOneZone");
304
305 return (buf);
306 }
307
308 void
interpret_atp_zip(int flags,struct atp_hdr * atp,int len)309 interpret_atp_zip(int flags, struct atp_hdr *atp, int len)
310 {
311 int cnt;
312 uint8_t *data;
313 uint8_t *tail = (uint8_t *)(atp+1) + len;
314
315 if (flags & F_SUM) {
316 if (len < 0) {
317 (void) snprintf(get_sum_line(), MAXLINE,
318 "ZIP (short packet)");
319 return;
320 }
321
322 switch (atp_fun(atp->atp_ctrl)) {
323 case ATP_TREQ:
324 switch (atp->atp_user[0]) {
325 case ZIP_ATP_GETMYZONE:
326 (void) snprintf(get_sum_line(), MAXLINE,
327 "ZIP GetMyZone");
328 break;
329
330 case ZIP_ATP_GETZONELIST:
331 (void) snprintf(get_sum_line(), MAXLINE,
332 "ZIP GetZoneList");
333 break;
334
335 case ZIP_ATP_GETLOCALZONES:
336 (void) snprintf(get_sum_line(), MAXLINE,
337 "ZIP GetLocalZones");
338 break;
339 }
340 break;
341 case ATP_TRESP:
342 cnt = get_short(&atp->atp_user[2]);
343 (void) snprintf(get_sum_line(), MAXLINE,
344 "ZIP ZoneReply, Cnt = %d", cnt);
345
346 break;
347 }
348 }
349
350 if (flags & F_DTAIL) {
351 show_header("ZIP: ", "ZIP Header", len);
352 show_space();
353
354 if (len < 0) {
355 (void) snprintf(get_line(0, 0), get_line_remain(),
356 "ZIP (short packet)");
357 return;
358 }
359
360 switch (atp_fun(atp->atp_ctrl)) {
361 case ATP_TREQ:
362 switch (atp->atp_user[0]) {
363 case ZIP_ATP_GETMYZONE:
364 (void) snprintf(get_line(0, 0),
365 get_line_remain(),
366 "GetMyZone, Start Index = %d",
367 get_short(&atp->atp_user[2]));
368 break;
369 case ZIP_ATP_GETZONELIST:
370 (void) snprintf(get_line(0, 0),
371 get_line_remain(),
372 "GetZoneList, Start Index = %d",
373 get_short(&atp->atp_user[2]));
374 break;
375 case ZIP_ATP_GETLOCALZONES:
376 (void) snprintf(get_line(0, 0),
377 get_line_remain(),
378 "GetLocalZones, Start Index = %d",
379 get_short(&atp->atp_user[2]));
380 break;
381 }
382 break;
383 case ATP_TRESP:
384 cnt = get_short(&atp->atp_user[2]);
385 (void) snprintf(get_line(0, 0), get_line_remain(),
386 "ZoneReply, Number of Zones = %d, Length = %d",
387 cnt, len);
388
389 data = (uint8_t *)atp + DDPHDR_SIZE + ATPHDR_SIZE;
390
391 while (cnt--) {
392 if (data > tail ||
393 (&data[1] + data[0]) > tail) {
394 (void) snprintf(get_line(0, 0),
395 get_line_remain(),
396 "ZoneReply (short packet)");
397 return;
398 }
399 (void) snprintf(get_line(0, 0),
400 get_line_remain(),
401 "Zone = \"%.*s\"", data[0], &data[1]);
402 data += data[0] + 1;
403 }
404 break;
405 }
406 }
407 }
408