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