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