print-decnet.c revision 17680
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1992, 1993, 1994, 1995, 1996
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that: (1) source code distributions
71590Srgrimes * retain the above copyright notice and this paragraph in its entirety, (2)
81590Srgrimes * distributions including binary code include the above copyright notice and
91590Srgrimes * this paragraph in its entirety in the documentation or other materials
101590Srgrimes * provided with the distribution, and (3) all advertising materials mentioning
111590Srgrimes * features or use of this software display the following acknowledgement:
121590Srgrimes * ``This product includes software developed by the University of California,
131590Srgrimes * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
141590Srgrimes * the University nor the names of its contributors may be used to endorse
151590Srgrimes * or promote products derived from this software without specific prior
161590Srgrimes * written permission.
171590Srgrimes * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
181590Srgrimes * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
191590Srgrimes * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
201590Srgrimes */
211590Srgrimes
221590Srgrimes#ifndef lint
231590Srgrimesstatic char rcsid[] =
241590Srgrimes    "@(#) $Header: print-decnet.c,v 1.22 96/07/23 14:17:22 leres Exp $ (LBL)";
251590Srgrimes#endif
261590Srgrimes
271590Srgrimes#include <sys/param.h>
281590Srgrimes#include <sys/time.h>
291590Srgrimes#include <sys/socket.h>
301590Srgrimes
311590Srgrimes#if __STDC__
321590Srgrimesstruct mbuf;
331590Srgrimesstruct rtentry;
341590Srgrimes#endif
3528693Scharnier#include <net/if.h>
361590Srgrimes
371590Srgrimes#ifdef	HAVE_LIBDNET
38123441Sbde#include <netdnet/dnetdb.h>
391590Srgrimes#endif
40123441Sbde
411590Srgrimes#include <ctype.h>
42123441Sbde#include <stdio.h>
43123441Sbde#include <stdlib.h>
4428693Scharnier#include <string.h>
451590Srgrimes#include <unistd.h>
46123441Sbde
47123441Sbde#include "decnet.h"
48123441Sbde#include "extract.h"
491590Srgrimes#include "interface.h"
501590Srgrimes#include "addrtoname.h"
511590Srgrimes
5212811Sbde/* Forwards */
531590Srgrimesstatic void print_decnet_ctlmsg(const union routehdr *, u_int);
541590Srgrimesstatic void print_t_info(int);
551590Srgrimesstatic void print_l1_routes(const char *, u_int);
561590Srgrimesstatic void print_l2_routes(const char *, u_int);
571590Srgrimesstatic void print_i_info(int);
58111008Sphkstatic void print_elist(const char *, u_int);
591590Srgrimesstatic void print_nsp(const u_char *, u_int);
6012804Speterstatic void print_reason(int);
6112811Sbde#ifdef	PRINT_NSPDATA
6212811Sbdestatic void pdata(u_char *, int);
6312811Sbde#endif
6428693Scharnier
6587690Smarkm#ifdef	HAVE_LIBDNET
6628693Scharnierextern char *dnet_htoa(struct dn_naddr *);
6728693Scharnier#endif
6828693Scharnier
6928693Scharniervoid
701590Srgrimesdecnet_print(register const u_char *ap, register u_int length,
7128693Scharnier	     register u_int caplen)
721590Srgrimes{
731590Srgrimes	static union routehdr rhcopy;
741590Srgrimes	register union routehdr *rhp = &rhcopy;
7530180Sdima	register int mflags;
7628693Scharnier	int dst, src, hops;
7728693Scharnier	u_int rhlen, nsplen, pktlen;
781590Srgrimes	const u_char *nspp;
7987690Smarkm
8087690Smarkm	if (length < sizeof(struct shorthdr)) {
8187690Smarkm		(void)printf("[|decnet]");
821590Srgrimes		return;
831590Srgrimes	}
8439230Sgibbs
851590Srgrimes	pktlen = EXTRACT_LE_16BITS(ap);
8639230Sgibbs
871590Srgrimes	rhlen = min(length, caplen);
8839230Sgibbs	rhlen = min(rhlen, sizeof(*rhp));
891590Srgrimes	memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
9039230Sgibbs
911590Srgrimes	mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
9239230Sgibbs
931590Srgrimes	if (mflags & RMF_PAD) {
9439230Sgibbs	    /* pad bytes of some sort in front of message */
951590Srgrimes	    u_int padlen = mflags & RMF_PADMASK;
9639230Sgibbs	    if (vflag)
971590Srgrimes		(void) printf("[pad:%d] ", padlen);
9839230Sgibbs	    ap += padlen;
991590Srgrimes	    length -= padlen;
10039230Sgibbs	    caplen -= padlen;
1011590Srgrimes	    rhlen = min(length, caplen);
102131300Sgreen	    rhlen = min(rhlen, sizeof(*rhp));
103131300Sgreen	    memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
104131300Sgreen	    mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
105131300Sgreen	}
10630180Sdima
107131300Sgreen	if (mflags & RMF_FVER) {
1081590Srgrimes		(void) printf("future-version-decnet");
109131300Sgreen		default_print(ap, length);
1101590Srgrimes		return;
111131300Sgreen	}
1121590Srgrimes
113131300Sgreen	/* is it a control message? */
1141590Srgrimes	if (mflags & RMF_CTLMSG) {
115131300Sgreen		print_decnet_ctlmsg(rhp, min(length, caplen));
11692653Sjeff		return;
117131300Sgreen	}
1181590Srgrimes
1191590Srgrimes	switch (mflags & RMF_MASK) {
1201590Srgrimes	case RMF_LONG:
1211590Srgrimes	    dst =
122123250Sdes		EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
123123250Sdes	    src =
124123250Sdes		EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
125123250Sdes	    hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
126123250Sdes	    nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
127123250Sdes	    nsplen = min((length - sizeof(struct longhdr)),
128123250Sdes			 (caplen - sizeof(struct longhdr)));
129123250Sdes	    break;
130123250Sdes	case RMF_SHORT:
131123250Sdes	    dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
132123250Sdes	    src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
1331590Srgrimes	    hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
134123250Sdes	    nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
1351590Srgrimes	    nsplen = min((length - sizeof(struct shorthdr)),
136123250Sdes			 (caplen - sizeof(struct shorthdr)));
137123250Sdes	    break;
138123250Sdes	default:
1391590Srgrimes	    (void) printf("unknown message flags under mask");
140123250Sdes	    default_print((u_char *)ap, length);
1411590Srgrimes	    return;
1421590Srgrimes	}
1431590Srgrimes
1441590Srgrimes	(void)printf("%s > %s %d ",
1451590Srgrimes			dnaddr_string(src), dnaddr_string(dst), pktlen);
1461590Srgrimes	if (vflag) {
1471590Srgrimes	    if (mflags & RMF_RQR)
14843962Sdillon		(void)printf("RQR ");
1491590Srgrimes	    if (mflags & RMF_RTS)
15092922Simp		(void)printf("RTS ");
15192922Simp	    if (mflags & RMF_IE)
152122300Sjmg		(void)printf("IE ");
15392922Simp	    (void)printf("%d hops ", hops);
15492922Simp	}
15592922Simp
156123401Sdwmalone	print_nsp(nspp, nsplen);
157123407Sdes}
15892922Simp
15992922Simpstatic void
160131300Sgreenprint_decnet_ctlmsg(register const union routehdr *rhp, u_int length)
161131300Sgreen{
16292922Simp	int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
16392922Simp	register union controlmsg *cmp = (union controlmsg *)rhp;
16492922Simp	int src, dst, info, blksize, eco, ueco, hello, other, vers;
1651590Srgrimes	etheraddr srcea, rtea;
16692922Simp	int priority;
16792922Simp	char *rhpx = (char *)rhp;
16887690Smarkm
169123250Sdes	switch (mflags & RMF_CTLMASK) {
17087690Smarkm	case RMF_INIT:
17128693Scharnier	    (void)printf("init ");
172123250Sdes	    src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
1731590Srgrimes	    info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
17487690Smarkm	    blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
175123407Sdes	    vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
1761590Srgrimes	    eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
1771590Srgrimes	    ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
17878474Sschweikh	    hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
1791590Srgrimes	    print_t_info(info);
1801590Srgrimes	    (void)printf(
1811590Srgrimes		"src %sblksize %d vers %d eco %d ueco %d hello %d",
18243822Sken			dnaddr_string(src), blksize, vers, eco, ueco,
183123250Sdes			hello);
1841590Srgrimes	    break;
185123250Sdes	case RMF_VER:
186123250Sdes	    (void)printf("verification ");
187123250Sdes	    src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
1881590Srgrimes	    other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
1891590Srgrimes	    (void)printf("src %s fcnval %o", dnaddr_string(src), other);
1901590Srgrimes	    break;
1911590Srgrimes	case RMF_TEST:
192113460Stjr	    (void)printf("test ");
1931590Srgrimes	    src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
1941590Srgrimes	    other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
1951590Srgrimes	    (void)printf("src %s data %o", dnaddr_string(src), other);
1961590Srgrimes	    break;
1971590Srgrimes	case RMF_L1ROUT:
1981590Srgrimes	    (void)printf("lev-1-routing ");
1991590Srgrimes	    src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
2001590Srgrimes	    (void)printf("src %s ", dnaddr_string(src));
2011590Srgrimes	    print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
2021590Srgrimes				length - sizeof(struct l1rout));
2031590Srgrimes	    break;
2041590Srgrimes	case RMF_L2ROUT:
2051590Srgrimes	    (void)printf("lev-2-routing ");
20639230Sgibbs	    src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
20739372Sdillon	    (void)printf("src %s ", dnaddr_string(src));
20839230Sgibbs	    print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
20939230Sgibbs				length - sizeof(struct l2rout));
21039230Sgibbs	    break;
21139230Sgibbs	case RMF_RHELLO:
21239230Sgibbs	    (void)printf("router-hello ");
21339230Sgibbs	    vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
214112284Sphk	    eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
21539230Sgibbs	    ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
21639230Sgibbs	    memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
2171590Srgrimes		sizeof(srcea));
2181590Srgrimes	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
2191590Srgrimes	    info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
2201590Srgrimes	    blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
22130180Sdima	    priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
2221590Srgrimes	    hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
22330180Sdima	    print_i_info(info);
22430180Sdima	    (void)printf(
22530180Sdima	    "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
2261590Srgrimes			vers, eco, ueco, dnaddr_string(src),
2271590Srgrimes			blksize, priority, hello);
2281590Srgrimes	    print_elist(&(rhpx[sizeof(struct rhellomsg)]),
2291590Srgrimes				length - sizeof(struct rhellomsg));
23044067Sbde	    break;
23144067Sbde	case RMF_EHELLO:
23244067Sbde	    (void)printf("endnode-hello ");
2331590Srgrimes	    vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
2341590Srgrimes	    eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
2351590Srgrimes	    ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
2361590Srgrimes	    memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
2371590Srgrimes		sizeof(srcea));
2381590Srgrimes	    src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
2391590Srgrimes	    info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
2401590Srgrimes	    blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
2411590Srgrimes	    /*seed*/
2421590Srgrimes	    memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
2431590Srgrimes		sizeof(rtea));
244123250Sdes	    dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
245123250Sdes	    hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
246123250Sdes	    other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
247123250Sdes	    print_i_info(info);
248123250Sdes	    (void)printf(
2491590Srgrimes	"vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
250123250Sdes			vers, eco, ueco, dnaddr_string(src),
2511590Srgrimes			blksize, dnaddr_string(dst), hello, other);
25228693Scharnier	    break;
2531590Srgrimes
254123250Sdes	default:
255123250Sdes	    (void)printf("unknown control message");
2561590Srgrimes	    default_print((u_char *)rhp, length);
25781537Sken	    break;
2581590Srgrimes	}
2591590Srgrimes}
2601590Srgrimes
26128693Scharnierstatic void
2621590Srgrimesprint_t_info(int info)
2631590Srgrimes{
2641590Srgrimes	int ntype = info & 3;
2651590Srgrimes	switch (ntype) {
2661590Srgrimes	case 0: (void)printf("reserved-ntype? "); break;
2671590Srgrimes	case TI_L2ROUT: (void)printf("l2rout "); break;
26843819Sken	case TI_L1ROUT: (void)printf("l1rout "); break;
26943819Sken	case TI_ENDNODE: (void)printf("endnode "); break;
27043819Sken	}
27143819Sken	if (info & TI_VERIF)
27243819Sken	    (void)printf("verif ");
273112284Sphk	if (info & TI_BLOCK)
27443819Sken	    (void)printf("blo ");
27543819Sken}
27643819Sken
2771590Srgrimesstatic void
2781590Srgrimesprint_l1_routes(const char *rp, u_int len)
2791590Srgrimes{
2801590Srgrimes	int count;
2811590Srgrimes	int id;
2821590Srgrimes	int info;
2831590Srgrimes
2841590Srgrimes	/* The last short is a checksum */
2851590Srgrimes	while (len > (3 * sizeof(short))) {
2861590Srgrimes	    count = EXTRACT_LE_16BITS(rp);
2871590Srgrimes	    if (count > 1024)
2881590Srgrimes		return;	/* seems to be bogus from here on */
2891590Srgrimes	    rp += sizeof(short);
2901590Srgrimes	    len -= sizeof(short);
2911590Srgrimes	    id = EXTRACT_LE_16BITS(rp);
2921590Srgrimes	    rp += sizeof(short);
2931590Srgrimes	    len -= sizeof(short);
2941590Srgrimes	    info = EXTRACT_LE_16BITS(rp);
2951590Srgrimes	    rp += sizeof(short);
2961590Srgrimes	    len -= sizeof(short);
2971590Srgrimes	    (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
2981590Srgrimes			    RI_COST(info), RI_HOPS(info));
2991590Srgrimes	}
3001590Srgrimes}
3011590Srgrimes
3021590Srgrimesstatic void
3031590Srgrimesprint_l2_routes(const char *rp, u_int len)
30443962Sdillon{
30543962Sdillon	int count;
3061590Srgrimes	int area;
3071590Srgrimes	int info;
30830180Sdima
3091590Srgrimes	/* The last short is a checksum */
3101590Srgrimes	while (len > (3 * sizeof(short))) {
3111590Srgrimes	    count = EXTRACT_LE_16BITS(rp);
3121590Srgrimes	    if (count > 1024)
3131590Srgrimes		return;	/* seems to be bogus from here on */
3141590Srgrimes	    rp += sizeof(short);
3151590Srgrimes	    len -= sizeof(short);
3161590Srgrimes	    area = EXTRACT_LE_16BITS(rp);
3171590Srgrimes	    rp += sizeof(short);
3181590Srgrimes	    len -= sizeof(short);
319123250Sdes	    info = EXTRACT_LE_16BITS(rp);
320123250Sdes	    rp += sizeof(short);
321123250Sdes	    len -= sizeof(short);
3221590Srgrimes	    (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
323123250Sdes			    RI_COST(info), RI_HOPS(info));
324123250Sdes	}
325123250Sdes}
326123250Sdes
327123250Sdesstatic void
328123250Sdesprint_i_info(int info)
329123250Sdes{
330123250Sdes	int ntype = info & II_TYPEMASK;
331123250Sdes	switch (ntype) {
332123250Sdes	case 0: (void)printf("reserved-ntype? "); break;
333123250Sdes	case II_L2ROUT: (void)printf("l2rout "); break;
334112284Sphk	case II_L1ROUT: (void)printf("l1rout "); break;
33539230Sgibbs	case II_ENDNODE: (void)printf("endnode "); break;
3361590Srgrimes	}
33739230Sgibbs	if (info & II_VERIF)
33839230Sgibbs	    (void)printf("verif ");
33939230Sgibbs	if (info & II_NOMCAST)
34039230Sgibbs	    (void)printf("nomcast ");
34139230Sgibbs	if (info & II_BLOCK)
342112284Sphk	    (void)printf("blo ");
34339230Sgibbs}
34439230Sgibbs
34539230Sgibbsstatic void
34639230Sgibbsprint_elist(const char *elp, u_int len)
34739230Sgibbs{
34839230Sgibbs	/* Not enough examples available for me to debug this */
34939230Sgibbs}
3501590Srgrimes
3511590Srgrimesstatic void
35239230Sgibbsprint_nsp(const u_char *nspp, u_int nsplen)
35339230Sgibbs{
35439230Sgibbs	const struct nsphdr *nsphp = (struct nsphdr *)nspp;
35539230Sgibbs	int dst, src, flags;
35639230Sgibbs
3571590Srgrimes	flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
35839230Sgibbs	dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
35939230Sgibbs	src = EXTRACT_LE_16BITS(nsphp->nh_src);
36039372Sdillon
36139372Sdillon	switch (flags & NSP_TYPEMASK) {
36239372Sdillon	case MFT_DATA:
36339230Sgibbs	    switch (flags & NSP_SUBMASK) {
36439230Sgibbs	    case MFS_BOM:
36539230Sgibbs	    case MFS_MOM:
36639230Sgibbs	    case MFS_EOM:
36739230Sgibbs	    case MFS_BOM+MFS_EOM:
36839230Sgibbs		printf("data %d>%d ", src, dst);
36939230Sgibbs		{
37039230Sgibbs		    struct seghdr *shp = (struct seghdr *)nspp;
37139230Sgibbs		    int ack;
37239230Sgibbs#ifdef	PRINT_NSPDATA
37339230Sgibbs		    u_char *dp;
374112284Sphk#endif
37539230Sgibbs		    u_int data_off = sizeof(struct minseghdr);
37639230Sgibbs
37739230Sgibbs		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
37839230Sgibbs		    if (ack & SGQ_ACK) {	/* acknum field */
37939230Sgibbs			if ((ack & SGQ_NAK) == SGQ_NAK)
38039230Sgibbs			    (void)printf("nak %d ", ack & SGQ_MASK);
38139230Sgibbs			else
38239230Sgibbs			    (void)printf("ack %d ", ack & SGQ_MASK);
38339230Sgibbs		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
38439230Sgibbs			data_off += sizeof(short);
38539230Sgibbs			if (ack & SGQ_OACK) {	/* ackoth field */
386112284Sphk			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
38739230Sgibbs				(void)printf("onak %d ", ack & SGQ_MASK);
38839230Sgibbs			    else
38939230Sgibbs				(void)printf("oack %d ", ack & SGQ_MASK);
39039230Sgibbs			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
39139230Sgibbs			    data_off += sizeof(short);
39239230Sgibbs			}
3931590Srgrimes		    }
3941590Srgrimes		    (void)printf("seg %d ", ack & SGQ_MASK);
3951590Srgrimes#ifdef	PRINT_NSPDATA
396123250Sdes		    dp = &(nspp[data_off]);
397123250Sdes		    pdata(dp, 10);
3981590Srgrimes#endif
399101590Stmm		}
400101590Stmm		break;
4011590Srgrimes	    case MFS_ILS+MFS_INT:
4021590Srgrimes		printf("intr ");
403123250Sdes		{
404123250Sdes		    struct seghdr *shp = (struct seghdr *)nspp;
405123250Sdes		    int ack;
406123250Sdes#ifdef	PRINT_NSPDATA
407123250Sdes		    u_char *dp;
408123250Sdes#endif
409123250Sdes		    u_int data_off = sizeof(struct minseghdr);
410123250Sdes
411123250Sdes		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
412123250Sdes		    if (ack & SGQ_ACK) {	/* acknum field */
413123250Sdes			if ((ack & SGQ_NAK) == SGQ_NAK)
414123250Sdes			    (void)printf("nak %d ", ack & SGQ_MASK);
4151590Srgrimes			else
416101590Stmm			    (void)printf("ack %d ", ack & SGQ_MASK);
41728693Scharnier		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
41828693Scharnier			data_off += sizeof(short);
4191590Srgrimes			if (ack & SGQ_OACK) {	/* ackdat field */
4201590Srgrimes			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
4211590Srgrimes				(void)printf("nakdat %d ", ack & SGQ_MASK);
422123250Sdes			    else
423123250Sdes				(void)printf("ackdat %d ", ack & SGQ_MASK);
424123250Sdes			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
425123250Sdes			    data_off += sizeof(short);
426123250Sdes			}
427123250Sdes		    }
428123250Sdes		    (void)printf("seg %d ", ack & SGQ_MASK);
429123250Sdes#ifdef	PRINT_NSPDATA
430123250Sdes		    dp = &(nspp[data_off]);
431123250Sdes		    pdata(dp, 10);
432123250Sdes#endif
433123250Sdes		}
434123250Sdes		break;
435123250Sdes	    case MFS_ILS:
436123250Sdes		(void)printf("link-service %d>%d ", src, dst);
4371590Srgrimes		{
438123250Sdes		    struct seghdr *shp = (struct seghdr *)nspp;
439123414Sdes		    struct lsmsg *lsmp =
440123414Sdes			(struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
441123414Sdes		    int ack;
442123414Sdes		    int lsflags, fcval;
443123414Sdes
444123414Sdes		    ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
445123414Sdes		    if (ack & SGQ_ACK) {	/* acknum field */
446123414Sdes			if ((ack & SGQ_NAK) == SGQ_NAK)
447123414Sdes			    (void)printf("nak %d ", ack & SGQ_MASK);
448123414Sdes			else
449123414Sdes			    (void)printf("ack %d ", ack & SGQ_MASK);
450123414Sdes		        ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
451123414Sdes			if (ack & SGQ_OACK) {	/* ackdat field */
452123414Sdes			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
453123414Sdes				(void)printf("nakdat %d ", ack & SGQ_MASK);
454123414Sdes			    else
455123414Sdes				(void)printf("ackdat %d ", ack & SGQ_MASK);
456123414Sdes			    ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
457123414Sdes			}
458123414Sdes		    }
459123414Sdes		    (void)printf("seg %d ", ack & SGQ_MASK);
460123414Sdes		    lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
461123414Sdes		    fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
462123414Sdes		    switch (lsflags & LSI_MASK) {
463123414Sdes		    case LSI_DATA:
464123414Sdes			(void)printf("dat seg count %d ", fcval);
465123414Sdes			switch (lsflags & LSM_MASK) {
466123414Sdes			case LSM_NOCHANGE:
467123414Sdes			    break;
468123414Sdes			case LSM_DONOTSEND:
469123414Sdes			    (void)printf("donotsend-data ");
470123414Sdes			    break;
471123414Sdes			case LSM_SEND:
472123414Sdes			    (void)printf("send-data ");
473123414Sdes			    break;
474123414Sdes			default:
475123250Sdes			    (void)printf("reserved-fcmod? %x", lsflags);
476123250Sdes			    break;
477123250Sdes			}
478123250Sdes			break;
479123250Sdes		    case LSI_INTR:
480123250Sdes			(void)printf("intr req count %d ", fcval);
481123250Sdes			break;
482123250Sdes		    default:
483123250Sdes			(void)printf("reserved-fcval-int? %x", lsflags);
484123250Sdes			break;
485123250Sdes		    }
486123250Sdes		}
487123250Sdes		break;
488123250Sdes	    default:
4891590Srgrimes		(void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
490123250Sdes		break;
491123250Sdes	    }
492123250Sdes	    break;
493123250Sdes	case MFT_ACK:
494123250Sdes	    switch (flags & NSP_SUBMASK) {
495123250Sdes	    case MFS_DACK:
496123250Sdes		(void)printf("data-ack %d>%d ", src, dst);
497123250Sdes		{
498123250Sdes		    struct ackmsg *amp = (struct ackmsg *)nspp;
499123250Sdes		    int ack;
500123250Sdes
501123250Sdes		    ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
502123250Sdes		    if (ack & SGQ_ACK) {	/* acknum field */
503123250Sdes			if ((ack & SGQ_NAK) == SGQ_NAK)
504123407Sdes			    (void)printf("nak %d ", ack & SGQ_MASK);
505123250Sdes			else
5061590Srgrimes			    (void)printf("ack %d ", ack & SGQ_MASK);
5071590Srgrimes		        ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
50839230Sgibbs			if (ack & SGQ_OACK) {	/* ackoth field */
50980551Stmm			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
5101590Srgrimes				(void)printf("onak %d ", ack & SGQ_MASK);
5111590Srgrimes			    else
5121590Srgrimes				(void)printf("oack %d ", ack & SGQ_MASK);
5131590Srgrimes			}
5141590Srgrimes		    }
515123250Sdes		}
516123250Sdes		break;
517123250Sdes	    case MFS_IACK:
518123250Sdes		(void)printf("ils-ack %d>%d ", src, dst);
519123250Sdes		{
520123250Sdes		    struct ackmsg *amp = (struct ackmsg *)nspp;
521123250Sdes		    int ack;
522123250Sdes
5231590Srgrimes		    ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
524123250Sdes		    if (ack & SGQ_ACK) {	/* acknum field */
525123250Sdes			if ((ack & SGQ_NAK) == SGQ_NAK)
526123250Sdes			    (void)printf("nak %d ", ack & SGQ_MASK);
527123250Sdes			else
528123250Sdes			    (void)printf("ack %d ", ack & SGQ_MASK);
529123250Sdes		        ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
530123250Sdes			if (ack & SGQ_OACK) {	/* ackdat field */
5311590Srgrimes			    if ((ack & SGQ_ONAK) == SGQ_ONAK)
5321590Srgrimes				(void)printf("nakdat %d ", ack & SGQ_MASK);
5331590Srgrimes			    else
534123250Sdes				(void)printf("ackdat %d ", ack & SGQ_MASK);
535123250Sdes			}
536123250Sdes		    }
537123250Sdes		}
538123250Sdes		break;
539123250Sdes	    case MFS_CACK:
540123250Sdes		(void)printf("conn-ack %d", dst);
541123250Sdes		break;
54239230Sgibbs	    default:
54339230Sgibbs		(void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
54439230Sgibbs		break;
54539230Sgibbs	    }
546112288Sphk	    break;
54739230Sgibbs	case MFT_CTL:
54839230Sgibbs	    switch (flags & NSP_SUBMASK) {
54939230Sgibbs	    case MFS_CI:
55039230Sgibbs	    case MFS_RCI:
55139230Sgibbs		if ((flags & NSP_SUBMASK) == MFS_CI)
55239230Sgibbs		    (void)printf("conn-initiate ");
55339230Sgibbs		else
55439230Sgibbs		    (void)printf("retrans-conn-initiate ");
555112284Sphk		(void)printf("%d>%d ", src, dst);
55639230Sgibbs		{
55739230Sgibbs		    struct cimsg *cimp = (struct cimsg *)nspp;
55839230Sgibbs		    int services, info, segsize;
55939230Sgibbs#ifdef	PRINT_NSPDATA
56039230Sgibbs		    u_char *dp;
56139230Sgibbs#endif
56239230Sgibbs
56339230Sgibbs		    services = EXTRACT_LE_8BITS(cimp->ci_services);
56439230Sgibbs		    info = EXTRACT_LE_8BITS(cimp->ci_info);
565112284Sphk		    segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
56639230Sgibbs
56739230Sgibbs		    switch (services & COS_MASK) {
56839230Sgibbs		    case COS_NONE:
56939230Sgibbs			break;
57039230Sgibbs		    case COS_SEGMENT:
57139230Sgibbs			(void)printf("seg ");
57239230Sgibbs			break;
57339230Sgibbs		    case COS_MESSAGE:
57439230Sgibbs			(void)printf("msg ");
57539230Sgibbs			break;
57639230Sgibbs		    case COS_CRYPTSER:
57739230Sgibbs			(void)printf("crypt ");
57839230Sgibbs			break;
57939230Sgibbs		    }
58039230Sgibbs		    switch (info & COI_MASK) {
58139230Sgibbs		    case COI_32:
58239230Sgibbs			(void)printf("ver 3.2 ");
58339230Sgibbs			break;
58439230Sgibbs		    case COI_31:
58539230Sgibbs			(void)printf("ver 3.1 ");
58639230Sgibbs			break;
587123250Sdes		    case COI_40:
588123250Sdes			(void)printf("ver 4.0 ");
58978672Sschweikh			break;
5901590Srgrimes		    case COI_41:
59172887Salfred			(void)printf("ver 4.1 ");
5921590Srgrimes			break;
59381537Sken		    }
59481537Sken		    (void)printf("segsize %d ", segsize);
59537453Sbde#ifdef	PRINT_NSPDATA
596123407Sdes		    dp = &(nspp[sizeof(struct cimsg)]);
5971590Srgrimes		    pdata(dp, nsplen - sizeof(struct cimsg));
598123407Sdes#endif
59937453Sbde		}
600123407Sdes		break;
6013659Sdg	    case MFS_CC:
60237453Sbde		(void)printf("conn-confirm %d>%d ", src, dst);
603123407Sdes		{
6043693Sdg		    struct ccmsg *ccmp = (struct ccmsg *)nspp;
60537453Sbde		    int services, info;
606123407Sdes		    u_int segsize, optlen;
60737453Sbde#ifdef	PRINT_NSPDATA
608123407Sdes		    u_char *dp;
60939230Sgibbs#endif
6101590Srgrimes
611123407Sdes		    services = EXTRACT_LE_8BITS(ccmp->cc_services);
612123407Sdes		    info = EXTRACT_LE_8BITS(ccmp->cc_info);
613123407Sdes		    segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
6141590Srgrimes		    optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
6151590Srgrimes
6161590Srgrimes		    switch (services & COS_MASK) {
6171590Srgrimes		    case COS_NONE:
6181590Srgrimes			break;
6191590Srgrimes		    case COS_SEGMENT:
6201590Srgrimes			(void)printf("seg ");
6211590Srgrimes			break;
6221590Srgrimes		    case COS_MESSAGE:
6231590Srgrimes			(void)printf("msg ");
6241590Srgrimes			break;
6253659Sdg		    case COS_CRYPTSER:
6263659Sdg			(void)printf("crypt ");
6273659Sdg			break;
6283659Sdg		    }
6291590Srgrimes		    switch (info & COI_MASK) {
6301590Srgrimes		    case COI_32:
6311590Srgrimes			(void)printf("ver 3.2 ");
6321590Srgrimes			break;
633123250Sdes		    case COI_31:
634123250Sdes			(void)printf("ver 3.1 ");
6351590Srgrimes			break;
63643822Sken		    case COI_40:
6371590Srgrimes			(void)printf("ver 4.0 ");
63843822Sken			break;
63978672Sschweikh		    case COI_41:
64043822Sken			(void)printf("ver 4.1 ");
64143822Sken			break;
64243822Sken		    }
64343822Sken		    (void)printf("segsize %d ", segsize);
64443822Sken		    if (optlen) {
64578672Sschweikh			(void)printf("optlen %d ", optlen);
64639230Sgibbs#ifdef	PRINT_NSPDATA
64739230Sgibbs			optlen = min(optlen, nsplen - sizeof(struct ccmsg));
64839230Sgibbs			dp = &(nspp[sizeof(struct ccmsg)]);
64939230Sgibbs			pdata(dp, optlen);
65039230Sgibbs#endif
65139230Sgibbs		    }
6521590Srgrimes		}
6531590Srgrimes		break;
6541590Srgrimes	    case MFS_DI:
6551590Srgrimes		(void)printf("disconn-initiate %d>%d ", src, dst);
6561590Srgrimes		{
6571590Srgrimes		    struct dimsg *dimp = (struct dimsg *)nspp;
6581590Srgrimes		    int reason;
659123250Sdes		    u_int optlen;
660123250Sdes#ifdef	PRINT_NSPDATA
6611590Srgrimes		    u_char *dp;
6621590Srgrimes#endif
6631590Srgrimes
6641590Srgrimes		    reason = EXTRACT_LE_16BITS(dimp->di_reason);
6651590Srgrimes		    optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
66630180Sdima
667123250Sdes		    print_reason(reason);
668123250Sdes		    if (optlen) {
6691590Srgrimes			(void)printf("optlen %d ", optlen);
670123407Sdes#ifdef	PRINT_NSPDATA
6711590Srgrimes			optlen = min(optlen, nsplen - sizeof(struct dimsg));
6721590Srgrimes			dp = &(nspp[sizeof(struct dimsg)]);
6731590Srgrimes			pdata(dp, optlen);
6741590Srgrimes#endif
6751590Srgrimes		    }
6761590Srgrimes		}
6771590Srgrimes		break;
6781590Srgrimes	    case MFS_DC:
6791590Srgrimes		(void)printf("disconn-confirm %d>%d ", src, dst);
6801590Srgrimes		{
6811590Srgrimes		    struct dcmsg *dcmp = (struct dcmsg *)nspp;
6821590Srgrimes		    int reason;
6831590Srgrimes
6841590Srgrimes		    reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
6851590Srgrimes
686123250Sdes		    print_reason(reason);
687123250Sdes		}
6881590Srgrimes		break;
6891590Srgrimes	    default:
6901590Srgrimes		(void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
6911590Srgrimes		break;
6921590Srgrimes	    }
6931590Srgrimes	    break;
6941590Srgrimes	default:
6951590Srgrimes	    (void)printf("reserved-type? %x %d > %d", flags, src, dst);
6961590Srgrimes	    break;
6971590Srgrimes	}
6981590Srgrimes}
699123250Sdes
700123250Sdesstatic struct tok reason2str[] = {
7011590Srgrimes	{ UC_OBJREJECT,		"object rejected connect" },
70287690Smarkm	{ UC_RESOURCES,		"insufficient resources" },
7031590Srgrimes	{ UC_NOSUCHNODE,	"unrecognized node name" },
7041590Srgrimes	{ DI_SHUT,		"node is shutting down" },
705123250Sdes	{ UC_NOSUCHOBJ,		"unrecognized object" },
7061590Srgrimes	{ UC_INVOBJFORMAT,	"invalid object name format" },
7071590Srgrimes	{ UC_OBJTOOBUSY,	"object too busy" },
7081590Srgrimes	{ DI_PROTOCOL,		"protocol error discovered" },
7091590Srgrimes	{ DI_TPA,		"third party abort" },
7101590Srgrimes	{ UC_USERABORT,		"user abort" },
71171429Sume	{ UC_INVNODEFORMAT,	"invalid node name format" },
71271429Sume	{ UC_LOCALSHUT,		"local node shutting down" },
71371429Sume	{ DI_LOCALRESRC,	"insufficient local resources" },
71471429Sume	{ DI_REMUSERRESRC,	"insufficient remote user resources" },
7153659Sdg	{ UC_ACCESSREJECT,	"invalid access control information" },
7163693Sdg	{ DI_BADACCNT,		"bad ACCOUNT information" },
7173659Sdg	{ UC_NORESPONSE,	"no response from object" },
7183659Sdg	{ UC_UNREACHABLE,	"node unreachable" },
7193659Sdg	{ DC_NOLINK,		"no link terminate" },
7203693Sdg	{ DC_COMPLETE,		"disconnect complete" },
7213659Sdg	{ DI_BADIMAGE,		"bad image data in connect" },
7223659Sdg	{ DI_SERVMISMATCH,	"cryptographic service mismatch" },
7233693Sdg	{ 0,			NULL }
7243693Sdg};
7251590Srgrimes
7267351Sdgstatic void
72734214Sdysonprint_reason(register int reason)
7287351Sdg{
72934214Sdyson	printf("%s ", tok2str(reason2str, "reason-%d", reason));
7301590Srgrimes}
7311590Srgrimes
73271429Sumechar *
73371429Sumednnum_string(u_short dnaddr)
73471429Sume{
73571429Sume	char *str;
7363693Sdg	int area = (dnaddr & AREAMASK) >> AREASHIFT;
7371590Srgrimes	int node = dnaddr & NODEMASK;
7381590Srgrimes
7391590Srgrimes	str = (char *)malloc(sizeof("00.0000"));
7401590Srgrimes	if (str == NULL)
7415463Sdg		error("dnnum_string: malloc");
7423693Sdg	sprintf(str, "%d.%d", area, node);
7433693Sdg	return(str);
7441590Srgrimes}
745123250Sdes
746123250Sdeschar *
747123250Sdesdnname_string(u_short dnaddr)
748123250Sdes{
749123250Sdes#ifdef	HAVE_LIBDNET
750123250Sdes	struct dn_naddr dna;
751123250Sdes
752123250Sdes	dna.a_len = sizeof(short);
75387690Smarkm	memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
75487690Smarkm	return (savestr(dnet_htoa(&dna)));
75587690Smarkm#else
7561590Srgrimes	return(dnnum_string(dnaddr));	/* punt */
7571590Srgrimes#endif
75828693Scharnier}
75987690Smarkm
76087690Smarkm#ifdef	PRINT_NSPDATA
76187690Smarkmstatic void
76228693Scharnierpdata(u_char *dp, u_int maxlen)
76387690Smarkm{
76487690Smarkm	char c;
76587690Smarkm	u_int x = maxlen;
7661590Srgrimes
7671590Srgrimes	while (x-- > 0) {
768123250Sdes	    c = *dp++;
769123250Sdes	    if (isprint(c))
7701590Srgrimes		putchar(c);
771123250Sdes	    else
772128573Stjr		printf("\\%o", c & 0xFF);
773113460Stjr	}
774113460Stjr}
775113460Stjr#endif
776128573Stjr