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