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