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