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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Ipaddress MIB architecture support
  3.  *
  4.  * $Id: ipaddress_common.c,v 1.7.2.1 2005/02/08 21:58:06 nba Exp $
  5.  */
  6. #include <net-snmp/net-snmp-config.h>
  7. #include <net-snmp/net-snmp-includes.h>
  8. #include <net-snmp/agent/net-snmp-agent-includes.h>
  9. #include <net-snmp/data_access/ipaddress.h>
  10. #include <net-snmp/data_access/interface.h>
  11. #include "ip-mib/ipAddressTable/ipAddressTable_constants.h"
  12. /**---------------------------------------------------------------------*/
  13. /*
  14.  * local static prototypes
  15.  */
  16. static int _access_ipaddress_entry_compare_addr(const void *lhs,
  17.                                                 const void *rhs);
  18. static void _access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry,
  19.                                             void *unused);
  20. /**---------------------------------------------------------------------*/
  21. /*
  22.  * external per-architecture functions prototypes
  23.  *
  24.  * These shouldn't be called by the general public, so they aren't in
  25.  * the header file.
  26.  */
  27. extern int
  28. netsnmp_arch_ipaddress_container_load(netsnmp_container* container,
  29.                                       u_int load_flags);
  30. extern int
  31. netsnmp_arch_ipaddress_entry_init(netsnmp_ipaddress_entry *entry);
  32. extern int
  33. netsnmp_arch_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
  34.                                   netsnmp_ipaddress_entry *rhs);
  35. extern void
  36. netsnmp_arch_ipaddress_entry_cleanup(netsnmp_ipaddress_entry *entry);
  37. extern int
  38. netsnmp_arch_ipaddress_create(netsnmp_ipaddress_entry *entry);
  39. extern int
  40. netsnmp_arch_ipaddress_delete(netsnmp_ipaddress_entry *entry);
  41. /**---------------------------------------------------------------------*/
  42. /*
  43.  * container functions
  44.  */
  45. /**
  46.  */
  47. netsnmp_container *
  48. netsnmp_access_ipaddress_container_init(u_int flags)
  49. {
  50.     netsnmp_container *container1;
  51.     DEBUGMSGTL(("access:ipaddress:container", "initn"));
  52.     /*
  53.      * create the containers. one indexed by ifIndex, the other
  54.      * indexed by ifName.
  55.      */
  56.     container1 = netsnmp_container_find("access_ipaddress:table_container");
  57.     if (NULL == container1) {
  58.         snmp_log(LOG_ERR, "ipaddress primary container not foundn");
  59.         return NULL;
  60.     }
  61.     container1->container_name = strdup("ia_index");
  62.     if (flags & NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR) {
  63.         netsnmp_container *container2 =
  64.             netsnmp_container_find("ipaddress_addr:access_ipaddress:table_container");
  65.         if (NULL == container2) {
  66.             snmp_log(LOG_ERR, "ipaddress secondary container not foundn");
  67.             CONTAINER_FREE(container1);
  68.             return NULL;
  69.         }
  70.         
  71.         container2->compare = _access_ipaddress_entry_compare_addr;
  72.         container2->container_name = strdup("ia_addr");
  73.         
  74.         netsnmp_container_add_index(container1, container2);
  75.     }
  76.     return container1;
  77. }
  78. /**
  79.  * @retval NULL  error
  80.  * @retval !NULL pointer to container
  81.  */
  82. netsnmp_container*
  83. netsnmp_access_ipaddress_container_load(netsnmp_container* container, u_int load_flags)
  84. {
  85.     int rc;
  86.     DEBUGMSGTL(("access:ipaddress:container", "loadn"));
  87.     if (NULL == container)
  88.         container = netsnmp_access_ipaddress_container_init(load_flags);
  89.     if (NULL == container) {
  90.         snmp_log(LOG_ERR, "no container specified/found for access_ipaddressn");
  91.         return NULL;
  92.     }
  93.     rc =  netsnmp_arch_ipaddress_container_load(container, load_flags);
  94.     if (0 != rc) {
  95.         netsnmp_access_ipaddress_container_free(container,
  96.                                                 NETSNMP_ACCESS_IPADDRESS_FREE_NOFLAGS);
  97.         container = NULL;
  98.     }
  99.     return container;
  100. }
  101. void
  102. netsnmp_access_ipaddress_container_free(netsnmp_container *container, u_int free_flags)
  103. {
  104.     DEBUGMSGTL(("access:ipaddress:container", "freen"));
  105.     if (NULL == container) {
  106.         snmp_log(LOG_ERR, "invalid container for netsnmp_access_ipaddress_freen");
  107.         return;
  108.     }
  109.     if(! (free_flags & NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR)) {
  110.         /*
  111.          * free all items.
  112.          */
  113.         CONTAINER_CLEAR(container,
  114.                         (netsnmp_container_obj_func*)_access_ipaddress_entry_release,
  115.                         NULL);
  116.     }
  117.     CONTAINER_FREE(container);
  118. }
  119. /**---------------------------------------------------------------------*/
  120. /*
  121.  * ipaddress_entry functions
  122.  */
  123. /**
  124.  */
  125. /**
  126.  */
  127. netsnmp_ipaddress_entry *
  128. netsnmp_access_ipaddress_entry_create(void)
  129. {
  130.     netsnmp_ipaddress_entry *entry =
  131.         SNMP_MALLOC_TYPEDEF(netsnmp_ipaddress_entry);
  132.     int rc = 0;
  133.     entry->oid_index.len = 1;
  134.     entry->oid_index.oids = &entry->ns_ia_index;
  135.     /*
  136.      * set up defaults
  137.      */
  138.     entry->ia_type = IPADDRESSTYPE_UNICAST;
  139.     entry->ia_status = IPADDRESSSTATUSTC_PREFERRED;
  140.     entry->ia_storagetype = STORAGETYPE_VOLATILE;
  141.     rc = netsnmp_arch_ipaddress_entry_init(entry);
  142.     if (SNMP_ERR_NOERROR != rc) {
  143.         DEBUGMSGT(("access:ipaddress:create","error %d in arch initn"));
  144.         netsnmp_access_ipaddress_entry_free(entry);
  145.     }
  146.     return entry;
  147. }
  148. /**
  149.  */
  150. void
  151. netsnmp_access_ipaddress_entry_free(netsnmp_ipaddress_entry * entry)
  152. {
  153.     if (NULL == entry)
  154.         return;
  155.     if (NULL != entry->ia_prefix_oid)
  156.         free(entry->ia_prefix_oid);
  157.     if (NULL != entry->arch_data)
  158.         netsnmp_arch_ipaddress_entry_cleanup(entry);
  159.     free(entry);
  160. }
  161. /**
  162.  * update underlying data store (kernel) for entry
  163.  *
  164.  * @retval  0 : success
  165.  * @retval -1 : error
  166.  */
  167. int
  168. netsnmp_access_ipaddress_entry_set(netsnmp_ipaddress_entry * entry)
  169. {
  170.     int rc = SNMP_ERR_NOERROR;
  171.     if (NULL == entry) {
  172.         netsnmp_assert(NULL != entry);
  173.         return -1;
  174.     }
  175.     
  176.     /*
  177.      * make sure interface and ifIndex match up
  178.      */
  179.     if (NULL == netsnmp_access_interface_name_find(entry->if_index)) {
  180.         DEBUGMSGT(("access:ipaddress:set", "cant find name for index %dn",
  181.                   entry->if_index));
  182.         return -1;
  183.     }
  184.     /*
  185.      * don't support non-volatile yet
  186.      */
  187.     if (STORAGETYPE_VOLATILE != entry->ia_storagetype) {
  188.         DEBUGMSGT(("access:ipaddress:set",
  189.                    "non-volatile storagetypes unsupportedn"));
  190.         return -1;
  191.     }
  192.     /*
  193.      *
  194.      */
  195.     rc = -1;
  196.     if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CREATE) {
  197.         rc = netsnmp_arch_ipaddress_create(entry);
  198.     }
  199.     else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CHANGE) {
  200.     }
  201.     else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_DELETE) {
  202.         rc = netsnmp_arch_ipaddress_delete(entry);
  203.     }
  204.     else {
  205.         snmp_log(LOG_ERR,"netsnmp_access_ipaddress_entry_set with no moden");
  206.         netsnmp_assert("ipaddress_entry_set" == "unknown mode"); 
  207.         rc = -1;
  208.     }
  209.     
  210.     return rc;
  211. }
  212. /**
  213.  * update an old ipaddress_entry from a new one
  214.  *
  215.  * @note: only mib related items are compared. Internal objects
  216.  * such as oid_index, ns_ia_index and flags are not compared.
  217.  *
  218.  * @retval -1  : error
  219.  * @retval >=0 : number of fields updated
  220.  */
  221. int
  222. netsnmp_access_ipaddress_entry_update(netsnmp_ipaddress_entry *lhs,
  223.                                       netsnmp_ipaddress_entry *rhs)
  224. {
  225.     int rc, changed = 0;
  226.     /*
  227.      * do any memory allocations first, using temp vars, so a failure can
  228.      * return w/out chaning lhs entry. length is dealt with right afterwards.
  229.      */
  230.     if (lhs->ia_prefix_oid != rhs->ia_prefix_oid) {
  231.         oid *tmp_oid;
  232.         if (NULL != rhs->ia_prefix_oid) {
  233.             int tmp_len = rhs->ia_prefix_oid_len * sizeof(oid);
  234.             tmp_oid = malloc(tmp_len);
  235.             if (NULL == tmp_oid) {
  236.                 snmp_log(LOG_ERR, "malloc failedn");
  237.                 return -1;
  238.             }
  239.             memcpy(tmp_oid,rhs->ia_prefix_oid, tmp_len);
  240.         }
  241.         else
  242.             tmp_oid = NULL;
  243.         if (NULL != lhs->ia_prefix_oid)
  244.             SNMP_FREE(lhs->ia_prefix_oid);
  245.         lhs->ia_prefix_oid = tmp_oid;
  246.         ++changed;
  247.     }
  248.     if (lhs->ia_prefix_oid_len != rhs->ia_prefix_oid_len) {
  249.         ++changed;
  250.         lhs->ia_prefix_oid_len = rhs->ia_prefix_oid_len;
  251.     }
  252.     /*
  253.      * copy arch stuff. we don't care if it changed
  254.      */
  255.     rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
  256.     if (0 != rc) {
  257.         snmp_log(LOG_ERR,"arch ipaddress copy failedn");
  258.         return -1;
  259.     }
  260.     if (lhs->if_index != rhs->if_index) {
  261.         ++changed;
  262.         lhs->if_index = rhs->if_index;
  263.     }
  264.     if (lhs->ia_storagetype != rhs->ia_storagetype) {
  265.         ++changed;
  266.         lhs->ia_storagetype = rhs->ia_storagetype;
  267.     }
  268.     if (lhs->ia_address_len != rhs->ia_address_len) {
  269.         changed += 2;
  270.         lhs->ia_address_len = rhs->ia_address_len;
  271.         memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
  272.     }
  273.     else if (memcmp(lhs->ia_address, rhs->ia_address, rhs->ia_address_len) != 0) {
  274.         ++changed;
  275.         memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
  276.     }
  277.     if (lhs->ia_type != rhs->ia_type) {
  278.         ++changed;
  279.         lhs->ia_type = rhs->ia_type;
  280.     }
  281.     if (lhs->ia_status != rhs->ia_status) {
  282.         ++changed;
  283.         lhs->ia_status = rhs->ia_status;
  284.     }
  285.     if (lhs->ia_origin != rhs->ia_origin) {
  286.         ++changed;
  287.         lhs->ia_origin = rhs->ia_origin;
  288.     }
  289.     return changed;
  290. }
  291. /**
  292.  * copy an  ipaddress_entry
  293.  *
  294.  * @retval -1  : error
  295.  * @retval 0   : no error
  296.  */
  297. int
  298. netsnmp_access_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
  299.                                     netsnmp_ipaddress_entry *rhs)
  300. {
  301.     int rc;
  302.     if (NULL != lhs->ia_prefix_oid)
  303.         SNMP_FREE(lhs->ia_prefix_oid);
  304.     snmp_clone_mem((void **) &lhs->ia_prefix_oid, rhs->ia_prefix_oid,
  305.                    rhs->ia_prefix_oid_len * sizeof(oid));
  306.     lhs->ia_prefix_oid_len = rhs->ia_prefix_oid_len;
  307.     /*
  308.      * copy arch stuff. we don't care if it changed
  309.      */
  310.     rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
  311.     if (0 != rc) {
  312.         snmp_log(LOG_ERR,"arch ipaddress copy failedn");
  313.         return -1;
  314.     }
  315.     lhs->if_index = rhs->if_index;
  316.     lhs->ia_storagetype = rhs->ia_storagetype;
  317.     lhs->ia_address_len = rhs->ia_address_len;
  318.     memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
  319.     lhs->ia_type = rhs->ia_type;
  320.     lhs->ia_status = rhs->ia_status;
  321.     lhs->ia_origin = rhs->ia_origin;
  322.     
  323.     return 0;
  324. }
  325. /**---------------------------------------------------------------------*/
  326. /*
  327.  * Utility routines
  328.  */
  329. /**
  330.  */
  331. void
  332. _access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry, void *context)
  333. {
  334.     netsnmp_access_ipaddress_entry_free(entry);
  335. }
  336. static int _access_ipaddress_entry_compare_addr(const void *lhs,
  337.                                                 const void *rhs)
  338. {
  339.     const netsnmp_ipaddress_entry *lh = (const netsnmp_ipaddress_entry *)lhs;
  340.     const netsnmp_ipaddress_entry *rh = (const netsnmp_ipaddress_entry *)rhs;
  341.     netsnmp_assert(NULL != lhs);
  342.     netsnmp_assert(NULL != rhs);
  343.     /*
  344.      * compare address length
  345.      */
  346.     if (lh->ia_address_len < rh->ia_address_len)
  347.         return -1;
  348.     else if (lh->ia_address_len > rh->ia_address_len)
  349.         return 1;
  350.     /*
  351.      * length equal, compare address
  352.      */
  353.     return memcmp(lh->ia_address, rh->ia_address, lh->ia_address_len);
  354. }