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