/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for ipAddressPrefixTable
 *
 * \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 "ipAddressPrefixTable.h"

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

#include "ipAddressPrefixTable_interface.h"

const oid       ipAddressPrefixTable_oid[] = { IPADDRESSPREFIXTABLE_OID };
const int       ipAddressPrefixTable_oid_size =
OID_LENGTH(ipAddressPrefixTable_oid);

ipAddressPrefixTable_registration ipAddressPrefixTable_user_context;
static ipAddressPrefixTable_registration *ipAddressPrefixTable_user_context_p;

void            initialize_table_ipAddressPrefixTable(void);
void            shutdown_table_ipAddressPrefixTable(void);


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

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

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

}                               /* init_ipAddressPrefixTable */

/**
 * Shut-down the ipAddressPrefixTable module (agent is exiting)
 */
void
shutdown_ipAddressPrefixTable(void)
{
    if (should_init("ipAddressPrefixTable"))
        shutdown_table_ipAddressPrefixTable();

}

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

    DEBUGMSGTL(("verbose:ipAddressPrefixTable:initialize_table_ipAddressPrefixTable", "called\n"));

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

    /*
     * TODO:302:o: |->Initialize ipAddressPrefixTable 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.
     */
    ipAddressPrefixTable_user_context_p
	= netsnmp_create_data_list("ipAddressPrefixTable", NULL, NULL);

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

    /*
     * call interface initialization code
     */
    _ipAddressPrefixTable_initialize_interface
	(ipAddressPrefixTable_user_context_p, flags);
}                               /* initialize_table_ipAddressPrefixTable */

/**
 * Shutdown the table ipAddressPrefixTable 
 */
