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