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;
189 /*ACK values and the strings to be displayed*/
190 static const value_string main_header_flags_ack_vals[] = {
192 { 0x1, "SuccessACK" },
193 { 0x2, "FailureACK" },
194 { 0x3, "AlwaysACK" },
198 /*Execution mode(EM) values and the strings to be displayed*/
199 static const value_string main_header_flags_em_vals[] = {
201 { 0x1, "Execute-all-or-none" },
202 { 0x2, "Execute-until-failure" },
203 { 0x3, "Continue-execute-on-failure" },
207 /*Transaction Phase values and the strings to be displayed*/
208 static const value_string main_header_flags_tp_vals[] = {
209 { 0x0, "SOT (Start of Transaction)" },
210 { 0x1, "MOT (Middle of Transaction)" },
211 { 0x2, "EOT (End of Transaction)" },
212 { 0x3, "ABT (Abort)" },
216 /*Atomic Transaction(AT) values and the strings to be displayed*/
217 static const value_string main_header_flags_at_vals[] = {
218 { 0x0, "Stand-alone Message"},
219 { 0x1, "2PC Transaction Message"},
223 /*Association Setup Result*/
224 static const value_string association_setup_result_at_vals[] = {
226 { 0x1, "FE ID invalid"},
227 { 0x2, "permission denied"},
232 static const value_string teardown_reason_at_vals[] = {
233 { 0x0, "normal-teardown by administrator"},
234 { 0x1, "error - loss of heartbeats"},
235 { 0x2, "error - out of bandwidth"},
236 { 0x3, "error - out of memory"},
237 { 0x4, "error - application crash"},
238 { 0x255, "error - other or unspecified"},
242 static const value_string message_type_vals[] = {
243 { AssociationSetup, "AssociationSetup" },
244 { AssociationTeardown, "AssociationTeardown" },
245 { Config, "Config" },
247 { EventNotification, "EventNotification" },
248 { PacketRedirect, "PacketRedirect" },
249 { Heartbeat, "Heartbeat" },
250 { AssociationSetupRepsonse, "AssociationSetupRepsonse" },
251 { ConfigResponse, "ConfigResponse" },
252 { QueryResponse, "QueryResponse" },
256 static const value_string tlv_type_vals[] = {
257 { REDIRECT_TLV, "REDIRECT-TLV" },
258 { ASResult_TLV, "ASResult-TLV" },
259 { ASTreason_TLV, "ASTreason-TLV" },
260 { LFBselect_TLV, "LFBselect-TLV" },
261 { PATH_DATA_TLV, "PATH DATA-TLV" },
262 { KEYINFO_TLV, "KEYINFO-TLV" },
263 { FULLDATA_TLV, "FULLDATA-TLV" },
264 { SPARSEDATA_TLV, "SPARSEDATA-TLV" },
265 { RESULT_TLV, "RESULT-TLV" },
266 { METADATA_TLV, "METADATA-TLV" },
267 { REDIRECTDATA_TLV, "REDIRECTDATA-TLV" },
271 static const value_string operation_type_vals[] = {
272 { Reserved, "Reserved" },
274 { SET_PROP, "SET-PROP" },
275 { SET_RESPONSE, "SET-RESPONSE" },
276 { SET_PROP_RESPONSE, "SET-PROP-RESPONSE" },
278 { DEL_RESPONSE, "DEL-RESPONSE" },
280 { GET_PROP, "GET-PROP" },
281 { GET_RESPONSE, "GET-RESPONSE" },
282 { GET_PROP_RESPONSE, "GET-PROP-RESPONSE" },
283 { REPORT, "REPORT" },
284 { COMMIT, "COMMIT" },
285 { COMMIT_RESPONSE, "COMMIT-RESPONSE" },
286 { TRCOMP, "TRCOMP" },
291 dissect_path_data_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
293 proto_item *ti, *flag_item;
294 guint length_TLV, IDcount, i;
296 proto_tree *tlv_tree, *path_data_tree, *flag_tree;
298 while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
300 ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "TLV");
301 tlv_tree = proto_item_add_subtree(ti, ett_forces_path_data_tlv);
303 type = tvb_get_ntohs(tvb, offset);
304 proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_type,
305 tvb, offset, 2, ENC_BIG_ENDIAN);
306 length_TLV = tvb_get_ntohs(tvb, offset+2);
307 proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_length,
308 tvb, offset+2, 2, ENC_BIG_ENDIAN);
309 if (length_TLV < TLV_TL_LENGTH)
311 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Bogus TLV length: %u", length_TLV);
314 proto_item_set_len(ti, length_TLV);
316 if (type == PATH_DATA_TLV)
318 ti = proto_tree_add_text(tree, tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, "Path Data TLV");
319 path_data_tree = proto_item_add_subtree(ti, ett_forces_path_data_tlv);
321 flag = tvb_get_ntohs(tvb, offset+TLV_TL_LENGTH);
322 flag_item = proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_flags,
323 tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
324 flag_tree = proto_item_add_subtree(flag_item, ett_forces_path_data_tlv_flags);
325 proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_selector,
326 tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
327 proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_reserved,
328 tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
330 IDcount = tvb_get_ntohs(tvb, offset + TLV_TL_LENGTH + 2);
331 proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDcount,
332 tvb, offset+TLV_TL_LENGTH+2, 2, ENC_BIG_ENDIAN);
334 for (i = 0; i < IDcount; i++)
335 proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDs,
336 tvb, offset+TLV_TL_LENGTH+2+(i*4), 4, ENC_BIG_ENDIAN);
341 proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_operation_path_data,
342 tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, ENC_NA);
345 if ((flag & FLAG_SELECTOR) == 0)
348 offset += length_TLV;
353 dissect_operation_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint length_count)
356 proto_tree *oper_tree;
359 while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
361 ti = proto_tree_add_text(tree, tvb, offset, length_count, "Operation TLV");
362 oper_tree = proto_item_add_subtree(ti, ett_forces_lfbselect_tlv_type_operation);
364 type = tvb_get_ntohs(tvb,offset);
365 ti = proto_tree_add_item(oper_tree, hf_forces_lfbselect_tlv_type_operation_type,
366 tvb, offset, 2, ENC_BIG_ENDIAN);
367 if (match_strval(type, operation_type_vals) == NULL)
368 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
369 "Bogus: ForCES Operation TLV (Type:0x%04x) is not supported", type);
371 length = tvb_get_ntohs(tvb, offset+2);
372 proto_tree_add_uint_format(oper_tree, hf_forces_lfbselect_tlv_type_operation_length,
373 tvb, offset+2, 2, length, "Length: %u Bytes", length);
375 dissect_path_data_tlv(tvb, pinfo, oper_tree, offset+TLV_TL_LENGTH);
383 dissect_lfbselecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint length_count)
387 proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_classid, tvb, offset, 4, ENC_BIG_ENDIAN);
388 proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_lfb_instanceid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
391 while ((tvb_reported_length_remaining(tvb, offset) > TLV_TL_LENGTH) && (length_count > 12))
393 tlv_length = tvb_get_ntohs(tvb, offset+2);
394 dissect_operation_tlv(tvb, pinfo, tree, offset, tlv_length);
397 offset += tlv_length;
402 dissect_redirecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
404 proto_tree *meta_data_tree, *meta_data_ilv_tree, *redirect_data_tree;
406 gint length_meta, length_ilv, length_redirect;
408 address src_addr = pinfo->src,
409 src_net_addr = pinfo->net_src,
410 dst_addr = pinfo->dst,
411 dst_net_addr = pinfo->net_dst;
413 ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Meta Data TLV");
414 meta_data_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_meta_data_tlv);
415 proto_tree_add_item(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
417 length_meta = tvb_get_ntohs(tvb, offset+2);
418 proto_tree_add_uint_format(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_length, tvb, offset+2, 2,
419 length_meta, "Length: %u Bytes", length_meta);
420 proto_item_set_len(ti, length_meta);
422 start_offset = offset;
423 while ((tvb_reported_length_remaining(tvb, offset) >= 8) && (start_offset+length_meta > offset))
425 ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Meta Data ILV");
426 meta_data_ilv_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv);
428 proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
429 tvb, offset+8, 4, ENC_BIG_ENDIAN);
430 length_ilv = tvb_get_ntohl(tvb, offset+12);
431 proto_tree_add_uint_format(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
432 tvb, offset+12, 4, length_ilv, "Length: %u Bytes", length_ilv);
434 proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
435 tvb, offset+8, length_ilv, ENC_NA);
437 proto_item_set_len(ti, length_ilv + 8);
438 offset += length_ilv + 8;
441 if (tvb_reported_length_remaining(tvb, offset) > 0)
443 ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Redirect Data TLV");
444 redirect_data_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_redirect_data_tlv);
446 proto_tree_add_item(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_type,
447 tvb, offset, 2, ENC_BIG_ENDIAN);
448 length_redirect = tvb_get_ntohs(tvb, offset+2);
449 proto_tree_add_uint_format(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_length,
450 tvb, offset+2, 2, length_redirect, "Length: %u Bytes", length_redirect);
452 if (tvb_reported_length_remaining(tvb, offset) < length_redirect)
454 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
455 "Bogus: Redirect Data TLV length (%u bytes) is wrong", length_redirect);
457 else if (length_redirect < TLV_TL_LENGTH + MIN_IP_HEADER_LENGTH)
459 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
460 "Bogus: Redirect Data TLV length (%u bytes) not big enough for IP layer", length_redirect);
466 next_tvb = tvb_new_subset(tvb, offset+4, length_redirect-TLV_TL_LENGTH, length_redirect-TLV_TL_LENGTH);
467 call_dissector(ip_handle, next_tvb, pinfo, redirect_data_tree);
469 /* Restore IP info */
470 memcpy(&(pinfo->src), &src_addr, sizeof(address));
471 memcpy(&(pinfo->net_src), &src_net_addr, sizeof(address));
472 memcpy(&(pinfo->dst), &dst_addr, sizeof(address));
473 memcpy(&(pinfo->net_dst), &dst_net_addr, sizeof(address));
479 dissect_forces(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset)
481 /* Set up structures needed to add the protocol subtree and manage it */
482 proto_item *ti, *tlv_item;
483 proto_tree *forces_tree, *forces_flags_tree;
484 proto_tree *forces_main_header_tree, *forces_tlv_tree, *tlv_tree;
490 /* Make entries in Protocol column and Info column on summary display */
491 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ForCES");
492 col_clear(pinfo->cinfo, COL_INFO);
494 ti = proto_tree_add_item(tree, proto_forces, tvb, 0, -1, ENC_NA);
495 forces_tree = proto_item_add_subtree(ti, ett_forces);
497 ti = proto_tree_add_text(forces_tree, tvb, 0, ForCES_HEADER_LENGTH, "Common Header");
498 forces_main_header_tree = proto_item_add_subtree(ti, ett_forces_main_header);
500 proto_tree_add_item(forces_main_header_tree, hf_forces_version, tvb, 0, 1, ENC_BIG_ENDIAN);
501 proto_tree_add_item(forces_main_header_tree, hf_forces_rsvd, tvb, 0, 1, ENC_BIG_ENDIAN);
503 message_type = tvb_get_guint8(tvb, offset+1);
504 proto_tree_add_item( forces_main_header_tree, hf_forces_messagetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);
506 length_count = tvb_get_ntohs(tvb, offset+2) * 4; /*multiply 4 DWORD*/
507 ti = proto_tree_add_uint_format( forces_main_header_tree, hf_forces_length,
508 tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count);
509 if (length_count != tvb_reported_length_remaining(tvb, offset))
510 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
511 "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)",
512 length_count, tvb_reported_length_remaining(tvb, offset));
513 if (length_count < 24)
514 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
515 "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count);
517 col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type: %s, Total Length: %u Bytes",
518 val_to_str(message_type, message_type_vals, "Unknown messagetype 0x%x"), length_count);
520 proto_tree_add_item( forces_main_header_tree, hf_forces_sid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
521 proto_tree_add_item( forces_main_header_tree, hf_forces_did, tvb, offset+8, 4, ENC_BIG_ENDIAN);
522 proto_tree_add_item( forces_main_header_tree, hf_forces_correlator, tvb, offset+12, 8, ENC_BIG_ENDIAN);
525 ti = proto_tree_add_item(forces_main_header_tree, hf_forces_flags, tvb, offset+20, 4, ENC_BIG_ENDIAN);
526 forces_flags_tree = proto_item_add_subtree(ti, ett_forces_flags);
528 proto_tree_add_item(forces_flags_tree, hf_forces_flags_ack, tvb, offset+20, 4, ENC_BIG_ENDIAN);
529 proto_tree_add_item(forces_flags_tree, hf_forces_flags_at, tvb, offset+20, 4, ENC_BIG_ENDIAN);
530 proto_tree_add_item(forces_flags_tree, hf_forces_flags_em, tvb, offset+20, 4, ENC_BIG_ENDIAN);
531 proto_tree_add_item(forces_flags_tree, hf_forces_flags_pri, tvb, offset+20, 4, ENC_BIG_ENDIAN);
532 proto_tree_add_item(forces_flags_tree, hf_forces_flags_reserved, tvb, offset+20, 4, ENC_BIG_ENDIAN);
533 proto_tree_add_item(forces_flags_tree, hf_forces_flags_rsrvd, tvb, offset+20, 4, ENC_BIG_ENDIAN);
534 proto_tree_add_item(forces_flags_tree, hf_forces_flags_tp, tvb, offset+20, 4, ENC_BIG_ENDIAN);
537 while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
539 ti = proto_tree_add_text(forces_tree, tvb, offset, TLV_TL_LENGTH, "TLV");
540 forces_tlv_tree = proto_item_add_subtree(ti, ett_forces_tlv);
542 tlv_type = tvb_get_ntohs(tvb, offset);
543 tlv_item = proto_tree_add_item(forces_tlv_tree, hf_forces_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
544 length_count = tvb_get_ntohs(tvb, offset+2) * 4;
545 proto_item_set_len(ti, length_count);
546 ti = proto_tree_add_uint_format(forces_tlv_tree, hf_forces_tlv_length,
547 tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count);
548 if (tvb_reported_length_remaining(tvb, offset) < length_count)
549 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN,
550 "Bogus: Main TLV length (%u bytes) is wrong", length_count);
552 if (length_count < TLV_TL_LENGTH)
554 expert_add_info_format(pinfo, ti, PI_PROTOCOL, PI_WARN, "Bogus TLV length: %u", length_count);
558 offset += TLV_TL_LENGTH;
559 length_count -= TLV_TL_LENGTH;
564 ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "LFB select TLV");
565 tlv_tree = proto_item_add_subtree(ti, ett_forces_lfbselect_tlv_type);
566 dissect_lfbselecttlv(tvb, pinfo, tlv_tree, offset, length_count);
570 ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "Redirect TLV");
571 tlv_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_type);
572 dissect_redirecttlv(tvb, pinfo, tlv_tree, offset);
576 ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "ASResult TLV");
577 tlv_tree = proto_item_add_subtree(ti, ett_forces_asresult_tlv);
578 proto_tree_add_item(tlv_tree, hf_forces_asresult_association_setup_result, tvb, offset, 4, ENC_BIG_ENDIAN);
582 ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "ASTreason TLV");
583 tlv_tree = proto_item_add_subtree(ti, ett_forces_astreason_tlv);
584 proto_tree_add_item(tlv_tree, hf_forces_astreason_tlv_teardown_reason, tvb, offset, 4, ENC_BIG_ENDIAN);
588 expert_add_info_format(pinfo, tlv_item, PI_PROTOCOL, PI_WARN,
589 "Bogus: The Main_TLV type is unknown");
590 ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "Unknown TLV");
591 tlv_tree = proto_item_add_subtree(ti, ett_forces_unknown_tlv);
592 proto_tree_add_item(tlv_tree, hf_forces_unknown_tlv, tvb, offset, length_count, ENC_NA);
596 offset += length_count;
600 /* Code to actually dissect the TCP packets */
602 dissect_forces_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
604 dissect_forces(tvb, pinfo, tree, TCP_UDP_TML_FOCES_MESSAGE_OFFSET_TCP);
607 /* Code to actually dissect the ForCES protocol layer packets,like UDP,SCTP and others */
609 dissect_forces_not_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
611 dissect_forces(tvb, pinfo, tree, 0);
614 void proto_reg_handoff_forces(void);
617 proto_register_forces(void)
619 module_t *forces_module;
621 /* Setup list of header fields See Section 1.6.1 for details*/
622 static hf_register_info hf[] = {
623 { &hf_forces_version,
624 { "Version", "forces.flags.version",
625 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
628 { "Rsvd", "forces.flags.rsvd",
629 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
631 { &hf_forces_messagetype,
632 { "Message Type", "forces.messagetype",
633 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }
636 { "Header Length", "forces.length",
637 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
640 { "Source ID", "forces.sid",
641 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
644 { "Destination ID", "forces.did",
645 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
647 { &hf_forces_correlator,
648 { "Correlator", "forces.correlator",
649 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }
651 { &hf_forces_tlv_type,
652 { "Type", "forces.tlv.type",
653 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
655 { &hf_forces_tlv_length,
656 { "Length", "forces.tlv.length",
657 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
661 { "Flags", "forces.Flags",
662 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
664 { &hf_forces_flags_ack,
665 { "ACK indicator", "forces.flags.ack",
666 FT_UINT32, BASE_DEC, VALS(main_header_flags_ack_vals), 0xC0000000, NULL, HFILL }
668 { &hf_forces_flags_pri,
669 { "Priority", "forces.flags.pri",
670 FT_UINT32, BASE_DEC, NULL, 0x38000000, NULL, HFILL }
672 { &hf_forces_flags_rsrvd,
673 { "Rsrvd", "forces.Flags",
674 FT_UINT32, BASE_DEC,NULL, 0x07000000, NULL, HFILL }
676 { &hf_forces_flags_em,
677 { "Execution mode", "forces.flags.em",
678 FT_UINT32, BASE_DEC, VALS(main_header_flags_em_vals), 0x00C00000, NULL, HFILL }
680 { &hf_forces_flags_at,
681 { "Atomic Transaction", "forces.flags.at",
682 FT_UINT32, BASE_DEC, VALS(main_header_flags_at_vals), 0x00200000, NULL, HFILL }
684 { &hf_forces_flags_tp,
685 { "Transaction phase", "forces.flags.tp",
686 FT_UINT32, BASE_DEC, VALS(main_header_flags_tp_vals), 0x00180000, NULL, HFILL }
688 { &hf_forces_flags_reserved,
689 { "Reserved", "forces.flags.reserved",
690 FT_UINT32, BASE_DEC,NULL, 0x0007ffff, NULL, HFILL }
693 { &hf_forces_lfbselect_tlv_type_lfb_classid,
694 { "Class ID", "forces.lfbselect.tlv.type.lfb.classid",
695 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
697 { &hf_forces_lfbselect_tlv_type_lfb_instanceid,
698 { "Instance ID", "forces.fbselect.tlv.type.lfb.instanceid",
699 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }
702 { &hf_forces_lfbselect_tlv_type_operation_type,
703 { "Type", "forces.lfbselect.tlv.type.operation.type",
704 FT_UINT16, BASE_DEC, VALS(operation_type_vals), 0x0, NULL, HFILL }
706 { &hf_forces_lfbselect_tlv_type_operation_length,
707 { "Length", "forces.lfbselect.tlv.type.operation.length",
708 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
710 { &hf_forces_lfbselect_tlv_type_operation_path_type,
711 { "Type", "forces.lfbselect.tlv.type.operation.path.type",
712 FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL }
714 { &hf_forces_lfbselect_tlv_type_operation_path_length,
715 { "Length", "forces.lfbselect.tlv.type.operation.path.length",
716 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
718 { &hf_forces_lfbselect_tlv_type_operation_path_data,
719 { "Data", "forces.lfbselect.tlv.type.operation.path.data",
720 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
722 { &hf_forces_lfbselect_tlv_type_operation_path_flags,
723 {"Path Data Flags", "forces.lfbselect.tlv.type.operation.path.data.flags",
724 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
726 { &hf_forces_lfbselect_tlv_type_operation_path_flags_selector,
727 {"Selector", "forces.lfbselect.tlv.type.operation.path.data.flags.selector",
728 FT_UINT16, BASE_HEX, NULL, 0x80, NULL, HFILL }
730 { &hf_forces_lfbselect_tlv_type_operation_path_flags_reserved,
731 {"Reserved", "forces.lfbselect.tlv.type.operation.path.data.flags.reserved",
732 FT_UINT16, BASE_HEX, NULL, 0x7F, NULL, HFILL }
734 { &hf_forces_lfbselect_tlv_type_operation_path_IDcount,
735 { "Path Data IDcount", "forces.lfbselect.tlv.type.operation.path.data.IDcount",
736 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
738 { &hf_forces_lfbselect_tlv_type_operation_path_IDs,
739 { "Path Data IDs", "forces.lfbselect.tlv.type.operation.path.data.IDs",
740 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
743 {&hf_forces_redirect_tlv_meta_data_tlv_type,
744 { "Type", "forces.redirect.tlv.meta.data.tlv.type",
745 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
747 { &hf_forces_redirect_tlv_meta_data_tlv_length,
748 { "Length", "forces.redirect.tlv.meta.data.tlv.length",
749 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
751 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
752 { "Meta Data ILV", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv",
753 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
755 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
756 { "ID", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.id",
757 FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }
759 { &hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
760 { "Length", "forces.redirect.tlv.meta.data.tlv.meta.data.ilv.length",
761 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
763 { &hf_forces_redirect_tlv_redirect_data_tlv_type,
764 { "Type", "forces.redirect.tlv.redirect.data.tlv.type",
765 FT_UINT16, BASE_DEC, VALS(tlv_type_vals), 0x0, NULL, HFILL }
767 { &hf_forces_redirect_tlv_redirect_data_tlv_length,
768 { "Length", "forces.redirect.tlv.redirect.data.tlv.length",
769 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
771 { &hf_forces_asresult_association_setup_result,
772 { "Association Setup Result", "forces.teardown.reason",
773 FT_UINT32, BASE_DEC, VALS(association_setup_result_at_vals), 0x0, NULL, HFILL }
775 { &hf_forces_astreason_tlv_teardown_reason,
776 { "AStreason TLV TearDonw Reason", "forces.astreason.tlv.teardonw.reason",
777 FT_UINT32, BASE_DEC, VALS(teardown_reason_at_vals), 0x0, NULL, HFILL }
779 { &hf_forces_unknown_tlv,
780 { "Data", "forces.unknown.tlv",
781 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
785 /* Setup protocol subtree array */
786 static gint *ett[] = {
788 &ett_forces_main_header,
791 &ett_forces_lfbselect_tlv_type,
792 &ett_forces_lfbselect_tlv_type_operation,
793 &ett_forces_lfbselect_tlv_type_operation_path,
794 &ett_forces_lfbselect_tlv_type_operation_path_data,
795 &ett_forces_lfbselect_tlv_type_operation_path_data_path,
796 &ett_forces_lfbselect_tlv_type_operation_path_selector,
797 &ett_forces_path_data_tlv,
798 &ett_forces_path_data_tlv_flags,
799 &ett_forces_redirect_tlv_type,
800 &ett_forces_redirect_tlv_meta_data_tlv,
801 &ett_forces_redirect_tlv_redirect_data_tlv,
802 &ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
803 &ett_forces_asresult_tlv,
804 &ett_forces_astreason_tlv,
805 &ett_forces_unknown_tlv
808 /* Register the protocol name and description */
809 proto_forces = proto_register_protocol("Forwarding and Control Element Separation Protocol", "ForCES", "forces");
811 /* Required function calls to register the header fields and subtrees used */
812 proto_register_field_array(proto_forces, hf, array_length(hf));
813 proto_register_subtree_array(ett, array_length(ett));
815 forces_module = prefs_register_protocol(proto_forces,proto_reg_handoff_forces);
817 prefs_register_uint_preference(forces_module, "tcp_alternate_port",
819 "Decode packets on this TCP port as ForCES",
820 10, &forces_alternate_tcp_port);
822 prefs_register_uint_preference(forces_module, "udp_alternate_port",
824 "Decode packets on this UDP port as ForCES",
825 10, &forces_alternate_udp_port);
827 prefs_register_uint_preference(forces_module, "sctp_high_prio_port",
828 "SCTP High Priority channel port",
829 "Decode packets on this sctp port as ForCES",
830 10, &forces_alternate_sctp_high_prio_channel_port);
832 prefs_register_uint_preference(forces_module, "sctp_med_prio_port",
833 "SCTP Meidium Priority channel port",
834 "Decode packets on this sctp port as ForCES",
835 10, &forces_alternate_sctp_med_prio_channel_port);
837 prefs_register_uint_preference(forces_module, "sctp_low_prio_port",
838 "SCTP Low Priority channel port",
839 "Decode packets on this sctp port as ForCES",
840 10, &forces_alternate_sctp_low_prio_channel_port);
844 proto_reg_handoff_forces(void)
846 static gboolean inited = FALSE;
848 static guint alternate_tcp_port = 0; /* 3000 */
849 static guint alternate_udp_port = 0;
850 static guint alternate_sctp_high_prio_channel_port = 0; /* 6700 */
851 static guint alternate_sctp_med_prio_channel_port = 0;
852 static guint alternate_sctp_low_prio_channel_port = 0;
854 static dissector_handle_t forces_handle_tcp, forces_handle;
857 forces_handle_tcp = create_dissector_handle(dissect_forces_tcp, proto_forces);
858 forces_handle = create_dissector_handle(dissect_forces_not_tcp, proto_forces);
859 ip_handle = find_dissector("ip");
863 /* Register TCP port for dissection */
864 if ((alternate_tcp_port != 0) && (alternate_tcp_port != forces_alternate_tcp_port))
865 dissector_delete_uint("tcp.port", alternate_tcp_port, forces_handle_tcp);
866 if ((forces_alternate_tcp_port != 0) && (alternate_tcp_port != forces_alternate_tcp_port))
867 dissector_add_uint("tcp.port", forces_alternate_tcp_port, forces_handle_tcp);
868 alternate_tcp_port = forces_alternate_tcp_port;
870 /* Register UDP port for dissection */
871 if ((alternate_udp_port != 0) && (alternate_udp_port != forces_alternate_udp_port))
872 dissector_delete_uint("udp.port", alternate_udp_port, forces_handle);
873 if ((forces_alternate_udp_port != 0) && (alternate_udp_port != forces_alternate_udp_port))
874 dissector_add_uint("udp.port", forces_alternate_udp_port, forces_handle);
875 alternate_udp_port = forces_alternate_udp_port;
877 /* Register SCTP port for high priority dissection */
878 if ((alternate_sctp_high_prio_channel_port != 0) &&
879 (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port))
880 dissector_delete_uint("sctp.port", alternate_sctp_high_prio_channel_port, forces_handle);
881 if ((forces_alternate_sctp_high_prio_channel_port != 0) &&
882 (alternate_sctp_high_prio_channel_port != forces_alternate_sctp_high_prio_channel_port))
883 dissector_add_uint("sctp.port", forces_alternate_sctp_high_prio_channel_port, forces_handle);
884 alternate_sctp_high_prio_channel_port = forces_alternate_sctp_high_prio_channel_port;
886 /* Register SCTP port for medium priority dissection */
887 if ((alternate_sctp_med_prio_channel_port != 0) &&
888 (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port))
889 dissector_delete_uint("udp.port", alternate_sctp_med_prio_channel_port, forces_handle);
890 if ((forces_alternate_sctp_med_prio_channel_port != 0) &&
891 (alternate_sctp_med_prio_channel_port != forces_alternate_sctp_med_prio_channel_port))
892 dissector_add_uint("udp.port", forces_alternate_sctp_med_prio_channel_port, forces_handle);
893 alternate_sctp_med_prio_channel_port = forces_alternate_sctp_med_prio_channel_port;
895 /* Register SCTP port for low priority dissection */
896 if ((alternate_sctp_low_prio_channel_port != 0) &&
897 (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port))
898 dissector_delete_uint("udp.port", alternate_sctp_low_prio_channel_port, forces_handle);
899 if ((forces_alternate_sctp_low_prio_channel_port != 0) &&
900 (alternate_sctp_low_prio_channel_port != forces_alternate_sctp_low_prio_channel_port))
901 dissector_add_uint("udp.port", forces_alternate_sctp_low_prio_channel_port, forces_handle);
902 alternate_sctp_low_prio_channel_port = forces_alternate_sctp_low_prio_channel_port;
906 * Editor modelines - http://www.wireshark.org/tools/modelines.html
911 * indent-tabs-mode: nil
914 * vi: set shiftwidth=4 tabstop=8 expandtab:
915 * :indentSize=4:tabSize=8:noTabs=true: