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-gadu-gadu.c
Line
Count
Source
1
/* packet-gadu-gadu.c
2
 * Routines for Gadu-Gadu dissection
3
 * Copyright 2011,2012, Jakub Zawadzki <darkjames-ws@darkjames.pl>
4
 *
5
 * Protocol documentation available at https://libgadu.github.io/index.en.html
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include <epan/prefs.h>
17
#include "packet-tcp.h"
18
19
void proto_register_gadu_gadu(void);
20
void proto_reg_handoff_gadu_gadu(void);
21
22
14
#define TCP_PORT_GADU_GADU 8074  /* assigned by IANA */
23
24
/* desegmentation of Gadu-Gadu over TCP */
25
static bool gadu_gadu_desegment = true;
26
27
static dissector_handle_t gadu_gadu_handle;
28
29
static int proto_gadu_gadu;
30
31
static int hf_dcc_filename;
32
static int hf_dcc_id;
33
static int hf_dcc_type;
34
static int hf_dcc_uin_from;
35
static int hf_dcc_uin_to;
36
static int hf_gadu_gadu_contact_type;
37
static int hf_gadu_gadu_contact_uin;
38
static int hf_gadu_gadu_contact_uin_str;
39
static int hf_gadu_gadu_data;
40
static int hf_gadu_gadu_header_length;
41
static int hf_gadu_gadu_header_type_recv;
42
static int hf_gadu_gadu_header_type_send;
43
static int hf_gadu_gadu_login80_lang;
44
static int hf_gadu_gadu_login_hash;
45
static int hf_gadu_gadu_login_hash_type;
46
static int hf_gadu_gadu_login_local_ip;
47
static int hf_gadu_gadu_login_local_port;
48
static int hf_gadu_gadu_login_protocol;
49
static int hf_gadu_gadu_login_status;
50
static int hf_gadu_gadu_login_uin;
51
static int hf_gadu_gadu_login_version;
52
static int hf_gadu_gadu_msg80_offset_attr;
53
static int hf_gadu_gadu_msg80_offset_plain;
54
static int hf_gadu_gadu_msg_ack_recipient;
55
static int hf_gadu_gadu_msg_ack_seq;
56
static int hf_gadu_gadu_msg_ack_status;
57
static int hf_gadu_gadu_msg_class;
58
static int hf_gadu_gadu_msg_recipient;
59
static int hf_gadu_gadu_msg_sender;
60
static int hf_gadu_gadu_msg_seq;
61
static int hf_gadu_gadu_msg_text;
62
static int hf_gadu_gadu_msg_time;
63
static int hf_gadu_gadu_msg_uin;
64
static int hf_gadu_gadu_new_status_desc;
65
static int hf_gadu_gadu_new_status_status;
66
static int hf_gadu_gadu_pubdir_reply_seq;
67
static int hf_gadu_gadu_pubdir_reply_str;
68
static int hf_gadu_gadu_pubdir_reply_type;
69
static int hf_gadu_gadu_pubdir_request_seq;
70
static int hf_gadu_gadu_pubdir_request_str;
71
static int hf_gadu_gadu_pubdir_request_type;
72
static int hf_gadu_gadu_status_descr;
73
static int hf_gadu_gadu_status_img_size;
74
static int hf_gadu_gadu_status_ip;
75
static int hf_gadu_gadu_status_port;
76
static int hf_gadu_gadu_status_status;
77
static int hf_gadu_gadu_status_uin;
78
static int hf_gadu_gadu_status_version;
79
static int hf_gadu_gadu_typing_notify_type;
80
static int hf_gadu_gadu_typing_notify_uin;
81
static int hf_gadu_gadu_userdata_attr_name;
82
static int hf_gadu_gadu_userdata_attr_type;
83
static int hf_gadu_gadu_userdata_attr_value;
84
static int hf_gadu_gadu_userdata_uin;
85
static int hf_gadu_gadu_userlist;
86
static int hf_gadu_gadu_userlist_format;
87
static int hf_gadu_gadu_userlist_reply_type;
88
static int hf_gadu_gadu_userlist_request_type;
89
static int hf_gadu_gadu_userlist_version;
90
static int hf_gadu_gadu_welcome_seed;
91
92
static int ett_gadu_gadu;
93
static int ett_gadu_gadu_contact;
94
95
0
#define GG_ERA_OMNIX_MASK 0x04000000
96
0
#define GG_HAS_AUDIO_MASK 0x40000000
97
98
0
#define GG_WELCOME                  0x01
99
0
#define GG_STATUS                   0x02
100
0
#define GG_LOGIN_OK                 0x03
101
0
#define GG_SEND_MSG_ACK             0x05
102
#define GG_PONG                     0x07
103
#define GG_PING                     0x08
104
0
#define GG_LOGIN_FAILED             0x09
105
0
#define GG_RECV_MSG                 0x0a
106
0
#define GG_DISCONNECTING            0x0b
107
0
#define GG_NOTIFY_REPLY             0x0c
108
0
#define GG_DISCONNECT_ACK           0x0d
109
0
#define GG_PUBDIR50_REPLY           0x0e
110
0
#define GG_STATUS60                 0x0f
111
0
#define GG_USERLIST_REPLY           0x10
112
0
#define GG_NOTIFY_REPLY60           0x11
113
0
#define GG_NEED_EMAIL               0x14
114
0
#define GG_LOGIN_HASH_TYPE_INVALID  0x16
115
0
#define GG_STATUS77                 0x17
116
0
#define GG_NOTIFY_REPLY77           0x18
117
#define GG_DCC7_INFO                0x1f
118
#define GG_DCC7_NEW                 0x20
119
#define GG_DCC7_ACCEPT              0x21
120
#define GG_DCC7_REJECT              0x22
121
1
#define GG_DCC7_ID_REPLY            0x23
122
0
#define GG_DCC7_ID_ABORTED          0x25
123
0
#define GG_XML_EVENT                0x27
124
0
#define GG_STATUS80BETA             0x2a
125
0
#define GG_NOTIFY_REPLY80BETA       0x2b
126
0
#define GG_XML_ACTION               0x2c
127
0
#define GG_RECV_MSG80               0x2e
128
0
#define GG_USERLIST_REPLY80         0x30
129
0
#define GG_LOGIN_OK80               0x35
130
0
#define GG_STATUS80                 0x36
131
0
#define GG_NOTIFY_REPLY80           0x37
132
0
#define GG_USERLIST100_REPLY        0x41
133
0
#define GG_LOGIN80_FAILED           0x43
134
0
#define GG_USER_DATA                0x44
135
#define GG_TYPING_NOTIFY            0x59
136
0
#define GG_OWN_MESSAGE              0x5A
137
0
#define GG_OWN_RESOURCE_INFO        0x5B
138
0
#define GG_USERLIST100_VERSION      0x5C
139
140
141
#define GG_TYPE_VS(x) { x, #x }
142
143
/* original (GG_*) names likes in documentation (https://libgadu.github.io/protocol/#ch1.16) */
144
static const value_string gadu_gadu_packets_type_recv[] = {
145
  GG_TYPE_VS(GG_WELCOME),
146
  GG_TYPE_VS(GG_STATUS),
147
  GG_TYPE_VS(GG_LOGIN_OK),
148
  GG_TYPE_VS(GG_SEND_MSG_ACK),
149
  GG_TYPE_VS(GG_PONG),
150
  GG_TYPE_VS(GG_PING),
151
  GG_TYPE_VS(GG_LOGIN_FAILED),
152
  GG_TYPE_VS(GG_RECV_MSG),
153
  GG_TYPE_VS(GG_DISCONNECTING),
154
  GG_TYPE_VS(GG_NOTIFY_REPLY),
155
  GG_TYPE_VS(GG_DISCONNECT_ACK),
156
  GG_TYPE_VS(GG_PUBDIR50_REPLY),
157
  GG_TYPE_VS(GG_STATUS60),
158
  GG_TYPE_VS(GG_USERLIST_REPLY),
159
  GG_TYPE_VS(GG_NOTIFY_REPLY60),
160
  GG_TYPE_VS(GG_NEED_EMAIL),
161
  GG_TYPE_VS(GG_LOGIN_HASH_TYPE_INVALID),
162
  GG_TYPE_VS(GG_STATUS77),
163
  GG_TYPE_VS(GG_NOTIFY_REPLY77),
164
  GG_TYPE_VS(GG_DCC7_INFO),
165
  GG_TYPE_VS(GG_DCC7_NEW),
166
  GG_TYPE_VS(GG_DCC7_ACCEPT),
167
  GG_TYPE_VS(GG_DCC7_REJECT),
168
  GG_TYPE_VS(GG_DCC7_ID_REPLY),
169
  GG_TYPE_VS(GG_DCC7_ID_ABORTED),
170
  GG_TYPE_VS(GG_XML_EVENT),
171
  GG_TYPE_VS(GG_STATUS80BETA),
172
  GG_TYPE_VS(GG_NOTIFY_REPLY80BETA),
173
  GG_TYPE_VS(GG_XML_ACTION),
174
  GG_TYPE_VS(GG_RECV_MSG80),
175
  GG_TYPE_VS(GG_USERLIST_REPLY80),
176
  GG_TYPE_VS(GG_LOGIN_OK80),
177
  GG_TYPE_VS(GG_STATUS80),
178
  GG_TYPE_VS(GG_NOTIFY_REPLY80),
179
  GG_TYPE_VS(GG_USERLIST100_REPLY),
180
  GG_TYPE_VS(GG_LOGIN80_FAILED),
181
  GG_TYPE_VS(GG_USER_DATA),
182
  GG_TYPE_VS(GG_TYPING_NOTIFY),
183
  GG_TYPE_VS(GG_OWN_MESSAGE),
184
  GG_TYPE_VS(GG_OWN_RESOURCE_INFO),
185
  GG_TYPE_VS(GG_USERLIST100_VERSION),
186
  { 0, NULL }
187
};
188
189
0
#define GG_NEW_STATUS           0x02
190
0
#define GG_PONG                 0x07
191
0
#define GG_PING                 0x08
192
0
#define GG_SEND_MSG             0x0b
193
0
#define GG_LOGIN                0x0c
194
0
#define GG_ADD_NOTIFY           0x0d
195
0
#define GG_REMOVE_NOTIFY        0x0e
196
0
#define GG_NOTIFY_FIRST         0x0f
197
0
#define GG_NOTIFY_LAST          0x10
198
0
#define GG_LIST_EMPTY           0x12
199
0
#define GG_LOGIN_EXT            0x13
200
0
#define GG_PUBDIR50_REQUEST     0x14
201
0
#define GG_LOGIN60              0x15
202
0
#define GG_USERLIST_REQUEST     0x16
203
0
#define GG_LOGIN70              0x19
204
0
#define GG_DCC7_INFO            0x1f
205
0
#define GG_DCC7_NEW             0x20
206
0
#define GG_DCC7_ACCEPT          0x21
207
0
#define GG_DCC7_REJECT          0x22
208
0
#define GG_DCC7_ID_REQUEST      0x23
209
0
#define GG_DCC7_ID_DUNNO1       0x24
210
0
#define GG_DCC7_ID_ABORT        0x25
211
0
#define GG_NEW_STATUS80BETA     0x28
212
0
#define GG_LOGIN80BETA          0x29
213
0
#define GG_SEND_MSG80           0x2d
214
0
#define GG_USERLIST_REQUEST80   0x2f
215
0
#define GG_LOGIN80              0x31
216
0
#define GG_NEW_STATUS80         0x38
217
1
#define GG_USERLIST100_REQUEST  0x40
218
0
#define GG_RECV_MSG_ACK         0x46
219
0
#define GG_TYPING_NOTIFY        0x59
220
0
#define GG_OWN_DISCONNECT       0x62
221
0
#define GG_NEW_STATUS105        0x63
222
0
#define GG_NOTIFY105            0x78
223
0
#define GG_ADD_NOTIFY105        0x7b
224
0
#define GG_REMOVE_NOTIFY105     0x7c
225
0
#define GG_LOGIN105             0x83
226
227
static const value_string gadu_gadu_packets_type_send[] = {
228
  GG_TYPE_VS(GG_NEW_STATUS),
229
  GG_TYPE_VS(GG_PONG),
230
  GG_TYPE_VS(GG_PING),
231
  GG_TYPE_VS(GG_SEND_MSG),
232
  GG_TYPE_VS(GG_LOGIN),
233
  GG_TYPE_VS(GG_ADD_NOTIFY),
234
  GG_TYPE_VS(GG_REMOVE_NOTIFY),
235
  GG_TYPE_VS(GG_NOTIFY_FIRST),
236
  GG_TYPE_VS(GG_NOTIFY_LAST),
237
  GG_TYPE_VS(GG_LIST_EMPTY),
238
  GG_TYPE_VS(GG_LOGIN_EXT),
239
  GG_TYPE_VS(GG_PUBDIR50_REQUEST),
240
  GG_TYPE_VS(GG_LOGIN60),
241
  GG_TYPE_VS(GG_USERLIST_REQUEST),
242
  GG_TYPE_VS(GG_LOGIN70),
243
  GG_TYPE_VS(GG_DCC7_INFO),
244
  GG_TYPE_VS(GG_DCC7_NEW),
245
  GG_TYPE_VS(GG_DCC7_ACCEPT),
246
  GG_TYPE_VS(GG_DCC7_REJECT),
247
  GG_TYPE_VS(GG_DCC7_ID_REQUEST),
248
  GG_TYPE_VS(GG_DCC7_ID_DUNNO1),
249
  GG_TYPE_VS(GG_DCC7_ID_ABORT),
250
  GG_TYPE_VS(GG_NEW_STATUS80BETA),
251
  GG_TYPE_VS(GG_LOGIN80BETA),
252
  GG_TYPE_VS(GG_SEND_MSG80),
253
  GG_TYPE_VS(GG_USERLIST_REQUEST80),
254
  GG_TYPE_VS(GG_LOGIN80),
255
  GG_TYPE_VS(GG_NEW_STATUS80),
256
  GG_TYPE_VS(GG_USERLIST100_REQUEST),
257
  GG_TYPE_VS(GG_RECV_MSG_ACK),
258
  GG_TYPE_VS(GG_TYPING_NOTIFY),
259
  GG_TYPE_VS(GG_OWN_DISCONNECT),
260
  GG_TYPE_VS(GG_NEW_STATUS105),
261
  GG_TYPE_VS(GG_NOTIFY105),
262
  GG_TYPE_VS(GG_ADD_NOTIFY105),
263
  GG_TYPE_VS(GG_REMOVE_NOTIFY105),
264
  GG_TYPE_VS(GG_LOGIN105),
265
  { 0, NULL }
266
};
267
268
static const value_string gadu_gadu_msg_ack_status_vals[] = {
269
  { 0x01, "Message blocked" },
270
  { 0x02, "Message delivered" },
271
  { 0x03, "Message queued" },
272
  { 0x04, "Message not delivered (queue full)" },
273
  { 0x06, "CTCP Message not delivered" },
274
  { 0, NULL }
275
};
276
277
#define GG_STATUS_NOT_AVAIL         0x01
278
0
#define GG_STATUS_NOT_AVAIL_DESCR   0x15
279
#define GG_STATUS_FFC               0x17
280
0
#define GG_STATUS_FFC_DESCR         0x18
281
#define GG_STATUS_AVAIL             0x02
282
0
#define GG_STATUS_AVAIL_DESCR       0x04
283
#define GG_STATUS_BUSY              0x03
284
0
#define GG_STATUS_BUSY_DESCR        0x05
285
#define GG_STATUS_DND               0x21
286
0
#define GG_STATUS_DND_DESCR         0x22
287
#define GG_STATUS_INVISIBLE         0x14
288
0
#define GG_STATUS_INVISIBLE_DESCR   0x16
289
#define GG_STATUS_BLOCKED           0x06
290
291
0
#define GG_LOGIN_HASH_GG32 0x01
292
0
#define GG_LOGIN_HASH_SHA1 0x02
293
294
static const value_string gadu_gadu_hash_type_vals[] = {
295
  { GG_LOGIN_HASH_GG32, "GG32 hash" },
296
  { GG_LOGIN_HASH_SHA1, "SHA1 hash" },
297
  { 0, NULL }
298
};
299
300
0
#define GG_USERLIST_PUT 0x00
301
#define GG_USERLIST_PUT_MORE 0x01
302
#define GG_USERLIST_GET 0x02
303
304
static const value_string gadu_gadu_userlist_request_type_vals[] = {
305
  { GG_USERLIST_PUT, "Userlist put" },
306
  { GG_USERLIST_PUT_MORE, "Userlist put (more)" },
307
  { GG_USERLIST_GET, "Userlist get" },
308
  { 0, NULL }
309
};
310
311
#define GG_USERLIST_PUT_REPLY 0x00
312
#define GG_USERLIST_PUT_MORE_REPLY 0x02
313
0
#define GG_USERLIST_GET_REPLY 0x06
314
#define GG_USERLIST_GET_MORE_REPLY 0x04
315
316
static const value_string gadu_gadu_userlist_reply_type_vals[] = {
317
  { GG_USERLIST_PUT_REPLY, "Userlist put" },
318
  { GG_USERLIST_PUT_MORE_REPLY, "Userlist put (more)" },
319
  { GG_USERLIST_GET_REPLY, "Userlist get" },
320
  { GG_USERLIST_GET_MORE_REPLY, "Userlist get (more)" },
321
  { 0, NULL }
322
};
323
324
#define GG_USERLIST100_FORMAT_TYPE_NONE 0x00
325
#define GG_USERLIST100_FORMAT_TYPE_GG70 0x01
326
0
#define GG_USERLIST100_FORMAT_TYPE_GG100 0x02
327
328
static const value_string gadu_gadu_userlist_request_format_vals[] = {
329
  { GG_USERLIST100_FORMAT_TYPE_NONE, "None" },
330
  { GG_USERLIST100_FORMAT_TYPE_GG70, "Classic (7.0)" },
331
  { GG_USERLIST100_FORMAT_TYPE_GG100, "XML (10.0)" },
332
  { 0, NULL }
333
};
334
335
/* XXX, add compatible libgadu versions? */
336
static const value_string gadu_gadu_version_vals[] = {
337
  { 0x2e, "Gadu-Gadu 8.0 (build 8283)" },
338
  { 0x2d, "Gadu-Gadu 8.0 (build 4881)" },
339
  { 0x2a, "Gadu-Gadu 7.7 (build 3315)" },
340
  { 0x29, "Gadu-Gadu 7.6 (build 1688)" },
341
  { 0x28, "Gadu-Gadu 7.5.0 (build 2201)" },
342
  { 0x27, "Gadu-Gadu 7.0 (build 22)" },
343
  { 0x26, "Gadu-Gadu 7.0 (build 20)" },
344
  { 0x25, "Gadu-Gadu 7.0 (build 1)" },
345
  { 0x24, "Gadu-Gadu 6.1 (build 155) or 7.6 (build 1359)" },
346
  { 0x22, "Gadu-Gadu 6.0 (build 140)" },
347
  { 0x21, "Gadu-Gadu 6.0 (build 133)" },
348
  { 0x20, "Gadu-Gadu 6.0" },
349
  { 0x1e, "Gadu-Gadu 5.7 beta (build 121)" },
350
  { 0x1c, "Gadu_Gadu 5.7 beta" },
351
  { 0x1b, "Gadu-Gadu 5.0.5" },
352
  { 0x19, "Gadu-Gadu 5.0.3" },
353
  { 0x18, "Gadu-Gadu 5.0.1, 5.0.0, 4.9.3" },
354
  { 0x17, "Gadu-Gadu 4.9.2" },
355
  { 0x16, "Gadu-Gadu 4.9.1" },
356
  { 0x15, "Gadu-Gadu 4.8.9" },
357
  { 0x14, "Gadu-Gadu 4.8.3, 4.8.1" },
358
  { 0x11, "Gadu-Gadu 4.6.10, 4.6.1" },
359
  { 0x10, "Gadu-Gadu 4.5.22, 4.5.21, 4.5.19, 4.5.17, 4.5.15" },
360
  { 0x0f, "Gadu-Gadu 4.5.12" },
361
  { 0x0b, "Gadu-Gadu 4.0.30, 4.0.29, 4.0.28, 4.0.25" },
362
  { 0, NULL }
363
};
364
365
static const value_string gadu_gadu_dcc_type_vals[] = {
366
  { 1, "Voice transmission" },
367
  { 4, "File transmission" },
368
  { 0, NULL }
369
};
370
371
static const value_string gadu_gadu_typing_notify_type_vals[] = {
372
  { 1, "Typing started" },
373
  { 0, "Typing stopped" },
374
  { 0, NULL }
375
};
376
377
static const value_string gadu_gadu_pubdir_type_vals[] = {
378
  { 1, "Public directory write" },
379
  { 2, "Public directory read" },
380
  { 3, "Public directory search" },
381
  { 0, NULL }
382
};
383
384
static dissector_handle_t xml_handle;
385
386
struct gadu_gadu_conv_data {
387
  uint32_t uin; /* uin from login packet */
388
};
389
390
static struct gadu_gadu_conv_data *
391
gadu_gadu_create_conversation(packet_info *pinfo, uint32_t uin)
392
0
{
393
0
  conversation_t *conv;
394
0
  struct gadu_gadu_conv_data *gg_conv;
395
396
0
  conv = find_or_create_conversation(pinfo);
397
0
  gg_conv = (struct gadu_gadu_conv_data *)conversation_get_proto_data(conv, proto_gadu_gadu);
398
0
  if (!gg_conv) {
399
0
    gg_conv = wmem_new(wmem_file_scope(), struct gadu_gadu_conv_data);
400
0
    gg_conv->uin = uin;
401
402
0
    conversation_add_proto_data(conv, proto_gadu_gadu, gg_conv);
403
0
  }
404
  /* assert(gg_conv->uin == uin); */
405
0
  return gg_conv;
406
0
}
407
408
static struct gadu_gadu_conv_data *
409
gadu_gadu_get_conversation_data(packet_info *pinfo)
410
0
{
411
0
  conversation_t *conv;
412
413
0
  conv = find_conversation_pinfo(pinfo, 0);
414
0
  if (conv)
415
0
    return (struct gadu_gadu_conv_data *)conversation_get_proto_data(conv, proto_gadu_gadu);
416
0
  return NULL;
417
0
}
418
419
static bool
420
gadu_gadu_status_has_descr(int status)
421
0
{
422
0
  return
423
0
    (status == GG_STATUS_NOT_AVAIL_DESCR) ||
424
0
    (status == GG_STATUS_FFC_DESCR) ||
425
0
    (status == GG_STATUS_AVAIL_DESCR) ||
426
0
    (status == GG_STATUS_BUSY_DESCR) ||
427
0
    (status == GG_STATUS_DND_DESCR) ||
428
0
    (status == GG_STATUS_INVISIBLE_DESCR);
429
0
}
430
431
/* like tvb_strsize() but return maximum length instead of throwing exception */
432
static unsigned
433
gadu_gadu_strsize(tvbuff_t *tvb, const int abs_offset)
434
0
{
435
0
  int len;
436
437
0
  len = tvb_strnlen(tvb, abs_offset, -1);
438
0
  if (len == -1) {
439
0
    len = tvb_captured_length(tvb);
440
0
  } else {
441
0
    len++; // Include the NUL
442
0
  }
443
444
0
  return (unsigned)len;
445
0
}
446
447
static unsigned
448
dissect_gadu_gadu_stringz_cp1250(tvbuff_t *tvb, int hfindex, proto_tree *tree, const unsigned offset)
449
0
{
450
0
  unsigned len = gadu_gadu_strsize(tvb, offset);
451
452
0
  proto_tree_add_item(tree, hfindex, tvb, offset, len, ENC_WINDOWS_1250 | ENC_NA);
453
454
0
  return offset + len;
455
0
}
456
457
static unsigned
458
dissect_gadu_gadu_uint32_string_utf8(tvbuff_t *tvb, int hfindex, proto_tree *tree, unsigned offset)
459
0
{
460
0
  const unsigned org_offset = offset;
461
462
0
  uint32_t len;
463
464
0
  len = tvb_get_letohl(tvb, offset);
465
0
  offset += 4;
466
467
0
  offset += len;
468
469
0
  proto_tree_add_item(tree, hfindex, tvb, org_offset, offset - org_offset, ENC_UTF_8 | ENC_NA);
470
471
0
  return offset;
472
0
}
473
474
475
static unsigned
476
dissect_gadu_gadu_disconnecting(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
477
0
{
478
0
  col_set_str(pinfo->cinfo, COL_INFO, "Disconnecting");
479
480
  /* empty packet */
481
482
0
  return offset;
483
0
}
484
485
486
static unsigned
487
dissect_gadu_gadu_disconnect_ack(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
488
0
{
489
0
  col_set_str(pinfo->cinfo, COL_INFO, "Disconnect acknowledge (< 10.0)");
490
491
  /* empty packet */
492
493
0
  return offset;
494
0
}
495
496
static void *
497
_tvb_memcpy_reverse(tvbuff_t *tvb, void *target, unsigned offset, size_t length)
498
0
{
499
0
  uint8_t *t = (uint8_t *) target;
500
501
0
  while (length > 0) {
502
0
    length--;
503
0
    t[length]  = tvb_get_uint8(tvb, offset);
504
0
    offset++;
505
0
  }
506
0
  return target;
507
0
}
508
509
static unsigned
510
dissect_gadu_gadu_login_protocol(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset)
511
0
{
512
0
  proto_item *ti;
513
514
0
  uint32_t protocol;
515
516
  /* TODO: is a 1 or 4 bytes field? */
517
0
  protocol = tvb_get_letohl(tvb, offset) & 0xff;
518
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_protocol, tvb, offset, 4, ENC_LITTLE_ENDIAN);
519
0
  ti = proto_tree_add_string(tree, hf_gadu_gadu_login_version, tvb, offset, 4, val_to_str(pinfo->pool, protocol, gadu_gadu_version_vals, "Unknown (0x%x)"));
520
0
  proto_item_set_generated(ti);
521
0
  offset += 4;
522
523
0
  return offset;
524
0
}
525
526
static unsigned
527
dissect_gadu_gadu_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
528
0
{
529
0
  proto_item *ti;
530
531
0
  uint32_t uin;
532
0
  uint8_t hash[4];
533
534
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login request (< 6.0)");
535
536
0
  uin = tvb_get_letohl(tvb, offset);
537
0
  gadu_gadu_create_conversation(pinfo, uin);
538
539
0
  proto_tree_add_uint(tree, hf_gadu_gadu_login_uin, tvb, offset, 4, uin);
540
0
  offset += 4;
541
542
0
  ti = proto_tree_add_uint(tree, hf_gadu_gadu_login_hash_type, tvb, 0, 0, GG_LOGIN_HASH_GG32);
543
0
  proto_item_set_generated(ti);
544
545
  /* hash is 32-bit number written in LE */
546
0
  _tvb_memcpy_reverse(tvb, hash, offset, 4);
547
0
  proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_login_hash, tvb, offset, 4, hash, "0x%.8x", tvb_get_letohl(tvb, offset));
548
0
  offset += 4;
549
550
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
551
0
  offset += 4;
552
553
0
  offset = dissect_gadu_gadu_login_protocol(tvb, pinfo, tree, offset);
554
555
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
556
0
  offset += 4;
557
558
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
559
0
  offset += 2;
560
561
0
  return offset;
562
0
}
563
564
static unsigned
565
dissect_gadu_gadu_login_hash(tvbuff_t *tvb, proto_tree *tree, unsigned offset)
566
0
{
567
0
  uint8_t hash_type;
568
569
0
  uint8_t hash[4];
570
0
  int i;
571
572
0
  proto_tree_add_item_ret_uint8(tree, hf_gadu_gadu_login_hash_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &hash_type);
573
0
  offset += 1;
574
575
0
  switch (hash_type) {
576
0
    case GG_LOGIN_HASH_GG32:
577
      /* hash is 32-bit number written in LE */
578
0
      _tvb_memcpy_reverse(tvb, hash, offset, 4);
579
0
      proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_login_hash, tvb, offset, 4, hash, "0x%.8x", tvb_get_letohl(tvb, offset));
580
0
      for (i = 4; i < 64; i++) {
581
0
        if (tvb_get_uint8(tvb, offset+i)) {
582
0
          proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset + 4, 64-4, ENC_NA);
583
0
          break;
584
0
        }
585
0
      }