void
shutdown_table_ipAddressPrefixTable(void)
{
    /*
     * call interface shutdown code
     */
    _ipAddressPrefixTable_shutdown_interface
        (ipAddressPrefixTable_user_context_p);
    netsnmp_free_all_list_data(ipAddressPrefixTable_user_context_p);
    ipAddressPrefixTable_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
ipAddressPrefixTable_rowreq_ctx_init(ipAddressPrefixTable_rowreq_ctx *
                                     rowreq_ctx, void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ipAddressPrefixTable rowreq initialization. (eg DEFVALS)
     */

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
ipAddressPrefixTable_rowreq_ctx_cleanup(ipAddressPrefixTable_rowreq_ctx *
                                        rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ipAddressPrefixTable rowreq cleanup.
     */
}                               /* ipAddressPrefixTable_rowreq_ctx_cleanup */

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

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

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_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
ipAddressPrefixTable_post_request(ipAddressPrefixTable_registration *
                                  user_context, int rc)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_post_request", "called\n"));

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

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table ipAddressPrefixTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipAddressPrefixTable is subid 32 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.32, length: 8
 */

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


/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param ipAddressPrefixIfIndex_val
 * @param ipAddressPrefixType_val
 * @param ipAddressPrefixPrefix_val_ptr
 * @param ipAddressPrefixPrefix_val_ptr_len
 * @param ipAddressPrefixLength_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
ipAddressPrefixTable_indexes_set_tbl_idx(ipAddressPrefixTable_mib_index *
                                         tbl_idx,
                                         long ipAddressPrefixIfIndex_val,
                                         u_long ipAddressPrefixType_val,
                                         char
                                         *ipAddressPrefixPrefix_val_ptr,
                                         size_t
                                         ipAddressPrefixPrefix_val_ptr_len,
                                         u_long ipAddressPrefixLength_val)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_indexes_set_tbl_idx", "called\n"));

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

    /*
     * ipAddressPrefixType(2)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    tbl_idx->ipAddressPrefixType = ipAddressPrefixType_val;

    /*
     * ipAddressPrefixPrefix(3)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    tbl_idx->ipAddressPrefixPrefix_len = sizeof(tbl_idx->ipAddressPrefixPrefix) / sizeof(tbl_idx->ipAddressPrefixPrefix[0]);    /* max length */
    /*
     * make sure there is enough space for ipAddressPrefixPrefix data
     */
    if ((NULL == tbl_idx->ipAddressPrefixPrefix) ||
        (tbl_idx->ipAddressPrefixPrefix_len <
         (ipAddressPrefixPrefix_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->ipAddressPrefixPrefix_len = ipAddressPrefixPrefix_val_ptr_len;
    memcpy(tbl_idx->ipAddressPrefixPrefix, ipAddressPrefixPrefix_val_ptr,
           ipAddressPrefixPrefix_val_ptr_len *
           sizeof(ipAddressPrefixPrefix_val_ptr[0]));

    /*
     * ipAddressPrefixLength(4)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    tbl_idx->ipAddressPrefixLength = ipAddressPrefixLength_val;


    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_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
ipAddressPrefixTable_indexes_set(ipAddressPrefixTable_rowreq_ctx *
                                 rowreq_ctx,
                                 long ipAddressPrefixIfIndex_val,
                                 u_long ipAddressPrefixType_val,
                                 char *ipAddressPrefixPrefix_val_ptr,
                                 size_t ipAddressPrefixPrefix_val_ptr_len,
                                 u_long ipAddressPrefixLength_val)
{
    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        ipAddressPrefixTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                                 ipAddressPrefixIfIndex_val,
                                                 ipAddressPrefixType_val,
                                                 ipAddressPrefixPrefix_val_ptr,
                                                 ipAddressPrefixPrefix_val_ptr_len,
                                                 ipAddressPrefixLength_val))
        return MFD_ERROR;

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

    return MFD_SUCCESS;
}                               /* ipAddressPrefixTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-MIB::ipAddressPrefixEntry.ipAddressPrefixOrigin
 * ipAddressPrefixOrigin is subid 5 of ipAddressPrefixEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.32.1.5
 * Description:
The origin of this prefix.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 4/8. Values:  other(1), manual(2), wellknown(3), dhcp(4), routeradv(5)
 *
 * Its syntax is IpAddressPrefixOriginTC (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressPrefixOrigin data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefixOrigin_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressPrefixOrigin_get(ipAddressPrefixTable_rowreq_ctx * rowreq_ctx,
                          u_long * ipAddressPrefixOrigin_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressPrefixOrigin_val_ptr);


    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixOrigin_get",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefixOrigin data.
     * copy (* ipAddressPrefixOrigin_val_ptr ) from rowreq_ctx->data
     */
          (*ipAddressPrefixOrigin_val_ptr) = rowreq_ctx->data.ipAddressPrefixOrigin;
    
           return MFD_SUCCESS;
}                               /* ipAddressPrefixOrigin_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressPrefixEntry.ipAddressPrefixOnLinkFlag
 * ipAddressPrefixOnLinkFlag is subid 6 of ipAddressPrefixEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.32.1.6
 * Description:
This object has the value 'true(1)', if this prefix can be
            used  for on-link determination and the value 'false(2)'
            otherwise.


            The default for IPv4 prefixes is 'true(1)'.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressPrefixOnLinkFlag data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefixOnLinkFlag_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressPrefixOnLinkFlag_get(ipAddressPrefixTable_rowreq_ctx * rowreq_ctx,
                              u_long * ipAddressPrefixOnLinkFlag_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressPrefixOnLinkFlag_val_ptr);


    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixOnLinkFlag_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefixOnLinkFlag data.
     * copy (* ipAddressPrefixOnLinkFlag_val_ptr ) from rowreq_ctx->data
     */
    if (INETADDRESSTYPE_IPV4 == rowreq_ctx->tbl_idx.ipAddressPrefixType) {
        (*ipAddressPrefixOnLinkFlag_val_ptr) = 1;       /* per MIB */
    } else
        (*ipAddressPrefixOnLinkFlag_val_ptr) =
            rowreq_ctx->data.ipAddressPrefixOnLinkFlag;

    return MFD_SUCCESS;
}                               /* ipAddressPrefixOnLinkFlag_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressPrefixEntry.ipAddressPrefixAutonomousFlag
 * ipAddressPrefixAutonomousFlag is subid 7 of ipAddressPrefixEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.32.1.7
 * Description:
Autonomous address configuration flag. When true(1),
            indicates that this prefix can be used for autonomous
            address configuration (i.e. can be used to form a local
            interface address).  If false(2), it is not used to auto-
            configure a local interface address.


            The default for IPv4 prefixes is 'false(2)'.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 2/8. Values:  true(1), false(2)
 *
 * Its syntax is TruthValue (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the ipAddressPrefixAutonomousFlag data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefixAutonomousFlag_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
ipAddressPrefixAutonomousFlag_get(ipAddressPrefixTable_rowreq_ctx *
                                  rowreq_ctx,
                                  u_long *
                                  ipAddressPrefixAutonomousFlag_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressPrefixAutonomousFlag_val_ptr);


    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixAutonomousFlag_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefixAutonomousFlag data.
     * copy (* ipAddressPrefixAutonomousFlag_val_ptr ) from rowreq_ctx->data
     */
    if (INETADDRESSTYPE_IPV4 == rowreq_ctx->tbl_idx.ipAddressPrefixType)
        (*ipAddressPrefixAutonomousFlag_val_ptr) = 2;   /* per MIB */
    else
        (*ipAddressPrefixAutonomousFlag_val_ptr) =
            rowreq_ctx->data.ipAddressPrefixAutonomousFlag;

    return MFD_SUCCESS;
}                               /* ipAddressPrefixAutonomousFlag_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressPrefixEntry.ipAddressPrefixAdvPreferredLifetime
 * ipAddressPrefixAdvPreferredLifetime is subid 8 of ipAddressPrefixEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.32.1.8
 * Description:
The remaining length of time in seconds that this prefix
            will continue to be preferred, i.e. time until deprecation.




            A value of 4,294,967,295 represents infinity.


            The address generated from a deprecated prefix should no
            longer be used as a source address in new communications,
            but packets received on such an interface are processed as
            expected.


            The default for IPv4 prefixes is 4,294,967,295 (infinity).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is UNSIGNED32 (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 ipAddressPrefixAdvPreferredLifetime data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefixAdvPreferredLifetime_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
ipAddressPrefixAdvPreferredLifetime_get(ipAddressPrefixTable_rowreq_ctx *
                                        rowreq_ctx,
                                        u_long *
                                        ipAddressPrefixAdvPreferredLifetime_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressPrefixAdvPreferredLifetime_val_ptr);


    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixAdvPreferredLifetime_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefixAdvPreferredLifetime data.
     * copy (* ipAddressPrefixAdvPreferredLifetime_val_ptr ) from rowreq_ctx->data
     */
    if (INETADDRESSTYPE_IPV4 == rowreq_ctx->tbl_idx.ipAddressPrefixType)
        (*ipAddressPrefixAdvPreferredLifetime_val_ptr) = 4294967295;    /* per MIB */
    else
        (*ipAddressPrefixAdvPreferredLifetime_val_ptr) =
            rowreq_ctx->data.ipAddressPrefixAdvPreferredLifetime;

    return MFD_SUCCESS;
}                               /* ipAddressPrefixAdvPreferredLifetime_get */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressPrefixEntry.ipAddressPrefixAdvValidLifetime
 * ipAddressPrefixAdvValidLifetime is subid 9 of ipAddressPrefixEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.32.1.9
 * Description:
The remaining length of time, in seconds, that this prefix
            will continue to be valid, i.e. time until invalidation.  A
            value of 4,294,967,295 represents infinity.


            The address generated from an invalidated prefix should not
            appear as the destination or source address of a packet.


            The default for IPv4 prefixes is 4,294,967,295 (infinity).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is UNSIGNED32 (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 ipAddressPrefixAdvValidLifetime data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipAddressPrefixAdvValidLifetime_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
ipAddressPrefixAdvValidLifetime_get(ipAddressPrefixTable_rowreq_ctx *
                                    rowreq_ctx,
                                    u_long *
                                    ipAddressPrefixAdvValidLifetime_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipAddressPrefixAdvValidLifetime_val_ptr);


    DEBUGMSGTL(("verbose:ipAddressPrefixTable:ipAddressPrefixAdvValidLifetime_get", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipAddressPrefixAdvValidLifetime data.
     * copy (* ipAddressPrefixAdvValidLifetime_val_ptr ) from rowreq_ctx->data
     */
    if (INETADDRESSTYPE_IPV4 == rowreq_ctx->tbl_idx.ipAddressPrefixType)
        (*ipAddressPrefixAdvValidLifetime_val_ptr) = 4294967295;        /* per MIB */
    else
        (*ipAddressPrefixAdvValidLifetime_val_ptr) =
            rowreq_ctx->data.ipAddressPrefixAdvValidLifetime;

    return MFD_SUCCESS;
}                               /* ipAddressPrefixAdvValidLifetime_get */



/** @} */
/** @} */
/** @{ */
