/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 14170 $ of $ 
 *
 * $Id:ipv6ScopeZoneIndexTable.c 14170 2007-04-29 00:12:32Z varun_c$
 */
/** \page MFD helper for ipv6ScopeZoneIndexTable
 *
 * \section intro Introduction
 * Introductory text.
 *
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "ipv6ScopeZoneIndexTable.h"

#include <net-snmp/agent/mib_modules.h>

#include "ipv6ScopeZoneIndexTable_interface.h"

const oid       ipv6ScopeZoneIndexTable_oid[] =
    { IPV6SCOPEZONEINDEXTABLE_OID };
const int       ipv6ScopeZoneIndexTable_oid_size =
OID_LENGTH(ipv6ScopeZoneIndexTable_oid);

ipv6ScopeZoneIndexTable_registration ipv6ScopeZoneIndexTable_user_context;
static ipv6ScopeZoneIndexTable_registration *ipv6ScopeZoneIndexTable_user_context_p;

void            initialize_table_ipv6ScopeZoneIndexTable(void);
void            shutdown_table_ipv6ScopeZoneIndexTable(void);


/**
 * Initializes the ipv6ScopeZoneIndexTable module
 */
void
init_ipv6ScopeZoneIndexTable(void)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:init_ipv6ScopeZoneIndexTable", "called\n"));

    /*
     * TODO:300:o: Perform ipv6ScopeZoneIndexTable one-time module initialization.
     */

    /*
     * here we initialize all the tables we're planning on supporting
     */
    if (should_init("ipv6ScopeZoneIndexTable"))
        initialize_table_ipv6ScopeZoneIndexTable();

}                               /* init_ipv6ScopeZoneIndexTable */

/**
 * Shut-down the ipv6ScopeZoneIndexTable module (agent is exiting)
 */
void
shutdown_ipv6ScopeZoneIndexTable(void)
{
    if (should_init("ipv6ScopeZoneIndexTable"))
        shutdown_table_ipv6ScopeZoneIndexTable();

}

/**
 * Initialize the table ipv6ScopeZoneIndexTable 
 *    (Define its contents and how it's structured)
 */
void
initialize_table_ipv6ScopeZoneIndexTable(void)
{
    u_long          flags;

    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:initialize_table_ipv6ScopeZoneIndexTable", "called\n"));

    /*
     * TODO:301:o: Perform ipv6ScopeZoneIndexTable one-time table initialization.
     */

    /*
     * TODO:302:o: |->Initialize ipv6ScopeZoneIndexTable user context
     * if you'd like to pass in a pointer to some data for this
     * table, allocate or set it up here.
     */
    /*
     * a netsnmp_data_list is a simple way to store void pointers. A simple
     * string token is used to add, find or remove pointers.
     */
    ipv6ScopeZoneIndexTable_user_context_p =
        netsnmp_create_data_list("ipv6ScopeZoneIndexTable", NULL, NULL);

    /*
     * No support for any flags yet, but in the future you would
     * set any flags here.
     */
    flags = 0;

    /*
     * call interface initialization code
     */
    _ipv6ScopeZoneIndexTable_initialize_interface
	(ipv6ScopeZoneIndexTable_user_context_p, flags);
}                               /* initialize_table_ipv6ScopeZoneIndexTable */

/**
 * Shutdown the table ipv6ScopeZoneIndexTable 
 */
void
shutdown_table_ipv6ScopeZoneIndexTable(void)
{
    /*
     * call interface shutdown code
     */
    _ipv6ScopeZoneIndexTable_shutdown_interface
        (ipv6ScopeZoneIndexTable_user_context_p);
    netsnmp_free_all_list_data(ipv6ScopeZoneIndexTable_user_context_p);
    ipv6ScopeZoneIndexTable_user_context_p = NULL;
}

/**
 * extra context initialization (eg default values)
 *
 * @param rowreq_ctx    : row request context
 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
 *
 * @retval MFD_SUCCESS  : no errors
 * @retval MFD_ERROR    : error (context allocate will fail)
 */