586
0
      break;
587
588
0
    case GG_LOGIN_HASH_SHA1:
589
0
      proto_tree_add_item(tree, hf_gadu_gadu_login_hash, tvb, offset, 20, ENC_NA);
590
0
      for (i = 20; i < 64; i++) {
591
0
        if (tvb_get_uint8(tvb, offset+i)) {
592
0
          proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset + 20, 64-20, ENC_NA);
593
0
          break;
594
0
        }
595
0
      }
596
0
      break;
597
598
0
    default:
599
0
      proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 64, ENC_NA);
600
0
      break;
601
0
  }
602
0
  offset += 64;
603
604
0
  return offset;
605
0
}
606
607
static unsigned
608
dissect_gadu_gadu_login70(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
609
0
{
610
0
  uint32_t uin;
611
612
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login request (7.0)");
613
614
0
  uin = tvb_get_letohl(tvb, offset) & ~(GG_ERA_OMNIX_MASK | GG_HAS_AUDIO_MASK);
615
0
  gadu_gadu_create_conversation(pinfo, uin);
616
617
0
  proto_tree_add_uint(tree, hf_gadu_gadu_login_uin, tvb, offset, 4, uin);
618
0
  offset += 4;
619
620
0
  offset = dissect_gadu_gadu_login_hash(tvb, tree, offset);
621
622
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
623
0
  offset += 4;
624
625
0
  offset = dissect_gadu_gadu_login_protocol(tvb, pinfo, tree, offset);
626
627
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 00 */
628
0
  offset += 1;
629
630
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
631
0
  offset += 4;
632
633
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
634
0
  offset += 2;
635
636
  /* XXX packet not fully dissected */
637
638
0
  return offset;
639
0
}
640
641
static int
642
dissect_gadu_gadu_login80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
643
0
{
644
0
  uint32_t uin;
645
646
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login request (8.0)");
647
648
0
  uin = tvb_get_letohl(tvb, offset);
649
0
  gadu_gadu_create_conversation(pinfo, uin);
650
651
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
652
0
  offset += 4;
653
654
0
  proto_tree_add_item(tree, hf_gadu_gadu_login80_lang, tvb, offset, 2, ENC_ASCII);
655
0
  offset += 2;
656
657
0
  offset = dissect_gadu_gadu_login_hash(tvb, tree, offset);
658
659
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
660
0
  offset += 4;
661
662
  /* XXX packet not fully dissected */
663
664
0
  return offset;
665
0
}
666
667
static int
668
dissect_gadu_gadu_login_ok(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
669
0
{
670
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login success (< 8.0)");
671
672
  /* not empty packet, but content unknown */
673
674
0
  return offset;
675
0
}
676
677
static int
678
dissect_gadu_gadu_login_failed(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
679
0
{
680
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login fail (< 8.0)");
681
682
  /* empty packet */
683
684
0
  return offset;
685
0
}
686
687
static int
688
dissect_gadu_gadu_login_ok80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
689
0
{
690
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login success (8.0)");
691
692
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);  /* 01 00 00 00 */
693
0
  offset += 4;
694
695
0
  return offset;
696
0
}
697
698
static int
699
dissect_gadu_gadu_login80_failed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
700
0
{
701
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login fail (8.0)");
702
703
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);  /* 01 00 00 00 */
704
0
  offset += 4;
705
706
0
  return offset;
707
0
}
708
709
static int
710
dissect_gadu_gadu_user_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
711
0
{
712
0
  uint32_t users_num;
713
714
0
  col_set_str(pinfo->cinfo, COL_INFO, "Contact details");
715
716
  /* XXX, add subtrees */
717
718
0
  offset += 4;
719
720
0
  users_num = tvb_get_letohl(tvb, offset);
721
0
  offset += 4;
722
723
0
  while (users_num--) {
724
0
    uint32_t attr_num;
725
726
0
    proto_tree_add_item(tree, hf_gadu_gadu_userdata_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
727
0
    offset += 4;
728
729
0
    attr_num = tvb_get_letohl(tvb, offset);
730
0
    offset += 4;
731
732
0
    while (attr_num--) {
733
0
      uint32_t name_size, val_size;
734
0
      char *name, *val;
735
  /* name */
736
0
      name_size = tvb_get_letohl(tvb, offset);
737
0
      offset += 4;
738
739
0
      name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, name_size, ENC_ASCII | ENC_NA);
740
0
      proto_tree_add_string(tree, hf_gadu_gadu_userdata_attr_name, tvb, offset - 4, 4 + name_size, name);
741
0
      offset += name_size;
742
  /* type */
743
0
      proto_tree_add_item(tree, hf_gadu_gadu_userdata_attr_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
744
0
      offset += 4;
745
  /* value */
746
0
      val_size = tvb_get_letohl(tvb, offset);
747
0
      offset += 4;
748
749
0
      val = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, val_size, ENC_ASCII | ENC_NA);
750
0
      proto_tree_add_string(tree, hf_gadu_gadu_userdata_attr_value, tvb, offset - 4, 4 + val_size, val);
751
0
      offset += val_size;
752
0
    }
753
0
  }
754
755
0
  return offset;
756
0
}
757
758
static unsigned
759
dissect_gadu_gadu_typing_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
760
0
{
761
0
  col_set_str(pinfo->cinfo, COL_INFO, "Typing notify");
762
763
  /* XXX, when type > 1, it's length not type ! */
764
0
  proto_tree_add_item(tree, hf_gadu_gadu_typing_notify_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
765
0
  offset += 2;
766
767
0
  proto_tree_add_item(tree, hf_gadu_gadu_typing_notify_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
768
0
  offset += 4;
769
770
0
  return offset;
771
0
}
772
773
static unsigned
774
dissect_gadu_gadu_msg_attr(tvbuff_t *tvb _U_, proto_tree *tree _U_, unsigned offset)
775
0
{
776
  /* XXX, stub */
777
778
0
  return offset;
779
0
}
780
781
static unsigned
782
dissect_gadu_gadu_recv_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
783
0
{
784
0
  struct gadu_gadu_conv_data *conv;
785
0
  proto_item *ti;
786
787
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive message (< 8.0)");
788
789
0
  if ((conv = gadu_gadu_get_conversation_data(pinfo))) {
790
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_recipient, tvb, 0, 0, conv->uin);
791
0
    proto_item_set_generated(ti);
792
793
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_uin, tvb, 0, 0, conv->uin);
794
0
    proto_item_set_generated(ti);
795
0
    proto_item_set_hidden(ti);
796
0
  }
797
798
0
  ti = proto_tree_add_item(tree, hf_gadu_gadu_msg_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
799
0
  proto_item_set_hidden(ti);
800
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_sender, tvb, offset, 4, ENC_LITTLE_ENDIAN);
801
0
  offset += 4;
802
803
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
804
0
  offset += 4;
805
806
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
807
0
  offset += 4;
808
809
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_class, tvb, offset, 4, ENC_LITTLE_ENDIAN);
810
0
  offset += 4;
811
812
0
  offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_msg_text, tree, offset);
