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