Coverage Report

Created: 2026-06-30 07:22

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