813
814
0
  offset = dissect_gadu_gadu_msg_attr(tvb, tree, offset);
815
816
0
  return offset;
817
0
}
818
819
static unsigned
820
dissect_gadu_gadu_send_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
821
0
{
822
0
  struct gadu_gadu_conv_data *conv;
823
0
  proto_item *ti;
824
825
0
  col_set_str(pinfo->cinfo, COL_INFO, "Send message (< 8.0)");
826
827
0
  ti = proto_tree_add_item(tree, hf_gadu_gadu_msg_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
828
0
  proto_item_set_hidden(ti);
829
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_recipient, tvb, offset, 4, ENC_LITTLE_ENDIAN);
830
0
  offset += 4;
831
832
0
  if ((conv = gadu_gadu_get_conversation_data(pinfo))) {
833
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_sender, tvb, 0, 0, conv->uin);
834
0
    proto_item_set_generated(ti);
835
836
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_uin, tvb, 0, 0, conv->uin);
837
0
    proto_item_set_generated(ti);
838
0
    proto_item_set_hidden(ti);
839
0
  }
840
841
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
842
0
  offset += 4;
843
844
0
  ti = proto_tree_add_time(tree, hf_gadu_gadu_msg_time, tvb, 0, 0, &(pinfo->abs_ts));
845
0
  proto_item_set_generated(ti);
846
847
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_class, tvb, offset, 4, ENC_LITTLE_ENDIAN);
848
0
  offset += 4;
849
850
0
  offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_msg_text, tree, offset);
851
852
0
  offset = dissect_gadu_gadu_msg_attr(tvb, tree, offset);
853
854
0
  return offset;
855
0
}
856
857
static unsigned
858
dissect_gadu_gadu_recv_msg80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
859
0
{
860
0
  struct gadu_gadu_conv_data *conv;
861
0
  proto_item *ti;
862
863
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive message (8.0)");
864
865
0
  if ((conv = gadu_gadu_get_conversation_data(pinfo))) {
866
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_recipient, tvb, 0, 0, conv->uin);
867
0
    proto_item_set_generated(ti);
868
869
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_uin, tvb, 0, 0, conv->uin);
870
0
    proto_item_set_generated(ti);
871
0
    proto_item_set_hidden(ti);
872
0
  }
873
874
0
  ti = proto_tree_add_item(tree, hf_gadu_gadu_msg_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
875
0
  proto_item_set_hidden(ti);
876
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_sender, tvb, offset, 4, ENC_LITTLE_ENDIAN);
877
0
  offset += 4;
878
879
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
880
0
  offset += 4;
881
882
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
883
0
  offset += 4;
884
885
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_class, tvb, offset, 4, ENC_LITTLE_ENDIAN);
886
0
  offset += 4;
887
888
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg80_offset_plain, tvb, offset, 4, ENC_LITTLE_ENDIAN);
889
0
  offset += 4;
890
891
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg80_offset_attr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
892
0
  offset += 4;
893
894
  /* XXX packet not fully dissected */
895
896
0
  return offset;
897
0
}
898
899
static unsigned
900
dissect_gadu_gadu_send_msg80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
901
0
{
902
0
  struct gadu_gadu_conv_data *conv;
903
0
  proto_item *ti;
904
905
0
  col_set_str(pinfo->cinfo, COL_INFO, "Send message (8.0)");
906
907
0
  ti = proto_tree_add_item(tree, hf_gadu_gadu_msg_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
908
0
  proto_item_set_hidden(ti);
909
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_recipient, tvb, offset, 4, ENC_LITTLE_ENDIAN);
910
0
  offset += 4;
911
912
0
  if ((conv = gadu_gadu_get_conversation_data(pinfo))) {
913
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_sender, tvb, 0, 0, conv->uin);
914
0
    proto_item_set_generated(ti);
915
916
0
    ti = proto_tree_add_uint(tree, hf_gadu_gadu_msg_uin, tvb, 0, 0, conv->uin);
917
0
    proto_item_set_generated(ti);
918
0
    proto_item_set_hidden(ti);
919
0
  }
920
921
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
922
0
  offset += 4;
923
924
0
  ti = proto_tree_add_time(tree, hf_gadu_gadu_msg_time, tvb, 0, 0, &(pinfo->abs_ts));
925
0
  proto_item_set_generated(ti);
926
927
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_class, tvb, offset, 4, ENC_LITTLE_ENDIAN);
928
0
  offset += 4;
929
930
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg80_offset_plain, tvb, offset, 4, ENC_LITTLE_ENDIAN);
931
0
  offset += 4;
932
933
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg80_offset_attr, tvb, offset, 4, ENC_LITTLE_ENDIAN);
934
0
  offset += 4;
935
936
  /* XXX packet not fully dissected */
937
938
0
  return offset;
939
0
}
940
941
static unsigned
942
dissect_gadu_gadu_send_msg_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
943
0
{
944
0
  col_set_str(pinfo->cinfo, COL_INFO, "Message acknowledge (server)");
945
946
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_ack_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
947
0
  offset += 4;
948
949
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_ack_recipient, tvb, offset, 4, ENC_LITTLE_ENDIAN);
950
0
  offset += 4;
951
952
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_ack_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
953
0
  offset += 4;
954
955
0
  return offset;
956
0
}
957
958
static unsigned
959
dissect_gadu_gadu_recv_msg_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
960
0
{
961
0
  col_set_str(pinfo->cinfo, COL_INFO, "Message acknowledge (client)");
962
963
0
  proto_tree_add_item(tree, hf_gadu_gadu_msg_ack_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
964
0
  offset += 4;
965
966
0
  return offset;
967
0
}
968
969
static unsigned
970
dissect_gadu_gadu_status60(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
971
0
{
972
0
  uint32_t uin;
973
0
  uint32_t status;
974
975
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status (6.0)");
976
977
0
  uin = tvb_get_letohl(tvb, offset) & ~(GG_ERA_OMNIX_MASK | GG_HAS_AUDIO_MASK);
978
0
  proto_tree_add_uint(tree, hf_gadu_gadu_status_uin, tvb, offset, 4, uin);
979
0
  offset += 4;
980
981
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_status_status, tvb, offset, 1, ENC_LITTLE_ENDIAN, &status);
982
0
  offset += 1;
983
984
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
985
0
  offset += 4;
986
987
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
988
0
  offset += 2;
989
990
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
991
0
  offset += 1;
992
993
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
994
0
  offset += 1;
995
996
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 00 */
997
0
  offset += 1;
998
999
0
  if (gadu_gadu_status_has_descr(status))
1000
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1001
1002
0
  return offset;
1003
0
}
1004
1005
static unsigned
1006
dissect_gadu_gadu_status77(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1007
0
{
1008
0
  uint32_t uin;
1009
0
  uint32_t status;
1010
1011
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status (7.7)");
1012
1013
0
  uin = tvb_get_letohl(tvb, offset) & ~(GG_ERA_OMNIX_MASK | GG_HAS_AUDIO_MASK);
1014
0
  proto_tree_add_uint(tree, hf_gadu_gadu_status_uin, tvb, offset, 4, uin);
1015
0
  offset += 4;
1016
1017
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_status_status, tvb, offset, 1, ENC_LITTLE_ENDIAN, &status);
1018
0
  offset += 1;
1019
1020
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1021
0
  offset += 4;
1022
1023
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1024
0
  offset += 2;
1025
1026
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1027
0
  offset += 1;
1028
1029
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1030
0
  offset += 1;
1031
1032
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 00 */
1033
0
  offset += 1;
1034
1035
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1036
0
  offset += 4;
1037
1038
0
  if (gadu_gadu_status_has_descr(status))
1039
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1040
1041
0
  return offset;
1042
0
}
1043
1044
static unsigned
1045
dissect_gadu_gadu_status80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1046
0
{
1047
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status (8.0)");
1048
1049
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1050
0
  offset += 4;
1051
1052
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1053
0
  offset += 4;
1054
1055
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1056
0
  offset += 4;
1057
1058
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1059
0
  offset += 4;
1060
1061
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1062
0
  offset += 2;
1063
1064
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1065
0
  offset += 1;
1066
1067
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);
1068
0
  offset += 1;
1069
1070
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1071
0
  offset += 4;
1072
1073
0
  offset = dissect_gadu_gadu_uint32_string_utf8(tvb, hf_gadu_gadu_status_descr, tree, offset);
1074
1075
0
  return offset;
1076
0
}
1077
1078
static unsigned
1079
dissect_gadu_gadu_notify_reply80(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
1080
0
{
1081
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status list (8.0)");
1082
1083
  /* XXX packet not fully dissected */
1084
1085
0
  return offset;
1086
0
}
1087
1088
static unsigned
1089
dissect_gadu_gadu_new_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1090
0
{
1091
0
  uint32_t status;
1092
1093
0
  col_set_str(pinfo->cinfo, COL_INFO, "New status (< 8.0)");
1094
1095
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_new_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN, &status);
1096
0
  offset += 4;
1097
1098
0
  if (gadu_gadu_status_has_descr(status & 0xff))
1099
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1100
1101
0
  return offset;
1102
0
}
1103
1104
static unsigned
1105
dissect_gadu_gadu_new_status80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1106
0
{
1107
0
  col_set_str(pinfo->cinfo, COL_INFO, "New status (8.0)");
1108
1109
0
  proto_tree_add_item(tree, hf_gadu_gadu_new_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1110
0
  offset += 4;
1111
1112
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1113
0
  offset += 4;
1114
1115
0
  offset = dissect_gadu_gadu_uint32_string_utf8(tvb, hf_gadu_gadu_new_status_desc, tree, offset);
1116
1117
0
  return offset;
1118
0
}
1119
1120
static unsigned
1121
dissect_gadu_gadu_list_empty(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
1122
0
{
1123
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (empty)");
1124
1125
  /* empty packet */
1126
1127
0
  return offset;
1128
0
}
1129
1130
static unsigned
1131
dissect_gadu_gadu_add_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1132
0
{
1133
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list add");
1134
1135
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1136
0
  offset += 4;
1137
1138
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1139
0
  offset += 1;
1140
1141
0
  return offset;
1142
0
}
1143
1144
static unsigned
1145
dissect_gadu_gadu_notify105_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, char **puin)
1146
0
{
1147
0
  uint16_t uin_len;
1148
0
  char *uin;
1149
1150
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA); /* unknown 00 */
1151
0
  offset += 1;
1152
1153
0
  uin_len = tvb_get_uint8(tvb, offset);
1154
0
  offset += 1;
1155
0
  uin = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, uin_len, ENC_ASCII | ENC_NA);
1156
0
  proto_tree_add_string(tree, hf_gadu_gadu_contact_uin_str, tvb, offset - 1, 1 + uin_len, uin);
1157
0
  offset += uin_len;
1158
0
  if (puin)
1159
0
    *puin = uin;
1160
1161
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1162
0
  offset += 1;
1163
1164
0
  return offset;
1165
0
}
1166
1167
static unsigned
1168
dissect_gadu_gadu_add_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1169
0
{
1170
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list add (10.5)");
1171
1172
0
  return dissect_gadu_gadu_notify105_common(tvb, pinfo, tree, offset, NULL);
1173
0
}
1174
1175
static unsigned
1176
dissect_gadu_gadu_remove_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1177
0
{
1178
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list remove");
1179
1180
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1181
0
  offset += 4;
1182
1183
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1184
0
  offset += 1;
1185
1186
0
  return offset;
1187
0
}
1188
1189
static unsigned
1190
dissect_gadu_gadu_remove_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1191
0
{
1192
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list remove (10.5)");
1193
1194
0
  return dissect_gadu_gadu_notify105_common(tvb, pinfo, tree, offset, NULL);
1195
0
}
1196
1197
static unsigned
1198
dissect_gadu_gadu_notify_common(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, unsigned offset)
1199
0
{
1200
0
  proto_tree *contact_tree;
1201
1202
0
  while (tvb_reported_length_remaining(tvb, offset) >= 4+1) {
1203
0
    uint32_t uin = tvb_get_letohl(tvb, offset);
1204
1205
0
    contact_tree = proto_tree_add_subtree_format(tree, tvb, offset, 5,
1206
0
                ett_gadu_gadu_contact, NULL, "Contact: %u", uin);
1207
1208
0
    proto_tree_add_item(contact_tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1209
0
    offset += 4;
1210
1211
0
    proto_tree_add_item(contact_tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1212
0
    offset += 1;
1213
0
  }
1214
1215
0
  return offset;
1216
0
}
1217
1218
static unsigned
1219
dissect_gadu_gadu_notify_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1220
0
{
1221
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list");
1222
1223
0
  return dissect_gadu_gadu_notify_common(tvb, pinfo, tree, offset);
1224
0
}
1225
1226
static unsigned
1227
dissect_gadu_gadu_notify_last(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1228
0
{
1229
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (last)");
1230
1231
0
  return dissect_gadu_gadu_notify_common(tvb, pinfo, tree, offset);
1232
0
}
1233
1234
static unsigned
1235
dissect_gadu_gadu_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1236
0
{
1237
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (10.5)");
1238
1239
0
  while (tvb_reported_length_remaining(tvb, offset) >= 2) {
1240
0
    const int org_offset = offset;
1241
1242
0
    proto_tree *contact_tree;
1243
0
    proto_item *ti;
1244
1245
0
    char *uin;
1246
1247
0
    contact_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_gadu_gadu_contact, &ti, "Contact: ");
1248
1249
0
    offset = dissect_gadu_gadu_notify105_common(tvb, pinfo, contact_tree, offset, &uin);
1250
0
    proto_item_append_text(ti, "%s", uin);
1251
1252
0
    proto_item_set_len(ti, offset - org_offset);
1253
0
  }
1254
1255
0
  return offset;
1256
0
}
1257
1258
static unsigned
1259
dissect_gadu_gadu_ping(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, unsigned offset)
1260
0
{
1261
0
  col_set_str(pinfo->cinfo, COL_INFO, "Ping");
1262
1263
  /* empty packet */
1264
1265
0
  return offset;
1266
0
}
1267
1268
static unsigned
1269
dissect_gadu_gadu_welcome(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1270
0
{
1271
0
  col_set_str(pinfo->cinfo, COL_INFO, "Welcome");
1272
1273
0
  proto_tree_add_item(tree, hf_gadu_gadu_welcome_seed, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1274
0
  offset += 4;
1275
1276
0
  return offset;
1277
0
}
1278
1279
static unsigned
1280
dissect_gadu_gadu_userlist_xml_compressed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1281
0
{
1282
0
  int remain = tvb_reported_length_remaining(tvb, offset);
1283
0
  tvbuff_t *uncomp_tvb;
1284
1285
0
  if (remain <= 0)
1286
0
    return offset;
1287
1288
0
  if ((uncomp_tvb = tvb_child_uncompress_zlib(tvb, tvb, offset, remain))) {
1289
0
    proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_userlist, tvb, offset, remain, NULL, "%s", "[Decompression succeeded]");
1290
1291
0
    add_new_data_source(pinfo, uncomp_tvb, "Uncompressed userlist");
1292
1293
    /* XXX add DTD (pinfo->match_string) */
1294
0
    call_dissector_only(xml_handle, uncomp_tvb, pinfo, tree, NULL);
1295
0
  } else
1296
0
    proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_userlist, tvb, offset, remain, NULL, "%s", "[Error: Decompression failed] (or no zlib)");
1297
1298
0
  offset += remain;
1299
1300
0
  return offset;
1301
0
}
1302
1303
static unsigned
1304
dissect_gadu_gadu_userlist_request80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1305
0
{
1306
0
  uint32_t type;
1307
0
  proto_item *ti;
1308
1309
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist request (8.0)");
1310
1311
0
  type = tvb_get_uint8(tvb, offset);
1312
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &type);
1313
0
  offset += 1;
1314
1315
0
  ti = proto_tree_add_uint(tree, hf_gadu_gadu_userlist_format, tvb, 0, 0, GG_USERLIST100_FORMAT_TYPE_GG100);
1316
0
  proto_item_set_generated(ti);
1317
1318
0
  switch (type) {
1319
0
    case GG_USERLIST_PUT:
1320
0
      offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1321
0
      break;
1322
0
  }
1323
1324
0
  return offset;
1325
0
}
1326
1327
static unsigned
1328
dissect_gadu_gadu_userlist_request100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1329
1
{
1330
1
  uint32_t type, format;
1331
1332
1
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist request (10.0)");
1333
1334
1
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &type);
1335
1
  offset += 1;
1336
1337
1
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1338
1
  offset += 4;
1339
1340
1
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_format, tvb, offset, 1, ENC_LITTLE_ENDIAN, &format);
1341
1
  offset += 1;
1342
1343
1
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 01 */
1344
1
  offset += 1;
1345
1346
1
  switch (type) {
1347
0
    case GG_USERLIST_PUT:
1348
0
      if (format == GG_USERLIST100_FORMAT_TYPE_GG100)
1349
0
        offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1350
0
      break;
1351
1
  }
1352
1353
0
  return offset;
1354
1
}
1355
1356
static unsigned
1357
dissect_gadu_gadu_userlist_reply80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1358
0
{
1359
0
  uint32_t type;
1360
1361
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist reply (8.0)");
1362
1363
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &type);
1364
0
  offset += 1;
1365
1366
0
  switch (type) {
1367
0
    case GG_USERLIST_GET_REPLY:
1368
0
      offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1369
0
      break;
1370
0
  }
1371
1372
0
  return offset;
1373
0
}
1374
1375
static unsigned
1376
dissect_gadu_gadu_userlist_reply100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1377
0
{
1378
0
  uint32_t type, format;
1379
1380
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist reply (10.0)");
1381
1382
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN, &type);
1383
0
  offset += 1;
1384
1385
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1386
0
  offset += 4;
1387
1388
0
  proto_tree_add_item_ret_uint(tree, hf_gadu_gadu_userlist_format, tvb, offset, 1, ENC_LITTLE_ENDIAN, &format);
1389
0
  offset += 1;
1390
1391
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 01 */
1392
0
  offset += 1;
1393
1394
0
  switch (type) {
1395
0
    case GG_USERLIST_GET_REPLY:
1396
0
      if (format == GG_USERLIST100_FORMAT_TYPE_GG100)
1397
0
        offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1398
0
      break;
1399
0
  }
1400
1401
0
  return offset;
1402
0
}
1403
1404
static unsigned
1405
dissect_gadu_gadu_userlist_version100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1406
0
{
1407
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist version (10.0)");
1408
1409
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1410
0
  offset += 4;
1411
1412
0
  return offset;
1413
0
}
1414
1415
static unsigned
1416
dissect_gadu_gadu_dcc7_id_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1417
0
{
1418
0
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection id request");
1419
1420
0
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1421
0
  offset += 4;
1422
1423
0
  return offset;
1424
0
}
1425
1426
static unsigned
1427
dissect_gadu_gadu_dcc7_id_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1428
1
{
1429
1
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection id reply");
1430
1431
1
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1432
1
  offset += 4;
1433
1434
1
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1435
1
  offset += 8;
1436
1437
1
  return offset;
1438
1
}
1439
1440
static unsigned
1441
dissect_gadu_gadu_dcc7_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1442
0
{
1443
0
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection new");
1444
1445
0
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1446
0
  offset += 8;
1447
1448
0
  proto_tree_add_item(tree, hf_dcc_uin_from, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1449
0
  offset += 4;
1450
1451
0
  proto_tree_add_item(tree, hf_dcc_uin_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1452
0
  offset += 4;
1453
1454
0
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1455
0
  offset += 4;
1456
1457
0
  proto_tree_add_item(tree, hf_dcc_filename, tvb, offset, 255, ENC_ASCII);
1458
0
  offset += 255;
1459
1460
0
  return offset;
1461
0
}
1462
1463
static unsigned
1464
dissect_gadu_gadu_dcc7_id_abort(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1465
0
{
1466
0
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection abort");
1467
1468
0
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1469
0
  offset += 8;
1470
1471
0
  proto_tree_add_item(tree, hf_dcc_uin_from, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1472
0
  offset += 4;
1473
1474
0
  proto_tree_add_item(tree, hf_dcc_uin_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1475
0
  offset += 4;
1476
1477
0
  return offset;
1478
0
}
1479
1480
static unsigned
1481
dissect_gadu_gadu_pubdir50_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1482
0
{
1483
0
  unsigned pos;
1484
1485
0
  col_set_str(pinfo->cinfo, COL_INFO, "Public directory request");
1486
1487
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1488
0
  offset += 1;
1489
1490
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1491
0
  offset += 4;
1492
  /* XXX, link request sequence with reply sequence */
1493
1494
0
  while ((tvb_find_uint8_remaining(tvb, offset, '\0', &pos)) > 0) {
1495
    /* XXX, display it better, field=value */
1496
0
    proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_str, tvb, offset, (pos - offset) + 1, ENC_WINDOWS_1250);
1497
0
    offset = pos + 1;
1498
0
  }
1499
1500
0
  return offset;
1501
0
}
1502
1503
static unsigned
1504
dissect_gadu_gadu_pubdir50_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1505
0
{
1506
0
  unsigned pos;
1507
1508
0
  col_set_str(pinfo->cinfo, COL_INFO, "Public directory reply");
1509
1510
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1511
0
  offset += 1;
1512
1513
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1514
0
  offset += 4;
1515
  /* XXX, link reply sequence with request sequence */
1516
1517
0
  while ((tvb_find_uint8_remaining(tvb, offset, '\0', &pos))) {
1518
    /* XXX, display it better, field=value */
1519
0
    proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_str, tvb, offset, (pos - offset) + 1, ENC_WINDOWS_1250);
1520
0
    offset = pos + 1;
1521
0
  }
1522
1523
0
  return offset;
1524
0
}
1525
1526
static int
1527
dissect_gadu_gadu_xml_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset)
1528
0
{
1529
0
  tvbuff_t *xml_tvb;
1530
0
  unsigned ret;
1531
1532
0
  col_set_str(pinfo->cinfo, COL_INFO, "XML action message");
1533
1534
0
  xml_tvb = tvb_new_subset_remaining(tvb, offset);
1535
1536
  /* XXX add DTD (pinfo->match_string) */
1537
0
  ret = call_dissector_only(xml_handle, xml_tvb, pinfo, tree, NULL);
1538
1539
0
  return offset + ret;
1540
0
}
1541
1542
static int
1543
dissect_gadu_gadu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1544
14
{
1545
14
  proto_tree *gadu_gadu_tree = NULL;
1546
1547
14
  unsigned offset = 0;
1548
14
  uint32_t pkt_type;
1549
1550
14
  col_clear(pinfo->cinfo, COL_INFO); /* XXX, remove, add separator when multiple PDU */
1551
1552
14
  if (tree) {
1553
14
    proto_item *ti = proto_tree_add_item(tree, proto_gadu_gadu, tvb, 0, -1, ENC_NA);
1554
14
    gadu_gadu_tree = proto_item_add_subtree(ti, ett_gadu_gadu);
1555
14
  }
1556
1557
14
  pkt_type = tvb_get_letohl(tvb, offset);
1558
14
  proto_tree_add_item(gadu_gadu_tree, (pinfo->p2p_dir == P2P_DIR_RECV) ? hf_gadu_gadu_header_type_recv : hf_gadu_gadu_header_type_send, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1559
14
  offset += 4;
1560
14
  proto_tree_add_item(gadu_gadu_tree, hf_gadu_gadu_header_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1561
14
  offset += 4;
1562
1563
14
  if (pinfo->p2p_dir == P2P_DIR_RECV) {
1564
9
    switch (pkt_type) {
1565
0
      case GG_DISCONNECTING:
1566
0
        offset = dissect_gadu_gadu_disconnecting(tvb, pinfo, gadu_gadu_tree, offset);
1567
0
        break;
1568
1569
0
      case GG_DISCONNECT_ACK:
1570
0
        offset = dissect_gadu_gadu_disconnect_ack(tvb, pinfo, gadu_gadu_tree, offset);
1571
0
        break;
1572
1573
0
      case GG_LOGIN_OK:
1574
0
        offset = dissect_gadu_gadu_login_ok(tvb, pinfo, gadu_gadu_tree, offset);
1575
0
        break;
1576
1577
0
      case GG_LOGIN_OK80:
1578
0
        offset = dissect_gadu_gadu_login_ok80(tvb, pinfo, gadu_gadu_tree, offset);
1579
0
        break;
1580
1581
0
      case GG_LOGIN_FAILED:
1582
0
        offset = dissect_gadu_gadu_login_failed(tvb, pinfo, gadu_gadu_tree, offset);
1583
0
        break;
1584
1585
0
      case GG_LOGIN80_FAILED:
1586
0
        offset = dissect_gadu_gadu_login80_failed(tvb, pinfo, gadu_gadu_tree, offset);
1587
0
        break;
1588
1589
0
      case GG_USER_DATA:
1590
0
        offset = dissect_gadu_gadu_user_data(tvb, pinfo, gadu_gadu_tree, offset);
1591
0
        break;
1592
1593
0
      case GG_TYPING_NOTIFY:
1594
0
        offset = dissect_gadu_gadu_typing_notify(tvb, pinfo, gadu_gadu_tree, offset);
1595
0
        break;
1596
1597
0
      case GG_RECV_MSG:
1598
0
        offset = dissect_gadu_gadu_recv_msg(tvb, pinfo, gadu_gadu_tree, offset);
1599
0
        break;
1600
1601
0
      case GG_RECV_MSG80:
1602
0
        offset = dissect_gadu_gadu_recv_msg80(tvb, pinfo, gadu_gadu_tree, offset);
1603
0
        break;
1604
1605
0
      case GG_SEND_MSG_ACK:
1606
        /* GG_SEND_MSG_ACK is received by client */
1607
0
        offset = dissect_gadu_gadu_send_msg_ack(tvb, pinfo, gadu_gadu_tree, offset);
1608
0
        break;
1609
1610
0
      case GG_STATUS60:
1611
0
        offset = dissect_gadu_gadu_status60(tvb, pinfo, gadu_gadu_tree, offset);
1612
0
        break;
1613
1614
0
      case GG_STATUS77:
1615
0
        offset = dissect_gadu_gadu_status77(tvb, pinfo, gadu_gadu_tree, offset);
1616
0
        break;
1617
1618
0
      case GG_STATUS80:
1619
0
        offset = dissect_gadu_gadu_status80(tvb, pinfo, gadu_gadu_tree, offset);
1620
0
        break;
1621
1622
0
      case GG_NOTIFY_REPLY80:
1623
0
        offset = dissect_gadu_gadu_notify_reply80(tvb, pinfo, gadu_gadu_tree, offset);
1624
0
        break;
1625
1626
1
      case GG_DCC7_ID_REPLY:
1627
1
        offset = dissect_gadu_gadu_dcc7_id_reply(tvb, pinfo, gadu_gadu_tree, offset);
1628
1
        break;
1629
1630
0
      case GG_WELCOME:
1631
0
        offset = dissect_gadu_gadu_welcome(tvb, pinfo, gadu_gadu_tree, offset);
1632
0
        break;
1633
1634
0
      case GG_USERLIST_REPLY80:
1635
0
        offset = dissect_gadu_gadu_userlist_reply80(tvb, pinfo, gadu_gadu_tree, offset);
1636
0
        break;
1637
1638
0
      case GG_USERLIST100_REPLY:
1639
0
        offset = dissect_gadu_gadu_userlist_reply100(tvb, pinfo, gadu_gadu_tree, offset);
1640
0
        break;
1641
1642
0
      case GG_USERLIST100_VERSION:
1643
0
        offset = dissect_gadu_gadu_userlist_version100(tvb, pinfo, gadu_gadu_tree, offset);
1644
0
        break;
1645
1646
0
      case GG_PUBDIR50_REPLY:
1647
0
        offset = dissect_gadu_gadu_pubdir50_reply(tvb, pinfo, gadu_gadu_tree, offset);
1648
0
        break;
1649
1650
0
      case GG_XML_ACTION:
1651
0
        offset = dissect_gadu_gadu_xml_action(tvb, pinfo, gadu_gadu_tree, offset);
1652
0
        break;
1653
1654
0
      case GG_STATUS:
1655
0
      case GG_PONG:
1656
0
      case GG_PING:
1657
0
      case GG_NOTIFY_REPLY:
1658
0
      case GG_USERLIST_REPLY:
1659
0
      case GG_NOTIFY_REPLY60:
1660
0
      case GG_NEED_EMAIL:
1661
0
      case GG_LOGIN_HASH_TYPE_INVALID:
1662
0
      case GG_NOTIFY_REPLY77:
1663
0
      case GG_DCC7_INFO:
1664
0
      case GG_DCC7_NEW:
1665
0
      case GG_DCC7_ACCEPT:
1666
0
      case GG_DCC7_REJECT:
1667
0
      case GG_DCC7_ID_ABORTED:
1668
0
      case GG_XML_EVENT:
1669
0
      case GG_STATUS80BETA:
1670
0
      case GG_NOTIFY_REPLY80BETA:
1671
0
      case GG_OWN_MESSAGE:
1672
0
      case GG_OWN_RESOURCE_INFO:
1673
8
      default:
1674
8
      {
1675
8
        const char *pkt_name = try_val_to_str(pkt_type, gadu_gadu_packets_type_recv);
1676
1677
8
        if (pkt_name)
1678
0
          col_set_str(pinfo->cinfo, COL_INFO, pkt_name);
1679
8
        else
1680
8
          col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown recv packet: %.2x", pkt_type);
1681
8
        break;
1682
0
      }
1683
9
    }
1684
1685
9
  } else {
1686
5
    switch (pkt_type) {
1687
0
      case GG_LOGIN:
1688
0
        offset = dissect_gadu_gadu_login(tvb, pinfo, gadu_gadu_tree, offset);
1689
0
        break;
1690
1691
0
      case GG_LOGIN70:
1692
0
        offset = dissect_gadu_gadu_login70(tvb, pinfo, gadu_gadu_tree, offset);
1693
0
        break;
1694
1695
0
      case GG_LOGIN80:
1696
0
        offset = dissect_gadu_gadu_login80(tvb, pinfo, gadu_gadu_tree, offset);
1697
0
        break;
1698
1699
0
      case GG_LIST_EMPTY:
1700
0
        offset = dissect_gadu_gadu_list_empty(tvb, pinfo, gadu_gadu_tree, offset);
1701
0
        break;
1702
1703
0
      case GG_NOTIFY_FIRST:
1704
0
        offset = dissect_gadu_gadu_notify_first(tvb, pinfo, gadu_gadu_tree, offset);
1705
0
        break;
1706
1707
0
      case GG_NOTIFY_LAST:
1708
0
        offset = dissect_gadu_gadu_notify_last(tvb, pinfo, gadu_gadu_tree, offset);
1709
0
        break;
1710
1711
0
      case GG_NOTIFY105:
1712
0
        offset = dissect_gadu_gadu_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1713
0
        break;
1714
1715
0
      case GG_ADD_NOTIFY:
1716
0
        offset = dissect_gadu_gadu_add_notify(tvb, pinfo, gadu_gadu_tree, offset);
1717
0
        break;
1718
1719
0
      case GG_ADD_NOTIFY105:
1720
0
        offset = dissect_gadu_gadu_add_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1721
0
        break;
1722
1723
0
      case GG_REMOVE_NOTIFY:
1724
0
        offset = dissect_gadu_gadu_remove_notify(tvb, pinfo, gadu_gadu_tree, offset);
1725
0
        break;
1726
1727
0
      case GG_REMOVE_NOTIFY105:
1728
0
        offset = dissect_gadu_gadu_remove_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1729
0
        break;
1730
1731
0
      case GG_PING:
1732
0
        offset = dissect_gadu_gadu_ping(tvb, pinfo, gadu_gadu_tree, offset);
1733
0
        break;
1734
1735
0
      case GG_TYPING_NOTIFY:
1736
0
        offset = dissect_gadu_gadu_typing_notify(tvb, pinfo, gadu_gadu_tree, offset);
1737
0
        break;
1738
1739
0
      case GG_SEND_MSG:
1740
0
        offset = dissect_gadu_gadu_send_msg(tvb, pinfo, gadu_gadu_tree, offset);
1741
0
        break;
1742
1743
0
      case GG_SEND_MSG80:
1744
0
        offset = dissect_gadu_gadu_send_msg80(tvb, pinfo, gadu_gadu_tree, offset);
1745
0
        break;
1746
1747
0
      case GG_RECV_MSG_ACK:
1748
        /* GG_RECV_MSG_ACK is send by client */
1749
0
        offset = dissect_gadu_gadu_recv_msg_ack(tvb, pinfo, gadu_gadu_tree, offset);
1750
0
        break;
1751
1752
0
      case GG_NEW_STATUS:
1753
0
        offset = dissect_gadu_gadu_new_status(tvb, pinfo, gadu_gadu_tree, offset);
1754
0
        break;
1755
1756
0
      case GG_NEW_STATUS80:
1757
0
        offset = dissect_gadu_gadu_new_status80(tvb, pinfo, gadu_gadu_tree, offset);
1758
0
        break;
1759
1760
0
      case GG_DCC7_ID_REQUEST:
1761
0
        offset = dissect_gadu_gadu_dcc7_id_request(tvb, pinfo, gadu_gadu_tree, offset);
1762
0
        break;
1763
1764
0
      case GG_DCC7_NEW:
1765
0
        offset = dissect_gadu_gadu_dcc7_new(tvb, pinfo, gadu_gadu_tree, offset);
1766
0
        break;
1767
1768
0
      case GG_DCC7_ID_ABORT:
1769
0
        offset = dissect_gadu_gadu_dcc7_id_abort(tvb, pinfo, gadu_gadu_tree, offset);
1770
0
        break;
1771
1772
0
      case GG_USERLIST_REQUEST80:
1773
0
        offset = dissect_gadu_gadu_userlist_request80(tvb, pinfo, gadu_gadu_tree, offset);
1774
0
        break;
1775
1776
1
      case GG_USERLIST100_REQUEST:
1777
1
        offset = dissect_gadu_gadu_userlist_request100(tvb, pinfo, gadu_gadu_tree, offset);
1778
1
        break;
1779
1780
0
      case GG_PUBDIR50_REQUEST:
1781
0
        offset = dissect_gadu_gadu_pubdir50_request(tvb, pinfo, gadu_gadu_tree, offset);
1782
0
        break;
1783
1784
0
      case GG_PONG:
1785
0
      case GG_LOGIN_EXT:
1786
0
      case GG_LOGIN60:
1787
0
      case GG_USERLIST_REQUEST:
1788
0
      case GG_DCC7_INFO:
1789
0
      case GG_DCC7_ACCEPT:
1790
0
      case GG_DCC7_REJECT:
1791
0
      case GG_DCC7_ID_DUNNO1:
1792
0
      case GG_NEW_STATUS80BETA:
1793
0
      case GG_LOGIN80BETA:
1794
0
      case GG_OWN_DISCONNECT:
1795
0
      case GG_NEW_STATUS105:
1796
0
      case GG_LOGIN105:
1797
4
      default:
1798
4
      {
1799
4
        const char *pkt_name = try_val_to_str(pkt_type, gadu_gadu_packets_type_send);
1800
1801
4
        if (pkt_name)
1802
0
          col_set_str(pinfo->cinfo, COL_INFO, pkt_name);
1803
4
        else
1804
4
          col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown send packet: %.2x", pkt_type);
1805
4
        break;
1806
0
      }
1807
5
    }
1808
5
  }
1809
1810
  /* for now display rest of data as FT_BYTES. */
1811
13
  if (tvb_reported_length_remaining(tvb, offset) > 0) {
1812
3
    proto_tree_add_item(gadu_gadu_tree, hf_gadu_gadu_data, tvb, offset, -1, ENC_NA);
1813
3
  }
1814
1815
13
  return tvb_captured_length(tvb);
1816
14
}
1817
1818
static unsigned
1819
get_gadu_gadu_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
1820
                      int offset, void *data _U_)
1821
15
{
1822
15
  uint32_t len = tvb_get_letohl(tvb, offset + 4);
1823
1824
15
  return len + 8;
1825
15
}
1826
1827
static int
1828
dissect_gadu_gadu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1829
5
{
1830
5
  if (pinfo->srcport == pinfo->match_uint && pinfo->destport != pinfo->match_uint)
1831
4
    pinfo->p2p_dir = P2P_DIR_RECV;
1832
1
  else if (pinfo->srcport != pinfo->match_uint && pinfo->destport == pinfo->match_uint)
1833
1
    pinfo->p2p_dir = P2P_DIR_SENT;
1834
0
  else
1835
0
    return 0;
1836
1837
5
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gadu-Gadu");
1838
5
  col_clear(pinfo->cinfo, COL_INFO);
1839
1840
5
  tcp_dissect_pdus(tvb, pinfo, tree, gadu_gadu_desegment, 8, get_gadu_gadu_pdu_len, dissect_gadu_gadu_pdu, data);
1841
5
  return tvb_captured_length(tvb);
1842
5
}
1843
1844
void
1845
proto_register_gadu_gadu(void)
1846
14
{
1847
14
  static hf_register_info hf[] = {
1848
14
    { &hf_gadu_gadu_header_type_recv,
1849
14
      { "Packet Type", "gadu-gadu.recv",
1850
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_packets_type_recv), 0x0,
1851
14
        "Packet Type (recv)", HFILL }
1852
14
    },
1853
14
    { &hf_gadu_gadu_header_type_send,
1854
14
      { "Packet Type", "gadu-gadu.send",
1855
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_packets_type_send), 0x0,
1856
14
        "Packet Type (send)", HFILL }
1857
14
    },
1858
14
    { &hf_gadu_gadu_header_length,
1859
14
      { "Packet Length", "gadu-gadu.len",
1860
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1861
14
        NULL, HFILL }
1862
14
    },
1863
14
    { &hf_gadu_gadu_login_uin,
1864
14
      { "Client UIN", "gadu-gadu.login.uin",
1865
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1866
14
        NULL, HFILL }
1867
14
    },
1868
14
    { &hf_gadu_gadu_login_hash_type,
1869
14
      { "Login hash type", "gadu-gadu.login.hash_type",
1870
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_hash_type_vals), 0x00,
1871
14
        NULL, HFILL }
1872
14
    },
1873
14
    { &hf_gadu_gadu_login_hash,
1874
14
      { "Login hash", "gadu-gadu.login.hash",
1875
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
1876
14
        NULL, HFILL }
1877
14
    },
1878
14
    { &hf_gadu_gadu_login_status,
1879
14
      { "Client status", "gadu-gadu.login.status",
1880
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1881
14
        NULL, HFILL }
1882
14
    },
1883
14
    { &hf_gadu_gadu_login_protocol,
1884
14
      { "Client protocol", "gadu-gadu.login.protocol",
1885
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1886
14
        NULL, HFILL }
1887
14
    },
1888
14
    { &hf_gadu_gadu_login_version,
1889
14
      { "Client version", "gadu-gadu.login.version",
1890
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1891
14
        NULL, HFILL }
1892
14
    },
1893
14
    { &hf_gadu_gadu_login_local_ip,
1894
14
      { "Client local IP", "gadu-gadu.login.local_ip",
1895
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
1896
14
        NULL, HFILL }
1897
14
    },
1898
14
    { &hf_gadu_gadu_login_local_port,
1899
14
      { "Client local port", "gadu-gadu.login.local_port",
1900
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
1901
14
        NULL, HFILL }
1902
14
    },
1903
14
    { &hf_gadu_gadu_login80_lang,
1904
14
      { "Client language", "gadu-gadu.login80.lang",
1905
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1906
14
        NULL, HFILL }
1907
14
    },
1908
14
    { &hf_gadu_gadu_userdata_uin,
1909
14
      { "UIN", "gadu-gadu.user_data.uin",
1910
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1911
14
        NULL, HFILL }
1912
14
    },
1913
14
    { &hf_gadu_gadu_userdata_attr_name,
1914
14
      { "Attribute name", "gadu-gadu.user_data.attr_name",
1915
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1916
14
        NULL, HFILL }
1917
14
    },
1918
14
    { &hf_gadu_gadu_userdata_attr_type,
1919
14
      { "Attribute type", "gadu-gadu.user_data.attr_type",
1920
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1921
14
        NULL, HFILL }
1922
14
    },
1923
14
    { &hf_gadu_gadu_userdata_attr_value,
1924
14
      { "Attribute value", "gadu-gadu.user_data.attr_val",
1925
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1926
14
        NULL, HFILL }
1927
14
    },
1928
14
    { &hf_gadu_gadu_typing_notify_type,
1929
14
      { "Typing notify type", "gadu-gadu.typing_notify.type",
1930
14
        FT_UINT16, BASE_HEX, VALS(gadu_gadu_typing_notify_type_vals), 0x00,
1931
14
        NULL, HFILL }
1932
14
    },
1933
14
    { &hf_gadu_gadu_typing_notify_uin,
1934
14
      { "Typing notify recipient", "gadu-gadu.typing_notify.uin",
1935
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1936
14
        NULL, HFILL }
1937
14
    },
1938
14
    { &hf_gadu_gadu_msg_uin,
1939
14
      { "Message sender or recipient", "gadu-gadu.msg.uin",
1940
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1941
14
        NULL, HFILL }
1942
14
    },
1943
14
    { &hf_gadu_gadu_msg_sender,
1944
14
      { "Message sender", "gadu-gadu.msg.sender",
1945
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1946
14
        NULL, HFILL }
1947
14
    },
1948
14
    { &hf_gadu_gadu_msg_recipient,
1949
14
      { "Message recipient", "gadu-gadu.msg.recipient",
1950
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1951
14
        NULL, HFILL }
1952
14
    },
1953
14
    { &hf_gadu_gadu_msg_seq,
1954
14
      { "Message sequence number", "gadu-gadu.msg.seq",
1955
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1956
14
        NULL, HFILL }
1957
14
    },
1958
14
    { &hf_gadu_gadu_msg_time,
1959
14
      { "Message time", "gadu-gadu.msg.time",
1960
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
1961
14
        NULL, HFILL }
1962
14
    },
1963
14
    { &hf_gadu_gadu_msg_class,
1964
14
      { "Message class", "gadu-gadu.msg.class",
1965
14
        FT_UINT32, BASE_HEX, NULL, 0x0,
1966
14
        NULL, HFILL }
1967
14
    },
1968
14
    { &hf_gadu_gadu_msg_text,
1969
14
      { "Message text", "gadu-gadu.msg.text",
1970
14
        FT_STRINGZ, BASE_NONE, NULL, 0x0,
1971
14
        NULL, HFILL }
1972
14
    },
1973
14
    { &hf_gadu_gadu_msg80_offset_plain,
1974
14
      { "Message plaintext offset", "gadu-gadu.msg80.offset_plain",
1975
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1976
14
        NULL, HFILL }
1977
14
    },
1978
14
    { &hf_gadu_gadu_msg80_offset_attr,
1979
14
      { "Message attribute offset", "gadu-gadu.msg80.offset_attributes",
1980
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1981
14
        NULL, HFILL }
1982
14
    },
1983
14
    { &hf_gadu_gadu_msg_ack_status,
1984
14
      { "Message status", "gadu-gadu.msg_ack.status",
1985
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_msg_ack_status_vals), 0x00,
1986
14
        NULL, HFILL }
1987
14
    },
1988
14
    { &hf_gadu_gadu_msg_ack_recipient,
1989
14
      { "Message recipient", "gadu-gadu.msg_ack.recipient",
1990
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1991
14
        NULL, HFILL }
1992
14
    },
1993
14
    { &hf_gadu_gadu_msg_ack_seq,
1994
14
      { "Message sequence number", "gadu-gadu.msg_ack.seq",
1995
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1996
14
        NULL, HFILL }
1997
14
    },
1998
14
    { &hf_gadu_gadu_status_uin,
1999
14
      { "UIN", "gadu-gadu.status.uin",
2000
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2001
14
        NULL, HFILL }
2002
14
    },
2003
14
    { &hf_gadu_gadu_status_status,
2004
14
      { "Status", "gadu-gadu.status.status",
2005
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2006
14
        NULL, HFILL }
2007
14
    },
2008
14
    { &hf_gadu_gadu_status_ip,
2009
14
      { "IP", "gadu-gadu.status.remote_ip",
2010
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
2011
14
        NULL, HFILL }
2012
14
    },
2013
14
    { &hf_gadu_gadu_status_port,
2014
14
      { "Port", "gadu-gadu.status.remote_port",
2015
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
2016
14
        NULL, HFILL }
2017
14
    },
2018
14
    { &hf_gadu_gadu_status_version,
2019
14
      { "Version", "gadu-gadu.status.version",
2020
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
2021
14
        NULL, HFILL }
2022
14
    },
2023
14
    { &hf_gadu_gadu_status_img_size,
2024
14
      { "Image size", "gadu-gadu.status.image_size",
2025
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
2026
14
        "Maximum image size in KB", HFILL }
2027
14
    },
2028
14
    { &hf_gadu_gadu_status_descr,
2029
14
      { "Description", "gadu-gadu.status.description",
2030
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2031
14
        NULL, HFILL }
2032
14
    },
2033
14
    { &hf_dcc_type,
2034
14
      { "Direct connection type", "gadu-gadu.dcc.type",
2035
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_dcc_type_vals), 0x00,
2036
14
        NULL, HFILL }
2037
14
    },
2038
14
    { &hf_dcc_id,
2039
14
      { "Direct connection id", "gadu-gadu.dcc.id",
2040
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
2041
14
        NULL, HFILL }
2042
14
    },
2043
14
    { &hf_dcc_uin_to,
2044
14
      { "Direct connection UIN target", "gadu-gadu.dcc.uin_to",
2045
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2046
14
        NULL, HFILL }
2047
14
    },
2048
14
    { &hf_dcc_uin_from,
2049
14
      { "Direct connection UIN initiator", "gadu-gadu.dcc.uin_from",
2050
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2051
14
        NULL, HFILL }
2052
14
    },
2053
14
    { &hf_dcc_filename,
2054
14
      { "Direct connection filename", "gadu-gadu.dcc.filename",
2055
14
        FT_STRING, BASE_NONE, NULL, 0x00,
2056
14
        NULL, HFILL }
2057
14
    },
2058
14
    { &hf_gadu_gadu_new_status_status,
2059
14
      { "Status", "gadu-gadu.new_status.status",
2060
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2061
14
        NULL, HFILL }
2062
14
    },
2063
14
    { &hf_gadu_gadu_new_status_desc,
2064
14
      { "Description", "gadu-gadu.new_status.description",
2065
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2066
14
        NULL, HFILL }
2067
14
    },
