ipAddressTable.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:80k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * Note: this file originally auto-generated by mib2c using
  3.  *       version : 1.32 $ of : mfd-top.m2c,v $ 
  4.  *
  5.  * $Id: ipAddressTable.c,v 1.12.2.1 2005/03/29 21:05:25 nba Exp $
  6.  */
  7. /** mainpage MFD helper for ipAddressTable
  8.  *
  9.  * section intro Introduction
  10.  * Introductory text.
  11.  *
  12.  */
  13. /*
  14.  * standard Net-SNMP includes 
  15.  */
  16. #include <net-snmp/net-snmp-config.h>
  17. #include <net-snmp/net-snmp-includes.h>
  18. #include <net-snmp/agent/net-snmp-agent-includes.h>
  19. #include <net-snmp/data_access/interface.h>
  20. /*
  21.  * include our parent header 
  22.  */
  23. #include "ipAddressTable.h"
  24. #include <net-snmp/agent/mib_modules.h>
  25. #include "ipAddressTable_interface.h"
  26. oid             ipAddressTable_oid[] = { IPADDRESSTABLE_OID };
  27. int             ipAddressTable_oid_size = OID_LENGTH(ipAddressTable_oid);
  28. void            initialize_table_ipAddressTable(void);
  29. /**
  30.  * Initializes the ipAddressTable module
  31.  */
  32. void
  33. init_ipAddressTable(void)
  34. {
  35.     DEBUGMSGTL(("verbose:ipAddressTable:init_ipAddressTable", "calledn"));
  36.     /*
  37.      * TODO:300:o: Perform ipAddressTable one-time module initialization.
  38.      */
  39.     /*
  40.      * here we initialize all the tables we're planning on supporting
  41.      */
  42.     if (should_init("ipAddressTable"))
  43.         initialize_table_ipAddressTable();
  44. }                               /* init_ipAddressTable */
  45. /**
  46.  * Initialize the table ipAddressTable 
  47.  *    (Define its contents and how it's structured)
  48.  */
  49. void
  50. initialize_table_ipAddressTable(void)
  51. {
  52.     ipAddressTable_registration_ptr user_context;
  53.     u_long          flags;
  54.     DEBUGMSGTL(("verbose:ipAddressTable:initialize_table_ipAddressTable",
  55.                 "calledn"));
  56.     /*
  57.      * TODO:301:o: Perform ipAddressTable one-time table initialization.
  58.      */
  59.     /*
  60.      * TODO:302:o: |->Initialize ipAddressTable user context
  61.      * if you'd like to pass in a pointer to some data for this
  62.      * table, allocate or set it up here.
  63.      */
  64.     user_context = NULL;
  65.     /*
  66.      * No support for any flags yet, but in the future you would
  67.      * set any flags here.
  68.      */
  69.     flags = 0;
  70.     /*
  71.      * call interface initialization code
  72.      */
  73.     _ipAddressTable_initialize_interface(user_context, flags);
  74. }                               /* initialize_table_ipAddressTable */
  75. /**
  76.  * pre-request callback
  77.  *
  78.  *
  79.  * @retval MFD_SUCCESS              : success.
  80.  * @retval MFD_ERROR                : other error
  81.  */
  82. int
  83. ipAddressTable_pre_request(ipAddressTable_registration_ptr user_context)
  84. {
  85.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_pre_request",
  86.                 "calledn"));
  87.     /*
  88.      * TODO:510:o: Perform ipAddressTable pre-request actions.
  89.      */
  90.     return MFD_SUCCESS;
  91. }                               /* ipAddressTable_pre_request */
  92. /**
  93.  * post-request callback
  94.  *
  95.  *
  96.  * @retval MFD_SUCCESS : success.
  97.  * @retval MFD_ERROR   : other error (ignored)
  98.  */
  99. int
  100. ipAddressTable_post_request(ipAddressTable_registration_ptr user_context)
  101. {
  102.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_post_request",
  103.                 "calledn"));
  104.     /*
  105.      * TODO:511:o: Perform ipAddressTable pos-request actions.
  106.      */
  107.     return MFD_SUCCESS;
  108. }                               /* ipAddressTable_post_request */
  109. /**********************************************************************
  110.  **********************************************************************
  111.  ***
  112.  *** Table ipAddressTable
  113.  ***
  114.  **********************************************************************
  115.  **********************************************************************/
  116. /*
  117.  * ipAddressTable is subid 34 of ip.
  118.  * Its status is Current.
  119.  * OID: .1.3.6.1.2.1.4.34, length: 8
  120.  */
  121. /*
  122.  * ---------------------------------------------------------------------
  123.  * * TODO:200:r: Implement ipAddressTable data context functions.
  124.  */
  125. /*
  126.  * ipAddressTable_allocate_data
  127.  *
  128.  * Purpose: create new ipAddressTable_data.
  129.  */
  130. ipAddressTable_data *
  131. ipAddressTable_allocate_data(void)
  132. {
  133.     /*
  134.      * TODO:201:r: |-> allocate memory for the ipAddressTable data context.
  135.      */
  136.     ipAddressTable_data *rtn = netsnmp_access_ipaddress_entry_create();
  137.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_allocate_data",
  138.                 "calledn"));
  139.     if (NULL == rtn) {
  140.         snmp_log(LOG_ERR, "unable to malloc memory for new "
  141.                  "ipAddressTable_data.n");
  142.     }
  143.     return rtn;
  144. }                               /* ipAddressTable_allocate_data */
  145. /*
  146.  * ipAddressTable_release_data
  147.  *
  148.  * Purpose: release ipAddressTable data.
  149.  */
  150. void
  151. ipAddressTable_release_data(ipAddressTable_data * data)
  152. {
  153.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_release_data",
  154.                 "calledn"));
  155.     /*
  156.      * TODO:202:r: |-> release memory for the ipAddressTable data context.
  157.      */
  158.     netsnmp_access_ipaddress_entry_free(data);
  159. }                               /* ipAddressTable_release_data */
  160. /*---------------------------------------------------------------------
  161.  * IP-MIB::ipAddressEntry.ipAddressAddrType
  162.  * ipAddressAddrType is subid 1 of ipAddressEntry.
  163.  * Its status is Current, and its access level is NoAccess.
  164.  * OID: .1.3.6.1.2.1.4.34.1.1
  165.  * Description:
  166. The address type of ipAddressAddr.
  167.  *
  168.  * Attributes:
  169.  *   accessible 0     isscalar 0     enums  1      hasdefval 0
  170.  *   readable   0     iscolumn 1     ranges 0      hashint   0
  171.  *   settable   0
  172.  *
  173.  * Enum range: 5/8. Values:  unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
  174.  *
  175.  * Its syntax is InetAddressType (based on perltype INTEGER)
  176.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  177.  *
  178.  *
  179.  *
  180.  * NOTE: NODE ipAddressAddrType IS NOT ACCESSIBLE
  181.  *
  182.  *
  183.  */
  184. /**
  185.  * map a value from its original native format to the MIB format.
  186.  *
  187.  * @retval MFD_SUCCESS         : success
  188.  * @retval MFD_ERROR           : Any other error
  189.  *
  190.  * @note parameters follow the memset convention (dest, src).
  191.  *
  192.  * @note generation and use of this function can be turned off by re-running
  193.  * mib2c after adding the following line to the file
  194.  * default-node-ipAddressAddrType.m2d :
  195.  *   @eval $m2c_node_skip_mapping = 1@
  196.  *
  197.  * @remark
  198.  *  If the values for your data type don't exactly match the
  199.  *  possible values defined by the mib, you should map them here.
  200.  *  Otherwise, just do a direct copy.
  201.  */
  202. int
  203. ipAddressAddrType_map(u_long * mib_ipAddressAddrType_val_ptr,
  204.                       u_long raw_ipAddressAddrType_val)
  205. {
  206.     netsnmp_assert(NULL != mib_ipAddressAddrType_val_ptr);
  207.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddrType_map",
  208.                 "calledn"));
  209.     /*
  210.      * TODO:241:o: |-> Implement ipAddressAddrType enum mapping.
  211.      * uses INTERNAL_* macros defined in the header files
  212.      */
  213.     switch (raw_ipAddressAddrType_val) {
  214.     case INTERNAL_IPADDRESSADDRTYPE_IPV4:
  215.         *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV4;
  216.         break;
  217.     case INTERNAL_IPADDRESSADDRTYPE_IPV6:
  218.         *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_IPV6;
  219.         break;
  220.     default:
  221.         snmp_log(LOG_ERR, "couldn't map value %lu for ipAddressAddrTypen",
  222.                  raw_ipAddressAddrType_val);
  223.         *mib_ipAddressAddrType_val_ptr = INETADDRESSTYPE_UNKNOWN;
  224.     }
  225.     return MFD_SUCCESS;
  226. }                               /* ipAddressAddrType_map */
  227. /**
  228.  * set mib index(es)
  229.  *
  230.  * @param tbl_idx mib index structure
  231.  *
  232.  * @retval MFD_SUCCESS     : success.
  233.  * @retval MFD_ERROR       : other error.
  234.  *
  235.  * @remark
  236.  *  This convenience function is useful for setting all the MIB index
  237.  *  components with a single function call. It is assume that the C values
  238.  *  have already been mapped from their native/rawformat to the MIB format.
  239.  */
  240. int
  241. ipAddressTable_indexes_set_tbl_idx(ipAddressTable_mib_index * tbl_idx,
  242.                                    u_long ipAddressAddrType_val,
  243.                                    char *ipAddressAddr_val_ptr,
  244.                                    size_t ipAddressAddr_val_ptr_len)
  245. {
  246.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set_tbl_idx", "calledn"));
  247.     /*
  248.      * ipAddressAddrType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
  249.      */
  250.     /** WARNING: this code might not work for netsnmp_ipaddress_entry */
  251.     ipAddressAddrType_map(&tbl_idx->ipAddressAddrType,
  252.                           ipAddressAddrType_val);
  253.     /*
  254.      * ipAddressAddr(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
  255.      */
  256.     tbl_idx->ipAddressAddr_len = sizeof(tbl_idx->ipAddressAddr);
  257.     /** WARNING: this code might not work for netsnmp_ipaddress_entry */
  258.     /*
  259.      * make sure there is enough space for ipAddressAddr data
  260.      */
  261.     if (tbl_idx->ipAddressAddr_len < ipAddressAddr_val_ptr_len) {
  262.         snmp_log(LOG_ERR, "not enough space for valuen");
  263.         return MFD_ERROR;
  264.     }
  265.     tbl_idx->ipAddressAddr_len = ipAddressAddr_val_ptr_len;
  266.     memcpy(tbl_idx->ipAddressAddr, ipAddressAddr_val_ptr,
  267.            tbl_idx->ipAddressAddr_len * sizeof(tbl_idx->ipAddressAddr[0]));
  268.     return MFD_SUCCESS;
  269. }                               /* ipAddressTable_indexes_set_tbl_idx */
  270. /**
  271.  * @internal
  272.  * set row context indexes
  273.  *
  274.  * @param reqreq_ctx the row context that needs updated indexes
  275.  *
  276.  * @retval MFD_SUCCESS     : success.
  277.  * @retval MFD_ERROR       : other error.
  278.  *
  279.  * @remark
  280.  *  This function sets the mib indexs, then updates the oid indexs
  281.  *  from the mib index.
  282.  */
  283. int
  284. ipAddressTable_indexes_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  285.                            u_long ipAddressAddrType_val,
  286.                            char *ipAddressAddr_val_ptr,
  287.                            size_t ipAddressAddr_val_ptr_len)
  288. {
  289.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_indexes_set",
  290.                 "calledn"));
  291.     if (MFD_SUCCESS !=
  292.         ipAddressTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
  293.                                            ipAddressAddrType_val,
  294.                                            ipAddressAddr_val_ptr,
  295.                                            ipAddressAddr_val_ptr_len))
  296.         return MFD_ERROR;
  297.     /*
  298.      * convert mib index to oid index
  299.      */
  300.     rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
  301.     if (0 != ipAddressTable_index_to_oid(&rowreq_ctx->oid_idx,
  302.                                          &rowreq_ctx->tbl_idx)) {
  303.         return MFD_ERROR;
  304.     }
  305.     return MFD_SUCCESS;
  306. }                               /* ipAddressTable_indexes_set */
  307. /*---------------------------------------------------------------------
  308.  * IP-MIB::ipAddressEntry.ipAddressIfIndex
  309.  * ipAddressIfIndex is subid 3 of ipAddressEntry.
  310.  * Its status is Current, and its access level is Create.
  311.  * OID: .1.3.6.1.2.1.4.34.1.3
  312.  * Description:
  313. The index value which uniquely identifies the interface to
  314.             which this entry is applicable.  The interface identified by
  315.             a particular value of this index is the same interface as
  316.             identified by the same value of the IF-MIB's ifIndex.
  317.  *
  318.  * Attributes:
  319.  *   accessible 1     isscalar 0     enums  0      hasdefval 0
  320.  *   readable   1     iscolumn 1     ranges 1      hashint   1
  321.  *   settable   1
  322.  *   hint: d
  323.  *
  324.  * Ranges:  1 - 2147483647;
  325.  *
  326.  * Its syntax is InterfaceIndex (based on perltype INTEGER32)
  327.  * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
  328.  */
  329. /**
  330.  * Extract the current value of the ipAddressIfIndex data.
  331.  *
  332.  * Set a value using the data context for the row.
  333.  *
  334.  * @param rowreq_ctx
  335.  *        Pointer to the row request context.
  336.  * @param ipAddressIfIndex_val_ptr
  337.  *        Pointer to storage for a long variable
  338.  *
  339.  * @retval MFD_SUCCESS         : success
  340.  * @retval MFD_SKIP            : skip this node (no value for now)
  341.  * @retval MFD_ERROR           : Any other error
  342.  */
  343. int
  344. ipAddressIfIndex_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  345.                      long *ipAddressIfIndex_val_ptr)
  346. {
  347.    /** we should have a non-NULL pointer */
  348.     netsnmp_assert(NULL != ipAddressIfIndex_val_ptr);
  349.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_get",
  350.                 "calledn"));
  351.     netsnmp_assert(NULL != rowreq_ctx);
  352.     /*
  353.      * TODO:231:o: |-> Extract the current value of the ipAddressIfIndex data.
  354.      * set (* ipAddressIfIndex_val_ptr ) from rowreq_ctx->data
  355.      */
  356.     (*ipAddressIfIndex_val_ptr) = rowreq_ctx->data->if_index;
  357.     return MFD_SUCCESS;
  358. }                               /* ipAddressIfIndex_get */
  359. /*---------------------------------------------------------------------
  360.  * IP-MIB::ipAddressEntry.ipAddressType
  361.  * ipAddressType is subid 4 of ipAddressEntry.
  362.  * Its status is Current, and its access level is Create.
  363.  * OID: .1.3.6.1.2.1.4.34.1.4
  364.  * Description:
  365. The type of address.  broadcast(3) is not a valid value for
  366.             IPv6 addresses (RFC3513).  
  367.  *
  368.  * Attributes:
  369.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  370.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  371.  *   settable   1
  372.  *   defval: unicast
  373.  *
  374.  * Enum range: 2/8. Values:  unicast(1), anycast(2), broadcast(3)
  375.  *
  376.  * Its syntax is INTEGER (based on perltype INTEGER)
  377.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  378.  */
  379. /**
  380.  * Extract the current value of the ipAddressType data.
  381.  *
  382.  * Set a value using the data context for the row.
  383.  *
  384.  * @param rowreq_ctx
  385.  *        Pointer to the row request context.
  386.  * @param ipAddressType_val_ptr
  387.  *        Pointer to storage for a long variable
  388.  *
  389.  * @retval MFD_SUCCESS         : success
  390.  * @retval MFD_SKIP            : skip this node (no value for now)
  391.  * @retval MFD_ERROR           : Any other error
  392.  */
  393. int
  394. ipAddressType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  395.                   u_long * ipAddressType_val_ptr)
  396. {
  397.    /** we should have a non-NULL pointer */
  398.     netsnmp_assert(NULL != ipAddressType_val_ptr);
  399.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_get", "calledn"));
  400.     netsnmp_assert(NULL != rowreq_ctx);
  401.     /*
  402.      * TODO:231:o: |-> Extract the current value of the ipAddressType data.
  403.      * set (* ipAddressType_val_ptr ) from rowreq_ctx->data
  404.      */
  405.     (*ipAddressType_val_ptr) = rowreq_ctx->data->ia_type;
  406.     return MFD_SUCCESS;
  407. }                               /* ipAddressType_get */
  408. /*---------------------------------------------------------------------
  409.  * IP-MIB::ipAddressEntry.ipAddressPrefix
  410.  * ipAddressPrefix is subid 5 of ipAddressEntry.
  411.  * Its status is Current, and its access level is ReadOnly.
  412.  * OID: .1.3.6.1.2.1.4.34.1.5
  413.  * Description:
  414. A pointer to the row in the prefix table to which this
  415.             address belongs.  May be { 0 0 } if there is no such row.
  416.  *
  417.  * Attributes:
  418.  *   accessible 1     isscalar 0     enums  0      hasdefval 1
  419.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  420.  *   settable   0
  421.  *   defval: zeroDotZero
  422.  *
  423.  *
  424.  * Its syntax is RowPointer (based on perltype OBJECTID)
  425.  * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
  426.  * This data type requires a length.  (Max 2147483647)
  427.  */
  428. /**
  429.  * Extract the current value of the ipAddressPrefix data.
  430.  *
  431.  * Set a value using the data context for the row.
  432.  *
  433.  * @param rowreq_ctx
  434.  *        Pointer to the row request context.
  435.  * @param ipAddressPrefix_val_ptr_ptr
  436.  *        Pointer to storage for a oid variable
  437.  * @param ipAddressPrefix_val_ptr_len_ptr
  438.  *        Pointer to a size_t. On entry, it will contain the size (in bytes)
  439.  *        pointed to by ipAddressPrefix.
  440.  *        On exit, this value should contain the data size (in bytes).
  441.  *
  442.  * @retval MFD_SUCCESS         : success
  443.  * @retval MFD_SKIP            : skip this node (no value for now)
  444.  * @retval MFD_ERROR           : Any other error
  445. *
  446.  * @note If you need more than (*ipAddressPrefix_val_ptr_len_ptr) bytes of memory,
  447.  *       allocate it using malloc() and update ipAddressPrefix_val_ptr_ptr.
  448.  *       <b>DO NOT</b> free the previous pointer.
  449.  *       The MFD helper will release the memory you allocate.
  450.  *
  451.  * @remark If you call this function yourself, you are responsible
  452.  *         for checking if the pointer changed, and freeing any
  453.  *         previously allocated memory. (Not necessary if you pass
  454.  *         in a pointer to static memory, obviously.)
  455.  */
  456. int
  457. ipAddressPrefix_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  458.                     oid ** ipAddressPrefix_val_ptr_ptr,
  459.                     size_t *ipAddressPrefix_val_ptr_len_ptr)
  460. {
  461.     oid            *src;
  462.     int             len;
  463.    /** we should have a non-NULL pointer and enough storage */
  464.     netsnmp_assert((NULL != ipAddressPrefix_val_ptr_ptr)
  465.                    && (NULL != *ipAddressPrefix_val_ptr_ptr));
  466.     netsnmp_assert(NULL != ipAddressPrefix_val_ptr_len_ptr);
  467.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressPrefix_get", "calledn"));
  468.     netsnmp_assert(NULL != rowreq_ctx);
  469.     /*
  470.      * TODO:231:o: |-> Extract the current value of the ipAddressPrefix data.
  471.      * set (* ipAddressPrefix_val_ptr_ptr ) and (* ipAddressPrefix_val_ptr_len_ptr ) from rowreq_ctx->data
  472.      */
  473.     if (NULL == rowreq_ctx->data->ia_prefix_oid) {
  474.         src = nullOid;
  475.         len = nullOidLen / sizeof(oid);
  476.     } else {
  477.         src = rowreq_ctx->data->ia_prefix_oid;
  478.         len = rowreq_ctx->data->ia_prefix_oid_len;
  479.     }
  480.     if ((*ipAddressPrefix_val_ptr_len_ptr) < len) {
  481.         (*ipAddressPrefix_val_ptr_ptr) =
  482.             malloc(len * sizeof((*ipAddressPrefix_val_ptr_ptr)[0]));
  483.         if (NULL == (*ipAddressPrefix_val_ptr_ptr)) {
  484.             snmp_log(LOG_ERR, "could not allocate memoryn");
  485.             return MFD_ERROR;
  486.         }
  487.     }
  488.     (*ipAddressPrefix_val_ptr_len_ptr) = len;
  489.     memcpy((*ipAddressPrefix_val_ptr_ptr), src,
  490.            len * sizeof((*ipAddressPrefix_val_ptr_ptr)[0]));
  491.     return MFD_SUCCESS;
  492. }                               /* ipAddressPrefix_get */
  493. /*---------------------------------------------------------------------
  494.  * IP-MIB::ipAddressEntry.ipAddressOrigin
  495.  * ipAddressOrigin is subid 6 of ipAddressEntry.
  496.  * Its status is Current, and its access level is ReadOnly.
  497.  * OID: .1.3.6.1.2.1.4.34.1.6
  498.  * Description:
  499. The origin of the address.
  500.  *
  501.  * Attributes:
  502.  *   accessible 1     isscalar 0     enums  1      hasdefval 0
  503.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  504.  *   settable   0
  505.  *
  506.  * Enum range: 4/8. Values:  other(1), manual(2), dhcp(4), linklayer(5), random(6)
  507.  *
  508.  * Its syntax is IpAddressOriginTC (based on perltype INTEGER)
  509.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  510.  */
  511. /**
  512.  * Extract the current value of the ipAddressOrigin data.
  513.  *
  514.  * Set a value using the data context for the row.
  515.  *
  516.  * @param rowreq_ctx
  517.  *        Pointer to the row request context.
  518.  * @param ipAddressOrigin_val_ptr
  519.  *        Pointer to storage for a long variable
  520.  *
  521.  * @retval MFD_SUCCESS         : success
  522.  * @retval MFD_SKIP            : skip this node (no value for now)
  523.  * @retval MFD_ERROR           : Any other error
  524.  */
  525. int
  526. ipAddressOrigin_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  527.                     u_long * ipAddressOrigin_val_ptr)
  528. {
  529.    /** we should have a non-NULL pointer */
  530.     netsnmp_assert(NULL != ipAddressOrigin_val_ptr);
  531.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressOrigin_get", "calledn"));
  532.     netsnmp_assert(NULL != rowreq_ctx);
  533.     /*
  534.      * TODO:231:o: |-> Extract the current value of the ipAddressOrigin data.
  535.      * set (* ipAddressOrigin_val_ptr ) from rowreq_ctx->data
  536.      */
  537.     (*ipAddressOrigin_val_ptr) = rowreq_ctx->data->ia_origin;
  538.     return MFD_SUCCESS;
  539. }                               /* ipAddressOrigin_get */
  540. /*---------------------------------------------------------------------
  541.  * IP-MIB::ipAddressEntry.ipAddressStatus
  542.  * ipAddressStatus is subid 7 of ipAddressEntry.
  543.  * Its status is Current, and its access level is Create.
  544.  * OID: .1.3.6.1.2.1.4.34.1.7
  545.  * Description:
  546. The status of the address, describing if the address can be
  547.             used for communication.
  548.             In the absence of other information, an IPv4 address is
  549.             always preferred(1).
  550.  *
  551.  * Attributes:
  552.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  553.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  554.  *   settable   1
  555.  *   defval: preferred
  556.  *
  557.  * Enum range: 5/8. Values:  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
  558.  *
  559.  * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
  560.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  561.  */
  562. /**
  563.  * Extract the current value of the ipAddressStatus data.
  564.  *
  565.  * Set a value using the data context for the row.
  566.  *
  567.  * @param rowreq_ctx
  568.  *        Pointer to the row request context.
  569.  * @param ipAddressStatus_val_ptr
  570.  *        Pointer to storage for a long variable
  571.  *
  572.  * @retval MFD_SUCCESS         : success
  573.  * @retval MFD_SKIP            : skip this node (no value for now)
  574.  * @retval MFD_ERROR           : Any other error
  575.  */
  576. int
  577. ipAddressStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  578.                     u_long * ipAddressStatus_val_ptr)
  579. {
  580.    /** we should have a non-NULL pointer */
  581.     netsnmp_assert(NULL != ipAddressStatus_val_ptr);
  582.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_get", "calledn"));
  583.     netsnmp_assert(NULL != rowreq_ctx);
  584.     /*
  585.      * TODO:231:o: |-> Extract the current value of the ipAddressStatus data.
  586.      * set (* ipAddressStatus_val_ptr ) from rowreq_ctx->data
  587.      */
  588.     (*ipAddressStatus_val_ptr) = rowreq_ctx->data->ia_status;
  589.     return MFD_SUCCESS;
  590. }                               /* ipAddressStatus_get */
  591. /*---------------------------------------------------------------------
  592.  * IP-MIB::ipAddressEntry.ipAddressCreated
  593.  * ipAddressCreated is subid 8 of ipAddressEntry.
  594.  * Its status is Current, and its access level is ReadOnly.
  595.  * OID: .1.3.6.1.2.1.4.34.1.8
  596.  * Description:
  597. The value of sysUpTime at the time this entry was created.
  598.             If this entry was created prior to the last re-
  599.             initialization of the local network management subsystem,
  600.             then this object contains a zero value.
  601.  *
  602.  * Attributes:
  603.  *   accessible 1     isscalar 0     enums  0      hasdefval 0
  604.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  605.  *   settable   0
  606.  *
  607.  *
  608.  * Its syntax is TimeStamp (based on perltype TICKS)
  609.  * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
  610.  */
  611. /**
  612.  * Extract the current value of the ipAddressCreated data.
  613.  *
  614.  * Set a value using the data context for the row.
  615.  *
  616.  * @param rowreq_ctx
  617.  *        Pointer to the row request context.
  618.  * @param ipAddressCreated_val_ptr
  619.  *        Pointer to storage for a u_long variable
  620.  *
  621.  * @retval MFD_SUCCESS         : success
  622.  * @retval MFD_SKIP            : skip this node (no value for now)
  623.  * @retval MFD_ERROR           : Any other error
  624.  */
  625. int
  626. ipAddressCreated_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  627.                      u_long * ipAddressCreated_val_ptr)
  628. {
  629.    /** we should have a non-NULL pointer */
  630.     netsnmp_assert(NULL != ipAddressCreated_val_ptr);
  631.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressCreated_get",
  632.                 "calledn"));
  633.     netsnmp_assert(NULL != rowreq_ctx);
  634.     /*
  635.      * TODO:231:o: |-> Extract the current value of the ipAddressCreated data.
  636.      * set (* ipAddressCreated_val_ptr ) from rowreq_ctx->data
  637.      */
  638.     (*ipAddressCreated_val_ptr) = rowreq_ctx->ipAddressCreated;
  639.     return MFD_SUCCESS;
  640. }                               /* ipAddressCreated_get */
  641. /*---------------------------------------------------------------------
  642.  * IP-MIB::ipAddressEntry.ipAddressLastChanged
  643.  * ipAddressLastChanged is subid 9 of ipAddressEntry.
  644.  * Its status is Current, and its access level is ReadOnly.
  645.  * OID: .1.3.6.1.2.1.4.34.1.9
  646.  * Description:
  647. The value of sysUpTime at the time this entry was last
  648.             updated.  If this entry was updated prior to the last re-
  649.             initialization of the local network management subsystem,
  650.             then this object contains a zero value.
  651.  *
  652.  * Attributes:
  653.  *   accessible 1     isscalar 0     enums  0      hasdefval 0
  654.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  655.  *   settable   0
  656.  *
  657.  *
  658.  * Its syntax is TimeStamp (based on perltype TICKS)
  659.  * The net-snmp type is ASN_TIMETICKS. The C type decl is u_long (u_long)
  660.  */
  661. /**
  662.  * Extract the current value of the ipAddressLastChanged data.
  663.  *
  664.  * Set a value using the data context for the row.
  665.  *
  666.  * @param rowreq_ctx
  667.  *        Pointer to the row request context.
  668.  * @param ipAddressLastChanged_val_ptr
  669.  *        Pointer to storage for a u_long variable
  670.  *
  671.  * @retval MFD_SUCCESS         : success
  672.  * @retval MFD_SKIP            : skip this node (no value for now)
  673.  * @retval MFD_ERROR           : Any other error
  674.  */
  675. int
  676. ipAddressLastChanged_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  677.                          u_long * ipAddressLastChanged_val_ptr)
  678. {
  679.    /** we should have a non-NULL pointer */
  680.     netsnmp_assert(NULL != ipAddressLastChanged_val_ptr);
  681.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressLastChanged_get",
  682.                 "calledn"));
  683.     netsnmp_assert(NULL != rowreq_ctx);
  684.     /*
  685.      * TODO:231:o: |-> Extract the current value of the ipAddressLastChanged data.
  686.      * set (* ipAddressLastChanged_val_ptr ) from rowreq_ctx->data
  687.      */
  688.     (*ipAddressLastChanged_val_ptr) = rowreq_ctx->ipAddressLastChanged;
  689.     return MFD_SUCCESS;
  690. }                               /* ipAddressLastChanged_get */
  691. /*---------------------------------------------------------------------
  692.  * IP-MIB::ipAddressEntry.ipAddressRowStatus
  693.  * ipAddressRowStatus is subid 10 of ipAddressEntry.
  694.  * Its status is Current, and its access level is Create.
  695.  * OID: .1.3.6.1.2.1.4.34.1.10
  696.  * Description:
  697. The status of this conceptual row.
  698.             The RowStatus TC requires that this DESCRIPTION clause
  699.             states under which circumstances other objects in this row
  700.             can be modified.  The value of this object has no effect on
  701.             whether other objects in this conceptual row can be
  702.             modified.
  703.             A conceptual row can not be made active until the
  704.             ipAddressIfIndex has been set to a valid index.  
  705.  *
  706.  * Attributes:
  707.  *   accessible 1     isscalar 0     enums  1      hasdefval 0
  708.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  709.  *   settable   1
  710.  *
  711.  * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
  712.  *
  713.  * Its syntax is RowStatus (based on perltype INTEGER)
  714.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  715.  */
  716. /**
  717.  * Extract the current value of the ipAddressRowStatus data.
  718.  *
  719.  * Set a value using the data context for the row.
  720.  *
  721.  * @param rowreq_ctx
  722.  *        Pointer to the row request context.
  723.  * @param ipAddressRowStatus_val_ptr
  724.  *        Pointer to storage for a long variable
  725.  *
  726.  * @retval MFD_SUCCESS         : success
  727.  * @retval MFD_SKIP            : skip this node (no value for now)
  728.  * @retval MFD_ERROR           : Any other error
  729.  */
  730. int
  731. ipAddressRowStatus_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  732.                        u_long * ipAddressRowStatus_val_ptr)
  733. {
  734.    /** we should have a non-NULL pointer */
  735.     netsnmp_assert(NULL != ipAddressRowStatus_val_ptr);
  736.     /** WARNING: this code might not work for netsnmp_ipaddress_entry */
  737.     (*ipAddressRowStatus_val_ptr) = rowreq_ctx->ipAddressRowStatus;
  738.     return MFD_SUCCESS;
  739. }                               /* ipAddressRowStatus_get */
  740. /*---------------------------------------------------------------------
  741.  * IP-MIB::ipAddressEntry.ipAddressStorageType
  742.  * ipAddressStorageType is subid 11 of ipAddressEntry.
  743.  * Its status is Current, and its access level is Create.
  744.  * OID: .1.3.6.1.2.1.4.34.1.11
  745.  * Description:
  746. The storage type for this conceptual row.  If this object
  747.             has a value of 'permanent' then no other objects are
  748.             required to be able to be modified.
  749.  *
  750.  * Attributes:
  751.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  752.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  753.  *   settable   1
  754.  *   defval: volatile
  755.  *
  756.  * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
  757.  *
  758.  * Its syntax is StorageType (based on perltype INTEGER)
  759.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  760.  */
  761. /**
  762.  * Extract the current value of the ipAddressStorageType data.
  763.  *
  764.  * Set a value using the data context for the row.
  765.  *
  766.  * @param rowreq_ctx
  767.  *        Pointer to the row request context.
  768.  * @param ipAddressStorageType_val_ptr
  769.  *        Pointer to storage for a long variable
  770.  *
  771.  * @retval MFD_SUCCESS         : success
  772.  * @retval MFD_SKIP            : skip this node (no value for now)
  773.  * @retval MFD_ERROR           : Any other error
  774.  */
  775. int
  776. ipAddressStorageType_get(ipAddressTable_rowreq_ctx * rowreq_ctx,
  777.                          u_long * ipAddressStorageType_val_ptr)
  778. {
  779.    /** we should have a non-NULL pointer */
  780.     netsnmp_assert(NULL != ipAddressStorageType_val_ptr);
  781.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_get",
  782.                 "calledn"));
  783.     netsnmp_assert(NULL != rowreq_ctx);
  784.     /*
  785.      * TODO:231:o: |-> Extract the current value of the ipAddressStorageType data.
  786.      * set (* ipAddressStorageType_val_ptr ) from rowreq_ctx->data
  787.      */
  788.     (*ipAddressStorageType_val_ptr) = rowreq_ctx->data->ia_storagetype;
  789.     return MFD_SUCCESS;
  790. }                               /* ipAddressStorageType_get */
  791. /** @} */
  792. /**********************************************************************
  793.  **********************************************************************
  794.  ***
  795.  *** Table ipAddressTable
  796.  ***
  797.  **********************************************************************
  798.  **********************************************************************/
  799. /*
  800.  * ipAddressTable is subid 34 of ip.
  801.  * Its status is Current.
  802.  * OID: .1.3.6.1.2.1.4.34, length: 8
  803.  */
  804.     /*
  805.      * NOTE: if you update this chart, please update the versions in
  806.      *       local/mib2c-conf.d/parent-set.m2i
  807.      *       agent/mibgroup/helpers/baby_steps.c
  808.      * while you're at it.
  809.      */
  810.     /*
  811.      ***********************************************************************
  812.      * Baby Steps Flow Chart (2004.06.05)                                  *
  813.      *                                                                     *
  814.      * +--------------+    +================+    U = unconditional path    *
  815.      * |optional state|    ||required state||    S = path for success      *
  816.      * +--------------+    +================+    E = path for error        *
  817.      ***********************************************************************
  818.      *
  819.      *                        +--------------+
  820.      *                        |     pre      |
  821.      *                        |   request    |
  822.      *                        +--------------+
  823.      *                               | U
  824.      * +-------------+        +==============+
  825.      * |    row    |f|<-------||  object    ||
  826.      * |  create   |1|      E ||  lookup    ||
  827.      * +-------------+        +==============+
  828.      *     E |   | S                 | S
  829.      *       |   +------------------>|
  830.      *       |                +==============+
  831.      *       |              E ||   check    ||
  832.      *       |<---------------||   values   ||
  833.      *       |                +==============+
  834.      *       |                       | S
  835.      *       |                +==============+
  836.      *       |       +<-------||   undo     ||
  837.      *       |       |      E ||   setup    ||
  838.      *       |       |        +==============+
  839.      *       |       |               | S
  840.      *       |       |        +==============+
  841.      *       |       |        ||    set     ||-------------------------->+
  842.      *       |       |        ||   value    || E                         |
  843.      *       |       |        +==============+                           |
  844.      *       |       |               | S                                 |
  845.      *       |       |        +--------------+                           |
  846.      *       |       |        |    check     |-------------------------->|
  847.      *       |       |        |  consistency | E                         |
  848.      *       |       |        +--------------+                           |
  849.      *       |       |               | S                                 |
  850.      *       |       |        +==============+         +==============+  |
  851.      *       |       |        ||   commit   ||-------->||     undo   ||  |
  852.      *       |       |        ||            || E       ||    commit  ||  |
  853.      *       |       |        +==============+         +==============+  |
  854.      *       |       |               | S                     U |<--------+
  855.      *       |       |        +--------------+         +==============+
  856.      *       |       |        | irreversible |         ||    undo    ||
  857.      *       |       |        |    commit    |         ||     set    ||
  858.      *       |       |        +--------------+         +==============+
  859.      *       |       |               | U                     U |
  860.      *       |       +-------------->|<------------------------+
  861.      *       |                +==============+
  862.      *       |                ||   undo     ||
  863.      *       |                ||  cleanup   ||
  864.      *       |                +==============+
  865.      *       +---------------------->| U
  866.      *                               |
  867.      *                          (err && f1)------------------->+
  868.      *                               |                         |
  869.      *                        +--------------+         +--------------+
  870.      *                        |    post      |<--------|      row     |
  871.      *                        |   request    |       U |    release   |
  872.      *                        +--------------+         +--------------+
  873.      *
  874.      */
  875. /**
  876.  * verify specified index is valid.
  877.  *
  878.  * This check is independent of whether or not the values specified for
  879.  * the columns of the new row are valid. Column values and row consistency
  880.  * will be checked later. At this point, only the index values should be
  881.  * checked.
  882.  *
  883.  * All of the individual index validation functions have been called, so this
  884.  * is the place to make sure they are valid as a whole when combined. If
  885.  * you only have one index, 
  886.  * 
  887.  *
  888.  *
  889.  * @param ipAddressTable_reg
  890.  *        Pointer to the user registration data
  891.  * @param ipAddressTable_rowreq_ctx
  892.  *        Pointer to the users context.
  893.  * @retval MFD_SUCCESS            : success
  894.  * @retval MFD_CANNOT_CREATE_NOW  : index not valid right now
  895.  * @retval MFD_CANNOT_CREATE_EVER : index never valid
  896.  */
  897. int
  898. ipAddressTable_validate_index(ipAddressTable_registration_ptr
  899.                               ipAddressTable_reg,
  900.                               ipAddressTable_rowreq_ctx * rowreq_ctx)
  901. {
  902.     int             rc = MFD_SUCCESS;
  903.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_validate_index",
  904.                 "calledn"));
  905.     /** we should have a non-NULL pointer */
  906.     netsnmp_assert(NULL != rowreq_ctx);
  907.     /*
  908.      * TODO:430:M: |-> Validate potential ipAddressTable index.
  909.      *
  910.      * xxx-rks: we only plan ipv4 support initially
  911.      */
  912.     if ((4 != rowreq_ctx->tbl_idx.ipAddressAddr_len)) {
  913.         snmp_log(LOG_WARNING, "invalid index for a new row in the "
  914.                  "ipAddressTable table.n");
  915.         /*
  916.          * determine failure type.
  917.          *
  918.          * If the index could not ever be created, return MFD_NOT_EVER
  919.          * If the index can not be created under the present circumstances
  920.          * (even though it could be created under other circumstances),
  921.          * return MFD_NOT_NOW.
  922.          */
  923.         if (0) {
  924.             return MFD_CANNOT_CREATE_EVER;
  925.         } else {
  926.             return MFD_CANNOT_CREATE_NOW;
  927.         }
  928.     } else {
  929.         rowreq_ctx->data->ia_address[0] =
  930.             rowreq_ctx->tbl_idx.ipAddressAddr[0];
  931.         rowreq_ctx->data->ia_address[1] =
  932.             rowreq_ctx->tbl_idx.ipAddressAddr[1];
  933.         rowreq_ctx->data->ia_address[2] =
  934.             rowreq_ctx->tbl_idx.ipAddressAddr[2];
  935.         rowreq_ctx->data->ia_address[3] =
  936.             rowreq_ctx->tbl_idx.ipAddressAddr[3];
  937.         rowreq_ctx->data->ia_address_len = 4;
  938.     }
  939.     return rc;
  940. }                               /* ipAddressTable_validate_index */
  941. /**
  942.  * Setup up context with information needed to undo a set request.
  943.  *
  944.  * This function will be called before the individual node undo setup
  945.  * functions are called. If you need to do any undo setup that is not
  946.  * related to a specific column, you can do it here.
  947.  *
  948.  * Note that an individual node's undo_setup function will only be called
  949.  * if that node is being set to a new value.
  950.  *
  951.  * If there is any setup specific to a particular column (e.g. allocating
  952.  * memory for a string), you should do that setup in the node's undo_setup
  953.  * function, so it won't be done unless it is necessary.
  954.  *
  955.  * @param rowreq_ctx
  956.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  957.  *
  958.  * @retval MFD_SUCCESS : success
  959.  * @retval MFD_ERROR   : error. set will fail.
  960.  */
  961. int
  962. ipAddressTable_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  963. {
  964.     int             rc = MFD_SUCCESS;
  965.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_setup",
  966.                 "calledn"));
  967.     /** we should have a non-NULL pointer */
  968.     netsnmp_assert(NULL != rowreq_ctx);
  969.     /*
  970.      * TODO:451:M: |-> Setup ipAddressTable undo.
  971.      * set up ipAddressTable undo information, in preparation for a set.
  972.      */
  973.     /*
  974.      * check for storage types that don't allow modification.
  975.      * probably should try and do this earlier (and we could, by
  976.      * adding code to the interface file), but this ought to suffice.
  977.      */
  978.     if (STORAGETYPE_READONLY == rowreq_ctx->data->ia_storagetype) {
  979.         DEBUGMSGTL(("ipAddressTable", "can't change readonly rown"));
  980.         return MFD_NOT_VALID_EVER;
  981.     }
  982.     /*
  983.      * save last changed
  984.      */
  985.     rowreq_ctx->ipAddressLastChanged_undo =
  986.         rowreq_ctx->ipAddressLastChanged;
  987.     rowreq_ctx->ipAddressLastChanged =
  988.         rowreq_ctx->ipAddressLastChanged_undo;
  989.     /*
  990.      * just copy everything
  991.      */
  992.     rc = netsnmp_access_ipaddress_entry_copy(rowreq_ctx->undo,
  993.                                              rowreq_ctx->data);
  994.     return rc;
  995. }                               /* ipAddressTable_undo_setup */
  996. /**
  997.  * Cleanup up context undo information.
  998.  *
  999.  * This function will be called after set/commit processing. If you
  1000.  * allocated any resources in undo_setup, this is the place to release
  1001.  * those resources.
  1002.  *
  1003.  * This function is called regardless of the success or failure of the set
  1004.  * request. If you need to perform different steps for cleanup depending
  1005.  * on success or failure, you can add a flag to the rowreq_ctx.
  1006.  *
  1007.  * @param rowreq_ctx
  1008.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  1009.  *
  1010.  * @retval MFD_SUCCESS : success
  1011.  * @retval MFD_ERROR   : error
  1012.  */
  1013. int
  1014. ipAddressTable_undo_cleanup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1015. {
  1016.     int             rc = MFD_SUCCESS;
  1017.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_cleanup",
  1018.                 "calledn"));
  1019.     /** we should have a non-NULL pointer */
  1020.     netsnmp_assert(NULL != rowreq_ctx);
  1021.     /*
  1022.      * TODO:452:M: |-> Cleanup ipAddressTable undo.
  1023.      */
  1024.     return rc;
  1025. }                               /* ipAddressTable_undo_cleanup */
  1026. /**
  1027.  * commit new values.
  1028.  *
  1029.  * At this point, you should have done everything you can to ensure that
  1030.  * this commit will not fail.
  1031.  *
  1032.  * Should you need different behavior depending on which columns were
  1033.  * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
  1034.  * set. The definitions for the FLAG_* bits can be found in
  1035.  * ipAddressTable.h.
  1036.  * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
  1037.  *
  1038.  * @param ipAddressTable_rowreq_ctx
  1039.  *        Pointer to the users context.
  1040.  *
  1041.  * @retval MFD_SUCCESS : success
  1042.  * @retval MFD_ERROR   : error
  1043.  */
  1044. int
  1045. ipAddressTable_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1046. {
  1047.     int             rc = MFD_SUCCESS;
  1048.     int             save_flags;
  1049.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_commit",
  1050.                 "calledn"));
  1051.     /** we should have a non-NULL pointer */
  1052.     netsnmp_assert(NULL != rowreq_ctx);
  1053.     /*
  1054.      * save flags, then clear until we actually do something
  1055.      */
  1056.     save_flags = rowreq_ctx->column_set_flags;
  1057.     rowreq_ctx->column_set_flags = 0;
  1058.     /*
  1059.      * commit ipAddressTable data
  1060.      * 1) check the column's flag in save_flags to see if it was set.
  1061.      * 2) clear the flag when you handle that column
  1062.      * 3) set the column's flag in column_set_flags if it needs undo
  1063.      *    processing in case of a failure.
  1064.      */
  1065.     /*
  1066.      * did anything change?
  1067.      */
  1068.     if (0 == save_flags) {
  1069.         DEBUGMSGTL(("ipAddressTable:ipAddressTable_commit",
  1070.                     "no changen"));
  1071.         return MFD_SUCCESS;
  1072.     }
  1073.     /*
  1074.      * pass everything to data access
  1075.      * let data access know what columns are set
  1076.      */
  1077.     rowreq_ctx->data->flags = save_flags;
  1078.     if (save_flags & FLAG_IPADDRESSROWSTATUS) {
  1079.         if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
  1080.             netsnmp_assert(ROWSTATUS_CREATEANDGO ==
  1081.                            rowreq_ctx->ipAddressRowStatus);
  1082.             rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
  1083.             rowreq_ctx->ipAddressCreated = netsnmp_get_agent_uptime();
  1084.         } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
  1085.             rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
  1086.         } else
  1087.             rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
  1088.     } else
  1089.         rowreq_ctx->data->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
  1090.     /*
  1091.      * do it
  1092.      */
  1093.     rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->data);
  1094.     if (rc) {
  1095.         DEBUGMSGTL(("ipAddressTable",
  1096.                     "bad rc %d from IP address data accessn", rc));
  1097.         rc = MFD_ERROR;
  1098.     } else {
  1099.         rowreq_ctx->ipAddressLastChanged = netsnmp_get_agent_uptime();
  1100.         /*
  1101.          * set flag, in case we need to undo
  1102.          */
  1103.         rowreq_ctx->column_set_flags |= save_flags;
  1104.     }
  1105.     return rc;
  1106. }                               /* ipAddressTable_commit */
  1107. /**
  1108.  * undo commit new values.
  1109.  *
  1110.  * Should you need different behavior depending on which columns were
  1111.  * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
  1112.  * set. The definitions for the FLAG_* bits can be found in
  1113.  * ipAddressTable.h.
  1114.  * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
  1115.  *
  1116.  * @param ipAddressTable_rowreq_ctx
  1117.  *        Pointer to the users context.
  1118.  *
  1119.  * @retval MFD_SUCCESS : success
  1120.  * @retval MFD_ERROR   : error
  1121.  */
  1122. int
  1123. ipAddressTable_undo_commit(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1124. {
  1125.     int             rc = MFD_SUCCESS;
  1126.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_undo_commit",
  1127.                 "calledn"));
  1128.     /** we should have a non-NULL pointer */
  1129.     netsnmp_assert(NULL != rowreq_ctx);
  1130.     /*
  1131.      * TODO:485:M: |-> Undo ipAddressTable commit.
  1132.      * check the column's flag in rowreq_ctx->column_set_flags to see
  1133.      * if it was set during commit, then undo it.
  1134.      */
  1135.     if (rowreq_ctx->column_set_flags & FLAG_IPADDRESSROWSTATUS) {
  1136.         /*
  1137.          * if we created an addr, delete it. if we deleted it,
  1138.          * re-create it. If we changed it, change it back.
  1139.          */
  1140.         if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
  1141.             rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_DELETE;
  1142.         } else if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
  1143.             rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CREATE;
  1144.         } else
  1145.             rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
  1146.     } else
  1147.         rowreq_ctx->undo->flags |= NETSNMP_ACCESS_IPADDRESS_CHANGE;
  1148.     /*
  1149.      * do it
  1150.      */
  1151.     rc = netsnmp_access_ipaddress_entry_set(rowreq_ctx->undo);
  1152.     if (rc) {
  1153.         DEBUGMSGTL(("ipAddressTable",
  1154.                     "bad rc %d from IP address data accessn", rc));
  1155.         rc = MFD_ERROR;
  1156.     }
  1157.     return rc;
  1158. }                               /* ipAddressTable_undo_commit */
  1159. /*
  1160.  * TODO:420:r: Implement ipAddressTable index validation.
  1161.  */
  1162. /*---------------------------------------------------------------------
  1163.  * IP-MIB::ipAddressEntry.ipAddressAddrType
  1164.  * ipAddressAddrType is subid 1 of ipAddressEntry.
  1165.  * Its status is Current, and its access level is NoAccess.
  1166.  * OID: .1.3.6.1.2.1.4.34.1.1
  1167.  * Description:
  1168. The address type of ipAddressAddr.
  1169.  *
  1170.  * Attributes:
  1171.  *   accessible 0     isscalar 0     enums  1      hasdefval 0
  1172.  *   readable   0     iscolumn 1     ranges 0      hashint   0
  1173.  *   settable   0
  1174.  *
  1175.  * Enum range: 5/8. Values:  unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
  1176.  *
  1177.  * Its syntax is InetAddressType (based on perltype INTEGER)
  1178.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  1179.  *
  1180.  *
  1181.  *
  1182.  * NOTE: NODE ipAddressAddrType IS NOT ACCESSIBLE
  1183.  *
  1184.  *
  1185.  */
  1186. /**
  1187.  * check validity of ipAddressAddrType index portion
  1188.  *
  1189.  * @retval MFD_SUCCESS   : the incoming value is legal
  1190.  * @retval MFD_BAD_VALUE : the incoming value is NOT legal
  1191.  *
  1192.  * @note this is not the place to do any checks for the sanity
  1193.  *       of multiple indexes. Those types of checks should be done in the
  1194.  *       ipAddressTable_validate_index() function.
  1195.  */
  1196. int
  1197. ipAddressAddrType_check_index(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1198. {
  1199.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddrType_check_index",
  1200.                 "calledn"));
  1201.     netsnmp_assert(NULL != rowreq_ctx);
  1202.     /*
  1203.      * TODO:426:M: |-> Check ipAddressTable index ipAddressAddrType.
  1204.      * check that index value in the table context (rowreq_ctx)
  1205.      * for ipAddressAddrType is legal.
  1206.      */
  1207.     switch (rowreq_ctx->tbl_idx.ipAddressAddrType) {
  1208.     case INETADDRESSTYPE_IPV4:
  1209.     case INETADDRESSTYPE_IPV6:
  1210.         break;
  1211.     default:
  1212.         DEBUGMSGT(("ipAddressTable", "illegal addr typen"));
  1213.         return MFD_ERROR;
  1214.     }
  1215.     return MFD_SUCCESS;         /* ipAddressAddrType index ok */
  1216. }                               /* ipAddressAddrType_check_index */
  1217. /*---------------------------------------------------------------------
  1218.  * IP-MIB::ipAddressEntry.ipAddressAddr
  1219.  * ipAddressAddr is subid 2 of ipAddressEntry.
  1220.  * Its status is Current, and its access level is NoAccess.
  1221.  * OID: .1.3.6.1.2.1.4.34.1.2
  1222.  * Description:
  1223. The IP address to which this entry's addressing information
  1224.             pertains.  The address type of this object is specified in
  1225.             ipAddressAddrType.
  1226.             Implementors need to be aware that if the size of
  1227.             ipAddressAddr exceeds 116 octets then OIDS of instances of
  1228.             columns in this row will have more than 128 sub-identifiers
  1229.             and cannot be accessed using SNMPv1, SNMPv2c or SNMPv3.
  1230.  *
  1231.  * Attributes:
  1232.  *   accessible 0     isscalar 0     enums  0      hasdefval 0
  1233.  *   readable   0     iscolumn 1     ranges 1      hashint   0
  1234.  *   settable   0
  1235.  *
  1236.  * Ranges:  0 - 255;
  1237.  *
  1238.  * Its syntax is InetAddress (based on perltype OCTETSTR)
  1239.  * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
  1240.  * This data type requires a length.  (Max 255)
  1241.  *
  1242.  *
  1243.  *
  1244.  * NOTE: NODE ipAddressAddr IS NOT ACCESSIBLE
  1245.  *
  1246.  *
  1247.  */
  1248. /**
  1249.  * check validity of ipAddressAddr index portion
  1250.  *
  1251.  * @retval MFD_SUCCESS   : the incoming value is legal
  1252.  * @retval MFD_BAD_VALUE : the incoming value is NOT legal
  1253.  *
  1254.  * @note this is not the place to do any checks for the sanity
  1255.  *       of multiple indexes. Those types of checks should be done in the
  1256.  *       ipAddressTable_validate_index() function.
  1257.  */
  1258. int
  1259. ipAddressAddr_check_index(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1260. {
  1261.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddr_check_index",
  1262.                 "calledn"));
  1263.     netsnmp_assert(NULL != rowreq_ctx);
  1264.     /*
  1265.      * TODO:426:M: |-> Check ipAddressTable index ipAddressAddr.
  1266.      * check that index value in the table context (rowreq_ctx)
  1267.      * for ipAddressAddr is legal.
  1268.      */
  1269.     switch (rowreq_ctx->tbl_idx.ipAddressAddrType) {
  1270.     case INETADDRESSTYPE_IPV4:
  1271.         if (4 != rowreq_ctx->tbl_idx.ipAddressAddr_len) {
  1272.             DEBUGMSGT(("ipAddressTable", "bad addr lenn"));
  1273.             return MFD_ERROR;
  1274.         }
  1275.         break;
  1276.     case INETADDRESSTYPE_IPV6:
  1277.             /** xxx-rks: allow 20? */
  1278.         if (16 != rowreq_ctx->tbl_idx.ipAddressAddr_len) {
  1279.             DEBUGMSGT(("ipAddressTable", "bad addr lenn"));
  1280.             return MFD_ERROR;
  1281.         }
  1282.         break;
  1283.     default:
  1284.         return MFD_ERROR;
  1285.     }
  1286.     return MFD_SUCCESS;         /* ipAddressAddr index ok */
  1287. }                               /* ipAddressAddr_check_index */
  1288. /*
  1289.  * TODO:440:M: Implement ipAddressTable node value checks.
  1290.  * TODO:450:M: Implement ipAddressTable undo functions.
  1291.  * TODO:460:M: Implement ipAddressTable set functions.
  1292.  * TODO:480:M: Implement ipAddressTable commit functions.
  1293.  */
  1294. /*---------------------------------------------------------------------
  1295.  * IP-MIB::ipAddressEntry.ipAddressIfIndex
  1296.  * ipAddressIfIndex is subid 3 of ipAddressEntry.
  1297.  * Its status is Current, and its access level is Create.
  1298.  * OID: .1.3.6.1.2.1.4.34.1.3
  1299.  * Description:
  1300. The index value which uniquely identifies the interface to
  1301.             which this entry is applicable.  The interface identified by
  1302.             a particular value of this index is the same interface as
  1303.             identified by the same value of the IF-MIB's ifIndex.
  1304.  *
  1305.  * Attributes:
  1306.  *   accessible 1     isscalar 0     enums  0      hasdefval 0
  1307.  *   readable   1     iscolumn 1     ranges 1      hashint   1
  1308.  *   settable   1
  1309.  *   hint: d
  1310.  *
  1311.  * Ranges:  1 - 2147483647;
  1312.  *
  1313.  * Its syntax is InterfaceIndex (based on perltype INTEGER32)
  1314.  * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
  1315.  */
  1316. /**
  1317.  * Check that the proposed new value is potentially valid.
  1318.  *
  1319.  * @param rowreq_ctx
  1320.  *        Pointer to the row request context.
  1321.  * @param ipAddressIfIndex_val
  1322.  *        A long containing the new value.
  1323.  *
  1324.  * @retval MFD_SUCCESS        : incoming value is legal
  1325.  * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
  1326.  * @retval MFD_NOT_VALID_EVER : incoming value is never valid
  1327.  *
  1328.  * This is the place to check for requirements that are not
  1329.  * expressed in the mib syntax (for example, a requirement that
  1330.  * is detailed in the description for an object).
  1331.  *
  1332.  * You should check that the requested change between the undo value and the
  1333.  * new value is legal (ie, the transistion from one value to another
  1334.  * is legal).
  1335.  *      
  1336.  *@note
  1337.  * This check is only to determine if the new value
  1338.  * is b potentially valid. This is the first check of many, and
  1339.  * is one of the simplest ones.
  1340.  * 
  1341.  *@note
  1342.  * this is not the place to do any checks for values
  1343.  * which depend on some other value in the mib. Those
  1344.  * types of checks should be done in the
  1345.  * ipAddressTable_check_dependencies() function.
  1346.  *
  1347.  * The following checks have already been done for you:
  1348.  *    The syntax is ASN_INTEGER
  1349.  *    The value is in (one of) the range set(s):  1 - 2147483647
  1350.  *
  1351.  * If there a no other checks you need to do, simply return MFD_SUCCESS.
  1352.  *
  1353.  */
  1354. int
  1355. ipAddressIfIndex_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1356.                              long ipAddressIfIndex_val)
  1357. {
  1358.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_check_value",
  1359.                 "calledn"));
  1360.     /** should never get a NULL pointer */
  1361.     netsnmp_assert(NULL != rowreq_ctx);
  1362.     /*
  1363.      * TODO:441:o: |-> Check for valid ipAddressIfIndex value.
  1364.      */
  1365.     /*
  1366.      * if the new value is the same as the old, accept it.
  1367.      */
  1368.     if (ipAddressIfIndex_val == rowreq_ctx->data->if_index)
  1369.         return MFD_SUCCESS;
  1370.     /*
  1371.      * currently don't support moving addresses between interfaces, so
  1372.      * if this isn't a new row, return error.
  1373.      */
  1374.     if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED)) {
  1375.         DEBUGMSGT(("ipAddressTable",
  1376.                    "changing ifIndex value not supportedn"));
  1377.         return MFD_NOT_VALID_EVER;
  1378.     }
  1379.     /*
  1380.      * find name for ifIndex
  1381.      */
  1382.     if (NULL == netsnmp_access_interface_name_find(ipAddressIfIndex_val)) {
  1383.         DEBUGMSGT(("ipAddressTable", "cant find name for index %dn",
  1384.                    ipAddressIfIndex_val));
  1385.         return MFD_NOT_VALID_NOW;
  1386.     }
  1387.     return MFD_SUCCESS;         /* ipAddressIfIndex value not illegal */
  1388. }                               /* ipAddressIfIndex_check_value */
  1389. /**
  1390.  * Save old value information
  1391.  *
  1392.  * @param rowreq_ctx
  1393.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  1394.  *
  1395.  * @retval MFD_SUCCESS : success
  1396.  * @retval MFD_ERROR   : error. set will fail.
  1397.  *
  1398.  * This function will be called after the table level undo setup function
  1399.  * ipAddressTable_undo_setup has been called.
  1400.  *
  1401.  *@note
  1402.  * this function will only be called if a new value is set for this column.
  1403.  *
  1404.  * If there is any setup specific to a particular column (e.g. allocating
  1405.  * memory for a string), you should do that setup in this function, so it
  1406.  * won't be done unless it is necessary.
  1407.  */
  1408. int
  1409. ipAddressIfIndex_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1410. {
  1411.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_undo_setup",
  1412.                 "calledn"));
  1413.     /** should never get a NULL pointer */
  1414.     netsnmp_assert(NULL != rowreq_ctx);
  1415.     /*
  1416.      * TODO:455:o: |-> Setup ipAddressIfIndex undo.
  1417.      */
  1418.     /*
  1419.      * handled in ipAddressTable_undo_setup
  1420.      */
  1421.     return MFD_SUCCESS;
  1422. }                               /* ipAddressIfIndex_undo_setup */
  1423. /**
  1424.  * Set the new value.
  1425.  *
  1426.  * @param rowreq_ctx
  1427.  *        Pointer to the users context. You should know how to
  1428.  *        manipulate the value from this object.
  1429.  * @param ipAddressIfIndex_val
  1430.  *        A long containing the new value.
  1431.  */
  1432. int
  1433. ipAddressIfIndex_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1434.                      long ipAddressIfIndex_val)
  1435. {
  1436.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_set",
  1437.                 "calledn"));
  1438.     /** should never get a NULL pointer */
  1439.     netsnmp_assert(NULL != rowreq_ctx);
  1440.     /*
  1441.      * TODO:461:M: |-> Set ipAddressIfIndex value.
  1442.      * set ipAddressIfIndex value in rowreq_ctx->data
  1443.      */
  1444.     if (rowreq_ctx->data->if_index != ipAddressIfIndex_val)
  1445.         rowreq_ctx->data->if_index = ipAddressIfIndex_val;
  1446.     else
  1447.         rowreq_ctx->column_set_flags &= ~FLAG_IPADDRESSIFINDEX;
  1448.     return MFD_SUCCESS;
  1449. }                               /* ipAddressIfIndex_set */
  1450. /**
  1451.  * undo the previous set.
  1452.  *
  1453.  * @param rowreq_ctx
  1454.  *        Pointer to the users context.
  1455.  */
  1456. int
  1457. ipAddressIfIndex_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1458. {
  1459.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressIfIndex_undo",
  1460.                 "calledn"));
  1461.     netsnmp_assert(NULL != rowreq_ctx);
  1462.     /*
  1463.      * TODO:456:o: |-> Clean up ipAddressIfIndex undo.
  1464.      */
  1465.     /*
  1466.      * copy ipAddressIfIndex data
  1467.      * set rowreq_ctx->data->ipAddressIfIndex from rowreq_ctx->undo->ipAddressIfIndex
  1468.      */
  1469.     rowreq_ctx->data->if_index = rowreq_ctx->undo->if_index;
  1470.     return MFD_SUCCESS;
  1471. }                               /* ipAddressIfIndex_undo */
  1472. /*---------------------------------------------------------------------
  1473.  * IP-MIB::ipAddressEntry.ipAddressType
  1474.  * ipAddressType is subid 4 of ipAddressEntry.
  1475.  * Its status is Current, and its access level is Create.
  1476.  * OID: .1.3.6.1.2.1.4.34.1.4
  1477.  * Description:
  1478. The type of address.  broadcast(3) is not a valid value for
  1479.             IPv6 addresses (RFC3513).  
  1480.  *
  1481.  * Attributes:
  1482.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  1483.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  1484.  *   settable   1
  1485.  *   defval: unicast
  1486.  *
  1487.  * Enum range: 2/8. Values:  unicast(1), anycast(2), broadcast(3)
  1488.  *
  1489.  * Its syntax is INTEGER (based on perltype INTEGER)
  1490.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  1491.  */
  1492. /**
  1493.  * Check that the proposed new value is potentially valid.
  1494.  *
  1495.  * @param rowreq_ctx
  1496.  *        Pointer to the row request context.
  1497.  * @param ipAddressType_val
  1498.  *        A long containing the new value.
  1499.  *
  1500.  * @retval MFD_SUCCESS        : incoming value is legal
  1501.  * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
  1502.  * @retval MFD_NOT_VALID_EVER : incoming value is never valid
  1503.  *
  1504.  * This is the place to check for requirements that are not
  1505.  * expressed in the mib syntax (for example, a requirement that
  1506.  * is detailed in the description for an object).
  1507.  *
  1508.  * You should check that the requested change between the undo value and the
  1509.  * new value is legal (ie, the transistion from one value to another
  1510.  * is legal).
  1511.  *      
  1512.  *@note
  1513.  * This check is only to determine if the new value
  1514.  * is b potentially valid. This is the first check of many, and
  1515.  * is one of the simplest ones.
  1516.  * 
  1517.  *@note
  1518.  * this is not the place to do any checks for values
  1519.  * which depend on some other value in the mib. Those
  1520.  * types of checks should be done in the
  1521.  * ipAddressTable_check_dependencies() function.
  1522.  *
  1523.  * The following checks have already been done for you:
  1524.  *    The syntax is ASN_INTEGER
  1525.  *    The value is one of  unicast(1), anycast(2), broadcast(3)
  1526.  *
  1527.  * If there a no other checks you need to do, simply return MFD_SUCCESS.
  1528.  *
  1529.  */
  1530. int
  1531. ipAddressType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1532.                           u_long ipAddressType_val)
  1533. {
  1534.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_check_value",
  1535.                 "calledn"));
  1536.     /** should never get a NULL pointer */
  1537.     netsnmp_assert(NULL != rowreq_ctx);
  1538.     /*
  1539.      * TODO:441:o: |-> Check for valid ipAddressType value.
  1540.      *
  1541.      * no support for anything but unicast yet
  1542.      */
  1543.     if (ipAddressType_val != IPADDRESSTYPE_UNICAST)
  1544.         return MFD_NOT_VALID_EVER;
  1545.     return MFD_SUCCESS;         /* ipAddressType value not illegal */
  1546. }                               /* ipAddressType_check_value */
  1547. /**
  1548.  * Save old value information
  1549.  *
  1550.  * @param rowreq_ctx
  1551.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  1552.  *
  1553.  * @retval MFD_SUCCESS : success
  1554.  * @retval MFD_ERROR   : error. set will fail.
  1555.  *
  1556.  * This function will be called after the table level undo setup function
  1557.  * ipAddressTable_undo_setup has been called.
  1558.  *
  1559.  *@note
  1560.  * this function will only be called if a new value is set for this column.
  1561.  *
  1562.  * If there is any setup specific to a particular column (e.g. allocating
  1563.  * memory for a string), you should do that setup in this function, so it
  1564.  * won't be done unless it is necessary.
  1565.  */
  1566. int
  1567. ipAddressType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1568. {
  1569.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_undo_setup",
  1570.                 "calledn"));
  1571.     /** should never get a NULL pointer */
  1572.     netsnmp_assert(NULL != rowreq_ctx);
  1573.     /*
  1574.      * TODO:455:o: |-> Setup ipAddressType undo.
  1575.      */
  1576.     /*
  1577.      * handled in ipAddressTable_undo_setup
  1578.      */
  1579.     return MFD_SUCCESS;
  1580. }                               /* ipAddressType_undo_setup */
  1581. /**
  1582.  * Set the new value.
  1583.  *
  1584.  * @param rowreq_ctx
  1585.  *        Pointer to the users context. You should know how to
  1586.  *        manipulate the value from this object.
  1587.  * @param ipAddressType_val
  1588.  *        A long containing the new value.
  1589.  */
  1590. int
  1591. ipAddressType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1592.                   u_long ipAddressType_val)
  1593. {
  1594.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_set", "calledn"));
  1595.     /** should never get a NULL pointer */
  1596.     netsnmp_assert(NULL != rowreq_ctx);
  1597.     /*
  1598.      * TODO:461:M: |-> Set ipAddressType value.
  1599.      * set ipAddressType value in rowreq_ctx->data
  1600.      */
  1601.     rowreq_ctx->data->ia_type = ipAddressType_val;
  1602.     return MFD_SUCCESS;
  1603. }                               /* ipAddressType_set */
  1604. /**
  1605.  * undo the previous set.
  1606.  *
  1607.  * @param rowreq_ctx
  1608.  *        Pointer to the users context.
  1609.  */
  1610. int
  1611. ipAddressType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1612. {
  1613.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressType_undo", "calledn"));
  1614.     netsnmp_assert(NULL != rowreq_ctx);
  1615.     /*
  1616.      * TODO:456:o: |-> Clean up ipAddressType undo.
  1617.      */
  1618.     /*
  1619.      * copy ipAddressType data
  1620.      * set rowreq_ctx->data->ipAddressType from rowreq_ctx->undo->ipAddressType
  1621.      */
  1622.     rowreq_ctx->data->ia_type = rowreq_ctx->undo->ia_type;
  1623.     return MFD_SUCCESS;
  1624. }                               /* ipAddressType_undo */
  1625. /*---------------------------------------------------------------------
  1626.  * IP-MIB::ipAddressEntry.ipAddressStatus
  1627.  * ipAddressStatus is subid 7 of ipAddressEntry.
  1628.  * Its status is Current, and its access level is Create.
  1629.  * OID: .1.3.6.1.2.1.4.34.1.7
  1630.  * Description:
  1631. The status of the address, describing if the address can be
  1632.             used for communication.
  1633.             In the absence of other information, an IPv4 address is
  1634.             always preferred(1).
  1635.  *
  1636.  * Attributes:
  1637.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  1638.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  1639.  *   settable   1
  1640.  *   defval: preferred
  1641.  *
  1642.  * Enum range: 5/8. Values:  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
  1643.  *
  1644.  * Its syntax is IpAddressStatusTC (based on perltype INTEGER)
  1645.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  1646.  */
  1647. /**
  1648.  * Check that the proposed new value is potentially valid.
  1649.  *
  1650.  * @param rowreq_ctx
  1651.  *        Pointer to the row request context.
  1652.  * @param ipAddressStatus_val
  1653.  *        A long containing the new value.
  1654.  *
  1655.  * @retval MFD_SUCCESS        : incoming value is legal
  1656.  * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
  1657.  * @retval MFD_NOT_VALID_EVER : incoming value is never valid
  1658.  *
  1659.  * This is the place to check for requirements that are not
  1660.  * expressed in the mib syntax (for example, a requirement that
  1661.  * is detailed in the description for an object).
  1662.  *
  1663.  * You should check that the requested change between the undo value and the
  1664.  * new value is legal (ie, the transistion from one value to another
  1665.  * is legal).
  1666.  *      
  1667.  *@note
  1668.  * This check is only to determine if the new value
  1669.  * is b potentially valid. This is the first check of many, and
  1670.  * is one of the simplest ones.
  1671.  * 
  1672.  *@note
  1673.  * this is not the place to do any checks for values
  1674.  * which depend on some other value in the mib. Those
  1675.  * types of checks should be done in the
  1676.  * ipAddressTable_check_dependencies() function.
  1677.  *
  1678.  * The following checks have already been done for you:
  1679.  *    The syntax is ASN_INTEGER
  1680.  *    The value is one of  preferred(1), invalid(3), inaccessible(4), unknown(5), tentative(6), duplicate(7)
  1681.  *
  1682.  * If there a no other checks you need to do, simply return MFD_SUCCESS.
  1683.  *
  1684.  */
  1685. int
  1686. ipAddressStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1687.                             u_long ipAddressStatus_val)
  1688. {
  1689.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_check_value",
  1690.                 "calledn"));
  1691.     /** should never get a NULL pointer */
  1692.     netsnmp_assert(NULL != rowreq_ctx);
  1693.     /*
  1694.      * TODO:441:o: |-> Check for valid ipAddressStatus value.
  1695.      *
  1696.      * nothing but preferred supported yet
  1697.      */
  1698.     if (IPADDRESSSTATUSTC_PREFERRED != ipAddressStatus_val)
  1699.         return MFD_NOT_VALID_EVER;
  1700.     return MFD_SUCCESS;         /* ipAddressStatus value not illegal */
  1701. }                               /* ipAddressStatus_check_value */
  1702. /**
  1703.  * Save old value information
  1704.  *
  1705.  * @param rowreq_ctx
  1706.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  1707.  *
  1708.  * @retval MFD_SUCCESS : success
  1709.  * @retval MFD_ERROR   : error. set will fail.
  1710.  *
  1711.  * This function will be called after the table level undo setup function
  1712.  * ipAddressTable_undo_setup has been called.
  1713.  *
  1714.  *@note
  1715.  * this function will only be called if a new value is set for this column.
  1716.  *
  1717.  * If there is any setup specific to a particular column (e.g. allocating
  1718.  * memory for a string), you should do that setup in this function, so it
  1719.  * won't be done unless it is necessary.
  1720.  */
  1721. int
  1722. ipAddressStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1723. {
  1724.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_undo_setup",
  1725.                 "calledn"));
  1726.     /** should never get a NULL pointer */
  1727.     netsnmp_assert(NULL != rowreq_ctx);
  1728.     /*
  1729.      * TODO:455:o: |-> Setup ipAddressStatus undo.
  1730.      */
  1731.     /*
  1732.      * handled in ipAddressTable_undo_setup
  1733.      */
  1734.     return MFD_SUCCESS;
  1735. }                               /* ipAddressStatus_undo_setup */
  1736. /**
  1737.  * Set the new value.
  1738.  *
  1739.  * @param rowreq_ctx
  1740.  *        Pointer to the users context. You should know how to
  1741.  *        manipulate the value from this object.
  1742.  * @param ipAddressStatus_val
  1743.  *        A long containing the new value.
  1744.  */
  1745. int
  1746. ipAddressStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1747.                     u_long ipAddressStatus_val)
  1748. {
  1749.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_set", "calledn"));
  1750.     /** should never get a NULL pointer */
  1751.     netsnmp_assert(NULL != rowreq_ctx);
  1752.     /*
  1753.      * TODO:461:M: |-> Set ipAddressStatus value.
  1754.      * set ipAddressStatus value in rowreq_ctx->data
  1755.      */
  1756.     rowreq_ctx->data->ia_status = ipAddressStatus_val;
  1757.     return MFD_SUCCESS;
  1758. }                               /* ipAddressStatus_set */
  1759. /**
  1760.  * undo the previous set.
  1761.  *
  1762.  * @param rowreq_ctx
  1763.  *        Pointer to the users context.
  1764.  */
  1765. int
  1766. ipAddressStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1767. {
  1768.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStatus_undo",
  1769.                 "calledn"));
  1770.     netsnmp_assert(NULL != rowreq_ctx);
  1771.     /*
  1772.      * TODO:456:o: |-> Clean up ipAddressStatus undo.
  1773.      */
  1774.     /*
  1775.      * copy ipAddressStatus data
  1776.      * set rowreq_ctx->data->ipAddressStatus from rowreq_ctx->undo->ipAddressStatus
  1777.      */
  1778.     rowreq_ctx->data->ia_status = rowreq_ctx->undo->ia_status;
  1779.     return MFD_SUCCESS;
  1780. }                               /* ipAddressStatus_undo */
  1781. /*---------------------------------------------------------------------
  1782.  * IP-MIB::ipAddressEntry.ipAddressRowStatus
  1783.  * ipAddressRowStatus is subid 10 of ipAddressEntry.
  1784.  * Its status is Current, and its access level is Create.
  1785.  * OID: .1.3.6.1.2.1.4.34.1.10
  1786.  * Description:
  1787. The status of this conceptual row.
  1788.             The RowStatus TC requires that this DESCRIPTION clause
  1789.             states under which circumstances other objects in this row
  1790.             can be modified.  The value of this object has no effect on
  1791.             whether other objects in this conceptual row can be
  1792.             modified.
  1793.             A conceptual row can not be made active until the
  1794.             ipAddressIfIndex has been set to a valid index.  
  1795.  *
  1796.  * Attributes:
  1797.  *   accessible 1     isscalar 0     enums  1      hasdefval 0
  1798.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  1799.  *   settable   1
  1800.  *
  1801.  * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
  1802.  *
  1803.  * Its syntax is RowStatus (based on perltype INTEGER)
  1804.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  1805.  */
  1806. /**
  1807.  * Check that the proposed new value is potentially valid.
  1808.  *
  1809.  * @param rowreq_ctx
  1810.  *        Pointer to the row request context.
  1811.  * @param ipAddressRowStatus_val
  1812.  *        A long containing the new value.
  1813.  *
  1814.  * @retval MFD_SUCCESS        : incoming value is legal
  1815.  * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
  1816.  * @retval MFD_NOT_VALID_EVER : incoming value is never valid
  1817.  *
  1818.  * This is the place to check for requirements that are not
  1819.  * expressed in the mib syntax (for example, a requirement that
  1820.  * is detailed in the description for an object).
  1821.  *
  1822.  * You should check that the requested change between the undo value and the
  1823.  * new value is legal (ie, the transistion from one value to another
  1824.  * is legal).
  1825.  *      
  1826.  *@note
  1827.  * This check is only to determine if the new value
  1828.  * is b potentially valid. This is the first check of many, and
  1829.  * is one of the simplest ones.
  1830.  * 
  1831.  *@note
  1832.  * this is not the place to do any checks for values
  1833.  * which depend on some other value in the mib. Those
  1834.  * types of checks should be done in the
  1835.  * ipAddressTable_check_dependencies() function.
  1836.  *
  1837.  * The following checks have already been done for you:
  1838.  *    The syntax is ASN_INTEGER
  1839.  *    The value is one of  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
  1840.  *
  1841.  * If there a no other checks you need to do, simply return MFD_SUCCESS.
  1842.  *
  1843.  */
  1844. int
  1845. ipAddressRowStatus_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1846.                                u_long ipAddressRowStatus_val)
  1847. {
  1848.     int             rc;
  1849.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_check_value",
  1850.                 "calledn"));
  1851.     /** should never get a NULL pointer */
  1852.     netsnmp_assert(NULL != rowreq_ctx);
  1853.     /*
  1854.      * TODO:441:o: |-> Check for valid ipAddressRowStatus value.
  1855.      *
  1856.      * don't support createAndWait
  1857.      * check for valid RowStatus transition (old, new)
  1858.      */
  1859.     if (ROWSTATUS_CREATEANDWAIT == ipAddressRowStatus_val) {
  1860.         DEBUGMSGTL(("ipAddressTable", "createAndWait not supportedn"));
  1861.         return MFD_NOT_VALID_EVER;
  1862.     }
  1863.     rc = check_rowstatus_transition(rowreq_ctx->ipAddressRowStatus,
  1864.                                     ipAddressRowStatus_val);
  1865.     if (MFD_SUCCESS != rc) {
  1866.         DEBUGMSGTL(("ipAddressTable", "row status transition from %d to %dn",
  1867.                     rowreq_ctx->ipAddressRowStatus, ipAddressRowStatus_val));
  1868.         return rc;
  1869.     }
  1870.     return MFD_SUCCESS;         /* ipAddressRowStatus value not illegal */
  1871. }                               /* ipAddressRowStatus_check_value */
  1872. /**
  1873.  * Save old value information
  1874.  *
  1875.  * @param rowreq_ctx
  1876.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  1877.  *
  1878.  * @retval MFD_SUCCESS : success
  1879.  * @retval MFD_ERROR   : error. set will fail.
  1880.  *
  1881.  * This function will be called after the table level undo setup function
  1882.  * ipAddressTable_undo_setup has been called.
  1883.  *
  1884.  *@note
  1885.  * this function will only be called if a new value is set for this column.
  1886.  *
  1887.  * If there is any setup specific to a particular column (e.g. allocating
  1888.  * memory for a string), you should do that setup in this function, so it
  1889.  * won't be done unless it is necessary.
  1890.  */
  1891. int
  1892. ipAddressRowStatus_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1893. {
  1894.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_undo_setup",
  1895.                 "calledn"));
  1896.     /** should never get a NULL pointer */
  1897.     netsnmp_assert(NULL != rowreq_ctx);
  1898.     /*
  1899.      * TODO:455:o: |-> Setup ipAddressRowStatus undo.
  1900.      */
  1901.     /*
  1902.      * handled in ipAddressTable_undo_setup
  1903.      */
  1904.     return MFD_SUCCESS;
  1905. }                               /* ipAddressRowStatus_undo_setup */
  1906. /**
  1907.  * Set the new value.
  1908.  *
  1909.  * @param rowreq_ctx
  1910.  *        Pointer to the users context. You should know how to
  1911.  *        manipulate the value from this object.
  1912.  * @param ipAddressRowStatus_val
  1913.  *        A long containing the new value.
  1914.  */
  1915. int
  1916. ipAddressRowStatus_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  1917.                        u_long ipAddressRowStatus_val)
  1918. {
  1919.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_set",
  1920.                 "calledn"));
  1921.     /** should never get a NULL pointer */
  1922.     netsnmp_assert(NULL != rowreq_ctx);
  1923.     /*
  1924.      * TODO:461:M: |-> Set ipAddressRowStatus value.
  1925.      * set ipAddressRowStatus value in rowreq_ctx->data
  1926.      */
  1927.     rowreq_ctx->ipAddressRowStatus = ipAddressRowStatus_val;
  1928.     return MFD_SUCCESS;
  1929. }                               /* ipAddressRowStatus_set */
  1930. /**
  1931.  * undo the previous set.
  1932.  *
  1933.  * @param rowreq_ctx
  1934.  *        Pointer to the users context.
  1935.  */
  1936. int
  1937. ipAddressRowStatus_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
  1938. {
  1939.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressRowStatus_undo",
  1940.                 "calledn"));
  1941.     netsnmp_assert(NULL != rowreq_ctx);
  1942.     /*
  1943.      * TODO:456:o: |-> Clean up ipAddressRowStatus undo.
  1944.      */
  1945.     /*
  1946.      * copy ipAddressRowStatus data
  1947.      * set rowreq_ctx->data->ipAddressRowStatus from rowreq_ctx->undo->ipAddressRowStatus
  1948.      */
  1949.     rowreq_ctx->ipAddressRowStatus = rowreq_ctx->ipAddressRowStatus_undo;
  1950.     return MFD_SUCCESS;
  1951. }                               /* ipAddressRowStatus_undo */
  1952. /*---------------------------------------------------------------------
  1953.  * IP-MIB::ipAddressEntry.ipAddressStorageType
  1954.  * ipAddressStorageType is subid 11 of ipAddressEntry.
  1955.  * Its status is Current, and its access level is Create.
  1956.  * OID: .1.3.6.1.2.1.4.34.1.11
  1957.  * Description:
  1958. The storage type for this conceptual row.  If this object
  1959.             has a value of 'permanent' then no other objects are
  1960.             required to be able to be modified.
  1961.  *
  1962.  * Attributes:
  1963.  *   accessible 1     isscalar 0     enums  1      hasdefval 1
  1964.  *   readable   1     iscolumn 1     ranges 0      hashint   0
  1965.  *   settable   1
  1966.  *   defval: volatile
  1967.  *
  1968.  * Enum range: 4/8. Values:  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
  1969.  *
  1970.  * Its syntax is StorageType (based on perltype INTEGER)
  1971.  * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
  1972.  */
  1973. /**
  1974.  * Check that the proposed new value is potentially valid.
  1975.  *
  1976.  * @param rowreq_ctx
  1977.  *        Pointer to the row request context.
  1978.  * @param ipAddressStorageType_val
  1979.  *        A long containing the new value.
  1980.  *
  1981.  * @retval MFD_SUCCESS        : incoming value is legal
  1982.  * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
  1983.  * @retval MFD_NOT_VALID_EVER : incoming value is never valid
  1984.  *
  1985.  * This is the place to check for requirements that are not
  1986.  * expressed in the mib syntax (for example, a requirement that
  1987.  * is detailed in the description for an object).
  1988.  *
  1989.  * You should check that the requested change between the undo value and the
  1990.  * new value is legal (ie, the transistion from one value to another
  1991.  * is legal).
  1992.  *      
  1993.  *@note
  1994.  * This check is only to determine if the new value
  1995.  * is b potentially valid. This is the first check of many, and
  1996.  * is one of the simplest ones.
  1997.  * 
  1998.  *@note
  1999.  * this is not the place to do any checks for values
  2000.  * which depend on some other value in the mib. Those
  2001.  * types of checks should be done in the
  2002.  * ipAddressTable_check_dependencies() function.
  2003.  *
  2004.  * The following checks have already been done for you:
  2005.  *    The syntax is ASN_INTEGER
  2006.  *    The value is one of  other(1), volatile(2), nonVolatile(3), permanent(4), readOnly(5)
  2007.  *
  2008.  * If there a no other checks you need to do, simply return MFD_SUCCESS.
  2009.  *
  2010.  */
  2011. int
  2012. ipAddressStorageType_check_value(ipAddressTable_rowreq_ctx * rowreq_ctx,
  2013.                                  u_long ipAddressStorageType_val)
  2014. {
  2015.     int             rc;
  2016.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_check_value",
  2017.                 "calledn"));
  2018.     /** should never get a NULL pointer */
  2019.     netsnmp_assert(NULL != rowreq_ctx);
  2020.     /*
  2021.      * TODO:441:o: |-> Check for valid ipAddressStorageType value.
  2022.      */
  2023.     /*
  2024.      * since I don't know how the various operating systems
  2025.      * deal with ip addresses, and whether or not changes will
  2026.      * be saved on reboot, so don't allow rows to be set to anything
  2027.      * but volatile. I'd prefer other, but since the default for
  2028.      * new rows, per the mib, is volatile...
  2029.      *
  2030.      * If some industrious soul would like
  2031.      * non-volaltile support, the first would need to 
  2032.      *   add it in  the data access code for their os
  2033.      *   define a flag bit for volatile/permanent/readonly
  2034.      *   set the bit in data access
  2035.      *   copy the bit to a new var in the rowreq_ctx (see _add_new_entry)
  2036.      *        with a default of volatile (for os' w/out nonvolatile support)
  2037.      *   update this code to use new flag
  2038.      */
  2039.     if (STORAGETYPE_VOLATILE != ipAddressStorageType_val)
  2040.         return MFD_NOT_VALID_EVER;
  2041.     /*
  2042.      * check for valid StorageType transition (old, new)
  2043.      */
  2044.     rc = check_storage_transition(rowreq_ctx->data->ia_storagetype,
  2045.                                   ipAddressStorageType_val);
  2046.     if (MFD_SUCCESS != rc)
  2047.         return rc;
  2048.     return MFD_SUCCESS;         /* ipAddressStorageType value not illegal */
  2049. }                               /* ipAddressStorageType_check_value */
  2050. /**
  2051.  * Save old value information
  2052.  *
  2053.  * @param rowreq_ctx
  2054.  *        Pointer to the table context (ipAddressTable_rowreq_ctx)
  2055.  *
  2056.  * @retval MFD_SUCCESS : success
  2057.  * @retval MFD_ERROR   : error. set will fail.
  2058.  *
  2059.  * This function will be called after the table level undo setup function
  2060.  * ipAddressTable_undo_setup has been called.
  2061.  *
  2062.  *@note
  2063.  * this function will only be called if a new value is set for this column.
  2064.  *
  2065.  * If there is any setup specific to a particular column (e.g. allocating
  2066.  * memory for a string), you should do that setup in this function, so it
  2067.  * won't be done unless it is necessary.
  2068.  */
  2069. int
  2070. ipAddressStorageType_undo_setup(ipAddressTable_rowreq_ctx * rowreq_ctx)
  2071. {
  2072.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_undo_setup",
  2073.                 "calledn"));
  2074.     /** should never get a NULL pointer */
  2075.     netsnmp_assert(NULL != rowreq_ctx);
  2076.     /*
  2077.      * TODO:455:o: |-> Setup ipAddressStorageType undo.
  2078.      */
  2079.     /*
  2080.      * handled in ipAddressTable_undo_setup
  2081.      */
  2082.     return MFD_SUCCESS;
  2083. }                               /* ipAddressStorageType_undo_setup */
  2084. /**
  2085.  * Set the new value.
  2086.  *
  2087.  * @param rowreq_ctx
  2088.  *        Pointer to the users context. You should know how to
  2089.  *        manipulate the value from this object.
  2090.  * @param ipAddressStorageType_val
  2091.  *        A long containing the new value.
  2092.  */
  2093. int
  2094. ipAddressStorageType_set(ipAddressTable_rowreq_ctx * rowreq_ctx,
  2095.                          u_long ipAddressStorageType_val)
  2096. {
  2097.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_set",
  2098.                 "calledn"));
  2099.     /** should never get a NULL pointer */
  2100.     netsnmp_assert(NULL != rowreq_ctx);
  2101.     /*
  2102.      * TODO:461:M: |-> Set ipAddressStorageType value.
  2103.      * set ipAddressStorageType value in rowreq_ctx->data
  2104.      */
  2105.     rowreq_ctx->data->ia_storagetype = ipAddressStorageType_val;
  2106.     return MFD_SUCCESS;
  2107. }                               /* ipAddressStorageType_set */
  2108. /**
  2109.  * undo the previous set.
  2110.  *
  2111.  * @param rowreq_ctx
  2112.  *        Pointer to the users context.
  2113.  */
  2114. int
  2115. ipAddressStorageType_undo(ipAddressTable_rowreq_ctx * rowreq_ctx)
  2116. {
  2117.     DEBUGMSGTL(("verbose:ipAddressTable:ipAddressStorageType_undo",
  2118.                 "calledn"));
  2119.     netsnmp_assert(NULL != rowreq_ctx);
  2120.     /*
  2121.      * TODO:456:o: |-> Clean up ipAddressStorageType undo.
  2122.      */
  2123.     /*
  2124.      * copy ipAddressStorageType data
  2125.      * set rowreq_ctx->data->ipAddressStorageType from rowreq_ctx->undo->ipAddressStorageType
  2126.      */
  2127.     rowreq_ctx->data->ia_storagetype = rowreq_ctx->undo->ia_storagetype;
  2128.     return MFD_SUCCESS;
  2129. }                               /* ipAddressStorageType_undo */
  2130. /**
  2131.  * check dependencies
  2132.  *
  2133.  * This is useful for for tables which have dependencies between columns
  2134.  * (or rows, or tables). For example, two columns allocating a percentage
  2135.  * of something add up 100%.
  2136.  *
  2137.  * Should you need different behavior depending on which columns were
  2138.  * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
  2139.  * set. The definitions for the FLAG_* bits can be found in
  2140.  * ipAddressTable.h.
  2141.  * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
  2142.  *
  2143.  * @retval MFD_SUCCESS all the changes to the row are legal
  2144.  * @retval MFD_ERROR   one or more changes are not legal
  2145.  *
  2146.  * (see README-table-ipAddressTable if you don't have dependencies)
  2147.  */
  2148. int
  2149. ipAddressTable_check_dependencies(ipAddressTable_rowreq_ctx * rowreq_ctx)
  2150. {
  2151.     int             rc = MFD_SUCCESS;
  2152.     DEBUGMSGTL(("internal:ipAddressTable:ipAddressTable_check_dependencies", "calledn"));
  2153.     netsnmp_assert(NULL != rowreq_ctx);
  2154.     /*
  2155.      * TODO:470:o: Check ipAddressTable row dependencies.
  2156.      * check that all new value are legal and consistent with each other
  2157.      */
  2158.     /*
  2159.      * check RowStatus dependencies
  2160.      */
  2161.     if (rowreq_ctx->column_set_flags & FLAG_IPADDRESSROWSTATUS) {
  2162.         /*
  2163.          * row creation requirements
  2164.          */
  2165.         if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
  2166.             if (ROWSTATUS_CREATEANDGO == rowreq_ctx->ipAddressRowStatus) {
  2167.                 if (rowreq_ctx->column_set_flags !=
  2168.                     IPADDRESSTABLE_REQUIRED_COLS) {
  2169.                     DEBUGMSGTL(("ipAddressTable",
  2170.                                 "required columns missingn"));
  2171.                     return MFD_CANNOT_CREATE_NOW;
  2172.                 }
  2173.             }
  2174.         } /* row creation */
  2175.         else {
  2176.             /*
  2177.              * row change requirements
  2178.              */
  2179.             /*
  2180.              * don't allow a destroy if any other value was changed, since
  2181.              * that might call data access routines with bad info.
  2182.              *
  2183.              * you may or may not require the row be notInService before it
  2184.              * can be destroyed.
  2185.              */
  2186.             if (ROWSTATUS_DESTROY == rowreq_ctx->ipAddressRowStatus) {
  2187.                 if (rowreq_ctx->
  2188.                     column_set_flags & ~FLAG_IPADDRESSROWSTATUS) {
  2189.                     DEBUGMSGTL(("ipAddressTable",
  2190.                                 "destroy must be only varbind for rown"));
  2191.                     return MFD_NOT_VALID_NOW;
  2192.                 }
  2193.             }                   /* row destroy */
  2194.         }                       /* row change */
  2195.     } else {
  2196.         /*
  2197.          * must have row status to create a row
  2198.          */
  2199.         if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
  2200.             DEBUGMSGTL(("ipAddressTable",
  2201.                         "must use RowStatus to create rowsn"));
  2202.             return MFD_CANNOT_CREATE_NOW;
  2203.         }
  2204.     }                           /* row status not set */
  2205.     return rc;
  2206. }                               /* ipAddressTable_check_dependencies */
  2207. /** @} */
  2208. /** @{ */