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 #include <sys/cdefs.h> 23 #ifndef lint 24 __RCSID("$NetBSD: print-decnet.c,v 1.9 2017/09/08 14:01:13 christos Exp $"); 25 #endif 26 27 /* \summary: DECnet printer */ 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include <netdissect-stdinc.h> 34 35 struct mbuf; 36 struct rtentry; 37 38 #ifdef HAVE_NETDNET_DNETDB_H 39 #include <netdnet/dnetdb.h> 40 #endif 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 46 #include "extract.h" 47 #include "netdissect.h" 48 #include "addrtoname.h" 49 50 static const char tstr[] = "[|decnet]"; 51 52 #ifndef _WIN32 53 typedef uint8_t byte[1]; /* single byte field */ 54 #else 55 /* 56 * the keyword 'byte' generates conflicts in Windows 57 */ 58 typedef unsigned char Byte[1]; /* single byte field */ 59 #define byte Byte 60 #endif /* _WIN32 */ 61 typedef uint8_t word[2]; /* 2 byte field */ 62 typedef uint8_t longword[4]; /* 4 bytes field */ 63 64 /* 65 * Definitions for DECNET Phase IV protocol headers 66 */ 67 union etheraddress { 68 uint8_t dne_addr[6]; /* full ethernet address */ 69 struct { 70 uint8_t dne_hiord[4]; /* DECnet HIORD prefix */ 71 uint8_t dne_nodeaddr[2]; /* DECnet node address */ 72 } dne_remote; 73 }; 74 75 typedef union etheraddress etheraddr; /* Ethernet address */ 76 77 #define HIORD 0x000400aa /* high 32-bits of address (swapped) */ 78 79 #define AREAMASK 0176000 /* mask for area field */ 80 #define AREASHIFT 10 /* bit-offset for area field */ 81 #define NODEMASK 01777 /* mask for node address field */ 82 83 #define DN_MAXADDL 20 /* max size of DECnet address */ 84 struct dn_naddr { 85 uint16_t a_len; /* length of address */ 86 uint8_t a_addr[DN_MAXADDL]; /* address as bytes */ 87 }; 88 89 /* 90 * Define long and short header formats. 91 */ 92 struct shorthdr 93 { 94 byte sh_flags; /* route flags */ 95 word sh_dst; /* destination node address */ 96 word sh_src; /* source node address */ 97 byte sh_visits; /* visit count */ 98 }; 99 100 struct longhdr 101 { 102 byte lg_flags; /* route flags */ 103 byte lg_darea; /* destination area (reserved) */ 104 byte lg_dsarea; /* destination subarea (reserved) */ 105 etheraddr lg_dst; /* destination id */ 106 byte lg_sarea; /* source area (reserved) */ 107 byte lg_ssarea; /* source subarea (reserved) */ 108 etheraddr lg_src; /* source id */ 109 byte lg_nextl2; /* next level 2 router (reserved) */ 110 byte lg_visits; /* visit count */ 111 byte lg_service; /* service class (reserved) */ 112 byte lg_pt; /* protocol type (reserved) */ 113 }; 114 115 union routehdr 116 { 117 struct shorthdr rh_short; /* short route header */ 118 struct longhdr rh_long; /* long route header */ 119 }; 120 121 /* 122 * Define the values of various fields in the protocol messages. 123 * 124 * 1. Data packet formats. 125 */ 126 #define RMF_MASK 7 /* mask for message type */ 127 #define RMF_SHORT 2 /* short message format */ 128 #define RMF_LONG 6 /* long message format */ 129 #ifndef RMF_RQR 130 #define RMF_RQR 010 /* request return to sender */ 131 #define RMF_RTS 020 /* returning to sender */ 132 #define RMF_IE 040 /* intra-ethernet packet */ 133 #endif /* RMR_RQR */ 134 #define RMF_FVER 0100 /* future version flag */ 135 #define RMF_PAD 0200 /* pad field */ 136 #define RMF_PADMASK 0177 /* pad field mask */ 137 138 #define VIS_MASK 077 /* visit field mask */ 139 140 /* 141 * 2. Control packet formats. 142 */ 143 #define RMF_CTLMASK 017 /* mask for message type */ 144 #define RMF_CTLMSG 01 /* control message indicator */ 145 #define RMF_INIT 01 /* initialization message */ 146 #define RMF_VER 03 /* verification message */ 147 #define RMF_TEST 05 /* hello and test message */ 148 #define RMF_L1ROUT 07 /* level 1 routing message */ 149 #define RMF_L2ROUT 011 /* level 2 routing message */ 150 #define RMF_RHELLO 013 /* router hello message */ 151 #define RMF_EHELLO 015 /* endnode hello message */ 152 153 #define TI_L2ROUT 01 /* level 2 router */ 154 #define TI_L1ROUT 02 /* level 1 router */ 155 #define TI_ENDNODE 03 /* endnode */ 156 #define TI_VERIF 04 /* verification required */ 157 #define TI_BLOCK 010 /* blocking requested */ 158 159 #define VE_VERS 2 /* version number (2) */ 160 #define VE_ECO 0 /* ECO number */ 161 #define VE_UECO 0 /* user ECO number (0) */ 162 163 #define P3_VERS 1 /* phase III version number (1) */ 164 #define P3_ECO 3 /* ECO number (3) */ 165 #define P3_UECO 0 /* user ECO number (0) */ 166 167 #define II_L2ROUT 01 /* level 2 router */ 168 #define II_L1ROUT 02 /* level 1 router */ 169 #define II_ENDNODE 03 /* endnode */ 170 #define II_VERIF 04 /* verification required */ 171 #define II_NOMCAST 040 /* no multicast traffic accepted */ 172 #define II_BLOCK 0100 /* blocking requested */ 173 #define II_TYPEMASK 03 /* mask for node type */ 174 175 #define TESTDATA 0252 /* test data bytes */ 176 #define TESTLEN 1 /* length of transmitted test data */ 177 178 /* 179 * Define control message formats. 180 */ 181 struct initmsgIII /* phase III initialization message */ 182 { 183 byte inIII_flags; /* route flags */ 184 word inIII_src; /* source node address */ 185 byte inIII_info; /* routing layer information */ 186 word inIII_blksize; /* maximum data link block size */ 187 byte inIII_vers; /* version number */ 188 byte inIII_eco; /* ECO number */ 189 byte inIII_ueco; /* user ECO number */ 190 byte inIII_rsvd; /* reserved image field */ 191 }; 192 193 struct initmsg /* initialization message */ 194 { 195 byte in_flags; /* route flags */ 196 word in_src; /* source node address */ 197 byte in_info; /* routing layer information */ 198 word in_blksize; /* maximum data link block size */ 199 byte in_vers; /* version number */ 200 byte in_eco; /* ECO number */ 201 byte in_ueco; /* user ECO number */ 202 word in_hello; /* hello timer */ 203 byte in_rsvd; /* reserved image field */ 204 }; 205 206 struct verifmsg /* verification message */ 207 { 208 byte ve_flags; /* route flags */ 209 word ve_src; /* source node address */ 210 byte ve_fcnval; /* function value image field */ 211 }; 212 213 struct testmsg /* hello and test message */ 214 { 215 byte te_flags; /* route flags */ 216 word te_src; /* source node address */ 217 byte te_data; /* test data image field */ 218 }; 219 220 struct l1rout /* level 1 routing message */ 221 { 222 byte r1_flags; /* route flags */ 223 word r1_src; /* source node address */ 224 byte r1_rsvd; /* reserved field */ 225 }; 226 227 struct l2rout /* level 2 routing message */ 228 { 229 byte r2_flags; /* route flags */ 230 word r2_src; /* source node address */ 231 byte r2_rsvd; /* reserved field */ 232 }; 233 234 struct rhellomsg /* router hello message */ 235 { 236 byte rh_flags; /* route flags */ 237 byte rh_vers; /* version number */ 238 byte rh_eco; /* ECO number */ 239 byte rh_ueco; /* user ECO number */ 240 etheraddr rh_src; /* source id */ 241 byte rh_info; /* routing layer information */ 242 word rh_blksize; /* maximum data link block size */ 243 byte rh_priority; /* router's priority */ 244 byte rh_area; /* reserved */ 245 word rh_hello; /* hello timer */ 246 byte rh_mpd; /* reserved */ 247 }; 248 249 struct ehellomsg /* endnode hello message */ 250 { 251 byte eh_flags; /* route flags */ 252 byte eh_vers; /* version number */ 253 byte eh_eco; /* ECO number */ 254 byte eh_ueco; /* user ECO number */ 255 etheraddr eh_src; /* source id */ 256 byte eh_info; /* routing layer information */ 257 word eh_blksize; /* maximum data link block size */ 258 byte eh_area; /* area (reserved) */ 259 byte eh_seed[8]; /* verification seed */ 260 etheraddr eh_router; /* designated router */ 261 word eh_hello; /* hello timer */ 262 byte eh_mpd; /* (reserved) */ 263 byte eh_data; /* test data image field */ 264 }; 265 266 union controlmsg 267 { 268 struct initmsg cm_init; /* initialization message */ 269 struct verifmsg cm_ver; /* verification message */ 270 struct testmsg cm_test; /* hello and test message */ 271 struct l1rout cm_l1rou; /* level 1 routing message */ 272 struct l2rout cm_l2rout; /* level 2 routing message */ 273 struct rhellomsg cm_rhello; /* router hello message */ 274 struct ehellomsg cm_ehello; /* endnode hello message */ 275 }; 276 277 /* Macros for decoding routing-info fields */ 278 #define RI_COST(x) ((x)&0777) 279 #define RI_HOPS(x) (((x)>>10)&037) 280 281 /* 282 * NSP protocol fields and values. 283 */ 284 285 #define NSP_TYPEMASK 014 /* mask to isolate type code */ 286 #define NSP_SUBMASK 0160 /* mask to isolate subtype code */ 287 #define NSP_SUBSHFT 4 /* shift to move subtype code */ 288 289 #define MFT_DATA 0 /* data message */ 290 #define MFT_ACK 04 /* acknowledgement message */ 291 #define MFT_CTL 010 /* control message */ 292 293 #define MFS_ILS 020 /* data or I/LS indicator */ 294 #define MFS_BOM 040 /* beginning of message (data) */ 295 #define MFS_MOM 0 /* middle of message (data) */ 296 #define MFS_EOM 0100 /* end of message (data) */ 297 #define MFS_INT 040 /* interrupt message */ 298 299 #define MFS_DACK 0 /* data acknowledgement */ 300 #define MFS_IACK 020 /* I/LS acknowledgement */ 301 #define MFS_CACK 040 /* connect acknowledgement */ 302 303 #define MFS_NOP 0 /* no operation */ 304 #define MFS_CI 020 /* connect initiate */ 305 #define MFS_CC 040 /* connect confirm */ 306 #define MFS_DI 060 /* disconnect initiate */ 307 #define MFS_DC 0100 /* disconnect confirm */ 308 #define MFS_RCI 0140 /* retransmitted connect initiate */ 309 310 #define SGQ_ACK 0100000 /* ack */ 311 #define SGQ_NAK 0110000 /* negative ack */ 312 #define SGQ_OACK 0120000 /* other channel ack */ 313 #define SGQ_ONAK 0130000 /* other channel negative ack */ 314 #define SGQ_MASK 07777 /* mask to isolate seq # */ 315 #define SGQ_OTHER 020000 /* other channel qualifier */ 316 #define SGQ_DELAY 010000 /* ack delay flag */ 317 318 #define SGQ_EOM 0100000 /* pseudo flag for end-of-message */ 319 320 #define LSM_MASK 03 /* mask for modifier field */ 321 #define LSM_NOCHANGE 0 /* no change */ 322 #define LSM_DONOTSEND 1 /* do not send data */ 323 #define LSM_SEND 2 /* send data */ 324 325 #define LSI_MASK 014 /* mask for interpretation field */ 326 #define LSI_DATA 0 /* data segment or message count */ 327 #define LSI_INTR 4 /* interrupt request count */ 328 #define LSI_INTM 0377 /* funny marker for int. message */ 329 330 #define COS_MASK 014 /* mask for flow control field */ 331 #define COS_NONE 0 /* no flow control */ 332 #define COS_SEGMENT 04 /* segment flow control */ 333 #define COS_MESSAGE 010 /* message flow control */ 334 #define COS_DEFAULT 1 /* default value for field */ 335 336 #define COI_MASK 3 /* mask for version field */ 337 #define COI_32 0 /* version 3.2 */ 338 #define COI_31 1 /* version 3.1 */ 339 #define COI_40 2 /* version 4.0 */ 340 #define COI_41 3 /* version 4.1 */ 341 342 #define MNU_MASK 140 /* mask for session control version */ 343 #define MNU_10 000 /* session V1.0 */ 344 #define MNU_20 040 /* session V2.0 */ 345 #define MNU_ACCESS 1 /* access control present */ 346 #define MNU_USRDATA 2 /* user data field present */ 347 #define MNU_INVKPROXY 4 /* invoke proxy field present */ 348 #define MNU_UICPROXY 8 /* use uic-based proxy */ 349 350 #define DC_NORESOURCES 1 /* no resource reason code */ 351 #define DC_NOLINK 41 /* no link terminate reason code */ 352 #define DC_COMPLETE 42 /* disconnect complete reason code */ 353 354 #define DI_NOERROR 0 /* user disconnect */ 355 #define DI_SHUT 3 /* node is shutting down */ 356 #define DI_NOUSER 4 /* destination end user does not exist */ 357 #define DI_INVDEST 5 /* invalid end user destination */ 358 #define DI_REMRESRC 6 /* insufficient remote resources */ 359 #define DI_TPA 8 /* third party abort */ 360 #define DI_PROTOCOL 7 /* protocol error discovered */ 361 #define DI_ABORT 9 /* user abort */ 362 #define DI_LOCALRESRC 32 /* insufficient local resources */ 363 #define DI_REMUSERRESRC 33 /* insufficient remote user resources */ 364 #define DI_BADACCESS 34 /* bad access control information */ 365 #define DI_BADACCNT 36 /* bad ACCOUNT information */ 366 #define DI_CONNECTABORT 38 /* connect request cancelled */ 367 #define DI_TIMEDOUT 38 /* remote node or user crashed */ 368 #define DI_UNREACHABLE 39 /* local timers expired due to ... */ 369 #define DI_BADIMAGE 43 /* bad image data in connect */ 370 #define DI_SERVMISMATCH 54 /* cryptographic service mismatch */ 371 372 #define UC_OBJREJECT 0 /* object rejected connect */ 373 #define UC_USERDISCONNECT 0 /* user disconnect */ 374 #define UC_RESOURCES 1 /* insufficient resources (local or remote) */ 375 #define UC_NOSUCHNODE 2 /* unrecognized node name */ 376 #define UC_REMOTESHUT 3 /* remote node shutting down */ 377 #define UC_NOSUCHOBJ 4 /* unrecognized object */ 378 #define UC_INVOBJFORMAT 5 /* invalid object name format */ 379 #define UC_OBJTOOBUSY 6 /* object too busy */ 380 #define UC_NETWORKABORT 8 /* network abort */ 381 #define UC_USERABORT 9 /* user abort */ 382 #define UC_INVNODEFORMAT 10 /* invalid node name format */ 383 #define UC_LOCALSHUT 11 /* local node shutting down */ 384 #define UC_ACCESSREJECT 34 /* invalid access control information */ 385 #define UC_NORESPONSE 38 /* no response from object */ 386 #define UC_UNREACHABLE 39 /* node unreachable */ 387 388 /* 389 * NSP message formats. 390 */ 391 struct nsphdr /* general nsp header */ 392 { 393 byte nh_flags; /* message flags */ 394 word nh_dst; /* destination link address */ 395 word nh_src; /* source link address */ 396 }; 397 398 struct seghdr /* data segment header */ 399 { 400 byte sh_flags; /* message flags */ 401 word sh_dst; /* destination link address */ 402 word sh_src; /* source link address */ 403 word sh_seq[3]; /* sequence numbers */ 404 }; 405 406 struct minseghdr /* minimum data segment header */ 407 { 408 byte ms_flags; /* message flags */ 409 word ms_dst; /* destination link address */ 410 word ms_src; /* source link address */ 411 word ms_seq; /* sequence number */ 412 }; 413 414 struct lsmsg /* link service message (after hdr) */ 415 { 416 byte ls_lsflags; /* link service flags */ 417 byte ls_fcval; /* flow control value */ 418 }; 419 420 struct ackmsg /* acknowledgement message */ 421 { 422 byte ak_flags; /* message flags */ 423 word ak_dst; /* destination link address */ 424 word ak_src; /* source link address */ 425 word ak_acknum[2]; /* acknowledgement numbers */ 426 }; 427 428 struct minackmsg /* minimum acknowledgement message */ 429 { 430 byte mk_flags; /* message flags */ 431 word mk_dst; /* destination link address */ 432 word mk_src; /* source link address */ 433 word mk_acknum; /* acknowledgement number */ 434 }; 435 436 struct ciackmsg /* connect acknowledgement message */ 437 { 438 byte ck_flags; /* message flags */ 439 word ck_dst; /* destination link address */ 440 }; 441 442 struct cimsg /* connect initiate message */ 443 { 444 byte ci_flags; /* message flags */ 445 word ci_dst; /* destination link address (0) */ 446 word ci_src; /* source link address */ 447 byte ci_services; /* requested services */ 448 byte ci_info; /* information */ 449 word ci_segsize; /* maximum segment size */ 450 }; 451 452 struct ccmsg /* connect confirm message */ 453 { 454 byte cc_flags; /* message flags */ 455 word cc_dst; /* destination link address */ 456 word cc_src; /* source link address */ 457 byte cc_services; /* requested services */ 458 byte cc_info; /* information */ 459 word cc_segsize; /* maximum segment size */ 460 byte cc_optlen; /* optional data length */ 461 }; 462 463 struct cnmsg /* generic connect message */ 464 { 465 byte cn_flags; /* message flags */ 466 word cn_dst; /* destination link address */ 467 word cn_src; /* source link address */ 468 byte cn_services; /* requested services */ 469 byte cn_info; /* information */ 470 word cn_segsize; /* maximum segment size */ 471 }; 472 473 struct dimsg /* disconnect initiate message */ 474 { 475 byte di_flags; /* message flags */ 476 word di_dst; /* destination link address */ 477 word di_src; /* source link address */ 478 word di_reason; /* reason code */ 479 byte di_optlen; /* optional data length */ 480 }; 481 482 struct dcmsg /* disconnect confirm message */ 483 { 484 byte dc_flags; /* message flags */ 485 word dc_dst; /* destination link address */ 486 word dc_src; /* source link address */ 487 word dc_reason; /* reason code */ 488 }; 489 490 /* Forwards */ 491 static int print_decnet_ctlmsg(netdissect_options *, const union routehdr *, u_int, u_int); 492 static void print_t_info(netdissect_options *, int); 493 static int print_l1_routes(netdissect_options *, const char *, u_int); 494 static int print_l2_routes(netdissect_options *, const char *, u_int); 495 static void print_i_info(netdissect_options *, int); 496 static int print_elist(const char *, u_int); 497 static int print_nsp(netdissect_options *, const u_char *, u_int); 498 static void print_reason(netdissect_options *, int); 499 500 #ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA 501 extern char *dnet_htoa(struct dn_naddr *); 502 #endif 503 504 void 505 decnet_print(netdissect_options *ndo, 506 register const u_char *ap, register u_int length, 507 register u_int caplen) 508 { 509 register const union routehdr *rhp; 510 register int mflags; 511 int dst, src, hops; 512 u_int nsplen, pktlen; 513 const u_char *nspp; 514 515 if (length < sizeof(struct shorthdr)) { 516 ND_PRINT((ndo, "%s", tstr)); 517 return; 518 } 519 520 ND_TCHECK2(*ap, sizeof(short)); 521 pktlen = EXTRACT_LE_16BITS(ap); 522 if (pktlen < sizeof(struct shorthdr)) { 523 ND_PRINT((ndo, "%s", tstr)); 524 return; 525 } 526 if (pktlen > length) { 527 ND_PRINT((ndo, "%s", tstr)); 528 return; 529 } 530 length = pktlen; 531 532 rhp = (const union routehdr *)&(ap[sizeof(short)]); 533 ND_TCHECK(rhp->rh_short.sh_flags); 534 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 535 536 if (mflags & RMF_PAD) { 537 /* pad bytes of some sort in front of message */ 538 u_int padlen = mflags & RMF_PADMASK; 539 if (ndo->ndo_vflag) 540 ND_PRINT((ndo, "[pad:%d] ", padlen)); 541 if (length < padlen + 2) { 542 ND_PRINT((ndo, "%s", tstr)); 543 return; 544 } 545 ND_TCHECK2(ap[sizeof(short)], padlen); 546 ap += padlen; 547 length -= padlen; 548 caplen -= padlen; 549 rhp = (const union routehdr *)&(ap[sizeof(short)]); 550 ND_TCHECK(rhp->rh_short.sh_flags); 551 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 552 } 553 554 if (mflags & RMF_FVER) { 555 ND_PRINT((ndo, "future-version-decnet")); 556 ND_DEFAULTPRINT(ap, min(length, caplen)); 557 return; 558 } 559 560 /* is it a control message? */ 561 if (mflags & RMF_CTLMSG) { 562 if (!print_decnet_ctlmsg(ndo, rhp, length, caplen)) 563 goto trunc; 564 return; 565 } 566 567 switch (mflags & RMF_MASK) { 568 case RMF_LONG: 569 if (length < sizeof(struct longhdr)) { 570 ND_PRINT((ndo, "%s", tstr)); 571 return; 572 } 573 ND_TCHECK(rhp->rh_long); 574 dst = 575 EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); 576 src = 577 EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); 578 hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); 579 nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); 580 nsplen = length - sizeof(struct longhdr); 581 break; 582 case RMF_SHORT: 583 ND_TCHECK(rhp->rh_short); 584 dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); 585 src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); 586 hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; 587 nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); 588 nsplen = length - sizeof(struct shorthdr); 589 break; 590 default: 591 ND_PRINT((ndo, "unknown message flags under mask")); 592 ND_DEFAULTPRINT((const u_char *)ap, min(length, caplen)); 593 return; 594 } 595 596 ND_PRINT((ndo, "%s > %s %d ", 597 dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); 598 if (ndo->ndo_vflag) { 599 if (mflags & RMF_RQR) 600 ND_PRINT((ndo, "RQR ")); 601 if (mflags & RMF_RTS) 602 ND_PRINT((ndo, "RTS ")); 603 if (mflags & RMF_IE) 604 ND_PRINT((ndo, "IE ")); 605 ND_PRINT((ndo, "%d hops ", hops)); 606 } 607 608 if (!print_nsp(ndo, nspp, nsplen)) 609 goto trunc; 610 return; 611 612 trunc: 613 ND_PRINT((ndo, "%s", tstr)); 614 return; 615 } 616 617 static int 618 print_decnet_ctlmsg(netdissect_options *ndo, 619 register const union routehdr *rhp, u_int length, 620 u_int caplen) 621 { 622 /* Our caller has already checked for mflags */ 623 int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 624 register const union controlmsg *cmp = (const union controlmsg *)rhp; 625 int src, dst, info, blksize, eco, ueco, hello, other, vers; 626 etheraddr srcea, rtea; 627 int priority; 628 const char *rhpx = (const char *)rhp; 629 int ret; 630 631 switch (mflags & RMF_CTLMASK) { 632 case RMF_INIT: 633 ND_PRINT((ndo, "init ")); 634 if (length < sizeof(struct initmsg)) 635 goto trunc; 636 ND_TCHECK(cmp->cm_init); 637 src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); 638 info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); 639 blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); 640 vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); 641 eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); 642 ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); 643 hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); 644 print_t_info(ndo, info); 645 ND_PRINT((ndo, 646 "src %sblksize %d vers %d eco %d ueco %d hello %d", 647 dnaddr_string(ndo, src), blksize, vers, eco, ueco, 648 hello)); 649 ret = 1; 650 break; 651 case RMF_VER: 652 ND_PRINT((ndo, "verification ")); 653 if (length < sizeof(struct verifmsg)) 654 goto trunc; 655 ND_TCHECK(cmp->cm_ver); 656 src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); 657 other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); 658 ND_PRINT((ndo, "src %s fcnval %o", dnaddr_string(ndo, src), other)); 659 ret = 1; 660 break; 661 case RMF_TEST: 662 ND_PRINT((ndo, "test ")); 663 if (length < sizeof(struct testmsg)) 664 goto trunc; 665 ND_TCHECK(cmp->cm_test); 666 src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); 667 other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); 668 ND_PRINT((ndo, "src %s data %o", dnaddr_string(ndo, src), other)); 669 ret = 1; 670 break; 671 case RMF_L1ROUT: 672 ND_PRINT((ndo, "lev-1-routing ")); 673 if (length < sizeof(struct l1rout)) 674 goto trunc; 675 ND_TCHECK(cmp->cm_l1rou); 676 src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 677 ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 678 ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), 679 length - sizeof(struct l1rout)); 680 break; 681 case RMF_L2ROUT: 682 ND_PRINT((ndo, "lev-2-routing ")); 683 if (length < sizeof(struct l2rout)) 684 goto trunc; 685 ND_TCHECK(cmp->cm_l2rout); 686 src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 687 ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 688 ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), 689 length - sizeof(struct l2rout)); 690 break; 691 case RMF_RHELLO: 692 ND_PRINT((ndo, "router-hello ")); 693 if (length < sizeof(struct rhellomsg)) 694 goto trunc; 695 ND_TCHECK(cmp->cm_rhello); 696 vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); 697 eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); 698 ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); 699 memcpy((char *)&srcea, (const char *)&(cmp->cm_rhello.rh_src), 700 sizeof(srcea)); 701 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 702 info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); 703 blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); 704 priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); 705 hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); 706 print_i_info(ndo, info); 707 ND_PRINT((ndo, 708 "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 709 vers, eco, ueco, dnaddr_string(ndo, src), 710 blksize, priority, hello)); 711 ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), 712 length - sizeof(struct rhellomsg)); 713 break; 714 case RMF_EHELLO: 715 ND_PRINT((ndo, "endnode-hello ")); 716 if (length < sizeof(struct ehellomsg)) 717 goto trunc; 718 ND_TCHECK(cmp->cm_ehello); 719 vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); 720 eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); 721 ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); 722 memcpy((char *)&srcea, (const char *)&(cmp->cm_ehello.eh_src), 723 sizeof(srcea)); 724 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 725 info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); 726 blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); 727 /*seed*/ 728 memcpy((char *)&rtea, (const char *)&(cmp->cm_ehello.eh_router), 729 sizeof(rtea)); 730 dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); 731 hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); 732 other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); 733 print_i_info(ndo, info); 734 ND_PRINT((ndo, 735 "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 736 vers, eco, ueco, dnaddr_string(ndo, src), 737 blksize, dnaddr_string(ndo, dst), hello, other)); 738 ret = 1; 739 break; 740 741 default: 742 ND_PRINT((ndo, "unknown control message")); 743 ND_DEFAULTPRINT((const u_char *)rhp, min(length, caplen)); 744 ret = 1; 745 break; 746 } 747 return (ret); 748 749 trunc: 750 return (0); 751 } 752 753 static void 754 print_t_info(netdissect_options *ndo, 755 int info) 756 { 757 int ntype = info & 3; 758 switch (ntype) { 759 case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 760 case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 761 case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 762 case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 763 } 764 if (info & TI_VERIF) 765 ND_PRINT((ndo, "verif ")); 766 if (info & TI_BLOCK) 767 ND_PRINT((ndo, "blo ")); 768 } 769 770 static int 771 print_l1_routes(netdissect_options *ndo, 772 const char *rp, u_int len) 773 { 774 int count; 775 int id; 776 int info; 777 778 /* The last short is a checksum */ 779 while (len > (3 * sizeof(short))) { 780 ND_TCHECK2(*rp, 3 * sizeof(short)); 781 count = EXTRACT_LE_16BITS(rp); 782 if (count > 1024) 783 return (1); /* seems to be bogus from here on */ 784 rp += sizeof(short); 785 len -= sizeof(short); 786 id = EXTRACT_LE_16BITS(rp); 787 rp += sizeof(short); 788 len -= sizeof(short); 789 info = EXTRACT_LE_16BITS(rp); 790 rp += sizeof(short); 791 len -= sizeof(short); 792 ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, 793 RI_COST(info), RI_HOPS(info))); 794 } 795 return (1); 796 797 trunc: 798 return (0); 799 } 800 801 static int 802 print_l2_routes(netdissect_options *ndo, 803 const char *rp, u_int len) 804 { 805 int count; 806 int area; 807 int info; 808 809 /* The last short is a checksum */ 810 while (len > (3 * sizeof(short))) { 811 ND_TCHECK2(*rp, 3 * sizeof(short)); 812 count = EXTRACT_LE_16BITS(rp); 813 if (count > 1024) 814 return (1); /* seems to be bogus from here on */ 815 rp += sizeof(short); 816 len -= sizeof(short); 817 area = EXTRACT_LE_16BITS(rp); 818 rp += sizeof(short); 819 len -= sizeof(short); 820 info = EXTRACT_LE_16BITS(rp); 821 rp += sizeof(short); 822 len -= sizeof(short); 823 ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, 824 RI_COST(info), RI_HOPS(info))); 825 } 826 return (1); 827 828 trunc: 829 return (0); 830 } 831 832 static void 833 print_i_info(netdissect_options *ndo, 834 int info) 835 { 836 int ntype = info & II_TYPEMASK; 837 switch (ntype) { 838 case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 839 case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 840 case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 841 case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 842 } 843 if (info & II_VERIF) 844 ND_PRINT((ndo, "verif ")); 845 if (info & II_NOMCAST) 846 ND_PRINT((ndo, "nomcast ")); 847 if (info & II_BLOCK) 848 ND_PRINT((ndo, "blo ")); 849 } 850 851 static int 852 print_elist(const char *elp _U_, u_int len _U_) 853 { 854 /* Not enough examples available for me to debug this */ 855 return (1); 856 } 857 858 static int 859 print_nsp(netdissect_options *ndo, 860 const u_char *nspp, u_int nsplen) 861 { 862 const struct nsphdr *nsphp = (const struct nsphdr *)nspp; 863 int dst, src, flags; 864 865 if (nsplen < sizeof(struct nsphdr)) 866 goto trunc; 867 ND_TCHECK(*nsphp); 868 flags = EXTRACT_LE_8BITS(nsphp->nh_flags); 869 dst = EXTRACT_LE_16BITS(nsphp->nh_dst); 870 src = EXTRACT_LE_16BITS(nsphp->nh_src); 871 872 switch (flags & NSP_TYPEMASK) { 873 case MFT_DATA: 874 switch (flags & NSP_SUBMASK) { 875 case MFS_BOM: 876 case MFS_MOM: 877 case MFS_EOM: 878 case MFS_BOM+MFS_EOM: 879 ND_PRINT((ndo, "data %d>%d ", src, dst)); 880 { 881 const struct seghdr *shp = (const struct seghdr *)nspp; 882 int ack; 883 u_int data_off = sizeof(struct minseghdr); 884 885 if (nsplen < data_off) 886 goto trunc; 887 ND_TCHECK(shp->sh_seq[0]); 888 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 889 if (ack & SGQ_ACK) { /* acknum field */ 890 if ((ack & SGQ_NAK) == SGQ_NAK) 891 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 892 else 893 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 894 data_off += sizeof(short); 895 if (nsplen < data_off) 896 goto trunc; 897 ND_TCHECK(shp->sh_seq[1]); 898 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 899 if (ack & SGQ_OACK) { /* ackoth field */ 900 if ((ack & SGQ_ONAK) == SGQ_ONAK) 901 ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 902 else 903 ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 904 data_off += sizeof(short); 905 if (nsplen < data_off) 906 goto trunc; 907 ND_TCHECK(shp->sh_seq[2]); 908 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 909 } 910 } 911 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 912 } 913 break; 914 case MFS_ILS+MFS_INT: 915 ND_PRINT((ndo, "intr ")); 916 { 917 const struct seghdr *shp = (const struct seghdr *)nspp; 918 int ack; 919 u_int data_off = sizeof(struct minseghdr); 920 921 if (nsplen < data_off) 922 goto trunc; 923 ND_TCHECK(shp->sh_seq[0]); 924 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 925 if (ack & SGQ_ACK) { /* acknum field */ 926 if ((ack & SGQ_NAK) == SGQ_NAK) 927 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 928 else 929 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 930 data_off += sizeof(short); 931 if (nsplen < data_off) 932 goto trunc; 933 ND_TCHECK(shp->sh_seq[1]); 934 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 935 if (ack & SGQ_OACK) { /* ackdat field */ 936 if ((ack & SGQ_ONAK) == SGQ_ONAK) 937 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 938 else 939 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 940 data_off += sizeof(short); 941 if (nsplen < data_off) 942 goto trunc; 943 ND_TCHECK(shp->sh_seq[2]); 944 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 945 } 946 } 947 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 948 } 949 break; 950 case MFS_ILS: 951 ND_PRINT((ndo, "link-service %d>%d ", src, dst)); 952 { 953 const struct seghdr *shp = (const struct seghdr *)nspp; 954 const struct lsmsg *lsmp = 955 (const struct lsmsg *)&(nspp[sizeof(struct seghdr)]); 956 int ack; 957 int lsflags, fcval; 958 959 if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) 960 goto trunc; 961 ND_TCHECK(shp->sh_seq[0]); 962 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 963 if (ack & SGQ_ACK) { /* acknum field */ 964 if ((ack & SGQ_NAK) == SGQ_NAK) 965 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 966 else 967 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 968 ND_TCHECK(shp->sh_seq[1]); 969 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 970 if (ack & SGQ_OACK) { /* ackdat field */ 971 if ((ack & SGQ_ONAK) == SGQ_ONAK) 972 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 973 else 974 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 975 ND_TCHECK(shp->sh_seq[2]); 976 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 977 } 978 } 979 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 980 ND_TCHECK(*lsmp); 981 lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); 982 fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); 983 switch (lsflags & LSI_MASK) { 984 case LSI_DATA: 985 ND_PRINT((ndo, "dat seg count %d ", fcval)); 986 switch (lsflags & LSM_MASK) { 987 case LSM_NOCHANGE: 988 break; 989 case LSM_DONOTSEND: 990 ND_PRINT((ndo, "donotsend-data ")); 991 break; 992 case LSM_SEND: 993 ND_PRINT((ndo, "send-data ")); 994 break; 995 default: 996 ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); 997 break; 998 } 999 break; 1000 case LSI_INTR: 1001 ND_PRINT((ndo, "intr req count %d ", fcval)); 1002 break; 1003 default: 1004 ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); 1005 break; 1006 } 1007 } 1008 break; 1009 default: 1010 ND_PRINT((ndo, "reserved-subtype? %x %d > %d", flags, src, dst)); 1011 break; 1012 } 1013 break; 1014 case MFT_ACK: 1015 switch (flags & NSP_SUBMASK) { 1016 case MFS_DACK: 1017 ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); 1018 { 1019 const struct ackmsg *amp = (const struct ackmsg *)nspp; 1020 int ack; 1021 1022 if (nsplen < sizeof(struct ackmsg)) 1023 goto trunc; 1024 ND_TCHECK(*amp); 1025 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 1026 if (ack & SGQ_ACK) { /* acknum field */ 1027 if ((ack & SGQ_NAK) == SGQ_NAK) 1028 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 1029 else 1030 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 1031 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 1032 if (ack & SGQ_OACK) { /* ackoth field */ 1033 if ((ack & SGQ_ONAK) == SGQ_ONAK) 1034 ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 1035 else 1036 ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 1037 } 1038 } 1039 } 1040 break; 1041 case MFS_IACK: 1042 ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); 1043 { 1044 const struct ackmsg *amp = (const struct ackmsg *)nspp; 1045 int ack; 1046 1047 if (nsplen < sizeof(struct ackmsg)) 1048 goto trunc; 1049 ND_TCHECK(*amp); 1050 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 1051 if (ack & SGQ_ACK) { /* acknum field */ 1052 if ((ack & SGQ_NAK) == SGQ_NAK) 1053 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 1054 else 1055 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 1056 ND_TCHECK(amp->ak_acknum[1]); 1057 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 1058 if (ack & SGQ_OACK) { /* ackdat field */ 1059 if ((ack & SGQ_ONAK) == SGQ_ONAK) 1060 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 1061 else 1062 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 1063 } 1064 } 1065 } 1066 break; 1067 case MFS_CACK: 1068 ND_PRINT((ndo, "conn-ack %d", dst)); 1069 break; 1070 default: 1071 ND_PRINT((ndo, "reserved-acktype? %x %d > %d", flags, src, dst)); 1072 break; 1073 } 1074 break; 1075 case MFT_CTL: 1076 switch (flags & NSP_SUBMASK) { 1077 case MFS_CI: 1078 case MFS_RCI: 1079 if ((flags & NSP_SUBMASK) == MFS_CI) 1080 ND_PRINT((ndo, "conn-initiate ")); 1081 else 1082 ND_PRINT((ndo, "retrans-conn-initiate ")); 1083 ND_PRINT((ndo, "%d>%d ", src, dst)); 1084 { 1085 const struct cimsg *cimp = (const struct cimsg *)nspp; 1086 int services, info, segsize; 1087 1088 if (nsplen < sizeof(struct cimsg)) 1089 goto trunc; 1090 ND_TCHECK(*cimp); 1091 services = EXTRACT_LE_8BITS(cimp->ci_services); 1092 info = EXTRACT_LE_8BITS(cimp->ci_info); 1093 segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); 1094 1095 switch (services & COS_MASK) { 1096 case COS_NONE: 1097 break; 1098 case COS_SEGMENT: 1099 ND_PRINT((ndo, "seg ")); 1100 break; 1101 case COS_MESSAGE: 1102 ND_PRINT((ndo, "msg ")); 1103 break; 1104 } 1105 switch (info & COI_MASK) { 1106 case COI_32: 1107 ND_PRINT((ndo, "ver 3.2 ")); 1108 break; 1109 case COI_31: 1110 ND_PRINT((ndo, "ver 3.1 ")); 1111 break; 1112 case COI_40: 1113 ND_PRINT((ndo, "ver 4.0 ")); 1114 break; 1115 case COI_41: 1116 ND_PRINT((ndo, "ver 4.1 ")); 1117 break; 1118 } 1119 ND_PRINT((ndo, "segsize %d ", segsize)); 1120 } 1121 break; 1122 case MFS_CC: 1123 ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); 1124 { 1125 const struct ccmsg *ccmp = (const struct ccmsg *)nspp; 1126 int services, info; 1127 u_int segsize, optlen; 1128 1129 if (nsplen < sizeof(struct ccmsg)) 1130 goto trunc; 1131 ND_TCHECK(*ccmp); 1132 services = EXTRACT_LE_8BITS(ccmp->cc_services); 1133 info = EXTRACT_LE_8BITS(ccmp->cc_info); 1134 segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); 1135 optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); 1136 1137 switch (services & COS_MASK) { 1138 case COS_NONE: 1139 break; 1140 case COS_SEGMENT: 1141 ND_PRINT((ndo, "seg ")); 1142 break; 1143 case COS_MESSAGE: 1144 ND_PRINT((ndo, "msg ")); 1145 break; 1146 } 1147 switch (info & COI_MASK) { 1148 case COI_32: 1149 ND_PRINT((ndo, "ver 3.2 ")); 1150 break; 1151 case COI_31: 1152 ND_PRINT((ndo, "ver 3.1 ")); 1153 break; 1154 case COI_40: 1155 ND_PRINT((ndo, "ver 4.0 ")); 1156 break; 1157 case COI_41: 1158 ND_PRINT((ndo, "ver 4.1 ")); 1159 break; 1160 } 1161 ND_PRINT((ndo, "segsize %d ", segsize)); 1162 if (optlen) { 1163 ND_PRINT((ndo, "optlen %d ", optlen)); 1164 } 1165 } 1166 break; 1167 case MFS_DI: 1168 ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); 1169 { 1170 const struct dimsg *dimp = (const struct dimsg *)nspp; 1171 int reason; 1172 u_int optlen; 1173 1174 if (nsplen < sizeof(struct dimsg)) 1175 goto trunc; 1176 ND_TCHECK(*dimp); 1177 reason = EXTRACT_LE_16BITS(dimp->di_reason); 1178 optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 1179 1180 print_reason(ndo, reason); 1181 if (optlen) { 1182 ND_PRINT((ndo, "optlen %d ", optlen)); 1183 } 1184 } 1185 break; 1186 case MFS_DC: 1187 ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); 1188 { 1189 const struct dcmsg *dcmp = (const struct dcmsg *)nspp; 1190 int reason; 1191 1192 ND_TCHECK(*dcmp); 1193 reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 1194 1195 print_reason(ndo, reason); 1196 } 1197 break; 1198 default: 1199 ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); 1200 break; 1201 } 1202 break; 1203 default: 1204 ND_PRINT((ndo, "reserved-type? %x %d > %d", flags, src, dst)); 1205 break; 1206 } 1207 return (1); 1208 1209 trunc: 1210 return (0); 1211 } 1212 1213 static const struct tok reason2str[] = { 1214 { UC_OBJREJECT, "object rejected connect" }, 1215 { UC_RESOURCES, "insufficient resources" }, 1216 { UC_NOSUCHNODE, "unrecognized node name" }, 1217 { DI_SHUT, "node is shutting down" }, 1218 { UC_NOSUCHOBJ, "unrecognized object" }, 1219 { UC_INVOBJFORMAT, "invalid object name format" }, 1220 { UC_OBJTOOBUSY, "object too busy" }, 1221 { DI_PROTOCOL, "protocol error discovered" }, 1222 { DI_TPA, "third party abort" }, 1223 { UC_USERABORT, "user abort" }, 1224 { UC_INVNODEFORMAT, "invalid node name format" }, 1225 { UC_LOCALSHUT, "local node shutting down" }, 1226 { DI_LOCALRESRC, "insufficient local resources" }, 1227 { DI_REMUSERRESRC, "insufficient remote user resources" }, 1228 { UC_ACCESSREJECT, "invalid access control information" }, 1229 { DI_BADACCNT, "bad ACCOUNT information" }, 1230 { UC_NORESPONSE, "no response from object" }, 1231 { UC_UNREACHABLE, "node unreachable" }, 1232 { DC_NOLINK, "no link terminate" }, 1233 { DC_COMPLETE, "disconnect complete" }, 1234 { DI_BADIMAGE, "bad image data in connect" }, 1235 { DI_SERVMISMATCH, "cryptographic service mismatch" }, 1236 { 0, NULL } 1237 }; 1238 1239 static void 1240 print_reason(netdissect_options *ndo, 1241 register int reason) 1242 { 1243 ND_PRINT((ndo, "%s ", tok2str(reason2str, "reason-%d", reason))); 1244 } 1245 1246 const char * 1247 dnnum_string(netdissect_options *ndo, u_short dnaddr) 1248 { 1249 char *str; 1250 size_t siz; 1251 int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; 1252 int node = dnaddr & NODEMASK; 1253 1254 str = (char *)malloc(siz = sizeof("00.0000")); 1255 if (str == NULL) 1256 (*ndo->ndo_error)(ndo, "dnnum_string: malloc"); 1257 snprintf(str, siz, "%d.%d", area, node); 1258 return(str); 1259 } 1260 1261 const char * 1262 dnname_string(netdissect_options *ndo, u_short dnaddr) 1263 { 1264 #ifdef HAVE_DNET_HTOA 1265 struct dn_naddr dna; 1266 char *dnname; 1267 1268 dna.a_len = sizeof(short); 1269 memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 1270 dnname = dnet_htoa(&dna); 1271 if(dnname != NULL) 1272 return (strdup(dnname)); 1273 else 1274 return(dnnum_string(ndo, dnaddr)); 1275 #else 1276 return(dnnum_string(ndo, dnaddr)); /* punt */ 1277 #endif 1278 } 1279