/src/wireshark/epan/dissectors/packet-forces.c
Line | Count | Source |
1 | | /* packet-forces.c |
2 | | * RFC 5810 |
3 | | * Routines for dissecting IETF ForCES protocol layer messages.Now support the following TML types:TCP+UDP,SCTP. |
4 | | * Copyright 2009, NDSC & Zhejiang Gongshang University,Fenggen Jia <fgjia@mail.zjgsu.edu.cn or fenggen.jia@gmail.com> |
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/prefs.h> |
17 | | #include <epan/expert.h> |
18 | | #include <epan/unit_strings.h> |
19 | | |
20 | | void proto_register_forces(void); |
21 | | void proto_reg_handoff_forces(void); |
22 | | |
23 | | static dissector_handle_t forces_handle_tcp, forces_handle; |
24 | | |
25 | | static dissector_handle_t ip_handle; |
26 | | |
27 | | /* Initialize the ForCES protocol and registered fields */ |
28 | | static int proto_forces; |
29 | | |
30 | | /*Main header*/ |
31 | | static int hf_forces_version; |
32 | | static int hf_forces_rsvd; |
33 | | static int hf_forces_messagetype; |
34 | | static int hf_forces_sid; |
35 | | static int hf_forces_did; |
36 | | static int hf_forces_correlator; |
37 | | static int hf_forces_length; |
38 | | /*Flags*/ |
39 | | static int hf_forces_flags; |
40 | | static int hf_forces_flags_ack; |
41 | | static int hf_forces_flags_pri; |
42 | | static int hf_forces_flags_rsrvd; |
43 | | static int hf_forces_flags_em; |
44 | | static int hf_forces_flags_at; |
45 | | static int hf_forces_flags_tp; |
46 | | static int hf_forces_flags_reserved; |
47 | | |
48 | | static int hf_forces_tlv_type; |
49 | | static int hf_forces_tlv_length; |
50 | | |
51 | | /*Initiation of LFBSelect TLV*/ |
52 | | static int hf_forces_lfbselect_tlv_type_lfb_classid; |
53 | | static int hf_forces_lfbselect_tlv_type_lfb_instanceid; |
54 | | |
55 | | /*Initiation of Operation TLV*/ |
56 | | static int hf_forces_lfbselect_tlv_type_operation_type; |
57 | | static int hf_forces_lfbselect_tlv_type_operation_length; |
58 | | static int hf_forces_lfbselect_tlv_type_operation_path_type; |
59 | | static int hf_forces_lfbselect_tlv_type_operation_path_length; |
60 | | static int hf_forces_lfbselect_tlv_type_operation_path_flags; |
61 | | static int hf_forces_lfbselect_tlv_type_operation_path_flags_selector; |
62 | | static int hf_forces_lfbselect_tlv_type_operation_path_flags_reserved; |
63 | | static int hf_forces_lfbselect_tlv_type_operation_path_IDcount; |
64 | | static int hf_forces_lfbselect_tlv_type_operation_path_IDs; |
65 | | static int hf_forces_lfbselect_tlv_type_operation_path_data; |
66 | | |
67 | | /*Initiation of Redirect TLV*/ |
68 | | static int hf_forces_redirect_tlv_meta_data_tlv_type; |
69 | | static int hf_forces_redirect_tlv_meta_data_tlv_length; |
70 | | static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv; |
71 | | static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id; |
72 | | static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length; |
73 | | static int hf_forces_redirect_tlv_redirect_data_tlv_type; |
74 | | static int hf_forces_redirect_tlv_redirect_data_tlv_length; |
75 | | |
76 | | /*Initiation of ASResult TLV*/ |
77 | | static int hf_forces_asresult_association_setup_result; |
78 | | |
79 | | /*Initiation of ASTreason TLV*/ |
80 | | static int hf_forces_astreason_tlv_teardown_reason; |
81 | | |
82 | | /*Main TLV may be unknown*/ |
83 | | static int hf_forces_unknown_tlv; |
84 | | |
85 | | /*Message Types */ |
86 | | #define AssociationSetup 0x01 |
87 | | #define AssociationTeardown 0x02 |
88 | | #define Config 0x03 |
89 | | #define Query 0x04 |
90 | | #define EventNotification 0x05 |
91 | | #define PacketRedirect 0x06 |
92 | | #define Heartbeat 0x0F |
93 | | #define AssociationSetupResponse 0x11 |
94 | | #define ConfigResponse 0x13 |
95 | | #define QueryResponse 0x14 |
96 | | |
97 | | /*TLV Types*/ |
98 | | #define Reserved 0x0000 |
99 | 0 | #define REDIRECT_TLV 0x0001 |
100 | 0 | #define ASResult_TLV 0x0010 |
101 | 0 | #define ASTreason_TLV 0x0011 |
102 | 0 | #define LFBselect_TLV 0x1000 |
103 | 0 | #define PATH_DATA_TLV 0x0110 |
104 | | #define KEYINFO_TLV 0x0111 |
105 | | #define FULLDATA_TLV 0x0112 |
106 | | #define SPARSEDATA_TLV 0x0113 |
107 | | #define RESULT_TLV 0x0114 |
108 | | #define METADATA_TLV 0x0115 |
109 | | #define REDIRECTDATA_TLV 0x0116 |
110 | | |
111 | | /*Operation Type*/ |
112 | | #define Reserved 0x0000 |
113 | | #define SET 0x0001 |
114 | | #define SET_PROP 0x0002 |
115 | | #define SET_RESPONSE 0x0003 |
116 | | #define SET_PROP_RESPONSE 0x0004 |
117 | | #define DEL 0x0005 |
118 | | #define DEL_RESPONSE 0x0006 |
119 | | #define GET 0x0007 |
120 | | #define GET_PROP 0x0008 |
121 | | #define GET_RESPONSE 0x0009 |
122 | | #define GET_PROP_RESPONSE 0x000A |
123 | | #define REPORT 0x000B |
124 | | #define COMMIT 0x000C |
125 | | #define COMMIT_RESPONSE 0x000D |
126 | | #define TRCOMP 0x000E |
127 | | |
128 | 0 | #define FLAG_SELECTOR 0x8000 |
129 | | |
130 | 0 | #define ForCES_HEADER_LENGTH 24 |
131 | 0 | #define TLV_TL_LENGTH 4 /*Type+length*/ |
132 | 0 | #define MIN_IP_HEADER_LENGTH 20 |
133 | | |
134 | | /*For TCP+UDP TML. There are two bytes added to the ForCES PL message, not strictly combine to the ForCES protocol. |
135 | | For other type TMLs,no need to add these 2 bytes.*/ |
136 | 0 | #define TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP 2 |
137 | | |
138 | | /*SCTP TML*/ |
139 | | static unsigned forces_alternate_sctp_high_prio_channel_port; |
140 | | static unsigned forces_alternate_sctp_med_prio_channel_port; |
141 | | static unsigned forces_alternate_sctp_low_prio_channel_port; |
142 | | |
143 | | /*Initialize the subtree pointers*/ |
144 | | static int ett_forces; |
145 | | static int ett_forces_main_header; |
146 | | static int ett_forces_flags; |
147 | | static int ett_forces_tlv; |
148 | | static int ett_forces_lfbselect_tlv_type; |
149 | | |
150 | | /*Operation TLV subtree*/ |
151 | | static int ett_forces_lfbselect_tlv_type_operation; |
152 | | static int ett_forces_lfbselect_tlv_type_operation_path; |
153 | | static int ett_forces_lfbselect_tlv_type_operation_path_data; |
154 | | static int ett_forces_lfbselect_tlv_type_operation_path_data_path; |
155 | | static int ett_forces_path_data_tlv; |
156 | | static int ett_forces_path_data_tlv_flags; |
157 | | |
158 | | /*Selector subtree*/ |
159 | | static int ett_forces_lfbselect_tlv_type_operation_path_selector; |
160 | | |
161 | | /*Redirect TLV subtree*/ |
162 | | static int ett_forces_redirect_tlv_type; |
163 | | static int ett_forces_redirect_tlv_meta_data_tlv; |
164 | | static int ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv; |
165 | | static int ett_forces_redirect_tlv_redirect_data_tlv; |
166 | | |
167 | | /*ASResult TLV subtree*/ |
168 | | static int ett_forces_asresult_tlv; |
169 | | |
170 | | /*ASReason subtree*/ |
171 | | static int ett_forces_astreason_tlv; |
172 | | |
173 | | /*Main_TLV unknown subtree*/ |
174 | | static int ett_forces_unknown_tlv; |
175 | | |
176 | | |
177 | | static expert_field ei_forces_length; |
178 | | static expert_field ei_forces_tlv_type; |
179 | | static expert_field ei_forces_tlv_length; |
180 | | static expert_field ei_forces_lfbselect_tlv_type_operation_path_length; |
181 | | static expert_field ei_forces_lfbselect_tlv_type_operation_type; |
182 | | static expert_field ei_forces_redirect_tlv_redirect_data_tlv_length; |
183 | | |
184 | | /*ACK values and the strings to be displayed*/ |
185 | | static const value_string main_header_flags_ack_vals[] = { |
186 | | { 0x0, "NoACK" }, |
187 | | { 0x1, "SuccessACK" }, |
188 | | { 0x2, "FailureACK" }, |
189 | | { 0x3, "AlwaysACK" }, |
190 | | { 0, NULL} |
191 | | }; |
192 | | |
193 | | /*Execution mode(EM) values and the strings to be displayed*/ |
194 | | static const value_string main_header_flags_em_vals[] = { |
195 | | { 0x0, "Reserved" }, |
196 | | { 0x1, "Execute-all-or-none" }, |
197 | | { 0x2, "Execute-until-failure" }, |
198 | | { 0x3, "Continue-execute-on-failure" }, |
199 | | { 0, NULL} |
200 | | }; |
201 | | |
202 | | /*Transaction Phase values and the strings to be displayed*/ |
203 | | static const value_string main_header_flags_tp_vals[] = { |
204 | | { 0x0, "SOT (Start of Transaction)" }, |
205 | | { 0x1, "MOT (Middle of Transaction)" }, |
206 | | { 0x2, "EOT (End of Transaction)" }, |
207 | | { 0x3, "ABT (Abort)" }, |
208 | | { 0, NULL} |
209 | | }; |
210 | | |
211 | | /*Atomic Transaction(AT) values and the strings to be displayed*/ |
212 | | static const value_string main_header_flags_at_vals[] = { |
213 | | { 0x0, "Stand-alone Message"}, |
214 | | { 0x1, "2PC Transaction Message"}, |
215 | | { 0, NULL} |
216 | | }; |
217 | | |
218 | | /*Association Setup Result*/ |
219 | | static const value_string association_setup_result_at_vals[] = { |
220 | | { 0x0, "success"}, |
221 | | { 0x1, "FE ID invalid"}, |
222 | | { 0x2, "permission denied"}, |
223 | | { 0, NULL}, |
224 | | }; |
225 | | |
226 | | /*Teardown Reason*/ |
227 | | static const value_string teardown_reason_at_vals[] = { |
228 | | { 0x0, "normal-teardown by administrator"}, |
229 | | { 0x1, "error - loss of heartbeats"}, |
230 | | { 0x2, "error - out of bandwidth"}, |
231 | | { 0x3, "error - out of memory"}, |
232 | | { 0x4, "error - application crash"}, |
233 | | { 0x255, "error - other or unspecified"}, |
234 | | { 0, NULL}, |
235 | | }; |
236 | | |
237 | | static const value_string message_type_vals[] = { |
238 | | { AssociationSetup, "AssociationSetup" }, |
239 | | { AssociationTeardown, "AssociationTeardown" }, |
240 | | { Config, "Config" }, |
241 | | { Query, "Query" }, |
242 | | { EventNotification, "EventNotification" }, |
243 | | { PacketRedirect, "PacketRedirect" }, |
244 | | { Heartbeat, "Heartbeat" }, |
245 | | { AssociationSetupResponse, "AssociationSetupResponse" }, |
246 | | { ConfigResponse, "ConfigResponse" }, |
247 | | { QueryResponse, "QueryResponse" }, |
248 | | { 0, NULL}, |
249 | | }; |
250 | | |
251 | | static const value_string tlv_type_vals[] = { |
252 | | { REDIRECT_TLV, "REDIRECT-TLV" }, |
253 | | { ASResult_TLV, "ASResult-TLV" }, |
254 | | { ASTreason_TLV, "ASTreason-TLV" }, |
255 | | { LFBselect_TLV, "LFBselect-TLV" }, |
256 | | { PATH_DATA_TLV, "PATH DATA-TLV" }, |
257 | | { KEYINFO_TLV, "KEYINFO-TLV" }, |
258 | | { FULLDATA_TLV, "FULLDATA-TLV" }, |
259 | | { SPARSEDATA_TLV, "SPARSEDATA-TLV" }, |
260 | | { RESULT_TLV, "RESULT-TLV" }, |
261 | | { METADATA_TLV, "METADATA-TLV" }, |
262 | | { REDIRECTDATA_TLV, "REDIRECTDATA-TLV" }, |
263 | | { 0, NULL}, |
264 | | }; |
265 | | |
266 | | static const value_string operation_type_vals[] = { |
267 | | { Reserved, "Reserved" }, |
268 | | { SET, "SET" }, |
269 | | { SET_PROP, "SET-PROP" }, |
270 | | { SET_RESPONSE, "SET-RESPONSE" }, |
271 | | { SET_PROP_RESPONSE, "SET-PROP-RESPONSE" }, |
272 | | { DEL, "DEL" }, |
273 | | { DEL_RESPONSE, "DEL-RESPONSE" }, |
274 | | { GET, "GET" }, |
275 | | { GET_PROP, "GET-PROP" }, |
276 | | { GET_RESPONSE, "GET-RESPONSE" }, |
277 | | { GET_PROP_RESPONSE, "GET-PROP-RESPONSE" }, |
278 | | { REPORT, "REPORT" }, |
279 | | { COMMIT, "COMMIT" }, |
280 | | { COMMIT_RESPONSE, "COMMIT-RESPONSE" }, |
281 | | { TRCOMP, "TRCOMP" }, |
282 | | { 0, NULL}, |
283 | | }; |
284 | | |
285 | | static void |
286 | | dissect_path_data_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) |
287 | 0 | { |
288 | 0 | proto_item *ti, *flag_item; |
289 | 0 | unsigned length_TLV, IDcount, i; |
290 | 0 | uint16_t type, flag; |
291 | 0 | proto_tree *tlv_tree, *path_data_tree, *flag_tree; |
292 | |
|
293 | 0 | while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH) |
294 | 0 | { |
295 | 0 | tlv_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH, ett_forces_path_data_tlv, &ti, "TLV"); |
296 | |
|
297 | 0 | type = tvb_get_ntohs(tvb, offset); |
298 | 0 | proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_type, |
299 | 0 | tvb, offset, 2, ENC_BIG_ENDIAN); |
300 | 0 | length_TLV = tvb_get_ntohs(tvb, offset+2); |
301 | 0 | proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_length, |
302 | 0 | tvb, offset+2, 2, ENC_BIG_ENDIAN); |
303 | 0 | if (length_TLV < TLV_TL_LENGTH) |
304 | 0 | { |
305 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_path_length, "Bogus TLV length: %u", length_TLV); |
306 | 0 | break; |
307 | 0 | } |
308 | 0 | proto_item_set_len(ti, length_TLV); |
309 | |
|
310 | 0 | if (type == PATH_DATA_TLV) |
311 | 0 | { |
312 | 0 | path_data_tree = proto_tree_add_subtree(tree, tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, |
313 | 0 | ett_forces_path_data_tlv, NULL, "Path Data TLV"); |
314 | |
|
315 | 0 | flag = tvb_get_ntohs(tvb, offset+TLV_TL_LENGTH); |
316 | 0 | flag_item = proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_flags, |
317 | 0 | tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN); |
318 | 0 | flag_tree = proto_item_add_subtree(flag_item, ett_forces_path_data_tlv_flags); |
319 | 0 | proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_selector, |
320 | 0 | tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN); |
321 | 0 | proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_reserved, |
322 | 0 | tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN); |
323 | |
|
324 | 0 | IDcount = tvb_get_ntohs(tvb, offset + TLV_TL_LENGTH + 2); |
325 | 0 | proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDcount, |
326 | 0 | tvb, offset+TLV_TL_LENGTH+2, 2, ENC_BIG_ENDIAN); |
327 | |
|
328 | 0 | for (i = 0; i < IDcount; i++) |
329 | 0 | proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDs, |
330 | 0 | tvb, offset+TLV_TL_LENGTH+2+(i*4), 4, ENC_BIG_ENDIAN); |
331 | 0 | } |
332 | 0 | else |
333 | 0 | { |
334 | 0 | flag = 0; |
335 | 0 | proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_operation_path_data, |
336 | 0 | tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, ENC_NA); |
337 | 0 | } |
338 | |
|
339 | 0 | if ((flag & FLAG_SELECTOR) == 0) |
340 | 0 | break; |
341 | | |
342 | 0 | offset += length_TLV; |
343 | 0 | } |
344 | 0 | } |
345 | | |
346 | | static void |
347 | | dissect_operation_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length_count) |
348 | 0 | { |
349 | 0 | proto_item *ti; |
350 | 0 | proto_tree *oper_tree; |
351 | 0 | unsigned type, length; |
352 | |
|
353 | 0 | while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH) |
354 | 0 | { |
355 | 0 | oper_tree = proto_tree_add_subtree(tree, tvb, offset, length_count, |
356 | 0 | ett_forces_lfbselect_tlv_type_operation, &ti, "Operation TLV"); |
357 | |
|
358 | 0 | type = tvb_get_ntohs(tvb,offset); |
359 | 0 | ti = proto_tree_add_item(oper_tree, hf_forces_lfbselect_tlv_type_operation_type, |
360 | 0 | tvb, offset, 2, ENC_BIG_ENDIAN); |
361 | 0 | if (try_val_to_str(type, operation_type_vals) == NULL) |
362 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_type, |
363 | 0 | "Bogus: ForCES Operation TLV (Type:0x%04x) is not supported", type); |
364 | |
|
365 | 0 | proto_tree_add_item_ret_uint(oper_tree, hf_forces_lfbselect_tlv_type_operation_length, |
366 | 0 | tvb, offset+2, 2, ENC_BIG_ENDIAN, &length); |
367 | |
|
368 | 0 | dissect_path_data_tlv(tvb, pinfo, oper_tree, offset+TLV_TL_LENGTH); |
369 | 0 | if (length == 0) |
370 | 0 | break; |
371 | 0 | offset += length; |
372 | 0 | } |
373 | 0 | } |
374 | | |
375 | | static void |
376 | | dissect_lfbselecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length_count) |
377 | 0 | { |
378 | 0 | unsigned tlv_length; |
379 | |
|
380 | 0 | proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_classid, tvb, offset, 4, ENC_BIG_ENDIAN); |
381 | 0 | proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_instanceid, tvb, offset+4, 4, ENC_BIG_ENDIAN); |
382 | |
|
383 | 0 | offset += 8; |
384 | 0 | while ((tvb_reported_length_remaining(tvb, offset) > TLV_TL_LENGTH) && (length_count > 12)) |
385 | 0 | { |
386 | 0 | tlv_length = tvb_get_ntohs(tvb, offset+2); |
387 | 0 | dissect_operation_tlv(tvb, pinfo, tree, offset, tlv_length); |
388 | 0 | if (tlv_length == 0) |
389 | 0 | break; |
390 | 0 | offset += tlv_length; |
391 | 0 | } |
392 | 0 | } |
393 | | |
394 | | static void |
395 | | dissect_redirecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) |
396 | 0 | { |
397 | 0 | proto_tree *meta_data_tree, *meta_data_ilv_tree, *redirect_data_tree; |
398 | 0 | int start_offset; |
399 | 0 | int length_meta, length_ilv, length_redirect; |
400 | 0 | proto_item *ti; |
401 | 0 | address src_addr, src_net_addr; |
402 | 0 | address dst_addr, dst_net_addr; |
403 | |
|
404 | 0 | copy_address_shallow(&src_addr, &pinfo->src); |
405 | 0 | copy_address_shallow(&src_net_addr, &pinfo->net_src); |
406 | 0 | copy_address_shallow(&dst_addr, &pinfo->dst); |
407 | 0 | copy_address_shallow(&dst_net_addr, &pinfo->net_dst); |
408 | |
|
409 | 0 | meta_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH, |
410 | 0 | ett_forces_redirect_tlv_meta_data_tlv, &ti, "Meta Data TLV"); |
411 | 0 | proto_tree_add_item(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
412 | |
|
413 | 0 | length_meta = tvb_get_ntohs(tvb, offset+2); |
414 | 0 | proto_tree_add_uint(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_length, tvb, offset+2, 2, length_meta); |
415 | 0 | proto_item_set_len(ti, length_meta); |
416 | |
|
417 | 0 | start_offset = offset; |
418 | 0 | while ((tvb_reported_length_remaining(tvb, offset) >= 8) && (start_offset+length_meta > offset)) |
419 | 0 | { |
420 | 0 | meta_data_ilv_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH, |
421 | 0 | ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, &ti, "Meta Data ILV"); |
422 | |
|
423 | 0 | proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id, |
424 | 0 | tvb, offset+8, 4, ENC_BIG_ENDIAN); |
425 | 0 | length_ilv = tvb_get_ntohl(tvb, offset+12); |
426 | 0 | proto_tree_add_uint(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length, |
427 | 0 | tvb, offset+12, 4, length_ilv); |
428 | 0 | offset += 8; |
429 | 0 | if (length_ilv > 0) { |
430 | 0 | proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, |
431 | 0 | tvb, offset, length_ilv, ENC_NA); |
432 | |
|
433 | 0 | if (offset + length_ilv > offset) { |
434 | 0 | offset += length_ilv; |
435 | 0 | } |
436 | 0 | } |
437 | |
|
438 | 0 | proto_item_set_len(ti, length_ilv + 8); |
439 | 0 | } |
440 | |
|
441 | 0 | if (tvb_reported_length_remaining(tvb, offset) > 0) |
442 | 0 | { |
443 | 0 | redirect_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH, |
444 | 0 | ett_forces_redirect_tlv_redirect_data_tlv, &ti, "Redirect Data TLV"); |
445 | |
|
446 | 0 | proto_tree_add_item(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_type, |
447 | 0 | tvb, offset, 2, ENC_BIG_ENDIAN); |
448 | 0 | length_redirect = tvb_get_ntohs(tvb, offset+2); |
449 | 0 | proto_tree_add_uint(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_length, |
450 | 0 | tvb, offset+2, 2, length_redirect); |
451 | |
|
452 | 0 | if (tvb_reported_length_remaining(tvb, offset) < length_redirect) |
453 | 0 | { |
454 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) is wrong", length_redirect); |
455 | 0 | } |
456 | 0 | else if (length_redirect < TLV_TL_LENGTH + MIN_IP_HEADER_LENGTH) |
457 | 0 | { |
458 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) not big enough for IP layer", length_redirect); |
459 | 0 | } |
460 | 0 | else |
461 | 0 | { |
462 | 0 | tvbuff_t *next_tvb; |
463 | |
|
464 | 0 | next_tvb = tvb_new_subset_length(tvb, offset+4, length_redirect-TLV_TL_LENGTH); |
465 | 0 | call_dissector(ip_handle, next_tvb, pinfo, redirect_data_tree); |
466 | | |
467 | | /* Restore IP info */ |
468 | 0 | copy_address_shallow(&pinfo->src, &src_addr); |
469 | 0 | copy_address_shallow(&pinfo->net_src, &src_net_addr); |
470 | 0 | copy_address_shallow(&pinfo->dst, &dst_addr); |
471 | 0 | copy_address_shallow(&pinfo->net_dst, &dst_net_addr); |
472 | 0 | } |
473 | 0 | } |
474 | 0 | } |
475 | | |
476 | | static void |
477 | | dissect_forces(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset) |
478 | 0 | { |
479 | | /* Set up structures needed to add the protocol subtree and manage it */ |
480 | 0 | proto_item *ti, *tlv_item; |
481 | 0 | proto_tree *forces_tree, *forces_flags_tree; |
482 | 0 | proto_tree *forces_main_header_tree, *forces_tlv_tree, *tlv_tree; |
483 | 0 | int length_count; |
484 | |
|
485 | 0 | uint8_t message_type; |
486 | 0 | uint16_t tlv_type; |
487 | | |
488 | | /* Make entries in Protocol column and Info column on summary display */ |
489 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ForCES"); |
490 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
491 | |
|
492 | 0 | ti = proto_tree_add_item(tree, proto_forces, tvb, 0, -1, ENC_NA); |
493 | 0 | forces_tree = proto_item_add_subtree(ti, ett_forces); |
494 | |
|
495 | 0 | forces_main_header_tree = proto_tree_add_subtree(forces_tree, tvb, 0, ForCES_HEADER_LENGTH, |
496 | 0 | ett_forces_main_header, NULL, "Common Header"); |
497 | |
|
498 | 0 | proto_tree_add_item(forces_main_header_tree, hf_forces_version, tvb, 0, 1, ENC_BIG_ENDIAN); |
499 | 0 | proto_tree_add_item(forces_main_header_tree, hf_forces_rsvd, tvb, 0, 1, ENC_BIG_ENDIAN); |
500 | |
|
501 | 0 | message_type = tvb_get_uint8(tvb, offset+1); |
502 | 0 | proto_tree_add_item( forces_main_header_tree, hf_forces_messagetype, tvb, offset+1, 1, ENC_BIG_ENDIAN); |
503 | |
|
504 | 0 | length_count = tvb_get_ntohs(tvb, offset+2) * 4; /*multiply 4 DWORD*/ |
505 | 0 | ti = proto_tree_add_uint_format( forces_main_header_tree, hf_forces_length, |
506 | 0 | tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count); |
507 | 0 | if (length_count != tvb_reported_length_remaining(tvb, offset)) |
508 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)", |
509 | 0 | length_count, tvb_reported_length_remaining(tvb, offset)); |
510 | 0 | if (length_count < 24) |
511 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count); |
512 | |
|
513 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type: %s, Total Length: %u Bytes", |
514 | 0 | val_to_str(pinfo->pool, message_type, message_type_vals, "Unknown messagetype 0x%x"), length_count); |
515 | |
|
516 | 0 | proto_tree_add_item( forces_main_header_tree, hf_forces_sid, tvb, offset+4, 4, ENC_BIG_ENDIAN); |
517 | 0 | proto_tree_add_item( forces_main_header_tree, hf_forces_did, tvb, offset+8, 4, ENC_BIG_ENDIAN); |
518 | 0 | proto_tree_add_item( forces_main_header_tree, hf_forces_correlator, tvb, offset+12, 8, ENC_BIG_ENDIAN); |
519 | | |
520 | | /*Add flags tree*/ |
521 | 0 | ti = proto_tree_add_item(forces_main_header_tree, hf_forces_flags, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
522 | 0 | forces_flags_tree = proto_item_add_subtree(ti, ett_forces_flags); |
523 | |
|
524 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_ack, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
525 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_at, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
526 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_em, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
527 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_pri, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
528 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_reserved, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
529 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_rsrvd, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
530 | 0 | proto_tree_add_item(forces_flags_tree, hf_forces_flags_tp, tvb, offset+20, 4, ENC_BIG_ENDIAN); |
531 | |
|
532 | 0 | offset += 24; |
533 | 0 | while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH) |
534 | 0 | { |
535 | 0 | forces_tlv_tree = proto_tree_add_subtree(forces_tree, tvb, offset, TLV_TL_LENGTH, ett_forces_tlv, &ti, "TLV"); |
536 | |
|
537 | 0 | tlv_type = tvb_get_ntohs(tvb, offset); |
538 | 0 | tlv_item = proto_tree_add_item(forces_tlv_tree, hf_forces_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
539 | 0 | length_count = tvb_get_ntohs(tvb, offset+2) * 4; |
540 | 0 | proto_item_set_len(ti, length_count); |
541 | 0 | ti = proto_tree_add_uint(forces_tlv_tree, hf_forces_tlv_length, |
542 | 0 | tvb, offset+2, 2, length_count); |
543 | 0 | if (tvb_reported_length_remaining(tvb, offset) < length_count) |
544 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus: Main TLV length (%u bytes) is wrong", length_count); |
545 | |
|
546 | 0 | if (length_count < TLV_TL_LENGTH) |
547 | 0 | { |
548 | 0 | expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus TLV length: %u", length_count); |
549 | 0 | break; |
550 | 0 | } |
551 | | |
552 | 0 | offset += TLV_TL_LENGTH; |
553 | 0 | length_count -= TLV_TL_LENGTH; |
554 | |
|
555 | 0 | switch(tlv_type) |
556 | 0 | { |
557 | 0 | case LFBselect_TLV: |
558 | 0 | tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count, |
559 | 0 | ett_forces_lfbselect_tlv_type, NULL, "LFB select TLV"); |
560 | 0 | dissect_lfbselecttlv(tvb, pinfo, tlv_tree, offset, length_count); |
561 | 0 | break; |
562 | | |
563 | 0 | case REDIRECT_TLV: |
564 | 0 | tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count, |
565 | 0 | ett_forces_redirect_tlv_type, NULL, "Redirect TLV"); |
566 | 0 | dissect_redirecttlv(tvb, pinfo, tlv_tree, offset); |
567 | 0 | break; |
568 | | |
569 | 0 | case ASResult_TLV: |
570 | 0 | tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count, |
571 | 0 | ett_forces_asresult_tlv, NULL, "ASResult TLV"); |
572 | 0 | proto_tree_add_item(tlv_tree, hf_forces_asresult_association_setup_result, tvb, offset, 4, ENC_BIG_ENDIAN); |
573 | 0 | break; |
574 | | |
575 | 0 | case ASTreason_TLV: |
576 | 0 | tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count, |
577 | 0 | ett_forces_astreason_tlv, NULL, "ASTreason TLV"); |
578 | 0 | proto_tree_add_item(tlv_tree, hf_forces_astreason_tlv_teardown_reason, tvb, offset, 4, ENC_BIG_ENDIAN); |
579 | 0 | break; |
580 | | |
581 | 0 | default: |
582 | 0 | expert_add_info(pinfo, tlv_item, &ei_forces_tlv_type); |
583 | 0 | tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count, |
584 | 0 | ett_forces_unknown_tlv, NULL, "Unknown TLV"); |
585 | 0 | proto_tree_add_item(tlv_tree, hf_forces_unknown_tlv, tvb, offset, length_count, ENC_NA); |
586 | 0 | break; |
587 | 0 | } |
588 | | |
589 | 0 | offset += length_count; |
590 | 0 | } |
591 | 0 | } |
592 | | |
593 | | /* Code to actually dissect the TCP packets */ |
594 | | static int |
595 | | dissect_forces_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
596 | 0 | { |
597 | 0 | dissect_forces(tvb, pinfo, tree, TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP); |
598 | 0 | return tvb_captured_length(tvb); |
599 | 0 | } |
600 | | |
601 | | /* Code to actually dissect the ForCES protocol layer packets,like UDP,SCTP and others */ |
602 | | static int |
603 | | dissect_forces_not_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
604 | 0 | { |
605 | 0 | dissect_forces(tvb, pinfo, tree, 0); |
606 | 0 | return tvb_captured_length(tvb); |
607 | 0 | } |
608 | | |
609 | | void |
610 | | proto_register_forces(void) |
611 | 14 | { |
612 | 14 | module_t *forces_module; |
613 | 14 | expert_module_t* expert_forces; |
614 | | |
615 | | /* Setup list of header fields See Section 1.6.1 for details*/ |
616 | 14 | static hf_register_info hf[] = { |
617 | 14 | { &hf_forces_version, |
618 | 14 | { "Version", "forces.flags.version", |
619 | 14 | FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL } |
620 | 14 | }, |
621 | 14 | { &hf_forces_rsvd, |
622 | 14 | { "Rsvd", "forces.flags.rsvd", |
623 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } |
624 | 14 | }, |
625 | 14 | { &hf_forces_messagetype, |
626 | 14 | { "Message Type", "forces.messagetype", |
627 | 14 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } |
628 | 14 | }, |
629 | 14 | { &hf_forces_length, |
630 | 14 | { "Header Length", "forces.length", |
631 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } |
632 | 14 | }, |
633 | 14 | { &hf_forces_sid, |
634 | 14 | { "Source ID", "forces.sid", |
635 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } |
636 | 14 | }, |
637 | 14 | { &hf_forces_did, |
638 | 14 | { "Destination ID", "forces.did", |
639 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } |
640 | 14 | }, |
641 | 14 | { &hf_forces_correlator, |
642 | 14 | { "Correlator", "forces.correlator", |
643 | 14 | FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } |
644 | 14 | }, |
645 | 14 | { &hf_forces_tlv_type, |
646 | 14 | { "Type", "forces.tlv.type", |
647 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } |
648 | 14 | }, |
649 | 14 | { &hf_forces_tlv_length, |
650 | 14 | { "Length", "forces.tlv.length", |
651 | 14 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL } |
652 | 14 | }, |
653 | | /*flags*/ |
654 | 14 | { &hf_forces_flags, |
655 | 14 | { "Flags", "forces.Flags", |
656 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } |
657 | 14 | }, |
658 | 14 | { &hf_forces_flags_ack, |
659 | 14 | { "ACK indicator", "forces.flags.ack", |
660 | 14 | FT_UINT32, BASE_DEC, VALS(main_header_flags_ack_vals), 0xC0000000, NULL, HFILL } |
661 | 14 | }, |
662 | 14 | { &hf_forces_flags_pri, |
663 | 14 | { "Priority", "forces.flags.pri", |
664 | 14 | FT_UINT32, BASE_DEC, NULL, 0x38000000, NULL, HFILL } |
665 | 14 | }, |
666 | 14 | { &hf_forces_flags_rsrvd, |
667 | 14 | { "Rsrvd", "forces.flags.rsrvd", |
668 | 14 | FT_UINT32, BASE_DEC,NULL, 0x07000000, NULL, HFILL } |
669 | 14 | }, |
670 | 14 | { &hf_forces_flags_em, |
671 | 14 | { "Execution mode", "forces.flags.em", |
672 | 14 | FT_UINT32, BASE_DEC, VALS(main_header_flags_em_vals), 0x00C00000, NULL, HFILL } |
673 | 14 | }, |
674 | 14 | { &hf_forces_flags_at, |
675 | 14 | { "Atomic Transaction", "forces.flags.at", |
676 | 14 | FT_UINT32, BASE_DEC, VALS(main_header_flags_at_vals), 0x00200000, NULL, HFILL } |
677 | 14 | }, |
678 | 14 | { &hf_forces_flags_tp, |
679 | 14 | { "Transaction phase", "forces.flags.tp", |
680 | 14 | FT_UINT32, BASE_DEC, VALS(main_header_flags_tp_vals), 0x00180000, NULL, HFILL } |
681 | 14 | }, |
682 | 14 | { &hf_forces_flags_reserved, |
683 | 14 | { "Reserved", "forces.flags.reserved", |
684 | 14 | FT_UINT32, BASE_DEC,NULL, 0x0007ffff, NULL, HFILL } |
685 | 14 | }, |
686 | | /*LFBSelectTLV*/ |
687 | 14 | { &hf_forces_lfbselect_tlv_type_lfb_classid, |
688 | 14 | { "Class ID", "forces.lfbselect.tlv.type.lfb.classid", |
689 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } |
690 | 14 | }, |
691 | 14 | { &hf_forces_lfbselect_tlv_type_lfb_instanceid, |
692 | 14 | { "Instance ID", "forces.fbselect.tlv.type.lfb.instanceid", |
693 | 14 | FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } |
694 | 14 | }, |
695 | | /*Operation TLV*/ |
696 | 14 | { &hf_forces_lfbselect_tlv_type_operation_type, |
697 | 14 | { "Type", "forces.lfbselect.tlv.type.operation.type", |
698 | 14 | FT_UINT16, BASE_DEC, VALS(operation_type_vals), 0x0, NULL, HFILL } |
699 | 14 | }, |
700 | 14 | { &hf_forces_lfbselect_tlv_type_operation_length, |
701 | 14 | { "Length", "forces.lfbselect.tlv.type.operation.length", |
702 | 14 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL } |
703 | 14 | }, |
704 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_type, |
705 | 14 | { "Type", "forces.lfbselect.tlv.type.operation.path.type", |
706 | 14 | FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL } |
707 | 14 | }, |
708 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_length, |
709 | 14 | { "Length", "forces.lfbselect.tlv.type.operation.path.length", |
710 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } |
711 | 14 | }, |
712 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_data, |
713 | 14 | { "Data", "forces.lfbselect.tlv.type.operation.path.data", |
714 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } |
715 | 14 | }, |
716 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_flags, |
717 | 14 | {"Path Data Flags", "forces.lfbselect.tlv.type.operation.path.data.flags", |
718 | 14 | FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } |
719 | 14 | }, |
720 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_flags_selector, |
721 | 14 | {"Selector", "forces.lfbselect.tlv.type.operation.path.data.flags.selector", |
722 | 14 | FT_UINT16, BASE_HEX, NULL, 0x80, NULL, HFILL } |
723 | 14 | }, |
724 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_flags_reserved, |
725 | 14 | {"Reserved", "forces.lfbselect.tlv.type.operation.path.data.flags.reserved", |
726 | 14 | FT_UINT16, BASE_HEX, NULL, 0x7F, NULL, HFILL } |
727 | 14 | }, |
728 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_IDcount, |
729 | 14 | { "Path Data IDcount", "forces.lfbselect.tlv.type.operation.path.data.IDcount", |
730 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } |
731 | 14 | }, |
732 | 14 | { &hf_forces_lfbselect_tlv_type_operation_path_IDs, |
733 | 14 | { "Path Data IDs", "forces.lfbselect.tlv.type.operation.path.data.IDs", |
734 | 14 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } |
735 | 14 | }, |
736 | | /*Meta data TLV*/ |
737 | 14 | {&hf_forces_redirect_tlv_meta_data_tlv_type, |
738 | 14 | { "Type", "forces.redirect.tlv.meta.data.tlv.type", |
739 | 14 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } |
740 | 14 | }, |
741 | 14 | { &hf_forces_redirect_tlv_meta_data_tlv_length, |
742 | 14 | { "Length", "forces.redirect.tlv.meta.data.tlv.length", |
743 | 14 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL } |
744 | 14 | }, |
745 | 14 | { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, |
746 | 14 | { "Meta Data ILV", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv", |
747 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } |
748 | 14 | }, |
749 | 14 | { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id, |
750 | 14 | { "ID", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.id", |
751 | 14 | FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL } |
752 | 14 | }, |
753 | 14 | { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length, |
754 | 14 | { "Length", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.length", |
755 | 14 | FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL } |
756 | 14 | }, |
757 | 14 | { &hf_forces_redirect_tlv_redirect_data_tlv_type, |
758 | 14 | { "Type", "forces.redirect.tlv.redirect.data.tlv.type", |
759 | 14 | FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL } |
760 | 14 | }, |
761 | 14 | { &hf_forces_redirect_tlv_redirect_data_tlv_length, |
762 | 14 | { "Length", "forces.redirect.tlv.redirect.data.tlv.length", |
763 | 14 | FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL } |
764 | 14 | }, |
765 | 14 | { &hf_forces_asresult_association_setup_result, |
766 | 14 | { "Association Setup Result", "forces.teardown.reason", |
767 | 14 | FT_UINT32, BASE_DEC, VALS(association_setup_result_at_vals), 0x0, NULL, HFILL } |
768 | 14 | }, |
769 | 14 | { &hf_forces_astreason_tlv_teardown_reason, |
770 | 14 | { "AStreason TLV TearDown Reason", "forces.astreason.tlv.teardown.reason", |
771 | 14 | FT_UINT32, BASE_DEC, VALS(teardown_reason_at_vals), 0x0, NULL, HFILL } |
772 | 14 | }, |
773 | 14 | { &hf_forces_unknown_tlv, |
774 | 14 | { "Data", "forces.unknown.tlv", |
775 | 14 | FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } |
776 | 14 | } |
777 | 14 | }; |
778 | | |
779 | | /* Setup protocol subtree array */ |
780 | 14 | static int *ett[] = { |
781 | 14 | &ett_forces, |
782 | 14 | &ett_forces_main_header, |
783 | 14 | &ett_forces_flags, |
784 | 14 | &ett_forces_tlv, |
785 | 14 | &ett_forces_lfbselect_tlv_type, |
786 | 14 | &ett_forces_lfbselect_tlv_type_operation, |
787 | 14 | &ett_forces_lfbselect_tlv_type_operation_path, |
788 | 14 | &ett_forces_lfbselect_tlv_type_operation_path_data, |
789 | 14 | &ett_forces_lfbselect_tlv_type_operation_path_data_path, |
790 | 14 | &ett_forces_lfbselect_tlv_type_operation_path_selector, |
791 | 14 | &ett_forces_path_data_tlv, |
792 | 14 | &ett_forces_path_data_tlv_flags, |
793 | 14 | &ett_forces_redirect_tlv_type, |
794 | 14 | &ett_forces_redirect_tlv_meta_data_tlv, |
795 | 14 | &ett_forces_redirect_tlv_redirect_data_tlv, |
796 | 14 | &ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, |
797 | 14 | &ett_forces_asresult_tlv, |
798 | 14 | &ett_forces_astreason_tlv, |
799 | 14 | &ett_forces_unknown_tlv |
800 | 14 | }; |
801 | | |
802 | 14 | static ei_register_info ei[] = { |
803 | 14 | { &ei_forces_length, { "forces.length.bad", PI_PROTOCOL, PI_WARN, "ForCES Header length is wrong", EXPFILL }}, |
804 | 14 | { &ei_forces_tlv_type, { "forces.tlv.type.unknown", PI_PROTOCOL, PI_WARN, "Bogus: The Main_TLV type is unknown", EXPFILL }}, |
805 | 14 | { &ei_forces_tlv_length, { "forces.tlv.length.bad", PI_PROTOCOL, PI_WARN, "Bogus TLV length", EXPFILL }}, |
806 | 14 | { &ei_forces_lfbselect_tlv_type_operation_path_length, { "forces.lfbselect.tlv.type.operation.path.length.bad", PI_PROTOCOL, PI_WARN, "Bogus TLV length", EXPFILL }}, |
807 | 14 | { &ei_forces_lfbselect_tlv_type_operation_type, { "forces.lfbselect.tlv.type.operation.type.unsupported", PI_PROTOCOL, PI_WARN, "ForCES Operation TLV is not supported", EXPFILL }}, |
808 | 14 | { &ei_forces_redirect_tlv_redirect_data_tlv_length, { "forces.redirect.tlv.redirect.data.tlv.length.bad", PI_PROTOCOL, PI_WARN, "Redirect Data TLV length is wrong", EXPFILL }}, |
809 | 14 | }; |
810 | | |
811 | | /* Register the protocol name and description */ |
812 | 14 | proto_forces = proto_register_protocol("Forwarding and Control Element Separation Protocol", "ForCES", "forces"); |
813 | | |
814 | | /* Required function calls to register the header fields and subtrees used */ |
815 | 14 | proto_register_field_array(proto_forces, hf, array_length(hf)); |
816 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
817 | 14 | expert_forces = expert_register_protocol(proto_forces); |
818 | 14 | expert_register_field_array(expert_forces, ei, array_length(ei)); |
819 | | |
820 | 14 | forces_handle_tcp = register_dissector("forces.tcp", dissect_forces_tcp, proto_forces); |
821 | 14 | forces_handle = register_dissector("forces", dissect_forces_not_tcp, proto_forces); |
822 | | |
823 | 14 | forces_module = prefs_register_protocol(proto_forces,proto_reg_handoff_forces); |
824 | | |
825 | 14 | prefs_register_uint_preference(forces_module, "sctp_high_prio_port", |
826 | 14 | "SCTP High Priority channel port", |
827 | 14 | "Decode packets on this sctp port as ForCES", |
828 | 14 | 10, &forces_alternate_sctp_high_prio_channel_port); |
829 | | |
830 | 14 | prefs_register_uint_preference(forces_module, "sctp_med_prio_port", |
831 | 14 | "SCTP Medium Priority channel port", |
832 | 14 | "Decode packets on this sctp port as ForCES", |
833 | 14 | 10, &forces_alternate_sctp_med_prio_channel_port); |
834 | | |
835 | 14 | prefs_register_uint_preference(forces_module, "sctp_low_prio_port", |
836 | 14 | "SCTP Low Priority channel port", |
837 | 14 | "Decode packets on this sctp port as ForCES", |
838 | 14 | 10, &forces_alternate_sctp_low_prio_channel_port); |
839 | 14 | } |
840 | | |
841 | | void |
842 | | proto_reg_handoff_forces(void) |
843 | 14 | { |
844 | 14 | static bool inited = false; |
845 | | |
846 | 14 | static unsigned alternate_sctp_high_prio_channel_port = 0; /* 6700 */ |
847 | 14 | static unsigned alternate_sctp_med_prio_channel_port = 0; |
848 | 14 | static unsigned alternate_sctp_low_prio_channel_port = 0; |
849 | | |
850 | 14 | if (!inited) { |
851 | 14 | ip_handle = find_dissector_add_dependency("ip", proto_forces); |
852 | | /* Register TCP port for dissection */ |
853 | 14 | dissector_add_for_decode_as_with_preference("tcp.port", forces_handle_tcp); |
854 | | /* Register UDP port for dissection */ |
855 | 14 | dissector_add_for_decode_as_with_preference("udp.port", forces_handle); |
856 | | |
857 | 14 | inited = true; |
858 | 14 | } |
859 | | |
860 | | /* Register SCTP port for high priority dissection */ |
861 | 14 | if ((alternate_sctp_high_prio_channel_port != 0) && |
862 | 0 | (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port)) |
863 | 0 | dissector_delete_uint("sctp.port", alternate_sctp_high_prio_channel_port, forces_handle); |
864 | 14 | if ((forces_alternate_sctp_high_prio_channel_port != 0) && |
865 | 0 | (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port)) |
866 | 0 | dissector_add_uint("sctp.port", forces_alternate_sctp_high_prio_channel_port, forces_handle); |
867 | 14 | alternate_sctp_high_prio_channel_port = forces_alternate_sctp_high_prio_channel_port; |
868 | | |
869 | | /* Register SCTP port for medium priority dissection */ |
870 | 14 | if ((alternate_sctp_med_prio_channel_port != 0) && |
871 | 0 | (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port)) |
872 | 0 | dissector_delete_uint("sctp.port", alternate_sctp_med_prio_channel_port, forces_handle); |
873 | 14 | if ((forces_alternate_sctp_med_prio_channel_port != 0) && |
874 | 0 | (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port)) |
875 | 0 | dissector_add_uint("sctp.port", forces_alternate_sctp_med_prio_channel_port, forces_handle); |
876 | 14 | alternate_sctp_med_prio_channel_port = forces_alternate_sctp_med_prio_channel_port; |
877 | | |
878 | | /* Register SCTP port for low priority dissection */ |
879 | 14 | if ((alternate_sctp_low_prio_channel_port != 0) && |
880 | 0 | (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port)) |
881 | 0 | dissector_delete_uint("sctp.port", alternate_sctp_low_prio_channel_port, forces_handle); |
882 | 14 | if ((forces_alternate_sctp_low_prio_channel_port != 0) && |
883 | 0 | (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port)) |
884 | 0 | dissector_add_uint("sctp.port", forces_alternate_sctp_low_prio_channel_port, forces_handle); |
885 | 14 | alternate_sctp_low_prio_channel_port = forces_alternate_sctp_low_prio_channel_port; |
886 | 14 | } |
887 | | |
888 | | /* |
889 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
890 | | * |
891 | | * Local variables: |
892 | | * c-basic-offset: 4 |
893 | | * tab-width: 8 |
894 | | * indent-tabs-mode: nil |
895 | | * End: |
896 | | * |
897 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
898 | | * :indentSize=4:tabSize=8:noTabs=true: |
899 | | */ |