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
12 * $Id: packet-slsk.c,v 1.4 2004/05/05 17:28:12 obiot Exp $
15 * Ethereal - Network traffic analyzer
16 * By Gerald Combs <gerald@ethereal.com>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #include <epan/packet.h>
45 #include <epan/tvbuff.h>
46 #include "packet-tcp.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_successfull = -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"},
197 static const value_string slsk_status_codes[] = {
204 static const value_string slsk_transfer_direction[] = {
209 static const value_string slsk_yes_no[] = {
214 static const value_string slsk_attr_type[] = {
220 static char* connection_type(char con_type[]) {
221 if (strlen(con_type) != 1) return "Unknown";
222 if (con_type[0] == 'D') return "Distributed Search";
223 if (con_type[0] == 'P') return "Peer Connection"; /* "File Search Result / User Info Request / Get Shared File List" */
224 if (con_type[0] == 'F') return "File Transfer";
228 static gboolean check_slsk_format(tvbuff_t *tvb, int offset, char format[]){
231 * Returns TRUE if tvbuff beginning at offset matches a certain format
232 * The format is given by an array of characters standing for a special field type
233 * i - integer (4 bytes)
235 * s - string (string_length + 4 bytes)
237 * * - can be used at the end of a format to ignore any following bytes
240 switch ( format[0] ) {
242 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
246 if (tvb_length_remaining(tvb, offset) < 1) return FALSE;
250 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
251 if (tvb_length_remaining(tvb, offset) < (int)tvb_get_letohl(tvb, offset)+4) return FALSE;
252 offset += tvb_get_letohl(tvb, offset)+4;
262 if (format[1] == '\0' ) {
263 if (tvb_length_remaining(tvb, offset) != 0) return FALSE; /* Checks for additional bytes at the end */
266 return check_slsk_format(tvb, offset, &format[1]);
270 static char* get_message_type(tvbuff_t *tvb) {
272 * Checks if the Message Code is known.
273 * If unknown checks if the Message Code is stored in a byte.
274 * Returns the Message Type.
276 int msg_code = tvb_get_letohl(tvb, 4);
277 gchar *message_type = val_to_str(msg_code, slsk_tcp_msgs, "Unknown");
278 if (strcmp(message_type, "Unknown") == 0) {
279 if (check_slsk_format(tvb, 4, "bisis")) message_type = "Distributed Search";
280 if (check_slsk_format(tvb, 4, "bssi")) message_type = "Peer Init";
281 if (check_slsk_format(tvb, 4, "bi")) message_type = "Pierce Fw";
286 static guint get_slsk_pdu_len(tvbuff_t *tvb, int offset)
289 msg_len = tvb_get_letohl(tvb, offset);
290 /* That length doesn't include the length field itself; add that in. */
295 /* Code to actually dissect the packets */
297 static void dissect_slsk_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
300 /* Set up structures needed to add the protocol subtree and manage it */
302 proto_tree *slsk_tree;
305 guint32 msg_len, msg_code;
310 int uncompr_tvb_offset = 0;
318 msg_len = tvb_get_letohl(tvb, offset);
319 msg_code = tvb_get_letohl(tvb, offset+4);
320 message_type = get_message_type(tvb);
322 /* Make entries in Protocol column and Info column on summary display */
323 if (check_col(pinfo->cinfo, COL_PROTOCOL))
324 col_set_str(pinfo->cinfo, COL_PROTOCOL, "slsk");
326 /* This field shows up as the "Info" column in the display */
328 if (check_col(pinfo->cinfo, COL_INFO))
329 col_set_str(pinfo->cinfo, COL_INFO, "SoulSeek Message");
331 if (check_col(pinfo->cinfo, COL_INFO)) {
332 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_type);
338 /* create display subtree for the protocol */
339 ti = proto_tree_add_item(tree, proto_slsk, tvb, 0, -1, FALSE);
340 slsk_tree = proto_item_add_subtree(ti, ett_slsk);
342 /* Continue adding tree items to process the packet here */
344 proto_tree_add_uint(slsk_tree, hf_slsk_message_length, tvb, offset, 4, msg_len);
350 if (check_slsk_format(tvb, offset, "issi")) {
351 /* Client-to-Server */
352 message_type = "Login";
353 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
354 "Message Type: %s (Code: %02d)", message_type, msg_code);
356 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
357 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
358 offset += 4+tvb_get_letohl(tvb, offset);
359 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
360 proto_tree_add_item(slsk_tree, hf_slsk_password, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
361 offset += 4+tvb_get_letohl(tvb, offset);
362 proto_tree_add_uint(slsk_tree, hf_slsk_version, tvb, offset, 4, tvb_get_letohl(tvb, offset));
365 else if (check_slsk_format(tvb, offset, "ibs") || check_slsk_format(tvb, offset, "ibsi")) {
366 /* Server-to-Client */
367 message_type = "Login Reply";
368 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
369 "Message Type: %s (Code: %02d)", message_type, msg_code);
371 i=tvb_get_guint8(tvb, offset);
372 proto_tree_add_uint_format(slsk_tree, hf_slsk_login_successfull, tvb, offset, 1, tvb_get_guint8(tvb, offset),
373 "Login successfull: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
375 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
376 proto_tree_add_item(slsk_tree, hf_slsk_login_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
377 offset += 4+tvb_get_letohl(tvb, offset);
379 proto_tree_add_ipv4(slsk_tree, hf_slsk_client_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
386 if (check_slsk_format(tvb, offset, "ii")) {
387 /* Client-to-Server */
388 message_type = "Set Wait Port";
389 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
390 "Message Type: %s (Code: %02d)", message_type, msg_code);
392 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
398 if (check_slsk_format(tvb, offset, "isii")) {
399 /* Server-to-Client */
400 message_type = "Get Peer Address Reply";
401 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
402 "Message Type: %s (Code: %02d)", message_type, msg_code);
404 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
405 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
406 offset += 4+tvb_get_letohl(tvb, offset);
407 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
409 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
412 else if (check_slsk_format(tvb, offset, "is")) {
413 /* Client-to-Server */
414 message_type = "Get Peer Address";
415 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
416 "Message Type: %s (Code: %02d)", message_type, msg_code);
418 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
419 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
420 offset += 4+tvb_get_letohl(tvb, offset);
425 if (check_slsk_format(tvb, offset, "i")) {
426 /* Client-to-Client */
427 message_type = "Get Shared File List";
428 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
429 "Message Type: %s (Code: %02d)", message_type, msg_code);
435 if (check_slsk_format(tvb, offset, "isb")) {
436 /* Server-to-Client */
437 message_type = "User Exists Reply";
438 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
439 "Message Type: %s (Code: %02d)", message_type, msg_code);
441 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
442 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
443 offset += 4+tvb_get_letohl(tvb, offset);
444 proto_tree_add_uint_format(slsk_tree, hf_slsk_user_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
445 "User exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
448 else if (check_slsk_format(tvb, offset, "is")) {
449 /* Client-to-Server */
450 message_type = "User Exists Request";
451 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
452 "Message Type: %s (Code: %02d)", message_type, msg_code);
454 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
455 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
456 offset += 4+tvb_get_letohl(tvb, offset);
458 else if (check_slsk_format(tvb, offset, "i*")) {
459 /* Client-to-Client */
460 message_type = "Shared File List";
461 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
462 "Message Type: %s (Code: %02d)", message_type, msg_code);
465 /* [zlib compressed] */
466 comprlen = tvb_length_remaining(tvb, offset);
468 if (slsk_decompress == TRUE){
470 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
472 if (uncompr_tvb == NULL) {
473 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
474 "[zlib compressed packet]");
475 offset += tvb_length_remaining(tvb, offset);
476 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
477 "(uncompression failed !)");
480 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
481 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
483 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
484 "( compressed packet length: %d)", comprlen);
485 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
486 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
487 "(uncompressed packet length: %d)", uncomprlen);
489 /* Dissects the uncompressed tvbuffer */
490 uncompr_tvb_offset = 0;
491 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "i*")) {
492 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
493 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
494 "Number of directories: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
495 uncompr_tvb_offset += 4;
497 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
498 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
499 "Directory #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
500 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
501 "Directory #%d Name: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
502 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
504 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
505 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
506 "Directory #%d Number of files: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
507 uncompr_tvb_offset += 4;
509 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
510 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
511 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
512 uncompr_tvb_offset += 1;
513 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
514 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
515 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
516 "Dir #%d File #%d Filename: %s", i+1, i2+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
517 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
518 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
519 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
520 uncompr_tvb_offset += 4;
521 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
522 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
523 uncompr_tvb_offset += 4;
524 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
525 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
526 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
527 "Dir #%d File #%d ext: %s", i+1, i2+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
528 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
530 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
531 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
532 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
533 uncompr_tvb_offset += 4;
535 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
536 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
537 "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));
538 uncompr_tvb_offset += 4;
539 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
540 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
541 uncompr_tvb_offset += 4;
554 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
555 "[zlib compressed packet]");
556 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
557 "( compressed packet length: %d)", comprlen);
558 offset += tvb_length_remaining(tvb, offset);
564 if (check_slsk_format(tvb, offset, "isi")) {
565 /* Server-to-Client */
566 message_type = "Get User Status Reply";
567 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
568 "Message Type: %s (Code: %02d)", message_type, msg_code);
570 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
571 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
572 offset += 4+tvb_get_letohl(tvb, offset);
573 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
574 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
577 else if (check_slsk_format(tvb, offset, "is")) {
578 /* Client-to-Server */
579 message_type = "Get User Status";
580 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
581 "Message Type: %s (Code: %02d)", message_type, msg_code);
583 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
584 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
585 offset += 4+tvb_get_letohl(tvb, offset);
590 if (check_slsk_format(tvb, offset, "i*")) {
591 /* Client-to-Client */
592 message_type = "File Search Result";
593 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
594 "Message Type: %s (Code: %02d)", message_type, msg_code);
597 /* [zlib compressed] */
598 comprlen = tvb_length_remaining(tvb, offset);
600 if (slsk_decompress == TRUE){
602 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
604 if (uncompr_tvb == NULL) {
605 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
606 "[zlib compressed packet]");
607 offset += tvb_length_remaining(tvb, offset);
608 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
609 "(uncompression failed !)");
612 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
613 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
615 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
616 "( compressed packet length: %d)", comprlen);
617 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
618 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
619 "(uncompressed packet length: %d)", uncomprlen);
621 /* Dissects the uncompressed tvbuffer */
622 uncompr_tvb_offset = 0;
623 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "sii*")) {
624 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
625 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
626 "Username: %s", tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
627 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
628 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_token, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
629 uncompr_tvb_offset += 4;
630 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
631 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
632 "Number of files: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
633 uncompr_tvb_offset += 4;
635 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
636 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
637 "File #%d Code: %d", i+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
638 uncompr_tvb_offset += 1;
639 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
640 "File #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
641 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
642 "File #%d Filename: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
643 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
644 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
645 "File #%d Size1: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
646 uncompr_tvb_offset += 4;
647 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
648 "File #%d Size2: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
649 uncompr_tvb_offset += 4;
650 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
651 "File #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
652 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
653 "File #%d ext: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
654 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
656 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
657 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
658 "File #%d Number of attributes: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
659 uncompr_tvb_offset += 4;
661 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
662 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
663 "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));
664 uncompr_tvb_offset += 4;
665 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
666 "File #%d Attr #%d value: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
667 uncompr_tvb_offset += 4;
674 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
675 "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));
676 uncompr_tvb_offset += 1;
677 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
678 "Upload speed: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
679 uncompr_tvb_offset += 4;
680 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
681 "In Queue: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
682 uncompr_tvb_offset += 4;
686 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
687 "[zlib compressed packet]");
688 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
689 "( compressed packet length: %d)", comprlen);
690 offset += tvb_length_remaining(tvb, offset);
696 if (check_slsk_format(tvb, offset, "isss")) {
697 /* Server-to-Client */
698 message_type = "Say ChatRoom";
699 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
700 "Message Type: %s (Code: %02d)", message_type, msg_code);
702 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
703 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
704 offset += 4+tvb_get_letohl(tvb, offset);
705 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
706 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
707 offset += 4+tvb_get_letohl(tvb, offset);
708 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
709 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
710 offset += 4+tvb_get_letohl(tvb, offset);
712 else if (check_slsk_format(tvb, offset, "iss")) {
713 /* Client-to-Server */
714 message_type = "Say ChatRoom";
715 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
716 "Message Type: %s (Code: %02d)", message_type, msg_code);
718 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
719 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
720 offset += 4+tvb_get_letohl(tvb, offset);
721 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
722 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
723 offset += 4+tvb_get_letohl(tvb, offset);
728 if (check_slsk_format(tvb, offset, "is")) {
729 /* Client-to-Server */
730 message_type = "Join/Add Room";
731 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
732 "Message Type: %s (Code: %02d)", message_type, msg_code);
734 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
735 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
736 offset += 4+tvb_get_letohl(tvb, offset);
738 else if (check_slsk_format(tvb, offset, "isi*")) {
739 /* Server-to-Client */
740 message_type = "Join Room User List";
741 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
742 "Message Type: %s (Code: %02d)", message_type, msg_code);
744 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
745 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
746 offset += 4+tvb_get_letohl(tvb, offset);
747 i=0; j = tvb_get_letohl(tvb, offset);
748 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
751 if (check_slsk_format(tvb, offset, "s*")) {
752 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
753 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
754 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
755 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
756 offset += 4+tvb_get_letohl(tvb, offset);
760 if (check_slsk_format(tvb, offset, "i*")) {
761 i=0; j = tvb_get_letohl(tvb, offset);
762 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
765 if (check_slsk_format(tvb, offset, "i*")) {
766 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
767 "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));
773 if (check_slsk_format(tvb, offset, "i*")) {
774 i=0; j = tvb_get_letohl(tvb, offset);
775 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
778 if (check_slsk_format(tvb, offset, "iiiii*")) {
779 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
780 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
782 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
783 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
785 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
786 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
788 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
789 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
791 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
792 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
798 if (check_slsk_format(tvb, offset, "i*")) {
799 i=0; j = tvb_get_letohl(tvb, offset);
800 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
801 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
804 if (check_slsk_format(tvb, offset, "i*")) {
805 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
806 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
816 if (check_slsk_format(tvb, offset, "is")) {
817 /* Client-to-Server & Server-to-Client */
818 message_type = "Leave Room";
819 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
820 "Message Type: %s (Code: %02d)", message_type, msg_code);
822 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
823 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
824 offset += 4+tvb_get_letohl(tvb, offset);
826 else if (check_slsk_format(tvb, offset, "i")) {
827 /* Client-to-Client */
828 message_type = "User Info Request";
829 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
830 "Message Type: %s (Code: %02d)", message_type, msg_code);
836 if (check_slsk_format(tvb, offset, "issiiiiiii")) {
837 /* Server-to-Client */
838 message_type = "User Joined Room";
839 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
840 "Message Type: %s (Code: %02d)", message_type, msg_code);
842 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
843 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
844 offset += 4+tvb_get_letohl(tvb, offset);
845 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
846 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
847 offset += 4+tvb_get_letohl(tvb, offset);
848 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
850 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
852 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
854 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
856 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
858 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
860 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
863 else if (check_slsk_format(tvb, offset, "isbiib") || check_slsk_format(tvb, offset, "isbsiib")) {
864 /* Client-to-Client */
865 message_type = "User Info Reply";
866 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
867 "Message Type: %s (Code: %02d)", message_type, msg_code);
869 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
870 proto_tree_add_item(slsk_tree, hf_slsk_user_description, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
871 offset += 4+tvb_get_letohl(tvb, offset);
872 proto_tree_add_uint_format(slsk_tree, hf_slsk_picture_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
873 "Picture exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
875 if ( tvb_get_guint8(tvb, offset -1 ) == 1 ) {
876 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
877 "Picture Size: %d", tvb_get_letohl(tvb, offset));
878 proto_tree_add_item(slsk_tree, hf_slsk_picture, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
879 offset += 4+tvb_get_letohl(tvb, offset);
881 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
883 proto_tree_add_uint(slsk_tree, hf_slsk_queued_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
885 proto_tree_add_uint_format(slsk_tree, hf_slsk_slots_available, tvb, offset, 1, tvb_get_guint8(tvb, offset),
886 "Upload Slots available: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
892 if (check_slsk_format(tvb, offset, "iss")) {
893 /* Server-to-Client */
894 message_type = "User Left Room";
895 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
896 "Message Type: %s (Code: %02d)", message_type, msg_code);
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_room, 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_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
902 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
903 offset += 4+tvb_get_letohl(tvb, offset);
908 if (check_slsk_format(tvb, offset, "iiss")) {
909 /* Client-to-Server */
910 message_type = "Connect To Peer";
911 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
912 "Message Type: %s (Code: %02d)", message_type, msg_code);
914 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
916 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
917 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
918 offset += 4+tvb_get_letohl(tvb, offset);
919 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
920 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)),
921 "Connection Type: %s (Char: %s)", connection_type(tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset))), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
922 offset += 4+tvb_get_letohl(tvb, offset);
924 else if (check_slsk_format(tvb, offset, "issiii")) {
925 /* Server-to-Client */
926 message_type = "Connect To Peer";
927 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
928 "Message Type: %s (Code: %02d)", message_type, msg_code);
930 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
931 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
932 offset += 4+tvb_get_letohl(tvb, offset);
933 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
934 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)),
935 "Connection Type: %s (Char: %s)", connection_type(tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset))), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
936 offset += 4+tvb_get_letohl(tvb, offset);
937 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
939 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
941 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
947 if (check_slsk_format(tvb, offset, "iss")) {
948 /* Client-to-Server */
949 message_type = "Message User Send";
950 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
951 "Message Type: %s (Code: %02d)", message_type, msg_code);
953 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
954 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
955 offset += 4+tvb_get_letohl(tvb, offset);
956 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
957 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
958 offset += 4+tvb_get_letohl(tvb, offset);
960 else if (check_slsk_format(tvb, offset, "iiiss")) {
961 /* Server-to-Client */
962 message_type = "Message User Receive";
963 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
964 "Message Type: %s (Code: %02d)", message_type, msg_code);
966 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
968 proto_tree_add_uint(slsk_tree, hf_slsk_timestamp, tvb, offset, 4, tvb_get_letohl(tvb, offset));
970 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
971 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
972 offset += 4+tvb_get_letohl(tvb, offset);
973 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
974 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
975 offset += 4+tvb_get_letohl(tvb, offset);
980 if (check_slsk_format(tvb, offset, "ii")) {
981 /* Client-to-Server */
982 message_type = "Message User Receive Ack";
983 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
984 "Message Type: %s (Code: %02d)", message_type, msg_code);
986 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
992 if (check_slsk_format(tvb, offset, "iis")) {
993 /* Client-to-Server */
994 message_type = "File Search";
995 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
996 "Message Type: %s (Code: %02d)", message_type, msg_code);
998 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1000 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1001 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1002 offset += 4+tvb_get_letohl(tvb, offset);
1007 if (check_slsk_format(tvb, offset, "ii")) {
1008 /* Client-to-Server */
1009 message_type = "Set Status";
1010 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1011 "Message Type: %s (Code: %02d)", message_type, msg_code);
1013 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1014 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1020 if (check_slsk_format(tvb, offset, "i")) {
1021 /* Client-to-Server */
1022 message_type = "Ping";
1023 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1024 "Message Type: %s (Code: %02d)", message_type, msg_code);
1030 if (check_slsk_format(tvb, offset, "isi")) {
1031 /* Client-to-Server */
1032 message_type = "Update Upload Speed";
1033 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1034 "Message Type: %s (Code: %02d)", message_type, msg_code);
1036 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1037 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1038 offset += 4+tvb_get_letohl(tvb, offset);
1039 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1045 if (check_slsk_format(tvb, offset, "iii")) {
1046 /* Client-to-Server */
1047 message_type = "Shared Files & Folders ";
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_folder_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1053 proto_tree_add_uint(slsk_tree, hf_slsk_file_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1059 if (check_slsk_format(tvb, offset, "isiiiii")) {
1060 /* Server-to-Client */
1061 message_type = "Get User Stats Reply";
1062 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1063 "Message Type: %s (Code: %02d)", message_type, msg_code);
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_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1067 offset += 4+tvb_get_letohl(tvb, offset);
1068 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1070 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1072 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1074 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1076 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1079 else if (check_slsk_format(tvb, offset, "is")) {
1080 /* Client-to-Client */
1081 /* Client-to-Server: send after login successfull */
1082 message_type = "Get User Stats";
1083 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1084 "Message Type: %s (Code: %02d)", message_type, msg_code);
1086 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1087 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1088 offset += 4+tvb_get_letohl(tvb, offset);
1090 else if (check_slsk_format(tvb, offset, "iis")) {
1091 /* Client-to-Client */
1092 message_type = "Folder Contents Request";
1093 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1094 "Message Type: %s (Code: %02d)", message_type, msg_code);
1096 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1098 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1099 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1100 offset += 4+tvb_get_letohl(tvb, offset);
1105 if (check_slsk_format(tvb, offset, "i*")) {
1106 /* Client-to-Client */
1107 message_type = "Folder Contents Response";
1108 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1109 "Message Type: %s (Code: %02d)", message_type, msg_code);
1112 /* [zlib compressed] */
1113 comprlen = tvb_length_remaining(tvb, offset);
1115 if (slsk_decompress == TRUE){
1117 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
1119 if (uncompr_tvb == NULL) {
1120 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1121 "[zlib compressed packet]");
1122 offset += tvb_length_remaining(tvb, offset);
1123 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
1124 "(uncompression failed !)");
1127 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
1128 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
1130 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1131 "( compressed packet length: %d)", comprlen);
1132 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
1133 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1134 "(uncompressed packet length: %d)", uncomprlen);
1136 /* Dissects the uncompressed tvbuffer */
1137 uncompr_tvb_offset = 0;
1138 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "isi*")) {
1139 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1140 "Token: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1141 uncompr_tvb_offset += 4;
1142 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1143 "Directory Name: %s", tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1144 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1146 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1147 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1148 "Number of directories: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1149 uncompr_tvb_offset += 4;
1151 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
1152 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1153 "Directory #%d Name: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1154 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1156 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1157 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1158 "Directory #%d Number of files: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1159 uncompr_tvb_offset += 4;
1161 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
1162 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
1163 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
1164 uncompr_tvb_offset += 1;
1165 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1166 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1167 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1168 "Dir #%d File #%d Filename: %s", i+1, i2+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1169 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1170 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1171 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1172 uncompr_tvb_offset += 4;
1173 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1174 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1175 uncompr_tvb_offset += 4;
1176 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1177 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1178 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1179 "Dir #%d File #%d ext: %s", i+1, i2+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1180 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1182 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1183 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1184 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1185 uncompr_tvb_offset += 4;
1187 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
1188 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1189 "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));
1190 uncompr_tvb_offset += 4;
1191 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1192 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1193 uncompr_tvb_offset += 4;
1206 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1207 "[zlib compressed packet]");
1208 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1209 "( compressed packet length: %d)", comprlen);
1210 offset += tvb_length_remaining(tvb, offset);
1216 if (check_slsk_format(tvb, offset, "isi")) {
1217 /* Server-to-Client */
1218 message_type = "Queued Downloads";
1219 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1220 "Message Type: %s (Code: %02d)", message_type, msg_code);
1222 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1223 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1224 offset += 4+tvb_get_letohl(tvb, offset);
1225 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1228 else if (check_slsk_format(tvb, offset, "iiis") || check_slsk_format(tvb, offset, "iiisii")) {
1229 /* Client-to-Client */
1230 message_type = "Transfer Request";
1231 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1232 "Message Type: %s (Code: %02d)", message_type, msg_code);
1234 i = tvb_get_letohl(tvb, offset);
1235 proto_tree_add_uint_format(slsk_tree, hf_slsk_transfer_direction, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1236 "Transfer Direction: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_transfer_direction, "Unknown"), tvb_get_letohl(tvb, offset));
1238 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1240 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1241 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1242 offset += 4+tvb_get_letohl(tvb, offset);
1244 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1246 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1254 if (check_slsk_format(tvb, offset, "iibs") || check_slsk_format(tvb, offset, "iibii") || check_slsk_format(tvb, offset, "iib")) {
1255 /* Client-to-Client */
1256 message_type = "Transfer Response";
1257 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1258 "Message Type: %s (Code: %02d)", message_type, msg_code);
1260 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1262 i = tvb_get_guint8(tvb, offset);
1263 proto_tree_add_uint_format(slsk_tree, hf_slsk_allowed, tvb, offset, 1, tvb_get_guint8(tvb, offset),
1264 "Download allowed: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
1267 if ( tvb_length_remaining(tvb, offset) == 8 ) {
1268 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1270 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1274 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1275 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1276 offset += 4+tvb_get_letohl(tvb, offset);
1282 if (check_slsk_format(tvb, offset, "is")) {
1283 /* Client-to-Client */
1284 message_type = "Placehold Upload";
1285 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1286 "Message Type: %s (Code: %02d)", message_type, msg_code);
1288 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1289 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1290 offset += 4+tvb_get_letohl(tvb, offset);
1295 if (check_slsk_format(tvb, offset, "is")) {
1296 /* Client-to-Client */
1297 message_type = "Queue Upload";
1298 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1299 "Message Type: %s (Code: %02d)", message_type, msg_code);
1301 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1302 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1303 offset += 4+tvb_get_letohl(tvb, offset);
1308 if (check_slsk_format(tvb, offset, "isi")) {
1309 /* Client-to-Client */
1310 message_type = "Place In Queue";
1311 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1312 "Message Type: %s (Code: %02d)", message_type, msg_code);
1314 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1315 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1316 offset += 4+tvb_get_letohl(tvb, offset);
1317 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1323 if (check_slsk_format(tvb, offset, "is")) {
1324 /* Client-to-Client */
1325 message_type = "Upload Failed";
1326 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1327 "Message Type: %s (Code: %02d)", message_type, msg_code);
1329 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1330 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1331 offset += 4+tvb_get_letohl(tvb, offset);
1336 if (check_slsk_format(tvb, offset, "is")) {
1337 /* Client-to-Server */
1338 message_type = "Make Own Recommendation";
1339 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1340 "Message Type: %s (Code: %02d)", message_type, msg_code);
1342 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1343 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1344 offset += 4+tvb_get_letohl(tvb, offset);
1346 else if (check_slsk_format(tvb, offset, "isi")) {
1347 /* Client-to-Server */
1348 message_type = "Remove Own Recommendation";
1349 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1350 "Message Type: %s (Code: %02d)", message_type, msg_code);
1352 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1353 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1354 offset += 4+tvb_get_letohl(tvb, offset);
1355 proto_tree_add_uint(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1358 else if (check_slsk_format(tvb, offset, "iss")) {
1359 /* Client-to-Client */
1360 message_type = "Queue Failed";
1361 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1362 "Message Type: %s (Code: %02d)", message_type, msg_code);
1364 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1365 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1366 offset += 4+tvb_get_letohl(tvb, offset);
1367 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1368 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1369 offset += 4+tvb_get_letohl(tvb, offset);
1374 if (check_slsk_format(tvb, offset, "is")) {
1375 /* Client-to-Server: "Add Things I like" */
1376 /* Client-to-Client: "Place In Queue Request" */
1377 message_type = "Add Things I like / Place In Queue Request";
1378 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1379 "Message Type: %s (Code: %02d)", message_type, msg_code);
1381 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1382 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1383 offset += 4+tvb_get_letohl(tvb, offset);
1388 if (check_slsk_format(tvb, offset, "is")) {
1389 /* Client-to-Server */
1390 message_type = "Remove Things I like";
1391 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1392 "Message Type: %s (Code: %02d)", message_type, msg_code);
1394 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1395 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1396 offset += 4+tvb_get_letohl(tvb, offset);
1401 if (check_slsk_format(tvb, offset, "i")) {
1402 /* Client-to-Server */
1403 message_type = "Get Recommendations";
1404 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1405 "Message Type: %s (Code: %02d)", message_type, msg_code);
1408 else if (check_slsk_format(tvb, offset, "ii*")) {
1409 /* Server-to-Client */
1410 message_type = "Get Recommendations Reply";
1411 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1412 "Message Type: %s (Code: %02d)", message_type, msg_code);
1414 i=0; j = tvb_get_letohl(tvb, offset);
1415 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1416 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1419 if (check_slsk_format(tvb, offset, "si*")) {
1420 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1421 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1422 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1423 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1424 offset += 4+tvb_get_letohl(tvb, offset);
1425 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1426 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1435 if (check_slsk_format(tvb, offset, "i")) {
1436 /* Client-to-Server */
1437 message_type = "Type 55";
1438 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1439 "Message Type: %s (Code: %02d)", message_type, msg_code);
1445 if (check_slsk_format(tvb, offset, "i")) {
1446 /* Client-to-Server */
1447 message_type = "Get Global Rankings";
1448 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1449 "Message Type: %s (Code: %02d)", message_type, msg_code);
1452 else if (check_slsk_format(tvb, offset, "ii*")) {
1453 /* Server-to-Client */
1454 message_type = "Get Global Rankings Reply";
1455 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1456 "Message Type: %s (Code: %02d)", message_type, msg_code);
1458 i=0; j = tvb_get_letohl(tvb, offset);
1459 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1460 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1463 if (check_slsk_format(tvb, offset, "si*")) {
1464 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1465 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1466 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1467 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1468 offset += 4+tvb_get_letohl(tvb, offset);
1469 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1470 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1479 if (check_slsk_format(tvb, offset, "is")) {
1480 /* Client-to-Server */
1481 message_type = "Get User Recommendations";
1482 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1483 "Message Type: %s (Code: %02d)", message_type, msg_code);
1485 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1486 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1487 offset += 4+tvb_get_letohl(tvb, offset);
1489 else if (check_slsk_format(tvb, offset, "isi*")) {
1490 /* Server-to-Client */
1491 message_type = "Get User Recommendations Reply";
1492 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1493 "Message Type: %s (Code: %02d)", message_type, msg_code);
1495 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1496 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1497 offset += 4+tvb_get_letohl(tvb, offset);
1498 i=0; j = tvb_get_letohl(tvb, offset);
1499 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1500 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1503 if (check_slsk_format(tvb, offset, "s*")) {
1504 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1505 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1506 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1507 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1508 offset += 4+tvb_get_letohl(tvb, offset);
1516 if (check_slsk_format(tvb, offset, "isi*")) {
1517 /* Client-to-Server */
1518 message_type = "Admin Command";
1519 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1520 "Message Type: %s (Code: %02d)", message_type, msg_code);
1522 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1523 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1524 offset += 4+tvb_get_letohl(tvb, offset);
1525 i=0; j = tvb_get_letohl(tvb, offset);
1526 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1527 "Number of Strings: %d", tvb_get_letohl(tvb, offset));
1530 if (check_slsk_format(tvb, offset, "s*")) {
1531 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1532 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1533 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1534 "String #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1535 offset += 4+tvb_get_letohl(tvb, offset);
1543 if (check_slsk_format(tvb, offset, "isii")) {
1544 /* Client-to-Server & Server-to-Client */
1545 message_type = "Place In Line Response";
1546 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1547 "Message Type: %s (Code: %02d)", message_type, msg_code);
1549 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1550 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1551 offset += 4+tvb_get_letohl(tvb, offset);
1552 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1554 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1560 if (check_slsk_format(tvb, offset, "is")) {
1561 /* Server-to-Client */
1562 message_type = "Room Added";
1563 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1564 "Message Type: %s (Code: %02d)", message_type, msg_code);
1566 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1567 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1568 offset += 4+tvb_get_letohl(tvb, offset);
1573 if (check_slsk_format(tvb, offset, "is")) {
1574 /* Server-to-Client */
1575 message_type = "Room Removed";
1576 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1577 "Message Type: %s (Code: %02d)", message_type, msg_code);
1579 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1580 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1581 offset += 4+tvb_get_letohl(tvb, offset);
1586 if (check_slsk_format(tvb, offset, "i")) {
1587 /* Client-to-Server */
1588 message_type = "Room List Request";
1589 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1590 "Message Type: %s (Code: %02d)", message_type, msg_code);
1593 else if (check_slsk_format(tvb, offset, "ii*")) {
1594 /* Server-to-Client */
1595 message_type = "Room List";
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 i=0; j = tvb_get_letohl(tvb, offset);
1600 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1603 if (check_slsk_format(tvb, offset, "s*")) {
1604 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1605 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1606 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1607 "Room #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1608 offset += 4+tvb_get_letohl(tvb, offset);
1612 if (check_slsk_format(tvb, offset, "i*")) {
1614 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1617 if (check_slsk_format(tvb, offset, "i*")) {
1618 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1619 "Users in Room #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1629 if (check_slsk_format(tvb, offset, "isissiii")) {
1630 /* Server-to-Client */
1631 message_type = "Exact File Search";
1632 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1633 "Message Type: %s (Code: %02d)", message_type, msg_code);
1635 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1636 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1637 offset += 4+tvb_get_letohl(tvb, offset);
1638 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1640 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1641 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1642 offset += 4+tvb_get_letohl(tvb, offset);
1643 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1644 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1645 offset += 4+tvb_get_letohl(tvb, offset);
1646 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 16, 0,
1650 else if (check_slsk_format(tvb, offset, "iissiiib")) {
1651 /* Client-to-Server */
1652 message_type = "Exact File Search";
1653 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1654 "Message Type: %s (Code: %02d)", message_type, msg_code);
1656 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1658 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1659 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1660 offset += 4+tvb_get_letohl(tvb, offset);
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_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1663 offset += 4+tvb_get_letohl(tvb, offset);
1664 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 13, 0,
1671 if (check_slsk_format(tvb, offset, "is")) {
1672 /* Server-to-Client */
1673 message_type = "Admin Message";
1674 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1675 "Message Type: %s (Code: %02d)", message_type, msg_code);
1677 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1678 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1679 offset += 4+tvb_get_letohl(tvb, offset);
1684 if (check_slsk_format(tvb, offset, "i")) {
1685 /* Client-to-Server */
1686 message_type = "Global User List Request";
1687 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1688 "Message Type: %s (Code: %02d)", message_type, msg_code);
1691 else if (check_slsk_format(tvb, offset, "isi*")) { /* same as case 14 */
1692 /* Server-to-Client */
1693 message_type = "Global User List";
1694 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1695 "Message Type: %s (Code: %02d)", message_type, msg_code);
1697 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1698 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1699 offset += 4+tvb_get_letohl(tvb, offset);
1700 i=0; j = tvb_get_letohl(tvb, offset);
1701 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1704 if (check_slsk_format(tvb, offset, "s*")) {
1705 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1706 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1707 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1708 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1709 offset += 4+tvb_get_letohl(tvb, offset);
1713 if (check_slsk_format(tvb, offset, "i*")) {
1714 i=0; j = tvb_get_letohl(tvb, offset);
1715 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1718 if (check_slsk_format(tvb, offset, "i*")) {
1719 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1720 "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));
1726 if (check_slsk_format(tvb, offset, "i*")) {
1727 i=0; j = tvb_get_letohl(tvb, offset);
1728 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1731 if (check_slsk_format(tvb, offset, "iiiii*")) {
1732 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1733 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1735 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1736 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1738 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1739 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1741 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1742 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1744 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1745 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1751 if (check_slsk_format(tvb, offset, "i*")) {
1752 i=0; j = tvb_get_letohl(tvb, offset);
1753 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1754 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
1757 if (check_slsk_format(tvb, offset, "i*")) {
1758 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1759 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1769 if (check_slsk_format(tvb, offset, "isiiiis")) {
1770 message_type = "Tunneled Message";
1771 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1772 "Message Type: %s (Code: %02d)", message_type, msg_code);
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_username, 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_code, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1779 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1781 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
1783 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1785 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1786 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1787 offset += 4+tvb_get_letohl(tvb, offset);
1792 if (check_slsk_format(tvb, offset, "i")) {
1793 /* Client-to-Server */
1794 message_type = "Privileged User List Request";
1795 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1796 "Message Type: %s (Code: %02d)", message_type, msg_code);
1799 else if (check_slsk_format(tvb, offset, "ii*")) {
1800 /* Server-to-Client */
1801 message_type = "Privileged User List";
1802 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1803 "Message Type: %s (Code: %02d)", message_type, msg_code);
1805 i=0; j = tvb_get_letohl(tvb, offset);
1806 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1807 "Number of Priviledged Users: %d", tvb_get_letohl(tvb, offset));
1810 if (check_slsk_format(tvb, offset, "s*")) {
1811 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1812 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1813 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1814 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1815 offset += 4+tvb_get_letohl(tvb, offset);
1823 if (check_slsk_format(tvb, offset, "ib")) {
1824 /* Client-to-Server */
1825 message_type = "Get Parent List";
1826 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1827 "Message Type: %s (Code: %02d)", message_type, msg_code);
1829 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1835 if (check_slsk_format(tvb, offset, "ii")) {
1836 /* Client-to-Server */
1837 message_type = "Type 73";
1838 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1839 "Message Type: %s (Code: %02d)", message_type, msg_code);
1841 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1847 if (check_slsk_format(tvb, offset, "ii")) {
1848 /* Server-to-Client */
1849 message_type = "Parent Min Speed";
1850 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1851 "Message Type: %s (Code: %02d)", message_type, msg_code);
1853 proto_tree_add_uint(slsk_tree, hf_slsk_parent_min_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1859 if (check_slsk_format(tvb, offset, "ii")) {
1860 /* Server-to-Client */
1861 message_type = "Parent Speed Connection Ratio";
1862 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1863 "Message Type: %s (Code: %02d)", message_type, msg_code);
1865 proto_tree_add_uint(slsk_tree, hf_slsk_parent_speed_connection_ratio, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1871 if (check_slsk_format(tvb, offset, "ii")) {
1872 /* Server-to-Client */
1873 message_type = "Parent Inactivity Before Disconnect";
1874 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1875 "Message Type: %s (Code: %02d)", message_type, msg_code);
1877 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_parent_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1883 if (check_slsk_format(tvb, offset, "ii")) {
1884 /* Server-to-Client */
1885 message_type = "Server Inactivity Before Disconnect";
1886 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1887 "Message Type: %s (Code: %02d)", message_type, msg_code);
1889 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_server_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1895 if (check_slsk_format(tvb, offset, "ii")) {
1896 /* Server-to-Client */
1897 message_type = "Nodes In Cache Before Disconnect";
1898 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1899 "Message Type: %s (Code: %02d)", message_type, msg_code);
1901 proto_tree_add_uint(slsk_tree, hf_slsk_nodes_in_cache_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1907 if (check_slsk_format(tvb, offset, "ii")) {
1908 /* Server-to-Client */
1909 message_type = "Seconds Before Ping Children";
1910 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1911 "Message Type: %s (Code: %02d)", message_type, msg_code);
1913 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_before_ping_children, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1919 if (check_slsk_format(tvb, offset, "is")) {
1920 /* Server-to-Client */
1921 message_type = "Add To Privileged";
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 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1926 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1927 offset += 4+tvb_get_letohl(tvb, offset);
1932 if (check_slsk_format(tvb, offset, "i")) {
1933 /* Client-to-Server */
1934 message_type = "Check Privileges";
1935 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1936 "Message Type: %s (Code: %02d)", message_type, msg_code);
1939 else if (check_slsk_format(tvb, offset, "ii")) {
1940 /* Server-to-Client */
1941 message_type = "Check Privileges Reply";
1942 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1943 "Message Type: %s (Code: %02d)", message_type, msg_code);
1945 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_days, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1951 if (check_slsk_format(tvb, offset, "ibisis")) {
1952 /* Server-to-Client */
1953 message_type = "Embedded Message";
1954 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1955 "Message Type: %s (Code: %02d)", message_type, msg_code);
1957 if ( tvb_get_guint8(tvb, offset) == 3 ){
1958 /* Client-to-Client */
1959 message_type = "Distributed Search";
1960 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
1961 "Embedded Message Type: %s (Byte: %d)", message_type, 3);
1963 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1965 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1966 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1967 offset += 4+tvb_get_letohl(tvb, offset);
1968 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1970 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1971 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1972 offset += 4+tvb_get_letohl(tvb, offset);
1978 if (check_slsk_format(tvb, offset, "ib")) {
1979 /* Client-to-Server */
1980 message_type = "Become Parent";
1981 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1982 "Message Type: %s (Code: %02d)", message_type, msg_code);
1984 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1990 if (check_slsk_format(tvb, offset, "ii*")) {
1991 /* Server-to-Client */
1992 message_type = "Random Parent Addresses";
1993 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1994 "Message Type: %s (Code: %02d)", message_type, msg_code);
1996 i=0; j = tvb_get_letohl(tvb, offset);
1997 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1998 "Number of Parent Addresses: %d", tvb_get_letohl(tvb, offset));
2001 if (check_slsk_format(tvb, offset, "sii*")) {
2002 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2003 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2004 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2005 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2006 offset += 4+tvb_get_letohl(tvb, offset);
2007 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
2009 proto_tree_add_uint_format(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2010 "Port Number #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2019 if (check_slsk_format(tvb, offset, "iis")) {
2020 /* Server-to-Client */
2021 message_type = "Send Wishlist Entry";
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_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2027 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2028 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2029 offset += 4+tvb_get_letohl(tvb, offset);
2034 if (check_slsk_format(tvb, offset, "ii")) {
2035 /* Server-to-Client */
2036 message_type = "Type 104";
2037 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2038 "Message Type: %s (Code: %02d)", message_type, msg_code);
2040 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2046 if (check_slsk_format(tvb, offset, "i")) {
2047 /* Client-to-Server */
2048 message_type = "Get Similar Users";
2049 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2050 "Message Type: %s (Code: %02d)", message_type, msg_code);
2053 else if (check_slsk_format(tvb, offset, "ii*")) {
2054 /* Server-to-Client */
2055 message_type = "Get Similar Users Reply";
2056 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2057 "Message Type: %s (Code: %02d)", message_type, msg_code);
2059 i=0; j = tvb_get_letohl(tvb, offset);
2060 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2061 "Number of Users: %d", tvb_get_letohl(tvb, offset));
2064 if (check_slsk_format(tvb, offset, "si*")) {
2065 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2066 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2067 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2068 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2069 offset += 4+tvb_get_letohl(tvb, offset);
2070 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2071 "Same Recommendations #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2080 if (check_slsk_format(tvb, offset, "is")) {
2081 /* Client-to-Server */
2082 message_type = "Get Recommendations for Item";
2083 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2084 "Message Type: %s (Code: %02d)", message_type, msg_code);
2086 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2087 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2088 offset += 4+tvb_get_letohl(tvb, offset);
2090 else if (check_slsk_format(tvb, offset, "isi*")) {
2091 /* Server-to-Client */
2092 message_type = "Get Recommendations for Item Reply";
2093 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2094 "Message Type: %s (Code: %02d)", message_type, msg_code);
2096 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2097 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2098 offset += 4+tvb_get_letohl(tvb, offset);
2099 i=0; j = tvb_get_letohl(tvb, offset);
2100 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2101 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2104 if (check_slsk_format(tvb, offset, "si*")) {
2105 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2106 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2107 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2108 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2109 offset += 4+tvb_get_letohl(tvb, offset);
2110 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2111 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2120 if (check_slsk_format(tvb, offset, "is")) {
2121 /* Client-to-Server */
2122 message_type = "Get Similar Users for Item";
2123 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2124 "Message Type: %s (Code: %02d)", message_type, msg_code);
2126 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2127 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2128 offset += 4+tvb_get_letohl(tvb, offset);
2130 else if (check_slsk_format(tvb, offset, "isi*")) {
2131 /* Server-to-Client */
2132 message_type = "Get Similar Users for Item Reply";
2133 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2134 "Message Type: %s (Code: %02d)", message_type, msg_code);
2136 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2137 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2138 offset += 4+tvb_get_letohl(tvb, offset);
2139 i=0; j = tvb_get_letohl(tvb, offset);
2140 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2141 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2144 if (check_slsk_format(tvb, offset, "s*")) {
2145 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2146 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2147 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2148 "Username #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2149 offset += 4+tvb_get_letohl(tvb, offset);
2157 if (check_slsk_format(tvb, offset, "iis")) {
2158 /* Client-to-Server */
2159 message_type = "Can't Connect To Peer";
2160 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2161 "Message Type: %s (Code: %02d)", message_type, msg_code);
2163 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2165 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2166 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2167 offset += 4+tvb_get_letohl(tvb, offset);
2169 else if (check_slsk_format(tvb, offset, "ii")) {
2170 /* Server-to-Client */
2171 message_type = "Can't Connect To Peer";
2172 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2173 "Message Type: %s (Code: %02d)", message_type, msg_code);
2175 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2181 if (check_slsk_format(tvb, offset, "bisis")) {
2182 if ( tvb_get_guint8(tvb, offset) == 3 ){
2183 /* Client-to-Client */
2184 message_type = "Distributed Search";
2185 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2186 "Message Type: %s (Byte: %d)", message_type, 3);
2188 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2190 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2191 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2192 offset += 4+tvb_get_letohl(tvb, offset);
2193 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2195 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2196 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2197 offset += 4+tvb_get_letohl(tvb, offset);
2200 else if (check_slsk_format(tvb, offset, "bssi")) {
2201 if ( tvb_get_guint8(tvb, offset) == 1 ){
2202 /* Client-to-Client */
2203 message_type = "Peer Init";
2204 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2205 "Message Type: %s (Byte: %d)", message_type, 1);
2207 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2208 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2209 offset += 4+tvb_get_letohl(tvb, offset);
2210 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2211 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)),
2212 "Connection Type: %s (Char: %s)", connection_type(tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset))), tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2213 offset += 4+tvb_get_letohl(tvb, offset);
2214 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2218 else if (check_slsk_format(tvb, offset, "bi")) {
2219 if ( tvb_get_guint8(tvb, offset) == 0 ){
2220 /* Client-to-Client */
2221 message_type = "Pierce Fw";
2222 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2223 "Message Type: %s (Byte: %d)", message_type, 0);
2225 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2230 message_type = "Unknown";
2231 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2232 "Message Type: %s (Code: %02d)", message_type, msg_code);
2245 static void dissect_slsk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2247 tcp_dissect_pdus(tvb, pinfo, tree, slsk_desegment, 4, get_slsk_pdu_len, dissect_slsk_pdu);
2252 /* Register the protocol with Ethereal */
2255 proto_register_slsk(void)
2258 /* Setup list of header fields */
2259 static hf_register_info hf[] = {
2261 { "Integer", "slsk.integer",
2262 FT_UINT32, BASE_DEC, NULL, 0, "Integer", HFILL } },
2264 { "String", "slsk.string",
2265 FT_STRING, BASE_NONE, NULL, 0, "String", HFILL } },
2267 { "Byte", "slsk.byte",
2268 FT_UINT8, BASE_DEC, NULL, 0, "Byte", HFILL } },
2269 { &hf_slsk_message_length,
2270 { "Message Length", "slsk.message.length",
2271 FT_UINT32, BASE_DEC, NULL, 0, "Message Length", HFILL } },
2272 { &hf_slsk_message_code,
2273 { "Message Code", "slsk.message.code",
2274 FT_UINT32, BASE_DEC, NULL, 0, "Message Code", HFILL } },
2275 { &hf_slsk_client_ip,
2276 { "Client IP", "slsk.server.ip",
2277 FT_IPv4, BASE_DEC, NULL, 0, "Client IP Address", HFILL } },
2278 { &hf_slsk_server_ip,
2279 { "SoulSeek Server IP", "slsk.server.ip",
2280 FT_UINT32, BASE_DEC, NULL, 0, "SoulSeek Server IP", HFILL } },
2281 { &hf_slsk_string_length,
2282 { "String Length", "slsk.string.length",
2283 FT_UINT32, BASE_DEC, NULL, 0, "String Length", HFILL } },
2284 { &hf_slsk_username,
2285 { "Username", "slsk.username",
2286 FT_STRING, BASE_NONE, NULL, 0, "Username", HFILL } },
2287 { &hf_slsk_password,
2288 { "Password", "slsk.password",
2289 FT_STRING, BASE_NONE, NULL, 0, "Password", HFILL } },
2291 { "Version", "slsk.version",
2292 FT_UINT32, BASE_DEC, NULL, 0, "Version", HFILL } },
2293 { &hf_slsk_login_successfull,
2294 { "Login successfull", "slsk.login.successfull",
2295 FT_UINT8, BASE_DEC, NULL, 0, "Login Successfull", HFILL } },
2296 { &hf_slsk_login_message,
2297 { "Login Message", "slsk.login.message",
2298 FT_STRING, BASE_NONE, NULL, 0, "Login Message", HFILL } },
2300 { "Port Number", "slsk.port.number",
2301 FT_UINT32, BASE_DEC, NULL, 0, "Port Number", HFILL } },
2303 { "IP Address", "slsk.ip.address",
2304 FT_IPv4, BASE_DEC, NULL, 0, "IP Address", HFILL } },
2305 { &hf_slsk_user_exists,
2306 { "user exists", "slsk.user.exists",
2307 FT_UINT8, BASE_DEC, NULL, 0, "User exists", HFILL } },
2308 { &hf_slsk_status_code,
2309 { "Status Code", "slsk.status.code",
2310 FT_UINT32, BASE_DEC, NULL, 0, "Status Code", HFILL } },
2312 { "Room", "slsk.room",
2313 FT_STRING, BASE_NONE, NULL, 0, "Room", HFILL } },
2314 { &hf_slsk_chat_message,
2315 { "Chat Message", "slsk.chat.message",
2316 FT_STRING, BASE_NONE, NULL, 0, "Chat Message", HFILL } },
2317 { &hf_slsk_users_in_room,
2318 { "Users in Room", "slsk.room.users",
2319 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users in Room", HFILL } },
2321 { "Token", "slsk.token",
2322 FT_UINT32, BASE_DEC, NULL, 0, "Token", HFILL } },
2323 { &hf_slsk_connection_type,
2324 { "Connection Type", "slsk.connection.type",
2325 FT_STRING, BASE_NONE, NULL, 0, "Connection Type", HFILL } },
2326 { &hf_slsk_chat_message_id,
2327 { "Chat Message ID", "slsk.chat.message.id",
2328 FT_UINT32, BASE_DEC, NULL, 0, "Chat Message ID", HFILL } },
2329 { &hf_slsk_timestamp,
2330 { "Timestamp", "slsk.timestamp",
2331 FT_UINT32, BASE_DEC, NULL, 0, "Timestamp", HFILL } },
2332 { &hf_slsk_search_text,
2333 { "Search Text", "slsk.search.text",
2334 FT_STRING, BASE_NONE, NULL, 0, "Search Text", HFILL } },
2335 { &hf_slsk_folder_count,
2336 { "Folder Count", "slsk.folder.count",
2337 FT_UINT32, BASE_DEC, NULL, 0, "Folder Count", HFILL } },
2338 { &hf_slsk_file_count,
2339 { "File Count", "slsk.file.count",
2340 FT_UINT32, BASE_DEC, NULL, 0, "File Count", HFILL } },
2341 { &hf_slsk_average_speed,
2342 { "Average Speed", "slsk.average.speed",
2343 FT_UINT32, BASE_DEC, NULL, 0, "Average Speed", HFILL } },
2344 { &hf_slsk_download_number,
2345 { "Download Number", "slsk.download.number",
2346 FT_UINT32, BASE_DEC, NULL, 0, "Download Number", HFILL } },
2348 { "Files", "slsk.files",
2349 FT_UINT32, BASE_DEC, NULL, 0, "Files", HFILL } },
2350 { &hf_slsk_directories,
2351 { "Directories", "slsk.directories",
2352 FT_UINT32, BASE_DEC, NULL, 0, "Directories", HFILL } },
2353 { &hf_slsk_slotsfull,
2354 { "Slots full", "slsk.slots.full",
2355 FT_UINT32, BASE_DEC, NULL, 0, "Upload Slots Full", HFILL } },
2356 { &hf_slsk_place_in_queue,
2357 { "Place in Queue", "slsk.queue.place",
2358 FT_UINT32, BASE_DEC, NULL, 0, "Place in Queue", HFILL } },
2359 { &hf_slsk_number_of_rooms,
2360 { "Number of Rooms", "slsk.room.count",
2361 FT_UINT32, BASE_DEC, NULL, 0, "Number of Rooms", HFILL } },
2362 { &hf_slsk_filename,
2363 { "Filename", "slsk.filename",
2364 FT_STRING, BASE_NONE, NULL, 0, "Filename", HFILL } },
2365 { &hf_slsk_directory,
2366 { "Directory", "slsk.directory",
2367 FT_STRING, BASE_NONE, NULL, 0, "Directory", HFILL } },
2369 { "Size", "slsk.size",
2370 FT_UINT32, BASE_DEC, NULL, 0, "File Size", HFILL } },
2371 { &hf_slsk_checksum,
2372 { "Checksum", "slsk.checksum",
2373 FT_UINT32, BASE_DEC, NULL, 0, "Checksum", HFILL } },
2375 { "Code", "slsk.code",
2376 FT_UINT32, BASE_DEC, NULL, 0, "Code", HFILL } },
2377 { &hf_slsk_number_of_users,
2378 { "Number of Users", "slsk.user.count",
2379 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users", HFILL } },
2380 { &hf_slsk_number_of_days,
2381 { "Number of Days", "slsk.day.count",
2382 FT_UINT32, BASE_DEC, NULL, 0, "Number of Days", HFILL } },
2383 { &hf_slsk_transfer_direction,
2384 { "Transfer Direction", "slsk.transfer.direction",
2385 FT_UINT32, BASE_DEC, NULL, 0, "Transfer Direction", HFILL } },
2386 { &hf_slsk_user_description,
2387 { "User Description", "slsk.user.description",
2388 FT_STRING, BASE_NONE, NULL, 0, "User Description", HFILL } },
2389 { &hf_slsk_picture_exists,
2390 { "Picture exists", "slsk.user.picture.exists",
2391 FT_UINT8, BASE_DEC, NULL, 0, "User has a picture", HFILL } },
2393 { "Picture", "slsk.user.picture",
2394 FT_STRING, BASE_NONE, NULL, 0, "User Picture", HFILL } },
2395 { &hf_slsk_user_uploads,
2396 { "User uploads", "slsk.uploads.user",
2397 FT_UINT32, BASE_DEC, NULL, 0, "User uploads", HFILL } },
2398 { &hf_slsk_total_uploads,
2399 { "Total uploads allowed", "slsk.uploads.total",
2400 FT_UINT32, BASE_DEC, NULL, 0, "Total uploads allowed", HFILL } },
2401 { &hf_slsk_queued_uploads,
2402 { "Queued uploads", "slsk.uploads.queued",
2403 FT_UINT32, BASE_DEC, NULL, 0, "Queued uploads", HFILL } },
2404 { &hf_slsk_slots_available,
2405 { "Upload Slots available", "slsk.uploads.available",
2406 FT_UINT8, BASE_DEC, NULL, 0, "Upload Slots available", HFILL } },
2408 { "Download allowed", "slsk.user.allowed",
2409 FT_UINT8, BASE_DEC, NULL, 0, "allowed", HFILL } },
2410 { &hf_slsk_compr_packet,
2411 { "[zlib compressed packet]", "slsk.compr.packet",
2412 FT_NONE, BASE_NONE, NULL, 0, "zlib compressed packet", HFILL } },
2413 { &hf_slsk_parent_min_speed,
2414 { "Parent Min Speed", "slsk.parent.min.speed",
2415 FT_UINT32, BASE_DEC, NULL, 0, "Parent Min Speed", HFILL } },
2416 { &hf_slsk_parent_speed_connection_ratio,
2417 { "Parent Speed Connection Ratio", "slsk.parent.speed.connection.ratio",
2418 FT_UINT32, BASE_DEC, NULL, 0, "Parent Speed Connection Ratio", HFILL } },
2419 { &hf_slsk_seconds_parent_inactivity_before_disconnect,
2420 { "Seconds Parent Inactivity Before Disconnect", "slsk.seconds.parent.inactivity.before.disconnect",
2421 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Parent Inactivity Before Disconnect", HFILL } },
2422 { &hf_slsk_seconds_server_inactivity_before_disconnect,
2423 { "Seconds Server Inactivity Before Disconnect", "slsk.seconds.server.inactivity.before.disconnect",
2424 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Server Inactivity Before Disconnect", HFILL } },
2425 { &hf_slsk_nodes_in_cache_before_disconnect,
2426 { "Nodes In Cache Before Disconnect", "slsk.nodes.in.cache.before.disconnect",
2427 FT_UINT32, BASE_DEC, NULL, 0, "Nodes In Cache Before Disconnect", HFILL } },
2428 { &hf_slsk_seconds_before_ping_children,
2429 { "Seconds Before Ping Children", "slsk.seconds.before.ping.children",
2430 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Before Ping Children", HFILL } },
2431 { &hf_slsk_recommendation,
2432 { "Recommendation", "slsk.recommendation",
2433 FT_STRING, BASE_NONE, NULL, 0, "Recommendation", HFILL } },
2435 { "Ranking", "slsk.ranking",
2436 FT_UINT32, BASE_DEC, NULL, 0, "Ranking", HFILL } },
2439 /* Setup protocol subtree array */
2440 static gint *ett[] = {
2442 &ett_slsk_compr_packet,
2444 module_t *slsk_module;
2446 /* Registers the protocol name and description */
2447 proto_slsk = proto_register_protocol("SoulSeek Protocol", "SoulSeek", "slsk");
2449 /* Required function calls to register the header fields and subtrees used */
2450 proto_register_field_array(proto_slsk, hf, array_length(hf));
2451 proto_register_subtree_array(ett, array_length(ett));
2453 slsk_module = prefs_register_protocol(proto_slsk, NULL);
2455 /* Registers the options in the menu preferences */
2456 prefs_register_bool_preference(slsk_module, "desegment",
2457 "Desegment all SoulSeek messages spanning multiple TCP segments",
2458 "Whether the SoulSeek dissector should desegment all messages spanning multiple TCP segments",
2461 prefs_register_bool_preference(slsk_module, "decompress",
2462 "Decompress zlib compressed packets inside SoulSeek messages",
2463 "Whether the SoulSeek dissector should decompress all zlib compressed packets inside messages",
2471 proto_reg_handoff_slsk(void)
2473 dissector_handle_t slsk_handle;
2475 slsk_handle = create_dissector_handle(dissect_slsk, proto_slsk);
2476 dissector_add("tcp.port", TCP_PORT_SLSK_1, slsk_handle);
2477 dissector_add("tcp.port", TCP_PORT_SLSK_2, slsk_handle);
2478 dissector_add("tcp.port", TCP_PORT_SLSK_3, slsk_handle);