2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <stdarg.h>
2N/A#include <stdlib.h>
2N/A#include <errno.h>
2N/A#include <string.h>
2N/A
2N/A#include "fru_access_impl.h"
2N/A
2N/A#include "libfruds.h"
2N/A#include "libfrup.h"
2N/A#include "fru_access.h"
2N/A#include "fruraw.h"
2N/A
2N/A
2N/Araw_list_t *g_raw = NULL;
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic raw_list_t *
2N/Atreehdl_to_rawlist(fru_treehdl_t handle)
2N/A{
2N/A return (g_raw);
2N/A}
2N/A
2N/A
2N/Astatic container_hdl_t
2N/Atreehdl_to_conthdl(fru_treehdl_t handle)
2N/A{
2N/A raw_list_t *ptr;
2N/A
2N/A ptr = treehdl_to_rawlist(handle);
2N/A if (ptr == NULL) {
2N/A return (-1);
2N/A }
2N/A
2N/A return (ptr->cont);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Amap_errno(int err)
2N/A{
2N/A switch (err) {
2N/A case ENFILE:
2N/A case EEXIST:
2N/A return (FRU_DUPSEG);
2N/A case EAGAIN:
2N/A return (FRU_NOSPACE);
2N/A case EPERM:
2N/A return (FRU_INVALPERM);
2N/A default :
2N/A return (FRU_IOERROR);
2N/A }
2N/A}
2N/A
2N/A
2N/Astatic raw_list_t *
2N/Amake_raw(uint8_t *buffer, size_t size, char *cont_type)
2N/A{
2N/A raw_list_t *node;
2N/A
2N/A node = (raw_list_t *)malloc(sizeof (raw_list_t));
2N/A if (node == NULL) {
2N/A return (NULL);
2N/A }
2N/A
2N/A node->hdl = 0;
2N/A node->raw = buffer;
2N/A node->size = size;
2N/A node->cont_type = strdup(cont_type);
2N/A if (node->cont_type == NULL) {
2N/A free(node);
2N/A return (NULL);
2N/A }
2N/A node->segs = NULL;
2N/A
2N/A return (node);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Arguments :
2N/A * 0 - pointer to byte buffer (in)
2N/A * 1 - size of buffer (in)
2N/A * 2 - container type, string (in)
2N/A */
2N/Astatic fru_errno_t
2N/Afrt_initialize(int num, char **args)
2N/A{
2N/A
2N/A
2N/A if (num != 3) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A g_raw = make_raw((uint8_t *)args[0], (size_t)args[1], args[2]);
2N/A if (g_raw == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A g_raw->cont = open_raw_data(g_raw);
2N/A if (g_raw->cont == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_shutdown(void)
2N/A{
2N/A segment_list_t *lptr, *lptr2;
2N/A
2N/A (void) fru_close_container(g_raw->cont);
2N/A free(g_raw->cont_type);
2N/A lptr = g_raw->segs;
2N/A while (lptr) {
2N/A lptr2 = lptr;
2N/A lptr = lptr->next;
2N/A free(lptr2);
2N/A }
2N/A g_raw = NULL;
2N/A
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_get_root(fru_treehdl_t *node)
2N/A{
2N/A *node = g_raw->hdl;
2N/A
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_peer(fru_treehdl_t sibling, fru_treehdl_t *peer)
2N/A{
2N/A return (FRU_NODENOTFOUND);
2N/A}
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_child(fru_treehdl_t handle, fru_treehdl_t *child)
2N/A{
2N/A return (FRU_NODENOTFOUND);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_parent(fru_treehdl_t handle, fru_treehdl_t *parent)
2N/A{
2N/A return (FRU_NODENOTFOUND);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_name_from_hdl(fru_treehdl_t handle, char **name)
2N/A{
2N/A *name = strdup("unknown");
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_node_type(fru_treehdl_t node, fru_node_t *type)
2N/A{
2N/A *type = FRU_NODE_CONTAINER;
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Aadd_segs_for_section(section_t *section, fru_strlist_t *list)
2N/A{
2N/A int i = 0;
2N/A segment_t *segs = NULL;
2N/A int acc_err = 0;
2N/A
2N/A int num_segment = fru_get_num_segments(section->handle, NULL);
2N/A if (num_segment == -1) {
2N/A return (map_errno(errno));
2N/A } else if (num_segment == 0) {
2N/A return (FRU_SUCCESS);
2N/A }
2N/A
2N/A segs = malloc(sizeof (*segs) * (num_segment));
2N/A if (segs == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A acc_err = fru_get_segments(section->handle, segs, num_segment, NULL);
2N/A if (acc_err == -1) {
2N/A free(segs);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A list->strs = realloc(list->strs, sizeof (char *)
2N/A * (list->num + num_segment));
2N/A
2N/A for (i = 0; i < num_segment; i++) {
2N/A /* ensure NULL terminated. */
2N/A char *tmp = malloc(sizeof (*tmp) * (sizeof (segs[i].name)+1));
2N/A if (tmp == NULL) {
2N/A free(segs);
2N/A return (FRU_FAILURE);
2N/A }
2N/A (void) memcpy(tmp, segs[i].name, sizeof (segs[i].name));
2N/A tmp[sizeof (segs[i].name)] = '\0';
2N/A
2N/A list->strs[(list->num)++] = tmp;
2N/A }
2N/A
2N/A free(segs);
2N/A
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_get_seg_list(fru_treehdl_t handle, fru_strlist_t *list)
2N/A{
2N/A fru_strlist_t rc_list;
2N/A fru_errno_t err = FRU_SUCCESS;
2N/A int acc_err = 0;
2N/A int i = 0;
2N/A int num_section = 0;
2N/A section_t *sects = NULL;
2N/A container_hdl_t cont;
2N/A
2N/A cont = treehdl_to_conthdl(handle);
2N/A
2N/A num_section = fru_get_num_sections(cont, NULL);
2N/A if (num_section == -1) {
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A sects = malloc(sizeof (*sects) * (num_section));
2N/A if (sects == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A acc_err = fru_get_sections(cont, sects, num_section, NULL);
2N/A if (acc_err == -1) {
2N/A free(sects);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A rc_list.num = 0;
2N/A rc_list.strs = NULL;
2N/A for (i = 0; i < num_section; i++) {
2N/A if ((err = add_segs_for_section(&(sects[i]), &rc_list))
2N/A != FRU_SUCCESS) {
2N/A fru_destroy_strlist(&rc_list);
2N/A free(sects);
2N/A return (err);
2N/A }
2N/A }
2N/A
2N/A list->strs = rc_list.strs;
2N/A list->num = rc_list.num;
2N/A
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afind_seg_in_sect(section_t *sect, const char *seg_name, int *prot_flg,
2N/A segment_t *segment)
2N/A{
2N/A int j = 0;
2N/A int acc_err = 0;
2N/A segment_t *segs = NULL;
2N/A
2N/A int num_seg = fru_get_num_segments(sect->handle, NULL);
2N/A if (num_seg == -1) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A segs = malloc(sizeof (*segs) * (num_seg));
2N/A if (segs == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A acc_err = fru_get_segments(sect->handle, segs, num_seg, NULL);
2N/A if (acc_err == -1) {
2N/A free(segs);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A for (j = 0; j < num_seg; j++) {
2N/A /* NULL terminate */
2N/A char tmp[SEG_NAME_LEN+1];
2N/A (void) memcpy(tmp, segs[j].name, SEG_NAME_LEN);
2N/A tmp[SEG_NAME_LEN] = '\0';
2N/A if (strcmp(tmp, seg_name) == 0) {
2N/A *segment = segs[j];
2N/A *prot_flg = (sect->protection ? 1 : 0);
2N/A free(segs);
2N/A return (FRU_SUCCESS);
2N/A }
2N/A }
2N/A
2N/A free(segs);
2N/A return (FRU_INVALSEG);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afind_segment(fru_treehdl_t handle, const char *seg_name, int *prot_flg,
2N/A segment_t *segment)
2N/A{
2N/A int i = 0;
2N/A int acc_err = 0;
2N/A section_t *sect = NULL;
2N/A container_hdl_t cont;
2N/A int num_sect;
2N/A
2N/A cont = treehdl_to_conthdl(handle);
2N/A
2N/A num_sect = fru_get_num_sections(cont, NULL);
2N/A if (num_sect == -1) {
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A sect = malloc(sizeof (*sect) * (num_sect));
2N/A if (sect == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A acc_err = fru_get_sections(cont, sect, num_sect, NULL);
2N/A if (acc_err == -1) {
2N/A free(sect);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A for (i = 0; i < num_sect; i++) {
2N/A if (find_seg_in_sect(&(sect[i]), seg_name, prot_flg, segment)
2N/A == FRU_SUCCESS) {
2N/A free(sect);
2N/A return (FRU_SUCCESS);
2N/A }
2N/A }
2N/A
2N/A free(sect);
2N/A return (FRU_INVALSEG);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_get_seg_def(fru_treehdl_t handle, const char *seg_name, fru_segdef_t *def)
2N/A{
2N/A fru_errno_t err = FRU_SUCCESS;
2N/A int prot_flg = 0;
2N/A segment_t segment;
2N/A
2N/A if ((err = find_segment(handle, seg_name, &prot_flg, &segment))
2N/A != FRU_SUCCESS) {
2N/A return (err);
2N/A }
2N/A
2N/A (void) memcpy(def->name, segment.name, SEG_NAME_LEN);
2N/A def->name[SEG_NAME_LEN] = '\0';
2N/A def->desc.raw_data = segment.descriptor;
2N/A def->size = segment.length;
2N/A def->address = segment.offset;
2N/A
2N/A if (prot_flg == 0)
2N/A def->hw_desc.field.read_only = 0;
2N/A else
2N/A def->hw_desc.field.read_only = 1;
2N/A
2N/A return (FRU_SUCCESS);
2N/A
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_add_seg(fru_treehdl_t handle, fru_segdef_t *def)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_delete_seg(fru_treehdl_t handle, const char *seg_name)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_for_each_segment(fru_nodehdl_t node,
2N/A int (*function)(fru_seghdl_t hdl, void *args), void *args)
2N/A{
2N/A int num_segment;
2N/A int cnt;
2N/A int num_sect;
2N/A int each_seg;
2N/A section_t *sects;
2N/A segment_t *segs;
2N/A segment_list_t *tmp_list;
2N/A int acc_err;
2N/A int status;
2N/A container_hdl_t cont;
2N/A
2N/A cont = g_raw->cont;
2N/A
2N/A num_sect = fru_get_num_sections(cont, NULL);
2N/A if (num_sect == -1) {
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A sects = malloc((num_sect + 1) * sizeof (section_t));
2N/A if (sects == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A num_sect = fru_get_sections(cont, sects, num_sect, NULL);
2N/A if (num_sect == -1) {
2N/A free(sects);
2N/A return (map_errno(errno));
2N/A }
2N/A for (cnt = 0; cnt < num_sect; cnt++) {
2N/A num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
2N/A if (num_segment == -1) {
2N/A return (map_errno(errno));
2N/A } else if (num_segment == 0) {
2N/A continue;
2N/A }
2N/A segs = malloc((num_segment + 1) * sizeof (segment_t));
2N/A if (segs == NULL) {
2N/A free(sects);
2N/A return (FRU_FAILURE);
2N/A }
2N/A acc_err = fru_get_segments(sects[cnt].handle, segs,
2N/A num_segment, NULL);
2N/A if (acc_err == -1) {
2N/A free(sects);
2N/A free(segs);
2N/A return (map_errno(errno));
2N/A }
2N/A for (each_seg = 0; each_seg < num_segment; each_seg++) {
2N/A tmp_list = malloc(sizeof (segment_list_t));
2N/A tmp_list->segment = &segs[each_seg];
2N/A tmp_list->next = NULL;
2N/A if (g_raw->segs == NULL) {
2N/A g_raw->segs = tmp_list;
2N/A } else {
2N/A tmp_list->next = g_raw->segs;
2N/A g_raw->segs = tmp_list;
2N/A }
2N/A
2N/A if ((status = function(segs[each_seg].handle, args))
2N/A != FRU_SUCCESS) {
2N/A free(segs);
2N/A free(sects);
2N/A return (status);
2N/A }
2N/A }
2N/A free(segs);
2N/A free(sects);
2N/A
2N/A }
2N/A return (FRU_SUCCESS);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_get_segment_name(fru_seghdl_t node, char **name)
2N/A{
2N/A int num_sect;
2N/A int acc_err;
2N/A int cnt;
2N/A int num_segment;
2N/A section_t *sects;
2N/A segment_t *segs;
2N/A int each_seg;
2N/A container_hdl_t cont;
2N/A
2N/A cont = treehdl_to_conthdl(node);
2N/A
2N/A num_sect = fru_get_num_sections(cont, NULL);
2N/A if (num_sect == -1) {
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A sects = malloc(sizeof (*sects) * (num_sect));
2N/A if (sects == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A acc_err = fru_get_sections(cont, sects, num_sect, NULL);
2N/A if (acc_err == -1) {
2N/A free(sects);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A for (cnt = 0; cnt < num_sect; cnt++) {
2N/A num_segment = fru_get_num_segments(sects[cnt].handle, NULL);
2N/A if (num_segment == -1) {
2N/A free(sects);
2N/A return (map_errno(errno));
2N/A } else if (num_segment == 0) {
2N/A continue;
2N/A }
2N/A
2N/A segs = malloc(sizeof (*segs) * (num_segment));
2N/A if (segs == NULL) {
2N/A free(sects);
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A acc_err = fru_get_segments(sects[cnt].handle, segs,
2N/A num_segment, NULL);
2N/A if (acc_err == -1) {
2N/A free(sects);
2N/A free(segs);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A for (each_seg = 0; each_seg < num_segment; each_seg++) {
2N/A if (segs[each_seg].handle == node) {
2N/A segs[each_seg].name[FRU_SEGNAMELEN] = '\0';
2N/A *name = strdup(segs[each_seg].name);
2N/A free(sects);
2N/A free(segs);
2N/A return (FRU_SUCCESS);
2N/A }
2N/A }
2N/A free(segs);
2N/A }
2N/A
2N/A return (FRU_FAILURE);
2N/A}
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_add_tag_to_seg(fru_treehdl_t handle, const char *seg_name,
2N/A fru_tag_t tag, uint8_t *data, size_t data_len)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_tag_list(fru_treehdl_t handle, const char *seg_name,
2N/A fru_tag_t **tags, int *number)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_get_tag_data(fru_treehdl_t handle, const char *seg_name,
2N/A fru_tag_t tag, int instance,
2N/A uint8_t **data, size_t *data_len)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_set_tag_data(fru_treehdl_t handle, const char *seg_name,
2N/A fru_tag_t tag, int instance,
2N/A uint8_t *data, size_t data_len)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A
2N/A/* ARGSUSED */
2N/Astatic fru_errno_t
2N/Afrt_delete_tag(fru_treehdl_t handle, const char *seg_name, fru_tag_t tag,
2N/A int instance)
2N/A{
2N/A /* NOT SUPPORTED */
2N/A return (FRU_NOTSUP);
2N/A}
2N/A
2N/A
2N/Astatic fru_errno_t
2N/Afrt_for_each_packet(fru_seghdl_t node,
2N/A int (*function)(fru_tag_t *tag, uint8_t *payload, size_t length,
2N/A void *args), void *args)
2N/A{
2N/A int rc_num;
2N/A int status;
2N/A char *rc_tags;
2N/A char *rc_data;
2N/A int i;
2N/A packet_t *packets = NULL;
2N/A segment_list_t *tmp_list;
2N/A fru_segdesc_t *descriptor;
2N/A
2N/A tmp_list = g_raw->segs;
2N/A
2N/A /* num of packet */
2N/A rc_num = fru_get_num_packets(node, NULL);
2N/A if (rc_num == -1) {
2N/A return (map_errno(errno));
2N/A } else if (rc_num == 0) {
2N/A return (FRU_SUCCESS);
2N/A }
2N/A while (tmp_list) {
2N/A if (node == tmp_list->segment->handle) {
2N/A break;
2N/A }
2N/A tmp_list = tmp_list->next;
2N/A }
2N/A if (tmp_list) {
2N/A descriptor = (fru_segdesc_t *)&tmp_list->segment->descriptor;
2N/A if (descriptor->field.opaque) {
2N/A return (FRU_SUCCESS);
2N/A }
2N/A
2N/A if (descriptor->field.encrypted && (encrypt_func == NULL)) {
2N/A return (FRU_SUCCESS);
2N/A }
2N/A }
2N/A
2N/A packets = malloc(sizeof (*packets) * (rc_num));
2N/A if (packets == NULL) {
2N/A return (FRU_FAILURE);
2N/A }
2N/A /* get all packets */
2N/A if (fru_get_packets(node, packets, rc_num, NULL) == -1) {
2N/A free(packets);
2N/A return (map_errno(errno));
2N/A }
2N/A
2N/A rc_tags = malloc(sizeof (*rc_tags) * (rc_num));
2N/A if (rc_tags == NULL) {
2N/A free(packets);
2N/A return (FRU_FAILURE);
2N/A }
2N/A
2N/A /* number of tags */
2N/A for (i = 0; i < rc_num; i++) {
2N/A size_t rc_len =
2N/A get_payload_length((fru_tag_t *)&packets[i].tag);
2N/A
2N/A rc_data = malloc(sizeof (*rc_data) * (rc_len));
2N/A if (rc_data == NULL) {
2N/A free(packets);
2N/A return (FRU_FAILURE);
2N/A }
2N/A /* get the payload data */
2N/A (void) fru_get_payload(packets[i].handle, (void *)rc_data,
2N/A rc_len, NULL);
2N/A
2N/A if (tmp_list) {
2N/A descriptor =
2N/A (fru_segdesc_t *)&tmp_list->segment->descriptor;
2N/A
2N/A if ((descriptor->field.encrypted) &&
2N/A ((status = encrypt_func(FRU_DECRYPT,
2N/A (void *)rc_data, rc_len))
2N/A != FRU_SUCCESS)) {
2N/A return (status);
2N/A }
2N/A }
2N/A /* print packet */
2N/A if ((status = function((fru_tag_t *)&packets[i].tag,
2N/A (uint8_t *)rc_data, rc_len, args)) != FRU_SUCCESS) {
2N/A free(rc_data);
2N/A free(packets);
2N/A return (status);
2N/A }
2N/A free(rc_data);
2N/A }
2N/A return (FRU_SUCCESS);
2N/A
2N/A}
2N/A
2N/A
2N/A/* object for libfru to link to */
2N/Afru_datasource_t data_source =
2N/A{
2N/A LIBFRU_DS_VER,
2N/A frt_initialize,
2N/A frt_shutdown,
2N/A frt_get_root,
2N/A frt_get_child,
2N/A frt_get_peer,
2N/A frt_get_parent,
2N/A frt_get_name_from_hdl,
2N/A frt_get_node_type,
2N/A frt_get_seg_list,
2N/A frt_get_seg_def,
2N/A frt_add_seg,
2N/A frt_delete_seg,
2N/A frt_for_each_segment,
2N/A frt_get_segment_name,
2N/A frt_add_tag_to_seg,
2N/A frt_get_tag_list,
2N/A frt_get_tag_data,
2N/A frt_set_tag_data,
2N/A frt_delete_tag,
2N/A frt_for_each_packet
2N/A};