nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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 | #define NETDISSECT_REWORKED |
||
23 | #ifdef HAVE_CONFIG_H |
||
24 | #include "config.h" |
||
25 | #endif |
||
26 | |||
27 | #include <tcpdump-stdinc.h> |
||
28 | |||
29 | struct mbuf; |
||
30 | struct rtentry; |
||
31 | |||
32 | #ifdef HAVE_NETDNET_DNETDB_H |
||
33 | #include <netdnet/dnetdb.h> |
||
34 | #endif |
||
35 | |||
36 | #include <stdio.h> |
||
37 | #include <stdlib.h> |
||
38 | #include <string.h> |
||
39 | |||
40 | #include "extract.h" |
||
41 | #include "interface.h" |
||
42 | #include "addrtoname.h" |
||
43 | |||
44 | static const char tstr[] = "[|decnet]"; |
||
45 | |||
46 | #ifndef WIN32 |
||
47 | typedef uint8_t byte[1]; /* single byte field */ |
||
48 | #else |
||
49 | /* |
||
50 | * the keyword 'byte' generates conflicts in Windows |
||
51 | */ |
||
52 | typedef unsigned char Byte[1]; /* single byte field */ |
||
53 | #define byte Byte |
||
54 | #endif /* WIN32 */ |
||
55 | typedef uint8_t word[2]; /* 2 byte field */ |
||
56 | typedef uint8_t longword[4]; /* 4 bytes field */ |
||
57 | |||
58 | /* |
||
59 | * Definitions for DECNET Phase IV protocol headers |
||
60 | */ |
||
61 | union etheraddress { |
||
62 | uint8_t dne_addr[6]; /* full ethernet address */ |
||
63 | struct { |
||
64 | uint8_t dne_hiord[4]; /* DECnet HIORD prefix */ |
||
65 | uint8_t dne_nodeaddr[2]; /* DECnet node address */ |
||
66 | } dne_remote; |
||
67 | }; |
||
68 | |||
69 | typedef union etheraddress etheraddr; /* Ethernet address */ |
||
70 | |||
71 | #define HIORD 0x000400aa /* high 32-bits of address (swapped) */ |
||
72 | |||
73 | #define AREAMASK 0176000 /* mask for area field */ |
||
74 | #define AREASHIFT 10 /* bit-offset for area field */ |
||
75 | #define NODEMASK 01777 /* mask for node address field */ |
||
76 | |||
77 | #define DN_MAXADDL 20 /* max size of DECnet address */ |
||
78 | struct dn_naddr { |
||
79 | uint16_t a_len; /* length of address */ |
||
80 | uint8_t a_addr[DN_MAXADDL]; /* address as bytes */ |
||
81 | }; |
||
82 | |||
83 | /* |
||
84 | * Define long and short header formats. |
||
85 | */ |
||
86 | struct shorthdr |
||
87 | { |
||
88 | byte sh_flags; /* route flags */ |
||
89 | word sh_dst; /* destination node address */ |
||
90 | word sh_src; /* source node address */ |
||
91 | byte sh_visits; /* visit count */ |
||
92 | }; |
||
93 | |||
94 | struct longhdr |
||
95 | { |
||
96 | byte lg_flags; /* route flags */ |
||
97 | byte lg_darea; /* destination area (reserved) */ |
||
98 | byte lg_dsarea; /* destination subarea (reserved) */ |
||
99 | etheraddr lg_dst; /* destination id */ |
||
100 | byte lg_sarea; /* source area (reserved) */ |
||
101 | byte lg_ssarea; /* source subarea (reserved) */ |
||
102 | etheraddr lg_src; /* source id */ |
||
103 | byte lg_nextl2; /* next level 2 router (reserved) */ |
||
104 | byte lg_visits; /* visit count */ |
||
105 | byte lg_service; /* service class (reserved) */ |
||
106 | byte lg_pt; /* protocol type (reserved) */ |
||
107 | }; |
||
108 | |||
109 | union routehdr |
||
110 | { |
||
111 | struct shorthdr rh_short; /* short route header */ |
||
112 | struct longhdr rh_long; /* long route header */ |
||
113 | }; |
||
114 | |||
115 | /* |
||
116 | * Define the values of various fields in the protocol messages. |
||
117 | * |
||
118 | * 1. Data packet formats. |
||
119 | */ |
||
120 | #define RMF_MASK 7 /* mask for message type */ |
||
121 | #define RMF_SHORT 2 /* short message format */ |
||
122 | #define RMF_LONG 6 /* long message format */ |
||
123 | #ifndef RMF_RQR |
||
124 | #define RMF_RQR 010 /* request return to sender */ |
||
125 | #define RMF_RTS 020 /* returning to sender */ |
||
126 | #define RMF_IE 040 /* intra-ethernet packet */ |
||
127 | #endif /* RMR_RQR */ |
||
128 | #define RMF_FVER 0100 /* future version flag */ |
||
129 | #define RMF_PAD 0200 /* pad field */ |
||
130 | #define RMF_PADMASK 0177 /* pad field mask */ |
||
131 | |||
132 | #define VIS_MASK 077 /* visit field mask */ |
||
133 | |||
134 | /* |
||
135 | * 2. Control packet formats. |
||
136 | */ |
||
137 | #define RMF_CTLMASK 017 /* mask for message type */ |
||
138 | #define RMF_CTLMSG 01 /* control message indicator */ |
||
139 | #define RMF_INIT 01 /* initialization message */ |
||
140 | #define RMF_VER 03 /* verification message */ |
||
141 | #define RMF_TEST 05 /* hello and test message */ |
||
142 | #define RMF_L1ROUT 07 /* level 1 routing message */ |
||
143 | #define RMF_L2ROUT 011 /* level 2 routing message */ |
||
144 | #define RMF_RHELLO 013 /* router hello message */ |
||
145 | #define RMF_EHELLO 015 /* endnode hello message */ |
||
146 | |||
147 | #define TI_L2ROUT 01 /* level 2 router */ |
||
148 | #define TI_L1ROUT 02 /* level 1 router */ |
||
149 | #define TI_ENDNODE 03 /* endnode */ |
||
150 | #define TI_VERIF 04 /* verification required */ |
||
151 | #define TI_BLOCK 010 /* blocking requested */ |
||
152 | |||
153 | #define VE_VERS 2 /* version number (2) */ |
||
154 | #define VE_ECO 0 /* ECO number */ |
||
155 | #define VE_UECO 0 /* user ECO number (0) */ |
||
156 | |||
157 | #define P3_VERS 1 /* phase III version number (1) */ |
||
158 | #define P3_ECO 3 /* ECO number (3) */ |
||
159 | #define P3_UECO 0 /* user ECO number (0) */ |
||
160 | |||
161 | #define II_L2ROUT 01 /* level 2 router */ |
||
162 | #define II_L1ROUT 02 /* level 1 router */ |
||
163 | #define II_ENDNODE 03 /* endnode */ |
||
164 | #define II_VERIF 04 /* verification required */ |
||
165 | #define II_NOMCAST 040 /* no multicast traffic accepted */ |
||
166 | #define II_BLOCK 0100 /* blocking requested */ |
||
167 | #define II_TYPEMASK 03 /* mask for node type */ |
||
168 | |||
169 | #define TESTDATA 0252 /* test data bytes */ |
||
170 | #define TESTLEN 1 /* length of transmitted test data */ |
||
171 | |||
172 | /* |
||
173 | * Define control message formats. |
||
174 | */ |
||
175 | struct initmsgIII /* phase III initialization message */ |
||
176 | { |
||
177 | byte inIII_flags; /* route flags */ |
||
178 | word inIII_src; /* source node address */ |
||
179 | byte inIII_info; /* routing layer information */ |
||
180 | word inIII_blksize; /* maximum data link block size */ |
||
181 | byte inIII_vers; /* version number */ |
||
182 | byte inIII_eco; /* ECO number */ |
||
183 | byte inIII_ueco; /* user ECO number */ |
||
184 | byte inIII_rsvd; /* reserved image field */ |
||
185 | }; |
||
186 | |||
187 | struct initmsg /* initialization message */ |
||
188 | { |
||
189 | byte in_flags; /* route flags */ |
||
190 | word in_src; /* source node address */ |
||
191 | byte in_info; /* routing layer information */ |
||
192 | word in_blksize; /* maximum data link block size */ |
||
193 | byte in_vers; /* version number */ |
||
194 | byte in_eco; /* ECO number */ |
||
195 | byte in_ueco; /* user ECO number */ |
||
196 | word in_hello; /* hello timer */ |
||
197 | byte in_rsvd; /* reserved image field */ |
||
198 | }; |
||
199 | |||
200 | struct verifmsg /* verification message */ |
||
201 | { |
||
202 | byte ve_flags; /* route flags */ |
||
203 | word ve_src; /* source node address */ |
||
204 | byte ve_fcnval; /* function value image field */ |
||
205 | }; |
||
206 | |||
207 | struct testmsg /* hello and test message */ |
||
208 | { |
||
209 | byte te_flags; /* route flags */ |
||
210 | word te_src; /* source node address */ |
||
211 | byte te_data; /* test data image field */ |
||
212 | }; |
||
213 | |||
214 | struct l1rout /* level 1 routing message */ |
||
215 | { |
||
216 | byte r1_flags; /* route flags */ |
||
217 | word r1_src; /* source node address */ |
||
218 | byte r1_rsvd; /* reserved field */ |
||
219 | }; |
||
220 | |||
221 | struct l2rout /* level 2 routing message */ |
||
222 | { |
||
223 | byte r2_flags; /* route flags */ |
||
224 | word r2_src; /* source node address */ |
||
225 | byte r2_rsvd; /* reserved field */ |
||
226 | }; |
||
227 | |||
228 | struct rhellomsg /* router hello message */ |
||
229 | { |
||
230 | byte rh_flags; /* route flags */ |
||
231 | byte rh_vers; /* version number */ |
||
232 | byte rh_eco; /* ECO number */ |
||
233 | byte rh_ueco; /* user ECO number */ |
||
234 | etheraddr rh_src; /* source id */ |
||
235 | byte rh_info; /* routing layer information */ |
||
236 | word rh_blksize; /* maximum data link block size */ |
||
237 | byte rh_priority; /* router's priority */ |
||
238 | byte rh_area; /* reserved */ |
||
239 | word rh_hello; /* hello timer */ |
||
240 | byte rh_mpd; /* reserved */ |
||
241 | }; |
||
242 | |||
243 | struct ehellomsg /* endnode hello message */ |
||
244 | { |
||
245 | byte eh_flags; /* route flags */ |
||
246 | byte eh_vers; /* version number */ |
||
247 | byte eh_eco; /* ECO number */ |
||
248 | byte eh_ueco; /* user ECO number */ |
||
249 | etheraddr eh_src; /* source id */ |
||
250 | byte eh_info; /* routing layer information */ |
||
251 | word eh_blksize; /* maximum data link block size */ |
||
252 | byte eh_area; /* area (reserved) */ |
||
253 | byte eh_seed[8]; /* verification seed */ |
||
254 | etheraddr eh_router; /* designated router */ |
||
255 | word eh_hello; /* hello timer */ |
||
256 | byte eh_mpd; /* (reserved) */ |
||
257 | byte eh_data; /* test data image field */ |
||
258 | }; |
||
259 | |||
260 | union controlmsg |
||
261 | { |
||
262 | struct initmsg cm_init; /* initialization message */ |
||
263 | struct verifmsg cm_ver; /* verification message */ |
||
264 | struct testmsg cm_test; /* hello and test message */ |
||
265 | struct l1rout cm_l1rou; /* level 1 routing message */ |
||
266 | struct l2rout cm_l2rout; /* level 2 routing message */ |
||
267 | struct rhellomsg cm_rhello; /* router hello message */ |
||
268 | struct ehellomsg cm_ehello; /* endnode hello message */ |
||
269 | }; |
||
270 | |||
271 | /* Macros for decoding routing-info fields */ |
||
272 | #define RI_COST(x) ((x)&0777) |
||
273 | #define RI_HOPS(x) (((x)>>10)&037) |
||
274 | |||
275 | /* |
||
276 | * NSP protocol fields and values. |
||
277 | */ |
||
278 | |||
279 | #define NSP_TYPEMASK 014 /* mask to isolate type code */ |
||
280 | #define NSP_SUBMASK 0160 /* mask to isolate subtype code */ |
||
281 | #define NSP_SUBSHFT 4 /* shift to move subtype code */ |
||
282 | |||
283 | #define MFT_DATA 0 /* data message */ |
||
284 | #define MFT_ACK 04 /* acknowledgement message */ |
||
285 | #define MFT_CTL 010 /* control message */ |
||
286 | |||
287 | #define MFS_ILS 020 /* data or I/LS indicator */ |
||
288 | #define MFS_BOM 040 /* beginning of message (data) */ |
||
289 | #define MFS_MOM 0 /* middle of message (data) */ |
||
290 | #define MFS_EOM 0100 /* end of message (data) */ |
||
291 | #define MFS_INT 040 /* interrupt message */ |
||
292 | |||
293 | #define MFS_DACK 0 /* data acknowledgement */ |
||
294 | #define MFS_IACK 020 /* I/LS acknowledgement */ |
||
295 | #define MFS_CACK 040 /* connect acknowledgement */ |
||
296 | |||
297 | #define MFS_NOP 0 /* no operation */ |
||
298 | #define MFS_CI 020 /* connect initiate */ |
||
299 | #define MFS_CC 040 /* connect confirm */ |
||
300 | #define MFS_DI 060 /* disconnect initiate */ |
||
301 | #define MFS_DC 0100 /* disconnect confirm */ |
||
302 | #define MFS_RCI 0140 /* retransmitted connect initiate */ |
||
303 | |||
304 | #define SGQ_ACK 0100000 /* ack */ |
||
305 | #define SGQ_NAK 0110000 /* negative ack */ |
||
306 | #define SGQ_OACK 0120000 /* other channel ack */ |
||
307 | #define SGQ_ONAK 0130000 /* other channel negative ack */ |
||
308 | #define SGQ_MASK 07777 /* mask to isolate seq # */ |
||
309 | #define SGQ_OTHER 020000 /* other channel qualifier */ |
||
310 | #define SGQ_DELAY 010000 /* ack delay flag */ |
||
311 | |||
312 | #define SGQ_EOM 0100000 /* pseudo flag for end-of-message */ |
||
313 | |||
314 | #define LSM_MASK 03 /* mask for modifier field */ |
||
315 | #define LSM_NOCHANGE 0 /* no change */ |
||
316 | #define LSM_DONOTSEND 1 /* do not send data */ |
||
317 | #define LSM_SEND 2 /* send data */ |
||
318 | |||
319 | #define LSI_MASK 014 /* mask for interpretation field */ |
||
320 | #define LSI_DATA 0 /* data segment or message count */ |
||
321 | #define LSI_INTR 4 /* interrupt request count */ |
||
322 | #define LSI_INTM 0377 /* funny marker for int. message */ |
||
323 | |||
324 | #define COS_MASK 014 /* mask for flow control field */ |
||
325 | #define COS_NONE 0 /* no flow control */ |
||
326 | #define COS_SEGMENT 04 /* segment flow control */ |
||
327 | #define COS_MESSAGE 010 /* message flow control */ |
||
328 | #define COS_CRYPTSER 020 /* cryptographic services requested */ |
||
329 | #define COS_DEFAULT 1 /* default value for field */ |
||
330 | |||
331 | #define COI_MASK 3 /* mask for version field */ |
||
332 | #define COI_32 0 /* version 3.2 */ |
||
333 | #define COI_31 1 /* version 3.1 */ |
||
334 | #define COI_40 2 /* version 4.0 */ |
||
335 | #define COI_41 3 /* version 4.1 */ |
||
336 | |||
337 | #define MNU_MASK 140 /* mask for session control version */ |
||
338 | #define MNU_10 000 /* session V1.0 */ |
||
339 | #define MNU_20 040 /* session V2.0 */ |
||
340 | #define MNU_ACCESS 1 /* access control present */ |
||
341 | #define MNU_USRDATA 2 /* user data field present */ |
||
342 | #define MNU_INVKPROXY 4 /* invoke proxy field present */ |
||
343 | #define MNU_UICPROXY 8 /* use uic-based proxy */ |
||
344 | |||
345 | #define DC_NORESOURCES 1 /* no resource reason code */ |
||
346 | #define DC_NOLINK 41 /* no link terminate reason code */ |
||
347 | #define DC_COMPLETE 42 /* disconnect complete reason code */ |
||
348 | |||
349 | #define DI_NOERROR 0 /* user disconnect */ |
||
350 | #define DI_SHUT 3 /* node is shutting down */ |
||
351 | #define DI_NOUSER 4 /* destination end user does not exist */ |
||
352 | #define DI_INVDEST 5 /* invalid end user destination */ |
||
353 | #define DI_REMRESRC 6 /* insufficient remote resources */ |
||
354 | #define DI_TPA 8 /* third party abort */ |
||
355 | #define DI_PROTOCOL 7 /* protocol error discovered */ |
||
356 | #define DI_ABORT 9 /* user abort */ |
||
357 | #define DI_LOCALRESRC 32 /* insufficient local resources */ |
||
358 | #define DI_REMUSERRESRC 33 /* insufficient remote user resources */ |
||
359 | #define DI_BADACCESS 34 /* bad access control information */ |
||
360 | #define DI_BADACCNT 36 /* bad ACCOUNT information */ |
||
361 | #define DI_CONNECTABORT 38 /* connect request cancelled */ |
||
362 | #define DI_TIMEDOUT 38 /* remote node or user crashed */ |
||
363 | #define DI_UNREACHABLE 39 /* local timers expired due to ... */ |
||
364 | #define DI_BADIMAGE 43 /* bad image data in connect */ |
||
365 | #define DI_SERVMISMATCH 54 /* cryptographic service mismatch */ |
||
366 | |||
367 | #define UC_OBJREJECT 0 /* object rejected connect */ |
||
368 | #define UC_USERDISCONNECT 0 /* user disconnect */ |
||
369 | #define UC_RESOURCES 1 /* insufficient resources (local or remote) */ |
||
370 | #define UC_NOSUCHNODE 2 /* unrecognized node name */ |
||
371 | #define UC_REMOTESHUT 3 /* remote node shutting down */ |
||
372 | #define UC_NOSUCHOBJ 4 /* unrecognized object */ |
||
373 | #define UC_INVOBJFORMAT 5 /* invalid object name format */ |
||
374 | #define UC_OBJTOOBUSY 6 /* object too busy */ |
||
375 | #define UC_NETWORKABORT 8 /* network abort */ |
||
376 | #define UC_USERABORT 9 /* user abort */ |
||
377 | #define UC_INVNODEFORMAT 10 /* invalid node name format */ |
||
378 | #define UC_LOCALSHUT 11 /* local node shutting down */ |
||
379 | #define UC_ACCESSREJECT 34 /* invalid access control information */ |
||
380 | #define UC_NORESPONSE 38 /* no response from object */ |
||
381 | #define UC_UNREACHABLE 39 /* node unreachable */ |
||
382 | |||
383 | /* |
||
384 | * NSP message formats. |
||
385 | */ |
||
386 | struct nsphdr /* general nsp header */ |
||
387 | { |
||
388 | byte nh_flags; /* message flags */ |
||
389 | word nh_dst; /* destination link address */ |
||
390 | word nh_src; /* source link address */ |
||
391 | }; |
||
392 | |||
393 | struct seghdr /* data segment header */ |
||
394 | { |
||
395 | byte sh_flags; /* message flags */ |
||
396 | word sh_dst; /* destination link address */ |
||
397 | word sh_src; /* source link address */ |
||
398 | word sh_seq[3]; /* sequence numbers */ |
||
399 | }; |
||
400 | |||
401 | struct minseghdr /* minimum data segment header */ |
||
402 | { |
||
403 | byte ms_flags; /* message flags */ |
||
404 | word ms_dst; /* destination link address */ |
||
405 | word ms_src; /* source link address */ |
||
406 | word ms_seq; /* sequence number */ |
||
407 | }; |
||
408 | |||
409 | struct lsmsg /* link service message (after hdr) */ |
||
410 | { |
||
411 | byte ls_lsflags; /* link service flags */ |
||
412 | byte ls_fcval; /* flow control value */ |
||
413 | }; |
||
414 | |||
415 | struct ackmsg /* acknowledgement message */ |
||
416 | { |
||
417 | byte ak_flags; /* message flags */ |
||
418 | word ak_dst; /* destination link address */ |
||
419 | word ak_src; /* source link address */ |
||
420 | word ak_acknum[2]; /* acknowledgement numbers */ |
||
421 | }; |
||
422 | |||
423 | struct minackmsg /* minimum acknowledgement message */ |
||
424 | { |
||
425 | byte mk_flags; /* message flags */ |
||
426 | word mk_dst; /* destination link address */ |
||
427 | word mk_src; /* source link address */ |
||
428 | word mk_acknum; /* acknowledgement number */ |
||
429 | }; |
||
430 | |||
431 | struct ciackmsg /* connect acknowledgement message */ |
||
432 | { |
||
433 | byte ck_flags; /* message flags */ |
||
434 | word ck_dst; /* destination link address */ |
||
435 | }; |
||
436 | |||
437 | struct cimsg /* connect initiate message */ |
||
438 | { |
||
439 | byte ci_flags; /* message flags */ |
||
440 | word ci_dst; /* destination link address (0) */ |
||
441 | word ci_src; /* source link address */ |
||
442 | byte ci_services; /* requested services */ |
||
443 | byte ci_info; /* information */ |
||
444 | word ci_segsize; /* maximum segment size */ |
||
445 | }; |
||
446 | |||
447 | struct ccmsg /* connect confirm message */ |
||
448 | { |
||
449 | byte cc_flags; /* message flags */ |
||
450 | word cc_dst; /* destination link address */ |
||
451 | word cc_src; /* source link address */ |
||
452 | byte cc_services; /* requested services */ |
||
453 | byte cc_info; /* information */ |
||
454 | word cc_segsize; /* maximum segment size */ |
||
455 | byte cc_optlen; /* optional data length */ |
||
456 | }; |
||
457 | |||
458 | struct cnmsg /* generic connect message */ |
||
459 | { |
||
460 | byte cn_flags; /* message flags */ |
||
461 | word cn_dst; /* destination link address */ |
||
462 | word cn_src; /* source link address */ |
||
463 | byte cn_services; /* requested services */ |
||
464 | byte cn_info; /* information */ |
||
465 | word cn_segsize; /* maximum segment size */ |
||
466 | }; |
||
467 | |||
468 | struct dimsg /* disconnect initiate message */ |
||
469 | { |
||
470 | byte di_flags; /* message flags */ |
||
471 | word di_dst; /* destination link address */ |
||
472 | word di_src; /* source link address */ |
||
473 | word di_reason; /* reason code */ |
||
474 | byte di_optlen; /* optional data length */ |
||
475 | }; |
||
476 | |||
477 | struct dcmsg /* disconnect confirm message */ |
||
478 | { |
||
479 | byte dc_flags; /* message flags */ |
||
480 | word dc_dst; /* destination link address */ |
||
481 | word dc_src; /* source link address */ |
||
482 | word dc_reason; /* reason code */ |
||
483 | }; |
||
484 | |||
485 | /* Forwards */ |
||
486 | static int print_decnet_ctlmsg(netdissect_options *, const union routehdr *, u_int, u_int); |
||
487 | static void print_t_info(netdissect_options *, int); |
||
488 | static int print_l1_routes(netdissect_options *, const char *, u_int); |
||
489 | static int print_l2_routes(netdissect_options *, const char *, u_int); |
||
490 | static void print_i_info(netdissect_options *, int); |
||
491 | static int print_elist(const char *, u_int); |
||
492 | static int print_nsp(netdissect_options *, const u_char *, u_int); |
||
493 | static void print_reason(netdissect_options *, int); |
||
494 | #ifdef PRINT_NSPDATA |
||
495 | static void pdata(netdissect_options *, u_char *, u_int); |
||
496 | #endif |
||
497 | |||
498 | #ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA |
||
499 | extern char *dnet_htoa(struct dn_naddr *); |
||
500 | #endif |
||
501 | |||
502 | void |
||
503 | decnet_print(netdissect_options *ndo, |
||
504 | register const u_char *ap, register u_int length, |
||
505 | register u_int caplen) |
||
506 | { |
||
507 | register const union routehdr *rhp; |
||
508 | register int mflags; |
||
509 | int dst, src, hops; |
||
510 | u_int nsplen, pktlen; |
||
511 | const u_char *nspp; |
||
512 | |||
513 | if (length < sizeof(struct shorthdr)) { |
||
514 | ND_PRINT((ndo, "%s", tstr)); |
||
515 | return; |
||
516 | } |
||
517 | |||
518 | ND_TCHECK2(*ap, sizeof(short)); |
||
519 | pktlen = EXTRACT_LE_16BITS(ap); |
||
520 | if (pktlen < sizeof(struct shorthdr)) { |
||
521 | ND_PRINT((ndo, "%s", tstr)); |
||
522 | return; |
||
523 | } |
||
524 | if (pktlen > length) { |
||
525 | ND_PRINT((ndo, "%s", tstr)); |
||
526 | return; |
||
527 | } |
||
528 | length = pktlen; |
||
529 | |||
530 | rhp = (const union routehdr *)&(ap[sizeof(short)]); |
||
531 | ND_TCHECK(rhp->rh_short.sh_flags); |
||
532 | mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); |
||
533 | |||
534 | if (mflags & RMF_PAD) { |
||
535 | /* pad bytes of some sort in front of message */ |
||
536 | u_int padlen = mflags & RMF_PADMASK; |
||
537 | if (ndo->ndo_vflag) |
||
538 | ND_PRINT((ndo, "[pad:%d] ", padlen)); |
||
539 | if (length < padlen + 2) { |
||
540 | ND_PRINT((ndo, "%s", tstr)); |
||
541 | return; |
||
542 | } |
||
543 | ND_TCHECK2(ap[sizeof(short)], padlen); |
||
544 | ap += padlen; |
||
545 | length -= padlen; |
||
546 | caplen -= padlen; |
||
547 | rhp = (const union routehdr *)&(ap[sizeof(short)]); |
||
548 | mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); |
||
549 | } |
||
550 | |||
551 | if (mflags & RMF_FVER) { |
||
552 | ND_PRINT((ndo, "future-version-decnet")); |
||
553 | ND_DEFAULTPRINT(ap, min(length, caplen)); |
||
554 | return; |
||
555 | } |
||
556 | |||
557 | /* is it a control message? */ |
||
558 | if (mflags & RMF_CTLMSG) { |
||
559 | if (!print_decnet_ctlmsg(ndo, rhp, length, caplen)) |
||
560 | goto trunc; |
||
561 | return; |
||
562 | } |
||
563 | |||
564 | switch (mflags & RMF_MASK) { |
||
565 | case RMF_LONG: |
||
566 | if (length < sizeof(struct longhdr)) { |
||
567 | ND_PRINT((ndo, "%s", tstr)); |
||
568 | return; |
||
569 | } |
||
570 | ND_TCHECK(rhp->rh_long); |
||
571 | dst = |
||
572 | EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr); |
||
573 | src = |
||
574 | EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr); |
||
575 | hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits); |
||
576 | nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]); |
||
577 | nsplen = length - sizeof(struct longhdr); |
||
578 | break; |
||
579 | case RMF_SHORT: |
||
580 | ND_TCHECK(rhp->rh_short); |
||
581 | dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst); |
||
582 | src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src); |
||
583 | hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1; |
||
584 | nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]); |
||
585 | nsplen = length - sizeof(struct shorthdr); |
||
586 | break; |
||
587 | default: |
||
588 | ND_PRINT((ndo, "unknown message flags under mask")); |
||
589 | ND_DEFAULTPRINT((u_char *)ap, min(length, caplen)); |
||
590 | return; |
||
591 | } |
||
592 | |||
593 | ND_PRINT((ndo, "%s > %s %d ", |
||
594 | dnaddr_string(ndo, src), dnaddr_string(ndo, dst), pktlen)); |
||
595 | if (ndo->ndo_vflag) { |
||
596 | if (mflags & RMF_RQR) |
||
597 | ND_PRINT((ndo, "RQR ")); |
||
598 | if (mflags & RMF_RTS) |
||
599 | ND_PRINT((ndo, "RTS ")); |
||
600 | if (mflags & RMF_IE) |
||
601 | ND_PRINT((ndo, "IE ")); |
||
602 | ND_PRINT((ndo, "%d hops ", hops)); |
||
603 | } |
||
604 | |||
605 | if (!print_nsp(ndo, nspp, nsplen)) |
||
606 | goto trunc; |
||
607 | return; |
||
608 | |||
609 | trunc: |
||
610 | ND_PRINT((ndo, "%s", tstr)); |
||
611 | return; |
||
612 | } |
||
613 | |||
614 | static int |
||
615 | print_decnet_ctlmsg(netdissect_options *ndo, |
||
616 | register const union routehdr *rhp, u_int length, |
||
617 | u_int caplen) |
||
618 | { |
||
619 | int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags); |
||
620 | register union controlmsg *cmp = (union controlmsg *)rhp; |
||
621 | int src, dst, info, blksize, eco, ueco, hello, other, vers; |
||
622 | etheraddr srcea, rtea; |
||
623 | int priority; |
||
624 | char *rhpx = (char *)rhp; |
||
625 | int ret; |
||
626 | |||
627 | switch (mflags & RMF_CTLMASK) { |
||
628 | case RMF_INIT: |
||
629 | ND_PRINT((ndo, "init ")); |
||
630 | if (length < sizeof(struct initmsg)) |
||
631 | goto trunc; |
||
632 | ND_TCHECK(cmp->cm_init); |
||
633 | src = EXTRACT_LE_16BITS(cmp->cm_init.in_src); |
||
634 | info = EXTRACT_LE_8BITS(cmp->cm_init.in_info); |
||
635 | blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize); |
||
636 | vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers); |
||
637 | eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco); |
||
638 | ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco); |
||
639 | hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello); |
||
640 | print_t_info(ndo, info); |
||
641 | ND_PRINT((ndo, |
||
642 | "src %sblksize %d vers %d eco %d ueco %d hello %d", |
||
643 | dnaddr_string(ndo, src), blksize, vers, eco, ueco, |
||
644 | hello)); |
||
645 | ret = 1; |
||
646 | break; |
||
647 | case RMF_VER: |
||
648 | ND_PRINT((ndo, "verification ")); |
||
649 | if (length < sizeof(struct verifmsg)) |
||
650 | goto trunc; |
||
651 | ND_TCHECK(cmp->cm_ver); |
||
652 | src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src); |
||
653 | other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval); |
||
654 | ND_PRINT((ndo, "src %s fcnval %o", dnaddr_string(ndo, src), other)); |
||
655 | ret = 1; |
||
656 | break; |
||
657 | case RMF_TEST: |
||
658 | ND_PRINT((ndo, "test ")); |
||
659 | if (length < sizeof(struct testmsg)) |
||
660 | goto trunc; |
||
661 | ND_TCHECK(cmp->cm_test); |
||
662 | src = EXTRACT_LE_16BITS(cmp->cm_test.te_src); |
||
663 | other = EXTRACT_LE_8BITS(cmp->cm_test.te_data); |
||
664 | ND_PRINT((ndo, "src %s data %o", dnaddr_string(ndo, src), other)); |
||
665 | ret = 1; |
||
666 | break; |
||
667 | case RMF_L1ROUT: |
||
668 | ND_PRINT((ndo, "lev-1-routing ")); |
||
669 | if (length < sizeof(struct l1rout)) |
||
670 | goto trunc; |
||
671 | ND_TCHECK(cmp->cm_l1rou); |
||
672 | src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src); |
||
673 | ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); |
||
674 | ret = print_l1_routes(ndo, &(rhpx[sizeof(struct l1rout)]), |
||
675 | length - sizeof(struct l1rout)); |
||
676 | break; |
||
677 | case RMF_L2ROUT: |
||
678 | ND_PRINT((ndo, "lev-2-routing ")); |
||
679 | if (length < sizeof(struct l2rout)) |
||
680 | goto trunc; |
||
681 | ND_TCHECK(cmp->cm_l2rout); |
||
682 | src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src); |
||
683 | ND_PRINT((ndo, "src %s ", dnaddr_string(ndo, src))); |
||
684 | ret = print_l2_routes(ndo, &(rhpx[sizeof(struct l2rout)]), |
||
685 | length - sizeof(struct l2rout)); |
||
686 | break; |
||
687 | case RMF_RHELLO: |
||
688 | ND_PRINT((ndo, "router-hello ")); |
||
689 | if (length < sizeof(struct rhellomsg)) |
||
690 | goto trunc; |
||
691 | ND_TCHECK(cmp->cm_rhello); |
||
692 | vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers); |
||
693 | eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco); |
||
694 | ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco); |
||
695 | memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src), |
||
696 | sizeof(srcea)); |
||
697 | src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); |
||
698 | info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info); |
||
699 | blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize); |
||
700 | priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority); |
||
701 | hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello); |
||
702 | print_i_info(ndo, info); |
||
703 | ND_PRINT((ndo, |
||
704 | "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d", |
||
705 | vers, eco, ueco, dnaddr_string(ndo, src), |
||
706 | blksize, priority, hello)); |
||
707 | ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]), |
||
708 | length - sizeof(struct rhellomsg)); |
||
709 | break; |
||
710 | case RMF_EHELLO: |
||
711 | ND_PRINT((ndo, "endnode-hello ")); |
||
712 | if (length < sizeof(struct ehellomsg)) |
||
713 | goto trunc; |
||
714 | ND_TCHECK(cmp->cm_ehello); |
||
715 | vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers); |
||
716 | eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco); |
||
717 | ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco); |
||
718 | memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src), |
||
719 | sizeof(srcea)); |
||
720 | src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr); |
||
721 | info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info); |
||
722 | blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize); |
||
723 | /*seed*/ |
||
724 | memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router), |
||
725 | sizeof(rtea)); |
||
726 | dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr); |
||
727 | hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello); |
||
728 | other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data); |
||
729 | print_i_info(ndo, info); |
||
730 | ND_PRINT((ndo, |
||
731 | "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o", |
||
732 | vers, eco, ueco, dnaddr_string(ndo, src), |
||
733 | blksize, dnaddr_string(ndo, dst), hello, other)); |
||
734 | ret = 1; |
||
735 | break; |
||
736 | |||
737 | default: |
||
738 | ND_PRINT((ndo, "unknown control message")); |
||
739 | ND_DEFAULTPRINT((u_char *)rhp, min(length, caplen)); |
||
740 | ret = 1; |
||
741 | break; |
||
742 | } |
||
743 | return (ret); |
||
744 | |||
745 | trunc: |
||
746 | return (0); |
||
747 | } |
||
748 | |||
749 | static void |
||
750 | print_t_info(netdissect_options *ndo, |
||
751 | int info) |
||
752 | { |
||
753 | int ntype = info & 3; |
||
754 | switch (ntype) { |
||
755 | case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; |
||
756 | case TI_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; |
||
757 | case TI_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; |
||
758 | case TI_ENDNODE: ND_PRINT((ndo, "endnode ")); break; |
||
759 | } |
||
760 | if (info & TI_VERIF) |
||
761 | ND_PRINT((ndo, "verif ")); |
||
762 | if (info & TI_BLOCK) |
||
763 | ND_PRINT((ndo, "blo ")); |
||
764 | } |
||
765 | |||
766 | static int |
||
767 | print_l1_routes(netdissect_options *ndo, |
||
768 | const char *rp, u_int len) |
||
769 | { |
||
770 | int count; |
||
771 | int id; |
||
772 | int info; |
||
773 | |||
774 | /* The last short is a checksum */ |
||
775 | while (len > (3 * sizeof(short))) { |
||
776 | ND_TCHECK2(*rp, 3 * sizeof(short)); |
||
777 | count = EXTRACT_LE_16BITS(rp); |
||
778 | if (count > 1024) |
||
779 | return (1); /* seems to be bogus from here on */ |
||
780 | rp += sizeof(short); |
||
781 | len -= sizeof(short); |
||
782 | id = EXTRACT_LE_16BITS(rp); |
||
783 | rp += sizeof(short); |
||
784 | len -= sizeof(short); |
||
785 | info = EXTRACT_LE_16BITS(rp); |
||
786 | rp += sizeof(short); |
||
787 | len -= sizeof(short); |
||
788 | ND_PRINT((ndo, "{ids %d-%d cost %d hops %d} ", id, id + count, |
||
789 | RI_COST(info), RI_HOPS(info))); |
||
790 | } |
||
791 | return (1); |
||
792 | |||
793 | trunc: |
||
794 | return (0); |
||
795 | } |
||
796 | |||
797 | static int |
||
798 | print_l2_routes(netdissect_options *ndo, |
||
799 | const char *rp, u_int len) |
||
800 | { |
||
801 | int count; |
||
802 | int area; |
||
803 | int info; |
||
804 | |||
805 | /* The last short is a checksum */ |
||
806 | while (len > (3 * sizeof(short))) { |
||
807 | ND_TCHECK2(*rp, 3 * sizeof(short)); |
||
808 | count = EXTRACT_LE_16BITS(rp); |
||
809 | if (count > 1024) |
||
810 | return (1); /* seems to be bogus from here on */ |
||
811 | rp += sizeof(short); |
||
812 | len -= sizeof(short); |
||
813 | area = EXTRACT_LE_16BITS(rp); |
||
814 | rp += sizeof(short); |
||
815 | len -= sizeof(short); |
||
816 | info = EXTRACT_LE_16BITS(rp); |
||
817 | rp += sizeof(short); |
||
818 | len -= sizeof(short); |
||
819 | ND_PRINT((ndo, "{areas %d-%d cost %d hops %d} ", area, area + count, |
||
820 | RI_COST(info), RI_HOPS(info))); |
||
821 | } |
||
822 | return (1); |
||
823 | |||
824 | trunc: |
||
825 | return (0); |
||
826 | } |
||
827 | |||
828 | static void |
||
829 | print_i_info(netdissect_options *ndo, |
||
830 | int info) |
||
831 | { |
||
832 | int ntype = info & II_TYPEMASK; |
||
833 | switch (ntype) { |
||
834 | case 0: ND_PRINT((ndo, "reserved-ntype? ")); break; |
||
835 | case II_L2ROUT: ND_PRINT((ndo, "l2rout ")); break; |
||
836 | case II_L1ROUT: ND_PRINT((ndo, "l1rout ")); break; |
||
837 | case II_ENDNODE: ND_PRINT((ndo, "endnode ")); break; |
||
838 | } |
||
839 | if (info & II_VERIF) |
||
840 | ND_PRINT((ndo, "verif ")); |
||
841 | if (info & II_NOMCAST) |
||
842 | ND_PRINT((ndo, "nomcast ")); |
||
843 | if (info & II_BLOCK) |
||
844 | ND_PRINT((ndo, "blo ")); |
||
845 | } |
||
846 | |||
847 | static int |
||
848 | print_elist(const char *elp _U_, u_int len _U_) |
||
849 | { |
||
850 | /* Not enough examples available for me to debug this */ |
||
851 | return (1); |
||
852 | } |
||
853 | |||
854 | static int |
||
855 | print_nsp(netdissect_options *ndo, |
||
856 | const u_char *nspp, u_int nsplen) |
||
857 | { |
||
858 | const struct nsphdr *nsphp = (struct nsphdr *)nspp; |
||
859 | int dst, src, flags; |
||
860 | |||
861 | if (nsplen < sizeof(struct nsphdr)) |
||
862 | goto trunc; |
||
863 | ND_TCHECK(*nsphp); |
||
864 | flags = EXTRACT_LE_8BITS(nsphp->nh_flags); |
||
865 | dst = EXTRACT_LE_16BITS(nsphp->nh_dst); |
||
866 | src = EXTRACT_LE_16BITS(nsphp->nh_src); |
||
867 | |||
868 | switch (flags & NSP_TYPEMASK) { |
||
869 | case MFT_DATA: |
||
870 | switch (flags & NSP_SUBMASK) { |
||
871 | case MFS_BOM: |
||
872 | case MFS_MOM: |
||
873 | case MFS_EOM: |
||
874 | case MFS_BOM+MFS_EOM: |
||
875 | ND_PRINT((ndo, "data %d>%d ", src, dst)); |
||
876 | { |
||
877 | struct seghdr *shp = (struct seghdr *)nspp; |
||
878 | int ack; |
||
879 | #ifdef PRINT_NSPDATA |
||
880 | u_char *dp; |
||
881 | #endif |
||
882 | u_int data_off = sizeof(struct minseghdr); |
||
883 | |||
884 | if (nsplen < data_off) |
||
885 | goto trunc; |
||
886 | ND_TCHECK(shp->sh_seq[0]); |
||
887 | ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); |
||
888 | if (ack & SGQ_ACK) { /* acknum field */ |
||
889 | if ((ack & SGQ_NAK) == SGQ_NAK) |
||
890 | ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); |
||
891 | else |
||
892 | ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); |
||
893 | data_off += sizeof(short); |
||
894 | if (nsplen < data_off) |
||
895 | goto trunc; |
||
896 | ND_TCHECK(shp->sh_seq[1]); |
||
897 | ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); |
||
898 | if (ack & SGQ_OACK) { /* ackoth field */ |
||
899 | if ((ack & SGQ_ONAK) == SGQ_ONAK) |
||
900 | ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); |
||
901 | else |
||
902 | ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); |
||
903 | data_off += sizeof(short); |
||
904 | if (nsplen < data_off) |
||
905 | goto trunc; |
||
906 | ND_TCHECK(shp->sh_seq[2]); |
||
907 | ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); |
||
908 | } |
||
909 | } |
||
910 | ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); |
||
911 | #ifdef PRINT_NSPDATA |
||
912 | if (nsplen > data_off) { |
||
913 | dp = &(nspp[data_off]); |
||
914 | ND_TCHECK2(*dp, nsplen - data_off); |
||
915 | pdata(ndo, dp, nsplen - data_off); |
||
916 | } |
||
917 | #endif |
||
918 | } |
||
919 | break; |
||
920 | case MFS_ILS+MFS_INT: |
||
921 | ND_PRINT((ndo, "intr ")); |
||
922 | { |
||
923 | struct seghdr *shp = (struct seghdr *)nspp; |
||
924 | int ack; |
||
925 | #ifdef PRINT_NSPDATA |
||
926 | u_char *dp; |
||
927 | #endif |
||
928 | u_int data_off = sizeof(struct minseghdr); |
||
929 | |||
930 | if (nsplen < data_off) |
||
931 | goto trunc; |
||
932 | ND_TCHECK(shp->sh_seq[0]); |
||
933 | ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); |
||
934 | if (ack & SGQ_ACK) { /* acknum field */ |
||
935 | if ((ack & SGQ_NAK) == SGQ_NAK) |
||
936 | ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); |
||
937 | else |
||
938 | ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); |
||
939 | data_off += sizeof(short); |
||
940 | if (nsplen < data_off) |
||
941 | goto trunc; |
||
942 | ND_TCHECK(shp->sh_seq[1]); |
||
943 | ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); |
||
944 | if (ack & SGQ_OACK) { /* ackdat field */ |
||
945 | if ((ack & SGQ_ONAK) == SGQ_ONAK) |
||
946 | ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); |
||
947 | else |
||
948 | ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); |
||
949 | data_off += sizeof(short); |
||
950 | if (nsplen < data_off) |
||
951 | goto trunc; |
||
952 | ND_TCHECK(shp->sh_seq[2]); |
||
953 | ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); |
||
954 | } |
||
955 | } |
||
956 | ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); |
||
957 | #ifdef PRINT_NSPDATA |
||
958 | if (nsplen > data_off) { |
||
959 | dp = &(nspp[data_off]); |
||
960 | ND_TCHECK2(*dp, nsplen - data_off); |
||
961 | pdata(ndo, dp, nsplen - data_off); |
||
962 | } |
||
963 | #endif |
||
964 | } |
||
965 | break; |
||
966 | case MFS_ILS: |
||
967 | ND_PRINT((ndo, "link-service %d>%d ", src, dst)); |
||
968 | { |
||
969 | struct seghdr *shp = (struct seghdr *)nspp; |
||
970 | struct lsmsg *lsmp = |
||
971 | (struct lsmsg *)&(nspp[sizeof(struct seghdr)]); |
||
972 | int ack; |
||
973 | int lsflags, fcval; |
||
974 | |||
975 | if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg)) |
||
976 | goto trunc; |
||
977 | ND_TCHECK(shp->sh_seq[0]); |
||
978 | ack = EXTRACT_LE_16BITS(shp->sh_seq[0]); |
||
979 | if (ack & SGQ_ACK) { /* acknum field */ |
||
980 | if ((ack & SGQ_NAK) == SGQ_NAK) |
||
981 | ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); |
||
982 | else |
||
983 | ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); |
||
984 | ND_TCHECK(shp->sh_seq[1]); |
||
985 | ack = EXTRACT_LE_16BITS(shp->sh_seq[1]); |
||
986 | if (ack & SGQ_OACK) { /* ackdat field */ |
||
987 | if ((ack & SGQ_ONAK) == SGQ_ONAK) |
||
988 | ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); |
||
989 | else |
||
990 | ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); |
||
991 | ND_TCHECK(shp->sh_seq[2]); |
||
992 | ack = EXTRACT_LE_16BITS(shp->sh_seq[2]); |
||
993 | } |
||
994 | } |
||
995 | ND_PRINT((ndo, "seg %d ", ack & SGQ_MASK)); |
||
996 | ND_TCHECK(*lsmp); |
||
997 | lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags); |
||
998 | fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval); |
||
999 | switch (lsflags & LSI_MASK) { |
||
1000 | case LSI_DATA: |
||
1001 | ND_PRINT((ndo, "dat seg count %d ", fcval)); |
||
1002 | switch (lsflags & LSM_MASK) { |
||
1003 | case LSM_NOCHANGE: |
||
1004 | break; |
||
1005 | case LSM_DONOTSEND: |
||
1006 | ND_PRINT((ndo, "donotsend-data ")); |
||
1007 | break; |
||
1008 | case LSM_SEND: |
||
1009 | ND_PRINT((ndo, "send-data ")); |
||
1010 | break; |
||
1011 | default: |
||
1012 | ND_PRINT((ndo, "reserved-fcmod? %x", lsflags)); |
||
1013 | break; |
||
1014 | } |
||
1015 | break; |
||
1016 | case LSI_INTR: |
||
1017 | ND_PRINT((ndo, "intr req count %d ", fcval)); |
||
1018 | break; |
||
1019 | default: |
||
1020 | ND_PRINT((ndo, "reserved-fcval-int? %x", lsflags)); |
||
1021 | break; |
||
1022 | } |
||
1023 | } |
||
1024 | break; |
||
1025 | default: |
||
1026 | ND_PRINT((ndo, "reserved-subtype? %x %d > %d", flags, src, dst)); |
||
1027 | break; |
||
1028 | } |
||
1029 | break; |
||
1030 | case MFT_ACK: |
||
1031 | switch (flags & NSP_SUBMASK) { |
||
1032 | case MFS_DACK: |
||
1033 | ND_PRINT((ndo, "data-ack %d>%d ", src, dst)); |
||
1034 | { |
||
1035 | struct ackmsg *amp = (struct ackmsg *)nspp; |
||
1036 | int ack; |
||
1037 | |||
1038 | if (nsplen < sizeof(struct ackmsg)) |
||
1039 | goto trunc; |
||
1040 | ND_TCHECK(*amp); |
||
1041 | ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); |
||
1042 | if (ack & SGQ_ACK) { /* acknum field */ |
||
1043 | if ((ack & SGQ_NAK) == SGQ_NAK) |
||
1044 | ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); |
||
1045 | else |
||
1046 | ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); |
||
1047 | ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); |
||
1048 | if (ack & SGQ_OACK) { /* ackoth field */ |
||
1049 | if ((ack & SGQ_ONAK) == SGQ_ONAK) |
||
1050 | ND_PRINT((ndo, "onak %d ", ack & SGQ_MASK)); |
||
1051 | else |
||
1052 | ND_PRINT((ndo, "oack %d ", ack & SGQ_MASK)); |
||
1053 | } |
||
1054 | } |
||
1055 | } |
||
1056 | break; |
||
1057 | case MFS_IACK: |
||
1058 | ND_PRINT((ndo, "ils-ack %d>%d ", src, dst)); |
||
1059 | { |
||
1060 | struct ackmsg *amp = (struct ackmsg *)nspp; |
||
1061 | int ack; |
||
1062 | |||
1063 | if (nsplen < sizeof(struct ackmsg)) |
||
1064 | goto trunc; |
||
1065 | ND_TCHECK(*amp); |
||
1066 | ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]); |
||
1067 | if (ack & SGQ_ACK) { /* acknum field */ |
||
1068 | if ((ack & SGQ_NAK) == SGQ_NAK) |
||
1069 | ND_PRINT((ndo, "nak %d ", ack & SGQ_MASK)); |
||
1070 | else |
||
1071 | ND_PRINT((ndo, "ack %d ", ack & SGQ_MASK)); |
||
1072 | ND_TCHECK(amp->ak_acknum[1]); |
||
1073 | ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]); |
||
1074 | if (ack & SGQ_OACK) { /* ackdat field */ |
||
1075 | if ((ack & SGQ_ONAK) == SGQ_ONAK) |
||
1076 | ND_PRINT((ndo, "nakdat %d ", ack & SGQ_MASK)); |
||
1077 | else |
||
1078 | ND_PRINT((ndo, "ackdat %d ", ack & SGQ_MASK)); |
||
1079 | } |
||
1080 | } |
||
1081 | } |
||
1082 | break; |
||
1083 | case MFS_CACK: |
||
1084 | ND_PRINT((ndo, "conn-ack %d", dst)); |
||
1085 | break; |
||
1086 | default: |
||
1087 | ND_PRINT((ndo, "reserved-acktype? %x %d > %d", flags, src, dst)); |
||
1088 | break; |
||
1089 | } |
||
1090 | break; |
||
1091 | case MFT_CTL: |
||
1092 | switch (flags & NSP_SUBMASK) { |
||
1093 | case MFS_CI: |
||
1094 | case MFS_RCI: |
||
1095 | if ((flags & NSP_SUBMASK) == MFS_CI) |
||
1096 | ND_PRINT((ndo, "conn-initiate ")); |
||
1097 | else |
||
1098 | ND_PRINT((ndo, "retrans-conn-initiate ")); |
||
1099 | ND_PRINT((ndo, "%d>%d ", src, dst)); |
||
1100 | { |
||
1101 | struct cimsg *cimp = (struct cimsg *)nspp; |
||
1102 | int services, info, segsize; |
||
1103 | #ifdef PRINT_NSPDATA |
||
1104 | u_char *dp; |
||
1105 | #endif |
||
1106 | |||
1107 | if (nsplen < sizeof(struct cimsg)) |
||
1108 | goto trunc; |
||
1109 | ND_TCHECK(*cimp); |
||
1110 | services = EXTRACT_LE_8BITS(cimp->ci_services); |
||
1111 | info = EXTRACT_LE_8BITS(cimp->ci_info); |
||
1112 | segsize = EXTRACT_LE_16BITS(cimp->ci_segsize); |
||
1113 | |||
1114 | switch (services & COS_MASK) { |
||
1115 | case COS_NONE: |
||
1116 | break; |
||
1117 | case COS_SEGMENT: |
||
1118 | ND_PRINT((ndo, "seg ")); |
||
1119 | break; |
||
1120 | case COS_MESSAGE: |
||
1121 | ND_PRINT((ndo, "msg ")); |
||
1122 | break; |
||
1123 | case COS_CRYPTSER: |
||
1124 | ND_PRINT((ndo, "crypt ")); |
||
1125 | break; |
||
1126 | } |
||
1127 | switch (info & COI_MASK) { |
||
1128 | case COI_32: |
||
1129 | ND_PRINT((ndo, "ver 3.2 ")); |
||
1130 | break; |
||
1131 | case COI_31: |
||
1132 | ND_PRINT((ndo, "ver 3.1 ")); |
||
1133 | break; |
||
1134 | case COI_40: |
||
1135 | ND_PRINT((ndo, "ver 4.0 ")); |
||
1136 | break; |
||
1137 | case COI_41: |
||
1138 | ND_PRINT((ndo, "ver 4.1 ")); |
||
1139 | break; |
||
1140 | } |
||
1141 | ND_PRINT((ndo, "segsize %d ", segsize)); |
||
1142 | #ifdef PRINT_NSPDATA |
||
1143 | if (nsplen > sizeof(struct cimsg)) { |
||
1144 | dp = &(nspp[sizeof(struct cimsg)]); |
||
1145 | ND_TCHECK2(*dp, nsplen - sizeof(struct cimsg)); |
||
1146 | pdata(ndo, dp, nsplen - sizeof(struct cimsg)); |
||
1147 | } |
||
1148 | #endif |
||
1149 | } |
||
1150 | break; |
||
1151 | case MFS_CC: |
||
1152 | ND_PRINT((ndo, "conn-confirm %d>%d ", src, dst)); |
||
1153 | { |
||
1154 | struct ccmsg *ccmp = (struct ccmsg *)nspp; |
||
1155 | int services, info; |
||
1156 | u_int segsize, optlen; |
||
1157 | #ifdef PRINT_NSPDATA |
||
1158 | u_char *dp; |
||
1159 | #endif |
||
1160 | |||
1161 | if (nsplen < sizeof(struct ccmsg)) |
||
1162 | goto trunc; |
||
1163 | ND_TCHECK(*ccmp); |
||
1164 | services = EXTRACT_LE_8BITS(ccmp->cc_services); |
||
1165 | info = EXTRACT_LE_8BITS(ccmp->cc_info); |
||
1166 | segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize); |
||
1167 | optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen); |
||
1168 | |||
1169 | switch (services & COS_MASK) { |
||
1170 | case COS_NONE: |
||
1171 | break; |
||
1172 | case COS_SEGMENT: |
||
1173 | ND_PRINT((ndo, "seg ")); |
||
1174 | break; |
||
1175 | case COS_MESSAGE: |
||
1176 | ND_PRINT((ndo, "msg ")); |
||
1177 | break; |
||
1178 | case COS_CRYPTSER: |
||
1179 | ND_PRINT((ndo, "crypt ")); |
||
1180 | break; |
||
1181 | } |
||
1182 | switch (info & COI_MASK) { |
||
1183 | case COI_32: |
||
1184 | ND_PRINT((ndo, "ver 3.2 ")); |
||
1185 | break; |
||
1186 | case COI_31: |
||
1187 | ND_PRINT((ndo, "ver 3.1 ")); |
||
1188 | break; |
||
1189 | case COI_40: |
||
1190 | ND_PRINT((ndo, "ver 4.0 ")); |
||
1191 | break; |
||
1192 | case COI_41: |
||
1193 | ND_PRINT((ndo, "ver 4.1 ")); |
||
1194 | break; |
||
1195 | } |
||
1196 | ND_PRINT((ndo, "segsize %d ", segsize)); |
||
1197 | if (optlen) { |
||
1198 | ND_PRINT((ndo, "optlen %d ", optlen)); |
||
1199 | #ifdef PRINT_NSPDATA |
||
1200 | if (optlen > nsplen - sizeof(struct ccmsg)) |
||
1201 | goto trunc; |
||
1202 | dp = &(nspp[sizeof(struct ccmsg)]); |
||
1203 | ND_TCHECK2(*dp, optlen); |
||
1204 | pdata(ndo, dp, optlen); |
||
1205 | #endif |
||
1206 | } |
||
1207 | } |
||
1208 | break; |
||
1209 | case MFS_DI: |
||
1210 | ND_PRINT((ndo, "disconn-initiate %d>%d ", src, dst)); |
||
1211 | { |
||
1212 | struct dimsg *dimp = (struct dimsg *)nspp; |
||
1213 | int reason; |
||
1214 | u_int optlen; |
||
1215 | #ifdef PRINT_NSPDATA |
||
1216 | u_char *dp; |
||
1217 | #endif |
||
1218 | |||
1219 | if (nsplen < sizeof(struct dimsg)) |
||
1220 | goto trunc; |
||
1221 | ND_TCHECK(*dimp); |
||
1222 | reason = EXTRACT_LE_16BITS(dimp->di_reason); |
||
1223 | optlen = EXTRACT_LE_8BITS(dimp->di_optlen); |
||
1224 | |||
1225 | print_reason(ndo, reason); |
||
1226 | if (optlen) { |
||
1227 | ND_PRINT((ndo, "optlen %d ", optlen)); |
||
1228 | #ifdef PRINT_NSPDATA |
||
1229 | if (optlen > nsplen - sizeof(struct dimsg)) |
||
1230 | goto trunc; |
||
1231 | dp = &(nspp[sizeof(struct dimsg)]); |
||
1232 | ND_TCHECK2(*dp, optlen); |
||
1233 | pdata(ndo, dp, optlen); |
||
1234 | #endif |
||
1235 | } |
||
1236 | } |
||
1237 | break; |
||
1238 | case MFS_DC: |
||
1239 | ND_PRINT((ndo, "disconn-confirm %d>%d ", src, dst)); |
||
1240 | { |
||
1241 | struct dcmsg *dcmp = (struct dcmsg *)nspp; |
||
1242 | int reason; |
||
1243 | |||
1244 | ND_TCHECK(*dcmp); |
||
1245 | reason = EXTRACT_LE_16BITS(dcmp->dc_reason); |
||
1246 | |||
1247 | print_reason(ndo, reason); |
||
1248 | } |
||
1249 | break; |
||
1250 | default: |
||
1251 | ND_PRINT((ndo, "reserved-ctltype? %x %d > %d", flags, src, dst)); |
||
1252 | break; |
||
1253 | } |
||
1254 | break; |
||
1255 | default: |
||
1256 | ND_PRINT((ndo, "reserved-type? %x %d > %d", flags, src, dst)); |
||
1257 | break; |
||
1258 | } |
||
1259 | return (1); |
||
1260 | |||
1261 | trunc: |
||
1262 | return (0); |
||
1263 | } |
||
1264 | |||
1265 | static const struct tok reason2str[] = { |
||
1266 | { UC_OBJREJECT, "object rejected connect" }, |
||
1267 | { UC_RESOURCES, "insufficient resources" }, |
||
1268 | { UC_NOSUCHNODE, "unrecognized node name" }, |
||
1269 | { DI_SHUT, "node is shutting down" }, |
||
1270 | { UC_NOSUCHOBJ, "unrecognized object" }, |
||
1271 | { UC_INVOBJFORMAT, "invalid object name format" }, |
||
1272 | { UC_OBJTOOBUSY, "object too busy" }, |
||
1273 | { DI_PROTOCOL, "protocol error discovered" }, |
||
1274 | { DI_TPA, "third party abort" }, |
||
1275 | { UC_USERABORT, "user abort" }, |
||
1276 | { UC_INVNODEFORMAT, "invalid node name format" }, |
||
1277 | { UC_LOCALSHUT, "local node shutting down" }, |
||
1278 | { DI_LOCALRESRC, "insufficient local resources" }, |
||
1279 | { DI_REMUSERRESRC, "insufficient remote user resources" }, |
||
1280 | { UC_ACCESSREJECT, "invalid access control information" }, |
||
1281 | { DI_BADACCNT, "bad ACCOUNT information" }, |
||
1282 | { UC_NORESPONSE, "no response from object" }, |
||
1283 | { UC_UNREACHABLE, "node unreachable" }, |
||
1284 | { DC_NOLINK, "no link terminate" }, |
||
1285 | { DC_COMPLETE, "disconnect complete" }, |
||
1286 | { DI_BADIMAGE, "bad image data in connect" }, |
||
1287 | { DI_SERVMISMATCH, "cryptographic service mismatch" }, |
||
1288 | { 0, NULL } |
||
1289 | }; |
||
1290 | |||
1291 | static void |
||
1292 | print_reason(netdissect_options *ndo, |
||
1293 | register int reason) |
||
1294 | { |
||
1295 | ND_PRINT((ndo, "%s ", tok2str(reason2str, "reason-%d", reason))); |
||
1296 | } |
||
1297 | |||
1298 | const char * |
||
1299 | dnnum_string(u_short dnaddr) |
||
1300 | { |
||
1301 | char *str; |
||
1302 | size_t siz; |
||
1303 | int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT; |
||
1304 | int node = dnaddr & NODEMASK; |
||
1305 | |||
1306 | str = (char *)malloc(siz = sizeof("00.0000")); |
||
1307 | if (str == NULL) |
||
1308 | error("dnnum_string: malloc"); |
||
1309 | snprintf(str, siz, "%d.%d", area, node); |
||
1310 | return(str); |
||
1311 | } |
||
1312 | |||
1313 | const char * |
||
1314 | dnname_string(u_short dnaddr) |
||
1315 | { |
||
1316 | #ifdef HAVE_DNET_HTOA |
||
1317 | struct dn_naddr dna; |
||
1318 | char *dnname; |
||
1319 | |||
1320 | dna.a_len = sizeof(short); |
||
1321 | memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short)); |
||
1322 | dnname = dnet_htoa(&dna); |
||
1323 | if(dnname != NULL) |
||
1324 | return (strdup(dnname)); |
||
1325 | else |
||
1326 | return(dnnum_string(dnaddr)); |
||
1327 | #else |
||
1328 | return(dnnum_string(dnaddr)); /* punt */ |
||
1329 | #endif |
||
1330 | } |
||
1331 | |||
1332 | #ifdef PRINT_NSPDATA |
||
1333 | static void |
||
1334 | pdata(netdissect_options *ndo, |
||
1335 | u_char *dp, u_int maxlen) |
||
1336 | { |
||
1337 | char c; |
||
1338 | u_int x = maxlen; |
||
1339 | |||
1340 | while (x-- > 0) { |
||
1341 | c = *dp++; |
||
1342 | safeputchar(ndo, c); |
||
1343 | } |
||
1344 | } |
||
1345 | #endif |