int
ipv6ScopeZoneIndexTable_rowreq_ctx_init(ipv6ScopeZoneIndexTable_rowreq_ctx
                                        * rowreq_ctx, void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ipv6ScopeZoneIndexTable rowreq initialization. (eg DEFVALS)
     */
    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
ipv6ScopeZoneIndexTable_rowreq_ctx_cleanup
    (ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ipv6ScopeZoneIndexTable rowreq cleanup.
     */
    netsnmp_access_scopezone_entry_free(rowreq_ctx->data);
    rowreq_ctx->data = NULL;
}                               /* ipv6ScopeZoneIndexTable_rowreq_ctx_cleanup */

/**
 * pre-request callback
 *
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_ERROR                : other error
 */
int
ipv6ScopeZoneIndexTable_pre_request(ipv6ScopeZoneIndexTable_registration *
                                    user_context)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_pre_request", "called\n"));

    /*
     * TODO:510:o: Perform ipv6ScopeZoneIndexTable pre-request actions.
     */

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexTable_pre_request */

/**
 * post-request callback
 *
 * Note:
 *   New rows have been inserted into the container, and
 *   deleted rows have been removed from the container and
 *   released.
 *
 * @param user_context
 * @param rc : MFD_SUCCESS if all requests succeeded
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : other error (ignored)
 */
int
ipv6ScopeZoneIndexTable_post_request(ipv6ScopeZoneIndexTable_registration *
                                     user_context, int rc)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_post_request", "called\n"));

    /*
     * TODO:511:o: Perform ipv6ScopeZoneIndexTable post-request actions.
     */

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexTable_post_request */

/*
 * ipv6ScopeZoneIndexTable_allocate_data
 *
 * Purpose: create new ipv6ScopeZoneIndexTable_data.
 */
ipv6ScopeZoneIndexTable_data *
ipv6ScopeZoneIndexTable_allocate_data(void)
{
    /*
     * TODO:201:r: |-> allocate memory for the ipv6ScopeZoneIndexTable data context.
     */
    ipv6ScopeZoneIndexTable_data *rtn = netsnmp_access_scopezone_entry_create();

    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_allocate_data", "called\n"));

    if (NULL == rtn) {
        snmp_log(LOG_ERR, "unable to malloc memory for new "
                 "ipv6ScopeZoneIndexTable_data.\n");
    }

    return rtn;
}                               /* ipv6ScopeZoneIndexTable_allocate_data */

/*
 * ipv6ScopeZoneIndexTable_release_data
 *
 * Purpose: release ipv6ScopeZoneIndexTable data.
 */
void
ipv6ScopeZoneIndexTable_release_data(ipv6ScopeZoneIndexTable_data * data)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_release_data", "called\n"));

    /*
     * TODO:202:r: |-> release memory for the ipv6ScopeZoneIndexTable data context.
     */
    netsnmp_access_scopezone_entry_free(data);
}                               /* ipv6ScopeZoneIndexTable_release_data */

/** @defgroup data_get data_get: Routines to get data
 *
 * TODO:230:M: Implement ipv6ScopeZoneIndexTable get routines.
 * TODO:240:M: Implement ipv6ScopeZoneIndexTable mapping routines (if any).
 *
 * These routine are used to get the value for individual objects. The
 * row context is passed, along with a pointer to the memory where the
 * value should be copied.
 *
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ipv6ScopeZoneIndexTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipv6ScopeZoneIndexTable is subid 36 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.36, length: 8
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement ipv6ScopeZoneIndexTable data context functions.
 */


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param ipv6ScopeZoneIndexIfIndex_val
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
ipv6ScopeZoneIndexTable_indexes_set_tbl_idx
    (ipv6ScopeZoneIndexTable_mib_index * tbl_idx,
     long ipv6ScopeZoneIndexIfIndex_val)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_indexes_set_tbl_idx", "called\n"));

    /*
     * ipv6ScopeZoneIndexIfIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/a/w/e/R/d/H
     */
    tbl_idx->ipv6ScopeZoneIndexIfIndex = ipv6ScopeZoneIndexIfIndex_val;


    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
