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_edsa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 edsa_tag; guint8 edsa_tagged; guint8 edsa_dev; guint8 edsa_port; guint8 edsa_trunk; guint8 edsa_cfi; guint8 edsa_prio; guint8 edsa_vid; guint8 edsa_code; guint16 edsa_ethtype; gboolean is_802_2; proto_tree *edsa_tree = NULL; proto_item *ti; edsa_tag = tvb_get_bits8(tvb, (8 * 2) + 0 , 2); edsa_tagged = tvb_get_bits8(tvb, (8 * 2) + 2, 1); edsa_dev = tvb_get_bits8(tvb, (8 * 2) + 3, 5); edsa_port = tvb_get_bits8(tvb, (8 * 3) + 0, 5); edsa_trunk = tvb_get_bits8(tvb, (8 * 3) + 5, 1); edsa_cfi = tvb_get_bits8(tvb, (8 * 3) + 7, 0); edsa_prio = tvb_get_bits8(tvb, (8 * 4) + 0, 3); edsa_vid = tvb_get_bits16(tvb, (8 * 4) + 4, 12, TRUE); edsa_code = (tvb_get_bits8(tvb, (8 * 3) + 5, 2) << 2 | tvb_get_bits8(tvb, (8 * 4) + 3, 1)); edsa_ethtype = tvb_get_ntohs(tvb, 6); if (tree) { ti = proto_tree_add_protocol_format( tree, proto_edsa, tvb, 0, EDSA_HEADER_SIZE, "EtherType Distributed Switch Architecture, %s Dev: %d Port: %d VID: %d", val_to_str(edsa_tag, tag_vals, "tag %d"), edsa_dev, edsa_port, edsa_vid); edsa_tree = proto_item_add_subtree(ti, ett_edsa); proto_tree_add_uint(edsa_tree, hf_edsa_tag, tvb, 2, 1, edsa_tag); switch (edsa_tag) { case TAG_TO_CPU: proto_tree_add_boolean( edsa_tree, hf_edsa_tagged, tvb, 2, 1, edsa_tagged); proto_tree_add_uint( edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev); proto_tree_add_uint( edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port); proto_tree_add_uint( edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid); proto_tree_add_uint( edsa_tree, hf_edsa_code, tvb, 3, 2, edsa_code); proto_tree_add_uint( edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio); proto_tree_add_boolean( edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi); break; case TAG_FROM_CPU: proto_tree_add_boolean( edsa_tree, hf_edsa_tagged, tvb, 2, 1, edsa_tagged); proto_tree_add_uint( edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev); proto_tree_add_uint( edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port); proto_tree_add_uint( edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid); proto_tree_add_uint( edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio); proto_tree_add_boolean( edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi); break; case TAG_FORWARD: proto_tree_add_boolean( edsa_tree, hf_edsa_tagged, tvb, 2, 1, edsa_tagged); proto_tree_add_uint( edsa_tree, hf_edsa_dev, tvb, 2, 1, edsa_dev); proto_tree_add_uint( edsa_tree, hf_edsa_port, tvb, 3, 1, edsa_port); proto_tree_add_boolean( edsa_tree, hf_edsa_trunk, tvb, 3, 1, edsa_trunk); proto_tree_add_uint( edsa_tree, hf_edsa_vid, tvb, 4, 2, edsa_vid); proto_tree_add_uint( edsa_tree, hf_edsa_prio, tvb, 4, 1, edsa_prio); proto_tree_add_boolean( edsa_tree, hf_edsa_cfi, tvb, 3, 1, edsa_cfi); break; } } if (edsa_ethtype <= IEEE_802_3_MAX_LEN) { /* Is there an 802.2 layer? I can tell by looking at the first 2 bytes after the VLAN header. If they are 0xffff, then what follows the VLAN header is an IPX payload, meaning no 802.2. (IPX/SPX is they only thing that can be contained inside a straight 802.3 packet, so presumably the same applies for Ethernet VLAN packets). A non-0xffff value means that there's an 802.2 layer inside the VLAN layer */ is_802_2 = TRUE; /* Don't throw an exception for this check (even a * BoundsError) */ if (tvb_captured_length_remaining(tvb, 8) >= 2) { if (tvb_get_ntohs(tvb, 8) == 0xffff) { is_802_2 = FALSE; } dissect_802_3(edsa_ethtype, is_802_2, tvb, 8, pinfo, tree, edsa_tree, hf_edsa_len, hf_edsa_trailer, &ei_edsa_len, 0); } } else { ethertype_data_t ethertype_data; ethertype_data.etype = edsa_ethtype; ethertype_data.offset_after_ethertype = 8; ethertype_data.fh_tree = edsa_tree; ethertype_data.etype_id = hf_edsa_ethtype; ethertype_data.trailer_id = hf_edsa_trailer; ethertype_data.fcs_len = 0; call_dissector_with_data(ethertype_handle, tvb, pinfo, tree, ðertype_data); } }