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