/src/wireshark/epan/dissectors/packet-osi-options.c
Line | Count | Source |
1 | | /* packet-osi-options.c |
2 | | * Routines for the decode of ISO/OSI option part |
3 | | * Covers: |
4 | | * ISO 8473 CLNP (ConnectionLess Mode Network Service Protocol) |
5 | | * ISO 10589 ISIS (Intradomain Routing Information Exchange Protocol) |
6 | | * ISO 9542 ESIS (End System To Intermediate System Routing Exchange Protocol) |
7 | | * |
8 | | * Ralf Schneider <Ralf.Schneider@t-online.de> |
9 | | * |
10 | | * Wireshark - Network traffic analyzer |
11 | | * By Gerald Combs <gerald@wireshark.org> |
12 | | * Copyright 1998 Gerald Combs |
13 | | * |
14 | | * SPDX-License-Identifier: GPL-2.0-or-later |
15 | | */ |
16 | | |
17 | | #include "config.h" |
18 | | |
19 | | #include <epan/packet.h> |
20 | | #include <epan/expert.h> |
21 | | #include <epan/decode_as.h> |
22 | | #include "packet-osi.h" |
23 | | #include "packet-osi-options.h" |
24 | | |
25 | | extern void proto_register_osi_options(void); |
26 | | |
27 | 6 | #define OSI_OPT_SECURITY 0xc5 |
28 | 4 | #define OSI_OPT_QOS_MAINTANANCE 0xc3 |
29 | 16 | #define OSI_OPT_PRIORITY 0xcd |
30 | 2 | #define OSI_OPT_ADDRESS_MASK 0xe1 |
31 | 14 | #define OSI_OPT_SNPA_MASK 0xe2 |
32 | 2 | #define OSI_OPT_ES_CONFIG_TIMER 0xc6 |
33 | | |
34 | 16 | #define OSI_OPT_MAX_PRIORITY 0x0e |
35 | | |
36 | 6 | #define OSI_OPT_PADDING 0xcc |
37 | 41 | #define OSI_OPT_SOURCE_ROUTING 0xc8 |
38 | 52 | #define OSI_OPT_RECORD_OF_ROUTE 0xcb |
39 | 12 | #define OSI_OPT_REASON_OF_DISCARD 0xc1 |
40 | | |
41 | 16 | #define OSI_OPT_SEC_MASK 0xc0 |
42 | 2 | #define OSI_OPT_SEC_RESERVED 0x00 |
43 | 2 | #define OSI_OPT_SEC_SRC_ADR_SPEC 0x01 |
44 | 2 | #define OSI_OPT_SEC_DST_ADR_SPEC 0x02 |
45 | 4 | #define OSI_OPT_SEC_GLOBAL_UNIQUE 0x03 |
46 | | |
47 | 20 | #define OSI_OPT_QOS_MASK 0xc0 |
48 | | #define OSI_OPT_QOS_RESERVED 0x00 |
49 | | #define OSI_OPT_QOS_SRC_ADR_SPEC 0x01 |
50 | | #define OSI_OPT_QOS_DST_ADR_SPEC 0x02 |
51 | 4 | #define OSI_OPT_QOS_GLOBAL_UNIQUE 0x03 |
52 | | |
53 | | #define OSI_OPT_QOS_SUB_MASK 0x3f |
54 | 16 | #define OSI_OPT_QOS_SUB_RSVD 0x20 |
55 | 16 | #define OSI_OPT_QOS_SUB_SEQ_VS_TRS 0x10 |
56 | 16 | #define OSI_OPT_QOS_SUB_CONG_EXPED 0x08 |
57 | 16 | #define OSI_OPT_QOS_SUB_TSD_VS_COST 0x04 |
58 | 16 | #define OSI_OPT_QOS_SUB_RESERR_TRS 0x02 |
59 | 16 | #define OSI_OPT_QOS_SUB_RESERR_COST 0x01 |
60 | | |
61 | 2 | #define OSI_OPT_RFD_GENERAL 0x00 |
62 | 0 | #define OSI_OPT_RFD_ADDRESS 0x08 |
63 | 0 | #define OSI_OPT_RFD_SOURCE_ROUTING 0x09 |
64 | 1 | #define OSI_OPT_RFD_LIFETIME 0x0a |
65 | 1 | #define OSI_OPT_RFD_PDU_DISCARDED 0x0b |
66 | 4 | #define OSI_OPT_RFD_REASSEMBLY 0x0c |
67 | | |
68 | 28 | #define OSI_OPT_RFD_MASK 0xf0 |
69 | 96 | #define OSI_OPT_RFD_SUB_MASK 0x0f |
70 | | |
71 | | /* Generated from convert_proto_tree_add_text.pl */ |
72 | | static int hf_osi_options_address_mask; |
73 | | static int hf_osi_options_transit_delay_vs_cost; |
74 | | static int hf_osi_options_rtd_general; |
75 | | static int hf_osi_options_residual_error_prob_vs_transit_delay; |
76 | | static int hf_osi_options_qos_sequencing_vs_transit_delay; |
77 | | static int hf_osi_options_rtd_address; |
78 | | static int hf_osi_options_congestion_experienced; |
79 | | static int hf_osi_options_esct; |
80 | | static int hf_osi_options_rtd_reassembly; |
81 | | static int hf_osi_options_qos_maintenance; |
82 | | static int hf_osi_options_security_type; |
83 | | static int hf_osi_options_route_recording; |
84 | | static int hf_osi_options_last_hop; |
85 | | static int hf_osi_options_route; |
86 | | static int hf_osi_options_rtd_lifetime; |
87 | | static int hf_osi_options_rtd_source_routing; |
88 | | static int hf_osi_options_padding; |
89 | | static int hf_osi_options_rfd_error_class; |
90 | | static int hf_osi_options_snpa_mask; |
91 | | static int hf_osi_options_source_routing; |
92 | | static int hf_osi_options_priority; |
93 | | static int hf_osi_options_qos_reserved; |
94 | | static int hf_osi_options_residual_error_prob_vs_cost; |
95 | | static int hf_osi_options_rtd_pdu_discarded; |
96 | | static int hf_osi_options_rfd_field; |
97 | | |
98 | | static int ett_osi_options; |
99 | | static int ett_osi_qos; |
100 | | static int ett_osi_route; |
101 | | static int ett_osi_redirect; |
102 | | |
103 | | static expert_field ei_osi_options_none; |
104 | | static expert_field ei_osi_options_rfd_error_class; |
105 | | |
106 | | static const value_string osi_opt_sec_vals[] = { |
107 | | {OSI_OPT_SEC_RESERVED, "Reserved"}, |
108 | | {OSI_OPT_SEC_SRC_ADR_SPEC, "Source Address Specific"}, |
109 | | {OSI_OPT_SEC_DST_ADR_SPEC, "Destination Address Specific"}, |
110 | | {OSI_OPT_SEC_GLOBAL_UNIQUE, "Globally Unique"}, |
111 | | {0, NULL} |
112 | | }; |
113 | | |
114 | | static const value_string osi_opt_qos_vals[] = { |
115 | | {OSI_OPT_QOS_RESERVED, "Reserved"}, |
116 | | {OSI_OPT_QOS_SRC_ADR_SPEC, "Source Address Specific"}, |
117 | | {OSI_OPT_QOS_DST_ADR_SPEC, "Destination Address Specific"}, |
118 | | {OSI_OPT_QOS_GLOBAL_UNIQUE, "Globally Unique"}, |
119 | | {0, NULL} |
120 | | }; |
121 | | |
122 | | static const value_string osi_opt_rfd_error_class[] = { |
123 | | {OSI_OPT_RFD_GENERAL, "General"}, |
124 | | {OSI_OPT_RFD_ADDRESS, "Address"}, |
125 | | {OSI_OPT_RFD_SOURCE_ROUTING, "Source Routing"}, |
126 | | {OSI_OPT_RFD_LIFETIME, "Lifetime"}, |
127 | | {OSI_OPT_RFD_PDU_DISCARDED, "PDU discarded"}, |
128 | | {OSI_OPT_RFD_REASSEMBLY, "Reassembly"}, |
129 | | {0, NULL} |
130 | | }; |
131 | | |
132 | | static const value_string osi_opt_rfd_general[] = { |
133 | | {0x00, "Reason not specified"}, |
134 | | {0x01, "Protocol procedure error"}, |
135 | | {0x02, "Incorrect checksum"}, |
136 | | {0x03, "PDU discarded due to congestion"}, |
137 | | {0x04, "Header syntax error ( cannot be parsed )"}, |
138 | | {0x05, "Segmentation needed but not permitted"}, |
139 | | {0x06, "Incomplete PDU received"}, |
140 | | {0x07, "Duplicate option"}, |
141 | | {0, NULL} |
142 | | }; |
143 | | |
144 | | static const value_string osi_opt_rfd_address[] = { |
145 | | {0x00, "Destination Address unreachable"}, |
146 | | {0x01, "Destination Address unknown"}, |
147 | | {0, NULL} |
148 | | }; |
149 | | |
150 | | static const value_string osi_opt_rfd_src_route[] = { |
151 | | {0x00, "Unspecified source routing error"}, |
152 | | {0x01, "Syntax error in source routing field"}, |
153 | | {0x02, "Unknown address in source routing field"}, |
154 | | {0x03, "Path not acceptable"}, |
155 | | {0, NULL} |
156 | | }; |
157 | | |
158 | | static const value_string osi_opt_rfd_lifetime[] = { |
159 | | {0x00, "Lifetime expired while data unit in transit"}, |
160 | | {0x01, "Lifetime expired during reassembly"}, |
161 | | {0, NULL} |
162 | | }; |
163 | | |
164 | | static const value_string osi_opt_rfd_discarded[] = { |
165 | | {0x00, "Unsupported option not specified"}, |
166 | | {0x01, "Unsupported protocol version"}, |
167 | | {0x02, "Unsupported security option"}, |
168 | | {0x03, "Unsupported source routing option"}, |
169 | | {0x04, "Unsupported recording of route option"}, |
170 | | {0, NULL} |
171 | | }; |
172 | | |
173 | | static const value_string osi_opt_rfd_reassembly[] = { |
174 | | {0x00, "Reassembly interference"}, |
175 | | {0, NULL} }; |
176 | | |
177 | | static dissector_table_t subdissector_decode_as_opt_security_table; |
178 | | |
179 | | static void |
180 | | dissect_option_qos(const uint8_t qos, proto_tree *tree, tvbuff_t *tvb, int offset) |
181 | 4 | { |
182 | 4 | proto_item *ti; |
183 | 4 | proto_tree *osi_qos_tree; |
184 | | |
185 | 4 | ti = proto_tree_add_item(tree, hf_osi_options_qos_maintenance, tvb, offset, 1, ENC_BIG_ENDIAN); |
186 | 4 | osi_qos_tree = proto_item_add_subtree(ti, ett_osi_qos); |
187 | | |
188 | 4 | if ( ((qos & OSI_OPT_QOS_MASK) >> 6) == OSI_OPT_QOS_GLOBAL_UNIQUE) { /* Analyze BIT field to get all Values */ |
189 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_qos_reserved, tvb, offset, 1, ENC_NA); |
190 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_qos_sequencing_vs_transit_delay, tvb, offset, 1, ENC_NA); |
191 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_congestion_experienced, tvb, offset, 1, ENC_NA); |
192 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_transit_delay_vs_cost, tvb, offset, 1, ENC_NA); |
193 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_residual_error_prob_vs_transit_delay, tvb, offset, 1, ENC_NA); |
194 | 2 | proto_tree_add_item(osi_qos_tree, hf_osi_options_residual_error_prob_vs_cost, tvb, offset, 1, ENC_NA); |
195 | 2 | } |
196 | 4 | } |
197 | | |
198 | | static void |
199 | | dissect_option_route(unsigned char parm_type, int offset, unsigned char parm_len, |
200 | | tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo ) |
201 | 31 | { |
202 | 31 | unsigned char next_hop = 0; |
203 | 31 | uint16_t this_hop = 0; |
204 | 31 | unsigned char netl = 0; |
205 | 31 | unsigned char last_hop = 0; |
206 | 31 | unsigned char cnt_hops = 0; |
207 | 31 | unsigned char crr = 0; |
208 | 31 | char* str; |
209 | | |
210 | 31 | proto_tree *osi_route_tree = NULL; |
211 | | |
212 | 31 | if ( parm_type == OSI_OPT_SOURCE_ROUTING ) { |
213 | 10 | next_hop = tvb_get_uint8(tvb, offset + 1); |
214 | 10 | netl = tvb_get_uint8(tvb, next_hop + 2); |
215 | 10 | this_hop = offset + 2; /* points to first netl */ |
216 | | |
217 | 10 | proto_tree_add_uint_format_value(tree, hf_osi_options_source_routing, tvb, offset + next_hop, netl, |
218 | 10 | tvb_get_uint8(tvb, offset), "%s ( Next Hop Highlighted In Data Buffer )", |
219 | 10 | (tvb_get_uint8(tvb, offset) == 0) ? "Partial Source Routing" : |
220 | 10 | "Complete Source Routing"); |
221 | 10 | } |
222 | 21 | else if ( parm_type == OSI_OPT_RECORD_OF_ROUTE ) { |
223 | 21 | crr = tvb_get_uint8(tvb, offset); |
224 | 21 | last_hop = tvb_get_uint8(tvb, offset + 1); |
225 | 21 | osi_route_tree = proto_tree_add_subtree(tree, tvb, offset, parm_len, ett_osi_route, NULL, |
226 | 21 | (crr == 0) ? "Partial Route Recording" : "Complete Route Recording"); |
227 | | |
228 | | /* Complete Route Recording or Partial Route Recording */ |
229 | 21 | proto_tree_add_uint_format_value(tree, hf_osi_options_route_recording, tvb, offset, 1, crr, "%s ", |
230 | 21 | (crr == 0) ? "Partial Route Recording" : |
231 | 21 | "Complete Route Recording"); |
232 | | |
233 | | /* "last_hop" is either : |
234 | | * 0x03 : special value for no NET recorded yet. |
235 | | * 0xFF : special value telling there is no more place |
236 | | in the Route Recording Allocated Length and |
237 | | therefore next NETs won't be recorded. |
238 | | * Other value : Total length of recorded NETs so far. |
239 | | */ |
240 | 21 | if ( last_hop == 0x03 ) |
241 | 1 | proto_tree_add_uint_format(osi_route_tree, hf_osi_options_last_hop, tvb, offset + 1, 1, last_hop, |
242 | 1 | "No Network Entity Titles Recorded Yet"); |
243 | 21 | if ( last_hop == 0xFF ) |
244 | 4 | proto_tree_add_uint_format(osi_route_tree, hf_osi_options_last_hop, tvb, offset + 1, 1, last_hop, |
245 | 4 | "Recording Terminated : No more space !"); |
246 | | |
247 | 21 | if ( last_hop == 255 || last_hop == 0x03 ) |
248 | 5 | this_hop = parm_len + 1; /* recording terminated, |
249 | | * or not begun, nothing to show */ |
250 | 16 | else |
251 | 16 | this_hop = offset + 2; /* points to first netl */ |
252 | 21 | } |
253 | | |
254 | 90 | while ( this_hop < offset + last_hop -2 ) { /* -2 for crr and last_hop */ |
255 | 59 | netl = tvb_get_uint8(tvb, this_hop); |
256 | 59 | str = print_nsap_net(pinfo->pool, tvb, this_hop + 1, netl); |
257 | 59 | proto_tree_add_string_format(osi_route_tree, hf_osi_options_route, tvb, this_hop, netl + 1, str, |
258 | 59 | "Hop #%3u NETL: %2u, NET: %s", cnt_hops++, netl, str); |
259 | 59 | this_hop += 1 + netl; |
260 | 59 | } |
261 | 31 | } |
262 | | |
263 | | |
264 | | static void |
265 | | dissect_option_rfd(const unsigned char error, const unsigned char field, int offset, |
266 | | unsigned char len _U_, tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo ) |
267 | 12 | { |
268 | 12 | proto_item *ti; |
269 | | |
270 | 12 | ti = proto_tree_add_item(tree, hf_osi_options_rfd_error_class, tvb, offset, 1, ENC_BIG_ENDIAN); |
271 | | |
272 | 12 | switch ((error & OSI_OPT_RFD_MASK) >> 4) |
273 | 12 | { |
274 | 2 | case OSI_OPT_RFD_GENERAL: |
275 | 2 | proto_tree_add_item(tree, hf_osi_options_rtd_general, tvb, offset, 1, ENC_BIG_ENDIAN); |
276 | 2 | break; |
277 | 0 | case OSI_OPT_RFD_ADDRESS: |
278 | 0 | proto_tree_add_item(tree, hf_osi_options_rtd_address, tvb, offset, 1, ENC_BIG_ENDIAN); |
279 | 0 | break; |
280 | 0 | case OSI_OPT_RFD_SOURCE_ROUTING: |
281 | 0 | proto_tree_add_item(tree, hf_osi_options_rtd_source_routing, tvb, offset, 1, ENC_BIG_ENDIAN); |
282 | 0 | break; |
283 | 1 | case OSI_OPT_RFD_LIFETIME: |
284 | 1 | proto_tree_add_item(tree, hf_osi_options_rtd_lifetime, tvb, offset, 1, ENC_BIG_ENDIAN); |
285 | 1 | break; |
286 | 1 | case OSI_OPT_RFD_PDU_DISCARDED: |
287 | 1 | proto_tree_add_item(tree, hf_osi_options_rtd_pdu_discarded, tvb, offset, 1, ENC_BIG_ENDIAN); |
288 | 1 | break; |
289 | 4 | case OSI_OPT_RFD_REASSEMBLY: |
290 | 4 | proto_tree_add_item(tree, hf_osi_options_rtd_reassembly, tvb, offset, 1, ENC_BIG_ENDIAN); |
291 | 4 | break; |
292 | 4 | default: |
293 | 4 | expert_add_info(pinfo, ti, &ei_osi_options_rfd_error_class); |
294 | 12 | } |
295 | | |
296 | 12 | proto_tree_add_uint(tree, hf_osi_options_rfd_field, tvb, offset + field, 1, field); |
297 | 12 | } |
298 | | |
299 | | /* ############################## Dissection Functions ###################### */ |
300 | | |
301 | | /* |
302 | | * Name: dissect_osi_options() |
303 | | * |
304 | | * Description: |
305 | | * Main entry area for esis de-mangling. This will build the |
306 | | * main esis tree data and call the sub-protocols as needed. |
307 | | * |
308 | | * Input: |
309 | | * unsigned char : length of option section |
310 | | * tvbuff_t * : tvbuff containing packet data |
311 | | * int : offset into packet where we are (packet_data[offset]== start |
312 | | * of what we care about) |
313 | | * proto_tree * : tree of display data. May be NULL. |
314 | | * |
315 | | * Output: |
316 | | * void, but we will add to the proto_tree if it is not NULL. |
317 | | */ |
318 | | void |
319 | | dissect_osi_options(unsigned char opt_len, tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) |
320 | 262 | { |
321 | 262 | proto_item *ti; |
322 | 262 | proto_tree *osi_option_tree = NULL; |
323 | 262 | unsigned char parm_len = 0; |
324 | 262 | unsigned char parm_type = 0; |
325 | 262 | uint8_t octet; |
326 | 262 | uint32_t sec_type; |
327 | 262 | tvbuff_t *next_tvb; |
328 | | |
329 | 262 | osi_option_tree = proto_tree_add_subtree(tree, tvb, offset, opt_len, |
330 | 262 | ett_osi_options, &ti, "### Option Section ###"); |
331 | 262 | if ( 0 == opt_len ) { |
332 | 156 | expert_add_info(pinfo, ti, &ei_osi_options_none); |
333 | 156 | return; |
334 | 156 | } |
335 | | |
336 | 1.16k | while ( 0 < opt_len ) { |
337 | 1.15k | parm_type = tvb_get_uint8(tvb, offset++); |
338 | 1.15k | parm_len = tvb_get_uint8(tvb, offset++); |
339 | | |
340 | 1.15k | switch ( parm_type ) { |
341 | 4 | case OSI_OPT_QOS_MAINTANANCE: |
342 | 4 | octet = tvb_get_uint8(tvb, offset); |
343 | 4 | dissect_option_qos(octet, osi_option_tree, tvb, offset); |
344 | 4 | break; |
345 | | |
346 | 6 | case OSI_OPT_SECURITY: |
347 | | /* |
348 | | * This is unspecified by ISO 8473, and the interpretation |
349 | | * of the value of the security option appears to be |
350 | | * specified by various profiles, such as GOSIP, TUBA, and |
351 | | * ATN. |
352 | | * |
353 | | * Thus, we use a payload dissector, so the user can |
354 | | * specify which dissector to use. |
355 | | */ |
356 | 6 | proto_tree_add_item_ret_uint(osi_option_tree, hf_osi_options_security_type, tvb, offset, 1, ENC_BIG_ENDIAN, &sec_type); |
357 | | /* XXX */ |
358 | 6 | switch ( sec_type ) { |
359 | | |
360 | 2 | case OSI_OPT_SEC_RESERVED: |
361 | 2 | case OSI_OPT_SEC_SRC_ADR_SPEC: |
362 | 2 | case OSI_OPT_SEC_DST_ADR_SPEC: |
363 | 2 | default: |
364 | 2 | break; |
365 | | |
366 | 4 | case OSI_OPT_SEC_GLOBAL_UNIQUE: |
367 | 4 | next_tvb = tvb_new_subset_length(tvb, offset + 1, parm_len - 1); |
368 | 4 | (void) dissector_try_payload_with_data(subdissector_decode_as_opt_security_table, |
369 | 4 | next_tvb, pinfo, osi_option_tree, true, NULL); |
370 | 4 | break; |
371 | 6 | } |
372 | 6 | break; |
373 | | |
374 | 16 | case OSI_OPT_PRIORITY: |
375 | 16 | octet = tvb_get_uint8(tvb, offset); |
376 | 16 | if ( OSI_OPT_MAX_PRIORITY >= octet ) { |
377 | 6 | ti = proto_tree_add_item(osi_option_tree, hf_osi_options_priority, tvb, offset, 1, ENC_BIG_ENDIAN); |
378 | 10 | } else { |
379 | 10 | ti = proto_tree_add_uint_format_value(osi_option_tree, hf_osi_options_priority, tvb, offset, 1, |
380 | 10 | octet, "%u ( Invalid )", octet); |
381 | 10 | } |
382 | 16 | proto_item_set_len(ti, parm_len); |
383 | 16 | break; |
384 | | |
385 | 2 | case OSI_OPT_ADDRESS_MASK: |
386 | 2 | proto_tree_add_bytes_format_value(osi_option_tree, hf_osi_options_address_mask, tvb, offset, parm_len, |
387 | 2 | NULL, "%s", |
388 | 2 | print_area(pinfo->pool, tvb, offset, parm_len)); |
389 | 2 | break; |
390 | | |
391 | 14 | case OSI_OPT_SNPA_MASK: |
392 | 14 | proto_tree_add_item(osi_option_tree, hf_osi_options_snpa_mask, tvb, offset, parm_len, ENC_NA); |
393 | 14 | break; |
394 | | |
395 | 2 | case OSI_OPT_ES_CONFIG_TIMER: |
396 | 2 | ti = proto_tree_add_item(osi_option_tree, hf_osi_options_esct, tvb, offset, 2, ENC_BIG_ENDIAN); |
397 | 2 | proto_item_set_len(ti, parm_len); break; |
398 | | |
399 | 6 | case OSI_OPT_PADDING: |
400 | 6 | proto_tree_add_item(osi_option_tree, hf_osi_options_padding, tvb, offset, parm_len, ENC_NA); |
401 | 6 | break; |
402 | | |
403 | 10 | case OSI_OPT_SOURCE_ROUTING: |
404 | 31 | case OSI_OPT_RECORD_OF_ROUTE: |
405 | 31 | dissect_option_route(parm_type, offset, parm_len, tvb, |
406 | 31 | osi_option_tree, pinfo); |
407 | 31 | break; |
408 | | |
409 | 12 | case OSI_OPT_REASON_OF_DISCARD: |
410 | 12 | dissect_option_rfd(tvb_get_uint8(tvb, offset), |
411 | 12 | tvb_get_uint8(tvb, offset + 1), offset, parm_len, |
412 | 12 | tvb, osi_option_tree, pinfo); |
413 | 12 | break; |
414 | 1.15k | } |
415 | 1.05k | opt_len -= parm_len + 2; |
416 | 1.05k | offset += parm_len; |
417 | 1.05k | } |
418 | 106 | } /* dissect-osi-options */ |
419 | | |
420 | | |
421 | | /* |
422 | | * Name: proto_register_osi_options() |
423 | | * |
424 | | * Description: |
425 | | * main register for esis protocol set. We register some display |
426 | | * formats and the protocol module variables. |
427 | | * |
428 | | * NOTE: this procedure to autolinked by the makefile process that |
429 | | * builds register.c |
430 | | * |
431 | | * Input: |
432 | | * void |
433 | | * |
434 | | * Output: |
435 | | * void |
436 | | */ |
437 | | |
438 | | void |
439 | 16 | proto_register_osi_options(void) { |
440 | | |
441 | 16 | static hf_register_info hf[] = |
442 | 16 | { |
443 | | /* Generated from convert_proto_tree_add_text.pl */ |
444 | 16 | { &hf_osi_options_qos_maintenance, { "Quality of service maintenance", "osi.options.qos.maintenance", FT_UINT8, BASE_DEC, VALS(osi_opt_qos_vals), OSI_OPT_QOS_MASK, NULL, HFILL }}, |
445 | 16 | { &hf_osi_options_qos_reserved, { "Reserved", "osi.options.qos.reserved", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_RSVD, NULL, HFILL }}, |
446 | 16 | { &hf_osi_options_qos_sequencing_vs_transit_delay, { "Sequencing versus transit delay", "osi.options.qos.seq_vs_trs", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_SEQ_VS_TRS, NULL, HFILL }}, |
447 | 16 | { &hf_osi_options_congestion_experienced, { "Congestion experienced", "osi.options.qos.cong_exped", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_CONG_EXPED, NULL, HFILL }}, |
448 | 16 | { &hf_osi_options_transit_delay_vs_cost, { "Transit delay versus cost", "osi.options.qos.tsd_vs_cost", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_TSD_VS_COST, NULL, HFILL }}, |
449 | 16 | { &hf_osi_options_residual_error_prob_vs_transit_delay, { "Residual error probability versus transit delay", "osi.options.qos.reserror_trs", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_RESERR_TRS, NULL, HFILL }}, |
450 | 16 | { &hf_osi_options_residual_error_prob_vs_cost, { "Residual error probability versus cost", "osi.options.qos.reserror_cost", FT_BOOLEAN, 8, NULL, OSI_OPT_QOS_SUB_RESERR_COST, NULL, HFILL }}, |
451 | 16 | { &hf_osi_options_source_routing, { "Source Routing", "osi.options.source_routing", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
452 | 16 | { &hf_osi_options_route_recording, { "Route Recording", "osi.options.route_recording", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
453 | 16 | { &hf_osi_options_last_hop, { "Last Hop", "osi.options.last_hop", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, |
454 | 16 | { &hf_osi_options_route, { "Route", "osi.options.route", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
455 | 16 | { &hf_osi_options_rfd_error_class, { "Error Class", "osi.options.rfd.error_class", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_error_class), OSI_OPT_RFD_MASK, NULL, HFILL }}, |
456 | 16 | { &hf_osi_options_rtd_general, { "Reason for discard {General}", "osi.options.rtd_general", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_general), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
457 | 16 | { &hf_osi_options_rtd_address, { "Reason for discard {Address}", "osi.options.rtd_address", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_address), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
458 | 16 | { &hf_osi_options_rtd_source_routing, { "Reason for discard {Source Routing}", "osi.options.rtd_source_routing", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_src_route), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
459 | 16 | { &hf_osi_options_rtd_lifetime, { "Reason for discard {Lifetime}", "osi.options.rtd_lifetime", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_lifetime), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
460 | 16 | { &hf_osi_options_rtd_pdu_discarded, { "Reason for discard {PDU discarded}", "osi.options.rtd_pdu_discarded", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_discarded), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
461 | 16 | { &hf_osi_options_rtd_reassembly, { "Reason for discard {Reassembly}", "osi.options.rtd_reassembly", FT_UINT8, BASE_DEC, VALS(osi_opt_rfd_reassembly), OSI_OPT_RFD_SUB_MASK, NULL, HFILL }}, |
462 | 16 | { &hf_osi_options_rfd_field, { "Field", "osi.options.rfd.field", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
463 | 16 | { &hf_osi_options_security_type, { "Security type", "osi.options.security_type", FT_UINT8, BASE_DEC, VALS(osi_opt_sec_vals), OSI_OPT_SEC_MASK, NULL, HFILL }}, |
464 | 16 | { &hf_osi_options_priority, { "Priority", "osi.options.priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
465 | 16 | { &hf_osi_options_address_mask, { "Address Mask", "osi.options.address_mask", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
466 | 16 | { &hf_osi_options_snpa_mask, { "SNPA Mask", "osi.options.snpa_mask", FT_SYSTEM_ID, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
467 | 16 | { &hf_osi_options_esct, { "ESCT (seconds)", "osi.options.esct", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
468 | 16 | { &hf_osi_options_padding, { "Padding", "osi.options.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
469 | 16 | }; |
470 | | |
471 | 16 | static int *ett[] = { |
472 | 16 | &ett_osi_options, |
473 | 16 | &ett_osi_qos, |
474 | 16 | &ett_osi_route, |
475 | 16 | &ett_osi_redirect |
476 | 16 | }; |
477 | | |
478 | 16 | static ei_register_info ei[] = { |
479 | 16 | { &ei_osi_options_none, { "osi.options.none", PI_PROTOCOL, PI_NOTE, "No Options for this PDU", EXPFILL }}, |
480 | 16 | { &ei_osi_options_rfd_error_class, { "osi.options.rfd.error_class.unknown", PI_PROTOCOL, PI_WARN, "UNKNOWN Error Class", EXPFILL }}, |
481 | 16 | }; |
482 | | |
483 | 16 | expert_module_t *expert_osi_options; |
484 | | |
485 | 16 | proto_register_field_array(proto_osi, hf, array_length(hf)); |
486 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
487 | 16 | expert_osi_options = expert_register_protocol(proto_osi); |
488 | 16 | expert_register_field_array(expert_osi_options, ei, array_length(ei)); |
489 | | |
490 | 16 | subdissector_decode_as_opt_security_table = register_decode_as_next_proto(proto_osi, |
491 | | "osi.opt_security", "OSI Security Option", NULL); |
492 | 16 | } |
493 | | |
494 | | /* |
495 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
496 | | * |
497 | | * Local variables: |
498 | | * c-basic-offset: 2 |
499 | | * tab-width: 8 |
500 | | * indent-tabs-mode: nil |
501 | | * End: |
502 | | * |
503 | | * vi: set shiftwidth=2 tabstop=8 expandtab: |
504 | | * :indentSize=2:tabSize=8:noTabs=true: |
505 | | */ |