2068
14
    { &hf_gadu_gadu_userlist_request_type,
2069
14
      { "Request type", "gadu-gadu.userlist.request_type",
2070
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_userlist_request_type_vals), 0x00,
2071
14
        NULL, HFILL }
2072
14
    },
2073
14
    { &hf_gadu_gadu_userlist_version,
2074
14
      { "Userlist version", "gadu-gadu.userlist.version",
2075
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2076
14
        NULL, HFILL }
2077
14
    },
2078
14
    { &hf_gadu_gadu_userlist_format,
2079
14
      { "Userlist format", "gadu-gadu.userlist.format",
2080
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_userlist_request_format_vals), 0x00,
2081
14
        NULL, HFILL }
2082
14
    },
2083
14
    { &hf_gadu_gadu_userlist_reply_type,
2084
14
      { "Reply type", "gadu-gadu.userlist.reply_type",
2085
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_userlist_reply_type_vals), 0x00,
2086
14
        NULL, HFILL }
2087
14
    },
2088
14
    { &hf_gadu_gadu_userlist,
2089
14
      { "Userlist XML data", "gadu-gadu.userlist",
2090
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
2091
14
        NULL, HFILL }
2092
14
    },
2093
14
    { &hf_gadu_gadu_pubdir_request_type,
2094
14
      { "Request type", "gadu-gadu.pubdir.request_type",
2095
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_pubdir_type_vals), 0x00,
2096
14
        NULL, HFILL }
2097
14
    },
2098
14
    { &hf_gadu_gadu_pubdir_request_seq,
2099
14
      { "Request sequence", "gadu-gadu.pubdir.request_seq",
2100
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2101
14
        NULL, HFILL }
2102
14
    },
2103
14
    { &hf_gadu_gadu_pubdir_request_str,
2104
14
      { "Request string", "gadu-gadu.pubdir.request_str",
2105
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2106
14
        NULL, HFILL }
2107
14
    },
2108
14
    { &hf_gadu_gadu_pubdir_reply_type,
2109
14
      { "Reply type", "gadu-gadu.pubdir.reply_type",
2110
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_pubdir_type_vals), 0x00,
2111
14
        NULL, HFILL }
2112
14
    },
2113
14
    { &hf_gadu_gadu_pubdir_reply_seq,
2114
14
      { "Reply sequence", "gadu-gadu.pubdir.reply_seq",
2115
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2116
14
        NULL, HFILL }
2117
14
    },
2118
14
    { &hf_gadu_gadu_pubdir_reply_str,
2119
14
      { "Reply string", "gadu-gadu.pubdir.reply_str",
2120
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2121
14
        NULL, HFILL }
2122
14
    },
2123
14
    { &hf_gadu_gadu_contact_uin,
2124
14
      { "UIN", "gadu-gadu.contact.uin",
2125
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2126
14
        NULL, HFILL }
2127
14
    },
2128
14
    { &hf_gadu_gadu_contact_uin_str,
2129
14
      { "UIN", "gadu-gadu.contact.uin_str",
2130
14
        FT_STRING, BASE_NONE, NULL, 0x00,
2131
14
        NULL, HFILL }
2132
14
    },
2133
14
    { &hf_gadu_gadu_contact_type,
2134
14
      { "Type", "gadu-gadu.contact.type",
2135
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
2136
14
        NULL, HFILL }
2137
14
    },
2138
14
    { &hf_gadu_gadu_welcome_seed,
2139
14
      { "Seed", "gadu-gadu.welcome.seed",
2140
14
        FT_UINT32, BASE_HEX, NULL, 0x0,
2141
14
        NULL, HFILL }
2142
14
    },
2143
14
    { &hf_gadu_gadu_data,
2144
14
      { "Packet Data", "gadu-gadu.data",
2145
14
        FT_BYTES, BASE_NONE, NULL, 0x0,
2146
14
        NULL, HFILL }
2147
14
    },
2148
14
  };
2149
2150
14
  static int *ett[] = {
2151
14
    &ett_gadu_gadu,
2152
14
    &ett_gadu_gadu_contact
2153
14
  };
2154
2155
14
  module_t *gadu_gadu_module;
2156
2157
14
  proto_gadu_gadu = proto_register_protocol("Gadu-Gadu Protocol", "Gadu-Gadu", "gadu-gadu");
2158
2159
14
  gadu_gadu_module = prefs_register_protocol(proto_gadu_gadu, NULL);
2160
14
  prefs_register_bool_preference(gadu_gadu_module, "desegment",
2161
14
      "Reassemble Gadu-Gadu messages spanning multiple TCP segments",
2162
14
      "Whether the Gadu-Gadu dissector should reassemble messages spanning multiple TCP segments."
2163
14
      "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2164
14
      &gadu_gadu_desegment);
2165
2166
14
  proto_register_field_array(proto_gadu_gadu, hf, array_length(hf));
2167
14
  proto_register_subtree_array(ett, array_length(ett));
2168
2169
14
  gadu_gadu_handle = register_dissector("gadugadu", dissect_gadu_gadu, proto_gadu_gadu);
2170
14
}
2171
2172
void
2173
proto_reg_handoff_gadu_gadu(void)
2174
14
{
2175
14
  dissector_add_uint_with_preference("tcp.port", TCP_PORT_GADU_GADU, gadu_gadu_handle);
2176
2177
14
  xml_handle = find_dissector_add_dependency("xml", proto_gadu_gadu);
2178
14
}
2179
2180
/*
2181
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2182
 *
2183
 * Local variables:
2184
 * c-basic-offset: 8
2185
 * tab-width: 8
2186
 * indent-tabs-mode: t
2187
 * End:
2188
 *
2189
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2190
 * :indentSize=8:tabSize=8:noTabs=false:
2191
 */