1 /* 2 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #ifndef lint 23 static const char rcsid[] = 24 "@(#) $Header: print-decnet.c,v 1.26 97/05/28 12:51:29 leres Exp $ (LBL)"; 25 #endif 26 27 #include <sys/param.h> 28 #include <sys/time.h> 29 #include <sys/socket.h> 30 31 #if __STDC__ 32 struct mbuf; 33 struct rtentry; 34 #endif 35 #include <net/if.h> 36 37 #ifdef HAVE_LIBDNET 38 #include <netdnet/dnetdb.h> 39 #endif 40 41 #include <ctype.h> 42 #ifdef HAVE_MALLOC_H 43 #include <malloc.h> 44 #endif 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 50 #include "decnet.h" 51 #include "extract.h" 52 #include "interface.h" 53 #include "addrtoname.h" 54 55 /* Forwards */ 56 static void print_decnet_ctlmsg(const union routehdr *, u_int); 57 static void print_t_info(int); 58 static void print_l1_routes(const char *, u_int); 59 static void print_l2_routes(const char *, u_int); 60 static void print_i_info(int); 61 static void print_elist(const char *, u_int); 62 static void print_nsp(const u_char *, u_int); 63 static void print_reason(int); 64 #ifdef PRINT_NSPDATA 65 static void pdata(u_char *, int); 66 #endif 67 68 #ifdef HAVE_LIBDNET 69 extern char *dnet_htoa(struct dn_naddr *); 70 #endif 71 72 void 73 decnet_print(register const u_char *ap, register u_int length, 74 register u_int caplen) 75 { 76 static union routehdr rhcopy; 77 register union routehdr *rhp = &rhcopy; 78 register int mflags; 79 int dst, src, hops; 80 u_int rhlen, nsplen, pktlen; 81 const u_char *nspp; 82 83 if (length < sizeof(struct shorthdr)) { 84 (void)printf("[|decnet]"); 85 return; 86 } 87 88 pktlen = EXTRACT_LE_16BITS(ap); 89 90 rhlen = min(length, caplen); 91 rhlen = min(rhlen, sizeof(*rhp)); 92 memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen); 93 94 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 95 96 if (mflags & RMF_PAD) { 97 /* pad bytes of some sort in front of message */ 98 u_int padlen = mflags & RMF_PADMASK; 99 if (vflag) 100 (void) printf("[pad:%d] ", padlen); 101 ap += padlen; 102 length -= padlen; 103 caplen -= padlen; 104 rhlen = min(length, caplen); 105 rhlen = min(rhlen, sizeof(*rhp)); 106 memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen); 107 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 108 } 109 110 if (mflags & RMF_FVER) { 111 (void) printf("future-version-decnet"); 112 default_print(ap, length); 113 return; 114 } 115 116 /* is it a control message? */ 117 if (mflags & RMF_CTLMSG) { 118 print_decnet_ctlmsg(rhp, min(length, caplen)); 119 return; 120 } 121 122 switch (mflags & RMF_MASK) { 123 case RMF_LONG: 124 dst = 125 EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); 126 src = 127 EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); 128 hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); 129 nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); 130 nsplen = min((length - sizeof(struct longhdr)), 131 (caplen - sizeof(struct longhdr))); 132 break; 133 case RMF_SHORT: 134 dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); 135 src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); 136 hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; 137 nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); 138 nsplen = min((length - sizeof(struct shorthdr)), 139 (caplen - sizeof(struct shorthdr))); 140 break; 141 default: 142 (void) printf("unknown message flags under mask"); 143 default_print((u_char *)ap, length); 144 return; 145 } 146 147 (void)printf("%s > %s %d ", 148 dnaddr_string(src), dnaddr_string(dst), pktlen); 149 if (vflag) { 150 if (mflags & RMF_RQR) 151 (void)printf("RQR "); 152 if (mflags & RMF_RTS) 153 (void)printf("RTS "); 154 if (mflags & RMF_IE) 155 (void)printf("IE "); 156 (void)printf("%d hops ", hops); 157 } 158 159 print_nsp(nspp, nsplen); 160 } 161 162 static void 163 print_decnet_ctlmsg(register const union routehdr *rhp, u_int length) 164 { 165 int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 166 register union controlmsg *cmp = (union controlmsg *)rhp; 167 int src, dst, info, blksize, eco, ueco, hello, other, vers; 168 etheraddr srcea, rtea; 169 int priority; 170 char *rhpx = (char *)rhp; 171 172 switch (mflags & RMF_CTLMASK) { 173 case RMF_INIT: 174 (void)printf("init "); 175 src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); 176 info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); 177 blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); 178 vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); 179 eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); 180 ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); 181 hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); 182 print_t_info(info); 183 (void)printf( 184 "src %sblksize %d vers %d eco %d ueco %d hello %d", 185 dnaddr_string(src), blksize, vers, eco, ueco, 186 hello); 187 break; 188 case RMF_VER: 189 (void)printf("verification "); 190 src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); 191 other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); 192 (void)printf("src %s fcnval %o", dnaddr_string(src), other); 193 break; 194 case RMF_TEST: 195 (void)printf("test "); 196 src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); 197 other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); 198 (void)printf("src %s data %o", dnaddr_string(src), other); 199 break; 200 case RMF_L1ROUT: 201 (void)printf("lev-1-routing "); 202 src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 203 (void)printf("src %s ", dnaddr_string(src)); 204 print_l1_routes(&(rhpx[sizeof(struct l1rout)]), 205 length - sizeof(struct l1rout)); 206 break; 207 case RMF_L2ROUT: 208 (void)printf("lev-2-routing "); 209 src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 210 (void)printf("src %s ", dnaddr_string(src)); 211 print_l2_routes(&(rhpx[sizeof(struct l2rout)]), 212 length - sizeof(struct l2rout)); 213 break; 214 case RMF_RHELLO: 215 (void)printf("router-hello "); 216 vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); 217 eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); 218 ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); 219 memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), 220 sizeof(srcea)); 221 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 222 info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); 223 blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); 224 priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); 225 hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); 226 print_i_info(info); 227 (void)printf( 228 "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 229 vers, eco, ueco, dnaddr_string(src), 230 blksize, priority, hello); 231 print_elist(&(rhpx[sizeof(struct rhellomsg)]), 232 length - sizeof(struct rhellomsg)); 233 break; 234 case RMF_EHELLO: 235 (void)printf("endnode-hello "); 236 vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); 237 eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); 238 ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); 239 memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), 240 sizeof(srcea)); 241 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 242 info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); 243 blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); 244 /*seed*/ 245 memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), 246 sizeof(rtea)); 247 dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); 248 hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); 249 other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); 250 print_i_info(info); 251 (void)printf( 252 "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 253 vers, eco, ueco, dnaddr_string(src), 254 blksize, dnaddr_string(dst), hello, other); 255 break; 256 257 default: 258 (void)printf("unknown control message"); 259 default_print((u_char *)rhp, length); 260 break; 261 } 262 } 263 264 static void 265 print_t_info(int info) 266 { 267 int ntype = info & 3; 268 switch (ntype) { 269 case 0: (void)printf("reserved-ntype? "); break; 270 case TI_L2ROUT: (void)printf("l2rout "); break; 271 case TI_L1ROUT: (void)printf("l1rout "); break; 272 case TI_ENDNODE: (void)printf("endnode "); break; 273 } 274 if (info & TI_VERIF) 275 (void)printf("verif "); 276 if (info & TI_BLOCK) 277 (void)printf("blo "); 278 } 279 280 static void 281 print_l1_routes(const char *rp, u_int len) 282 { 283 int count; 284 int id; 285 int info; 286 287 /* The last short is a checksum */ 288 while (len > (3 * sizeof(short))) { 289 count = EXTRACT_LE_16BITS(rp); 290 if (count > 1024) 291 return; /* seems to be bogus from here on */ 292 rp += sizeof(short); 293 len -= sizeof(short); 294 id = EXTRACT_LE_16BITS(rp); 295 rp += sizeof(short); 296 len -= sizeof(short); 297 info = EXTRACT_LE_16BITS(rp); 298 rp += sizeof(short); 299 len -= sizeof(short); 300 (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count, 301 RI_COST(info), RI_HOPS(info)); 302 } 303 } 304 305 static void 306 print_l2_routes(const char *rp, u_int len) 307 { 308 int count; 309 int area; 310 int info; 311 312 /* The last short is a checksum */ 313 while (len > (3 * sizeof(short))) { 314 count = EXTRACT_LE_16BITS(rp); 315 if (count > 1024) 316 return; /* seems to be bogus from here on */ 317 rp += sizeof(short); 318 len -= sizeof(short); 319 area = EXTRACT_LE_16BITS(rp); 320 rp += sizeof(short); 321 len -= sizeof(short); 322 info = EXTRACT_LE_16BITS(rp); 323 rp += sizeof(short); 324 len -= sizeof(short); 325 (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count, 326 RI_COST(info), RI_HOPS(info)); 327 } 328 } 329 330 static void 331 print_i_info(int info) 332 { 333 int ntype = info & II_TYPEMASK; 334 switch (ntype) { 335 case 0: (void)printf("reserved-ntype? "); break; 336 case II_L2ROUT: (void)printf("l2rout "); break; 337 case II_L1ROUT: (void)printf("l1rout "); break; 338 case II_ENDNODE: (void)printf("endnode "); break; 339 } 340 if (info & II_VERIF) 341 (void)printf("verif "); 342 if (info & II_NOMCAST) 343 (void)printf("nomcast "); 344 if (info & II_BLOCK) 345 (void)printf("blo "); 346 } 347 348 static void 349 print_elist(const char *elp, u_int len) 350 { 351 /* Not enough examples available for me to debug this */ 352 } 353 354 static void 355 print_nsp(const u_char *nspp, u_int nsplen) 356 { 357 const struct nsphdr *nsphp = (struct nsphdr *)nspp; 358 int dst, src, flags; 359 360 flags = EXTRACT_LE_8BITS(nsphp->nh_flags); 361 dst = EXTRACT_LE_16BITS(nsphp->nh_dst); 362 src = EXTRACT_LE_16BITS(nsphp->nh_src); 363 364 switch (flags & NSP_TYPEMASK) { 365 case MFT_DATA: 366 switch (flags & NSP_SUBMASK) { 367 case MFS_BOM: 368 case MFS_MOM: 369 case MFS_EOM: 370 case MFS_BOM+MFS_EOM: 371 printf("data %d>%d ", src, dst); 372 { 373 struct seghdr *shp = (struct seghdr *)nspp; 374 int ack; 375 #ifdef PRINT_NSPDATA 376 u_char *dp; 377 #endif 378 u_int data_off = sizeof(struct minseghdr); 379 380 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 381 if (ack & SGQ_ACK) { /* acknum field */ 382 if ((ack & SGQ_NAK) == SGQ_NAK) 383 (void)printf("nak %d ", ack & SGQ_MASK); 384 else 385 (void)printf("ack %d ", ack & SGQ_MASK); 386 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 387 data_off += sizeof(short); 388 if (ack & SGQ_OACK) { /* ackoth field */ 389 if ((ack & SGQ_ONAK) == SGQ_ONAK) 390 (void)printf("onak %d ", ack & SGQ_MASK); 391 else 392 (void)printf("oack %d ", ack & SGQ_MASK); 393 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 394 data_off += sizeof(short); 395 } 396 } 397 (void)printf("seg %d ", ack & SGQ_MASK); 398 #ifdef PRINT_NSPDATA 399 dp = &(nspp[data_off]); 400 pdata(dp, 10); 401 #endif 402 } 403 break; 404 case MFS_ILS+MFS_INT: 405 printf("intr "); 406 { 407 struct seghdr *shp = (struct seghdr *)nspp; 408 int ack; 409 #ifdef PRINT_NSPDATA 410 u_char *dp; 411 #endif 412 u_int data_off = sizeof(struct minseghdr); 413 414 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 415 if (ack & SGQ_ACK) { /* acknum field */ 416 if ((ack & SGQ_NAK) == SGQ_NAK) 417 (void)printf("nak %d ", ack & SGQ_MASK); 418 else 419 (void)printf("ack %d ", ack & SGQ_MASK); 420 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 421 data_off += sizeof(short); 422 if (ack & SGQ_OACK) { /* ackdat field */ 423 if ((ack & SGQ_ONAK) == SGQ_ONAK) 424 (void)printf("nakdat %d ", ack & SGQ_MASK); 425 else 426 (void)printf("ackdat %d ", ack & SGQ_MASK); 427 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 428 data_off += sizeof(short); 429 } 430 } 431 (void)printf("seg %d ", ack & SGQ_MASK); 432 #ifdef PRINT_NSPDATA 433 dp = &(nspp[data_off]); 434 pdata(dp, 10); 435 #endif 436 } 437 break; 438 case MFS_ILS: 439 (void)printf("link-service %d>%d ", src, dst); 440 { 441 struct seghdr *shp = (struct seghdr *)nspp; 442 struct lsmsg *lsmp = 443 (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); 444 int ack; 445 int lsflags, fcval; 446 447 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 448 if (ack & SGQ_ACK) { /* acknum field */ 449 if ((ack & SGQ_NAK) == SGQ_NAK) 450 (void)printf("nak %d ", ack & SGQ_MASK); 451 else 452 (void)printf("ack %d ", ack & SGQ_MASK); 453 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 454 if (ack & SGQ_OACK) { /* ackdat field */ 455 if ((ack & SGQ_ONAK) == SGQ_ONAK) 456 (void)printf("nakdat %d ", ack & SGQ_MASK); 457 else 458 (void)printf("ackdat %d ", ack & SGQ_MASK); 459 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 460 } 461 } 462 (void)printf("seg %d ", ack & SGQ_MASK); 463 lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); 464 fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); 465 switch (lsflags & LSI_MASK) { 466 case LSI_DATA: 467 (void)printf("dat seg count %d ", fcval); 468 switch (lsflags & LSM_MASK) { 469 case LSM_NOCHANGE: 470 break; 471 case LSM_DONOTSEND: 472 (void)printf("donotsend-data "); 473 break; 474 case LSM_SEND: 475 (void)printf("send-data "); 476 break; 477 default: 478 (void)printf("reserved-fcmod? %x", lsflags); 479 break; 480 } 481 break; 482 case LSI_INTR: 483 (void)printf("intr req count %d ", fcval); 484 break; 485 default: 486 (void)printf("reserved-fcval-int? %x", lsflags); 487 break; 488 } 489 } 490 break; 491 default: 492 (void)printf("reserved-subtype? %x %d > %d", flags, src, dst); 493 break; 494 } 495 break; 496 case MFT_ACK: 497 switch (flags & NSP_SUBMASK) { 498 case MFS_DACK: 499 (void)printf("data-ack %d>%d ", src, dst); 500 { 501 struct ackmsg *amp = (struct ackmsg *)nspp; 502 int ack; 503 504 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 505 if (ack & SGQ_ACK) { /* acknum field */ 506 if ((ack & SGQ_NAK) == SGQ_NAK) 507 (void)printf("nak %d ", ack & SGQ_MASK); 508 else 509 (void)printf("ack %d ", ack & SGQ_MASK); 510 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 511 if (ack & SGQ_OACK) { /* ackoth field */ 512 if ((ack & SGQ_ONAK) == SGQ_ONAK) 513 (void)printf("onak %d ", ack & SGQ_MASK); 514 else 515 (void)printf("oack %d ", ack & SGQ_MASK); 516 } 517 } 518 } 519 break; 520 case MFS_IACK: 521 (void)printf("ils-ack %d>%d ", src, dst); 522 { 523 struct ackmsg *amp = (struct ackmsg *)nspp; 524 int ack; 525 526 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 527 if (ack & SGQ_ACK) { /* acknum field */ 528 if ((ack & SGQ_NAK) == SGQ_NAK) 529 (void)printf("nak %d ", ack & SGQ_MASK); 530 else 531 (void)printf("ack %d ", ack & SGQ_MASK); 532 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 533 if (ack & SGQ_OACK) { /* ackdat field */ 534 if ((ack & SGQ_ONAK) == SGQ_ONAK) 535 (void)printf("nakdat %d ", ack & SGQ_MASK); 536 else 537 (void)printf("ackdat %d ", ack & SGQ_MASK); 538 } 539 } 540 } 541 break; 542 case MFS_CACK: 543 (void)printf("conn-ack %d", dst); 544 break; 545 default: 546 (void)printf("reserved-acktype? %x %d > %d", flags, src, dst); 547 break; 548 } 549 break; 550 case MFT_CTL: 551 switch (flags & NSP_SUBMASK) { 552 case MFS_CI: 553 case MFS_RCI: 554 if ((flags & NSP_SUBMASK) == MFS_CI) 555 (void)printf("conn-initiate "); 556 else 557 (void)printf("retrans-conn-initiate "); 558 (void)printf("%d>%d ", src, dst); 559 { 560 struct cimsg *cimp = (struct cimsg *)nspp; 561 int services, info, segsize; 562 #ifdef PRINT_NSPDATA 563 u_char *dp; 564 #endif 565 566 services = EXTRACT_LE_8BITS(cimp->ci_services); 567 info = EXTRACT_LE_8BITS(cimp->ci_info); 568 segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); 569 570 switch (services & COS_MASK) { 571 case COS_NONE: 572 break; 573 case COS_SEGMENT: 574 (void)printf("seg "); 575 break; 576 case COS_MESSAGE: 577 (void)printf("msg "); 578 break; 579 case COS_CRYPTSER: 580 (void)printf("crypt "); 581 break; 582 } 583 switch (info & COI_MASK) { 584 case COI_32: 585 (void)printf("ver 3.2 "); 586 break; 587 case COI_31: 588 (void)printf("ver 3.1 "); 589 break; 590 case COI_40: 591 (void)printf("ver 4.0 "); 592 break; 593 case COI_41: 594 (void)printf("ver 4.1 "); 595 break; 596 } 597 (void)printf("segsize %d ", segsize); 598 #ifdef PRINT_NSPDATA 599 dp = &(nspp[sizeof(struct cimsg)]); 600 pdata(dp, nsplen - sizeof(struct cimsg)); 601 #endif 602 } 603 break; 604 case MFS_CC: 605 (void)printf("conn-confirm %d>%d ", src, dst); 606 { 607 struct ccmsg *ccmp = (struct ccmsg *)nspp; 608 int services, info; 609 u_int segsize, optlen; 610 #ifdef PRINT_NSPDATA 611 u_char *dp; 612 #endif 613 614 services = EXTRACT_LE_8BITS(ccmp->cc_services); 615 info = EXTRACT_LE_8BITS(ccmp->cc_info); 616 segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); 617 optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); 618 619 switch (services & COS_MASK) { 620 case COS_NONE: 621 break; 622 case COS_SEGMENT: 623 (void)printf("seg "); 624 break; 625 case COS_MESSAGE: 626 (void)printf("msg "); 627 break; 628 case COS_CRYPTSER: 629 (void)printf("crypt "); 630 break; 631 } 632 switch (info & COI_MASK) { 633 case COI_32: 634 (void)printf("ver 3.2 "); 635 break; 636 case COI_31: 637 (void)printf("ver 3.1 "); 638 break; 639 case COI_40: 640 (void)printf("ver 4.0 "); 641 break; 642 case COI_41: 643 (void)printf("ver 4.1 "); 644 break; 645 } 646 (void)printf("segsize %d ", segsize); 647 if (optlen) { 648 (void)printf("optlen %d ", optlen); 649 #ifdef PRINT_NSPDATA 650 optlen = min(optlen, nsplen - sizeof(struct ccmsg)); 651 dp = &(nspp[sizeof(struct ccmsg)]); 652 pdata(dp, optlen); 653 #endif 654 } 655 } 656 break; 657 case MFS_DI: 658 (void)printf("disconn-initiate %d>%d ", src, dst); 659 { 660 struct dimsg *dimp = (struct dimsg *)nspp; 661 int reason; 662 u_int optlen; 663 #ifdef PRINT_NSPDATA 664 u_char *dp; 665 #endif 666 667 reason = EXTRACT_LE_16BITS(dimp->di_reason); 668 optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 669 670 print_reason(reason); 671 if (optlen) { 672 (void)printf("optlen %d ", optlen); 673 #ifdef PRINT_NSPDATA 674 optlen = min(optlen, nsplen - sizeof(struct dimsg)); 675 dp = &(nspp[sizeof(struct dimsg)]); 676 pdata(dp, optlen); 677 #endif 678 } 679 } 680 break; 681 case MFS_DC: 682 (void)printf("disconn-confirm %d>%d ", src, dst); 683 { 684 struct dcmsg *dcmp = (struct dcmsg *)nspp; 685 int reason; 686 687 reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 688 689 print_reason(reason); 690 } 691 break; 692 default: 693 (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst); 694 break; 695 } 696 break; 697 default: 698 (void)printf("reserved-type? %x %d > %d", flags, src, dst); 699 break; 700 } 701 } 702 703 static struct tok reason2str[] = { 704 { UC_OBJREJECT, "object rejected connect" }, 705 { UC_RESOURCES, "insufficient resources" }, 706 { UC_NOSUCHNODE, "unrecognized node name" }, 707 { DI_SHUT, "node is shutting down" }, 708 { UC_NOSUCHOBJ, "unrecognized object" }, 709 { UC_INVOBJFORMAT, "invalid object name format" }, 710 { UC_OBJTOOBUSY, "object too busy" }, 711 { DI_PROTOCOL, "protocol error discovered" }, 712 { DI_TPA, "third party abort" }, 713 { UC_USERABORT, "user abort" }, 714 { UC_INVNODEFORMAT, "invalid node name format" }, 715 { UC_LOCALSHUT, "local node shutting down" }, 716 { DI_LOCALRESRC, "insufficient local resources" }, 717 { DI_REMUSERRESRC, "insufficient remote user resources" }, 718 { UC_ACCESSREJECT, "invalid access control information" }, 719 { DI_BADACCNT, "bad ACCOUNT information" }, 720 { UC_NORESPONSE, "no response from object" }, 721 { UC_UNREACHABLE, "node unreachable" }, 722 { DC_NOLINK, "no link terminate" }, 723 { DC_COMPLETE, "disconnect complete" }, 724 { DI_BADIMAGE, "bad image data in connect" }, 725 { DI_SERVMISMATCH, "cryptographic service mismatch" }, 726 { 0, NULL } 727 }; 728 729 static void 730 print_reason(register int reason) 731 { 732 printf("%s ", tok2str(reason2str, "reason-%d", reason)); 733 } 734 735 char * 736 dnnum_string(u_short dnaddr) 737 { 738 char *str; 739 int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; 740 int node = dnaddr & NODEMASK; 741 742 str = (char *)malloc(sizeof("00.0000")); 743 if (str == NULL) 744 error("dnnum_string: malloc"); 745 sprintf(str, "%d.%d", area, node); 746 return(str); 747 } 748 749 char * 750 dnname_string(u_short dnaddr) 751 { 752 #ifdef HAVE_LIBDNET 753 struct dn_naddr dna; 754 755 dna.a_len = sizeof(short); 756 memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 757 return (savestr(dnet_htoa(&dna))); 758 #else 759 return(dnnum_string(dnaddr)); /* punt */ 760 #endif 761 } 762 763 #ifdef PRINT_NSPDATA 764 static void 765 pdata(u_char *dp, u_int maxlen) 766 { 767 char c; 768 u_int x = maxlen; 769 770 while (x-- > 0) { 771 c = *dp++; 772 if (isprint(c)) 773 putchar(c); 774 else 775 printf("\\%o", c & 0xFF); 776 } 777 } 778 #endif 779