Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / tcpdump / print-decnet.c
blob2db70e5781c3a51a912d1441e681e814980dcbd3
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
24 #include <sys/cdefs.h>
25 #ifndef lint
26 #if 0
27 static const char rcsid[] _U_ =
28 "@(#) Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.38.2.1 2005/05/06 02:16:53 guy Exp (LBL)";
29 #else
30 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
31 #endif
32 #endif
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
38 #include <tcpdump-stdinc.h>
40 struct mbuf;
41 struct rtentry;
43 #ifdef HAVE_NETDNET_DNETDB_H
44 #include <netdnet/dnetdb.h>
45 #endif
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
51 #include "decnet.h"
52 #include "extract.h"
53 #include "interface.h"
54 #include "addrtoname.h"
56 /* Forwards */
57 static int print_decnet_ctlmsg(const union routehdr *, u_int, u_int);
58 static void print_t_info(int);
59 static int print_l1_routes(const char *, u_int);
60 static int print_l2_routes(const char *, u_int);
61 static void print_i_info(int);
62 static int print_elist(const char *, u_int);
63 static int print_nsp(const u_char *, u_int);
64 static void print_reason(int);
65 #ifdef PRINT_NSPDATA
66 static void pdata(u_char *, int);
67 #endif
69 #ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA
70 extern char *dnet_htoa(struct dn_naddr *);
71 #endif
73 void
74 decnet_print(register const u_char *ap, register u_int length,
75 register u_int caplen)
77 register const union routehdr *rhp;
78 register int mflags;
79 int dst, src, hops;
80 u_int nsplen, pktlen;
81 const u_char *nspp;
83 if (length < sizeof(struct shorthdr)) {
84 (void)printf("[|decnet]");
85 return;
88 TCHECK2(*ap, sizeof(short));
89 pktlen = EXTRACT_LE_16BITS(ap);
90 if (pktlen < sizeof(struct shorthdr)) {
91 (void)printf("[|decnet]");
92 return;
94 if (pktlen > length) {
95 (void)printf("[|decnet]");
96 return;
98 length = pktlen;
100 rhp = (const union routehdr *)&(ap[sizeof(short)]);
101 TCHECK(rhp->rh_short.sh_flags);
102 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
104 if (mflags & RMF_PAD) {
105 /* pad bytes of some sort in front of message */
106 u_int padlen = mflags & RMF_PADMASK;
107 if (vflag)
108 (void) printf("[pad:%d] ", padlen);
109 if (length < padlen + 2) {
110 (void)printf("[|decnet]");
111 return;
113 TCHECK2(ap[sizeof(short)], padlen);
114 ap += padlen;
115 length -= padlen;
116 caplen -= padlen;
117 rhp = (const union routehdr *)&(ap[sizeof(short)]);
118 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
121 if (mflags & RMF_FVER) {
122 (void) printf("future-version-decnet");
123 default_print(ap, min(length, caplen));
124 return;
127 /* is it a control message? */
128 if (mflags & RMF_CTLMSG) {
129 if (!print_decnet_ctlmsg(rhp, length, caplen))
130 goto trunc;
131 return;
134 switch (mflags & RMF_MASK) {
135 case RMF_LONG:
136 if (length < sizeof(struct longhdr)) {
137 (void)printf("[|decnet]");
138 return;
140 TCHECK(rhp->rh_long);
141 dst =
142 EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
143 src =
144 EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
145 hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
146 nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
147 nsplen = length - sizeof(struct longhdr);
148 break;
149 case RMF_SHORT:
150 TCHECK(rhp->rh_short);
151 dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
152 src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
153 hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
154 nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
155 nsplen = length - sizeof(struct shorthdr);
156 break;
157 default:
158 (void) printf("unknown message flags under mask");
159 default_print((u_char *)ap, min(length, caplen));
160 return;
163 (void)printf("%s > %s %d ",
164 dnaddr_string(src), dnaddr_string(dst), pktlen);
165 if (vflag) {
166 if (mflags & RMF_RQR)
167 (void)printf("RQR ");
168 if (mflags & RMF_RTS)
169 (void)printf("RTS ");
170 if (mflags & RMF_IE)
171 (void)printf("IE ");
172 (void)printf("%d hops ", hops);
175 if (!print_nsp(nspp, nsplen))
176 goto trunc;
177 return;
179 trunc:
180 (void)printf("[|decnet]");
181 return;
184 static int
185 print_decnet_ctlmsg(register const union routehdr *rhp, u_int length,
186 u_int caplen)
188 int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
189 register union controlmsg *cmp = (union controlmsg *)rhp;
190 int src, dst, info, blksize, eco, ueco, hello, other, vers;
191 etheraddr srcea, rtea;
192 int priority;
193 char *rhpx = (char *)rhp;
194 int ret;
196 switch (mflags & RMF_CTLMASK) {
197 case RMF_INIT:
198 (void)printf("init ");
199 if (length < sizeof(struct initmsg))
200 goto trunc;
201 TCHECK(cmp->cm_init);
202 src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
203 info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
204 blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
205 vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
206 eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
207 ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
208 hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
209 print_t_info(info);
210 (void)printf(
211 "src %sblksize %d vers %d eco %d ueco %d hello %d",
212 dnaddr_string(src), blksize, vers, eco, ueco,
213 hello);
214 ret = 1;
215 break;
216 case RMF_VER:
217 (void)printf("verification ");
218 if (length < sizeof(struct verifmsg))
219 goto trunc;
220 TCHECK(cmp->cm_ver);
221 src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
222 other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
223 (void)printf("src %s fcnval %o", dnaddr_string(src), other);
224 ret = 1;
225 break;
226 case RMF_TEST:
227 (void)printf("test ");
228 if (length < sizeof(struct testmsg))
229 goto trunc;
230 TCHECK(cmp->cm_test);
231 src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
232 other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
233 (void)printf("src %s data %o", dnaddr_string(src), other);
234 ret = 1;
235 break;
236 case RMF_L1ROUT:
237 (void)printf("lev-1-routing ");
238 if (length < sizeof(struct l1rout))
239 goto trunc;
240 TCHECK(cmp->cm_l1rou);
241 src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
242 (void)printf("src %s ", dnaddr_string(src));
243 ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
244 length - sizeof(struct l1rout));
245 break;
246 case RMF_L2ROUT:
247 (void)printf("lev-2-routing ");
248 if (length < sizeof(struct l2rout))
249 goto trunc;
250 TCHECK(cmp->cm_l2rout);
251 src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
252 (void)printf("src %s ", dnaddr_string(src));
253 ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
254 length - sizeof(struct l2rout));
255 break;
256 case RMF_RHELLO:
257 (void)printf("router-hello ");
258 if (length < sizeof(struct rhellomsg))
259 goto trunc;
260 TCHECK(cmp->cm_rhello);
261 vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
262 eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
263 ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
264 memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
265 sizeof(srcea));
266 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
267 info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
268 blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
269 priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
270 hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
271 print_i_info(info);
272 (void)printf(
273 "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
274 vers, eco, ueco, dnaddr_string(src),
275 blksize, priority, hello);
276 ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]),
277 length - sizeof(struct rhellomsg));
278 break;
279 case RMF_EHELLO:
280 (void)printf("endnode-hello ");
281 if (length < sizeof(struct ehellomsg))
282 goto trunc;
283 TCHECK(cmp->cm_ehello);
284 vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
285 eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
286 ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
287 memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
288 sizeof(srcea));
289 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
290 info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
291 blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
292 /*seed*/
293 memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
294 sizeof(rtea));
295 dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
296 hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
297 other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
298 print_i_info(info);
299 (void)printf(
300 "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
301 vers, eco, ueco, dnaddr_string(src),
302 blksize, dnaddr_string(dst), hello, other);
303 ret = 1;
304 break;
306 default:
307 (void)printf("unknown control message");
308 default_print((u_char *)rhp, min(length, caplen));
309 ret = 1;
310 break;
312 return (ret);
314 trunc:
315 return (0);
318 static void
319 print_t_info(int info)
321 int ntype = info & 3;
322 switch (ntype) {
323 case 0: (void)printf("reserved-ntype? "); break;
324 case TI_L2ROUT: (void)printf("l2rout "); break;
325 case TI_L1ROUT: (void)printf("l1rout "); break;
326 case TI_ENDNODE: (void)printf("endnode "); break;
328 if (info & TI_VERIF)
329 (void)printf("verif ");
330 if (info & TI_BLOCK)
331 (void)printf("blo ");
334 static int
335 print_l1_routes(const char *rp, u_int len)
337 int count;
338 int id;
339 int info;
341 /* The last short is a checksum */
342 while (len > (3 * sizeof(short))) {
343 TCHECK2(*rp, 3 * sizeof(short));
344 count = EXTRACT_LE_16BITS(rp);
345 if (count > 1024)
346 return (1); /* seems to be bogus from here on */
347 rp += sizeof(short);
348 len -= sizeof(short);
349 id = EXTRACT_LE_16BITS(rp);
350 rp += sizeof(short);
351 len -= sizeof(short);
352 info = EXTRACT_LE_16BITS(rp);
353 rp += sizeof(short);
354 len -= sizeof(short);
355 (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
356 RI_COST(info), RI_HOPS(info));
358 return (1);
360 trunc:
361 return (0);
364 static int
365 print_l2_routes(const char *rp, u_int len)
367 int count;
368 int area;
369 int info;
371 /* The last short is a checksum */
372 while (len > (3 * sizeof(short))) {
373 TCHECK2(*rp, 3 * sizeof(short));
374 count = EXTRACT_LE_16BITS(rp);
375 if (count > 1024)
376 return (1); /* seems to be bogus from here on */
377 rp += sizeof(short);
378 len -= sizeof(short);
379 area = EXTRACT_LE_16BITS(rp);
380 rp += sizeof(short);
381 len -= sizeof(short);
382 info = EXTRACT_LE_16BITS(rp);
383 rp += sizeof(short);
384 len -= sizeof(short);
385 (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
386 RI_COST(info), RI_HOPS(info));
388 return (1);
390 trunc:
391 return (0);
394 static void
395 print_i_info(int info)
397 int ntype = info & II_TYPEMASK;
398 switch (ntype) {
399 case 0: (void)printf("reserved-ntype? "); break;
400 case II_L2ROUT: (void)printf("l2rout "); break;
401 case II_L1ROUT: (void)printf("l1rout "); break;
402 case II_ENDNODE: (void)printf("endnode "); break;
404 if (info & II_VERIF)
405 (void)printf("verif ");
406 if (info & II_NOMCAST)
407 (void)printf("nomcast ");
408 if (info & II_BLOCK)
409 (void)printf("blo ");
412 static int
413 print_elist(const char *elp _U_, u_int len _U_)
415 /* Not enough examples available for me to debug this */
416 return (1);
419 static int
420 print_nsp(const u_char *nspp, u_int nsplen)
422 const struct nsphdr *nsphp = (struct nsphdr *)nspp;
423 int dst, src, flags;
425 if (nsplen < sizeof(struct nsphdr))
426 goto trunc;
427 TCHECK(*nsphp);
428 flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
429 dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
430 src = EXTRACT_LE_16BITS(nsphp->nh_src);
432 switch (flags & NSP_TYPEMASK) {
433 case MFT_DATA:
434 switch (flags & NSP_SUBMASK) {
435 case MFS_BOM:
436 case MFS_MOM:
437 case MFS_EOM:
438 case MFS_BOM+MFS_EOM:
439 printf("data %d>%d ", src, dst);
441 struct seghdr *shp = (struct seghdr *)nspp;
442 int ack;
443 #ifdef PRINT_NSPDATA
444 u_char *dp;
445 #endif
446 u_int data_off = sizeof(struct minseghdr);
448 if (nsplen < data_off)
449 goto trunc;
450 TCHECK(shp->sh_seq[0]);
451 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
452 if (ack & SGQ_ACK) { /* acknum field */
453 if ((ack & SGQ_NAK) == SGQ_NAK)
454 (void)printf("nak %d ", ack & SGQ_MASK);
455 else
456 (void)printf("ack %d ", ack & SGQ_MASK);
457 data_off += sizeof(short);
458 if (nsplen < data_off)
459 goto trunc;
460 TCHECK(shp->sh_seq[1]);
461 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
462 if (ack & SGQ_OACK) { /* ackoth field */
463 if ((ack & SGQ_ONAK) == SGQ_ONAK)
464 (void)printf("onak %d ", ack & SGQ_MASK);
465 else
466 (void)printf("oack %d ", ack & SGQ_MASK);
467 data_off += sizeof(short);
468 if (nsplen < data_off)
469 goto trunc;
470 TCHECK(shp->sh_seq[2]);
471 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
474 (void)printf("seg %d ", ack & SGQ_MASK);
475 #ifdef PRINT_NSPDATA
476 if (nsplen > data_off) {
477 dp = &(nspp[data_off]);
478 TCHECK2(*dp, nsplen - data_off);
479 pdata(dp, nsplen - data_off);
481 #endif
483 break;
484 case MFS_ILS+MFS_INT:
485 printf("intr ");
487 struct seghdr *shp = (struct seghdr *)nspp;
488 int ack;
489 #ifdef PRINT_NSPDATA
490 u_char *dp;
491 #endif
492 u_int data_off = sizeof(struct minseghdr);
494 if (nsplen < data_off)
495 goto trunc;
496 TCHECK(shp->sh_seq[0]);
497 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
498 if (ack & SGQ_ACK) { /* acknum field */
499 if ((ack & SGQ_NAK) == SGQ_NAK)
500 (void)printf("nak %d ", ack & SGQ_MASK);
501 else
502 (void)printf("ack %d ", ack & SGQ_MASK);
503 data_off += sizeof(short);
504 if (nsplen < data_off)
505 goto trunc;
506 TCHECK(shp->sh_seq[1]);
507 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
508 if (ack & SGQ_OACK) { /* ackdat field */
509 if ((ack & SGQ_ONAK) == SGQ_ONAK)
510 (void)printf("nakdat %d ", ack & SGQ_MASK);
511 else
512 (void)printf("ackdat %d ", ack & SGQ_MASK);
513 data_off += sizeof(short);
514 if (nsplen < data_off)
515 goto trunc;
516 TCHECK(shp->sh_seq[2]);
517 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
520 (void)printf("seg %d ", ack & SGQ_MASK);
521 #ifdef PRINT_NSPDATA
522 if (nsplen > data_off) {
523 dp = &(nspp[data_off]);
524 TCHECK2(*dp, nsplen - data_off);
525 pdata(dp, nsplen - data_off);
527 #endif
529 break;
530 case MFS_ILS:
531 (void)printf("link-service %d>%d ", src, dst);
533 struct seghdr *shp = (struct seghdr *)nspp;
534 struct lsmsg *lsmp =
535 (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
536 int ack;
537 int lsflags, fcval;
539 if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg))
540 goto trunc;
541 TCHECK(shp->sh_seq[0]);
542 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
543 if (ack & SGQ_ACK) { /* acknum field */
544 if ((ack & SGQ_NAK) == SGQ_NAK)
545 (void)printf("nak %d ", ack & SGQ_MASK);
546 else
547 (void)printf("ack %d ", ack & SGQ_MASK);
548 TCHECK(shp->sh_seq[1]);
549 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
550 if (ack & SGQ_OACK) { /* ackdat field */
551 if ((ack & SGQ_ONAK) == SGQ_ONAK)
552 (void)printf("nakdat %d ", ack & SGQ_MASK);
553 else
554 (void)printf("ackdat %d ", ack & SGQ_MASK);
555 TCHECK(shp->sh_seq[2]);
556 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
559 (void)printf("seg %d ", ack & SGQ_MASK);
560 TCHECK(*lsmp);
561 lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
562 fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
563 switch (lsflags & LSI_MASK) {
564 case LSI_DATA:
565 (void)printf("dat seg count %d ", fcval);
566 switch (lsflags & LSM_MASK) {
567 case LSM_NOCHANGE:
568 break;
569 case LSM_DONOTSEND:
570 (void)printf("donotsend-data ");
571 break;
572 case LSM_SEND:
573 (void)printf("send-data ");
574 break;
575 default:
576 (void)printf("reserved-fcmod? %x", lsflags);
577 break;
579 break;
580 case LSI_INTR:
581 (void)printf("intr req count %d ", fcval);
582 break;
583 default:
584 (void)printf("reserved-fcval-int? %x", lsflags);
585 break;
588 break;
589 default:
590 (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
591 break;
593 break;
594 case MFT_ACK:
595 switch (flags & NSP_SUBMASK) {
596 case MFS_DACK:
597 (void)printf("data-ack %d>%d ", src, dst);
599 struct ackmsg *amp = (struct ackmsg *)nspp;
600 int ack;
602 if (nsplen < sizeof(struct ackmsg))
603 goto trunc;
604 TCHECK(*amp);
605 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
606 if (ack & SGQ_ACK) { /* acknum field */
607 if ((ack & SGQ_NAK) == SGQ_NAK)
608 (void)printf("nak %d ", ack & SGQ_MASK);
609 else
610 (void)printf("ack %d ", ack & SGQ_MASK);
611 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
612 if (ack & SGQ_OACK) { /* ackoth field */
613 if ((ack & SGQ_ONAK) == SGQ_ONAK)
614 (void)printf("onak %d ", ack & SGQ_MASK);
615 else
616 (void)printf("oack %d ", ack & SGQ_MASK);
620 break;
621 case MFS_IACK:
622 (void)printf("ils-ack %d>%d ", src, dst);
624 struct ackmsg *amp = (struct ackmsg *)nspp;
625 int ack;
627 if (nsplen < sizeof(struct ackmsg))
628 goto trunc;
629 TCHECK(*amp);
630 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
631 if (ack & SGQ_ACK) { /* acknum field */
632 if ((ack & SGQ_NAK) == SGQ_NAK)
633 (void)printf("nak %d ", ack & SGQ_MASK);
634 else
635 (void)printf("ack %d ", ack & SGQ_MASK);
636 TCHECK(amp->ak_acknum[1]);
637 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
638 if (ack & SGQ_OACK) { /* ackdat field */
639 if ((ack & SGQ_ONAK) == SGQ_ONAK)
640 (void)printf("nakdat %d ", ack & SGQ_MASK);
641 else
642 (void)printf("ackdat %d ", ack & SGQ_MASK);
646 break;
647 case MFS_CACK:
648 (void)printf("conn-ack %d", dst);
649 break;
650 default:
651 (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
652 break;
654 break;
655 case MFT_CTL:
656 switch (flags & NSP_SUBMASK) {
657 case MFS_CI:
658 case MFS_RCI:
659 if ((flags & NSP_SUBMASK) == MFS_CI)
660 (void)printf("conn-initiate ");
661 else
662 (void)printf("retrans-conn-initiate ");
663 (void)printf("%d>%d ", src, dst);
665 struct cimsg *cimp = (struct cimsg *)nspp;
666 int services, info, segsize;
667 #ifdef PRINT_NSPDATA
668 u_char *dp;
669 #endif
671 if (nsplen < sizeof(struct cimsg))
672 goto trunc;
673 TCHECK(*cimp);
674 services = EXTRACT_LE_8BITS(cimp->ci_services);
675 info = EXTRACT_LE_8BITS(cimp->ci_info);
676 segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
678 switch (services & COS_MASK) {
679 case COS_NONE:
680 break;
681 case COS_SEGMENT:
682 (void)printf("seg ");
683 break;
684 case COS_MESSAGE:
685 (void)printf("msg ");
686 break;
687 case COS_CRYPTSER:
688 (void)printf("crypt ");
689 break;
691 switch (info & COI_MASK) {
692 case COI_32:
693 (void)printf("ver 3.2 ");
694 break;
695 case COI_31:
696 (void)printf("ver 3.1 ");
697 break;
698 case COI_40:
699 (void)printf("ver 4.0 ");
700 break;
701 case COI_41:
702 (void)printf("ver 4.1 ");
703 break;
705 (void)printf("segsize %d ", segsize);
706 #ifdef PRINT_NSPDATA
707 if (nsplen > sizeof(struct cimsg)) {
708 dp = &(nspp[sizeof(struct cimsg)]);
709 TCHECK2(*dp, nsplen - sizeof(struct cimsg));
710 pdata(dp, nsplen - sizeof(struct cimsg));
712 #endif
714 break;
715 case MFS_CC:
716 (void)printf("conn-confirm %d>%d ", src, dst);
718 struct ccmsg *ccmp = (struct ccmsg *)nspp;
719 int services, info;
720 u_int segsize, optlen;
721 #ifdef PRINT_NSPDATA
722 u_char *dp;
723 #endif
725 if (nsplen < sizeof(struct ccmsg))
726 goto trunc;
727 TCHECK(*ccmp);
728 services = EXTRACT_LE_8BITS(ccmp->cc_services);
729 info = EXTRACT_LE_8BITS(ccmp->cc_info);
730 segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
731 optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
733 switch (services & COS_MASK) {
734 case COS_NONE:
735 break;
736 case COS_SEGMENT:
737 (void)printf("seg ");
738 break;
739 case COS_MESSAGE:
740 (void)printf("msg ");
741 break;
742 case COS_CRYPTSER:
743 (void)printf("crypt ");
744 break;
746 switch (info & COI_MASK) {
747 case COI_32:
748 (void)printf("ver 3.2 ");
749 break;
750 case COI_31:
751 (void)printf("ver 3.1 ");
752 break;
753 case COI_40:
754 (void)printf("ver 4.0 ");
755 break;
756 case COI_41:
757 (void)printf("ver 4.1 ");
758 break;
760 (void)printf("segsize %d ", segsize);
761 if (optlen) {
762 (void)printf("optlen %d ", optlen);
763 #ifdef PRINT_NSPDATA
764 if (optlen > nsplen - sizeof(struct ccmsg))
765 goto trunc;
766 dp = &(nspp[sizeof(struct ccmsg)]);
767 TCHECK2(*dp, optlen);
768 pdata(dp, optlen);
769 #endif
772 break;
773 case MFS_DI:
774 (void)printf("disconn-initiate %d>%d ", src, dst);
776 struct dimsg *dimp = (struct dimsg *)nspp;
777 int reason;
778 u_int optlen;
779 #ifdef PRINT_NSPDATA
780 u_char *dp;
781 #endif
783 if (nsplen < sizeof(struct dimsg))
784 goto trunc;
785 TCHECK(*dimp);
786 reason = EXTRACT_LE_16BITS(dimp->di_reason);
787 optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
789 print_reason(reason);
790 if (optlen) {
791 (void)printf("optlen %d ", optlen);
792 #ifdef PRINT_NSPDATA
793 if (optlen > nsplen - sizeof(struct dimsg))
794 goto trunc;
795 dp = &(nspp[sizeof(struct dimsg)]);
796 TCHECK2(*dp, optlen);
797 pdata(dp, optlen);
798 #endif
801 break;
802 case MFS_DC:
803 (void)printf("disconn-confirm %d>%d ", src, dst);
805 struct dcmsg *dcmp = (struct dcmsg *)nspp;
806 int reason;
808 TCHECK(*dcmp);
809 reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
811 print_reason(reason);
813 break;
814 default:
815 (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
816 break;
818 break;
819 default:
820 (void)printf("reserved-type? %x %d > %d", flags, src, dst);
821 break;
823 return (1);
825 trunc:
826 return (0);
829 static struct tok reason2str[] = {
830 { UC_OBJREJECT, "object rejected connect" },
831 { UC_RESOURCES, "insufficient resources" },
832 { UC_NOSUCHNODE, "unrecognized node name" },
833 { DI_SHUT, "node is shutting down" },
834 { UC_NOSUCHOBJ, "unrecognized object" },
835 { UC_INVOBJFORMAT, "invalid object name format" },
836 { UC_OBJTOOBUSY, "object too busy" },
837 { DI_PROTOCOL, "protocol error discovered" },
838 { DI_TPA, "third party abort" },
839 { UC_USERABORT, "user abort" },
840 { UC_INVNODEFORMAT, "invalid node name format" },
841 { UC_LOCALSHUT, "local node shutting down" },
842 { DI_LOCALRESRC, "insufficient local resources" },
843 { DI_REMUSERRESRC, "insufficient remote user resources" },
844 { UC_ACCESSREJECT, "invalid access control information" },
845 { DI_BADACCNT, "bad ACCOUNT information" },
846 { UC_NORESPONSE, "no response from object" },
847 { UC_UNREACHABLE, "node unreachable" },
848 { DC_NOLINK, "no link terminate" },
849 { DC_COMPLETE, "disconnect complete" },
850 { DI_BADIMAGE, "bad image data in connect" },
851 { DI_SERVMISMATCH, "cryptographic service mismatch" },
852 { 0, NULL }
855 static void
856 print_reason(register int reason)
858 printf("%s ", tok2str(reason2str, "reason-%d", reason));
861 const char *
862 dnnum_string(u_short dnaddr)
864 char *str;
865 size_t siz;
866 int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT;
867 int node = dnaddr & NODEMASK;
869 str = (char *)malloc(siz = sizeof("00.0000"));
870 if (str == NULL)
871 error("dnnum_string: malloc");
872 snprintf(str, siz, "%d.%d", area, node);
873 return(str);
876 const char *
877 dnname_string(u_short dnaddr)
879 #ifdef HAVE_DNET_HTOA
880 struct dn_naddr dna;
882 dna.a_len = sizeof(short);
883 memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
884 return (strdup(dnet_htoa(&dna)));
885 #else
886 return(dnnum_string(dnaddr)); /* punt */
887 #endif
890 #ifdef PRINT_NSPDATA
891 static void
892 pdata(u_char *dp, u_int maxlen)
894 char c;
895 u_int x = maxlen;
897 while (x-- > 0) {
898 c = *dp++;
899 safeputchar(c);
902 #endif