示例#1
0
static void
dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item     *main_item;
    proto_tree     *main_tree;
    btl2cap_data_t *l2cap_data;
    gint            offset = 0;
    gboolean        is_client_message;

    l2cap_data = (btl2cap_data_t *) pinfo->private_data;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCRP");
    col_clear(pinfo->cinfo, COL_INFO);

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_add_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_add_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
                pinfo->p2p_dir);
            break;
    }

    main_item = proto_tree_add_item(tree, proto_bthcrp, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_bthcrp);

/* TODO: Implement streams reconizing by SDP
 * Server provide SDP record for Control and Data PSM
 * Client provide SDP record for Notification PSM (optional)
 */
    is_client_message = (is_client && pinfo->p2p_dir == P2P_DIR_SENT) ||
            (!is_client && pinfo->p2p_dir == P2P_DIR_RECV);

    if (psm_control != 0 && l2cap_data->psm == psm_control) {
        offset = dissect_control(tvb, pinfo, main_tree, offset, is_client_message);
    } else if (psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) {
        offset = dissect_data(tvb, pinfo, main_tree, offset);
    } else if (psm_notification != 0 && l2cap_data->psm == psm_notification) {
        offset = dissect_notification(tvb, pinfo, main_tree, offset, is_client_message);
    } else {
        col_append_fstr(pinfo->cinfo, COL_INFO, "HCRP stream (CID: 0x%04X)", l2cap_data->cid);
    }

    if (tvb_length_remaining(tvb, offset)) {
        proto_item *pitem;

        pitem = proto_tree_add_item(main_tree, hf_bthcrp_data, tvb, offset, -1, ENC_NA);
        expert_add_info_format(pinfo, pitem, PI_PROTOCOL, PI_WARN,
                "Unexpected data");
    }
}
示例#2
0
static gint
dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item      *main_item;
    proto_tree      *main_tree;
    gint             offset = 0;
    gint             protocol = -1;
    gboolean         is_client_message = FALSE;
    gint             previous_proto;

    previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
    if (previous_proto == proto_btl2cap) {
        btl2cap_data_t  *l2cap_data;
        wmem_tree_key_t  key[10];
        guint32          interface_id;
        guint32          adapter_id;
        guint32          sdp_psm = SDP_PSM_DEFAULT;
        guint32          direction;
        guint32          bd_addr_oui;
        guint32          bd_addr_id;
        guint32          service_type;
        guint32          service_channel;
        guint32          frame_number;
        service_info_t  *service_info;

        l2cap_data = (btl2cap_data_t *) data;

        interface_id       = l2cap_data->interface_id;
        adapter_id         = l2cap_data->adapter_id;

        direction       = (l2cap_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
        if (direction == P2P_DIR_RECV) {
            bd_addr_oui = l2cap_data->remote_bd_addr_oui;
            bd_addr_id  = l2cap_data->remote_bd_addr_id;
        } else {
            bd_addr_oui = 0;
            bd_addr_id  = 0;
        }

        service_type    = BTSDP_L2CAP_PROTOCOL_UUID;
        service_channel = l2cap_data->psm;
        frame_number    = pinfo->fd->num;

        key[0].length = 1;
        key[0].key = &interface_id;
        key[1].length = 1;
        key[1].key = &adapter_id;
        key[2].length = 1;
        key[2].key = &sdp_psm;
        key[3].length = 1;
        key[3].key = &direction;
        key[4].length = 1;
        key[4].key = &bd_addr_oui;
        key[5].length = 1;
        key[5].key = &bd_addr_id;
        key[6].length = 1;
        key[6].key = &service_type;
        key[7].length = 1;
        key[7].key = &service_channel;
        key[8].length = 1;
        key[8].key = &frame_number;
        key[9].length = 0;
        key[9].key = NULL;

        service_info = btsdp_get_service_info(key);
        if (service_info && service_info->interface_id == interface_id &&
                service_info->adapter_id == adapter_id &&
                service_info->sdp_psm == SDP_PSM_DEFAULT &&
                ((service_info->direction == P2P_DIR_RECV &&
                service_info->bd_addr_oui == bd_addr_oui &&
                service_info->bd_addr_id == bd_addr_id) ||
                (service_info->direction != P2P_DIR_RECV &&
                service_info->bd_addr_oui == 0 &&
                service_info->bd_addr_id == 0)) &&
                service_info->type == BTSDP_L2CAP_PROTOCOL_UUID &&
                service_info->channel == l2cap_data->psm) {

            if ((service_info->protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID ||
                    service_info->protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) &&
                    ((!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
                    (l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
                is_client_message = TRUE;
            } else if (service_info->protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID &&
                    ((l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
                    (!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
                is_client_message = TRUE;
            }

            protocol = service_info->protocol;
        }

        if (psm_control != 0 && l2cap_data->psm == psm_control) {
            protocol = BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID;
        } else if (psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) {
            protocol = BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID;
        } else if (psm_notification != 0 && l2cap_data->psm == psm_notification) {
            protocol = BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID;
        }

    }

    main_item = proto_tree_add_item(tree, proto_bthcrp, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_bthcrp);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCRP");

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
            break;
    }

    if (force_client != FORCE_CLIENT_DEFAULT) {
        is_client_message = (force_client == FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_SENT) ||
                (force_client != FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_RECV);
    }

    if (protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID) {
        offset = dissect_control(tvb, pinfo, main_tree, offset, is_client_message);
    } else if (protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) {
        offset = dissect_data(tvb, pinfo, main_tree, offset);
    } else if (protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID) {
        offset = dissect_notification(tvb, pinfo, main_tree, offset, is_client_message);
    } else {
        col_append_fstr(pinfo->cinfo, COL_INFO, "HCRP stream");
    }

    if (tvb_reported_length_remaining(tvb, offset)) {
        proto_item *pitem;

        pitem = proto_tree_add_item(main_tree, hf_bthcrp_data, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
        expert_add_info(pinfo, pitem, &ei_bthcrp_unexpected_data);
    }

    return offset;
}