2 * Routines for SoulSeek Protocol dissection
3 * Copyright 2003, Christian Wagner <Christian.Wagner@stud.uni-karlsruhe.de>
4 * Institute of Telematics - University of Karlsruhe
5 * part of this work supported by
6 * Deutsche Forschungsgemeinschaft (DFG) Grant Number FU448/1
8 * SoulSeek Protocol dissector based on protocol descriptions from SoleSeek Project:
9 * http://cvs.sourceforge.net/viewcvs.py/soleseek/SoleSeek/doc/protocol.html?rev=HEAD
10 * Updated for SoulSeek client version 151
14 * Wireshark - Network traffic analyzer
15 * By Gerald Combs <gerald@wireshark.org>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
43 #include <epan/packet.h>
44 #include <epan/tvbuff.h>
45 #include "packet-tcp.h"
46 #include <epan/prefs.h>
47 #include <epan/strutil.h>
49 /* Initialize the protocol and registered fields */
50 static int proto_slsk = -1;
52 static int hf_slsk_integer = -1;
53 static int hf_slsk_string = -1;
54 static int hf_slsk_byte = -1;
55 static int hf_slsk_message_length = -1;
56 static int hf_slsk_message_code = -1;
57 static int hf_slsk_client_ip = -1;
58 static int hf_slsk_server_ip = -1;
59 static int hf_slsk_string_length = -1;
60 static int hf_slsk_username = -1;
61 static int hf_slsk_password = -1;
62 static int hf_slsk_version = -1;
63 static int hf_slsk_login_successful = -1;
64 static int hf_slsk_login_message = -1;
65 static int hf_slsk_port = -1;
66 static int hf_slsk_ip = -1;
67 static int hf_slsk_user_exists = -1;
68 static int hf_slsk_status_code = -1;
69 static int hf_slsk_room = -1;
70 static int hf_slsk_chat_message = -1;
71 static int hf_slsk_users_in_room = -1;
72 static int hf_slsk_token = -1;
73 static int hf_slsk_connection_type = -1;
74 static int hf_slsk_chat_message_id = -1;
75 static int hf_slsk_timestamp = -1;
76 static int hf_slsk_search_text = -1;
77 static int hf_slsk_folder_count = -1;
78 static int hf_slsk_file_count = -1;
79 static int hf_slsk_average_speed = -1;
80 static int hf_slsk_download_number = -1;
81 static int hf_slsk_files = -1;
82 static int hf_slsk_directories = -1;
83 static int hf_slsk_slotsfull = -1;
84 static int hf_slsk_place_in_queue = -1;
85 static int hf_slsk_number_of_rooms = -1;
86 static int hf_slsk_filename = -1;
87 static int hf_slsk_directory = -1;
88 static int hf_slsk_size = -1;
89 static int hf_slsk_checksum = -1;
90 static int hf_slsk_code = -1;
91 static int hf_slsk_number_of_users = -1;
92 static int hf_slsk_number_of_days = -1;
93 static int hf_slsk_transfer_direction = -1;
94 static int hf_slsk_user_description = -1;
95 static int hf_slsk_picture_exists = -1;
96 static int hf_slsk_picture = -1;
97 static int hf_slsk_user_uploads = -1;
98 static int hf_slsk_total_uploads = -1;
99 static int hf_slsk_queued_uploads = -1;
100 static int hf_slsk_slots_available = -1;
101 static int hf_slsk_allowed = -1;
102 static int hf_slsk_compr_packet = -1;
103 static int hf_slsk_parent_min_speed = -1;
104 static int hf_slsk_parent_speed_connection_ratio = -1;
105 static int hf_slsk_seconds_parent_inactivity_before_disconnect = -1;
106 static int hf_slsk_seconds_server_inactivity_before_disconnect = -1;
107 static int hf_slsk_nodes_in_cache_before_disconnect = -1;
108 static int hf_slsk_seconds_before_ping_children = -1;
109 static int hf_slsk_recommendation = -1;
110 static int hf_slsk_ranking = -1;
113 /* Initialize the subtree pointers */
114 static gint ett_slsk = -1;
115 static gint ett_slsk_compr_packet = -1;
117 #define TCP_PORT_SLSK_1 2234
118 #define TCP_PORT_SLSK_2 5534
119 #define TCP_PORT_SLSK_3 2240
122 /* desegmentation of SoulSeek Message over TCP */
123 static gboolean slsk_desegment = TRUE;
125 static gboolean slsk_decompress = TRUE;
127 static gboolean slsk_decompress = FALSE;
130 static const value_string slsk_tcp_msgs[] = {
132 { 2, "Set Wait Port"},
133 { 3, "Get Peer Address"},
134 { 4, "Get Shared File List"},
135 { 5, "User Exists / Shared File List"},
136 { 7, "Get User Status"},
137 { 9, "File Search Result"},
138 { 13, "Say ChatRoom"},
140 { 15, "Leave Room / User Info Request"},
141 { 16, "User Joined Room / User Info Reply"},
142 { 17, "User Left Room"},
143 { 18, "Connect To Peer"},
144 { 22, "Message User"},
145 { 23, "Message User Ack"},
146 { 26, "File Search"},
149 { 34, "Update Upload Speed"},
150 { 35, "Shared Files & Folders"},
151 { 36, "Get User Stats / Folder Contents Request"},
152 { 37, "Folder Contents Response"},
153 { 40, "Queued Downloads / Transfer Request"},
154 { 41, "Transfer Response"},
155 { 42, "Placehold Upload"},
156 { 43, "Queue Upload"},
157 { 44, "Place In Queue"},
158 { 46, "Upload Failed"},
159 { 50, "Queue Failed / Own Recommendation"},
160 { 51, "Add Things I like / Place In Queue Request"},
161 { 52, "Remove Things I like"},
162 { 54, "Get Recommendations"},
164 { 56, "Get Global Rankings"},
165 { 57, "Get User Recommendations"},
166 { 58, "Admin Command"},
167 { 60, "Place In Line Response"},
169 { 63, "Room Removed"},
171 { 65, "Exact File Search"},
172 { 66, "Admin Message"},
173 { 67, "Global User List"},
174 { 68, "Tunneled Message"},
175 { 69, "Privileged User List"},
176 { 71, "Get Parent List"},
178 { 83, "Parent Min Speed"},
179 { 84, "Parent Speed Connection Ratio"},
180 { 86, "Parent Inactivity Before Disconnect"},
181 { 87, "Server Inactivity Before Disconnect"},
182 { 88, "Nodes In Cache Before Disconnect"},
183 { 90, "Seconds Before Ping Children"},
184 { 91, "Add To Privileged"},
185 { 92, "Check Privileges"},
186 { 93, "Embedded Message"},
187 { 100, "Become Parent"},
188 { 102, "Random Parent Addresses"},
189 { 103, "Send Wishlist Entry"},
191 { 110, "Get Similar Users"},
192 { 111, "Get Recommendations for Item"},
193 { 112, "Get Similar Users for Item"},
194 { 1001, "Can't Connect To Peer"},
198 static const value_string slsk_status_codes[] = {
206 static const value_string slsk_transfer_direction[] = {
212 static const value_string slsk_yes_no[] = {
218 static const value_string slsk_attr_type[] = {
225 static const char* connection_type(char con_type[]) {
226 if (strlen(con_type) != 1) return "Unknown";
227 if (con_type[0] == 'D') return "Distributed Search";
228 if (con_type[0] == 'P') return "Peer Connection"; /* "File Search Result / User Info Request / Get Shared File List" */
229 if (con_type[0] == 'F') return "File Transfer";
233 static gboolean check_slsk_format(tvbuff_t *tvb, int offset, const char format[]){
236 * Returns TRUE if tvbuff beginning at offset matches a certain format
237 * The format is given by an array of characters standing for a special field type
238 * i - integer (4 bytes)
240 * s - string (string_length + 4 bytes)
242 * * - can be used at the end of a format to ignore any following bytes
245 switch ( format[0] ) {
247 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
251 if (tvb_length_remaining(tvb, offset) < 1) return FALSE;
255 if (tvb_length_remaining(tvb, offset) < 4) return FALSE;
256 if (tvb_length_remaining(tvb, offset) < (int)tvb_get_letohl(tvb, offset)+4) return FALSE;
257 offset += tvb_get_letohl(tvb, offset)+4;
265 if (format[1] == '\0' ) {
266 if (tvb_length_remaining(tvb, offset) != 0) return FALSE; /* Checks for additional bytes at the end */
269 return check_slsk_format(tvb, offset, &format[1]);
273 static const char* get_message_type(tvbuff_t *tvb) {
275 * Checks if the Message Code is known.
276 * If unknown checks if the Message Code is stored in a byte.
277 * Returns the Message Type.
279 int msg_code = tvb_get_letohl(tvb, 4);
280 const gchar *message_type = match_strval(msg_code, slsk_tcp_msgs);
281 if (message_type == NULL) {
282 if (check_slsk_format(tvb, 4, "bisis"))
283 message_type = "Distributed Search";
284 else if (check_slsk_format(tvb, 4, "bssi"))
285 message_type = "Peer Init";
286 else if (check_slsk_format(tvb, 4, "bi"))
287 message_type = "Pierce Fw";
289 message_type = "Unknown";
294 static guint get_slsk_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
297 msg_len = tvb_get_letohl(tvb, offset);
298 /* That length doesn't include the length field itself; add that in. */
303 /* Code to actually dissect the packets */
305 static void dissect_slsk_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
308 /* Set up structures needed to add the protocol subtree and manage it */
310 proto_tree *slsk_tree;
313 guint32 msg_len, msg_code;
314 const gchar *message_type;
319 int uncompr_tvb_offset = 0;
327 msg_len = tvb_get_letohl(tvb, offset);
328 msg_code = tvb_get_letohl(tvb, offset+4);
329 message_type = get_message_type(tvb);
331 /* Make entries in Protocol column and Info column on summary display */
332 if (check_col(pinfo->cinfo, COL_PROTOCOL))
333 col_set_str(pinfo->cinfo, COL_PROTOCOL, "slsk");
335 /* This field shows up as the "Info" column in the display */
337 if (check_col(pinfo->cinfo, COL_INFO))
338 col_set_str(pinfo->cinfo, COL_INFO, "SoulSeek Message");
340 if (check_col(pinfo->cinfo, COL_INFO)) {
341 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", message_type);
347 /* create display subtree for the protocol */
348 ti = proto_tree_add_item(tree, proto_slsk, tvb, 0, -1, FALSE);
349 slsk_tree = proto_item_add_subtree(ti, ett_slsk);
351 /* Continue adding tree items to process the packet here */
353 proto_tree_add_uint(slsk_tree, hf_slsk_message_length, tvb, offset, 4, msg_len);
359 if (check_slsk_format(tvb, offset, "issi")) {
360 /* Client-to-Server */
361 message_type = "Login";
362 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
363 "Message Type: %s (Code: %02d)", message_type, msg_code);
365 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
366 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
367 offset += 4+tvb_get_letohl(tvb, offset);
368 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
369 proto_tree_add_item(slsk_tree, hf_slsk_password, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
370 offset += 4+tvb_get_letohl(tvb, offset);
371 proto_tree_add_uint(slsk_tree, hf_slsk_version, tvb, offset, 4, tvb_get_letohl(tvb, offset));
374 else if (check_slsk_format(tvb, offset, "ibs") || check_slsk_format(tvb, offset, "ibsi")) {
375 /* Server-to-Client */
376 message_type = "Login Reply";
377 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
378 "Message Type: %s (Code: %02d)", message_type, msg_code);
380 i=tvb_get_guint8(tvb, offset);
381 proto_tree_add_uint_format(slsk_tree, hf_slsk_login_successful, tvb, offset, 1, tvb_get_guint8(tvb, offset),
382 "Login successful: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
384 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
385 proto_tree_add_item(slsk_tree, hf_slsk_login_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
386 offset += 4+tvb_get_letohl(tvb, offset);
388 proto_tree_add_ipv4(slsk_tree, hf_slsk_client_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
395 if (check_slsk_format(tvb, offset, "ii")) {
396 /* Client-to-Server */
397 message_type = "Set Wait Port";
398 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
399 "Message Type: %s (Code: %02d)", message_type, msg_code);
401 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
407 if (check_slsk_format(tvb, offset, "isii")) {
408 /* Server-to-Client */
409 message_type = "Get Peer Address Reply";
410 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
411 "Message Type: %s (Code: %02d)", message_type, msg_code);
413 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
414 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
415 offset += 4+tvb_get_letohl(tvb, offset);
416 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
418 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
421 else if (check_slsk_format(tvb, offset, "is")) {
422 /* Client-to-Server */
423 message_type = "Get Peer Address";
424 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
425 "Message Type: %s (Code: %02d)", message_type, msg_code);
427 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
428 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
429 offset += 4+tvb_get_letohl(tvb, offset);
434 if (check_slsk_format(tvb, offset, "i")) {
435 /* Client-to-Client */
436 message_type = "Get Shared File List";
437 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
438 "Message Type: %s (Code: %02d)", message_type, msg_code);
444 if (check_slsk_format(tvb, offset, "isb")) {
445 /* Server-to-Client */
446 message_type = "User Exists Reply";
447 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
448 "Message Type: %s (Code: %02d)", message_type, msg_code);
450 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
451 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
452 offset += 4+tvb_get_letohl(tvb, offset);
453 proto_tree_add_uint_format(slsk_tree, hf_slsk_user_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
454 "User exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
457 else if (check_slsk_format(tvb, offset, "is")) {
458 /* Client-to-Server */
459 message_type = "User Exists Request";
460 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
461 "Message Type: %s (Code: %02d)", message_type, msg_code);
463 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
464 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
465 offset += 4+tvb_get_letohl(tvb, offset);
467 else if (check_slsk_format(tvb, offset, "i*")) {
468 /* Client-to-Client */
469 message_type = "Shared File List";
470 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
471 "Message Type: %s (Code: %02d)", message_type, msg_code);
474 /* [zlib compressed] */
475 comprlen = tvb_length_remaining(tvb, offset);
477 if (slsk_decompress == TRUE){
479 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
481 if (uncompr_tvb == NULL) {
482 proto_tree_add_text(slsk_tree, tvb, offset, -1,
483 "[zlib compressed packet]");
484 offset += tvb_length_remaining(tvb, offset);
485 proto_tree_add_text(slsk_tree, tvb, 0, 0,
486 "(uncompression failed !)");
489 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
490 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
492 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
493 "( compressed packet length: %d)", comprlen);
494 uncomprlen = tvb_reported_length_remaining(uncompr_tvb, 0);
495 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
496 "(uncompressed packet length: %d)", uncomprlen);
498 /* Dissects the uncompressed tvbuffer */
499 tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
500 add_new_data_source(pinfo, uncompr_tvb,
501 "Uncompressed SoulSeek data");
502 uncompr_tvb_offset = 0;
503 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "i*")) {
505 j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
506 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
507 "Number of directories: %u", j);
508 uncompr_tvb_offset += 4;
510 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
513 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
514 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
515 uncompr_tvb_offset, 4, len,
516 "Directory #%d String Length: %u", i+1, len);
517 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
518 "Directory #%d Name: %s", i+1,
519 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
520 uncompr_tvb_offset += 4+len;
522 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
523 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
524 uncompr_tvb_offset, 4, j2,
525 "Directory #%d Number of files: %u", i+1, j2);
526 uncompr_tvb_offset += 4;
528 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
529 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb,
530 uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
531 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
532 uncompr_tvb_offset += 1;
533 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
534 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
535 uncompr_tvb, uncompr_tvb_offset, 4, len,
536 "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
537 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
538 uncompr_tvb_offset+4, len,
539 "Dir #%d File #%d Filename: %s", i+1, i2+1,
540 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
541 uncompr_tvb_offset += 4+len;
542 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
543 uncompr_tvb, uncompr_tvb_offset, 4,
544 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
545 "Dir #%d File #%d Size1: %u", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
546 uncompr_tvb_offset += 4;
547 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
548 uncompr_tvb, uncompr_tvb_offset, 4,
549 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
550 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
551 uncompr_tvb_offset += 4;
552 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
553 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
554 uncompr_tvb, uncompr_tvb_offset, 4, len,
555 "Dir #%d File #%d String Length: %u", i+1, i2+1, len);
556 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
557 uncompr_tvb_offset+4, len,
558 "Dir #%d File #%d ext: %s", i+1, i2+1,
559 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
560 uncompr_tvb_offset += 4+len;
562 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
563 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
564 uncompr_tvb, uncompr_tvb_offset, 4,
565 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
566 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
567 uncompr_tvb_offset += 4;
569 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
570 proto_tree_add_uint_format(slsk_compr_packet_tree,
571 hf_slsk_integer, uncompr_tvb,
572 uncompr_tvb_offset, 4,
573 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
574 "Dir #%d File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, i3+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
575 uncompr_tvb_offset += 4;
576 proto_tree_add_uint_format(slsk_compr_packet_tree,
577 hf_slsk_integer, uncompr_tvb,
578 uncompr_tvb_offset, 4,
579 tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
580 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
581 uncompr_tvb_offset += 4;
594 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
595 "[zlib compressed packet]");
596 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 0, 0,
597 "( compressed packet length: %d)", comprlen);
598 offset += tvb_length_remaining(tvb, offset);
604 if (check_slsk_format(tvb, offset, "isi")) {
605 /* Server-to-Client */
606 message_type = "Get User Status Reply";
607 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
608 "Message Type: %s (Code: %02d)", message_type, msg_code);
610 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
611 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
612 offset += 4+tvb_get_letohl(tvb, offset);
613 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
614 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
617 else if (check_slsk_format(tvb, offset, "is")) {
618 /* Client-to-Server */
619 message_type = "Get User Status";
620 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
621 "Message Type: %s (Code: %02d)", message_type, msg_code);
623 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
624 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
625 offset += 4+tvb_get_letohl(tvb, offset);
630 if (check_slsk_format(tvb, offset, "i*")) {
631 /* Client-to-Client */
632 message_type = "File Search Result";
633 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
634 "Message Type: %s (Code: %02d)", message_type, msg_code);
637 /* [zlib compressed] */
638 comprlen = tvb_length_remaining(tvb, offset);
640 if (slsk_decompress == TRUE){
642 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
644 if (uncompr_tvb == NULL) {
645 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, tvb_length_remaining(tvb, offset), 0,
646 "[zlib compressed packet]");
647 offset += tvb_length_remaining(tvb, offset);
648 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, 0, 0, 0,
649 "(uncompression failed !)");
652 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
653 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
655 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
656 "( compressed packet length: %d)", comprlen);
657 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
658 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
659 "(uncompressed packet length: %d)", uncomprlen);
661 /* Dissects the uncompressed tvbuffer */
662 tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
663 add_new_data_source(pinfo, uncompr_tvb,
664 "Uncompressed SoulSeek data");
665 uncompr_tvb_offset = 0;
666 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "sii*")) {
669 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
670 proto_tree_add_uint(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb, uncompr_tvb_offset, 4, len);
671 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_username, uncompr_tvb, uncompr_tvb_offset+4, len, TRUE);
672 uncompr_tvb_offset += 4+len;
673 proto_tree_add_item(slsk_compr_packet_tree, hf_slsk_token, uncompr_tvb, uncompr_tvb_offset, 4, TRUE);
674 uncompr_tvb_offset += 4;
675 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
676 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, j,
677 "Number of files: %d", j);
678 uncompr_tvb_offset += 4;
680 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
681 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, 0, 0, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
682 "File #%d Code: %d", i+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
683 uncompr_tvb_offset += 1;
684 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
685 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
686 uncompr_tvb_offset, 4, len,
687 "File #%d String Length: %u", i+1, len);
688 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
689 "File #%d Filename: %s", i+1,
690 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
691 uncompr_tvb_offset += 4+len;
692 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
693 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
694 "File #%d Size1: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
695 uncompr_tvb_offset += 4;
696 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
697 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
698 "File #%d Size2: %d", i+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
699 uncompr_tvb_offset += 4;
700 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
701 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length, uncompr_tvb,
702 uncompr_tvb_offset, 4, len,
703 "File #%d String Length: %d", i+1, len);
704 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
705 "File #%d ext: %s", i+1,
706 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
707 uncompr_tvb_offset += 4+len;
709 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
710 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
711 uncompr_tvb_offset, 4, j,
712 "File #%d Number of attributes: %d", i+1, j);
713 uncompr_tvb_offset += 4;
715 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
716 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
717 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
718 "File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
719 uncompr_tvb_offset += 4;
720 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
721 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
722 "File #%d Attr #%d value: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
723 uncompr_tvb_offset += 4;
730 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte, uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
731 "Free upload slots: %s (Byte: %d)", val_to_str(tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset), slsk_yes_no, "Unknown"), tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
732 uncompr_tvb_offset += 1;
733 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
734 "Upload speed: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
735 uncompr_tvb_offset += 4;
736 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
737 "In Queue: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
738 uncompr_tvb_offset += 4;
742 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
743 "[zlib compressed packet]");
744 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
745 "( compressed packet length: %d)", comprlen);
746 offset += tvb_length_remaining(tvb, offset);
752 if (check_slsk_format(tvb, offset, "isss")) {
753 /* Server-to-Client */
754 message_type = "Say ChatRoom";
755 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
756 "Message Type: %s (Code: %02d)", message_type, msg_code);
758 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
759 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
760 offset += 4+tvb_get_letohl(tvb, offset);
761 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
762 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
763 offset += 4+tvb_get_letohl(tvb, offset);
764 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
765 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
766 offset += 4+tvb_get_letohl(tvb, offset);
768 else if (check_slsk_format(tvb, offset, "iss")) {
769 /* Client-to-Server */
770 message_type = "Say ChatRoom";
771 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
772 "Message Type: %s (Code: %02d)", message_type, msg_code);
774 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
775 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
776 offset += 4+tvb_get_letohl(tvb, offset);
777 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
778 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
779 offset += 4+tvb_get_letohl(tvb, offset);
784 if (check_slsk_format(tvb, offset, "is")) {
785 /* Client-to-Server */
786 message_type = "Join/Add Room";
787 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
788 "Message Type: %s (Code: %02d)", message_type, msg_code);
790 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
791 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
792 offset += 4+tvb_get_letohl(tvb, offset);
794 else if (check_slsk_format(tvb, offset, "isi*")) {
795 /* Server-to-Client */
796 message_type = "Join Room User List";
797 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
798 "Message Type: %s (Code: %02d)", message_type, msg_code);
800 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
801 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
802 offset += 4+tvb_get_letohl(tvb, offset);
803 i=0; j = tvb_get_letohl(tvb, offset);
804 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
807 if (check_slsk_format(tvb, offset, "s*")) {
810 len = tvb_get_letohl(tvb, offset);
811 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
812 "String #%d Length: %d", i+1, len);
813 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
814 "User #%d: %s", i+1, tvb_format_text(tvb, offset+4, len));
819 if (check_slsk_format(tvb, offset, "i*")) {
820 i=0; j = tvb_get_letohl(tvb, offset);
821 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
824 if (check_slsk_format(tvb, offset, "i*")) {
825 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
826 "Status of User #%d: %s (Code: %d)", i+1, val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
832 if (check_slsk_format(tvb, offset, "i*")) {
833 i=0; j = tvb_get_letohl(tvb, offset);
834 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
837 if (check_slsk_format(tvb, offset, "iiiii*")) {
838 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
839 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
841 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
842 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
844 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
845 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
847 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
848 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
850 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
851 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
857 if (check_slsk_format(tvb, offset, "i*")) {
858 i=0; j = tvb_get_letohl(tvb, offset);
859 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
860 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
863 if (check_slsk_format(tvb, offset, "i*")) {
864 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
865 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
875 if (check_slsk_format(tvb, offset, "is")) {
876 /* Client-to-Server & Server-to-Client */
877 message_type = "Leave Room";
878 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
879 "Message Type: %s (Code: %02d)", message_type, msg_code);
881 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
882 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
883 offset += 4+tvb_get_letohl(tvb, offset);
885 else if (check_slsk_format(tvb, offset, "i")) {
886 /* Client-to-Client */
887 message_type = "User Info Request";
888 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
889 "Message Type: %s (Code: %02d)", message_type, msg_code);
895 if (check_slsk_format(tvb, offset, "issiiiiiii")) {
896 /* Server-to-Client */
897 message_type = "User Joined Room";
898 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
899 "Message Type: %s (Code: %02d)", message_type, msg_code);
901 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
902 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
903 offset += 4+tvb_get_letohl(tvb, offset);
904 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
905 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
906 offset += 4+tvb_get_letohl(tvb, offset);
907 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
909 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
911 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
913 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
915 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
917 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
919 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
922 else if (check_slsk_format(tvb, offset, "isbiib") || check_slsk_format(tvb, offset, "isbsiib")) {
923 /* Client-to-Client */
924 message_type = "User Info Reply";
925 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
926 "Message Type: %s (Code: %02d)", message_type, msg_code);
928 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
929 proto_tree_add_item(slsk_tree, hf_slsk_user_description, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
930 offset += 4+tvb_get_letohl(tvb, offset);
931 proto_tree_add_uint_format(slsk_tree, hf_slsk_picture_exists, tvb, offset, 1, tvb_get_guint8(tvb, offset),
932 "Picture exists: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
934 if ( tvb_get_guint8(tvb, offset -1 ) == 1 ) {
935 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
936 "Picture Size: %d", tvb_get_letohl(tvb, offset));
937 proto_tree_add_item(slsk_tree, hf_slsk_picture, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
938 offset += 4+tvb_get_letohl(tvb, offset);
940 proto_tree_add_uint(slsk_tree, hf_slsk_total_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
942 proto_tree_add_uint(slsk_tree, hf_slsk_queued_uploads, tvb, offset, 4, tvb_get_letohl(tvb, offset));
944 proto_tree_add_uint_format(slsk_tree, hf_slsk_slots_available, tvb, offset, 1, tvb_get_guint8(tvb, offset),
945 "Upload Slots available: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
951 if (check_slsk_format(tvb, offset, "iss")) {
952 /* Server-to-Client */
953 message_type = "User Left Room";
954 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
955 "Message Type: %s (Code: %02d)", message_type, msg_code);
957 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
958 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
959 offset += 4+tvb_get_letohl(tvb, offset);
960 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
961 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
962 offset += 4+tvb_get_letohl(tvb, offset);
967 if (check_slsk_format(tvb, offset, "iiss")) {
968 /* Client-to-Server */
971 message_type = "Connect To Peer";
972 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
973 "Message Type: %s (Code: %02d)", message_type, msg_code);
975 proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
977 len = tvb_get_letohl(tvb, offset);
978 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
979 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
981 len = tvb_get_letohl(tvb, offset);
982 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
983 str = tvb_get_ephemeral_string(tvb, offset+4, len);
984 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
985 "Connection Type: %s (Char: %s)", connection_type(str),
986 format_text(str, len));
989 else if (check_slsk_format(tvb, offset, "issiii")) {
990 /* Server-to-Client */
993 message_type = "Connect To Peer";
994 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
995 "Message Type: %s (Code: %02d)", message_type, msg_code);
997 len = tvb_get_letohl(tvb, offset);
998 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
999 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
1001 len = tvb_get_letohl(tvb, offset);
1002 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
1003 str = tvb_get_ephemeral_string(tvb, offset+4, len);
1004 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
1005 "Connection Type: %s (Char: %s)", connection_type(str),
1006 format_text(str, len));
1008 proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
1010 proto_tree_add_item(slsk_tree, hf_slsk_port, tvb, offset, 4, TRUE);
1012 proto_tree_add_item(slsk_tree, hf_slsk_token, tvb, offset, 4, TRUE);
1018 if (check_slsk_format(tvb, offset, "iss")) {
1019 /* Client-to-Server */
1020 message_type = "Message User Send";
1021 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1022 "Message Type: %s (Code: %02d)", message_type, msg_code);
1024 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1025 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1026 offset += 4+tvb_get_letohl(tvb, offset);
1027 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1028 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1029 offset += 4+tvb_get_letohl(tvb, offset);
1031 else if (check_slsk_format(tvb, offset, "iiiss")) {
1032 /* Server-to-Client */
1033 message_type = "Message User Receive";
1034 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1035 "Message Type: %s (Code: %02d)", message_type, msg_code);
1037 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1039 proto_tree_add_uint(slsk_tree, hf_slsk_timestamp, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1041 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1042 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1043 offset += 4+tvb_get_letohl(tvb, offset);
1044 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1045 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1046 offset += 4+tvb_get_letohl(tvb, offset);
1051 if (check_slsk_format(tvb, offset, "ii")) {
1052 /* Client-to-Server */
1053 message_type = "Message User Receive Ack";
1054 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1055 "Message Type: %s (Code: %02d)", message_type, msg_code);
1057 proto_tree_add_uint(slsk_tree, hf_slsk_chat_message_id, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1063 if (check_slsk_format(tvb, offset, "iis")) {
1064 /* Client-to-Server */
1065 message_type = "File Search";
1066 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1067 "Message Type: %s (Code: %02d)", message_type, msg_code);
1069 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1071 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1072 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1073 offset += 4+tvb_get_letohl(tvb, offset);
1078 if (check_slsk_format(tvb, offset, "ii")) {
1079 /* Client-to-Server */
1080 message_type = "Set Status";
1081 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1082 "Message Type: %s (Code: %02d)", message_type, msg_code);
1084 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1085 "Status: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1091 if (check_slsk_format(tvb, offset, "i")) {
1092 /* Client-to-Server */
1093 message_type = "Ping";
1094 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1095 "Message Type: %s (Code: %02d)", message_type, msg_code);
1101 if (check_slsk_format(tvb, offset, "isi")) {
1102 /* Client-to-Server */
1103 message_type = "Update Upload Speed";
1104 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1105 "Message Type: %s (Code: %02d)", message_type, msg_code);
1107 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1108 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1109 offset += 4+tvb_get_letohl(tvb, offset);
1110 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1116 if (check_slsk_format(tvb, offset, "iii")) {
1117 /* Client-to-Server */
1118 message_type = "Shared Files & Folders ";
1119 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1120 "Message Type: %s (Code: %02d)", message_type, msg_code);
1122 proto_tree_add_uint(slsk_tree, hf_slsk_folder_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1124 proto_tree_add_uint(slsk_tree, hf_slsk_file_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1130 if (check_slsk_format(tvb, offset, "isiiiii")) {
1131 /* Server-to-Client */
1132 message_type = "Get User Stats Reply";
1133 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1134 "Message Type: %s (Code: %02d)", message_type, msg_code);
1136 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1137 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1138 offset += 4+tvb_get_letohl(tvb, offset);
1139 proto_tree_add_uint(slsk_tree, hf_slsk_average_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1141 proto_tree_add_uint(slsk_tree, hf_slsk_download_number, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1143 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1145 proto_tree_add_uint(slsk_tree, hf_slsk_files, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1147 proto_tree_add_uint(slsk_tree, hf_slsk_directories, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1150 else if (check_slsk_format(tvb, offset, "is")) {
1151 /* Client-to-Client */
1152 /* Client-to-Server: send after login successful */
1153 message_type = "Get User Stats";
1154 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1155 "Message Type: %s (Code: %02d)", message_type, msg_code);
1157 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1158 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1159 offset += 4+tvb_get_letohl(tvb, offset);
1161 else if (check_slsk_format(tvb, offset, "iis")) {
1162 /* Client-to-Client */
1163 message_type = "Folder Contents Request";
1164 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1165 "Message Type: %s (Code: %02d)", message_type, msg_code);
1167 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1169 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1170 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1171 offset += 4+tvb_get_letohl(tvb, offset);
1176 if (check_slsk_format(tvb, offset, "i*")) {
1177 /* Client-to-Client */
1178 message_type = "Folder Contents Response";
1179 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1180 "Message Type: %s (Code: %02d)", message_type, msg_code);
1183 /* [zlib compressed] */
1184 comprlen = tvb_length_remaining(tvb, offset);
1186 if (slsk_decompress == TRUE){
1188 tvbuff_t *uncompr_tvb = tvb_uncompress(tvb, offset, comprlen);
1190 if (uncompr_tvb == NULL) {
1191 proto_tree_add_text(slsk_tree, tvb, offset, -1,
1192 "[zlib compressed packet]");
1193 offset += tvb_length_remaining(tvb, offset);
1194 proto_tree_add_text(slsk_tree, tvb, 0, 0,
1195 "[uncompression failed !]");
1198 proto_item *ti2 = proto_tree_add_item(slsk_tree, hf_slsk_compr_packet, tvb, offset, -1, FALSE);
1199 proto_tree *slsk_compr_packet_tree = proto_item_add_subtree(ti2, ett_slsk_compr_packet);
1201 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1202 "[compressed packet length: %d]", comprlen);
1203 uncomprlen = tvb_length_remaining(uncompr_tvb, 0);
1204 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1205 "[uncompressed packet length: %d]", uncomprlen);
1207 /* Dissects the uncompressed tvbuffer */
1208 tvb_set_child_real_data_tvbuff(tvb, uncompr_tvb);
1209 add_new_data_source(pinfo, uncompr_tvb,
1210 "Uncompressed SoulSeek data");
1211 uncompr_tvb_offset = 0;
1212 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "isi*")) {
1215 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1216 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1217 "Token: %d", tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1218 uncompr_tvb_offset += 4;
1219 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1220 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1221 uncompr_tvb, uncompr_tvb_offset, 4, len,
1222 "Directory Name String Length: %u", len);
1223 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1224 "Directory Name: %s", tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1225 uncompr_tvb_offset += 4+len;
1227 i=0; j = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1228 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1229 uncompr_tvb_offset, 4, j,
1230 "Number of directories: %d", j);
1231 uncompr_tvb_offset += 4;
1233 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "si*")) {
1234 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1235 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1236 uncompr_tvb, uncompr_tvb_offset, 4, len,
1237 "Directory #%d Name String Length: %u", i+1, len);
1238 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb, uncompr_tvb_offset+4, len,
1239 "Directory #%d Name: %s", i+1,
1240 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1241 uncompr_tvb_offset += 4+len;
1243 j2 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1244 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1245 uncompr_tvb_offset, 4, j2,
1246 "Directory #%d Number of files: %d", i+1, j2);
1247 uncompr_tvb_offset += 4;
1249 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "bsiisi*")) {
1250 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_byte,
1251 uncompr_tvb, uncompr_tvb_offset, 1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset),
1252 "Dir #%d File #%d Code: %d", i+1, i2+1, tvb_get_guint8(uncompr_tvb, uncompr_tvb_offset));
1253 uncompr_tvb_offset += 1;
1254 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1255 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1256 uncompr_tvb, uncompr_tvb_offset, 4, len,
1257 "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1258 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1259 uncompr_tvb_offset+4, len,
1260 "Dir #%d File #%d Filename: %s", i+1, i2+1,
1261 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1262 uncompr_tvb_offset += 4+len;
1263 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1264 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1265 "Dir #%d File #%d Size1: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1266 uncompr_tvb_offset += 4;
1267 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer,
1268 uncompr_tvb, uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1269 "Dir #%d File #%d Size2: %d", i+1, i2+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1270 uncompr_tvb_offset += 4;
1271 len = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1272 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_string_length,
1273 uncompr_tvb, uncompr_tvb_offset, 4, len,
1274 "Dir #%d File #%d String Length: %d", i+1, i2+1, len);
1275 proto_tree_add_text(slsk_compr_packet_tree, uncompr_tvb,
1276 uncompr_tvb_offset+4, len,
1277 "Dir #%d File #%d ext: %s", i+1, i2+1,
1278 tvb_format_text(uncompr_tvb, uncompr_tvb_offset+4, len));
1279 uncompr_tvb_offset += 4+len;
1281 j3 = tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset);
1282 proto_tree_add_uint_format(slsk_compr_packet_tree, hf_slsk_integer, uncompr_tvb,
1283 uncompr_tvb_offset, 4, j3,
1284 "Dir #%d File #%d Number of attributes: %d", i+1, i2+1, j3);
1285 uncompr_tvb_offset += 4;
1287 if (check_slsk_format(uncompr_tvb, uncompr_tvb_offset, "ii*")) {
1288 proto_tree_add_uint_format(slsk_compr_packet_tree,
1289 hf_slsk_integer, uncompr_tvb,
1290 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1291 "Dir #%d File #%d Attr #%d type: %s (Code: %d)", i+1, i2+1, i3+1, val_to_str(tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset), slsk_attr_type, "Unknown"), tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1292 uncompr_tvb_offset += 4;
1293 proto_tree_add_uint_format(slsk_compr_packet_tree,
1294 hf_slsk_integer, uncompr_tvb,
1295 uncompr_tvb_offset, 4, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset),
1296 "Dir #%d File #%d Attr #%d value: %d", i+1, i2+1, i3+1, tvb_get_letohl(uncompr_tvb, uncompr_tvb_offset));
1297 uncompr_tvb_offset += 4;
1310 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1311 "[zlib compressed packet]");
1312 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, -1, 0,
1313 "( compressed packet length: %d)", comprlen);
1314 offset += tvb_length_remaining(tvb, offset);
1320 if (check_slsk_format(tvb, offset, "isi")) {
1321 /* Server-to-Client */
1322 message_type = "Queued Downloads";
1323 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1324 "Message Type: %s (Code: %02d)", message_type, msg_code);
1326 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1327 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1328 offset += 4+tvb_get_letohl(tvb, offset);
1329 proto_tree_add_uint(slsk_tree, hf_slsk_slotsfull, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1332 else if (check_slsk_format(tvb, offset, "iiis") || check_slsk_format(tvb, offset, "iiisii")) {
1333 /* Client-to-Client */
1334 message_type = "Transfer Request";
1335 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1336 "Message Type: %s (Code: %02d)", message_type, msg_code);
1338 i = tvb_get_letohl(tvb, offset);
1339 proto_tree_add_uint_format(slsk_tree, hf_slsk_transfer_direction, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1340 "Transfer Direction: %s (Code: %d)", val_to_str(tvb_get_letohl(tvb, offset), slsk_transfer_direction, "Unknown"), tvb_get_letohl(tvb, offset));
1342 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1344 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1345 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1346 offset += 4+tvb_get_letohl(tvb, offset);
1348 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1350 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1358 if (check_slsk_format(tvb, offset, "iibs") || check_slsk_format(tvb, offset, "iibii") || check_slsk_format(tvb, offset, "iib")) {
1359 /* Client-to-Client */
1360 message_type = "Transfer Response";
1361 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1362 "Message Type: %s (Code: %02d)", message_type, msg_code);
1364 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1366 i = tvb_get_guint8(tvb, offset);
1367 proto_tree_add_uint_format(slsk_tree, hf_slsk_allowed, tvb, offset, 1, tvb_get_guint8(tvb, offset),
1368 "Download allowed: %s (Byte: %d)", val_to_str(tvb_get_guint8(tvb, offset), slsk_yes_no, "Unknown"), tvb_get_guint8(tvb, offset));
1371 if ( tvb_length_remaining(tvb, offset) == 8 ) {
1372 proto_tree_add_uint(slsk_tree, hf_slsk_size, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1374 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1378 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1379 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1380 offset += 4+tvb_get_letohl(tvb, offset);
1386 if (check_slsk_format(tvb, offset, "is")) {
1387 /* Client-to-Client */
1388 message_type = "Placehold Upload";
1389 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1390 "Message Type: %s (Code: %02d)", message_type, msg_code);
1392 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1393 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1394 offset += 4+tvb_get_letohl(tvb, offset);
1399 if (check_slsk_format(tvb, offset, "is")) {
1400 /* Client-to-Client */
1401 message_type = "Queue Upload";
1402 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1403 "Message Type: %s (Code: %02d)", message_type, msg_code);
1405 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1406 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1407 offset += 4+tvb_get_letohl(tvb, offset);
1412 if (check_slsk_format(tvb, offset, "isi")) {
1413 /* Client-to-Client */
1414 message_type = "Place In Queue";
1415 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1416 "Message Type: %s (Code: %02d)", message_type, msg_code);
1418 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1419 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1420 offset += 4+tvb_get_letohl(tvb, offset);
1421 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1427 if (check_slsk_format(tvb, offset, "is")) {
1428 /* Client-to-Client */
1429 message_type = "Upload Failed";
1430 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1431 "Message Type: %s (Code: %02d)", message_type, msg_code);
1433 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1434 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1435 offset += 4+tvb_get_letohl(tvb, offset);
1440 if (check_slsk_format(tvb, offset, "is")) {
1441 /* Client-to-Server */
1442 message_type = "Make Own Recommendation";
1443 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1444 "Message Type: %s (Code: %02d)", message_type, msg_code);
1446 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1447 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1448 offset += 4+tvb_get_letohl(tvb, offset);
1450 else if (check_slsk_format(tvb, offset, "isi")) {
1451 /* Client-to-Server */
1452 message_type = "Remove Own Recommendation";
1453 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1454 "Message Type: %s (Code: %02d)", message_type, msg_code);
1456 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1457 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1458 offset += 4+tvb_get_letohl(tvb, offset);
1459 proto_tree_add_uint(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1462 else if (check_slsk_format(tvb, offset, "iss")) {
1463 /* Client-to-Client */
1464 message_type = "Queue Failed";
1465 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1466 "Message Type: %s (Code: %02d)", message_type, msg_code);
1468 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1469 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1470 offset += 4+tvb_get_letohl(tvb, offset);
1471 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1472 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1473 offset += 4+tvb_get_letohl(tvb, offset);
1478 if (check_slsk_format(tvb, offset, "is")) {
1479 /* Client-to-Server: "Add Things I like" */
1480 /* Client-to-Client: "Place In Queue Request" */
1481 message_type = "Add Things I like / Place In Queue Request";
1482 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1483 "Message Type: %s (Code: %02d)", message_type, msg_code);
1485 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1486 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1487 offset += 4+tvb_get_letohl(tvb, offset);
1492 if (check_slsk_format(tvb, offset, "is")) {
1493 /* Client-to-Server */
1494 message_type = "Remove Things I like";
1495 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1496 "Message Type: %s (Code: %02d)", message_type, msg_code);
1498 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1499 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1500 offset += 4+tvb_get_letohl(tvb, offset);
1505 if (check_slsk_format(tvb, offset, "i")) {
1506 /* Client-to-Server */
1507 message_type = "Get Recommendations";
1508 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1509 "Message Type: %s (Code: %02d)", message_type, msg_code);
1512 else if (check_slsk_format(tvb, offset, "ii*")) {
1513 /* Server-to-Client */
1514 message_type = "Get Recommendations Reply";
1515 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1516 "Message Type: %s (Code: %02d)", message_type, msg_code);
1518 i=0; j = tvb_get_letohl(tvb, offset);
1519 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1520 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1523 if (check_slsk_format(tvb, offset, "si*")) {
1526 len = tvb_get_letohl(tvb, offset);
1527 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1528 "String #%d Length: %d", i+1, len);
1529 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1530 "Recommendation #%d: %s", i+1,
1531 tvb_format_text(tvb, offset+4, len));
1533 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1534 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1543 if (check_slsk_format(tvb, offset, "i")) {
1544 /* Client-to-Server */
1545 message_type = "Type 55";
1546 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1547 "Message Type: %s (Code: %02d)", message_type, msg_code);
1553 if (check_slsk_format(tvb, offset, "i")) {
1554 /* Client-to-Server */
1555 message_type = "Get Global Rankings";
1556 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1557 "Message Type: %s (Code: %02d)", message_type, msg_code);
1560 else if (check_slsk_format(tvb, offset, "ii*")) {
1561 /* Server-to-Client */
1562 message_type = "Get Global Rankings Reply";
1563 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1564 "Message Type: %s (Code: %02d)", message_type, msg_code);
1566 i=0; j = tvb_get_letohl(tvb, offset);
1567 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1568 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1571 if (check_slsk_format(tvb, offset, "si*")) {
1574 len = tvb_get_letohl(tvb, offset);
1575 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1576 "String #%d Length: %d", i+1, len);
1577 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1578 "Recommendation #%d: %s", i+1,
1579 tvb_format_text(tvb, offset+4, len));
1581 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1582 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1591 if (check_slsk_format(tvb, offset, "is")) {
1592 /* Client-to-Server */
1593 message_type = "Get User Recommendations";
1594 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1595 "Message Type: %s (Code: %02d)", message_type, msg_code);
1597 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1598 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1599 offset += 4+tvb_get_letohl(tvb, offset);
1601 else if (check_slsk_format(tvb, offset, "isi*")) {
1602 /* Server-to-Client */
1603 message_type = "Get User Recommendations Reply";
1604 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1605 "Message Type: %s (Code: %02d)", message_type, msg_code);
1607 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1608 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1609 offset += 4+tvb_get_letohl(tvb, offset);
1610 i=0; j = tvb_get_letohl(tvb, offset);
1611 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1612 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
1615 if (check_slsk_format(tvb, offset, "s*")) {
1618 len = tvb_get_letohl(tvb, offset);
1619 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1620 "String #%d Length: %d", i+1, len);
1621 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1622 "Recommendation #%d: %s", i+1,
1623 tvb_format_text(tvb, offset+4, len));
1632 if (check_slsk_format(tvb, offset, "isi*")) {
1633 /* Client-to-Server */
1634 message_type = "Admin Command";
1635 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1636 "Message Type: %s (Code: %02d)", message_type, msg_code);
1638 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1639 proto_tree_add_item(slsk_tree, hf_slsk_string, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1640 offset += 4+tvb_get_letohl(tvb, offset);
1641 i=0; j = tvb_get_letohl(tvb, offset);
1642 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1643 "Number of Strings: %d", tvb_get_letohl(tvb, offset));
1646 if (check_slsk_format(tvb, offset, "s*")) {
1649 len = tvb_get_letohl(tvb, offset);
1650 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1651 "String #%d Length: %d", i+1, len);
1652 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1653 "String #%d: %s", i+1,
1654 tvb_format_text(tvb, offset+4, len));
1663 if (check_slsk_format(tvb, offset, "isii")) {
1664 /* Client-to-Server & Server-to-Client */
1665 message_type = "Place In Line Response";
1666 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1667 "Message Type: %s (Code: %02d)", message_type, msg_code);
1669 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1670 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1671 offset += 4+tvb_get_letohl(tvb, offset);
1672 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1674 proto_tree_add_uint(slsk_tree, hf_slsk_place_in_queue, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1680 if (check_slsk_format(tvb, offset, "is")) {
1681 /* Server-to-Client */
1682 message_type = "Room Added";
1683 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1684 "Message Type: %s (Code: %02d)", message_type, msg_code);
1686 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1687 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1688 offset += 4+tvb_get_letohl(tvb, offset);
1693 if (check_slsk_format(tvb, offset, "is")) {
1694 /* Server-to-Client */
1695 message_type = "Room Removed";
1696 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1697 "Message Type: %s (Code: %02d)", message_type, msg_code);
1699 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1700 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1701 offset += 4+tvb_get_letohl(tvb, offset);
1706 if (check_slsk_format(tvb, offset, "i")) {
1707 /* Client-to-Server */
1708 message_type = "Room List Request";
1709 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1710 "Message Type: %s (Code: %02d)", message_type, msg_code);
1713 else if (check_slsk_format(tvb, offset, "ii*")) {
1714 /* Server-to-Client */
1715 message_type = "Room List";
1716 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1717 "Message Type: %s (Code: %02d)", message_type, msg_code);
1719 i=0; j = tvb_get_letohl(tvb, offset);
1720 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1723 if (check_slsk_format(tvb, offset, "s*")) {
1726 len = tvb_get_letohl(tvb, offset);
1727 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1728 "String #%d Length: %d", i+1, len);
1729 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1730 "Room #%d: %s", i+1,
1731 tvb_format_text(tvb, offset+4, len));
1736 if (check_slsk_format(tvb, offset, "i*")) {
1738 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_rooms, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1741 if (check_slsk_format(tvb, offset, "i*")) {
1742 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1743 "Users in Room #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1753 if (check_slsk_format(tvb, offset, "isissiii")) {
1754 /* Server-to-Client */
1755 message_type = "Exact File Search";
1756 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1757 "Message Type: %s (Code: %02d)", message_type, msg_code);
1759 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1760 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1761 offset += 4+tvb_get_letohl(tvb, offset);
1762 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1764 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1765 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1766 offset += 4+tvb_get_letohl(tvb, offset);
1767 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1768 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1769 offset += 4+tvb_get_letohl(tvb, offset);
1770 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 16, 0,
1774 else if (check_slsk_format(tvb, offset, "iissiiib")) {
1775 /* Client-to-Server */
1776 message_type = "Exact File Search";
1777 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1778 "Message Type: %s (Code: %02d)", message_type, msg_code);
1780 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1782 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1783 proto_tree_add_item(slsk_tree, hf_slsk_filename, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1784 offset += 4+tvb_get_letohl(tvb, offset);
1785 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1786 proto_tree_add_item(slsk_tree, hf_slsk_directory, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1787 offset += 4+tvb_get_letohl(tvb, offset);
1788 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 13, 0,
1795 if (check_slsk_format(tvb, offset, "is")) {
1796 /* Server-to-Client */
1797 message_type = "Admin Message";
1798 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1799 "Message Type: %s (Code: %02d)", message_type, msg_code);
1801 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1802 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1803 offset += 4+tvb_get_letohl(tvb, offset);
1808 if (check_slsk_format(tvb, offset, "i")) {
1809 /* Client-to-Server */
1810 message_type = "Global User List Request";
1811 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1812 "Message Type: %s (Code: %02d)", message_type, msg_code);
1815 else if (check_slsk_format(tvb, offset, "isi*")) { /* same as case 14 */
1816 /* Server-to-Client */
1817 message_type = "Global User List";
1818 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1819 "Message Type: %s (Code: %02d)", message_type, msg_code);
1821 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1822 proto_tree_add_item(slsk_tree, hf_slsk_room, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1823 offset += 4+tvb_get_letohl(tvb, offset);
1824 i=0; j = tvb_get_letohl(tvb, offset);
1825 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1828 if (check_slsk_format(tvb, offset, "s*")) {
1831 len = tvb_get_letohl(tvb, offset);
1832 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1833 "String #%d Length: %d", i+1, len);
1834 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1835 "User #%d: %s", i+1,
1836 tvb_format_text(tvb, offset+4, len));
1841 if (check_slsk_format(tvb, offset, "i*")) {
1842 i=0; j = tvb_get_letohl(tvb, offset);
1843 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, j);
1846 if (check_slsk_format(tvb, offset, "i*")) {
1847 proto_tree_add_uint_format(slsk_tree, hf_slsk_status_code, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1848 "Status of User #%d: %s (Code: %d)", i+1, val_to_str(tvb_get_letohl(tvb, offset), slsk_status_codes, "Unknown"), tvb_get_letohl(tvb, offset));
1854 if (check_slsk_format(tvb, offset, "i*")) {
1855 i=0; j = tvb_get_letohl(tvb, offset);
1856 proto_tree_add_uint(slsk_tree, hf_slsk_users_in_room, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1859 if (check_slsk_format(tvb, offset, "iiiii*")) {
1860 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1861 "Average Speed of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1863 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1864 "Downloadnum of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1866 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1867 "Something of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1869 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1870 "Files of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1872 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1873 "Folders of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1879 if (check_slsk_format(tvb, offset, "i*")) {
1880 i=0; j = tvb_get_letohl(tvb, offset);
1881 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1882 "Number of Slotsfull Records: %d", tvb_get_letohl(tvb, offset));
1885 if (check_slsk_format(tvb, offset, "i*")) {
1886 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1887 "Slots full of User #%d: %d", i+1, tvb_get_letohl(tvb, offset));
1897 if (check_slsk_format(tvb, offset, "isiiiis")) {
1898 message_type = "Tunneled Message";
1899 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1900 "Message Type: %s (Code: %02d)", message_type, msg_code);
1902 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1903 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1904 offset += 4+tvb_get_letohl(tvb, offset);
1905 proto_tree_add_uint(slsk_tree, hf_slsk_code, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1907 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1909 proto_tree_add_ipv4(slsk_tree, hf_slsk_ip, tvb, offset, 4, tvb_get_ntohl(tvb, offset));
1911 proto_tree_add_uint(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1913 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1914 proto_tree_add_item(slsk_tree, hf_slsk_chat_message, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
1915 offset += 4+tvb_get_letohl(tvb, offset);
1920 if (check_slsk_format(tvb, offset, "i")) {
1921 /* Client-to-Server */
1922 message_type = "Privileged User List Request";
1923 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1924 "Message Type: %s (Code: %02d)", message_type, msg_code);
1927 else if (check_slsk_format(tvb, offset, "ii*")) {
1928 /* Server-to-Client */
1929 message_type = "Privileged User List";
1930 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1931 "Message Type: %s (Code: %02d)", message_type, msg_code);
1933 i=0; j = tvb_get_letohl(tvb, offset);
1934 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
1935 "Number of Priviledged Users: %d", tvb_get_letohl(tvb, offset));
1938 if (check_slsk_format(tvb, offset, "s*")) {
1941 len = tvb_get_letohl(tvb, offset);
1942 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
1943 "String #%d Length: %d", i+1, len);
1944 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
1945 "User #%d: %s", i+1,
1946 tvb_format_text(tvb, offset+4, len));
1955 if (check_slsk_format(tvb, offset, "ib")) {
1956 /* Client-to-Server */
1957 message_type = "Get Parent List";
1958 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1959 "Message Type: %s (Code: %02d)", message_type, msg_code);
1961 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
1967 if (check_slsk_format(tvb, offset, "ii")) {
1968 /* Client-to-Server */
1969 message_type = "Type 73";
1970 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1971 "Message Type: %s (Code: %02d)", message_type, msg_code);
1973 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1979 if (check_slsk_format(tvb, offset, "ii")) {
1980 /* Server-to-Client */
1981 message_type = "Parent Min Speed";
1982 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1983 "Message Type: %s (Code: %02d)", message_type, msg_code);
1985 proto_tree_add_uint(slsk_tree, hf_slsk_parent_min_speed, tvb, offset, 4, tvb_get_letohl(tvb, offset));
1991 if (check_slsk_format(tvb, offset, "ii")) {
1992 /* Server-to-Client */
1993 message_type = "Parent Speed Connection Ratio";
1994 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
1995 "Message Type: %s (Code: %02d)", message_type, msg_code);
1997 proto_tree_add_uint(slsk_tree, hf_slsk_parent_speed_connection_ratio, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2003 if (check_slsk_format(tvb, offset, "ii")) {
2004 /* Server-to-Client */
2005 message_type = "Parent Inactivity Before Disconnect";
2006 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2007 "Message Type: %s (Code: %02d)", message_type, msg_code);
2009 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_parent_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2015 if (check_slsk_format(tvb, offset, "ii")) {
2016 /* Server-to-Client */
2017 message_type = "Server Inactivity Before Disconnect";
2018 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2019 "Message Type: %s (Code: %02d)", message_type, msg_code);
2021 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_server_inactivity_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2027 if (check_slsk_format(tvb, offset, "ii")) {
2028 /* Server-to-Client */
2029 message_type = "Nodes In Cache Before Disconnect";
2030 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2031 "Message Type: %s (Code: %02d)", message_type, msg_code);
2033 proto_tree_add_uint(slsk_tree, hf_slsk_nodes_in_cache_before_disconnect, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2039 if (check_slsk_format(tvb, offset, "ii")) {
2040 /* Server-to-Client */
2041 message_type = "Seconds Before Ping Children";
2042 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2043 "Message Type: %s (Code: %02d)", message_type, msg_code);
2045 proto_tree_add_uint(slsk_tree, hf_slsk_seconds_before_ping_children, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2051 if (check_slsk_format(tvb, offset, "is")) {
2052 /* Server-to-Client */
2053 message_type = "Add To Privileged";
2054 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2055 "Message Type: %s (Code: %02d)", message_type, msg_code);
2057 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2058 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2059 offset += 4+tvb_get_letohl(tvb, offset);
2064 if (check_slsk_format(tvb, offset, "i")) {
2065 /* Client-to-Server */
2066 message_type = "Check Privileges";
2067 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2068 "Message Type: %s (Code: %02d)", message_type, msg_code);
2071 else if (check_slsk_format(tvb, offset, "ii")) {
2072 /* Server-to-Client */
2073 message_type = "Check Privileges Reply";
2074 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2075 "Message Type: %s (Code: %02d)", message_type, msg_code);
2077 proto_tree_add_uint(slsk_tree, hf_slsk_number_of_days, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2083 if (check_slsk_format(tvb, offset, "ibisis")) {
2084 /* Server-to-Client */
2085 message_type = "Embedded Message";
2086 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2087 "Message Type: %s (Code: %02d)", message_type, msg_code);
2089 if ( tvb_get_guint8(tvb, offset) == 3 ){
2090 /* Client-to-Client */
2091 message_type = "Distributed Search";
2092 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2093 "Embedded Message Type: %s (Byte: %d)", message_type, 3);
2095 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2097 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2098 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2099 offset += 4+tvb_get_letohl(tvb, offset);
2100 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2102 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2103 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2104 offset += 4+tvb_get_letohl(tvb, offset);
2110 if (check_slsk_format(tvb, offset, "ib")) {
2111 /* Client-to-Server */
2112 message_type = "Become Parent";
2113 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2114 "Message Type: %s (Code: %02d)", message_type, msg_code);
2116 proto_tree_add_uint(slsk_tree, hf_slsk_byte, tvb, offset, 1, tvb_get_guint8(tvb, offset));
2122 if (check_slsk_format(tvb, offset, "ii*")) {
2123 /* Server-to-Client */
2124 message_type = "Random Parent Addresses";
2125 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2126 "Message Type: %s (Code: %02d)", message_type, msg_code);
2128 i=0; j = tvb_get_letohl(tvb, offset);
2129 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2130 "Number of Parent Addresses: %d", tvb_get_letohl(tvb, offset));
2133 if (check_slsk_format(tvb, offset, "sii*")) {
2136 len = tvb_get_letohl(tvb, offset);
2137 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2138 "String #%d Length: %d", i+1, len);
2139 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2140 "User #%d: %s", i+1,
2141 tvb_format_text(tvb, offset+4, len));
2143 proto_tree_add_item(slsk_tree, hf_slsk_ip, tvb, offset, 4, FALSE);
2145 proto_tree_add_uint_format(slsk_tree, hf_slsk_port, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2146 "Port Number #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2155 if (check_slsk_format(tvb, offset, "iis")) {
2156 /* Server-to-Client */
2157 message_type = "Send Wishlist Entry";
2158 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2159 "Message Type: %s (Code: %02d)", message_type, msg_code);
2161 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2163 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2164 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2165 offset += 4+tvb_get_letohl(tvb, offset);
2170 if (check_slsk_format(tvb, offset, "ii")) {
2171 /* Server-to-Client */
2172 message_type = "Type 104";
2173 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2174 "Message Type: %s (Code: %02d)", message_type, msg_code);
2176 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2182 if (check_slsk_format(tvb, offset, "i")) {
2183 /* Client-to-Server */
2184 message_type = "Get Similar Users";
2185 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2186 "Message Type: %s (Code: %02d)", message_type, msg_code);
2189 else if (check_slsk_format(tvb, offset, "ii*")) {
2190 /* Server-to-Client */
2191 message_type = "Get Similar Users Reply";
2192 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2193 "Message Type: %s (Code: %02d)", message_type, msg_code);
2195 i=0; j = tvb_get_letohl(tvb, offset);
2196 proto_tree_add_uint_format(slsk_tree, hf_slsk_number_of_users, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2197 "Number of Users: %d", tvb_get_letohl(tvb, offset));
2200 if (check_slsk_format(tvb, offset, "si*")) {
2203 len = tvb_get_letohl(tvb, offset);
2204 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2205 "String #%d Length: %d", i+1, len);
2206 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2207 "User #%d: %s", i+1,
2208 tvb_format_text(tvb, offset+4, len));
2210 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2211 "Same Recommendations #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2220 if (check_slsk_format(tvb, offset, "is")) {
2221 /* Client-to-Server */
2222 message_type = "Get Recommendations for Item";
2223 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2224 "Message Type: %s (Code: %02d)", message_type, msg_code);
2226 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2227 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2228 offset += 4+tvb_get_letohl(tvb, offset);
2230 else if (check_slsk_format(tvb, offset, "isi*")) {
2231 /* Server-to-Client */
2232 message_type = "Get Recommendations for Item Reply";
2233 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2234 "Message Type: %s (Code: %02d)", message_type, msg_code);
2236 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2237 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2238 offset += 4+tvb_get_letohl(tvb, offset);
2239 i=0; j = tvb_get_letohl(tvb, offset);
2240 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2241 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2244 if (check_slsk_format(tvb, offset, "si*")) {
2247 len = tvb_get_letohl(tvb, offset);
2248 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2249 "String #%d Length: %d", i+1, len);
2250 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2251 "Recommendation #%d: %s", i+1,
2252 tvb_format_text(tvb, offset+4, len));
2254 proto_tree_add_uint_format(slsk_tree, hf_slsk_ranking, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2255 "Ranking #%d: %d", i+1, tvb_get_letohl(tvb, offset));
2264 if (check_slsk_format(tvb, offset, "is")) {
2265 /* Client-to-Server */
2266 message_type = "Get Similar Users for Item";
2267 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2268 "Message Type: %s (Code: %02d)", message_type, msg_code);
2270 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2271 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2272 offset += 4+tvb_get_letohl(tvb, offset);
2274 else if (check_slsk_format(tvb, offset, "isi*")) {
2275 /* Server-to-Client */
2276 message_type = "Get Similar Users for Item Reply";
2277 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2278 "Message Type: %s (Code: %02d)", message_type, msg_code);
2280 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2281 proto_tree_add_item(slsk_tree, hf_slsk_recommendation, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2282 offset += 4+tvb_get_letohl(tvb, offset);
2283 i=0; j = tvb_get_letohl(tvb, offset);
2284 proto_tree_add_uint_format(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset),
2285 "Number of Recommendations: %d", tvb_get_letohl(tvb, offset));
2288 if (check_slsk_format(tvb, offset, "s*")) {
2291 len = tvb_get_letohl(tvb, offset);
2292 proto_tree_add_uint_format(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len,
2293 "String #%d Length: %d", i+1, len);
2294 proto_tree_add_text(slsk_tree, tvb, offset+4, len,
2295 "Username #%d: %s", i+1,
2296 tvb_format_text(tvb, offset+4, len));
2305 if (check_slsk_format(tvb, offset, "iis")) {
2306 /* Client-to-Server */
2307 message_type = "Can't Connect To Peer";
2308 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2309 "Message Type: %s (Code: %02d)", message_type, msg_code);
2311 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2313 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2314 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2315 offset += 4+tvb_get_letohl(tvb, offset);
2317 else if (check_slsk_format(tvb, offset, "ii")) {
2318 /* Server-to-Client */
2319 message_type = "Can't Connect To Peer";
2320 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2321 "Message Type: %s (Code: %02d)", message_type, msg_code);
2323 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2329 if (check_slsk_format(tvb, offset, "bisis")) {
2330 if ( tvb_get_guint8(tvb, offset) == 3 ){
2331 /* Client-to-Client */
2332 message_type = "Distributed Search";
2333 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2334 "Message Type: %s (Byte: %d)", message_type, 3);
2336 proto_tree_add_uint(slsk_tree, hf_slsk_integer, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2338 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2339 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2340 offset += 4+tvb_get_letohl(tvb, offset);
2341 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2343 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2344 proto_tree_add_item(slsk_tree, hf_slsk_search_text, tvb, offset+4, tvb_get_letohl(tvb, offset), FALSE);
2345 offset += 4+tvb_get_letohl(tvb, offset);
2348 else if (check_slsk_format(tvb, offset, "bssi")) {
2349 if ( tvb_get_guint8(tvb, offset) == 1 ){
2350 /* Client-to-Client */
2353 message_type = "Peer Init";
2354 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2355 "Message Type: %s (Byte: %d)", message_type, 1);
2357 len = tvb_get_letohl(tvb, offset);
2358 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2359 proto_tree_add_item(slsk_tree, hf_slsk_username, tvb, offset+4, len, FALSE);
2361 len = tvb_get_letohl(tvb, offset);
2362 proto_tree_add_uint(slsk_tree, hf_slsk_string_length, tvb, offset, 4, len);
2363 str = tvb_get_ephemeral_string(tvb, offset+4, len);
2364 proto_tree_add_string_format(slsk_tree, hf_slsk_connection_type, tvb, offset+4, len, str,
2365 "Connection Type: %s (Char: %s)", connection_type(str),
2366 format_text(str, len));
2368 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2372 else if (check_slsk_format(tvb, offset, "bi")) {
2373 if ( tvb_get_guint8(tvb, offset) == 0 ){
2374 /* Client-to-Client */
2375 message_type = "Pierce Fw";
2376 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 1, msg_code,
2377 "Message Type: %s (Byte: %d)", message_type, 0);
2379 proto_tree_add_uint(slsk_tree, hf_slsk_token, tvb, offset, 4, tvb_get_letohl(tvb, offset));
2384 message_type = "Unknown";
2385 proto_tree_add_uint_format(slsk_tree, hf_slsk_message_code, tvb, offset, 4, msg_code,
2386 "Message Type: %s (Code: %02d)", message_type, msg_code);
2399 static void dissect_slsk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2401 tcp_dissect_pdus(tvb, pinfo, tree, slsk_desegment, 4, get_slsk_pdu_len, dissect_slsk_pdu);
2406 /* Register the protocol with Wireshark */
2409 proto_register_slsk(void)
2412 /* Setup list of header fields */
2413 static hf_register_info hf[] = {
2415 { "Integer", "slsk.integer",
2416 FT_UINT32, BASE_DEC, NULL, 0, "Integer", HFILL } },
2418 { "String", "slsk.string",
2419 FT_STRING, BASE_NONE, NULL, 0, "String", HFILL } },
2421 { "Byte", "slsk.byte",
2422 FT_UINT8, BASE_DEC, NULL, 0, "Byte", HFILL } },
2423 { &hf_slsk_message_length,
2424 { "Message Length", "slsk.message.length",
2425 FT_UINT32, BASE_DEC, NULL, 0, "Message Length", HFILL } },
2426 { &hf_slsk_message_code,
2427 { "Message Code", "slsk.message.code",
2428 FT_UINT32, BASE_DEC, NULL, 0, "Message Code", HFILL } },
2429 { &hf_slsk_client_ip,
2430 { "Client IP", "slsk.server.ip",
2431 FT_IPv4, BASE_DEC, NULL, 0, "Client IP Address", HFILL } },
2432 { &hf_slsk_server_ip,
2433 { "SoulSeek Server IP", "slsk.server.ip",
2434 FT_UINT32, BASE_DEC, NULL, 0, "SoulSeek Server IP", HFILL } },
2435 { &hf_slsk_string_length,
2436 { "String Length", "slsk.string.length",
2437 FT_UINT32, BASE_DEC, NULL, 0, "String Length", HFILL } },
2438 { &hf_slsk_username,
2439 { "Username", "slsk.username",
2440 FT_STRING, BASE_NONE, NULL, 0, "Username", HFILL } },
2441 { &hf_slsk_password,
2442 { "Password", "slsk.password",
2443 FT_STRING, BASE_NONE, NULL, 0, "Password", HFILL } },
2445 { "Version", "slsk.version",
2446 FT_UINT32, BASE_DEC, NULL, 0, "Version", HFILL } },
2447 { &hf_slsk_login_successful,
2448 { "Login successful", "slsk.login.successful",
2449 FT_UINT8, BASE_DEC, NULL, 0, "Login Successful", HFILL } },
2450 { &hf_slsk_login_message,
2451 { "Login Message", "slsk.login.message",
2452 FT_STRING, BASE_NONE, NULL, 0, "Login Message", HFILL } },
2454 { "Port Number", "slsk.port.number",
2455 FT_UINT32, BASE_DEC, NULL, 0, "Port Number", HFILL } },
2457 { "IP Address", "slsk.ip.address",
2458 FT_IPv4, BASE_DEC, NULL, 0, "IP Address", HFILL } },
2459 { &hf_slsk_user_exists,
2460 { "user exists", "slsk.user.exists",
2461 FT_UINT8, BASE_DEC, NULL, 0, "User exists", HFILL } },
2462 { &hf_slsk_status_code,
2463 { "Status Code", "slsk.status.code",
2464 FT_UINT32, BASE_DEC, NULL, 0, "Status Code", HFILL } },
2466 { "Room", "slsk.room",
2467 FT_STRING, BASE_NONE, NULL, 0, "Room", HFILL } },
2468 { &hf_slsk_chat_message,
2469 { "Chat Message", "slsk.chat.message",
2470 FT_STRING, BASE_NONE, NULL, 0, "Chat Message", HFILL } },
2471 { &hf_slsk_users_in_room,
2472 { "Users in Room", "slsk.room.users",
2473 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users in Room", HFILL } },
2475 { "Token", "slsk.token",
2476 FT_UINT32, BASE_DEC, NULL, 0, "Token", HFILL } },
2477 { &hf_slsk_connection_type,
2478 { "Connection Type", "slsk.connection.type",
2479 FT_STRING, BASE_NONE, NULL, 0, "Connection Type", HFILL } },
2480 { &hf_slsk_chat_message_id,
2481 { "Chat Message ID", "slsk.chat.message.id",
2482 FT_UINT32, BASE_DEC, NULL, 0, "Chat Message ID", HFILL } },
2483 { &hf_slsk_timestamp,
2484 { "Timestamp", "slsk.timestamp",
2485 FT_UINT32, BASE_DEC, NULL, 0, "Timestamp", HFILL } },
2486 { &hf_slsk_search_text,
2487 { "Search Text", "slsk.search.text",
2488 FT_STRING, BASE_NONE, NULL, 0, "Search Text", HFILL } },
2489 { &hf_slsk_folder_count,
2490 { "Folder Count", "slsk.folder.count",
2491 FT_UINT32, BASE_DEC, NULL, 0, "Folder Count", HFILL } },
2492 { &hf_slsk_file_count,
2493 { "File Count", "slsk.file.count",
2494 FT_UINT32, BASE_DEC, NULL, 0, "File Count", HFILL } },
2495 { &hf_slsk_average_speed,
2496 { "Average Speed", "slsk.average.speed",
2497 FT_UINT32, BASE_DEC, NULL, 0, "Average Speed", HFILL } },
2498 { &hf_slsk_download_number,
2499 { "Download Number", "slsk.download.number",
2500 FT_UINT32, BASE_DEC, NULL, 0, "Download Number", HFILL } },
2502 { "Files", "slsk.files",
2503 FT_UINT32, BASE_DEC, NULL, 0, "Files", HFILL } },
2504 { &hf_slsk_directories,
2505 { "Directories", "slsk.directories",
2506 FT_UINT32, BASE_DEC, NULL, 0, "Directories", HFILL } },
2507 { &hf_slsk_slotsfull,
2508 { "Slots full", "slsk.slots.full",
2509 FT_UINT32, BASE_DEC, NULL, 0, "Upload Slots Full", HFILL } },
2510 { &hf_slsk_place_in_queue,
2511 { "Place in Queue", "slsk.queue.place",
2512 FT_UINT32, BASE_DEC, NULL, 0, "Place in Queue", HFILL } },
2513 { &hf_slsk_number_of_rooms,
2514 { "Number of Rooms", "slsk.room.count",
2515 FT_UINT32, BASE_DEC, NULL, 0, "Number of Rooms", HFILL } },
2516 { &hf_slsk_filename,
2517 { "Filename", "slsk.filename",
2518 FT_STRING, BASE_NONE, NULL, 0, "Filename", HFILL } },
2519 { &hf_slsk_directory,
2520 { "Directory", "slsk.directory",
2521 FT_STRING, BASE_NONE, NULL, 0, "Directory", HFILL } },
2523 { "Size", "slsk.size",
2524 FT_UINT32, BASE_DEC, NULL, 0, "File Size", HFILL } },
2525 { &hf_slsk_checksum,
2526 { "Checksum", "slsk.checksum",
2527 FT_UINT32, BASE_DEC, NULL, 0, "Checksum", HFILL } },
2529 { "Code", "slsk.code",
2530 FT_UINT32, BASE_DEC, NULL, 0, "Code", HFILL } },
2531 { &hf_slsk_number_of_users,
2532 { "Number of Users", "slsk.user.count",
2533 FT_UINT32, BASE_DEC, NULL, 0, "Number of Users", HFILL } },
2534 { &hf_slsk_number_of_days,
2535 { "Number of Days", "slsk.day.count",
2536 FT_UINT32, BASE_DEC, NULL, 0, "Number of Days", HFILL } },
2537 { &hf_slsk_transfer_direction,
2538 { "Transfer Direction", "slsk.transfer.direction",
2539 FT_UINT32, BASE_DEC, NULL, 0, "Transfer Direction", HFILL } },
2540 { &hf_slsk_user_description,
2541 { "User Description", "slsk.user.description",
2542 FT_STRING, BASE_NONE, NULL, 0, "User Description", HFILL } },
2543 { &hf_slsk_picture_exists,
2544 { "Picture exists", "slsk.user.picture.exists",
2545 FT_UINT8, BASE_DEC, NULL, 0, "User has a picture", HFILL } },
2547 { "Picture", "slsk.user.picture",
2548 FT_STRING, BASE_NONE, NULL, 0, "User Picture", HFILL } },
2549 { &hf_slsk_user_uploads,
2550 { "User uploads", "slsk.uploads.user",
2551 FT_UINT32, BASE_DEC, NULL, 0, "User uploads", HFILL } },
2552 { &hf_slsk_total_uploads,
2553 { "Total uploads allowed", "slsk.uploads.total",
2554 FT_UINT32, BASE_DEC, NULL, 0, "Total uploads allowed", HFILL } },
2555 { &hf_slsk_queued_uploads,
2556 { "Queued uploads", "slsk.uploads.queued",
2557 FT_UINT32, BASE_DEC, NULL, 0, "Queued uploads", HFILL } },
2558 { &hf_slsk_slots_available,
2559 { "Upload Slots available", "slsk.uploads.available",
2560 FT_UINT8, BASE_DEC, NULL, 0, "Upload Slots available", HFILL } },
2562 { "Download allowed", "slsk.user.allowed",
2563 FT_UINT8, BASE_DEC, NULL, 0, "allowed", HFILL } },
2564 { &hf_slsk_compr_packet,
2565 { "[zlib compressed packet]", "slsk.compr.packet",
2566 FT_NONE, BASE_NONE, NULL, 0, "zlib compressed packet", HFILL } },
2567 { &hf_slsk_parent_min_speed,
2568 { "Parent Min Speed", "slsk.parent.min.speed",
2569 FT_UINT32, BASE_DEC, NULL, 0, "Parent Min Speed", HFILL } },
2570 { &hf_slsk_parent_speed_connection_ratio,
2571 { "Parent Speed Connection Ratio", "slsk.parent.speed.connection.ratio",
2572 FT_UINT32, BASE_DEC, NULL, 0, "Parent Speed Connection Ratio", HFILL } },
2573 { &hf_slsk_seconds_parent_inactivity_before_disconnect,
2574 { "Seconds Parent Inactivity Before Disconnect", "slsk.seconds.parent.inactivity.before.disconnect",
2575 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Parent Inactivity Before Disconnect", HFILL } },
2576 { &hf_slsk_seconds_server_inactivity_before_disconnect,
2577 { "Seconds Server Inactivity Before Disconnect", "slsk.seconds.server.inactivity.before.disconnect",
2578 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Server Inactivity Before Disconnect", HFILL } },
2579 { &hf_slsk_nodes_in_cache_before_disconnect,
2580 { "Nodes In Cache Before Disconnect", "slsk.nodes.in.cache.before.disconnect",
2581 FT_UINT32, BASE_DEC, NULL, 0, "Nodes In Cache Before Disconnect", HFILL } },
2582 { &hf_slsk_seconds_before_ping_children,
2583 { "Seconds Before Ping Children", "slsk.seconds.before.ping.children",
2584 FT_UINT32, BASE_DEC, NULL, 0, "Seconds Before Ping Children", HFILL } },
2585 { &hf_slsk_recommendation,
2586 { "Recommendation", "slsk.recommendation",
2587 FT_STRING, BASE_NONE, NULL, 0, "Recommendation", HFILL } },
2589 { "Ranking", "slsk.ranking",
2590 FT_UINT32, BASE_DEC, NULL, 0, "Ranking", HFILL } },
2593 /* Setup protocol subtree array */
2594 static gint *ett[] = {
2596 &ett_slsk_compr_packet,
2598 module_t *slsk_module;
2600 /* Registers the protocol name and description */
2601 proto_slsk = proto_register_protocol("SoulSeek Protocol", "SoulSeek", "slsk");
2603 /* Required function calls to register the header fields and subtrees used */
2604 proto_register_field_array(proto_slsk, hf, array_length(hf));
2605 proto_register_subtree_array(ett, array_length(ett));
2607 slsk_module = prefs_register_protocol(proto_slsk, NULL);
2609 /* Registers the options in the menu preferences */
2610 prefs_register_bool_preference(slsk_module, "desegment",
2611 "Reassemble SoulSeek messages spanning multiple TCP segments",
2612 "Whether the SoulSeek dissector should reassemble messages spanning multiple TCP segments."
2613 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2616 prefs_register_bool_preference(slsk_module, "decompress",
2617 "Decompress zlib compressed packets inside SoulSeek messages",
2618 "Whether the SoulSeek dissector should decompress all zlib compressed packets inside messages",
2626 proto_reg_handoff_slsk(void)
2628 dissector_handle_t slsk_handle;
2630 slsk_handle = create_dissector_handle(dissect_slsk, proto_slsk);
2631 dissector_add("tcp.port", TCP_PORT_SLSK_1, slsk_handle);
2632 dissector_add("tcp.port", TCP_PORT_SLSK_2, slsk_handle);
2633 dissector_add("tcp.port", TCP_PORT_SLSK_3, slsk_handle);