Coverage Report

Created: 2026-01-02 06:13

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 http://toxygen.net/libgadu/protocol/
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
1
#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
3
#define GG_DCC7_ID_REPLY            0x23
122
1
#define GG_DCC7_ID_ABORTED          0x25
123
1
#define GG_XML_EVENT                0x27
124
1
#define GG_STATUS80BETA             0x2a
125
1
#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
1
#define GG_OWN_MESSAGE              0x5A
137
1
#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 (http://toxygen.net/libgadu/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
1
#define GG_NEW_STATUS           0x02
190
0
#define GG_PONG                 0x07
191
1
#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
1
#define GG_NOTIFY_FIRST         0x0f
197
6
#define GG_NOTIFY_LAST          0x10
198
0
#define GG_LIST_EMPTY           0x12
199
1
#define GG_LOGIN_EXT            0x13
200
0
#define GG_PUBDIR50_REQUEST     0x14
201
1
#define GG_LOGIN60              0x15
202
1
#define GG_USERLIST_REQUEST     0x16
203
0
#define GG_LOGIN70              0x19
204
1
#define GG_DCC7_INFO            0x1f
205
1
#define GG_DCC7_NEW             0x20
206
1
#define GG_DCC7_ACCEPT          0x21
207
2
#define GG_DCC7_REJECT          0x22
208
1
#define GG_DCC7_ID_REQUEST      0x23
209
1
#define GG_DCC7_ID_DUNNO1       0x24
210
0
#define GG_DCC7_ID_ABORT        0x25
211
1
#define GG_NEW_STATUS80BETA     0x28
212
1
#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
2
#define GG_USERLIST100_REQUEST  0x40
218
0
#define GG_RECV_MSG_ACK         0x46
219
0
#define GG_TYPING_NOTIFY        0x59
220
1
#define GG_OWN_DISCONNECT       0x62
221
1
#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
1
#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 int
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 len;
445
0
}
446
447
static int
448
dissect_gadu_gadu_stringz_cp1250(tvbuff_t *tvb, int hfindex, proto_tree *tree, const int offset)
449
0
{
450
0
  int 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 int
458
dissect_gadu_gadu_uint32_string_utf8(tvbuff_t *tvb, int hfindex, proto_tree *tree, int offset)
459
0
{
460
0
  const int 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 int
476
dissect_gadu_gadu_disconnecting(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int 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 int
487
dissect_gadu_gadu_disconnect_ack(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int 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, int 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 int
510
dissect_gadu_gadu_login_protocol(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, int offset)
511
0
{
512
0
  proto_item *ti;
513
514
0
  uint32_t protocol;
515
516
0
  protocol = tvb_get_letohl(tvb, offset) & 0xff;
517
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_protocol, tvb, offset, 4, ENC_LITTLE_ENDIAN);
518
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)"));
519
0
  proto_item_set_generated(ti);
520
0
  offset += 4;
521
522
0
  return offset;
523
0
}
524
525
static int
526
dissect_gadu_gadu_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
527
0
{
528
0
  proto_item *ti;
529
530
0
  uint32_t uin;
531
0
  uint8_t hash[4];
532
533
0
  col_set_str(pinfo->cinfo, COL_INFO, "Login request (< 6.0)");
534
535
0
  uin = tvb_get_letohl(tvb, offset);
536
0
  gadu_gadu_create_conversation(pinfo, uin);
537
538
0
  proto_tree_add_uint(tree, hf_gadu_gadu_login_uin, tvb, offset, 4, uin);
539
0
  offset += 4;
540
541
0
  ti = proto_tree_add_uint(tree, hf_gadu_gadu_login_hash_type, tvb, 0, 0, GG_LOGIN_HASH_GG32);
542
0
  proto_item_set_generated(ti);
543
544
  /* hash is 32-bit number written in LE */
545
0
  _tvb_memcpy_reverse(tvb, hash, offset, 4);
546
0
  proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_login_hash, tvb, offset, 4, hash, "0x%.8x", tvb_get_letohl(tvb, offset));
547
0
  offset += 4;
548
549
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
550
0
  offset += 4;
551
552
0
  offset = dissect_gadu_gadu_login_protocol(tvb, pinfo, tree, offset);
553
554
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
555
0
  offset += 4;
556
557
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_local_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
558
0
  offset += 2;
559
560
0
  return offset;
561
0
}
562
563
static int
564
dissect_gadu_gadu_login_hash(tvbuff_t *tvb, proto_tree *tree, int offset)
565
0
{
566
0
  uint8_t hash_type;
567
568
0
  uint8_t hash[4];
569
0
  int i;
570
571
0
  hash_type = tvb_get_uint8(tvb, offset);
572
0
  proto_tree_add_item(tree, hf_gadu_gadu_login_hash_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
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 int
608
dissect_gadu_gadu_login70(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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, int 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_, int offset)
669
1
{
670
1
  col_set_str(pinfo->cinfo, COL_INFO, "Login success (< 8.0)");
671
672
  /* not empty packet, but content unknown */
673
674
1
  return offset;
675
1
}
676
677
static int
678
dissect_gadu_gadu_login_failed(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int 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, int 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, int 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, int 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 int
759
dissect_gadu_gadu_typing_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
774
dissect_gadu_gadu_msg_attr(tvbuff_t *tvb _U_, proto_tree *tree _U_, int offset)
775
0
{
776
  /* XXX, stub */
777
778
0
  return offset;
779
0
}
780
781
static int
782
dissect_gadu_gadu_recv_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
820
dissect_gadu_gadu_send_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
858
dissect_gadu_gadu_recv_msg80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
900
dissect_gadu_gadu_send_msg80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
942
dissect_gadu_gadu_send_msg_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
959
dissect_gadu_gadu_recv_msg_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int 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 int
970
dissect_gadu_gadu_status60(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
971
0
{
972
0
  uint32_t uin;
973
0
  uint8_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
  status = tvb_get_uint8(tvb, offset);
982
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
983
0
  offset += 1;
984
985
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
986
0
  offset += 4;
987
988
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
989
0
  offset += 2;
990
991
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
992
0
  offset += 1;
993
994
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
995
0
  offset += 1;
996
997
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 00 */
998
0
  offset += 1;
999
1000
0
  if (gadu_gadu_status_has_descr(status))
1001
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1002
1003
0
  return offset;
1004
0
}
1005
1006
static int
1007
dissect_gadu_gadu_status77(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1008
0
{
1009
0
  uint32_t uin;
1010
0
  uint8_t status;
1011
1012
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status (7.7)");
1013
1014
0
  uin = tvb_get_letohl(tvb, offset) & ~(GG_ERA_OMNIX_MASK | GG_HAS_AUDIO_MASK);
1015
0
  proto_tree_add_uint(tree, hf_gadu_gadu_status_uin, tvb, offset, 4, uin);
1016
0
  offset += 4;
1017
1018
0
  status = tvb_get_uint8(tvb, offset);
1019
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1020
0
  offset += 1;
1021
1022
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1023
0
  offset += 4;
1024
1025
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1026
0
  offset += 2;
1027
1028
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1029
0
  offset += 1;
1030
1031
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1032
0
  offset += 1;
1033
1034
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 00 */
1035
0
  offset += 1;
1036
1037
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1038
0
  offset += 4;
1039
1040
0
  if (gadu_gadu_status_has_descr(status))
1041
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1042
1043
0
  return offset;
1044
0
}
1045
1046
static int
1047
dissect_gadu_gadu_status80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1048
0
{
1049
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status (8.0)");
1050
1051
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1052
0
  offset += 4;
1053
1054
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1055
0
  offset += 4;
1056
1057
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1058
0
  offset += 4;
1059
1060
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1061
0
  offset += 4;
1062
1063
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_port, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1064
0
  offset += 2;
1065
1066
0
  proto_tree_add_item(tree, hf_gadu_gadu_status_img_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1067
0
  offset += 1;
1068
1069
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);
1070
0
  offset += 1;
1071
1072
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1073
0
  offset += 4;
1074
1075
0
  offset = dissect_gadu_gadu_uint32_string_utf8(tvb, hf_gadu_gadu_status_descr, tree, offset);
1076
1077
0
  return offset;
1078
0
}
1079
1080
static int
1081
dissect_gadu_gadu_notify_reply80(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int offset)
1082
0
{
1083
0
  col_set_str(pinfo->cinfo, COL_INFO, "Receive status list (8.0)");
1084
1085
  /* XXX packet not fully dissected */
1086
1087
0
  return offset;
1088
0
}
1089
1090
static int
1091
dissect_gadu_gadu_new_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1092
1
{
1093
1
  uint32_t status;
1094
1095
1
  col_set_str(pinfo->cinfo, COL_INFO, "New status (< 8.0)");
1096
1097
1
  status = tvb_get_letohl(tvb, offset);
1098
1
  proto_tree_add_item(tree, hf_gadu_gadu_new_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1099
1
  offset += 4;
1100
1101
1
  if (gadu_gadu_status_has_descr(status & 0xff))
1102
0
    offset = dissect_gadu_gadu_stringz_cp1250(tvb, hf_gadu_gadu_status_descr, tree, offset);
1103
1104
1
  return offset;
1105
1
}
1106
1107
static int
1108
dissect_gadu_gadu_new_status80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1109
0
{
1110
0
  col_set_str(pinfo->cinfo, COL_INFO, "New status (8.0)");
1111
1112
0
  proto_tree_add_item(tree, hf_gadu_gadu_new_status_status, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1113
0
  offset += 4;
1114
1115
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 4, ENC_NA);
1116
0
  offset += 4;
1117
1118
0
  offset = dissect_gadu_gadu_uint32_string_utf8(tvb, hf_gadu_gadu_new_status_desc, tree, offset);
1119
1120
0
  return offset;
1121
0
}
1122
1123
static int
1124
dissect_gadu_gadu_list_empty(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int offset)
1125
0
{
1126
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (empty)");
1127
1128
  /* empty packet */
1129
1130
0
  return offset;
1131
0
}
1132
1133
static int
1134
dissect_gadu_gadu_add_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1135
0
{
1136
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list add");
1137
1138
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1139
0
  offset += 4;
1140
1141
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1142
0
  offset += 1;
1143
1144
0
  return offset;
1145
0
}
1146
1147
static int
1148
dissect_gadu_gadu_notify105_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, char **puin)
1149
0
{
1150
0
  uint16_t uin_len;
1151
0
  char *uin;
1152
1153
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA); /* unknown 00 */
1154
0
  offset += 1;
1155
1156
0
  uin_len = tvb_get_uint8(tvb, offset);
1157
0
  offset += 1;
1158
0
  uin = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, uin_len, ENC_ASCII | ENC_NA);
1159
0
  proto_tree_add_string(tree, hf_gadu_gadu_contact_uin_str, tvb, offset - 1, 1 + uin_len, uin);
1160
0
  offset += uin_len;
1161
0
  if (puin)
1162
0
    *puin = uin;
1163
1164
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1165
0
  offset += 1;
1166
1167
0
  return offset;
1168
0
}
1169
1170
static int
1171
dissect_gadu_gadu_add_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1172
0
{
1173
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list add (10.5)");
1174
1175
0
  return dissect_gadu_gadu_notify105_common(tvb, pinfo, tree, offset, NULL);
1176
0
}
1177
1178
static int
1179
dissect_gadu_gadu_remove_notify(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1180
0
{
1181
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list remove");
1182
1183
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1184
0
  offset += 4;
1185
1186
0
  proto_tree_add_item(tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1187
0
  offset += 1;
1188
1189
0
  return offset;
1190
0
}
1191
1192
static int
1193
dissect_gadu_gadu_remove_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1194
0
{
1195
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list remove (10.5)");
1196
1197
0
  return dissect_gadu_gadu_notify105_common(tvb, pinfo, tree, offset, NULL);
1198
0
}
1199
1200
static int
1201
dissect_gadu_gadu_notify_common(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1202
7
{
1203
7
  proto_tree *contact_tree;
1204
1205
31
  while (tvb_reported_length_remaining(tvb, offset) >= 4+1) {
1206
24
    uint32_t uin = tvb_get_letohl(tvb, offset);
1207
1208
24
    contact_tree = proto_tree_add_subtree_format(tree, tvb, offset, 5,
1209
24
                ett_gadu_gadu_contact, NULL, "Contact: %u", uin);
1210
1211
24
    proto_tree_add_item(contact_tree, hf_gadu_gadu_contact_uin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1212
24
    offset += 4;
1213
1214
24
    proto_tree_add_item(contact_tree, hf_gadu_gadu_contact_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1215
24
    offset += 1;
1216
24
  }
1217
1218
7
  return offset;
1219
7
}
1220
1221
static int
1222
dissect_gadu_gadu_notify_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1223
1
{
1224
1
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list");
1225
1226
1
  return dissect_gadu_gadu_notify_common(tvb, pinfo, tree, offset);
1227
1
}
1228
1229
static int
1230
dissect_gadu_gadu_notify_last(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1231
6
{
1232
6
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (last)");
1233
1234
6
  return dissect_gadu_gadu_notify_common(tvb, pinfo, tree, offset);
1235
6
}
1236
1237
static int
1238
dissect_gadu_gadu_notify105(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1239
0
{
1240
0
  col_set_str(pinfo->cinfo, COL_INFO, "Notify list (10.5)");
1241
1242
0
  while (tvb_reported_length_remaining(tvb, offset) >= 2) {
1243
0
    const int org_offset = offset;
1244
1245
0
    proto_tree *contact_tree;
1246
0
    proto_item *ti;
1247
1248
0
    char *uin;
1249
1250
0
    contact_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_gadu_gadu_contact, &ti, "Contact: ");
1251
1252
0
    offset = dissect_gadu_gadu_notify105_common(tvb, pinfo, contact_tree, offset, &uin);
1253
0
    proto_item_append_text(ti, "%s", uin);
1254
1255
0
    proto_item_set_len(ti, offset - org_offset);
1256
0
  }
1257
1258
0
  return offset;
1259
0
}
1260
1261
static int
1262
dissect_gadu_gadu_ping(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree _U_, int offset)
1263
1
{
1264
1
  col_set_str(pinfo->cinfo, COL_INFO, "Ping");
1265
1266
  /* empty packet */
1267
1268
1
  return offset;
1269
1
}
1270
1271
static int
1272
dissect_gadu_gadu_welcome(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1273
0
{
1274
0
  col_set_str(pinfo->cinfo, COL_INFO, "Welcome");
1275
1276
0
  proto_tree_add_item(tree, hf_gadu_gadu_welcome_seed, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1277
0
  offset += 4;
1278
1279
0
  return offset;
1280
0
}
1281
1282
static int
1283
dissect_gadu_gadu_userlist_xml_compressed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1284
0
{
1285
0
  int remain = tvb_reported_length_remaining(tvb, offset);
1286
0
  tvbuff_t *uncomp_tvb;
1287
1288
0
  if (remain <= 0)
1289
0
    return offset;
1290
1291
0
  if ((uncomp_tvb = tvb_child_uncompress_zlib(tvb, tvb, offset, remain))) {
1292
0
    proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_userlist, tvb, offset, remain, NULL, "%s", "[Decompression succeeded]");
1293
1294
0
    add_new_data_source(pinfo, uncomp_tvb, "Uncompressed userlist");
1295
1296
    /* XXX add DTD (pinfo->match_string) */
1297
0
    call_dissector_only(xml_handle, uncomp_tvb, pinfo, tree, NULL);
1298
0
  } else
1299
0
    proto_tree_add_bytes_format_value(tree, hf_gadu_gadu_userlist, tvb, offset, remain, NULL, "%s", "[Error: Decompression failed] (or no zlib)");
1300
1301
0
  offset += remain;
1302
1303
0
  return offset;
1304
0
}
1305
1306
static int
1307
dissect_gadu_gadu_userlist_request80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1308
0
{
1309
0
  uint8_t type;
1310
0
  proto_item *ti;
1311
1312
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist request (8.0)");
1313
1314
0
  type = tvb_get_uint8(tvb, offset);
1315
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1316
0
  offset += 1;
1317
1318
0
  ti = proto_tree_add_uint(tree, hf_gadu_gadu_userlist_format, tvb, 0, 0, GG_USERLIST100_FORMAT_TYPE_GG100);
1319
0
  proto_item_set_generated(ti);
1320
1321
0
  switch (type) {
1322
0
    case GG_USERLIST_PUT:
1323
0
      offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1324
0
      break;
1325
0
  }
1326
1327
0
  return offset;
1328
0
}
1329
1330
static int
1331
dissect_gadu_gadu_userlist_request100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1332
2
{
1333
2
  uint8_t type, format;
1334
1335
2
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist request (10.0)");
1336
1337
2
  type = tvb_get_uint8(tvb, offset);
1338
2
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1339
2
  offset += 1;
1340
1341
2
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1342
2
  offset += 4;
1343
1344
2
  format = tvb_get_uint8(tvb, offset);
1345
2
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1346
2
  offset += 1;
1347
1348
2
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 01 */
1349
2
  offset += 1;
1350
1351
2
  switch (type) {
1352
0
    case GG_USERLIST_PUT:
1353
0
      if (format == GG_USERLIST100_FORMAT_TYPE_GG100)
1354
0
        offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1355
0
      break;
1356
2
  }
1357
1358
0
  return offset;
1359
2
}
1360
1361
static int
1362
dissect_gadu_gadu_userlist_reply80(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1363
0
{
1364
0
  uint8_t type;
1365
1366
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist reply (8.0)");
1367
1368
0
  type = tvb_get_uint8(tvb, offset);
1369
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1370
0
  offset += 1;
1371
1372
0
  switch (type) {
1373
0
    case GG_USERLIST_GET_REPLY:
1374
0
      offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1375
0
      break;
1376
0
  }
1377
1378
0
  return offset;
1379
0
}
1380
1381
static int
1382
dissect_gadu_gadu_userlist_reply100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1383
0
{
1384
0
  uint8_t type, format;
1385
1386
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist reply (10.0)");
1387
1388
0
  type = tvb_get_uint8(tvb, offset);
1389
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1390
0
  offset += 1;
1391
1392
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1393
0
  offset += 4;
1394
1395
0
  format = tvb_get_uint8(tvb, offset);
1396
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_format, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1397
0
  offset += 1;
1398
1399
0
  proto_tree_add_item(tree, hf_gadu_gadu_data, tvb, offset, 1, ENC_NA);  /* 01 */
1400
0
  offset += 1;
1401
1402
0
  switch (type) {
1403
0
    case GG_USERLIST_GET_REPLY:
1404
0
      if (format == GG_USERLIST100_FORMAT_TYPE_GG100)
1405
0
        offset = dissect_gadu_gadu_userlist_xml_compressed(tvb, pinfo, tree, offset);
1406
0
      break;
1407
0
  }
1408
1409
0
  return offset;
1410
0
}
1411
1412
static int
1413
dissect_gadu_gadu_userlist_version100(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1414
0
{
1415
0
  col_set_str(pinfo->cinfo, COL_INFO, "Userlist version (10.0)");
1416
1417
0
  proto_tree_add_item(tree, hf_gadu_gadu_userlist_version, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1418
0
  offset += 4;
1419
1420
0
  return offset;
1421
0
}
1422
1423
static int
1424
dissect_gadu_gadu_dcc7_id_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1425
1
{
1426
1
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection id request");
1427
1428
1
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1429
1
  offset += 4;
1430
1431
1
  return offset;
1432
1
}
1433
1434
static int
1435
dissect_gadu_gadu_dcc7_id_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1436
3
{
1437
3
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection id reply");
1438
1439
3
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1440
3
  offset += 4;
1441
1442
3
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1443
3
  offset += 8;
1444
1445
3
  return offset;
1446
3
}
1447
1448
static int
1449
dissect_gadu_gadu_dcc7_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1450
1
{
1451
1
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection new");
1452
1453
1
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1454
1
  offset += 8;
1455
1456
1
  proto_tree_add_item(tree, hf_dcc_uin_from, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1457
1
  offset += 4;
1458
1459
1
  proto_tree_add_item(tree, hf_dcc_uin_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1460
1
  offset += 4;
1461
1462
1
  proto_tree_add_item(tree, hf_dcc_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1463
1
  offset += 4;
1464
1465
1
  proto_tree_add_item(tree, hf_dcc_filename, tvb, offset, 255, ENC_ASCII);
1466
1
  offset += 255;
1467
1468
1
  return offset;
1469
1
}
1470
1471
static int
1472
dissect_gadu_gadu_dcc7_id_abort(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1473
0
{
1474
0
  col_set_str(pinfo->cinfo, COL_INFO, "Direct connection abort");
1475
1476
0
  proto_tree_add_item(tree, hf_dcc_id, tvb, offset, 8, ENC_NA);
1477
0
  offset += 8;
1478
1479
0
  proto_tree_add_item(tree, hf_dcc_uin_from, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1480
0
  offset += 4;
1481
1482
0
  proto_tree_add_item(tree, hf_dcc_uin_to, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1483
0
  offset += 4;
1484
1485
0
  return offset;
1486
0
}
1487
1488
static int
1489
dissect_gadu_gadu_pubdir50_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1490
0
{
1491
0
  int pos;
1492
1493
0
  col_set_str(pinfo->cinfo, COL_INFO, "Public directory request");
1494
1495
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1496
0
  offset += 1;
1497
1498
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1499
0
  offset += 4;
1500
  /* XXX, link request sequence with reply sequence */
1501
1502
0
  while ((pos = tvb_find_uint8(tvb, offset, -1, '\0')) > 0) {
1503
    /* XXX, display it better, field=value */
1504
0
    proto_tree_add_item(tree, hf_gadu_gadu_pubdir_request_str, tvb, offset, (pos - offset) + 1, ENC_WINDOWS_1250);
1505
0
    offset = pos + 1;
1506
0
  }
1507
1508
0
  return offset;
1509
0
}
1510
1511
static int
1512
dissect_gadu_gadu_pubdir50_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1513
0
{
1514
0
  int pos;
1515
1516
0
  col_set_str(pinfo->cinfo, COL_INFO, "Public directory reply");
1517
1518
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1519
0
  offset += 1;
1520
1521
0
  proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_seq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1522
0
  offset += 4;
1523
  /* XXX, link reply sequence with request sequence */
1524
1525
0
  while ((pos = tvb_find_uint8(tvb, offset, -1, '\0')) > 0) {
1526
    /* XXX, display it better, field=value */
1527
0
    proto_tree_add_item(tree, hf_gadu_gadu_pubdir_reply_str, tvb, offset, (pos - offset) + 1, ENC_WINDOWS_1250);
1528
0
    offset = pos + 1;
1529
0
  }
1530
1531
0
  return offset;
1532
0
}
1533
1534
static int
1535
dissect_gadu_gadu_xml_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1536
0
{
1537
0
  tvbuff_t *xml_tvb;
1538
0
  int ret;
1539
1540
0
  col_set_str(pinfo->cinfo, COL_INFO, "XML action message");
1541
1542
0
  xml_tvb = tvb_new_subset_remaining(tvb, offset);
1543
1544
  /* XXX add DTD (pinfo->match_string) */
1545
0
  ret = call_dissector_only(xml_handle, xml_tvb, pinfo, tree, NULL);
1546
1547
0
  return offset + ret;
1548
0
}
1549
1550
static int
1551
dissect_gadu_gadu_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1552
151
{
1553
151
  proto_tree *gadu_gadu_tree = NULL;
1554
1555
151
  int offset = 0;
1556
151
  uint32_t pkt_type;
1557
1558
151
  col_clear(pinfo->cinfo, COL_INFO); /* XXX, remove, add separator when multiple PDU */
1559
1560
151
  if (tree) {
1561
151
    proto_item *ti = proto_tree_add_item(tree, proto_gadu_gadu, tvb, 0, -1, ENC_NA);
1562
151
    gadu_gadu_tree = proto_item_add_subtree(ti, ett_gadu_gadu);
1563
151
  }
1564
1565
151
  pkt_type = tvb_get_letohl(tvb, offset);
1566
151
  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);
1567
151
  offset += 4;
1568
151
  proto_tree_add_item(gadu_gadu_tree, hf_gadu_gadu_header_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1569
151
  offset += 4;
1570
1571
151
  if (pinfo->p2p_dir == P2P_DIR_RECV) {
1572
25
    switch (pkt_type) {
1573
0
      case GG_DISCONNECTING:
1574
0
        offset = dissect_gadu_gadu_disconnecting(tvb, pinfo, gadu_gadu_tree, offset);
1575
0
        break;
1576
1577
0
      case GG_DISCONNECT_ACK:
1578
0
        offset = dissect_gadu_gadu_disconnect_ack(tvb, pinfo, gadu_gadu_tree, offset);
1579
0
        break;
1580
1581
1
      case GG_LOGIN_OK:
1582
1
        offset = dissect_gadu_gadu_login_ok(tvb, pinfo, gadu_gadu_tree, offset);
1583
1
        break;
1584
1585
0
      case GG_LOGIN_OK80:
1586
0
        offset = dissect_gadu_gadu_login_ok80(tvb, pinfo, gadu_gadu_tree, offset);
1587
0
        break;
1588
1589
0
      case GG_LOGIN_FAILED:
1590
0
        offset = dissect_gadu_gadu_login_failed(tvb, pinfo, gadu_gadu_tree, offset);
1591
0
        break;
1592
1593
0
      case GG_LOGIN80_FAILED:
1594
0
        offset = dissect_gadu_gadu_login80_failed(tvb, pinfo, gadu_gadu_tree, offset);
1595
0
        break;
1596
1597
0
      case GG_USER_DATA:
1598
0
        offset = dissect_gadu_gadu_user_data(tvb, pinfo, gadu_gadu_tree, offset);
1599
0
        break;
1600
1601
0
      case GG_TYPING_NOTIFY:
1602
0
        offset = dissect_gadu_gadu_typing_notify(tvb, pinfo, gadu_gadu_tree, offset);
1603
0
        break;
1604
1605
0
      case GG_RECV_MSG:
1606
0
        offset = dissect_gadu_gadu_recv_msg(tvb, pinfo, gadu_gadu_tree, offset);
1607
0
        break;
1608
1609
0
      case GG_RECV_MSG80:
1610
0
        offset = dissect_gadu_gadu_recv_msg80(tvb, pinfo, gadu_gadu_tree, offset);
1611
0
        break;
1612
1613
0
      case GG_SEND_MSG_ACK:
1614
        /* GG_SEND_MSG_ACK is received by client */
1615
0
        offset = dissect_gadu_gadu_send_msg_ack(tvb, pinfo, gadu_gadu_tree, offset);
1616
0
        break;
1617
1618
0
      case GG_STATUS60:
1619
0
        offset = dissect_gadu_gadu_status60(tvb, pinfo, gadu_gadu_tree, offset);
1620
0
        break;
1621
1622
0
      case GG_STATUS77:
1623
0
        offset = dissect_gadu_gadu_status77(tvb, pinfo, gadu_gadu_tree, offset);
1624
0
        break;
1625
1626
0
      case GG_STATUS80:
1627
0
        offset = dissect_gadu_gadu_status80(tvb, pinfo, gadu_gadu_tree, offset);
1628
0
        break;
1629
1630
0
      case GG_NOTIFY_REPLY80:
1631
0
        offset = dissect_gadu_gadu_notify_reply80(tvb, pinfo, gadu_gadu_tree, offset);
1632
0
        break;
1633
1634
3
      case GG_DCC7_ID_REPLY:
1635
3
        offset = dissect_gadu_gadu_dcc7_id_reply(tvb, pinfo, gadu_gadu_tree, offset);
1636
3
        break;
1637
1638
0
      case GG_WELCOME:
1639
0
        offset = dissect_gadu_gadu_welcome(tvb, pinfo, gadu_gadu_tree, offset);
1640
0
        break;
1641
1642
0
      case GG_USERLIST_REPLY80:
1643
0
        offset = dissect_gadu_gadu_userlist_reply80(tvb, pinfo, gadu_gadu_tree, offset);
1644
0
        break;
1645
1646
0
      case GG_USERLIST100_REPLY:
1647
0
        offset = dissect_gadu_gadu_userlist_reply100(tvb, pinfo, gadu_gadu_tree, offset);
1648
0
        break;
1649
1650
0
      case GG_USERLIST100_VERSION:
1651
0
        offset = dissect_gadu_gadu_userlist_version100(tvb, pinfo, gadu_gadu_tree, offset);
1652
0
        break;
1653
1654
0
      case GG_PUBDIR50_REPLY:
1655
0
        offset = dissect_gadu_gadu_pubdir50_reply(tvb, pinfo, gadu_gadu_tree, offset);
1656
0
        break;
1657
1658
0
      case GG_XML_ACTION:
1659
0
        offset = dissect_gadu_gadu_xml_action(tvb, pinfo, gadu_gadu_tree, offset);
1660
0
        break;
1661
1662
0
      case GG_STATUS:
1663
0
      case GG_PONG:
1664
0
      case GG_PING:
1665
0
      case GG_NOTIFY_REPLY:
1666
0
      case GG_USERLIST_REPLY:
1667
0
      case GG_NOTIFY_REPLY60:
1668
0
      case GG_NEED_EMAIL:
1669
0
      case GG_LOGIN_HASH_TYPE_INVALID:
1670
0
      case GG_NOTIFY_REPLY77:
1671
0
      case GG_DCC7_INFO:
1672
0
      case GG_DCC7_NEW:
1673
0
      case GG_DCC7_ACCEPT:
1674
1
      case GG_DCC7_REJECT:
1675
1
      case GG_DCC7_ID_ABORTED:
1676
1
      case GG_XML_EVENT:
1677
1
      case GG_STATUS80BETA:
1678
1
      case GG_NOTIFY_REPLY80BETA:
1679
1
      case GG_OWN_MESSAGE:
1680
1
      case GG_OWN_RESOURCE_INFO:
1681
21
      default:
1682
21
      {
1683
21
        const char *pkt_name = try_val_to_str(pkt_type, gadu_gadu_packets_type_recv);
1684
1685
21
        if (pkt_name)
1686
1
          col_set_str(pinfo->cinfo, COL_INFO, pkt_name);
1687
20
        else
1688
20
          col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown recv packet: %.2x", pkt_type);
1689
21
        break;
1690
1
      }
1691
25
    }
1692
1693
126
  } else {
1694
126
    switch (pkt_type) {
1695
0
      case GG_LOGIN:
1696
0
        offset = dissect_gadu_gadu_login(tvb, pinfo, gadu_gadu_tree, offset);
1697
0
        break;
1698
1699
0
      case GG_LOGIN70:
1700
0
        offset = dissect_gadu_gadu_login70(tvb, pinfo, gadu_gadu_tree, offset);
1701
0
        break;
1702
1703
0
      case GG_LOGIN80:
1704
0
        offset = dissect_gadu_gadu_login80(tvb, pinfo, gadu_gadu_tree, offset);
1705
0
        break;
1706
1707
0
      case GG_LIST_EMPTY:
1708
0
        offset = dissect_gadu_gadu_list_empty(tvb, pinfo, gadu_gadu_tree, offset);
1709
0
        break;
1710
1711
1
      case GG_NOTIFY_FIRST:
1712
1
        offset = dissect_gadu_gadu_notify_first(tvb, pinfo, gadu_gadu_tree, offset);
1713
1
        break;
1714
1715
6
      case GG_NOTIFY_LAST:
1716
6
        offset = dissect_gadu_gadu_notify_last(tvb, pinfo, gadu_gadu_tree, offset);
1717
6
        break;
1718
1719
0
      case GG_NOTIFY105:
1720
0
        offset = dissect_gadu_gadu_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1721
0
        break;
1722
1723
0
      case GG_ADD_NOTIFY:
1724
0
        offset = dissect_gadu_gadu_add_notify(tvb, pinfo, gadu_gadu_tree, offset);
1725
0
        break;
1726
1727
0
      case GG_ADD_NOTIFY105:
1728
0
        offset = dissect_gadu_gadu_add_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1729
0
        break;
1730
1731
0
      case GG_REMOVE_NOTIFY:
1732
0
        offset = dissect_gadu_gadu_remove_notify(tvb, pinfo, gadu_gadu_tree, offset);
1733
0
        break;
1734
1735
0
      case GG_REMOVE_NOTIFY105:
1736
0
        offset = dissect_gadu_gadu_remove_notify105(tvb, pinfo, gadu_gadu_tree, offset);
1737
0
        break;
1738
1739
1
      case GG_PING:
1740
1
        offset = dissect_gadu_gadu_ping(tvb, pinfo, gadu_gadu_tree, offset);
1741
1
        break;
1742
1743
0
      case GG_TYPING_NOTIFY:
1744
0
        offset = dissect_gadu_gadu_typing_notify(tvb, pinfo, gadu_gadu_tree, offset);
1745
0
        break;
1746
1747
0
      case GG_SEND_MSG:
1748
0
        offset = dissect_gadu_gadu_send_msg(tvb, pinfo, gadu_gadu_tree, offset);
1749
0
        break;
1750
1751
0
      case GG_SEND_MSG80:
1752
0
        offset = dissect_gadu_gadu_send_msg80(tvb, pinfo, gadu_gadu_tree, offset);
1753
0
        break;
1754
1755
0
      case GG_RECV_MSG_ACK:
1756
        /* GG_RECV_MSG_ACK is send by client */
1757
0
        offset = dissect_gadu_gadu_recv_msg_ack(tvb, pinfo, gadu_gadu_tree, offset);
1758
0
        break;
1759
1760
1
      case GG_NEW_STATUS:
1761
1
        offset = dissect_gadu_gadu_new_status(tvb, pinfo, gadu_gadu_tree, offset);
1762
1
        break;
1763
1764
0
      case GG_NEW_STATUS80:
1765
0
        offset = dissect_gadu_gadu_new_status80(tvb, pinfo, gadu_gadu_tree, offset);
1766
0
        break;
1767
1768
1
      case GG_DCC7_ID_REQUEST:
1769
1
        offset = dissect_gadu_gadu_dcc7_id_request(tvb, pinfo, gadu_gadu_tree, offset);
1770
1
        break;
1771
1772
1
      case GG_DCC7_NEW:
1773
1
        offset = dissect_gadu_gadu_dcc7_new(tvb, pinfo, gadu_gadu_tree, offset);
1774
1
        break;
1775
1776
0
      case GG_DCC7_ID_ABORT:
1777
0
        offset = dissect_gadu_gadu_dcc7_id_abort(tvb, pinfo, gadu_gadu_tree, offset);
1778
0
        break;
1779
1780
0
      case GG_USERLIST_REQUEST80:
1781
0
        offset = dissect_gadu_gadu_userlist_request80(tvb, pinfo, gadu_gadu_tree, offset);
1782
0
        break;
1783
1784
2
      case GG_USERLIST100_REQUEST:
1785
2
        offset = dissect_gadu_gadu_userlist_request100(tvb, pinfo, gadu_gadu_tree, offset);
1786
2
        break;
1787
1788
0
      case GG_PUBDIR50_REQUEST:
1789
0
        offset = dissect_gadu_gadu_pubdir50_request(tvb, pinfo, gadu_gadu_tree, offset);
1790
0
        break;
1791
1792
0
      case GG_PONG:
1793
1
      case GG_LOGIN_EXT:
1794
1
      case GG_LOGIN60:
1795
1
      case GG_USERLIST_REQUEST:
1796
1
      case GG_DCC7_INFO:
1797
1
      case GG_DCC7_ACCEPT:
1798
1
      case GG_DCC7_REJECT:
1799
1
      case GG_DCC7_ID_DUNNO1:
1800
1
      case GG_NEW_STATUS80BETA:
1801
1
      case GG_LOGIN80BETA:
1802
1
      case GG_OWN_DISCONNECT:
1803
1
      case GG_NEW_STATUS105:
1804
1
      case GG_LOGIN105:
1805
113
      default:
1806
113
      {
1807
113
        const char *pkt_name = try_val_to_str(pkt_type, gadu_gadu_packets_type_send);
1808
1809
113
        if (pkt_name)
1810
1
          col_set_str(pinfo->cinfo, COL_INFO, pkt_name);
1811
112
        else
1812
112
          col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown send packet: %.2x", pkt_type);
1813
113
        break;
1814
1
      }
1815
126
    }
1816
126
  }
1817
1818
  /* for now display rest of data as FT_BYTES. */
1819
143
  if (tvb_reported_length_remaining(tvb, offset) > 0) {
1820
28
    proto_tree_add_item(gadu_gadu_tree, hf_gadu_gadu_data, tvb, offset, -1, ENC_NA);
1821
28
  }
1822
1823
143
  return tvb_captured_length(tvb);
1824
151
}
1825
1826
static unsigned
1827
get_gadu_gadu_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
1828
                      int offset, void *data _U_)
1829
154
{
1830
154
  uint32_t len = tvb_get_letohl(tvb, offset + 4);
1831
1832
154
  return len + 8;
1833
154
}
1834
1835
static int
1836
dissect_gadu_gadu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1837
27
{
1838
27
  if (pinfo->srcport == pinfo->match_uint && pinfo->destport != pinfo->match_uint)
1839
10
    pinfo->p2p_dir = P2P_DIR_RECV;
1840
17
  else if (pinfo->srcport != pinfo->match_uint && pinfo->destport == pinfo->match_uint)
1841
17
    pinfo->p2p_dir = P2P_DIR_SENT;
1842
0
  else
1843
0
    return 0;
1844
1845
27
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "Gadu-Gadu");
1846
27
  col_clear(pinfo->cinfo, COL_INFO);
1847
1848
27
  tcp_dissect_pdus(tvb, pinfo, tree, gadu_gadu_desegment, 8, get_gadu_gadu_pdu_len, dissect_gadu_gadu_pdu, data);
1849
27
  return tvb_captured_length(tvb);
1850
27
}
1851
1852
void
1853
proto_register_gadu_gadu(void)
1854
14
{
1855
14
  static hf_register_info hf[] = {
1856
14
    { &hf_gadu_gadu_header_type_recv,
1857
14
      { "Packet Type", "gadu-gadu.recv",
1858
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_packets_type_recv), 0x0,
1859
14
        "Packet Type (recv)", HFILL }
1860
14
    },
1861
14
    { &hf_gadu_gadu_header_type_send,
1862
14
      { "Packet Type", "gadu-gadu.send",
1863
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_packets_type_send), 0x0,
1864
14
        "Packet Type (send)", HFILL }
1865
14
    },
1866
14
    { &hf_gadu_gadu_header_length,
1867
14
      { "Packet Length", "gadu-gadu.len",
1868
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1869
14
        NULL, HFILL }
1870
14
    },
1871
14
    { &hf_gadu_gadu_login_uin,
1872
14
      { "Client UIN", "gadu-gadu.login.uin",
1873
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1874
14
        NULL, HFILL }
1875
14
    },
1876
14
    { &hf_gadu_gadu_login_hash_type,
1877
14
      { "Login hash type", "gadu-gadu.login.hash_type",
1878
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_hash_type_vals), 0x00,
1879
14
        NULL, HFILL }
1880
14
    },
1881
14
    { &hf_gadu_gadu_login_hash,
1882
14
      { "Login hash", "gadu-gadu.login.hash",
1883
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
1884
14
        NULL, HFILL }
1885
14
    },
1886
14
    { &hf_gadu_gadu_login_status,
1887
14
      { "Client status", "gadu-gadu.login.status",
1888
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1889
14
        NULL, HFILL }
1890
14
    },
1891
14
    { &hf_gadu_gadu_login_protocol,
1892
14
      { "Client protocol", "gadu-gadu.login.protocol",
1893
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1894
14
        NULL, HFILL }
1895
14
    },
1896
14
    { &hf_gadu_gadu_login_version,
1897
14
      { "Client version", "gadu-gadu.login.version",
1898
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1899
14
        NULL, HFILL }
1900
14
    },
1901
14
    { &hf_gadu_gadu_login_local_ip,
1902
14
      { "Client local IP", "gadu-gadu.login.local_ip",
1903
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
1904
14
        NULL, HFILL }
1905
14
    },
1906
14
    { &hf_gadu_gadu_login_local_port,
1907
14
      { "Client local port", "gadu-gadu.login.local_port",
1908
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
1909
14
        NULL, HFILL }
1910
14
    },
1911
14
    { &hf_gadu_gadu_login80_lang,
1912
14
      { "Client language", "gadu-gadu.login80.lang",
1913
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1914
14
        NULL, HFILL }
1915
14
    },
1916
14
    { &hf_gadu_gadu_userdata_uin,
1917
14
      { "UIN", "gadu-gadu.user_data.uin",
1918
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1919
14
        NULL, HFILL }
1920
14
    },
1921
14
    { &hf_gadu_gadu_userdata_attr_name,
1922
14
      { "Attribute name", "gadu-gadu.user_data.attr_name",
1923
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1924
14
        NULL, HFILL }
1925
14
    },
1926
14
    { &hf_gadu_gadu_userdata_attr_type,
1927
14
      { "Attribute type", "gadu-gadu.user_data.attr_type",
1928
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
1929
14
        NULL, HFILL }
1930
14
    },
1931
14
    { &hf_gadu_gadu_userdata_attr_value,
1932
14
      { "Attribute value", "gadu-gadu.user_data.attr_val",
1933
14
        FT_STRING, BASE_NONE, NULL, 0x00,
1934
14
        NULL, HFILL }
1935
14
    },
1936
14
    { &hf_gadu_gadu_typing_notify_type,
1937
14
      { "Typing notify type", "gadu-gadu.typing_notify.type",
1938
14
        FT_UINT16, BASE_HEX, VALS(gadu_gadu_typing_notify_type_vals), 0x00,
1939
14
        NULL, HFILL }
1940
14
    },
1941
14
    { &hf_gadu_gadu_typing_notify_uin,
1942
14
      { "Typing notify recipient", "gadu-gadu.typing_notify.uin",
1943
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1944
14
        NULL, HFILL }
1945
14
    },
1946
14
    { &hf_gadu_gadu_msg_uin,
1947
14
      { "Message sender or recipient", "gadu-gadu.msg.uin",
1948
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1949
14
        NULL, HFILL }
1950
14
    },
1951
14
    { &hf_gadu_gadu_msg_sender,
1952
14
      { "Message sender", "gadu-gadu.msg.sender",
1953
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1954
14
        NULL, HFILL }
1955
14
    },
1956
14
    { &hf_gadu_gadu_msg_recipient,
1957
14
      { "Message recipient", "gadu-gadu.msg.recipient",
1958
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1959
14
        NULL, HFILL }
1960
14
    },
1961
14
    { &hf_gadu_gadu_msg_seq,
1962
14
      { "Message sequence number", "gadu-gadu.msg.seq",
1963
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1964
14
        NULL, HFILL }
1965
14
    },
1966
14
    { &hf_gadu_gadu_msg_time,
1967
14
      { "Message time", "gadu-gadu.msg.time",
1968
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
1969
14
        NULL, HFILL }
1970
14
    },
1971
14
    { &hf_gadu_gadu_msg_class,
1972
14
      { "Message class", "gadu-gadu.msg.class",
1973
14
        FT_UINT32, BASE_HEX, NULL, 0x0,
1974
14
        NULL, HFILL }
1975
14
    },
1976
14
    { &hf_gadu_gadu_msg_text,
1977
14
      { "Message text", "gadu-gadu.msg.text",
1978
14
        FT_STRINGZ, BASE_NONE, NULL, 0x0,
1979
14
        NULL, HFILL }
1980
14
    },
1981
14
    { &hf_gadu_gadu_msg80_offset_plain,
1982
14
      { "Message plaintext offset", "gadu-gadu.msg80.offset_plain",
1983
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1984
14
        NULL, HFILL }
1985
14
    },
1986
14
    { &hf_gadu_gadu_msg80_offset_attr,
1987
14
      { "Message attribute offset", "gadu-gadu.msg80.offset_attributes",
1988
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1989
14
        NULL, HFILL }
1990
14
    },
1991
14
    { &hf_gadu_gadu_msg_ack_status,
1992
14
      { "Message status", "gadu-gadu.msg_ack.status",
1993
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_msg_ack_status_vals), 0x00,
1994
14
        NULL, HFILL }
1995
14
    },
1996
14
    { &hf_gadu_gadu_msg_ack_recipient,
1997
14
      { "Message recipient", "gadu-gadu.msg_ack.recipient",
1998
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
1999
14
        NULL, HFILL }
2000
14
    },
2001
14
    { &hf_gadu_gadu_msg_ack_seq,
2002
14
      { "Message sequence number", "gadu-gadu.msg_ack.seq",
2003
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2004
14
        NULL, HFILL }
2005
14
    },
2006
14
    { &hf_gadu_gadu_status_uin,
2007
14
      { "UIN", "gadu-gadu.status.uin",
2008
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2009
14
        NULL, HFILL }
2010
14
    },
2011
14
    { &hf_gadu_gadu_status_status,
2012
14
      { "Status", "gadu-gadu.status.status",
2013
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2014
14
        NULL, HFILL }
2015
14
    },
2016
14
    { &hf_gadu_gadu_status_ip,
2017
14
      { "IP", "gadu-gadu.status.remote_ip",
2018
14
        FT_IPv4, BASE_NONE, NULL, 0x00,
2019
14
        NULL, HFILL }
2020
14
    },
2021
14
    { &hf_gadu_gadu_status_port,
2022
14
      { "Port", "gadu-gadu.status.remote_port",
2023
14
        FT_UINT16, BASE_DEC, NULL, 0x00,
2024
14
        NULL, HFILL }
2025
14
    },
2026
14
    { &hf_gadu_gadu_status_version,
2027
14
      { "Version", "gadu-gadu.status.version",
2028
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
2029
14
        NULL, HFILL }
2030
14
    },
2031
14
    { &hf_gadu_gadu_status_img_size,
2032
14
      { "Image size", "gadu-gadu.status.image_size",
2033
14
        FT_UINT8, BASE_DEC, NULL, 0x00,
2034
14
        "Maximum image size in KB", HFILL }
2035
14
    },
2036
14
    { &hf_gadu_gadu_status_descr,
2037
14
      { "Description", "gadu-gadu.status.description",
2038
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2039
14
        NULL, HFILL }
2040
14
    },
2041
14
    { &hf_dcc_type,
2042
14
      { "Direct connection type", "gadu-gadu.dcc.type",
2043
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_dcc_type_vals), 0x00,
2044
14
        NULL, HFILL }
2045
14
    },
2046
14
    { &hf_dcc_id,
2047
14
      { "Direct connection id", "gadu-gadu.dcc.id",
2048
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
2049
14
        NULL, HFILL }
2050
14
    },
2051
14
    { &hf_dcc_uin_to,
2052
14
      { "Direct connection UIN target", "gadu-gadu.dcc.uin_to",
2053
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2054
14
        NULL, HFILL }
2055
14
    },
2056
14
    { &hf_dcc_uin_from,
2057
14
      { "Direct connection UIN initiator", "gadu-gadu.dcc.uin_from",
2058
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2059
14
        NULL, HFILL }
2060
14
    },
2061
14
    { &hf_dcc_filename,
2062
14
      { "Direct connection filename", "gadu-gadu.dcc.filename",
2063
14
        FT_STRING, BASE_NONE, NULL, 0x00,
2064
14
        NULL, HFILL }
2065
14
    },
2066
14
    { &hf_gadu_gadu_new_status_status,
2067
14
      { "Status", "gadu-gadu.new_status.status",
2068
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2069
14
        NULL, HFILL }
2070
14
    },
2071
14
    { &hf_gadu_gadu_new_status_desc,
2072
14
      { "Description", "gadu-gadu.new_status.description",
2073
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2074
14
        NULL, HFILL }
2075
14
    },
2076
14
    { &hf_gadu_gadu_userlist_request_type,
2077
14
      { "Request type", "gadu-gadu.userlist.request_type",
2078
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_userlist_request_type_vals), 0x00,
2079
14
        NULL, HFILL }
2080
14
    },
2081
14
    { &hf_gadu_gadu_userlist_version,
2082
14
      { "Userlist version", "gadu-gadu.userlist.version",
2083
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2084
14
        NULL, HFILL }
2085
14
    },
2086
14
    { &hf_gadu_gadu_userlist_format,
2087
14
      { "Userlist format", "gadu-gadu.userlist.format",
2088
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_userlist_request_format_vals), 0x00,
2089
14
        NULL, HFILL }
2090
14
    },
2091
14
    { &hf_gadu_gadu_userlist_reply_type,
2092
14
      { "Reply type", "gadu-gadu.userlist.reply_type",
2093
14
        FT_UINT32, BASE_HEX, VALS(gadu_gadu_userlist_reply_type_vals), 0x00,
2094
14
        NULL, HFILL }
2095
14
    },
2096
14
    { &hf_gadu_gadu_userlist,
2097
14
      { "Userlist XML data", "gadu-gadu.userlist",
2098
14
        FT_BYTES, BASE_NONE, NULL, 0x00,
2099
14
        NULL, HFILL }
2100
14
    },
2101
14
    { &hf_gadu_gadu_pubdir_request_type,
2102
14
      { "Request type", "gadu-gadu.pubdir.request_type",
2103
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_pubdir_type_vals), 0x00,
2104
14
        NULL, HFILL }
2105
14
    },
2106
14
    { &hf_gadu_gadu_pubdir_request_seq,
2107
14
      { "Request sequence", "gadu-gadu.pubdir.request_seq",
2108
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2109
14
        NULL, HFILL }
2110
14
    },
2111
14
    { &hf_gadu_gadu_pubdir_request_str,
2112
14
      { "Request string", "gadu-gadu.pubdir.request_str",
2113
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2114
14
        NULL, HFILL }
2115
14
    },
2116
14
    { &hf_gadu_gadu_pubdir_reply_type,
2117
14
      { "Reply type", "gadu-gadu.pubdir.reply_type",
2118
14
        FT_UINT8, BASE_HEX, VALS(gadu_gadu_pubdir_type_vals), 0x00,
2119
14
        NULL, HFILL }
2120
14
    },
2121
14
    { &hf_gadu_gadu_pubdir_reply_seq,
2122
14
      { "Reply sequence", "gadu-gadu.pubdir.reply_seq",
2123
14
        FT_UINT32, BASE_HEX, NULL, 0x00,
2124
14
        NULL, HFILL }
2125
14
    },
2126
14
    { &hf_gadu_gadu_pubdir_reply_str,
2127
14
      { "Reply string", "gadu-gadu.pubdir.reply_str",
2128
14
        FT_STRINGZ, BASE_NONE, NULL, 0x00,
2129
14
        NULL, HFILL }
2130
14
    },
2131
14
    { &hf_gadu_gadu_contact_uin,
2132
14
      { "UIN", "gadu-gadu.contact.uin",
2133
14
        FT_UINT32, BASE_DEC, NULL, 0x00,
2134
14
        NULL, HFILL }
2135
14
    },
2136
14
    { &hf_gadu_gadu_contact_uin_str,
2137
14
      { "UIN", "gadu-gadu.contact.uin_str",
2138
14
        FT_STRING, BASE_NONE, NULL, 0x00,
2139
14
        NULL, HFILL }
2140
14
    },
2141
14
    { &hf_gadu_gadu_contact_type,
2142
14
      { "Type", "gadu-gadu.contact.type",
2143
14
        FT_UINT8, BASE_HEX, NULL, 0x00,
2144
14
        NULL, HFILL }
2145
14
    },
2146
14
    { &hf_gadu_gadu_welcome_seed,
2147
14
      { "Seed", "gadu-gadu.welcome.seed",
2148
14
        FT_UINT32, BASE_HEX, NULL, 0x0,
2149
14
        NULL, HFILL }
2150
14
    },
2151
14
    { &hf_gadu_gadu_data,
2152
14
      { "Packet Data", "gadu-gadu.data",
2153
14
        FT_BYTES, BASE_NONE, NULL, 0x0,
2154
14
        NULL, HFILL }
2155
14
    },
2156
14
  };
2157
2158
14
  static int *ett[] = {
2159
14
    &ett_gadu_gadu,
2160
14
    &ett_gadu_gadu_contact
2161
14
  };
2162
2163
14
  module_t *gadu_gadu_module;
2164
2165
14
  proto_gadu_gadu = proto_register_protocol("Gadu-Gadu Protocol", "Gadu-Gadu", "gadu-gadu");
2166
2167
14
  gadu_gadu_module = prefs_register_protocol(proto_gadu_gadu, NULL);
2168
14
  prefs_register_bool_preference(gadu_gadu_module, "desegment",
2169
14
      "Reassemble Gadu-Gadu messages spanning multiple TCP segments",
2170
14
      "Whether the Gadu-Gadu dissector should reassemble messages spanning multiple TCP segments."
2171
14
      "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2172
14
      &gadu_gadu_desegment);
2173
2174
14
  proto_register_field_array(proto_gadu_gadu, hf, array_length(hf));
2175
14
  proto_register_subtree_array(ett, array_length(ett));
2176
2177
14
  gadu_gadu_handle = register_dissector("gadugadu", dissect_gadu_gadu, proto_gadu_gadu);
2178
14
}
2179
2180
void
2181
proto_reg_handoff_gadu_gadu(void)
2182
14
{
2183
14
  dissector_add_uint_with_preference("tcp.port", TCP_PORT_GADU_GADU, gadu_gadu_handle);
2184
2185
14
  xml_handle = find_dissector_add_dependency("xml", proto_gadu_gadu);
2186
14
}
2187
2188
/*
2189
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2190
 *
2191
 * Local variables:
2192
 * c-basic-offset: 8
2193
 * tab-width: 8
2194
 * indent-tabs-mode: t
2195
 * End:
2196
 *
2197
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2198
 * :indentSize=8:tabSize=8:noTabs=false:
2199
 */