Trivial warning fixes
[obnox/wireshark/wip.git] / epan / dissectors / packet-slsk.c
1 /* packet-slsk.c
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
7  *
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
11  *
12  * $Id$
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include <glib.h>
42
43 #include <epan/packet.h>
44 #include <epan/tvbuff.h>
45 #include "packet-tcp.h"
46 #include <epan/prefs.h>
47 #include <epan/strutil.h>
48
49 /* Initialize the protocol and registered fields */
50 static int proto_slsk = -1;
51
52 static int hf_slsk_integer = -1;
53 static int hf_slsk_string = -1;
54 static int hf_slsk_byte = -1;
55 static int hf_slsk_message_length = -1;
56 static int hf_slsk_message_code = -1;
57 static int hf_slsk_client_ip = -1;
58 static int hf_slsk_server_ip = -1;
59 static int hf_slsk_string_length = -1;
60 static int hf_slsk_username = -1;
61 static int hf_slsk_password = -1;
62 static int hf_slsk_version = -1;
63 static int hf_slsk_login_successful = -1;
64 static int hf_slsk_login_message = -1;
65 static int hf_slsk_port = -1;
66 static int hf_slsk_ip = -1;
67 static int hf_slsk_user_exists = -1;
68 static int hf_slsk_status_code = -1;
69 static int hf_slsk_room = -1;
70 static int hf_slsk_chat_message = -1;
71 static int hf_slsk_users_in_room = -1;
72 static int hf_slsk_token = -1;
73 static int hf_slsk_connection_type = -1;
74 static int hf_slsk_chat_message_id = -1;
75 static int hf_slsk_timestamp = -1;
76 static int hf_slsk_search_text = -1;
77 static int hf_slsk_folder_count = -1;
78 static int hf_slsk_file_count = -1;
79 static int hf_slsk_average_speed = -1;
80 static int hf_slsk_download_number = -1;
81 static int hf_slsk_files = -1;
82 static int hf_slsk_directories = -1;
83 static int hf_slsk_slotsfull = -1;
84 static int hf_slsk_place_in_queue = -1;
85 static int hf_slsk_number_of_rooms = -1;
86 static int hf_slsk_filename = -1;
87 static int hf_slsk_directory = -1;
88 static int hf_slsk_size = -1;
89 static int hf_slsk_checksum = -1;
90 static int hf_slsk_code = -1;
91 static int hf_slsk_number_of_users = -1;
92 static int hf_slsk_number_of_days = -1;
93 static int hf_slsk_transfer_direction = -1;
94 static int hf_slsk_user_description = -1;
95 static int hf_slsk_picture_exists = -1;
96 static int hf_slsk_picture = -1;
97 static int hf_slsk_user_uploads = -1;
98 static int hf_slsk_total_uploads = -1;
99 static int hf_slsk_queued_uploads = -1;
100 static int hf_slsk_slots_available = -1;
101 static int hf_slsk_allowed = -1;
102 static int hf_slsk_compr_packet = -1;
103 static int hf_slsk_parent_min_speed = -1;
104 static int hf_slsk_parent_speed_connection_ratio = -1;
105 static int hf_slsk_seconds_parent_inactivity_before_disconnect = -1;
106 static int hf_slsk_seconds_server_inactivity_before_disconnect = -1;
107 static int hf_slsk_nodes_in_cache_before_disconnect = -1;
108 static int hf_slsk_seconds_before_ping_children = -1;
109 static int hf_slsk_recommendation = -1;
110 static int hf_slsk_ranking = -1;
111
112
113 /* Initialize the subtree pointers */
114 static gint ett_slsk = -1;
115 static gint ett_slsk_compr_packet = -1;
116
117 #define TCP_PORT_SLSK_1                         2234
118 #define TCP_PORT_SLSK_2                         5534
119 #define TCP_PORT_SLSK_3                         2240
120
121
122 /* desegmentation of SoulSeek Message over TCP */
123 static gboolean slsk_desegment = TRUE;
124 #ifdef HAVE_LIBZ
125 static gboolean slsk_decompress = TRUE;
126 #else
127 static gboolean slsk_decompress = FALSE;
128 #endif
129
130 static const value_string slsk_tcp_msgs[] = {
131         { 1, "Login"},
132         { 2, "Set Wait Port"},
133         { 3, "Get Peer Address"},
134         { 4, "Get Shared File List"},
135         { 5, "User Exists / Shared File List"},
136         { 7, "Get User Status"},
137         { 9, "File Search Result"},
138         { 13, "Say ChatRoom"},
139         { 14, "Join Room"},
140         { 15, "Leave Room / User Info Request"},
141         { 16, "User Joined Room / User Info Reply"},
142         { 17, "User Left Room"},
143         { 18, "Connect To Peer"},
144         { 22, "Message User"},
145         { 23, "Message User Ack"},
146         { 26, "File Search"},
147         { 28, "Set Status"},
148         { 32, "Ping"},
149         { 34, "Update Upload Speed"},
150         { 35, "Shared Files & Folders"},
151         { 36, "Get User Stats / Folder Contents Request"},
152         { 37, "Folder Contents Response"},
153         { 40, "Queued Downloads / Transfer Request"},
154         { 41, "Transfer Response"},
155         { 42, "Placehold Upload"},
156         { 43, "Queue Upload"},
157         { 44, "Place In Queue"},
158         { 46, "Upload Failed"},
159         { 50, "Queue Failed / Own Recommendation"},
160         { 51, "Add Things I like / Place In Queue Request"},
161         { 52, "Remove Things I like"},
162         { 54, "Get Recommendations"},
163         { 55, "Type 55"},
164         { 56, "Get Global Rankings"},
165         { 57, "Get User Recommendations"},
166         { 58, "Admin Command"},
167         { 60, "Place In Line Response"},
168         { 62, "Room Added"},
169         { 63, "Room Removed"},
170         { 64, "Room List"},
171         { 65, "Exact File Search"},
172         { 66, "Admin Message"},
173         { 67, "Global User List"},
174         { 68, "Tunneled Message"},
175         { 69, "Privileged User List"},
176         { 71, "Get Parent List"},
177         { 73, "Type 73"},
178         { 83, "Parent Min Speed"},
179         { 84, "Parent Speed Connection Ratio"},
180         { 86, "Parent Inactivity Before Disconnect"},
181         { 87, "Server Inactivity Before Disconnect"},
182         { 88, "Nodes In Cache Before Disconnect"},
183         { 90, "Seconds Before Ping Children"},
184         { 91, "Add To Privileged"},
185         { 92, "Check Privileges"},
186         { 93, "Embedded Message"},
187         { 100, "Become Parent"},
188         { 102, "Random Parent Addresses"},
189         { 103, "Send Wishlist Entry"},
190         { 104, "Type 104"},
191         { 110, "Get Similar Users"},
192         { 111, "Get Recommendations for Item"},
193         { 112, "Get Similar Users for Item"},
194         { 1001, "Can't Connect To Peer"},
195         { 0, NULL }
196 };
197
198 static const value_string slsk_status_codes[] = {
199         { -1, "Unknown"},
200         { 0, "Offline"},
201         { 1, "Away"},
202         { 2, "Online"},
203         { 0, NULL }
204 };
205
206 static const value_string slsk_transfer_direction[] = {
207         { 0, "Download"},
208         { 1, "Upload"},
209         { 0, NULL }
210 };
211
212 static const value_string slsk_yes_no[] = {
213         { 0, "No"},
214         { 1, "Yes"},
215         { 0, NULL }
216 };
217
218 static const value_string slsk_attr_type[] = {
219         { 0, "Bitrate"},
220         { 1, "Length"},
221         { 2, "VBR"},
222         { 0, NULL }
223 };
224
225 static const char* connection_type(char con_type[]) {
226         if (strlen(con_type) != 1) return "Unknown";
227         if (con_type[0] == 'D') return "Distributed Search";
228         if (con_type[0] == 'P') return "Peer Connection";               /* "File Search Result / User Info Request / Get Shared File List" */
229         if (con_type[0] == 'F') return "File Transfer";
230         return "Unknown";
231 }
232
233 static gboolean check_slsk_format(tvbuff_t *tvb, int offset, const char format[]){
234
235         /*
236         * Returns TRUE if tvbuff beginning at offset matches a certain format
237         * The format is given by an array of characters standing for a special field type
238         *               i - integer     (4 bytes)
239         *               b - byte        (1 byte)
240         *               s - string      (string_length + 4 bytes)
241         *
242         *               * - can be used at the end of a format to ignore any following bytes
243         */
244
245         switch ( format[0] ) {
246                 case 'i':
247                         if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
248                         offset += 4;
249                 break;
250                 case 'b':
251                         if (tvb_length_remaining(tvb, offset) < 1) return FALSE;
252                         offset += 1;
253                 break;
254                 case 's':
255                         if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
256                         if (tvb_length_remaining(tvb, offset) < (int)tvb_get_letohl(tvb, offset)+4) return FALSE;
257                         offset += tvb_get_letohl(tvb, offset)+4;
258                 break;
259                 case '*':
260                         return TRUE;
261                 default:
262                         return FALSE;
263         }
264
265         if (format[1] == '\0' ) {
266                 if (tvb_length_remaining(tvb, offset) != 0) return FALSE;       /* Checks for additional bytes at the end */
267                         return TRUE;
268         }
269         return check_slsk_format(tvb, offset, &format[1]);
270
271 }
272
273 static const char* get_message_type(tvbuff_t *tvb) {
274         /*
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.
278         */
279         int msg_code = tvb_get_letohl(tvb, 4);
280         const gchar *message_type =  match_strval(msg_code, slsk_tcp_msgs);
281         if (message_type == NULL) {
282                 if (check_slsk_format(tvb, 4, "bisis"))
283                         message_type = "Distributed Search";
284                 else if (check_slsk_format(tvb, 4, "bssi"))
285                         message_type = "Peer Init";
286                 else if (check_slsk_format(tvb, 4, "bi"))
287                         message_type = "Pierce Fw";
288                 else
289                         message_type = "Unknown";
290         }
291         return message_type;
292 }
293
294 static guint get_slsk_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
295 {
296         guint32 msg_len;
297         msg_len = tvb_get_letohl(tvb, offset);
298         /* That length doesn't include the length field itself; add that in. */
299         msg_len += 4;
300         return msg_len;
301 }
302
303 /* Code to actually dissect the packets */
304
305 static void dissect_slsk_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
306 {
307
308 /* Set up structures needed to add the protocol subtree and manage it */
309         proto_item *ti;
310         proto_tree *slsk_tree;
311
312         int offset, i, j;
313         guint32 msg_len, msg_code;
314         const gchar *message_type;
315         guint8 *str;
316
317         int comprlen = 0;
318         int uncomprlen = 0;
319         int uncompr_tvb_offset = 0;
320         int i2 = 0;
321         int j2 = 0;
322         int i3 = 0;
323         int j3 = 0;
324
325         offset = 0;
326
327         msg_len = tvb_get_letohl(tvb, offset);
328         msg_code = tvb_get_letohl(tvb, offset+4);
329         message_type =  get_message_type(tvb);
330
331 /* Make entries in Protocol column and Info column on summary display */
332         if (check_col(pinfo->cinfo, COL_PROTOCOL))
333                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "slsk");
334
335 /* This field shows up as the "Info" column in the display  */
336
337         if (check_col(pinfo->cinfo, COL_INFO))
338                 col_set_str(pinfo->cinfo, COL_INFO, "SoulSeek Message");
339
340         if (check_col(pinfo->cinfo, COL_INFO)) {
341             col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_type);
342         }
343
344
345         if (tree) {
346
347 /* create display subtree for the protocol */
348                 ti = proto_tree_add_item(tree, proto_slsk, tvb, 0, -1, FALSE);
349                 slsk_tree = proto_item_add_subtree(ti, ett_slsk);
350
351 /* Continue adding tree items to process the packet here */
352
353                 proto_tree_add_uint(slsk_tree, hf_slsk_message_length, tvb, offset, 4, msg_len);
354                 offset += 4;
355
356                 switch (msg_code) {
357
358                         case  1:
359                                 if (check_slsk_format(tvb, offset, "issi")) {
360                                         /* Client-to-Server */
361                                         message_type = "Login";
362                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
363                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
364                                         offset += 4;
365                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
366                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
367                                         offset += 4+tvb_get_letohl(tvb, offset);
368                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
369                                         proto_tree_add_item(slsk_tree, hf_slsk_password, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
370                                         offset += 4+tvb_get_letohl(tvb, offset);
371                                         proto_tree_add_uint(slsk_tree, hf_slsk_version, tvb, offset, 4, tvb_get_letohl(tvb, offset));
372                                         offset += 4;
373                                 }
374                                 else if (check_slsk_format(tvb, offset, "ibs") || check_slsk_format(tvb, offset, "ibsi")) {
375                                         /* Server-to-Client */
376                                         message_type = "Login Reply";
377                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
378                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
379                                         offset += 4;
380                                         i=tvb_get_guint8(tvb, offset);
381                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_login_successful, tvb, offset, 1, tvb_get_guint8(tvb, offset),
382                                                 "Login successful: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
383                                         offset += 1;
384                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
385                                         proto_tree_add_item(slsk_tree, hf_slsk_login_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
386                                         offset += 4+tvb_get_letohl(tvb, offset);
387                                         if (i == 1){
388                                                 proto_tree_add_ipv4(slsk_tree, hf_slsk_client_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
389                                                 offset += 4;
390                                         }
391                                 }
392                         break;
393
394                         case  2:
395                                 if (check_slsk_format(tvb, offset, "ii")) {
396                                         /* Client-to-Server */
397                                         message_type = "Set Wait Port";
398                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
399                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
400                                         offset += 4;
401                                         proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
402                                         offset += 4;
403                                 }
404                         break;
405
406                         case  3:
407                                 if (check_slsk_format(tvb, offset, "isii")) {
408                                         /* Server-to-Client */
409                                         message_type = "Get Peer Address Reply";
410                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
411                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
412                                         offset += 4;
413                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
414                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
415                                         offset += 4+tvb_get_letohl(tvb, offset);
416                                         proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
417                                         offset += 4;
418                                         proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
419                                         offset += 4;
420                                 }
421                                 else if (check_slsk_format(tvb, offset, "is")) {
422                                         /* Client-to-Server */
423                                         message_type = "Get Peer Address";
424                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
425                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
426                                         offset += 4;
427                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
428                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
429                                         offset += 4+tvb_get_letohl(tvb, offset);
430                                 }
431                         break;
432
433                         case 4:
434                                 if (check_slsk_format(tvb, offset, "i")) {
435                                         /* Client-to-Client */
436                                         message_type = "Get Shared File List";
437                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
438                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
439                                         offset += 4;
440                                 }
441                         break;
442
443                         case  5:
444                                 if (check_slsk_format(tvb, offset, "isb")) {
445                                         /* Server-to-Client */
446                                         message_type = "User Exists Reply";
447                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
448                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
449                                         offset += 4;
450                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
451                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
452                                         offset += 4+tvb_get_letohl(tvb, offset);
453                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_user_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
454                                                 "User exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
455                                         offset += 1;
456                                 }
457                                 else if (check_slsk_format(tvb, offset, "is")) {
458                                         /* Client-to-Server */
459                                         message_type = "User Exists Request";
460                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
461                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
462                                         offset += 4;
463                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
464                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
465                                         offset += 4+tvb_get_letohl(tvb, offset);
466                                 }
467                                 else if (check_slsk_format(tvb, offset, "i*")) {
468                                         /* Client-to-Client */
469                                         message_type = "Shared File List";
470                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
471                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
472                                         offset += 4;
473
474                                         /* [zlib compressed] */
475                                         comprlen = tvb_length_remaining(tvb, offset);
476
477                                         if (slsk_decompress == TRUE){
478
479                                                 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
480
481                                                 if (uncompr_tvb == NULL) {
482                                                         proto_tree_add_text(slsk_tree, tvb, offset, -1,
483                                                                 "[zlib compressed packet]");
484                                                         offset += tvb_length_remaining(tvb, offset);
485                                                         proto_tree_add_text(slsk_tree, tvb, 0, 0,
486                                                                 "(uncompression failed !)");
487                                                 } else {
488
489                                                         proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
490                                                         proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
491
492                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
493                                                                 "(  compressed packet length: %d)", comprlen);
494                                                         uncomprlen = tvb_reported_length_remaining(uncompr_tvb, 0);
495                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
496                                                                 "(uncompressed packet length: %d)", uncomprlen);
497
498                                                         /* Dissects the uncompressed tvbuffer */
499                                                         tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
500                                                         add_new_data_source(pinfo, uncompr_tvb,
501                                                             "Uncompressed SoulSeek data");
502                                                         uncompr_tvb_offset = 0;
503                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "i*")) {
504                                                                 i=0;
505                                                                 j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
506                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
507                                                                         "Number of directories: %u", j);
508                                                                 uncompr_tvb_offset += 4;
509                                                                 while (i<j){
510                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
511                                                                                 guint32 len;
512
513                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
514                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
515                                                                                         uncompr_tvb_offset, 4, len,
516                                                                                         "Directory #%d String Length: %u", i+1, len);
517                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
518                                                                                         "Directory #%d Name: %s", i+1,
519                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
520                                                                                 uncompr_tvb_offset += 4+len;
521                                                                                 i2=0;
522                                                                                 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
523                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
524                                                                                         uncompr_tvb_offset, 4, j2,
525                                                                                         "Directory #%d Number of files: %u", i+1, j2);
526                                                                                 uncompr_tvb_offset += 4;
527                                                                                 while (i2<j2){
528                                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
529                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb,
530                                                                                                         uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
531                                                                                                         "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
532                                                                                                 uncompr_tvb_offset += 1;
533                                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
534                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
535                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
536                                                                                                         "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
537                                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
538                                                                                                         uncompr_tvb_offset+4, len,
539                                                                                                         "Dir #%d File #%d Filename: %s", i+1, i2+1,
540                                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
541                                                                                                 uncompr_tvb_offset += 4+len;
542                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
543                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4,
544                                                                                                         tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
545                                                                                                         "Dir #%d File #%d Size1: %u", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
546                                                                                                 uncompr_tvb_offset += 4;
547                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
548                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4,
549                                                                                                         tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
550                                                                                                         "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
551                                                                                                 uncompr_tvb_offset += 4;
552                                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
553                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
554                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
555                                                                                                         "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
556                                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
557                                                                                                         uncompr_tvb_offset+4, len,
558                                                                                                         "Dir #%d File #%d ext: %s", i+1, i2+1,
559                                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
560                                                                                                 uncompr_tvb_offset += 4+len;
561                                                                                                 i3=0;
562                                                                                                 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
563                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
564                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4,
565                                                                                                         tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
566                                                                                                         "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
567                                                                                                 uncompr_tvb_offset += 4;
568                                                                                                 while (i3<j3){
569                                                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
570                                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree,
571                                                                                                                         hf_slsk_integer, uncompr_tvb,
572                                                                                                                         uncompr_tvb_offset, 4,
573                                                                                                                         tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
574                                                                                                                         "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));
575                                                                                                                 uncompr_tvb_offset += 4;
576                                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree,
577                                                                                                                         hf_slsk_integer, uncompr_tvb,
578                                                                                                                         uncompr_tvb_offset, 4,
579                                                                                                                         tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
580                                                                                                                         "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
581                                                                                                                 uncompr_tvb_offset += 4;
582                                                                                                                 i3++;
583                                                                                                         }
584                                                                                                 }
585                                                                                         }
586                                                                                         i2++;
587                                                                                 }
588                                                                         }
589                                                                         i++;
590                                                                 }
591                                                         }
592                                                 }
593                                         }else {
594                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
595                                                         "[zlib compressed packet]");
596                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 0, 0,
597                                                         "(  compressed packet length: %d)", comprlen);
598                                                 offset += tvb_length_remaining(tvb, offset);
599                                         }
600                                 }
601                         break;
602
603                         case  7:
604                                 if (check_slsk_format(tvb, offset, "isi")) {
605                                         /* Server-to-Client */
606                                         message_type = "Get User Status Reply";
607                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
608                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
609                                         offset += 4;
610                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
611                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
612                                         offset += 4+tvb_get_letohl(tvb, offset);
613                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
614                                                 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
615                                         offset += 4;
616                                 }
617                                 else if (check_slsk_format(tvb, offset, "is")) {
618                                         /* Client-to-Server */
619                                         message_type = "Get User Status";
620                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
621                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
622                                         offset += 4;
623                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
624                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
625                                         offset += 4+tvb_get_letohl(tvb, offset);
626                                 }
627                         break;
628
629                         case 9:
630                                 if (check_slsk_format(tvb, offset, "i*")) {
631                                         /* Client-to-Client */
632                                         message_type = "File Search Result";
633                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
634                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
635                                         offset += 4;
636
637                                         /* [zlib compressed] */
638                                         comprlen = tvb_length_remaining(tvb, offset);
639
640                                         if (slsk_decompress == TRUE){
641
642                                                 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
643
644                                                 if (uncompr_tvb == NULL) {
645                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
646                                                                 "[zlib compressed packet]");
647                                                         offset += tvb_length_remaining(tvb, offset);
648                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
649                                                                 "(uncompression failed !)");
650                                                 } else {
651
652                                                         proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
653                                                         proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
654
655                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
656                                                                 "(  compressed packet length: %d)", comprlen);
657                                                         uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
658                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
659                                                                 "(uncompressed packet length: %d)", uncomprlen);
660
661                                                         /* Dissects the uncompressed tvbuffer */
662                                                         tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
663                                                         add_new_data_source(pinfo, uncompr_tvb,
664                                                             "Uncompressed SoulSeek data");
665                                                         uncompr_tvb_offset = 0;
666                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "sii*")) {
667                                                                 guint32 len;
668
669                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
670                                                                 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, uncompr_tvb_offset, 4, len);
671                                                                 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_username, uncompr_tvb, uncompr_tvb_offset+4, len, TRUE);
672                                                                 uncompr_tvb_offset += 4+len;
673                                                                 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_token, uncompr_tvb, uncompr_tvb_offset, 4, TRUE);
674                                                                 uncompr_tvb_offset += 4;
675                                                                 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
676                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
677                                                                         "Number of files: %d", j);
678                                                                 uncompr_tvb_offset += 4;
679                                                                 while (i<j){
680                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
681                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
682                                                                                         "File #%d Code: %d", i+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
683                                                                                 uncompr_tvb_offset += 1;
684                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
685                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
686                                                                                         uncompr_tvb_offset, 4, len,
687                                                                                         "File #%d String Length: %u", i+1, len);
688                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
689                                                                                         "File #%d Filename: %s", i+1,
690                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
691                                                                                 uncompr_tvb_offset += 4+len;
692                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
693                                                                                         uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
694                                                                                         "File #%d Size1: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
695                                                                                 uncompr_tvb_offset += 4;
696                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
697                                                                                         uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
698                                                                                         "File #%d Size2: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
699                                                                                 uncompr_tvb_offset += 4;
700                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
701                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
702                                                                                         uncompr_tvb_offset, 4, len,
703                                                                                         "File #%d String Length: %d", i+1, len);
704                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
705                                                                                         "File #%d ext: %s", i+1,
706                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
707                                                                                 uncompr_tvb_offset += 4+len;
708                                                                                 i2=0;
709                                                                                 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
710                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
711                                                                                         uncompr_tvb_offset, 4, j,
712                                                                                         "File #%d Number of attributes: %d", i+1, j);
713                                                                                 uncompr_tvb_offset += 4;
714                                                                                 while (i2<j2){
715                                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
716                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
717                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
718                                                                                                         "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));
719                                                                                                 uncompr_tvb_offset += 4;
720                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
721                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
722                                                                                                         "File #%d Attr #%d value: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
723                                                                                                 uncompr_tvb_offset += 4;
724                                                                                         }
725                                                                                         i2++;
726                                                                                 }
727                                                                         }
728                                                                         i++;
729                                                                 }
730                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
731                                                                         "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));
732                                                                 uncompr_tvb_offset += 1;
733                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
734                                                                         "Upload speed: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
735                                                                 uncompr_tvb_offset += 4;
736                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
737                                                                         "In Queue: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
738                                                                 uncompr_tvb_offset += 4;
739                                                         }
740                                                 }
741                                         }else {
742                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
743                                                         "[zlib compressed packet]");
744                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
745                                                         "(  compressed packet length: %d)", comprlen);
746                                                 offset += tvb_length_remaining(tvb, offset);
747                                         }
748                                 }
749                         break;
750
751                         case 13:
752                                 if (check_slsk_format(tvb, offset, "isss")) {
753                                         /* Server-to-Client */
754                                         message_type = "Say ChatRoom";
755                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
756                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
757                                         offset += 4;
758                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
759                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
760                                         offset += 4+tvb_get_letohl(tvb, offset);
761                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
762                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
763                                         offset += 4+tvb_get_letohl(tvb, offset);
764                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
765                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
766                                         offset += 4+tvb_get_letohl(tvb, offset);
767                                 }
768                                 else if (check_slsk_format(tvb, offset, "iss")) {
769                                         /* Client-to-Server */
770                                         message_type = "Say ChatRoom";
771                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
772                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
773                                         offset += 4;
774                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
775                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
776                                         offset += 4+tvb_get_letohl(tvb, offset);
777                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
778                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
779                                         offset += 4+tvb_get_letohl(tvb, offset);
780                                 }
781                         break;
782
783                         case 14:
784                                 if (check_slsk_format(tvb, offset, "is")) {
785                                         /* Client-to-Server */
786                                         message_type = "Join/Add Room";
787                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
788                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
789                                         offset += 4;
790                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
791                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
792                                         offset += 4+tvb_get_letohl(tvb, offset);
793                                 }
794                                 else if (check_slsk_format(tvb, offset, "isi*")) {
795                                         /* Server-to-Client */
796                                         message_type = "Join Room User List";
797                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
798                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
799                                         offset += 4;
800                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
801                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
802                                         offset += 4+tvb_get_letohl(tvb, offset);
803                                         i=0; j = tvb_get_letohl(tvb, offset);
804                                         proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
805                                         offset += 4;
806                                         while (i<j){
807                                                 if (check_slsk_format(tvb, offset, "s*")) {
808                                                         guint32 len;
809
810                                                         len = tvb_get_letohl(tvb, offset);
811                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
812                                                                 "String #%d Length: %d", i+1, len);
813                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
814                                                                 "User #%d: %s", i+1, tvb_format_text(tvb, offset+4, len));
815                                                         offset += 4+len;
816                                                 }
817                                                 i++;
818                                         }
819                                         if (check_slsk_format(tvb, offset, "i*")) {
820                                                 i=0; j = tvb_get_letohl(tvb, offset);
821                                                 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
822                                                 offset += 4;
823                                                 while (i<j){
824                                                         if (check_slsk_format(tvb, offset, "i*")) {
825                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
826                                                                         "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));
827                                                                 offset += 4;
828                                                         }
829                                                         i++;
830                                                 }
831                                         }
832                                         if (check_slsk_format(tvb, offset, "i*")) {
833                                                 i=0; j = tvb_get_letohl(tvb, offset);
834                                                 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
835                                                 offset += 4;
836                                                 while (i<j){
837                                                         if (check_slsk_format(tvb, offset, "iiiii*")) {
838                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
839                                                                         "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
840                                                                 offset += 4;
841                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
842                                                                         "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
843                                                                 offset += 4;
844                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
845                                                                         "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
846                                                                 offset += 4;
847                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
848                                                                         "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
849                                                                 offset += 4;
850                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
851                                                                         "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
852                                                                 offset += 4;
853                                                         }
854                                                         i++;
855                                                 }
856                                         }
857                                         if (check_slsk_format(tvb, offset, "i*")) {
858                                                 i=0; j = tvb_get_letohl(tvb, offset);
859                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
860                                                         "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
861                                                 offset += 4;
862                                                 while (i<j){
863                                                         if (check_slsk_format(tvb, offset, "i*")) {
864                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
865                                                                         "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
866                                                                 offset += 4;
867                                                         }
868                                                         i++;
869                                                 }
870                                         }
871                                 }
872                         break;
873
874                         case 15:
875                                 if (check_slsk_format(tvb, offset, "is")) {
876                                         /* Client-to-Server & Server-to-Client */
877                                         message_type = "Leave Room";
878                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
879                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
880                                         offset += 4;
881                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
882                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
883                                         offset += 4+tvb_get_letohl(tvb, offset);
884                                 }
885                                 else if (check_slsk_format(tvb, offset, "i")) {
886                                         /* Client-to-Client */
887                                         message_type = "User Info Request";
888                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
889                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
890                                         offset += 4;
891                                 }
892                         break;
893
894                         case 16:
895                                 if (check_slsk_format(tvb, offset, "issiiiiiii")) {
896                                         /* Server-to-Client */
897                                         message_type = "User Joined Room";
898                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
899                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
900                                         offset += 4;
901                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
902                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
903                                         offset += 4+tvb_get_letohl(tvb, offset);
904                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
905                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
906                                         offset += 4+tvb_get_letohl(tvb, offset);
907                                         proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
908                                         offset += 4;
909                                         proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
910                                         offset += 4;
911                                         proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
912                                         offset += 4;
913                                         proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
914                                         offset += 4;
915                                         proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
916                                         offset += 4;
917                                         proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
918                                         offset += 4;
919                                         proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
920                                         offset += 4;
921                                 }
922                                 else if (check_slsk_format(tvb, offset, "isbiib") || check_slsk_format(tvb, offset, "isbsiib")) {
923                                         /* Client-to-Client */
924                                         message_type = "User Info Reply";
925                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
926                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
927                                         offset += 4;
928                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
929                                         proto_tree_add_item(slsk_tree, hf_slsk_user_description, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
930                                         offset += 4+tvb_get_letohl(tvb, offset);
931                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_picture_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
932                                                 "Picture exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
933                                         offset += 1;
934                                         if ( tvb_get_guint8(tvb, offset -1 ) == 1 ) {
935                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
936                                                         "Picture Size: %d", tvb_get_letohl(tvb, offset));
937                                                 proto_tree_add_item(slsk_tree, hf_slsk_picture, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
938                                                 offset += 4+tvb_get_letohl(tvb, offset);
939                                         }
940                                         proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
941                                         offset += 4;
942                                         proto_tree_add_uint(slsk_tree, hf_slsk_queued_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
943                                         offset += 4;
944                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_slots_available, tvb, offset, 1, tvb_get_guint8(tvb, offset),
945                                                 "Upload Slots available: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
946                                         offset += 1;
947                                 }
948                         break;
949
950                         case 17:
951                                 if (check_slsk_format(tvb, offset, "iss")) {
952                                         /* Server-to-Client */
953                                         message_type = "User Left Room";
954                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
955                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
956                                         offset += 4;
957                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
958                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
959                                         offset += 4+tvb_get_letohl(tvb, offset);
960                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
961                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
962                                         offset += 4+tvb_get_letohl(tvb, offset);
963                                 }
964                         break;
965
966                         case 18:
967                                 if (check_slsk_format(tvb, offset, "iiss")) {
968                                         /* Client-to-Server */
969                                         guint32 len;
970
971                                         message_type = "Connect To Peer";
972                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
973                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
974                                         offset += 4;
975                                         proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
976                                         offset += 4;
977                                         len = tvb_get_letohl(tvb, offset);
978                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
979                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
980                                         offset += 4+len;
981                                         len = tvb_get_letohl(tvb, offset);
982                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
983                                         str = tvb_get_ephemeral_string(tvb, offset+4, len);
984                                         proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
985                                                 "Connection Type: %s (Char: %s)", connection_type(str),
986                                                 format_text(str, len));
987                                         offset += 4+len;
988                                 }
989                                 else if (check_slsk_format(tvb, offset, "issiii")) {
990                                         /* Server-to-Client */
991                                         guint32 len;
992
993                                         message_type = "Connect To Peer";
994                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
995                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
996                                         offset += 4;
997                                         len = tvb_get_letohl(tvb, offset);
998                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
999                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
1000                                         offset += 4+len;
1001                                         len = tvb_get_letohl(tvb, offset);
1002                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
1003                                         str = tvb_get_ephemeral_string(tvb, offset+4, len);
1004                                         proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
1005                                                 "Connection Type: %s (Char: %s)", connection_type(str),
1006                                                 format_text(str, len));
1007                                         offset += 4+len;
1008                                         proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
1009                                         offset += 4;
1010                                         proto_tree_add_item(slsk_tree, hf_slsk_port, tvb, offset, 4, TRUE);
1011                                         offset += 4;
1012                                         proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
1013                                         offset += 4;
1014                                 }
1015                         break;
1016
1017                         case 22:
1018                                 if (check_slsk_format(tvb, offset, "iss")) {
1019                                         /* Client-to-Server */
1020                                         message_type = "Message User Send";
1021                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1022                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1023                                         offset += 4;
1024                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1025                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1026                                         offset += 4+tvb_get_letohl(tvb, offset);
1027                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1028                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1029                                         offset += 4+tvb_get_letohl(tvb, offset);
1030                                 }
1031                                 else if (check_slsk_format(tvb, offset, "iiiss")) {
1032                                         /* Server-to-Client */
1033                                         message_type = "Message User Receive";
1034                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1035                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1036                                         offset += 4;
1037                                         proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1038                                         offset += 4;
1039                                         proto_tree_add_uint(slsk_tree, hf_slsk_timestamp, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1040                                         offset += 4;
1041                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1042                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1043                                         offset += 4+tvb_get_letohl(tvb, offset);
1044                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1045                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1046                                         offset += 4+tvb_get_letohl(tvb, offset);
1047                                 }
1048                         break;
1049
1050                         case 23:
1051                                 if (check_slsk_format(tvb, offset, "ii")) {
1052                                         /* Client-to-Server */
1053                                         message_type = "Message User Receive Ack";
1054                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1055                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1056                                         offset += 4;
1057                                         proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1058                                         offset += 4;
1059                                 }
1060                         break;
1061
1062                         case 26:
1063                                 if (check_slsk_format(tvb, offset, "iis")) {
1064                                         /* Client-to-Server */
1065                                         message_type = "File Search";
1066                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1067                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1068                                         offset += 4;
1069                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1070                                         offset += 4;
1071                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1072                                         proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1073                                         offset += 4+tvb_get_letohl(tvb, offset);
1074                                 }
1075                         break;
1076
1077                         case 28:
1078                                 if (check_slsk_format(tvb, offset, "ii")) {
1079                                         /* Client-to-Server */
1080                                         message_type = "Set Status";
1081                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1082                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1083                                         offset += 4;
1084                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1085                                                 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1086                                         offset += 4;
1087                                 }
1088                         break;
1089
1090                         case 32:
1091                                 if (check_slsk_format(tvb, offset, "i")) {
1092                                         /* Client-to-Server */
1093                                         message_type = "Ping";
1094                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1095                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1096                                         offset += 4;
1097                                 }
1098                         break;
1099
1100                         case 34:
1101                                 if (check_slsk_format(tvb, offset, "isi")) {
1102                                         /* Client-to-Server */
1103                                         message_type = "Update Upload Speed";
1104                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1105                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1106                                         offset += 4;
1107                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1108                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1109                                         offset += 4+tvb_get_letohl(tvb, offset);
1110                                         proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1111                                         offset += 4;
1112                                 }
1113                         break;
1114
1115                         case 35:
1116                                 if (check_slsk_format(tvb, offset, "iii")) {
1117                                         /* Client-to-Server */
1118                                         message_type = "Shared Files & Folders ";
1119                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1120                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1121                                         offset += 4;
1122                                         proto_tree_add_uint(slsk_tree, hf_slsk_folder_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1123                                         offset += 4;
1124                                         proto_tree_add_uint(slsk_tree, hf_slsk_file_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1125                                         offset += 4;
1126                                 }
1127                         break;
1128
1129                         case 36:
1130                                 if (check_slsk_format(tvb, offset, "isiiiii")) {
1131                                         /* Server-to-Client */
1132                                         message_type = "Get User Stats Reply";
1133                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1134                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1135                                         offset += 4;
1136                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1137                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1138                                         offset += 4+tvb_get_letohl(tvb, offset);
1139                                         proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1140                                         offset += 4;
1141                                         proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1142                                         offset += 4;
1143                                         proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1144                                         offset += 4;
1145                                         proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1146                                         offset += 4;
1147                                         proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1148                                         offset += 4;
1149                                 }
1150                                 else if (check_slsk_format(tvb, offset, "is")) {
1151                                         /* Client-to-Client */
1152                                         /* Client-to-Server: send after login successful */
1153                                         message_type = "Get User Stats";
1154                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1155                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1156                                         offset += 4;
1157                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1158                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1159                                         offset += 4+tvb_get_letohl(tvb, offset);
1160                                 }
1161                                 else if (check_slsk_format(tvb, offset, "iis")) {
1162                                         /* Client-to-Client */
1163                                         message_type = "Folder Contents Request";
1164                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1165                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1166                                         offset += 4;
1167                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1168                                         offset += 4;
1169                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1170                                         proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1171                                         offset += 4+tvb_get_letohl(tvb, offset);
1172                                 }
1173                         break;
1174
1175                         case 37:
1176                                 if (check_slsk_format(tvb, offset, "i*")) {
1177                                         /* Client-to-Client */
1178                                         message_type = "Folder Contents Response";
1179                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1180                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1181                                         offset += 4;
1182
1183                                         /* [zlib compressed] */
1184                                         comprlen = tvb_length_remaining(tvb, offset);
1185
1186                                         if (slsk_decompress == TRUE){
1187
1188                                                 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
1189
1190                                                 if (uncompr_tvb == NULL) {
1191                                                         proto_tree_add_text(slsk_tree, tvb, offset, -1,
1192                                                                 "[zlib compressed packet]");
1193                                                         offset += tvb_length_remaining(tvb, offset);
1194                                                         proto_tree_add_text(slsk_tree, tvb, 0, 0,
1195                                                                 "[uncompression failed !]");
1196                                                 } else {
1197
1198                                                         proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
1199                                                         proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
1200
1201                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1202                                                                 "[compressed packet length: %d]", comprlen);
1203                                                         uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
1204                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1205                                                                 "[uncompressed packet length: %d]", uncomprlen);
1206
1207                                                         /* Dissects the uncompressed tvbuffer */
1208                                                         tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
1209                                                         add_new_data_source(pinfo, uncompr_tvb,
1210                                                             "Uncompressed SoulSeek data");
1211                                                         uncompr_tvb_offset = 0;
1212                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "isi*")) {
1213                                                                 guint32 len;
1214
1215                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1216                                                                         uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1217                                                                         "Token: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1218                                                                 uncompr_tvb_offset += 4;
1219                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1220                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1221                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
1222                                                                         "Directory Name String Length: %u", len);
1223                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1224                                                                         "Directory Name: %s", tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1225                                                                 uncompr_tvb_offset += 4+len;
1226
1227                                                                 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1228                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1229                                                                         uncompr_tvb_offset, 4, j,
1230                                                                         "Number of directories: %d", j);
1231                                                                 uncompr_tvb_offset += 4;
1232                                                                 while (i<j){
1233                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
1234                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1235                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1236                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
1237                                                                                         "Directory #%d Name String Length: %u", i+1, len);
1238                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1239                                                                                         "Directory #%d Name: %s", i+1,
1240                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1241                                                                                 uncompr_tvb_offset += 4+len;
1242                                                                                 i2 = 0;
1243                                                                                 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1244                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1245                                                                                         uncompr_tvb_offset, 4, j2,
1246                                                                                         "Directory #%d Number of files: %d", i+1, j2);
1247                                                                                 uncompr_tvb_offset += 4;
1248                                                                                 while (i2<j2){
1249                                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
1250                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte,
1251                                                                                                         uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
1252                                                                                                         "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
1253                                                                                                 uncompr_tvb_offset += 1;
1254                                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1255                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1256                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
1257                                                                                                         "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1258                                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1259                                                                                                         uncompr_tvb_offset+4, len,
1260                                                                                                         "Dir #%d File #%d Filename: %s", i+1, i2+1,
1261                                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1262                                                                                                 uncompr_tvb_offset += 4+len;
1263                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1264                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1265                                                                                                         "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1266                                                                                                 uncompr_tvb_offset += 4;
1267                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1268                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1269                                                                                                         "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1270                                                                                                 uncompr_tvb_offset += 4;
1271                                                                                                 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1272                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1273                                                                                                         uncompr_tvb, uncompr_tvb_offset, 4, len,
1274                                                                                                         "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1275                                                                                                 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1276                                                                                                         uncompr_tvb_offset+4, len,
1277                                                                                                         "Dir #%d File #%d ext: %s", i+1, i2+1,
1278                                                                                                         tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1279                                                                                                 uncompr_tvb_offset += 4+len;
1280                                                                                                 i3 = 0;
1281                                                                                                 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1282                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1283                                                                                                         uncompr_tvb_offset, 4, j3,
1284                                                                                                         "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, j3);
1285                                                                                                 uncompr_tvb_offset += 4;
1286                                                                                                 while (i3<j3){
1287                                                                                                         if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
1288                                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree,
1289                                                                                                                         hf_slsk_integer, uncompr_tvb,
1290                                                                                                                         uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1291                                                                                                                         "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));
1292                                                                                                                 uncompr_tvb_offset += 4;
1293                                                                                                                 proto_tree_add_uint_format(slsk_compr_packet_tree,
1294                                                                                                                         hf_slsk_integer, uncompr_tvb,
1295                                                                                                                         uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1296                                                                                                                         "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1297                                                                                                                 uncompr_tvb_offset += 4;
1298                                                                                                         }
1299                                                                                                         i3++;
1300                                                                                                 }
1301                                                                                         }
1302                                                                                         i2++;
1303                                                                                 }
1304                                                                         }
1305                                                                         i++;
1306                                                                 }
1307                                                         }
1308                                                 }
1309                                         }else {
1310                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1311                                                         "[zlib compressed packet]");
1312                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1313                                                         "(  compressed packet length: %d)", comprlen);
1314                                                 offset += tvb_length_remaining(tvb, offset);
1315                                         }
1316                                 }
1317                         break;
1318
1319                         case 40:
1320                                 if (check_slsk_format(tvb, offset, "isi")) {
1321                                         /* Server-to-Client */
1322                                         message_type = "Queued Downloads";
1323                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1324                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1325                                         offset += 4;
1326                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1327                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1328                                         offset += 4+tvb_get_letohl(tvb, offset);
1329                                         proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1330                                         offset += 4;
1331                                 }
1332                                 else if (check_slsk_format(tvb, offset, "iiis") || check_slsk_format(tvb, offset, "iiisii")) {
1333                                         /* Client-to-Client */
1334                                         message_type = "Transfer Request";
1335                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1336                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1337                                         offset += 4;
1338                                         i = tvb_get_letohl(tvb, offset);
1339                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_transfer_direction, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1340                                                 "Transfer Direction: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_transfer_direction, "Unknown"), tvb_get_letohl(tvb, offset));
1341                                         offset += 4;
1342                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1343                                         offset += 4;
1344                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1345                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1346                                         offset += 4+tvb_get_letohl(tvb, offset);
1347                                         if (i == 1){
1348                                                 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1349                                                 offset += 4;
1350                                                 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1351                                                 offset += 4;
1352                                         }
1353                                 }
1354
1355                         break;
1356
1357                         case 41:
1358                                 if (check_slsk_format(tvb, offset, "iibs") || check_slsk_format(tvb, offset, "iibii") || check_slsk_format(tvb, offset, "iib")) {
1359                                         /* Client-to-Client */
1360                                         message_type = "Transfer Response";
1361                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1362                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1363                                         offset += 4;
1364                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1365                                         offset += 4;
1366                                         i = tvb_get_guint8(tvb, offset);
1367                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_allowed, tvb, offset, 1, tvb_get_guint8(tvb, offset),
1368                                                 "Download allowed: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
1369                                         offset += 1;
1370                                         if ( i == 1 ) {
1371                                                 if ( tvb_length_remaining(tvb, offset) == 8 ) {
1372                                                         proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1373                                                         offset += 4;
1374                                                         proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1375                                                         offset += 4;
1376                                                 }
1377                                         } else {
1378                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1379                                                 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1380                                                 offset += 4+tvb_get_letohl(tvb, offset);
1381                                         }
1382                                 }
1383                         break;
1384
1385                         case 42:
1386                                 if (check_slsk_format(tvb, offset, "is")) {
1387                                         /* Client-to-Client */
1388                                         message_type = "Placehold Upload";
1389                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1390                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1391                                         offset += 4;
1392                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1393                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1394                                         offset += 4+tvb_get_letohl(tvb, offset);
1395                                 }
1396                         break;
1397
1398                         case 43:
1399                                 if (check_slsk_format(tvb, offset, "is")) {
1400                                         /* Client-to-Client */
1401                                         message_type = "Queue Upload";
1402                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1403                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1404                                         offset += 4;
1405                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1406                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1407                                         offset += 4+tvb_get_letohl(tvb, offset);
1408                                 }
1409                         break;
1410
1411                         case 44:
1412                                 if (check_slsk_format(tvb, offset, "isi")) {
1413                                         /* Client-to-Client */
1414                                         message_type = "Place In Queue";
1415                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1416                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1417                                         offset += 4;
1418                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1419                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1420                                         offset += 4+tvb_get_letohl(tvb, offset);
1421                                         proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1422                                         offset += 4;
1423                                 }
1424                         break;
1425
1426                         case 46:
1427                                 if (check_slsk_format(tvb, offset, "is")) {
1428                                         /* Client-to-Client */
1429                                         message_type = "Upload Failed";
1430                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1431                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1432                                         offset += 4;
1433                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1434                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1435                                         offset += 4+tvb_get_letohl(tvb, offset);
1436                                 }
1437                         break;
1438
1439                         case 50:
1440                                 if (check_slsk_format(tvb, offset, "is")) {
1441                                         /* Client-to-Server */
1442                                         message_type = "Make Own Recommendation";
1443                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1444                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1445                                         offset += 4;
1446                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1447                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1448                                         offset += 4+tvb_get_letohl(tvb, offset);
1449                                 }
1450                                 else if (check_slsk_format(tvb, offset, "isi")) {
1451                                         /* Client-to-Server */
1452                                         message_type = "Remove Own Recommendation";
1453                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1454                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1455                                         offset += 4;
1456                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1457                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1458                                         offset += 4+tvb_get_letohl(tvb, offset);
1459                                         proto_tree_add_uint(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1460                                         offset += 4;
1461                                 }
1462                                 else if (check_slsk_format(tvb, offset, "iss")) {
1463                                         /* Client-to-Client */
1464                                         message_type = "Queue Failed";
1465                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1466                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1467                                         offset += 4;
1468                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1469                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1470                                         offset += 4+tvb_get_letohl(tvb, offset);
1471                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1472                                         proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1473                                         offset += 4+tvb_get_letohl(tvb, offset);
1474                                 }
1475                         break;
1476
1477                         case 51:
1478                                 if (check_slsk_format(tvb, offset, "is")) {
1479                                         /* Client-to-Server: "Add Things I like" */
1480                                         /* Client-to-Client:  "Place In Queue Request" */
1481                                         message_type = "Add Things I like / Place In Queue Request";
1482                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1483                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1484                                         offset += 4;
1485                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1486                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1487                                         offset += 4+tvb_get_letohl(tvb, offset);
1488                                 }
1489                         break;
1490
1491                         case 52:
1492                                 if (check_slsk_format(tvb, offset, "is")) {
1493                                         /* Client-to-Server */
1494                                         message_type = "Remove Things I like";
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);
1497                                         offset += 4;
1498                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1499                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1500                                         offset += 4+tvb_get_letohl(tvb, offset);
1501                                 }
1502                         break;
1503
1504                         case 54:
1505                                 if (check_slsk_format(tvb, offset, "i")) {
1506                                         /* Client-to-Server */
1507                                         message_type = "Get Recommendations";
1508                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1509                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1510                                         offset += 4;
1511                                 }
1512                                 else if (check_slsk_format(tvb, offset, "ii*")) {
1513                                         /* Server-to-Client */
1514                                         message_type = "Get Recommendations Reply";
1515                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1516                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1517                                         offset += 4;
1518                                         i=0; j = tvb_get_letohl(tvb, offset);
1519                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1520                                                 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1521                                         offset += 4;
1522                                         while (i<j){
1523                                                 if (check_slsk_format(tvb, offset, "si*")) {
1524                                                         guint32 len;
1525
1526                                                         len = tvb_get_letohl(tvb, offset);
1527                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1528                                                                 "String #%d Length: %d", i+1, len);
1529                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1530                                                                 "Recommendation #%d: %s", i+1,
1531                                                                 tvb_format_text(tvb, offset+4, len));
1532                                                         offset += 4+len;
1533                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1534                                                                 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1535                                                         offset += 4;
1536                                                 }
1537                                                 i++;
1538                                         }
1539                                 }
1540                         break;
1541
1542                         case 55:
1543                                 if (check_slsk_format(tvb, offset, "i")) {
1544                                         /* Client-to-Server */
1545                                         message_type = "Type 55";
1546                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1547                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1548                                         offset += 4;
1549                                 }
1550                         break;
1551
1552                         case 56:
1553                                 if (check_slsk_format(tvb, offset, "i")) {
1554                                         /* Client-to-Server */
1555                                         message_type = "Get Global Rankings";
1556                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1557                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1558                                         offset += 4;
1559                                 }
1560                                 else if (check_slsk_format(tvb, offset, "ii*")) {
1561                                         /* Server-to-Client */
1562                                         message_type = "Get Global Rankings Reply";
1563                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1564                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1565                                         offset += 4;
1566                                         i=0; j = tvb_get_letohl(tvb, offset);
1567                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1568                                                 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1569                                         offset += 4;
1570                                         while (i<j){
1571                                                 if (check_slsk_format(tvb, offset, "si*")) {
1572                                                         guint32 len;
1573
1574                                                         len = tvb_get_letohl(tvb, offset);
1575                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1576                                                                 "String #%d Length: %d", i+1, len);
1577                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1578                                                                 "Recommendation #%d: %s", i+1,
1579                                                                 tvb_format_text(tvb, offset+4, len));
1580                                                         offset += 4+len;
1581                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1582                                                                 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1583                                                         offset += 4;
1584                                                 }
1585                                                 i++;
1586                                         }
1587                                 }
1588                         break;
1589
1590                         case 57:
1591                                 if (check_slsk_format(tvb, offset, "is")) {
1592                                         /* Client-to-Server */
1593                                         message_type = "Get User Recommendations";
1594                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1595                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1596                                         offset += 4;
1597                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1598                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1599                                         offset += 4+tvb_get_letohl(tvb, offset);
1600                                 }
1601                                 else if (check_slsk_format(tvb, offset, "isi*")) {
1602                                         /* Server-to-Client */
1603                                         message_type = "Get User Recommendations Reply";
1604                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1605                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1606                                         offset += 4;
1607                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1608                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1609                                         offset += 4+tvb_get_letohl(tvb, offset);
1610                                         i=0; j = tvb_get_letohl(tvb, offset);
1611                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1612                                                 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1613                                         offset += 4;
1614                                         while (i<j){
1615                                                 if (check_slsk_format(tvb, offset, "s*")) {
1616                                                         guint32 len;
1617
1618                                                         len = tvb_get_letohl(tvb, offset);
1619                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1620                                                                 "String #%d Length: %d", i+1, len);
1621                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1622                                                                 "Recommendation #%d: %s", i+1,
1623                                                                 tvb_format_text(tvb, offset+4, len));
1624                                                         offset += 4+len;
1625                                                 }
1626                                                 i++;
1627                                         }
1628                                 }
1629                         break;
1630
1631                         case 58:
1632                                 if (check_slsk_format(tvb, offset, "isi*")) {
1633                                         /* Client-to-Server */
1634                                         message_type = "Admin Command";
1635                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1636                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1637                                         offset += 4;
1638                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1639                                         proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1640                                         offset += 4+tvb_get_letohl(tvb, offset);
1641                                         i=0; j = tvb_get_letohl(tvb, offset);
1642                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1643                                                 "Number of Strings: %d", tvb_get_letohl(tvb, offset));
1644                                         offset += 4;
1645                                         while (i<j){
1646                                                 if (check_slsk_format(tvb, offset, "s*")) {
1647                                                         guint32 len;
1648
1649                                                         len = tvb_get_letohl(tvb, offset);
1650                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1651                                                                 "String #%d Length: %d", i+1, len);
1652                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1653                                                                 "String #%d: %s", i+1,
1654                                                                 tvb_format_text(tvb, offset+4, len));
1655                                                         offset += 4+len;
1656                                                 }
1657                                                 i++;
1658                                         }
1659                                 }
1660                         break;
1661
1662                         case 60:
1663                                 if (check_slsk_format(tvb, offset, "isii")) {
1664                                         /* Client-to-Server & Server-to-Client */
1665                                         message_type = "Place In Line Response";
1666                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1667                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1668                                         offset += 4;
1669                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1670                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1671                                         offset += 4+tvb_get_letohl(tvb, offset);
1672                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1673                                         offset += 4;
1674                                         proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1675                                         offset += 4;
1676                                 }
1677                         break;
1678
1679                         case 62:
1680                                 if (check_slsk_format(tvb, offset, "is")) {
1681                                         /* Server-to-Client */
1682                                         message_type = "Room Added";
1683                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1684                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1685                                         offset += 4;
1686                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1687                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1688                                         offset += 4+tvb_get_letohl(tvb, offset);
1689                                 }
1690                         break;
1691
1692                         case 63:
1693                                 if (check_slsk_format(tvb, offset, "is")) {
1694                                         /* Server-to-Client */
1695                                         message_type = "Room Removed";
1696                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1697                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1698                                         offset += 4;
1699                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1700                                         proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1701                                         offset += 4+tvb_get_letohl(tvb, offset);
1702                                 }
1703                         break;
1704
1705                         case 64:
1706                                 if (check_slsk_format(tvb, offset, "i")) {
1707                                         /* Client-to-Server */
1708                                         message_type = "Room List Request";
1709                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1710                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1711                                         offset += 4;
1712                                 }
1713                                 else if (check_slsk_format(tvb, offset, "ii*")) {
1714                                         /* Server-to-Client */
1715                                         message_type = "Room List";
1716                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1717                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1718                                         offset += 4;
1719                                         i=0; j = tvb_get_letohl(tvb, offset);
1720                                         proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1721                                         offset += 4;
1722                                         while (i<j){
1723                                                 if (check_slsk_format(tvb, offset, "s*")) {
1724                                                         guint32 len;
1725
1726                                                         len = tvb_get_letohl(tvb, offset);
1727                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1728                                                                 "String #%d Length: %d", i+1, len);
1729                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1730                                                                 "Room #%d: %s", i+1,
1731                                                                 tvb_format_text(tvb, offset+4, len));
1732                                                         offset += 4+len;
1733                                                 }
1734                                                 i++;
1735                                         }
1736                                         if (check_slsk_format(tvb, offset, "i*")) {
1737                                                 i=0;
1738                                                 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1739                                                 offset += 4;
1740                                                 while (i<j){
1741                                                         if (check_slsk_format(tvb, offset, "i*")) {
1742                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1743                                                                         "Users in Room #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1744                                                                 offset += 4;
1745                                                         }
1746                                                         i++;
1747                                                 }
1748                                         }
1749                                 }
1750                         break;
1751
1752                         case 65:
1753                                 if (check_slsk_format(tvb, offset, "isissiii")) {
1754                                         /* Server-to-Client */
1755                                         message_type = "Exact File Search";
1756                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1757                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1758                                         offset += 4;
1759                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1760                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1761                                         offset += 4+tvb_get_letohl(tvb, offset);
1762                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1763                                         offset += 4;
1764                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1765                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1766                                         offset += 4+tvb_get_letohl(tvb, offset);
1767                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1768                                         proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1769                                         offset += 4+tvb_get_letohl(tvb, offset);
1770                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 16, 0,
1771                                                 "(+12 0 bytes)");
1772                                         offset += 12;
1773                                 }
1774                                 else if (check_slsk_format(tvb, offset, "iissiiib")) {
1775                                         /* Client-to-Server */
1776                                         message_type = "Exact File Search";
1777                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1778                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1779                                         offset += 4;
1780                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1781                                         offset += 4;
1782                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1783                                         proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1784                                         offset += 4+tvb_get_letohl(tvb, offset);
1785                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1786                                         proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1787                                         offset += 4+tvb_get_letohl(tvb, offset);
1788                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 13, 0,
1789                                                 "(+13 0 bytes)");
1790                                         offset += 13;
1791                                 }
1792                         break;
1793
1794                         case 66:
1795                                 if (check_slsk_format(tvb, offset, "is")) {
1796                                         /* Server-to-Client */
1797                                         message_type = "Admin Message";
1798                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1799                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1800                                         offset += 4;
1801                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1802                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1803                                         offset += 4+tvb_get_letohl(tvb, offset);
1804                                 }
1805                         break;
1806
1807                         case 67:
1808                                 if (check_slsk_format(tvb, offset, "i")) {
1809                                         /* Client-to-Server */
1810                                         message_type = "Global User List Request";
1811                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1812                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1813                                         offset += 4;
1814                                 }
1815                                 else if (check_slsk_format(tvb, offset, "isi*")) {              /* same as case 14 */
1816                                         /* Server-to-Client */
1817                                         message_type = "Global User List";
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);
1820                                         offset += 4;
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_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1823                                         offset += 4+tvb_get_letohl(tvb, offset);
1824                                         i=0; j = tvb_get_letohl(tvb, offset);
1825                                         proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1826                                         offset += 4;
1827                                         while (i<j){
1828                                                 if (check_slsk_format(tvb, offset, "s*")) {
1829                                                         guint32 len;
1830
1831                                                         len = tvb_get_letohl(tvb, offset);
1832                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1833                                                                 "String #%d Length: %d", i+1, len);
1834                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1835                                                                 "User #%d: %s", i+1,
1836                                                                 tvb_format_text(tvb, offset+4, len));
1837                                                         offset += 4+len;
1838                                                 }
1839                                                 i++;
1840                                         }
1841                                         if (check_slsk_format(tvb, offset, "i*")) {
1842                                                 i=0; j = tvb_get_letohl(tvb, offset);
1843                                                 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, j);
1844                                                 offset += 4;
1845                                                 while (i<j){
1846                                                         if (check_slsk_format(tvb, offset, "i*")) {
1847                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1848                                                                         "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));
1849                                                                 offset += 4;
1850                                                         }
1851                                                         i++;
1852                                                 }
1853                                         }
1854                                         if (check_slsk_format(tvb, offset, "i*")) {
1855                                                 i=0; j = tvb_get_letohl(tvb, offset);
1856                                                 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1857                                                 offset += 4;
1858                                                 while (i<j){
1859                                                         if (check_slsk_format(tvb, offset, "iiiii*")) {
1860                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1861                                                                         "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1862                                                                 offset += 4;
1863                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1864                                                                         "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1865                                                                 offset += 4;
1866                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1867                                                                         "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1868                                                                 offset += 4;
1869                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1870                                                                         "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1871                                                                 offset += 4;
1872                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1873                                                                         "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1874                                                                 offset += 4;
1875                                                         }
1876                                                         i++;
1877                                                 }
1878                                         }
1879                                         if (check_slsk_format(tvb, offset, "i*")) {
1880                                                 i=0; j = tvb_get_letohl(tvb, offset);
1881                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1882                                                         "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
1883                                                 offset += 4;
1884                                                 while (i<j){
1885                                                         if (check_slsk_format(tvb, offset, "i*")) {
1886                                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1887                                                                         "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1888                                                                 offset += 4;
1889                                                         }
1890                                                         i++;
1891                                                 }
1892                                         }
1893                                 }
1894                         break;
1895
1896                         case 68:
1897                                 if (check_slsk_format(tvb, offset, "isiiiis")) {
1898                                         message_type = "Tunneled Message";
1899                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1900                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1901                                         offset += 4;
1902                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1903                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1904                                         offset += 4+tvb_get_letohl(tvb, offset);
1905                                         proto_tree_add_uint(slsk_tree, hf_slsk_code, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1906                                         offset += 4;
1907                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1908                                         offset += 4;
1909                                         proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
1910                                         offset += 4;
1911                                         proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1912                                         offset += 4;
1913                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1914                                         proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1915                                         offset += 4+tvb_get_letohl(tvb, offset);
1916                                 }
1917                         break;
1918
1919                         case 69:
1920                                 if (check_slsk_format(tvb, offset, "i")) {
1921                                         /* Client-to-Server */
1922                                         message_type = "Privileged User List Request";
1923                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1924                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1925                                         offset += 4;
1926                                 }
1927                                 else if (check_slsk_format(tvb, offset, "ii*")) {
1928                                         /* Server-to-Client */
1929                                         message_type = "Privileged User List";
1930                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1931                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1932                                         offset += 4;
1933                                         i=0; j = tvb_get_letohl(tvb, offset);
1934                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1935                                                 "Number of Priviledged Users: %d", tvb_get_letohl(tvb, offset));
1936                                         offset += 4;
1937                                         while (i<j){
1938                                                 if (check_slsk_format(tvb, offset, "s*")) {
1939                                                         guint32 len;
1940
1941                                                         len = tvb_get_letohl(tvb, offset);
1942                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1943                                                                 "String #%d Length: %d", i+1, len);
1944                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1945                                                                 "User #%d: %s", i+1,
1946                                                                 tvb_format_text(tvb, offset+4, len));
1947                                                         offset += 4+len;
1948                                                 }
1949                                                 i++;
1950                                         }
1951                                 }
1952                         break;
1953
1954                         case 71:
1955                                 if (check_slsk_format(tvb, offset, "ib")) {
1956                                         /* Client-to-Server */
1957                                         message_type = "Get Parent List";
1958                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1959                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1960                                         offset += 4;
1961                                         proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1962                                         offset += 1;
1963                                 }
1964                         break;
1965
1966                         case 73:
1967                                 if (check_slsk_format(tvb, offset, "ii")) {
1968                                         /* Client-to-Server */
1969                                         message_type = "Type 73";
1970                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1971                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1972                                         offset += 4;
1973                                         proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1974                                         offset += 4;
1975                                 }
1976                         break;
1977
1978                         case 83:
1979                                 if (check_slsk_format(tvb, offset, "ii")) {
1980                                         /* Server-to-Client */
1981                                         message_type = "Parent Min Speed";
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);
1984                                         offset += 4;
1985                                         proto_tree_add_uint(slsk_tree, hf_slsk_parent_min_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1986                                         offset += 4;
1987                                 }
1988                         break;
1989
1990                         case 84:
1991                                 if (check_slsk_format(tvb, offset, "ii")) {
1992                                         /* Server-to-Client */
1993                                         message_type = "Parent Speed Connection Ratio";
1994                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1995                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
1996                                         offset += 4;
1997                                         proto_tree_add_uint(slsk_tree, hf_slsk_parent_speed_connection_ratio, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1998                                         offset += 4;
1999                                 }
2000                         break;
2001
2002                         case 86:
2003                                 if (check_slsk_format(tvb, offset, "ii")) {
2004                                         /* Server-to-Client */
2005                                         message_type = "Parent Inactivity Before Disconnect";
2006                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2007                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2008                                         offset += 4;
2009                                         proto_tree_add_uint(slsk_tree, hf_slsk_seconds_parent_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2010                                         offset += 4;
2011                                 }
2012                         break;
2013
2014                         case 87:
2015                                 if (check_slsk_format(tvb, offset, "ii")) {
2016                                         /* Server-to-Client */
2017                                         message_type = "Server Inactivity Before Disconnect";
2018                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2019                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2020                                         offset += 4;
2021                                         proto_tree_add_uint(slsk_tree, hf_slsk_seconds_server_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2022                                         offset += 4;
2023                                 }
2024                         break;
2025
2026                         case 88:
2027                                 if (check_slsk_format(tvb, offset, "ii")) {
2028                                         /* Server-to-Client */
2029                                         message_type = "Nodes In Cache Before Disconnect";
2030                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2031                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2032                                         offset += 4;
2033                                         proto_tree_add_uint(slsk_tree, hf_slsk_nodes_in_cache_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2034                                         offset += 4;
2035                                 }
2036                         break;
2037
2038                         case 90:
2039                                 if (check_slsk_format(tvb, offset, "ii")) {
2040                                         /* Server-to-Client */
2041                                         message_type = "Seconds Before Ping Children";
2042                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2043                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2044                                         offset += 4;
2045                                         proto_tree_add_uint(slsk_tree, hf_slsk_seconds_before_ping_children, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2046                                         offset += 4;
2047                                 }
2048                         break;
2049
2050                         case 91:
2051                                 if (check_slsk_format(tvb, offset, "is")) {
2052                                         /* Server-to-Client */
2053                                         message_type = "Add To Privileged";
2054                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2055                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2056                                         offset += 4;
2057                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2058                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2059                                         offset += 4+tvb_get_letohl(tvb, offset);
2060                                 }
2061                         break;
2062
2063                         case 92:
2064                                 if (check_slsk_format(tvb, offset, "i")) {
2065                                         /* Client-to-Server */
2066                                         message_type = "Check Privileges";
2067                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2068                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2069                                         offset += 4;
2070                                 }
2071                                 else if (check_slsk_format(tvb, offset, "ii")) {
2072                                         /* Server-to-Client */
2073                                         message_type = "Check Privileges Reply";
2074                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2075                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2076                                         offset += 4;
2077                                         proto_tree_add_uint(slsk_tree, hf_slsk_number_of_days, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2078                                         offset += 4;
2079                                 }
2080                         break;
2081
2082                         case 93:
2083                                 if (check_slsk_format(tvb, offset, "ibisis")) {
2084                                         /* Server-to-Client */
2085                                         message_type = "Embedded Message";
2086                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2087                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2088                                         offset += 4;
2089                                         if ( tvb_get_guint8(tvb, offset) == 3 ){
2090                                                 /* Client-to-Client */
2091                                                 message_type = "Distributed Search";
2092                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2093                                                                        "Embedded Message Type: %s (Byte: %d)", message_type, 3);
2094                                                 offset += 1;
2095                                                 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2096                                                 offset += 4;
2097                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2098                                                 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2099                                                 offset += 4+tvb_get_letohl(tvb, offset);
2100                                                 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2101                                                 offset += 4;
2102                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2103                                                 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2104                                                 offset += 4+tvb_get_letohl(tvb, offset);
2105                                         }
2106                                 }
2107                         break;
2108
2109                         case 100:
2110                                 if (check_slsk_format(tvb, offset, "ib")) {
2111                                         /* Client-to-Server */
2112                                         message_type = "Become Parent";
2113                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2114                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2115                                         offset += 4;
2116                                         proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
2117                                         offset += 1;
2118                                 }
2119                         break;
2120
2121                         case 102:
2122                                 if (check_slsk_format(tvb, offset, "ii*")) {
2123                                         /* Server-to-Client */
2124                                         message_type = "Random Parent Addresses";
2125                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2126                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2127                                         offset += 4;
2128                                         i=0; j = tvb_get_letohl(tvb, offset);
2129                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2130                                                 "Number of Parent Addresses: %d", tvb_get_letohl(tvb, offset));
2131                                         offset += 4;
2132                                         while (i<j){
2133                                                 if (check_slsk_format(tvb, offset, "sii*")) {
2134                                                         guint32 len;
2135
2136                                                         len = tvb_get_letohl(tvb, offset);
2137                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2138                                                                 "String #%d Length: %d", i+1, len);
2139                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2140                                                                 "User #%d: %s", i+1,
2141                                                                 tvb_format_text(tvb, offset+4, len));
2142                                                         offset += 4+len;
2143                                                         proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
2144                                                         offset += 4;
2145                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2146                                                                 "Port Number #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2147                                                         offset += 4;
2148                                                 }
2149                                                 i++;
2150                                         }
2151                                 }
2152                         break;
2153
2154                         case 103:
2155                                 if (check_slsk_format(tvb, offset, "iis")) {
2156                                         /* Server-to-Client */
2157                                         message_type = "Send Wishlist Entry";
2158                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2159                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2160                                         offset += 4;
2161                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2162                                         offset += 4;
2163                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2164                                         proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2165                                         offset += 4+tvb_get_letohl(tvb, offset);
2166                                 }
2167                         break;
2168
2169                         case 104:
2170                                 if (check_slsk_format(tvb, offset, "ii")) {
2171                                         /* Server-to-Client */
2172                                         message_type = "Type 104";
2173                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2174                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2175                                         offset += 4;
2176                                         proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2177                                         offset += 4;
2178                                 }
2179                         break;
2180
2181                         case 110:
2182                                 if (check_slsk_format(tvb, offset, "i")) {
2183                                         /* Client-to-Server */
2184                                         message_type = "Get Similar Users";
2185                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2186                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2187                                         offset += 4;
2188                                 }
2189                                 else if (check_slsk_format(tvb, offset, "ii*")) {
2190                                         /* Server-to-Client */
2191                                         message_type = "Get Similar Users Reply";
2192                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2193                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2194                                         offset += 4;
2195                                         i=0; j = tvb_get_letohl(tvb, offset);
2196                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2197                                                 "Number of Users: %d", tvb_get_letohl(tvb, offset));
2198                                         offset += 4;
2199                                         while (i<j){
2200                                                 if (check_slsk_format(tvb, offset, "si*")) {
2201                                                         guint32 len;
2202
2203                                                         len = tvb_get_letohl(tvb, offset);
2204                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2205                                                                 "String #%d Length: %d", i+1, len);
2206                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2207                                                                 "User #%d: %s", i+1,
2208                                                                 tvb_format_text(tvb, offset+4, len));
2209                                                         offset += 4+len;
2210                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2211                                                                 "Same Recommendations #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2212                                                         offset += 4;
2213                                                 }
2214                                                 i++;
2215                                         }
2216                                 }
2217                         break;
2218
2219                         case 111:
2220                                 if (check_slsk_format(tvb, offset, "is")) {
2221                                         /* Client-to-Server */
2222                                         message_type = "Get Recommendations for Item";
2223                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2224                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2225                                         offset += 4;
2226                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2227                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2228                                         offset += 4+tvb_get_letohl(tvb, offset);
2229                                 }
2230                                 else if (check_slsk_format(tvb, offset, "isi*")) {
2231                                         /* Server-to-Client */
2232                                         message_type = "Get Recommendations for Item Reply";
2233                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2234                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2235                                         offset += 4;
2236                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2237                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2238                                         offset += 4+tvb_get_letohl(tvb, offset);
2239                                         i=0; j = tvb_get_letohl(tvb, offset);
2240                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2241                                                 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2242                                         offset += 4;
2243                                         while (i<j){
2244                                                 if (check_slsk_format(tvb, offset, "si*")) {
2245                                                         guint32 len;
2246
2247                                                         len = tvb_get_letohl(tvb, offset);
2248                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2249                                                                 "String #%d Length: %d", i+1, len);
2250                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2251                                                                 "Recommendation #%d: %s", i+1,
2252                                                                 tvb_format_text(tvb, offset+4, len));
2253                                                         offset += 4+len;
2254                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2255                                                                 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2256                                                         offset += 4;
2257                                                 }
2258                                                 i++;
2259                                         }
2260                                 }
2261                         break;
2262
2263                         case 112:
2264                                 if (check_slsk_format(tvb, offset, "is")) {
2265                                         /* Client-to-Server */
2266                                         message_type = "Get Similar Users for Item";
2267                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2268                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2269                                         offset += 4;
2270                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2271                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2272                                         offset += 4+tvb_get_letohl(tvb, offset);
2273                                 }
2274                                 else if (check_slsk_format(tvb, offset, "isi*")) {
2275                                         /* Server-to-Client */
2276                                         message_type = "Get Similar Users for Item Reply";
2277                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2278                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2279                                         offset += 4;
2280                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2281                                         proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2282                                         offset += 4+tvb_get_letohl(tvb, offset);
2283                                         i=0; j = tvb_get_letohl(tvb, offset);
2284                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2285                                                 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2286                                         offset += 4;
2287                                         while (i<j){
2288                                                 if (check_slsk_format(tvb, offset, "s*")) {
2289                                                         guint32 len;
2290
2291                                                         len = tvb_get_letohl(tvb, offset);
2292                                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2293                                                                 "String #%d Length: %d", i+1, len);
2294                                                         proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2295                                                                 "Username #%d: %s", i+1,
2296                                                                 tvb_format_text(tvb, offset+4, len));
2297                                                         offset += 4+len;
2298                                                 }
2299                                                 i++;
2300                                         }
2301                                 }
2302                         break;
2303
2304                         case 1001:
2305                                 if (check_slsk_format(tvb, offset, "iis")) {
2306                                         /* Client-to-Server */
2307                                         message_type = "Can't Connect To Peer";
2308                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2309                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2310                                         offset += 4;
2311                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2312                                         offset += 4;
2313                                         proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2314                                         proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2315                                         offset += 4+tvb_get_letohl(tvb, offset);
2316                                 }
2317                                 else if (check_slsk_format(tvb, offset, "ii")) {
2318                                         /* Server-to-Client */
2319                                         message_type = "Can't Connect To Peer";
2320                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2321                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2322                                         offset += 4;
2323                                         proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2324                                         offset += 4;
2325                                 }
2326                         break;
2327
2328                         default:
2329                                 if (check_slsk_format(tvb, offset, "bisis")) {
2330                                         if ( tvb_get_guint8(tvb, offset) == 3 ){
2331                                                 /* Client-to-Client */
2332                                                 message_type = "Distributed Search";
2333                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2334                                                                        "Message Type: %s (Byte: %d)", message_type, 3);
2335                                                 offset += 1;
2336                                                 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2337                                                 offset += 4;
2338                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2339                                                 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2340                                                 offset += 4+tvb_get_letohl(tvb, offset);
2341                                                 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2342                                                 offset += 4;
2343                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2344                                                 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2345                                                 offset += 4+tvb_get_letohl(tvb, offset);
2346                                         }
2347                                 }
2348                                 else if (check_slsk_format(tvb, offset, "bssi")) {
2349                                         if ( tvb_get_guint8(tvb, offset) == 1 ){
2350                                                 /* Client-to-Client */
2351                                                 guint32 len;
2352
2353                                                 message_type = "Peer Init";
2354                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2355                                                                        "Message Type: %s (Byte: %d)", message_type, 1);
2356                                                 offset += 1;
2357                                                 len = tvb_get_letohl(tvb, offset);
2358                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2359                                                 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
2360                                                 offset += 4+len;
2361                                                 len = tvb_get_letohl(tvb, offset);
2362                                                 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2363                                                 str = tvb_get_ephemeral_string(tvb, offset+4, len);
2364                                                 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
2365                                                         "Connection Type: %s (Char: %s)", connection_type(str),
2366                                                         format_text(str, len));
2367                                                 offset += 4+len;
2368                                                 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2369                                                 offset += 4;
2370                                         }
2371                                 }
2372                                 else if (check_slsk_format(tvb, offset, "bi")) {
2373                                         if ( tvb_get_guint8(tvb, offset) == 0 ){
2374                                                 /* Client-to-Client */
2375                                                 message_type = "Pierce Fw";
2376                                                 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2377                                                                        "Message Type: %s (Byte: %d)", message_type, 0);
2378                                                 offset += 1;
2379                                                 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2380                                                 offset += 4;
2381                                         }
2382                                 }
2383                                 else {
2384                                         message_type = "Unknown";
2385                                         proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2386                                                                "Message Type: %s (Code: %02d)", message_type, msg_code);
2387                                         offset += 4;
2388                                 }
2389                         break;
2390
2391                 }
2392
2393         }
2394
2395
2396 }
2397
2398
2399 static void dissect_slsk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2400 {
2401         tcp_dissect_pdus(tvb, pinfo, tree, slsk_desegment, 4, get_slsk_pdu_len, dissect_slsk_pdu);
2402
2403 }
2404
2405
2406 /* Register the protocol with Wireshark */
2407
2408 void
2409 proto_register_slsk(void)
2410 {
2411
2412 /* Setup list of header fields  */
2413         static hf_register_info hf[] = {
2414                 { &hf_slsk_integer,
2415                         { "Integer", "slsk.integer",
2416                         FT_UINT32, BASE_DEC, NULL, 0, "Integer", HFILL } },
2417                 { &hf_slsk_string,
2418                         { "String", "slsk.string",
2419                         FT_STRING, BASE_NONE, NULL, 0, "String", HFILL } },
2420                 { &hf_slsk_byte,
2421                         { "Byte", "slsk.byte",
2422                         FT_UINT8, BASE_DEC, NULL, 0, "Byte", HFILL } },
2423                 { &hf_slsk_message_length,
2424                         { "Message Length", "slsk.message.length",
2425                         FT_UINT32, BASE_DEC, NULL, 0, "Message Length", HFILL } },
2426                 { &hf_slsk_message_code,
2427                         { "Message Code", "slsk.message.code",
2428                         FT_UINT32, BASE_DEC, NULL, 0, "Message Code", HFILL } },
2429                 { &hf_slsk_client_ip,
2430                         { "Client IP", "slsk.server.ip",
2431                         FT_IPv4, BASE_DEC, NULL, 0, "Client IP Address", HFILL } },
2432                 { &hf_slsk_server_ip,
2433                         { "SoulSeek Server IP", "slsk.server.ip",
2434                         FT_UINT32, BASE_DEC, NULL, 0, "SoulSeek Server IP", HFILL } },
2435                 { &hf_slsk_string_length,
2436                         { "String Length", "slsk.string.length",
2437                         FT_UINT32, BASE_DEC, NULL, 0, "String Length", HFILL } },
2438                 { &hf_slsk_username,
2439                         { "Username", "slsk.username",
2440                         FT_STRING, BASE_NONE, NULL, 0, "Username", HFILL } },
2441                 { &hf_slsk_password,
2442                         { "Password", "slsk.password",
2443                         FT_STRING, BASE_NONE, NULL, 0, "Password", HFILL } },
2444                 { &hf_slsk_version,
2445                         { "Version", "slsk.version",
2446                         FT_UINT32, BASE_DEC, NULL, 0, "Version", HFILL } },
2447                 { &hf_slsk_login_successful,
2448                         { "Login successful", "slsk.login.successful",
2449                         FT_UINT8, BASE_DEC, NULL, 0, "Login Successful", HFILL } },
2450                 { &hf_slsk_login_message,
2451                         { "Login Message", "slsk.login.message",
2452                         FT_STRING, BASE_NONE, NULL, 0, "Login Message", HFILL } },
2453                 { &hf_slsk_port,
2454                         { "Port Number", "slsk.port.number",
2455                         FT_UINT32, BASE_DEC, NULL, 0, "Port Number", HFILL } },
2456                 { &hf_slsk_ip,
2457                         { "IP Address", "slsk.ip.address",
2458                         FT_IPv4, BASE_DEC, NULL, 0, "IP Address", HFILL } },
2459                 { &hf_slsk_user_exists,
2460                         { "user exists", "slsk.user.exists",
2461                         FT_UINT8, BASE_DEC, NULL, 0, "User exists", HFILL } },
2462                 { &hf_slsk_status_code,
2463                         { "Status Code", "slsk.status.code",
2464                         FT_UINT32, BASE_DEC, NULL, 0, "Status Code", HFILL } },
2465                 { &hf_slsk_room,
2466                         { "Room", "slsk.room",
2467                         FT_STRING, BASE_NONE, NULL, 0, "Room", HFILL } },
2468                 { &hf_slsk_chat_message,
2469                         { "Chat Message", "slsk.chat.message",
2470                         FT_STRING, BASE_NONE, NULL, 0, "Chat Message", HFILL } },
2471                 { &hf_slsk_users_in_room,
2472                         { "Users in Room", "slsk.room.users",
2473                         FT_UINT32, BASE_DEC, NULL, 0, "Number of Users in Room", HFILL } },
2474                 { &hf_slsk_token,
2475                         { "Token", "slsk.token",
2476                         FT_UINT32, BASE_DEC, NULL, 0, "Token", HFILL } },
2477                 { &hf_slsk_connection_type,
2478                         { "Connection Type", "slsk.connection.type",
2479                         FT_STRING, BASE_NONE, NULL, 0, "Connection Type", HFILL } },
2480                 { &hf_slsk_chat_message_id,
2481                         { "Chat Message ID", "slsk.chat.message.id",
2482                         FT_UINT32, BASE_DEC, NULL, 0, "Chat Message ID", HFILL } },
2483                 { &hf_slsk_timestamp,
2484                         { "Timestamp", "slsk.timestamp",
2485                         FT_UINT32, BASE_DEC, NULL, 0, "Timestamp", HFILL } },
2486                 { &hf_slsk_search_text,
2487                         { "Search Text", "slsk.search.text",
2488                         FT_STRING, BASE_NONE, NULL, 0, "Search Text", HFILL } },
2489                 { &hf_slsk_folder_count,
2490                         { "Folder Count", "slsk.folder.count",
2491                         FT_UINT32, BASE_DEC, NULL, 0, "Folder Count", HFILL } },
2492                 { &hf_slsk_file_count,
2493                         { "File Count", "slsk.file.count",
2494                         FT_UINT32, BASE_DEC, NULL, 0, "File Count", HFILL } },
2495                 { &hf_slsk_average_speed,
2496                         { "Average Speed", "slsk.average.speed",
2497                         FT_UINT32, BASE_DEC, NULL, 0, "Average Speed", HFILL } },
2498                 { &hf_slsk_download_number,
2499                         { "Download Number", "slsk.download.number",
2500                         FT_UINT32, BASE_DEC, NULL, 0, "Download Number", HFILL } },
2501                 { &hf_slsk_files,
2502                         { "Files", "slsk.files",
2503                         FT_UINT32, BASE_DEC, NULL, 0, "Files", HFILL } },
2504                 { &hf_slsk_directories,
2505                         { "Directories", "slsk.directories",
2506                         FT_UINT32, BASE_DEC, NULL, 0, "Directories", HFILL } },
2507                 { &hf_slsk_slotsfull,
2508                         { "Slots full", "slsk.slots.full",
2509                         FT_UINT32, BASE_DEC, NULL, 0, "Upload Slots Full", HFILL } },
2510                 { &hf_slsk_place_in_queue,
2511                         { "Place in Queue", "slsk.queue.place",
2512                         FT_UINT32, BASE_DEC, NULL, 0, "Place in Queue", HFILL } },
2513                 { &hf_slsk_number_of_rooms,
2514                         { "Number of Rooms", "slsk.room.count",
2515                         FT_UINT32, BASE_DEC, NULL, 0, "Number of Rooms", HFILL } },
2516                 { &hf_slsk_filename,
2517                         { "Filename", "slsk.filename",
2518                         FT_STRING, BASE_NONE, NULL, 0, "Filename", HFILL } },
2519                 { &hf_slsk_directory,
2520                         { "Directory", "slsk.directory",
2521                         FT_STRING, BASE_NONE, NULL, 0, "Directory", HFILL } },
2522                 { &hf_slsk_size,
2523                         { "Size", "slsk.size",
2524                         FT_UINT32, BASE_DEC, NULL, 0, "File Size", HFILL } },
2525                 { &hf_slsk_checksum,
2526                         { "Checksum", "slsk.checksum",
2527                         FT_UINT32, BASE_DEC, NULL, 0, "Checksum", HFILL } },
2528                 { &hf_slsk_code,
2529                         { "Code", "slsk.code",
2530                         FT_UINT32, BASE_DEC, NULL, 0, "Code", HFILL } },
2531                 { &hf_slsk_number_of_users,
2532                         { "Number of Users", "slsk.user.count",
2533                         FT_UINT32, BASE_DEC, NULL, 0, "Number of Users", HFILL } },
2534                 { &hf_slsk_number_of_days,
2535                         { "Number of Days", "slsk.day.count",
2536                         FT_UINT32, BASE_DEC, NULL, 0, "Number of Days", HFILL } },
2537                 { &hf_slsk_transfer_direction,
2538                         { "Transfer Direction", "slsk.transfer.direction",
2539                         FT_UINT32, BASE_DEC, NULL, 0, "Transfer Direction", HFILL } },
2540                 { &hf_slsk_user_description,
2541                         { "User Description", "slsk.user.description",
2542                         FT_STRING, BASE_NONE, NULL, 0, "User Description", HFILL } },
2543                 { &hf_slsk_picture_exists,
2544                         { "Picture exists", "slsk.user.picture.exists",
2545                         FT_UINT8, BASE_DEC, NULL, 0, "User has a picture", HFILL } },
2546                 { &hf_slsk_picture,
2547                         { "Picture", "slsk.user.picture",
2548                         FT_STRING, BASE_NONE, NULL, 0, "User Picture", HFILL } },
2549                 { &hf_slsk_user_uploads,
2550                         { "User uploads", "slsk.uploads.user",
2551                         FT_UINT32, BASE_DEC, NULL, 0, "User uploads", HFILL } },
2552                 { &hf_slsk_total_uploads,
2553                         { "Total uploads allowed", "slsk.uploads.total",
2554                         FT_UINT32, BASE_DEC, NULL, 0, "Total uploads allowed", HFILL } },
2555                 { &hf_slsk_queued_uploads,
2556                         { "Queued uploads", "slsk.uploads.queued",
2557                         FT_UINT32, BASE_DEC, NULL, 0, "Queued uploads", HFILL } },
2558                 { &hf_slsk_slots_available,
2559                         { "Upload Slots available", "slsk.uploads.available",
2560                         FT_UINT8, BASE_DEC, NULL, 0, "Upload Slots available", HFILL } },
2561                 { &hf_slsk_allowed,
2562                         { "Download allowed", "slsk.user.allowed",
2563                         FT_UINT8, BASE_DEC, NULL, 0, "allowed", HFILL } },
2564                 { &hf_slsk_compr_packet,
2565                         { "[zlib compressed packet]", "slsk.compr.packet",
2566                         FT_NONE, BASE_NONE, NULL, 0, "zlib compressed packet", HFILL } },
2567                 { &hf_slsk_parent_min_speed,
2568                         { "Parent Min Speed", "slsk.parent.min.speed",
2569                         FT_UINT32, BASE_DEC, NULL, 0, "Parent Min Speed", HFILL } },
2570                 { &hf_slsk_parent_speed_connection_ratio,
2571                         { "Parent Speed Connection Ratio", "slsk.parent.speed.connection.ratio",
2572                         FT_UINT32, BASE_DEC, NULL, 0, "Parent Speed Connection Ratio", HFILL } },
2573                 { &hf_slsk_seconds_parent_inactivity_before_disconnect,
2574                         { "Seconds Parent Inactivity Before Disconnect", "slsk.seconds.parent.inactivity.before.disconnect",
2575                         FT_UINT32, BASE_DEC, NULL, 0, "Seconds Parent Inactivity Before Disconnect", HFILL } },
2576                 { &hf_slsk_seconds_server_inactivity_before_disconnect,
2577                         { "Seconds Server Inactivity Before Disconnect", "slsk.seconds.server.inactivity.before.disconnect",
2578                         FT_UINT32, BASE_DEC, NULL, 0, "Seconds Server Inactivity Before Disconnect", HFILL } },
2579                 { &hf_slsk_nodes_in_cache_before_disconnect,
2580                         { "Nodes In Cache Before Disconnect", "slsk.nodes.in.cache.before.disconnect",
2581                         FT_UINT32, BASE_DEC, NULL, 0, "Nodes In Cache Before Disconnect", HFILL } },
2582                 { &hf_slsk_seconds_before_ping_children,
2583                         { "Seconds Before Ping Children", "slsk.seconds.before.ping.children",
2584                         FT_UINT32, BASE_DEC, NULL, 0, "Seconds Before Ping Children", HFILL } },
2585                 { &hf_slsk_recommendation,
2586                         { "Recommendation", "slsk.recommendation",
2587                         FT_STRING, BASE_NONE, NULL, 0, "Recommendation", HFILL } },
2588                 { &hf_slsk_ranking,
2589                         { "Ranking", "slsk.ranking",
2590                         FT_UINT32, BASE_DEC, NULL, 0, "Ranking", HFILL } },
2591         };
2592
2593 /* Setup protocol subtree array */
2594         static gint *ett[] = {
2595                 &ett_slsk,
2596                 &ett_slsk_compr_packet,
2597         };
2598         module_t *slsk_module;
2599
2600 /* Registers the protocol name and description */
2601         proto_slsk = proto_register_protocol("SoulSeek Protocol", "SoulSeek", "slsk");
2602
2603 /* Required function calls to register the header fields and subtrees used */
2604         proto_register_field_array(proto_slsk, hf, array_length(hf));
2605         proto_register_subtree_array(ett, array_length(ett));
2606
2607         slsk_module = prefs_register_protocol(proto_slsk, NULL);
2608
2609 /* Registers the options in the menu preferences */
2610         prefs_register_bool_preference(slsk_module, "desegment",
2611             "Reassemble SoulSeek messages spanning multiple TCP segments",
2612             "Whether the SoulSeek dissector should reassemble messages spanning multiple TCP segments."
2613             " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2614             &slsk_desegment);
2615 #ifdef HAVE_LIBZ
2616         prefs_register_bool_preference(slsk_module, "decompress",
2617             "Decompress zlib compressed packets inside SoulSeek messages",
2618             "Whether the SoulSeek dissector should decompress all zlib compressed packets inside messages",
2619             &slsk_decompress);
2620 #endif
2621
2622 }
2623
2624
2625 void
2626 proto_reg_handoff_slsk(void)
2627 {
2628         dissector_handle_t slsk_handle;
2629
2630         slsk_handle = create_dissector_handle(dissect_slsk, proto_slsk);
2631         dissector_add("tcp.port", TCP_PORT_SLSK_1, slsk_handle);
2632         dissector_add("tcp.port", TCP_PORT_SLSK_2, slsk_handle);
2633         dissector_add("tcp.port", TCP_PORT_SLSK_3, slsk_handle);
2634 }
2635