/src/wireshark/epan/dissectors/packet-nlsp.c
Line | Count | Source |
1 | | /* packet-nlsp.c |
2 | | * Routines for NetWare Link Services Protocol |
3 | | * |
4 | | * Based on ISIS dissector by Stuart Stanley <stuarts@mxmail.net> |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * SPDX-License-Identifier: GPL-2.0-or-later |
11 | | */ |
12 | | |
13 | | #include "config.h" |
14 | | |
15 | | #include <epan/packet.h> |
16 | | #include <epan/expert.h> |
17 | | #include <epan/to_str.h> |
18 | | #include <epan/tfs.h> |
19 | | #include <epan/unit_strings.h> |
20 | | |
21 | | #include <wsutil/array.h> |
22 | | #include "packet-ipx.h" |
23 | | |
24 | | void proto_register_nlsp(void); |
25 | | void proto_reg_handoff_nlsp(void); |
26 | | |
27 | | static dissector_handle_t nlsp_handle; |
28 | | |
29 | | /* NLSP base header */ |
30 | | static int proto_nlsp; |
31 | | |
32 | | static int hf_nlsp_irpd; |
33 | | static int hf_nlsp_header_length; |
34 | | static int hf_nlsp_minor_version; |
35 | | static int hf_nlsp_nr; |
36 | | static int hf_nlsp_type; |
37 | | static int hf_nlsp_major_version; |
38 | | static int hf_nlsp_packet_length; |
39 | | static int hf_nlsp_hello_state; |
40 | | static int hf_nlsp_hello_multicast; |
41 | | static int hf_nlsp_hello_circuit_type; |
42 | | static int hf_nlsp_hello_holding_timer; |
43 | | static int hf_nlsp_hello_priority; |
44 | | static int hf_nlsp_lsp_sequence_number; |
45 | | static int hf_nlsp_lsp_checksum; |
46 | | static int hf_nlsp_lsp_p; |
47 | | static int hf_nlsp_lsp_attached_flag; |
48 | | static int hf_nlsp_lsp_lspdbol; |
49 | | static int hf_nlsp_lsp_router_type; |
50 | | static int hf_nlsp_lsp_link_info_clv_flags_cost_present; |
51 | | static int hf_nlsp_lsp_link_info_clv_flags_cost_metric; |
52 | | static int hf_nlsp_lsp_link_info_clv_flags_cost; |
53 | | |
54 | | /* Generated from convert_proto_tree_add_text.pl */ |
55 | | static int hf_nlsp_psnp_lsp_checksum; |
56 | | static int hf_nlsp_csnp_start_lsp_id_source_id; |
57 | | static int hf_nlsp_svcs_info_node_number; |
58 | | static int hf_nlsp_ext_routes_rip_delay; |
59 | | static int hf_nlsp_psnp_source_id_system_id; |
60 | | static int hf_nlsp_svcs_info_socket; |
61 | | static int hf_nlsp_hello_sending_router_system_id; |
62 | | static int hf_nlsp_csnp_start_lsp_id_lsp_number; |
63 | | static int hf_nlsp_lsp_id_system_id; |
64 | | static int hf_nlsp_psnp_lsp_id_pseudonode_id; |
65 | | static int hf_nlsp_csnp_end_lsp_id_lsp_number; |
66 | | static int hf_nlsp_remaining_lifetime; |
67 | | static int hf_nlsp_csnp_remaining_lifetime; |
68 | | static int hf_nlsp_psnp_lsp_id_source_id; |
69 | | static int hf_nlsp_ext_routes_hops; |
70 | | static int hf_nlsp_hello_local_mtu_mtu_size; |
71 | | static int hf_nlsp_link_info_throughput; |
72 | | static int hf_nlsp_link_info_media_type; |
73 | | static int hf_nlsp_mgt_info_name; |
74 | | static int hf_nlsp_mgt_info_node_number; |
75 | | static int hf_nlsp_csnp_end_lsp_id_source_id; |
76 | | static int hf_nlsp_csnp_lsp_id_pseudonode_id; |
77 | | static int hf_nlsp_psnp_lsp_sequence_number; |
78 | | static int hf_nlsp_link_info_mtu_size; |
79 | | static int hf_nlsp_lsp_id_lsp_number; |
80 | | static int hf_nlsp_unknown_code; |
81 | | static int hf_nlsp_mgt_info_ipx_version_number; |
82 | | static int hf_nlsp_link_info_router_pseudonode_id; |
83 | | static int hf_nlsp_psnp_source_id_pseudonode_id; |
84 | | static int hf_nlsp_csnp_lsp_id_lsp_number; |
85 | | static int hf_nlsp_csnp_source_id_pseudonode_id; |
86 | | static int hf_nlsp_csnp_end_lsp_id_pseudonode_id; |
87 | | static int hf_nlsp_csnp_lsp_sequence_number; |
88 | | static int hf_nlsp_link_info_router_system_id; |
89 | | static int hf_nlsp_svcs_info_type; |
90 | | static int hf_nlsp_csnp_lsp_checksum; |
91 | | static int hf_nlsp_hello_local_wan_circuit_id; |
92 | | static int hf_nlsp_svcs_info_service_name; |
93 | | static int hf_nlsp_mgt_info_name_length; |
94 | | static int hf_nlsp_neighbor; |
95 | | static int hf_nlsp_area_address_network_number; |
96 | | static int hf_nlsp_link_info_delay; |
97 | | static int hf_nlsp_csnp_start_lsp_id_pseudonode_id; |
98 | | static int hf_nlsp_svcs_info_network_number; |
99 | | static int hf_nlsp_csnp_source_id_system_id; |
100 | | static int hf_nlsp_mgt_info_network_number; |
101 | | static int hf_nlsp_hello_designated_router_pseudonode_id; |
102 | | static int hf_nlsp_lsp_id_pseudonode_id; |
103 | | static int hf_nlsp_csnp_lsp_id_source_id; |
104 | | static int hf_nlsp_psnp_remaining_lifetime; |
105 | | static int hf_nlsp_area_address_mask; |
106 | | static int hf_nlsp_hello_designated_router_system_id; |
107 | | static int hf_nlsp_svcs_info_hops_to_reach_the_service; |
108 | | static int hf_nlsp_psnp_lsp_id_lsp_number; |
109 | | static int hf_nlsp_ext_routes_network_number; |
110 | | |
111 | | static expert_field ei_nlsp_short_packet; |
112 | | static expert_field ei_nlsp_long_packet; |
113 | | static expert_field ei_nlsp_major_version; |
114 | | static expert_field ei_nlsp_type; |
115 | | |
116 | | static int ett_nlsp; |
117 | | static int ett_nlsp_hello_clv_area_addr; |
118 | | static int ett_nlsp_hello_clv_neighbors; |
119 | | static int ett_nlsp_hello_local_mtu; |
120 | | static int ett_nlsp_hello_clv_unknown; |
121 | | static int ett_nlsp_lsp_info; |
122 | | static int ett_nlsp_lsp_clv_area_addr; |
123 | | static int ett_nlsp_lsp_clv_mgt_info; |
124 | | static int ett_nlsp_lsp_clv_link_info; |
125 | | static int ett_nlsp_lsp_clv_svcs_info; |
126 | | static int ett_nlsp_lsp_clv_ext_routes; |
127 | | static int ett_nlsp_lsp_clv_unknown; |
128 | | static int ett_nlsp_csnp_lsp_entries; |
129 | | static int ett_nlsp_csnp_lsp_entry; |
130 | | static int ett_nlsp_csnp_clv_unknown; |
131 | | static int ett_nlsp_psnp_lsp_entries; |
132 | | static int ett_nlsp_psnp_lsp_entry; |
133 | | static int ett_nlsp_psnp_clv_unknown; |
134 | | |
135 | 25 | #define PACKET_TYPE_MASK 0x1f |
136 | | |
137 | | /* |
138 | | * See |
139 | | * |
140 | | * http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/nlsp.htm |
141 | | * |
142 | | * for some information about Hello packets. |
143 | | */ |
144 | | |
145 | 0 | #define NLSP_TYPE_L1_HELLO 15 |
146 | 0 | #define NLSP_TYPE_WAN_HELLO 17 |
147 | 14 | #define NLSP_TYPE_L1_LSP 18 |
148 | 0 | #define NLSP_TYPE_L1_CSNP 24 |
149 | 3 | #define NLSP_TYPE_L1_PSNP 26 |
150 | | |
151 | | static const value_string nlsp_packet_type_vals[] = { |
152 | | { NLSP_TYPE_L1_HELLO, "L1 Hello"}, |
153 | | { NLSP_TYPE_WAN_HELLO, "WAN Hello"}, |
154 | | { NLSP_TYPE_L1_LSP, "L1 LSP"}, |
155 | | { NLSP_TYPE_L1_CSNP, "L1 CSNP"}, |
156 | | { NLSP_TYPE_L1_PSNP, "L1 PSNP"}, |
157 | | { 0, NULL} |
158 | | }; |
159 | | |
160 | | static const value_string nlsp_attached_flag_vals[] = { |
161 | | { 0, "Other routing areas cannot be reached through this router"}, |
162 | | { 1, "Other routing areas can be reached through this router"}, |
163 | | { 0, NULL} |
164 | | }; |
165 | | |
166 | | static const value_string nlsp_router_type_vals[] = { |
167 | | { 1, "Level 1 Router"}, |
168 | | { 3, "Level 1 and Level 2 Router"}, |
169 | | { 0, NULL} |
170 | | }; |
171 | | |
172 | | static const true_false_string tfs_internal_external = { "Internal", "External" }; |
173 | | |
174 | | /* |
175 | | * Our sub-packet dismantle structure for CLV's |
176 | | */ |
177 | | typedef struct { |
178 | | int optcode; /* code for option */ |
179 | | const char *tree_text; /* text for fold out */ |
180 | | int *tree_id; /* id for add_item */ |
181 | | void (*dissect)(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, |
182 | | unsigned offset, unsigned length); |
183 | | } nlsp_clv_handle_t; |
184 | | |
185 | | /* |
186 | | * Name: nlsp_dissect_clvs() |
187 | | * |
188 | | * Description: |
189 | | * Dispatch routine to shred all the CLVs in a packet. We just |
190 | | * walk through the clv entries in the packet. For each one, we |
191 | | * search the passed in valid clv's for this protocol (opts) for |
192 | | * a matching code. If found, we add to the display tree and |
193 | | * then call the dissector. If it is not, we just post an |
194 | | * "unknown" clv entry using the passed in unknown clv tree id. |
195 | | * XXX: The "unknown tree id" is an 'ett' index for use |
196 | | * when creating a subtree; |
197 | | * Since the 'unknown' subtree was not actually used in the |
198 | | * code below, what was the intention for this ? |
199 | | * For now: code related to creating an 'unknown' subtrree |
200 | | * disabled. |
201 | | * |
202 | | * Input: |
203 | | * tvbuff_t * : tvbuffer for packet data |
204 | | * proto_tree * : protocol display tree to fill out. May be NULL |
205 | | * int : offset into packet data where we are. |
206 | | * nlsp_clv_handle_t * : NULL dissector terminated array of codes |
207 | | * and handlers (along with tree text and tree id's). |
208 | | * int : length of CLV area. |
209 | | * int : unknown clv tree id |
210 | | * |
211 | | * Output: |
212 | | * void, but we will add to proto tree if !NULL. |
213 | | */ |
214 | | static void |
215 | | nlsp_dissect_clvs(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
216 | | const nlsp_clv_handle_t *opts, int len, int unknown_tree_id _U_) |
217 | 7 | { |
218 | 7 | uint8_t code; |
219 | 7 | uint8_t length; |
220 | 7 | int q; |
221 | 7 | proto_tree *clv_tree; |
222 | | |
223 | 56 | while ( len > 0 ) { |
224 | 52 | code = tvb_get_uint8(tvb, offset); |
225 | 52 | offset += 1; |
226 | 52 | len -= 1; |
227 | 52 | if (len == 0) |
228 | 0 | break; |
229 | | |
230 | 52 | length = tvb_get_uint8(tvb, offset); |
231 | 52 | offset += 1; |
232 | 52 | len -= 1; |
233 | 52 | if (len == 0) |
234 | 0 | break; |
235 | | |
236 | 52 | if ( len < length ) { |
237 | 3 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
238 | 3 | "Short CLV header (%d vs %d)", length, len ); |
239 | 3 | return; |
240 | 3 | } |
241 | 49 | q = 0; |
242 | 218 | while ((opts[q].dissect != NULL )&&( opts[q].optcode != code )){ |
243 | 169 | q++; |
244 | 169 | } |
245 | 49 | if ( opts[q].dissect ) { |
246 | | /* adjust by 2 for code/len octets */ |
247 | 0 | clv_tree = proto_tree_add_subtree_format(tree, tvb, offset - 2, |
248 | 0 | length + 2, *opts[q].tree_id, NULL, "%s (%u)", |
249 | 0 | opts[q].tree_text, length ); |
250 | 0 | opts[q].dissect(tvb, pinfo, clv_tree, offset, |
251 | 0 | length); |
252 | 49 | } else { |
253 | 49 | proto_item* ti; |
254 | 49 | ti = proto_tree_add_uint_format_value(tree, hf_nlsp_unknown_code, tvb, offset - 2, |
255 | 49 | 1, code, "%u (%u)", code, length); |
256 | 49 | proto_item_set_len(ti, length + 2); |
257 | 49 | } |
258 | 49 | offset += length; |
259 | 49 | len -= length; |
260 | 49 | } |
261 | 7 | } |
262 | | |
263 | | /* |
264 | | * Name: dissect_area_address_clv() |
265 | | * |
266 | | * Description: |
267 | | * Decode an area address clv. |
268 | | * |
269 | | * Input: |
270 | | * tvbuff_t * : tvbuffer for packet data |
271 | | * proto_tree * : protocol display tree to fill out. May be NULL |
272 | | * int : offset into packet data where we are. |
273 | | * int : length of clv we are decoding |
274 | | * |
275 | | * Output: |
276 | | * void, but we will add to proto tree if !NULL. |
277 | | */ |
278 | | static void |
279 | | dissect_area_address_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
280 | | unsigned length) |
281 | 0 | { |
282 | 0 | while (length > 0) { |
283 | 0 | if (length < 4) { |
284 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
285 | 0 | "Short area address entry"); |
286 | 0 | return; |
287 | 0 | } |
288 | 0 | proto_tree_add_item(tree, hf_nlsp_area_address_network_number, tvb, offset, 4, ENC_BIG_ENDIAN); |
289 | |
|
290 | 0 | offset += 4; |
291 | 0 | length -= 4; |
292 | |
|
293 | 0 | if (length < 4) { |
294 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
295 | 0 | "Short area address entry"); |
296 | 0 | return; |
297 | 0 | } |
298 | 0 | proto_tree_add_item(tree, hf_nlsp_area_address_mask, tvb, offset, 4, ENC_BIG_ENDIAN); |
299 | |
|
300 | 0 | offset += 4; |
301 | 0 | length -= 4; |
302 | 0 | } |
303 | 0 | } |
304 | | |
305 | | /* |
306 | | * Name: dissect_neighbor_clv() |
307 | | * |
308 | | * Description: |
309 | | * Decode an neighbor clv. |
310 | | * |
311 | | * Input: |
312 | | * tvbuff_t * : tvbuffer for packet data |
313 | | * proto_tree * : protocol display tree to fill out. May be NULL |
314 | | * int : offset into packet data where we are. |
315 | | * int : length of clv we are decoding |
316 | | * |
317 | | * Output: |
318 | | * void, but we will add to proto tree if !NULL. |
319 | | */ |
320 | | static void |
321 | | dissect_neighbor_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
322 | | unsigned length) |
323 | 0 | { |
324 | 0 | while (length > 0) { |
325 | 0 | if (length < 6) { |
326 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, |
327 | 0 | tvb, offset, "Short neighbor entry"); |
328 | 0 | return; |
329 | 0 | } |
330 | 0 | proto_tree_add_item(tree, hf_nlsp_neighbor, tvb, offset, 6, ENC_NA); |
331 | 0 | offset += 6; |
332 | 0 | length -= 6; |
333 | 0 | } |
334 | 0 | } |
335 | | |
336 | | /* |
337 | | * Name: dissect_hello_local_mtu_clv() |
338 | | * |
339 | | * Description: |
340 | | * Decode for a hello packet's local MTU clv. |
341 | | * |
342 | | * Input: |
343 | | * tvbuff_t * : tvbuffer for packet data |
344 | | * proto_tree * : protocol display tree to fill out. May be NULL |
345 | | * int : offset into packet data where we are. |
346 | | * int : length of clv we are decoding |
347 | | * |
348 | | * Output: |
349 | | * void, but we will add to proto tree if !NULL. |
350 | | */ |
351 | | static void |
352 | | dissect_hello_local_mtu_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
353 | | unsigned length) |
354 | 0 | { |
355 | 0 | if (length < 4) { |
356 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
357 | 0 | "Short link info entry"); |
358 | 0 | return; |
359 | 0 | } |
360 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_local_mtu_mtu_size, tvb, offset, 4, ENC_BIG_ENDIAN); |
361 | 0 | } |
362 | | |
363 | | static const nlsp_clv_handle_t clv_hello_opts[] = { |
364 | | { |
365 | | 0xC0, |
366 | | "Area address(es)", |
367 | | &ett_nlsp_hello_clv_area_addr, |
368 | | dissect_area_address_clv |
369 | | }, |
370 | | { |
371 | | 6, |
372 | | "Neighbors", |
373 | | &ett_nlsp_hello_clv_neighbors, |
374 | | dissect_neighbor_clv |
375 | | }, |
376 | | { |
377 | | 0xC5, |
378 | | "Local MTU", |
379 | | &ett_nlsp_hello_local_mtu, |
380 | | dissect_hello_local_mtu_clv |
381 | | }, |
382 | | |
383 | | { |
384 | | 0, |
385 | | "", |
386 | | NULL, |
387 | | NULL |
388 | | } |
389 | | }; |
390 | | |
391 | | /* |
392 | | * Name: nlsp_dissect_nlsp_hello() |
393 | | * |
394 | | * Description: |
395 | | * This procedure rips apart NLSP hellos. |
396 | | * |
397 | | * Input: |
398 | | * tvbuff_t * : tvbuffer for packet data |
399 | | * proto_tree * : protocol display tree to add to. May be NULL. |
400 | | * unsigned offset : our offset into packet data. |
401 | | * int : hello type, a la NLSP_TYPE_* values |
402 | | * int : header length of packet. |
403 | | * |
404 | | * Output: |
405 | | * void, will modify proto_tree if not NULL. |
406 | | */ |
407 | 15 | #define NLSP_HELLO_CTYPE_MASK 0x03 |
408 | 15 | #define NLSP_HELLO_STATE_MASK 0xC0 |
409 | 15 | #define NLSP_HELLO_MULTICAST_MASK 0x10 |
410 | | |
411 | | static const value_string nlsp_hello_state_vals[] = { |
412 | | { 0, "Up" }, |
413 | | { 1, "Initializing" }, |
414 | | { 2, "Down" }, |
415 | | { 0, NULL } |
416 | | }; |
417 | | |
418 | | #define NLSP_HELLO_TYPE_RESERVED 0 |
419 | | #define NLSP_HELLO_TYPE_LEVEL_1 1 |
420 | | #define NLSP_HELLO_TYPE_LEVEL_2 2 |
421 | | #define NLSP_HELLO_TYPE_LEVEL_12 3 |
422 | | |
423 | | static const value_string nlsp_hello_circuit_type_vals[] = { |
424 | | { NLSP_HELLO_TYPE_RESERVED, "Reserved 0 (discard PDU)"}, |
425 | | { NLSP_HELLO_TYPE_LEVEL_1, "Level 1 only"}, |
426 | | { NLSP_HELLO_TYPE_LEVEL_2, "Level 2 only"}, |
427 | | { NLSP_HELLO_TYPE_LEVEL_12, "Level 1 and 2"}, |
428 | | { 0, NULL} |
429 | | }; |
430 | | |
431 | 15 | #define NLSP_HELLO_PRIORITY_MASK 0x7f |
432 | | |
433 | | static void |
434 | | nlsp_dissect_nlsp_hello(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
435 | | unsigned offset, int hello_type, int header_length) |
436 | 0 | { |
437 | 0 | uint16_t packet_length; |
438 | 0 | int len; |
439 | |
|
440 | 0 | if (hello_type == NLSP_TYPE_WAN_HELLO) { |
441 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_state, tvb, |
442 | 0 | offset, 1, ENC_BIG_ENDIAN); |
443 | 0 | } else { |
444 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_multicast, tvb, |
445 | 0 | offset, 1, ENC_BIG_ENDIAN); |
446 | 0 | } |
447 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_circuit_type, tvb, |
448 | 0 | offset, 1, ENC_BIG_ENDIAN); |
449 | 0 | offset += 1; |
450 | |
|
451 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_sending_router_system_id, tvb, offset, 6, ENC_NA); |
452 | |
|
453 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", System ID: %s", |
454 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
455 | |
|
456 | 0 | offset += 6; |
457 | |
|
458 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_holding_timer, tvb, offset, 2, ENC_BIG_ENDIAN); |
459 | 0 | offset += 2; |
460 | |
|
461 | 0 | packet_length = tvb_get_ntohs(tvb, offset); |
462 | 0 | proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb, offset, 2, packet_length); |
463 | 0 | offset += 2; |
464 | |
|
465 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_priority, tvb, offset, 1, ENC_BIG_ENDIAN); |
466 | 0 | offset += 1; |
467 | |
|
468 | 0 | if (hello_type == NLSP_TYPE_WAN_HELLO) { |
469 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_local_wan_circuit_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
470 | 0 | offset += 1; |
471 | 0 | } else { |
472 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_designated_router_system_id, tvb, offset, 6, ENC_NA); |
473 | 0 | proto_tree_add_item(tree, hf_nlsp_hello_designated_router_pseudonode_id, tvb, offset+6, 1, ENC_BIG_ENDIAN); |
474 | 0 | offset += 7; |
475 | 0 | } |
476 | |
|
477 | 0 | len = packet_length - header_length; |
478 | 0 | if (len < 0) { |
479 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_long_packet, tvb, offset, |
480 | 0 | "packet header length %d went beyond packet", |
481 | 0 | header_length); |
482 | 0 | return; |
483 | 0 | } |
484 | | |
485 | | /* |
486 | | * Now, we need to decode our CLVs. We need to pass in |
487 | | * our list of valid ones! |
488 | | */ |
489 | 0 | nlsp_dissect_clvs(tvb, pinfo, tree, offset, |
490 | 0 | clv_hello_opts, len, ett_nlsp_hello_clv_unknown); |
491 | 0 | } |
492 | | |
493 | | /* |
494 | | * Name: dissect_lsp_mgt_info_clv() |
495 | | * |
496 | | * Description: |
497 | | * Decode for a lsp packet's management information clv. |
498 | | * |
499 | | * Input: |
500 | | * tvbuff_t * : tvbuffer for packet data |
501 | | * proto_tree * : protocol display tree to fill out. May be NULL |
502 | | * int : offset into packet data where we are. |
503 | | * int : length of clv we are decoding |
504 | | * |
505 | | * Output: |
506 | | * void, but we will add to proto tree if !NULL. |
507 | | */ |
508 | | static void |
509 | | dissect_lsp_mgt_info_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
510 | | unsigned length) |
511 | 0 | { |
512 | 0 | uint8_t name_length; |
513 | |
|
514 | 0 | if (length < 4) { |
515 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
516 | 0 | "Short management info entry"); |
517 | 0 | return; |
518 | 0 | } |
519 | 0 | proto_tree_add_item(tree, hf_nlsp_mgt_info_network_number, tvb, offset, 4, ENC_BIG_ENDIAN); |
520 | 0 | offset += 4; |
521 | 0 | length -= 4; |
522 | |
|
523 | 0 | if (length < 6) { |
524 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
525 | 0 | "Short management info entry"); |
526 | 0 | return; |
527 | 0 | } |
528 | 0 | proto_tree_add_item(tree, hf_nlsp_mgt_info_node_number, tvb, offset, 6, ENC_NA); |
529 | 0 | offset += 6; |
530 | 0 | length -= 6; |
531 | |
|
532 | 0 | if (length < 1) { |
533 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
534 | 0 | "Short management info entry"); |
535 | 0 | return; |
536 | 0 | } |
537 | | |
538 | 0 | proto_tree_add_item(tree, hf_nlsp_mgt_info_ipx_version_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
539 | 0 | offset += 1; |
540 | 0 | length -= 1; |
541 | |
|
542 | 0 | if (length < 1) { |
543 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
544 | 0 | "Short management info entry"); |
545 | 0 | return; |
546 | 0 | } |
547 | | |
548 | 0 | proto_tree_add_item_ret_uint8(tree, hf_nlsp_mgt_info_name_length, tvb, offset, 1, ENC_BIG_ENDIAN, &name_length); |
549 | 0 | offset += 1; |
550 | 0 | length -= 1; |
551 | |
|
552 | 0 | if (name_length != 0) { |
553 | 0 | if (length < name_length) { |
554 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
555 | 0 | "Short management info entry"); |
556 | 0 | return; |
557 | 0 | } |
558 | 0 | proto_tree_add_item(tree, hf_nlsp_mgt_info_name, tvb, offset, name_length, ENC_ASCII); |
559 | 0 | } |
560 | 0 | } |
561 | | |
562 | | /* |
563 | | * Name: dissect_lsp_link_info_clv() |
564 | | * |
565 | | * Description: |
566 | | * Decode for a lsp packet's link information clv. |
567 | | * |
568 | | * Input: |
569 | | * tvbuff_t * : tvbuffer for packet data |
570 | | * proto_tree * : protocol display tree to fill out. May be NULL |
571 | | * int : offset into packet data where we are. |
572 | | * int : length of clv we are decoding |
573 | | * |
574 | | * Output: |
575 | | * void, but we will add to proto tree if !NULL. |
576 | | */ |
577 | | static const value_string media_type_vals[] = { |
578 | | { 0x0000, "Generic LAN" }, |
579 | | { 0x8000, "Generic WAN" }, |
580 | | { 0x0001, "Localtalk" }, |
581 | | { 0x0002, "Ethernet II" }, |
582 | | { 0x0003, "IEEE 802.3 with IEEE 802.2 without SNAP" }, |
583 | | { 0x0005, "IEEE 802.3 with IPX header and no 802.2 header" }, |
584 | | { 0x000A, "IEEE 802.3 with IEEE 802.2 and SNAP" }, |
585 | | { 0x0004, "IEEE 802.5 with IEEE 802.2 without SNAP" }, |
586 | | { 0x000B, "IEEE 802.5 with IEEE 802.2 and SNAP" }, |
587 | | { 0x0006, "IEEE 802.4" }, |
588 | | { 0x0007, "IBM PC Network II" }, |
589 | | { 0x0008, "Gateway G/Net" }, |
590 | | { 0x0009, "Proteon ProNET" }, |
591 | | { 0x000C, "Racore LANPAC" }, |
592 | | { 0x800D, "ISDN" }, |
593 | | { 0x000E, "ARCnet" }, |
594 | | { 0x000F, "IBM PC Network II with 802.2 without SNAP" }, |
595 | | { 0x0010, "IBM PC Network II with 802.2 and SNAP" }, |
596 | | { 0x0011, "Corvus OmniNet at 4 Mbps" }, |
597 | | { 0x0012, "Harris Adacom" }, |
598 | | { 0x0013, "IP tunnel" }, |
599 | | { 0x8013, "IP Relay" }, |
600 | | { 0x0014, "FDDI with 802.2 without SNAP" }, |
601 | | { 0x0015, "Commtex IVDLAN" }, |
602 | | { 0x0016, "Dataco OSI" }, |
603 | | { 0x0017, "FDDI with 802.2 and SNAP" }, |
604 | | { 0x0018, "IBM SDLC tunnel" }, |
605 | | { 0x0019, "PC Office frame" }, |
606 | | { 0x001A, "Hypercommunications WAIDNET" }, |
607 | | { 0x801C, "PPP" }, |
608 | | { 0x801D, "Proxim RangeLAN" }, |
609 | | { 0x801E, "X.25" }, |
610 | | { 0x801F, "Frame Relay" }, |
611 | | { 0x0020, "Integrated Workstations BUS-NET" }, |
612 | | { 0x8021, "Novell SNA Links" }, |
613 | | { 0, NULL } |
614 | | }; |
615 | | |
616 | | static void |
617 | | dissect_lsp_link_info_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
618 | | unsigned length) |
619 | 0 | { |
620 | 0 | uint8_t flags_cost; |
621 | |
|
622 | 0 | if (length < 1) { |
623 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
624 | 0 | "Short link info entry"); |
625 | 0 | return; |
626 | 0 | } |
627 | 0 | if (tree) { |
628 | 0 | flags_cost = tvb_get_uint8(tvb, offset); |
629 | 0 | proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost_present, tvb, offset, 1, ENC_BIG_ENDIAN); |
630 | 0 | if (!(flags_cost & 0x80)) { |
631 | | /* |
632 | | * 0x80 clear => cost present. |
633 | | */ |
634 | 0 | proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost_metric, tvb, offset, 1, ENC_BIG_ENDIAN); |
635 | 0 | proto_tree_add_item(tree, hf_nlsp_lsp_link_info_clv_flags_cost, tvb, offset, 1, ENC_BIG_ENDIAN); |
636 | 0 | } |
637 | 0 | } |
638 | 0 | offset += 1; |
639 | 0 | length -= 1; |
640 | |
|
641 | 0 | if (length < 3) { |
642 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
643 | 0 | "Short link info entry"); |
644 | 0 | return; |
645 | 0 | } |
646 | 0 | offset += 3; /* Reserved */ |
647 | 0 | length -= 3; |
648 | |
|
649 | 0 | if (length < 7) { |
650 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
651 | 0 | "Short link info entry"); |
652 | 0 | return; |
653 | 0 | } |
654 | | |
655 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_router_system_id, tvb, offset, 6, ENC_NA); |
656 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_router_pseudonode_id, tvb, offset+6, 1, ENC_BIG_ENDIAN); |
657 | 0 | offset += 7; |
658 | 0 | length -= 7; |
659 | |
|
660 | 0 | if (length < 4) { |
661 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
662 | 0 | "Short link info entry"); |
663 | 0 | return; |
664 | 0 | } |
665 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_mtu_size, tvb, offset, 4, ENC_BIG_ENDIAN); |
666 | 0 | offset += 4; |
667 | 0 | length -= 4; |
668 | |
|
669 | 0 | if (length < 4) { |
670 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
671 | 0 | "Short link info entry"); |
672 | 0 | return; |
673 | 0 | } |
674 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_delay, tvb, offset, 4, ENC_BIG_ENDIAN); |
675 | 0 | offset += 4; |
676 | 0 | length -= 4; |
677 | |
|
678 | 0 | if (length < 4) { |
679 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
680 | 0 | "Short link info entry"); |
681 | 0 | return; |
682 | 0 | } |
683 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_throughput, tvb, offset, 4, ENC_BIG_ENDIAN); |
684 | 0 | offset += 4; |
685 | 0 | length -= 4; |
686 | |
|
687 | 0 | if (length < 2) { |
688 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
689 | 0 | "Short link info entry"); |
690 | 0 | return; |
691 | 0 | } |
692 | 0 | proto_tree_add_item(tree, hf_nlsp_link_info_media_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
693 | 0 | } |
694 | | |
695 | | /* |
696 | | * Name: dissect_lsp_svcs_info_clv() |
697 | | * |
698 | | * Description: |
699 | | * Decode for a lsp packet's services information clv. |
700 | | * |
701 | | * Input: |
702 | | * tvbuff_t * : tvbuffer for packet data |
703 | | * proto_tree * : protocol display tree to fill out. May be NULL |
704 | | * int : offset into packet data where we are. |
705 | | * int : length of clv we are decoding |
706 | | * |
707 | | * Output: |
708 | | * void, but we will add to proto tree if !NULL. |
709 | | */ |
710 | | static void |
711 | | dissect_lsp_svcs_info_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
712 | | unsigned length) |
713 | 0 | { |
714 | 0 | if (length < 1) { |
715 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
716 | 0 | "Short services info entry"); |
717 | 0 | return; |
718 | 0 | } |
719 | | |
720 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_hops_to_reach_the_service, tvb, offset, 1, ENC_BIG_ENDIAN); |
721 | 0 | offset += 1; |
722 | 0 | length -= 1; |
723 | |
|
724 | 0 | if (length < 4) { |
725 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
726 | 0 | "Short services info entry"); |
727 | 0 | return; |
728 | 0 | } |
729 | | |
730 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_network_number, tvb, offset, 4, ENC_BIG_ENDIAN); |
731 | 0 | offset += 4; |
732 | 0 | length -= 4; |
733 | |
|
734 | 0 | if (length < 6) { |
735 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
736 | 0 | "Short services info entry"); |
737 | 0 | return; |
738 | 0 | } |
739 | | |
740 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_node_number, tvb, offset, 6, ENC_NA); |
741 | 0 | offset += 6; |
742 | 0 | length -= 6; |
743 | |
|
744 | 0 | if (length < 2) { |
745 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
746 | 0 | "Short services info entry"); |
747 | 0 | return; |
748 | 0 | } |
749 | | |
750 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_socket, tvb, offset, 2, ENC_BIG_ENDIAN); |
751 | 0 | offset += 2; |
752 | 0 | length -= 2; |
753 | |
|
754 | 0 | if (length < 2) { |
755 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
756 | 0 | "Short services info entry"); |
757 | 0 | return; |
758 | 0 | } |
759 | | |
760 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
761 | 0 | offset += 2; |
762 | 0 | length -= 2; |
763 | |
|
764 | 0 | if (length > 0) { |
765 | 0 | proto_tree_add_item(tree, hf_nlsp_svcs_info_service_name, tvb, offset, length, ENC_ASCII); |
766 | 0 | } |
767 | 0 | } |
768 | | |
769 | | |
770 | | /* |
771 | | * Name: dissect_lsp_ext_routes_clv() |
772 | | * |
773 | | * Description: |
774 | | * Decode for a lsp packet's external routes clv. |
775 | | * |
776 | | * Input: |
777 | | * tvbuff_t * : tvbuffer for packet data |
778 | | * proto_tree * : protocol display tree to fill out. May be NULL |
779 | | * int : offset into packet data where we are. |
780 | | * int : length of clv we are decoding |
781 | | * |
782 | | * Output: |
783 | | * void, but we will add to proto tree if !NULL. |
784 | | */ |
785 | | static void |
786 | | dissect_lsp_ext_routes_clv(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
787 | | unsigned length) |
788 | 0 | { |
789 | 0 | while (length > 0) { |
790 | 0 | proto_tree_add_item(tree, hf_nlsp_ext_routes_hops, tvb, offset, 1, ENC_BIG_ENDIAN); |
791 | 0 | offset += 1; |
792 | 0 | length -= 1; |
793 | |
|
794 | 0 | if (length < 4) { |
795 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
796 | 0 | "Short external routes entry"); |
797 | 0 | return; |
798 | 0 | } |
799 | | |
800 | 0 | proto_tree_add_item(tree, hf_nlsp_ext_routes_network_number, tvb, offset, 4, ENC_BIG_ENDIAN); |
801 | 0 | offset += 4; |
802 | 0 | length -= 4; |
803 | |
|
804 | 0 | if (length < 2) { |
805 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
806 | 0 | "Short external routes entry"); |
807 | 0 | return; |
808 | 0 | } |
809 | | |
810 | 0 | proto_tree_add_item(tree, hf_nlsp_ext_routes_rip_delay, tvb, offset, 2, ENC_BIG_ENDIAN); |
811 | 0 | offset += 2; |
812 | 0 | length -= 2; |
813 | 0 | } |
814 | 0 | } |
815 | | |
816 | | static const nlsp_clv_handle_t clv_l1_lsp_opts[] = { |
817 | | { |
818 | | 0xC0, |
819 | | "Area address(es)", |
820 | | &ett_nlsp_lsp_clv_area_addr, |
821 | | dissect_area_address_clv |
822 | | }, |
823 | | { |
824 | | 0xC1, |
825 | | "Management information", |
826 | | &ett_nlsp_lsp_clv_mgt_info, |
827 | | dissect_lsp_mgt_info_clv |
828 | | }, |
829 | | { |
830 | | 0xC2, |
831 | | "Link information", |
832 | | &ett_nlsp_lsp_clv_link_info, |
833 | | dissect_lsp_link_info_clv |
834 | | }, |
835 | | { |
836 | | 0xC3, |
837 | | "Services information", |
838 | | &ett_nlsp_lsp_clv_svcs_info, |
839 | | dissect_lsp_svcs_info_clv |
840 | | }, |
841 | | { |
842 | | 0xC4, |
843 | | "External routes", |
844 | | &ett_nlsp_lsp_clv_ext_routes, |
845 | | dissect_lsp_ext_routes_clv |
846 | | }, |
847 | | |
848 | | { |
849 | | 0, |
850 | | "", |
851 | | NULL, |
852 | | NULL |
853 | | } |
854 | | }; |
855 | | |
856 | | /* |
857 | | * Name: nlsp_dissect_nlsp_lsp() |
858 | | * |
859 | | * Description: |
860 | | * Print out the LSP part of the main header and then call the CLV |
861 | | * de-mangler with the right list of valid CLVs. |
862 | | * |
863 | | * Input: |
864 | | * tvbuff_t * : tvbuffer for packet data |
865 | | * proto_tree * : protocol display tree to add to. May be NULL. |
866 | | * unsigned offset : our offset into packet data. |
867 | | * int : header length of packet. |
868 | | * |
869 | | * Output: |
870 | | * void, but we will add to proto tree if !NULL. |
871 | | */ |
872 | | /* P | ATT | OVERFLOW | ROUTER TYPE FIELD description */ |
873 | 15 | #define NLSP_LSP_PARTITION_MASK 0x80 |
874 | | #define NLSP_LSP_PARTITION_SHIFT 7 |
875 | | #define NLSP_LSP_PARTITION(info) (((info) & NLSP_LSP_PARTITION_MASK) >> NLSP_LSP_PARTITION_SHIFT) |
876 | | |
877 | 15 | #define NLSP_LSP_ATT_MASK 0x78 |
878 | | #define NLSP_LSP_ATT_SHIFT 3 |
879 | | #define NLSP_LSP_ATT(info) (((info) & NLSP_LSP_ATT_MASK) >> NLSP_LSP_ATT_SHIFT) |
880 | | |
881 | 15 | #define NLSP_LSP_OVERFLOW_MASK 0x04 |
882 | | #define NLSP_LSP_OVERFLOW_SHIFT 2 |
883 | | #define NLSP_LSP_OVERFLOW(info) (((info) & NLSP_LSP_OVERFLOW_MASK) >> NLSP_LSP_OVERFLOW_SHIFT) |
884 | | |
885 | 15 | #define NLSP_LSP_ROUTER_TYPE_MASK 0x03 |
886 | | #define NLSP_LSP_ROUTER_TYPE(info) ((info) & NLSP_LSP_ROUTER_TYPE_MASK) |
887 | | |
888 | | static void |
889 | | nlsp_dissect_nlsp_lsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
890 | | unsigned offset, int header_length) |
891 | 4 | { |
892 | 4 | uint16_t packet_length; |
893 | 4 | uint16_t remaining_lifetime; |
894 | 4 | uint32_t sequence_number; |
895 | 4 | int len; |
896 | | |
897 | 4 | packet_length = tvb_get_ntohs(tvb, offset); |
898 | 4 | proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb, |
899 | 4 | offset, 2, packet_length); |
900 | 4 | offset += 2; |
901 | | |
902 | 4 | remaining_lifetime = tvb_get_ntohs(tvb, offset); |
903 | 4 | proto_tree_add_uint(tree, hf_nlsp_remaining_lifetime, tvb, offset, 2, remaining_lifetime); |
904 | 4 | offset += 2; |
905 | | |
906 | 4 | col_append_fstr(pinfo->cinfo, COL_INFO, ", LSP ID: %s", |
907 | 4 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
908 | | |
909 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_id_system_id, tvb, offset, 6, ENC_NA); |
910 | | |
911 | 4 | offset += 6; |
912 | | /* XXX - append the pseudonode ID */ |
913 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_id_pseudonode_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
914 | | |
915 | 4 | offset += 1; |
916 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_id_lsp_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
917 | 4 | offset += 1; |
918 | | |
919 | 4 | sequence_number = tvb_get_ntohl(tvb, offset); |
920 | 4 | col_append_fstr(pinfo->cinfo, COL_INFO, |
921 | 4 | ", Sequence: 0x%08x, Lifetime: %us", |
922 | 4 | sequence_number, remaining_lifetime); |
923 | | |
924 | 4 | proto_tree_add_uint(tree, hf_nlsp_lsp_sequence_number, tvb, |
925 | 4 | offset, 4, sequence_number); |
926 | 4 | offset += 4; |
927 | | |
928 | | /* XXX -> we could validate the cksum here! */ |
929 | 4 | proto_tree_add_checksum(tree, tvb, offset, hf_nlsp_lsp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
930 | 4 | offset += 2; |
931 | | |
932 | 4 | if (tree) { |
933 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_p, tvb, |
934 | 4 | offset, 1, ENC_BIG_ENDIAN); |
935 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_attached_flag, tvb, |
936 | 4 | offset, 1, ENC_BIG_ENDIAN); |
937 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_lspdbol, tvb, |
938 | 4 | offset, 1, ENC_BIG_ENDIAN); |
939 | 4 | proto_tree_add_item(tree, hf_nlsp_lsp_router_type, tvb, |
940 | 4 | offset, 1, ENC_BIG_ENDIAN); |
941 | 4 | } |
942 | 4 | offset += 1; |
943 | | |
944 | 4 | len = packet_length - header_length; |
945 | 4 | if (len < 0) { |
946 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_long_packet, tvb, offset, |
947 | 0 | "packet header length %d went beyond packet", |
948 | 0 | header_length); |
949 | 0 | return; |
950 | 0 | } |
951 | | |
952 | | /* |
953 | | * Now, we need to decode our CLVs. We need to pass in |
954 | | * our list of valid ones! |
955 | | */ |
956 | 4 | nlsp_dissect_clvs(tvb, pinfo, tree, offset, |
957 | 4 | clv_l1_lsp_opts, len, ett_nlsp_lsp_clv_unknown); |
958 | 4 | } |
959 | | |
960 | | /* |
961 | | * Name: dissect_snp_lsp_entries() |
962 | | * |
963 | | * Description: |
964 | | * All the snp packets use a common payload format. We have up |
965 | | * to n entries (based on length), which are made of: |
966 | | * 2 : remaining life time |
967 | | * 8 : lsp id |
968 | | * 4 : sequence number |
969 | | * 2 : checksum |
970 | | * |
971 | | * Input: |
972 | | * tvbuff_t * : tvbuffer for packet data |
973 | | * proto_tree * : protocol display tree to fill out. May be NULL |
974 | | * int : offset into packet data where we are. |
975 | | * int : length of payload to decode. |
976 | | * |
977 | | * Output: |
978 | | * void, but we will add to proto tree if !NULL. |
979 | | */ |
980 | | static void |
981 | | dissect_csnp_lsp_entries(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
982 | | unsigned length) |
983 | 0 | { |
984 | 0 | proto_tree *subtree; |
985 | |
|
986 | 0 | while (length > 0) { |
987 | 0 | if (length < 16) { |
988 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
989 | 0 | "Short CSNP header entry"); |
990 | 0 | return; |
991 | 0 | } |
992 | | |
993 | 0 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, 16, |
994 | 0 | ett_nlsp_csnp_lsp_entry, NULL, "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x", |
995 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset+2), /* XXX - rest of system ID */ |
996 | 0 | tvb_get_ntohl(tvb, offset+10), |
997 | 0 | tvb_get_ntohs(tvb, offset), |
998 | 0 | tvb_get_ntohs(tvb, offset+14)); |
999 | |
|
1000 | 0 | proto_tree_add_item(subtree, hf_nlsp_csnp_lsp_id_source_id, tvb, offset+2, 6, ENC_NA); |
1001 | 0 | proto_tree_add_item(subtree, hf_nlsp_csnp_lsp_id_pseudonode_id, tvb, offset+8, 1, ENC_BIG_ENDIAN); |
1002 | 0 | proto_tree_add_item(subtree, hf_nlsp_csnp_lsp_id_lsp_number, tvb, offset+9, 1, ENC_BIG_ENDIAN); |
1003 | |
|
1004 | 0 | proto_tree_add_item(subtree, hf_nlsp_csnp_lsp_sequence_number, tvb, offset+10, 4, ENC_BIG_ENDIAN); |
1005 | |
|
1006 | 0 | proto_tree_add_item(subtree, hf_nlsp_csnp_remaining_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN); |
1007 | |
|
1008 | 0 | proto_tree_add_checksum(subtree, tvb, offset+14, hf_nlsp_csnp_lsp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
1009 | |
|
1010 | 0 | length -= 16; |
1011 | 0 | offset += 16; |
1012 | 0 | } |
1013 | 0 | } |
1014 | | |
1015 | | static void |
1016 | | dissect_psnp_lsp_entries(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset, |
1017 | | unsigned length) |
1018 | 0 | { |
1019 | 0 | proto_tree *subtree; |
1020 | |
|
1021 | 0 | while (length > 0) { |
1022 | 0 | if (length < 16) { |
1023 | 0 | proto_tree_add_expert_format_remaining(tree, pinfo, &ei_nlsp_short_packet, tvb, offset, |
1024 | 0 | "Short PSNP header entry"); |
1025 | 0 | return; |
1026 | 0 | } |
1027 | | |
1028 | 0 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, 16, |
1029 | 0 | ett_nlsp_psnp_lsp_entry, NULL, "LSP-ID: %s, Sequence: 0x%08x, Lifetime: %5us, Checksum: 0x%04x", |
1030 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset+2), /* XXX - rest of system ID */ |
1031 | 0 | tvb_get_ntohl(tvb, offset+10), |
1032 | 0 | tvb_get_ntohs(tvb, offset), |
1033 | 0 | tvb_get_ntohs(tvb, offset+14)); |
1034 | |
|
1035 | 0 | proto_tree_add_item(subtree, hf_nlsp_psnp_lsp_id_source_id, tvb, offset+2, 6, ENC_NA); |
1036 | 0 | proto_tree_add_item(subtree, hf_nlsp_psnp_lsp_id_pseudonode_id, tvb, offset+8, 1, ENC_BIG_ENDIAN); |
1037 | 0 | proto_tree_add_item(subtree, hf_nlsp_psnp_lsp_id_lsp_number, tvb, offset+9, 1, ENC_BIG_ENDIAN); |
1038 | |
|
1039 | 0 | proto_tree_add_item(subtree, hf_nlsp_psnp_lsp_sequence_number, tvb, offset+10, 4, ENC_BIG_ENDIAN); |
1040 | |
|
1041 | 0 | proto_tree_add_item(subtree, hf_nlsp_psnp_remaining_lifetime, tvb, offset, 2, ENC_BIG_ENDIAN); |
1042 | |
|
1043 | 0 | proto_tree_add_checksum(subtree, tvb, offset+14, hf_nlsp_psnp_lsp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); |
1044 | |
|
1045 | 0 | length -= 16; |
1046 | 0 | offset += 16; |
1047 | 0 | } |
1048 | 0 | } |
1049 | | |
1050 | | static const nlsp_clv_handle_t clv_l1_csnp_opts[] = { |
1051 | | { |
1052 | | 9, |
1053 | | "LSP entries", |
1054 | | &ett_nlsp_csnp_lsp_entries, |
1055 | | dissect_csnp_lsp_entries |
1056 | | }, |
1057 | | |
1058 | | { |
1059 | | 0, |
1060 | | "", |
1061 | | NULL, |
1062 | | NULL |
1063 | | } |
1064 | | }; |
1065 | | |
1066 | | /* |
1067 | | * Name: nlsp_dissect_nlsp_csnp() |
1068 | | * |
1069 | | * Description: |
1070 | | * Tear apart a L1 CSNP header and then call into payload dissect |
1071 | | * to pull apart the lsp id payload. |
1072 | | * |
1073 | | * Input: |
1074 | | * tvbuff_t * : tvbuffer for packet data |
1075 | | * proto_tree * : protocol display tree to add to. May be NULL. |
1076 | | * unsigned offset : our offset into packet data. |
1077 | | * int : header length of packet. |
1078 | | * |
1079 | | * Output: |
1080 | | * void, but we will add to proto tree if !NULL. |
1081 | | */ |
1082 | | static void |
1083 | | nlsp_dissect_nlsp_csnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1084 | | unsigned offset, int header_length) |
1085 | 0 | { |
1086 | 0 | uint16_t packet_length; |
1087 | 0 | int len; |
1088 | |
|
1089 | 0 | packet_length = tvb_get_ntohs(tvb, offset); |
1090 | 0 | proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb, offset, 2, packet_length); |
1091 | 0 | offset += 2; |
1092 | |
|
1093 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Source ID: %s", |
1094 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
1095 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_source_id_system_id, tvb, offset, 6, ENC_NA); |
1096 | 0 | offset += 6; |
1097 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_source_id_pseudonode_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
1098 | 0 | offset += 1; |
1099 | |
|
1100 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Start LSP ID: %s", |
1101 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
1102 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_start_lsp_id_source_id, tvb, offset, 6, ENC_NA); |
1103 | 0 | offset += 6; |
1104 | | /* XXX - append the pseudonode ID */ |
1105 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_start_lsp_id_pseudonode_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
1106 | 0 | offset += 1; |
1107 | |
|
1108 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_start_lsp_id_lsp_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
1109 | 0 | offset += 1; |
1110 | |
|
1111 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, ", End LSP ID: %s", |
1112 | 0 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
1113 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_end_lsp_id_source_id, tvb, offset, 6, ENC_NA); |
1114 | 0 | offset += 6; |
1115 | | /* XXX - append the pseudonode ID */ |
1116 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_end_lsp_id_pseudonode_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
1117 | 0 | offset += 1; |
1118 | 0 | proto_tree_add_item(tree, hf_nlsp_csnp_end_lsp_id_lsp_number, tvb, offset, 1, ENC_BIG_ENDIAN); |
1119 | 0 | offset += 1; |
1120 | |
|
1121 | 0 | len = packet_length - header_length; |
1122 | 0 | if (len < 0) { |
1123 | 0 | return; |
1124 | 0 | } |
1125 | | /* Call into payload dissector */ |
1126 | 0 | nlsp_dissect_clvs(tvb, pinfo, tree, offset, |
1127 | 0 | clv_l1_csnp_opts, len, ett_nlsp_csnp_clv_unknown); |
1128 | 0 | } |
1129 | | |
1130 | | static const nlsp_clv_handle_t clv_l1_psnp_opts[] = { |
1131 | | { |
1132 | | 9, |
1133 | | "LSP entries", |
1134 | | &ett_nlsp_psnp_lsp_entries, |
1135 | | dissect_psnp_lsp_entries |
1136 | | }, |
1137 | | |
1138 | | { |
1139 | | 0, |
1140 | | "", |
1141 | | NULL, |
1142 | | NULL |
1143 | | } |
1144 | | }; |
1145 | | |
1146 | | /* |
1147 | | * Name: nlsp_dissect_nlsp_psnp() |
1148 | | * |
1149 | | * Description: |
1150 | | * Tear apart a L1 PSNP header and then call into payload dissect |
1151 | | * to pull apart the lsp id payload. |
1152 | | * |
1153 | | * Input: |
1154 | | * tvbuff_t * : tvbuffer for packet data |
1155 | | * proto_tree * : protocol display tree to add to. May be NULL. |
1156 | | * unsigned offset : our offset into packet data. |
1157 | | * int : header length of packet. |
1158 | | * |
1159 | | * Output: |
1160 | | * void, but we will add to proto tree if !NULL. |
1161 | | */ |
1162 | | static void |
1163 | | nlsp_dissect_nlsp_psnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
1164 | | unsigned offset, int header_length) |
1165 | 3 | { |
1166 | 3 | uint16_t packet_length; |
1167 | 3 | int len; |
1168 | | |
1169 | 3 | packet_length = tvb_get_ntohs(tvb, offset); |
1170 | 3 | proto_tree_add_uint(tree, hf_nlsp_packet_length, tvb, |
1171 | 3 | offset, 2, packet_length); |
1172 | 3 | offset += 2; |
1173 | | |
1174 | 3 | col_append_fstr(pinfo->cinfo, COL_INFO, ", Source ID: %s", |
1175 | 3 | tvb_ether_to_str(pinfo->pool, tvb, offset)); |
1176 | 3 | proto_tree_add_item(tree, hf_nlsp_psnp_source_id_system_id, tvb, offset, 6, ENC_NA); |
1177 | 3 | offset += 6; |
1178 | | /* XXX - add the pseudonode ID */ |
1179 | 3 | proto_tree_add_item(tree, hf_nlsp_psnp_source_id_pseudonode_id, tvb, offset, 1, ENC_BIG_ENDIAN); |
1180 | 3 | offset += 1; |
1181 | | |
1182 | 3 | len = packet_length - header_length; |
1183 | 3 | if (len < 0) { |
1184 | 0 | return; |
1185 | 0 | } |
1186 | | /* Call into payload dissector */ |
1187 | 3 | nlsp_dissect_clvs(tvb, pinfo, tree, offset, |
1188 | 3 | clv_l1_psnp_opts, len, ett_nlsp_psnp_clv_unknown); |
1189 | 3 | } |
1190 | | |
1191 | | /* |
1192 | | * Name: dissect_nlsp() |
1193 | | * |
1194 | | * Description: |
1195 | | * Main entry area for nlsp de-mangling. This will build the |
1196 | | * main nlsp tree data and call the sub-protocols as needed. |
1197 | | * |
1198 | | * Input: |
1199 | | * tvbuff_t * : tvbuffer for packet data |
1200 | | * packet_info * : info for current packet |
1201 | | * proto_tree * : tree of display data. May be NULL. |
1202 | | * |
1203 | | * Output: |
1204 | | * void, but we will add to the proto_tree if it is not NULL. |
1205 | | */ |
1206 | | static int |
1207 | | dissect_nlsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
1208 | 10 | { |
1209 | 10 | proto_item *ti, *type_item; |
1210 | 10 | proto_tree *nlsp_tree; |
1211 | 10 | unsigned offset = 0; |
1212 | 10 | uint8_t nlsp_major_version; |
1213 | 10 | uint8_t nlsp_header_length; |
1214 | 10 | uint8_t packet_type_flags; |
1215 | 10 | uint8_t packet_type; |
1216 | | |
1217 | 10 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "NLSP"); |
1218 | 10 | col_clear(pinfo->cinfo, COL_INFO); |
1219 | | |
1220 | 10 | ti = proto_tree_add_item(tree, proto_nlsp, tvb, 0, -1, ENC_NA); |
1221 | 10 | nlsp_tree = proto_item_add_subtree(ti, ett_nlsp); |
1222 | | |
1223 | 10 | proto_tree_add_item(nlsp_tree, hf_nlsp_irpd, tvb, offset, 1, |
1224 | 10 | ENC_BIG_ENDIAN ); |
1225 | 10 | offset += 1; |
1226 | | |
1227 | 10 | nlsp_header_length = tvb_get_uint8(tvb, 1); |
1228 | 10 | proto_tree_add_uint(nlsp_tree, hf_nlsp_header_length, tvb, |
1229 | 10 | offset, 1, nlsp_header_length ); |
1230 | 10 | offset += 1; |
1231 | | |
1232 | 10 | proto_tree_add_item(nlsp_tree, hf_nlsp_minor_version, tvb, |
1233 | 10 | offset, 1, ENC_BIG_ENDIAN ); |
1234 | 10 | offset += 1; |
1235 | | |
1236 | 10 | offset += 1; /* Reserved */ |
1237 | | |
1238 | 10 | packet_type_flags = tvb_get_uint8(tvb, offset); |
1239 | 10 | packet_type = packet_type_flags & PACKET_TYPE_MASK; |
1240 | 10 | col_add_str(pinfo->cinfo, COL_INFO, |
1241 | 10 | val_to_str(pinfo->pool, packet_type, nlsp_packet_type_vals, "Unknown (%u)")); |
1242 | 10 | if (packet_type == NLSP_TYPE_L1_LSP) { |
1243 | 4 | proto_tree_add_boolean(nlsp_tree, hf_nlsp_nr, tvb, offset, 1, packet_type_flags ); |
1244 | 4 | } |
1245 | 10 | type_item = proto_tree_add_uint(nlsp_tree, hf_nlsp_type, tvb, offset, 1, packet_type_flags ); |
1246 | 10 | offset += 1; |
1247 | | |
1248 | 10 | nlsp_major_version = tvb_get_uint8(tvb, offset); |
1249 | 10 | ti = proto_tree_add_item(nlsp_tree, hf_nlsp_major_version, tvb, |
1250 | 10 | offset, 1, ENC_BIG_ENDIAN ); |
1251 | 10 | if (nlsp_major_version != 1){ |
1252 | 10 | expert_add_info_format(pinfo, ti, &ei_nlsp_major_version, |
1253 | 10 | "Unknown NLSP version (%d vs 1)", |
1254 | 10 | nlsp_major_version); |
1255 | 10 | } |
1256 | 10 | offset += 1; |
1257 | | |
1258 | 10 | offset += 2; /* Reserved */ |
1259 | | |
1260 | 10 | switch (packet_type) { |
1261 | | |
1262 | 0 | case NLSP_TYPE_L1_HELLO: |
1263 | 0 | case NLSP_TYPE_WAN_HELLO: |
1264 | 0 | nlsp_dissect_nlsp_hello(tvb, pinfo, nlsp_tree, offset, |
1265 | 0 | packet_type, nlsp_header_length); |
1266 | 0 | break; |
1267 | | |
1268 | 4 | case NLSP_TYPE_L1_LSP: |
1269 | 4 | nlsp_dissect_nlsp_lsp(tvb, pinfo, nlsp_tree, offset, |
1270 | 4 | nlsp_header_length); |
1271 | 4 | break; |
1272 | | |
1273 | 0 | case NLSP_TYPE_L1_CSNP: |
1274 | 0 | nlsp_dissect_nlsp_csnp(tvb, pinfo, nlsp_tree, offset, |
1275 | 0 | nlsp_header_length); |
1276 | 0 | break; |
1277 | | |
1278 | 3 | case NLSP_TYPE_L1_PSNP: |
1279 | 3 | nlsp_dissect_nlsp_psnp(tvb, pinfo, nlsp_tree, offset, |
1280 | 3 | nlsp_header_length); |
1281 | 3 | break; |
1282 | | |
1283 | 3 | default: |
1284 | 3 | expert_add_info(pinfo, type_item, &ei_nlsp_type); |
1285 | 10 | } |
1286 | 6 | return tvb_captured_length(tvb); |
1287 | 10 | } |
1288 | | |
1289 | | /* |
1290 | | * Name: proto_register_nlsp() |
1291 | | * |
1292 | | * Description: |
1293 | | * main register for NLSP protocol set. We register some display |
1294 | | * formats and the protocol module variables. |
1295 | | * |
1296 | | * NOTE: this procedure to autolinked by the makefile process that |
1297 | | * builds register.c |
1298 | | * |
1299 | | * Input: |
1300 | | * void |
1301 | | * |
1302 | | * Output: |
1303 | | * void |
1304 | | */ |
1305 | | void |
1306 | | proto_register_nlsp(void) |
1307 | 15 | { |
1308 | 15 | static hf_register_info hf[] = { |
1309 | 15 | { &hf_nlsp_irpd, |
1310 | 15 | { "NetWare Link Services Protocol Discriminator", "nlsp.irpd", |
1311 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1312 | 15 | NULL, HFILL } |
1313 | 15 | }, |
1314 | | |
1315 | 15 | { &hf_nlsp_header_length, |
1316 | 15 | { "PDU Header Length", "nlsp.header_length", |
1317 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1318 | 15 | NULL, HFILL } |
1319 | 15 | }, |
1320 | | |
1321 | 15 | { &hf_nlsp_minor_version, |
1322 | 15 | { "Minor Version", "nlsp.minor_version", |
1323 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1324 | 15 | NULL, HFILL } |
1325 | 15 | }, |
1326 | | |
1327 | 15 | { &hf_nlsp_nr, |
1328 | 15 | { "Multi-homed Non-routing Server", "nlsp.nr", |
1329 | 15 | FT_BOOLEAN, 8, NULL, 0x80, |
1330 | 15 | NULL, HFILL } |
1331 | 15 | }, |
1332 | | |
1333 | 15 | { &hf_nlsp_type, |
1334 | 15 | { "Packet Type", "nlsp.type", |
1335 | 15 | FT_UINT8, BASE_DEC, VALS(nlsp_packet_type_vals), PACKET_TYPE_MASK, |
1336 | 15 | NULL, HFILL } |
1337 | 15 | }, |
1338 | | |
1339 | 15 | { &hf_nlsp_major_version, |
1340 | 15 | { "Major Version", "nlsp.major_version", |
1341 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1342 | 15 | NULL, HFILL } |
1343 | 15 | }, |
1344 | | |
1345 | 15 | { &hf_nlsp_packet_length, |
1346 | 15 | { "Packet Length", "nlsp.packet_length", |
1347 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1348 | 15 | NULL, HFILL } |
1349 | 15 | }, |
1350 | | |
1351 | 15 | { &hf_nlsp_hello_state, |
1352 | 15 | { "State", "nlsp.hello.state", |
1353 | 15 | FT_UINT8, BASE_DEC, VALS(nlsp_hello_state_vals), NLSP_HELLO_STATE_MASK, |
1354 | 15 | NULL, HFILL } |
1355 | 15 | }, |
1356 | | |
1357 | 15 | { &hf_nlsp_hello_multicast, |
1358 | 15 | { "Multicast Routing", "nlsp.hello.multicast", |
1359 | 15 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), NLSP_HELLO_MULTICAST_MASK, |
1360 | 15 | "If set, this router supports multicast routing", HFILL } |
1361 | 15 | }, |
1362 | | |
1363 | 15 | { &hf_nlsp_hello_circuit_type, |
1364 | 15 | { "Circuit Type", "nlsp.hello.circuit_type", |
1365 | 15 | FT_UINT8, BASE_DEC, VALS(nlsp_hello_circuit_type_vals), NLSP_HELLO_CTYPE_MASK, |
1366 | 15 | NULL, HFILL } |
1367 | 15 | }, |
1368 | | |
1369 | 15 | { &hf_nlsp_hello_holding_timer, |
1370 | 15 | { "Holding Timer", "nlsp.hello.holding_timer", |
1371 | 15 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, |
1372 | 15 | NULL, HFILL } |
1373 | 15 | }, |
1374 | | |
1375 | 15 | { &hf_nlsp_hello_priority, |
1376 | 15 | { "Priority", "nlsp.hello.priority", |
1377 | 15 | FT_UINT8, BASE_DEC, NULL, NLSP_HELLO_PRIORITY_MASK, |
1378 | 15 | NULL, HFILL } |
1379 | 15 | }, |
1380 | | |
1381 | 15 | { &hf_nlsp_lsp_sequence_number, |
1382 | 15 | { "Sequence Number", "nlsp.sequence_number", |
1383 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1384 | 15 | NULL, HFILL } |
1385 | 15 | }, |
1386 | | |
1387 | 15 | { &hf_nlsp_lsp_checksum, |
1388 | 15 | { "Checksum", "nlsp.lsp.checksum", |
1389 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1390 | 15 | NULL, HFILL } |
1391 | 15 | }, |
1392 | | |
1393 | 15 | { &hf_nlsp_lsp_p, |
1394 | 15 | { "Partition Repair", "nlsp.lsp.partition_repair", |
1395 | 15 | FT_BOOLEAN, 8, TFS(&tfs_supported_not_supported), NLSP_LSP_PARTITION_MASK, |
1396 | 15 | "If set, this router supports the optional Partition Repair function", HFILL } |
1397 | 15 | }, |
1398 | | |
1399 | 15 | { &hf_nlsp_lsp_attached_flag, |
1400 | 15 | { "Attached Flag", "nlsp.lsp.attached_flag", |
1401 | 15 | FT_UINT8, BASE_DEC, VALS(nlsp_attached_flag_vals), NLSP_LSP_ATT_MASK, |
1402 | 15 | NULL, HFILL } |
1403 | 15 | }, |
1404 | | |
1405 | 15 | { &hf_nlsp_lsp_lspdbol, |
1406 | 15 | { "LSP Database Overloaded", "nlsp.lsp.lspdbol", |
1407 | 15 | FT_BOOLEAN, 8, NULL, NLSP_LSP_OVERFLOW_MASK, |
1408 | 15 | NULL, HFILL } |
1409 | 15 | }, |
1410 | | |
1411 | 15 | { &hf_nlsp_lsp_router_type, |
1412 | 15 | { "Router Type", "nlsp.lsp.router_type", |
1413 | 15 | FT_UINT8, BASE_DEC, VALS(nlsp_router_type_vals), NLSP_LSP_ROUTER_TYPE_MASK, |
1414 | 15 | NULL, HFILL } |
1415 | 15 | }, |
1416 | | |
1417 | 15 | { &hf_nlsp_lsp_link_info_clv_flags_cost_present, |
1418 | 15 | { "Cost present", "nlsp.lsp.link_info_clv.flags.cost_present", |
1419 | 15 | FT_BOOLEAN, 8, TFS(&tfs_no_yes), 0x80, |
1420 | 15 | NULL, HFILL } |
1421 | 15 | }, |
1422 | | |
1423 | 15 | { &hf_nlsp_lsp_link_info_clv_flags_cost_metric, |
1424 | 15 | { "Cost metric", "nlsp.lsp.link_info_clv.flags.cost_metric", |
1425 | 15 | FT_BOOLEAN, 8, TFS(&tfs_internal_external), 0x40, |
1426 | 15 | NULL, HFILL } |
1427 | 15 | }, |
1428 | | |
1429 | 15 | { &hf_nlsp_lsp_link_info_clv_flags_cost, |
1430 | 15 | { "Cost", "nlsp.lsp.link_info_clv.flags.cost", |
1431 | 15 | FT_UINT8, BASE_DEC, NULL, 0x3F, |
1432 | 15 | NULL, HFILL } |
1433 | 15 | }, |
1434 | | |
1435 | | /* Generated from convert_proto_tree_add_text.pl */ |
1436 | 15 | { &hf_nlsp_unknown_code, |
1437 | 15 | { "Unknown code", "nlsp.unknown_code", |
1438 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1439 | 15 | NULL, HFILL } |
1440 | 15 | }, |
1441 | 15 | { &hf_nlsp_area_address_network_number, |
1442 | 15 | { "Area address network number", "nlsp.area_address.network_number", |
1443 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1444 | 15 | NULL, HFILL } |
1445 | 15 | }, |
1446 | 15 | { &hf_nlsp_area_address_mask, |
1447 | 15 | { "Area address mask", "nlsp.area_address.mask", |
1448 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1449 | 15 | NULL, HFILL } |
1450 | 15 | }, |
1451 | 15 | { &hf_nlsp_neighbor, |
1452 | 15 | { "Neighbor", "nlsp.neighbor", |
1453 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1454 | 15 | NULL, HFILL } |
1455 | 15 | }, |
1456 | 15 | { &hf_nlsp_hello_local_mtu_mtu_size, |
1457 | 15 | { "MTU Size", "nlsp.hello_local_mtu.mtu_size", |
1458 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1459 | 15 | NULL, HFILL } |
1460 | 15 | }, |
1461 | 15 | { &hf_nlsp_hello_sending_router_system_id, |
1462 | 15 | { "Sending Router System ID", "nlsp.hello.sending_router_system_id", |
1463 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1464 | 15 | NULL, HFILL } |
1465 | 15 | }, |
1466 | 15 | { &hf_nlsp_hello_local_wan_circuit_id, |
1467 | 15 | { "Local WAN Circuit ID", "nlsp.hello.local_wan_circuit_id", |
1468 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1469 | 15 | NULL, HFILL } |
1470 | 15 | }, |
1471 | 15 | { &hf_nlsp_hello_designated_router_system_id, |
1472 | 15 | { "Designated Router System ID", "nlsp.hello.designated_router_system_id", |
1473 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1474 | 15 | NULL, HFILL } |
1475 | 15 | }, |
1476 | 15 | { &hf_nlsp_hello_designated_router_pseudonode_id, |
1477 | 15 | { "Designated Router Pseudonode ID", "nlsp.hello.designated_router_pseudonode_id", |
1478 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1479 | 15 | NULL, HFILL } |
1480 | 15 | }, |
1481 | 15 | { &hf_nlsp_mgt_info_network_number, |
1482 | 15 | { "Network number", "nlsp.mgt_info.network_number", |
1483 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1484 | 15 | NULL, HFILL } |
1485 | 15 | }, |
1486 | 15 | { &hf_nlsp_mgt_info_node_number, |
1487 | 15 | { "Node number", "nlsp.mgt_info.node_number", |
1488 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1489 | 15 | NULL, HFILL } |
1490 | 15 | }, |
1491 | 15 | { &hf_nlsp_mgt_info_ipx_version_number, |
1492 | 15 | { "IPX version number", "nlsp.mgt_info.ipx_version_number", |
1493 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1494 | 15 | NULL, HFILL } |
1495 | 15 | }, |
1496 | 15 | { &hf_nlsp_mgt_info_name_length, |
1497 | 15 | { "Name length", "nlsp.mgt_info.name_length", |
1498 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1499 | 15 | NULL, HFILL } |
1500 | 15 | }, |
1501 | 15 | { &hf_nlsp_mgt_info_name, |
1502 | 15 | { "Name", "nlsp.mgt_info.name", |
1503 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, |
1504 | 15 | NULL, HFILL } |
1505 | 15 | }, |
1506 | 15 | { &hf_nlsp_link_info_router_system_id, |
1507 | 15 | { "Router System ID", "nlsp.link_info.router_system_id", |
1508 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1509 | 15 | NULL, HFILL } |
1510 | 15 | }, |
1511 | 15 | { &hf_nlsp_link_info_router_pseudonode_id, |
1512 | 15 | { "Router Pseudonode ID", "nlsp.link_info.router_pseudonode_id", |
1513 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1514 | 15 | NULL, HFILL } |
1515 | 15 | }, |
1516 | 15 | { &hf_nlsp_link_info_mtu_size, |
1517 | 15 | { "MTU Size", "nlsp.link_info.mtu_size", |
1518 | 15 | FT_UINT32, BASE_DEC, NULL, 0x0, |
1519 | 15 | NULL, HFILL } |
1520 | 15 | }, |
1521 | 15 | { &hf_nlsp_link_info_delay, |
1522 | 15 | { "Delay", "nlsp.link_info.delay", |
1523 | 15 | FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_microseconds), 0x0, |
1524 | 15 | NULL, HFILL } |
1525 | 15 | }, |
1526 | 15 | { &hf_nlsp_link_info_throughput, |
1527 | 15 | { "Throughput", "nlsp.link_info.throughput", |
1528 | 15 | FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, |
1529 | 15 | NULL, HFILL } |
1530 | 15 | }, |
1531 | 15 | { &hf_nlsp_link_info_media_type, |
1532 | 15 | { "Media type", "nlsp.link_info.media_type", |
1533 | 15 | FT_UINT16, BASE_DEC, VALS(media_type_vals), 0x0, |
1534 | 15 | NULL, HFILL } |
1535 | 15 | }, |
1536 | 15 | { &hf_nlsp_svcs_info_hops_to_reach_the_service, |
1537 | 15 | { "Hops to reach the service", "nlsp.svcs_info.hops_to_reach_the_service", |
1538 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1539 | 15 | NULL, HFILL } |
1540 | 15 | }, |
1541 | 15 | { &hf_nlsp_svcs_info_network_number, |
1542 | 15 | { "Network number", "nlsp.svcs_info.network_number", |
1543 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1544 | 15 | NULL, HFILL } |
1545 | 15 | }, |
1546 | 15 | { &hf_nlsp_svcs_info_node_number, |
1547 | 15 | { "Node number", "nlsp.svcs_info.node_number", |
1548 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1549 | 15 | NULL, HFILL } |
1550 | 15 | }, |
1551 | 15 | { &hf_nlsp_svcs_info_socket, |
1552 | 15 | { "Socket", "nlsp.svcs_info.socket", |
1553 | 15 | FT_UINT16, BASE_DEC|BASE_EXT_STRING, &ipx_socket_vals_ext, 0x0, |
1554 | 15 | NULL, HFILL } |
1555 | 15 | }, |
1556 | 15 | { &hf_nlsp_svcs_info_type, |
1557 | 15 | { "Type", "nlsp.svcs_info.type", |
1558 | 15 | FT_UINT16, BASE_DEC|BASE_EXT_STRING, &novell_server_vals_ext, 0x0, |
1559 | 15 | NULL, HFILL } |
1560 | 15 | }, |
1561 | 15 | { &hf_nlsp_svcs_info_service_name, |
1562 | 15 | { "Service Name", "nlsp.svcs_info.service_name", |
1563 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, |
1564 | 15 | NULL, HFILL } |
1565 | 15 | }, |
1566 | 15 | { &hf_nlsp_ext_routes_hops, |
1567 | 15 | { "Hops", "nlsp.ext_routes.hops", |
1568 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1569 | 15 | NULL, HFILL } |
1570 | 15 | }, |
1571 | 15 | { &hf_nlsp_ext_routes_network_number, |
1572 | 15 | { "Network number", "nlsp.ext_routes.network_number", |
1573 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1574 | 15 | NULL, HFILL } |
1575 | 15 | }, |
1576 | 15 | { &hf_nlsp_ext_routes_rip_delay, |
1577 | 15 | { "RIP delay", "nlsp.ext_routes.rip_delay", |
1578 | 15 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_tick_ticks), 0x0, |
1579 | 15 | NULL, HFILL } |
1580 | 15 | }, |
1581 | 15 | { &hf_nlsp_remaining_lifetime, |
1582 | 15 | { "Remaining Lifetime", "nlsp.remaining_lifetime", |
1583 | 15 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, |
1584 | 15 | NULL, HFILL } |
1585 | 15 | }, |
1586 | 15 | { &hf_nlsp_lsp_id_system_id, |
1587 | 15 | { "LSP ID system ID", "nlsp.lsp_id_system_id", |
1588 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1589 | 15 | NULL, HFILL } |
1590 | 15 | }, |
1591 | 15 | { &hf_nlsp_lsp_id_pseudonode_id, |
1592 | 15 | { "LSP ID pseudonode ID", "nlsp.lsp_id_pseudonode_id", |
1593 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1594 | 15 | NULL, HFILL } |
1595 | 15 | }, |
1596 | 15 | { &hf_nlsp_lsp_id_lsp_number, |
1597 | 15 | { "LSP ID LSP number", "nlsp.lsp_id_lsp_number", |
1598 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1599 | 15 | NULL, HFILL } |
1600 | 15 | }, |
1601 | 15 | { &hf_nlsp_csnp_lsp_id_source_id, |
1602 | 15 | { "LSP ID source ID", "nlsp.csnp.lsp_id_source_id", |
1603 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1604 | 15 | NULL, HFILL } |
1605 | 15 | }, |
1606 | 15 | { &hf_nlsp_csnp_lsp_id_pseudonode_id, |
1607 | 15 | { "LSP ID pseudonode ID", "nlsp.csnp.lsp_id_pseudonode_id", |
1608 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1609 | 15 | NULL, HFILL } |
1610 | 15 | }, |
1611 | 15 | { &hf_nlsp_csnp_lsp_id_lsp_number, |
1612 | 15 | { "LSP ID LSP number", "nlsp.csnp.lsp_id_lsp_number", |
1613 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1614 | 15 | NULL, HFILL } |
1615 | 15 | }, |
1616 | 15 | { &hf_nlsp_csnp_lsp_sequence_number, |
1617 | 15 | { "LSP Sequence Number", "nlsp.csnp.lsp_sequence_number", |
1618 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1619 | 15 | NULL, HFILL } |
1620 | 15 | }, |
1621 | 15 | { &hf_nlsp_csnp_remaining_lifetime, |
1622 | 15 | { "Remaining Lifetime", "nlsp.csnp.remaining_lifetime", |
1623 | 15 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, |
1624 | 15 | NULL, HFILL } |
1625 | 15 | }, |
1626 | 15 | { &hf_nlsp_csnp_lsp_checksum, |
1627 | 15 | { "LSP checksum", "nlsp.csnp.lsp_checksum", |
1628 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1629 | 15 | NULL, HFILL } |
1630 | 15 | }, |
1631 | 15 | { &hf_nlsp_psnp_lsp_id_source_id, |
1632 | 15 | { "LSP ID source ID", "nlsp.psnp.lsp_id_source_id", |
1633 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1634 | 15 | NULL, HFILL } |
1635 | 15 | }, |
1636 | 15 | { &hf_nlsp_psnp_lsp_id_pseudonode_id, |
1637 | 15 | { "LSP ID pseudonode ID", "nlsp.psnp.lsp_id_pseudonode_id", |
1638 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1639 | 15 | NULL, HFILL } |
1640 | 15 | }, |
1641 | 15 | { &hf_nlsp_psnp_lsp_id_lsp_number, |
1642 | 15 | { "LSP ID LSP number", "nlsp.psnp.lsp_id_lsp_number", |
1643 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1644 | 15 | NULL, HFILL } |
1645 | 15 | }, |
1646 | 15 | { &hf_nlsp_psnp_lsp_sequence_number, |
1647 | 15 | { "LSP Sequence Number", "nlsp.psnp.lsp_sequence_number", |
1648 | 15 | FT_UINT32, BASE_HEX, NULL, 0x0, |
1649 | 15 | NULL, HFILL } |
1650 | 15 | }, |
1651 | 15 | { &hf_nlsp_psnp_remaining_lifetime, |
1652 | 15 | { "Remaining Lifetime", "nlsp.psnp.remaining_lifetime", |
1653 | 15 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_seconds), 0x0, |
1654 | 15 | NULL, HFILL } |
1655 | 15 | }, |
1656 | 15 | { &hf_nlsp_psnp_lsp_checksum, |
1657 | 15 | { "LSP checksum", "nlsp.psnp.lsp_checksum", |
1658 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1659 | 15 | NULL, HFILL } |
1660 | 15 | }, |
1661 | 15 | { &hf_nlsp_csnp_source_id_system_id, |
1662 | 15 | { "Source ID system ID", "nlsp.csnp.source_id_system_id", |
1663 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1664 | 15 | NULL, HFILL } |
1665 | 15 | }, |
1666 | 15 | { &hf_nlsp_csnp_source_id_pseudonode_id, |
1667 | 15 | { "Source ID pseudonode ID", "nlsp.csnp.source_id_pseudonode_id", |
1668 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1669 | 15 | NULL, HFILL } |
1670 | 15 | }, |
1671 | 15 | { &hf_nlsp_csnp_start_lsp_id_source_id, |
1672 | 15 | { "Start LSP ID source ID", "nlsp.csnp.start_lsp_id_source_id", |
1673 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1674 | 15 | NULL, HFILL } |
1675 | 15 | }, |
1676 | 15 | { &hf_nlsp_csnp_start_lsp_id_pseudonode_id, |
1677 | 15 | { "Start LSP ID pseudonode ID", "nlsp.csnp.start_lsp_id_pseudonode_id", |
1678 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1679 | 15 | NULL, HFILL } |
1680 | 15 | }, |
1681 | 15 | { &hf_nlsp_csnp_start_lsp_id_lsp_number, |
1682 | 15 | { "Start LSP ID LSP number", "nlsp.csnp.start_lsp_id_lsp_number", |
1683 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1684 | 15 | NULL, HFILL } |
1685 | 15 | }, |
1686 | 15 | { &hf_nlsp_csnp_end_lsp_id_source_id, |
1687 | 15 | { "End LSP ID source ID", "nlsp.csnp.end_lsp_id_source_id", |
1688 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1689 | 15 | NULL, HFILL } |
1690 | 15 | }, |
1691 | 15 | { &hf_nlsp_csnp_end_lsp_id_pseudonode_id, |
1692 | 15 | { "End LSP ID pseudonode ID", "nlsp.csnp.end_lsp_id_pseudonode_id", |
1693 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1694 | 15 | NULL, HFILL } |
1695 | 15 | }, |
1696 | 15 | { &hf_nlsp_csnp_end_lsp_id_lsp_number, |
1697 | 15 | { "End LSP ID LSP number", "nlsp.csnp.end_lsp_id_lsp_number", |
1698 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1699 | 15 | NULL, HFILL } |
1700 | 15 | }, |
1701 | 15 | { &hf_nlsp_psnp_source_id_system_id, |
1702 | 15 | { "Source ID system ID", "nlsp.psnp.source_id_system_id", |
1703 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
1704 | 15 | NULL, HFILL } |
1705 | 15 | }, |
1706 | 15 | { &hf_nlsp_psnp_source_id_pseudonode_id, |
1707 | 15 | { "Source ID pseudonode ID", "nlsp.psnp.source_id_pseudonode_id", |
1708 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1709 | 15 | NULL, HFILL } |
1710 | 15 | }, |
1711 | 15 | }; |
1712 | 15 | static int *ett[] = { |
1713 | 15 | &ett_nlsp, |
1714 | 15 | &ett_nlsp_hello_clv_area_addr, |
1715 | 15 | &ett_nlsp_hello_clv_neighbors, |
1716 | 15 | &ett_nlsp_hello_local_mtu, |
1717 | 15 | &ett_nlsp_hello_clv_unknown, |
1718 | 15 | &ett_nlsp_lsp_info, |
1719 | 15 | &ett_nlsp_lsp_clv_area_addr, |
1720 | 15 | &ett_nlsp_lsp_clv_mgt_info, |
1721 | 15 | &ett_nlsp_lsp_clv_link_info, |
1722 | 15 | &ett_nlsp_lsp_clv_svcs_info, |
1723 | 15 | &ett_nlsp_lsp_clv_ext_routes, |
1724 | 15 | &ett_nlsp_lsp_clv_unknown, |
1725 | 15 | &ett_nlsp_csnp_lsp_entries, |
1726 | 15 | &ett_nlsp_csnp_lsp_entry, |
1727 | 15 | &ett_nlsp_csnp_clv_unknown, |
1728 | 15 | &ett_nlsp_psnp_lsp_entries, |
1729 | 15 | &ett_nlsp_psnp_lsp_entry, |
1730 | 15 | &ett_nlsp_psnp_clv_unknown, |
1731 | 15 | }; |
1732 | | |
1733 | 15 | static ei_register_info ei[] = { |
1734 | 15 | { &ei_nlsp_short_packet, { "nlsp.short_packet", PI_MALFORMED, PI_ERROR, "Short packet", EXPFILL }}, |
1735 | 15 | { &ei_nlsp_long_packet, { "nlsp.long_packet", PI_MALFORMED, PI_ERROR, "Long packet", EXPFILL }}, |
1736 | 15 | { &ei_nlsp_major_version, { "nlsp.major_version.unknown", PI_PROTOCOL, PI_WARN, "Unknown NLSP version", EXPFILL }}, |
1737 | 15 | { &ei_nlsp_type, { "nlsp.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown NLSP packet type", EXPFILL }}, |
1738 | 15 | }; |
1739 | | |
1740 | 15 | expert_module_t* expert_nlsp; |
1741 | | |
1742 | 15 | proto_nlsp = proto_register_protocol("NetWare Link Services Protocol", |
1743 | 15 | "NLSP", "nlsp"); |
1744 | 15 | proto_register_field_array(proto_nlsp, hf, array_length(hf)); |
1745 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1746 | 15 | expert_nlsp = expert_register_protocol(proto_nlsp); |
1747 | 15 | expert_register_field_array(expert_nlsp, ei, array_length(ei)); |
1748 | | |
1749 | 15 | nlsp_handle = register_dissector("nlsp", dissect_nlsp, proto_nlsp); |
1750 | 15 | } |
1751 | | |
1752 | | void |
1753 | | proto_reg_handoff_nlsp(void) |
1754 | 15 | { |
1755 | 15 | dissector_add_uint("ipx.socket", IPX_SOCKET_NLSP, nlsp_handle); |
1756 | 15 | } |
1757 | | |
1758 | | /* |
1759 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1760 | | * |
1761 | | * Local variables: |
1762 | | * c-basic-offset: 8 |
1763 | | * tab-width: 8 |
1764 | | * indent-tabs-mode: t |
1765 | | * End: |
1766 | | * |
1767 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
1768 | | * :indentSize=8:tabSize=8:noTabs=false: |
1769 | | */ |