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