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