2 * Routines for SoulSeek Protocol dissection
3 * Copyright 2003, Christian Wagner <Christian.Wagner@stud.uni-karlsruhe.de>
4 * Institute of Telematics - University of Karlsruhe
5 * part of this work supported by
6 * Deutsche Forschungsgemeinschaft (DFG) Grant Number FU448/1
8 * SoulSeek Protocol dissector based on protocol descriptions from SoleSeek Project:
9 * http://cvs.sourceforge.net/viewcvs.py/soleseek/SoleSeek/doc/protocol.html?rev=HEAD
10 * Updated for SoulSeek client version 151
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 #include <epan/packet.h>
44 #include <epan/tvbuff.h>
45 #include "packet-tcp.h"
46 #include <epan/prefs.h>
47 #include <epan/strutil.h>
49 /* Initialize the protocol and registered fields */
50 static int proto_slsk = -1;
52 static int hf_slsk_integer = -1;
53 static int hf_slsk_string = -1;
54 static int hf_slsk_byte = -1;
55 static int hf_slsk_message_length = -1;
56 static int hf_slsk_message_code = -1;
57 static int hf_slsk_client_ip = -1;
58 static int hf_slsk_server_ip = -1;
59 static int hf_slsk_string_length = -1;
60 static int hf_slsk_username = -1;
61 static int hf_slsk_password = -1;
62 static int hf_slsk_version = -1;
63 static int hf_slsk_login_successful = -1;
64 static int hf_slsk_login_message = -1;
65 static int hf_slsk_port = -1;
66 static int hf_slsk_ip = -1;
67 static int hf_slsk_user_exists = -1;
68 static int hf_slsk_status_code = -1;
69 static int hf_slsk_room = -1;
70 static int hf_slsk_chat_message = -1;
71 static int hf_slsk_users_in_room = -1;
72 static int hf_slsk_token = -1;
73 static int hf_slsk_connection_type = -1;
74 static int hf_slsk_chat_message_id = -1;
75 static int hf_slsk_timestamp = -1;
76 static int hf_slsk_search_text = -1;
77 static int hf_slsk_folder_count = -1;
78 static int hf_slsk_file_count = -1;
79 static int hf_slsk_average_speed = -1;
80 static int hf_slsk_download_number = -1;
81 static int hf_slsk_files = -1;
82 static int hf_slsk_directories = -1;
83 static int hf_slsk_slotsfull = -1;
84 static int hf_slsk_place_in_queue = -1;
85 static int hf_slsk_number_of_rooms = -1;
86 static int hf_slsk_filename = -1;
87 static int hf_slsk_directory = -1;
88 static int hf_slsk_size = -1;
89 static int hf_slsk_checksum = -1;
90 static int hf_slsk_code = -1;
91 static int hf_slsk_number_of_users = -1;
92 static int hf_slsk_number_of_days = -1;
93 static int hf_slsk_transfer_direction = -1;
94 static int hf_slsk_user_description = -1;
95 static int hf_slsk_picture_exists = -1;
96 static int hf_slsk_picture = -1;
97 static int hf_slsk_user_uploads = -1;
98 static int hf_slsk_total_uploads = -1;
99 static int hf_slsk_queued_uploads = -1;
100 static int hf_slsk_slots_available = -1;
101 static int hf_slsk_allowed = -1;
102 static int hf_slsk_compr_packet = -1;
103 static int hf_slsk_parent_min_speed = -1;
104 static int hf_slsk_parent_speed_connection_ratio = -1;
105 static int hf_slsk_seconds_parent_inactivity_before_disconnect = -1;
106 static int hf_slsk_seconds_server_inactivity_before_disconnect = -1;
107 static int hf_slsk_nodes_in_cache_before_disconnect = -1;
108 static int hf_slsk_seconds_before_ping_children = -1;
109 static int hf_slsk_recommendation = -1;
110 static int hf_slsk_ranking = -1;
113 /* Initialize the subtree pointers */
114 static gint ett_slsk = -1;
115 static gint ett_slsk_compr_packet = -1;
117 #define TCP_PORT_SLSK_1 2234
118 #define TCP_PORT_SLSK_2 5534
119 #define TCP_PORT_SLSK_3 2240
122 /* desegmentation of SoulSeek Message over TCP */
123 static gboolean slsk_desegment = TRUE;
125 static gboolean slsk_decompress = TRUE;
127 static gboolean slsk_decompress = FALSE;
130 static const value_string slsk_tcp_msgs[] = {
132 { 2, "Set Wait Port"},
133 { 3, "Get Peer Address"},
134 { 4, "Get Shared File List"},
135 { 5, "User Exists / Shared File List"},
136 { 7, "Get User Status"},
137 { 9, "File Search Result"},
138 { 13, "Say ChatRoom"},
140 { 15, "Leave Room / User Info Request"},
141 { 16, "User Joined Room / User Info Reply"},
142 { 17, "User Left Room"},
143 { 18, "Connect To Peer"},
144 { 22, "Message User"},
145 { 23, "Message User Ack"},
146 { 26, "File Search"},
149 { 34, "Update Upload Speed"},
150 { 35, "Shared Files & Folders"},
151 { 36, "Get User Stats / Folder Contents Request"},
152 { 37, "Folder Contents Response"},
153 { 40, "Queued Downloads / Transfer Request"},
154 { 41, "Transfer Response"},
155 { 42, "Placehold Upload"},
156 { 43, "Queue Upload"},
157 { 44, "Place In Queue"},
158 { 46, "Upload Failed"},
159 { 50, "Queue Failed / Own Recommendation"},
160 { 51, "Add Things I like / Place In Queue Request"},
161 { 52, "Remove Things I like"},
162 { 54, "Get Recommendations"},
164 { 56, "Get Global Rankings"},
165 { 57, "Get User Recommendations"},
166 { 58, "Admin Command"},
167 { 60, "Place In Line Response"},
169 { 63, "Room Removed"},
171 { 65, "Exact File Search"},
172 { 66, "Admin Message"},
173 { 67, "Global User List"},
174 { 68, "Tunneled Message"},
175 { 69, "Privileged User List"},
176 { 71, "Get Parent List"},
178 { 83, "Parent Min Speed"},
179 { 84, "Parent Speed Connection Ratio"},
180 { 86, "Parent Inactivity Before Disconnect"},
181 { 87, "Server Inactivity Before Disconnect"},
182 { 88, "Nodes In Cache Before Disconnect"},
183 { 90, "Seconds Before Ping Children"},
184 { 91, "Add To Privileged"},
185 { 92, "Check Privileges"},
186 { 93, "Embedded Message"},
187 { 100, "Become Parent"},
188 { 102, "Random Parent Addresses"},
189 { 103, "Send Wishlist Entry"},
191 { 110, "Get Similar Users"},
192 { 111, "Get Recommendations for Item"},
193 { 112, "Get Similar Users for Item"},
194 { 1001, "Can't Connect To Peer"},
198 static const value_string slsk_status_codes[] = {
206 static const value_string slsk_transfer_direction[] = {
212 static const value_string slsk_yes_no[] = {
218 static const value_string slsk_attr_type[] = {
225 static const char* connection_type(char con_type[]) {
226 if (strlen(con_type) != 1) return "Unknown";
227 if (con_type[0] == 'D') return "Distributed Search";
228 if (con_type[0] == 'P') return "Peer Connection"; /* "File Search Result / User Info Request / Get Shared File List" */
229 if (con_type[0] == 'F') return "File Transfer";
233 static gboolean check_slsk_format(tvbuff_t *tvb, int offset, const char format[]){
236 * Returns TRUE if tvbuff beginning at offset matches a certain format
237 * The format is given by an array of characters standing for a special field type
238 * i - integer (4 bytes)
240 * s - string (string_length + 4 bytes)
242 * * - can be used at the end of a format to ignore any following bytes
245 switch ( format[0] ) {
247 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
251 if (tvb_length_remaining(tvb, offset) < 1) return FALSE;
255 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
256 if (tvb_length_remaining(tvb, offset) < (int)tvb_get_letohl(tvb, offset)+4) return FALSE;
257 offset += tvb_get_letohl(tvb, offset)+4;
265 if (format[1] == '\0' ) {
266 if (tvb_length_remaining(tvb, offset) != 0) return FALSE; /* Checks for additional bytes at the end */
269 return check_slsk_format(tvb, offset, &format[1]);
273 static const char* get_message_type(tvbuff_t *tvb) {
275 * Checks if the Message Code is known.
276 * If unknown checks if the Message Code is stored in a byte.
277 * Returns the Message Type.
279 int msg_code = tvb_get_letohl(tvb, 4);
280 const gchar *message_type = match_strval(msg_code, slsk_tcp_msgs);
281 if (message_type == NULL) {
282 if (check_slsk_format(tvb, 4, "bisis"))
283 message_type = "Distributed Search";
284 else if (check_slsk_format(tvb, 4, "bssi"))
285 message_type = "Peer Init";
286 else if (check_slsk_format(tvb, 4, "bi"))
287 message_type = "Pierce Fw";
289 message_type = "Unknown";
294 static guint get_slsk_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
297 msg_len = tvb_get_letohl(tvb, offset);
298 /* That length doesn't include the length field itself; add that in. */
303 /* Code to actually dissect the packets */
305 static void dissect_slsk_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
308 /* Set up structures needed to add the protocol subtree and manage it */
310 proto_tree *slsk_tree;
313 guint32 msg_len, msg_code;
314 const gchar *message_type;
319 int uncompr_tvb_offset = 0;
327 msg_len = tvb_get_letohl(tvb, offset);
328 msg_code = tvb_get_letohl(tvb, offset+4);
329 message_type = get_message_type(tvb);
331 /* Make entries in Protocol column and Info column on summary display */
332 col_set_str(pinfo->cinfo, COL_PROTOCOL, "slsk");
334 /* This field shows up as the "Info" column in the display */
336 col_set_str(pinfo->cinfo, COL_INFO, "SoulSeek Message");
338 if (check_col(pinfo->cinfo, COL_INFO)) {
339 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_type);
345 /* create display subtree for the protocol */
346 ti = proto_tree_add_item(tree, proto_slsk, tvb, 0, -1, FALSE);
347 slsk_tree = proto_item_add_subtree(ti, ett_slsk);
349 /* Continue adding tree items to process the packet here */
351 proto_tree_add_uint(slsk_tree, hf_slsk_message_length, tvb, offset, 4, msg_len);
357 if (check_slsk_format(tvb, offset, "issi")) {
358 /* Client-to-Server */
359 message_type = "Login";
360 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
361 "Message Type: %s (Code: %02d)", message_type, msg_code);
363 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
364 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
365 offset += 4+tvb_get_letohl(tvb, offset);
366 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
367 proto_tree_add_item(slsk_tree, hf_slsk_password, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
368 offset += 4+tvb_get_letohl(tvb, offset);
369 proto_tree_add_uint(slsk_tree, hf_slsk_version, tvb, offset, 4, tvb_get_letohl(tvb, offset));
372 else if (check_slsk_format(tvb, offset, "ibs") || check_slsk_format(tvb, offset, "ibsi")) {
373 /* Server-to-Client */
374 message_type = "Login Reply";
375 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
376 "Message Type: %s (Code: %02d)", message_type, msg_code);
378 i=tvb_get_guint8(tvb, offset);
379 proto_tree_add_uint_format(slsk_tree, hf_slsk_login_successful, tvb, offset, 1, tvb_get_guint8(tvb, offset),
380 "Login successful: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
382 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
383 proto_tree_add_item(slsk_tree, hf_slsk_login_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
384 offset += 4+tvb_get_letohl(tvb, offset);
386 proto_tree_add_ipv4(slsk_tree, hf_slsk_client_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
393 if (check_slsk_format(tvb, offset, "ii")) {
394 /* Client-to-Server */
395 message_type = "Set Wait Port";
396 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
397 "Message Type: %s (Code: %02d)", message_type, msg_code);
399 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
405 if (check_slsk_format(tvb, offset, "isii")) {
406 /* Server-to-Client */
407 message_type = "Get Peer Address Reply";
408 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
409 "Message Type: %s (Code: %02d)", message_type, msg_code);
411 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
412 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
413 offset += 4+tvb_get_letohl(tvb, offset);
414 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
416 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
419 else if (check_slsk_format(tvb, offset, "is")) {
420 /* Client-to-Server */
421 message_type = "Get Peer Address";
422 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
423 "Message Type: %s (Code: %02d)", message_type, msg_code);
425 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
426 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
427 offset += 4+tvb_get_letohl(tvb, offset);
432 if (check_slsk_format(tvb, offset, "i")) {
433 /* Client-to-Client */
434 message_type = "Get Shared File List";
435 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
436 "Message Type: %s (Code: %02d)", message_type, msg_code);
442 if (check_slsk_format(tvb, offset, "isb")) {
443 /* Server-to-Client */
444 message_type = "User Exists Reply";
445 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
446 "Message Type: %s (Code: %02d)", message_type, msg_code);
448 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
449 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
450 offset += 4+tvb_get_letohl(tvb, offset);
451 proto_tree_add_uint_format(slsk_tree, hf_slsk_user_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
452 "User exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
455 else if (check_slsk_format(tvb, offset, "is")) {
456 /* Client-to-Server */
457 message_type = "User Exists Request";
458 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
459 "Message Type: %s (Code: %02d)", message_type, msg_code);
461 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
462 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
463 offset += 4+tvb_get_letohl(tvb, offset);
465 else if (check_slsk_format(tvb, offset, "i*")) {
466 /* Client-to-Client */
467 message_type = "Shared File List";
468 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
469 "Message Type: %s (Code: %02d)", message_type, msg_code);
472 /* [zlib compressed] */
473 comprlen = tvb_length_remaining(tvb, offset);
475 if (slsk_decompress == TRUE){
477 tvbuff_t *uncompr_tvb = tvb_child_uncompress(tvb, tvb, offset, comprlen);
479 if (uncompr_tvb == NULL) {
480 proto_tree_add_text(slsk_tree, tvb, offset, -1,
481 "[zlib compressed packet]");
482 offset += tvb_length_remaining(tvb, offset);
483 proto_tree_add_text(slsk_tree, tvb, 0, 0,
484 "(uncompression failed !)");
487 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
488 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
490 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
491 "( compressed packet length: %d)", comprlen);
492 uncomprlen = tvb_reported_length_remaining(uncompr_tvb, 0);
493 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
494 "(uncompressed packet length: %d)", uncomprlen);
496 add_new_data_source(pinfo, uncompr_tvb,
497 "Uncompressed SoulSeek data");
498 uncompr_tvb_offset = 0;
499 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "i*")) {
501 j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
502 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
503 "Number of directories: %u", j);
504 uncompr_tvb_offset += 4;
506 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
509 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
510 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
511 uncompr_tvb_offset, 4, len,
512 "Directory #%d String Length: %u", i+1, len);
513 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
514 "Directory #%d Name: %s", i+1,
515 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
516 uncompr_tvb_offset += 4+len;
518 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
519 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
520 uncompr_tvb_offset, 4, j2,
521 "Directory #%d Number of files: %u", i+1, j2);
522 uncompr_tvb_offset += 4;
524 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
525 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb,
526 uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
527 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
528 uncompr_tvb_offset += 1;
529 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
530 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
531 uncompr_tvb, uncompr_tvb_offset, 4, len,
532 "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
533 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
534 uncompr_tvb_offset+4, len,
535 "Dir #%d File #%d Filename: %s", i+1, i2+1,
536 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
537 uncompr_tvb_offset += 4+len;
538 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
539 uncompr_tvb, uncompr_tvb_offset, 4,
540 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
541 "Dir #%d File #%d Size1: %u", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
542 uncompr_tvb_offset += 4;
543 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
544 uncompr_tvb, uncompr_tvb_offset, 4,
545 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
546 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
547 uncompr_tvb_offset += 4;
548 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
549 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
550 uncompr_tvb, uncompr_tvb_offset, 4, len,
551 "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
552 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
553 uncompr_tvb_offset+4, len,
554 "Dir #%d File #%d ext: %s", i+1, i2+1,
555 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
556 uncompr_tvb_offset += 4+len;
558 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
559 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
560 uncompr_tvb, uncompr_tvb_offset, 4,
561 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
562 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
563 uncompr_tvb_offset += 4;
565 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
566 proto_tree_add_uint_format(slsk_compr_packet_tree,
567 hf_slsk_integer, uncompr_tvb,
568 uncompr_tvb_offset, 4,
569 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
570 "Dir #%d File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, i3+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
571 uncompr_tvb_offset += 4;
572 proto_tree_add_uint_format(slsk_compr_packet_tree,
573 hf_slsk_integer, uncompr_tvb,
574 uncompr_tvb_offset, 4,
575 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
576 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
577 uncompr_tvb_offset += 4;
590 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
591 "[zlib compressed packet]");
592 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 0, 0,
593 "( compressed packet length: %d)", comprlen);
594 offset += tvb_length_remaining(tvb, offset);
600 if (check_slsk_format(tvb, offset, "isi")) {
601 /* Server-to-Client */
602 message_type = "Get User Status Reply";
603 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
604 "Message Type: %s (Code: %02d)", message_type, msg_code);
606 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
607 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
608 offset += 4+tvb_get_letohl(tvb, offset);
609 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
610 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
613 else if (check_slsk_format(tvb, offset, "is")) {
614 /* Client-to-Server */
615 message_type = "Get User Status";
616 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
617 "Message Type: %s (Code: %02d)", message_type, msg_code);
619 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
620 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
621 offset += 4+tvb_get_letohl(tvb, offset);
626 if (check_slsk_format(tvb, offset, "i*")) {
627 /* Client-to-Client */
628 message_type = "File Search Result";
629 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
630 "Message Type: %s (Code: %02d)", message_type, msg_code);
633 /* [zlib compressed] */
634 comprlen = tvb_length_remaining(tvb, offset);
636 if (slsk_decompress == TRUE){
638 tvbuff_t *uncompr_tvb = tvb_child_uncompress(tvb, tvb, offset, comprlen);
640 if (uncompr_tvb == NULL) {
641 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
642 "[zlib compressed packet]");
643 offset += tvb_length_remaining(tvb, offset);
644 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
645 "(uncompression failed !)");
648 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
649 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
651 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
652 "( compressed packet length: %d)", comprlen);
653 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
654 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
655 "(uncompressed packet length: %d)", uncomprlen);
657 add_new_data_source(pinfo, uncompr_tvb,
658 "Uncompressed SoulSeek data");
659 uncompr_tvb_offset = 0;
660 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "sii*")) {
663 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
664 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, uncompr_tvb_offset, 4, len);
665 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_username, uncompr_tvb, uncompr_tvb_offset+4, len, TRUE);
666 uncompr_tvb_offset += 4+len;
667 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_token, uncompr_tvb, uncompr_tvb_offset, 4, TRUE);
668 uncompr_tvb_offset += 4;
669 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
670 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
671 "Number of files: %d", j);
672 uncompr_tvb_offset += 4;
674 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
675 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
676 "File #%d Code: %d", i+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
677 uncompr_tvb_offset += 1;
678 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
679 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
680 uncompr_tvb_offset, 4, len,
681 "File #%d String Length: %u", i+1, len);
682 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
683 "File #%d Filename: %s", i+1,
684 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
685 uncompr_tvb_offset += 4+len;
686 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
687 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
688 "File #%d Size1: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
689 uncompr_tvb_offset += 4;
690 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
691 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
692 "File #%d Size2: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
693 uncompr_tvb_offset += 4;
694 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
695 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
696 uncompr_tvb_offset, 4, len,
697 "File #%d String Length: %d", i+1, len);
698 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
699 "File #%d ext: %s", i+1,
700 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
701 uncompr_tvb_offset += 4+len;
703 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
704 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
705 uncompr_tvb_offset, 4, j,
706 "File #%d Number of attributes: %d", i+1, j);
707 uncompr_tvb_offset += 4;
709 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
710 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
711 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
712 "File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
713 uncompr_tvb_offset += 4;
714 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
715 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
716 "File #%d Attr #%d value: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
717 uncompr_tvb_offset += 4;
724 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
725 "Free upload slots: %s (Byte: %d)", val_to_str(tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset), slsk_yes_no, "Unknown"), tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
726 uncompr_tvb_offset += 1;
727 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
728 "Upload speed: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
729 uncompr_tvb_offset += 4;
730 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
731 "In Queue: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
732 uncompr_tvb_offset += 4;
736 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
737 "[zlib compressed packet]");
738 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
739 "( compressed packet length: %d)", comprlen);
740 offset += tvb_length_remaining(tvb, offset);
746 if (check_slsk_format(tvb, offset, "isss")) {
747 /* Server-to-Client */
748 message_type = "Say ChatRoom";
749 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
750 "Message Type: %s (Code: %02d)", message_type, msg_code);
752 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
753 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
754 offset += 4+tvb_get_letohl(tvb, offset);
755 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
756 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
757 offset += 4+tvb_get_letohl(tvb, offset);
758 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
759 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
760 offset += 4+tvb_get_letohl(tvb, offset);
762 else if (check_slsk_format(tvb, offset, "iss")) {
763 /* Client-to-Server */
764 message_type = "Say ChatRoom";
765 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
766 "Message Type: %s (Code: %02d)", message_type, msg_code);
768 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
769 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
770 offset += 4+tvb_get_letohl(tvb, offset);
771 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
772 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
773 offset += 4+tvb_get_letohl(tvb, offset);
778 if (check_slsk_format(tvb, offset, "is")) {
779 /* Client-to-Server */
780 message_type = "Join/Add Room";
781 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
782 "Message Type: %s (Code: %02d)", message_type, msg_code);
784 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
785 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
786 offset += 4+tvb_get_letohl(tvb, offset);
788 else if (check_slsk_format(tvb, offset, "isi*")) {
789 /* Server-to-Client */
790 message_type = "Join Room User List";
791 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
792 "Message Type: %s (Code: %02d)", message_type, msg_code);
794 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
795 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
796 offset += 4+tvb_get_letohl(tvb, offset);
797 i=0; j = tvb_get_letohl(tvb, offset);
798 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
801 if (check_slsk_format(tvb, offset, "s*")) {
804 len = tvb_get_letohl(tvb, offset);
805 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
806 "String #%d Length: %d", i+1, len);
807 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
808 "User #%d: %s", i+1, tvb_format_text(tvb, offset+4, len));
813 if (check_slsk_format(tvb, offset, "i*")) {
814 i=0; j = tvb_get_letohl(tvb, offset);
815 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
818 if (check_slsk_format(tvb, offset, "i*")) {
819 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
820 "Status of User #%d: %s (Code: %d)", i+1, val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
826 if (check_slsk_format(tvb, offset, "i*")) {
827 i=0; j = tvb_get_letohl(tvb, offset);
828 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
831 if (check_slsk_format(tvb, offset, "iiiii*")) {
832 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
833 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
835 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
836 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
838 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
839 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
841 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
842 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
844 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
845 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
851 if (check_slsk_format(tvb, offset, "i*")) {
852 i=0; j = tvb_get_letohl(tvb, offset);
853 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
854 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
857 if (check_slsk_format(tvb, offset, "i*")) {
858 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
859 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
869 if (check_slsk_format(tvb, offset, "is")) {
870 /* Client-to-Server & Server-to-Client */
871 message_type = "Leave Room";
872 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
873 "Message Type: %s (Code: %02d)", message_type, msg_code);
875 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
876 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
877 offset += 4+tvb_get_letohl(tvb, offset);
879 else if (check_slsk_format(tvb, offset, "i")) {
880 /* Client-to-Client */
881 message_type = "User Info Request";
882 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
883 "Message Type: %s (Code: %02d)", message_type, msg_code);
889 if (check_slsk_format(tvb, offset, "issiiiiiii")) {
890 /* Server-to-Client */
891 message_type = "User Joined Room";
892 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
893 "Message Type: %s (Code: %02d)", message_type, msg_code);
895 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
896 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
897 offset += 4+tvb_get_letohl(tvb, offset);
898 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
899 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
900 offset += 4+tvb_get_letohl(tvb, offset);
901 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
903 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
905 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
907 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
909 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
911 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
913 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
916 else if (check_slsk_format(tvb, offset, "isbiib") || check_slsk_format(tvb, offset, "isbsiib")) {
917 /* Client-to-Client */
918 message_type = "User Info Reply";
919 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
920 "Message Type: %s (Code: %02d)", message_type, msg_code);
922 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
923 proto_tree_add_item(slsk_tree, hf_slsk_user_description, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
924 offset += 4+tvb_get_letohl(tvb, offset);
925 proto_tree_add_uint_format(slsk_tree, hf_slsk_picture_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
926 "Picture exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
928 if ( tvb_get_guint8(tvb, offset -1 ) == 1 ) {
929 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
930 "Picture Size: %d", tvb_get_letohl(tvb, offset));
931 proto_tree_add_item(slsk_tree, hf_slsk_picture, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
932 offset += 4+tvb_get_letohl(tvb, offset);
934 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
936 proto_tree_add_uint(slsk_tree, hf_slsk_queued_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
938 proto_tree_add_uint_format(slsk_tree, hf_slsk_slots_available, tvb, offset, 1, tvb_get_guint8(tvb, offset),
939 "Upload Slots available: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
945 if (check_slsk_format(tvb, offset, "iss")) {
946 /* Server-to-Client */
947 message_type = "User Left Room";
948 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
949 "Message Type: %s (Code: %02d)", message_type, msg_code);
951 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
952 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
953 offset += 4+tvb_get_letohl(tvb, offset);
954 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
955 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
956 offset += 4+tvb_get_letohl(tvb, offset);
961 if (check_slsk_format(tvb, offset, "iiss")) {
962 /* Client-to-Server */
965 message_type = "Connect To Peer";
966 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
967 "Message Type: %s (Code: %02d)", message_type, msg_code);
969 proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
971 len = tvb_get_letohl(tvb, offset);
972 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
973 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
975 len = tvb_get_letohl(tvb, offset);
976 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
977 str = tvb_get_ephemeral_string(tvb, offset+4, len);
978 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
979 "Connection Type: %s (Char: %s)", connection_type(str),
980 format_text(str, len));
983 else if (check_slsk_format(tvb, offset, "issiii")) {
984 /* Server-to-Client */
987 message_type = "Connect To Peer";
988 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
989 "Message Type: %s (Code: %02d)", message_type, msg_code);
991 len = tvb_get_letohl(tvb, offset);
992 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
993 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
995 len = tvb_get_letohl(tvb, offset);
996 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
997 str = tvb_get_ephemeral_string(tvb, offset+4, len);
998 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
999 "Connection Type: %s (Char: %s)", connection_type(str),
1000 format_text(str, len));
1002 proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
1004 proto_tree_add_item(slsk_tree, hf_slsk_port, tvb, offset, 4, TRUE);
1006 proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
1012 if (check_slsk_format(tvb, offset, "iss")) {
1013 /* Client-to-Server */
1014 message_type = "Message User Send";
1015 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1016 "Message Type: %s (Code: %02d)", message_type, msg_code);
1018 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1019 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1020 offset += 4+tvb_get_letohl(tvb, offset);
1021 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1022 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1023 offset += 4+tvb_get_letohl(tvb, offset);
1025 else if (check_slsk_format(tvb, offset, "iiiss")) {
1026 /* Server-to-Client */
1027 message_type = "Message User Receive";
1028 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1029 "Message Type: %s (Code: %02d)", message_type, msg_code);
1031 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1033 proto_tree_add_uint(slsk_tree, hf_slsk_timestamp, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1035 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1036 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1037 offset += 4+tvb_get_letohl(tvb, offset);
1038 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1039 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1040 offset += 4+tvb_get_letohl(tvb, offset);
1045 if (check_slsk_format(tvb, offset, "ii")) {
1046 /* Client-to-Server */
1047 message_type = "Message User Receive Ack";
1048 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1049 "Message Type: %s (Code: %02d)", message_type, msg_code);
1051 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1057 if (check_slsk_format(tvb, offset, "iis")) {
1058 /* Client-to-Server */
1059 message_type = "File Search";
1060 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1061 "Message Type: %s (Code: %02d)", message_type, msg_code);
1063 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1065 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1066 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1067 offset += 4+tvb_get_letohl(tvb, offset);
1072 if (check_slsk_format(tvb, offset, "ii")) {
1073 /* Client-to-Server */
1074 message_type = "Set Status";
1075 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1076 "Message Type: %s (Code: %02d)", message_type, msg_code);
1078 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1079 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1085 if (check_slsk_format(tvb, offset, "i")) {
1086 /* Client-to-Server */
1087 message_type = "Ping";
1088 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1089 "Message Type: %s (Code: %02d)", message_type, msg_code);
1095 if (check_slsk_format(tvb, offset, "isi")) {
1096 /* Client-to-Server */
1097 message_type = "Update Upload Speed";
1098 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1099 "Message Type: %s (Code: %02d)", message_type, msg_code);
1101 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1102 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1103 offset += 4+tvb_get_letohl(tvb, offset);
1104 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1110 if (check_slsk_format(tvb, offset, "iii")) {
1111 /* Client-to-Server */
1112 message_type = "Shared Files & Folders ";
1113 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1114 "Message Type: %s (Code: %02d)", message_type, msg_code);
1116 proto_tree_add_uint(slsk_tree, hf_slsk_folder_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1118 proto_tree_add_uint(slsk_tree, hf_slsk_file_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1124 if (check_slsk_format(tvb, offset, "isiiiii")) {
1125 /* Server-to-Client */
1126 message_type = "Get User Stats Reply";
1127 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1128 "Message Type: %s (Code: %02d)", message_type, msg_code);
1130 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1131 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1132 offset += 4+tvb_get_letohl(tvb, offset);
1133 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1135 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1137 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1139 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1141 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1144 else if (check_slsk_format(tvb, offset, "is")) {
1145 /* Client-to-Client */
1146 /* Client-to-Server: send after login successful */
1147 message_type = "Get User Stats";
1148 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1149 "Message Type: %s (Code: %02d)", message_type, msg_code);
1151 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1152 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1153 offset += 4+tvb_get_letohl(tvb, offset);
1155 else if (check_slsk_format(tvb, offset, "iis")) {
1156 /* Client-to-Client */
1157 message_type = "Folder Contents Request";
1158 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1159 "Message Type: %s (Code: %02d)", message_type, msg_code);
1161 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1163 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1164 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1165 offset += 4+tvb_get_letohl(tvb, offset);
1170 if (check_slsk_format(tvb, offset, "i*")) {
1171 /* Client-to-Client */
1172 message_type = "Folder Contents Response";
1173 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1174 "Message Type: %s (Code: %02d)", message_type, msg_code);
1177 /* [zlib compressed] */
1178 comprlen = tvb_length_remaining(tvb, offset);
1180 if (slsk_decompress == TRUE){
1182 tvbuff_t *uncompr_tvb = tvb_child_uncompress(tvb, tvb, offset, comprlen);
1184 if (uncompr_tvb == NULL) {
1185 proto_tree_add_text(slsk_tree, tvb, offset, -1,
1186 "[zlib compressed packet]");
1187 offset += tvb_length_remaining(tvb, offset);
1188 proto_tree_add_text(slsk_tree, tvb, 0, 0,
1189 "[uncompression failed !]");
1192 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
1193 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
1195 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1196 "[compressed packet length: %d]", comprlen);
1197 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
1198 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1199 "[uncompressed packet length: %d]", uncomprlen);
1201 add_new_data_source(pinfo, uncompr_tvb,
1202 "Uncompressed SoulSeek data");
1203 uncompr_tvb_offset = 0;
1204 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "isi*")) {
1207 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1208 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1209 "Token: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1210 uncompr_tvb_offset += 4;
1211 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1212 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1213 uncompr_tvb, uncompr_tvb_offset, 4, len,
1214 "Directory Name String Length: %u", len);
1215 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1216 "Directory Name: %s", tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1217 uncompr_tvb_offset += 4+len;
1219 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1220 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1221 uncompr_tvb_offset, 4, j,
1222 "Number of directories: %d", j);
1223 uncompr_tvb_offset += 4;
1225 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
1226 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1227 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1228 uncompr_tvb, uncompr_tvb_offset, 4, len,
1229 "Directory #%d Name String Length: %u", i+1, len);
1230 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1231 "Directory #%d Name: %s", i+1,
1232 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1233 uncompr_tvb_offset += 4+len;
1235 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1236 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1237 uncompr_tvb_offset, 4, j2,
1238 "Directory #%d Number of files: %d", i+1, j2);
1239 uncompr_tvb_offset += 4;
1241 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
1242 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte,
1243 uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
1244 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
1245 uncompr_tvb_offset += 1;
1246 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1247 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1248 uncompr_tvb, uncompr_tvb_offset, 4, len,
1249 "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1250 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1251 uncompr_tvb_offset+4, len,
1252 "Dir #%d File #%d Filename: %s", i+1, i2+1,
1253 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1254 uncompr_tvb_offset += 4+len;
1255 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1256 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1257 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1258 uncompr_tvb_offset += 4;
1259 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1260 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1261 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1262 uncompr_tvb_offset += 4;
1263 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1264 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1265 uncompr_tvb, uncompr_tvb_offset, 4, len,
1266 "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1267 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1268 uncompr_tvb_offset+4, len,
1269 "Dir #%d File #%d ext: %s", i+1, i2+1,
1270 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1271 uncompr_tvb_offset += 4+len;
1273 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1274 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1275 uncompr_tvb_offset, 4, j3,
1276 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, j3);
1277 uncompr_tvb_offset += 4;
1279 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
1280 proto_tree_add_uint_format(slsk_compr_packet_tree,
1281 hf_slsk_integer, uncompr_tvb,
1282 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1283 "Dir #%d File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, i3+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1284 uncompr_tvb_offset += 4;
1285 proto_tree_add_uint_format(slsk_compr_packet_tree,
1286 hf_slsk_integer, uncompr_tvb,
1287 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1288 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1289 uncompr_tvb_offset += 4;
1302 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1303 "[zlib compressed packet]");
1304 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1305 "( compressed packet length: %d)", comprlen);
1306 offset += tvb_length_remaining(tvb, offset);
1312 if (check_slsk_format(tvb, offset, "isi")) {
1313 /* Server-to-Client */
1314 message_type = "Queued Downloads";
1315 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1316 "Message Type: %s (Code: %02d)", message_type, msg_code);
1318 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1319 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1320 offset += 4+tvb_get_letohl(tvb, offset);
1321 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1324 else if (check_slsk_format(tvb, offset, "iiis") || check_slsk_format(tvb, offset, "iiisii")) {
1325 /* Client-to-Client */
1326 message_type = "Transfer Request";
1327 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1328 "Message Type: %s (Code: %02d)", message_type, msg_code);
1330 i = tvb_get_letohl(tvb, offset);
1331 proto_tree_add_uint_format(slsk_tree, hf_slsk_transfer_direction, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1332 "Transfer Direction: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_transfer_direction, "Unknown"), tvb_get_letohl(tvb, offset));
1334 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1336 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1337 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1338 offset += 4+tvb_get_letohl(tvb, offset);
1340 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1342 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1350 if (check_slsk_format(tvb, offset, "iibs") || check_slsk_format(tvb, offset, "iibii") || check_slsk_format(tvb, offset, "iib")) {
1351 /* Client-to-Client */
1352 message_type = "Transfer Response";
1353 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1354 "Message Type: %s (Code: %02d)", message_type, msg_code);
1356 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1358 i = tvb_get_guint8(tvb, offset);
1359 proto_tree_add_uint_format(slsk_tree, hf_slsk_allowed, tvb, offset, 1, tvb_get_guint8(tvb, offset),
1360 "Download allowed: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
1363 if ( tvb_length_remaining(tvb, offset) == 8 ) {
1364 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1366 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1370 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1371 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1372 offset += 4+tvb_get_letohl(tvb, offset);
1378 if (check_slsk_format(tvb, offset, "is")) {
1379 /* Client-to-Client */
1380 message_type = "Placehold Upload";
1381 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1382 "Message Type: %s (Code: %02d)", message_type, msg_code);
1384 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1385 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1386 offset += 4+tvb_get_letohl(tvb, offset);
1391 if (check_slsk_format(tvb, offset, "is")) {
1392 /* Client-to-Client */
1393 message_type = "Queue Upload";
1394 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1395 "Message Type: %s (Code: %02d)", message_type, msg_code);
1397 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1398 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1399 offset += 4+tvb_get_letohl(tvb, offset);
1404 if (check_slsk_format(tvb, offset, "isi")) {
1405 /* Client-to-Client */
1406 message_type = "Place In Queue";
1407 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1408 "Message Type: %s (Code: %02d)", message_type, msg_code);
1410 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1411 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1412 offset += 4+tvb_get_letohl(tvb, offset);
1413 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1419 if (check_slsk_format(tvb, offset, "is")) {
1420 /* Client-to-Client */
1421 message_type = "Upload Failed";
1422 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1423 "Message Type: %s (Code: %02d)", message_type, msg_code);
1425 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1426 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1427 offset += 4+tvb_get_letohl(tvb, offset);
1432 if (check_slsk_format(tvb, offset, "is")) {
1433 /* Client-to-Server */
1434 message_type = "Make Own Recommendation";
1435 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1436 "Message Type: %s (Code: %02d)", message_type, msg_code);
1438 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1439 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1440 offset += 4+tvb_get_letohl(tvb, offset);
1442 else if (check_slsk_format(tvb, offset, "isi")) {
1443 /* Client-to-Server */
1444 message_type = "Remove Own Recommendation";
1445 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1446 "Message Type: %s (Code: %02d)", message_type, msg_code);
1448 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1449 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1450 offset += 4+tvb_get_letohl(tvb, offset);
1451 proto_tree_add_uint(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1454 else if (check_slsk_format(tvb, offset, "iss")) {
1455 /* Client-to-Client */
1456 message_type = "Queue Failed";
1457 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1458 "Message Type: %s (Code: %02d)", message_type, msg_code);
1460 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1461 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1462 offset += 4+tvb_get_letohl(tvb, offset);
1463 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1464 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1465 offset += 4+tvb_get_letohl(tvb, offset);
1470 if (check_slsk_format(tvb, offset, "is")) {
1471 /* Client-to-Server: "Add Things I like" */
1472 /* Client-to-Client: "Place In Queue Request" */
1473 message_type = "Add Things I like / Place In Queue Request";
1474 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1475 "Message Type: %s (Code: %02d)", message_type, msg_code);
1477 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1478 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1479 offset += 4+tvb_get_letohl(tvb, offset);
1484 if (check_slsk_format(tvb, offset, "is")) {
1485 /* Client-to-Server */
1486 message_type = "Remove Things I like";
1487 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1488 "Message Type: %s (Code: %02d)", message_type, msg_code);
1490 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1491 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1492 offset += 4+tvb_get_letohl(tvb, offset);
1497 if (check_slsk_format(tvb, offset, "i")) {
1498 /* Client-to-Server */
1499 message_type = "Get Recommendations";
1500 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1501 "Message Type: %s (Code: %02d)", message_type, msg_code);
1504 else if (check_slsk_format(tvb, offset, "ii*")) {
1505 /* Server-to-Client */
1506 message_type = "Get Recommendations Reply";
1507 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1508 "Message Type: %s (Code: %02d)", message_type, msg_code);
1510 i=0; j = tvb_get_letohl(tvb, offset);
1511 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1512 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1515 if (check_slsk_format(tvb, offset, "si*")) {
1518 len = tvb_get_letohl(tvb, offset);
1519 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1520 "String #%d Length: %d", i+1, len);
1521 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1522 "Recommendation #%d: %s", i+1,
1523 tvb_format_text(tvb, offset+4, len));
1525 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1526 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1535 if (check_slsk_format(tvb, offset, "i")) {
1536 /* Client-to-Server */
1537 message_type = "Type 55";
1538 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1539 "Message Type: %s (Code: %02d)", message_type, msg_code);
1545 if (check_slsk_format(tvb, offset, "i")) {
1546 /* Client-to-Server */
1547 message_type = "Get Global Rankings";
1548 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1549 "Message Type: %s (Code: %02d)", message_type, msg_code);
1552 else if (check_slsk_format(tvb, offset, "ii*")) {
1553 /* Server-to-Client */
1554 message_type = "Get Global Rankings Reply";
1555 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1556 "Message Type: %s (Code: %02d)", message_type, msg_code);
1558 i=0; j = tvb_get_letohl(tvb, offset);
1559 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1560 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1563 if (check_slsk_format(tvb, offset, "si*")) {
1566 len = tvb_get_letohl(tvb, offset);
1567 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1568 "String #%d Length: %d", i+1, len);
1569 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1570 "Recommendation #%d: %s", i+1,
1571 tvb_format_text(tvb, offset+4, len));
1573 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1574 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1583 if (check_slsk_format(tvb, offset, "is")) {
1584 /* Client-to-Server */
1585 message_type = "Get User Recommendations";
1586 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1587 "Message Type: %s (Code: %02d)", message_type, msg_code);
1589 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1590 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1591 offset += 4+tvb_get_letohl(tvb, offset);
1593 else if (check_slsk_format(tvb, offset, "isi*")) {
1594 /* Server-to-Client */
1595 message_type = "Get User Recommendations Reply";
1596 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1597 "Message Type: %s (Code: %02d)", message_type, msg_code);
1599 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1600 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1601 offset += 4+tvb_get_letohl(tvb, offset);
1602 i=0; j = tvb_get_letohl(tvb, offset);
1603 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1604 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1607 if (check_slsk_format(tvb, offset, "s*")) {
1610 len = tvb_get_letohl(tvb, offset);
1611 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1612 "String #%d Length: %d", i+1, len);
1613 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1614 "Recommendation #%d: %s", i+1,
1615 tvb_format_text(tvb, offset+4, len));
1624 if (check_slsk_format(tvb, offset, "isi*")) {
1625 /* Client-to-Server */
1626 message_type = "Admin Command";
1627 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1628 "Message Type: %s (Code: %02d)", message_type, msg_code);
1630 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1631 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1632 offset += 4+tvb_get_letohl(tvb, offset);
1633 i=0; j = tvb_get_letohl(tvb, offset);
1634 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1635 "Number of Strings: %d", tvb_get_letohl(tvb, offset));
1638 if (check_slsk_format(tvb, offset, "s*")) {
1641 len = tvb_get_letohl(tvb, offset);
1642 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1643 "String #%d Length: %d", i+1, len);
1644 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1645 "String #%d: %s", i+1,
1646 tvb_format_text(tvb, offset+4, len));
1655 if (check_slsk_format(tvb, offset, "isii")) {
1656 /* Client-to-Server & Server-to-Client */
1657 message_type = "Place In Line Response";
1658 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1659 "Message Type: %s (Code: %02d)", message_type, msg_code);
1661 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1662 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1663 offset += 4+tvb_get_letohl(tvb, offset);
1664 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1666 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1672 if (check_slsk_format(tvb, offset, "is")) {
1673 /* Server-to-Client */
1674 message_type = "Room Added";
1675 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1676 "Message Type: %s (Code: %02d)", message_type, msg_code);
1678 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1679 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1680 offset += 4+tvb_get_letohl(tvb, offset);
1685 if (check_slsk_format(tvb, offset, "is")) {
1686 /* Server-to-Client */
1687 message_type = "Room Removed";
1688 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1689 "Message Type: %s (Code: %02d)", message_type, msg_code);
1691 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1692 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1693 offset += 4+tvb_get_letohl(tvb, offset);
1698 if (check_slsk_format(tvb, offset, "i")) {
1699 /* Client-to-Server */
1700 message_type = "Room List Request";
1701 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1702 "Message Type: %s (Code: %02d)", message_type, msg_code);
1705 else if (check_slsk_format(tvb, offset, "ii*")) {
1706 /* Server-to-Client */
1707 message_type = "Room List";
1708 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1709 "Message Type: %s (Code: %02d)", message_type, msg_code);
1711 i=0; j = tvb_get_letohl(tvb, offset);
1712 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1715 if (check_slsk_format(tvb, offset, "s*")) {
1718 len = tvb_get_letohl(tvb, offset);
1719 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1720 "String #%d Length: %d", i+1, len);
1721 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1722 "Room #%d: %s", i+1,
1723 tvb_format_text(tvb, offset+4, len));
1728 if (check_slsk_format(tvb, offset, "i*")) {
1730 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1733 if (check_slsk_format(tvb, offset, "i*")) {
1734 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1735 "Users in Room #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1745 if (check_slsk_format(tvb, offset, "isissiii")) {
1746 /* Server-to-Client */
1747 message_type = "Exact File Search";
1748 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1749 "Message Type: %s (Code: %02d)", message_type, msg_code);
1751 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1752 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1753 offset += 4+tvb_get_letohl(tvb, offset);
1754 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1756 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1757 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1758 offset += 4+tvb_get_letohl(tvb, offset);
1759 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1760 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1761 offset += 4+tvb_get_letohl(tvb, offset);
1762 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 16, 0,
1766 else if (check_slsk_format(tvb, offset, "iissiiib")) {
1767 /* Client-to-Server */
1768 message_type = "Exact File Search";
1769 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1770 "Message Type: %s (Code: %02d)", message_type, msg_code);
1772 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1774 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1775 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1776 offset += 4+tvb_get_letohl(tvb, offset);
1777 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1778 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1779 offset += 4+tvb_get_letohl(tvb, offset);
1780 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 13, 0,
1787 if (check_slsk_format(tvb, offset, "is")) {
1788 /* Server-to-Client */
1789 message_type = "Admin Message";
1790 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1791 "Message Type: %s (Code: %02d)", message_type, msg_code);
1793 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1794 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1795 offset += 4+tvb_get_letohl(tvb, offset);
1800 if (check_slsk_format(tvb, offset, "i")) {
1801 /* Client-to-Server */
1802 message_type = "Global User List Request";
1803 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1804 "Message Type: %s (Code: %02d)", message_type, msg_code);
1807 else if (check_slsk_format(tvb, offset, "isi*")) { /* same as case 14 */
1808 /* Server-to-Client */
1809 message_type = "Global User List";
1810 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1811 "Message Type: %s (Code: %02d)", message_type, msg_code);
1813 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1814 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1815 offset += 4+tvb_get_letohl(tvb, offset);
1816 i=0; j = tvb_get_letohl(tvb, offset);
1817 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1820 if (check_slsk_format(tvb, offset, "s*")) {
1823 len = tvb_get_letohl(tvb, offset);
1824 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1825 "String #%d Length: %d", i+1, len);
1826 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1827 "User #%d: %s", i+1,
1828 tvb_format_text(tvb, offset+4, len));
1833 if (check_slsk_format(tvb, offset, "i*")) {
1834 i=0; j = tvb_get_letohl(tvb, offset);
1835 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, j);
1838 if (check_slsk_format(tvb, offset, "i*")) {
1839 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1840 "Status of User #%d: %s (Code: %d)", i+1, val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1846 if (check_slsk_format(tvb, offset, "i*")) {
1847 i=0; j = tvb_get_letohl(tvb, offset);
1848 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1851 if (check_slsk_format(tvb, offset, "iiiii*")) {
1852 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1853 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1855 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1856 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1858 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1859 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1861 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1862 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1864 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1865 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1871 if (check_slsk_format(tvb, offset, "i*")) {
1872 i=0; j = tvb_get_letohl(tvb, offset);
1873 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1874 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
1877 if (check_slsk_format(tvb, offset, "i*")) {
1878 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1879 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1889 if (check_slsk_format(tvb, offset, "isiiiis")) {
1890 message_type = "Tunneled Message";
1891 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1892 "Message Type: %s (Code: %02d)", message_type, msg_code);
1894 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1895 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1896 offset += 4+tvb_get_letohl(tvb, offset);
1897 proto_tree_add_uint(slsk_tree, hf_slsk_code, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1899 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1901 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
1903 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1905 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1906 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1907 offset += 4+tvb_get_letohl(tvb, offset);
1912 if (check_slsk_format(tvb, offset, "i")) {
1913 /* Client-to-Server */
1914 message_type = "Privileged User List Request";
1915 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1916 "Message Type: %s (Code: %02d)", message_type, msg_code);
1919 else if (check_slsk_format(tvb, offset, "ii*")) {
1920 /* Server-to-Client */
1921 message_type = "Privileged User List";
1922 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1923 "Message Type: %s (Code: %02d)", message_type, msg_code);
1925 i=0; j = tvb_get_letohl(tvb, offset);
1926 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1927 "Number of Privileged Users: %d", tvb_get_letohl(tvb, offset));
1930 if (check_slsk_format(tvb, offset, "s*")) {
1933 len = tvb_get_letohl(tvb, offset);
1934 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1935 "String #%d Length: %d", i+1, len);
1936 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1937 "User #%d: %s", i+1,
1938 tvb_format_text(tvb, offset+4, len));
1947 if (check_slsk_format(tvb, offset, "ib")) {
1948 /* Client-to-Server */
1949 message_type = "Get Parent List";
1950 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1951 "Message Type: %s (Code: %02d)", message_type, msg_code);
1953 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1959 if (check_slsk_format(tvb, offset, "ii")) {
1960 /* Client-to-Server */
1961 message_type = "Type 73";
1962 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1963 "Message Type: %s (Code: %02d)", message_type, msg_code);
1965 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1971 if (check_slsk_format(tvb, offset, "ii")) {
1972 /* Server-to-Client */
1973 message_type = "Parent Min Speed";
1974 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1975 "Message Type: %s (Code: %02d)", message_type, msg_code);
1977 proto_tree_add_uint(slsk_tree, hf_slsk_parent_min_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1983 if (check_slsk_format(tvb, offset, "ii")) {
1984 /* Server-to-Client */
1985 message_type = "Parent Speed Connection Ratio";
1986 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1987 "Message Type: %s (Code: %02d)", message_type, msg_code);
1989 proto_tree_add_uint(slsk_tree, hf_slsk_parent_speed_connection_ratio, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1995 if (check_slsk_format(tvb, offset, "ii")) {
1996 /* Server-to-Client */
1997 message_type = "Parent Inactivity Before Disconnect";
1998 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1999 "Message Type: %s (Code: %02d)", message_type, msg_code);
2001 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_parent_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2007 if (check_slsk_format(tvb, offset, "ii")) {
2008 /* Server-to-Client */
2009 message_type = "Server Inactivity Before Disconnect";
2010 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2011 "Message Type: %s (Code: %02d)", message_type, msg_code);
2013 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_server_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2019 if (check_slsk_format(tvb, offset, "ii")) {
2020 /* Server-to-Client */
2021 message_type = "Nodes In Cache Before Disconnect";
2022 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2023 "Message Type: %s (Code: %02d)", message_type, msg_code);
2025 proto_tree_add_uint(slsk_tree, hf_slsk_nodes_in_cache_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2031 if (check_slsk_format(tvb, offset, "ii")) {
2032 /* Server-to-Client */
2033 message_type = "Seconds Before Ping Children";
2034 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2035 "Message Type: %s (Code: %02d)", message_type, msg_code);
2037 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_before_ping_children, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2043 if (check_slsk_format(tvb, offset, "is")) {
2044 /* Server-to-Client */
2045 message_type = "Add To Privileged";
2046 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2047 "Message Type: %s (Code: %02d)", message_type, msg_code);
2049 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2050 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2051 offset += 4+tvb_get_letohl(tvb, offset);
2056 if (check_slsk_format(tvb, offset, "i")) {
2057 /* Client-to-Server */
2058 message_type = "Check Privileges";
2059 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2060 "Message Type: %s (Code: %02d)", message_type, msg_code);
2063 else if (check_slsk_format(tvb, offset, "ii")) {
2064 /* Server-to-Client */
2065 message_type = "Check Privileges Reply";
2066 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2067 "Message Type: %s (Code: %02d)", message_type, msg_code);
2069 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_days, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2075 if (check_slsk_format(tvb, offset, "ibisis")) {
2076 /* Server-to-Client */
2077 message_type = "Embedded Message";
2078 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2079 "Message Type: %s (Code: %02d)", message_type, msg_code);
2081 if ( tvb_get_guint8(tvb, offset) == 3 ){
2082 /* Client-to-Client */
2083 message_type = "Distributed Search";
2084 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2085 "Embedded Message Type: %s (Byte: %d)", message_type, 3);
2087 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2089 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2090 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2091 offset += 4+tvb_get_letohl(tvb, offset);
2092 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2094 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2095 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2096 offset += 4+tvb_get_letohl(tvb, offset);
2102 if (check_slsk_format(tvb, offset, "ib")) {
2103 /* Client-to-Server */
2104 message_type = "Become Parent";
2105 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2106 "Message Type: %s (Code: %02d)", message_type, msg_code);
2108 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
2114 if (check_slsk_format(tvb, offset, "ii*")) {
2115 /* Server-to-Client */
2116 message_type = "Random Parent Addresses";
2117 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2118 "Message Type: %s (Code: %02d)", message_type, msg_code);
2120 i=0; j = tvb_get_letohl(tvb, offset);
2121 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2122 "Number of Parent Addresses: %d", tvb_get_letohl(tvb, offset));
2125 if (check_slsk_format(tvb, offset, "sii*")) {
2128 len = tvb_get_letohl(tvb, offset);
2129 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2130 "String #%d Length: %d", i+1, len);
2131 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2132 "User #%d: %s", i+1,
2133 tvb_format_text(tvb, offset+4, len));
2135 proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
2137 proto_tree_add_uint_format(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2138 "Port Number #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2147 if (check_slsk_format(tvb, offset, "iis")) {
2148 /* Server-to-Client */
2149 message_type = "Send Wishlist Entry";
2150 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2151 "Message Type: %s (Code: %02d)", message_type, msg_code);
2153 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2155 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2156 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2157 offset += 4+tvb_get_letohl(tvb, offset);
2162 if (check_slsk_format(tvb, offset, "ii")) {
2163 /* Server-to-Client */
2164 message_type = "Type 104";
2165 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2166 "Message Type: %s (Code: %02d)", message_type, msg_code);
2168 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2174 if (check_slsk_format(tvb, offset, "i")) {
2175 /* Client-to-Server */
2176 message_type = "Get Similar Users";
2177 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2178 "Message Type: %s (Code: %02d)", message_type, msg_code);
2181 else if (check_slsk_format(tvb, offset, "ii*")) {
2182 /* Server-to-Client */
2183 message_type = "Get Similar Users Reply";
2184 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2185 "Message Type: %s (Code: %02d)", message_type, msg_code);
2187 i=0; j = tvb_get_letohl(tvb, offset);
2188 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2189 "Number of Users: %d", tvb_get_letohl(tvb, offset));
2192 if (check_slsk_format(tvb, offset, "si*")) {
2195 len = tvb_get_letohl(tvb, offset);
2196 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2197 "String #%d Length: %d", i+1, len);
2198 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2199 "User #%d: %s", i+1,
2200 tvb_format_text(tvb, offset+4, len));
2202 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2203 "Same Recommendations #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2212 if (check_slsk_format(tvb, offset, "is")) {
2213 /* Client-to-Server */
2214 message_type = "Get Recommendations for Item";
2215 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2216 "Message Type: %s (Code: %02d)", message_type, msg_code);
2218 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2219 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2220 offset += 4+tvb_get_letohl(tvb, offset);
2222 else if (check_slsk_format(tvb, offset, "isi*")) {
2223 /* Server-to-Client */
2224 message_type = "Get Recommendations for Item Reply";
2225 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2226 "Message Type: %s (Code: %02d)", message_type, msg_code);
2228 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2229 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2230 offset += 4+tvb_get_letohl(tvb, offset);
2231 i=0; j = tvb_get_letohl(tvb, offset);
2232 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2233 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2236 if (check_slsk_format(tvb, offset, "si*")) {
2239 len = tvb_get_letohl(tvb, offset);
2240 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2241 "String #%d Length: %d", i+1, len);
2242 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2243 "Recommendation #%d: %s", i+1,
2244 tvb_format_text(tvb, offset+4, len));
2246 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2247 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2256 if (check_slsk_format(tvb, offset, "is")) {
2257 /* Client-to-Server */
2258 message_type = "Get Similar Users for Item";
2259 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2260 "Message Type: %s (Code: %02d)", message_type, msg_code);
2262 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2263 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2264 offset += 4+tvb_get_letohl(tvb, offset);
2266 else if (check_slsk_format(tvb, offset, "isi*")) {
2267 /* Server-to-Client */
2268 message_type = "Get Similar Users for Item Reply";
2269 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2270 "Message Type: %s (Code: %02d)", message_type, msg_code);
2272 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2273 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2274 offset += 4+tvb_get_letohl(tvb, offset);
2275 i=0; j = tvb_get_letohl(tvb, offset);
2276 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2277 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2280 if (check_slsk_format(tvb, offset, "s*")) {
2283 len = tvb_get_letohl(tvb, offset);
2284 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2285 "String #%d Length: %d", i+1, len);
2286 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2287 "Username #%d: %s", i+1,
2288 tvb_format_text(tvb, offset+4, len));
2297 if (check_slsk_format(tvb, offset, "iis")) {
2298 /* Client-to-Server */
2299 message_type = "Can't Connect To Peer";
2300 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2301 "Message Type: %s (Code: %02d)", message_type, msg_code);
2303 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2305 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2306 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2307 offset += 4+tvb_get_letohl(tvb, offset);
2309 else if (check_slsk_format(tvb, offset, "ii")) {
2310 /* Server-to-Client */
2311 message_type = "Can't Connect To Peer";
2312 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2313 "Message Type: %s (Code: %02d)", message_type, msg_code);
2315 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2321 if (check_slsk_format(tvb, offset, "bisis")) {
2322 if ( tvb_get_guint8(tvb, offset) == 3 ){
2323 /* Client-to-Client */
2324 message_type = "Distributed Search";
2325 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2326 "Message Type: %s (Byte: %d)", message_type, 3);
2328 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2330 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2331 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2332 offset += 4+tvb_get_letohl(tvb, offset);
2333 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2335 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2336 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2337 offset += 4+tvb_get_letohl(tvb, offset);
2340 else if (check_slsk_format(tvb, offset, "bssi")) {
2341 if ( tvb_get_guint8(tvb, offset) == 1 ){
2342 /* Client-to-Client */
2345 message_type = "Peer Init";
2346 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2347 "Message Type: %s (Byte: %d)", message_type, 1);
2349 len = tvb_get_letohl(tvb, offset);
2350 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2351 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
2353 len = tvb_get_letohl(tvb, offset);
2354 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2355 str = tvb_get_ephemeral_string(tvb, offset+4, len);
2356 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
2357 "Connection Type: %s (Char: %s)", connection_type(str),
2358 format_text(str, len));
2360 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2364 else if (check_slsk_format(tvb, offset, "bi")) {
2365 if ( tvb_get_guint8(tvb, offset) == 0 ){
2366 /* Client-to-Client */
2367 message_type = "Pierce Fw";
2368 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2369 "Message Type: %s (Byte: %d)", message_type, 0);
2371 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2376 message_type = "Unknown";
2377 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2378 "Message Type: %s (Code: %02d)", message_type, msg_code);
2391 static void dissect_slsk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2393 tcp_dissect_pdus(tvb, pinfo, tree, slsk_desegment, 4, get_slsk_pdu_len, dissect_slsk_pdu);
2398 /* Register the protocol with Wireshark */
2401 proto_register_slsk(void)
2404 /* Setup list of header fields */
2405 static hf_register_info hf[] = {
2407 { "Integer", "slsk.integer",
2408 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2410 { "String", "slsk.string",
2411 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2413 { "Byte", "slsk.byte",
2414 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
2415 { &hf_slsk_message_length,
2416 { "Message Length", "slsk.message.length",
2417 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2418 { &hf_slsk_message_code,
2419 { "Message Code", "slsk.message.code",
2420 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2421 { &hf_slsk_client_ip,
2422 { "Client IP", "slsk.server.ip",
2423 FT_IPv4, BASE_NONE, NULL, 0, "Client IP Address", HFILL } },
2424 { &hf_slsk_server_ip,
2425 { "SoulSeek Server IP", "slsk.server.ip",
2426 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2427 { &hf_slsk_string_length,
2428 { "String Length", "slsk.string.length",
2429 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2430 { &hf_slsk_username,
2431 { "Username", "slsk.username",
2432 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2433 { &hf_slsk_password,
2434 { "Password", "slsk.password",
2435 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2437 { "Version", "slsk.version",
2438 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2439 { &hf_slsk_login_successful,
2440 { "Login successful", "slsk.login.successful",
2441 FT_UINT8, BASE_DEC, NULL, 0, "Login Successful", HFILL } },
2442 { &hf_slsk_login_message,
2443 { "Login Message", "slsk.login.message",
2444 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2446 { "Port Number", "slsk.port.number",
2447 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2449 { "IP Address", "slsk.ip.address",
2450 FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL } },
2451 { &hf_slsk_user_exists,
2452 { "user exists", "slsk.user.exists",
2453 FT_UINT8, BASE_DEC, NULL, 0, "User exists", HFILL } },
2454 { &hf_slsk_status_code,
2455 { "Status Code", "slsk.status.code",
2456 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2458 { "Room", "slsk.room",
2459 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2460 { &hf_slsk_chat_message,
2461 { "Chat Message", "slsk.chat.message",
2462 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2463 { &hf_slsk_users_in_room,
2464 { "Users in Room", "slsk.room.users",
2465 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users in Room", HFILL } },
2467 { "Token", "slsk.token",
2468 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2469 { &hf_slsk_connection_type,
2470 { "Connection Type", "slsk.connection.type",
2471 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2472 { &hf_slsk_chat_message_id,
2473 { "Chat Message ID", "slsk.chat.message.id",
2474 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2475 { &hf_slsk_timestamp,
2476 { "Timestamp", "slsk.timestamp",
2477 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2478 { &hf_slsk_search_text,
2479 { "Search Text", "slsk.search.text",
2480 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2481 { &hf_slsk_folder_count,
2482 { "Folder Count", "slsk.folder.count",
2483 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2484 { &hf_slsk_file_count,
2485 { "File Count", "slsk.file.count",
2486 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2487 { &hf_slsk_average_speed,
2488 { "Average Speed", "slsk.average.speed",
2489 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2490 { &hf_slsk_download_number,
2491 { "Download Number", "slsk.download.number",
2492 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2494 { "Files", "slsk.files",
2495 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2496 { &hf_slsk_directories,
2497 { "Directories", "slsk.directories",
2498 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2499 { &hf_slsk_slotsfull,
2500 { "Slots full", "slsk.slots.full",
2501 FT_UINT32, BASE_DEC, NULL, 0, "Upload Slots Full", HFILL } },
2502 { &hf_slsk_place_in_queue,
2503 { "Place in Queue", "slsk.queue.place",
2504 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2505 { &hf_slsk_number_of_rooms,
2506 { "Number of Rooms", "slsk.room.count",
2507 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2508 { &hf_slsk_filename,
2509 { "Filename", "slsk.filename",
2510 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2511 { &hf_slsk_directory,
2512 { "Directory", "slsk.directory",
2513 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2515 { "Size", "slsk.size",
2516 FT_UINT32, BASE_DEC, NULL, 0, "File Size", HFILL } },
2517 { &hf_slsk_checksum,
2518 { "Checksum", "slsk.checksum",
2519 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2521 { "Code", "slsk.code",
2522 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2523 { &hf_slsk_number_of_users,
2524 { "Number of Users", "slsk.user.count",
2525 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2526 { &hf_slsk_number_of_days,
2527 { "Number of Days", "slsk.day.count",
2528 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2529 { &hf_slsk_transfer_direction,
2530 { "Transfer Direction", "slsk.transfer.direction",
2531 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2532 { &hf_slsk_user_description,
2533 { "User Description", "slsk.user.description",
2534 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2535 { &hf_slsk_picture_exists,
2536 { "Picture exists", "slsk.user.picture.exists",
2537 FT_UINT8, BASE_DEC, NULL, 0, "User has a picture", HFILL } },
2539 { "Picture", "slsk.user.picture",
2540 FT_STRING, BASE_NONE, NULL, 0, "User Picture", HFILL } },
2541 { &hf_slsk_user_uploads,
2542 { "User uploads", "slsk.uploads.user",
2543 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2544 { &hf_slsk_total_uploads,
2545 { "Total uploads allowed", "slsk.uploads.total",
2546 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2547 { &hf_slsk_queued_uploads,
2548 { "Queued uploads", "slsk.uploads.queued",
2549 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2550 { &hf_slsk_slots_available,
2551 { "Upload Slots available", "slsk.uploads.available",
2552 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
2554 { "Download allowed", "slsk.user.allowed",
2555 FT_UINT8, BASE_DEC, NULL, 0, "allowed", HFILL } },
2556 { &hf_slsk_compr_packet,
2557 { "[zlib compressed packet]", "slsk.compr.packet",
2558 FT_NONE, BASE_NONE, NULL, 0, "zlib compressed packet", HFILL } },
2559 { &hf_slsk_parent_min_speed,
2560 { "Parent Min Speed", "slsk.parent.min.speed",
2561 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2562 { &hf_slsk_parent_speed_connection_ratio,
2563 { "Parent Speed Connection Ratio", "slsk.parent.speed.connection.ratio",
2564 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2565 { &hf_slsk_seconds_parent_inactivity_before_disconnect,
2566 { "Seconds Parent Inactivity Before Disconnect", "slsk.seconds.parent.inactivity.before.disconnect",
2567 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2568 { &hf_slsk_seconds_server_inactivity_before_disconnect,
2569 { "Seconds Server Inactivity Before Disconnect", "slsk.seconds.server.inactivity.before.disconnect",
2570 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2571 { &hf_slsk_nodes_in_cache_before_disconnect,
2572 { "Nodes In Cache Before Disconnect", "slsk.nodes.in.cache.before.disconnect",
2573 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2574 { &hf_slsk_seconds_before_ping_children,
2575 { "Seconds Before Ping Children", "slsk.seconds.before.ping.children",
2576 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2577 { &hf_slsk_recommendation,
2578 { "Recommendation", "slsk.recommendation",
2579 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
2581 { "Ranking", "slsk.ranking",
2582 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } },
2585 /* Setup protocol subtree array */
2586 static gint *ett[] = {
2588 &ett_slsk_compr_packet,
2590 module_t *slsk_module;
2592 /* Registers the protocol name and description */
2593 proto_slsk = proto_register_protocol("SoulSeek Protocol", "SoulSeek", "slsk");
2595 /* Required function calls to register the header fields and subtrees used */
2596 proto_register_field_array(proto_slsk, hf, array_length(hf));
2597 proto_register_subtree_array(ett, array_length(ett));
2599 slsk_module = prefs_register_protocol(proto_slsk, NULL);
2601 /* Registers the options in the menu preferences */
2602 prefs_register_bool_preference(slsk_module, "desegment",
2603 "Reassemble SoulSeek messages spanning multiple TCP segments",
2604 "Whether the SoulSeek dissector should reassemble messages spanning multiple TCP segments."
2605 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2608 prefs_register_bool_preference(slsk_module, "decompress",
2609 "Decompress zlib compressed packets inside SoulSeek messages",
2610 "Whether the SoulSeek dissector should decompress all zlib compressed packets inside messages",
2618 proto_reg_handoff_slsk(void)
2620 dissector_handle_t slsk_handle;
2622 slsk_handle = create_dissector_handle(dissect_slsk, proto_slsk);
2623 dissector_add("tcp.port", TCP_PORT_SLSK_1, slsk_handle);
2624 dissector_add("tcp.port", TCP_PORT_SLSK_2, slsk_handle);
2625 dissector_add("tcp.port", TCP_PORT_SLSK_3, slsk_handle);