1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | #ifdef __rtems__ |
---|
4 | #include <machine/rtems-bsd-program.h> |
---|
5 | #include "rtems-bsd-tcpdump-namespace.h" |
---|
6 | #endif /* __rtems__ */ |
---|
7 | /* |
---|
8 | * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997 |
---|
9 | * The Regents of the University of California. All rights reserved. |
---|
10 | * |
---|
11 | * Redistribution and use in source and binary forms, with or without |
---|
12 | * modification, are permitted provided that: (1) source code distributions |
---|
13 | * retain the above copyright notice and this paragraph in its entirety, (2) |
---|
14 | * distributions including binary code include the above copyright notice and |
---|
15 | * this paragraph in its entirety in the documentation or other materials |
---|
16 | * provided with the distribution, and (3) all advertising materials mentioning |
---|
17 | * features or use of this software display the following acknowledgement: |
---|
18 | * ``This product includes software developed by the University of California, |
---|
19 | * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
---|
20 | * the University nor the names of its contributors may be used to endorse |
---|
21 | * or promote products derived from this software without specific prior |
---|
22 | * written permission. |
---|
23 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
---|
24 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
---|
25 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
---|
26 | * |
---|
27 | * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu) |
---|
28 | */ |
---|
29 | |
---|
30 | /* \summary: Open Shortest Path First (OSPF) printer */ |
---|
31 | |
---|
32 | #ifdef HAVE_CONFIG_H |
---|
33 | #include "config.h" |
---|
34 | #endif |
---|
35 | |
---|
36 | #include <netdissect-stdinc.h> |
---|
37 | |
---|
38 | #include "netdissect.h" |
---|
39 | #include "addrtoname.h" |
---|
40 | #include "extract.h" |
---|
41 | #include "gmpls.h" |
---|
42 | |
---|
43 | #include "ospf.h" |
---|
44 | |
---|
45 | static const char tstr[] = " [|ospf2]"; |
---|
46 | |
---|
47 | static const struct tok ospf_option_values[] = { |
---|
48 | { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */ |
---|
49 | { OSPF_OPTION_E, "External" }, |
---|
50 | { OSPF_OPTION_MC, "Multicast" }, |
---|
51 | { OSPF_OPTION_NP, "NSSA" }, |
---|
52 | { OSPF_OPTION_L, "LLS" }, |
---|
53 | { OSPF_OPTION_DC, "Demand Circuit" }, |
---|
54 | { OSPF_OPTION_O, "Opaque" }, |
---|
55 | { OSPF_OPTION_DN, "Up/Down" }, |
---|
56 | { 0, NULL } |
---|
57 | }; |
---|
58 | |
---|
59 | static const struct tok ospf_authtype_values[] = { |
---|
60 | { OSPF_AUTH_NONE, "none" }, |
---|
61 | { OSPF_AUTH_SIMPLE, "simple" }, |
---|
62 | { OSPF_AUTH_MD5, "MD5" }, |
---|
63 | { 0, NULL } |
---|
64 | }; |
---|
65 | |
---|
66 | static const struct tok ospf_rla_flag_values[] = { |
---|
67 | { RLA_FLAG_B, "ABR" }, |
---|
68 | { RLA_FLAG_E, "ASBR" }, |
---|
69 | { RLA_FLAG_W1, "Virtual" }, |
---|
70 | { RLA_FLAG_W2, "W2" }, |
---|
71 | { 0, NULL } |
---|
72 | }; |
---|
73 | |
---|
74 | static const struct tok type2str[] = { |
---|
75 | { OSPF_TYPE_UMD, "UMD" }, |
---|
76 | { OSPF_TYPE_HELLO, "Hello" }, |
---|
77 | { OSPF_TYPE_DD, "Database Description" }, |
---|
78 | { OSPF_TYPE_LS_REQ, "LS-Request" }, |
---|
79 | { OSPF_TYPE_LS_UPDATE, "LS-Update" }, |
---|
80 | { OSPF_TYPE_LS_ACK, "LS-Ack" }, |
---|
81 | { 0, NULL } |
---|
82 | }; |
---|
83 | |
---|
84 | static const struct tok lsa_values[] = { |
---|
85 | { LS_TYPE_ROUTER, "Router" }, |
---|
86 | { LS_TYPE_NETWORK, "Network" }, |
---|
87 | { LS_TYPE_SUM_IP, "Summary" }, |
---|
88 | { LS_TYPE_SUM_ABR, "ASBR Summary" }, |
---|
89 | { LS_TYPE_ASE, "External" }, |
---|
90 | { LS_TYPE_GROUP, "Multicast Group" }, |
---|
91 | { LS_TYPE_NSSA, "NSSA" }, |
---|
92 | { LS_TYPE_OPAQUE_LL, "Link Local Opaque" }, |
---|
93 | { LS_TYPE_OPAQUE_AL, "Area Local Opaque" }, |
---|
94 | { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" }, |
---|
95 | { 0, NULL } |
---|
96 | }; |
---|
97 | |
---|
98 | static const struct tok ospf_dd_flag_values[] = { |
---|
99 | { OSPF_DB_INIT, "Init" }, |
---|
100 | { OSPF_DB_MORE, "More" }, |
---|
101 | { OSPF_DB_MASTER, "Master" }, |
---|
102 | { OSPF_DB_RESYNC, "OOBResync" }, |
---|
103 | { 0, NULL } |
---|
104 | }; |
---|
105 | |
---|
106 | static const struct tok lsa_opaque_values[] = { |
---|
107 | { LS_OPAQUE_TYPE_TE, "Traffic Engineering" }, |
---|
108 | { LS_OPAQUE_TYPE_GRACE, "Graceful restart" }, |
---|
109 | { LS_OPAQUE_TYPE_RI, "Router Information" }, |
---|
110 | { 0, NULL } |
---|
111 | }; |
---|
112 | |
---|
113 | static const struct tok lsa_opaque_te_tlv_values[] = { |
---|
114 | { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" }, |
---|
115 | { LS_OPAQUE_TE_TLV_LINK, "Link" }, |
---|
116 | { 0, NULL } |
---|
117 | }; |
---|
118 | |
---|
119 | static const struct tok lsa_opaque_te_link_tlv_subtlv_values[] = { |
---|
120 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" }, |
---|
121 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" }, |
---|
122 | { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" }, |
---|
123 | { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" }, |
---|
124 | { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" }, |
---|
125 | { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" }, |
---|
126 | { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" }, |
---|
127 | { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" }, |
---|
128 | { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" }, |
---|
129 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, |
---|
130 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" }, |
---|
131 | { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, |
---|
132 | { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" }, |
---|
133 | { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS, "Bandwidth Constraints" }, |
---|
134 | { 0, NULL } |
---|
135 | }; |
---|
136 | |
---|
137 | static const struct tok lsa_opaque_grace_tlv_values[] = { |
---|
138 | { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" }, |
---|
139 | { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" }, |
---|
140 | { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" }, |
---|
141 | { 0, NULL } |
---|
142 | }; |
---|
143 | |
---|
144 | static const struct tok lsa_opaque_grace_tlv_reason_values[] = { |
---|
145 | { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" }, |
---|
146 | { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" }, |
---|
147 | { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" }, |
---|
148 | { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" }, |
---|
149 | { 0, NULL } |
---|
150 | }; |
---|
151 | |
---|
152 | static const struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = { |
---|
153 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" }, |
---|
154 | { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" }, |
---|
155 | { 0, NULL } |
---|
156 | }; |
---|
157 | |
---|
158 | static const struct tok lsa_opaque_ri_tlv_values[] = { |
---|
159 | { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" }, |
---|
160 | { 0, NULL } |
---|
161 | }; |
---|
162 | |
---|
163 | static const struct tok lsa_opaque_ri_tlv_cap_values[] = { |
---|
164 | { 1, "Reserved" }, |
---|
165 | { 2, "Reserved" }, |
---|
166 | { 4, "Reserved" }, |
---|
167 | { 8, "Reserved" }, |
---|
168 | { 16, "graceful restart capable" }, |
---|
169 | { 32, "graceful restart helper" }, |
---|
170 | { 64, "Stub router support" }, |
---|
171 | { 128, "Traffic engineering" }, |
---|
172 | { 256, "p2p over LAN" }, |
---|
173 | { 512, "path computation server" }, |
---|
174 | { 0, NULL } |
---|
175 | }; |
---|
176 | |
---|
177 | static const struct tok ospf_lls_tlv_values[] = { |
---|
178 | { OSPF_LLS_EO, "Extended Options" }, |
---|
179 | { OSPF_LLS_MD5, "MD5 Authentication" }, |
---|
180 | { 0, NULL } |
---|
181 | }; |
---|
182 | |
---|
183 | static const struct tok ospf_lls_eo_options[] = { |
---|
184 | { OSPF_LLS_EO_LR, "LSDB resync" }, |
---|
185 | { OSPF_LLS_EO_RS, "Restart" }, |
---|
186 | { 0, NULL } |
---|
187 | }; |
---|
188 | |
---|
189 | int |
---|
190 | ospf_print_grace_lsa(netdissect_options *ndo, |
---|
191 | const uint8_t *tptr, u_int ls_length) |
---|
192 | { |
---|
193 | u_int tlv_type, tlv_length; |
---|
194 | |
---|
195 | |
---|
196 | while (ls_length > 0) { |
---|
197 | ND_TCHECK2(*tptr, 4); |
---|
198 | if (ls_length < 4) { |
---|
199 | ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); |
---|
200 | return -1; |
---|
201 | } |
---|
202 | tlv_type = EXTRACT_16BITS(tptr); |
---|
203 | tlv_length = EXTRACT_16BITS(tptr+2); |
---|
204 | tptr+=4; |
---|
205 | ls_length-=4; |
---|
206 | |
---|
207 | ND_PRINT((ndo, "\n\t %s TLV (%u), length %u, value: ", |
---|
208 | tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type), |
---|
209 | tlv_type, |
---|
210 | tlv_length)); |
---|
211 | |
---|
212 | if (tlv_length > ls_length) { |
---|
213 | ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, |
---|
214 | ls_length)); |
---|
215 | return -1; |
---|
216 | } |
---|
217 | |
---|
218 | /* Infinite loop protection. */ |
---|
219 | if (tlv_type == 0 || tlv_length ==0) { |
---|
220 | return -1; |
---|
221 | } |
---|
222 | |
---|
223 | ND_TCHECK2(*tptr, tlv_length); |
---|
224 | switch(tlv_type) { |
---|
225 | |
---|
226 | case LS_OPAQUE_GRACE_TLV_PERIOD: |
---|
227 | if (tlv_length != 4) { |
---|
228 | ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); |
---|
229 | return -1; |
---|
230 | } |
---|
231 | ND_PRINT((ndo, "%us", EXTRACT_32BITS(tptr))); |
---|
232 | break; |
---|
233 | |
---|
234 | case LS_OPAQUE_GRACE_TLV_REASON: |
---|
235 | if (tlv_length != 1) { |
---|
236 | ND_PRINT((ndo, "\n\t Bogus length %u != 1", tlv_length)); |
---|
237 | return -1; |
---|
238 | } |
---|
239 | ND_PRINT((ndo, "%s (%u)", |
---|
240 | tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr), |
---|
241 | *tptr)); |
---|
242 | break; |
---|
243 | |
---|
244 | case LS_OPAQUE_GRACE_TLV_INT_ADDRESS: |
---|
245 | if (tlv_length != 4) { |
---|
246 | ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); |
---|
247 | return -1; |
---|
248 | } |
---|
249 | ND_PRINT((ndo, "%s", ipaddr_string(ndo, tptr))); |
---|
250 | break; |
---|
251 | |
---|
252 | default: |
---|
253 | if (ndo->ndo_vflag <= 1) { |
---|
254 | if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_length)) |
---|
255 | return -1; |
---|
256 | } |
---|
257 | break; |
---|
258 | |
---|
259 | } |
---|
260 | /* in OSPF everything has to be 32-bit aligned, including TLVs */ |
---|
261 | if (tlv_length%4 != 0) |
---|
262 | tlv_length+=4-(tlv_length%4); |
---|
263 | ls_length-=tlv_length; |
---|
264 | tptr+=tlv_length; |
---|
265 | } |
---|
266 | |
---|
267 | return 0; |
---|
268 | trunc: |
---|
269 | return -1; |
---|
270 | } |
---|
271 | |
---|
272 | int |
---|
273 | ospf_print_te_lsa(netdissect_options *ndo, |
---|
274 | const uint8_t *tptr, u_int ls_length) |
---|
275 | { |
---|
276 | u_int tlv_type, tlv_length, subtlv_type, subtlv_length; |
---|
277 | u_int priority_level, te_class, count_srlg; |
---|
278 | union { /* int to float conversion buffer for several subTLVs */ |
---|
279 | float f; |
---|
280 | uint32_t i; |
---|
281 | } bw; |
---|
282 | |
---|
283 | while (ls_length != 0) { |
---|
284 | ND_TCHECK2(*tptr, 4); |
---|
285 | if (ls_length < 4) { |
---|
286 | ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); |
---|
287 | return -1; |
---|
288 | } |
---|
289 | tlv_type = EXTRACT_16BITS(tptr); |
---|
290 | tlv_length = EXTRACT_16BITS(tptr+2); |
---|
291 | tptr+=4; |
---|
292 | ls_length-=4; |
---|
293 | |
---|
294 | ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u", |
---|
295 | tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type), |
---|
296 | tlv_type, |
---|
297 | tlv_length)); |
---|
298 | |
---|
299 | if (tlv_length > ls_length) { |
---|
300 | ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, |
---|
301 | ls_length)); |
---|
302 | return -1; |
---|
303 | } |
---|
304 | |
---|
305 | /* Infinite loop protection. */ |
---|
306 | if (tlv_type == 0 || tlv_length ==0) { |
---|
307 | return -1; |
---|
308 | } |
---|
309 | |
---|
310 | switch(tlv_type) { |
---|
311 | case LS_OPAQUE_TE_TLV_LINK: |
---|
312 | while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) { |
---|
313 | if (tlv_length < 4) { |
---|
314 | ND_PRINT((ndo, "\n\t Remaining TLV length %u < 4", |
---|
315 | tlv_length)); |
---|
316 | return -1; |
---|
317 | } |
---|
318 | ND_TCHECK2(*tptr, 4); |
---|
319 | subtlv_type = EXTRACT_16BITS(tptr); |
---|
320 | subtlv_length = EXTRACT_16BITS(tptr+2); |
---|
321 | tptr+=4; |
---|
322 | tlv_length-=4; |
---|
323 | |
---|
324 | /* Infinite loop protection */ |
---|
325 | if (subtlv_type == 0 || subtlv_length == 0) |
---|
326 | goto invalid; |
---|
327 | |
---|
328 | ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u", |
---|
329 | tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type), |
---|
330 | subtlv_type, |
---|
331 | subtlv_length)); |
---|
332 | |
---|
333 | ND_TCHECK2(*tptr, subtlv_length); |
---|
334 | switch(subtlv_type) { |
---|
335 | case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP: |
---|
336 | if (subtlv_length != 4) { |
---|
337 | ND_PRINT((ndo, " != 4")); |
---|
338 | goto invalid; |
---|
339 | } |
---|
340 | ND_PRINT((ndo, ", 0x%08x", EXTRACT_32BITS(tptr))); |
---|
341 | break; |
---|
342 | case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID: |
---|
343 | case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID: |
---|
344 | if (subtlv_length != 4 && subtlv_length != 8) { |
---|
345 | ND_PRINT((ndo, " != 4 && != 8")); |
---|
346 | goto invalid; |
---|
347 | } |
---|
348 | ND_PRINT((ndo, ", %s (0x%08x)", |
---|
349 | ipaddr_string(ndo, tptr), |
---|
350 | EXTRACT_32BITS(tptr))); |
---|
351 | if (subtlv_length == 8) /* rfc4203 */ |
---|
352 | ND_PRINT((ndo, ", %s (0x%08x)", |
---|
353 | ipaddr_string(ndo, tptr+4), |
---|
354 | EXTRACT_32BITS(tptr + 4))); |
---|
355 | break; |
---|
356 | case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP: |
---|
357 | case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP: |
---|
358 | if (subtlv_length != 4) { |
---|
359 | ND_PRINT((ndo, " != 4")); |
---|
360 | goto invalid; |
---|
361 | } |
---|
362 | ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr))); |
---|
363 | break; |
---|
364 | case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW: |
---|
365 | case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW: |
---|
366 | if (subtlv_length != 4) { |
---|
367 | ND_PRINT((ndo, " != 4")); |
---|
368 | goto invalid; |
---|
369 | } |
---|
370 | bw.i = EXTRACT_32BITS(tptr); |
---|
371 | ND_PRINT((ndo, ", %.3f Mbps", bw.f * 8 / 1000000)); |
---|
372 | break; |
---|
373 | case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW: |
---|
374 | if (subtlv_length != 32) { |
---|
375 | ND_PRINT((ndo, " != 32")); |
---|
376 | goto invalid; |
---|
377 | } |
---|
378 | for (te_class = 0; te_class < 8; te_class++) { |
---|
379 | bw.i = EXTRACT_32BITS(tptr+te_class*4); |
---|
380 | ND_PRINT((ndo, "\n\t\tTE-Class %u: %.3f Mbps", |
---|
381 | te_class, |
---|
382 | bw.f * 8 / 1000000)); |
---|
383 | } |
---|
384 | break; |
---|
385 | case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS: |
---|
386 | if (subtlv_length < 4) { |
---|
387 | ND_PRINT((ndo, " < 4")); |
---|
388 | goto invalid; |
---|
389 | } |
---|
390 | /* BC Model Id (1 octet) + Reserved (3 octets) */ |
---|
391 | ND_PRINT((ndo, "\n\t\tBandwidth Constraints Model ID: %s (%u)", |
---|
392 | tok2str(diffserv_te_bc_values, "unknown", *tptr), |
---|
393 | *tptr)); |
---|
394 | if (subtlv_length % 4 != 0) { |
---|
395 | ND_PRINT((ndo, "\n\t\tlength %u != N x 4", subtlv_length)); |
---|
396 | goto invalid; |
---|
397 | } |
---|
398 | if (subtlv_length > 36) { |
---|
399 | ND_PRINT((ndo, "\n\t\tlength %u > 36", subtlv_length)); |
---|
400 | goto invalid; |
---|
401 | } |
---|
402 | /* decode BCs until the subTLV ends */ |
---|
403 | for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) { |
---|
404 | bw.i = EXTRACT_32BITS(tptr+4+te_class*4); |
---|
405 | ND_PRINT((ndo, "\n\t\t Bandwidth constraint CT%u: %.3f Mbps", |
---|
406 | te_class, |
---|
407 | bw.f * 8 / 1000000)); |
---|
408 | } |
---|
409 | break; |
---|
410 | case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC: |
---|
411 | if (subtlv_length != 4) { |
---|
412 | ND_PRINT((ndo, " != 4")); |
---|
413 | goto invalid; |
---|
414 | } |
---|
415 | ND_PRINT((ndo, ", Metric %u", EXTRACT_32BITS(tptr))); |
---|
416 | break; |
---|
417 | case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE: |
---|
418 | /* Protection Cap (1 octet) + Reserved ((3 octets) */ |
---|
419 | if (subtlv_length != 4) { |
---|
420 | ND_PRINT((ndo, " != 4")); |
---|
421 | goto invalid; |
---|
422 | } |
---|
423 | ND_PRINT((ndo, ", %s", |
---|
424 | bittok2str(gmpls_link_prot_values, "none", *tptr))); |
---|
425 | break; |
---|
426 | case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR: |
---|
427 | if (subtlv_length < 36) { |
---|
428 | ND_PRINT((ndo, " < 36")); |
---|
429 | goto invalid; |
---|
430 | } |
---|
431 | /* Switching Cap (1 octet) + Encoding (1) + Reserved (2) */ |
---|
432 | ND_PRINT((ndo, "\n\t\tInterface Switching Capability: %s", |
---|
433 | tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)))); |
---|
434 | ND_PRINT((ndo, "\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:", |
---|
435 | tok2str(gmpls_encoding_values, "Unknown", *(tptr + 1)))); |
---|
436 | for (priority_level = 0; priority_level < 8; priority_level++) { |
---|
437 | bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4)); |
---|
438 | ND_PRINT((ndo, "\n\t\t priority level %d: %.3f Mbps", |
---|
439 | priority_level, |
---|
440 | bw.f * 8 / 1000000)); |
---|
441 | } |
---|
442 | break; |
---|
443 | case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE: |
---|
444 | if (subtlv_length != 1) { |
---|
445 | ND_PRINT((ndo, " != 1")); |
---|
446 | goto invalid; |
---|
447 | } |
---|
448 | ND_PRINT((ndo, ", %s (%u)", |
---|
449 | tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr), |
---|
450 | *tptr)); |
---|
451 | break; |
---|
452 | |
---|
453 | case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP: |
---|
454 | if (subtlv_length % 4 != 0) { |
---|
455 | ND_PRINT((ndo, " != N x 4")); |
---|
456 | goto invalid; |
---|
457 | } |
---|
458 | count_srlg = subtlv_length / 4; |
---|
459 | if (count_srlg != 0) |
---|
460 | ND_PRINT((ndo, "\n\t\t Shared risk group: ")); |
---|
461 | while (count_srlg > 0) { |
---|
462 | bw.i = EXTRACT_32BITS(tptr); |
---|
463 | ND_PRINT((ndo, "%d", bw.i)); |
---|
464 | tptr+=4; |
---|
465 | count_srlg--; |
---|
466 | if (count_srlg > 0) |
---|
467 | ND_PRINT((ndo, ", ")); |
---|
468 | } |
---|
469 | break; |
---|
470 | |
---|
471 | default: |
---|
472 | if (ndo->ndo_vflag <= 1) { |
---|
473 | if (!print_unknown_data(ndo, tptr, "\n\t\t", subtlv_length)) |
---|
474 | return -1; |
---|
475 | } |
---|
476 | break; |
---|
477 | } |
---|
478 | /* in OSPF everything has to be 32-bit aligned, including subTLVs */ |
---|
479 | if (subtlv_length%4 != 0) |
---|
480 | subtlv_length+=4-(subtlv_length%4); |
---|
481 | |
---|
482 | tlv_length-=subtlv_length; |
---|
483 | tptr+=subtlv_length; |
---|
484 | |
---|
485 | } |
---|
486 | break; |
---|
487 | |
---|
488 | case LS_OPAQUE_TE_TLV_ROUTER: |
---|
489 | if (tlv_length < 4) { |
---|
490 | ND_PRINT((ndo, "\n\t TLV length %u < 4", tlv_length)); |
---|
491 | return -1; |
---|
492 | } |
---|
493 | ND_TCHECK2(*tptr, 4); |
---|
494 | ND_PRINT((ndo, ", %s", ipaddr_string(ndo, tptr))); |
---|
495 | break; |
---|
496 | |
---|
497 | default: |
---|
498 | if (ndo->ndo_vflag <= 1) { |
---|
499 | if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_length)) |
---|
500 | return -1; |
---|
501 | } |
---|
502 | break; |
---|
503 | } |
---|
504 | /* in OSPF everything has to be 32-bit aligned, including TLVs */ |
---|
505 | if (tlv_length%4 != 0) |
---|
506 | tlv_length+=4-(tlv_length%4); |
---|
507 | ls_length-=tlv_length; |
---|
508 | tptr+=tlv_length; |
---|
509 | } |
---|
510 | return 0; |
---|
511 | trunc: |
---|
512 | return -1; |
---|
513 | invalid: |
---|
514 | ND_PRINT((ndo, "%s", istr)); |
---|
515 | return -1; |
---|
516 | } |
---|
517 | |
---|
518 | static int |
---|
519 | ospf_print_lshdr(netdissect_options *ndo, |
---|
520 | register const struct lsa_hdr *lshp) |
---|
521 | { |
---|
522 | u_int ls_length; |
---|
523 | |
---|
524 | ND_TCHECK(lshp->ls_length); |
---|
525 | ls_length = EXTRACT_16BITS(&lshp->ls_length); |
---|
526 | if (ls_length < sizeof(struct lsa_hdr)) { |
---|
527 | ND_PRINT((ndo, "\n\t Bogus length %u < header (%lu)", ls_length, |
---|
528 | (unsigned long)sizeof(struct lsa_hdr))); |
---|
529 | return(-1); |
---|
530 | } |
---|
531 | |
---|
532 | ND_TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ |
---|
533 | ND_PRINT((ndo, "\n\t Advertising Router %s, seq 0x%08x, age %us, length %u", |
---|
534 | ipaddr_string(ndo, &lshp->ls_router), |
---|
535 | EXTRACT_32BITS(&lshp->ls_seq), |
---|
536 | EXTRACT_16BITS(&lshp->ls_age), |
---|
537 | ls_length - (u_int)sizeof(struct lsa_hdr))); |
---|
538 | |
---|
539 | ND_TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ |
---|
540 | switch (lshp->ls_type) { |
---|
541 | /* the LSA header for opaque LSAs was slightly changed */ |
---|
542 | case LS_TYPE_OPAQUE_LL: |
---|
543 | case LS_TYPE_OPAQUE_AL: |
---|
544 | case LS_TYPE_OPAQUE_DW: |
---|
545 | ND_PRINT((ndo, "\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u", |
---|
546 | tok2str(lsa_values,"unknown",lshp->ls_type), |
---|
547 | lshp->ls_type, |
---|
548 | |
---|
549 | tok2str(lsa_opaque_values, |
---|
550 | "unknown", |
---|
551 | *(&lshp->un_lsa_id.opaque_field.opaque_type)), |
---|
552 | *(&lshp->un_lsa_id.opaque_field.opaque_type), |
---|
553 | EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) |
---|
554 | |
---|
555 | )); |
---|
556 | break; |
---|
557 | |
---|
558 | /* all other LSA types use regular style LSA headers */ |
---|
559 | default: |
---|
560 | ND_PRINT((ndo, "\n\t %s LSA (%d), LSA-ID: %s", |
---|
561 | tok2str(lsa_values,"unknown",lshp->ls_type), |
---|
562 | lshp->ls_type, |
---|
563 | ipaddr_string(ndo, &lshp->un_lsa_id.lsa_id))); |
---|
564 | break; |
---|
565 | } |
---|
566 | |
---|
567 | ND_TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ |
---|
568 | ND_PRINT((ndo, "\n\t Options: [%s]", bittok2str(ospf_option_values, "none", lshp->ls_options))); |
---|
569 | |
---|
570 | return (ls_length); |
---|
571 | trunc: |
---|
572 | return (-1); |
---|
573 | } |
---|
574 | |
---|
575 | /* draft-ietf-ospf-mt-09 */ |
---|
576 | static const struct tok ospf_topology_values[] = { |
---|
577 | { 0, "default" }, |
---|
578 | { 1, "multicast" }, |
---|
579 | { 2, "management" }, |
---|
580 | { 0, NULL } |
---|
581 | }; |
---|
582 | |
---|
583 | /* |
---|
584 | * Print all the per-topology metrics. |
---|
585 | */ |
---|
586 | static int |
---|
587 | ospf_print_tos_metrics(netdissect_options *ndo, |
---|
588 | const union un_tos *tos) |
---|
589 | { |
---|
590 | int metric_count; |
---|
591 | int toscount; |
---|
592 | |
---|
593 | toscount = tos->link.link_tos_count+1; |
---|
594 | metric_count = 0; |
---|
595 | |
---|
596 | /* |
---|
597 | * All but the first metric contain a valid topology id. |
---|
598 | */ |
---|
599 | while (toscount > 0) { |
---|
600 | ND_TCHECK(*tos); |
---|
601 | ND_PRINT((ndo, "\n\t\ttopology %s (%u), metric %u", |
---|
602 | tok2str(ospf_topology_values, "Unknown", |
---|
603 | metric_count ? tos->metrics.tos_type : 0), |
---|
604 | metric_count ? tos->metrics.tos_type : 0, |
---|
605 | EXTRACT_16BITS(&tos->metrics.tos_metric))); |
---|
606 | metric_count++; |
---|
607 | tos++; |
---|
608 | toscount--; |
---|
609 | } |
---|
610 | return 0; |
---|
611 | trunc: |
---|
612 | return 1; |
---|
613 | } |
---|
614 | |
---|
615 | /* |
---|
616 | * Print a single link state advertisement. If truncated or if LSA length |
---|
617 | * field is less than the length of the LSA header, return NULl, else |
---|
618 | * return pointer to data past end of LSA. |
---|
619 | */ |
---|
620 | static const uint8_t * |
---|
621 | ospf_print_lsa(netdissect_options *ndo, |
---|
622 | register const struct lsa *lsap) |
---|
623 | { |
---|
624 | register const uint8_t *ls_end; |
---|
625 | register const struct rlalink *rlp; |
---|
626 | register const struct in_addr *ap; |
---|
627 | register const struct aslametric *almp; |
---|
628 | register const struct mcla *mcp; |
---|
629 | register const uint32_t *lp; |
---|
630 | register int j, tlv_type, tlv_length, topology; |
---|
631 | register int ls_length; |
---|
632 | const uint8_t *tptr; |
---|
633 | |
---|
634 | tptr = (const uint8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */ |
---|
635 | ls_length = ospf_print_lshdr(ndo, &lsap->ls_hdr); |
---|
636 | if (ls_length == -1) |
---|
637 | return(NULL); |
---|
638 | ls_end = (const uint8_t *)lsap + ls_length; |
---|
639 | ls_length -= sizeof(struct lsa_hdr); |
---|
640 | |
---|
641 | switch (lsap->ls_hdr.ls_type) { |
---|
642 | |
---|
643 | case LS_TYPE_ROUTER: |
---|
644 | ND_TCHECK(lsap->lsa_un.un_rla.rla_flags); |
---|
645 | ND_PRINT((ndo, "\n\t Router LSA Options: [%s]", |
---|
646 | bittok2str(ospf_rla_flag_values, "none", lsap->lsa_un.un_rla.rla_flags))); |
---|
647 | |
---|
648 | ND_TCHECK(lsap->lsa_un.un_rla.rla_count); |
---|
649 | j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count); |
---|
650 | ND_TCHECK(lsap->lsa_un.un_rla.rla_link); |
---|
651 | rlp = lsap->lsa_un.un_rla.rla_link; |
---|
652 | while (j--) { |
---|
653 | ND_TCHECK(*rlp); |
---|
654 | switch (rlp->un_tos.link.link_type) { |
---|
655 | |
---|
656 | case RLA_TYPE_VIRTUAL: |
---|
657 | ND_PRINT((ndo, "\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s", |
---|
658 | ipaddr_string(ndo, &rlp->link_id), |
---|
659 | ipaddr_string(ndo, &rlp->link_data))); |
---|
660 | break; |
---|
661 | |
---|
662 | case RLA_TYPE_ROUTER: |
---|
663 | ND_PRINT((ndo, "\n\t Neighbor Router-ID: %s, Interface Address: %s", |
---|
664 | ipaddr_string(ndo, &rlp->link_id), |
---|
665 | ipaddr_string(ndo, &rlp->link_data))); |
---|
666 | break; |
---|
667 | |
---|
668 | case RLA_TYPE_TRANSIT: |
---|
669 | ND_PRINT((ndo, "\n\t Neighbor Network-ID: %s, Interface Address: %s", |
---|
670 | ipaddr_string(ndo, &rlp->link_id), |
---|
671 | ipaddr_string(ndo, &rlp->link_data))); |
---|
672 | break; |
---|
673 | |
---|
674 | case RLA_TYPE_STUB: |
---|
675 | ND_PRINT((ndo, "\n\t Stub Network: %s, Mask: %s", |
---|
676 | ipaddr_string(ndo, &rlp->link_id), |
---|
677 | ipaddr_string(ndo, &rlp->link_data))); |
---|
678 | break; |
---|
679 | |
---|
680 | default: |
---|
681 | ND_PRINT((ndo, "\n\t Unknown Router Link Type (%u)", |
---|
682 | rlp->un_tos.link.link_type)); |
---|
683 | return (ls_end); |
---|
684 | } |
---|
685 | |
---|
686 | if (ospf_print_tos_metrics(ndo, &rlp->un_tos)) |
---|
687 | goto trunc; |
---|
688 | |
---|
689 | rlp = (const struct rlalink *)((const u_char *)(rlp + 1) + |
---|
690 | ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos))); |
---|
691 | } |
---|
692 | break; |
---|
693 | |
---|
694 | case LS_TYPE_NETWORK: |
---|
695 | ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); |
---|
696 | ND_PRINT((ndo, "\n\t Mask %s\n\t Connected Routers:", |
---|
697 | ipaddr_string(ndo, &lsap->lsa_un.un_nla.nla_mask))); |
---|
698 | ap = lsap->lsa_un.un_nla.nla_router; |
---|
699 | while ((const u_char *)ap < ls_end) { |
---|
700 | ND_TCHECK(*ap); |
---|
701 | ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); |
---|
702 | ++ap; |
---|
703 | } |
---|
704 | break; |
---|
705 | |
---|
706 | case LS_TYPE_SUM_IP: |
---|
707 | ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); |
---|
708 | ND_PRINT((ndo, "\n\t Mask %s", |
---|
709 | ipaddr_string(ndo, &lsap->lsa_un.un_sla.sla_mask))); |
---|
710 | ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); |
---|
711 | lp = lsap->lsa_un.un_sla.sla_tosmetric; |
---|
712 | while ((const u_char *)lp < ls_end) { |
---|
713 | register uint32_t ul; |
---|
714 | |
---|
715 | ND_TCHECK_32BITS(lp); |
---|
716 | ul = EXTRACT_32BITS(lp); |
---|
717 | topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; |
---|
718 | ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", |
---|
719 | tok2str(ospf_topology_values, "Unknown", topology), |
---|
720 | topology, |
---|
721 | ul & SLA_MASK_METRIC)); |
---|
722 | ++lp; |
---|
723 | } |
---|
724 | break; |
---|
725 | |
---|
726 | case LS_TYPE_SUM_ABR: |
---|
727 | ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); |
---|
728 | lp = lsap->lsa_un.un_sla.sla_tosmetric; |
---|
729 | while ((const u_char *)lp < ls_end) { |
---|
730 | register uint32_t ul; |
---|
731 | |
---|
732 | ND_TCHECK_32BITS(lp); |
---|
733 | ul = EXTRACT_32BITS(lp); |
---|
734 | topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS; |
---|
735 | ND_PRINT((ndo, "\n\t\ttopology %s (%u) metric %d", |
---|
736 | tok2str(ospf_topology_values, "Unknown", topology), |
---|
737 | topology, |
---|
738 | ul & SLA_MASK_METRIC)); |
---|
739 | ++lp; |
---|
740 | } |
---|
741 | break; |
---|
742 | |
---|
743 | case LS_TYPE_ASE: |
---|
744 | case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */ |
---|
745 | ND_TCHECK(lsap->lsa_un.un_nla.nla_mask); |
---|
746 | ND_PRINT((ndo, "\n\t Mask %s", |
---|
747 | ipaddr_string(ndo, &lsap->lsa_un.un_asla.asla_mask))); |
---|
748 | |
---|
749 | ND_TCHECK(lsap->lsa_un.un_sla.sla_tosmetric); |
---|
750 | almp = lsap->lsa_un.un_asla.asla_metric; |
---|
751 | while ((const u_char *)almp < ls_end) { |
---|
752 | register uint32_t ul; |
---|
753 | |
---|
754 | ND_TCHECK(almp->asla_tosmetric); |
---|
755 | ul = EXTRACT_32BITS(&almp->asla_tosmetric); |
---|
756 | topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS); |
---|
757 | ND_PRINT((ndo, "\n\t\ttopology %s (%u), type %d, metric", |
---|
758 | tok2str(ospf_topology_values, "Unknown", topology), |
---|
759 | topology, |
---|
760 | (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1)); |
---|
761 | if ((ul & ASLA_MASK_METRIC) == 0xffffff) |
---|
762 | ND_PRINT((ndo, " infinite")); |
---|
763 | else |
---|
764 | ND_PRINT((ndo, " %d", (ul & ASLA_MASK_METRIC))); |
---|
765 | |
---|
766 | ND_TCHECK(almp->asla_forward); |
---|
767 | if (almp->asla_forward.s_addr) { |
---|
768 | ND_PRINT((ndo, ", forward %s", ipaddr_string(ndo, &almp->asla_forward))); |
---|
769 | } |
---|
770 | ND_TCHECK(almp->asla_tag); |
---|
771 | if (almp->asla_tag.s_addr) { |
---|
772 | ND_PRINT((ndo, ", tag %s", ipaddr_string(ndo, &almp->asla_tag))); |
---|
773 | } |
---|
774 | ++almp; |
---|
775 | } |
---|
776 | break; |
---|
777 | |
---|
778 | case LS_TYPE_GROUP: |
---|
779 | /* Multicast extensions as of 23 July 1991 */ |
---|
780 | mcp = lsap->lsa_un.un_mcla; |
---|
781 | while ((const u_char *)mcp < ls_end) { |
---|
782 | ND_TCHECK(mcp->mcla_vid); |
---|
783 | switch (EXTRACT_32BITS(&mcp->mcla_vtype)) { |
---|
784 | |
---|
785 | case MCLA_VERTEX_ROUTER: |
---|
786 | ND_PRINT((ndo, "\n\t Router Router-ID %s", |
---|
787 | ipaddr_string(ndo, &mcp->mcla_vid))); |
---|
788 | break; |
---|
789 | |
---|
790 | case MCLA_VERTEX_NETWORK: |
---|
791 | ND_PRINT((ndo, "\n\t Network Designated Router %s", |
---|
792 | ipaddr_string(ndo, &mcp->mcla_vid))); |
---|
793 | break; |
---|
794 | |
---|
795 | default: |
---|
796 | ND_PRINT((ndo, "\n\t unknown VertexType (%u)", |
---|
797 | EXTRACT_32BITS(&mcp->mcla_vtype))); |
---|
798 | break; |
---|
799 | } |
---|
800 | ++mcp; |
---|
801 | } |
---|
802 | break; |
---|
803 | |
---|
804 | case LS_TYPE_OPAQUE_LL: /* fall through */ |
---|
805 | case LS_TYPE_OPAQUE_AL: |
---|
806 | case LS_TYPE_OPAQUE_DW: |
---|
807 | |
---|
808 | switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) { |
---|
809 | case LS_OPAQUE_TYPE_RI: |
---|
810 | tptr = (const uint8_t *)(&lsap->lsa_un.un_ri_tlv.type); |
---|
811 | |
---|
812 | while (ls_length != 0) { |
---|
813 | ND_TCHECK2(*tptr, 4); |
---|
814 | if (ls_length < 4) { |
---|
815 | ND_PRINT((ndo, "\n\t Remaining LS length %u < 4", ls_length)); |
---|
816 | return(ls_end); |
---|
817 | } |
---|
818 | tlv_type = EXTRACT_16BITS(tptr); |
---|
819 | tlv_length = EXTRACT_16BITS(tptr+2); |
---|
820 | tptr+=4; |
---|
821 | ls_length-=4; |
---|
822 | |
---|
823 | ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u, value: ", |
---|
824 | tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type), |
---|
825 | tlv_type, |
---|
826 | tlv_length)); |
---|
827 | |
---|
828 | if (tlv_length > ls_length) { |
---|
829 | ND_PRINT((ndo, "\n\t Bogus length %u > %u", tlv_length, |
---|
830 | ls_length)); |
---|
831 | return(ls_end); |
---|
832 | } |
---|
833 | ND_TCHECK2(*tptr, tlv_length); |
---|
834 | switch(tlv_type) { |
---|
835 | |
---|
836 | case LS_OPAQUE_RI_TLV_CAP: |
---|
837 | if (tlv_length != 4) { |
---|
838 | ND_PRINT((ndo, "\n\t Bogus length %u != 4", tlv_length)); |
---|
839 | return(ls_end); |
---|
840 | } |
---|
841 | ND_PRINT((ndo, "Capabilities: %s", |
---|
842 | bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr)))); |
---|
843 | break; |
---|
844 | default: |
---|
845 | if (ndo->ndo_vflag <= 1) { |
---|
846 | if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_length)) |
---|
847 | return(ls_end); |
---|
848 | } |
---|
849 | break; |
---|
850 | |
---|
851 | } |
---|
852 | tptr+=tlv_length; |
---|
853 | ls_length-=tlv_length; |
---|
854 | } |
---|
855 | break; |
---|
856 | |
---|
857 | case LS_OPAQUE_TYPE_GRACE: |
---|
858 | if (ospf_print_grace_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_grace_tlv.type), |
---|
859 | ls_length) == -1) { |
---|
860 | return(ls_end); |
---|
861 | } |
---|
862 | break; |
---|
863 | |
---|
864 | case LS_OPAQUE_TYPE_TE: |
---|
865 | if (ospf_print_te_lsa(ndo, (const uint8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type), |
---|
866 | ls_length) == -1) { |
---|
867 | return(ls_end); |
---|
868 | } |
---|
869 | break; |
---|
870 | |
---|
871 | default: |
---|
872 | if (ndo->ndo_vflag <= 1) { |
---|
873 | if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown, |
---|
874 | "\n\t ", ls_length)) |
---|
875 | return(ls_end); |
---|
876 | } |
---|
877 | break; |
---|
878 | } |
---|
879 | } |
---|
880 | |
---|
881 | /* do we want to see an additionally hexdump ? */ |
---|
882 | if (ndo->ndo_vflag> 1) |
---|
883 | if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown, |
---|
884 | "\n\t ", ls_length)) { |
---|
885 | return(ls_end); |
---|
886 | } |
---|
887 | |
---|
888 | return (ls_end); |
---|
889 | trunc: |
---|
890 | return (NULL); |
---|
891 | } |
---|
892 | |
---|
893 | static int |
---|
894 | ospf_decode_lls(netdissect_options *ndo, |
---|
895 | register const struct ospfhdr *op, register u_int length) |
---|
896 | { |
---|
897 | register const u_char *dptr; |
---|
898 | register const u_char *dataend; |
---|
899 | register u_int length2; |
---|
900 | register uint16_t lls_type, lls_len; |
---|
901 | register uint32_t lls_flags; |
---|
902 | |
---|
903 | switch (op->ospf_type) { |
---|
904 | |
---|
905 | case OSPF_TYPE_HELLO: |
---|
906 | if (!(op->ospf_hello.hello_options & OSPF_OPTION_L)) |
---|
907 | return (0); |
---|
908 | break; |
---|
909 | |
---|
910 | case OSPF_TYPE_DD: |
---|
911 | if (!(op->ospf_db.db_options & OSPF_OPTION_L)) |
---|
912 | return (0); |
---|
913 | break; |
---|
914 | |
---|
915 | default: |
---|
916 | return (0); |
---|
917 | } |
---|
918 | |
---|
919 | /* dig deeper if LLS data is available; see RFC4813 */ |
---|
920 | length2 = EXTRACT_16BITS(&op->ospf_len); |
---|
921 | dptr = (const u_char *)op + length2; |
---|
922 | dataend = (const u_char *)op + length; |
---|
923 | |
---|
924 | if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { |
---|
925 | dptr = dptr + op->ospf_authdata[3]; |
---|
926 | length2 += op->ospf_authdata[3]; |
---|
927 | } |
---|
928 | if (length2 >= length) { |
---|
929 | ND_PRINT((ndo, "\n\t[LLS truncated]")); |
---|
930 | return (1); |
---|
931 | } |
---|
932 | ND_TCHECK2(*dptr, 2); |
---|
933 | ND_PRINT((ndo, "\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr))); |
---|
934 | |
---|
935 | dptr += 2; |
---|
936 | ND_TCHECK2(*dptr, 2); |
---|
937 | length2 = EXTRACT_16BITS(dptr); |
---|
938 | ND_PRINT((ndo, ", length: %u", length2)); |
---|
939 | |
---|
940 | dptr += 2; |
---|
941 | ND_TCHECK(*dptr); |
---|
942 | while (dptr < dataend) { |
---|
943 | ND_TCHECK2(*dptr, 2); |
---|
944 | lls_type = EXTRACT_16BITS(dptr); |
---|
945 | ND_PRINT((ndo, "\n\t %s (%u)", |
---|
946 | tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type), |
---|
947 | lls_type)); |
---|
948 | dptr += 2; |
---|
949 | ND_TCHECK2(*dptr, 2); |
---|
950 | lls_len = EXTRACT_16BITS(dptr); |
---|
951 | ND_PRINT((ndo, ", length: %u", lls_len)); |
---|
952 | dptr += 2; |
---|
953 | switch (lls_type) { |
---|
954 | |
---|
955 | case OSPF_LLS_EO: |
---|
956 | if (lls_len != 4) { |
---|
957 | ND_PRINT((ndo, " [should be 4]")); |
---|
958 | lls_len = 4; |
---|
959 | } |
---|
960 | ND_TCHECK2(*dptr, 4); |
---|
961 | lls_flags = EXTRACT_32BITS(dptr); |
---|
962 | ND_PRINT((ndo, "\n\t Options: 0x%08x [%s]", lls_flags, |
---|
963 | bittok2str(ospf_lls_eo_options, "?", lls_flags))); |
---|
964 | |
---|
965 | break; |
---|
966 | |
---|
967 | case OSPF_LLS_MD5: |
---|
968 | if (lls_len != 20) { |
---|
969 | ND_PRINT((ndo, " [should be 20]")); |
---|
970 | lls_len = 20; |
---|
971 | } |
---|
972 | ND_TCHECK2(*dptr, 4); |
---|
973 | ND_PRINT((ndo, "\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr))); |
---|
974 | break; |
---|
975 | } |
---|
976 | |
---|
977 | dptr += lls_len; |
---|
978 | } |
---|
979 | |
---|
980 | return (0); |
---|
981 | trunc: |
---|
982 | return (1); |
---|
983 | } |
---|
984 | |
---|
985 | static int |
---|
986 | ospf_decode_v2(netdissect_options *ndo, |
---|
987 | register const struct ospfhdr *op, register const u_char *dataend) |
---|
988 | { |
---|
989 | register const struct in_addr *ap; |
---|
990 | register const struct lsr *lsrp; |
---|
991 | register const struct lsa_hdr *lshp; |
---|
992 | register const struct lsa *lsap; |
---|
993 | register uint32_t lsa_count,lsa_count_max; |
---|
994 | |
---|
995 | switch (op->ospf_type) { |
---|
996 | |
---|
997 | case OSPF_TYPE_UMD: |
---|
998 | /* |
---|
999 | * Rob Coltun's special monitoring packets; |
---|
1000 | * do nothing |
---|
1001 | */ |
---|
1002 | break; |
---|
1003 | |
---|
1004 | case OSPF_TYPE_HELLO: |
---|
1005 | ND_TCHECK(op->ospf_hello.hello_options); |
---|
1006 | ND_PRINT((ndo, "\n\tOptions [%s]", |
---|
1007 | bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options))); |
---|
1008 | |
---|
1009 | ND_TCHECK(op->ospf_hello.hello_deadint); |
---|
1010 | ND_PRINT((ndo, "\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u", |
---|
1011 | EXTRACT_16BITS(&op->ospf_hello.hello_helloint), |
---|
1012 | EXTRACT_32BITS(&op->ospf_hello.hello_deadint), |
---|
1013 | ipaddr_string(ndo, &op->ospf_hello.hello_mask), |
---|
1014 | op->ospf_hello.hello_priority)); |
---|
1015 | |
---|
1016 | ND_TCHECK(op->ospf_hello.hello_dr); |
---|
1017 | if (op->ospf_hello.hello_dr.s_addr != 0) |
---|
1018 | ND_PRINT((ndo, "\n\t Designated Router %s", |
---|
1019 | ipaddr_string(ndo, &op->ospf_hello.hello_dr))); |
---|
1020 | |
---|
1021 | ND_TCHECK(op->ospf_hello.hello_bdr); |
---|
1022 | if (op->ospf_hello.hello_bdr.s_addr != 0) |
---|
1023 | ND_PRINT((ndo, ", Backup Designated Router %s", |
---|
1024 | ipaddr_string(ndo, &op->ospf_hello.hello_bdr))); |
---|
1025 | |
---|
1026 | ap = op->ospf_hello.hello_neighbor; |
---|
1027 | if ((const u_char *)ap < dataend) |
---|
1028 | ND_PRINT((ndo, "\n\t Neighbor List:")); |
---|
1029 | while ((const u_char *)ap < dataend) { |
---|
1030 | ND_TCHECK(*ap); |
---|
1031 | ND_PRINT((ndo, "\n\t %s", ipaddr_string(ndo, ap))); |
---|
1032 | ++ap; |
---|
1033 | } |
---|
1034 | break; /* HELLO */ |
---|
1035 | |
---|
1036 | case OSPF_TYPE_DD: |
---|
1037 | ND_TCHECK(op->ospf_db.db_options); |
---|
1038 | ND_PRINT((ndo, "\n\tOptions [%s]", |
---|
1039 | bittok2str(ospf_option_values, "none", op->ospf_db.db_options))); |
---|
1040 | ND_TCHECK(op->ospf_db.db_flags); |
---|
1041 | ND_PRINT((ndo, ", DD Flags [%s]", |
---|
1042 | bittok2str(ospf_dd_flag_values, "none", op->ospf_db.db_flags))); |
---|
1043 | ND_TCHECK(op->ospf_db.db_ifmtu); |
---|
1044 | if (op->ospf_db.db_ifmtu) { |
---|
1045 | ND_PRINT((ndo, ", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu))); |
---|
1046 | } |
---|
1047 | ND_TCHECK(op->ospf_db.db_seq); |
---|
1048 | ND_PRINT((ndo, ", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq))); |
---|
1049 | |
---|
1050 | /* Print all the LS adv's */ |
---|
1051 | lshp = op->ospf_db.db_lshdr; |
---|
1052 | while (((const u_char *)lshp < dataend) && ospf_print_lshdr(ndo, lshp) != -1) { |
---|
1053 | ++lshp; |
---|
1054 | } |
---|
1055 | break; |
---|
1056 | |
---|
1057 | case OSPF_TYPE_LS_REQ: |
---|
1058 | lsrp = op->ospf_lsr; |
---|
1059 | while ((const u_char *)lsrp < dataend) { |
---|
1060 | ND_TCHECK(*lsrp); |
---|
1061 | |
---|
1062 | ND_PRINT((ndo, "\n\t Advertising Router: %s, %s LSA (%u)", |
---|
1063 | ipaddr_string(ndo, &lsrp->ls_router), |
---|
1064 | tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)), |
---|
1065 | EXTRACT_32BITS(&lsrp->ls_type))); |
---|
1066 | |
---|
1067 | switch (EXTRACT_32BITS(lsrp->ls_type)) { |
---|
1068 | /* the LSA header for opaque LSAs was slightly changed */ |
---|
1069 | case LS_TYPE_OPAQUE_LL: |
---|
1070 | case LS_TYPE_OPAQUE_AL: |
---|
1071 | case LS_TYPE_OPAQUE_DW: |
---|
1072 | ND_PRINT((ndo, ", Opaque-Type: %s LSA (%u), Opaque-ID: %u", |
---|
1073 | tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type), |
---|
1074 | lsrp->un_ls_stateid.opaque_field.opaque_type, |
---|
1075 | EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id))); |
---|
1076 | break; |
---|
1077 | default: |
---|
1078 | ND_PRINT((ndo, ", LSA-ID: %s", |
---|
1079 | ipaddr_string(ndo, &lsrp->un_ls_stateid.ls_stateid))); |
---|
1080 | break; |
---|
1081 | } |
---|
1082 | |
---|
1083 | ++lsrp; |
---|
1084 | } |
---|
1085 | break; |
---|
1086 | |
---|
1087 | case OSPF_TYPE_LS_UPDATE: |
---|
1088 | lsap = op->ospf_lsu.lsu_lsa; |
---|
1089 | ND_TCHECK(op->ospf_lsu.lsu_count); |
---|
1090 | lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count); |
---|
1091 | ND_PRINT((ndo, ", %d LSA%s", lsa_count_max, PLURAL_SUFFIX(lsa_count_max))); |
---|
1092 | for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) { |
---|
1093 | ND_PRINT((ndo, "\n\t LSA #%u", lsa_count)); |
---|
1094 | lsap = (const struct lsa *)ospf_print_lsa(ndo, lsap); |
---|
1095 | if (lsap == NULL) |
---|
1096 | goto trunc; |
---|
1097 | } |
---|
1098 | break; |
---|
1099 | |
---|
1100 | case OSPF_TYPE_LS_ACK: |
---|
1101 | lshp = op->ospf_lsa.lsa_lshdr; |
---|
1102 | while (ospf_print_lshdr(ndo, lshp) != -1) { |
---|
1103 | ++lshp; |
---|
1104 | } |
---|
1105 | break; |
---|
1106 | |
---|
1107 | default: |
---|
1108 | break; |
---|
1109 | } |
---|
1110 | return (0); |
---|
1111 | trunc: |
---|
1112 | return (1); |
---|
1113 | } |
---|
1114 | |
---|
1115 | void |
---|
1116 | ospf_print(netdissect_options *ndo, |
---|
1117 | register const u_char *bp, register u_int length, |
---|
1118 | const u_char *bp2 _U_) |
---|
1119 | { |
---|
1120 | register const struct ospfhdr *op; |
---|
1121 | register const u_char *dataend; |
---|
1122 | register const char *cp; |
---|
1123 | |
---|
1124 | op = (const struct ospfhdr *)bp; |
---|
1125 | |
---|
1126 | /* XXX Before we do anything else, strip off the MD5 trailer */ |
---|
1127 | ND_TCHECK(op->ospf_authtype); |
---|
1128 | if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) { |
---|
1129 | length -= OSPF_AUTH_MD5_LEN; |
---|
1130 | ndo->ndo_snapend -= OSPF_AUTH_MD5_LEN; |
---|
1131 | } |
---|
1132 | |
---|
1133 | /* If the type is valid translate it, or just print the type */ |
---|
1134 | /* value. If it's not valid, say so and return */ |
---|
1135 | ND_TCHECK(op->ospf_type); |
---|
1136 | cp = tok2str(type2str, "unknown LS-type", op->ospf_type); |
---|
1137 | ND_PRINT((ndo, "OSPFv%u, %s, length %u", op->ospf_version, cp, length)); |
---|
1138 | if (*cp == 'u') |
---|
1139 | return; |
---|
1140 | |
---|
1141 | if (!ndo->ndo_vflag) { /* non verbose - so lets bail out here */ |
---|
1142 | return; |
---|
1143 | } |
---|
1144 | |
---|
1145 | ND_TCHECK(op->ospf_len); |
---|
1146 | if (length != EXTRACT_16BITS(&op->ospf_len)) { |
---|
1147 | ND_PRINT((ndo, " [len %d]", EXTRACT_16BITS(&op->ospf_len))); |
---|
1148 | } |
---|
1149 | |
---|
1150 | if (length > EXTRACT_16BITS(&op->ospf_len)) { |
---|
1151 | dataend = bp + EXTRACT_16BITS(&op->ospf_len); |
---|
1152 | } else { |
---|
1153 | dataend = bp + length; |
---|
1154 | } |
---|
1155 | |
---|
1156 | ND_TCHECK(op->ospf_routerid); |
---|
1157 | ND_PRINT((ndo, "\n\tRouter-ID %s", ipaddr_string(ndo, &op->ospf_routerid))); |
---|
1158 | |
---|
1159 | ND_TCHECK(op->ospf_areaid); |
---|
1160 | if (op->ospf_areaid.s_addr != 0) |
---|
1161 | ND_PRINT((ndo, ", Area %s", ipaddr_string(ndo, &op->ospf_areaid))); |
---|
1162 | else |
---|
1163 | ND_PRINT((ndo, ", Backbone Area")); |
---|
1164 | |
---|
1165 | if (ndo->ndo_vflag) { |
---|
1166 | /* Print authentication data (should we really do this?) */ |
---|
1167 | ND_TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata)); |
---|
1168 | |
---|
1169 | ND_PRINT((ndo, ", Authentication Type: %s (%u)", |
---|
1170 | tok2str(ospf_authtype_values, "unknown", EXTRACT_16BITS(&op->ospf_authtype)), |
---|
1171 | EXTRACT_16BITS(&op->ospf_authtype))); |
---|
1172 | |
---|
1173 | switch (EXTRACT_16BITS(&op->ospf_authtype)) { |
---|
1174 | |
---|
1175 | case OSPF_AUTH_NONE: |
---|
1176 | break; |
---|
1177 | |
---|
1178 | case OSPF_AUTH_SIMPLE: |
---|
1179 | ND_PRINT((ndo, "\n\tSimple text password: ")); |
---|
1180 | safeputs(ndo, op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN); |
---|
1181 | break; |
---|
1182 | |
---|
1183 | case OSPF_AUTH_MD5: |
---|
1184 | ND_PRINT((ndo, "\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x", |
---|
1185 | *((op->ospf_authdata) + 2), |
---|
1186 | *((op->ospf_authdata) + 3), |
---|
1187 | EXTRACT_32BITS((op->ospf_authdata) + 4))); |
---|
1188 | break; |
---|
1189 | |
---|
1190 | default: |
---|
1191 | return; |
---|
1192 | } |
---|
1193 | } |
---|
1194 | /* Do rest according to version. */ |
---|
1195 | switch (op->ospf_version) { |
---|
1196 | |
---|
1197 | case 2: |
---|
1198 | /* ospf version 2 */ |
---|
1199 | if (ospf_decode_v2(ndo, op, dataend)) |
---|
1200 | goto trunc; |
---|
1201 | if (length > EXTRACT_16BITS(&op->ospf_len)) { |
---|
1202 | if (ospf_decode_lls(ndo, op, length)) |
---|
1203 | goto trunc; |
---|
1204 | } |
---|
1205 | break; |
---|
1206 | |
---|
1207 | default: |
---|
1208 | ND_PRINT((ndo, " ospf [version %d]", op->ospf_version)); |
---|
1209 | break; |
---|
1210 | } /* end switch on version */ |
---|
1211 | |
---|
1212 | return; |
---|
1213 | trunc: |
---|
1214 | ND_PRINT((ndo, "%s", tstr)); |
---|
1215 | } |
---|
1216 | #ifdef __rtems__ |
---|
1217 | #include "rtems-bsd-tcpdump-print-ospf-data.h" |
---|
1218 | #endif /* __rtems__ */ |
---|