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) 1991, 1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/errno.h> 29 #include <setjmp.h> 30 #include <string.h> 31 32 #include <sys/socket.h> 33 #include <sys/sockio.h> 34 #include <sys/tiuser.h> 35 #include <net/if.h> 36 #include <netinet/in_systm.h> 37 #include <netinet/in.h> 38 #include <rpc/types.h> 39 #include <rpc/xdr.h> 40 #include <rpc/auth.h> 41 #include <rpc/clnt.h> 42 #include <rpc/rpc_msg.h> 43 #include <rpcsvc/yp_prot.h> 44 #include "snoop.h" 45 46 extern char *dlc_header; 47 extern jmp_buf xdr_err; 48 char *ypbind_error(); 49 char *sum_ypxfrstat(); 50 char *sum_ypmaplist(); 51 void detail_ypmaplist(); 52 53 static void niscall(int); 54 static void nisreply(int); 55 static int detail_ypstat(void); 56 static int sum_ypstat(char *); 57 58 /* 59 * Defines missing from 5.0 yp_prot.h 60 */ 61 #define YPBINDPROG ((ulong_t)100007) 62 #define YPBINDVERS ((ulong_t)2) 63 #define YPBINDVERS_ORIG ((ulong_t)1) 64 65 /* Procedure symbols */ 66 67 #define YPBINDPROC_NULL ((ulong_t)0) 68 #define YPBINDPROC_DOMAIN ((ulong_t)1) 69 #define YPBINDPROC_SETDOM ((ulong_t)2) 70 71 #define YPBIND_ERR_ERR 1 /* Internal error */ 72 #define YPBIND_ERR_NOSERV 2 /* No bound server for passed domain */ 73 #define YPBIND_ERR_RESC 3 /* System resource allocation failure */ 74 75 76 static char *procnames_bind_short[] = { 77 "NULL", /* 0 */ 78 "DOMAIN", /* 1 */ 79 "SETDOMAIN", /* 2 */ 80 }; 81 82 static char *procnames_bind_long[] = { 83 "Null procedure", /* 0 */ 84 "Get domain name", /* 1 */ 85 "Set domain name", /* 2 */ 86 }; 87 88 static char *procnames_short[] = { 89 "NULL", /* 0 */ 90 "DOMAIN", /* 1 */ 91 "DOMAIN_NONACK", /* 2 */ 92 "MATCH", /* 3 */ 93 "FIRST", /* 4 */ 94 "NEXT", /* 5 */ 95 "XFR", /* 6 */ 96 "CLEAR", /* 7 */ 97 "ALL", /* 8 */ 98 "MASTER", /* 9 */ 99 "ORDER", /* 10 */ 100 "MAPLIST", /* 11 */ 101 "NEWXFR", /* 12 */ 102 }; 103 104 #define MAXPROC_BIND 2 105 #define MAXPROC 12 106 107 static char *procnames_long[] = { 108 "Null procedure", /* 0 */ 109 "Verify domain support", /* 1 */ 110 "Verify domain support (broadcast)", /* 2 */ 111 "Return value of a key", /* 3 */ 112 "Return first key-value pair in map", /* 4 */ 113 "Return next key-value pair in map", /* 5 */ 114 "Request map update (old)", /* 6 */ 115 "Close current map on server", /* 7 */ 116 "Get all key-value pairs in map", /* 8 */ 117 "Get master server", /* 9 */ 118 "Get order", /* 10 */ 119 "Return list of supported maps", /* 11 */ 120 "Request map update", /* 12 */ 121 }; 122 123 void 124 interpret_nisbind(int flags, int type, int xid, int vers, int proc, char *data, 125 int len) 126 { 127 char *line; 128 char buff[YPMAXDOMAIN + 1]; 129 unsigned int status; 130 131 if (proc < 0 || proc > MAXPROC_BIND) 132 return; 133 134 if (flags & F_SUM) { 135 if (setjmp(xdr_err)) { 136 return; 137 } 138 139 line = get_sum_line(); 140 141 if (type == CALL) { 142 (void) sprintf(line, "NISBIND C %s", 143 procnames_bind_short[proc]); 144 line += strlen(line); 145 switch (proc) { 146 case YPBINDPROC_NULL: 147 break; 148 case YPBINDPROC_DOMAIN: 149 (void) sprintf(line, " %s", 150 getxdr_string(buff, YPMAXDOMAIN)); 151 break; 152 case YPBINDPROC_SETDOM: 153 (void) sprintf(line, " %s", 154 getxdr_string(buff, YPMAXDOMAIN)); 155 break; 156 default: 157 break; 158 } 159 check_retransmit(line, xid); 160 } else { 161 (void) sprintf(line, "NISBIND R %s ", 162 procnames_bind_short[proc]); 163 line += strlen(line); 164 switch (proc) { 165 case YPBINDPROC_NULL: 166 break; 167 case YPBINDPROC_DOMAIN: 168 status = getxdr_long(); 169 if (status == 1) { /* success */ 170 (void) strcat(line, "OK"); 171 } else { /* failure */ 172 status = getxdr_long(); 173 (void) sprintf(line, "ERROR=%s", 174 ypbind_error(status)); 175 } 176 break; 177 case YPBINDPROC_SETDOM: 178 break; 179 default: 180 break; 181 } 182 } 183 } 184 185 if (flags & F_DTAIL) { 186 show_header("NISBIND:", 187 "Network Information Service Bind", len); 188 show_space(); 189 if (setjmp(xdr_err)) { 190 return; 191 } 192 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 193 proc, procnames_bind_long[proc]); 194 if (type == CALL) { 195 switch (proc) { 196 case YPBINDPROC_NULL: 197 break; 198 case YPBINDPROC_DOMAIN: 199 (void) showxdr_string(YPMAXDOMAIN, 200 "Domain = %s"); 201 break; 202 case YPBINDPROC_SETDOM: 203 (void) showxdr_string(YPMAXDOMAIN, 204 "Domain = %s"); 205 (void) showxdr_hex(4, "Address=%s"); 206 (void) showxdr_hex(2, "Port=%s"); 207 (void) showxdr_u_long("Version=%lu"); 208 break; 209 default: 210 break; 211 } 212 } else { 213 switch (proc) { 214 case YPBINDPROC_NULL: 215 break; 216 case YPBINDPROC_DOMAIN: 217 status = getxdr_u_long(); 218 (void) sprintf(get_line(0, 0), 219 "Status = %lu (%s)", 220 status, 221 status == 1 ? "OK":"Fail"); 222 if (status == 1) { 223 (void) showxdr_hex(4, "Address=%s"); 224 (void) showxdr_hex(2, "Port=%s"); 225 } else { 226 status = getxdr_u_long(); 227 (void) sprintf(get_line(0, 0), 228 "Error = %lu (%s)", status, 229 ypbind_error(status)); 230 } 231 break; 232 case YPBINDPROC_SETDOM: 233 break; 234 default: 235 break; 236 } 237 } 238 show_trailer(); 239 } 240 } 241 242 void 243 interpret_nis(int flags, int type, int xid, int vers, int proc, char *data, 244 int len) 245 { 246 char *line; 247 char *dom, *map, *key; 248 int transid, status; 249 /* buffers are all the same size so we don't have to keep track */ 250 char buff1[YPMAXRECORD + 1], buff2[YPMAXRECORD + 1]; 251 char buff3[YPMAXRECORD + 1]; 252 253 if (flags & F_SUM) { 254 if (setjmp(xdr_err)) { 255 return; 256 } 257 258 line = get_sum_line(); 259 260 if (type == CALL) { 261 if (proc > MAXPROC) 262 (void) sprintf(line, "NIS C %d", proc); 263 else 264 (void) sprintf(line, "NIS C %s", 265 procnames_short[proc]); 266 line += strlen(line); 267 switch (proc) { 268 case YPPROC_NULL: 269 break; 270 case YPPROC_DOMAIN: 271 case YPPROC_DOMAIN_NONACK: 272 case YPPROC_MAPLIST: 273 /* YPMAXDOMAIN > YPMAXMAP */ 274 (void) sprintf(line, " %s", 275 getxdr_string(buff1, YPMAXDOMAIN)); 276 break; 277 case YPPROC_FIRST: 278 dom = getxdr_string(buff1, YPMAXDOMAIN); 279 map = getxdr_string(buff2, YPMAXMAP); 280 (void) sprintf(line, " %s", map); 281 break; 282 case YPPROC_MATCH: 283 case YPPROC_NEXT: 284 dom = getxdr_string(buff1, YPMAXDOMAIN); 285 map = getxdr_string(buff2, YPMAXMAP); 286 key = getxdr_string(buff3, YPMAXRECORD); 287 (void) sprintf(line, " %s in %s", key, map); 288 break; 289 case YPPROC_NEWXFR: 290 case YPPROC_XFR: 291 dom = getxdr_string(buff1, YPMAXDOMAIN); 292 map = getxdr_string(buff2, YPMAXMAP); 293 (void) sprintf(line, " map %s in %s", map, dom); 294 break; 295 case YPPROC_CLEAR: 296 break; 297 case YPPROC_ALL: 298 case YPPROC_MASTER: 299 case YPPROC_ORDER: 300 dom = getxdr_string(buff1, YPMAXDOMAIN); 301 map = getxdr_string(buff2, YPMAXMAP); 302 (void) sprintf(line, " map %s in %s", map, dom); 303 break; 304 default: 305 break; 306 } 307 check_retransmit(line, xid); 308 } else { 309 if (proc > MAXPROC) 310 (void) sprintf(line, "NIS R %d ", proc); 311 else 312 (void) sprintf(line, "NIS R %s ", 313 procnames_short[proc]); 314 line += strlen(line); 315 switch (proc) { 316 case YPPROC_NULL: 317 break; 318 case YPPROC_DOMAIN: 319 case YPPROC_DOMAIN_NONACK: 320 (void) sprintf(line, "%s", 321 getxdr_long() ? "OK":"Fail"); 322 break; 323 case YPPROC_MATCH: 324 (void) sum_ypstat(line); 325 break; 326 case YPPROC_FIRST: 327 case YPPROC_NEXT: 328 if (sum_ypstat(line) == YP_TRUE) { 329 line += strlen(line); 330 (void) getxdr_string(buff1, 331 YPMAXRECORD); 332 (void) sprintf(line, " key=%s", 333 getxdr_string(buff1, 334 YPMAXRECORD)); 335 } 336 break; 337 case YPPROC_NEWXFR: 338 case YPPROC_XFR: 339 transid = getxdr_u_long(); 340 status = getxdr_long(); 341 (void) sprintf(line, "transid=%lu %s", transid, 342 sum_ypxfrstat(status)); 343 break; 344 case YPPROC_CLEAR: 345 break; 346 case YPPROC_ALL: 347 if (getxdr_u_long()) { 348 (void) sum_ypstat(line); 349 line += strlen(line); 350 (void) sprintf(line, " key=%s", 351 getxdr_string(buff1, YPMAXRECORD)); 352 } else { 353 (void) sprintf(line, "No more"); 354 } 355 break; 356 case YPPROC_MASTER: 357 if (sum_ypstat(line) == YP_TRUE) { 358 line += strlen(line); 359 (void) sprintf(line, " peer=%s", 360 getxdr_string(buff1, YPMAXPEER)); 361 } 362 break; 363 case YPPROC_ORDER: 364 if (sum_ypstat(line) == YP_TRUE) { 365 line += strlen(line); 366 (void) sprintf(line, " order=%lu", 367 getxdr_u_long()); 368 } 369 break; 370 case YPPROC_MAPLIST: 371 if (sum_ypstat(line) == YP_TRUE) { 372 line += strlen(line); 373 (void) sprintf(line, " %s", 374 sum_ypmaplist()); 375 } 376 break; 377 default: 378 break; 379 } 380 } 381 } 382 383 if (flags & F_DTAIL) { 384 show_header("NIS: ", "Network Information Service", len); 385 show_space(); 386 if (setjmp(xdr_err)) { 387 return; 388 } 389 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", proc, 390 proc > MAXPROC ? "unknown" : procnames_long[proc]); 391 if (type == CALL) 392 niscall(proc); 393 else 394 nisreply(proc); 395 show_trailer(); 396 } 397 } 398 399 /* 400 * Print out version 2 NIS call packets 401 */ 402 403 static void 404 niscall(int proc) 405 { 406 switch (proc) { 407 case YPPROC_NULL: 408 break; 409 case YPPROC_DOMAIN: 410 case YPPROC_DOMAIN_NONACK: 411 case YPPROC_MAPLIST: 412 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 413 break; 414 case YPPROC_FIRST: 415 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 416 (void) showxdr_string(YPMAXMAP, "Map = %s"); 417 break; 418 case YPPROC_MATCH: 419 case YPPROC_NEXT: 420 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 421 (void) showxdr_string(YPMAXMAP, "Map = %s"); 422 (void) showxdr_string(YPMAXRECORD, "Key = %s"); 423 break; 424 case YPPROC_NEWXFR: 425 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 426 (void) showxdr_string(YPMAXMAP, "Map = %s"); 427 (void) showxdr_u_long("Order = %lu"); 428 (void) showxdr_string(YPMAXPEER, "Peer = %s"); 429 (void) showxdr_u_long("Transid = %lu"); 430 (void) showxdr_u_long("Prog = %lu"); 431 (void) showxdr_string(YPMAXPEER, "Name = %s"); 432 break; 433 case YPPROC_XFR: 434 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 435 (void) showxdr_string(YPMAXMAP, "Map = %s"); 436 (void) showxdr_u_long("Order = %lu"); 437 (void) showxdr_string(YPMAXPEER, "Peer = %s"); 438 (void) showxdr_u_long("Transid = %lu"); 439 (void) showxdr_u_long("Prog = %lu"); 440 (void) showxdr_u_long("Port = %lu"); 441 break; 442 case YPPROC_CLEAR: 443 break; 444 case YPPROC_ALL: 445 case YPPROC_MASTER: 446 case YPPROC_ORDER: 447 (void) showxdr_string(YPMAXDOMAIN, "Domain = %s"); 448 (void) showxdr_string(YPMAXMAP, "Map = %s"); 449 break; 450 default: 451 break; 452 } 453 } 454 455 /* 456 * Print out version 2 NIS reply packets 457 */ 458 459 void 460 nisreply(int proc) 461 { 462 unsigned int xfrstat, more; 463 464 switch (proc) { 465 case YPPROC_NULL: 466 break; 467 case YPPROC_DOMAIN: 468 case YPPROC_DOMAIN_NONACK: 469 (void) sprintf(get_line(0, 0), "Result=%s", 470 getxdr_u_long() ? "OK":"Fail"); 471 break; 472 case YPPROC_MATCH: 473 (void) detail_ypstat(); 474 (void) showxdr_string(YPMAXRECORD, "Value = %s"); 475 break; 476 case YPPROC_FIRST: 477 case YPPROC_NEXT: 478 (void) detail_ypstat(); 479 (void) showxdr_string(YPMAXRECORD, "Value = %s"); 480 (void) showxdr_string(YPMAXRECORD, "Key = %s"); 481 break; 482 case YPPROC_NEWXFR: 483 case YPPROC_XFR: 484 (void) showxdr_u_long("Transid = %lu"); 485 xfrstat = getxdr_u_long(); 486 (void) sprintf(get_line(0, 0), "Transfer status = %lu (%s)", 487 xfrstat, sum_ypxfrstat(xfrstat)); 488 break; 489 case YPPROC_CLEAR: 490 break; 491 case YPPROC_ALL: 492 more = getxdr_u_long(); 493 (void) sprintf(get_line(0, 0), "More = %s", 494 more ? "true" : "false"); 495 if (more) { 496 (void) detail_ypstat(); 497 (void) showxdr_string(YPMAXRECORD, "Value = %s"); 498 (void) showxdr_string(YPMAXRECORD, "Key = %s"); 499 } 500 break; 501 case YPPROC_MASTER: 502 (void) detail_ypstat(); 503 (void) showxdr_string(YPMAXPEER, "Peer = %s"); 504 break; 505 case YPPROC_ORDER: 506 (void) detail_ypstat(); 507 (void) showxdr_u_long("Order=%lu"); 508 break; 509 case YPPROC_MAPLIST: 510 (void) detail_ypstat(); 511 detail_ypmaplist(); 512 break; 513 default: 514 break; 515 } 516 } 517 518 char * 519 sum_ypxfrstat(int status) 520 { 521 static char buff [16]; 522 523 switch (status) { 524 case 1: return ("Success"); 525 case 2: return ("Master's version not newer"); 526 case -1: return ("Can't find server for map"); 527 case -2: return ("No such domain"); 528 case -3: return ("Resource allocation failure"); 529 case -4: return ("RPC failure talking to server"); 530 case -5: return ("Can't get master address"); 531 case -6: return ("NIS server/map db error"); 532 case -7: return ("Bad arguments"); 533 case -8: return ("Local dbm operation failed"); 534 case -9: return ("Local file I/O operation failed"); 535 case -10: return ("Map version skew during transfer"); 536 case -11: return ("Can't send clear req to local ypserv"); 537 case -12: return ("No local order number in map"); 538 case -13: return ("Transfer error"); 539 case -14: return ("Transfer request refused"); 540 default: 541 (void) sprintf(buff, "(%d)", status); 542 return (buff); 543 } 544 /* NOTREACHED */ 545 } 546 547 static int 548 sum_ypstat(char *line) 549 { 550 ulong_t status; 551 char *str; 552 char buff[16]; 553 554 status = getxdr_u_long(); 555 switch (status) { 556 case YP_TRUE: str = "OK"; break; 557 case YP_NOMORE: str = "No more entries"; break; 558 case YP_FALSE: str = "Fail"; break; 559 case YP_NOMAP: str = "No such map"; break; 560 case YP_NODOM: str = "No such domain"; break; 561 case YP_NOKEY: str = "No such key"; break; 562 case YP_BADOP: str = "Invalid operation"; break; 563 case YP_BADDB: str = "Bad database"; break; 564 case YP_YPERR: str = "Server error"; break; 565 case YP_BADARGS:str = "Bad args"; break; 566 case YP_VERS: str = "Version mismatch"; break; 567 default: (void) sprintf(buff, "(%lu)", status); 568 str = buff; 569 break; 570 } 571 (void) strcpy(line, str); 572 return ((int)status); 573 } 574 575 static int 576 detail_ypstat(void) 577 { 578 ulong_t status; 579 char buff[32]; 580 581 582 status = sum_ypstat(buff); 583 (void) sprintf(get_line(0, 0), "Status = %d (%s)", status, buff); 584 585 return ((int)status); 586 } 587 588 char * 589 sum_ypmaplist(void) 590 { 591 static char buff[YPMAXMAP + 1]; 592 int maps = 0; 593 594 if (setjmp(xdr_err)) { 595 (void) sprintf(buff, "%d+ maps", maps); 596 return (buff); 597 } 598 599 while (getxdr_long()) { 600 (void) getxdr_string(buff, YPMAXMAP); 601 maps++; 602 } 603 604 (void) sprintf(buff, "%d maps", maps); 605 return (buff); 606 } 607 608 void 609 detail_ypmaplist(void) 610 { 611 int maps = 0; 612 613 if (setjmp(xdr_err)) { 614 (void) sprintf(get_line(0, 0), 615 " %d+ maps. (Frame is incomplete)", maps); 616 return; 617 } 618 619 (void) sprintf(get_line(0, 0), "Map list"); 620 621 while (getxdr_long()) { 622 (void) showxdr_string(YPMAXMAP, " %s"); 623 maps++; 624 } 625 626 (void) sprintf(get_line(0, 0), "%d maps", maps); 627 } 628 629 char * 630 ypbind_error(int err) 631 { 632 static char buff[16]; 633 634 switch (err) { 635 case YPBIND_ERR_ERR: return ("Internal error"); 636 case YPBIND_ERR_NOSERV: return ("Internal error"); 637 case YPBIND_ERR_RESC: return ("Resource allocation fail"); 638 default: 639 (void) sprintf(buff, "(%d)", err); 640 return (buff); 641 } 642 /* NOTREACHED */ 643 } 644