gint rtps_util_add_locator_t(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset,
                             const guint encoding, const char *label) {

  proto_tree *ti;
  proto_tree *locator_tree;
  guint32 kind;
  gint32 port;
  const gint parameter_size = 24;

  locator_tree = proto_tree_add_subtree(tree, tvb, offset, parameter_size, ett_rtps_locator,
          NULL, label);

  proto_tree_add_item_ret_uint(locator_tree, hf_rtps_locator_kind, tvb, offset, 4, encoding, &kind);
  switch (kind) {
    case LOCATOR_KIND_UDPV4:
    case LOCATOR_KIND_TUDPV4: {
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv4, tvb, offset+20, 4,
              ENC_BIG_ENDIAN);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      proto_item_append_text(tree, " (%s, %s:%d)",
                 val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                 tvb_ip_to_str(tvb, offset + 20), port);
      break;
    }
    case LOCATOR_KIND_TCPV4_LAN:
    case LOCATOR_KIND_TCPV4_WAN:
    case LOCATOR_KIND_TLSV4_LAN:
    case LOCATOR_KIND_TLSV4_WAN: {
      guint16 ip_kind;
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      ip_kind = tvb_get_guint16(tvb, offset+16, encoding);
      if (ip_kind == 0xFFFF) { /* IPv4 format */
        guint16 public_address_port = tvb_get_guint16(tvb, offset + 18, ENC_BIG_ENDIAN);
        proto_tree_add_item(locator_tree, hf_rtps_locator_public_address_port,
                tvb, offset+18, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(locator_tree, hf_rtps_locator_ipv4, tvb, offset+20,
                4, ENC_BIG_ENDIAN);
        proto_item_append_text(tree, " (%s, %s:%d, Logical Port = %d)",
                   val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                   tvb_ip_to_str(tvb, offset + 20), public_address_port, port);
        } else { /* IPv6 format */
          proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8,
                  16, ENC_NA);
          proto_item_append_text(tree, " (%s, %s, Logical Port = %d)",
                  val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                  tvb_ip6_to_str(tvb, offset + 8), port);
        }
      break;
    }
    case LOCATOR_KIND_SHMEM: {
      guint32 hostId;
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item_ret_uint(locator_tree, hf_rtps_param_host_id, tvb, offset+10, 4, ENC_BIG_ENDIAN, &hostId);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      proto_item_append_text(tree, " (%s, HostId = 0x%08x, Port = %d)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              hostId, port);
      break;
    }
    case LOCATOR_KIND_UDPV6: {
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8, 16, ENC_NA);
      proto_item_append_text(tree, " (%s, %s)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              tvb_ip6_to_str(tvb, offset + 8));
      break;
    }
    case LOCATOR_KIND_DTLS: {
      proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8, 16, ENC_NA);
      proto_item_append_text(tree, " (%s, %s:%d)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              tvb_ip6_to_str(tvb, offset + 8), port);
      break;
    }
    /* Default case, we already have the locator kind so don't do anything */
    default:
      break;
  }
  return offset + parameter_size;
}
gint rtps_util_add_locator_t(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset,
                             const guint encoding, const char *label) {

  proto_tree *ti;
  proto_tree *locator_tree;
  guint32 kind;
  gint32 port;
  const gint parameter_size = 24;

  locator_tree = proto_tree_add_subtree(tree, tvb, offset, parameter_size, ett_rtps_locator,
          NULL, label);

  proto_tree_add_item_ret_uint(locator_tree, hf_rtps_locator_kind, tvb, offset, 4, encoding, &kind);
  switch (kind) {
    case LOCATOR_KIND_UDPV4:
    case LOCATOR_KIND_TUDPV4: {
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv4, tvb, offset+20, 4,
              ENC_BIG_ENDIAN);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      proto_item_append_text(tree, " (%s, %s:%d)",
                 val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                 tvb_ip_to_str(tvb, offset + 20), port);
      break;
    }
    case LOCATOR_KIND_TCPV4_LAN:
    case LOCATOR_KIND_TCPV4_WAN:
    case LOCATOR_KIND_TLSV4_LAN:
    case LOCATOR_KIND_TLSV4_WAN: {
      guint16 ip_kind;
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      ip_kind = tvb_get_guint16(tvb, offset+16, encoding);
      if (ip_kind == 0xFFFF) {  
        guint16 public_address_port = tvb_get_guint16(tvb, offset + 18, ENC_BIG_ENDIAN);
        proto_tree_add_item(locator_tree, hf_rtps_locator_public_address_port,
                tvb, offset+18, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(locator_tree, hf_rtps_locator_ipv4, tvb, offset+20,
                4, ENC_BIG_ENDIAN);
        proto_item_append_text(tree, " (%s, %s:%d, Logical Port = %d)",
                   val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                   tvb_ip_to_str(tvb, offset + 20), public_address_port, port);
        } else {  
          proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8,
                  16, ENC_NA);
          proto_item_append_text(tree, " (%s, %s, Logical Port = %d)",
                  val_to_str(kind, rtps_locator_kind_vals, "%02x"),
                  tvb_ip6_to_str(tvb, offset + 8), port);
        }
      break;
    }
    case LOCATOR_KIND_SHMEM: {
      guint32 hostId;
      ti = proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item_ret_uint(locator_tree, hf_rtps_param_host_id, tvb, offset+10, 4, ENC_BIG_ENDIAN, &hostId);
      if (port == 0)
        expert_add_info(pinfo, ti, &ei_rtps_locator_port);
      proto_item_append_text(tree, " (%s, HostId = 0x%08x, Port = %d)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              hostId, port);
      break;
    }
    case LOCATOR_KIND_UDPV6: {
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8, 16, ENC_NA);
      proto_item_append_text(tree, " (%s, %s)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              tvb_ip6_to_str(tvb, offset + 8));
      break;
    }
    case LOCATOR_KIND_DTLS: {
      proto_tree_add_item_ret_int(locator_tree, hf_rtps_locator_port, tvb, offset+4, 4, encoding, &port);
      proto_tree_add_item(locator_tree, hf_rtps_locator_ipv6, tvb, offset+8, 16, ENC_NA);
      proto_item_append_text(tree, " (%s, %s:%d)",
              val_to_str(kind, rtps_locator_kind_vals, "%02x"),
              tvb_ip6_to_str(tvb, offset + 8), port);
      break;
    }
     
    default:
      break;
  }
  return offset + parameter_size;
}