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