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>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33 #include <epan/expert.h>
35 static dissector_handle_t ip_handle
;
37 /* Initialize the ForCES protocol and registered fields */
38 static int proto_forces
= -1;
41 static int hf_forces_version
= -1;
42 static int hf_forces_rsvd
= -1;
43 static int hf_forces_messagetype
= -1;
44 static int hf_forces_sid
= -1;
45 static int hf_forces_did
= -1;
46 static int hf_forces_correlator
= -1;
47 static int hf_forces_length
= -1;
49 static int hf_forces_flags
= -1;
50 static int hf_forces_flags_ack
= -1;
51 static int hf_forces_flags_pri
= -1;
52 static int hf_forces_flags_rsrvd
= -1;
53 static int hf_forces_flags_em
= -1;
54 static int hf_forces_flags_at
= -1;
55 static int hf_forces_flags_tp
= -1;
56 static int hf_forces_flags_reserved
= -1;
58 static int hf_forces_tlv_type
= -1;
59 static int hf_forces_tlv_length
= -1;
61 /*Initiation of LFBSelect TLV*/
62 static int hf_forces_lfbselect_tlv_type_lfb_classid
= -1;
63 static int hf_forces_lfbselect_tlv_type_lfb_instanceid
= -1;
65 /*Initiation of Operation TLV*/
66 static int hf_forces_lfbselect_tlv_type_operation_type
= -1;
67 static int hf_forces_lfbselect_tlv_type_operation_length
= -1;
68 static int hf_forces_lfbselect_tlv_type_operation_path_type
= -1;
69 static int hf_forces_lfbselect_tlv_type_operation_path_length
= -1;
70 static int hf_forces_lfbselect_tlv_type_operation_path_flags
= -1;
71 static int hf_forces_lfbselect_tlv_type_operation_path_flags_selector
= -1;
72 static int hf_forces_lfbselect_tlv_type_operation_path_flags_reserved
= -1;
73 static int hf_forces_lfbselect_tlv_type_operation_path_IDcount
= -1;
74 static int hf_forces_lfbselect_tlv_type_operation_path_IDs
= -1;
75 static int hf_forces_lfbselect_tlv_type_operation_path_data
= -1;
77 /*Initiation of Redirect TLV*/
78 static int hf_forces_redirect_tlv_meta_data_tlv_type
= -1;
79 static int hf_forces_redirect_tlv_meta_data_tlv_length
= -1;
80 static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
= -1;
81 static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id
= -1;
82 static int hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length
= -1;
83 static int hf_forces_redirect_tlv_redirect_data_tlv_type
= -1;
84 static int hf_forces_redirect_tlv_redirect_data_tlv_length
= -1;
86 /*Initiation of ASResult TLV*/
87 static int hf_forces_asresult_association_setup_result
= -1;
89 /*Initiation of ASTreason TLV*/
90 static int hf_forces_astreason_tlv_teardown_reason
= -1;
92 /*Main TLV may be unknown*/
93 static int hf_forces_unknown_tlv
= -1;
96 #define AssociationSetup 0x01
97 #define AssociationTeardown 0x02
100 #define EventNotification 0x05
101 #define PacketRedirect 0x06
102 #define Heartbeat 0x0F
103 #define AssociationSetupRepsonse 0x11
104 #define ConfigResponse 0x13
105 #define QueryResponse 0x14
108 #define Reserved 0x0000
109 #define REDIRECT_TLV 0x0001
110 #define ASResult_TLV 0x0010
111 #define ASTreason_TLV 0x0011
112 #define LFBselect_TLV 0x1000
113 #define PATH_DATA_TLV 0x0110
114 #define KEYINFO_TLV 0x0111
115 #define FULLDATA_TLV 0x0112
116 #define SPARSEDATA_TLV 0x0113
117 #define RESULT_TLV 0x0114
118 #define METADATA_TLV 0x0115
119 #define REDIRECTDATA_TLV 0x0116
122 #define Reserved 0x0000
124 #define SET_PROP 0x0002
125 #define SET_RESPONSE 0x0003
126 #define SET_PROP_RESPONSE 0x0004
128 #define DEL_RESPONSE 0x0006
130 #define GET_PROP 0x0008
131 #define GET_RESPONSE 0x0009
132 #define GET_PROP_RESPONSE 0x000A
133 #define REPORT 0x000B
134 #define COMMIT 0x000C
135 #define COMMIT_RESPONSE 0x000D
136 #define TRCOMP 0x000E
138 #define FLAG_SELECTOR 0x8000
140 #define ForCES_HEADER_LENGTH 24
141 #define TLV_TL_LENGTH 4 /*Type+length*/
142 #define MIN_IP_HEADER_LENGTH 20
144 /*For TCP+UDP TML. There are two bytes added to the ForCES PL message, not strictly combine to the ForCES protocol.
145 For other type TMLs,no need to add these 2 bytes.*/
146 #define TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP 2
149 static guint forces_alternate_tcp_port
= 0;
150 static guint forces_alternate_udp_port
= 0;
152 static guint forces_alternate_sctp_high_prio_channel_port
= 0;
153 static guint forces_alternate_sctp_med_prio_channel_port
= 0;
154 static guint forces_alternate_sctp_low_prio_channel_port
= 0;
156 /*Initialize the subtree pointers*/
157 static gint ett_forces
= -1;
158 static gint ett_forces_main_header
= -1;
159 static gint ett_forces_flags
= -1;
160 static gint ett_forces_tlv
= -1;
161 static gint ett_forces_lfbselect_tlv_type
= -1;
163 /*Operation TLV subtree*/
164 static gint ett_forces_lfbselect_tlv_type_operation
= -1;
165 static gint ett_forces_lfbselect_tlv_type_operation_path
= -1;
166 static gint ett_forces_lfbselect_tlv_type_operation_path_data
= -1;
167 static gint ett_forces_lfbselect_tlv_type_operation_path_data_path
= -1;
168 static gint ett_forces_path_data_tlv
= -1;
169 static gint ett_forces_path_data_tlv_flags
= -1;
172 static gint ett_forces_lfbselect_tlv_type_operation_path_selector
= -1;
174 /*Redirect TLV subtree*/
175 static gint ett_forces_redirect_tlv_type
= -1;
176 static gint ett_forces_redirect_tlv_meta_data_tlv
= -1;
177 static gint ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
= -1;
178 static gint ett_forces_redirect_tlv_redirect_data_tlv
= -1;
180 /*ASResult TLV subtree*/
181 static gint ett_forces_asresult_tlv
= -1;
184 static gint ett_forces_astreason_tlv
= -1;
186 /*Main_TLV unknown subtree*/
187 static gint ett_forces_unknown_tlv
= -1;
190 static expert_field ei_forces_length
= EI_INIT
;
191 static expert_field ei_forces_tlv_type
= EI_INIT
;
192 static expert_field ei_forces_tlv_length
= EI_INIT
;
193 static expert_field ei_forces_lfbselect_tlv_type_operation_path_length
= EI_INIT
;
194 static expert_field ei_forces_lfbselect_tlv_type_operation_type
= EI_INIT
;
195 static expert_field ei_forces_redirect_tlv_redirect_data_tlv_length
= EI_INIT
;
197 /*ACK values and the strings to be displayed*/
198 static const value_string main_header_flags_ack_vals
[] = {
200 { 0x1, "SuccessACK" },
201 { 0x2, "FailureACK" },
202 { 0x3, "AlwaysACK" },
206 /*Execution mode(EM) values and the strings to be displayed*/
207 static const value_string main_header_flags_em_vals
[] = {
209 { 0x1, "Execute-all-or-none" },
210 { 0x2, "Execute-until-failure" },
211 { 0x3, "Continue-execute-on-failure" },
215 /*Transaction Phase values and the strings to be displayed*/
216 static const value_string main_header_flags_tp_vals
[] = {
217 { 0x0, "SOT (Start of Transaction)" },
218 { 0x1, "MOT (Middle of Transaction)" },
219 { 0x2, "EOT (End of Transaction)" },
220 { 0x3, "ABT (Abort)" },
224 /*Atomic Transaction(AT) values and the strings to be displayed*/
225 static const value_string main_header_flags_at_vals
[] = {
226 { 0x0, "Stand-alone Message"},
227 { 0x1, "2PC Transaction Message"},
231 /*Association Setup Result*/
232 static const value_string association_setup_result_at_vals
[] = {
234 { 0x1, "FE ID invalid"},
235 { 0x2, "permission denied"},
240 static const value_string teardown_reason_at_vals
[] = {
241 { 0x0, "normal-teardown by administrator"},
242 { 0x1, "error - loss of heartbeats"},
243 { 0x2, "error - out of bandwidth"},
244 { 0x3, "error - out of memory"},
245 { 0x4, "error - application crash"},
246 { 0x255, "error - other or unspecified"},
250 static const value_string message_type_vals
[] = {
251 { AssociationSetup
, "AssociationSetup" },
252 { AssociationTeardown
, "AssociationTeardown" },
253 { Config
, "Config" },
255 { EventNotification
, "EventNotification" },
256 { PacketRedirect
, "PacketRedirect" },
257 { Heartbeat
, "Heartbeat" },
258 { AssociationSetupRepsonse
, "AssociationSetupRepsonse" },
259 { ConfigResponse
, "ConfigResponse" },
260 { QueryResponse
, "QueryResponse" },
264 static const value_string tlv_type_vals
[] = {
265 { REDIRECT_TLV
, "REDIRECT-TLV" },
266 { ASResult_TLV
, "ASResult-TLV" },
267 { ASTreason_TLV
, "ASTreason-TLV" },
268 { LFBselect_TLV
, "LFBselect-TLV" },
269 { PATH_DATA_TLV
, "PATH DATA-TLV" },
270 { KEYINFO_TLV
, "KEYINFO-TLV" },
271 { FULLDATA_TLV
, "FULLDATA-TLV" },
272 { SPARSEDATA_TLV
, "SPARSEDATA-TLV" },
273 { RESULT_TLV
, "RESULT-TLV" },
274 { METADATA_TLV
, "METADATA-TLV" },
275 { REDIRECTDATA_TLV
, "REDIRECTDATA-TLV" },
279 static const value_string operation_type_vals
[] = {
280 { Reserved
, "Reserved" },
282 { SET_PROP
, "SET-PROP" },
283 { SET_RESPONSE
, "SET-RESPONSE" },
284 { SET_PROP_RESPONSE
, "SET-PROP-RESPONSE" },
286 { DEL_RESPONSE
, "DEL-RESPONSE" },
288 { GET_PROP
, "GET-PROP" },
289 { GET_RESPONSE
, "GET-RESPONSE" },
290 { GET_PROP_RESPONSE
, "GET-PROP-RESPONSE" },
291 { REPORT
, "REPORT" },
292 { COMMIT
, "COMMIT" },
293 { COMMIT_RESPONSE
, "COMMIT-RESPONSE" },
294 { TRCOMP
, "TRCOMP" },
299 dissect_path_data_tlv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint offset
)
301 proto_item
*ti
, *flag_item
;
302 guint length_TLV
, IDcount
, i
;
304 proto_tree
*tlv_tree
, *path_data_tree
, *flag_tree
;
306 while (tvb_reported_length_remaining(tvb
, offset
) >= TLV_TL_LENGTH
)
308 ti
= proto_tree_add_text(tree
, tvb
, offset
, TLV_TL_LENGTH
, "TLV");
309 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_path_data_tlv
);
311 type
= tvb_get_ntohs(tvb
, offset
);
312 proto_tree_add_item(tlv_tree
, hf_forces_lfbselect_tlv_type_operation_path_type
,
313 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
314 length_TLV
= tvb_get_ntohs(tvb
, offset
+2);
315 proto_tree_add_item(tlv_tree
, hf_forces_lfbselect_tlv_type_operation_path_length
,
316 tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
317 if (length_TLV
< TLV_TL_LENGTH
)
319 expert_add_info_format(pinfo
, ti
, &ei_forces_lfbselect_tlv_type_operation_path_length
, "Bogus TLV length: %u", length_TLV
);
322 proto_item_set_len(ti
, length_TLV
);
324 if (type
== PATH_DATA_TLV
)
326 ti
= proto_tree_add_text(tree
, tvb
, offset
+TLV_TL_LENGTH
, length_TLV
-TLV_TL_LENGTH
, "Path Data TLV");
327 path_data_tree
= proto_item_add_subtree(ti
, ett_forces_path_data_tlv
);
329 flag
= tvb_get_ntohs(tvb
, offset
+TLV_TL_LENGTH
);
330 flag_item
= proto_tree_add_item(path_data_tree
, hf_forces_lfbselect_tlv_type_operation_path_flags
,
331 tvb
, offset
+TLV_TL_LENGTH
, 2, ENC_BIG_ENDIAN
);
332 flag_tree
= proto_item_add_subtree(flag_item
, ett_forces_path_data_tlv_flags
);
333 proto_tree_add_item(flag_tree
, hf_forces_lfbselect_tlv_type_operation_path_flags_selector
,
334 tvb
, offset
+TLV_TL_LENGTH
, 2, ENC_BIG_ENDIAN
);
335 proto_tree_add_item(flag_tree
, hf_forces_lfbselect_tlv_type_operation_path_flags_reserved
,
336 tvb
, offset
+TLV_TL_LENGTH
, 2, ENC_BIG_ENDIAN
);
338 IDcount
= tvb_get_ntohs(tvb
, offset
+ TLV_TL_LENGTH
+ 2);
339 proto_tree_add_item(path_data_tree
, hf_forces_lfbselect_tlv_type_operation_path_IDcount
,
340 tvb
, offset
+TLV_TL_LENGTH
+2, 2, ENC_BIG_ENDIAN
);
342 for (i
= 0; i
< IDcount
; i
++)
343 proto_tree_add_item(path_data_tree
, hf_forces_lfbselect_tlv_type_operation_path_IDs
,
344 tvb
, offset
+TLV_TL_LENGTH
+2+(i
*4), 4, ENC_BIG_ENDIAN
);
349 proto_tree_add_item(tree
, hf_forces_lfbselect_tlv_type_operation_path_data
,
350 tvb
, offset
+TLV_TL_LENGTH
, length_TLV
-TLV_TL_LENGTH
, ENC_NA
);
353 if ((flag
& FLAG_SELECTOR
) == 0)
356 offset
+= length_TLV
;
361 dissect_operation_tlv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint offset
, gint length_count
)
364 proto_tree
*oper_tree
;
367 while (tvb_reported_length_remaining(tvb
, offset
) >= TLV_TL_LENGTH
)
369 ti
= proto_tree_add_text(tree
, tvb
, offset
, length_count
, "Operation TLV");
370 oper_tree
= proto_item_add_subtree(ti
, ett_forces_lfbselect_tlv_type_operation
);
372 type
= tvb_get_ntohs(tvb
,offset
);
373 ti
= proto_tree_add_item(oper_tree
, hf_forces_lfbselect_tlv_type_operation_type
,
374 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
375 if (try_val_to_str(type
, operation_type_vals
) == NULL
)
376 expert_add_info_format(pinfo
, ti
, &ei_forces_lfbselect_tlv_type_operation_type
,
377 "Bogus: ForCES Operation TLV (Type:0x%04x) is not supported", type
);
379 length
= tvb_get_ntohs(tvb
, offset
+2);
380 proto_tree_add_uint_format_value(oper_tree
, hf_forces_lfbselect_tlv_type_operation_length
,
381 tvb
, offset
+2, 2, length
, "%u Bytes", length
);
383 dissect_path_data_tlv(tvb
, pinfo
, oper_tree
, offset
+TLV_TL_LENGTH
);
391 dissect_lfbselecttlv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint offset
, gint length_count
)
395 proto_tree_add_item(tree
, hf_forces_lfbselect_tlv_type_lfb_classid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
396 proto_tree_add_item(tree
, hf_forces_lfbselect_tlv_type_lfb_instanceid
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
399 while ((tvb_reported_length_remaining(tvb
, offset
) > TLV_TL_LENGTH
) && (length_count
> 12))
401 tlv_length
= tvb_get_ntohs(tvb
, offset
+2);
402 dissect_operation_tlv(tvb
, pinfo
, tree
, offset
, tlv_length
);
405 offset
+= tlv_length
;
410 dissect_redirecttlv(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gint offset
)
412 proto_tree
*meta_data_tree
, *meta_data_ilv_tree
, *redirect_data_tree
;
414 gint length_meta
, length_ilv
, length_redirect
;
416 address src_addr
= pinfo
->src
,
417 src_net_addr
= pinfo
->net_src
,
418 dst_addr
= pinfo
->dst
,
419 dst_net_addr
= pinfo
->net_dst
;
421 ti
= proto_tree_add_text(tree
, tvb
, offset
, TLV_TL_LENGTH
, "Meta Data TLV");
422 meta_data_tree
= proto_item_add_subtree(ti
, ett_forces_redirect_tlv_meta_data_tlv
);
423 proto_tree_add_item(meta_data_tree
, hf_forces_redirect_tlv_meta_data_tlv_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
425 length_meta
= tvb_get_ntohs(tvb
, offset
+2);
426 proto_tree_add_uint_format_value(meta_data_tree
, hf_forces_redirect_tlv_meta_data_tlv_length
, tvb
, offset
+2, 2,
427 length_meta
, "%u Bytes", length_meta
);
428 proto_item_set_len(ti
, length_meta
);
430 start_offset
= offset
;
431 while ((tvb_reported_length_remaining(tvb
, offset
) >= 8) && (start_offset
+length_meta
> offset
))
433 ti
= proto_tree_add_text(tree
, tvb
, offset
, TLV_TL_LENGTH
, "Meta Data ILV");
434 meta_data_ilv_tree
= proto_item_add_subtree(ti
, ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
);
436 proto_tree_add_item(meta_data_ilv_tree
, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id
,
437 tvb
, offset
+8, 4, ENC_BIG_ENDIAN
);
438 length_ilv
= tvb_get_ntohl(tvb
, offset
+12);
439 proto_tree_add_uint_format_value(meta_data_ilv_tree
, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length
,
440 tvb
, offset
+12, 4, length_ilv
, "%u Bytes", length_ilv
);
442 proto_tree_add_item(meta_data_ilv_tree
, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
,
443 tvb
, offset
+8, length_ilv
, ENC_NA
);
445 proto_item_set_len(ti
, length_ilv
+ 8);
446 offset
+= length_ilv
+ 8;
449 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
451 ti
= proto_tree_add_text(tree
, tvb
, offset
, TLV_TL_LENGTH
, "Redirect Data TLV");
452 redirect_data_tree
= proto_item_add_subtree(ti
, ett_forces_redirect_tlv_redirect_data_tlv
);
454 proto_tree_add_item(redirect_data_tree
, hf_forces_redirect_tlv_redirect_data_tlv_type
,
455 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
456 length_redirect
= tvb_get_ntohs(tvb
, offset
+2);
457 proto_tree_add_uint_format_value(redirect_data_tree
, hf_forces_redirect_tlv_redirect_data_tlv_length
,
458 tvb
, offset
+2, 2, length_redirect
, "%u Bytes", length_redirect
);
460 if (tvb_reported_length_remaining(tvb
, offset
) < length_redirect
)
462 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
);
464 else if (length_redirect
< TLV_TL_LENGTH
+ MIN_IP_HEADER_LENGTH
)
466 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
);
472 next_tvb
= tvb_new_subset(tvb
, offset
+4, length_redirect
-TLV_TL_LENGTH
, length_redirect
-TLV_TL_LENGTH
);
473 call_dissector(ip_handle
, next_tvb
, pinfo
, redirect_data_tree
);
475 /* Restore IP info */
476 memcpy(&(pinfo
->src
), &src_addr
, sizeof(address
));
477 memcpy(&(pinfo
->net_src
), &src_net_addr
, sizeof(address
));
478 memcpy(&(pinfo
->dst
), &dst_addr
, sizeof(address
));
479 memcpy(&(pinfo
->net_dst
), &dst_net_addr
, sizeof(address
));
485 dissect_forces(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint32 offset
)
487 /* Set up structures needed to add the protocol subtree and manage it */
488 proto_item
*ti
, *tlv_item
;
489 proto_tree
*forces_tree
, *forces_flags_tree
;
490 proto_tree
*forces_main_header_tree
, *forces_tlv_tree
, *tlv_tree
;
496 /* Make entries in Protocol column and Info column on summary display */
497 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ForCES");
498 col_clear(pinfo
->cinfo
, COL_INFO
);
500 ti
= proto_tree_add_item(tree
, proto_forces
, tvb
, 0, -1, ENC_NA
);
501 forces_tree
= proto_item_add_subtree(ti
, ett_forces
);
503 ti
= proto_tree_add_text(forces_tree
, tvb
, 0, ForCES_HEADER_LENGTH
, "Common Header");
504 forces_main_header_tree
= proto_item_add_subtree(ti
, ett_forces_main_header
);
506 proto_tree_add_item(forces_main_header_tree
, hf_forces_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
507 proto_tree_add_item(forces_main_header_tree
, hf_forces_rsvd
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
509 message_type
= tvb_get_guint8(tvb
, offset
+1);
510 proto_tree_add_item( forces_main_header_tree
, hf_forces_messagetype
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
512 length_count
= tvb_get_ntohs(tvb
, offset
+2) * 4; /*multiply 4 DWORD*/
513 ti
= proto_tree_add_uint_format( forces_main_header_tree
, hf_forces_length
,
514 tvb
, offset
+2, 2, length_count
, "Length: %u Bytes", length_count
);
515 if (length_count
!= tvb_reported_length_remaining(tvb
, offset
))
516 expert_add_info_format(pinfo
, ti
, &ei_forces_length
, "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)",
517 length_count
, tvb_reported_length_remaining(tvb
, offset
));
518 if (length_count
< 24)
519 expert_add_info_format(pinfo
, ti
, &ei_forces_length
, "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count
);
521 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Message Type: %s, Total Length: %u Bytes",
522 val_to_str(message_type
, message_type_vals
, "Unknown messagetype 0x%x"), length_count
);
524 proto_tree_add_item( forces_main_header_tree
, hf_forces_sid
, tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
525 proto_tree_add_item( forces_main_header_tree
, hf_forces_did
, tvb
, offset
+8, 4, ENC_BIG_ENDIAN
);
526 proto_tree_add_item( forces_main_header_tree
, hf_forces_correlator
, tvb
, offset
+12, 8, ENC_BIG_ENDIAN
);
529 ti
= proto_tree_add_item(forces_main_header_tree
, hf_forces_flags
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
530 forces_flags_tree
= proto_item_add_subtree(ti
, ett_forces_flags
);
532 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_ack
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
533 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_at
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
534 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_em
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
535 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_pri
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
536 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_reserved
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
537 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_rsrvd
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
538 proto_tree_add_item(forces_flags_tree
, hf_forces_flags_tp
, tvb
, offset
+20, 4, ENC_BIG_ENDIAN
);
541 while (tvb_reported_length_remaining(tvb
, offset
) >= TLV_TL_LENGTH
)
543 ti
= proto_tree_add_text(forces_tree
, tvb
, offset
, TLV_TL_LENGTH
, "TLV");
544 forces_tlv_tree
= proto_item_add_subtree(ti
, ett_forces_tlv
);
546 tlv_type
= tvb_get_ntohs(tvb
, offset
);
547 tlv_item
= proto_tree_add_item(forces_tlv_tree
, hf_forces_tlv_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
548 length_count
= tvb_get_ntohs(tvb
, offset
+2) * 4;
549 proto_item_set_len(ti
, length_count
);
550 ti
= proto_tree_add_uint_format_value(forces_tlv_tree
, hf_forces_tlv_length
,
551 tvb
, offset
+2, 2, length_count
, "%u Bytes", length_count
);
552 if (tvb_reported_length_remaining(tvb
, offset
) < length_count
)
553 expert_add_info_format(pinfo
, ti
, &ei_forces_tlv_length
, "Bogus: Main TLV length (%u bytes) is wrong", length_count
);
555 if (length_count
< TLV_TL_LENGTH
)
557 expert_add_info_format(pinfo
, ti
, &ei_forces_tlv_length
, "Bogus TLV length: %u", length_count
);
561 offset
+= TLV_TL_LENGTH
;
562 length_count
-= TLV_TL_LENGTH
;
567 ti
= proto_tree_add_text(forces_tlv_tree
, tvb
, offset
, length_count
, "LFB select TLV");
568 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_lfbselect_tlv_type
);
569 dissect_lfbselecttlv(tvb
, pinfo
, tlv_tree
, offset
, length_count
);
573 ti
= proto_tree_add_text(forces_tlv_tree
, tvb
, offset
, length_count
, "Redirect TLV");
574 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_redirect_tlv_type
);
575 dissect_redirecttlv(tvb
, pinfo
, tlv_tree
, offset
);
579 ti
= proto_tree_add_text(forces_tlv_tree
, tvb
, offset
, length_count
, "ASResult TLV");
580 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_asresult_tlv
);
581 proto_tree_add_item(tlv_tree
, hf_forces_asresult_association_setup_result
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
585 ti
= proto_tree_add_text(forces_tlv_tree
, tvb
, offset
, length_count
, "ASTreason TLV");
586 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_astreason_tlv
);
587 proto_tree_add_item(tlv_tree
, hf_forces_astreason_tlv_teardown_reason
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
591 expert_add_info(pinfo
, tlv_item
, &ei_forces_tlv_type
);
592 ti
= proto_tree_add_text(forces_tlv_tree
, tvb
, offset
, length_count
, "Unknown TLV");
593 tlv_tree
= proto_item_add_subtree(ti
, ett_forces_unknown_tlv
);
594 proto_tree_add_item(tlv_tree
, hf_forces_unknown_tlv
, tvb
, offset
, length_count
, ENC_NA
);
598 offset
+= length_count
;
602 /* Code to actually dissect the TCP packets */
604 dissect_forces_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
606 dissect_forces(tvb
, pinfo
, tree
, TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP
);
609 /* Code to actually dissect the ForCES protocol layer packets,like UDP,SCTP and others */
611 dissect_forces_not_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
613 dissect_forces(tvb
, pinfo
, tree
, 0);
616 void proto_reg_handoff_forces(void);
619 proto_register_forces(void)
621 module_t
*forces_module
;
622 expert_module_t
* expert_forces
;
624 /* Setup list of header fields See Section 1.6.1 for details*/
625 static hf_register_info hf
[] = {
626 { &hf_forces_version
,
627 { "Version", "forces.flags.version",
628 FT_UINT8
, BASE_DEC
, NULL
, 0xF0, NULL
, HFILL
}
631 { "Rsvd", "forces.flags.rsvd",
632 FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}
634 { &hf_forces_messagetype
,
635 { "Message Type", "forces.messagetype",
636 FT_UINT8
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
639 { "Header Length", "forces.length",
640 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
643 { "Source ID", "forces.sid",
644 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
647 { "Destination ID", "forces.did",
648 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
650 { &hf_forces_correlator
,
651 { "Correlator", "forces.correlator",
652 FT_UINT64
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
654 { &hf_forces_tlv_type
,
655 { "Type", "forces.tlv.type",
656 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
658 { &hf_forces_tlv_length
,
659 { "Length", "forces.tlv.length",
660 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
664 { "Flags", "forces.Flags",
665 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
667 { &hf_forces_flags_ack
,
668 { "ACK indicator", "forces.flags.ack",
669 FT_UINT32
, BASE_DEC
, VALS(main_header_flags_ack_vals
), 0xC0000000, NULL
, HFILL
}
671 { &hf_forces_flags_pri
,
672 { "Priority", "forces.flags.pri",
673 FT_UINT32
, BASE_DEC
, NULL
, 0x38000000, NULL
, HFILL
}
675 { &hf_forces_flags_rsrvd
,
676 { "Rsrvd", "forces.Flags",
677 FT_UINT32
, BASE_DEC
,NULL
, 0x07000000, NULL
, HFILL
}
679 { &hf_forces_flags_em
,
680 { "Execution mode", "forces.flags.em",
681 FT_UINT32
, BASE_DEC
, VALS(main_header_flags_em_vals
), 0x00C00000, NULL
, HFILL
}
683 { &hf_forces_flags_at
,
684 { "Atomic Transaction", "forces.flags.at",
685 FT_UINT32
, BASE_DEC
, VALS(main_header_flags_at_vals
), 0x00200000, NULL
, HFILL
}
687 { &hf_forces_flags_tp
,
688 { "Transaction phase", "forces.flags.tp",
689 FT_UINT32
, BASE_DEC
, VALS(main_header_flags_tp_vals
), 0x00180000, NULL
, HFILL
}
691 { &hf_forces_flags_reserved
,
692 { "Reserved", "forces.flags.reserved",
693 FT_UINT32
, BASE_DEC
,NULL
, 0x0007ffff, NULL
, HFILL
}
696 { &hf_forces_lfbselect_tlv_type_lfb_classid
,
697 { "Class ID", "forces.lfbselect.tlv.type.lfb.classid",
698 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
700 { &hf_forces_lfbselect_tlv_type_lfb_instanceid
,
701 { "Instance ID", "forces.fbselect.tlv.type.lfb.instanceid",
702 FT_IPv4
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
705 { &hf_forces_lfbselect_tlv_type_operation_type
,
706 { "Type", "forces.lfbselect.tlv.type.operation.type",
707 FT_UINT16
, BASE_DEC
, VALS(operation_type_vals
), 0x0, NULL
, HFILL
}
709 { &hf_forces_lfbselect_tlv_type_operation_length
,
710 { "Length", "forces.lfbselect.tlv.type.operation.length",
711 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
713 { &hf_forces_lfbselect_tlv_type_operation_path_type
,
714 { "Type", "forces.lfbselect.tlv.type.operation.path.type",
715 FT_UINT16
, BASE_DEC
, VALS(tlv_type_vals
), 0x0, NULL
, HFILL
}
717 { &hf_forces_lfbselect_tlv_type_operation_path_length
,
718 { "Length", "forces.lfbselect.tlv.type.operation.path.length",
719 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
721 { &hf_forces_lfbselect_tlv_type_operation_path_data
,
722 { "Data", "forces.lfbselect.tlv.type.operation.path.data",
723 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
725 { &hf_forces_lfbselect_tlv_type_operation_path_flags
,
726 {"Path Data Flags", "forces.lfbselect.tlv.type.operation.path.data.flags",
727 FT_UINT16
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
729 { &hf_forces_lfbselect_tlv_type_operation_path_flags_selector
,
730 {"Selector", "forces.lfbselect.tlv.type.operation.path.data.flags.selector",
731 FT_UINT16
, BASE_HEX
, NULL
, 0x80, NULL
, HFILL
}
733 { &hf_forces_lfbselect_tlv_type_operation_path_flags_reserved
,
734 {"Reserved", "forces.lfbselect.tlv.type.operation.path.data.flags.reserved",
735 FT_UINT16
, BASE_HEX
, NULL
, 0x7F, NULL
, HFILL
}
737 { &hf_forces_lfbselect_tlv_type_operation_path_IDcount
,
738 { "Path Data IDcount", "forces.lfbselect.tlv.type.operation.path.data.IDcount",
739 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
741 { &hf_forces_lfbselect_tlv_type_operation_path_IDs
,
742 { "Path Data IDs", "forces.lfbselect.tlv.type.operation.path.data.IDs",
743 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
746 {&hf_forces_redirect_tlv_meta_data_tlv_type
,
747 { "Type", "forces.redirect.tlv.meta.data.tlv.type",
748 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
750 { &hf_forces_redirect_tlv_meta_data_tlv_length
,
751 { "Length", "forces.redirect.tlv.meta.data.tlv.length",
752 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
754 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
,
755 { "Meta Data ILV", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv",
756 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
758 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id
,
759 { "ID", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.id",
760 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0, NULL
, HFILL
}
762 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length
,
763 { "Length", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.length",
764 FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
766 { &hf_forces_redirect_tlv_redirect_data_tlv_type
,
767 { "Type", "forces.redirect.tlv.redirect.data.tlv.type",
768 FT_UINT16
, BASE_DEC
, VALS(tlv_type_vals
), 0x0, NULL
, HFILL
}
770 { &hf_forces_redirect_tlv_redirect_data_tlv_length
,
771 { "Length", "forces.redirect.tlv.redirect.data.tlv.length",
772 FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
774 { &hf_forces_asresult_association_setup_result
,
775 { "Association Setup Result", "forces.teardown.reason",
776 FT_UINT32
, BASE_DEC
, VALS(association_setup_result_at_vals
), 0x0, NULL
, HFILL
}
778 { &hf_forces_astreason_tlv_teardown_reason
,
779 { "AStreason TLV TearDonw Reason", "forces.astreason.tlv.teardonw.reason",
780 FT_UINT32
, BASE_DEC
, VALS(teardown_reason_at_vals
), 0x0, NULL
, HFILL
}
782 { &hf_forces_unknown_tlv
,
783 { "Data", "forces.unknown.tlv",
784 FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
788 /* Setup protocol subtree array */
789 static gint
*ett
[] = {
791 &ett_forces_main_header
,
794 &ett_forces_lfbselect_tlv_type
,
795 &ett_forces_lfbselect_tlv_type_operation
,
796 &ett_forces_lfbselect_tlv_type_operation_path
,
797 &ett_forces_lfbselect_tlv_type_operation_path_data
,
798 &ett_forces_lfbselect_tlv_type_operation_path_data_path
,
799 &ett_forces_lfbselect_tlv_type_operation_path_selector
,
800 &ett_forces_path_data_tlv
,
801 &ett_forces_path_data_tlv_flags
,
802 &ett_forces_redirect_tlv_type
,
803 &ett_forces_redirect_tlv_meta_data_tlv
,
804 &ett_forces_redirect_tlv_redirect_data_tlv
,
805 &ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv
,
806 &ett_forces_asresult_tlv
,
807 &ett_forces_astreason_tlv
,
808 &ett_forces_unknown_tlv
811 static ei_register_info ei
[] = {
812 { &ei_forces_length
, { "forces.length.bad", PI_PROTOCOL
, PI_WARN
, "ForCES Header length is wrong", EXPFILL
}},
813 { &ei_forces_tlv_type
, { "forces.tlv.type.unknown", PI_PROTOCOL
, PI_WARN
, "Bogus: The Main_TLV type is unknown", EXPFILL
}},
814 { &ei_forces_tlv_length
, { "forces.tlv.length.bad", PI_PROTOCOL
, PI_WARN
, "Bogus TLV length", EXPFILL
}},
815 { &ei_forces_lfbselect_tlv_type_operation_path_length
, { "forces.lfbselect.tlv.type.operation.path.length.bad", PI_PROTOCOL
, PI_WARN
, "Bogus TLV length", EXPFILL
}},
816 { &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
}},
817 { &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
}},
820 /* Register the protocol name and description */
821 proto_forces
= proto_register_protocol("Forwarding and Control Element Separation Protocol", "ForCES", "forces");
823 /* Required function calls to register the header fields and subtrees used */
824 proto_register_field_array(proto_forces
, hf
, array_length(hf
));
825 proto_register_subtree_array(ett
, array_length(ett
));
826 expert_forces
= expert_register_protocol(proto_forces
);
827 expert_register_field_array(expert_forces
, ei
, array_length(ei
));
829 forces_module
= prefs_register_protocol(proto_forces
,proto_reg_handoff_forces
);
831 prefs_register_uint_preference(forces_module
, "tcp_alternate_port",
833 "Decode packets on this TCP port as ForCES",
834 10, &forces_alternate_tcp_port
);
836 prefs_register_uint_preference(forces_module
, "udp_alternate_port",
838 "Decode packets on this UDP port as ForCES",
839 10, &forces_alternate_udp_port
);
841 prefs_register_uint_preference(forces_module
, "sctp_high_prio_port",
842 "SCTP High Priority channel port",
843 "Decode packets on this sctp port as ForCES",
844 10, &forces_alternate_sctp_high_prio_channel_port
);
846 prefs_register_uint_preference(forces_module
, "sctp_med_prio_port",
847 "SCTP Meidium Priority channel port",
848 "Decode packets on this sctp port as ForCES",
849 10, &forces_alternate_sctp_med_prio_channel_port
);
851 prefs_register_uint_preference(forces_module
, "sctp_low_prio_port",
852 "SCTP Low Priority channel port",
853 "Decode packets on this sctp port as ForCES",
854 10, &forces_alternate_sctp_low_prio_channel_port
);
858 proto_reg_handoff_forces(void)
860 static gboolean inited
= FALSE
;
862 static guint alternate_tcp_port
= 0; /* 3000 */
863 static guint alternate_udp_port
= 0;
864 static guint alternate_sctp_high_prio_channel_port
= 0; /* 6700 */
865 static guint alternate_sctp_med_prio_channel_port
= 0;
866 static guint alternate_sctp_low_prio_channel_port
= 0;
868 static dissector_handle_t forces_handle_tcp
, forces_handle
;
871 forces_handle_tcp
= create_dissector_handle(dissect_forces_tcp
, proto_forces
);
872 forces_handle
= create_dissector_handle(dissect_forces_not_tcp
, proto_forces
);
873 ip_handle
= find_dissector("ip");
877 /* Register TCP port for dissection */
878 if ((alternate_tcp_port
!= 0) && (alternate_tcp_port
!= forces_alternate_tcp_port
))
879 dissector_delete_uint("tcp.port", alternate_tcp_port
, forces_handle_tcp
);
880 if ((forces_alternate_tcp_port
!= 0) && (alternate_tcp_port
!= forces_alternate_tcp_port
))
881 dissector_add_uint("tcp.port", forces_alternate_tcp_port
, forces_handle_tcp
);
882 alternate_tcp_port
= forces_alternate_tcp_port
;
884 /* Register UDP port for dissection */
885 if ((alternate_udp_port
!= 0) && (alternate_udp_port
!= forces_alternate_udp_port
))
886 dissector_delete_uint("udp.port", alternate_udp_port
, forces_handle
);
887 if ((forces_alternate_udp_port
!= 0) && (alternate_udp_port
!= forces_alternate_udp_port
))
888 dissector_add_uint("udp.port", forces_alternate_udp_port
, forces_handle
);
889 alternate_udp_port
= forces_alternate_udp_port
;
891 /* Register SCTP port for high priority dissection */
892 if ((alternate_sctp_high_prio_channel_port
!= 0) &&
893 (alternate_sctp_high_prio_channel_port
!= forces_alternate_sctp_high_prio_channel_port
))
894 dissector_delete_uint("sctp.port", alternate_sctp_high_prio_channel_port
, forces_handle
);
895 if ((forces_alternate_sctp_high_prio_channel_port
!= 0) &&
896 (alternate_sctp_high_prio_channel_port
!= forces_alternate_sctp_high_prio_channel_port
))
897 dissector_add_uint("sctp.port", forces_alternate_sctp_high_prio_channel_port
, forces_handle
);
898 alternate_sctp_high_prio_channel_port
= forces_alternate_sctp_high_prio_channel_port
;
900 /* Register SCTP port for medium priority dissection */
901 if ((alternate_sctp_med_prio_channel_port
!= 0) &&
902 (alternate_sctp_med_prio_channel_port
!= forces_alternate_sctp_med_prio_channel_port
))
903 dissector_delete_uint("udp.port", alternate_sctp_med_prio_channel_port
, forces_handle
);
904 if ((forces_alternate_sctp_med_prio_channel_port
!= 0) &&
905 (alternate_sctp_med_prio_channel_port
!= forces_alternate_sctp_med_prio_channel_port
))
906 dissector_add_uint("udp.port", forces_alternate_sctp_med_prio_channel_port
, forces_handle
);
907 alternate_sctp_med_prio_channel_port
= forces_alternate_sctp_med_prio_channel_port
;
909 /* Register SCTP port for low priority dissection */
910 if ((alternate_sctp_low_prio_channel_port
!= 0) &&
911 (alternate_sctp_low_prio_channel_port
!= forces_alternate_sctp_low_prio_channel_port
))
912 dissector_delete_uint("udp.port", alternate_sctp_low_prio_channel_port
, forces_handle
);
913 if ((forces_alternate_sctp_low_prio_channel_port
!= 0) &&
914 (alternate_sctp_low_prio_channel_port
!= forces_alternate_sctp_low_prio_channel_port
))
915 dissector_add_uint("udp.port", forces_alternate_sctp_low_prio_channel_port
, forces_handle
);
916 alternate_sctp_low_prio_channel_port
= forces_alternate_sctp_low_prio_channel_port
;
920 * Editor modelines - http://www.wireshark.org/tools/modelines.html
925 * indent-tabs-mode: nil
928 * vi: set shiftwidth=4 tabstop=8 expandtab:
929 * :indentSize=4:tabSize=8:noTabs=true: