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