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 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 * 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 * 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 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