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 223c602fabSXin 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 443c602fabSXin LI static const char tstr[] = "[|decnet]"; 453c602fabSXin LI 463c602fabSXin LI #ifndef WIN32 473c602fabSXin LI typedef uint8_t byte[1]; /* single byte field */ 483c602fabSXin LI #else 493c602fabSXin LI /* 503c602fabSXin LI * the keyword 'byte' generates conflicts in Windows 513c602fabSXin LI */ 523c602fabSXin LI typedef unsigned char Byte[1]; /* single byte field */ 533c602fabSXin LI #define byte Byte 543c602fabSXin LI #endif /* WIN32 */ 553c602fabSXin LI typedef uint8_t word[2]; /* 2 byte field */ 563c602fabSXin LI typedef uint8_t longword[4]; /* 4 bytes field */ 573c602fabSXin LI 583c602fabSXin LI /* 593c602fabSXin LI * Definitions for DECNET Phase IV protocol headers 603c602fabSXin LI */ 613c602fabSXin LI union etheraddress { 623c602fabSXin LI uint8_t dne_addr[6]; /* full ethernet address */ 633c602fabSXin LI struct { 643c602fabSXin LI uint8_t dne_hiord[4]; /* DECnet HIORD prefix */ 653c602fabSXin LI uint8_t dne_nodeaddr[2]; /* DECnet node address */ 663c602fabSXin LI } dne_remote; 673c602fabSXin LI }; 683c602fabSXin LI 693c602fabSXin LI typedef union etheraddress etheraddr; /* Ethernet address */ 703c602fabSXin LI 713c602fabSXin LI #define HIORD 0x000400aa /* high 32-bits of address (swapped) */ 723c602fabSXin LI 733c602fabSXin LI #define AREAMASK 0176000 /* mask for area field */ 743c602fabSXin LI #define AREASHIFT 10 /* bit-offset for area field */ 753c602fabSXin LI #define NODEMASK 01777 /* mask for node address field */ 763c602fabSXin LI 773c602fabSXin LI #define DN_MAXADDL 20 /* max size of DECnet address */ 783c602fabSXin LI struct dn_naddr { 793c602fabSXin LI uint16_t a_len; /* length of address */ 803c602fabSXin LI uint8_t a_addr[DN_MAXADDL]; /* address as bytes */ 813c602fabSXin LI }; 823c602fabSXin LI 833c602fabSXin LI /* 843c602fabSXin LI * Define long and short header formats. 853c602fabSXin LI */ 863c602fabSXin LI struct shorthdr 873c602fabSXin LI { 883c602fabSXin LI byte sh_flags; /* route flags */ 893c602fabSXin LI word sh_dst; /* destination node address */ 903c602fabSXin LI word sh_src; /* source node address */ 913c602fabSXin LI byte sh_visits; /* visit count */ 923c602fabSXin LI }; 933c602fabSXin LI 943c602fabSXin LI struct longhdr 953c602fabSXin LI { 963c602fabSXin LI byte lg_flags; /* route flags */ 973c602fabSXin LI byte lg_darea; /* destination area (reserved) */ 983c602fabSXin LI byte lg_dsarea; /* destination subarea (reserved) */ 993c602fabSXin LI etheraddr lg_dst; /* destination id */ 1003c602fabSXin LI byte lg_sarea; /* source area (reserved) */ 1013c602fabSXin LI byte lg_ssarea; /* source subarea (reserved) */ 1023c602fabSXin LI etheraddr lg_src; /* source id */ 1033c602fabSXin LI byte lg_nextl2; /* next level 2 router (reserved) */ 1043c602fabSXin LI byte lg_visits; /* visit count */ 1053c602fabSXin LI byte lg_service; /* service class (reserved) */ 1063c602fabSXin LI byte lg_pt; /* protocol type (reserved) */ 1073c602fabSXin LI }; 1083c602fabSXin LI 1093c602fabSXin LI union routehdr 1103c602fabSXin LI { 1113c602fabSXin LI struct shorthdr rh_short; /* short route header */ 1123c602fabSXin LI struct longhdr rh_long; /* long route header */ 1133c602fabSXin LI }; 1143c602fabSXin LI 1153c602fabSXin LI /* 1163c602fabSXin LI * Define the values of various fields in the protocol messages. 1173c602fabSXin LI * 1183c602fabSXin LI * 1. Data packet formats. 1193c602fabSXin LI */ 1203c602fabSXin LI #define RMF_MASK 7 /* mask for message type */ 1213c602fabSXin LI #define RMF_SHORT 2 /* short message format */ 1223c602fabSXin LI #define RMF_LONG 6 /* long message format */ 1233c602fabSXin LI #ifndef RMF_RQR 1243c602fabSXin LI #define RMF_RQR 010 /* request return to sender */ 1253c602fabSXin LI #define RMF_RTS 020 /* returning to sender */ 1263c602fabSXin LI #define RMF_IE 040 /* intra-ethernet packet */ 1273c602fabSXin LI #endif /* RMR_RQR */ 1283c602fabSXin LI #define RMF_FVER 0100 /* future version flag */ 1293c602fabSXin LI #define RMF_PAD 0200 /* pad field */ 1303c602fabSXin LI #define RMF_PADMASK 0177 /* pad field mask */ 1313c602fabSXin LI 1323c602fabSXin LI #define VIS_MASK 077 /* visit field mask */ 1333c602fabSXin LI 1343c602fabSXin LI /* 1353c602fabSXin LI * 2. Control packet formats. 1363c602fabSXin LI */ 1373c602fabSXin LI #define RMF_CTLMASK 017 /* mask for message type */ 1383c602fabSXin LI #define RMF_CTLMSG 01 /* control message indicator */ 1393c602fabSXin LI #define RMF_INIT 01 /* initialization message */ 1403c602fabSXin LI #define RMF_VER 03 /* verification message */ 1413c602fabSXin LI #define RMF_TEST 05 /* hello and test message */ 1423c602fabSXin LI #define RMF_L1ROUT 07 /* level 1 routing message */ 1433c602fabSXin LI #define RMF_L2ROUT 011 /* level 2 routing message */ 1443c602fabSXin LI #define RMF_RHELLO 013 /* router hello message */ 1453c602fabSXin LI #define RMF_EHELLO 015 /* endnode hello message */ 1463c602fabSXin LI 1473c602fabSXin LI #define TI_L2ROUT 01 /* level 2 router */ 1483c602fabSXin LI #define TI_L1ROUT 02 /* level 1 router */ 1493c602fabSXin LI #define TI_ENDNODE 03 /* endnode */ 1503c602fabSXin LI #define TI_VERIF 04 /* verification required */ 1513c602fabSXin LI #define TI_BLOCK 010 /* blocking requested */ 1523c602fabSXin LI 1533c602fabSXin LI #define VE_VERS 2 /* version number (2) */ 1543c602fabSXin LI #define VE_ECO 0 /* ECO number */ 1553c602fabSXin LI #define VE_UECO 0 /* user ECO number (0) */ 1563c602fabSXin LI 1573c602fabSXin LI #define P3_VERS 1 /* phase III version number (1) */ 1583c602fabSXin LI #define P3_ECO 3 /* ECO number (3) */ 1593c602fabSXin LI #define P3_UECO 0 /* user ECO number (0) */ 1603c602fabSXin LI 1613c602fabSXin LI #define II_L2ROUT 01 /* level 2 router */ 1623c602fabSXin LI #define II_L1ROUT 02 /* level 1 router */ 1633c602fabSXin LI #define II_ENDNODE 03 /* endnode */ 1643c602fabSXin LI #define II_VERIF 04 /* verification required */ 1653c602fabSXin LI #define II_NOMCAST 040 /* no multicast traffic accepted */ 1663c602fabSXin LI #define II_BLOCK 0100 /* blocking requested */ 1673c602fabSXin LI #define II_TYPEMASK 03 /* mask for node type */ 1683c602fabSXin LI 1693c602fabSXin LI #define TESTDATA 0252 /* test data bytes */ 1703c602fabSXin LI #define TESTLEN 1 /* length of transmitted test data */ 1713c602fabSXin LI 1723c602fabSXin LI /* 1733c602fabSXin LI * Define control message formats. 1743c602fabSXin LI */ 1753c602fabSXin LI struct initmsgIII /* phase III initialization message */ 1763c602fabSXin LI { 1773c602fabSXin LI byte inIII_flags; /* route flags */ 1783c602fabSXin LI word inIII_src; /* source node address */ 1793c602fabSXin LI byte inIII_info; /* routing layer information */ 1803c602fabSXin LI word inIII_blksize; /* maximum data link block size */ 1813c602fabSXin LI byte inIII_vers; /* version number */ 1823c602fabSXin LI byte inIII_eco; /* ECO number */ 1833c602fabSXin LI byte inIII_ueco; /* user ECO number */ 1843c602fabSXin LI byte inIII_rsvd; /* reserved image field */ 1853c602fabSXin LI }; 1863c602fabSXin LI 1873c602fabSXin LI struct initmsg /* initialization message */ 1883c602fabSXin LI { 1893c602fabSXin LI byte in_flags; /* route flags */ 1903c602fabSXin LI word in_src; /* source node address */ 1913c602fabSXin LI byte in_info; /* routing layer information */ 1923c602fabSXin LI word in_blksize; /* maximum data link block size */ 1933c602fabSXin LI byte in_vers; /* version number */ 1943c602fabSXin LI byte in_eco; /* ECO number */ 1953c602fabSXin LI byte in_ueco; /* user ECO number */ 1963c602fabSXin LI word in_hello; /* hello timer */ 1973c602fabSXin LI byte in_rsvd; /* reserved image field */ 1983c602fabSXin LI }; 1993c602fabSXin LI 2003c602fabSXin LI struct verifmsg /* verification message */ 2013c602fabSXin LI { 2023c602fabSXin LI byte ve_flags; /* route flags */ 2033c602fabSXin LI word ve_src; /* source node address */ 2043c602fabSXin LI byte ve_fcnval; /* function value image field */ 2053c602fabSXin LI }; 2063c602fabSXin LI 2073c602fabSXin LI struct testmsg /* hello and test message */ 2083c602fabSXin LI { 2093c602fabSXin LI byte te_flags; /* route flags */ 2103c602fabSXin LI word te_src; /* source node address */ 2113c602fabSXin LI byte te_data; /* test data image field */ 2123c602fabSXin LI }; 2133c602fabSXin LI 2143c602fabSXin LI struct l1rout /* level 1 routing message */ 2153c602fabSXin LI { 2163c602fabSXin LI byte r1_flags; /* route flags */ 2173c602fabSXin LI word r1_src; /* source node address */ 2183c602fabSXin LI byte r1_rsvd; /* reserved field */ 2193c602fabSXin LI }; 2203c602fabSXin LI 2213c602fabSXin LI struct l2rout /* level 2 routing message */ 2223c602fabSXin LI { 2233c602fabSXin LI byte r2_flags; /* route flags */ 2243c602fabSXin LI word r2_src; /* source node address */ 2253c602fabSXin LI byte r2_rsvd; /* reserved field */ 2263c602fabSXin LI }; 2273c602fabSXin LI 2283c602fabSXin LI struct rhellomsg /* router hello message */ 2293c602fabSXin LI { 2303c602fabSXin LI byte rh_flags; /* route flags */ 2313c602fabSXin LI byte rh_vers; /* version number */ 2323c602fabSXin LI byte rh_eco; /* ECO number */ 2333c602fabSXin LI byte rh_ueco; /* user ECO number */ 2343c602fabSXin LI etheraddr rh_src; /* source id */ 2353c602fabSXin LI byte rh_info; /* routing layer information */ 2363c602fabSXin LI word rh_blksize; /* maximum data link block size */ 2373c602fabSXin LI byte rh_priority; /* router's priority */ 2383c602fabSXin LI byte rh_area; /* reserved */ 2393c602fabSXin LI word rh_hello; /* hello timer */ 2403c602fabSXin LI byte rh_mpd; /* reserved */ 2413c602fabSXin LI }; 2423c602fabSXin LI 2433c602fabSXin LI struct ehellomsg /* endnode hello message */ 2443c602fabSXin LI { 2453c602fabSXin LI byte eh_flags; /* route flags */ 2463c602fabSXin LI byte eh_vers; /* version number */ 2473c602fabSXin LI byte eh_eco; /* ECO number */ 2483c602fabSXin LI byte eh_ueco; /* user ECO number */ 2493c602fabSXin LI etheraddr eh_src; /* source id */ 2503c602fabSXin LI byte eh_info; /* routing layer information */ 2513c602fabSXin LI word eh_blksize; /* maximum data link block size */ 2523c602fabSXin LI byte eh_area; /* area (reserved) */ 2533c602fabSXin LI byte eh_seed[8]; /* verification seed */ 2543c602fabSXin LI etheraddr eh_router; /* designated router */ 2553c602fabSXin LI word eh_hello; /* hello timer */ 2563c602fabSXin LI byte eh_mpd; /* (reserved) */ 2573c602fabSXin LI byte eh_data; /* test data image field */ 2583c602fabSXin LI }; 2593c602fabSXin LI 2603c602fabSXin LI union controlmsg 2613c602fabSXin LI { 2623c602fabSXin LI struct initmsg cm_init; /* initialization message */ 2633c602fabSXin LI struct verifmsg cm_ver; /* verification message */ 2643c602fabSXin LI struct testmsg cm_test; /* hello and test message */ 2653c602fabSXin LI struct l1rout cm_l1rou; /* level 1 routing message */ 2663c602fabSXin LI struct l2rout cm_l2rout; /* level 2 routing message */ 2673c602fabSXin LI struct rhellomsg cm_rhello; /* router hello message */ 2683c602fabSXin LI struct ehellomsg cm_ehello; /* endnode hello message */ 2693c602fabSXin LI }; 2703c602fabSXin LI 2713c602fabSXin LI /* Macros for decoding routing-info fields */ 2723c602fabSXin LI #define RI_COST(x) ((x)&0777) 2733c602fabSXin LI #define RI_HOPS(x) (((x)>>10)&037) 274*8bdc5a62SPatrick Kelsey 2753c602fabSXin LI /* 2763c602fabSXin LI * NSP protocol fields and values. 2773c602fabSXin LI */ 2783c602fabSXin LI 2793c602fabSXin LI #define NSP_TYPEMASK 014 /* mask to isolate type code */ 2803c602fabSXin LI #define NSP_SUBMASK 0160 /* mask to isolate subtype code */ 2813c602fabSXin LI #define NSP_SUBSHFT 4 /* shift to move subtype code */ 2823c602fabSXin LI 2833c602fabSXin LI #define MFT_DATA 0 /* data message */ 2843c602fabSXin LI #define MFT_ACK 04 /* acknowledgement message */ 2853c602fabSXin LI #define MFT_CTL 010 /* control message */ 2863c602fabSXin LI 2873c602fabSXin LI #define MFS_ILS 020 /* data or I/LS indicator */ 2883c602fabSXin LI #define MFS_BOM 040 /* beginning of message (data) */ 2893c602fabSXin LI #define MFS_MOM 0 /* middle of message (data) */ 2903c602fabSXin LI #define MFS_EOM 0100 /* end of message (data) */ 2913c602fabSXin LI #define MFS_INT 040 /* interrupt message */ 2923c602fabSXin LI 2933c602fabSXin LI #define MFS_DACK 0 /* data acknowledgement */ 2943c602fabSXin LI #define MFS_IACK 020 /* I/LS acknowledgement */ 2953c602fabSXin LI #define MFS_CACK 040 /* connect acknowledgement */ 2963c602fabSXin LI 2973c602fabSXin LI #define MFS_NOP 0 /* no operation */ 2983c602fabSXin LI #define MFS_CI 020 /* connect initiate */ 2993c602fabSXin LI #define MFS_CC 040 /* connect confirm */ 3003c602fabSXin LI #define MFS_DI 060 /* disconnect initiate */ 3013c602fabSXin LI #define MFS_DC 0100 /* disconnect confirm */ 3023c602fabSXin LI #define MFS_RCI 0140 /* retransmitted connect initiate */ 3033c602fabSXin LI 3043c602fabSXin LI #define SGQ_ACK 0100000 /* ack */ 3053c602fabSXin LI #define SGQ_NAK 0110000 /* negative ack */ 3063c602fabSXin LI #define SGQ_OACK 0120000 /* other channel ack */ 3073c602fabSXin LI #define SGQ_ONAK 0130000 /* other channel negative ack */ 3083c602fabSXin LI #define SGQ_MASK 07777 /* mask to isolate seq # */ 3093c602fabSXin LI #define SGQ_OTHER 020000 /* other channel qualifier */ 3103c602fabSXin LI #define SGQ_DELAY 010000 /* ack delay flag */ 3113c602fabSXin LI 3123c602fabSXin LI #define SGQ_EOM 0100000 /* pseudo flag for end-of-message */ 3133c602fabSXin LI 3143c602fabSXin LI #define LSM_MASK 03 /* mask for modifier field */ 3153c602fabSXin LI #define LSM_NOCHANGE 0 /* no change */ 3163c602fabSXin LI #define LSM_DONOTSEND 1 /* do not send data */ 3173c602fabSXin LI #define LSM_SEND 2 /* send data */ 3183c602fabSXin LI 3193c602fabSXin LI #define LSI_MASK 014 /* mask for interpretation field */ 3203c602fabSXin LI #define LSI_DATA 0 /* data segment or message count */ 3213c602fabSXin LI #define LSI_INTR 4 /* interrupt request count */ 3223c602fabSXin LI #define LSI_INTM 0377 /* funny marker for int. message */ 3233c602fabSXin LI 3243c602fabSXin LI #define COS_MASK 014 /* mask for flow control field */ 3253c602fabSXin LI #define COS_NONE 0 /* no flow control */ 3263c602fabSXin LI #define COS_SEGMENT 04 /* segment flow control */ 3273c602fabSXin LI #define COS_MESSAGE 010 /* message flow control */ 3283c602fabSXin LI #define COS_CRYPTSER 020 /* cryptographic services requested */ 3293c602fabSXin LI #define COS_DEFAULT 1 /* default value for field */ 3303c602fabSXin LI 3313c602fabSXin LI #define COI_MASK 3 /* mask for version field */ 3323c602fabSXin LI #define COI_32 0 /* version 3.2 */ 3333c602fabSXin LI #define COI_31 1 /* version 3.1 */ 3343c602fabSXin LI #define COI_40 2 /* version 4.0 */ 3353c602fabSXin LI #define COI_41 3 /* version 4.1 */ 3363c602fabSXin LI 3373c602fabSXin LI #define MNU_MASK 140 /* mask for session control version */ 3383c602fabSXin LI #define MNU_10 000 /* session V1.0 */ 3393c602fabSXin LI #define MNU_20 040 /* session V2.0 */ 3403c602fabSXin LI #define MNU_ACCESS 1 /* access control present */ 3413c602fabSXin LI #define MNU_USRDATA 2 /* user data field present */ 3423c602fabSXin LI #define MNU_INVKPROXY 4 /* invoke proxy field present */ 3433c602fabSXin LI #define MNU_UICPROXY 8 /* use uic-based proxy */ 3443c602fabSXin LI 3453c602fabSXin LI #define DC_NORESOURCES 1 /* no resource reason code */ 3463c602fabSXin LI #define DC_NOLINK 41 /* no link terminate reason code */ 3473c602fabSXin LI #define DC_COMPLETE 42 /* disconnect complete reason code */ 3483c602fabSXin LI 3493c602fabSXin LI #define DI_NOERROR 0 /* user disconnect */ 3503c602fabSXin LI #define DI_SHUT 3 /* node is shutting down */ 3513c602fabSXin LI #define DI_NOUSER 4 /* destination end user does not exist */ 3523c602fabSXin LI #define DI_INVDEST 5 /* invalid end user destination */ 3533c602fabSXin LI #define DI_REMRESRC 6 /* insufficient remote resources */ 3543c602fabSXin LI #define DI_TPA 8 /* third party abort */ 3553c602fabSXin LI #define DI_PROTOCOL 7 /* protocol error discovered */ 3563c602fabSXin LI #define DI_ABORT 9 /* user abort */ 3573c602fabSXin LI #define DI_LOCALRESRC 32 /* insufficient local resources */ 3583c602fabSXin LI #define DI_REMUSERRESRC 33 /* insufficient remote user resources */ 3593c602fabSXin LI #define DI_BADACCESS 34 /* bad access control information */ 3603c602fabSXin LI #define DI_BADACCNT 36 /* bad ACCOUNT information */ 3613c602fabSXin LI #define DI_CONNECTABORT 38 /* connect request cancelled */ 3623c602fabSXin LI #define DI_TIMEDOUT 38 /* remote node or user crashed */ 3633c602fabSXin LI #define DI_UNREACHABLE 39 /* local timers expired due to ... */ 3643c602fabSXin LI #define DI_BADIMAGE 43 /* bad image data in connect */ 3653c602fabSXin LI #define DI_SERVMISMATCH 54 /* cryptographic service mismatch */ 3663c602fabSXin LI 3673c602fabSXin LI #define UC_OBJREJECT 0 /* object rejected connect */ 3683c602fabSXin LI #define UC_USERDISCONNECT 0 /* user disconnect */ 3693c602fabSXin LI #define UC_RESOURCES 1 /* insufficient resources (local or remote) */ 3703c602fabSXin LI #define UC_NOSUCHNODE 2 /* unrecognized node name */ 3713c602fabSXin LI #define UC_REMOTESHUT 3 /* remote node shutting down */ 3723c602fabSXin LI #define UC_NOSUCHOBJ 4 /* unrecognized object */ 3733c602fabSXin LI #define UC_INVOBJFORMAT 5 /* invalid object name format */ 3743c602fabSXin LI #define UC_OBJTOOBUSY 6 /* object too busy */ 3753c602fabSXin LI #define UC_NETWORKABORT 8 /* network abort */ 3763c602fabSXin LI #define UC_USERABORT 9 /* user abort */ 3773c602fabSXin LI #define UC_INVNODEFORMAT 10 /* invalid node name format */ 3783c602fabSXin LI #define UC_LOCALSHUT 11 /* local node shutting down */ 3793c602fabSXin LI #define UC_ACCESSREJECT 34 /* invalid access control information */ 3803c602fabSXin LI #define UC_NORESPONSE 38 /* no response from object */ 3813c602fabSXin LI #define UC_UNREACHABLE 39 /* node unreachable */ 3823c602fabSXin LI 3833c602fabSXin LI /* 3843c602fabSXin LI * NSP message formats. 3853c602fabSXin LI */ 3863c602fabSXin LI struct nsphdr /* general nsp header */ 3873c602fabSXin LI { 3883c602fabSXin LI byte nh_flags; /* message flags */ 3893c602fabSXin LI word nh_dst; /* destination link address */ 3903c602fabSXin LI word nh_src; /* source link address */ 3913c602fabSXin LI }; 3923c602fabSXin LI 3933c602fabSXin LI struct seghdr /* data segment header */ 3943c602fabSXin LI { 3953c602fabSXin LI byte sh_flags; /* message flags */ 3963c602fabSXin LI word sh_dst; /* destination link address */ 3973c602fabSXin LI word sh_src; /* source link address */ 3983c602fabSXin LI word sh_seq[3]; /* sequence numbers */ 3993c602fabSXin LI }; 4003c602fabSXin LI 4013c602fabSXin LI struct minseghdr /* minimum data segment header */ 4023c602fabSXin LI { 4033c602fabSXin LI byte ms_flags; /* message flags */ 4043c602fabSXin LI word ms_dst; /* destination link address */ 4053c602fabSXin LI word ms_src; /* source link address */ 4063c602fabSXin LI word ms_seq; /* sequence number */ 4073c602fabSXin LI }; 4083c602fabSXin LI 4093c602fabSXin LI struct lsmsg /* link service message (after hdr) */ 4103c602fabSXin LI { 4113c602fabSXin LI byte ls_lsflags; /* link service flags */ 4123c602fabSXin LI byte ls_fcval; /* flow control value */ 4133c602fabSXin LI }; 4143c602fabSXin LI 4153c602fabSXin LI struct ackmsg /* acknowledgement message */ 4163c602fabSXin LI { 4173c602fabSXin LI byte ak_flags; /* message flags */ 4183c602fabSXin LI word ak_dst; /* destination link address */ 4193c602fabSXin LI word ak_src; /* source link address */ 4203c602fabSXin LI word ak_acknum[2]; /* acknowledgement numbers */ 4213c602fabSXin LI }; 4223c602fabSXin LI 4233c602fabSXin LI struct minackmsg /* minimum acknowledgement message */ 4243c602fabSXin LI { 4253c602fabSXin LI byte mk_flags; /* message flags */ 4263c602fabSXin LI word mk_dst; /* destination link address */ 4273c602fabSXin LI word mk_src; /* source link address */ 4283c602fabSXin LI word mk_acknum; /* acknowledgement number */ 4293c602fabSXin LI }; 4303c602fabSXin LI 4313c602fabSXin LI struct ciackmsg /* connect acknowledgement message */ 4323c602fabSXin LI { 4333c602fabSXin LI byte ck_flags; /* message flags */ 4343c602fabSXin LI word ck_dst; /* destination link address */ 4353c602fabSXin LI }; 4363c602fabSXin LI 4373c602fabSXin LI struct cimsg /* connect initiate message */ 4383c602fabSXin LI { 4393c602fabSXin LI byte ci_flags; /* message flags */ 4403c602fabSXin LI word ci_dst; /* destination link address (0) */ 4413c602fabSXin LI word ci_src; /* source link address */ 4423c602fabSXin LI byte ci_services; /* requested services */ 4433c602fabSXin LI byte ci_info; /* information */ 4443c602fabSXin LI word ci_segsize; /* maximum segment size */ 4453c602fabSXin LI }; 4463c602fabSXin LI 4473c602fabSXin LI struct ccmsg /* connect confirm message */ 4483c602fabSXin LI { 4493c602fabSXin LI byte cc_flags; /* message flags */ 4503c602fabSXin LI word cc_dst; /* destination link address */ 4513c602fabSXin LI word cc_src; /* source link address */ 4523c602fabSXin LI byte cc_services; /* requested services */ 4533c602fabSXin LI byte cc_info; /* information */ 4543c602fabSXin LI word cc_segsize; /* maximum segment size */ 4553c602fabSXin LI byte cc_optlen; /* optional data length */ 4563c602fabSXin LI }; 4573c602fabSXin LI 4583c602fabSXin LI struct cnmsg /* generic connect message */ 4593c602fabSXin LI { 4603c602fabSXin LI byte cn_flags; /* message flags */ 4613c602fabSXin LI word cn_dst; /* destination link address */ 4623c602fabSXin LI word cn_src; /* source link address */ 4633c602fabSXin LI byte cn_services; /* requested services */ 4643c602fabSXin LI byte cn_info; /* information */ 4653c602fabSXin LI word cn_segsize; /* maximum segment size */ 4663c602fabSXin LI }; 4673c602fabSXin LI 4683c602fabSXin LI struct dimsg /* disconnect initiate message */ 4693c602fabSXin LI { 4703c602fabSXin LI byte di_flags; /* message flags */ 4713c602fabSXin LI word di_dst; /* destination link address */ 4723c602fabSXin LI word di_src; /* source link address */ 4733c602fabSXin LI word di_reason; /* reason code */ 4743c602fabSXin LI byte di_optlen; /* optional data length */ 4753c602fabSXin LI }; 4763c602fabSXin LI 4773c602fabSXin LI struct dcmsg /* disconnect confirm message */ 4783c602fabSXin LI { 4793c602fabSXin LI byte dc_flags; /* message flags */ 4803c602fabSXin LI word dc_dst; /* destination link address */ 4813c602fabSXin LI word dc_src; /* source link address */ 4823c602fabSXin LI word dc_reason; /* reason code */ 4833c602fabSXin LI }; 4843c602fabSXin LI 4854edb46e9SPaul Traina /* Forwards */ 4863c602fabSXin LI static int print_decnet_ctlmsg(netdissect_options *, const union routehdr *, u_int, u_int); 4873c602fabSXin LI static void print_t_info(netdissect_options *, int); 4883c602fabSXin LI static int print_l1_routes(netdissect_options *, const char *, u_int); 4893c602fabSXin LI static int print_l2_routes(netdissect_options *, const char *, u_int); 4903c602fabSXin LI static void print_i_info(netdissect_options *, int); 491f4d0c64aSSam Leffler static int print_elist(const char *, u_int); 4923c602fabSXin LI static int print_nsp(netdissect_options *, const u_char *, u_int); 4933c602fabSXin LI static void print_reason(netdissect_options *, int); 4944edb46e9SPaul Traina #ifdef PRINT_NSPDATA 4953c602fabSXin 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 5033c602fabSXin LI decnet_print(netdissect_options *ndo, 5043c602fabSXin 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)) { 5143c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 5154edb46e9SPaul Traina return; 5164edb46e9SPaul Traina } 5174edb46e9SPaul Traina 5183c602fabSXin LI ND_TCHECK2(*ap, sizeof(short)); 5194edb46e9SPaul Traina pktlen = EXTRACT_LE_16BITS(ap); 520f4d0c64aSSam Leffler if (pktlen < sizeof(struct shorthdr)) { 5213c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 522f4d0c64aSSam Leffler return; 523f4d0c64aSSam Leffler } 524f4d0c64aSSam Leffler if (pktlen > length) { 5253c602fabSXin 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)]); 5313c602fabSXin 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; 5373c602fabSXin LI if (ndo->ndo_vflag) 5383c602fabSXin LI ND_PRINT((ndo, "[pad:%d] ", padlen)); 539f4d0c64aSSam Leffler if (length < padlen + 2) { 5403c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 541f4d0c64aSSam Leffler return; 542f4d0c64aSSam Leffler } 5433c602fabSXin 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) { 5523c602fabSXin LI ND_PRINT((ndo, "future-version-decnet")); 5533c602fabSXin 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) { 5593c602fabSXin 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)) { 5673c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 568f4d0c64aSSam Leffler return; 569f4d0c64aSSam Leffler } 5703c602fabSXin 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: 5803c602fabSXin 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: 5883c602fabSXin LI ND_PRINT((ndo, "unknown message flags under mask")); 5893c602fabSXin LI ND_DEFAULTPRINT((u_char *)ap, min(length, caplen)); 5904edb46e9SPaul Traina return; 5914edb46e9SPaul Traina } 5924edb46e9SPaul Traina 5933c602fabSXin LI ND_PRINT((ndo, "%s > %s %d ", 5943c602fabSXin LI dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); 5953c602fabSXin LI if (ndo->ndo_vflag) { 5964edb46e9SPaul Traina if (mflags & RMF_RQR) 5973c602fabSXin LI ND_PRINT((ndo, "RQR ")); 5984edb46e9SPaul Traina if (mflags & RMF_RTS) 5993c602fabSXin LI ND_PRINT((ndo, "RTS ")); 6004edb46e9SPaul Traina if (mflags & RMF_IE) 6013c602fabSXin LI ND_PRINT((ndo, "IE ")); 6023c602fabSXin LI ND_PRINT((ndo, "%d hops ", hops)); 6034edb46e9SPaul Traina } 6044edb46e9SPaul Traina 6053c602fabSXin LI if (!print_nsp(ndo, nspp, nsplen)) 606f4d0c64aSSam Leffler goto trunc; 607f4d0c64aSSam Leffler return; 608f4d0c64aSSam Leffler 609f4d0c64aSSam Leffler trunc: 6103c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 611f4d0c64aSSam Leffler return; 6124edb46e9SPaul Traina } 6134edb46e9SPaul Traina 614f4d0c64aSSam Leffler static int 6153c602fabSXin LI print_decnet_ctlmsg(netdissect_options *ndo, 6163c602fabSXin 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: 6293c602fabSXin LI ND_PRINT((ndo, "init ")); 630f4d0c64aSSam Leffler if (length < sizeof(struct initmsg)) 631f4d0c64aSSam Leffler goto trunc; 6323c602fabSXin 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); 6403c602fabSXin LI print_t_info(ndo, info); 6413c602fabSXin LI ND_PRINT((ndo, 6424edb46e9SPaul Traina "src %sblksize %d vers %d eco %d ueco %d hello %d", 6433c602fabSXin LI dnaddr_string(ndo, src), blksize, vers, eco, ueco, 6443c602fabSXin LI hello)); 645f4d0c64aSSam Leffler ret = 1; 6464edb46e9SPaul Traina break; 6474edb46e9SPaul Traina case RMF_VER: 6483c602fabSXin LI ND_PRINT((ndo, "verification ")); 649f4d0c64aSSam Leffler if (length < sizeof(struct verifmsg)) 650f4d0c64aSSam Leffler goto trunc; 6513c602fabSXin 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); 6543c602fabSXin 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: 6583c602fabSXin LI ND_PRINT((ndo, "test ")); 659f4d0c64aSSam Leffler if (length < sizeof(struct testmsg)) 660f4d0c64aSSam Leffler goto trunc; 6613c602fabSXin 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); 6643c602fabSXin 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: 6683c602fabSXin LI ND_PRINT((ndo, "lev-1-routing ")); 669f4d0c64aSSam Leffler if (length < sizeof(struct l1rout)) 670f4d0c64aSSam Leffler goto trunc; 6713c602fabSXin LI ND_TCHECK(cmp->cm_l1rou); 6724edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 6733c602fabSXin LI ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 6743c602fabSXin LI ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), 6754edb46e9SPaul Traina length - sizeof(struct l1rout)); 6764edb46e9SPaul Traina break; 6774edb46e9SPaul Traina case RMF_L2ROUT: 6783c602fabSXin LI ND_PRINT((ndo, "lev-2-routing ")); 679f4d0c64aSSam Leffler if (length < sizeof(struct l2rout)) 680f4d0c64aSSam Leffler goto trunc; 6813c602fabSXin LI ND_TCHECK(cmp->cm_l2rout); 6824edb46e9SPaul Traina src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 6833c602fabSXin LI ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); 6843c602fabSXin LI ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), 6854edb46e9SPaul Traina length - sizeof(struct l2rout)); 6864edb46e9SPaul Traina break; 6874edb46e9SPaul Traina case RMF_RHELLO: 6883c602fabSXin LI ND_PRINT((ndo, "router-hello ")); 689f4d0c64aSSam Leffler if (length < sizeof(struct rhellomsg)) 690f4d0c64aSSam Leffler goto trunc; 6913c602fabSXin 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); 7023c602fabSXin LI print_i_info(ndo, info); 7033c602fabSXin LI ND_PRINT((ndo, 7044edb46e9SPaul Traina "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 7053c602fabSXin LI vers, eco, ueco, dnaddr_string(ndo, src), 7063c602fabSXin 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: 7113c602fabSXin LI ND_PRINT((ndo, "endnode-hello ")); 712f4d0c64aSSam Leffler if (length < sizeof(struct ehellomsg)) 713f4d0c64aSSam Leffler goto trunc; 7143c602fabSXin 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); 7293c602fabSXin LI print_i_info(ndo, info); 7303c602fabSXin LI ND_PRINT((ndo, 7314edb46e9SPaul Traina "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 7323c602fabSXin LI vers, eco, ueco, dnaddr_string(ndo, src), 7333c602fabSXin LI blksize, dnaddr_string(ndo, dst), hello, other)); 734f4d0c64aSSam Leffler ret = 1; 7354edb46e9SPaul Traina break; 7364edb46e9SPaul Traina 7374edb46e9SPaul Traina default: 7383c602fabSXin LI ND_PRINT((ndo, "unknown control message")); 7393c602fabSXin 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 7503c602fabSXin LI print_t_info(netdissect_options *ndo, 7513c602fabSXin LI int info) 7524edb46e9SPaul Traina { 7534edb46e9SPaul Traina int ntype = info & 3; 7544edb46e9SPaul Traina switch (ntype) { 7553c602fabSXin LI case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 7563c602fabSXin LI case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 7573c602fabSXin LI case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 7583c602fabSXin LI case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 7594edb46e9SPaul Traina } 7604edb46e9SPaul Traina if (info & TI_VERIF) 7613c602fabSXin LI ND_PRINT((ndo, "verif ")); 7624edb46e9SPaul Traina if (info & TI_BLOCK) 7633c602fabSXin LI ND_PRINT((ndo, "blo ")); 7644edb46e9SPaul Traina } 7654edb46e9SPaul Traina 766f4d0c64aSSam Leffler static int 7673c602fabSXin LI print_l1_routes(netdissect_options *ndo, 7683c602fabSXin 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))) { 7763c602fabSXin 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); 7883c602fabSXin LI ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, 7893c602fabSXin 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 7983c602fabSXin LI print_l2_routes(netdissect_options *ndo, 7993c602fabSXin 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))) { 8073c602fabSXin 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); 8193c602fabSXin LI ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, 8203c602fabSXin 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 8293c602fabSXin LI print_i_info(netdissect_options *ndo, 8303c602fabSXin LI int info) 8314edb46e9SPaul Traina { 8324edb46e9SPaul Traina int ntype = info & II_TYPEMASK; 8334edb46e9SPaul Traina switch (ntype) { 8343c602fabSXin LI case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; 8353c602fabSXin LI case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; 8363c602fabSXin LI case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; 8373c602fabSXin LI case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; 8384edb46e9SPaul Traina } 8394edb46e9SPaul Traina if (info & II_VERIF) 8403c602fabSXin LI ND_PRINT((ndo, "verif ")); 8414edb46e9SPaul Traina if (info & II_NOMCAST) 8423c602fabSXin LI ND_PRINT((ndo, "nomcast ")); 8434edb46e9SPaul Traina if (info & II_BLOCK) 8443c602fabSXin 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 8553c602fabSXin LI print_nsp(netdissect_options *ndo, 8563c602fabSXin 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; 8633c602fabSXin 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: 8753c602fabSXin 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; 8863c602fabSXin 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) 8903c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 8914edb46e9SPaul Traina else 8923c602fabSXin 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; 8963c602fabSXin 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) 9003c602fabSXin LI ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 9014edb46e9SPaul Traina else 9023c602fabSXin 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; 9063c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 907f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9084edb46e9SPaul Traina } 9094edb46e9SPaul Traina } 9103c602fabSXin 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]); 9143c602fabSXin LI ND_TCHECK2(*dp, nsplen - data_off); 9153c602fabSXin LI pdata(ndo, dp, nsplen - data_off); 916f4d0c64aSSam Leffler } 9174edb46e9SPaul Traina #endif 9184edb46e9SPaul Traina } 9194edb46e9SPaul Traina break; 9204edb46e9SPaul Traina case MFS_ILS+MFS_INT: 9213c602fabSXin 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; 9323c602fabSXin 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) 9363c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 9374edb46e9SPaul Traina else 9383c602fabSXin 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; 9423c602fabSXin 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) 9463c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 9474edb46e9SPaul Traina else 9483c602fabSXin 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; 9523c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 953f4d0c64aSSam Leffler ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9544edb46e9SPaul Traina } 9554edb46e9SPaul Traina } 9563c602fabSXin 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]); 9603c602fabSXin LI ND_TCHECK2(*dp, nsplen - data_off); 9613c602fabSXin LI pdata(ndo, dp, nsplen - data_off); 962f4d0c64aSSam Leffler } 9634edb46e9SPaul Traina #endif 9644edb46e9SPaul Traina } 9654edb46e9SPaul Traina break; 9664edb46e9SPaul Traina case MFS_ILS: 9673c602fabSXin 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; 9773c602fabSXin 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) 9813c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 9824edb46e9SPaul Traina else 9833c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 9843c602fabSXin 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) 9883c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 9894edb46e9SPaul Traina else 9903c602fabSXin LI ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 9913c602fabSXin LI ND_TCHECK(shp->sh_seq[2]); 9924edb46e9SPaul Traina ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 9934edb46e9SPaul Traina } 9944edb46e9SPaul Traina } 9953c602fabSXin LI ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); 9963c602fabSXin 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: 10013c602fabSXin 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: 10063c602fabSXin LI ND_PRINT((ndo, "donotsend-data ")); 10074edb46e9SPaul Traina break; 10084edb46e9SPaul Traina case LSM_SEND: 10093c602fabSXin LI ND_PRINT((ndo, "send-data ")); 10104edb46e9SPaul Traina break; 10114edb46e9SPaul Traina default: 10123c602fabSXin LI ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); 10134edb46e9SPaul Traina break; 10144edb46e9SPaul Traina } 10154edb46e9SPaul Traina break; 10164edb46e9SPaul Traina case LSI_INTR: 10173c602fabSXin LI ND_PRINT((ndo, "intr req count %d ", fcval)); 10184edb46e9SPaul Traina break; 10194edb46e9SPaul Traina default: 10203c602fabSXin LI ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); 10214edb46e9SPaul Traina break; 10224edb46e9SPaul Traina } 10234edb46e9SPaul Traina } 10244edb46e9SPaul Traina break; 10254edb46e9SPaul Traina default: 10263c602fabSXin 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: 10333c602fabSXin 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; 10403c602fabSXin 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) 10443c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 10454edb46e9SPaul Traina else 10463c602fabSXin 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) 10503c602fabSXin LI ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); 10514edb46e9SPaul Traina else 10523c602fabSXin LI ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); 10534edb46e9SPaul Traina } 10544edb46e9SPaul Traina } 10554edb46e9SPaul Traina } 10564edb46e9SPaul Traina break; 10574edb46e9SPaul Traina case MFS_IACK: 10583c602fabSXin 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; 10653c602fabSXin 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) 10693c602fabSXin LI ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); 10704edb46e9SPaul Traina else 10713c602fabSXin LI ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); 10723c602fabSXin 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) 10763c602fabSXin LI ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); 10774edb46e9SPaul Traina else 10783c602fabSXin LI ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); 10794edb46e9SPaul Traina } 10804edb46e9SPaul Traina } 10814edb46e9SPaul Traina } 10824edb46e9SPaul Traina break; 10834edb46e9SPaul Traina case MFS_CACK: 10843c602fabSXin LI ND_PRINT((ndo, "conn-ack %d", dst)); 10854edb46e9SPaul Traina break; 10864edb46e9SPaul Traina default: 10873c602fabSXin 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) 10963c602fabSXin LI ND_PRINT((ndo, "conn-initiate ")); 10974edb46e9SPaul Traina else 10983c602fabSXin LI ND_PRINT((ndo, "retrans-conn-initiate ")); 10993c602fabSXin 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; 11093c602fabSXin 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: 11183c602fabSXin LI ND_PRINT((ndo, "seg ")); 11194edb46e9SPaul Traina break; 11204edb46e9SPaul Traina case COS_MESSAGE: 11213c602fabSXin LI ND_PRINT((ndo, "msg ")); 11224edb46e9SPaul Traina break; 11234edb46e9SPaul Traina case COS_CRYPTSER: 11243c602fabSXin LI ND_PRINT((ndo, "crypt ")); 11254edb46e9SPaul Traina break; 11264edb46e9SPaul Traina } 11274edb46e9SPaul Traina switch (info & COI_MASK) { 11284edb46e9SPaul Traina case COI_32: 11293c602fabSXin LI ND_PRINT((ndo, "ver 3.2 ")); 11304edb46e9SPaul Traina break; 11314edb46e9SPaul Traina case COI_31: 11323c602fabSXin LI ND_PRINT((ndo, "ver 3.1 ")); 11334edb46e9SPaul Traina break; 11344edb46e9SPaul Traina case COI_40: 11353c602fabSXin LI ND_PRINT((ndo, "ver 4.0 ")); 11364edb46e9SPaul Traina break; 11374edb46e9SPaul Traina case COI_41: 11383c602fabSXin LI ND_PRINT((ndo, "ver 4.1 ")); 11394edb46e9SPaul Traina break; 11404edb46e9SPaul Traina } 11413c602fabSXin 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)]); 11453c602fabSXin LI ND_TCHECK2(*dp, nsplen - sizeof(struct cimsg)); 11463c602fabSXin LI pdata(ndo, dp, nsplen - sizeof(struct cimsg)); 1147f4d0c64aSSam Leffler } 11484edb46e9SPaul Traina #endif 11494edb46e9SPaul Traina } 11504edb46e9SPaul Traina break; 11514edb46e9SPaul Traina case MFS_CC: 11523c602fabSXin 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; 11633c602fabSXin 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: 11733c602fabSXin LI ND_PRINT((ndo, "seg ")); 11744edb46e9SPaul Traina break; 11754edb46e9SPaul Traina case COS_MESSAGE: 11763c602fabSXin LI ND_PRINT((ndo, "msg ")); 11774edb46e9SPaul Traina break; 11784edb46e9SPaul Traina case COS_CRYPTSER: 11793c602fabSXin LI ND_PRINT((ndo, "crypt ")); 11804edb46e9SPaul Traina break; 11814edb46e9SPaul Traina } 11824edb46e9SPaul Traina switch (info & COI_MASK) { 11834edb46e9SPaul Traina case COI_32: 11843c602fabSXin LI ND_PRINT((ndo, "ver 3.2 ")); 11854edb46e9SPaul Traina break; 11864edb46e9SPaul Traina case COI_31: 11873c602fabSXin LI ND_PRINT((ndo, "ver 3.1 ")); 11884edb46e9SPaul Traina break; 11894edb46e9SPaul Traina case COI_40: 11903c602fabSXin LI ND_PRINT((ndo, "ver 4.0 ")); 11914edb46e9SPaul Traina break; 11924edb46e9SPaul Traina case COI_41: 11933c602fabSXin LI ND_PRINT((ndo, "ver 4.1 ")); 11944edb46e9SPaul Traina break; 11954edb46e9SPaul Traina } 11963c602fabSXin LI ND_PRINT((ndo, "segsize %d ", segsize)); 11974edb46e9SPaul Traina if (optlen) { 11983c602fabSXin 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)]); 12033c602fabSXin LI ND_TCHECK2(*dp, optlen); 12043c602fabSXin LI pdata(ndo, dp, optlen); 12054edb46e9SPaul Traina #endif 12064edb46e9SPaul Traina } 12074edb46e9SPaul Traina } 12084edb46e9SPaul Traina break; 12094edb46e9SPaul Traina case MFS_DI: 12103c602fabSXin 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; 12213c602fabSXin LI ND_TCHECK(*dimp); 12224edb46e9SPaul Traina reason = EXTRACT_LE_16BITS(dimp->di_reason); 12234edb46e9SPaul Traina optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 12244edb46e9SPaul Traina 12253c602fabSXin LI print_reason(ndo, reason); 12264edb46e9SPaul Traina if (optlen) { 12273c602fabSXin 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)]); 12323c602fabSXin LI ND_TCHECK2(*dp, optlen); 12333c602fabSXin LI pdata(ndo, dp, optlen); 12344edb46e9SPaul Traina #endif 12354edb46e9SPaul Traina } 12364edb46e9SPaul Traina } 12374edb46e9SPaul Traina break; 12384edb46e9SPaul Traina case MFS_DC: 12393c602fabSXin 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 12443c602fabSXin LI ND_TCHECK(*dcmp); 12454edb46e9SPaul Traina reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 12464edb46e9SPaul Traina 12473c602fabSXin LI print_reason(ndo, reason); 12484edb46e9SPaul Traina } 12494edb46e9SPaul Traina break; 12504edb46e9SPaul Traina default: 12513c602fabSXin LI ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); 12524edb46e9SPaul Traina break; 12534edb46e9SPaul Traina } 12544edb46e9SPaul Traina break; 12554edb46e9SPaul Traina default: 12563c602fabSXin 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 12653c602fabSXin 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 12923c602fabSXin LI print_reason(netdissect_options *ndo, 12933c602fabSXin LI register int reason) 12944edb46e9SPaul Traina { 12953c602fabSXin 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; 1318*8bdc5a62SPatrick Kelsey char *dnname; 13194edb46e9SPaul Traina 13204edb46e9SPaul Traina dna.a_len = sizeof(short); 13214edb46e9SPaul Traina memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 1322*8bdc5a62SPatrick Kelsey dnname = dnet_htoa(&dna); 1323*8bdc5a62SPatrick Kelsey if(dnname != NULL) 1324*8bdc5a62SPatrick Kelsey return (strdup(dnname)); 1325*8bdc5a62SPatrick Kelsey else 1326*8bdc5a62SPatrick Kelsey return(dnnum_string(dnaddr)); 13274edb46e9SPaul Traina #else 13284edb46e9SPaul Traina return(dnnum_string(dnaddr)); /* punt */ 13294edb46e9SPaul Traina #endif 13304edb46e9SPaul Traina } 13314edb46e9SPaul Traina 13324edb46e9SPaul Traina #ifdef PRINT_NSPDATA 13334edb46e9SPaul Traina static void 13343c602fabSXin LI pdata(netdissect_options *ndo, 13353c602fabSXin LI u_char *dp, u_int maxlen) 13364edb46e9SPaul Traina { 13374edb46e9SPaul Traina char c; 13384edb46e9SPaul Traina u_int x = maxlen; 13394edb46e9SPaul Traina 13404edb46e9SPaul Traina while (x-- > 0) { 13414edb46e9SPaul Traina c = *dp++; 13423c602fabSXin LI safeputchar(ndo, c); 13434edb46e9SPaul Traina } 13444edb46e9SPaul Traina } 13454edb46e9SPaul Traina #endif 1346