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