ipv6ScopeZoneIndexTable_indexes_set(ipv6ScopeZoneIndexTable_rowreq_ctx *
                                    rowreq_ctx,
                                    long ipv6ScopeZoneIndexIfIndex_val)
{
    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        ipv6ScopeZoneIndexTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                                    ipv6ScopeZoneIndexIfIndex_val))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != ipv6ScopeZoneIndexTable_index_to_oid(&rowreq_ctx->oid_idx,
                                                  &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexLinkLocal
 * ipv6ScopeZoneIndexLinkLocal is subid 2 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.2
 * Description:
The zone index for the link-local scope on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexLinkLocal data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexLinkLocal_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexLinkLocal_get(ipv6ScopeZoneIndexTable_rowreq_ctx *
                                rowreq_ctx,
                                u_long *
                                ipv6ScopeZoneIndexLinkLocal_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexLinkLocal_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexLinkLocal_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexLinkLocal data.
     * copy (* ipv6ScopeZoneIndexLinkLocal_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexLinkLocal_val_ptr) =
        rowreq_ctx->data->scopezone_linklocal;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexLinkLocal_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndex3
 * ipv6ScopeZoneIndex3 is subid 3 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.3
 * Description:
The zone index for scope 3 on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndex3 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndex3_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndex3_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndex3_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndex3_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndex3_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndex3 data.
     * copy (* ipv6ScopeZoneIndex3_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndex3_val_ptr) = 0;


    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndex3_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexAdminLocal
 * ipv6ScopeZoneIndexAdminLocal is subid 4 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.4
 * Description:
The zone index for the admin-local scope on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexAdminLocal data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexAdminLocal_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexAdminLocal_get(ipv6ScopeZoneIndexTable_rowreq_ctx *
                                 rowreq_ctx,
                                 u_long *
                                 ipv6ScopeZoneIndexAdminLocal_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexAdminLocal_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexAdminLocal_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexAdminLocal data.
     * copy (* ipv6ScopeZoneIndexAdminLocal_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexAdminLocal_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexAdminLocal_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexSiteLocal
 * ipv6ScopeZoneIndexSiteLocal is subid 5 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.5
 * Description:
The zone index for the site-local scope on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexSiteLocal data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexSiteLocal_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexSiteLocal_get(ipv6ScopeZoneIndexTable_rowreq_ctx *
                                rowreq_ctx,
                                u_long *
                                ipv6ScopeZoneIndexSiteLocal_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexSiteLocal_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexSiteLocal_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexSiteLocal data.
     * copy (* ipv6ScopeZoneIndexSiteLocal_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexSiteLocal_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexSiteLocal_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndex6
 * ipv6ScopeZoneIndex6 is subid 6 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.6
 * Description:
The zone index for scope 6 on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndex6 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndex6_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndex6_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndex6_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndex6_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndex6_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndex6 data.
     * copy (* ipv6ScopeZoneIndex6_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndex6_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndex6_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndex7
 * ipv6ScopeZoneIndex7 is subid 7 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.7
 * Description:
The zone index for scope 7 on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndex7 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndex7_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndex7_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndex7_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndex7_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndex7_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndex7 data.
     * copy (* ipv6ScopeZoneIndex7_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndex7_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndex7_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexOrganizationLocal
 * ipv6ScopeZoneIndexOrganizationLocal is subid 8 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.8
 * Description:
The zone index for the organization-local scope on this
            interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexOrganizationLocal data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexOrganizationLocal_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexOrganizationLocal_get(ipv6ScopeZoneIndexTable_rowreq_ctx
                                        * rowreq_ctx,
                                        u_long *
                                        ipv6ScopeZoneIndexOrganizationLocal_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexOrganizationLocal_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexOrganizationLocal_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexOrganizationLocal data.
     * copy (* ipv6ScopeZoneIndexOrganizationLocal_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexOrganizationLocal_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexOrganizationLocal_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndex9
 * ipv6ScopeZoneIndex9 is subid 9 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.9
 * Description:
The zone index for scope 9 on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndex9 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndex9_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndex9_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndex9_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndex9_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndex9_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndex9 data.
     * copy (* ipv6ScopeZoneIndex9_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndex9_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndex9_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexA
 * ipv6ScopeZoneIndexA is subid 10 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.10
 * Description:
The zone index for scope A on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexA data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexA_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexA_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndexA_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexA_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexA_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexA data.
     * copy (* ipv6ScopeZoneIndexA_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexA_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexA_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexB
 * ipv6ScopeZoneIndexB is subid 11 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.11
 * Description:
The zone index for scope B on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexB data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexB_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexB_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndexB_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexB_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexB_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexB data.
     * copy (* ipv6ScopeZoneIndexB_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexB_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexB_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexC
 * ipv6ScopeZoneIndexC is subid 12 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.12
 * Description:
The zone index for scope C on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexC data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexC_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexC_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndexC_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexC_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexC_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexC data.
     * copy (* ipv6ScopeZoneIndexC_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexC_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexC_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipv6ScopeZoneIndexEntry.ipv6ScopeZoneIndexD
 * ipv6ScopeZoneIndexD is subid 13 of ipv6ScopeZoneIndexEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.36.1.13
 * Description:
The zone index for scope D on this interface.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   0
 *   hint: d
 *
 *
 * Its syntax is InetZoneIndex (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the ipv6ScopeZoneIndexD data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipv6ScopeZoneIndexD_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipv6ScopeZoneIndexD_get(ipv6ScopeZoneIndexTable_rowreq_ctx * rowreq_ctx,
                        u_long * ipv6ScopeZoneIndexD_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipv6ScopeZoneIndexD_val_ptr);


    DEBUGMSGTL(("verbose:ipv6ScopeZoneIndexTable:ipv6ScopeZoneIndexD_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipv6ScopeZoneIndexD data.
     * copy (* ipv6ScopeZoneIndexD_val_ptr ) from rowreq_ctx->data
     */
    (*ipv6ScopeZoneIndexD_val_ptr) = 0;

    return MFD_SUCCESS;
}                               /* ipv6ScopeZoneIndexD_get */


/** @{ */
