Home | History | Annotate | Download | only in snoop
      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