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