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.2 2004/02/12 20:58:01 guy 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.
48 #include <epan/packet.h>
49 #include "packet-tcp.h"
52 /* Initialize the protocol and registered fields */
53 static int proto_slsk = -1;
55 static int hf_slsk_integer = -1;
56 static int hf_slsk_string = -1;
57 static int hf_slsk_byte = -1;
58 static int hf_slsk_message_length = -1;
59 static int hf_slsk_message_code = -1;
60 static int hf_slsk_client_ip = -1;
61 static int hf_slsk_server_ip = -1;
62 static int hf_slsk_string_length = -1;
63 static int hf_slsk_username = -1;
64 static int hf_slsk_password = -1;
65 static int hf_slsk_version = -1;
66 static int hf_slsk_login_successfull = -1;
67 static int hf_slsk_login_message = -1;
68 static int hf_slsk_port = -1;
69 static int hf_slsk_ip = -1;
70 static int hf_slsk_user_exists = -1;
71 static int hf_slsk_status_code = -1;
72 static int hf_slsk_room = -1;
73 static int hf_slsk_chat_message = -1;
74 static int hf_slsk_users_in_room = -1;
75 static int hf_slsk_token = -1;
76 static int hf_slsk_connection_type = -1;
77 static int hf_slsk_chat_message_id = -1;
78 static int hf_slsk_timestamp = -1;
79 static int hf_slsk_search_text = -1;
80 static int hf_slsk_folder_count = -1;
81 static int hf_slsk_file_count = -1;
82 static int hf_slsk_average_speed = -1;
83 static int hf_slsk_download_number = -1;
84 static int hf_slsk_files = -1;
85 static int hf_slsk_directories = -1;
86 static int hf_slsk_slotsfull = -1;
87 static int hf_slsk_place_in_queue = -1;
88 static int hf_slsk_number_of_rooms = -1;
89 static int hf_slsk_filename = -1;
90 static int hf_slsk_directory = -1;
91 static int hf_slsk_size = -1;
92 static int hf_slsk_checksum = -1;
93 static int hf_slsk_code = -1;
94 static int hf_slsk_number_of_users = -1;
95 static int hf_slsk_number_of_days = -1;
96 static int hf_slsk_transfer_direction = -1;
97 static int hf_slsk_user_description = -1;
98 static int hf_slsk_picture_exists = -1;
99 static int hf_slsk_picture = -1;
100 static int hf_slsk_user_uploads = -1;
101 static int hf_slsk_total_uploads = -1;
102 static int hf_slsk_queued_uploads = -1;
103 static int hf_slsk_slots_available = -1;
104 static int hf_slsk_allowed = -1;
105 static int hf_slsk_compr_packet = -1;
106 static int hf_slsk_parent_min_speed = -1;
107 static int hf_slsk_parent_speed_connection_ratio = -1;
108 static int hf_slsk_seconds_parent_inactivity_before_disconnect = -1;
109 static int hf_slsk_seconds_server_inactivity_before_disconnect = -1;
110 static int hf_slsk_nodes_in_cache_before_disconnect = -1;
111 static int hf_slsk_seconds_before_ping_children = -1;
112 static int hf_slsk_recommendation = -1;
113 static int hf_slsk_ranking = -1;
116 /* Initialize the subtree pointers */
117 static gint ett_slsk = -1;
118 static gint ett_slsk_compr_packet = -1;
120 #define TCP_PORT_SLSK_1 2234
121 #define TCP_PORT_SLSK_2 5534
122 #define TCP_PORT_SLSK_3 2240
125 /* desegmentation of SoulSeek Message over TCP */
126 static gboolean slsk_desegment = TRUE;
128 static gboolean slsk_decompress = TRUE;
130 static gboolean slsk_decompress = FALSE;
133 static const value_string slsk_tcp_msgs[] = {
135 { 2, "Set Wait Port"},
136 { 3, "Get Peer Address"},
137 { 4, "Get Shared File List"},
138 { 5, "User Exists / Shared File List"},
139 { 7, "Get User Status"},
140 { 9, "File Search Result"},
141 { 13, "Say ChatRoom"},
143 { 15, "Leave Room / User Info Request"},
144 { 16, "User Joined Room / User Info Reply"},
145 { 17, "User Left Room"},
146 { 18, "Connect To Peer"},
147 { 22, "Message User"},
148 { 23, "Message User Ack"},
149 { 26, "File Search"},
152 { 34, "Update Upload Speed"},
153 { 35, "Shared Files & Folders"},
154 { 36, "Get User Stats / Folder Contents Request"},
155 { 37, "Folder Contents Response"},
156 { 40, "Queued Downloads / Transfer Request"},
157 { 41, "Transfer Response"},
158 { 42, "Placehold Upload"},
159 { 43, "Queue Upload"},
160 { 44, "Place In Queue"},
161 { 46, "Upload Failed"},
162 { 50, "Queue Failed / Own Recommendation"},
163 { 51, "Add Things I like / Place In Queue Request"},
164 { 52, "Remove Things I like"},
165 { 54, "Get Recommendations"},
167 { 56, "Get Global Rankings"},
168 { 57, "Get User Recommendations"},
169 { 58, "Admin Command"},
170 { 60, "Place In Line Response"},
172 { 63, "Room Removed"},
174 { 65, "Exact File Search"},
175 { 66, "Admin Message"},
176 { 67, "Global User List"},
177 { 68, "Tunneled Message"},
178 { 69, "Privileged User List"},
179 { 71, "Get Parent List"},
181 { 83, "Parent Min Speed"},
182 { 84, "Parent Speed Connection Ratio"},
183 { 86, "Parent Inactivity Before Disconnect"},
184 { 87, "Server Inactivity Before Disconnect"},
185 { 88, "Nodes In Cache Before Disconnect"},
186 { 90, "Seconds Before Ping Children"},
187 { 91, "Add To Privileged"},
188 { 92, "Check Privileges"},
189 { 93, "Embedded Message"},
190 { 100, "Become Parent"},
191 { 102, "Random Parent Addresses"},
192 { 103, "Send Wishlist Entry"},
194 { 110, "Get Similar Users"},
195 { 111, "Get Recommendations for Item"},
196 { 112, "Get Similar Users for Item"},
197 { 1001, "Can't Connect To Peer"},
200 static const value_string slsk_status_codes[] = {
207 static const value_string slsk_transfer_direction[] = {
212 static const value_string slsk_yes_no[] = {
217 static const value_string slsk_attr_type[] = {
223 static char* connection_type(char con_type[]) {
224 if (strlen(con_type) != 1) return "Unknown";
225 if (con_type[0] == 'D') return "Distributed Search";
226 if (con_type[0] == 'P') return "Peer Connection"; /* "File Search Result / User Info Request / Get Shared File List" */
227 if (con_type[0] == 'F') return "File Transfer";
231 static gboolean check_slsk_format(tvbuff_t *tvb, int offset, char format[]){
234 * Returns TRUE if tvbuff beginning at offset matches a certain format
235 * The format is given by an array of characters standing for a special field type
236 * i - integer (4 bytes)
238 * s - string (string_length + 4 bytes)
240 * * - can be used at the end of a format to ignore any following bytes
243 switch ( format[0] ) {
245 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
249 if (tvb_length_remaining(tvb, offset) < 1) return FALSE;
253 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
254 if (tvb_length_remaining(tvb, offset) < (int)tvb_get_letohl(tvb, offset)+4) return FALSE;
255 offset += tvb_get_letohl(tvb, offset)+4;
265 if (format[1] == '\0' ) {
266 if (tvb_length_remaining(tvb, offset) != 0) return FALSE; /* Checks for additional bytes at the end */
269 return check_slsk_format(tvb, offset, &format[1]);
273 static char* get_message_type(tvbuff_t *tvb) {
275 * Checks if the Message Code is known.
276 * If unknown checks if the Message Code is stored in a byte.
277 * Returns the Message Type.
279 int msg_code = tvb_get_letohl(tvb, 4);
280 gchar *message_type = val_to_str(msg_code, slsk_tcp_msgs, "Unknown");
281 if (strcmp(message_type, "Unknown") == 0) {
282 if (check_slsk_format(tvb, 4, "bisis")) message_type = "Distributed Search";
283 if (check_slsk_format(tvb, 4, "bssi")) message_type = "Peer Init";
284 if (check_slsk_format(tvb, 4, "bi")) message_type = "Pierce Fw";
289 static guint get_slsk_pdu_len(tvbuff_t *tvb, int offset)
292 msg_len = tvb_get_letohl(tvb, offset);
293 /* That length doesn't include the length field itself; add that in. */
299 static tvbuff_t* uncompress_packet(tvbuff_t *tvb, int offset, int comprlen){
302 * Uncompresses a zlib compressed packet inside a message of tvb at offset with length comprlen
303 * Returns an uncompressed tvbuffer if uncompression succeeded
304 * or NULL if uncompression failed
308 long uncomprlen = (comprlen*10);
311 tvbuff_t *uncompr_tvb;
313 compr = tvb_memdup(tvb, offset, comprlen);
317 uncompr = g_malloc(uncomprlen);
323 err = uncompress((Bytef *)uncompr, &uncomprlen, (Bytef *)compr, comprlen);
330 uncompr_tvb = tvb_new_real_data((guint8*) uncompr, uncomprlen, uncomprlen);
335 static tvbuff_t* uncompress_packet(tvbuff_t *tvb, int offset, int comprlen){
342 /* Code to actually dissect the packets */
344 static void dissect_slsk_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
347 /* Set up structures needed to add the protocol subtree and manage it */
349 proto_tree *slsk_tree;
352 guint32 msg_len, msg_code;
357 int uncompr_tvb_offset = 0;
365 msg_len = tvb_get_letohl(tvb, offset);
366 msg_code = tvb_get_letohl(tvb, offset+4);
367 message_type = get_message_type(tvb);
369 /* Make entries in Protocol column and Info column on summary display */
370 if (check_col(pinfo->cinfo, COL_PROTOCOL))
371 col_set_str(pinfo->cinfo, COL_PROTOCOL, "slsk");
373 /* This field shows up as the "Info" column in the display */
375 if (check_col(pinfo->cinfo, COL_INFO))
376 col_set_str(pinfo->cinfo, COL_INFO, "SoulSeek Message");
378 if (check_col(pinfo->cinfo, COL_INFO)) {
379 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_type);
385 /* create display subtree for the protocol */
386 ti = proto_tree_add_item(tree, proto_slsk, tvb, 0, -1, FALSE);
387 slsk_tree = proto_item_add_subtree(ti, ett_slsk);
389 /* Continue adding tree items to process the packet here */
391 proto_tree_add_uint(slsk_tree, hf_slsk_message_length, tvb, offset, 4, msg_len);
397 if (check_slsk_format(tvb, offset, "issi")) {
398 /* Client-to-Server */
399 message_type = "Login";
400 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
401 "Message Type: %s (Code: %02d)", message_type, msg_code);
403 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
404 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
405 offset += 4+tvb_get_letohl(tvb, offset);
406 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
407 proto_tree_add_item(slsk_tree, hf_slsk_password, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
408 offset += 4+tvb_get_letohl(tvb, offset);
409 proto_tree_add_uint(slsk_tree, hf_slsk_version, tvb, offset, 4, tvb_get_letohl(tvb, offset));
412 else if (check_slsk_format(tvb, offset, "ibs") || check_slsk_format(tvb, offset, "ibsi")) {
413 /* Server-to-Client */
414 message_type = "Login Reply";
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 i=tvb_get_guint8(tvb, offset);
419 proto_tree_add_uint_format(slsk_tree, hf_slsk_login_successfull, tvb, offset, 1, tvb_get_guint8(tvb, offset),
420 "Login successfull: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
422 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
423 proto_tree_add_item(slsk_tree, hf_slsk_login_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
424 offset += 4+tvb_get_letohl(tvb, offset);
426 proto_tree_add_ipv4(slsk_tree, hf_slsk_client_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
433 if (check_slsk_format(tvb, offset, "ii")) {
434 /* Client-to-Server */
435 message_type = "Set Wait Port";
436 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
437 "Message Type: %s (Code: %02d)", message_type, msg_code);
439 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
445 if (check_slsk_format(tvb, offset, "isii")) {
446 /* Server-to-Client */
447 message_type = "Get Peer Address Reply";
448 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
449 "Message Type: %s (Code: %02d)", message_type, msg_code);
451 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
452 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
453 offset += 4+tvb_get_letohl(tvb, offset);
454 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
456 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
459 else if (check_slsk_format(tvb, offset, "is")) {
460 /* Client-to-Server */
461 message_type = "Get Peer Address";
462 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
463 "Message Type: %s (Code: %02d)", message_type, msg_code);
465 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
466 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
467 offset += 4+tvb_get_letohl(tvb, offset);
472 if (check_slsk_format(tvb, offset, "i")) {
473 /* Client-to-Client */
474 message_type = "Get Shared File List";
475 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
476 "Message Type: %s (Code: %02d)", message_type, msg_code);
482 if (check_slsk_format(tvb, offset, "isb")) {
483 /* Server-to-Client */
484 message_type = "User Exists Reply";
485 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
486 "Message Type: %s (Code: %02d)", message_type, msg_code);
488 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
489 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
490 offset += 4+tvb_get_letohl(tvb, offset);
491 proto_tree_add_uint_format(slsk_tree, hf_slsk_user_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
492 "User exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
495 else if (check_slsk_format(tvb, offset, "is")) {
496 /* Client-to-Server */
497 message_type = "User Exists Request";
498 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
499 "Message Type: %s (Code: %02d)", message_type, msg_code);
501 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
502 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
503 offset += 4+tvb_get_letohl(tvb, offset);
505 else if (check_slsk_format(tvb, offset, "i*")) {
506 /* Client-to-Client */
507 message_type = "Shared File List";
508 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
509 "Message Type: %s (Code: %02d)", message_type, msg_code);
512 /* [zlib compressed] */
513 comprlen = tvb_length_remaining(tvb, offset);
515 if (slsk_decompress == TRUE){
517 tvbuff_t *uncompr_tvb = uncompress_packet(tvb, offset, comprlen);
519 if (uncompr_tvb == NULL) {
520 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
521 "[zlib compressed packet]");
522 offset += tvb_length_remaining(tvb, offset);
523 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
524 "(uncompression failed !)");
527 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
528 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
530 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
531 "( compressed packet length: %d)", comprlen);
532 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
533 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
534 "(uncompressed packet length: %d)", uncomprlen);
536 /* Dissects the uncompressed tvbuffer */
537 uncompr_tvb_offset = 0;
538 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "i*")) {
539 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
540 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
541 "Number of directories: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
542 uncompr_tvb_offset += 4;
544 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
545 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),
546 "Directory #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
547 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),
548 "Directory #%d Name: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
549 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
551 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
552 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
553 "Directory #%d Number of files: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
554 uncompr_tvb_offset += 4;
556 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
557 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
558 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
559 uncompr_tvb_offset += 1;
560 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),
561 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
562 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),
563 "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)));
564 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
565 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
566 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
567 uncompr_tvb_offset += 4;
568 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
569 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
570 uncompr_tvb_offset += 4;
571 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),
572 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
573 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),
574 "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)));
575 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
577 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
578 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
579 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
580 uncompr_tvb_offset += 4;
582 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
583 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
584 "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));
585 uncompr_tvb_offset += 4;
586 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
587 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
588 uncompr_tvb_offset += 4;
601 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
602 "[zlib compressed packet]");
603 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
604 "( compressed packet length: %d)", comprlen);
605 offset += tvb_length_remaining(tvb, offset);
611 if (check_slsk_format(tvb, offset, "isi")) {
612 /* Server-to-Client */
613 message_type = "Get User Status Reply";
614 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
615 "Message Type: %s (Code: %02d)", message_type, msg_code);
617 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
618 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
619 offset += 4+tvb_get_letohl(tvb, offset);
620 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
621 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
624 else if (check_slsk_format(tvb, offset, "is")) {
625 /* Client-to-Server */
626 message_type = "Get User Status";
627 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
628 "Message Type: %s (Code: %02d)", message_type, msg_code);
630 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
631 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
632 offset += 4+tvb_get_letohl(tvb, offset);
637 if (check_slsk_format(tvb, offset, "i*")) {
638 /* Client-to-Client */
639 message_type = "File Search Result";
640 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
641 "Message Type: %s (Code: %02d)", message_type, msg_code);
644 /* [zlib compressed] */
645 comprlen = tvb_length_remaining(tvb, offset);
647 if (slsk_decompress == TRUE){
649 tvbuff_t *uncompr_tvb = uncompress_packet(tvb, offset, comprlen);
651 if (uncompr_tvb == NULL) {
652 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
653 "[zlib compressed packet]");
654 offset += tvb_length_remaining(tvb, offset);
655 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
656 "(uncompression failed !)");
659 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
660 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
662 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
663 "( compressed packet length: %d)", comprlen);
664 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
665 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
666 "(uncompressed packet length: %d)", uncomprlen);
668 /* Dissects the uncompressed tvbuffer */
669 uncompr_tvb_offset = 0;
670 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "sii*")) {
671 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
672 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),
673 "Username: %s", tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
674 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
675 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_token, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
676 uncompr_tvb_offset += 4;
677 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
678 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
679 "Number of files: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
680 uncompr_tvb_offset += 4;
682 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
683 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
684 "File #%d Code: %d", i+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
685 uncompr_tvb_offset += 1;
686 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),
687 "File #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
688 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),
689 "File #%d Filename: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
690 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
691 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
692 "File #%d Size1: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
693 uncompr_tvb_offset += 4;
694 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
695 "File #%d Size2: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
696 uncompr_tvb_offset += 4;
697 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),
698 "File #%d String Length: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
699 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),
700 "File #%d ext: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
701 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
703 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
704 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
705 "File #%d Number of attributes: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
706 uncompr_tvb_offset += 4;
708 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
709 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
710 "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));
711 uncompr_tvb_offset += 4;
712 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
713 "File #%d Attr #%d value: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
714 uncompr_tvb_offset += 4;
721 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
722 "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));
723 uncompr_tvb_offset += 1;
724 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
725 "Upload speed: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
726 uncompr_tvb_offset += 4;
727 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
728 "In Queue: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
729 uncompr_tvb_offset += 4;
733 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
734 "[zlib compressed packet]");
735 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
736 "( compressed packet length: %d)", comprlen);
737 offset += tvb_length_remaining(tvb, offset);
743 if (check_slsk_format(tvb, offset, "isss")) {
744 /* Server-to-Client */
745 message_type = "Say ChatRoom";
746 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
747 "Message Type: %s (Code: %02d)", message_type, msg_code);
749 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
750 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
751 offset += 4+tvb_get_letohl(tvb, offset);
752 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
753 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
754 offset += 4+tvb_get_letohl(tvb, offset);
755 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
756 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
757 offset += 4+tvb_get_letohl(tvb, offset);
759 else if (check_slsk_format(tvb, offset, "iss")) {
760 /* Client-to-Server */
761 message_type = "Say ChatRoom";
762 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
763 "Message Type: %s (Code: %02d)", message_type, msg_code);
765 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
766 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
767 offset += 4+tvb_get_letohl(tvb, offset);
768 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
769 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
770 offset += 4+tvb_get_letohl(tvb, offset);
775 if (check_slsk_format(tvb, offset, "is")) {
776 /* Client-to-Server */
777 message_type = "Join/Add Room";
778 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
779 "Message Type: %s (Code: %02d)", message_type, msg_code);
781 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
782 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
783 offset += 4+tvb_get_letohl(tvb, offset);
785 else if (check_slsk_format(tvb, offset, "isi*")) {
786 /* Server-to-Client */
787 message_type = "Join Room User List";
788 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
789 "Message Type: %s (Code: %02d)", message_type, msg_code);
791 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
792 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
793 offset += 4+tvb_get_letohl(tvb, offset);
794 i=0; j = tvb_get_letohl(tvb, offset);
795 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
798 if (check_slsk_format(tvb, offset, "s*")) {
799 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
800 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
801 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
802 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
803 offset += 4+tvb_get_letohl(tvb, offset);
807 if (check_slsk_format(tvb, offset, "i*")) {
808 i=0; j = tvb_get_letohl(tvb, offset);
809 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
812 if (check_slsk_format(tvb, offset, "i*")) {
813 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
814 "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));
820 if (check_slsk_format(tvb, offset, "i*")) {
821 i=0; j = tvb_get_letohl(tvb, offset);
822 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
825 if (check_slsk_format(tvb, offset, "iiiii*")) {
826 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
827 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
829 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
830 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
832 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
833 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
835 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
836 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
838 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
839 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
845 if (check_slsk_format(tvb, offset, "i*")) {
846 i=0; j = tvb_get_letohl(tvb, offset);
847 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
848 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
851 if (check_slsk_format(tvb, offset, "i*")) {
852 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
853 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
863 if (check_slsk_format(tvb, offset, "is")) {
864 /* Client-to-Server & Server-to-Client */
865 message_type = "Leave Room";
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_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
871 offset += 4+tvb_get_letohl(tvb, offset);
873 else if (check_slsk_format(tvb, offset, "i")) {
874 /* Client-to-Client */
875 message_type = "User Info Request";
876 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
877 "Message Type: %s (Code: %02d)", message_type, msg_code);
883 if (check_slsk_format(tvb, offset, "issiiiiiii")) {
884 /* Server-to-Client */
885 message_type = "User Joined Room";
886 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
887 "Message Type: %s (Code: %02d)", message_type, msg_code);
889 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
890 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
891 offset += 4+tvb_get_letohl(tvb, offset);
892 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
893 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
894 offset += 4+tvb_get_letohl(tvb, offset);
895 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
897 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
899 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
901 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
903 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
905 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
907 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
910 else if (check_slsk_format(tvb, offset, "isbiib") || check_slsk_format(tvb, offset, "isbsiib")) {
911 /* Client-to-Client */
912 message_type = "User Info Reply";
913 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
914 "Message Type: %s (Code: %02d)", message_type, msg_code);
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_user_description, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
918 offset += 4+tvb_get_letohl(tvb, offset);
919 proto_tree_add_uint_format(slsk_tree, hf_slsk_picture_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
920 "Picture exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
922 if ( tvb_get_guint8(tvb, offset -1 ) == 1 ) {
923 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
924 "Picture Size: %d", tvb_get_letohl(tvb, offset));
925 proto_tree_add_item(slsk_tree, hf_slsk_picture, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
926 offset += 4+tvb_get_letohl(tvb, offset);
928 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
930 proto_tree_add_uint(slsk_tree, hf_slsk_queued_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
932 proto_tree_add_uint_format(slsk_tree, hf_slsk_slots_available, tvb, offset, 1, tvb_get_guint8(tvb, offset),
933 "Upload Slots available: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
939 if (check_slsk_format(tvb, offset, "iss")) {
940 /* Server-to-Client */
941 message_type = "User Left Room";
942 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
943 "Message Type: %s (Code: %02d)", message_type, msg_code);
945 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
946 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
947 offset += 4+tvb_get_letohl(tvb, offset);
948 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
949 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
950 offset += 4+tvb_get_letohl(tvb, offset);
955 if (check_slsk_format(tvb, offset, "iiss")) {
956 /* Client-to-Server */
957 message_type = "Connect To Peer";
958 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
959 "Message Type: %s (Code: %02d)", message_type, msg_code);
961 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
963 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
964 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
965 offset += 4+tvb_get_letohl(tvb, offset);
966 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
967 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)),
968 "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)));
969 offset += 4+tvb_get_letohl(tvb, offset);
971 else if (check_slsk_format(tvb, offset, "issiii")) {
972 /* Server-to-Client */
973 message_type = "Connect To Peer";
974 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
975 "Message Type: %s (Code: %02d)", message_type, msg_code);
977 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
978 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
979 offset += 4+tvb_get_letohl(tvb, offset);
980 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
981 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)),
982 "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)));
983 offset += 4+tvb_get_letohl(tvb, offset);
984 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
986 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
988 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
994 if (check_slsk_format(tvb, offset, "iss")) {
995 /* Client-to-Server */
996 message_type = "Message User Send";
997 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
998 "Message Type: %s (Code: %02d)", message_type, msg_code);
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_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1002 offset += 4+tvb_get_letohl(tvb, offset);
1003 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1004 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1005 offset += 4+tvb_get_letohl(tvb, offset);
1007 else if (check_slsk_format(tvb, offset, "iiiss")) {
1008 /* Server-to-Client */
1009 message_type = "Message User Receive";
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(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1015 proto_tree_add_uint(slsk_tree, hf_slsk_timestamp, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1017 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1018 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1019 offset += 4+tvb_get_letohl(tvb, offset);
1020 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1021 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1022 offset += 4+tvb_get_letohl(tvb, offset);
1027 if (check_slsk_format(tvb, offset, "ii")) {
1028 /* Client-to-Server */
1029 message_type = "Message User Receive Ack";
1030 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1031 "Message Type: %s (Code: %02d)", message_type, msg_code);
1033 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1039 if (check_slsk_format(tvb, offset, "iis")) {
1040 /* Client-to-Server */
1041 message_type = "File Search";
1042 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1043 "Message Type: %s (Code: %02d)", message_type, msg_code);
1045 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1047 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1048 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1049 offset += 4+tvb_get_letohl(tvb, offset);
1054 if (check_slsk_format(tvb, offset, "ii")) {
1055 /* Client-to-Server */
1056 message_type = "Set Status";
1057 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1058 "Message Type: %s (Code: %02d)", message_type, msg_code);
1060 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1061 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1067 if (check_slsk_format(tvb, offset, "i")) {
1068 /* Client-to-Server */
1069 message_type = "Ping";
1070 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1071 "Message Type: %s (Code: %02d)", message_type, msg_code);
1077 if (check_slsk_format(tvb, offset, "isi")) {
1078 /* Client-to-Server */
1079 message_type = "Update Upload Speed";
1080 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1081 "Message Type: %s (Code: %02d)", message_type, msg_code);
1083 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1084 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1085 offset += 4+tvb_get_letohl(tvb, offset);
1086 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1092 if (check_slsk_format(tvb, offset, "iii")) {
1093 /* Client-to-Server */
1094 message_type = "Shared Files & Folders ";
1095 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1096 "Message Type: %s (Code: %02d)", message_type, msg_code);
1098 proto_tree_add_uint(slsk_tree, hf_slsk_folder_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1100 proto_tree_add_uint(slsk_tree, hf_slsk_file_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1106 if (check_slsk_format(tvb, offset, "isiiiii")) {
1107 /* Server-to-Client */
1108 message_type = "Get User Stats Reply";
1109 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1110 "Message Type: %s (Code: %02d)", message_type, msg_code);
1112 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1113 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1114 offset += 4+tvb_get_letohl(tvb, offset);
1115 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1117 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1119 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1121 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1123 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1126 else if (check_slsk_format(tvb, offset, "is")) {
1127 /* Client-to-Client */
1128 /* Client-to-Server: send after login successfull */
1129 message_type = "Get User Stats";
1130 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1131 "Message Type: %s (Code: %02d)", message_type, msg_code);
1133 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1134 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1135 offset += 4+tvb_get_letohl(tvb, offset);
1137 else if (check_slsk_format(tvb, offset, "iis")) {
1138 /* Client-to-Client */
1139 message_type = "Folder Contents Request";
1140 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1141 "Message Type: %s (Code: %02d)", message_type, msg_code);
1143 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1145 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1146 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1147 offset += 4+tvb_get_letohl(tvb, offset);
1152 if (check_slsk_format(tvb, offset, "i*")) {
1153 /* Client-to-Client */
1154 message_type = "Folder Contents Response";
1155 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1156 "Message Type: %s (Code: %02d)", message_type, msg_code);
1159 /* [zlib compressed] */
1160 comprlen = tvb_length_remaining(tvb, offset);
1162 if (slsk_decompress == TRUE){
1164 tvbuff_t *uncompr_tvb = uncompress_packet(tvb, offset, comprlen);
1166 if (uncompr_tvb == NULL) {
1167 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1168 "[zlib compressed packet]");
1169 offset += tvb_length_remaining(tvb, offset);
1170 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
1171 "(uncompression failed !)");
1174 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
1175 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
1177 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1178 "( compressed packet length: %d)", comprlen);
1179 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
1180 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1181 "(uncompressed packet length: %d)", uncomprlen);
1183 /* Dissects the uncompressed tvbuffer */
1184 uncompr_tvb_offset = 0;
1185 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "isi*")) {
1186 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1187 "Token: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1188 uncompr_tvb_offset += 4;
1189 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),
1190 "Directory Name: %s", tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1191 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1193 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1194 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1195 "Number of directories: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1196 uncompr_tvb_offset += 4;
1198 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
1199 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),
1200 "Directory #%d Name: %s", i+1, tvb_get_string(uncompr_tvb, uncompr_tvb_offset+4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset)));
1201 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1203 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1204 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1205 "Directory #%d Number of files: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1206 uncompr_tvb_offset += 4;
1208 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
1209 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
1210 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
1211 uncompr_tvb_offset += 1;
1212 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),
1213 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1214 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),
1215 "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)));
1216 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1217 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1218 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1219 uncompr_tvb_offset += 4;
1220 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1221 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1222 uncompr_tvb_offset += 4;
1223 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),
1224 "Dir #%d File #%d String Length: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1225 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),
1226 "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)));
1227 uncompr_tvb_offset += 4+tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1229 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1230 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1231 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1232 uncompr_tvb_offset += 4;
1234 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
1235 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1236 "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));
1237 uncompr_tvb_offset += 4;
1238 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, 0, 0, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1239 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1240 uncompr_tvb_offset += 4;
1253 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1254 "[zlib compressed packet]");
1255 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
1256 "( compressed packet length: %d)", comprlen);
1257 offset += tvb_length_remaining(tvb, offset);
1263 if (check_slsk_format(tvb, offset, "isi")) {
1264 /* Server-to-Client */
1265 message_type = "Queued Downloads";
1266 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1267 "Message Type: %s (Code: %02d)", message_type, msg_code);
1269 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1270 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1271 offset += 4+tvb_get_letohl(tvb, offset);
1272 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1275 else if (check_slsk_format(tvb, offset, "iiis") || check_slsk_format(tvb, offset, "iiisii")) {
1276 /* Client-to-Client */
1277 message_type = "Transfer Request";
1278 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1279 "Message Type: %s (Code: %02d)", message_type, msg_code);
1281 i = tvb_get_letohl(tvb, offset);
1282 proto_tree_add_uint_format(slsk_tree, hf_slsk_transfer_direction, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1283 "Transfer Direction: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_transfer_direction, "Unknown"), tvb_get_letohl(tvb, offset));
1285 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1287 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1288 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1289 offset += 4+tvb_get_letohl(tvb, offset);
1291 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1293 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1301 if (check_slsk_format(tvb, offset, "iibs") || check_slsk_format(tvb, offset, "iibii") || check_slsk_format(tvb, offset, "iib")) {
1302 /* Client-to-Client */
1303 message_type = "Transfer Response";
1304 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1305 "Message Type: %s (Code: %02d)", message_type, msg_code);
1307 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1309 i = tvb_get_guint8(tvb, offset);
1310 proto_tree_add_uint_format(slsk_tree, hf_slsk_allowed, tvb, offset, 1, tvb_get_guint8(tvb, offset),
1311 "Download allowed: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
1314 if ( tvb_length_remaining(tvb, offset) == 8 ) {
1315 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1317 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1321 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1322 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1323 offset += 4+tvb_get_letohl(tvb, offset);
1329 if (check_slsk_format(tvb, offset, "is")) {
1330 /* Client-to-Client */
1331 message_type = "Placehold Upload";
1332 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1333 "Message Type: %s (Code: %02d)", message_type, msg_code);
1335 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1336 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1337 offset += 4+tvb_get_letohl(tvb, offset);
1342 if (check_slsk_format(tvb, offset, "is")) {
1343 /* Client-to-Client */
1344 message_type = "Queue Upload";
1345 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1346 "Message Type: %s (Code: %02d)", message_type, msg_code);
1348 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1349 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1350 offset += 4+tvb_get_letohl(tvb, offset);
1355 if (check_slsk_format(tvb, offset, "isi")) {
1356 /* Client-to-Client */
1357 message_type = "Place In Queue";
1358 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1359 "Message Type: %s (Code: %02d)", message_type, msg_code);
1361 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1362 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1363 offset += 4+tvb_get_letohl(tvb, offset);
1364 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1370 if (check_slsk_format(tvb, offset, "is")) {
1371 /* Client-to-Client */
1372 message_type = "Upload Failed";
1373 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1374 "Message Type: %s (Code: %02d)", message_type, msg_code);
1376 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1377 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1378 offset += 4+tvb_get_letohl(tvb, offset);
1383 if (check_slsk_format(tvb, offset, "is")) {
1384 /* Client-to-Server */
1385 message_type = "Make Own Recommendation";
1386 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1387 "Message Type: %s (Code: %02d)", message_type, msg_code);
1389 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1390 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1391 offset += 4+tvb_get_letohl(tvb, offset);
1393 else if (check_slsk_format(tvb, offset, "isi")) {
1394 /* Client-to-Server */
1395 message_type = "Remove Own Recommendation";
1396 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1397 "Message Type: %s (Code: %02d)", message_type, msg_code);
1399 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1400 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1401 offset += 4+tvb_get_letohl(tvb, offset);
1402 proto_tree_add_uint(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1405 else if (check_slsk_format(tvb, offset, "iss")) {
1406 /* Client-to-Client */
1407 message_type = "Queue Failed";
1408 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1409 "Message Type: %s (Code: %02d)", message_type, msg_code);
1411 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1412 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1413 offset += 4+tvb_get_letohl(tvb, offset);
1414 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1415 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1416 offset += 4+tvb_get_letohl(tvb, offset);
1421 if (check_slsk_format(tvb, offset, "is")) {
1422 /* Client-to-Server: "Add Things I like" */
1423 /* Client-to-Client: "Place In Queue Request" */
1424 message_type = "Add Things I like / Place In Queue Request";
1425 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1426 "Message Type: %s (Code: %02d)", message_type, msg_code);
1428 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1429 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1430 offset += 4+tvb_get_letohl(tvb, offset);
1435 if (check_slsk_format(tvb, offset, "is")) {
1436 /* Client-to-Server */
1437 message_type = "Remove Things I like";
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);
1441 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1442 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1443 offset += 4+tvb_get_letohl(tvb, offset);
1448 if (check_slsk_format(tvb, offset, "i")) {
1449 /* Client-to-Server */
1450 message_type = "Get Recommendations";
1451 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1452 "Message Type: %s (Code: %02d)", message_type, msg_code);
1455 else if (check_slsk_format(tvb, offset, "ii*")) {
1456 /* Server-to-Client */
1457 message_type = "Get Recommendations Reply";
1458 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1459 "Message Type: %s (Code: %02d)", message_type, msg_code);
1461 i=0; j = tvb_get_letohl(tvb, offset);
1462 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1463 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1466 if (check_slsk_format(tvb, offset, "si*")) {
1467 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1468 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1469 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1470 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1471 offset += 4+tvb_get_letohl(tvb, offset);
1472 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1473 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1482 if (check_slsk_format(tvb, offset, "i")) {
1483 /* Client-to-Server */
1484 message_type = "Type 55";
1485 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1486 "Message Type: %s (Code: %02d)", message_type, msg_code);
1492 if (check_slsk_format(tvb, offset, "i")) {
1493 /* Client-to-Server */
1494 message_type = "Get Global Rankings";
1495 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1496 "Message Type: %s (Code: %02d)", message_type, msg_code);
1499 else if (check_slsk_format(tvb, offset, "ii*")) {
1500 /* Server-to-Client */
1501 message_type = "Get Global Rankings Reply";
1502 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1503 "Message Type: %s (Code: %02d)", message_type, msg_code);
1505 i=0; j = tvb_get_letohl(tvb, offset);
1506 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1507 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1510 if (check_slsk_format(tvb, offset, "si*")) {
1511 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1512 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1513 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1514 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1515 offset += 4+tvb_get_letohl(tvb, offset);
1516 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1517 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1526 if (check_slsk_format(tvb, offset, "is")) {
1527 /* Client-to-Server */
1528 message_type = "Get User Recommendations";
1529 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1530 "Message Type: %s (Code: %02d)", message_type, msg_code);
1532 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1533 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1534 offset += 4+tvb_get_letohl(tvb, offset);
1536 else if (check_slsk_format(tvb, offset, "isi*")) {
1537 /* Server-to-Client */
1538 message_type = "Get User Recommendations Reply";
1539 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1540 "Message Type: %s (Code: %02d)", message_type, msg_code);
1542 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1543 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1544 offset += 4+tvb_get_letohl(tvb, offset);
1545 i=0; j = tvb_get_letohl(tvb, offset);
1546 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1547 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1550 if (check_slsk_format(tvb, offset, "s*")) {
1551 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1552 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1553 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1554 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1555 offset += 4+tvb_get_letohl(tvb, offset);
1563 if (check_slsk_format(tvb, offset, "isi*")) {
1564 /* Client-to-Server */
1565 message_type = "Admin Command";
1566 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1567 "Message Type: %s (Code: %02d)", message_type, msg_code);
1569 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1570 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1571 offset += 4+tvb_get_letohl(tvb, offset);
1572 i=0; j = tvb_get_letohl(tvb, offset);
1573 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1574 "Number of Strings: %d", tvb_get_letohl(tvb, offset));
1577 if (check_slsk_format(tvb, offset, "s*")) {
1578 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1579 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1580 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1581 "String #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1582 offset += 4+tvb_get_letohl(tvb, offset);
1590 if (check_slsk_format(tvb, offset, "isii")) {
1591 /* Client-to-Server & Server-to-Client */
1592 message_type = "Place In Line Response";
1593 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1594 "Message Type: %s (Code: %02d)", message_type, msg_code);
1596 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1597 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1598 offset += 4+tvb_get_letohl(tvb, offset);
1599 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1601 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1607 if (check_slsk_format(tvb, offset, "is")) {
1608 /* Server-to-Client */
1609 message_type = "Room Added";
1610 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1611 "Message Type: %s (Code: %02d)", message_type, msg_code);
1613 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1614 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1615 offset += 4+tvb_get_letohl(tvb, offset);
1620 if (check_slsk_format(tvb, offset, "is")) {
1621 /* Server-to-Client */
1622 message_type = "Room Removed";
1623 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1624 "Message Type: %s (Code: %02d)", message_type, msg_code);
1626 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1627 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1628 offset += 4+tvb_get_letohl(tvb, offset);
1633 if (check_slsk_format(tvb, offset, "i")) {
1634 /* Client-to-Server */
1635 message_type = "Room List Request";
1636 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1637 "Message Type: %s (Code: %02d)", message_type, msg_code);
1640 else if (check_slsk_format(tvb, offset, "ii*")) {
1641 /* Server-to-Client */
1642 message_type = "Room List";
1643 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1644 "Message Type: %s (Code: %02d)", message_type, msg_code);
1646 i=0; j = tvb_get_letohl(tvb, offset);
1647 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1650 if (check_slsk_format(tvb, offset, "s*")) {
1651 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1652 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1653 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1654 "Room #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1655 offset += 4+tvb_get_letohl(tvb, offset);
1659 if (check_slsk_format(tvb, offset, "i*")) {
1661 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1664 if (check_slsk_format(tvb, offset, "i*")) {
1665 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1666 "Users in Room #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1676 if (check_slsk_format(tvb, offset, "isissiii")) {
1677 /* Server-to-Client */
1678 message_type = "Exact File Search";
1679 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1680 "Message Type: %s (Code: %02d)", message_type, msg_code);
1682 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1683 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1684 offset += 4+tvb_get_letohl(tvb, offset);
1685 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1687 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1688 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1689 offset += 4+tvb_get_letohl(tvb, offset);
1690 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1691 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1692 offset += 4+tvb_get_letohl(tvb, offset);
1693 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 16, 0,
1697 else if (check_slsk_format(tvb, offset, "iissiiib")) {
1698 /* Client-to-Server */
1699 message_type = "Exact File Search";
1700 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1701 "Message Type: %s (Code: %02d)", message_type, msg_code);
1703 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1705 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1706 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1707 offset += 4+tvb_get_letohl(tvb, offset);
1708 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1709 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1710 offset += 4+tvb_get_letohl(tvb, offset);
1711 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 13, 0,
1718 if (check_slsk_format(tvb, offset, "is")) {
1719 /* Server-to-Client */
1720 message_type = "Admin Message";
1721 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1722 "Message Type: %s (Code: %02d)", message_type, msg_code);
1724 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1725 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1726 offset += 4+tvb_get_letohl(tvb, offset);
1731 if (check_slsk_format(tvb, offset, "i")) {
1732 /* Client-to-Server */
1733 message_type = "Global User List Request";
1734 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1735 "Message Type: %s (Code: %02d)", message_type, msg_code);
1738 else if (check_slsk_format(tvb, offset, "isi*")) { /* same as case 14 */
1739 /* Server-to-Client */
1740 message_type = "Global User List";
1741 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1742 "Message Type: %s (Code: %02d)", message_type, msg_code);
1744 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1745 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1746 offset += 4+tvb_get_letohl(tvb, offset);
1747 i=0; j = tvb_get_letohl(tvb, offset);
1748 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1751 if (check_slsk_format(tvb, offset, "s*")) {
1752 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1753 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1754 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1755 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1756 offset += 4+tvb_get_letohl(tvb, offset);
1760 if (check_slsk_format(tvb, offset, "i*")) {
1761 i=0; j = tvb_get_letohl(tvb, offset);
1762 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1765 if (check_slsk_format(tvb, offset, "i*")) {
1766 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1767 "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));
1773 if (check_slsk_format(tvb, offset, "i*")) {
1774 i=0; j = tvb_get_letohl(tvb, offset);
1775 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1778 if (check_slsk_format(tvb, offset, "iiiii*")) {
1779 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1780 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1782 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1783 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1785 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1786 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1788 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1789 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1791 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1792 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1798 if (check_slsk_format(tvb, offset, "i*")) {
1799 i=0; j = tvb_get_letohl(tvb, offset);
1800 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1801 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
1804 if (check_slsk_format(tvb, offset, "i*")) {
1805 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1806 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1816 if (check_slsk_format(tvb, offset, "isiiiis")) {
1817 message_type = "Tunneled Message";
1818 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1819 "Message Type: %s (Code: %02d)", message_type, msg_code);
1821 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1822 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1823 offset += 4+tvb_get_letohl(tvb, offset);
1824 proto_tree_add_uint(slsk_tree, hf_slsk_code, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1826 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1828 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
1830 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1832 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1833 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1834 offset += 4+tvb_get_letohl(tvb, offset);
1839 if (check_slsk_format(tvb, offset, "i")) {
1840 /* Client-to-Server */
1841 message_type = "Privileged User List Request";
1842 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1843 "Message Type: %s (Code: %02d)", message_type, msg_code);
1846 else if (check_slsk_format(tvb, offset, "ii*")) {
1847 /* Server-to-Client */
1848 message_type = "Privileged User List";
1849 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1850 "Message Type: %s (Code: %02d)", message_type, msg_code);
1852 i=0; j = tvb_get_letohl(tvb, offset);
1853 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1854 "Number of Priviledged Users: %d", tvb_get_letohl(tvb, offset));
1857 if (check_slsk_format(tvb, offset, "s*")) {
1858 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1859 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
1860 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
1861 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
1862 offset += 4+tvb_get_letohl(tvb, offset);
1870 if (check_slsk_format(tvb, offset, "ib")) {
1871 /* Client-to-Server */
1872 message_type = "Get Parent List";
1873 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1874 "Message Type: %s (Code: %02d)", message_type, msg_code);
1876 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1882 if (check_slsk_format(tvb, offset, "ii")) {
1883 /* Client-to-Server */
1884 message_type = "Type 73";
1885 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1886 "Message Type: %s (Code: %02d)", message_type, msg_code);
1888 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1894 if (check_slsk_format(tvb, offset, "ii")) {
1895 /* Server-to-Client */
1896 message_type = "Parent Min Speed";
1897 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1898 "Message Type: %s (Code: %02d)", message_type, msg_code);
1900 proto_tree_add_uint(slsk_tree, hf_slsk_parent_min_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1906 if (check_slsk_format(tvb, offset, "ii")) {
1907 /* Server-to-Client */
1908 message_type = "Parent Speed Connection Ratio";
1909 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1910 "Message Type: %s (Code: %02d)", message_type, msg_code);
1912 proto_tree_add_uint(slsk_tree, hf_slsk_parent_speed_connection_ratio, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1918 if (check_slsk_format(tvb, offset, "ii")) {
1919 /* Server-to-Client */
1920 message_type = "Parent Inactivity Before Disconnect";
1921 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1922 "Message Type: %s (Code: %02d)", message_type, msg_code);
1924 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_parent_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1930 if (check_slsk_format(tvb, offset, "ii")) {
1931 /* Server-to-Client */
1932 message_type = "Server Inactivity Before Disconnect";
1933 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1934 "Message Type: %s (Code: %02d)", message_type, msg_code);
1936 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_server_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1942 if (check_slsk_format(tvb, offset, "ii")) {
1943 /* Server-to-Client */
1944 message_type = "Nodes In Cache Before Disconnect";
1945 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1946 "Message Type: %s (Code: %02d)", message_type, msg_code);
1948 proto_tree_add_uint(slsk_tree, hf_slsk_nodes_in_cache_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1954 if (check_slsk_format(tvb, offset, "ii")) {
1955 /* Server-to-Client */
1956 message_type = "Seconds Before Ping Children";
1957 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1958 "Message Type: %s (Code: %02d)", message_type, msg_code);
1960 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_before_ping_children, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1966 if (check_slsk_format(tvb, offset, "is")) {
1967 /* Server-to-Client */
1968 message_type = "Add To Privileged";
1969 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1970 "Message Type: %s (Code: %02d)", message_type, msg_code);
1972 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1973 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1974 offset += 4+tvb_get_letohl(tvb, offset);
1979 if (check_slsk_format(tvb, offset, "i")) {
1980 /* Client-to-Server */
1981 message_type = "Check Privileges";
1982 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1983 "Message Type: %s (Code: %02d)", message_type, msg_code);
1986 else if (check_slsk_format(tvb, offset, "ii")) {
1987 /* Server-to-Client */
1988 message_type = "Check Privileges Reply";
1989 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1990 "Message Type: %s (Code: %02d)", message_type, msg_code);
1992 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_days, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1998 if (check_slsk_format(tvb, offset, "ibisis")) {
1999 /* Server-to-Client */
2000 message_type = "Embedded Message";
2001 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2002 "Message Type: %s (Code: %02d)", message_type, msg_code);
2004 if ( tvb_get_guint8(tvb, offset) == 3 ){
2005 /* Client-to-Client */
2006 message_type = "Distributed Search";
2007 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2008 "Embedded Message Type: %s (Byte: %d)", message_type, 3);
2010 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2012 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2013 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2014 offset += 4+tvb_get_letohl(tvb, offset);
2015 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2017 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2018 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2019 offset += 4+tvb_get_letohl(tvb, offset);
2025 if (check_slsk_format(tvb, offset, "ib")) {
2026 /* Client-to-Server */
2027 message_type = "Become Parent";
2028 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2029 "Message Type: %s (Code: %02d)", message_type, msg_code);
2031 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
2037 if (check_slsk_format(tvb, offset, "ii*")) {
2038 /* Server-to-Client */
2039 message_type = "Random Parent Addresses";
2040 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2041 "Message Type: %s (Code: %02d)", message_type, msg_code);
2043 i=0; j = tvb_get_letohl(tvb, offset);
2044 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2045 "Number of Parent Addresses: %d", tvb_get_letohl(tvb, offset));
2048 if (check_slsk_format(tvb, offset, "sii*")) {
2049 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2050 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2051 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2052 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2053 offset += 4+tvb_get_letohl(tvb, offset);
2054 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
2056 proto_tree_add_uint_format(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2057 "Port Number #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2066 if (check_slsk_format(tvb, offset, "iis")) {
2067 /* Server-to-Client */
2068 message_type = "Send Wishlist Entry";
2069 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2070 "Message Type: %s (Code: %02d)", message_type, msg_code);
2072 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2074 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2075 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2076 offset += 4+tvb_get_letohl(tvb, offset);
2081 if (check_slsk_format(tvb, offset, "ii")) {
2082 /* Server-to-Client */
2083 message_type = "Type 104";
2084 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2085 "Message Type: %s (Code: %02d)", message_type, msg_code);
2087 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2093 if (check_slsk_format(tvb, offset, "i")) {
2094 /* Client-to-Server */
2095 message_type = "Get Similar Users";
2096 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2097 "Message Type: %s (Code: %02d)", message_type, msg_code);
2100 else if (check_slsk_format(tvb, offset, "ii*")) {
2101 /* Server-to-Client */
2102 message_type = "Get Similar Users Reply";
2103 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2104 "Message Type: %s (Code: %02d)", message_type, msg_code);
2106 i=0; j = tvb_get_letohl(tvb, offset);
2107 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2108 "Number of Users: %d", tvb_get_letohl(tvb, offset));
2111 if (check_slsk_format(tvb, offset, "si*")) {
2112 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2113 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2114 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2115 "User #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2116 offset += 4+tvb_get_letohl(tvb, offset);
2117 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2118 "Same Recommendations #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2127 if (check_slsk_format(tvb, offset, "is")) {
2128 /* Client-to-Server */
2129 message_type = "Get Recommendations for Item";
2130 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2131 "Message Type: %s (Code: %02d)", message_type, msg_code);
2133 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2134 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2135 offset += 4+tvb_get_letohl(tvb, offset);
2137 else if (check_slsk_format(tvb, offset, "isi*")) {
2138 /* Server-to-Client */
2139 message_type = "Get Recommendations for Item Reply";
2140 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2141 "Message Type: %s (Code: %02d)", message_type, msg_code);
2143 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2144 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2145 offset += 4+tvb_get_letohl(tvb, offset);
2146 i=0; j = tvb_get_letohl(tvb, offset);
2147 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2148 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2151 if (check_slsk_format(tvb, offset, "si*")) {
2152 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2153 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2154 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2155 "Recommendation #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2156 offset += 4+tvb_get_letohl(tvb, offset);
2157 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2158 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2167 if (check_slsk_format(tvb, offset, "is")) {
2168 /* Client-to-Server */
2169 message_type = "Get Similar Users for Item";
2170 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2171 "Message Type: %s (Code: %02d)", message_type, msg_code);
2173 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2174 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2175 offset += 4+tvb_get_letohl(tvb, offset);
2177 else if (check_slsk_format(tvb, offset, "isi*")) {
2178 /* Server-to-Client */
2179 message_type = "Get Similar Users for Item Reply";
2180 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2181 "Message Type: %s (Code: %02d)", message_type, msg_code);
2183 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2184 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2185 offset += 4+tvb_get_letohl(tvb, offset);
2186 i=0; j = tvb_get_letohl(tvb, offset);
2187 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2188 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2191 if (check_slsk_format(tvb, offset, "s*")) {
2192 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2193 "String #%d Length: %d", i+1, tvb_get_letohl(tvb, offset));
2194 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset+4, tvb_get_letohl(tvb, offset), tvb_get_letohl(tvb, offset),
2195 "Username #%d: %s", i+1, tvb_get_string(tvb, offset+4, tvb_get_letohl(tvb, offset)));
2196 offset += 4+tvb_get_letohl(tvb, offset);
2204 if (check_slsk_format(tvb, offset, "iis")) {
2205 /* Client-to-Server */
2206 message_type = "Can't Connect To Peer";
2207 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2208 "Message Type: %s (Code: %02d)", message_type, msg_code);
2210 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2212 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2213 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2214 offset += 4+tvb_get_letohl(tvb, offset);
2216 else if (check_slsk_format(tvb, offset, "ii")) {
2217 /* Server-to-Client */
2218 message_type = "Can't Connect To Peer";
2219 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2220 "Message Type: %s (Code: %02d)", message_type, msg_code);
2222 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2228 if (check_slsk_format(tvb, offset, "bisis")) {
2229 if ( tvb_get_guint8(tvb, offset) == 3 ){
2230 /* Client-to-Client */
2231 message_type = "Distributed Search";
2232 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2233 "Message Type: %s (Byte: %d)", message_type, 3);
2235 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2237 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2238 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2239 offset += 4+tvb_get_letohl(tvb, offset);
2240 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2242 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2243 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2244 offset += 4+tvb_get_letohl(tvb, offset);
2247 else if (check_slsk_format(tvb, offset, "bssi")) {
2248 if ( tvb_get_guint8(tvb, offset) == 1 ){
2249 /* Client-to-Client */
2250 message_type = "Peer Init";
2251 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2252 "Message Type: %s (Byte: %d)", message_type, 1);
2254 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2255 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2256 offset += 4+tvb_get_letohl(tvb, offset);
2257 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2258 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)),
2259 "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)));
2260 offset += 4+tvb_get_letohl(tvb, offset);
2261 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2265 else if (check_slsk_format(tvb, offset, "bi")) {
2266 if ( tvb_get_guint8(tvb, offset) == 0 ){
2267 /* Client-to-Client */
2268 message_type = "Pierce Fw";
2269 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2270 "Message Type: %s (Byte: %d)", message_type, 0);
2272 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2277 message_type = "Unknown";
2278 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2279 "Message Type: %s (Code: %02d)", message_type, msg_code);
2292 static void dissect_slsk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2294 tcp_dissect_pdus(tvb, pinfo, tree, slsk_desegment, 4, get_slsk_pdu_len, dissect_slsk_pdu);
2299 /* Register the protocol with Ethereal */
2302 proto_register_slsk(void)
2305 /* Setup list of header fields */
2306 static hf_register_info hf[] = {
2308 { "Integer", "slsk.integer",
2309 FT_UINT32, BASE_DEC, NULL, 0, "Integer", HFILL } },
2311 { "String", "slsk.string",
2312 FT_STRING, BASE_NONE, NULL, 0, "String", HFILL } },
2314 { "Byte", "slsk.byte",
2315 FT_UINT8, BASE_DEC, NULL, 0, "Byte", HFILL } },
2316 { &hf_slsk_message_length,
2317 { "Message Length", "slsk.message.length",
2318 FT_UINT32, BASE_DEC, NULL, 0, "Message Length", HFILL } },
2319 { &hf_slsk_message_code,
2320 { "Message Code", "slsk.message.code",
2321 FT_UINT32, BASE_DEC, NULL, 0, "Message Code", HFILL } },
2322 { &hf_slsk_client_ip,
2323 { "Client IP", "slsk.server.ip",
2324 FT_IPv4, BASE_DEC, NULL, 0, "Client IP Address", HFILL } },
2325 { &hf_slsk_server_ip,
2326 { "SoulSeek Server IP", "slsk.server.ip",
2327 FT_UINT32, BASE_DEC, NULL, 0, "SoulSeek Server IP", HFILL } },
2328 { &hf_slsk_string_length,
2329 { "String Length", "slsk.string.length",
2330 FT_UINT32, BASE_DEC, NULL, 0, "String Length", HFILL } },
2331 { &hf_slsk_username,
2332 { "Username", "slsk.username",
2333 FT_STRING, BASE_NONE, NULL, 0, "Username", HFILL } },
2334 { &hf_slsk_password,
2335 { "Password", "slsk.password",
2336 FT_STRING, BASE_NONE, NULL, 0, "Password", HFILL } },
2338 { "Version", "slsk.version",
2339 FT_UINT32, BASE_DEC, NULL, 0, "Version", HFILL } },
2340 { &hf_slsk_login_successfull,
2341 { "Login successfull", "slsk.login.successfull",
2342 FT_UINT8, BASE_DEC, NULL, 0, "Login Successfull", HFILL } },
2343 { &hf_slsk_login_message,
2344 { "Login Message", "slsk.login.message",
2345 FT_STRING, BASE_NONE, NULL, 0, "Login Message", HFILL } },
2347 { "Port Number", "slsk.port.number",
2348 FT_UINT32, BASE_DEC, NULL, 0, "Port Number", HFILL } },
2350 { "IP Address", "slsk.ip.address",
2351 FT_IPv4, BASE_DEC, NULL, 0, "IP Address", HFILL } },
2352 { &hf_slsk_user_exists,
2353 { "user exists", "slsk.user.exists",
2354 FT_UINT8, BASE_DEC, NULL, 0, "User exists", HFILL } },
2355 { &hf_slsk_status_code,
2356 { "Status Code", "slsk.status.code",
2357 FT_UINT32, BASE_DEC, NULL, 0, "Status Code", HFILL } },
2359 { "Room", "slsk.room",
2360 FT_STRING, BASE_NONE, NULL, 0, "Room", HFILL } },
2361 { &hf_slsk_chat_message,
2362 { "Chat Message", "slsk.chat.message",
2363 FT_STRING, BASE_NONE, NULL, 0, "Chat Message", HFILL } },
2364 { &hf_slsk_users_in_room,
2365 { "Users in Room", "slsk.room.users",
2366 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users in Room", HFILL } },
2368 { "Token", "slsk.token",
2369 FT_UINT32, BASE_DEC, NULL, 0, "Token", HFILL } },
2370 { &hf_slsk_connection_type,
2371 { "Connection Type", "slsk.connection.type",
2372 FT_STRING, BASE_NONE, NULL, 0, "Connection Type", HFILL } },
2373 { &hf_slsk_chat_message_id,
2374 { "Chat Message ID", "slsk.chat.message.id",
2375 FT_UINT32, BASE_DEC, NULL, 0, "Chat Message ID", HFILL } },
2376 { &hf_slsk_timestamp,
2377 { "Timestamp", "slsk.timestamp",
2378 FT_UINT32, BASE_DEC, NULL, 0, "Timestamp", HFILL } },
2379 { &hf_slsk_search_text,
2380 { "Search Text", "slsk.search.text",
2381 FT_STRING, BASE_NONE, NULL, 0, "Search Text", HFILL } },
2382 { &hf_slsk_folder_count,
2383 { "Folder Count", "slsk.folder.count",
2384 FT_UINT32, BASE_DEC, NULL, 0, "Folder Count", HFILL } },
2385 { &hf_slsk_file_count,
2386 { "File Count", "slsk.file.count",
2387 FT_UINT32, BASE_DEC, NULL, 0, "File Count", HFILL } },
2388 { &hf_slsk_average_speed,
2389 { "Average Speed", "slsk.average.speed",
2390 FT_UINT32, BASE_DEC, NULL, 0, "Average Speed", HFILL } },
2391 { &hf_slsk_download_number,
2392 { "Download Number", "slsk.download.number",
2393 FT_UINT32, BASE_DEC, NULL, 0, "Download Number", HFILL } },
2395 { "Files", "slsk.files",
2396 FT_UINT32, BASE_DEC, NULL, 0, "Files", HFILL } },
2397 { &hf_slsk_directories,
2398 { "Directories", "slsk.directories",
2399 FT_UINT32, BASE_DEC, NULL, 0, "Directories", HFILL } },
2400 { &hf_slsk_slotsfull,
2401 { "Slots full", "slsk.slots.full",
2402 FT_UINT32, BASE_DEC, NULL, 0, "Upload Slots Full", HFILL } },
2403 { &hf_slsk_place_in_queue,
2404 { "Place in Queue", "slsk.queue.place",
2405 FT_UINT32, BASE_DEC, NULL, 0, "Place in Queue", HFILL } },
2406 { &hf_slsk_number_of_rooms,
2407 { "Number of Rooms", "slsk.room.count",
2408 FT_UINT32, BASE_DEC, NULL, 0, "Number of Rooms", HFILL } },
2409 { &hf_slsk_filename,
2410 { "Filename", "slsk.filename",
2411 FT_STRING, BASE_NONE, NULL, 0, "Filename", HFILL } },
2412 { &hf_slsk_directory,
2413 { "Directory", "slsk.directory",
2414 FT_STRING, BASE_NONE, NULL, 0, "Directory", HFILL } },
2416 { "Size", "slsk.size",
2417 FT_UINT32, BASE_DEC, NULL, 0, "File Size", HFILL } },
2418 { &hf_slsk_checksum,
2419 { "Checksum", "slsk.checksum",
2420 FT_UINT32, BASE_DEC, NULL, 0, "Checksum", HFILL } },
2422 { "Code", "slsk.code",
2423 FT_UINT32, BASE_DEC, NULL, 0, "Code", HFILL } },
2424 { &hf_slsk_number_of_users,
2425 { "Number of Users", "slsk.user.count",
2426 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users", HFILL } },
2427 { &hf_slsk_number_of_days,
2428 { "Number of Days", "slsk.day.count",
2429 FT_UINT32, BASE_DEC, NULL, 0, "Number of Days", HFILL } },
2430 { &hf_slsk_transfer_direction,
2431 { "Transfer Direction", "slsk.transfer.direction",
2432 FT_UINT32, BASE_DEC, NULL, 0, "Transfer Direction", HFILL } },
2433 { &hf_slsk_user_description,
2434 { "User Description", "slsk.user.description",
2435 FT_STRING, BASE_NONE, NULL, 0, "User Description", HFILL } },
2436 { &hf_slsk_picture_exists,
2437 { "Picture exists", "slsk.user.picture.exists",
2438 FT_UINT8, BASE_DEC, NULL, 0, "User has a picture", HFILL } },
2440 { "Picture", "slsk.user.picture",
2441 FT_STRING, BASE_NONE, NULL, 0, "User Picture", HFILL } },
2442 { &hf_slsk_user_uploads,
2443 { "User uploads", "slsk.uploads.user",
2444 FT_UINT32, BASE_DEC, NULL, 0, "User uploads", HFILL } },
2445 { &hf_slsk_total_uploads,
2446 { "Total uploads allowed", "slsk.uploads.total",
2447 FT_UINT32, BASE_DEC, NULL, 0, "Total uploads allowed", HFILL } },
2448 { &hf_slsk_queued_uploads,
2449 { "Queued uploads", "slsk.uploads.queued",
2450 FT_UINT32, BASE_DEC, NULL, 0, "Queued uploads", HFILL } },
2451 { &hf_slsk_slots_available,
2452 { "Upload Slots available", "slsk.uploads.available",
2453 FT_UINT8, BASE_DEC, NULL, 0, "Upload Slots available", HFILL } },
2455 { "Download allowed", "slsk.user.allowed",
2456 FT_UINT8, BASE_DEC, NULL, 0, "allowed", HFILL } },
2457 { &hf_slsk_compr_packet,
2458 { "[zlib compressed packet]", "slsk.compr.packet",
2459 FT_NONE, BASE_NONE, NULL, 0, "zlib compressed packet", HFILL } },
2460 { &hf_slsk_parent_min_speed,
2461 { "Parent Min Speed", "slsk.parent.min.speed",
2462 FT_UINT32, BASE_DEC, NULL, 0, "Parent Min Speed", HFILL } },
2463 { &hf_slsk_parent_speed_connection_ratio,
2464 { "Parent Speed Connection Ratio", "slsk.parent.speed.connection.ratio",
2465 FT_UINT32, BASE_DEC, NULL, 0, "Parent Speed Connection Ratio", HFILL } },
2466 { &hf_slsk_seconds_parent_inactivity_before_disconnect,
2467 { "Seconds Parent Inactivity Before Disconnect", "slsk.seconds.parent.inactivity.before.disconnect",
2468 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Parent Inactivity Before Disconnect", HFILL } },
2469 { &hf_slsk_seconds_server_inactivity_before_disconnect,
2470 { "Seconds Server Inactivity Before Disconnect", "slsk.seconds.server.inactivity.before.disconnect",
2471 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Server Inactivity Before Disconnect", HFILL } },
2472 { &hf_slsk_nodes_in_cache_before_disconnect,
2473 { "Nodes In Cache Before Disconnect", "slsk.nodes.in.cache.before.disconnect",
2474 FT_UINT32, BASE_DEC, NULL, 0, "Nodes In Cache Before Disconnect", HFILL } },
2475 { &hf_slsk_seconds_before_ping_children,
2476 { "Seconds Before Ping Children", "slsk.seconds.before.ping.children",
2477 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Before Ping Children", HFILL } },
2478 { &hf_slsk_recommendation,
2479 { "Recommendation", "slsk.recommendation",
2480 FT_STRING, BASE_NONE, NULL, 0, "Recommendation", HFILL } },
2482 { "Ranking", "slsk.ranking",
2483 FT_UINT32, BASE_DEC, NULL, 0, "Ranking", HFILL } },
2486 /* Setup protocol subtree array */
2487 static gint *ett[] = {
2489 &ett_slsk_compr_packet,
2491 module_t *slsk_module;
2493 /* Registers the protocol name and description */
2494 proto_slsk = proto_register_protocol("SoulSeek Protocol", "SoulSeek", "slsk");
2496 /* Required function calls to register the header fields and subtrees used */
2497 proto_register_field_array(proto_slsk, hf, array_length(hf));
2498 proto_register_subtree_array(ett, array_length(ett));
2500 slsk_module = prefs_register_protocol(proto_slsk, NULL);
2502 /* Registers the options in the menu preferences */
2503 prefs_register_bool_preference(slsk_module, "desegment",
2504 "Desegment all SoulSeek messages spanning multiple TCP segments",
2505 "Whether the SoulSeek dissector should desegment all messages spanning multiple TCP segments",
2508 prefs_register_bool_preference(slsk_module, "decompress",
2509 "Decompress zlib compressed packets inside SoulSeek messages",
2510 "Whether the SoulSeek dissector should decompress all zlib compressed packets inside messages",
2518 proto_reg_handoff_slsk(void)
2520 dissector_handle_t slsk_handle;
2522 slsk_handle = create_dissector_handle(dissect_slsk, proto_slsk);
2523 dissector_add("tcp.port", TCP_PORT_SLSK_1, slsk_handle);
2524 dissector_add("tcp.port", TCP_PORT_SLSK_2, slsk_handle);
2525 dissector_add("tcp.port", TCP_PORT_SLSK_3, slsk_handle);