2 * Routines for swift protocol packet disassembly
3 * By Andrew Keating <andrewzkeating@gmail.com>
4 * Copyright 2011 Andrew Keating
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 static int proto_swift = -1;
36 static int hf_swift_receiving_channel = -1;
37 static int hf_swift_message_type = -1;
39 /* 00 Handshake fields */
40 static int hf_swift_handshake_channel = -1;
43 static int hf_swift_data_bin_id = -1;
44 static int hf_swift_data_payload = -1;
47 static int hf_swift_ack_bin_id = -1;
48 static int hf_swift_ack_timestamp = -1;
51 static int hf_swift_have_bin_id = -1;
54 static int hf_swift_hash_bin_id = -1;
55 static int hf_swift_hash_value = -1;
58 static int hf_swift_pexplus_ip = -1;
59 static int hf_swift_pexplus_port = -1;
62 static int hf_swift_pexminus_ip = -1;
63 static int hf_swift_pexminus_port = -1;
65 /* 07 Signed hash fields */
66 static int hf_swift_signed_hash_bin_id = -1;
67 static int hf_swift_signed_hash_value = -1;
68 static int hf_swift_signed_hash_signature = -1;
71 static int hf_swift_hint_bin_id = -1;
73 static gint ett_swift = -1;
75 static void dissect_swift(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
76 static gboolean dissect_swift_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
78 static const value_string message_type_names[] = {
88 { 9, "SWIFT_MSGTYPE_RCVD" },
89 { 10, "SWIFT_MESSAGE_COUNT" },
95 proto_register_swift(void)
97 static hf_register_info hf[] = {
99 { &hf_swift_receiving_channel,
100 { "Receiving Channel", "swift.receiving.channel",
105 { &hf_swift_message_type,
106 { "Message Type", "swift.message.type",
108 VALS(message_type_names), 0x0,
113 { &hf_swift_handshake_channel,
114 { "Handshake Channel", "swift.handshake.channel",
121 { &hf_swift_data_bin_id,
122 { "Data Bin ID", "swift.data.bin_id",
127 { &hf_swift_data_payload,
128 { "Data Payload", "swift.data.payload",
135 { &hf_swift_ack_bin_id,
136 { "Ack Bin ID", "swift.ack.bin_id",
141 { &hf_swift_ack_timestamp,
142 { "Timestamp", "swift.ack.timestamp",
149 { &hf_swift_have_bin_id,
150 { "Have Bin ID", "swift.have.bin_id",
157 { &hf_swift_hash_bin_id,
158 { "Hash Bin ID", "swift.hash.bin_id",
163 { &hf_swift_hash_value,
164 { "Hash Value", "swift.hash.value",
171 { &hf_swift_pexplus_ip,
172 { "PEX+ IP Address", "swift.pex_plus.ip",
177 { &hf_swift_pexplus_port,
178 { "PEX+ Port", "swift.pex_plus.port",
185 { &hf_swift_pexminus_ip,
186 { "PEX- IP Address", "swift.pex_minus.ip",
191 { &hf_swift_pexminus_port,
192 { "PEX- Port", "swift.pex_minus.port",
199 { &hf_swift_signed_hash_bin_id,
200 { "Signed Hash Bin ID", "swift.signed_hash.bin_id",
205 { &hf_swift_signed_hash_value,
206 { "Signed Hash Value", "swift.signed_hash.value",
211 { &hf_swift_signed_hash_signature,
212 { "Signed Hash Signature", "swift.signed_hash.signature",
219 { &hf_swift_hint_bin_id,
220 { "Hint Bin ID", "swift.hint.bin_id",
227 /* Setup protocol subtree array */
228 static gint *ett[] = {
232 proto_swift = proto_register_protocol (
233 "swift: the multiparty transport protocol", /* name */
234 "swift", /* short name */
238 proto_register_field_array(proto_swift, hf, array_length(hf));
239 proto_register_subtree_array(ett, array_length(ett));
240 register_dissector("swift", dissect_swift, proto_swift);
244 proto_reg_handoff_swift(void)
246 dissector_handle_t swift_handle;
247 swift_handle = find_dissector("swift");
249 /* Allow "Decode As" with any UDP packet. */
250 dissector_add_handle("udp.port", swift_handle);
252 /* Add our heuristic packet finder. */
253 heur_dissector_add("udp", dissect_swift_heur, proto_swift);
256 /* This heuristic is somewhat ambiguous, but for research purposes, it should be fine */
258 dissect_swift_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
260 guint message_length;
261 message_length = tvb_length(tvb);
262 /* If the fifth byte isn't one of the supported packet types, it's not swift (except keep-alives) */
263 if(message_length != 4) {
265 message_type = tvb_get_guint8(tvb, 4);
266 if(message_type > 10) {
271 dissect_swift(tvb, pinfo, tree);
276 dissect_swift(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
279 col_set_str(pinfo->cinfo, COL_PROTOCOL, "swift");
280 /* Clear out stuff in the info column */
281 col_clear(pinfo->cinfo,COL_INFO);
283 if (tree) { /* we are being asked for details */
285 ti = proto_tree_add_item(tree, proto_swift, tvb, 0, -1, FALSE);
287 proto_tree *swift_tree;
288 swift_tree = proto_item_add_subtree(ti, ett_swift);
290 /* All messages start with the receiving channel, so we can pull it out here */
291 proto_tree_add_item(swift_tree, hf_swift_receiving_channel, tvb, offset, 4, FALSE); offset += 4;
293 /* Loop until there is nothing left to read in the packet */
294 while(tvb_bytes_exist(tvb, offset, 1)) {
297 message_type = tvb_get_guint8(tvb, offset);
298 proto_tree_add_item(swift_tree, hf_swift_message_type, tvb, offset, 1, FALSE);
301 /* Add message type to the info column */
303 col_append_fstr(pinfo->cinfo, COL_INFO, ", ");
305 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
306 val_to_str(message_type, message_type_names, "Unknown (0x%02x)"));
308 /* Add it to the dissection window as well */
309 proto_item_append_text(ti, ", %s",
310 val_to_str(message_type, message_type_names, "Unknown (0x%02x)"));
312 switch(message_type) {
313 case 0: /* Handshake */
314 proto_tree_add_item(swift_tree, hf_swift_handshake_channel, tvb, offset, 4, FALSE);
318 proto_tree_add_item(swift_tree, hf_swift_data_bin_id, tvb, offset, 4, FALSE);
320 /* We assume that the data field comprises the rest of this packet */
321 dat_len = tvb_length(tvb) - offset;
322 proto_tree_add_item(swift_tree, hf_swift_data_payload, tvb, offset, dat_len, FALSE);
326 proto_tree_add_item(swift_tree, hf_swift_ack_bin_id, tvb, offset, 4, FALSE);
328 proto_tree_add_item(swift_tree, hf_swift_ack_timestamp, tvb, offset, 8, FALSE);
332 proto_tree_add_item(swift_tree, hf_swift_have_bin_id, tvb, offset, 4, FALSE);
336 proto_tree_add_item(swift_tree, hf_swift_hash_bin_id, tvb, offset, 4, FALSE);
338 proto_tree_add_item(swift_tree, hf_swift_hash_value, tvb, offset, 20, FALSE);
342 proto_tree_add_item(swift_tree, hf_swift_pexplus_ip, tvb, offset, 4, FALSE);
344 proto_tree_add_item(swift_tree, hf_swift_pexplus_port, tvb, offset, 2, FALSE);
348 proto_tree_add_item(swift_tree, hf_swift_pexminus_ip, tvb, offset, 4, FALSE);
350 proto_tree_add_item(swift_tree, hf_swift_pexminus_port, tvb, offset, 2, FALSE);
353 case 7: /* Signed Hash */
354 proto_tree_add_item(swift_tree, hf_swift_signed_hash_bin_id, tvb, offset, 4, FALSE);
356 proto_tree_add_item(swift_tree, hf_swift_signed_hash_value, tvb, offset, 20, FALSE);
358 /* It is not entirely clear what size the public key will be, so we allow any size
359 For this to work, we must assume there aren't any more messages in the packet */
360 dat_len = tvb_length(tvb) - offset;
361 proto_tree_add_item(swift_tree, hf_swift_signed_hash_signature, tvb, offset, dat_len, FALSE);
365 proto_tree_add_item(swift_tree, hf_swift_hint_bin_id, tvb, offset, 4, FALSE);
368 case 9: /* SWIFT_MSGTYPE_RCVD */
370 case 10: /* SWIFT_MESSAGE_COUNT */
376 /* If the offset is still 4 here, the message is a keep-alive */
378 col_append_fstr(pinfo->cinfo, COL_INFO, "Keep-Alive");
379 proto_item_append_text(ti, ", Keep-Alive");