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