xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_zip.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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
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 *
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 *
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
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