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