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