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