]> git.saurik.com Git - apple/network_cmds.git/blob - tcpdump.tproj/print-decnet.c
network_cmds-76.tar.gz
[apple/network_cmds.git] / tcpdump.tproj / print-decnet.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1992, 1993, 1994, 1995, 1996
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that: (1) source code distributions
30 * retain the above copyright notice and this paragraph in its entirety, (2)
31 * distributions including binary code include the above copyright notice and
32 * this paragraph in its entirety in the documentation or other materials
33 * provided with the distribution, and (3) all advertising materials mentioning
34 * features or use of this software display the following acknowledgement:
35 * ``This product includes software developed by the University of California,
36 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
37 * the University nor the names of its contributors may be used to endorse
38 * or promote products derived from this software without specific prior
39 * written permission.
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
41 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
43 */
44
45 #ifndef lint
46 static const char rcsid[] =
47 "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-decnet.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
48 #endif
49
50 #include <sys/param.h>
51 #include <sys/time.h>
52 #include <sys/socket.h>
53
54 #if __STDC__
55 struct mbuf;
56 struct rtentry;
57 #endif
58 #include <net/if.h>
59
60 #ifdef HAVE_LIBDNET
61 #include <netdnet/dnetdb.h>
62 #endif
63
64 #include <ctype.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69
70 #include "decnet.h"
71 #include "extract.h"
72 #include "interface.h"
73 #include "addrtoname.h"
74
75 /* Forwards */
76 static void print_decnet_ctlmsg(const union routehdr *, u_int);
77 static void print_t_info(int);
78 static void print_l1_routes(const char *, u_int);
79 static void print_l2_routes(const char *, u_int);
80 static void print_i_info(int);
81 static void print_elist(const char *, u_int);
82 static void print_nsp(const u_char *, u_int);
83 static void print_reason(int);
84 #ifdef PRINT_NSPDATA
85 static void pdata(u_char *, int);
86 #endif
87
88 #ifdef HAVE_LIBDNET
89 extern char *dnet_htoa(struct dn_naddr *);
90 #endif
91
92 void
93 decnet_print(register const u_char *ap, register u_int length,
94 register u_int caplen)
95 {
96 static union routehdr rhcopy;
97 register union routehdr *rhp = &rhcopy;
98 register int mflags;
99 int dst, src, hops;
100 u_int rhlen, nsplen, pktlen;
101 const u_char *nspp;
102
103 if (length < sizeof(struct shorthdr)) {
104 (void)printf("[|decnet]");
105 return;
106 }
107
108 pktlen = EXTRACT_LE_16BITS(ap);
109
110 rhlen = min(length, caplen);
111 rhlen = min(rhlen, sizeof(*rhp));
112 memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
113
114 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
115
116 if (mflags & RMF_PAD) {
117 /* pad bytes of some sort in front of message */
118 u_int padlen = mflags & RMF_PADMASK;
119 if (vflag)
120 (void) printf("[pad:%d] ", padlen);
121 ap += padlen;
122 length -= padlen;
123 caplen -= padlen;
124 rhlen = min(length, caplen);
125 rhlen = min(rhlen, sizeof(*rhp));
126 memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
127 mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
128 }
129
130 if (mflags & RMF_FVER) {
131 (void) printf("future-version-decnet");
132 default_print(ap, length);
133 return;
134 }
135
136 /* is it a control message? */
137 if (mflags & RMF_CTLMSG) {
138 print_decnet_ctlmsg(rhp, min(length, caplen));
139 return;
140 }
141
142 switch (mflags & RMF_MASK) {
143 case RMF_LONG:
144 dst =
145 EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
146 src =
147 EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
148 hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
149 nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
150 nsplen = min((length - sizeof(struct longhdr)),
151 (caplen - sizeof(struct longhdr)));
152 break;
153 case RMF_SHORT:
154 dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
155 src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
156 hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
157 nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
158 nsplen = min((length - sizeof(struct shorthdr)),
159 (caplen - sizeof(struct shorthdr)));
160 break;
161 default:
162 (void) printf("unknown message flags under mask");
163 default_print((u_char *)ap, length);
164 return;
165 }
166
167 (void)printf("%s > %s %d ",
168 dnaddr_string(src), dnaddr_string(dst), pktlen);
169 if (vflag) {
170 if (mflags & RMF_RQR)
171 (void)printf("RQR ");
172 if (mflags & RMF_RTS)
173 (void)printf("RTS ");
174 if (mflags & RMF_IE)
175 (void)printf("IE ");
176 (void)printf("%d hops ", hops);
177 }
178
179 print_nsp(nspp, nsplen);
180 }
181
182 static void
183 print_decnet_ctlmsg(register const union routehdr *rhp, u_int length)
184 {
185 int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
186 register union controlmsg *cmp = (union controlmsg *)rhp;
187 int src, dst, info, blksize, eco, ueco, hello, other, vers;
188 etheraddr srcea, rtea;
189 int priority;
190 char *rhpx = (char *)rhp;
191
192 switch (mflags & RMF_CTLMASK) {
193 case RMF_INIT:
194 (void)printf("init ");
195 src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
196 info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
197 blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
198 vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
199 eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
200 ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
201 hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
202 print_t_info(info);
203 (void)printf(
204 "src %sblksize %d vers %d eco %d ueco %d hello %d",
205 dnaddr_string(src), blksize, vers, eco, ueco,
206 hello);
207 break;
208 case RMF_VER:
209 (void)printf("verification ");
210 src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
211 other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
212 (void)printf("src %s fcnval %o", dnaddr_string(src), other);
213 break;
214 case RMF_TEST:
215 (void)printf("test ");
216 src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
217 other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
218 (void)printf("src %s data %o", dnaddr_string(src), other);
219 break;
220 case RMF_L1ROUT:
221 (void)printf("lev-1-routing ");
222 src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
223 (void)printf("src %s ", dnaddr_string(src));
224 print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
225 length - sizeof(struct l1rout));
226 break;
227 case RMF_L2ROUT:
228 (void)printf("lev-2-routing ");
229 src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
230 (void)printf("src %s ", dnaddr_string(src));
231 print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
232 length - sizeof(struct l2rout));
233 break;
234 case RMF_RHELLO:
235 (void)printf("router-hello ");
236 vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
237 eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
238 ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
239 memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
240 sizeof(srcea));
241 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
242 info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
243 blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
244 priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
245 hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
246 print_i_info(info);
247 (void)printf(
248 "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
249 vers, eco, ueco, dnaddr_string(src),
250 blksize, priority, hello);
251 print_elist(&(rhpx[sizeof(struct rhellomsg)]),
252 length - sizeof(struct rhellomsg));
253 break;
254 case RMF_EHELLO:
255 (void)printf("endnode-hello ");
256 vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
257 eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
258 ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
259 memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
260 sizeof(srcea));
261 src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
262 info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
263 blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
264 /*seed*/
265 memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
266 sizeof(rtea));
267 dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
268 hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
269 other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
270 print_i_info(info);
271 (void)printf(
272 "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
273 vers, eco, ueco, dnaddr_string(src),
274 blksize, dnaddr_string(dst), hello, other);
275 break;
276
277 default:
278 (void)printf("unknown control message");
279 default_print((u_char *)rhp, length);
280 break;
281 }
282 }
283
284 static void
285 print_t_info(int info)
286 {
287 int ntype = info & 3;
288 switch (ntype) {
289 case 0: (void)printf("reserved-ntype? "); break;
290 case TI_L2ROUT: (void)printf("l2rout "); break;
291 case TI_L1ROUT: (void)printf("l1rout "); break;
292 case TI_ENDNODE: (void)printf("endnode "); break;
293 }
294 if (info & TI_VERIF)
295 (void)printf("verif ");
296 if (info & TI_BLOCK)
297 (void)printf("blo ");
298 }
299
300 static void
301 print_l1_routes(const char *rp, u_int len)
302 {
303 int count;
304 int id;
305 int info;
306
307 /* The last short is a checksum */
308 while (len > (3 * sizeof(short))) {
309 count = EXTRACT_LE_16BITS(rp);
310 if (count > 1024)
311 return; /* seems to be bogus from here on */
312 rp += sizeof(short);
313 len -= sizeof(short);
314 id = EXTRACT_LE_16BITS(rp);
315 rp += sizeof(short);
316 len -= sizeof(short);
317 info = EXTRACT_LE_16BITS(rp);
318 rp += sizeof(short);
319 len -= sizeof(short);
320 (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
321 RI_COST(info), RI_HOPS(info));
322 }
323 }
324
325 static void
326 print_l2_routes(const char *rp, u_int len)
327 {
328 int count;
329 int area;
330 int info;
331
332 /* The last short is a checksum */
333 while (len > (3 * sizeof(short))) {
334 count = EXTRACT_LE_16BITS(rp);
335 if (count > 1024)
336 return; /* seems to be bogus from here on */
337 rp += sizeof(short);
338 len -= sizeof(short);
339 area = EXTRACT_LE_16BITS(rp);
340 rp += sizeof(short);
341 len -= sizeof(short);
342 info = EXTRACT_LE_16BITS(rp);
343 rp += sizeof(short);
344 len -= sizeof(short);
345 (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
346 RI_COST(info), RI_HOPS(info));
347 }
348 }
349
350 static void
351 print_i_info(int info)
352 {
353 int ntype = info & II_TYPEMASK;
354 switch (ntype) {
355 case 0: (void)printf("reserved-ntype? "); break;
356 case II_L2ROUT: (void)printf("l2rout "); break;
357 case II_L1ROUT: (void)printf("l1rout "); break;
358 case II_ENDNODE: (void)printf("endnode "); break;
359 }
360 if (info & II_VERIF)
361 (void)printf("verif ");
362 if (info & II_NOMCAST)
363 (void)printf("nomcast ");
364 if (info & II_BLOCK)
365 (void)printf("blo ");
366 }
367
368 static void
369 print_elist(const char *elp, u_int len)
370 {
371 /* Not enough examples available for me to debug this */
372 }
373
374 static void
375 print_nsp(const u_char *nspp, u_int nsplen)
376 {
377 const struct nsphdr *nsphp = (struct nsphdr *)nspp;
378 int dst, src, flags;
379
380 flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
381 dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
382 src = EXTRACT_LE_16BITS(nsphp->nh_src);
383
384 switch (flags & NSP_TYPEMASK) {
385 case MFT_DATA:
386 switch (flags & NSP_SUBMASK) {
387 case MFS_BOM:
388 case MFS_MOM:
389 case MFS_EOM:
390 case MFS_BOM+MFS_EOM:
391 printf("data %d>%d ", src, dst);
392 {
393 struct seghdr *shp = (struct seghdr *)nspp;
394 int ack;
395 #ifdef PRINT_NSPDATA
396 u_char *dp;
397 #endif
398 u_int data_off = sizeof(struct minseghdr);
399
400 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
401 if (ack & SGQ_ACK) { /* acknum field */
402 if ((ack & SGQ_NAK) == SGQ_NAK)
403 (void)printf("nak %d ", ack & SGQ_MASK);
404 else
405 (void)printf("ack %d ", ack & SGQ_MASK);
406 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
407 data_off += sizeof(short);
408 if (ack & SGQ_OACK) { /* ackoth field */
409 if ((ack & SGQ_ONAK) == SGQ_ONAK)
410 (void)printf("onak %d ", ack & SGQ_MASK);
411 else
412 (void)printf("oack %d ", ack & SGQ_MASK);
413 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
414 data_off += sizeof(short);
415 }
416 }
417 (void)printf("seg %d ", ack & SGQ_MASK);
418 #ifdef PRINT_NSPDATA
419 dp = &(nspp[data_off]);
420 pdata(dp, 10);
421 #endif
422 }
423 break;
424 case MFS_ILS+MFS_INT:
425 printf("intr ");
426 {
427 struct seghdr *shp = (struct seghdr *)nspp;
428 int ack;
429 #ifdef PRINT_NSPDATA
430 u_char *dp;
431 #endif
432 u_int data_off = sizeof(struct minseghdr);
433
434 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
435 if (ack & SGQ_ACK) { /* acknum field */
436 if ((ack & SGQ_NAK) == SGQ_NAK)
437 (void)printf("nak %d ", ack & SGQ_MASK);
438 else
439 (void)printf("ack %d ", ack & SGQ_MASK);
440 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
441 data_off += sizeof(short);
442 if (ack & SGQ_OACK) { /* ackdat field */
443 if ((ack & SGQ_ONAK) == SGQ_ONAK)
444 (void)printf("nakdat %d ", ack & SGQ_MASK);
445 else
446 (void)printf("ackdat %d ", ack & SGQ_MASK);
447 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
448 data_off += sizeof(short);
449 }
450 }
451 (void)printf("seg %d ", ack & SGQ_MASK);
452 #ifdef PRINT_NSPDATA
453 dp = &(nspp[data_off]);
454 pdata(dp, 10);
455 #endif
456 }
457 break;
458 case MFS_ILS:
459 (void)printf("link-service %d>%d ", src, dst);
460 {
461 struct seghdr *shp = (struct seghdr *)nspp;
462 struct lsmsg *lsmp =
463 (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
464 int ack;
465 int lsflags, fcval;
466
467 ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
468 if (ack & SGQ_ACK) { /* acknum field */
469 if ((ack & SGQ_NAK) == SGQ_NAK)
470 (void)printf("nak %d ", ack & SGQ_MASK);
471 else
472 (void)printf("ack %d ", ack & SGQ_MASK);
473 ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
474 if (ack & SGQ_OACK) { /* ackdat field */
475 if ((ack & SGQ_ONAK) == SGQ_ONAK)
476 (void)printf("nakdat %d ", ack & SGQ_MASK);
477 else
478 (void)printf("ackdat %d ", ack & SGQ_MASK);
479 ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
480 }
481 }
482 (void)printf("seg %d ", ack & SGQ_MASK);
483 lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
484 fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
485 switch (lsflags & LSI_MASK) {
486 case LSI_DATA:
487 (void)printf("dat seg count %d ", fcval);
488 switch (lsflags & LSM_MASK) {
489 case LSM_NOCHANGE:
490 break;
491 case LSM_DONOTSEND:
492 (void)printf("donotsend-data ");
493 break;
494 case LSM_SEND:
495 (void)printf("send-data ");
496 break;
497 default:
498 (void)printf("reserved-fcmod? %x", lsflags);
499 break;
500 }
501 break;
502 case LSI_INTR:
503 (void)printf("intr req count %d ", fcval);
504 break;
505 default:
506 (void)printf("reserved-fcval-int? %x", lsflags);
507 break;
508 }
509 }
510 break;
511 default:
512 (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
513 break;
514 }
515 break;
516 case MFT_ACK:
517 switch (flags & NSP_SUBMASK) {
518 case MFS_DACK:
519 (void)printf("data-ack %d>%d ", src, dst);
520 {
521 struct ackmsg *amp = (struct ackmsg *)nspp;
522 int ack;
523
524 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
525 if (ack & SGQ_ACK) { /* acknum field */
526 if ((ack & SGQ_NAK) == SGQ_NAK)
527 (void)printf("nak %d ", ack & SGQ_MASK);
528 else
529 (void)printf("ack %d ", ack & SGQ_MASK);
530 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
531 if (ack & SGQ_OACK) { /* ackoth field */
532 if ((ack & SGQ_ONAK) == SGQ_ONAK)
533 (void)printf("onak %d ", ack & SGQ_MASK);
534 else
535 (void)printf("oack %d ", ack & SGQ_MASK);
536 }
537 }
538 }
539 break;
540 case MFS_IACK:
541 (void)printf("ils-ack %d>%d ", src, dst);
542 {
543 struct ackmsg *amp = (struct ackmsg *)nspp;
544 int ack;
545
546 ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
547 if (ack & SGQ_ACK) { /* acknum field */
548 if ((ack & SGQ_NAK) == SGQ_NAK)
549 (void)printf("nak %d ", ack & SGQ_MASK);
550 else
551 (void)printf("ack %d ", ack & SGQ_MASK);
552 ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
553 if (ack & SGQ_OACK) { /* ackdat field */
554 if ((ack & SGQ_ONAK) == SGQ_ONAK)
555 (void)printf("nakdat %d ", ack & SGQ_MASK);
556 else
557 (void)printf("ackdat %d ", ack & SGQ_MASK);
558 }
559 }
560 }
561 break;
562 case MFS_CACK:
563 (void)printf("conn-ack %d", dst);
564 break;
565 default:
566 (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
567 break;
568 }
569 break;
570 case MFT_CTL:
571 switch (flags & NSP_SUBMASK) {
572 case MFS_CI:
573 case MFS_RCI:
574 if ((flags & NSP_SUBMASK) == MFS_CI)
575 (void)printf("conn-initiate ");
576 else
577 (void)printf("retrans-conn-initiate ");
578 (void)printf("%d>%d ", src, dst);
579 {
580 struct cimsg *cimp = (struct cimsg *)nspp;
581 int services, info, segsize;
582 #ifdef PRINT_NSPDATA
583 u_char *dp;
584 #endif
585
586 services = EXTRACT_LE_8BITS(cimp->ci_services);
587 info = EXTRACT_LE_8BITS(cimp->ci_info);
588 segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
589
590 switch (services & COS_MASK) {
591 case COS_NONE:
592 break;
593 case COS_SEGMENT:
594 (void)printf("seg ");
595 break;
596 case COS_MESSAGE:
597 (void)printf("msg ");
598 break;
599 case COS_CRYPTSER:
600 (void)printf("crypt ");
601 break;
602 }
603 switch (info & COI_MASK) {
604 case COI_32:
605 (void)printf("ver 3.2 ");
606 break;
607 case COI_31:
608 (void)printf("ver 3.1 ");
609 break;
610 case COI_40:
611 (void)printf("ver 4.0 ");
612 break;
613 case COI_41:
614 (void)printf("ver 4.1 ");
615 break;
616 }
617 (void)printf("segsize %d ", segsize);
618 #ifdef PRINT_NSPDATA
619 dp = &(nspp[sizeof(struct cimsg)]);
620 pdata(dp, nsplen - sizeof(struct cimsg));
621 #endif
622 }
623 break;
624 case MFS_CC:
625 (void)printf("conn-confirm %d>%d ", src, dst);
626 {
627 struct ccmsg *ccmp = (struct ccmsg *)nspp;
628 int services, info;
629 u_int segsize, optlen;
630 #ifdef PRINT_NSPDATA
631 u_char *dp;
632 #endif
633
634 services = EXTRACT_LE_8BITS(ccmp->cc_services);
635 info = EXTRACT_LE_8BITS(ccmp->cc_info);
636 segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
637 optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
638
639 switch (services & COS_MASK) {
640 case COS_NONE:
641 break;
642 case COS_SEGMENT:
643 (void)printf("seg ");
644 break;
645 case COS_MESSAGE:
646 (void)printf("msg ");
647 break;
648 case COS_CRYPTSER:
649 (void)printf("crypt ");
650 break;
651 }
652 switch (info & COI_MASK) {
653 case COI_32:
654 (void)printf("ver 3.2 ");
655 break;
656 case COI_31:
657 (void)printf("ver 3.1 ");
658 break;
659 case COI_40:
660 (void)printf("ver 4.0 ");
661 break;
662 case COI_41:
663 (void)printf("ver 4.1 ");
664 break;
665 }
666 (void)printf("segsize %d ", segsize);
667 if (optlen) {
668 (void)printf("optlen %d ", optlen);
669 #ifdef PRINT_NSPDATA
670 optlen = min(optlen, nsplen - sizeof(struct ccmsg));
671 dp = &(nspp[sizeof(struct ccmsg)]);
672 pdata(dp, optlen);
673 #endif
674 }
675 }
676 break;
677 case MFS_DI:
678 (void)printf("disconn-initiate %d>%d ", src, dst);
679 {
680 struct dimsg *dimp = (struct dimsg *)nspp;
681 int reason;
682 u_int optlen;
683 #ifdef PRINT_NSPDATA
684 u_char *dp;
685 #endif
686
687 reason = EXTRACT_LE_16BITS(dimp->di_reason);
688 optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
689
690 print_reason(reason);
691 if (optlen) {
692 (void)printf("optlen %d ", optlen);
693 #ifdef PRINT_NSPDATA
694 optlen = min(optlen, nsplen - sizeof(struct dimsg));
695 dp = &(nspp[sizeof(struct dimsg)]);
696 pdata(dp, optlen);
697 #endif
698 }
699 }
700 break;
701 case MFS_DC:
702 (void)printf("disconn-confirm %d>%d ", src, dst);
703 {
704 struct dcmsg *dcmp = (struct dcmsg *)nspp;
705 int reason;
706
707 reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
708
709 print_reason(reason);
710 }
711 break;
712 default:
713 (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
714 break;
715 }
716 break;
717 default:
718 (void)printf("reserved-type? %x %d > %d", flags, src, dst);
719 break;
720 }
721 }
722
723 static struct tok reason2str[] = {
724 { UC_OBJREJECT, "object rejected connect" },
725 { UC_RESOURCES, "insufficient resources" },
726 { UC_NOSUCHNODE, "unrecognized node name" },
727 { DI_SHUT, "node is shutting down" },
728 { UC_NOSUCHOBJ, "unrecognized object" },
729 { UC_INVOBJFORMAT, "invalid object name format" },
730 { UC_OBJTOOBUSY, "object too busy" },
731 { DI_PROTOCOL, "protocol error discovered" },
732 { DI_TPA, "third party abort" },
733 { UC_USERABORT, "user abort" },
734 { UC_INVNODEFORMAT, "invalid node name format" },
735 { UC_LOCALSHUT, "local node shutting down" },
736 { DI_LOCALRESRC, "insufficient local resources" },
737 { DI_REMUSERRESRC, "insufficient remote user resources" },
738 { UC_ACCESSREJECT, "invalid access control information" },
739 { DI_BADACCNT, "bad ACCOUNT information" },
740 { UC_NORESPONSE, "no response from object" },
741 { UC_UNREACHABLE, "node unreachable" },
742 { DC_NOLINK, "no link terminate" },
743 { DC_COMPLETE, "disconnect complete" },
744 { DI_BADIMAGE, "bad image data in connect" },
745 { DI_SERVMISMATCH, "cryptographic service mismatch" },
746 { 0, NULL }
747 };
748
749 static void
750 print_reason(register int reason)
751 {
752 printf("%s ", tok2str(reason2str, "reason-%d", reason));
753 }
754
755 char *
756 dnnum_string(u_short dnaddr)
757 {
758 char *str;
759 int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT;
760 int node = dnaddr & NODEMASK;
761
762 str = (char *)malloc(sizeof("00.0000"));
763 if (str == NULL)
764 error("dnnum_string: malloc");
765 sprintf(str, "%d.%d", area, node);
766 return(str);
767 }
768
769 char *
770 dnname_string(u_short dnaddr)
771 {
772 #ifdef HAVE_LIBDNET
773 struct dn_naddr dna;
774
775 dna.a_len = sizeof(short);
776 memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
777 return (savestr(dnet_htoa(&dna)));
778 #else
779 return(dnnum_string(dnaddr)); /* punt */
780 #endif
781 }
782
783 #ifdef PRINT_NSPDATA
784 static void
785 pdata(u_char *dp, u_int maxlen)
786 {
787 char c;
788 u_int x = maxlen;
789
790 while (x-- > 0) {
791 c = *dp++;
792 if (isprint(c))
793 putchar(c);
794 else
795 printf("\\%o", c & 0xFF);
796 }
797 }
798 #endif