|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Ipaddress MIB architecture support
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* $Id$
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit |
fcad23 |
#include <net-snmp/data_access/ipaddress.h>
|
|
Packit |
fcad23 |
#include <net-snmp/data_access/interface.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include "ip-mib/ipAddressTable/ipAddressTable_constants.h"
|
|
Packit |
fcad23 |
#include "ipaddress.h"
|
|
Packit |
fcad23 |
#include "ipaddress_private.h"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-features.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(ipaddress_common, libnetsnmpmibs)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(ipaddress_common_copy_utilities, ipaddress_common)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(ipaddress_entry_copy, ipaddress_common)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(ipaddress_entry_update, ipaddress_common)
|
|
Packit |
fcad23 |
netsnmp_feature_child_of(ipaddress_prefix_copy, ipaddress_common_copy_utilities)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef NETSNMP_FEATURE_REQUIRE_IPADDRESS_ENTRY_COPY
|
|
Packit |
fcad23 |
netsnmp_feature_require(ipaddress_arch_entry_copy)
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REQUIRE_IPADDRESS_ENTRY_COPY */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**---------------------------------------------------------------------*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* local static prototypes
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
static int _access_ipaddress_entry_compare_addr(const void *lhs,
|
|
Packit |
fcad23 |
const void *rhs);
|
|
Packit |
fcad23 |
static void _access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry,
|
|
Packit |
fcad23 |
void *unused);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**---------------------------------------------------------------------*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* container functions
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_container *
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_container_init(u_int flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_container *container1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("access:ipaddress:container", "init\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* create the containers. one indexed by ifIndex, the other
|
|
Packit |
fcad23 |
* indexed by ifName.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
container1 = netsnmp_container_find("access_ipaddress:table_container");
|
|
Packit |
fcad23 |
if (NULL == container1) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "ipaddress primary container not found\n");
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
container1->container_name = strdup("ia_index");
|
|
Packit |
fcad23 |
container1->flags = CONTAINER_KEY_ALLOW_DUPLICATES;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (flags & NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR) {
|
|
Packit |
fcad23 |
netsnmp_container *container2 =
|
|
Packit |
fcad23 |
netsnmp_container_find("ipaddress_addr:access_ipaddress:table_container");
|
|
Packit |
fcad23 |
if (NULL == container2) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "ipaddress secondary container not found\n");
|
|
Packit |
fcad23 |
CONTAINER_FREE(container1);
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
container2->compare = _access_ipaddress_entry_compare_addr;
|
|
Packit |
fcad23 |
container2->container_name = strdup("ia_addr");
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* With allowed duplicates, CONTAINER_INSERT does not need to sort whole
|
|
Packit |
fcad23 |
* container and check for duplicates. We remove duplicates manually in
|
|
Packit |
fcad23 |
* netsnmp_access_ipaddress_container_load.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
container2->flags = CONTAINER_KEY_ALLOW_DUPLICATES;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_container_add_index(container1, container2);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return container1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* Remove duplicate entries from the container.
|
|
Packit |
fcad23 |
* This function returns new copy of the container and destroys
|
|
Packit |
fcad23 |
* the original one. Use like this:
|
|
Packit |
fcad23 |
* c = _remove_duplicates(c, flags);
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
static netsnmp_container *
|
|
Packit |
fcad23 |
_remove_duplicates(netsnmp_container *container, u_int container_flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_container *c;
|
|
Packit |
fcad23 |
netsnmp_iterator *it;
|
|
Packit |
fcad23 |
netsnmp_container *ret;
|
|
Packit |
fcad23 |
netsnmp_ipaddress_entry *entry, *prev_entry;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (! (container_flags & NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR)) {
|
|
Packit |
fcad23 |
/* We don't have address index, we can't detect duplicates */
|
|
Packit |
fcad23 |
return container;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
ret = netsnmp_access_ipaddress_container_init(container_flags);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* use the IpAddress index */
|
|
Packit |
fcad23 |
c = container->next;
|
|
Packit |
fcad23 |
it = CONTAINER_ITERATOR(c);
|
|
Packit |
fcad23 |
/* Sort the address index */
|
|
Packit |
fcad23 |
CONTAINER_FIND(c, ITERATOR_FIRST(it));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Sequentially iterate over sorted container and add only unique entries
|
|
Packit |
fcad23 |
* to 'ret'
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
prev_entry = NULL;
|
|
Packit |
fcad23 |
for (entry = ITERATOR_FIRST(it); entry; entry = ITERATOR_NEXT(it)) {
|
|
Packit |
fcad23 |
if (prev_entry && _access_ipaddress_entry_compare_addr(prev_entry, entry) == 0) {
|
|
Packit |
fcad23 |
/* 'entry' is duplicate of the previous one -> delete it */
|
|
Packit |
8b5d9b |
NETSNMP_LOGONCE((LOG_ERR, "Duplicate IPv4 address detected, some interfaces may not be visible in IP-MIB\n"));
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_free(entry);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
CONTAINER_INSERT(ret, entry);
|
|
Packit |
fcad23 |
prev_entry = entry;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
CONTAINER_FREE(container);
|
|
Packit |
fcad23 |
free(it);
|
|
Packit |
fcad23 |
return ret;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* @retval NULL error
|
|
Packit |
fcad23 |
* @retval !NULL pointer to container
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_container*
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_container_load(netsnmp_container* container,
|
|
Packit |
fcad23 |
u_int load_flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int rc;
|
|
Packit |
fcad23 |
u_int container_flags = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("access:ipaddress:container", "load\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_ADDL_IDX_BY_ADDR)
|
|
Packit |
fcad23 |
container_flags |= NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == container) {
|
|
Packit |
fcad23 |
container = netsnmp_access_ipaddress_container_init(container_flags);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (NULL == container) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "no container specified/found for access_ipaddress\n");
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_container_load(container, load_flags);
|
|
Packit |
fcad23 |
if (0 != rc) {
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_container_free(container,
|
|
Packit |
fcad23 |
NETSNMP_ACCESS_IPADDRESS_FREE_NOFLAGS);
|
|
Packit |
fcad23 |
container = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (container)
|
|
Packit |
fcad23 |
container = _remove_duplicates(container, container_flags);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return container;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_container_free(netsnmp_container *container, u_int free_flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
DEBUGMSGTL(("access:ipaddress:container", "free\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == container) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "invalid container for netsnmp_access_ipaddress_free\n");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if(! (free_flags & NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* free all items.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
CONTAINER_CLEAR(container,
|
|
Packit |
fcad23 |
(netsnmp_container_obj_func*)_access_ipaddress_entry_release,
|
|
Packit |
fcad23 |
NULL);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if(! (free_flags & NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER))
|
|
Packit |
fcad23 |
CONTAINER_FREE(container);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**---------------------------------------------------------------------*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* ipaddress_entry functions
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
netsnmp_ipaddress_entry *
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_create(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_ipaddress_entry *entry =
|
|
Packit |
fcad23 |
SNMP_MALLOC_TYPEDEF(netsnmp_ipaddress_entry);
|
|
Packit |
fcad23 |
int rc = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
entry->oid_index.len = 1;
|
|
Packit |
fcad23 |
entry->oid_index.oids = &entry->ns_ia_index;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* set up defaults
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry->ia_type = IPADDRESSTYPE_UNICAST;
|
|
Packit |
fcad23 |
entry->ia_status = IPADDRESSSTATUSTC_PREFERRED;
|
|
Packit |
fcad23 |
entry->ia_storagetype = STORAGETYPE_VOLATILE;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_entry_init(entry);
|
|
Packit |
fcad23 |
if (SNMP_ERR_NOERROR != rc) {
|
|
Packit |
fcad23 |
DEBUGMSGT(("access:ipaddress:create","error %d in arch init\n", rc));
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_free(entry);
|
|
Packit |
fcad23 |
entry = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return entry;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_free(netsnmp_ipaddress_entry * entry)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (NULL == entry)
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL != entry->arch_data)
|
|
Packit |
fcad23 |
netsnmp_arch_ipaddress_entry_cleanup(entry);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
free(entry);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* update underlying data store (kernel) for entry
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @retval 0 : success
|
|
Packit |
fcad23 |
* @retval -1 : error
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_set(netsnmp_ipaddress_entry * entry)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int rc = SNMP_ERR_NOERROR;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == entry) {
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != entry);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* make sure interface and ifIndex match up
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (NULL == netsnmp_access_interface_name_find(entry->if_index)) {
|
|
Packit |
fcad23 |
DEBUGMSGT(("access:ipaddress:set",
|
|
Packit |
fcad23 |
"cant find name for index %" NETSNMP_PRIo "d\n",
|
|
Packit |
fcad23 |
entry->if_index));
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* don't support non-volatile yet
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (STORAGETYPE_VOLATILE != entry->ia_storagetype) {
|
|
Packit |
fcad23 |
DEBUGMSGT(("access:ipaddress:set",
|
|
Packit |
fcad23 |
"non-volatile storagetypes unsupported\n"));
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
rc = -1;
|
|
Packit |
fcad23 |
if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CREATE) {
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_create(entry);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CHANGE) {
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_DELETE) {
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_delete(entry);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"netsnmp_access_ipaddress_entry_set with no mode\n");
|
|
Packit |
fcad23 |
netsnmp_assert(!"ipaddress_entry_set == unknown mode"); /* always false */
|
|
Packit |
fcad23 |
rc = -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return rc;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_ENTRY_UPDATE
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* update an old ipaddress_entry from a new one
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @note: only mib related items are compared. Internal objects
|
|
Packit |
fcad23 |
* such as oid_index, ns_ia_index and flags are not compared.
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @retval -1 : error
|
|
Packit |
fcad23 |
* @retval >=0 : number of fields updated
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_update(netsnmp_ipaddress_entry *lhs,
|
|
Packit |
fcad23 |
netsnmp_ipaddress_entry *rhs)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int rc, changed = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* copy arch stuff. we don't care if it changed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
|
|
Packit |
fcad23 |
if (0 != rc) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"arch ipaddress copy failed\n");
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->if_index != rhs->if_index) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->if_index = rhs->if_index;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_storagetype != rhs->ia_storagetype) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_storagetype = rhs->ia_storagetype;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_address_len != rhs->ia_address_len) {
|
|
Packit |
fcad23 |
changed += 2;
|
|
Packit |
fcad23 |
lhs->ia_address_len = rhs->ia_address_len;
|
|
Packit |
fcad23 |
memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if (memcmp(lhs->ia_address, rhs->ia_address, rhs->ia_address_len) != 0) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_type != rhs->ia_type) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_type = rhs->ia_type;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_status != rhs->ia_status) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_status = rhs->ia_status;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_origin != rhs->ia_origin) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_origin = rhs->ia_origin;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_onlink_flag != rhs->ia_onlink_flag) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_onlink_flag = rhs->ia_onlink_flag;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_autonomous_flag != rhs->ia_autonomous_flag) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_autonomous_flag = rhs->ia_autonomous_flag;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_prefered_lifetime != rhs->ia_prefered_lifetime) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_prefered_lifetime = rhs->ia_prefered_lifetime;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (lhs->ia_valid_lifetime != rhs->ia_valid_lifetime) {
|
|
Packit |
fcad23 |
++changed;
|
|
Packit |
fcad23 |
lhs->ia_valid_lifetime = rhs->ia_valid_lifetime;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return changed;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_ENTRY_UPDATE */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_ENTRY_COPY
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* copy an ipaddress_entry
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @retval -1 : error
|
|
Packit |
fcad23 |
* @retval 0 : no error
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
|
|
Packit |
fcad23 |
netsnmp_ipaddress_entry *rhs)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int rc;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* copy arch stuff. we don't care if it changed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
|
|
Packit |
fcad23 |
if (0 != rc) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"arch ipaddress copy failed\n");
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
lhs->if_index = rhs->if_index;
|
|
Packit |
fcad23 |
lhs->ia_storagetype = rhs->ia_storagetype;
|
|
Packit |
fcad23 |
lhs->ia_address_len = rhs->ia_address_len;
|
|
Packit |
fcad23 |
memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
|
|
Packit |
fcad23 |
lhs->ia_type = rhs->ia_type;
|
|
Packit |
fcad23 |
lhs->ia_status = rhs->ia_status;
|
|
Packit |
fcad23 |
lhs->ia_origin = rhs->ia_origin;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_ENTRY_COPY */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**---------------------------------------------------------------------*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Utility routines
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_PREFIX_COPY
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* copy the prefix portion of an ip address
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_ipaddress_prefix_copy(u_char *dst, u_char *src, int addr_len, int pfx_len)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int bytes = pfx_len / 8;
|
|
Packit |
fcad23 |
int bits = pfx_len % 8;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((NULL == dst) || (NULL == src) || (0 == pfx_len))
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
memcpy(dst, src, bytes);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (bytes < addr_len)
|
|
Packit |
fcad23 |
memset(&dst[bytes],0x0, addr_len - bytes);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (bits) {
|
|
Packit |
fcad23 |
u_char mask = (0xff << (8-bits));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
dst[bytes] = (src[bytes] & mask);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return pfx_len;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_PREFIX_COPY */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
* Compute the prefix length of a network mask
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @param mask network byte order mask
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* @returns number of prefix bits
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_ipaddress_ipv4_prefix_len(in_addr_t mask)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i, len = 0;
|
|
Packit |
fcad23 |
unsigned char *mp = (unsigned char *)&mas;;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (i = 0; i < 4; i++)
|
|
Packit |
fcad23 |
if (mp[i] == 0xFF) len += 8;
|
|
Packit |
fcad23 |
else break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (i == 4)
|
|
Packit |
fcad23 |
return len;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while(0x80 & mp[i]) {
|
|
Packit |
fcad23 |
++len;
|
|
Packit |
fcad23 |
mp[i] <<= 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return len;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
in_addr_t netsnmp_ipaddress_ipv4_mask(int len)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i = 0, m = 0x80;
|
|
Packit |
fcad23 |
in_addr_t mask;
|
|
Packit |
fcad23 |
unsigned char *mp = (unsigned char *)&mas;;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (len < 0 || len > 32) abort();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
memset(mp, 0, sizeof(mask));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (len >= 8) {
|
|
Packit |
fcad23 |
mp[i] = 0xFF;
|
|
Packit |
fcad23 |
len -= 8;
|
|
Packit |
fcad23 |
i++;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
while (len) {
|
|
Packit |
fcad23 |
mp[i] |= m;
|
|
Packit |
fcad23 |
m >>= 1;
|
|
Packit |
fcad23 |
len--;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return mask;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_ipaddress_ipv6_prefix_len(struct in6_addr mask)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i, len = 0;
|
|
Packit |
fcad23 |
unsigned char *mp = (unsigned char *)&mask.s6_addr;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (i = 0; i < 16; i++)
|
|
Packit |
fcad23 |
if (mp[i] == 0xFF) len += 8;
|
|
Packit |
fcad23 |
else break;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (i == 16)
|
|
Packit |
fcad23 |
return len;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while(0x80 & mp[i]) {
|
|
Packit |
fcad23 |
++len;
|
|
Packit |
fcad23 |
mp[i] <<= 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return len;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/**
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
_access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry, void *context)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_access_ipaddress_entry_free(entry);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int _access_ipaddress_entry_compare_addr(const void *lhs,
|
|
Packit |
fcad23 |
const void *rhs)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
const netsnmp_ipaddress_entry *lh = (const netsnmp_ipaddress_entry *)lhs;
|
|
Packit |
fcad23 |
const netsnmp_ipaddress_entry *rh = (const netsnmp_ipaddress_entry *)rhs;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != lhs);
|
|
Packit |
fcad23 |
netsnmp_assert(NULL != rhs);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* compare address length
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (lh->ia_address_len < rh->ia_address_len)
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
else if (lh->ia_address_len > rh->ia_address_len)
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* length equal, compare address
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
return memcmp(lh->ia_address, rh->ia_address, lh->ia_address_len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_COMMON_COPY_UTILITIES
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
|
|
Packit |
fcad23 |
u_long *ipAddressPrefixAdvValidLifetime,
|
|
Packit |
fcad23 |
u_long *ipAddressPrefixOnLinkFlag,
|
|
Packit |
fcad23 |
u_long *ipAddressPrefixAutonomousFlag,
|
|
Packit |
fcad23 |
u_long *ia_prefered_lifetime,
|
|
Packit |
fcad23 |
u_long *ia_valid_lifetime,
|
|
Packit |
fcad23 |
u_char *ia_onlink_flag,
|
|
Packit |
fcad23 |
u_char *ia_autonomous_flag)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*Copy all the flags*/
|
|
Packit |
fcad23 |
*ipAddressPrefixAdvPreferredLifetime = *ia_prefered_lifetime;
|
|
Packit |
fcad23 |
*ipAddressPrefixAdvValidLifetime = *ia_valid_lifetime;
|
|
Packit |
fcad23 |
*ipAddressPrefixOnLinkFlag = *ia_onlink_flag;
|
|
Packit |
fcad23 |
*ipAddressPrefixAutonomousFlag = *ia_autonomous_flag;
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
|
|
Packit |
fcad23 |
u_char ia_origin,
|
|
Packit |
fcad23 |
int flags,
|
|
Packit |
fcad23 |
u_long ipAddressAddrType)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if(ipAddressAddrType == INETADDRESSTYPE_IPV4){
|
|
Packit |
fcad23 |
if(ia_origin == 6) /*Random*/
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = ia_origin;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if(ia_origin == 5) { /*Link Layer*/
|
|
Packit |
fcad23 |
if(!flags) /*Global address assigned by router adv*/
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if(ia_origin == 6) /*Random*/
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
(*ipAddressPrefixOrigin) = ia_origin;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_COMMON_COPY_UTILITIES */
|
|
Packit |
fcad23 |
|