2 * Routines for Gadu-Gadu dissection
3 * Copyright 2011,2012, Jakub Zawadzki <darkjames-ws@darkjames.pl>
5 * Protocol documentation available at http://toxygen.net/libgadu/protocol/
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include "packet-tcp.h"
19 void proto_register_gadu_gadu(void);
20 void proto_reg_handoff_gadu_gadu(void);
22 #define TCP_PORT_GADU_GADU 8074 /* assigned by IANA */
24 /* desegmentation of Gadu-Gadu over TCP */
25 static bool gadu_gadu_desegment
= true;
27 static dissector_handle_t gadu_gadu_handle
;
29 static int proto_gadu_gadu
;
31 static int hf_dcc_filename
;
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
;
92 static int ett_gadu_gadu
;
93 static int ett_gadu_gadu_contact
;
95 #define GG_ERA_OMNIX_MASK 0x04000000
96 #define GG_HAS_AUDIO_MASK 0x40000000
98 #define GG_WELCOME 0x01
99 #define GG_STATUS 0x02
100 #define GG_LOGIN_OK 0x03
101 #define GG_SEND_MSG_ACK 0x05
104 #define GG_LOGIN_FAILED 0x09
105 #define GG_RECV_MSG 0x0a
106 #define GG_DISCONNECTING 0x0b
107 #define GG_NOTIFY_REPLY 0x0c
108 #define GG_DISCONNECT_ACK 0x0d
109 #define GG_PUBDIR50_REPLY 0x0e
110 #define GG_STATUS60 0x0f
111 #define GG_USERLIST_REPLY 0x10
112 #define GG_NOTIFY_REPLY60 0x11
113 #define GG_NEED_EMAIL 0x14
114 #define GG_LOGIN_HASH_TYPE_INVALID 0x16
115 #define GG_STATUS77 0x17
116 #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 #define GG_DCC7_ID_REPLY 0x23
122 #define GG_DCC7_ID_ABORTED 0x25
123 #define GG_XML_EVENT 0x27
124 #define GG_STATUS80BETA 0x2a
125 #define GG_NOTIFY_REPLY80BETA 0x2b
126 #define GG_XML_ACTION 0x2c
127 #define GG_RECV_MSG80 0x2e
128 #define GG_USERLIST_REPLY80 0x30
129 #define GG_LOGIN_OK80 0x35
130 #define GG_STATUS80 0x36
131 #define GG_NOTIFY_REPLY80 0x37
132 #define GG_USERLIST100_REPLY 0x41
133 #define GG_LOGIN80_FAILED 0x43
134 #define GG_USER_DATA 0x44
135 #define GG_TYPING_NOTIFY 0x59
136 #define GG_OWN_MESSAGE 0x5A
137 #define GG_OWN_RESOURCE_INFO 0x5B
138 #define GG_USERLIST100_VERSION 0x5C
141 #define GG_TYPE_VS(x) { x, #x }
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
),
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
),
189 #define GG_NEW_STATUS 0x02
192 #define GG_SEND_MSG 0x0b
193 #define GG_LOGIN 0x0c
194 #define GG_ADD_NOTIFY 0x0d
195 #define GG_REMOVE_NOTIFY 0x0e
196 #define GG_NOTIFY_FIRST 0x0f
197 #define GG_NOTIFY_LAST 0x10
198 #define GG_LIST_EMPTY 0x12
199 #define GG_LOGIN_EXT 0x13
200 #define GG_PUBDIR50_REQUEST 0x14
201 #define GG_LOGIN60 0x15
202 #define GG_USERLIST_REQUEST 0x16
203 #define GG_LOGIN70 0x19
204 #define GG_DCC7_INFO 0x1f
205 #define GG_DCC7_NEW 0x20
206 #define GG_DCC7_ACCEPT 0x21
207 #define GG_DCC7_REJECT 0x22
208 #define GG_DCC7_ID_REQUEST 0x23
209 #define GG_DCC7_ID_DUNNO1 0x24
210 #define GG_DCC7_ID_ABORT 0x25
211 #define GG_NEW_STATUS80BETA 0x28
212 #define GG_LOGIN80BETA 0x29
213 #define GG_SEND_MSG80 0x2d
214 #define GG_USERLIST_REQUEST80 0x2f
215 #define GG_LOGIN80 0x31
216 #define GG_NEW_STATUS80 0x38
217 #define GG_USERLIST100_REQUEST 0x40
218 #define GG_RECV_MSG_ACK 0x46
219 #define GG_TYPING_NOTIFY 0x59
220 #define GG_OWN_DISCONNECT 0x62
221 #define GG_NEW_STATUS105 0x63
222 #define GG_NOTIFY105 0x78
223 #define GG_ADD_NOTIFY105 0x7b
224 #define GG_REMOVE_NOTIFY105 0x7c
225 #define GG_LOGIN105 0x83
227 static const value_string gadu_gadu_packets_type_send
[] = {
228 GG_TYPE_VS(GG_NEW_STATUS
),
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
),
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" },
277 #define GG_STATUS_NOT_AVAIL 0x01
278 #define GG_STATUS_NOT_AVAIL_DESCR 0x15
279 #define GG_STATUS_FFC 0x17
280 #define GG_STATUS_FFC_DESCR 0x18
281 #define GG_STATUS_AVAIL 0x02
282 #define GG_STATUS_AVAIL_DESCR 0x04
283 #define GG_STATUS_BUSY 0x03
284 #define GG_STATUS_BUSY_DESCR 0x05
285 #define GG_STATUS_DND 0x21
286 #define GG_STATUS_DND_DESCR 0x22
287 #define GG_STATUS_INVISIBLE 0x14
288 #define GG_STATUS_INVISIBLE_DESCR 0x16
289 #define GG_STATUS_BLOCKED 0x06
291 #define GG_LOGIN_HASH_GG32 0x01
292 #define GG_LOGIN_HASH_SHA1 0x02
294 static const value_string gadu_gadu_hash_type_vals
[] = {
295 { GG_LOGIN_HASH_GG32
, "GG32 hash" },
296 { GG_LOGIN_HASH_SHA1
, "SHA1 hash" },
300 #define GG_USERLIST_PUT 0x00
301 #define GG_USERLIST_PUT_MORE 0x01
302 #define GG_USERLIST_GET 0x02
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" },
311 #define GG_USERLIST_PUT_REPLY 0x00
312 #define GG_USERLIST_PUT_MORE_REPLY 0x02
313 #define GG_USERLIST_GET_REPLY 0x06
314 #define GG_USERLIST_GET_MORE_REPLY 0x04
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)" },
324 #define GG_USERLIST100_FORMAT_TYPE_NONE 0x00
325 #define GG_USERLIST100_FORMAT_TYPE_GG70 0x01
326 #define GG_USERLIST100_FORMAT_TYPE_GG100 0x02
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)" },
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" },
365 static const value_string gadu_gadu_dcc_type_vals
[] = {
366 { 1, "Voice transmission" },
367 { 4, "File transmission" },
371 static const value_string gadu_gadu_typing_notify_type_vals
[] = {
372 { 1, "Typing started" },
373 { 0, "Typing stopped" },
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" },
384 static dissector_handle_t xml_handle
;
386 struct gadu_gadu_conv_data
{
387 uint32_t uin
; /* uin from login packet */
390 static struct gadu_gadu_conv_data
*
391 gadu_gadu_create_conversation(packet_info
*pinfo
, uint32_t uin
)
393 conversation_t
*conv
;
394 struct gadu_gadu_conv_data
*gg_conv
;
396 conv
= find_or_create_conversation(pinfo
);
397 gg_conv
= (struct gadu_gadu_conv_data
*)conversation_get_proto_data(conv
, proto_gadu_gadu
);
399 gg_conv
= wmem_new(wmem_file_scope(), struct gadu_gadu_conv_data
);
402 conversation_add_proto_data(conv
, proto_gadu_gadu
, gg_conv
);
404 /* assert(gg_conv->uin == uin); */
408 static struct gadu_gadu_conv_data
*
409 gadu_gadu_get_conversation_data(packet_info
*pinfo
)
411 conversation_t
*conv
;
413 conv
= find_conversation_pinfo(pinfo
, 0);
415 return (struct gadu_gadu_conv_data
*)conversation_get_proto_data(conv
, proto_gadu_gadu
);
420 gadu_gadu_status_has_descr(int status
)
423 (status
== GG_STATUS_NOT_AVAIL_DESCR
) ||
424 (status
== GG_STATUS_FFC_DESCR
) ||
425 (status
== GG_STATUS_AVAIL_DESCR
) ||
426 (status
== GG_STATUS_BUSY_DESCR
) ||
427 (status
== GG_STATUS_DND_DESCR
) ||
428 (status
== GG_STATUS_INVISIBLE_DESCR
);
431 /* like tvb_strsize() but return maximum length instead of throwing exception */
433 gadu_gadu_strsize(tvbuff_t
*tvb
, const int abs_offset
)
437 nul_offset
= tvb_find_uint8(tvb
, abs_offset
, -1, 0);
438 if (nul_offset
== -1)
439 nul_offset
= tvb_captured_length(tvb
) - 1;
441 return (nul_offset
- abs_offset
) + 1;
445 dissect_gadu_gadu_stringz_cp1250(tvbuff_t
*tvb
, int hfindex
, proto_tree
*tree
, const int offset
)
447 int len
= gadu_gadu_strsize(tvb
, offset
);
449 proto_tree_add_item(tree
, hfindex
, tvb
, offset
, len
, ENC_WINDOWS_1250
| ENC_NA
);
455 dissect_gadu_gadu_uint32_string_utf8(tvbuff_t
*tvb
, int hfindex
, proto_tree
*tree
, int offset
)
457 const int org_offset
= offset
;
461 len
= tvb_get_letohl(tvb
, offset
);
466 proto_tree_add_item(tree
, hfindex
, tvb
, org_offset
, offset
- org_offset
, ENC_UTF_8
| ENC_NA
);
473 dissect_gadu_gadu_disconnecting(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
475 col_set_str(pinfo
->cinfo
, COL_INFO
, "Disconnecting");
484 dissect_gadu_gadu_disconnect_ack(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
486 col_set_str(pinfo
->cinfo
, COL_INFO
, "Disconnect acknowledge (< 10.0)");
494 _tvb_memcpy_reverse(tvbuff_t
*tvb
, void *target
, int offset
, size_t length
)
496 uint8_t *t
= (uint8_t *) target
;
500 t
[length
] = tvb_get_uint8(tvb
, offset
);
507 dissect_gadu_gadu_login_protocol(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
513 protocol
= tvb_get_letohl(tvb
, offset
) & 0xff;
514 proto_tree_add_item(tree
, hf_gadu_gadu_login_protocol
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
515 ti
= proto_tree_add_string(tree
, hf_gadu_gadu_login_version
, tvb
, offset
, 4, val_to_str(protocol
, gadu_gadu_version_vals
, "Unknown (0x%x)"));
516 proto_item_set_generated(ti
);
523 dissect_gadu_gadu_login(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
530 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login request (< 6.0)");
532 uin
= tvb_get_letohl(tvb
, offset
);
533 gadu_gadu_create_conversation(pinfo
, uin
);
535 proto_tree_add_uint(tree
, hf_gadu_gadu_login_uin
, tvb
, offset
, 4, uin
);
538 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_login_hash_type
, tvb
, 0, 0, GG_LOGIN_HASH_GG32
);
539 proto_item_set_generated(ti
);
541 /* hash is 32-bit number written in LE */
542 _tvb_memcpy_reverse(tvb
, hash
, offset
, 4);
543 proto_tree_add_bytes_format_value(tree
, hf_gadu_gadu_login_hash
, tvb
, offset
, 4, hash
, "0x%.8x", tvb_get_letohl(tvb
, offset
));
546 proto_tree_add_item(tree
, hf_gadu_gadu_login_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
549 offset
= dissect_gadu_gadu_login_protocol(tvb
, tree
, offset
);
551 proto_tree_add_item(tree
, hf_gadu_gadu_login_local_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
554 proto_tree_add_item(tree
, hf_gadu_gadu_login_local_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
561 dissect_gadu_gadu_login_hash(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
568 hash_type
= tvb_get_uint8(tvb
, offset
);
569 proto_tree_add_item(tree
, hf_gadu_gadu_login_hash_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
573 case GG_LOGIN_HASH_GG32
:
574 /* hash is 32-bit number written in LE */
575 _tvb_memcpy_reverse(tvb
, hash
, offset
, 4);
576 proto_tree_add_bytes_format_value(tree
, hf_gadu_gadu_login_hash
, tvb
, offset
, 4, hash
, "0x%.8x", tvb_get_letohl(tvb
, offset
));
577 for (i
= 4; i
< 64; i
++) {
578 if (tvb_get_uint8(tvb
, offset
+i
)) {
579 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
+ 4, 64-4, ENC_NA
);
585 case GG_LOGIN_HASH_SHA1
:
586 proto_tree_add_item(tree
, hf_gadu_gadu_login_hash
, tvb
, offset
, 20, ENC_NA
);
587 for (i
= 20; i
< 64; i
++) {
588 if (tvb_get_uint8(tvb
, offset
+i
)) {
589 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
+ 20, 64-20, ENC_NA
);
596 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 64, ENC_NA
);
605 dissect_gadu_gadu_login70(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
609 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login request (7.0)");
611 uin
= tvb_get_letohl(tvb
, offset
) & ~(GG_ERA_OMNIX_MASK
| GG_HAS_AUDIO_MASK
);
612 gadu_gadu_create_conversation(pinfo
, uin
);
614 proto_tree_add_uint(tree
, hf_gadu_gadu_login_uin
, tvb
, offset
, 4, uin
);
617 offset
= dissect_gadu_gadu_login_hash(tvb
, tree
, offset
);
619 proto_tree_add_item(tree
, hf_gadu_gadu_login_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
622 offset
= dissect_gadu_gadu_login_protocol(tvb
, tree
, offset
);
624 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* 00 */
627 proto_tree_add_item(tree
, hf_gadu_gadu_login_local_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
630 proto_tree_add_item(tree
, hf_gadu_gadu_login_local_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
633 /* XXX packet not fully dissected */
639 dissect_gadu_gadu_login80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
643 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login request (8.0)");
645 uin
= tvb_get_letohl(tvb
, offset
);
646 gadu_gadu_create_conversation(pinfo
, uin
);
648 proto_tree_add_item(tree
, hf_gadu_gadu_login_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
651 proto_tree_add_item(tree
, hf_gadu_gadu_login80_lang
, tvb
, offset
, 2, ENC_ASCII
| ENC_NA
);
654 offset
= dissect_gadu_gadu_login_hash(tvb
, tree
, offset
);
656 proto_tree_add_item(tree
, hf_gadu_gadu_login_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
659 /* XXX packet not fully dissected */
665 dissect_gadu_gadu_login_ok(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
667 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login success (< 8.0)");
669 /* not empty packet, but content unknown */
675 dissect_gadu_gadu_login_failed(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
677 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login fail (< 8.0)");
685 dissect_gadu_gadu_login_ok80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
687 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login success (8.0)");
689 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
); /* 01 00 00 00 */
696 dissect_gadu_gadu_login80_failed(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
698 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login fail (8.0)");
700 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
); /* 01 00 00 00 */
707 dissect_gadu_gadu_user_data(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
711 col_set_str(pinfo
->cinfo
, COL_INFO
, "Contact details");
713 /* XXX, add subtrees */
717 users_num
= tvb_get_letohl(tvb
, offset
);
720 while (users_num
--) {
723 proto_tree_add_item(tree
, hf_gadu_gadu_userdata_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
726 attr_num
= tvb_get_letohl(tvb
, offset
);
730 uint32_t name_size
, val_size
;
733 name_size
= tvb_get_letohl(tvb
, offset
);
736 name
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, name_size
, ENC_ASCII
| ENC_NA
);
737 proto_tree_add_string(tree
, hf_gadu_gadu_userdata_attr_name
, tvb
, offset
- 4, 4 + name_size
, name
);
740 proto_tree_add_item(tree
, hf_gadu_gadu_userdata_attr_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
743 val_size
= tvb_get_letohl(tvb
, offset
);
746 val
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, val_size
, ENC_ASCII
| ENC_NA
);
747 proto_tree_add_string(tree
, hf_gadu_gadu_userdata_attr_value
, tvb
, offset
- 4, 4 + val_size
, val
);
756 dissect_gadu_gadu_typing_notify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
758 col_set_str(pinfo
->cinfo
, COL_INFO
, "Typing notify");
760 /* XXX, when type > 1, it's length not type ! */
761 proto_tree_add_item(tree
, hf_gadu_gadu_typing_notify_type
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
764 proto_tree_add_item(tree
, hf_gadu_gadu_typing_notify_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
771 dissect_gadu_gadu_msg_attr(tvbuff_t
*tvb _U_
, proto_tree
*tree _U_
, int offset
)
779 dissect_gadu_gadu_recv_msg(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
781 struct gadu_gadu_conv_data
*conv
;
784 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive message (< 8.0)");
786 if ((conv
= gadu_gadu_get_conversation_data(pinfo
))) {
787 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_recipient
, tvb
, 0, 0, conv
->uin
);
788 proto_item_set_generated(ti
);
790 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_uin
, tvb
, 0, 0, conv
->uin
);
791 proto_item_set_generated(ti
);
792 proto_item_set_hidden(ti
);
795 ti
= proto_tree_add_item(tree
, hf_gadu_gadu_msg_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
796 proto_item_set_hidden(ti
);
797 proto_tree_add_item(tree
, hf_gadu_gadu_msg_sender
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
800 proto_tree_add_item(tree
, hf_gadu_gadu_msg_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
803 proto_tree_add_item(tree
, hf_gadu_gadu_msg_time
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
806 proto_tree_add_item(tree
, hf_gadu_gadu_msg_class
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
809 offset
= dissect_gadu_gadu_stringz_cp1250(tvb
, hf_gadu_gadu_msg_text
, tree
, offset
);
811 offset
= dissect_gadu_gadu_msg_attr(tvb
, tree
, offset
);
817 dissect_gadu_gadu_send_msg(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
819 struct gadu_gadu_conv_data
*conv
;
822 col_set_str(pinfo
->cinfo
, COL_INFO
, "Send message (< 8.0)");
824 ti
= proto_tree_add_item(tree
, hf_gadu_gadu_msg_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
825 proto_item_set_hidden(ti
);
826 proto_tree_add_item(tree
, hf_gadu_gadu_msg_recipient
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
829 if ((conv
= gadu_gadu_get_conversation_data(pinfo
))) {
830 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_sender
, tvb
, 0, 0, conv
->uin
);
831 proto_item_set_generated(ti
);
833 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_uin
, tvb
, 0, 0, conv
->uin
);
834 proto_item_set_generated(ti
);
835 proto_item_set_hidden(ti
);
838 proto_tree_add_item(tree
, hf_gadu_gadu_msg_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
841 ti
= proto_tree_add_time(tree
, hf_gadu_gadu_msg_time
, tvb
, 0, 0, &(pinfo
->abs_ts
));
842 proto_item_set_generated(ti
);
844 proto_tree_add_item(tree
, hf_gadu_gadu_msg_class
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
847 offset
= dissect_gadu_gadu_stringz_cp1250(tvb
, hf_gadu_gadu_msg_text
, tree
, offset
);
849 offset
= dissect_gadu_gadu_msg_attr(tvb
, tree
, offset
);
855 dissect_gadu_gadu_recv_msg80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
857 struct gadu_gadu_conv_data
*conv
;
860 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive message (8.0)");
862 if ((conv
= gadu_gadu_get_conversation_data(pinfo
))) {
863 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_recipient
, tvb
, 0, 0, conv
->uin
);
864 proto_item_set_generated(ti
);
866 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_uin
, tvb
, 0, 0, conv
->uin
);
867 proto_item_set_generated(ti
);
868 proto_item_set_hidden(ti
);
871 ti
= proto_tree_add_item(tree
, hf_gadu_gadu_msg_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
872 proto_item_set_hidden(ti
);
873 proto_tree_add_item(tree
, hf_gadu_gadu_msg_sender
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
876 proto_tree_add_item(tree
, hf_gadu_gadu_msg_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
879 proto_tree_add_item(tree
, hf_gadu_gadu_msg_time
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
882 proto_tree_add_item(tree
, hf_gadu_gadu_msg_class
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
885 proto_tree_add_item(tree
, hf_gadu_gadu_msg80_offset_plain
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
888 proto_tree_add_item(tree
, hf_gadu_gadu_msg80_offset_attr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
891 /* XXX packet not fully dissected */
897 dissect_gadu_gadu_send_msg80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
899 struct gadu_gadu_conv_data
*conv
;
902 col_set_str(pinfo
->cinfo
, COL_INFO
, "Send message (8.0)");
904 ti
= proto_tree_add_item(tree
, hf_gadu_gadu_msg_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
905 proto_item_set_hidden(ti
);
906 proto_tree_add_item(tree
, hf_gadu_gadu_msg_recipient
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
909 if ((conv
= gadu_gadu_get_conversation_data(pinfo
))) {
910 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_sender
, tvb
, 0, 0, conv
->uin
);
911 proto_item_set_generated(ti
);
913 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_msg_uin
, tvb
, 0, 0, conv
->uin
);
914 proto_item_set_generated(ti
);
915 proto_item_set_hidden(ti
);
918 proto_tree_add_item(tree
, hf_gadu_gadu_msg_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
921 ti
= proto_tree_add_time(tree
, hf_gadu_gadu_msg_time
, tvb
, 0, 0, &(pinfo
->abs_ts
));
922 proto_item_set_generated(ti
);
924 proto_tree_add_item(tree
, hf_gadu_gadu_msg_class
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
927 proto_tree_add_item(tree
, hf_gadu_gadu_msg80_offset_plain
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
930 proto_tree_add_item(tree
, hf_gadu_gadu_msg80_offset_attr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
933 /* XXX packet not fully dissected */
939 dissect_gadu_gadu_send_msg_ack(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
941 col_set_str(pinfo
->cinfo
, COL_INFO
, "Message acknowledge (server)");
943 proto_tree_add_item(tree
, hf_gadu_gadu_msg_ack_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
946 proto_tree_add_item(tree
, hf_gadu_gadu_msg_ack_recipient
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
949 proto_tree_add_item(tree
, hf_gadu_gadu_msg_ack_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
956 dissect_gadu_gadu_recv_msg_ack(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
958 col_set_str(pinfo
->cinfo
, COL_INFO
, "Message acknowledge (client)");
960 proto_tree_add_item(tree
, hf_gadu_gadu_msg_ack_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
967 dissect_gadu_gadu_status60(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
972 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive status (6.0)");
974 uin
= tvb_get_letohl(tvb
, offset
) & ~(GG_ERA_OMNIX_MASK
| GG_HAS_AUDIO_MASK
);
975 proto_tree_add_uint(tree
, hf_gadu_gadu_status_uin
, tvb
, offset
, 4, uin
);
978 status
= tvb_get_uint8(tvb
, offset
);
979 proto_tree_add_item(tree
, hf_gadu_gadu_status_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
982 proto_tree_add_item(tree
, hf_gadu_gadu_status_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
985 proto_tree_add_item(tree
, hf_gadu_gadu_status_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
988 proto_tree_add_item(tree
, hf_gadu_gadu_status_version
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
991 proto_tree_add_item(tree
, hf_gadu_gadu_status_img_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
994 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* 00 */
997 if (gadu_gadu_status_has_descr(status
))
998 offset
= dissect_gadu_gadu_stringz_cp1250(tvb
, hf_gadu_gadu_status_descr
, tree
, offset
);
1004 dissect_gadu_gadu_status77(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1009 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive status (7.7)");
1011 uin
= tvb_get_letohl(tvb
, offset
) & ~(GG_ERA_OMNIX_MASK
| GG_HAS_AUDIO_MASK
);
1012 proto_tree_add_uint(tree
, hf_gadu_gadu_status_uin
, tvb
, offset
, 4, uin
);
1015 status
= tvb_get_uint8(tvb
, offset
);
1016 proto_tree_add_item(tree
, hf_gadu_gadu_status_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1019 proto_tree_add_item(tree
, hf_gadu_gadu_status_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1022 proto_tree_add_item(tree
, hf_gadu_gadu_status_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1025 proto_tree_add_item(tree
, hf_gadu_gadu_status_version
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1028 proto_tree_add_item(tree
, hf_gadu_gadu_status_img_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1031 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* 00 */
1034 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
);
1037 if (gadu_gadu_status_has_descr(status
))
1038 offset
= dissect_gadu_gadu_stringz_cp1250(tvb
, hf_gadu_gadu_status_descr
, tree
, offset
);
1044 dissect_gadu_gadu_status80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1046 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive status (8.0)");
1048 proto_tree_add_item(tree
, hf_gadu_gadu_status_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1051 proto_tree_add_item(tree
, hf_gadu_gadu_status_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1054 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
);
1057 proto_tree_add_item(tree
, hf_gadu_gadu_status_ip
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1060 proto_tree_add_item(tree
, hf_gadu_gadu_status_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1063 proto_tree_add_item(tree
, hf_gadu_gadu_status_img_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1066 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
);
1069 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
);
1072 offset
= dissect_gadu_gadu_uint32_string_utf8(tvb
, hf_gadu_gadu_status_descr
, tree
, offset
);
1078 dissect_gadu_gadu_notify_reply80(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
1080 col_set_str(pinfo
->cinfo
, COL_INFO
, "Receive status list (8.0)");
1082 /* XXX packet not fully dissected */
1088 dissect_gadu_gadu_new_status(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1092 col_set_str(pinfo
->cinfo
, COL_INFO
, "New status (< 8.0)");
1094 status
= tvb_get_letohl(tvb
, offset
);
1095 proto_tree_add_item(tree
, hf_gadu_gadu_new_status_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1098 if (gadu_gadu_status_has_descr(status
& 0xff))
1099 offset
= dissect_gadu_gadu_stringz_cp1250(tvb
, hf_gadu_gadu_status_descr
, tree
, offset
);
1105 dissect_gadu_gadu_new_status80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1107 col_set_str(pinfo
->cinfo
, COL_INFO
, "New status (8.0)");
1109 proto_tree_add_item(tree
, hf_gadu_gadu_new_status_status
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1112 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 4, ENC_NA
);
1115 offset
= dissect_gadu_gadu_uint32_string_utf8(tvb
, hf_gadu_gadu_new_status_desc
, tree
, offset
);
1121 dissect_gadu_gadu_list_empty(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
1123 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list (empty)");
1131 dissect_gadu_gadu_add_notify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1133 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list add");
1135 proto_tree_add_item(tree
, hf_gadu_gadu_contact_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1138 proto_tree_add_item(tree
, hf_gadu_gadu_contact_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1145 dissect_gadu_gadu_notify105_common(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, char **puin
)
1150 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* unknown 00 */
1153 uin_len
= tvb_get_uint8(tvb
, offset
);
1155 uin
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, uin_len
, ENC_ASCII
| ENC_NA
);
1156 proto_tree_add_string(tree
, hf_gadu_gadu_contact_uin_str
, tvb
, offset
- 1, 1 + uin_len
, uin
);
1161 proto_tree_add_item(tree
, hf_gadu_gadu_contact_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1168 dissect_gadu_gadu_add_notify105(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1170 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list add (10.5)");
1172 return dissect_gadu_gadu_notify105_common(tvb
, pinfo
, tree
, offset
, NULL
);
1176 dissect_gadu_gadu_remove_notify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1178 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list remove");
1180 proto_tree_add_item(tree
, hf_gadu_gadu_contact_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1183 proto_tree_add_item(tree
, hf_gadu_gadu_contact_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1190 dissect_gadu_gadu_remove_notify105(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1192 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list remove (10.5)");
1194 return dissect_gadu_gadu_notify105_common(tvb
, pinfo
, tree
, offset
, NULL
);
1198 dissect_gadu_gadu_notify_common(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1200 proto_tree
*contact_tree
;
1202 while (tvb_reported_length_remaining(tvb
, offset
) >= 4+1) {
1203 uint32_t uin
= tvb_get_letohl(tvb
, offset
);
1205 contact_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 5,
1206 ett_gadu_gadu_contact
, NULL
, "Contact: %u", uin
);
1208 proto_tree_add_item(contact_tree
, hf_gadu_gadu_contact_uin
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1211 proto_tree_add_item(contact_tree
, hf_gadu_gadu_contact_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1219 dissect_gadu_gadu_notify_first(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1221 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list");
1223 return dissect_gadu_gadu_notify_common(tvb
, pinfo
, tree
, offset
);
1227 dissect_gadu_gadu_notify_last(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1229 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list (last)");
1231 return dissect_gadu_gadu_notify_common(tvb
, pinfo
, tree
, offset
);
1235 dissect_gadu_gadu_notify105(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1237 col_set_str(pinfo
->cinfo
, COL_INFO
, "Notify list (10.5)");
1239 while (tvb_reported_length_remaining(tvb
, offset
) >= 2) {
1240 const int org_offset
= offset
;
1242 proto_tree
*contact_tree
;
1247 contact_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_gadu_gadu_contact
, &ti
, "Contact: ");
1249 offset
= dissect_gadu_gadu_notify105_common(tvb
, pinfo
, contact_tree
, offset
, &uin
);
1250 proto_item_append_text(ti
, "%s", uin
);
1252 proto_item_set_len(ti
, offset
- org_offset
);
1259 dissect_gadu_gadu_ping(tvbuff_t
*tvb _U_
, packet_info
*pinfo
, proto_tree
*tree _U_
, int offset
)
1261 col_set_str(pinfo
->cinfo
, COL_INFO
, "Ping");
1269 dissect_gadu_gadu_welcome(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1271 col_set_str(pinfo
->cinfo
, COL_INFO
, "Welcome");
1273 proto_tree_add_item(tree
, hf_gadu_gadu_welcome_seed
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1280 dissect_gadu_gadu_userlist_xml_compressed(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1282 int remain
= tvb_reported_length_remaining(tvb
, offset
);
1283 tvbuff_t
*uncomp_tvb
;
1288 if ((uncomp_tvb
= tvb_child_uncompress_zlib(tvb
, tvb
, offset
, remain
))) {
1289 proto_tree_add_bytes_format_value(tree
, hf_gadu_gadu_userlist
, tvb
, offset
, remain
, NULL
, "%s", "[Decompression succeeded]");
1291 add_new_data_source(pinfo
, uncomp_tvb
, "Uncompressed userlist");
1293 /* XXX add DTD (pinfo->match_string) */
1294 call_dissector_only(xml_handle
, uncomp_tvb
, pinfo
, tree
, NULL
);
1296 proto_tree_add_bytes_format_value(tree
, hf_gadu_gadu_userlist
, tvb
, offset
, remain
, NULL
, "%s", "[Error: Decompression failed] (or no zlib)");
1304 dissect_gadu_gadu_userlist_request80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1309 col_set_str(pinfo
->cinfo
, COL_INFO
, "Userlist request (8.0)");
1311 type
= tvb_get_uint8(tvb
, offset
);
1312 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_request_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1315 ti
= proto_tree_add_uint(tree
, hf_gadu_gadu_userlist_format
, tvb
, 0, 0, GG_USERLIST100_FORMAT_TYPE_GG100
);
1316 proto_item_set_generated(ti
);
1319 case GG_USERLIST_PUT
:
1320 offset
= dissect_gadu_gadu_userlist_xml_compressed(tvb
, pinfo
, tree
, offset
);
1328 dissect_gadu_gadu_userlist_request100(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1330 uint8_t type
, format
;
1332 col_set_str(pinfo
->cinfo
, COL_INFO
, "Userlist request (10.0)");
1334 type
= tvb_get_uint8(tvb
, offset
);
1335 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_request_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1338 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1341 format
= tvb_get_uint8(tvb
, offset
);
1342 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_format
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1345 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* 01 */
1349 case GG_USERLIST_PUT
:
1350 if (format
== GG_USERLIST100_FORMAT_TYPE_GG100
)
1351 offset
= dissect_gadu_gadu_userlist_xml_compressed(tvb
, pinfo
, tree
, offset
);
1359 dissect_gadu_gadu_userlist_reply80(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1363 col_set_str(pinfo
->cinfo
, COL_INFO
, "Userlist reply (8.0)");
1365 type
= tvb_get_uint8(tvb
, offset
);
1366 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_reply_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1370 case GG_USERLIST_GET_REPLY
:
1371 offset
= dissect_gadu_gadu_userlist_xml_compressed(tvb
, pinfo
, tree
, offset
);
1379 dissect_gadu_gadu_userlist_reply100(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1381 uint8_t type
, format
;
1383 col_set_str(pinfo
->cinfo
, COL_INFO
, "Userlist reply (10.0)");
1385 type
= tvb_get_uint8(tvb
, offset
);
1386 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_reply_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1389 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1392 format
= tvb_get_uint8(tvb
, offset
);
1393 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_format
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1396 proto_tree_add_item(tree
, hf_gadu_gadu_data
, tvb
, offset
, 1, ENC_NA
); /* 01 */
1400 case GG_USERLIST_GET_REPLY
:
1401 if (format
== GG_USERLIST100_FORMAT_TYPE_GG100
)
1402 offset
= dissect_gadu_gadu_userlist_xml_compressed(tvb
, pinfo
, tree
, offset
);
1410 dissect_gadu_gadu_userlist_version100(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1412 col_set_str(pinfo
->cinfo
, COL_INFO
, "Userlist version (10.0)");
1414 proto_tree_add_item(tree
, hf_gadu_gadu_userlist_version
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1421 dissect_gadu_gadu_dcc7_id_request(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1423 col_set_str(pinfo
->cinfo
, COL_INFO
, "Direct connection id request");
1425 proto_tree_add_item(tree
, hf_dcc_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1432 dissect_gadu_gadu_dcc7_id_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1434 col_set_str(pinfo
->cinfo
, COL_INFO
, "Direct connection id reply");
1436 proto_tree_add_item(tree
, hf_dcc_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1439 proto_tree_add_item(tree
, hf_dcc_id
, tvb
, offset
, 8, ENC_NA
);
1446 dissect_gadu_gadu_dcc7_new(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1448 col_set_str(pinfo
->cinfo
, COL_INFO
, "Direct connection new");
1450 proto_tree_add_item(tree
, hf_dcc_id
, tvb
, offset
, 8, ENC_NA
);
1453 proto_tree_add_item(tree
, hf_dcc_uin_from
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1456 proto_tree_add_item(tree
, hf_dcc_uin_to
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1459 proto_tree_add_item(tree
, hf_dcc_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1462 proto_tree_add_item(tree
, hf_dcc_filename
, tvb
, offset
, 255, ENC_ASCII
| ENC_NA
);
1469 dissect_gadu_gadu_dcc7_id_abort(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1471 col_set_str(pinfo
->cinfo
, COL_INFO
, "Direct connection abort");
1473 proto_tree_add_item(tree
, hf_dcc_id
, tvb
, offset
, 8, ENC_NA
);
1476 proto_tree_add_item(tree
, hf_dcc_uin_from
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1479 proto_tree_add_item(tree
, hf_dcc_uin_to
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1486 dissect_gadu_gadu_pubdir50_request(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1490 col_set_str(pinfo
->cinfo
, COL_INFO
, "Public directory request");
1492 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_request_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1495 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_request_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1497 /* XXX, link request sequence with reply sequence */
1499 while ((pos
= tvb_find_uint8(tvb
, offset
, -1, '\0')) > 0) {
1500 /* XXX, display it better, field=value */
1501 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_request_str
, tvb
, offset
, (pos
- offset
) + 1, ENC_NA
| ENC_WINDOWS_1250
);
1509 dissect_gadu_gadu_pubdir50_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1513 col_set_str(pinfo
->cinfo
, COL_INFO
, "Public directory reply");
1515 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_reply_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1518 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_reply_seq
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1520 /* XXX, link reply sequence with request sequence */
1522 while ((pos
= tvb_find_uint8(tvb
, offset
, -1, '\0')) > 0) {
1523 /* XXX, display it better, field=value */
1524 proto_tree_add_item(tree
, hf_gadu_gadu_pubdir_reply_str
, tvb
, offset
, (pos
- offset
) + 1, ENC_NA
| ENC_WINDOWS_1250
);
1532 dissect_gadu_gadu_xml_action(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1537 col_set_str(pinfo
->cinfo
, COL_INFO
, "XML action message");
1539 xml_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1541 /* XXX add DTD (pinfo->match_string) */
1542 ret
= call_dissector_only(xml_handle
, xml_tvb
, pinfo
, tree
, NULL
);
1544 return offset
+ ret
;
1548 dissect_gadu_gadu_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1550 proto_tree
*gadu_gadu_tree
= NULL
;
1555 col_clear(pinfo
->cinfo
, COL_INFO
); /* XXX, remove, add separator when multiple PDU */
1558 proto_item
*ti
= proto_tree_add_item(tree
, proto_gadu_gadu
, tvb
, 0, -1, ENC_NA
);
1559 gadu_gadu_tree
= proto_item_add_subtree(ti
, ett_gadu_gadu
);
1562 pkt_type
= tvb_get_letohl(tvb
, offset
);
1563 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
);
1565 proto_tree_add_item(gadu_gadu_tree
, hf_gadu_gadu_header_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1568 if (pinfo
->p2p_dir
== P2P_DIR_RECV
) {
1570 case GG_DISCONNECTING
:
1571 offset
= dissect_gadu_gadu_disconnecting(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1574 case GG_DISCONNECT_ACK
:
1575 offset
= dissect_gadu_gadu_disconnect_ack(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1579 offset
= dissect_gadu_gadu_login_ok(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1583 offset
= dissect_gadu_gadu_login_ok80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1586 case GG_LOGIN_FAILED
:
1587 offset
= dissect_gadu_gadu_login_failed(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1590 case GG_LOGIN80_FAILED
:
1591 offset
= dissect_gadu_gadu_login80_failed(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1595 offset
= dissect_gadu_gadu_user_data(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1598 case GG_TYPING_NOTIFY
:
1599 offset
= dissect_gadu_gadu_typing_notify(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1603 offset
= dissect_gadu_gadu_recv_msg(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1607 offset
= dissect_gadu_gadu_recv_msg80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1610 case GG_SEND_MSG_ACK
:
1611 /* GG_SEND_MSG_ACK is received by client */
1612 offset
= dissect_gadu_gadu_send_msg_ack(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1616 offset
= dissect_gadu_gadu_status60(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1620 offset
= dissect_gadu_gadu_status77(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1624 offset
= dissect_gadu_gadu_status80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1627 case GG_NOTIFY_REPLY80
:
1628 offset
= dissect_gadu_gadu_notify_reply80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1631 case GG_DCC7_ID_REPLY
:
1632 offset
= dissect_gadu_gadu_dcc7_id_reply(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1636 offset
= dissect_gadu_gadu_welcome(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1639 case GG_USERLIST_REPLY80
:
1640 offset
= dissect_gadu_gadu_userlist_reply80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1643 case GG_USERLIST100_REPLY
:
1644 offset
= dissect_gadu_gadu_userlist_reply100(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1647 case GG_USERLIST100_VERSION
:
1648 offset
= dissect_gadu_gadu_userlist_version100(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1651 case GG_PUBDIR50_REPLY
:
1652 offset
= dissect_gadu_gadu_pubdir50_reply(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1656 offset
= dissect_gadu_gadu_xml_action(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1662 case GG_NOTIFY_REPLY
:
1663 case GG_USERLIST_REPLY
:
1664 case GG_NOTIFY_REPLY60
:
1666 case GG_LOGIN_HASH_TYPE_INVALID
:
1667 case GG_NOTIFY_REPLY77
:
1670 case GG_DCC7_ACCEPT
:
1671 case GG_DCC7_REJECT
:
1672 case GG_DCC7_ID_ABORTED
:
1674 case GG_STATUS80BETA
:
1675 case GG_NOTIFY_REPLY80BETA
:
1676 case GG_OWN_MESSAGE
:
1677 case GG_OWN_RESOURCE_INFO
:
1680 const char *pkt_name
= try_val_to_str(pkt_type
, gadu_gadu_packets_type_recv
);
1683 col_set_str(pinfo
->cinfo
, COL_INFO
, pkt_name
);
1685 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown recv packet: %.2x", pkt_type
);
1693 offset
= dissect_gadu_gadu_login(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1697 offset
= dissect_gadu_gadu_login70(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1701 offset
= dissect_gadu_gadu_login80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1705 offset
= dissect_gadu_gadu_list_empty(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1708 case GG_NOTIFY_FIRST
:
1709 offset
= dissect_gadu_gadu_notify_first(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1712 case GG_NOTIFY_LAST
:
1713 offset
= dissect_gadu_gadu_notify_last(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1717 offset
= dissect_gadu_gadu_notify105(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1721 offset
= dissect_gadu_gadu_add_notify(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1724 case GG_ADD_NOTIFY105
:
1725 offset
= dissect_gadu_gadu_add_notify105(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1728 case GG_REMOVE_NOTIFY
:
1729 offset
= dissect_gadu_gadu_remove_notify(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1732 case GG_REMOVE_NOTIFY105
:
1733 offset
= dissect_gadu_gadu_remove_notify105(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1737 offset
= dissect_gadu_gadu_ping(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1740 case GG_TYPING_NOTIFY
:
1741 offset
= dissect_gadu_gadu_typing_notify(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1745 offset
= dissect_gadu_gadu_send_msg(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1749 offset
= dissect_gadu_gadu_send_msg80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1752 case GG_RECV_MSG_ACK
:
1753 /* GG_RECV_MSG_ACK is send by client */
1754 offset
= dissect_gadu_gadu_recv_msg_ack(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1758 offset
= dissect_gadu_gadu_new_status(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1761 case GG_NEW_STATUS80
:
1762 offset
= dissect_gadu_gadu_new_status80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1765 case GG_DCC7_ID_REQUEST
:
1766 offset
= dissect_gadu_gadu_dcc7_id_request(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1770 offset
= dissect_gadu_gadu_dcc7_new(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1773 case GG_DCC7_ID_ABORT
:
1774 offset
= dissect_gadu_gadu_dcc7_id_abort(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1777 case GG_USERLIST_REQUEST80
:
1778 offset
= dissect_gadu_gadu_userlist_request80(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1781 case GG_USERLIST100_REQUEST
:
1782 offset
= dissect_gadu_gadu_userlist_request100(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1785 case GG_PUBDIR50_REQUEST
:
1786 offset
= dissect_gadu_gadu_pubdir50_request(tvb
, pinfo
, gadu_gadu_tree
, offset
);
1792 case GG_USERLIST_REQUEST
:
1794 case GG_DCC7_ACCEPT
:
1795 case GG_DCC7_REJECT
:
1796 case GG_DCC7_ID_DUNNO1
:
1797 case GG_NEW_STATUS80BETA
:
1798 case GG_LOGIN80BETA
:
1799 case GG_OWN_DISCONNECT
:
1800 case GG_NEW_STATUS105
:
1804 const char *pkt_name
= try_val_to_str(pkt_type
, gadu_gadu_packets_type_send
);
1807 col_set_str(pinfo
->cinfo
, COL_INFO
, pkt_name
);
1809 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Unknown send packet: %.2x", pkt_type
);
1815 /* for now display rest of data as FT_BYTES. */
1816 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
1817 proto_tree_add_item(gadu_gadu_tree
, hf_gadu_gadu_data
, tvb
, offset
, -1, ENC_NA
);
1820 return tvb_captured_length(tvb
);
1824 get_gadu_gadu_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
1825 int offset
, void *data _U_
)
1827 uint32_t len
= tvb_get_letohl(tvb
, offset
+ 4);
1833 dissect_gadu_gadu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
1835 if (pinfo
->srcport
== pinfo
->match_uint
&& pinfo
->destport
!= pinfo
->match_uint
)
1836 pinfo
->p2p_dir
= P2P_DIR_RECV
;
1837 else if (pinfo
->srcport
!= pinfo
->match_uint
&& pinfo
->destport
== pinfo
->match_uint
)
1838 pinfo
->p2p_dir
= P2P_DIR_SENT
;
1842 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Gadu-Gadu");
1843 col_clear(pinfo
->cinfo
, COL_INFO
);
1845 tcp_dissect_pdus(tvb
, pinfo
, tree
, gadu_gadu_desegment
, 8, get_gadu_gadu_pdu_len
, dissect_gadu_gadu_pdu
, data
);
1846 return tvb_captured_length(tvb
);
1850 proto_register_gadu_gadu(void)
1852 static hf_register_info hf
[] = {
1853 { &hf_gadu_gadu_header_type_recv
,
1854 { "Packet Type", "gadu-gadu.recv",
1855 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_packets_type_recv
), 0x0,
1856 "Packet Type (recv)", HFILL
}
1858 { &hf_gadu_gadu_header_type_send
,
1859 { "Packet Type", "gadu-gadu.send",
1860 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_packets_type_send
), 0x0,
1861 "Packet Type (send)", HFILL
}
1863 { &hf_gadu_gadu_header_length
,
1864 { "Packet Length", "gadu-gadu.len",
1865 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1868 { &hf_gadu_gadu_login_uin
,
1869 { "Client UIN", "gadu-gadu.login.uin",
1870 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1873 { &hf_gadu_gadu_login_hash_type
,
1874 { "Login hash type", "gadu-gadu.login.hash_type",
1875 FT_UINT8
, BASE_HEX
, VALS(gadu_gadu_hash_type_vals
), 0x00,
1878 { &hf_gadu_gadu_login_hash
,
1879 { "Login hash", "gadu-gadu.login.hash",
1880 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
1883 { &hf_gadu_gadu_login_status
,
1884 { "Client status", "gadu-gadu.login.status",
1885 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
1888 { &hf_gadu_gadu_login_protocol
,
1889 { "Client protocol", "gadu-gadu.login.protocol",
1890 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
1893 { &hf_gadu_gadu_login_version
,
1894 { "Client version", "gadu-gadu.login.version",
1895 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1898 { &hf_gadu_gadu_login_local_ip
,
1899 { "Client local IP", "gadu-gadu.login.local_ip",
1900 FT_IPv4
, BASE_NONE
, NULL
, 0x00,
1903 { &hf_gadu_gadu_login_local_port
,
1904 { "Client local port", "gadu-gadu.login.local_port",
1905 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
1908 { &hf_gadu_gadu_login80_lang
,
1909 { "Client language", "gadu-gadu.login80.lang",
1910 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1913 { &hf_gadu_gadu_userdata_uin
,
1914 { "UIN", "gadu-gadu.user_data.uin",
1915 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1918 { &hf_gadu_gadu_userdata_attr_name
,
1919 { "Attribute name", "gadu-gadu.user_data.attr_name",
1920 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1923 { &hf_gadu_gadu_userdata_attr_type
,
1924 { "Attribute type", "gadu-gadu.user_data.attr_type",
1925 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
1928 { &hf_gadu_gadu_userdata_attr_value
,
1929 { "Attribute value", "gadu-gadu.user_data.attr_val",
1930 FT_STRING
, BASE_NONE
, NULL
, 0x00,
1933 { &hf_gadu_gadu_typing_notify_type
,
1934 { "Typing notify type", "gadu-gadu.typing_notify.type",
1935 FT_UINT16
, BASE_HEX
, VALS(gadu_gadu_typing_notify_type_vals
), 0x00,
1938 { &hf_gadu_gadu_typing_notify_uin
,
1939 { "Typing notify recipient", "gadu-gadu.typing_notify.uin",
1940 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1943 { &hf_gadu_gadu_msg_uin
,
1944 { "Message sender or recipient", "gadu-gadu.msg.uin",
1945 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1948 { &hf_gadu_gadu_msg_sender
,
1949 { "Message sender", "gadu-gadu.msg.sender",
1950 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1953 { &hf_gadu_gadu_msg_recipient
,
1954 { "Message recipient", "gadu-gadu.msg.recipient",
1955 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1958 { &hf_gadu_gadu_msg_seq
,
1959 { "Message sequence number", "gadu-gadu.msg.seq",
1960 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1963 { &hf_gadu_gadu_msg_time
,
1964 { "Message time", "gadu-gadu.msg.time",
1965 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
1968 { &hf_gadu_gadu_msg_class
,
1969 { "Message class", "gadu-gadu.msg.class",
1970 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1973 { &hf_gadu_gadu_msg_text
,
1974 { "Message text", "gadu-gadu.msg.text",
1975 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
1978 { &hf_gadu_gadu_msg80_offset_plain
,
1979 { "Message plaintext offset", "gadu-gadu.msg80.offset_plain",
1980 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1983 { &hf_gadu_gadu_msg80_offset_attr
,
1984 { "Message attribute offset", "gadu-gadu.msg80.offset_attributes",
1985 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1988 { &hf_gadu_gadu_msg_ack_status
,
1989 { "Message status", "gadu-gadu.msg_ack.status",
1990 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_msg_ack_status_vals
), 0x00,
1993 { &hf_gadu_gadu_msg_ack_recipient
,
1994 { "Message recipient", "gadu-gadu.msg_ack.recipient",
1995 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
1998 { &hf_gadu_gadu_msg_ack_seq
,
1999 { "Message sequence number", "gadu-gadu.msg_ack.seq",
2000 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2003 { &hf_gadu_gadu_status_uin
,
2004 { "UIN", "gadu-gadu.status.uin",
2005 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2008 { &hf_gadu_gadu_status_status
,
2009 { "Status", "gadu-gadu.status.status",
2010 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
2013 { &hf_gadu_gadu_status_ip
,
2014 { "IP", "gadu-gadu.status.remote_ip",
2015 FT_IPv4
, BASE_NONE
, NULL
, 0x00,
2018 { &hf_gadu_gadu_status_port
,
2019 { "Port", "gadu-gadu.status.remote_port",
2020 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
2023 { &hf_gadu_gadu_status_version
,
2024 { "Version", "gadu-gadu.status.version",
2025 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2028 { &hf_gadu_gadu_status_img_size
,
2029 { "Image size", "gadu-gadu.status.image_size",
2030 FT_UINT8
, BASE_DEC
, NULL
, 0x00,
2031 "Maximum image size in KB", HFILL
}
2033 { &hf_gadu_gadu_status_descr
,
2034 { "Description", "gadu-gadu.status.description",
2035 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
2039 { "Direct connection type", "gadu-gadu.dcc.type",
2040 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_dcc_type_vals
), 0x00,
2044 { "Direct connection id", "gadu-gadu.dcc.id",
2045 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
2049 { "Direct connection UIN target", "gadu-gadu.dcc.uin_to",
2050 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2054 { "Direct connection UIN initiator", "gadu-gadu.dcc.uin_from",
2055 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2059 { "Direct connection filename", "gadu-gadu.dcc.filename",
2060 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2063 { &hf_gadu_gadu_new_status_status
,
2064 { "Status", "gadu-gadu.new_status.status",
2065 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
2068 { &hf_gadu_gadu_new_status_desc
,
2069 { "Description", "gadu-gadu.new_status.description",
2070 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
2073 { &hf_gadu_gadu_userlist_request_type
,
2074 { "Request type", "gadu-gadu.userlist.request_type",
2075 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_userlist_request_type_vals
), 0x00,
2078 { &hf_gadu_gadu_userlist_version
,
2079 { "Userlist version", "gadu-gadu.userlist.version",
2080 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2083 { &hf_gadu_gadu_userlist_format
,
2084 { "Userlist format", "gadu-gadu.userlist.format",
2085 FT_UINT8
, BASE_HEX
, VALS(gadu_gadu_userlist_request_format_vals
), 0x00,
2088 { &hf_gadu_gadu_userlist_reply_type
,
2089 { "Reply type", "gadu-gadu.userlist.reply_type",
2090 FT_UINT32
, BASE_HEX
, VALS(gadu_gadu_userlist_reply_type_vals
), 0x00,
2093 { &hf_gadu_gadu_userlist
,
2094 { "Userlist XML data", "gadu-gadu.userlist",
2095 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
2098 { &hf_gadu_gadu_pubdir_request_type
,
2099 { "Request type", "gadu-gadu.pubdir.request_type",
2100 FT_UINT8
, BASE_HEX
, VALS(gadu_gadu_pubdir_type_vals
), 0x00,
2103 { &hf_gadu_gadu_pubdir_request_seq
,
2104 { "Request sequence", "gadu-gadu.pubdir.request_seq",
2105 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
2108 { &hf_gadu_gadu_pubdir_request_str
,
2109 { "Request string", "gadu-gadu.pubdir.request_str",
2110 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
2113 { &hf_gadu_gadu_pubdir_reply_type
,
2114 { "Reply type", "gadu-gadu.pubdir.reply_type",
2115 FT_UINT8
, BASE_HEX
, VALS(gadu_gadu_pubdir_type_vals
), 0x00,
2118 { &hf_gadu_gadu_pubdir_reply_seq
,
2119 { "Reply sequence", "gadu-gadu.pubdir.reply_seq",
2120 FT_UINT32
, BASE_HEX
, NULL
, 0x00,
2123 { &hf_gadu_gadu_pubdir_reply_str
,
2124 { "Reply string", "gadu-gadu.pubdir.reply_str",
2125 FT_STRINGZ
, BASE_NONE
, NULL
, 0x00,
2128 { &hf_gadu_gadu_contact_uin
,
2129 { "UIN", "gadu-gadu.contact.uin",
2130 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
2133 { &hf_gadu_gadu_contact_uin_str
,
2134 { "UIN", "gadu-gadu.contact.uin_str",
2135 FT_STRING
, BASE_NONE
, NULL
, 0x00,
2138 { &hf_gadu_gadu_contact_type
,
2139 { "Type", "gadu-gadu.contact.type",
2140 FT_UINT8
, BASE_HEX
, NULL
, 0x00,
2143 { &hf_gadu_gadu_welcome_seed
,
2144 { "Seed", "gadu-gadu.welcome.seed",
2145 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2148 { &hf_gadu_gadu_data
,
2149 { "Packet Data", "gadu-gadu.data",
2150 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2155 static int *ett
[] = {
2157 &ett_gadu_gadu_contact
2160 module_t
*gadu_gadu_module
;
2162 proto_gadu_gadu
= proto_register_protocol("Gadu-Gadu Protocol", "Gadu-Gadu", "gadu-gadu");
2164 gadu_gadu_module
= prefs_register_protocol(proto_gadu_gadu
, NULL
);
2165 prefs_register_bool_preference(gadu_gadu_module
, "desegment",
2166 "Reassemble Gadu-Gadu messages spanning multiple TCP segments",
2167 "Whether the Gadu-Gadu dissector should reassemble messages spanning multiple TCP segments."
2168 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2169 &gadu_gadu_desegment
);
2171 proto_register_field_array(proto_gadu_gadu
, hf
, array_length(hf
));
2172 proto_register_subtree_array(ett
, array_length(ett
));
2174 gadu_gadu_handle
= register_dissector("gadugadu", dissect_gadu_gadu
, proto_gadu_gadu
);
2178 proto_reg_handoff_gadu_gadu(void)
2180 dissector_add_uint_with_preference("tcp.port", TCP_PORT_GADU_GADU
, gadu_gadu_handle
);
2182 xml_handle
= find_dissector_add_dependency("xml", proto_gadu_gadu
);
2186 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2191 * indent-tabs-mode: t
2194 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2195 * :indentSize=8:tabSize=8:noTabs=false: