1 /* xmpp-gtalk.c
2  * Wireshark's XMPP dissector.
3  *
4  * GTalk extensions.
5  *
6  * Copyright 2011, Mariusz Okroj <okrojmariusz[]gmail.com>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14 
15 #include "config.h"
16 
17 #include <epan/packet.h>
18 
19 #include "packet-xmpp.h"
20 #include "packet-xmpp-gtalk.h"
21 #include "packet-xmpp-conference.h"
22 
23 
24 static void xmpp_gtalk_session_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
25 static void xmpp_gtalk_session_desc_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
26 static void xmpp_gtalk_session_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
27 static void xmpp_gtalk_session_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
28 static void xmpp_gtalk_jingleinfo_stun(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
29 static void xmpp_gtalk_jingleinfo_server(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
30 static void xmpp_gtalk_jingleinfo_relay(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
31 static void xmpp_gtalk_jingleinfo_relay_serv(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
32 static void xmpp_gtalk_mail_mail_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
33 static void xmpp_gtalk_mail_senders(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
34 static void xmpp_gtalk_mail_sender(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
35 static void xmpp_gtalk_mail_snippet(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
36 static void xmpp_gtalk_status_status_list(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
37 static void xmpp_gtalk_transport_p2p_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element);
38 
39 void
xmpp_gtalk_session(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)40 xmpp_gtalk_session(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
41 {
42     proto_item *session_item;
43     proto_tree *session_tree;
44 
45     xmpp_attr_info attrs_info [] = {
46         {"xmlns", &hf_xmpp_xmlns, TRUE, FALSE, NULL, NULL},
47         {"type", &hf_xmpp_gtalk_session_type, TRUE, TRUE, NULL, NULL},
48         {"initiator", NULL, FALSE, TRUE, NULL, NULL},
49         {"id", NULL, TRUE, TRUE, NULL, NULL}
50     };
51 
52     xmpp_elem_info elems_info [] = {
53         {NAME,"description", xmpp_gtalk_session_desc, ONE},
54         {NAME, "candidate", xmpp_gtalk_session_cand, MANY},
55         {NAME, "reason", xmpp_gtalk_session_reason, ONE},
56         {NAME_AND_ATTR, xmpp_name_attr_struct(pinfo->pool, "transport", "xmlns", "http://www.google.com/transport/p2p"), xmpp_gtalk_transport_p2p, ONE},
57         {NAME, "conference-info", xmpp_conferece_info_advert, ONE}
58     };
59 
60     xmpp_attr_t *attr_type = xmpp_get_attr(element, "type");
61 
62     col_append_fstr(pinfo->cinfo, COL_INFO, "GTALK-SESSION(%s) ", attr_type?attr_type->value:"");
63 
64     session_item = proto_tree_add_item(tree, hf_xmpp_gtalk_session, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
65     session_tree = proto_item_add_subtree(session_item, ett_xmpp_gtalk_session);
66 
67     xmpp_display_attrs(session_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
68 
69     xmpp_display_elems(session_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
70 }
71 
72 static void
xmpp_gtalk_session_desc(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)73 xmpp_gtalk_session_desc(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
74 {
75     proto_tree *desc_tree;
76 
77     xmpp_attr_info attrs_info[] = {
78         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
79         {"xml:lang", NULL, FALSE, FALSE, NULL, NULL}
80     };
81 
82     xmpp_elem_info elems_info[] = {
83         {NAME, "payload-type", xmpp_gtalk_session_desc_payload, MANY}
84     };
85 
86     desc_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_session_desc, NULL, "DESCRIPTION");
87 
88     xmpp_display_attrs(desc_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
89     xmpp_display_elems(desc_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
90 }
91 
92 static void
xmpp_gtalk_session_desc_payload(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)93 xmpp_gtalk_session_desc_payload(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
94 {
95     proto_tree *payload_tree;
96 
97     xmpp_attr_info attrs_info[] = {
98         {"xmlns", &hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
99         {"id", NULL, FALSE, TRUE, NULL, NULL},
100         {"name", NULL, FALSE, TRUE, NULL, NULL},
101         {"channels", NULL, FALSE, FALSE, NULL, NULL},
102         {"clockrate", NULL, FALSE, FALSE, NULL, NULL},
103         {"bitrate", NULL, FALSE, FALSE, NULL, NULL},
104         {"width", NULL, FALSE, FALSE, NULL, NULL},
105         {"height", NULL, FALSE, FALSE, NULL, NULL},
106         {"framerate", NULL, FALSE, FALSE, NULL, NULL},
107     };
108 
109     payload_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_session_desc_payload, NULL, "PAYLOAD-TYPE");
110 
111     xmpp_display_attrs(payload_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
112     xmpp_display_elems(payload_tree, element, pinfo, tvb, NULL, 0);
113 }
114 
115 static void
xmpp_gtalk_session_cand(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)116 xmpp_gtalk_session_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
117 {
118     proto_tree *cand_tree;
119 
120     xmpp_attr_info attrs_info[] = {
121         {"name", NULL, TRUE, TRUE, NULL, NULL},
122         {"address", NULL, TRUE, FALSE, NULL, NULL},
123         {"port", NULL, TRUE, FALSE, NULL, NULL},
124         {"preference", NULL, TRUE, FALSE, NULL, NULL},
125         {"type", NULL, TRUE, TRUE, NULL, NULL},
126         {"protocol", NULL, TRUE, TRUE, NULL, NULL},
127         {"network", NULL, TRUE, FALSE, NULL, NULL},
128         {"username", NULL, TRUE, FALSE, NULL, NULL},
129         {"password", NULL, TRUE, FALSE, NULL, NULL},
130         {"generation", NULL, TRUE, FALSE, NULL, NULL},
131         {"foundation", NULL, FALSE, FALSE, NULL, NULL},
132         {"component", NULL, FALSE, FALSE, NULL, NULL}
133     };
134 
135     cand_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_session_cand, NULL, "CANDIDATE");
136 
137     xmpp_display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
138     xmpp_display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
139 }
140 
141 static void
xmpp_gtalk_session_reason(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)142 xmpp_gtalk_session_reason(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
143 {
144     proto_tree *reason_tree;
145 
146     xmpp_attr_info attrs_info[] = {
147         {"condition", NULL, TRUE, TRUE, NULL, NULL},
148         {"text", NULL, FALSE, FALSE, NULL, NULL}
149    };
150 
151     xmpp_element_t *condition;
152     xmpp_element_t *text;
153 
154     static const gchar *reason_names[] = { "success", "busy", "cancel"};
155 
156     reason_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_session_reason, NULL, "REASON");
157 
158 
159     /*Looks for reason description.*/
160     if((condition = xmpp_steal_element_by_names(element, reason_names, array_length(reason_names)))!=NULL)
161     {
162         xmpp_attr_t *fake_cond = xmpp_ep_init_attr_t(pinfo->pool, condition->name, condition->offset, condition->length);
163         g_hash_table_insert(element->attrs, (gpointer)"condition", fake_cond);
164 
165     }
166 
167     if((text = xmpp_steal_element_by_name(element, "text"))!=NULL)
168     {
169         xmpp_attr_t *fake_text = xmpp_ep_init_attr_t(pinfo->pool, text->data?text->data->value:"", text->offset, text->length);
170         g_hash_table_insert(element->attrs, (gpointer)"text", fake_text);
171     }
172 
173     xmpp_display_attrs(reason_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
174 
175     xmpp_unknown(reason_tree, tvb, pinfo, element);
176 }
177 
178 void
xmpp_gtalk_jingleinfo_query(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)179 xmpp_gtalk_jingleinfo_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
180 {
181     proto_item *query_item;
182     proto_tree *query_tree;
183 
184     xmpp_attr_info attrs_info[] = {
185         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
186     };
187 
188     xmpp_elem_info elems_info [] = {
189         {NAME, "stun", xmpp_gtalk_jingleinfo_stun, ONE},
190         {NAME, "relay", xmpp_gtalk_jingleinfo_relay, ONE}
191     };
192 
193     col_append_str(pinfo->cinfo, COL_INFO, "QUERY(google:jingleinfo) ");
194 
195     query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
196         ENC_BIG_ENDIAN);
197     query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
198 
199     xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
200     xmpp_display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
201 }
202 
203 static void
xmpp_gtalk_jingleinfo_stun(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)204 xmpp_gtalk_jingleinfo_stun(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
205 {
206     proto_tree *stun_tree;
207 
208     xmpp_elem_info elems_info [] = {
209         {NAME, "server", xmpp_gtalk_jingleinfo_server, MANY},
210     };
211 
212     stun_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_jingleinfo_stun, NULL, "STUN");
213 
214     xmpp_display_attrs(stun_tree, element, pinfo, tvb, NULL, 0);
215     xmpp_display_elems(stun_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
216 
217 }
218 
219 static void
xmpp_gtalk_jingleinfo_server(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)220 xmpp_gtalk_jingleinfo_server(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
221 {
222     proto_tree *serv_tree;
223 
224     xmpp_attr_info attrs_info[] = {
225         {"host", NULL, TRUE, TRUE, NULL, NULL},
226         {"udp", NULL, TRUE, TRUE, NULL, NULL}
227     };
228 
229     serv_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_jingleinfo_server, NULL, "SERVER");
230 
231     xmpp_display_attrs(serv_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
232     xmpp_display_elems(serv_tree, element, pinfo, tvb, NULL, 0);
233 }
234 
235 static void
xmpp_gtalk_jingleinfo_relay(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)236 xmpp_gtalk_jingleinfo_relay(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
237 {
238     proto_tree *relay_tree;
239 
240     xmpp_attr_info attrs_info[] = {
241         {"token", NULL, FALSE, FALSE, NULL, NULL}
242     };
243 
244     xmpp_elem_info elems_info [] = {
245         {NAME, "server", xmpp_gtalk_jingleinfo_relay_serv, ONE}
246     };
247 
248     xmpp_element_t *token;
249 
250     relay_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_jingleinfo_relay, NULL, "RELAY");
251 
252     if((token  = xmpp_steal_element_by_name(element, "token"))!=NULL)
253     {
254         xmpp_attr_t *fake_token = xmpp_ep_init_attr_t(pinfo->pool, token->data?token->data->value:"", token->offset, token->length);
255         g_hash_table_insert(element->attrs, (gpointer)"token", fake_token);
256     }
257 
258     xmpp_display_attrs(relay_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
259     xmpp_display_elems(relay_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
260 }
261 
262 static void
xmpp_gtalk_jingleinfo_relay_serv(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)263 xmpp_gtalk_jingleinfo_relay_serv(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
264 {
265     proto_tree *serv_tree;
266 
267     xmpp_attr_info attrs_info[] = {
268         {"host", NULL, TRUE, TRUE, NULL, NULL},
269         {"udp", NULL, FALSE, TRUE, NULL, NULL},
270         {"tcp", NULL, FALSE, TRUE, NULL, NULL},
271         {"tcpssl", NULL, FALSE, TRUE, NULL, NULL}
272     };
273 
274     serv_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_jingleinfo_relay_serv, NULL, "SERVER");
275 
276     xmpp_display_attrs(serv_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
277     xmpp_display_elems(serv_tree, element, pinfo, tvb, NULL, 0);
278 }
279 
280 void
xmpp_gtalk_usersetting(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)281 xmpp_gtalk_usersetting(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
282 {
283     proto_item *sett_item;
284     proto_tree *sett_tree;
285 
286     xmpp_attr_info attrs_info [] = {
287         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL}
288     };
289 
290     guint i;
291 
292     sett_item = proto_tree_add_item(tree, hf_xmpp_gtalk_setting, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
293     sett_tree = proto_item_add_subtree(sett_item, ett_xmpp_gtalk_setting);
294 
295     xmpp_display_attrs(sett_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
296 
297     for(i = 0; i < g_list_length(element->elements); i++)
298     {
299         GList *elem_l = g_list_nth(element->elements,i);
300         xmpp_element_t *elem = (xmpp_element_t *)(elem_l?elem_l->data:NULL);
301 
302         if(elem)
303         {
304             xmpp_attr_t *val = xmpp_get_attr(elem,"value");
305             proto_tree_add_string_format(sett_tree, hf_xmpp_gtalk_setting_element, tvb, elem->offset, elem->length, val?val->value:"",
306                             "%s [%s]",elem->name,val?val->value:"");
307         }
308     }
309 }
310 
311 void
xmpp_gtalk_nosave_x(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)312 xmpp_gtalk_nosave_x(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
313 {
314     proto_item *x_item;
315     proto_tree *x_tree;
316 
317     xmpp_attr_info attrs_info [] = {
318         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
319         {"value", NULL, FALSE, TRUE, NULL, NULL}
320     };
321 
322     x_item = proto_tree_add_item(tree, hf_xmpp_gtalk_nosave_x, tvb, element->offset, element->length,
323         ENC_BIG_ENDIAN);
324     x_tree = proto_item_add_subtree(x_item, ett_xmpp_gtalk_nosave_x);
325 
326     xmpp_display_attrs(x_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
327     xmpp_display_elems(x_tree, element, pinfo, tvb, NULL, 0);
328 }
329 
330 void
xmpp_gtalk_mail_query(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)331 xmpp_gtalk_mail_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
332 {
333     proto_item *query_item;
334     proto_tree *query_tree;
335 
336     xmpp_attr_info attrs_info[] = {
337         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
338         {"newer-than-time", NULL, FALSE, TRUE, NULL, NULL},
339         {"newer-than-tid", NULL, FALSE, TRUE, NULL, NULL},
340         {"q", NULL, FALSE, TRUE, NULL, NULL}
341     };
342 
343     col_append_str(pinfo->cinfo, COL_INFO, "QUERY(google:mail:notify) ");
344 
345     query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
346         ENC_BIG_ENDIAN);
347     query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
348 
349     xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
350     xmpp_display_elems(query_tree, element, pinfo, tvb, NULL, 0);
351 }
352 
353 void
xmpp_gtalk_mail_mailbox(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)354 xmpp_gtalk_mail_mailbox(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
355 {
356     proto_item *mail_item;
357     proto_tree *mail_tree;
358 
359     xmpp_attr_info attrs_info [] = {
360         {"xmlns", &hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL},
361         {"result-time", NULL, FALSE, TRUE, NULL, NULL},
362         {"total-matched", NULL, FALSE, TRUE, NULL, NULL},
363         {"total-estimate", NULL, FALSE, TRUE, NULL, NULL},
364         {"url", NULL, FALSE, TRUE, NULL, NULL}
365     };
366 
367     xmpp_elem_info elems_info [] = {
368         {NAME,"mail-thread-info", xmpp_gtalk_mail_mail_info, MANY}
369     };
370 
371     col_append_str(pinfo->cinfo, COL_INFO, "MAILBOX ");
372 
373     mail_item = proto_tree_add_item(tree, hf_xmpp_gtalk_mail_mailbox, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
374     mail_tree = proto_item_add_subtree(mail_item, ett_xmpp_gtalk_mail_mailbox);
375 
376     xmpp_display_attrs(mail_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
377     xmpp_display_elems(mail_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
378 }
379 
380 static void
xmpp_gtalk_mail_mail_info(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)381 xmpp_gtalk_mail_mail_info(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
382 {
383     proto_tree *mail_info_tree;
384 
385     xmpp_attr_info attrs_info [] = {
386         {"tid", NULL, FALSE, FALSE, NULL, NULL},
387         {"participation", NULL, FALSE, FALSE, NULL, NULL},
388         {"messages", NULL, FALSE, TRUE, NULL, NULL},
389         {"date", NULL, FALSE, TRUE, NULL, NULL},
390         {"url", NULL, FALSE, FALSE, NULL, NULL},
391         {"labels", NULL, FALSE, FALSE, NULL, NULL},
392         {"subject", NULL, FALSE, TRUE, NULL, NULL}
393     };
394 
395     xmpp_elem_info elems_info [] = {
396         {NAME, "senders", xmpp_gtalk_mail_senders, ONE},
397         {NAME, "snippet", xmpp_gtalk_mail_snippet, ONE}/*or MANY?*/
398     };
399 
400     xmpp_element_t *labels, *subject;
401 
402     mail_info_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_mail_mail_info, NULL, "MAIL-THREAD-INFO");
403 
404     if((labels = xmpp_steal_element_by_name(element,"labels"))!=NULL)
405     {
406         xmpp_attr_t *fake_labels = xmpp_ep_init_attr_t(pinfo->pool, labels->data?labels->data->value:"",labels->offset, labels->length);
407         g_hash_table_insert(element->attrs, (gpointer)"labels", fake_labels);
408     }
409     if((subject = xmpp_steal_element_by_name(element,"subject"))!=NULL)
410     {
411         xmpp_attr_t *fake_subject = xmpp_ep_init_attr_t(pinfo->pool, subject->data?subject->data->value:"",subject->offset, subject->length);
412         g_hash_table_insert(element->attrs, (gpointer)"subject", fake_subject);
413     }
414 
415     xmpp_display_attrs(mail_info_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
416     xmpp_display_elems(mail_info_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
417 }
418 
419 
420 static void
xmpp_gtalk_mail_senders(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)421 xmpp_gtalk_mail_senders(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
422 {
423     proto_tree *senders_tree;
424 
425     xmpp_elem_info elems_info [] = {
426         {NAME, "sender", xmpp_gtalk_mail_sender, MANY}
427     };
428 
429     senders_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_mail_senders, NULL, "SENDERS");
430 
431     xmpp_display_attrs(senders_tree, element, pinfo, tvb, NULL, 0);
432     xmpp_display_elems(senders_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
433 }
434 
435 static void
xmpp_gtalk_mail_sender(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)436 xmpp_gtalk_mail_sender(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
437 {
438     proto_tree *sender_tree;
439 
440     xmpp_attr_info attrs_info [] = {
441         {"name", NULL, FALSE, TRUE, NULL, NULL},
442         {"address", NULL, FALSE, TRUE, NULL, NULL},
443         {"originator", NULL, FALSE, TRUE, NULL, NULL},
444         {"unread", NULL, FALSE, TRUE, NULL, NULL}
445     };
446 
447     sender_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_mail_sender, NULL, "SENDER");
448 
449     xmpp_display_attrs(sender_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
450     xmpp_display_elems(sender_tree, element, pinfo, tvb, NULL, 0);
451 }
452 
453 static void
xmpp_gtalk_mail_snippet(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)454 xmpp_gtalk_mail_snippet(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
455 {
456     proto_tree_add_string(tree, hf_xmpp_gtalk_mail_snippet, tvb, element->offset, element->length, element->data?element->data->value:"");
457     xmpp_unknown(tree, tvb, pinfo, element);
458 }
459 
460 void
xmpp_gtalk_mail_new_mail(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)461 xmpp_gtalk_mail_new_mail(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
462 {
463     col_append_str(pinfo->cinfo, COL_INFO, "NEW-MAIL ");
464     proto_tree_add_item(tree, hf_xmpp_gtalk_mail_new_mail, tvb, element->offset, element->length,
465         ENC_BIG_ENDIAN);
466     xmpp_unknown(tree, tvb, pinfo, element);
467 }
468 
469 
470 void
xmpp_gtalk_status_query(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)471 xmpp_gtalk_status_query(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
472 {
473     proto_item *query_item;
474     proto_tree *query_tree;
475 
476     xmpp_attr_info attrs_info[] = {
477         {"xmlns", &hf_xmpp_xmlns, TRUE, TRUE, NULL, NULL},
478         {"version", NULL, FALSE, TRUE, NULL, NULL},
479         {"status-max", NULL, FALSE, FALSE, NULL, NULL},
480         {"status-list-max", NULL, FALSE, FALSE, NULL, NULL},
481         {"status-list-contents-max", NULL, FALSE, FALSE, NULL, NULL},
482         {"status-min-ver", NULL, FALSE, TRUE, NULL, NULL},
483         {"show", NULL, FALSE, TRUE, NULL, NULL},
484         {"status", NULL, FALSE, TRUE, NULL, NULL},
485         {"invisible", NULL, FALSE, TRUE, NULL, NULL},
486     };
487 
488     xmpp_elem_info elems_info [] = {
489         {NAME, "status-list", xmpp_gtalk_status_status_list, MANY}
490     };
491 
492     xmpp_element_t *status, *show, *invisible;
493 
494     col_append_str(pinfo->cinfo, COL_INFO, "QUERY(google:shared-status) ");
495 
496     query_item = proto_tree_add_item(tree, hf_xmpp_query, tvb, element->offset, element->length,
497         ENC_BIG_ENDIAN);
498     query_tree = proto_item_add_subtree(query_item, ett_xmpp_query);
499 
500     if((status = xmpp_steal_element_by_name(element,"status"))!=NULL)
501     {
502         xmpp_attr_t *fake_status = xmpp_ep_init_attr_t(pinfo->pool, status->data?status->data->value:"",status->offset, status->length);
503         g_hash_table_insert(element->attrs, (gpointer)"status", fake_status);
504     }
505 
506     if((show = xmpp_steal_element_by_name(element,"show"))!=NULL)
507     {
508         xmpp_attr_t *fake_show = xmpp_ep_init_attr_t(pinfo->pool, show->data?show->data->value:"",show->offset, show->length);
509         g_hash_table_insert(element->attrs, (gpointer)"show", fake_show);
510     }
511 
512     if((invisible = xmpp_steal_element_by_name(element,"invisible"))!=NULL)
513     {
514         xmpp_attr_t *value = xmpp_get_attr(invisible, "value");
515         xmpp_attr_t *fake_invisible = xmpp_ep_init_attr_t(pinfo->pool, value?value->value:"",invisible->offset, invisible->length);
516         g_hash_table_insert(element->attrs, (gpointer)"invisible", fake_invisible);
517     }
518 
519     xmpp_display_attrs(query_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
520     xmpp_display_elems(query_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
521 }
522 
523 static void
xmpp_gtalk_status_status_list(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)524 xmpp_gtalk_status_status_list(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
525 {
526     proto_tree *list_tree;
527 
528     xmpp_attr_info attrs_info [] = {
529         {"show", NULL, TRUE, TRUE, NULL, NULL}
530     };
531 
532     xmpp_element_t *status;
533 
534     list_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_status_status_list, NULL, "STATUS LIST");
535 
536     while((status = xmpp_steal_element_by_name(element, "status"))!=NULL)
537     {
538         proto_tree_add_string(list_tree, hf_xmpp_gtalk_status_status_list, tvb, status->offset, status->length, status->data?status->data->value:"");
539     }
540 
541     xmpp_display_attrs(list_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
542     xmpp_display_elems(list_tree, element, pinfo, tvb, NULL, 0);
543 }
544 
545 /*http://www.google.com/transport/p2p*/
546 void
xmpp_gtalk_transport_p2p(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)547 xmpp_gtalk_transport_p2p(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element)
548 {
549     proto_item *trans_item;
550     proto_tree *trans_tree;
551 
552     xmpp_attr_info attrs_info[] = {
553         {"xmlns", &hf_xmpp_xmlns, FALSE, TRUE, NULL, NULL}
554     };
555 
556     xmpp_elem_info elems_info [] = {
557         {NAME, "candidate", xmpp_gtalk_transport_p2p_cand, MANY}
558     };
559 
560     trans_item = proto_tree_add_item(tree, hf_xmpp_gtalk_transport_p2p, tvb, element->offset, element->length, ENC_BIG_ENDIAN);
561     trans_tree = proto_item_add_subtree(trans_item, ett_xmpp_gtalk_transport_p2p);
562 
563     xmpp_display_attrs(trans_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
564 
565     xmpp_display_elems(trans_tree, element, pinfo, tvb, elems_info, array_length(elems_info));
566 }
567 
568 static void
xmpp_gtalk_transport_p2p_cand(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,xmpp_element_t * element)569 xmpp_gtalk_transport_p2p_cand(proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo, xmpp_element_t* element) {
570     proto_tree *cand_tree;
571 
572     xmpp_attr_info attrs_info[] = {
573         {"xmlns", &hf_xmpp_xmlns, FALSE, FALSE, NULL, NULL},
574         {"name", NULL, FALSE, TRUE, NULL, NULL},
575         {"generation", NULL, FALSE, FALSE, NULL, NULL},
576         {"network", NULL, FALSE, FALSE, NULL, NULL},
577         {"component", NULL, FALSE, FALSE, NULL, NULL},
578         {"type", NULL, FALSE, FALSE, NULL, NULL},
579         {"protocol", NULL, FALSE, TRUE, NULL, NULL},
580         {"preference", NULL, FALSE, FALSE, NULL, NULL},
581         {"password", NULL, FALSE, FALSE, NULL, NULL},
582         {"username", NULL, FALSE, FALSE, NULL, NULL},
583         {"port", NULL, FALSE, TRUE, NULL, NULL},
584         {"address", NULL, FALSE, TRUE, NULL, NULL}
585     };
586 
587     cand_tree = proto_tree_add_subtree(tree, tvb, element->offset, element->length, ett_xmpp_gtalk_transport_p2p_cand, NULL, "CANDIDATE");
588 
589     xmpp_display_attrs(cand_tree, element, pinfo, tvb, attrs_info, array_length(attrs_info));
590     xmpp_display_elems(cand_tree, element, pinfo, tvb, NULL, 0);
591 
592 }
593 /*
594 * Editor modelines - https://www.wireshark.org/tools/modelines.html
595 *
596 * Local variables:
597 * c-basic-offset: 4
598 * tab-width: 8
599 * indent-tabs-mode: nil
600 * End:
601 *
602 * ex: set shiftwidth=4 tabstop=8 expandtab:
603 * :indentSize=4:tabSize=8:noTabs=true:
604 */
605