2 * Routines for SAMETIME dissection
3 * Copyright 2010, Toralf Foerster <toralf.foerster [AT] gmx.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <epan/wmem/wmem.h>
30 #include <epan/dissectors/packet-tcp.h>
31 #include <epan/prefs.h>
33 #include <epan/stats_tree.h>
35 #define DEFAULT_SAMETIME_PORT 1533
37 static int proto_sametime
= -1;
38 static guint global_sametime_port
= DEFAULT_SAMETIME_PORT
;
39 static dissector_handle_t sametime_handle
;
42 static gboolean global_sametime_show_length
= FALSE
;
43 static gboolean global_sametime_reassemble_packets
= TRUE
;
46 static int hf_sametime_heartbeat
= -1;
48 /*sametime message header*/
49 static int hf_sametime_message_length
= -1;
50 static int hf_sametime_message_type
= -1;
51 static int hf_sametime_message_options
= -1;
52 static int hf_sametime_message_options_attribute
= -1;
53 static int hf_sametime_message_options_encrypted
= -1;
54 static int hf_sametime_message_channel
= -1;
57 static int hf_sametime_field_length
= -1;
58 static int hf_sametime_field_text
= -1;
59 static int hf_sametime_code
= -1;
60 static int hf_sametime_login_type
= -1;
61 static int hf_sametime_time
= -1;
64 static int hf_sametime_handshake_major
= -1;
65 static int hf_sametime_handshake_minor
= -1;
66 static int hf_sametime_handshake_srvrcalc_addr
= -1;
67 static int hf_sametime_handshake_loclcalc_addr
= -1;
70 static int hf_sametime_channel_service
= -1;
71 static int hf_sametime_channel_id
= -1;
72 static int hf_sametime_channel_send_type
= -1;
73 static int hf_sametime_channel_awareness
= -1;
76 static int hf_sametime_user_status
= -1;
79 static int hf_sametime_location_country
= -1;
80 static int hf_sametime_location_postalcode
= -1;
81 static int hf_sametime_location_province
= -1;
82 static int hf_sametime_location_city
= -1;
83 static int hf_sametime_location_phone
= -1;
84 static int hf_sametime_location_name
= -1;
85 static int hf_sametime_location_timezone
= -1;
87 /*packet detail tree*/
88 static gint ett_sametime
= -1;
89 static gint ett_sametime_options
= -1;
92 static int sametime_tap
= -1;
93 static const guint8
* st_str_packet
= "Sametime Message Count";
94 static const guint8
* st_str_message_type
= "Message Type";
95 static const guint8
* st_str_send_type
= "Send Type";
96 static const guint8
* st_str_user_status
= "User Status";
97 static int st_node_packet
= -1;
98 static int st_node_message_type
= -1;
99 static int st_node_send_type
= -1;
100 static int st_node_user_status
= -1;
102 typedef struct SametimeTap
{
108 #define SAMETIME_MESSAGETYPE_HEARTBEAT 0x80
109 #define SAMETIME_MESSAGETYPE_HANDSHAKE 0x0000
111 #define SAMETIME_MESSAGETYPE_HANDSHAKE_ACK 0x8000
112 #define SAMETIME_MESSAGETYPE_HANDSHAKE_SYN 0x0025
113 #define SAMETIME_MESSAGETYPE_LOGIN 0x0001
114 #define SAMETIME_MESSAGETYPE_LOGIN_ACK 0x8001
115 #define SAMETIME_MESSAGETYPE_LOGIN_REDIRECT 0x0018
116 #define SAMETIME_MESSAGETYPE_LOGIN_CONTINUE 0x0016
118 #define SAMETIME_MESSAGETYPE_CHANNEL_CREATE 0x0002
119 #define SAMETIME_MESSAGETYPE_CHANNEL_DESTROY 0x0003
120 #define SAMETIME_MESSAGETYPE_CHANNEL_SEND 0x0004
121 #define SAMETIME_MESSAGETYPE_CHANNEL_ACCEPT 0x0006
123 #define SAMETIME_MESSAGETYPE_SET_USER_STATUS 0x0009
124 #define SAMETIME_MESSAGETYPE_SET_PRIVACY_LIST 0x000b
125 #define SAMETIME_MESSAGETYPE_SENSE_SERVICE 0x0011
126 #define SAMETIME_MESSAGETYPE_ADMIN 0x0019
127 #define SAMETIME_MESSAGETYPE_ANNOUNCE 0x0022
130 static const value_string messagetypenames
[] = {
131 { SAMETIME_MESSAGETYPE_HEARTBEAT
, "HEARTBEAT" },
133 { SAMETIME_MESSAGETYPE_HANDSHAKE
, "HANDSHAKE" },
134 { SAMETIME_MESSAGETYPE_HANDSHAKE_SYN
, "HANDSHAKE_SYN" },
135 { SAMETIME_MESSAGETYPE_HANDSHAKE_ACK
, "HANDSHAKE_ACK" },
136 { SAMETIME_MESSAGETYPE_LOGIN
, "LOGIN" },
137 { SAMETIME_MESSAGETYPE_LOGIN_ACK
, "LOGIN_ACK" },
138 { SAMETIME_MESSAGETYPE_LOGIN_REDIRECT
, "LOGIN_REDIRECT" },
139 { SAMETIME_MESSAGETYPE_LOGIN_CONTINUE
, "LOGIN_CONTINUE" },
141 { SAMETIME_MESSAGETYPE_CHANNEL_CREATE
, "CHANNEL_CREATE" },
142 { SAMETIME_MESSAGETYPE_CHANNEL_DESTROY
, "CHANNEL_DESTROY" },
143 { SAMETIME_MESSAGETYPE_CHANNEL_SEND
, "CHANNEL_SEND" },
144 { SAMETIME_MESSAGETYPE_CHANNEL_ACCEPT
, "CHANNEL_ACCEPT" },
146 { SAMETIME_MESSAGETYPE_SET_USER_STATUS
, "SET_USER_STATUS" },
147 { SAMETIME_MESSAGETYPE_SET_PRIVACY_LIST
, "SET_PRIVACY_LIST" },
148 { SAMETIME_MESSAGETYPE_SENSE_SERVICE
, "SENSE_SERVICE" },
149 { SAMETIME_MESSAGETYPE_ADMIN
, "ADMIN" },
150 { SAMETIME_MESSAGETYPE_ANNOUNCE
, "ANNOUNCE" },
155 #define SAMETIME_MESSAGEOPTION_ENCRYPT 0x4000
156 #define SAMETIME_MESSAGEOPTION_HAS_ATTRIBS 0x8000
158 static const value_string optionnames
[] = {
160 { SAMETIME_MESSAGEOPTION_ENCRYPT
, "ENCRYPT" },
161 { SAMETIME_MESSAGEOPTION_HAS_ATTRIBS
, "HAS_ATTRIBS" },
166 static const value_string userstatusnames
[] = {
167 { 0x0020, "ACTIVE" }, /* "I am available" */
168 { 0x0040, "IDLE" }, /* never seen in the wild, maybe non-pc :-) ? */
169 { 0x0060, "AWAY" }, /* "I am away from my computer now" */
170 { 0x0080, "BUSY" }, /* "Please do not disturb me" */
171 { 0x0008, "MEETING" }, /* "I am in a meeting" */
176 #define SAMETIME_SENDTYPE_AWARE_ADD 0x0068
177 #define SAMETIME_SENDTYPE_OPT_DO_SET 0x00c9
178 #define SAMETIME_SENDTYPE_AWARE_SNAPSHOT 0x01f4
179 #define SAMETIME_SENDTYPE_AWARE_UPDATE 0x01f5
180 #define SAMETIME_SENDTYPE_OPT_GOT_SET 0x0259
182 static const value_string sendtypenames
[] = {
183 { SAMETIME_SENDTYPE_AWARE_ADD
, "AWARE_ADD" },
184 { 0x0069, "AWARE_REMOVE" },
185 { SAMETIME_SENDTYPE_OPT_DO_SET
, "OPT_DO_SET" },
186 { 0x00cb, "OPT_WATCH" },
187 { SAMETIME_SENDTYPE_AWARE_SNAPSHOT
, "AWARE_SNAPSHOT" },
188 { SAMETIME_SENDTYPE_AWARE_UPDATE
, "AWARE_UPDATE" },
189 { SAMETIME_SENDTYPE_OPT_GOT_SET
, "OPT_GOT_SET" },
191 { 0x025d, "OPT_DID_SET" },
196 static const value_string awarenessnames
[] = {
199 { 0x0008, "SERVER" },
203 static const value_string codenames
[] = {
204 { 0x00000011, "SERVICE_AWARE" },
205 { 0x00000015, "SERVICE_RESOLVE" },
206 { 0x00000018, "SERVICE_STORAGE" },
207 { 0x0000001a, "SERVICE_DIRECTORY" },
209 { 0x80000011, "ERR_USER_SKETCHY" },
210 { 0x80000015, "ERR_TOKEN_INVALID" },
211 { 0x80000018, "ERR_PORT_IN_USE" },
212 { 0x80000022, "ERR_CHANNEL_DESTROYED" },
219 add_text_item(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
, int hf
)
223 /* heuristic rule, string should start w/ valid character(s) */
224 if (! tvb_get_guint8(tvb
, offset
+ 2))
227 length
= tvb_get_ntohs(tvb
, offset
);
229 /* the string length must not exceed the packet length */
230 if (length
> tvb_reported_length_remaining(tvb
, offset
+ 2))
233 /* add string length only if preferences is set */
234 if (global_sametime_show_length
)
235 proto_tree_add_item(tree
, hf_sametime_field_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
238 proto_tree_add_string(tree
, hf
, tvb
, offset
+ 2, length
, tvb_get_string(wmem_packet_scope(), tvb
, offset
+ 2, length
));
246 dissect_set_user_status(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
250 user_status
= tvb_get_ntohs(tvb
, offset
);
251 proto_item_append_text(tree
, ", %s", val_to_str(user_status
, userstatusnames
, "0x%04x"));
252 proto_tree_add_item(tree
, hf_sametime_user_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
254 proto_tree_add_item(tree
, hf_sametime_time
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
256 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
263 dissect_handshake(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
265 proto_tree_add_item(tree
, hf_sametime_handshake_major
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
267 proto_tree_add_item(tree
, hf_sametime_handshake_minor
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
270 proto_tree_add_item(tree
, hf_sametime_handshake_srvrcalc_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
272 proto_tree_add_item(tree
, hf_sametime_login_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
274 proto_tree_add_item(tree
, hf_sametime_handshake_loclcalc_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
277 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
279 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
286 dissect_handshake_ack(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
288 proto_tree_add_item(tree
, hf_sametime_handshake_major
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
290 proto_tree_add_item(tree
, hf_sametime_handshake_minor
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
292 proto_tree_add_item(tree
, hf_sametime_handshake_loclcalc_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
296 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
301 dissect_login(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
304 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
309 dissect_login_redirect(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
312 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
317 dissect_login_ack(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
319 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
320 proto_tree_add_item(tree
, hf_sametime_login_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
322 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
323 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
325 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
326 proto_tree_add_item(tree
, hf_sametime_handshake_loclcalc_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
328 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
330 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
331 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
336 dissect_channel_create(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
339 proto_tree_add_item(tree
, hf_sametime_channel_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
341 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
342 proto_tree_add_item(tree
, hf_sametime_channel_service
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
345 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
350 dissect_channel_send(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
352 guint16 send_type
, awareness
;
355 send_type
= tvb_get_ntohs(tvb
, offset
);
356 proto_item_append_text(tree
, ", %s", val_to_str(send_type
, sendtypenames
, "0x%04x"));
357 proto_tree_add_item(tree
, hf_sametime_channel_send_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
361 case SAMETIME_SENDTYPE_AWARE_ADD
:
363 awareness
= tvb_get_ntohs(tvb
, offset
);
364 proto_item_append_text(tree
, ", %s", val_to_str(awareness
, awarenessnames
, "0x%04x"));
365 proto_tree_add_item(tree
, hf_sametime_channel_awareness
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
367 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
371 case SAMETIME_SENDTYPE_OPT_DO_SET
:
373 na
= tvb_get_ntohl(tvb
, offset
);
376 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_country
);
377 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_postalcode
);
378 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_province
);
379 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_city
);
380 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_phone
);
382 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_location_name
);
383 add_text_item(tvb
, tree
, offset
, hf_sametime_location_timezone
);
385 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
390 case SAMETIME_SENDTYPE_OPT_GOT_SET
:
392 awareness
= tvb_get_ntohs(tvb
, offset
);
393 proto_item_append_text(tree
, ", %s", val_to_str(awareness
, awarenessnames
, "0x%04x"));
394 proto_tree_add_item(tree
, hf_sametime_channel_awareness
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
396 while (tvb_reported_length_remaining(tvb
, offset
) > 2) {
397 int n
= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
398 offset
+= (n
) ? n
: 1;
403 case SAMETIME_SENDTYPE_AWARE_SNAPSHOT
:
405 awareness
= tvb_get_ntohs(tvb
, offset
);
406 proto_item_append_text(tree
, ", %s", val_to_str(awareness
, awarenessnames
, "0x%04x"));
407 proto_tree_add_item(tree
, hf_sametime_channel_awareness
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
409 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
413 case SAMETIME_SENDTYPE_AWARE_UPDATE
:
416 awareness
= tvb_get_ntohs(tvb
, offset
);
417 proto_item_append_text(tree
, ", %s", val_to_str(awareness
, awarenessnames
, "0x%04x"));
418 proto_tree_add_item(tree
, hf_sametime_channel_awareness
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
420 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
422 if (tvb_get_guint8(tvb
, offset
)) {
424 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
425 dissect_set_user_status(tvb
, tree
, offset
);
432 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
438 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
440 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
444 case 0x0005: /* XML */
445 if (26 <= tvb_reported_length_remaining(tvb
, offset
+ 2)) {
447 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
454 if (4 <= tvb_reported_length_remaining(tvb
, offset
+ 2)) {
455 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
456 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
458 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
459 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
466 add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
479 dissect_channel_accept(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
482 if (tvb_reported_length_remaining(tvb
, offset
+ 2)) {
483 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
484 if (tvb_get_guint8(tvb
, offset
)) {
486 offset
+= add_text_item(tvb
, tree
, offset
, hf_sametime_field_text
);
487 dissect_set_user_status(tvb
, tree
, offset
);
494 dissect_sense_service(tvbuff_t
*tvb
, proto_tree
*tree
, int offset
)
498 code
= tvb_get_ntohl(tvb
, offset
);
499 proto_item_append_text(tree
, ", %s", val_to_str(code
, codenames
, "0x%04x"));
500 proto_tree_add_item(tree
, hf_sametime_code
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
505 here we really dissect the message(s)
508 dissect_sametime_content(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
510 proto_tree
*sametime_tree
;
512 static SametimeTap
*sinfo
;
514 int packet_length
, offset
= 0;
516 /* we expect either 1 heartbeat byte (0x80) or a sametime message */
517 packet_length
= tvb_reported_length_remaining(tvb
, offset
);
518 if (packet_length
== 1) {
519 message_type
= tvb_get_guint8(tvb
, 0);
521 } else if (packet_length
< 12) {
525 message_type
= tvb_get_ntohs(tvb
, 4);
528 /* add message type */
529 col_append_str(pinfo
->cinfo
, COL_INFO
, val_to_str(message_type
, messagetypenames
, "0x%04x"));
530 col_append_str(pinfo
->cinfo
, COL_INFO
, " ");
532 /* message type statistic */
533 sinfo
= wmem_new(wmem_packet_scope(), struct SametimeTap
);
534 sinfo
->message_type
= message_type
;
535 sinfo
->send_type
= -1;
536 sinfo
->user_status
= -1;
538 /* packet detail tree */
539 ti
= proto_tree_add_item(tree
, proto_sametime
, tvb
, offset
, -1, ENC_NA
);
540 sametime_tree
= proto_item_add_subtree(ti
, ett_sametime
);
541 proto_item_append_text(sametime_tree
, ", %s", val_to_str(message_type
, messagetypenames
, "0x%04x"));
543 /* dissect message */
544 if (message_type
== SAMETIME_MESSAGETYPE_HEARTBEAT
) {
545 proto_tree_add_item(sametime_tree
, hf_sametime_heartbeat
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
547 } else if (message_type
!= -1) {
548 proto_tree
*options_tree
;
551 /* first 4 bytes gives the length of the sametime message */
552 if (global_sametime_show_length
) {
553 proto_tree_add_item(sametime_tree
, hf_sametime_message_length
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
557 /* next 2 bytes gives the message type */
558 proto_tree_add_item(sametime_tree
, hf_sametime_message_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
561 /* next 2 bytes are the message options */
562 op
= proto_tree_add_item(sametime_tree
, hf_sametime_message_options
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
563 options_tree
= proto_item_add_subtree(op
, ett_sametime_options
);
564 proto_tree_add_item(options_tree
, hf_sametime_message_options_attribute
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
565 proto_tree_add_item(options_tree
, hf_sametime_message_options_encrypted
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
568 /* next 4 bytes contains the channel id */
569 proto_tree_add_item(sametime_tree
, hf_sametime_message_channel
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
572 switch (message_type
)
574 case SAMETIME_MESSAGETYPE_HANDSHAKE
:
575 dissect_handshake(tvb
, sametime_tree
, offset
);
578 case SAMETIME_MESSAGETYPE_HANDSHAKE_ACK
:
579 dissect_handshake_ack(tvb
, sametime_tree
, offset
);
582 case SAMETIME_MESSAGETYPE_HANDSHAKE_SYN
:
585 case SAMETIME_MESSAGETYPE_LOGIN
:
586 dissect_login(tvb
, sametime_tree
, offset
);
589 case SAMETIME_MESSAGETYPE_LOGIN_REDIRECT
:
590 dissect_login_redirect(tvb
, sametime_tree
, offset
);
593 case SAMETIME_MESSAGETYPE_LOGIN_ACK
:
594 dissect_login_ack(tvb
, sametime_tree
, offset
);
597 case SAMETIME_MESSAGETYPE_CHANNEL_CREATE
:
598 dissect_channel_create(tvb
, sametime_tree
, offset
);
601 case SAMETIME_MESSAGETYPE_CHANNEL_SEND
:
602 sinfo
->send_type
= dissect_channel_send(tvb
, sametime_tree
, offset
);
605 case SAMETIME_MESSAGETYPE_CHANNEL_ACCEPT
:
606 dissect_channel_accept(tvb
, sametime_tree
, offset
);
609 case SAMETIME_MESSAGETYPE_SET_USER_STATUS
:
610 sinfo
->user_status
= dissect_set_user_status(tvb
, sametime_tree
, offset
);
613 case SAMETIME_MESSAGETYPE_SENSE_SERVICE
:
614 dissect_sense_service(tvb
, sametime_tree
, offset
);
618 /* do not fill the statistics with useless data from encrypted packages */
619 sinfo
->message_type
= -1;
624 tap_queue_packet(sametime_tap
, pinfo
, sinfo
);
625 return tvb_length(tvb
);
633 sametime_stats_tree_packet(stats_tree
* st
, packet_info
* pinfo _U_
, epan_dissect_t
* edt _U_
, const void* p
)
635 struct SametimeTap
*pi
= (struct SametimeTap
*)p
;
637 tick_stat_node(st
, st_str_packet
, 0, FALSE
);
638 if (pi
->message_type
!= -1)
639 stats_tree_tick_pivot(st
, st_node_message_type
, val_to_str(pi
->message_type
, messagetypenames
, "Unknown (0x%04x)"));
641 if (pi
->send_type
!= -1)
642 stats_tree_tick_pivot(st
, st_node_send_type
, val_to_str(pi
->send_type
, sendtypenames
, "Unknown (0x%04x)"));
644 if (pi
->user_status
!= -1)
645 stats_tree_tick_pivot(st
, st_node_user_status
, val_to_str(pi
->user_status
, userstatusnames
, "Unknown (0x%04x)"));
655 sametime_stats_tree_init(stats_tree
* st
)
657 st_node_packet
= stats_tree_create_node(st
, st_str_packet
, 0, TRUE
);
658 st_node_message_type
= stats_tree_create_pivot(st
, st_str_message_type
, st_node_packet
);
659 st_node_send_type
= stats_tree_create_pivot(st
, st_str_send_type
, st_node_packet
);
660 st_node_user_status
= stats_tree_create_pivot(st
, st_str_user_status
, st_node_packet
);
665 length of the sametime message
668 get_sametime_message_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
670 /* XXX: Actually: the length of the tvb will always be 4 or greater at this point */
671 /* because tcp_dissect_pdus was called with 4 as a required "fixed length". */
672 /* But newer variants of this protocol with a full encrypted network stream */
673 /* may require a more sophisticated dissection logic here */
674 guint32 N
= tvb_length_remaining(tvb
, offset
);
676 return (N
< 4) ? N
: tvb_get_ntohl(tvb
, offset
) + 4;
684 dissect_sametime(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
686 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SAMETIME");
687 col_clear(pinfo
->cinfo
,COL_INFO
);
689 tcp_dissect_pdus(tvb
, pinfo
, tree
, global_sametime_reassemble_packets
, 4,
690 get_sametime_message_len
, dissect_sametime_content
, data
);
691 return tvb_length(tvb
);
696 proto_register_sametime(void)
698 static hf_register_info hf
[] = {
699 /*tcp payload is one byte : SAMETIME_MESSAGETYPE_HEARTBEAT*/
700 { &hf_sametime_heartbeat
,
701 { "heartbeat", "sametime.heartbeat",
707 /*sametime message header*/
708 { &hf_sametime_message_length
,
709 { "msg length", "sametime.message_length",
714 { &hf_sametime_message_type
,
715 { "msg type", "sametime.message_type",
717 VALS(messagetypenames
), 0x0,
720 { &hf_sametime_message_options
,
721 { "msg options", "sametime.message_options",
723 VALS(optionnames
), 0x0,
726 { &hf_sametime_message_options_encrypted
,
727 { "ENCRYPT", "sametime.message_options.encrypted",
729 NULL
, SAMETIME_MESSAGEOPTION_ENCRYPT
,
732 { &hf_sametime_message_options_attribute
,
733 { "HAS_ATTRIBS", "sametime.message_options.attribute",
735 NULL
, SAMETIME_MESSAGEOPTION_HAS_ATTRIBS
,
738 { &hf_sametime_message_channel
,
739 { "msg channel", "sametime.message_channel",
745 /*common fields within various message types*/
746 { &hf_sametime_field_length
,
747 { "length", "sametime.field_length",
752 { &hf_sametime_field_text
,
753 { "text", "sametime.field_text",
754 FT_STRING
, BASE_NONE
,
759 { "code", "sametime.code",
761 VALS(codenames
), 0x0,
764 { &hf_sametime_login_type
,
765 { "login type", "sametime.login_type",
771 { "time", "sametime.time",
778 { &hf_sametime_handshake_major
,
779 { "major", "sametime.handshake.major",
784 { &hf_sametime_handshake_minor
,
785 { "minor", "sametime.handshake.minor",
790 { &hf_sametime_handshake_srvrcalc_addr
,
791 { "srvr", "sametime.handshake.srvrcalc_addr",
796 { &hf_sametime_handshake_loclcalc_addr
,
797 { "locl", "sametime.handshake.loclcalc_addr",
804 { &hf_sametime_channel_service
,
805 { "service id", "sametime.channel.service",
810 { &hf_sametime_channel_id
,
811 { "channel id", "sametime.channel.id",
816 { &hf_sametime_channel_send_type
,
817 { "send type", "sametime.channel.send_type",
819 VALS(sendtypenames
), 0,
822 { &hf_sametime_channel_awareness
,
823 { "awareness", "sametime.channel.awareness",
825 VALS(awarenessnames
), 0x0,
830 { &hf_sametime_user_status
,
831 { "user status", "sametime.user_status_type",
833 VALS(userstatusnames
), 0x0,
838 { &hf_sametime_location_name
,
839 { "name", "sametime.location.name",
840 FT_STRING
, BASE_NONE
,
844 { &hf_sametime_location_city
,
845 { "city", "sametime.location.city",
846 FT_STRING
, BASE_NONE
,
850 { &hf_sametime_location_province
,
851 { "province", "sametime.location.province",
852 FT_STRING
, BASE_NONE
,
856 { &hf_sametime_location_postalcode
,
857 { "postal code", "sametime.location.postalcode",
858 FT_STRING
, BASE_NONE
,
862 { &hf_sametime_location_country
,
863 { "country", "sametime.location.country",
864 FT_STRING
, BASE_NONE
,
868 { &hf_sametime_location_phone
,
869 { "phone", "sametime.location.phone",
870 FT_STRING
, BASE_NONE
,
874 { &hf_sametime_location_timezone
,
875 { "time zone", "sametime.location.timezone",
876 FT_STRING
, BASE_NONE
,
882 static gint
*ett
[] = {
884 &ett_sametime_options
887 module_t
*sametime_module
;
889 proto_sametime
= proto_register_protocol (
890 "Sametime Protocol", /* name */
891 "SAMETIME", /* short name */
892 "sametime" /* abbrev */
894 proto_register_field_array(proto_sametime
, hf
, array_length(hf
));
895 proto_register_subtree_array(ett
, array_length(ett
));
897 sametime_tap
= register_tap("sametime");
899 /* Preference setting */
900 sametime_module
= prefs_register_protocol(proto_sametime
, NULL
);
901 prefs_register_bool_preference(sametime_module
, "show_length",
903 "Show length of text field",
904 &global_sametime_show_length
);
905 prefs_register_bool_preference(sametime_module
, "reassemble",
906 "Reassemble","reassemble packets",
907 &global_sametime_reassemble_packets
);
908 prefs_register_uint_preference(sametime_module
, "tcp_port",
909 "SAMETIME port number",
910 "port number for sametime traffic",
911 10, &global_sametime_port
);
919 proto_reg_handoff_sametime(void)
921 static gboolean initialized
= FALSE
;
922 static guint saved_sametime_tcp_port
;
925 sametime_handle
= new_create_dissector_handle(dissect_sametime
, proto_sametime
);
926 stats_tree_register("sametime", "sametime", "Sametime/Messages", 0,
927 sametime_stats_tree_packet
,
928 sametime_stats_tree_init
, NULL
);
931 dissector_delete_uint("tcp.port", saved_sametime_tcp_port
, sametime_handle
);
934 dissector_add_uint("tcp.port", global_sametime_port
, sametime_handle
);
935 saved_sametime_tcp_port
= global_sametime_port
;