Beispiel #1
0
WSLUA_METHOD TvbRange_bitfield(lua_State* L) {
	/* Get a bitfield from a TvbRange. */
#define WSLUA_OPTARG_TvbRange_bitfield_POSITION 2 /* The bit offset from the beginning of the TvbRange. Defaults to 0. */
#define WSLUA_OPTARG_TvbRange_bitfield_LENGTH 3 /* The length (in bits) of the field. Defaults to 1. */

    TvbRange tvbr = checkTvbRange(L,1);
    int pos = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_POSITION,0);
    int len = luaL_optint(L,WSLUA_OPTARG_TvbRange_bitfield_LENGTH,1);

    if (!(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    if ((pos+len) > (tvbr->len<<3)) {
        luaL_error(L, "Requested bitfield out of range");
        return 0;
    }

    if (len <= 8) {
        lua_pushnumber(L,(lua_Number)tvb_get_bits8(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len));
        return 1;
    } else if (len <= 16) {
        lua_pushnumber(L,tvb_get_bits16(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
        return 1;
    } else if (len <= 32) {
        lua_pushnumber(L,tvb_get_bits32(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE));
        return 1;
    } else if (len <= 64) {
        UInt64 num = (UInt64)g_malloc(sizeof(guint64));
        *num = tvb_get_bits64(tvbr->tvb->ws_tvb,tvbr->offset*8 + pos, len, FALSE);
        pushUInt64(L,num);
        WSLUA_RETURN(1); /* The bitfield value */
    } else {
        luaL_error(L,"TvbRange:bitfield() does not handle %d bits",len);
        return 0;
    }
}
static void dissect_turbocell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    proto_item *ti, *name_item;
    proto_tree *turbocell_tree = NULL, *network_tree;
    tvbuff_t   *next_tvb;
    int i=0;
    guint8 packet_type;
    guint8 * str_name;
    guint str_len;
    gint remaining_length;

    packet_type = tvb_get_guint8(tvb, 0);

    if (!(packet_type & 0x0F)) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Beacon)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }  else if ( packet_type == TURBOCELL_TYPE_MANAGEMENT ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Management)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else if ( packet_type == TURBOCELL_TYPE_DATA ) {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Data)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    } else {
        col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Unknown)");
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell");
    }

    if (tree) {
        ti = proto_tree_add_item(tree, proto_turbocell, tvb, 0, 20, ENC_NA);

        turbocell_tree = proto_item_add_subtree(ti, ett_turbocell);

        proto_tree_add_item(turbocell_tree, hf_turbocell_type, tvb, 0, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_satmode, tvb, 1, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_nwid, tvb, 1, 1, ENC_BIG_ENDIAN);

        /* it seem when we have this magic number,that means an alternate header version */

        if (tvb_get_bits64(tvb, 64,48,ENC_BIG_ENDIAN) != G_GINT64_CONSTANT(0x000001fe23dc45ba)) {
            proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x02, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x04, 6, ENC_NA);
            proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x0A, 3, ENC_BIG_ENDIAN);

        } else {
            proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x02, 3, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x05, 3, ENC_BIG_ENDIAN);
            proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x08, 6, ENC_NA);
        }

        proto_tree_add_item(turbocell_tree, hf_turbocell_unknown, tvb, 0x0E, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(turbocell_tree, hf_turbocell_ip, tvb, 0x10, 4, ENC_BIG_ENDIAN);

    }

    remaining_length=tvb_length_remaining(tvb, 0x14);

    if (remaining_length > 6) {

        /* If the first character is a printable character that means we have a payload with network info */
        /* I couldn't find anything in the header that would definitvely indicate if payload is either data or network info */
        /* Since the frame size is limited this should work ok */

        if (tvb_get_guint8(tvb, 0x14)>=0x20) {
            name_item = proto_tree_add_item(turbocell_tree, hf_turbocell_name, tvb, 0x14, 30, ENC_ASCII|ENC_NA);
            network_tree = proto_item_add_subtree(name_item, ett_network);

            str_name=tvb_get_ephemeral_stringz(tvb, 0x14, &str_len);
            if (check_col (pinfo->cinfo, COL_INFO) && str_len > 0)
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Network=\"%s\"",format_text(str_name, str_len-1));

            while(tvb_get_guint8(tvb, 0x34 + 8*i)==0x00 && (tvb_length_remaining(tvb,0x34 + 8*i) > 6) && (i<32)) {
                proto_tree_add_item(network_tree, hf_turbocell_station[i], tvb, 0x34+8*i, 6, ENC_NA);
                i++;
            }

            /*Couldn't make sense of the apparently random data in the end*/

            next_tvb = tvb_new_subset_remaining(tvb, 0x34 + 8*i);
            call_dissector(data_handle, next_tvb, pinfo, tree);

        } else {

            tvbuff_t *volatile msdu_tvb = NULL;
            guint32 msdu_offset = 0x04;
            guint16 j = 1;
            guint16 msdu_length;

            proto_item *parent_item;
            proto_tree *mpdu_tree;
            proto_tree *subframe_tree;

            next_tvb = tvb_new_subset(tvb, 0x14, -1, tvb_get_ntohs(tvb, 0x14));
            parent_item = proto_tree_add_protocol_format(tree, proto_aggregate, next_tvb, 0,
                          tvb_reported_length_remaining(next_tvb, 0), "Turbocell Aggregate Frames");
            mpdu_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_parent_tree);
            proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_len, next_tvb, 0x00, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_unknown1, next_tvb, 0x02, 2, ENC_BIG_ENDIAN);

            remaining_length=tvb_length_remaining(next_tvb, msdu_offset);

            do {
                msdu_length = (tvb_get_letohs(next_tvb, msdu_offset) & 0x0FFF);
                if (msdu_length==0) break;
                parent_item = proto_tree_add_uint_format(mpdu_tree, hf_turbocell_aggregate_msdu_header_text,
                              next_tvb,msdu_offset, msdu_length + 0x02,j, "A-MSDU Subframe #%u", j);

                subframe_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_subframe_tree);
                j++;

                proto_tree_add_uint_format(subframe_tree, hf_turbocell_aggregate_msdu_len, next_tvb, msdu_offset, 2,
                                           msdu_length, "MSDU length: %u (0x%04X)", msdu_length,msdu_length);
                proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_unknown2, next_tvb, msdu_offset+1, 1, ENC_BIG_ENDIAN);

                msdu_offset += 0x02;
                remaining_length -= 0x02;
                msdu_tvb = tvb_new_subset(next_tvb, msdu_offset, (msdu_length>remaining_length)?remaining_length:msdu_length, msdu_length);
                call_dissector(eth_handle, msdu_tvb, pinfo, subframe_tree);
                msdu_offset += msdu_length;
                remaining_length -= msdu_length;
            } while (remaining_length > 6);

            if (remaining_length > 2) {
                next_tvb = tvb_new_subset_remaining(next_tvb, msdu_offset);
                call_dissector(data_handle, next_tvb, pinfo, tree);
            }
        }
    }
}