14edb46e9SPaul Traina /* 24644f044SBill Fenner * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 204edb46e9SPaul Traina */ 214edb46e9SPaul Traina 22*3c602fabSXin LI #define NETDISSECT_REWORKED 23b0453382SBill Fenner #ifdef HAVE_CONFIG_H 24b0453382SBill Fenner #include "config.h" 254edb46e9SPaul Traina #endif 264edb46e9SPaul Traina 275b0fe478SBruce M Simpson #include <tcpdump-stdinc.h> 284edb46e9SPaul Traina 294edb46e9SPaul Traina struct mbuf; 304edb46e9SPaul Traina struct rtentry; 314edb46e9SPaul Traina 325b0fe478SBruce M Simpson #ifdef HAVE_NETDNET_DNETDB_H 334edb46e9SPaul Traina #include <netdnet/dnetdb.h> 344edb46e9SPaul Traina #endif 354edb46e9SPaul Traina 364edb46e9SPaul Traina #include <stdio.h> 374edb46e9SPaul Traina #include <stdlib.h> 384edb46e9SPaul Traina #include <string.h> 394edb46e9SPaul Traina 404edb46e9SPaul Traina #include "extract.h" 414edb46e9SPaul Traina #include "interface.h" 424edb46e9SPaul Traina #include "addrtoname.h" 434edb46e9SPaul Traina 44*3c602fabSXin LI static const char tstr[] = "[|decnet]"; 45*3c602fabSXin LI 46*3c602fabSXin LI #ifndef WIN32 47*3c602fabSXin LI typedef uint8_t byte[1]; /* single byte field */ 48*3c602fabSXin LI #else 49*3c602fabSXin LI /* 50*3c602fabSXin LI * the keyword 'byte' generates conflicts in Windows 51*3c602fabSXin LI */ 52*3c602fabSXin LI typedef unsigned char Byte[1]; /* single byte field */ 53*3c602fabSXin LI #define byte Byte 54*3c602fabSXin LI #endif /* WIN32 */ 55*3c602fabSXin LI typedef uint8_t word[2]; /* 2 byte field */ 56*3c602fabSXin LI typedef uint8_t longword[4]; /* 4 bytes field */ 57*3c602fabSXin LI 58*3c602fabSXin LI /* 59*3c602fabSXin LI * Definitions for DECNET Phase IV protocol headers 60*3c602fabSXin LI */ 61*3c602fabSXin LI union etheraddress { 62*3c602fabSXin LI uint8_t dne_addr[6]; /* full ethernet address */ 63*3c602fabSXin LI struct { 64*3c602fabSXin LI uint8_t dne_hiord[4]; /* DECnet HIORD prefix */ 65*3c602fabSXin LI uint8_t dne_nodeaddr[2]; /* DECnet node address */ 66*3c602fabSXin LI } dne_remote; 67*3c602fabSXin LI }; 68*3c602fabSXin LI 69*3c602fabSXin LI typedef union etheraddress etheraddr; /* Ethernet address */ 70*3c602fabSXin LI 71*3c602fabSXin LI #define HIORD 0x000400aa /* high 32-bits of address (swapped) */ 72*3c602fabSXin LI 73*3c602fabSXin LI #define AREAMASK 0176000 /* mask for area field */ 74*3c602fabSXin LI #define AREASHIFT 10 /* bit-offset for area field */ 75*3c602fabSXin LI #define NODEMASK 01777 /* mask for node address field */ 76*3c602fabSXin LI 77*3c602fabSXin LI #define DN_MAXADDL 20 /* max size of DECnet address */ 78*3c602fabSXin LI struct dn_naddr { 79*3c602fabSXin LI uint16_t a_len; /* length of address */ 80*3c602fabSXin LI uint8_t a_addr[DN_MAXADDL]; /* address as bytes */ 81*3c602fabSXin LI }; 82*3c602fabSXin LI 83*3c602fabSXin LI /* 84*3c602fabSXin LI * Define long and short header formats. 85*3c602fabSXin LI */ 86*3c602fabSXin LI struct shorthdr 87*3c602fabSXin LI { 88*3c602fabSXin LI byte sh_flags; /* route flags */ 89*3c602fabSXin LI word sh_dst; /* destination node address */ 90*3c602fabSXin LI word sh_src; /* source node address */ 91*3c602fabSXin LI byte sh_visits; /* visit count */ 92*3c602fabSXin LI }; 93*3c602fabSXin LI 94*3c602fabSXin LI struct longhdr 95*3c602fabSXin LI { 96*3c602fabSXin LI byte lg_flags; /* route flags */ 97*3c602fabSXin LI byte lg_darea; /* destination area (reserved) */ 98*3c602fabSXin LI byte lg_dsarea; /* destination subarea (reserved) */ 99*3c602fabSXin LI etheraddr lg_dst; /* destination id */ 100*3c602fabSXin LI byte lg_sarea; /* source area (reserved) */ 101*3c602fabSXin LI byte lg_ssarea; /* source subarea (reserved) */ 102*3c602fabSXin LI etheraddr lg_src; /* source id */ 103*3c602fabSXin LI byte lg_nextl2; /* next level 2 router (reserved) */ 104*3c602fabSXin LI byte lg_visits; /* visit count */ 105*3c602fabSXin LI byte lg_service; /* service class (reserved) */ 106*3c602fabSXin LI byte lg_pt; /* protocol type (reserved) */ 107*3c602fabSXin LI }; 108*3c602fabSXin LI 109*3c602fabSXin LI union routehdr 110*3c602fabSXin LI { 111*3c602fabSXin LI struct shorthdr rh_short; /* short route header */ 112*3c602fabSXin LI struct longhdr rh_long; /* long route header */ 113*3c602fabSXin LI }; 114*3c602fabSXin LI 115*3c602fabSXin LI /* 116*3c602fabSXin LI * Define the values of various fields in the protocol messages. 117*3c602fabSXin LI * 118*3c602fabSXin LI * 1. Data packet formats. 119*3c602fabSXin LI */ 120*3c602fabSXin LI #define RMF_MASK 7 /* mask for message type */ 121*3c602fabSXin LI #define RMF_SHORT 2 /* short message format */ 122*3c602fabSXin LI #define RMF_LONG 6 /* long message format */ 123*3c602fabSXin LI #ifndef RMF_RQR 124*3c602fabSXin LI #define RMF_RQR 010 /* request return to sender */ 125*3c602fabSXin LI #define RMF_RTS 020 /* returning to sender */ 126*3c602fabSXin LI #define RMF_IE 040 /* intra-ethernet packet */ 127*3c602fabSXin LI #endif /* RMR_RQR */ 128*3c602fabSXin LI #define RMF_FVER 0100 /* future version flag */ 129*3c602fabSXin LI #define RMF_PAD 0200 /* pad field */ 130*3c602fabSXin LI #define RMF_PADMASK 0177 /* pad field mask */ 131*3c602fabSXin LI 132*3c602fabSXin LI #define VIS_MASK 077 /* visit field mask */ 133*3c602fabSXin LI 134*3c602fabSXin LI /* 135*3c602fabSXin LI * 2. Control packet formats. 136*3c602fabSXin LI */ 137*3c602fabSXin LI #define RMF_CTLMASK 017 /* mask for message type */ 138*3c602fabSXin LI #define RMF_CTLMSG 01 /* control message indicator */ 139*3c602fabSXin LI #define RMF_INIT 01 /* initialization message */ 140*3c602fabSXin LI #define RMF_VER 03 /* verification message */ 141*3c602fabSXin LI #define RMF_TEST 05 /* hello and test message */ 142*3c602fabSXin LI #define RMF_L1ROUT 07 /* level 1 routing message */ 143*3c602fabSXin LI #define RMF_L2ROUT 011 /* level 2 routing message */ 144*3c602fabSXin LI #define RMF_RHELLO 013 /* router hello message */ 145*3c602fabSXin LI #define RMF_EHELLO 015 /* endnode hello message */ 146*3c602fabSXin LI 147*3c602fabSXin LI #define TI_L2ROUT 01 /* level 2 router */ 148*3c602fabSXin LI #define TI_L1ROUT 02 /* level 1 router */ 149*3c602fabSXin LI #define TI_ENDNODE 03 /* endnode */ 150*3c602fabSXin LI #define TI_VERIF 04 /* verification required */ 151*3c602fabSXin LI #define TI_BLOCK 010 /* blocking requested */ 152*3c602fabSXin LI 153*3c602fabSXin LI #define VE_VERS 2 /* version number (2) */ 154*3c602fabSXin LI #define VE_ECO 0 /* ECO number */ 155*3c602fabSXin LI #define VE_UECO 0 /* user ECO number (0) */ 156*3c602fabSXin LI 157*3c602fabSXin LI #define P3_VERS 1 /* phase III version number (1) */ 158*3c602fabSXin LI #define P3_ECO 3 /* ECO number (3) */ 159*3c602fabSXin LI #define P3_UECO 0 /* user ECO number (0) */ 160*3c602fabSXin LI 161*3c602fabSXin LI #define II_L2ROUT 01 /* level 2 router */ 162*3c602fabSXin LI #define II_L1ROUT 02 /* level 1 router */ 163*3c602fabSXin LI #define II_ENDNODE 03 /* endnode */ 164*3c602fabSXin LI #define II_VERIF 04 /* verification required */ 165*3c602fabSXin LI #define II_NOMCAST 040 /* no multicast traffic accepted */ 166*3c602fabSXin LI #define II_BLOCK 0100 /* blocking requested */ 167*3c602fabSXin LI #define II_TYPEMASK 03 /* mask for node type */ 168*3c602fabSXin LI 169*3c602fabSXin LI #define TESTDATA 0252 /* test data bytes */ 170*3c602fabSXin LI #define TESTLEN 1 /* length of transmitted test data */ 171*3c602fabSXin LI 172*3c602fabSXin LI /* 173*3c602fabSXin LI * Define control message formats. 174*3c602fabSXin LI */ 175*3c602fabSXin LI struct initmsgIII /* phase III initialization message */ 176*3c602fabSXin LI { 177*3c602fabSXin LI byte inIII_flags; /* route flags */ 178*3c602fabSXin LI word inIII_src; /* source node address */ 179*3c602fabSXin LI byte inIII_info; /* routing layer information */ 180*3c602fabSXin LI word inIII_blksize; /* maximum data link block size */ 181*3c602fabSXin LI byte inIII_vers; /* version number */ 182*3c602fabSXin LI byte inIII_eco; /* ECO number */ 183*3c602fabSXin LI byte inIII_ueco; /* user ECO number */ 184*3c602fabSXin LI byte inIII_rsvd; /* reserved image field */ 185*3c602fabSXin LI }; 186*3c602fabSXin LI 187*3c602fabSXin LI struct initmsg /* initialization message */ 188*3c602fabSXin LI { 189*3c602fabSXin LI byte in_flags; /* route flags */ 190*3c602fabSXin LI word in_src; /* source node address */ 191*3c602fabSXin LI byte in_info; /* routing layer information */ 192*3c602fabSXin LI word in_blksize; /* maximum data link block size */ 193*3c602fabSXin LI byte in_vers; /* version number */ 194*3c602fabSXin LI byte in_eco; /* ECO number */ 195*3c602fabSXin LI byte in_ueco; /* user ECO number */ 196*3c602fabSXin LI word in_hello; /* hello timer */ 197*3c602fabSXin LI byte in_rsvd; /* reserved image field */ 198*3c602fabSXin LI }; 199*3c602fabSXin LI 200*3c602fabSXin LI struct verifmsg /* verification message */ 201*3c602fabSXin LI { 202*3c602fabSXin LI byte ve_flags; /* route flags */ 203*3c602fabSXin LI word ve_src; /* source node address */ 204*3c602fabSXin LI byte ve_fcnval; /* function value image field */ 205*3c602fabSXin LI }; 206*3c602fabSXin LI 207*3c602fabSXin LI struct testmsg /* hello and test message */ 208*3c602fabSXin LI { 209*3c602fabSXin LI byte te_flags; /* route flags */ 210*3c602fabSXin LI word te_src; /* source node address */ 211*3c602fabSXin LI byte te_data; /* test data image field */ 212*3c602fabSXin LI }; 213*3c602fabSXin LI 214*3c602fabSXin LI struct l1rout /* level 1 routing message */ 215*3c602fabSXin LI { 216*3c602fabSXin LI byte r1_flags; /* route flags */ 217*3c602fabSXin LI word r1_src; /* source node address */ 218*3c602fabSXin LI byte r1_rsvd; /* reserved field */ 219*3c602fabSXin LI }; 220*3c602fabSXin LI 221*3c602fabSXin LI struct l2rout /* level 2 routing message */ 222*3c602fabSXin LI { 223*3c602fabSXin LI byte r2_flags; /* route flags */ 224*3c602fabSXin LI word r2_src; /* source node address */ 225*3c602fabSXin LI byte r2_rsvd; /* reserved field */ 226*3c602fabSXin LI }; 227*3c602fabSXin LI 228*3c602fabSXin LI struct rhellomsg /* router hello message */ 229*3c602fabSXin LI { 230*3c602fabSXin LI byte rh_flags; /* route flags */ 231*3c602fabSXin LI byte rh_vers; /* version number */ 232*3c602fabSXin LI byte rh_eco; /* ECO number */ 233*3c602fabSXin LI byte rh_ueco; /* user ECO number */ 234*3c602fabSXin LI etheraddr rh_src; /* source id */ 235*3c602fabSXin LI byte rh_info; /* routing layer information */ 236*3c602fabSXin LI word rh_blksize; /* maximum data link block size */ 237*3c602fabSXin LI byte rh_priority; /* router's priority */ 238*3c602fabSXin LI byte rh_area; /* reserved */ 239*3c602fabSXin LI word rh_hello; /* hello timer */ 240*3c602fabSXin LI byte rh_mpd; /* reserved */ 241*3c602fabSXin LI }; 242*3c602fabSXin LI 243*3c602fabSXin LI struct ehellomsg /* endnode hello message */ 244*3c602fabSXin LI { 245*3c602fabSXin LI byte eh_flags; /* route flags */ 246*3c602fabSXin LI byte eh_vers; /* version number */ 247*3c602fabSXin LI byte eh_eco; /* ECO number */ 248*3c602fabSXin LI byte eh_ueco; /* user ECO number */ 249*3c602fabSXin LI etheraddr eh_src; /* source id */ 250*3c602fabSXin LI byte eh_info; /* routing layer information */ 251*3c602fabSXin LI word eh_blksize; /* maximum data link block size */ 252*3c602fabSXin LI byte eh_area; /* area (reserved) */ 253*3c602fabSXin LI byte eh_seed[8]; /* verification seed */ 254*3c602fabSXin LI etheraddr eh_router; /* designated router */ 255*3c602fabSXin LI word eh_hello; /* hello timer */ 256*3c602fabSXin LI byte eh_mpd; /* (reserved) */ 257*3c602fabSXin LI byte eh_data; /* test data image field */ 258*3c602fabSXin LI }; 259*3c602fabSXin LI 260*3c602fabSXin LI union controlmsg 261*3c602fabSXin LI { 262*3c602fabSXin LI struct initmsg cm_init; /* initialization message */ 263*3c602fabSXin LI struct verifmsg cm_ver; /* verification message */ 264*3c602fabSXin LI struct testmsg cm_test; /* hello and test message */ 265*3c602fabSXin LI struct l1rout cm_l1rou; /* level 1 routing message */ 266*3c602fabSXin LI struct l2rout cm_l2rout; /* level 2 routing message */ 267*3c602fabSXin LI struct rhellomsg cm_rhello; /* router hello message */ 268*3c602fabSXin LI struct ehellomsg cm_ehello; /* endnode hello message */ 269*3c602fabSXin LI }; 270*3c602fabSXin LI 271*3c602fabSXin LI /* Macros for decoding routing-info fields */ 272*3c602fabSXin LI #define RI_COST(x) ((x)&0777) 273*3c602fabSXin LI #define RI_HOPS(x) (((x)>>10)&037) 274*3c602fabSXin LI 275*3c602fabSXin LI /* 276*3c602fabSXin LI * NSP protocol fields and values. 277*3c602fabSXin LI */ 278*3c602fabSXin LI 279*3c602fabSXin LI #define NSP_TYPEMASK 014 /* mask to isolate type code */ 280*3c602fabSXin LI #define NSP_SUBMASK 0160 /* mask to isolate subtype code */ 281*3c602fabSXin LI #define NSP_SUBSHFT 4 /* shift to move subtype code */ 282*3c602fabSXin LI 283*3c602fabSXin LI #define MFT_DATA 0 /* data message */ 284*3c602fabSXin LI #define MFT_ACK 04 /* acknowledgement message */ 285*3c602fabSXin LI #define MFT_CTL 010 /* control message */ 286*3c602fabSXin LI 287*3c602fabSXin LI #define MFS_ILS 020 /* data or I/LS indicator */ 288*3c602fabSXin LI #define MFS_BOM 040 /* beginning of message (data) */ 289*3c602fabSXin LI #define MFS_MOM 0 /* middle of message (data) */ 290*3c602fabSXin LI #define MFS_EOM 0100 /* end of message (data) */ 291*3c602fabSXin LI #define MFS_INT 040 /* interrupt message */ 292*3c602fabSXin LI 293*3c602fabSXin LI #define MFS_DACK 0 /* data acknowledgement */ 294*3c602fabSXin LI #define MFS_IACK 020 /* I/LS acknowledgement */ 295*3c602fabSXin LI #define MFS_CACK 040 /* connect acknowledgement */ 296*3c602fabSXin LI 297*3c602fabSXin LI #define MFS_NOP 0 /* no operation */ 298*3c602fabSXin LI #define MFS_CI 020 /* connect initiate */ 299*3c602fabSXin LI #define MFS_CC 040 /* connect confirm */ 300*3c602fabSXin LI #define MFS_DI 060 /* disconnect initiate */ 301*3c602fabSXin LI #define MFS_DC 0100 /* disconnect confirm */ 302*3c602fabSXin LI #define MFS_RCI 0140 /* retransmitted connect initiate */ 303*3c602fabSXin LI 304*3c602fabSXin LI #define SGQ_ACK 0100000 /* ack */ 305*3c602fabSXin LI #define SGQ_NAK 0110000 /* negative ack */ 306*3c602fabSXin LI #define SGQ_OACK 0120000 /* other channel ack */ 307*3c602fabSXin LI #define SGQ_ONAK 0130000 /* other channel negative ack */ 308*3c602fabSXin LI #define SGQ_MASK 07777 /* mask to isolate seq # */ 309*3c602fabSXin LI #define SGQ_OTHER 020000 /* other channel qualifier */ 310*3c602fabSXin LI #define SGQ_DELAY 010000 /* ack delay flag */ 311*3c602fabSXin LI 312*3c602fabSXin LI #define SGQ_EOM 0100000 /* pseudo flag for end-of-message */ 313*3c602fabSXin LI 314*3c602fabSXin LI #define LSM_MASK 03 /* mask for modifier field */ 315*3c602fabSXin LI #define LSM_NOCHANGE 0 /* no change */ 316*3c602fabSXin LI #define LSM_DONOTSEND 1 /* do not send data */ 317*3c602fabSXin LI #define LSM_SEND 2 /* send data */ 318*3c602fabSXin LI 319*3c602fabSXin LI #define LSI_MASK 014 /* mask for interpretation field */ 320*3c602fabSXin LI #define LSI_DATA 0 /* data segment or message count */ 321*3c602fabSXin LI #define LSI_INTR 4 /* interrupt request count */ 322*3c602fabSXin LI #define LSI_INTM 0377 /* funny marker for int. message */ 323*3c602fabSXin LI 324*3c602fabSXin LI #define COS_MASK 014 /* mask for flow control field */ 325*3c602fabSXin LI #define COS_NONE 0 /* no flow control */ 326*3c602fabSXin LI #define COS_SEGMENT 04 /* segment flow control */ 327*3c602fabSXin LI #define COS_MESSAGE 010 /* message flow control */ 328*3c602fabSXin LI #define COS_CRYPTSER 020 /* cryptographic services requested */ 329*3c602fabSXin LI #define COS_DEFAULT 1 /* default value for field */ 330*3c602fabSXin LI 331*3c602fabSXin LI #define COI_MASK 3 /* mask for version field */ 332*3c602fabSXin LI #define COI_32 0 /* version 3.2 */ 333*3c602fabSXin LI #define COI_31 1 /* version 3.1 */ 334*3c602fabSXin LI #define COI_40 2 /* version 4.0 */ 335*3c602fabSXin LI #define COI_41 3 /* version 4.1 */ 336*3c602fabSXin LI 337*3c602fabSXin LI #define MNU_MASK 140 /* mask for session control version */ 338*3c602fabSXin LI #define MNU_10 000 /* session V1.0 */ 339*3c602fabSXin LI #define MNU_20 040 /* session V2.0 */ 340*3c602fabSXin LI #define MNU_ACCESS 1 /* access control present */ 341*3c602fabSXin LI #define MNU_USRDATA 2 /* user data field present */ 342*3c602fabSXin LI #define MNU_INVKPROXY 4 /* invoke proxy field present */ 343*3c602fabSXin LI #define MNU_UICPROXY 8 /* use uic-based proxy */ 344*3c602fabSXin LI 345*3c602fabSXin LI #define DC_NORESOURCES 1 /* no resource reason code */ 346*3c602fabSXin LI #define DC_NOLINK 41 /* no link terminate reason code */ 347*3c602fabSXin LI #define DC_COMPLETE 42 /* disconnect complete reason code */ 348*3c602fabSXin LI 349*3c602fabSXin LI #define DI_NOERROR 0 /* user disconnect */ 350*3c602fabSXin LI #define DI_SHUT 3 /* node is shutting down */ 351*3c602fabSXin LI #define DI_NOUSER 4 /* destination end user does not exist */ 352*3c602fabSXin LI #define DI_INVDEST 5 /* invalid end user destination */ 353*3c602fabSXin LI #define DI_REMRESRC 6 /* insufficient remote resources */ 354*3c602fabSXin LI #define DI_TPA 8 /* third party abort */ 355*3c602fabSXin LI #define DI_PROTOCOL 7 /* protocol error discovered */ 356*3c602fabSXin LI #define DI_ABORT 9 /* user abort */ 357*3c602fabSXin LI #define DI_LOCALRESRC 32 /* insufficient local resources */ 358*3c602fabSXin LI #define DI_REMUSERRESRC 33 /* insufficient remote user resources */ 359*3c602fabSXin LI #define DI_BADACCESS 34 /* bad access control information */ 360*3c602fabSXin LI #define DI_BADACCNT 36 /* bad ACCOUNT information */ 361*3c602fabSXin LI #define DI_CONNECTABORT 38 /* connect request cancelled */ 362*3c602fabSXin LI #define DI_TIMEDOUT 38 /* remote node or user crashed */ 363*3c602fabSXin LI #define DI_UNREACHABLE 39 /* local timers expired due to ... */ 364*3c602fabSXin LI #define DI_BADIMAGE 43 /* bad image data in connect */ 365*3c602fabSXin LI #define DI_SERVMISMATCH 54 /* cryptographic service mismatch */ 366*3c602fabSXin LI 367*3c602fabSXin LI #define UC_OBJREJECT 0 /* object rejected connect */ 368*3c602fabSXin LI #define UC_USERDISCONNECT 0 /* user disconnect */ 369*3c602fabSXin LI #define UC_RESOURCES 1 /* insufficient resources (local or remote) */ 370*3c602fabSXin LI #define UC_NOSUCHNODE 2 /* unrecognized node name */ 371*3c602fabSXin LI #define UC_REMOTESHUT 3 /* remote node shutting down */ 372*3c602fabSXin LI #define UC_NOSUCHOBJ 4 /* unrecognized object */ 373*3c602fabSXin LI #define UC_INVOBJFORMAT 5 /* invalid object name format */ 374*3c602fabSXin LI #define UC_OBJTOOBUSY 6 /* object too busy */ 375*3c602fabSXin LI #define UC_NETWORKABORT 8 /* network abort */ 376*3c602fabSXin LI #define UC_USERABORT 9 /* user abort */ 377*3c602fabSXin LI #define UC_INVNODEFORMAT 10 /* invalid node name format */ 378*3c602fabSXin LI #define UC_LOCALSHUT 11 /* local node shutting down */ 379*3c602fabSXin LI #define UC_ACCESSREJECT 34 /* invalid access control information */ 380*3c602fabSXin LI #define UC_NORESPONSE 38 /* no response from object */ 381*3c602fabSXin LI #define UC_UNREACHABLE 39 /* node unreachable */ 382*3c602fabSXin LI 383*3c602fabSXin LI /* 384*3c602fabSXin LI * NSP message formats. 385*3c602fabSXin LI */ 386*3c602fabSXin LI struct nsphdr /* general nsp header */ 387*3c602fabSXin LI { 388*3c602fabSXin LI byte nh_flags; /* message flags */ 389*3c602fabSXin LI word nh_dst; /* destination link address */ 390*3c602fabSXin LI word nh_src; /* source link address */ 391*3c602fabSXin LI }; 392*3c602fabSXin LI 393*3c602fabSXin LI struct seghdr /* data segment header */ 394*3c602fabSXin LI { 395*3c602fabSXin LI byte sh_flags; /* message flags */ 396*3c602fabSXin LI word sh_dst; /* destination link address */ 397*3c602fabSXin LI word sh_src; /* source link address */ 398*3c602fabSXin LI word sh_seq[3]; /* sequence numbers */ 399*3c602fabSXin LI }; 400*3c602fabSXin LI 401*3c602fabSXin LI struct minseghdr /* minimum data segment header */ 402*3c602fabSXin LI { 403*3c602fabSXin LI byte ms_flags; /* message flags */ 404*3c602fabSXin LI word ms_dst; /* destination link address */ 405*3c602fabSXin LI word ms_src; /* source link address */ 406*3c602fabSXin LI word ms_seq; /* sequence number */ 407*3c602fabSXin LI }; 408*3c602fabSXin LI 409*3c602fabSXin LI struct lsmsg /* link service message (after hdr) */ 410*3c602fabSXin LI { 411*3c602fabSXin LI byte ls_lsflags; /* link service flags */ 412*3c602fabSXin LI byte ls_fcval; /* flow control value */ 413*3c602fabSXin LI }; 414*3c602fabSXin LI 415*3c602fabSXin LI struct ackmsg /* acknowledgement message */ 416*3c602fabSXin LI { 417*3c602fabSXin LI byte ak_flags; /* message flags */ 418*3c602fabSXin LI word ak_dst; /* destination link address */ 419*3c602fabSXin LI word ak_src; /* source link address */ 420*3c602fabSXin LI word ak_acknum[2]; /* acknowledgement numbers */ 421*3c602fabSXin LI }; 422*3c602fabSXin LI 423*3c602fabSXin LI struct minackmsg /* minimum acknowledgement message */ 424*3c602fabSXin LI { 425*3c602fabSXin LI byte mk_flags; /* message flags */ 426*3c602fabSXin LI word mk_dst; /* destination link address */ 427*3c602fabSXin LI word mk_src; /* source link address */ 428*3c602fabSXin LI word mk_acknum; /* acknowledgement number */ 429*3c602fabSXin LI }; 430*3c602fabSXin LI 431*3c602fabSXin LI struct ciackmsg /* connect acknowledgement message */ 432*3c602fabSXin LI { 433*3c602fabSXin LI byte ck_flags; /* message flags */ 434*3c602fabSXin LI word ck_dst; /* destination link address */ 435*3c602fabSXin LI }; 436*3c602fabSXin LI 437*3c602fabSXin LI struct cimsg /* connect initiate message */ 438*3c602fabSXin LI { 439*3c602fabSXin LI byte ci_flags; /* message flags */ 440*3c602fabSXin LI word ci_dst; /* destination link address (0) */ 441*3c602fabSXin LI word ci_src; /* source link address */ 442*3c602fabSXin LI byte ci_services; /* requested services */ 443*3c602fabSXin LI byte ci_info; /* information */ 444*3c602fabSXin LI word ci_segsize; /* maximum segment size */ 445*3c602fabSXin LI }; 446*3c602fabSXin LI 447*3c602fabSXin LI struct ccmsg /* connect confirm message */ 448*3c602fabSXin LI { 449*3c602fabSXin LI byte cc_flags; /* message flags */ 450*3c602fabSXin LI word cc_dst; /* destination link address */ 451*3c602fabSXin LI word cc_src; /* source link address */ 452*3c602fabSXin LI byte cc_services; /* requested services */ 453*3c602fabSXin LI byte cc_info; /* information */ 454*3c602fabSXin LI word cc_segsize; /* maximum segment size */ 455*3c602fabSXin LI byte cc_optlen; /* optional data length */ 456*3c602fabSXin LI }; 457*3c602fabSXin LI 458*3c602fabSXin LI struct cnmsg /* generic connect message */ 459*3c602fabSXin LI { 460*3c602fabSXin LI byte cn_flags; /* message flags */ 461*3c602fabSXin LI word cn_dst; /* destination link address */ 462*3c602fabSXin LI word cn_src; /* source link address */ 463*3c602fabSXin LI byte cn_services; /* requested services */ 464*3c602fabSXin LI byte cn_info; /* information */ 465*3c602fabSXin LI word cn_segsize; /* maximum segment size */ 466*3c602fabSXin LI }; 467*3c602fabSXin LI 468*3c602fabSXin LI struct dimsg /* disconnect initiate message */ 469*3c602fabSXin LI { 470*3c602fabSXin LI byte di_flags; /* message flags */ 471*3c602fabSXin LI word di_dst; /* destination link address */ 472*3c602fabSXin LI word di_src; /* source link address */ 473*3c602fabSXin LI word di_reason; /* reason code */ 474*3c602fabSXin LI byte di_optlen; /* optional data length */ 475*3c602fabSXin LI }; 476*3c602fabSXin LI 477*3c602fabSXin LI struct dcmsg /* disconnect confirm message */ 478*3c602fabSXin LI { 479*3c602fabSXin LI byte dc_flags; /* message flags */ 480*3c602fabSXin LI word dc_dst; /* destination link address */ 481*3c602fabSXin LI word dc_src; /* source link address */ 482*3c602fabSXin LI word dc_reason; /* reason code */ 483*3c602fabSXin LI }; 484*3c602fabSXin LI 4854edb46e9SPaul Traina /* Forwards */ 486*3c602fabSXin LI static int print_decnet_ctlmsg(netdissect_options *, const union routehdr *, u_int, u_int); 487*3c602fabSXin LI static void print_t_info(netdissect_options *, int); 488*3c602fabSXin LI static int print_l1_routes(netdissect_options *, const char *, u_int); 489*3c602fabSXin LI static int print_l2_routes(netdissect_options *, const char *, u_int); 490*3c602fabSXin LI static void print_i_info(netdissect_options *, int); 491f4d0c64aSSam Leffler static int print_elist(const char *, u_int); 492*3c602fabSXin LI static int print_nsp(netdissect_options *, const u_char *, u_int); 493*3c602fabSXin LI static void print_reason(netdissect_options *, int); 4944edb46e9SPaul Traina #ifdef PRINT_NSPDATA 495*3c602fabSXin LI static void pdata(netdissect_options *, u_char *, u_int); 4964edb46e9SPaul Traina #endif 4974edb46e9SPaul Traina 4985b0fe478SBruce M Simpson #ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA 4994edb46e9SPaul Traina extern char *dnet_htoa(struct dn_naddr *); 5004edb46e9SPaul Traina #endif 5014edb46e9SPaul Traina 5024edb46e9SPaul Traina void 503*3c602fabSXin LI decnet_print(netdissect_options *ndo, 504*3c602fabSXin LI register const u_char *ap, register u_int length, 5054edb46e9SPaul Traina register u_int caplen) 5064edb46e9SPaul Traina { 507f4d0c64aSSam Leffler register const union routehdr *rhp; 5084edb46e9SPaul Traina register int mflags; 5094edb46e9SPaul Traina int dst, src, hops; 510f4d0c64aSSam Leffler u_int nsplen, pktlen; 5114edb46e9SPaul Traina const u_char *nspp; 5124edb46e9SPaul Traina 5134edb46e9SPaul Traina if (length < sizeof(struct shorthdr)) { 514*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 5154edb46e9SPaul Traina return; 5164edb46e9SPaul Traina } 5174edb46e9SPaul Traina 518*3c602fabSXin LI ND_TCHECK2(*ap, sizeof(short)); 5194edb46e9SPaul Traina pktlen = EXTRACT_LE_16BITS(ap); 520f4d0c64aSSam Leffler if (pktlen < sizeof(struct shorthdr)) { 521*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 522f4d0c64aSSam Leffler return; 523f4d0c64aSSam Leffler } 524f4d0c64aSSam Leffler if (pktlen > length) { 525*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 526f4d0c64aSSam Leffler return; 527f4d0c64aSSam Leffler } 528f4d0c64aSSam Leffler length = pktlen; 5294edb46e9SPaul Traina 530f4d0c64aSSam Leffler rhp = (const union routehdr *)&(ap[sizeof(short)]); 531*3c602fabSXin LI ND_TCHECK(rhp->rh_short.sh_flags); 5324edb46e9SPaul Traina mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 5334edb46e9SPaul Traina 5344edb46e9SPaul Traina if (mflags & RMF_PAD) { 5354edb46e9SPaul Traina /* pad bytes of some sort in front of message */ 5364edb46e9SPaul Traina u_int padlen = mflags & RMF_PADMASK; 537*3c602fabSXin LI if (ndo->ndo_vflag) 538*3c602fabSXin LI ND_PRINT((ndo, "[pad:%d] ", padlen)); 539f4d0c64aSSam Leffler if (length < padlen + 2) { 540*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 541f4d0c64aSSam Leffler return; 542f4d0c64aSSam Leffler } 543*3c602fabSXin LI ND_TCHECK2(ap[sizeof(short)], padlen); 5444edb46e9SPaul Traina ap += padlen; 5454edb46e9SPaul Traina length -= padlen; 5464edb46e9SPaul Traina caplen -= padlen; 547f4d0c64aSSam Leffler rhp = (const union routehdr *)&(ap[sizeof(short)]); 5484edb46e9SPaul Traina mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 5494edb46e9SPaul Traina } 5504edb46e9SPaul Traina 5514edb46e9SPaul Traina if (mflags & RMF_FVER) { 552*3c602fabSXin LI ND_PRINT((ndo, "future-version-decnet")); 553*3c602fabSXin LI ND_DEFAULTPRINT(ap, min(length, caplen)); 5544edb46e9SPaul Traina return; 5554edb46e9SPaul Traina } 5564edb46e9SPaul Traina 5574edb46e9SPaul Traina /* is it a control message? */ 5584edb46e9SPaul Traina if (mflags & RMF_CTLMSG) { 559*3c602fabSXin LI if (!print_decnet_ctlmsg(ndo, rhp, length, caplen)) 560f4d0c64aSSam Leffler goto trunc; 5614edb46e9SPaul Traina return; 5624edb46e9SPaul Traina } 5634edb46e9SPaul Traina 5644edb46e9SPaul Traina switch (mflags & RMF_MASK) { 5654edb46e9SPaul Traina case RMF_LONG: 566f4d0c64aSSam Leffler if (length < sizeof(struct longhdr)) { 567*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 568f4d0c64aSSam Leffler return; 569f4d0c64aSSam Leffler } 570*3c602fabSXin LI ND_TCHECK(rhp->rh_long); 5714edb46e9SPaul Traina dst = 5724edb46e9SPaul Traina EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); 5734edb46e9SPaul Traina src = 5744edb46e9SPaul Traina EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); 5754edb46e9SPaul Traina hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); 5764edb46e9SPaul Traina nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); 577f4d0c64aSSam Leffler nsplen = length - sizeof(struct longhdr); 5784edb46e9SPaul Traina break; 5794edb46e9SPaul Traina case RMF_SHORT: 580*3c602fabSXin LI ND_TCHECK(rhp->rh_short); 5814edb46e9SPaul Traina dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); 5824edb46e9SPaul Traina src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); 5834edb46e9SPaul Traina hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; 5844edb46e9SPaul Traina nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); 585f4d0c64aSSam Leffler nsplen = length - sizeof(struct shorthdr); 5864edb46e9SPaul Traina break; 5874edb46e9SPaul Traina default: 588*3c602fabSXin LI ND_PRINT((ndo, "unknown message flags under mask")); 589*3c602fabSXin LI ND_DEFAULTPRINT((u_char *)ap, min(length, caplen)); 5904edb46e9SPaul Traina return; 5914edb46e9SPaul Traina } 5924edb46e9SPaul Traina 593*3c602fabSXin LI ND_PRINT((ndo, "%s > %s %d ", 594*3c602fabSXin LI dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); 595*3c602fabSXin LI if (ndo->ndo_vflag) { 5964edb46e9SPaul Traina if (mflags & RMF_RQR) 597*3c602fabSXin LI ND_PRINT((ndo, "RQR ")); 5984edb46e9SPaul Traina if (mflags & RMF_RTS) 599*3c602fabSXin LI ND_PRINT((ndo, "RTS ")); 6004edb46e9SPaul Traina if (mflags & RMF_IE) 601*3c602fabSXin LI ND_PRINT((ndo, "IE ")); 602*3c602fabSXin LI ND_PRINT((ndo, "%d hops ", hops)); 6034edb46e9SPaul Traina } 6044edb46e9SPaul Traina 605*3c602fabSXin LI if (!print_nsp(ndo, nspp, nsplen)) 606f4d0c64aSSam Leffler goto trunc; 607f4d0c64aSSam Leffler return; 608f4d0c64aSSam Leffler 609f4d0c64aSSam Leffler trunc: 610*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 611f4d0c64aSSam Leffler return; 6124edb46e9SPaul Traina } 6134edb46e9SPaul Traina 614f4d0c64aSSam Leffler static int 615*3c602fabSXin LI print_decnet_ctlmsg(netdissect_options *ndo, 616*3c602fabSXin LI register const union routehdr *rhp, u_int length, 617f4d0c64aSSam Leffler u_int caplen) 6184edb46e9SPaul Traina { 6194edb46e9SPaul Traina int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 6204edb46e9SPaul Traina register union controlmsg *cmp = (union controlmsg *)rhp; 6214edb46e9SPaul Traina int src, dst, info, blksize, eco, ueco, hello, other, vers; 6224edb46e9SPaul Traina etheraddr srcea, rtea; 6234edb46e9SPaul Traina int priority; 6244edb46e9SPaul Traina char *rhpx = (char *)rhp; 625f4d0c64aSSam Leffler int ret; 6264edb46e9SPaul Traina 6274edb46e9SPaul Traina switch (mflags & RMF_CTLMASK) { 6284edb46e9SPaul Traina case RMF_INIT: 629*3c602fabSXin LI ND_PRINT((ndo, "init ")); 630f4d0c64aSSam Leffler if (length < sizeof(struct initmsg)) 631f4d0c64aSSam Leffler goto trunc; 632*3c602fabSXin LI ND_TCHECK(cmp->cm_init); 6334edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); 6344edb46e9SPaul Traina info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); 6354edb46e9SPaul Traina blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); 6364edb46e9SPaul Traina vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); 6374edb46e9SPaul Traina eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); 6384edb46e9SPaul Traina ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); 6394edb46e9SPaul Traina hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); 640*3c602fabSXin LI print_t_info(ndo, info); 641*3c602fabSXin LI ND_PRINT((ndo, 6424edb46e9SPaul Traina "src %sblksize %d vers %d eco %d ueco %d hello %d", 643*3c602fabSXin LI dnaddr_string(ndo, src), blksize, vers, eco, ueco, 644*3c602fabSXin LI hello)); 645f4d0c64aSSam Leffler ret = 1; 6464edb46e9SPaul Traina break; 6474edb46e9SPaul Traina case RMF_VER: 648*3c602fabSXin LI ND_PRINT((ndo, "verification ")); 649f4d0c64aSSam Leffler if (length < sizeof(struct verifmsg)) 650f4d0c64aSSam Leffler goto trunc; 651*3c602fabSXin LI ND_TCHECK(cmp->cm_ver); 6524edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); 6534edb46e9SPaul Traina other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); 654*3c602fabSXin LI ND_PRINT((ndo, "src %s fcnval %o", dnaddr_string(ndo, src), other)); 655f4d0c64aSSam Leffler ret = 1; 6564edb46e9SPaul Traina break; 6574edb46e9SPaul Traina case RMF_TEST: 658*3c602fabSXin LI ND_PRINT((ndo, "test ")); 659f4d0c64aSSam Leffler if (length < sizeof(struct testmsg)) 660f4d0c64aSSam Leffler goto trunc; 661*3c602fabSXin LI ND_TCHECK(cmp->cm_test); 6624edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); 6634edb46e9SPaul Traina other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); 664*3c602fabSXin LI ND_PRINT((ndo, "src %s data %o", dnaddr_string(ndo, src), other)); 665f4d0c64aSSam Leffler ret = 1; 6664edb46e9SPaul Traina break; 6674edb46e9SPaul Traina case RMF_L1ROUT: 668*3c602fabSXin LI ND_PRINT((ndo, "lev-1-routing ")); 669f4d0c64aSSam Leffler if (length < sizeof(struct l1rout)) 670f4d0c64aSSam Leffler goto trunc; 671*3c602fabSXin LI ND_TCHECK(cmp->cm_l1rou); 6724edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 673*3c602fabSXin LI ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 674*3c602fabSXin LI ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), 6754edb46e9SPaul Traina length - sizeof(struct l1rout)); 6764edb46e9SPaul Traina break; 6774edb46e9SPaul Traina case RMF_L2ROUT: 678*3c602fabSXin LI ND_PRINT((ndo, "lev-2-routing ")); 679f4d0c64aSSam Leffler if (length < sizeof(struct l2rout)) 680f4d0c64aSSam Leffler goto trunc; 681*3c602fabSXin LI ND_TCHECK(cmp->cm_l2rout); 6824edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 683*3c602fabSXin LI ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 684*3c602fabSXin LI ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), 6854edb46e9SPaul Traina length - sizeof(struct l2rout)); 6864edb46e9SPaul Traina break; 6874edb46e9SPaul Traina case RMF_RHELLO: 688*3c602fabSXin LI ND_PRINT((ndo, "router-hello ")); 689f4d0c64aSSam Leffler if (length < sizeof(struct rhellomsg)) 690f4d0c64aSSam Leffler goto trunc; 691*3c602fabSXin LI ND_TCHECK(cmp->cm_rhello); 6924edb46e9SPaul Traina vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); 6934edb46e9SPaul Traina eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); 6944edb46e9SPaul Traina ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); 6954edb46e9SPaul Traina memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), 6964edb46e9SPaul Traina sizeof(srcea)); 6974edb46e9SPaul Traina src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 6984edb46e9SPaul Traina info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); 6994edb46e9SPaul Traina blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); 7004edb46e9SPaul Traina priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); 7014edb46e9SPaul Traina hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); 702*3c602fabSXin LI print_i_info(ndo, info); 703*3c602fabSXin LI ND_PRINT((ndo, 7044edb46e9SPaul Traina "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 705*3c602fabSXin LI vers, eco, ueco, dnaddr_string(ndo, src), 706*3c602fabSXin LI blksize, priority, hello)); 707f4d0c64aSSam Leffler ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), 7084edb46e9SPaul Traina length - sizeof(struct rhellomsg)); 7094edb46e9SPaul Traina break; 7104edb46e9SPaul Traina case RMF_EHELLO: 711*3c602fabSXin LI ND_PRINT((ndo, "endnode-hello ")); 712f4d0c64aSSam Leffler if (length < sizeof(struct ehellomsg)) 713f4d0c64aSSam Leffler goto trunc; 714*3c602fabSXin LI ND_TCHECK(cmp->cm_ehello); 7154edb46e9SPaul Traina vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); 7164edb46e9SPaul Traina eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); 7174edb46e9SPaul Traina ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); 7184edb46e9SPaul Traina memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), 7194edb46e9SPaul Traina sizeof(srcea)); 7204edb46e9SPaul Traina src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 7214edb46e9SPaul Traina info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); 7224edb46e9SPaul Traina blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); 7234edb46e9SPaul Traina /*seed*/ 7244edb46e9SPaul Traina memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), 7254edb46e9SPaul Traina sizeof(rtea)); 7264edb46e9SPaul Traina dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); 7274edb46e9SPaul Traina hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); 7284edb46e9SPaul Traina other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); 729*3c602fabSXin LI print_i_info(ndo, info); 730*3c602fabSXin LI ND_PRINT((ndo, 7314edb46e9SPaul Traina "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 732*3c602fabSXin LI vers, eco, ueco, dnaddr_string(ndo, src), 733*3c602fabSXin LI blksize, dnaddr_string(ndo, dst), hello, other)); 734f4d0c64aSSam Leffler ret = 1; 7354edb46e9SPaul Traina break; 7364edb46e9SPaul Traina 7374edb46e9SPaul Traina default: 738*3c602fabSXin LI ND_PRINT((ndo, "unknown control message")); 739*3c602fabSXin LI ND_DEFAULTPRINT((u_char *)rhp, min(length, caplen)); 740f4d0c64aSSam Leffler ret = 1; 7414edb46e9SPaul Traina break; 7424edb46e9SPaul Traina } 743f4d0c64aSSam Leffler return (ret); 744f4d0c64aSSam Leffler 745f4d0c64aSSam Leffler trunc: 746f4d0c64aSSam Leffler return (0); 7474edb46e9SPaul Traina } 7484edb46e9SPaul Traina 7494edb46e9SPaul Traina static void 750*3c602fabSXin LI print_t_info(netdissect_options *ndo, 751*3c602fabSXin LI int info) 7524edb46e9SPaul Traina { 7534edb46e9SPaul Traina int ntype = info & 3; 7544edb46e9SPaul Traina switch (ntype) { 755*3c602fabSXin LI case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 756*3c602fabSXin LI case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 757*3c602fabSXin LI case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 758*3c602fabSXin LI case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 7594edb46e9SPaul Traina } 7604edb46e9SPaul Traina if (info & TI_VERIF) 761*3c602fabSXin LI ND_PRINT((ndo, "verif ")); 7624edb46e9SPaul Traina if (info & TI_BLOCK) 763*3c602fabSXin LI ND_PRINT((ndo, "blo ")); 7644edb46e9SPaul Traina } 7654edb46e9SPaul Traina 766f4d0c64aSSam Leffler static int 767*3c602fabSXin LI print_l1_routes(netdissect_options *ndo, 768*3c602fabSXin LI const char *rp, u_int len) 7694edb46e9SPaul Traina { 7704edb46e9SPaul Traina int count; 7714edb46e9SPaul Traina int id; 7724edb46e9SPaul Traina int info; 7734edb46e9SPaul Traina 7744edb46e9SPaul Traina /* The last short is a checksum */ 7754edb46e9SPaul Traina while (len > (3 * sizeof(short))) { 776*3c602fabSXin LI ND_TCHECK2(*rp, 3 * sizeof(short)); 7774edb46e9SPaul Traina count = EXTRACT_LE_16BITS(rp); 7784edb46e9SPaul Traina if (count > 1024) 779f4d0c64aSSam Leffler return (1); /* seems to be bogus from here on */ 7804edb46e9SPaul Traina rp += sizeof(short); 7814edb46e9SPaul Traina len -= sizeof(short); 7824edb46e9SPaul Traina id = EXTRACT_LE_16BITS(rp); 7834edb46e9SPaul Traina rp += sizeof(short); 7844edb46e9SPaul Traina len -= sizeof(short); 7854edb46e9SPaul Traina info = EXTRACT_LE_16BITS(rp); 7864edb46e9SPaul Traina rp += sizeof(short); 7874edb46e9SPaul Traina len -= sizeof(short); 788*3c602fabSXin LI ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, 789*3c602fabSXin LI RI_COST(info), RI_HOPS(info))); 7904edb46e9SPaul Traina } 791f4d0c64aSSam Leffler return (1); 792f4d0c64aSSam Leffler 793f4d0c64aSSam Leffler trunc: 794f4d0c64aSSam Leffler return (0); 7954edb46e9SPaul Traina } 7964edb46e9SPaul Traina 797f4d0c64aSSam Leffler static int 798*3c602fabSXin LI print_l2_routes(netdissect_options *ndo, 799*3c602fabSXin LI const char *rp, u_int len) 8004edb46e9SPaul Traina { 8014edb46e9SPaul Traina int count; 8024edb46e9SPaul Traina int area; 8034edb46e9SPaul Traina int info; 8044edb46e9SPaul Traina 8054edb46e9SPaul Traina /* The last short is a checksum */ 8064edb46e9SPaul Traina while (len > (3 * sizeof(short))) { 807*3c602fabSXin LI ND_TCHECK2(*rp, 3 * sizeof(short)); 8084edb46e9SPaul Traina count = EXTRACT_LE_16BITS(rp); 8094edb46e9SPaul Traina if (count > 1024) 810f4d0c64aSSam Leffler return (1); /* seems to be bogus from here on */ 8114edb46e9SPaul Traina rp += sizeof(short); 8124edb46e9SPaul Traina len -= sizeof(short); 8134edb46e9SPaul Traina area = EXTRACT_LE_16BITS(rp); 8144edb46e9SPaul Traina rp += sizeof(short); 8154edb46e9SPaul Traina len -= sizeof(short); 8164edb46e9SPaul Traina info = EXTRACT_LE_16BITS(rp); 8174edb46e9SPaul Traina rp += sizeof(short); 8184edb46e9SPaul Traina len -= sizeof(short); 819*3c602fabSXin LI ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, 820*3c602fabSXin LI RI_COST(info), RI_HOPS(info))); 8214edb46e9SPaul Traina } 822f4d0c64aSSam Leffler return (1); 823f4d0c64aSSam Leffler 824f4d0c64aSSam Leffler trunc: 825f4d0c64aSSam Leffler return (0); 8264edb46e9SPaul Traina } 8274edb46e9SPaul Traina 8284edb46e9SPaul Traina static void 829*3c602fabSXin LI print_i_info(netdissect_options *ndo, 830*3c602fabSXin LI int info) 8314edb46e9SPaul Traina { 8324edb46e9SPaul Traina int ntype = info & II_TYPEMASK; 8334edb46e9SPaul Traina switch (ntype) { 834*3c602fabSXin LI case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 835*3c602fabSXin LI case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 836*3c602fabSXin LI case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 837*3c602fabSXin LI case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 8384edb46e9SPaul Traina } 8394edb46e9SPaul Traina if (info & II_VERIF) 840*3c602fabSXin LI ND_PRINT((ndo, "verif ")); 8414edb46e9SPaul Traina if (info & II_NOMCAST) 842*3c602fabSXin LI ND_PRINT((ndo, "nomcast ")); 8434edb46e9SPaul Traina if (info & II_BLOCK) 844*3c602fabSXin LI ND_PRINT((ndo, "blo ")); 8454edb46e9SPaul Traina } 8464edb46e9SPaul Traina 847f4d0c64aSSam Leffler static int 8485b0fe478SBruce M Simpson print_elist(const char *elp _U_, u_int len _U_) 8494edb46e9SPaul Traina { 8504edb46e9SPaul Traina /* Not enough examples available for me to debug this */ 851f4d0c64aSSam Leffler return (1); 8524edb46e9SPaul Traina } 8534edb46e9SPaul Traina 854f4d0c64aSSam Leffler static int 855*3c602fabSXin LI print_nsp(netdissect_options *ndo, 856*3c602fabSXin LI const u_char *nspp, u_int nsplen) 8574edb46e9SPaul Traina { 8584edb46e9SPaul Traina const struct nsphdr *nsphp = (struct nsphdr *)nspp; 8594edb46e9SPaul Traina int dst, src, flags; 8604edb46e9SPaul Traina 861f4d0c64aSSam Leffler if (nsplen < sizeof(struct nsphdr)) 862f4d0c64aSSam Leffler goto trunc; 863*3c602fabSXin LI ND_TCHECK(*nsphp); 8644edb46e9SPaul Traina flags = EXTRACT_LE_8BITS(nsphp->nh_flags); 8654edb46e9SPaul Traina dst = EXTRACT_LE_16BITS(nsphp->nh_dst); 8664edb46e9SPaul Traina src = EXTRACT_LE_16BITS(nsphp->nh_src); 8674edb46e9SPaul Traina 8684edb46e9SPaul Traina switch (flags & NSP_TYPEMASK) { 8694edb46e9SPaul Traina case MFT_DATA: 8704edb46e9SPaul Traina switch (flags & NSP_SUBMASK) { 8714edb46e9SPaul Traina case MFS_BOM: 8724edb46e9SPaul Traina case MFS_MOM: 8734edb46e9SPaul Traina case MFS_EOM: 8744edb46e9SPaul Traina case MFS_BOM+MFS_EOM: 875*3c602fabSXin LI ND_PRINT((ndo, "data %d>%d ", src, dst)); 8764edb46e9SPaul Traina { 8774edb46e9SPaul Traina struct seghdr *shp = (struct seghdr *)nspp; 8784edb46e9SPaul Traina int ack; 8794edb46e9SPaul Traina #ifdef PRINT_NSPDATA 8804edb46e9SPaul Traina u_char *dp; 8814edb46e9SPaul Traina #endif 8824edb46e9SPaul Traina u_int data_off = sizeof(struct minseghdr); 8834edb46e9SPaul Traina 884f4d0c64aSSam Leffler if (nsplen < data_off) 885f4d0c64aSSam Leffler goto trunc; 886*3c602fabSXin LI ND_TCHECK(shp->sh_seq[0]); 8874edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 8884edb46e9SPaul Traina if (ack & SGQ_ACK) { /* acknum field */ 8894edb46e9SPaul Traina if ((ack & SGQ_NAK) == SGQ_NAK) 890*3c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 8914edb46e9SPaul Traina else 892*3c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 8934edb46e9SPaul Traina data_off += sizeof(short); 894f4d0c64aSSam Leffler if (nsplen < data_off) 895f4d0c64aSSam Leffler goto trunc; 896*3c602fabSXin LI ND_TCHECK(shp->sh_seq[1]); 897f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 8984edb46e9SPaul Traina if (ack & SGQ_OACK) { /* ackoth field */ 8994edb46e9SPaul Traina if ((ack & SGQ_ONAK) == SGQ_ONAK) 900*3c602fabSXin LI ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 9014edb46e9SPaul Traina else 902*3c602fabSXin LI ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 9034edb46e9SPaul Traina data_off += sizeof(short); 904f4d0c64aSSam Leffler if (nsplen < data_off) 905f4d0c64aSSam Leffler goto trunc; 906*3c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 907f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9084edb46e9SPaul Traina } 9094edb46e9SPaul Traina } 910*3c602fabSXin LI ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 9114edb46e9SPaul Traina #ifdef PRINT_NSPDATA 912f4d0c64aSSam Leffler if (nsplen > data_off) { 9134edb46e9SPaul Traina dp = &(nspp[data_off]); 914*3c602fabSXin LI ND_TCHECK2(*dp, nsplen - data_off); 915*3c602fabSXin LI pdata(ndo, dp, nsplen - data_off); 916f4d0c64aSSam Leffler } 9174edb46e9SPaul Traina #endif 9184edb46e9SPaul Traina } 9194edb46e9SPaul Traina break; 9204edb46e9SPaul Traina case MFS_ILS+MFS_INT: 921*3c602fabSXin LI ND_PRINT((ndo, "intr ")); 9224edb46e9SPaul Traina { 9234edb46e9SPaul Traina struct seghdr *shp = (struct seghdr *)nspp; 9244edb46e9SPaul Traina int ack; 9254edb46e9SPaul Traina #ifdef PRINT_NSPDATA 9264edb46e9SPaul Traina u_char *dp; 9274edb46e9SPaul Traina #endif 9284edb46e9SPaul Traina u_int data_off = sizeof(struct minseghdr); 9294edb46e9SPaul Traina 930f4d0c64aSSam Leffler if (nsplen < data_off) 931f4d0c64aSSam Leffler goto trunc; 932*3c602fabSXin LI ND_TCHECK(shp->sh_seq[0]); 9334edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 9344edb46e9SPaul Traina if (ack & SGQ_ACK) { /* acknum field */ 9354edb46e9SPaul Traina if ((ack & SGQ_NAK) == SGQ_NAK) 936*3c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 9374edb46e9SPaul Traina else 938*3c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 9394edb46e9SPaul Traina data_off += sizeof(short); 940f4d0c64aSSam Leffler if (nsplen < data_off) 941f4d0c64aSSam Leffler goto trunc; 942*3c602fabSXin LI ND_TCHECK(shp->sh_seq[1]); 943f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 9444edb46e9SPaul Traina if (ack & SGQ_OACK) { /* ackdat field */ 9454edb46e9SPaul Traina if ((ack & SGQ_ONAK) == SGQ_ONAK) 946*3c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 9474edb46e9SPaul Traina else 948*3c602fabSXin LI ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 9494edb46e9SPaul Traina data_off += sizeof(short); 950f4d0c64aSSam Leffler if (nsplen < data_off) 951f4d0c64aSSam Leffler goto trunc; 952*3c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 953f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9544edb46e9SPaul Traina } 9554edb46e9SPaul Traina } 956*3c602fabSXin LI ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 9574edb46e9SPaul Traina #ifdef PRINT_NSPDATA 958f4d0c64aSSam Leffler if (nsplen > data_off) { 9594edb46e9SPaul Traina dp = &(nspp[data_off]); 960*3c602fabSXin LI ND_TCHECK2(*dp, nsplen - data_off); 961*3c602fabSXin LI pdata(ndo, dp, nsplen - data_off); 962f4d0c64aSSam Leffler } 9634edb46e9SPaul Traina #endif 9644edb46e9SPaul Traina } 9654edb46e9SPaul Traina break; 9664edb46e9SPaul Traina case MFS_ILS: 967*3c602fabSXin LI ND_PRINT((ndo, "link-service %d>%d ", src, dst)); 9684edb46e9SPaul Traina { 9694edb46e9SPaul Traina struct seghdr *shp = (struct seghdr *)nspp; 9704edb46e9SPaul Traina struct lsmsg *lsmp = 9714edb46e9SPaul Traina (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); 9724edb46e9SPaul Traina int ack; 9734edb46e9SPaul Traina int lsflags, fcval; 9744edb46e9SPaul Traina 975f4d0c64aSSam Leffler if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) 976f4d0c64aSSam Leffler goto trunc; 977*3c602fabSXin LI ND_TCHECK(shp->sh_seq[0]); 9784edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 9794edb46e9SPaul Traina if (ack & SGQ_ACK) { /* acknum field */ 9804edb46e9SPaul Traina if ((ack & SGQ_NAK) == SGQ_NAK) 981*3c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 9824edb46e9SPaul Traina else 983*3c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 984*3c602fabSXin LI ND_TCHECK(shp->sh_seq[1]); 9854edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 9864edb46e9SPaul Traina if (ack & SGQ_OACK) { /* ackdat field */ 9874edb46e9SPaul Traina if ((ack & SGQ_ONAK) == SGQ_ONAK) 988*3c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 9894edb46e9SPaul Traina else 990*3c602fabSXin LI ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 991*3c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 9924edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9934edb46e9SPaul Traina } 9944edb46e9SPaul Traina } 995*3c602fabSXin LI ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 996*3c602fabSXin LI ND_TCHECK(*lsmp); 9974edb46e9SPaul Traina lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); 9984edb46e9SPaul Traina fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); 9994edb46e9SPaul Traina switch (lsflags & LSI_MASK) { 10004edb46e9SPaul Traina case LSI_DATA: 1001*3c602fabSXin LI ND_PRINT((ndo, "dat seg count %d ", fcval)); 10024edb46e9SPaul Traina switch (lsflags & LSM_MASK) { 10034edb46e9SPaul Traina case LSM_NOCHANGE: 10044edb46e9SPaul Traina break; 10054edb46e9SPaul Traina case LSM_DONOTSEND: 1006*3c602fabSXin LI ND_PRINT((ndo, "donotsend-data ")); 10074edb46e9SPaul Traina break; 10084edb46e9SPaul Traina case LSM_SEND: 1009*3c602fabSXin LI ND_PRINT((ndo, "send-data ")); 10104edb46e9SPaul Traina break; 10114edb46e9SPaul Traina default: 1012*3c602fabSXin LI ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); 10134edb46e9SPaul Traina break; 10144edb46e9SPaul Traina } 10154edb46e9SPaul Traina break; 10164edb46e9SPaul Traina case LSI_INTR: 1017*3c602fabSXin LI ND_PRINT((ndo, "intr req count %d ", fcval)); 10184edb46e9SPaul Traina break; 10194edb46e9SPaul Traina default: 1020*3c602fabSXin LI ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); 10214edb46e9SPaul Traina break; 10224edb46e9SPaul Traina } 10234edb46e9SPaul Traina } 10244edb46e9SPaul Traina break; 10254edb46e9SPaul Traina default: 1026*3c602fabSXin LI ND_PRINT((ndo, "reserved-subtype? %x %d > %d", flags, src, dst)); 10274edb46e9SPaul Traina break; 10284edb46e9SPaul Traina } 10294edb46e9SPaul Traina break; 10304edb46e9SPaul Traina case MFT_ACK: 10314edb46e9SPaul Traina switch (flags & NSP_SUBMASK) { 10324edb46e9SPaul Traina case MFS_DACK: 1033*3c602fabSXin LI ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); 10344edb46e9SPaul Traina { 10354edb46e9SPaul Traina struct ackmsg *amp = (struct ackmsg *)nspp; 10364edb46e9SPaul Traina int ack; 10374edb46e9SPaul Traina 1038f4d0c64aSSam Leffler if (nsplen < sizeof(struct ackmsg)) 1039f4d0c64aSSam Leffler goto trunc; 1040*3c602fabSXin LI ND_TCHECK(*amp); 10414edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 10424edb46e9SPaul Traina if (ack & SGQ_ACK) { /* acknum field */ 10434edb46e9SPaul Traina if ((ack & SGQ_NAK) == SGQ_NAK) 1044*3c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 10454edb46e9SPaul Traina else 1046*3c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 10474edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 10484edb46e9SPaul Traina if (ack & SGQ_OACK) { /* ackoth field */ 10494edb46e9SPaul Traina if ((ack & SGQ_ONAK) == SGQ_ONAK) 1050*3c602fabSXin LI ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 10514edb46e9SPaul Traina else 1052*3c602fabSXin LI ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 10534edb46e9SPaul Traina } 10544edb46e9SPaul Traina } 10554edb46e9SPaul Traina } 10564edb46e9SPaul Traina break; 10574edb46e9SPaul Traina case MFS_IACK: 1058*3c602fabSXin LI ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); 10594edb46e9SPaul Traina { 10604edb46e9SPaul Traina struct ackmsg *amp = (struct ackmsg *)nspp; 10614edb46e9SPaul Traina int ack; 10624edb46e9SPaul Traina 1063f4d0c64aSSam Leffler if (nsplen < sizeof(struct ackmsg)) 1064f4d0c64aSSam Leffler goto trunc; 1065*3c602fabSXin LI ND_TCHECK(*amp); 10664edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 10674edb46e9SPaul Traina if (ack & SGQ_ACK) { /* acknum field */ 10684edb46e9SPaul Traina if ((ack & SGQ_NAK) == SGQ_NAK) 1069*3c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 10704edb46e9SPaul Traina else 1071*3c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 1072*3c602fabSXin LI ND_TCHECK(amp->ak_acknum[1]); 10734edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 10744edb46e9SPaul Traina if (ack & SGQ_OACK) { /* ackdat field */ 10754edb46e9SPaul Traina if ((ack & SGQ_ONAK) == SGQ_ONAK) 1076*3c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 10774edb46e9SPaul Traina else 1078*3c602fabSXin LI ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 10794edb46e9SPaul Traina } 10804edb46e9SPaul Traina } 10814edb46e9SPaul Traina } 10824edb46e9SPaul Traina break; 10834edb46e9SPaul Traina case MFS_CACK: 1084*3c602fabSXin LI ND_PRINT((ndo, "conn-ack %d", dst)); 10854edb46e9SPaul Traina break; 10864edb46e9SPaul Traina default: 1087*3c602fabSXin LI ND_PRINT((ndo, "reserved-acktype? %x %d > %d", flags, src, dst)); 10884edb46e9SPaul Traina break; 10894edb46e9SPaul Traina } 10904edb46e9SPaul Traina break; 10914edb46e9SPaul Traina case MFT_CTL: 10924edb46e9SPaul Traina switch (flags & NSP_SUBMASK) { 10934edb46e9SPaul Traina case MFS_CI: 10944edb46e9SPaul Traina case MFS_RCI: 10954edb46e9SPaul Traina if ((flags & NSP_SUBMASK) == MFS_CI) 1096*3c602fabSXin LI ND_PRINT((ndo, "conn-initiate ")); 10974edb46e9SPaul Traina else 1098*3c602fabSXin LI ND_PRINT((ndo, "retrans-conn-initiate ")); 1099*3c602fabSXin LI ND_PRINT((ndo, "%d>%d ", src, dst)); 11004edb46e9SPaul Traina { 11014edb46e9SPaul Traina struct cimsg *cimp = (struct cimsg *)nspp; 11024edb46e9SPaul Traina int services, info, segsize; 11034edb46e9SPaul Traina #ifdef PRINT_NSPDATA 11044edb46e9SPaul Traina u_char *dp; 11054edb46e9SPaul Traina #endif 11064edb46e9SPaul Traina 1107f4d0c64aSSam Leffler if (nsplen < sizeof(struct cimsg)) 1108f4d0c64aSSam Leffler goto trunc; 1109*3c602fabSXin LI ND_TCHECK(*cimp); 11104edb46e9SPaul Traina services = EXTRACT_LE_8BITS(cimp->ci_services); 11114edb46e9SPaul Traina info = EXTRACT_LE_8BITS(cimp->ci_info); 11124edb46e9SPaul Traina segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); 11134edb46e9SPaul Traina 11144edb46e9SPaul Traina switch (services & COS_MASK) { 11154edb46e9SPaul Traina case COS_NONE: 11164edb46e9SPaul Traina break; 11174edb46e9SPaul Traina case COS_SEGMENT: 1118*3c602fabSXin LI ND_PRINT((ndo, "seg ")); 11194edb46e9SPaul Traina break; 11204edb46e9SPaul Traina case COS_MESSAGE: 1121*3c602fabSXin LI ND_PRINT((ndo, "msg ")); 11224edb46e9SPaul Traina break; 11234edb46e9SPaul Traina case COS_CRYPTSER: 1124*3c602fabSXin LI ND_PRINT((ndo, "crypt ")); 11254edb46e9SPaul Traina break; 11264edb46e9SPaul Traina } 11274edb46e9SPaul Traina switch (info & COI_MASK) { 11284edb46e9SPaul Traina case COI_32: 1129*3c602fabSXin LI ND_PRINT((ndo, "ver 3.2 ")); 11304edb46e9SPaul Traina break; 11314edb46e9SPaul Traina case COI_31: 1132*3c602fabSXin LI ND_PRINT((ndo, "ver 3.1 ")); 11334edb46e9SPaul Traina break; 11344edb46e9SPaul Traina case COI_40: 1135*3c602fabSXin LI ND_PRINT((ndo, "ver 4.0 ")); 11364edb46e9SPaul Traina break; 11374edb46e9SPaul Traina case COI_41: 1138*3c602fabSXin LI ND_PRINT((ndo, "ver 4.1 ")); 11394edb46e9SPaul Traina break; 11404edb46e9SPaul Traina } 1141*3c602fabSXin LI ND_PRINT((ndo, "segsize %d ", segsize)); 11424edb46e9SPaul Traina #ifdef PRINT_NSPDATA 1143f4d0c64aSSam Leffler if (nsplen > sizeof(struct cimsg)) { 11444edb46e9SPaul Traina dp = &(nspp[sizeof(struct cimsg)]); 1145*3c602fabSXin LI ND_TCHECK2(*dp, nsplen - sizeof(struct cimsg)); 1146*3c602fabSXin LI pdata(ndo, dp, nsplen - sizeof(struct cimsg)); 1147f4d0c64aSSam Leffler } 11484edb46e9SPaul Traina #endif 11494edb46e9SPaul Traina } 11504edb46e9SPaul Traina break; 11514edb46e9SPaul Traina case MFS_CC: 1152*3c602fabSXin LI ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); 11534edb46e9SPaul Traina { 11544edb46e9SPaul Traina struct ccmsg *ccmp = (struct ccmsg *)nspp; 11554edb46e9SPaul Traina int services, info; 11564edb46e9SPaul Traina u_int segsize, optlen; 11574edb46e9SPaul Traina #ifdef PRINT_NSPDATA 11584edb46e9SPaul Traina u_char *dp; 11594edb46e9SPaul Traina #endif 11604edb46e9SPaul Traina 1161f4d0c64aSSam Leffler if (nsplen < sizeof(struct ccmsg)) 1162f4d0c64aSSam Leffler goto trunc; 1163*3c602fabSXin LI ND_TCHECK(*ccmp); 11644edb46e9SPaul Traina services = EXTRACT_LE_8BITS(ccmp->cc_services); 11654edb46e9SPaul Traina info = EXTRACT_LE_8BITS(ccmp->cc_info); 11664edb46e9SPaul Traina segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); 11674edb46e9SPaul Traina optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); 11684edb46e9SPaul Traina 11694edb46e9SPaul Traina switch (services & COS_MASK) { 11704edb46e9SPaul Traina case COS_NONE: 11714edb46e9SPaul Traina break; 11724edb46e9SPaul Traina case COS_SEGMENT: 1173*3c602fabSXin LI ND_PRINT((ndo, "seg ")); 11744edb46e9SPaul Traina break; 11754edb46e9SPaul Traina case COS_MESSAGE: 1176*3c602fabSXin LI ND_PRINT((ndo, "msg ")); 11774edb46e9SPaul Traina break; 11784edb46e9SPaul Traina case COS_CRYPTSER: 1179*3c602fabSXin LI ND_PRINT((ndo, "crypt ")); 11804edb46e9SPaul Traina break; 11814edb46e9SPaul Traina } 11824edb46e9SPaul Traina switch (info & COI_MASK) { 11834edb46e9SPaul Traina case COI_32: 1184*3c602fabSXin LI ND_PRINT((ndo, "ver 3.2 ")); 11854edb46e9SPaul Traina break; 11864edb46e9SPaul Traina case COI_31: 1187*3c602fabSXin LI ND_PRINT((ndo, "ver 3.1 ")); 11884edb46e9SPaul Traina break; 11894edb46e9SPaul Traina case COI_40: 1190*3c602fabSXin LI ND_PRINT((ndo, "ver 4.0 ")); 11914edb46e9SPaul Traina break; 11924edb46e9SPaul Traina case COI_41: 1193*3c602fabSXin LI ND_PRINT((ndo, "ver 4.1 ")); 11944edb46e9SPaul Traina break; 11954edb46e9SPaul Traina } 1196*3c602fabSXin LI ND_PRINT((ndo, "segsize %d ", segsize)); 11974edb46e9SPaul Traina if (optlen) { 1198*3c602fabSXin LI ND_PRINT((ndo, "optlen %d ", optlen)); 11994edb46e9SPaul Traina #ifdef PRINT_NSPDATA 1200f4d0c64aSSam Leffler if (optlen > nsplen - sizeof(struct ccmsg)) 1201f4d0c64aSSam Leffler goto trunc; 12024edb46e9SPaul Traina dp = &(nspp[sizeof(struct ccmsg)]); 1203*3c602fabSXin LI ND_TCHECK2(*dp, optlen); 1204*3c602fabSXin LI pdata(ndo, dp, optlen); 12054edb46e9SPaul Traina #endif 12064edb46e9SPaul Traina } 12074edb46e9SPaul Traina } 12084edb46e9SPaul Traina break; 12094edb46e9SPaul Traina case MFS_DI: 1210*3c602fabSXin LI ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); 12114edb46e9SPaul Traina { 12124edb46e9SPaul Traina struct dimsg *dimp = (struct dimsg *)nspp; 12134edb46e9SPaul Traina int reason; 12144edb46e9SPaul Traina u_int optlen; 12154edb46e9SPaul Traina #ifdef PRINT_NSPDATA 12164edb46e9SPaul Traina u_char *dp; 12174edb46e9SPaul Traina #endif 12184edb46e9SPaul Traina 1219f4d0c64aSSam Leffler if (nsplen < sizeof(struct dimsg)) 1220f4d0c64aSSam Leffler goto trunc; 1221*3c602fabSXin LI ND_TCHECK(*dimp); 12224edb46e9SPaul Traina reason = EXTRACT_LE_16BITS(dimp->di_reason); 12234edb46e9SPaul Traina optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 12244edb46e9SPaul Traina 1225*3c602fabSXin LI print_reason(ndo, reason); 12264edb46e9SPaul Traina if (optlen) { 1227*3c602fabSXin LI ND_PRINT((ndo, "optlen %d ", optlen)); 12284edb46e9SPaul Traina #ifdef PRINT_NSPDATA 1229f4d0c64aSSam Leffler if (optlen > nsplen - sizeof(struct dimsg)) 1230f4d0c64aSSam Leffler goto trunc; 12314edb46e9SPaul Traina dp = &(nspp[sizeof(struct dimsg)]); 1232*3c602fabSXin LI ND_TCHECK2(*dp, optlen); 1233*3c602fabSXin LI pdata(ndo, dp, optlen); 12344edb46e9SPaul Traina #endif 12354edb46e9SPaul Traina } 12364edb46e9SPaul Traina } 12374edb46e9SPaul Traina break; 12384edb46e9SPaul Traina case MFS_DC: 1239*3c602fabSXin LI ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); 12404edb46e9SPaul Traina { 12414edb46e9SPaul Traina struct dcmsg *dcmp = (struct dcmsg *)nspp; 12424edb46e9SPaul Traina int reason; 12434edb46e9SPaul Traina 1244*3c602fabSXin LI ND_TCHECK(*dcmp); 12454edb46e9SPaul Traina reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 12464edb46e9SPaul Traina 1247*3c602fabSXin LI print_reason(ndo, reason); 12484edb46e9SPaul Traina } 12494edb46e9SPaul Traina break; 12504edb46e9SPaul Traina default: 1251*3c602fabSXin LI ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); 12524edb46e9SPaul Traina break; 12534edb46e9SPaul Traina } 12544edb46e9SPaul Traina break; 12554edb46e9SPaul Traina default: 1256*3c602fabSXin LI ND_PRINT((ndo, "reserved-type? %x %d > %d", flags, src, dst)); 12574edb46e9SPaul Traina break; 12584edb46e9SPaul Traina } 1259f4d0c64aSSam Leffler return (1); 1260f4d0c64aSSam Leffler 1261f4d0c64aSSam Leffler trunc: 1262f4d0c64aSSam Leffler return (0); 12634edb46e9SPaul Traina } 12644edb46e9SPaul Traina 1265*3c602fabSXin LI static const struct tok reason2str[] = { 12664edb46e9SPaul Traina { UC_OBJREJECT, "object rejected connect" }, 12674edb46e9SPaul Traina { UC_RESOURCES, "insufficient resources" }, 12684edb46e9SPaul Traina { UC_NOSUCHNODE, "unrecognized node name" }, 12694edb46e9SPaul Traina { DI_SHUT, "node is shutting down" }, 12704edb46e9SPaul Traina { UC_NOSUCHOBJ, "unrecognized object" }, 12714edb46e9SPaul Traina { UC_INVOBJFORMAT, "invalid object name format" }, 12724edb46e9SPaul Traina { UC_OBJTOOBUSY, "object too busy" }, 12734edb46e9SPaul Traina { DI_PROTOCOL, "protocol error discovered" }, 12744edb46e9SPaul Traina { DI_TPA, "third party abort" }, 12754edb46e9SPaul Traina { UC_USERABORT, "user abort" }, 12764edb46e9SPaul Traina { UC_INVNODEFORMAT, "invalid node name format" }, 12774edb46e9SPaul Traina { UC_LOCALSHUT, "local node shutting down" }, 12784edb46e9SPaul Traina { DI_LOCALRESRC, "insufficient local resources" }, 12794edb46e9SPaul Traina { DI_REMUSERRESRC, "insufficient remote user resources" }, 12804edb46e9SPaul Traina { UC_ACCESSREJECT, "invalid access control information" }, 12814edb46e9SPaul Traina { DI_BADACCNT, "bad ACCOUNT information" }, 12824edb46e9SPaul Traina { UC_NORESPONSE, "no response from object" }, 12834edb46e9SPaul Traina { UC_UNREACHABLE, "node unreachable" }, 12844edb46e9SPaul Traina { DC_NOLINK, "no link terminate" }, 12854edb46e9SPaul Traina { DC_COMPLETE, "disconnect complete" }, 12864edb46e9SPaul Traina { DI_BADIMAGE, "bad image data in connect" }, 12874edb46e9SPaul Traina { DI_SERVMISMATCH, "cryptographic service mismatch" }, 12884edb46e9SPaul Traina { 0, NULL } 12894edb46e9SPaul Traina }; 12904edb46e9SPaul Traina 12914edb46e9SPaul Traina static void 1292*3c602fabSXin LI print_reason(netdissect_options *ndo, 1293*3c602fabSXin LI register int reason) 12944edb46e9SPaul Traina { 1295*3c602fabSXin LI ND_PRINT((ndo, "%s ", tok2str(reason2str, "reason-%d", reason))); 12964edb46e9SPaul Traina } 12974edb46e9SPaul Traina 1298a90e161bSBill Fenner const char * 12994edb46e9SPaul Traina dnnum_string(u_short dnaddr) 13004edb46e9SPaul Traina { 13014edb46e9SPaul Traina char *str; 1302685295f4SBill Fenner size_t siz; 13034de76e31SBill Fenner int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; 13044edb46e9SPaul Traina int node = dnaddr & NODEMASK; 13054edb46e9SPaul Traina 1306685295f4SBill Fenner str = (char *)malloc(siz = sizeof("00.0000")); 13074edb46e9SPaul Traina if (str == NULL) 13084edb46e9SPaul Traina error("dnnum_string: malloc"); 1309685295f4SBill Fenner snprintf(str, siz, "%d.%d", area, node); 13104edb46e9SPaul Traina return(str); 13114edb46e9SPaul Traina } 13124edb46e9SPaul Traina 1313a90e161bSBill Fenner const char * 13144edb46e9SPaul Traina dnname_string(u_short dnaddr) 13154edb46e9SPaul Traina { 13165b0fe478SBruce M Simpson #ifdef HAVE_DNET_HTOA 13174edb46e9SPaul Traina struct dn_naddr dna; 13184edb46e9SPaul Traina 13194edb46e9SPaul Traina dna.a_len = sizeof(short); 13204edb46e9SPaul Traina memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 1321a90e161bSBill Fenner return (strdup(dnet_htoa(&dna))); 13224edb46e9SPaul Traina #else 13234edb46e9SPaul Traina return(dnnum_string(dnaddr)); /* punt */ 13244edb46e9SPaul Traina #endif 13254edb46e9SPaul Traina } 13264edb46e9SPaul Traina 13274edb46e9SPaul Traina #ifdef PRINT_NSPDATA 13284edb46e9SPaul Traina static void 1329*3c602fabSXin LI pdata(netdissect_options *ndo, 1330*3c602fabSXin LI u_char *dp, u_int maxlen) 13314edb46e9SPaul Traina { 13324edb46e9SPaul Traina char c; 13334edb46e9SPaul Traina u_int x = maxlen; 13344edb46e9SPaul Traina 13354edb46e9SPaul Traina while (x-- > 0) { 13364edb46e9SPaul Traina c = *dp++; 1337*3c602fabSXin LI safeputchar(ndo, c); 13384edb46e9SPaul Traina } 13394edb46e9SPaul Traina } 13404edb46e9SPaul Traina #endif 1341