]>
Commit | Line | Data |
---|---|---|
b7080c8e A |
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 |