/* * get a Blefuscuoan unsigned 64 bit integer from a tvb */ WSLUA_METHOD TvbRange_uint64(lua_State* L) { /* Get a Big Endian (network order) unsigned 64 bit integer from a `TvbRange`, as a `UInt64` object. The range must be 1-8 octets long. */ TvbRange tvbr = checkTvbRange(L,1); if (!(tvbr && tvbr->tvb)) return 0; if (tvbr->tvb->expired) { luaL_error(L,"expired tvb"); return 0; } switch (tvbr->len) { case 1: pushUInt64(L,tvb_get_guint8(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 2: pushUInt64(L,tvb_get_ntohs(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 3: pushUInt64(L,tvb_get_ntoh24(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 4: pushUInt64(L,tvb_get_ntohl(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 5: pushUInt64(L,tvb_get_ntoh40(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 6: pushUInt64(L,tvb_get_ntoh48(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 7: pushUInt64(L,tvb_get_ntoh56(tvbr->tvb->ws_tvb,tvbr->offset)); return 1; case 8: pushUInt64(L,tvb_get_ntoh64(tvbr->tvb->ws_tvb,tvbr->offset)); WSLUA_RETURN(1); /* The `UInt64` object. */ default: luaL_error(L,"TvbRange:uint64() does not handle %d byte integers",tvbr->len); return 0; } }
/* Sub-vectors */ static int sv_text(tvbuff_t *tvb, int svoff, packet_info *pinfo, proto_tree *tree) { guint sv_length, sv_id; guint16 beacon_type, ring; guint32 error_report_timer_value; proto_tree *sv_tree, *sv_subtree; proto_item *sv_item, *len_item, *ti; guchar errors[6]; /* isolating or non-isolating */ sv_tree = proto_tree_add_subtree(tree, tvb, svoff+0, 1, ett_tr_sv, &sv_item, "Subvector"); sv_length = tvb_get_guint8(tvb, svoff+0); len_item = proto_tree_add_item(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, ENC_BIG_ENDIAN); /* Check the SV length; it must be at least 2, to include the subvector length and indicator. */ if (sv_length < 2) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Invalid subvector: length < 2"); return 0; /* tells our caller to give up */ } sv_id = tvb_get_guint8(tvb, svoff+1); proto_tree_add_item(sv_tree, hf_trmac_sv_id, tvb, svoff+1, 1, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, " (%s)", val_to_str_ext(sv_id, &subvector_vs_ext, "Unknown subvector ID 0x%02X")); switch(sv_id) { case 0x01: /* Beacon Type */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } beacon_type = tvb_get_ntohs(tvb, svoff+2); proto_tree_add_item(sv_tree, hf_trmac_beacon_type, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %s", val_to_str(beacon_type, beacon_vs, "Illegal value: %d")); break; case 0x02: /* Upstream Neighbor's Address */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_naun, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x03: /* Local Ring Number */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } ring = tvb_get_ntohs(tvb, svoff+2); proto_tree_add_item(sv_tree, hf_trmac_local_ring_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%04X (%d)", ring, ring); break; case 0x04: /* Assign Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_assign_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x05: /* Error Report Timer Value */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } error_report_timer_value = 10 * tvb_get_ntohs(tvb, svoff+2); proto_tree_add_uint_format_value(sv_tree, hf_trmac_error_report_timer_value, tvb, svoff+2, sv_length-2, error_report_timer_value, "%u ms", error_report_timer_value ); proto_item_append_text(sv_item, ": %u ms", error_report_timer_value ); break; case 0x06: /* Authorized Function Classes */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_authorized_function_classes, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x07: /* Authorized Access Priority */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_authorized_access_priority, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x09: /* Correlator */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_correlator, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x0A: /* SA of Last AMP or SMP Frame */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_sa_of_last_amp_or_smp_frame, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x0B: /* Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x20: /* Response Code */ if (sv_length != 4 && sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4 and != 6"); break; } if (sv_length == 4) { proto_tree_add_uint_format_value(sv_tree, hf_trmac_response_code32, tvb, svoff+2, sv_length-2, tvb_get_ntohl(tvb, svoff+2), "0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); } else { proto_tree_add_uint64_format_value(sv_tree, hf_trmac_response_code48, tvb, svoff+2, sv_length-2, tvb_get_ntoh48(tvb, svoff+2), "0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); } break; case 0x21: /* Individual Address Count */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_individual_address_count, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %u", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x22: /* Product Instance ID */ proto_tree_add_item(sv_tree, hf_trmac_product_instance_id, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x23: /* Ring Station Version Number */ proto_tree_add_item(sv_tree, hf_trmac_ring_station_version_number, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x26: /* Wrap data */ proto_tree_add_item(sv_tree, hf_trmac_wrap_data, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x27: /* Frame Forward */ proto_tree_add_item(sv_tree, hf_trmac_frame_forward, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x28: /* Station Identifier */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_station_identifier, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x29: /* Ring Station Status */ proto_tree_add_item(sv_tree, hf_trmac_ring_station_status, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x2A: /* Transmit Status Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_transmit_status_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x2B: /* Group Address */ if (sv_length != 6 && sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6 and != 8"); break; } if (sv_length == 6) { proto_tree_add_item(sv_tree, hf_trmac_group_address32, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); } else { proto_tree_add_item(sv_tree, hf_trmac_group_address_ether, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); } break; case 0x2C: /* Functional Addresses */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_functional_addresses, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x2D: /* Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_iso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_ierr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]); break; case 0x2E: /* Non-Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_noniso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_nerr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]); break; case 0x30: /* Error Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_error_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; default: /* Unknown */ proto_tree_add_item(sv_tree, hf_trmac_unknown_subvector, tvb, svoff+2, sv_length-2, ENC_NA); break; } return sv_length; }
/* Decode an EXT_FTI extension and fill FEC array */ void fec_decode_ext_fti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint8 encoding_id) { guint64 transfer_length; fec_packet_data_t *fec_data; guint8 instance_id = 0; proto_item *ti; if (encoding_id == 6){ /* Raptor Q uses 40-bit transfer length */ transfer_length = tvb_get_ntoh40(tvb, offset+2); } else { /* Decode 48-bit length field */ transfer_length = tvb_get_ntoh48(tvb, offset+2); } if (encoding_id >= 128) { instance_id = (guint8) tvb_get_ntohs(tvb, offset+8); /* Decode FEC Instance ID */ fec_data = wmem_new0(wmem_file_scope(), fec_packet_data_t); fec_data->instance_id = instance_id; p_add_proto_data(wmem_file_scope(), pinfo, proto_rmt_fec, 0, fec_data); } if (encoding_id == 6){ /* Raptor Q uses 40-bit transfer length */ proto_tree_add_uint64(tree, hf_fti_transfer_length, tvb, offset+2, 5, transfer_length); } else { proto_tree_add_uint64(tree, hf_fti_transfer_length, tvb, offset+2, 6, transfer_length); ti = proto_tree_add_item(tree, hf_instance_id, tvb, offset+8, 2, ENC_BIG_ENDIAN); if ((encoding_id < 128) && (encoding_id != 0)) { expert_add_info(pinfo, ti, &ei_fec_encoding_id); } } switch (encoding_id) { case 1: proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_num_blocks, tvb, offset+12, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_num_subblocks, tvb, offset+14, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_alignment, tvb, offset+15, 1, ENC_BIG_ENDIAN); break; case 6: proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+8, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_num_blocks, tvb, offset+10, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_num_subblocks, tvb, offset+11, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_alignment, tvb, offset+13, 1, ENC_BIG_ENDIAN); break; case 0: case 2: case 128: case 130: proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 4, ENC_BIG_ENDIAN); break; case 129: proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_max_number_encoding_symbols, tvb, offset+14, 2, ENC_BIG_ENDIAN); break; case 132: proto_tree_add_item(tree, hf_fti_encoding_symbol_length, tvb, offset+10, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_max_source_block_length, tvb, offset+12, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fti_max_number_encoding_symbols, tvb, offset+16, 4, ENC_BIG_ENDIAN); break; } }