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.8 2017/02/05 04:05:05 spz 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 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 551 } 552 553 if (mflags & RMF_FVER) { 554 ND_PRINT((ndo, "future-version-decnet")); 555 ND_DEFAULTPRINT(ap, min(length, caplen)); 556 return; 557 } 558 559 /* is it a control message? */ 560 if (mflags & RMF_CTLMSG) { 561 if (!print_decnet_ctlmsg(ndo, rhp, length, caplen)) 562 goto trunc; 563 return; 564 } 565 566 switch (mflags & RMF_MASK) { 567 case RMF_LONG: 568 if (length < sizeof(struct longhdr)) { 569 ND_PRINT((ndo, "%s", tstr)); 570 return; 571 } 572 ND_TCHECK(rhp->rh_long); 573 dst = 574 EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); 575 src = 576 EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); 577 hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); 578 nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); 579 nsplen = length - sizeof(struct longhdr); 580 break; 581 case RMF_SHORT: 582 ND_TCHECK(rhp->rh_short); 583 dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); 584 src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); 585 hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; 586 nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); 587 nsplen = length - sizeof(struct shorthdr); 588 break; 589 default: 590 ND_PRINT((ndo, "unknown message flags under mask")); 591 ND_DEFAULTPRINT((const u_char *)ap, min(length, caplen)); 592 return; 593 } 594 595 ND_PRINT((ndo, "%s > %s %d ", 596 dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); 597 if (ndo->ndo_vflag) { 598 if (mflags & RMF_RQR) 599 ND_PRINT((ndo, "RQR ")); 600 if (mflags & RMF_RTS) 601 ND_PRINT((ndo, "RTS ")); 602 if (mflags & RMF_IE) 603 ND_PRINT((ndo, "IE ")); 604 ND_PRINT((ndo, "%d hops ", hops)); 605 } 606 607 if (!print_nsp(ndo, nspp, nsplen)) 608 goto trunc; 609 return; 610 611 trunc: 612 ND_PRINT((ndo, "%s", tstr)); 613 return; 614 } 615 616 static int 617 print_decnet_ctlmsg(netdissect_options *ndo, 618 register const union routehdr *rhp, u_int length, 619 u_int caplen) 620 { 621 int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 622 register const union controlmsg *cmp = (const union controlmsg *)rhp; 623 int src, dst, info, blksize, eco, ueco, hello, other, vers; 624 etheraddr srcea, rtea; 625 int priority; 626 const char *rhpx = (const char *)rhp; 627 int ret; 628 629 switch (mflags & RMF_CTLMASK) { 630 case RMF_INIT: 631 ND_PRINT((ndo, "init ")); 632 if (length < sizeof(struct initmsg)) 633 goto trunc; 634 ND_TCHECK(cmp->cm_init); 635 src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); 636 info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); 637 blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); 638 vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); 639 eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); 640 ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); 641 hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); 642 print_t_info(ndo, info); 643 ND_PRINT((ndo, 644 "src %sblksize %d vers %d eco %d ueco %d hello %d", 645 dnaddr_string(ndo, src), blksize, vers, eco, ueco, 646 hello)); 647 ret = 1; 648 break; 649 case RMF_VER: 650 ND_PRINT((ndo, "verification ")); 651 if (length < sizeof(struct verifmsg)) 652 goto trunc; 653 ND_TCHECK(cmp->cm_ver); 654 src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); 655 other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); 656 ND_PRINT((ndo, "src %s fcnval %o", dnaddr_string(ndo, src), other)); 657 ret = 1; 658 break; 659 case RMF_TEST: 660 ND_PRINT((ndo, "test ")); 661 if (length < sizeof(struct testmsg)) 662 goto trunc; 663 ND_TCHECK(cmp->cm_test); 664 src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); 665 other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); 666 ND_PRINT((ndo, "src %s data %o", dnaddr_string(ndo, src), other)); 667 ret = 1; 668 break; 669 case RMF_L1ROUT: 670 ND_PRINT((ndo, "lev-1-routing ")); 671 if (length < sizeof(struct l1rout)) 672 goto trunc; 673 ND_TCHECK(cmp->cm_l1rou); 674 src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 675 ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 676 ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), 677 length - sizeof(struct l1rout)); 678 break; 679 case RMF_L2ROUT: 680 ND_PRINT((ndo, "lev-2-routing ")); 681 if (length < sizeof(struct l2rout)) 682 goto trunc; 683 ND_TCHECK(cmp->cm_l2rout); 684 src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 685 ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 686 ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), 687 length - sizeof(struct l2rout)); 688 break; 689 case RMF_RHELLO: 690 ND_PRINT((ndo, "router-hello ")); 691 if (length < sizeof(struct rhellomsg)) 692 goto trunc; 693 ND_TCHECK(cmp->cm_rhello); 694 vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); 695 eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); 696 ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); 697 memcpy((char *)&srcea, (const char *)&(cmp->cm_rhello.rh_src), 698 sizeof(srcea)); 699 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 700 info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); 701 blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); 702 priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); 703 hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); 704 print_i_info(ndo, info); 705 ND_PRINT((ndo, 706 "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 707 vers, eco, ueco, dnaddr_string(ndo, src), 708 blksize, priority, hello)); 709 ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), 710 length - sizeof(struct rhellomsg)); 711 break; 712 case RMF_EHELLO: 713 ND_PRINT((ndo, "endnode-hello ")); 714 if (length < sizeof(struct ehellomsg)) 715 goto trunc; 716 ND_TCHECK(cmp->cm_ehello); 717 vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); 718 eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); 719 ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); 720 memcpy((char *)&srcea, (const char *)&(cmp->cm_ehello.eh_src), 721 sizeof(srcea)); 722 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 723 info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); 724 blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); 725 /*seed*/ 726 memcpy((char *)&rtea, (const char *)&(cmp->cm_ehello.eh_router), 727 sizeof(rtea)); 728 dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); 729 hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); 730 other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); 731 print_i_info(ndo, info); 732 ND_PRINT((ndo, 733 "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 734 vers, eco, ueco, dnaddr_string(ndo, src), 735 blksize, dnaddr_string(ndo, dst), hello, other)); 736 ret = 1; 737 break; 738 739 default: 740 ND_PRINT((ndo, "unknown control message")); 741 ND_DEFAULTPRINT((const u_char *)rhp, min(length, caplen)); 742 ret = 1; 743 break; 744 } 745 return (ret); 746 747 trunc: 748 return (0); 749 } 750 751 static void 752 print_t_info(netdissect_options *ndo, 753 int info) 754 { 755 int ntype = info & 3; 756 switch (ntype) { 757 case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 758 case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 759 case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 760 case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 761 } 762 if (info & TI_VERIF) 763 ND_PRINT((ndo, "verif ")); 764 if (info & TI_BLOCK) 765 ND_PRINT((ndo, "blo ")); 766 } 767 768 static int 769 print_l1_routes(netdissect_options *ndo, 770 const char *rp, u_int len) 771 { 772 int count; 773 int id; 774 int info; 775 776 /* The last short is a checksum */ 777 while (len > (3 * sizeof(short))) { 778 ND_TCHECK2(*rp, 3 * sizeof(short)); 779 count = EXTRACT_LE_16BITS(rp); 780 if (count > 1024) 781 return (1); /* seems to be bogus from here on */ 782 rp += sizeof(short); 783 len -= sizeof(short); 784 id = EXTRACT_LE_16BITS(rp); 785 rp += sizeof(short); 786 len -= sizeof(short); 787 info = EXTRACT_LE_16BITS(rp); 788 rp += sizeof(short); 789 len -= sizeof(short); 790 ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, 791 RI_COST(info), RI_HOPS(info))); 792 } 793 return (1); 794 795 trunc: 796 return (0); 797 } 798 799 static int 800 print_l2_routes(netdissect_options *ndo, 801 const char *rp, u_int len) 802 { 803 int count; 804 int area; 805 int info; 806 807 /* The last short is a checksum */ 808 while (len > (3 * sizeof(short))) { 809 ND_TCHECK2(*rp, 3 * sizeof(short)); 810 count = EXTRACT_LE_16BITS(rp); 811 if (count > 1024) 812 return (1); /* seems to be bogus from here on */ 813 rp += sizeof(short); 814 len -= sizeof(short); 815 area = EXTRACT_LE_16BITS(rp); 816 rp += sizeof(short); 817 len -= sizeof(short); 818 info = EXTRACT_LE_16BITS(rp); 819 rp += sizeof(short); 820 len -= sizeof(short); 821 ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, 822 RI_COST(info), RI_HOPS(info))); 823 } 824 return (1); 825 826 trunc: 827 return (0); 828 } 829 830 static void 831 print_i_info(netdissect_options *ndo, 832 int info) 833 { 834 int ntype = info & II_TYPEMASK; 835 switch (ntype) { 836 case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 837 case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 838 case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 839 case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 840 } 841 if (info & II_VERIF) 842 ND_PRINT((ndo, "verif ")); 843 if (info & II_NOMCAST) 844 ND_PRINT((ndo, "nomcast ")); 845 if (info & II_BLOCK) 846 ND_PRINT((ndo, "blo ")); 847 } 848 849 static int 850 print_elist(const char *elp _U_, u_int len _U_) 851 { 852 /* Not enough examples available for me to debug this */ 853 return (1); 854 } 855 856 static int 857 print_nsp(netdissect_options *ndo, 858 const u_char *nspp, u_int nsplen) 859 { 860 const struct nsphdr *nsphp = (const struct nsphdr *)nspp; 861 int dst, src, flags; 862 863 if (nsplen < sizeof(struct nsphdr)) 864 goto trunc; 865 ND_TCHECK(*nsphp); 866 flags = EXTRACT_LE_8BITS(nsphp->nh_flags); 867 dst = EXTRACT_LE_16BITS(nsphp->nh_dst); 868 src = EXTRACT_LE_16BITS(nsphp->nh_src); 869 870 switch (flags & NSP_TYPEMASK) { 871 case MFT_DATA: 872 switch (flags & NSP_SUBMASK) { 873 case MFS_BOM: 874 case MFS_MOM: 875 case MFS_EOM: 876 case MFS_BOM+MFS_EOM: 877 ND_PRINT((ndo, "data %d>%d ", src, dst)); 878 { 879 const struct seghdr *shp = (const struct seghdr *)nspp; 880 int ack; 881 u_int data_off = sizeof(struct minseghdr); 882 883 if (nsplen < data_off) 884 goto trunc; 885 ND_TCHECK(shp->sh_seq[0]); 886 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 887 if (ack & SGQ_ACK) { /* acknum field */ 888 if ((ack & SGQ_NAK) == SGQ_NAK) 889 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 890 else 891 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 892 data_off += sizeof(short); 893 if (nsplen < data_off) 894 goto trunc; 895 ND_TCHECK(shp->sh_seq[1]); 896 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 897 if (ack & SGQ_OACK) { /* ackoth field */ 898 if ((ack & SGQ_ONAK) == SGQ_ONAK) 899 ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 900 else 901 ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 902 data_off += sizeof(short); 903 if (nsplen < data_off) 904 goto trunc; 905 ND_TCHECK(shp->sh_seq[2]); 906 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 907 } 908 } 909 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 910 } 911 break; 912 case MFS_ILS+MFS_INT: 913 ND_PRINT((ndo, "intr ")); 914 { 915 const struct seghdr *shp = (const struct seghdr *)nspp; 916 int ack; 917 u_int data_off = sizeof(struct minseghdr); 918 919 if (nsplen < data_off) 920 goto trunc; 921 ND_TCHECK(shp->sh_seq[0]); 922 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 923 if (ack & SGQ_ACK) { /* acknum field */ 924 if ((ack & SGQ_NAK) == SGQ_NAK) 925 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 926 else 927 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 928 data_off += sizeof(short); 929 if (nsplen < data_off) 930 goto trunc; 931 ND_TCHECK(shp->sh_seq[1]); 932 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 933 if (ack & SGQ_OACK) { /* ackdat field */ 934 if ((ack & SGQ_ONAK) == SGQ_ONAK) 935 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 936 else 937 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 938 data_off += sizeof(short); 939 if (nsplen < data_off) 940 goto trunc; 941 ND_TCHECK(shp->sh_seq[2]); 942 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 943 } 944 } 945 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 946 } 947 break; 948 case MFS_ILS: 949 ND_PRINT((ndo, "link-service %d>%d ", src, dst)); 950 { 951 const struct seghdr *shp = (const struct seghdr *)nspp; 952 const struct lsmsg *lsmp = 953 (const struct lsmsg *)&(nspp[sizeof(struct seghdr)]); 954 int ack; 955 int lsflags, fcval; 956 957 if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) 958 goto trunc; 959 ND_TCHECK(shp->sh_seq[0]); 960 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 961 if (ack & SGQ_ACK) { /* acknum field */ 962 if ((ack & SGQ_NAK) == SGQ_NAK) 963 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 964 else 965 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 966 ND_TCHECK(shp->sh_seq[1]); 967 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 968 if (ack & SGQ_OACK) { /* ackdat field */ 969 if ((ack & SGQ_ONAK) == SGQ_ONAK) 970 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 971 else 972 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 973 ND_TCHECK(shp->sh_seq[2]); 974 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 975 } 976 } 977 ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 978 ND_TCHECK(*lsmp); 979 lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); 980 fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); 981 switch (lsflags & LSI_MASK) { 982 case LSI_DATA: 983 ND_PRINT((ndo, "dat seg count %d ", fcval)); 984 switch (lsflags & LSM_MASK) { 985 case LSM_NOCHANGE: 986 break; 987 case LSM_DONOTSEND: 988 ND_PRINT((ndo, "donotsend-data ")); 989 break; 990 case LSM_SEND: 991 ND_PRINT((ndo, "send-data ")); 992 break; 993 default: 994 ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); 995 break; 996 } 997 break; 998 case LSI_INTR: 999 ND_PRINT((ndo, "intr req count %d ", fcval)); 1000 break; 1001 default: 1002 ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); 1003 break; 1004 } 1005 } 1006 break; 1007 default: 1008 ND_PRINT((ndo, "reserved-subtype? %x %d > %d", flags, src, dst)); 1009 break; 1010 } 1011 break; 1012 case MFT_ACK: 1013 switch (flags & NSP_SUBMASK) { 1014 case MFS_DACK: 1015 ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); 1016 { 1017 const struct ackmsg *amp = (const struct ackmsg *)nspp; 1018 int ack; 1019 1020 if (nsplen < sizeof(struct ackmsg)) 1021 goto trunc; 1022 ND_TCHECK(*amp); 1023 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 1024 if (ack & SGQ_ACK) { /* acknum field */ 1025 if ((ack & SGQ_NAK) == SGQ_NAK) 1026 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 1027 else 1028 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 1029 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 1030 if (ack & SGQ_OACK) { /* ackoth field */ 1031 if ((ack & SGQ_ONAK) == SGQ_ONAK) 1032 ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 1033 else 1034 ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 1035 } 1036 } 1037 } 1038 break; 1039 case MFS_IACK: 1040 ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); 1041 { 1042 const struct ackmsg *amp = (const struct ackmsg *)nspp; 1043 int ack; 1044 1045 if (nsplen < sizeof(struct ackmsg)) 1046 goto trunc; 1047 ND_TCHECK(*amp); 1048 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 1049 if (ack & SGQ_ACK) { /* acknum field */ 1050 if ((ack & SGQ_NAK) == SGQ_NAK) 1051 ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 1052 else 1053 ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 1054 ND_TCHECK(amp->ak_acknum[1]); 1055 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 1056 if (ack & SGQ_OACK) { /* ackdat field */ 1057 if ((ack & SGQ_ONAK) == SGQ_ONAK) 1058 ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 1059 else 1060 ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 1061 } 1062 } 1063 } 1064 break; 1065 case MFS_CACK: 1066 ND_PRINT((ndo, "conn-ack %d", dst)); 1067 break; 1068 default: 1069 ND_PRINT((ndo, "reserved-acktype? %x %d > %d", flags, src, dst)); 1070 break; 1071 } 1072 break; 1073 case MFT_CTL: 1074 switch (flags & NSP_SUBMASK) { 1075 case MFS_CI: 1076 case MFS_RCI: 1077 if ((flags & NSP_SUBMASK) == MFS_CI) 1078 ND_PRINT((ndo, "conn-initiate ")); 1079 else 1080 ND_PRINT((ndo, "retrans-conn-initiate ")); 1081 ND_PRINT((ndo, "%d>%d ", src, dst)); 1082 { 1083 const struct cimsg *cimp = (const struct cimsg *)nspp; 1084 int services, info, segsize; 1085 1086 if (nsplen < sizeof(struct cimsg)) 1087 goto trunc; 1088 ND_TCHECK(*cimp); 1089 services = EXTRACT_LE_8BITS(cimp->ci_services); 1090 info = EXTRACT_LE_8BITS(cimp->ci_info); 1091 segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); 1092 1093 switch (services & COS_MASK) { 1094 case COS_NONE: 1095 break; 1096 case COS_SEGMENT: 1097 ND_PRINT((ndo, "seg ")); 1098 break; 1099 case COS_MESSAGE: 1100 ND_PRINT((ndo, "msg ")); 1101 break; 1102 } 1103 switch (info & COI_MASK) { 1104 case COI_32: 1105 ND_PRINT((ndo, "ver 3.2 ")); 1106 break; 1107 case COI_31: 1108 ND_PRINT((ndo, "ver 3.1 ")); 1109 break; 1110 case COI_40: 1111 ND_PRINT((ndo, "ver 4.0 ")); 1112 break; 1113 case COI_41: 1114 ND_PRINT((ndo, "ver 4.1 ")); 1115 break; 1116 } 1117 ND_PRINT((ndo, "segsize %d ", segsize)); 1118 } 1119 break; 1120 case MFS_CC: 1121 ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); 1122 { 1123 const struct ccmsg *ccmp = (const struct ccmsg *)nspp; 1124 int services, info; 1125 u_int segsize, optlen; 1126 1127 if (nsplen < sizeof(struct ccmsg)) 1128 goto trunc; 1129 ND_TCHECK(*ccmp); 1130 services = EXTRACT_LE_8BITS(ccmp->cc_services); 1131 info = EXTRACT_LE_8BITS(ccmp->cc_info); 1132 segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); 1133 optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); 1134 1135 switch (services & COS_MASK) { 1136 case COS_NONE: 1137 break; 1138 case COS_SEGMENT: 1139 ND_PRINT((ndo, "seg ")); 1140 break; 1141 case COS_MESSAGE: 1142 ND_PRINT((ndo, "msg ")); 1143 break; 1144 } 1145 switch (info & COI_MASK) { 1146 case COI_32: 1147 ND_PRINT((ndo, "ver 3.2 ")); 1148 break; 1149 case COI_31: 1150 ND_PRINT((ndo, "ver 3.1 ")); 1151 break; 1152 case COI_40: 1153 ND_PRINT((ndo, "ver 4.0 ")); 1154 break; 1155 case COI_41: 1156 ND_PRINT((ndo, "ver 4.1 ")); 1157 break; 1158 } 1159 ND_PRINT((ndo, "segsize %d ", segsize)); 1160 if (optlen) { 1161 ND_PRINT((ndo, "optlen %d ", optlen)); 1162 } 1163 } 1164 break; 1165 case MFS_DI: 1166 ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); 1167 { 1168 const struct dimsg *dimp = (const struct dimsg *)nspp; 1169 int reason; 1170 u_int optlen; 1171 1172 if (nsplen < sizeof(struct dimsg)) 1173 goto trunc; 1174 ND_TCHECK(*dimp); 1175 reason = EXTRACT_LE_16BITS(dimp->di_reason); 1176 optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 1177 1178 print_reason(ndo, reason); 1179 if (optlen) { 1180 ND_PRINT((ndo, "optlen %d ", optlen)); 1181 } 1182 } 1183 break; 1184 case MFS_DC: 1185 ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); 1186 { 1187 const struct dcmsg *dcmp = (const struct dcmsg *)nspp; 1188 int reason; 1189 1190 ND_TCHECK(*dcmp); 1191 reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 1192 1193 print_reason(ndo, reason); 1194 } 1195 break; 1196 default: 1197 ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); 1198 break; 1199 } 1200 break; 1201 default: 1202 ND_PRINT((ndo, "reserved-type? %x %d > %d", flags, src, dst)); 1203 break; 1204 } 1205 return (1); 1206 1207 trunc: 1208 return (0); 1209 } 1210 1211 static const struct tok reason2str[] = { 1212 { UC_OBJREJECT, "object rejected connect" }, 1213 { UC_RESOURCES, "insufficient resources" }, 1214 { UC_NOSUCHNODE, "unrecognized node name" }, 1215 { DI_SHUT, "node is shutting down" }, 1216 { UC_NOSUCHOBJ, "unrecognized object" }, 1217 { UC_INVOBJFORMAT, "invalid object name format" }, 1218 { UC_OBJTOOBUSY, "object too busy" }, 1219 { DI_PROTOCOL, "protocol error discovered" }, 1220 { DI_TPA, "third party abort" }, 1221 { UC_USERABORT, "user abort" }, 1222 { UC_INVNODEFORMAT, "invalid node name format" }, 1223 { UC_LOCALSHUT, "local node shutting down" }, 1224 { DI_LOCALRESRC, "insufficient local resources" }, 1225 { DI_REMUSERRESRC, "insufficient remote user resources" }, 1226 { UC_ACCESSREJECT, "invalid access control information" }, 1227 { DI_BADACCNT, "bad ACCOUNT information" }, 1228 { UC_NORESPONSE, "no response from object" }, 1229 { UC_UNREACHABLE, "node unreachable" }, 1230 { DC_NOLINK, "no link terminate" }, 1231 { DC_COMPLETE, "disconnect complete" }, 1232 { DI_BADIMAGE, "bad image data in connect" }, 1233 { DI_SERVMISMATCH, "cryptographic service mismatch" }, 1234 { 0, NULL } 1235 }; 1236 1237 static void 1238 print_reason(netdissect_options *ndo, 1239 register int reason) 1240 { 1241 ND_PRINT((ndo, "%s ", tok2str(reason2str, "reason-%d", reason))); 1242 } 1243 1244 const char * 1245 dnnum_string(netdissect_options *ndo, u_short dnaddr) 1246 { 1247 char *str; 1248 size_t siz; 1249 int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; 1250 int node = dnaddr & NODEMASK; 1251 1252 str = (char *)malloc(siz = sizeof("00.0000")); 1253 if (str == NULL) 1254 (*ndo->ndo_error)(ndo, "dnnum_string: malloc"); 1255 snprintf(str, siz, "%d.%d", area, node); 1256 return(str); 1257 } 1258 1259 const char * 1260 dnname_string(netdissect_options *ndo, u_short dnaddr) 1261 { 1262 #ifdef HAVE_DNET_HTOA 1263 struct dn_naddr dna; 1264 char *dnname; 1265 1266 dna.a_len = sizeof(short); 1267 memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 1268 dnname = dnet_htoa(&dna); 1269 if(dnname != NULL) 1270 return (strdup(dnname)); 1271 else 1272 return(dnnum_string(ndo, dnaddr)); 1273 #else 1274 return(dnnum_string(ndo, dnaddr)); /* punt */ 1275 #endif 1276 } 1277