117680Spst/* 239297Sfenner * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst */ 2117680Spst 2217680Spst#ifndef lint 23127668Sbmsstatic const char rcsid[] _U_ = 24190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.39 2005-05-06 02:16:26 guy Exp $ (LBL)"; 2517680Spst#endif 2617680Spst 2756893Sfenner#ifdef HAVE_CONFIG_H 2856893Sfenner#include "config.h" 2956893Sfenner#endif 3056893Sfenner 31127668Sbms#include <tcpdump-stdinc.h> 3217680Spst 3317680Spststruct mbuf; 3417680Spststruct rtentry; 3517680Spst 36127668Sbms#ifdef HAVE_NETDNET_DNETDB_H 3717680Spst#include <netdnet/dnetdb.h> 3817680Spst#endif 3917680Spst 4017680Spst#include <stdio.h> 4117680Spst#include <stdlib.h> 4217680Spst#include <string.h> 4317680Spst 4417680Spst#include "decnet.h" 4517680Spst#include "extract.h" 4617680Spst#include "interface.h" 4717680Spst#include "addrtoname.h" 4817680Spst 4917680Spst/* Forwards */ 50147899Ssamstatic int print_decnet_ctlmsg(const union routehdr *, u_int, u_int); 5117680Spststatic void print_t_info(int); 52147899Ssamstatic int print_l1_routes(const char *, u_int); 53147899Ssamstatic int print_l2_routes(const char *, u_int); 5417680Spststatic void print_i_info(int); 55147899Ssamstatic int print_elist(const char *, u_int); 56147899Ssamstatic int print_nsp(const u_char *, u_int); 5717680Spststatic void print_reason(int); 5817680Spst#ifdef PRINT_NSPDATA 5917680Spststatic void pdata(u_char *, int); 6017680Spst#endif 6117680Spst 62127668Sbms#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA 6317680Spstextern char *dnet_htoa(struct dn_naddr *); 6417680Spst#endif 6517680Spst 6617680Spstvoid 6717680Spstdecnet_print(register const u_char *ap, register u_int length, 6817680Spst register u_int caplen) 6917680Spst{ 70147899Ssam register const union routehdr *rhp; 7117680Spst register int mflags; 7217680Spst int dst, src, hops; 73147899Ssam u_int nsplen, pktlen; 7417680Spst const u_char *nspp; 7517680Spst 7617680Spst if (length < sizeof(struct shorthdr)) { 7717680Spst (void)printf("[|decnet]"); 7817680Spst return; 7917680Spst } 8017680Spst 81147899Ssam TCHECK2(*ap, sizeof(short)); 8217680Spst pktlen = EXTRACT_LE_16BITS(ap); 83147899Ssam if (pktlen < sizeof(struct shorthdr)) { 84147899Ssam (void)printf("[|decnet]"); 85147899Ssam return; 86147899Ssam } 87147899Ssam if (pktlen > length) { 88147899Ssam (void)printf("[|decnet]"); 89147899Ssam return; 90147899Ssam } 91147899Ssam length = pktlen; 9217680Spst 93147899Ssam rhp = (const union routehdr *)&(ap[sizeof(short)]); 94147899Ssam TCHECK(rhp->rh_short.sh_flags); 9517680Spst mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 9617680Spst 9717680Spst if (mflags & RMF_PAD) { 9817680Spst /* pad bytes of some sort in front of message */ 9917680Spst u_int padlen = mflags & RMF_PADMASK; 10017680Spst if (vflag) 10117680Spst (void) printf("[pad:%d] ", padlen); 102147899Ssam if (length < padlen + 2) { 103147899Ssam (void)printf("[|decnet]"); 104147899Ssam return; 105147899Ssam } 106147899Ssam TCHECK2(ap[sizeof(short)], padlen); 10717680Spst ap += padlen; 10817680Spst length -= padlen; 10917680Spst caplen -= padlen; 110147899Ssam rhp = (const union routehdr *)&(ap[sizeof(short)]); 11117680Spst mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 11217680Spst } 11317680Spst 11417680Spst if (mflags & RMF_FVER) { 11517680Spst (void) printf("future-version-decnet"); 116147899Ssam default_print(ap, min(length, caplen)); 11717680Spst return; 11817680Spst } 11917680Spst 12017680Spst /* is it a control message? */ 12117680Spst if (mflags & RMF_CTLMSG) { 122147899Ssam if (!print_decnet_ctlmsg(rhp, length, caplen)) 123147899Ssam goto trunc; 12417680Spst return; 12517680Spst } 12617680Spst 12717680Spst switch (mflags & RMF_MASK) { 12817680Spst case RMF_LONG: 129147899Ssam if (length < sizeof(struct longhdr)) { 130147899Ssam (void)printf("[|decnet]"); 131147899Ssam return; 132147899Ssam } 133147899Ssam TCHECK(rhp->rh_long); 13417680Spst dst = 13517680Spst EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); 13617680Spst src = 13717680Spst EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); 13817680Spst hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); 13917680Spst nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); 140147899Ssam nsplen = length - sizeof(struct longhdr); 14117680Spst break; 14217680Spst case RMF_SHORT: 143147899Ssam TCHECK(rhp->rh_short); 14417680Spst dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); 14517680Spst src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); 14617680Spst hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; 14717680Spst nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); 148147899Ssam nsplen = length - sizeof(struct shorthdr); 14917680Spst break; 15017680Spst default: 15117680Spst (void) printf("unknown message flags under mask"); 152147899Ssam default_print((u_char *)ap, min(length, caplen)); 15317680Spst return; 15417680Spst } 15517680Spst 15617680Spst (void)printf("%s > %s %d ", 15717680Spst dnaddr_string(src), dnaddr_string(dst), pktlen); 15817680Spst if (vflag) { 15917680Spst if (mflags & RMF_RQR) 16017680Spst (void)printf("RQR "); 16117680Spst if (mflags & RMF_RTS) 16217680Spst (void)printf("RTS "); 16317680Spst if (mflags & RMF_IE) 16417680Spst (void)printf("IE "); 16517680Spst (void)printf("%d hops ", hops); 16617680Spst } 16717680Spst 168147899Ssam if (!print_nsp(nspp, nsplen)) 169147899Ssam goto trunc; 170147899Ssam return; 171147899Ssam 172147899Ssamtrunc: 173147899Ssam (void)printf("[|decnet]"); 174147899Ssam return; 17517680Spst} 17617680Spst 177147899Ssamstatic int 178147899Ssamprint_decnet_ctlmsg(register const union routehdr *rhp, u_int length, 179147899Ssam u_int caplen) 18017680Spst{ 18117680Spst int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); 18217680Spst register union controlmsg *cmp = (union controlmsg *)rhp; 18317680Spst int src, dst, info, blksize, eco, ueco, hello, other, vers; 18417680Spst etheraddr srcea, rtea; 18517680Spst int priority; 18617680Spst char *rhpx = (char *)rhp; 187147899Ssam int ret; 18817680Spst 18917680Spst switch (mflags & RMF_CTLMASK) { 19017680Spst case RMF_INIT: 19117680Spst (void)printf("init "); 192147899Ssam if (length < sizeof(struct initmsg)) 193147899Ssam goto trunc; 194147899Ssam TCHECK(cmp->cm_init); 19517680Spst src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); 19617680Spst info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); 19717680Spst blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); 19817680Spst vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); 19917680Spst eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); 20017680Spst ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); 20117680Spst hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); 20217680Spst print_t_info(info); 20317680Spst (void)printf( 20417680Spst "src %sblksize %d vers %d eco %d ueco %d hello %d", 20517680Spst dnaddr_string(src), blksize, vers, eco, ueco, 20617680Spst hello); 207147899Ssam ret = 1; 20817680Spst break; 20917680Spst case RMF_VER: 21017680Spst (void)printf("verification "); 211147899Ssam if (length < sizeof(struct verifmsg)) 212147899Ssam goto trunc; 213147899Ssam TCHECK(cmp->cm_ver); 21417680Spst src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); 21517680Spst other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); 21617680Spst (void)printf("src %s fcnval %o", dnaddr_string(src), other); 217147899Ssam ret = 1; 21817680Spst break; 21917680Spst case RMF_TEST: 22017680Spst (void)printf("test "); 221147899Ssam if (length < sizeof(struct testmsg)) 222147899Ssam goto trunc; 223147899Ssam TCHECK(cmp->cm_test); 22417680Spst src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); 22517680Spst other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); 22617680Spst (void)printf("src %s data %o", dnaddr_string(src), other); 227147899Ssam ret = 1; 22817680Spst break; 22917680Spst case RMF_L1ROUT: 23017680Spst (void)printf("lev-1-routing "); 231147899Ssam if (length < sizeof(struct l1rout)) 232147899Ssam goto trunc; 233147899Ssam TCHECK(cmp->cm_l1rou); 23417680Spst src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); 23517680Spst (void)printf("src %s ", dnaddr_string(src)); 236147899Ssam ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]), 23717680Spst length - sizeof(struct l1rout)); 23817680Spst break; 23917680Spst case RMF_L2ROUT: 24017680Spst (void)printf("lev-2-routing "); 241147899Ssam if (length < sizeof(struct l2rout)) 242147899Ssam goto trunc; 243147899Ssam TCHECK(cmp->cm_l2rout); 24417680Spst src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); 24517680Spst (void)printf("src %s ", dnaddr_string(src)); 246147899Ssam ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]), 24717680Spst length - sizeof(struct l2rout)); 24817680Spst break; 24917680Spst case RMF_RHELLO: 25017680Spst (void)printf("router-hello "); 251147899Ssam if (length < sizeof(struct rhellomsg)) 252147899Ssam goto trunc; 253147899Ssam TCHECK(cmp->cm_rhello); 25417680Spst vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); 25517680Spst eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); 25617680Spst ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); 25717680Spst memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), 25817680Spst sizeof(srcea)); 25917680Spst src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 26017680Spst info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); 26117680Spst blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); 26217680Spst priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); 26317680Spst hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); 26417680Spst print_i_info(info); 26517680Spst (void)printf( 26617680Spst "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", 26717680Spst vers, eco, ueco, dnaddr_string(src), 26817680Spst blksize, priority, hello); 269147899Ssam ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), 27017680Spst length - sizeof(struct rhellomsg)); 27117680Spst break; 27217680Spst case RMF_EHELLO: 27317680Spst (void)printf("endnode-hello "); 274147899Ssam if (length < sizeof(struct ehellomsg)) 275147899Ssam goto trunc; 276147899Ssam TCHECK(cmp->cm_ehello); 27717680Spst vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); 27817680Spst eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); 27917680Spst ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); 28017680Spst memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), 28117680Spst sizeof(srcea)); 28217680Spst src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); 28317680Spst info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); 28417680Spst blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); 28517680Spst /*seed*/ 28617680Spst memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), 28717680Spst sizeof(rtea)); 28817680Spst dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); 28917680Spst hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); 29017680Spst other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); 29117680Spst print_i_info(info); 29217680Spst (void)printf( 29317680Spst "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", 29417680Spst vers, eco, ueco, dnaddr_string(src), 29517680Spst blksize, dnaddr_string(dst), hello, other); 296147899Ssam ret = 1; 29717680Spst break; 29817680Spst 29917680Spst default: 30017680Spst (void)printf("unknown control message"); 301147899Ssam default_print((u_char *)rhp, min(length, caplen)); 302147899Ssam ret = 1; 30317680Spst break; 30417680Spst } 305147899Ssam return (ret); 306147899Ssam 307147899Ssamtrunc: 308147899Ssam return (0); 30917680Spst} 31017680Spst 31117680Spststatic void 31217680Spstprint_t_info(int info) 31317680Spst{ 31417680Spst int ntype = info & 3; 31517680Spst switch (ntype) { 31617680Spst case 0: (void)printf("reserved-ntype? "); break; 31717680Spst case TI_L2ROUT: (void)printf("l2rout "); break; 31817680Spst case TI_L1ROUT: (void)printf("l1rout "); break; 31917680Spst case TI_ENDNODE: (void)printf("endnode "); break; 32017680Spst } 32117680Spst if (info & TI_VERIF) 32217680Spst (void)printf("verif "); 32317680Spst if (info & TI_BLOCK) 32417680Spst (void)printf("blo "); 32517680Spst} 32617680Spst 327147899Ssamstatic int 32817680Spstprint_l1_routes(const char *rp, u_int len) 32917680Spst{ 33017680Spst int count; 33117680Spst int id; 33217680Spst int info; 33317680Spst 33417680Spst /* The last short is a checksum */ 33517680Spst while (len > (3 * sizeof(short))) { 336147899Ssam TCHECK2(*rp, 3 * sizeof(short)); 33717680Spst count = EXTRACT_LE_16BITS(rp); 33817680Spst if (count > 1024) 339147899Ssam return (1); /* seems to be bogus from here on */ 34017680Spst rp += sizeof(short); 34117680Spst len -= sizeof(short); 34217680Spst id = EXTRACT_LE_16BITS(rp); 34317680Spst rp += sizeof(short); 34417680Spst len -= sizeof(short); 34517680Spst info = EXTRACT_LE_16BITS(rp); 34617680Spst rp += sizeof(short); 34717680Spst len -= sizeof(short); 34817680Spst (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count, 34917680Spst RI_COST(info), RI_HOPS(info)); 35017680Spst } 351147899Ssam return (1); 352147899Ssam 353147899Ssamtrunc: 354147899Ssam return (0); 35517680Spst} 35617680Spst 357147899Ssamstatic int 35817680Spstprint_l2_routes(const char *rp, u_int len) 35917680Spst{ 36017680Spst int count; 36117680Spst int area; 36217680Spst int info; 36317680Spst 36417680Spst /* The last short is a checksum */ 36517680Spst while (len > (3 * sizeof(short))) { 366147899Ssam TCHECK2(*rp, 3 * sizeof(short)); 36717680Spst count = EXTRACT_LE_16BITS(rp); 36817680Spst if (count > 1024) 369147899Ssam return (1); /* seems to be bogus from here on */ 37017680Spst rp += sizeof(short); 37117680Spst len -= sizeof(short); 37217680Spst area = EXTRACT_LE_16BITS(rp); 37317680Spst rp += sizeof(short); 37417680Spst len -= sizeof(short); 37517680Spst info = EXTRACT_LE_16BITS(rp); 37617680Spst rp += sizeof(short); 37717680Spst len -= sizeof(short); 37817680Spst (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count, 37917680Spst RI_COST(info), RI_HOPS(info)); 38017680Spst } 381147899Ssam return (1); 382147899Ssam 383147899Ssamtrunc: 384147899Ssam return (0); 38517680Spst} 38617680Spst 38717680Spststatic void 38817680Spstprint_i_info(int info) 38917680Spst{ 39017680Spst int ntype = info & II_TYPEMASK; 39117680Spst switch (ntype) { 39217680Spst case 0: (void)printf("reserved-ntype? "); break; 39317680Spst case II_L2ROUT: (void)printf("l2rout "); break; 39417680Spst case II_L1ROUT: (void)printf("l1rout "); break; 39517680Spst case II_ENDNODE: (void)printf("endnode "); break; 39617680Spst } 39717680Spst if (info & II_VERIF) 39817680Spst (void)printf("verif "); 39917680Spst if (info & II_NOMCAST) 40017680Spst (void)printf("nomcast "); 40117680Spst if (info & II_BLOCK) 40217680Spst (void)printf("blo "); 40317680Spst} 40417680Spst 405147899Ssamstatic int 406127668Sbmsprint_elist(const char *elp _U_, u_int len _U_) 40717680Spst{ 40817680Spst /* Not enough examples available for me to debug this */ 409147899Ssam return (1); 41017680Spst} 41117680Spst 412147899Ssamstatic int 413147899Ssamprint_nsp(const u_char *nspp, u_int nsplen) 41417680Spst{ 41517680Spst const struct nsphdr *nsphp = (struct nsphdr *)nspp; 41617680Spst int dst, src, flags; 41717680Spst 418147899Ssam if (nsplen < sizeof(struct nsphdr)) 419147899Ssam goto trunc; 420147899Ssam TCHECK(*nsphp); 42117680Spst flags = EXTRACT_LE_8BITS(nsphp->nh_flags); 42217680Spst dst = EXTRACT_LE_16BITS(nsphp->nh_dst); 42317680Spst src = EXTRACT_LE_16BITS(nsphp->nh_src); 42417680Spst 42517680Spst switch (flags & NSP_TYPEMASK) { 42617680Spst case MFT_DATA: 42717680Spst switch (flags & NSP_SUBMASK) { 42817680Spst case MFS_BOM: 42917680Spst case MFS_MOM: 43017680Spst case MFS_EOM: 43117680Spst case MFS_BOM+MFS_EOM: 43217680Spst printf("data %d>%d ", src, dst); 43317680Spst { 43417680Spst struct seghdr *shp = (struct seghdr *)nspp; 43517680Spst int ack; 43617680Spst#ifdef PRINT_NSPDATA 43717680Spst u_char *dp; 43817680Spst#endif 43917680Spst u_int data_off = sizeof(struct minseghdr); 44017680Spst 441147899Ssam if (nsplen < data_off) 442147899Ssam goto trunc; 443147899Ssam TCHECK(shp->sh_seq[0]); 44417680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 44517680Spst if (ack & SGQ_ACK) { /* acknum field */ 44617680Spst if ((ack & SGQ_NAK) == SGQ_NAK) 44717680Spst (void)printf("nak %d ", ack & SGQ_MASK); 44817680Spst else 44917680Spst (void)printf("ack %d ", ack & SGQ_MASK); 450147899Ssam data_off += sizeof(short); 451147899Ssam if (nsplen < data_off) 452147899Ssam goto trunc; 453147899Ssam TCHECK(shp->sh_seq[1]); 45417680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 45517680Spst if (ack & SGQ_OACK) { /* ackoth field */ 45617680Spst if ((ack & SGQ_ONAK) == SGQ_ONAK) 45717680Spst (void)printf("onak %d ", ack & SGQ_MASK); 45817680Spst else 45917680Spst (void)printf("oack %d ", ack & SGQ_MASK); 460147899Ssam data_off += sizeof(short); 461147899Ssam if (nsplen < data_off) 462147899Ssam goto trunc; 463147899Ssam TCHECK(shp->sh_seq[2]); 46417680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 46517680Spst } 46617680Spst } 46717680Spst (void)printf("seg %d ", ack & SGQ_MASK); 46817680Spst#ifdef PRINT_NSPDATA 469147899Ssam if (nsplen > data_off) { 470147899Ssam dp = &(nspp[data_off]); 471147899Ssam TCHECK2(*dp, nsplen - data_off); 472147899Ssam pdata(dp, nsplen - data_off); 473147899Ssam } 47417680Spst#endif 47517680Spst } 47617680Spst break; 47717680Spst case MFS_ILS+MFS_INT: 47817680Spst printf("intr "); 47917680Spst { 48017680Spst struct seghdr *shp = (struct seghdr *)nspp; 48117680Spst int ack; 48217680Spst#ifdef PRINT_NSPDATA 48317680Spst u_char *dp; 48417680Spst#endif 48517680Spst u_int data_off = sizeof(struct minseghdr); 48617680Spst 487147899Ssam if (nsplen < data_off) 488147899Ssam goto trunc; 489147899Ssam TCHECK(shp->sh_seq[0]); 49017680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 49117680Spst if (ack & SGQ_ACK) { /* acknum field */ 49217680Spst if ((ack & SGQ_NAK) == SGQ_NAK) 49317680Spst (void)printf("nak %d ", ack & SGQ_MASK); 49417680Spst else 49517680Spst (void)printf("ack %d ", ack & SGQ_MASK); 496147899Ssam data_off += sizeof(short); 497147899Ssam if (nsplen < data_off) 498147899Ssam goto trunc; 499147899Ssam TCHECK(shp->sh_seq[1]); 50017680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 50117680Spst if (ack & SGQ_OACK) { /* ackdat field */ 50217680Spst if ((ack & SGQ_ONAK) == SGQ_ONAK) 50317680Spst (void)printf("nakdat %d ", ack & SGQ_MASK); 50417680Spst else 50517680Spst (void)printf("ackdat %d ", ack & SGQ_MASK); 506147899Ssam data_off += sizeof(short); 507147899Ssam if (nsplen < data_off) 508147899Ssam goto trunc; 509147899Ssam TCHECK(shp->sh_seq[2]); 51017680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 51117680Spst } 51217680Spst } 51317680Spst (void)printf("seg %d ", ack & SGQ_MASK); 51417680Spst#ifdef PRINT_NSPDATA 515147899Ssam if (nsplen > data_off) { 516147899Ssam dp = &(nspp[data_off]); 517147899Ssam TCHECK2(*dp, nsplen - data_off); 518147899Ssam pdata(dp, nsplen - data_off); 519147899Ssam } 52017680Spst#endif 52117680Spst } 52217680Spst break; 52317680Spst case MFS_ILS: 52417680Spst (void)printf("link-service %d>%d ", src, dst); 52517680Spst { 52617680Spst struct seghdr *shp = (struct seghdr *)nspp; 52717680Spst struct lsmsg *lsmp = 52817680Spst (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); 52917680Spst int ack; 53017680Spst int lsflags, fcval; 53117680Spst 532147899Ssam if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) 533147899Ssam goto trunc; 534147899Ssam TCHECK(shp->sh_seq[0]); 53517680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); 53617680Spst if (ack & SGQ_ACK) { /* acknum field */ 53717680Spst if ((ack & SGQ_NAK) == SGQ_NAK) 53817680Spst (void)printf("nak %d ", ack & SGQ_MASK); 53917680Spst else 54017680Spst (void)printf("ack %d ", ack & SGQ_MASK); 541147899Ssam TCHECK(shp->sh_seq[1]); 54217680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); 54317680Spst if (ack & SGQ_OACK) { /* ackdat field */ 54417680Spst if ((ack & SGQ_ONAK) == SGQ_ONAK) 54517680Spst (void)printf("nakdat %d ", ack & SGQ_MASK); 54617680Spst else 54717680Spst (void)printf("ackdat %d ", ack & SGQ_MASK); 548147899Ssam TCHECK(shp->sh_seq[2]); 54917680Spst ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); 55017680Spst } 55117680Spst } 55217680Spst (void)printf("seg %d ", ack & SGQ_MASK); 553147899Ssam TCHECK(*lsmp); 55417680Spst lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); 55517680Spst fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); 55617680Spst switch (lsflags & LSI_MASK) { 55717680Spst case LSI_DATA: 55817680Spst (void)printf("dat seg count %d ", fcval); 55917680Spst switch (lsflags & LSM_MASK) { 56017680Spst case LSM_NOCHANGE: 56117680Spst break; 56217680Spst case LSM_DONOTSEND: 56317680Spst (void)printf("donotsend-data "); 56417680Spst break; 56517680Spst case LSM_SEND: 56617680Spst (void)printf("send-data "); 56717680Spst break; 56817680Spst default: 56917680Spst (void)printf("reserved-fcmod? %x", lsflags); 57017680Spst break; 57117680Spst } 57217680Spst break; 57317680Spst case LSI_INTR: 57417680Spst (void)printf("intr req count %d ", fcval); 57517680Spst break; 57617680Spst default: 57717680Spst (void)printf("reserved-fcval-int? %x", lsflags); 57817680Spst break; 57917680Spst } 58017680Spst } 58117680Spst break; 58217680Spst default: 58317680Spst (void)printf("reserved-subtype? %x %d > %d", flags, src, dst); 58417680Spst break; 58517680Spst } 58617680Spst break; 58717680Spst case MFT_ACK: 58817680Spst switch (flags & NSP_SUBMASK) { 58917680Spst case MFS_DACK: 59017680Spst (void)printf("data-ack %d>%d ", src, dst); 59117680Spst { 59217680Spst struct ackmsg *amp = (struct ackmsg *)nspp; 59317680Spst int ack; 59417680Spst 595147899Ssam if (nsplen < sizeof(struct ackmsg)) 596147899Ssam goto trunc; 597147899Ssam TCHECK(*amp); 59817680Spst ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 59917680Spst if (ack & SGQ_ACK) { /* acknum field */ 60017680Spst if ((ack & SGQ_NAK) == SGQ_NAK) 60117680Spst (void)printf("nak %d ", ack & SGQ_MASK); 60217680Spst else 60317680Spst (void)printf("ack %d ", ack & SGQ_MASK); 60417680Spst ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 60517680Spst if (ack & SGQ_OACK) { /* ackoth field */ 60617680Spst if ((ack & SGQ_ONAK) == SGQ_ONAK) 60717680Spst (void)printf("onak %d ", ack & SGQ_MASK); 60817680Spst else 60917680Spst (void)printf("oack %d ", ack & SGQ_MASK); 61017680Spst } 61117680Spst } 61217680Spst } 61317680Spst break; 61417680Spst case MFS_IACK: 61517680Spst (void)printf("ils-ack %d>%d ", src, dst); 61617680Spst { 61717680Spst struct ackmsg *amp = (struct ackmsg *)nspp; 61817680Spst int ack; 61917680Spst 620147899Ssam if (nsplen < sizeof(struct ackmsg)) 621147899Ssam goto trunc; 622147899Ssam TCHECK(*amp); 62317680Spst ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); 62417680Spst if (ack & SGQ_ACK) { /* acknum field */ 62517680Spst if ((ack & SGQ_NAK) == SGQ_NAK) 62617680Spst (void)printf("nak %d ", ack & SGQ_MASK); 62717680Spst else 62817680Spst (void)printf("ack %d ", ack & SGQ_MASK); 629147899Ssam TCHECK(amp->ak_acknum[1]); 63017680Spst ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); 63117680Spst if (ack & SGQ_OACK) { /* ackdat field */ 63217680Spst if ((ack & SGQ_ONAK) == SGQ_ONAK) 63317680Spst (void)printf("nakdat %d ", ack & SGQ_MASK); 63417680Spst else 63517680Spst (void)printf("ackdat %d ", ack & SGQ_MASK); 63617680Spst } 63717680Spst } 63817680Spst } 63917680Spst break; 64017680Spst case MFS_CACK: 64117680Spst (void)printf("conn-ack %d", dst); 64217680Spst break; 64317680Spst default: 64417680Spst (void)printf("reserved-acktype? %x %d > %d", flags, src, dst); 64517680Spst break; 64617680Spst } 64717680Spst break; 64817680Spst case MFT_CTL: 64917680Spst switch (flags & NSP_SUBMASK) { 65017680Spst case MFS_CI: 65117680Spst case MFS_RCI: 65217680Spst if ((flags & NSP_SUBMASK) == MFS_CI) 65317680Spst (void)printf("conn-initiate "); 65417680Spst else 65517680Spst (void)printf("retrans-conn-initiate "); 65617680Spst (void)printf("%d>%d ", src, dst); 65717680Spst { 65817680Spst struct cimsg *cimp = (struct cimsg *)nspp; 65917680Spst int services, info, segsize; 66017680Spst#ifdef PRINT_NSPDATA 66117680Spst u_char *dp; 66217680Spst#endif 66317680Spst 664147899Ssam if (nsplen < sizeof(struct cimsg)) 665147899Ssam goto trunc; 666147899Ssam TCHECK(*cimp); 66717680Spst services = EXTRACT_LE_8BITS(cimp->ci_services); 66817680Spst info = EXTRACT_LE_8BITS(cimp->ci_info); 66917680Spst segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); 67017680Spst 67117680Spst switch (services & COS_MASK) { 67217680Spst case COS_NONE: 67317680Spst break; 67417680Spst case COS_SEGMENT: 67517680Spst (void)printf("seg "); 67617680Spst break; 67717680Spst case COS_MESSAGE: 67817680Spst (void)printf("msg "); 67917680Spst break; 68017680Spst case COS_CRYPTSER: 68117680Spst (void)printf("crypt "); 68217680Spst break; 68317680Spst } 68417680Spst switch (info & COI_MASK) { 68517680Spst case COI_32: 68617680Spst (void)printf("ver 3.2 "); 68717680Spst break; 68817680Spst case COI_31: 68917680Spst (void)printf("ver 3.1 "); 69017680Spst break; 69117680Spst case COI_40: 69217680Spst (void)printf("ver 4.0 "); 69317680Spst break; 69417680Spst case COI_41: 69517680Spst (void)printf("ver 4.1 "); 69617680Spst break; 69717680Spst } 69817680Spst (void)printf("segsize %d ", segsize); 69917680Spst#ifdef PRINT_NSPDATA 700147899Ssam if (nsplen > sizeof(struct cimsg)) { 701147899Ssam dp = &(nspp[sizeof(struct cimsg)]); 702147899Ssam TCHECK2(*dp, nsplen - sizeof(struct cimsg)); 703147899Ssam pdata(dp, nsplen - sizeof(struct cimsg)); 704147899Ssam } 70517680Spst#endif 70617680Spst } 70717680Spst break; 70817680Spst case MFS_CC: 70917680Spst (void)printf("conn-confirm %d>%d ", src, dst); 71017680Spst { 71117680Spst struct ccmsg *ccmp = (struct ccmsg *)nspp; 71217680Spst int services, info; 71317680Spst u_int segsize, optlen; 71417680Spst#ifdef PRINT_NSPDATA 71517680Spst u_char *dp; 71617680Spst#endif 71717680Spst 718147899Ssam if (nsplen < sizeof(struct ccmsg)) 719147899Ssam goto trunc; 720147899Ssam TCHECK(*ccmp); 72117680Spst services = EXTRACT_LE_8BITS(ccmp->cc_services); 72217680Spst info = EXTRACT_LE_8BITS(ccmp->cc_info); 72317680Spst segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); 72417680Spst optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); 72517680Spst 72617680Spst switch (services & COS_MASK) { 72717680Spst case COS_NONE: 72817680Spst break; 72917680Spst case COS_SEGMENT: 73017680Spst (void)printf("seg "); 73117680Spst break; 73217680Spst case COS_MESSAGE: 73317680Spst (void)printf("msg "); 73417680Spst break; 73517680Spst case COS_CRYPTSER: 73617680Spst (void)printf("crypt "); 73717680Spst break; 73817680Spst } 73917680Spst switch (info & COI_MASK) { 74017680Spst case COI_32: 74117680Spst (void)printf("ver 3.2 "); 74217680Spst break; 74317680Spst case COI_31: 74417680Spst (void)printf("ver 3.1 "); 74517680Spst break; 74617680Spst case COI_40: 74717680Spst (void)printf("ver 4.0 "); 74817680Spst break; 74917680Spst case COI_41: 75017680Spst (void)printf("ver 4.1 "); 75117680Spst break; 75217680Spst } 75317680Spst (void)printf("segsize %d ", segsize); 75417680Spst if (optlen) { 75517680Spst (void)printf("optlen %d ", optlen); 75617680Spst#ifdef PRINT_NSPDATA 757147899Ssam if (optlen > nsplen - sizeof(struct ccmsg)) 758147899Ssam goto trunc; 75917680Spst dp = &(nspp[sizeof(struct ccmsg)]); 760147899Ssam TCHECK2(*dp, optlen); 76117680Spst pdata(dp, optlen); 76217680Spst#endif 76317680Spst } 76417680Spst } 76517680Spst break; 76617680Spst case MFS_DI: 76717680Spst (void)printf("disconn-initiate %d>%d ", src, dst); 76817680Spst { 76917680Spst struct dimsg *dimp = (struct dimsg *)nspp; 77017680Spst int reason; 77117680Spst u_int optlen; 77217680Spst#ifdef PRINT_NSPDATA 77317680Spst u_char *dp; 77417680Spst#endif 77517680Spst 776147899Ssam if (nsplen < sizeof(struct dimsg)) 777147899Ssam goto trunc; 778147899Ssam TCHECK(*dimp); 77917680Spst reason = EXTRACT_LE_16BITS(dimp->di_reason); 78017680Spst optlen = EXTRACT_LE_8BITS(dimp->di_optlen); 78117680Spst 78217680Spst print_reason(reason); 78317680Spst if (optlen) { 78417680Spst (void)printf("optlen %d ", optlen); 78517680Spst#ifdef PRINT_NSPDATA 786147899Ssam if (optlen > nsplen - sizeof(struct dimsg)) 787147899Ssam goto trunc; 78817680Spst dp = &(nspp[sizeof(struct dimsg)]); 789147899Ssam TCHECK2(*dp, optlen); 79017680Spst pdata(dp, optlen); 79117680Spst#endif 79217680Spst } 79317680Spst } 79417680Spst break; 79517680Spst case MFS_DC: 79617680Spst (void)printf("disconn-confirm %d>%d ", src, dst); 79717680Spst { 79817680Spst struct dcmsg *dcmp = (struct dcmsg *)nspp; 79917680Spst int reason; 80017680Spst 801147899Ssam TCHECK(*dcmp); 80217680Spst reason = EXTRACT_LE_16BITS(dcmp->dc_reason); 80317680Spst 80417680Spst print_reason(reason); 80517680Spst } 80617680Spst break; 80717680Spst default: 80817680Spst (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst); 80917680Spst break; 81017680Spst } 81117680Spst break; 81217680Spst default: 81317680Spst (void)printf("reserved-type? %x %d > %d", flags, src, dst); 81417680Spst break; 81517680Spst } 816147899Ssam return (1); 817147899Ssam 818147899Ssamtrunc: 819147899Ssam return (0); 82017680Spst} 82117680Spst 82217680Spststatic struct tok reason2str[] = { 82317680Spst { UC_OBJREJECT, "object rejected connect" }, 82417680Spst { UC_RESOURCES, "insufficient resources" }, 82517680Spst { UC_NOSUCHNODE, "unrecognized node name" }, 82617680Spst { DI_SHUT, "node is shutting down" }, 82717680Spst { UC_NOSUCHOBJ, "unrecognized object" }, 82817680Spst { UC_INVOBJFORMAT, "invalid object name format" }, 82917680Spst { UC_OBJTOOBUSY, "object too busy" }, 83017680Spst { DI_PROTOCOL, "protocol error discovered" }, 83117680Spst { DI_TPA, "third party abort" }, 83217680Spst { UC_USERABORT, "user abort" }, 83317680Spst { UC_INVNODEFORMAT, "invalid node name format" }, 83417680Spst { UC_LOCALSHUT, "local node shutting down" }, 83517680Spst { DI_LOCALRESRC, "insufficient local resources" }, 83617680Spst { DI_REMUSERRESRC, "insufficient remote user resources" }, 83717680Spst { UC_ACCESSREJECT, "invalid access control information" }, 83817680Spst { DI_BADACCNT, "bad ACCOUNT information" }, 83917680Spst { UC_NORESPONSE, "no response from object" }, 84017680Spst { UC_UNREACHABLE, "node unreachable" }, 84117680Spst { DC_NOLINK, "no link terminate" }, 84217680Spst { DC_COMPLETE, "disconnect complete" }, 84317680Spst { DI_BADIMAGE, "bad image data in connect" }, 84417680Spst { DI_SERVMISMATCH, "cryptographic service mismatch" }, 84517680Spst { 0, NULL } 84617680Spst}; 84717680Spst 84817680Spststatic void 84917680Spstprint_reason(register int reason) 85017680Spst{ 85117680Spst printf("%s ", tok2str(reason2str, "reason-%d", reason)); 85217680Spst} 85317680Spst 85498524Sfennerconst char * 85517680Spstdnnum_string(u_short dnaddr) 85617680Spst{ 85717680Spst char *str; 85875115Sfenner size_t siz; 85926180Sfenner int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; 86017680Spst int node = dnaddr & NODEMASK; 86117680Spst 86275115Sfenner str = (char *)malloc(siz = sizeof("00.0000")); 86317680Spst if (str == NULL) 86417680Spst error("dnnum_string: malloc"); 86575115Sfenner snprintf(str, siz, "%d.%d", area, node); 86617680Spst return(str); 86717680Spst} 86817680Spst 86998524Sfennerconst char * 87017680Spstdnname_string(u_short dnaddr) 87117680Spst{ 872127668Sbms#ifdef HAVE_DNET_HTOA 87317680Spst struct dn_naddr dna; 87417680Spst 87517680Spst dna.a_len = sizeof(short); 87617680Spst memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); 87798524Sfenner return (strdup(dnet_htoa(&dna))); 87817680Spst#else 87917680Spst return(dnnum_string(dnaddr)); /* punt */ 88017680Spst#endif 88117680Spst} 88217680Spst 88317680Spst#ifdef PRINT_NSPDATA 88417680Spststatic void 88517680Spstpdata(u_char *dp, u_int maxlen) 88617680Spst{ 88717680Spst char c; 88817680Spst u_int x = maxlen; 88917680Spst 89017680Spst while (x-- > 0) { 89117680Spst c = *dp++; 89298524Sfenner safeputchar(c); 89317680Spst } 89417680Spst} 89517680Spst#endif 896