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