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