static void dissect_channel_accept(tvbuff_t *tvb, proto_tree *tree, int offset) { offset += 34; if (tvb_reported_length_remaining(tvb, offset + 2)) { offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); if (tvb_get_guint8(tvb, offset)) { offset += 1; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); dissect_set_user_status(tvb, tree, offset); } } }
static guint16 dissect_channel_send(tvbuff_t *tvb, proto_tree *tree, int offset) { guint16 send_type, awareness; guint na; send_type = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(send_type, sendtypenames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_send_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; switch (send_type) { case SAMETIME_SENDTYPE_AWARE_ADD: offset += 8; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case SAMETIME_SENDTYPE_OPT_DO_SET: offset += 20; na = tvb_get_ntohl(tvb, offset); offset += 4; if (na == 0x33) { offset += add_text_item(tvb, tree, offset, hf_sametime_location_country); offset += add_text_item(tvb, tree, offset, hf_sametime_location_postalcode); offset += add_text_item(tvb, tree, offset, hf_sametime_location_province); offset += add_text_item(tvb, tree, offset, hf_sametime_location_city); offset += add_text_item(tvb, tree, offset, hf_sametime_location_phone); offset += 1; offset += add_text_item(tvb, tree, offset, hf_sametime_location_name); add_text_item(tvb, tree, offset, hf_sametime_location_timezone); } else { add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case SAMETIME_SENDTYPE_OPT_GOT_SET: offset += 8; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; while (tvb_reported_length_remaining(tvb, offset) > 2) { int n = add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += (n) ? n : 1; } break; case SAMETIME_SENDTYPE_AWARE_SNAPSHOT: offset += 12; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case SAMETIME_SENDTYPE_AWARE_UPDATE: offset += 4; offset += 4; awareness = tvb_get_ntohs(tvb, offset); proto_item_append_text(tree, ", %s", val_to_str(awareness, awarenessnames, "0x%04x")); proto_tree_add_item(tree, hf_sametime_channel_awareness, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 4; if (tvb_get_guint8(tvb, offset)) { offset += 1; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); dissect_set_user_status(tvb, tree, offset); } break; case 0x0000: offset += 14; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case 0x0002: offset += 8; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 3; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; case 0x0005: /* XML */ if (26 <= tvb_reported_length_remaining(tvb, offset + 2)) { offset += 26; add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case 0x0007: offset += 8; if (4 <= tvb_reported_length_remaining(tvb, offset + 2)) { offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); offset += 3; offset += add_text_item(tvb, tree, offset, hf_sametime_field_text); add_text_item(tvb, tree, offset, hf_sametime_field_text); } break; case 0x025a: offset += 10; add_text_item(tvb, tree, offset, hf_sametime_field_text); break; default: break; } return send_type; }
/* here we really dissect the message(s) */ static void dissect_sametime_content(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *sametime_tree; proto_item *ti; static SametimeTap *sinfo; gint message_type; int packet_length, offset = 0; /* we expect either 1 heartbeat byte (0x80) or a sametime message */ packet_length = tvb_reported_length_remaining(tvb, offset); if (packet_length == 1) { message_type = tvb_get_guint8(tvb, 0); } else if (packet_length < 12) { message_type = -1; } else { message_type = tvb_get_ntohs(tvb, 4); } /* add message type */ col_append_str(pinfo->cinfo, COL_INFO, val_to_str(message_type, messagetypenames, "0x%04x")); col_append_str(pinfo->cinfo, COL_INFO, " "); /* message type statistic */ sinfo = ep_new(struct SametimeTap); sinfo->message_type = message_type; sinfo->send_type = -1; sinfo->user_status = -1; /* packet detail tree */ ti = proto_tree_add_item(tree, proto_sametime, tvb, offset, -1, ENC_NA); sametime_tree = proto_item_add_subtree(ti, ett_sametime); proto_item_append_text(sametime_tree, ", %s", val_to_str(message_type, messagetypenames, "0x%04x")); /* dissect message */ if (message_type == SAMETIME_MESSAGETYPE_HEARTBEAT) { proto_tree_add_item(sametime_tree, hf_sametime_heartbeat, tvb, offset, 1, ENC_BIG_ENDIAN); } else if (message_type != -1) { proto_tree *options_tree; proto_item *op; /* first 4 bytes gives the length of the sametime message */ if (global_sametime_show_length) { proto_tree_add_item(sametime_tree, hf_sametime_message_length, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; /* next 2 bytes gives the message type */ proto_tree_add_item(sametime_tree, hf_sametime_message_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* next 2 bytes are the message options */ op = proto_tree_add_item(sametime_tree, hf_sametime_message_options, tvb, offset, 2, ENC_BIG_ENDIAN); options_tree = proto_item_add_subtree(op, ett_sametime_options); proto_tree_add_item(options_tree, hf_sametime_message_options_attribute, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(options_tree, hf_sametime_message_options_encrypted, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* next 4 bytes contains the channel id */ proto_tree_add_item(sametime_tree, hf_sametime_message_channel, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; switch (message_type) { case SAMETIME_MESSAGETYPE_HANDSHAKE: dissect_handshake(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_HANDSHAKE_ACK: dissect_handshake_ack(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_HANDSHAKE_SYN: break; case SAMETIME_MESSAGETYPE_LOGIN: dissect_login(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_LOGIN_REDIRECT: dissect_login_redirect(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_LOGIN_ACK: dissect_login_ack(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_CHANNEL_CREATE: dissect_channel_create(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_CHANNEL_SEND: sinfo->send_type = dissect_channel_send(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_CHANNEL_ACCEPT: dissect_channel_accept(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_SET_USER_STATUS: sinfo->user_status = dissect_set_user_status(tvb, sametime_tree, offset); break; case SAMETIME_MESSAGETYPE_SENSE_SERVICE: dissect_sense_service(tvb, sametime_tree, offset); break; default: /* do not fill the statistics with useless data from encrypted packages */ sinfo->message_type = -1; break; } } tap_queue_packet(sametime_tap, pinfo, sinfo); }