|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* Interface MIB architecture support
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* $Id$
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-config.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-features.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit Service |
b38f0b |
#include "mibII/mibII_common.h"
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/data_access/ipaddress.h>
|
|
Packit Service |
b38f0b |
#include <net-snmp/data_access/interface.h>
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include "ip-mib/ipAddressTable/ipAddressTable_constants.h"
|
|
Packit Service |
b38f0b |
#include "ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h"
|
|
Packit Service |
b38f0b |
#include "mibgroup/util_funcs.h"
|
|
Packit Service |
b38f0b |
#include "../../if-mib/data_access/interface_private.h"
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include <errno.h>
|
|
Packit Service |
b38f0b |
#include <sys/ioctl.h>
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_feature_require(prefix_info)
|
|
Packit Service |
b38f0b |
netsnmp_feature_require(find_prefix_info)
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_feature_child_of(ipaddress_arch_entry_copy, ipaddress_common)
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#ifdef NETSNMP_FEATURE_REQUIRE_IPADDRESS_ARCH_ENTRY_COPY
|
|
Packit Service |
b38f0b |
netsnmp_feature_require(ipaddress_ioctl_entry_copy)
|
|
Packit Service |
b38f0b |
#endif /* NETSNMP_FEATURE_REQUIRE_IPADDRESS_ARCH_ENTRY_COPY */
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#if defined (NETSNMP_ENABLE_IPV6)
|
|
Packit Service |
b38f0b |
#include <linux/types.h>
|
|
Packit Service |
b38f0b |
#include <asm/types.h>
|
|
Packit Service |
b38f0b |
#if defined(HAVE_LINUX_RTNETLINK_H)
|
|
Packit Service |
b38f0b |
#include <linux/netlink.h>
|
|
Packit Service |
b38f0b |
#include <linux/rtnetlink.h>
|
|
Packit Service |
b38f0b |
#ifdef RTMGRP_IPV6_PREFIX
|
|
Packit Service |
b38f0b |
#define SUPPORT_PREFIX_FLAGS 1
|
|
Packit Service |
b38f0b |
#endif /* RTMGRP_IPV6_PREFIX */
|
|
Packit Service |
b38f0b |
#endif /* HAVE_LINUX_RTNETLINK_H */
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#include "ipaddress.h"
|
|
Packit Service |
b38f0b |
#include "ipaddress_ioctl.h"
|
|
Packit Service |
b38f0b |
#include "ipaddress_private.h"
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
int _load_v6(netsnmp_container *container, int idx_offset);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#ifdef HAVE_LINUX_RTNETLINK_H
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_extra_prefix_info(int index,
|
|
Packit Service |
b38f0b |
u_long *preferedlt,
|
|
Packit Service |
b38f0b |
ulong *validlt,
|
|
Packit Service |
b38f0b |
char *addr);
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* initialize arch specific storage
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* @retval 0: success
|
|
Packit Service |
b38f0b |
* @retval <0: error
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_entry_init(netsnmp_ipaddress_entry *entry)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* init ipv4 stuff
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (NULL == netsnmp_ioctl_ipaddress_entry_init(entry))
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* init ipv6 stuff
|
|
Packit Service |
b38f0b |
* so far, we can just share the ipv4 stuff, so nothing to do
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* cleanup arch specific storage
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
void
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_entry_cleanup(netsnmp_ipaddress_entry *entry)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* cleanup ipv4 stuff
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
netsnmp_ioctl_ipaddress_entry_cleanup(entry);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* cleanup ipv6 stuff
|
|
Packit Service |
b38f0b |
* so far, we can just share the ipv4 stuff, so nothing to do
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_ARCH_ENTRY_COPY
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* copy arch specific storage
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
|
|
Packit Service |
b38f0b |
netsnmp_ipaddress_entry *rhs)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
int rc;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* copy ipv4 stuff
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
rc = netsnmp_ioctl_ipaddress_entry_copy(lhs, rhs);
|
|
Packit Service |
b38f0b |
if (rc)
|
|
Packit Service |
b38f0b |
return rc;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* copy ipv6 stuff
|
|
Packit Service |
b38f0b |
* so far, we can just share the ipv4 stuff, so nothing to do
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return rc;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_ARCH_ENTRY_COPY */
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* create a new entry
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_create(netsnmp_ipaddress_entry *entry)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
if (NULL == entry)
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (4 == entry->ia_address_len) {
|
|
Packit Service |
b38f0b |
return _netsnmp_ioctl_ipaddress_set_v4(entry);
|
|
Packit Service |
b38f0b |
} else if (16 == entry->ia_address_len) {
|
|
Packit Service |
b38f0b |
return _netsnmp_ioctl_ipaddress_set_v6(entry);
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
DEBUGMSGT(("access:ipaddress:create", "wrong length of IP address\n"));
|
|
Packit Service |
b38f0b |
return -2;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* create a new entry
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_delete(netsnmp_ipaddress_entry *entry)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
if (NULL == entry)
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (4 == entry->ia_address_len) {
|
|
Packit Service |
b38f0b |
return _netsnmp_ioctl_ipaddress_delete_v4(entry);
|
|
Packit Service |
b38f0b |
} else if (16 == entry->ia_address_len) {
|
|
Packit Service |
b38f0b |
return _netsnmp_ioctl_ipaddress_delete_v6(entry);
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
DEBUGMSGT(("access:ipaddress:create", "only ipv4 supported\n"));
|
|
Packit Service |
b38f0b |
return -2;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/**
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* @retval 0 no errors
|
|
Packit Service |
b38f0b |
* @retval !0 errors
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_arch_ipaddress_container_load(netsnmp_container *container,
|
|
Packit Service |
b38f0b |
u_int load_flags)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
int rc = 0, idx_offset = 0;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (0 == (load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_IPV6_ONLY)) {
|
|
Packit Service |
b38f0b |
rc = _netsnmp_ioctl_ipaddress_container_load_v4(container, idx_offset);
|
|
Packit Service |
b38f0b |
if(rc < 0) {
|
|
Packit Service |
b38f0b |
u_int flags = NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER;
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_container_free(container, flags);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#if defined (NETSNMP_ENABLE_IPV6)
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (0 == (load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_IPV4_ONLY)) {
|
|
Packit Service |
b38f0b |
if (rc < 0)
|
|
Packit Service |
b38f0b |
rc = 0;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
idx_offset = rc;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* load ipv6, ignoring errors if file not found
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
rc = _load_v6(container, idx_offset);
|
|
Packit Service |
b38f0b |
if (-2 == rc)
|
|
Packit Service |
b38f0b |
rc = 0;
|
|
Packit Service |
b38f0b |
else if(rc < 0) {
|
|
Packit Service |
b38f0b |
u_int flags = NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER;
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_container_free(container, flags);
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* return no errors (0) if we found any interfaces
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if(rc > 0)
|
|
Packit Service |
b38f0b |
rc = 0;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return rc;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#if defined (NETSNMP_ENABLE_IPV6)
|
|
Packit Service |
b38f0b |
/**
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
_load_v6(netsnmp_container *container, int idx_offset)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
#ifndef HAVE_LINUX_RTNETLINK_H
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:container",
|
|
Packit Service |
b38f0b |
"cannot get ip address information"
|
|
Packit Service |
b38f0b |
"as netlink socket is not available\n"));
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
#else
|
|
Packit Service |
b38f0b |
FILE *in;
|
|
Packit Service |
b38f0b |
char line[80], addr[40];
|
|
Packit Service |
b38f0b |
char if_name[IFNAMSIZ+1];/* +1 for '\0' because of the ugly sscanf below */
|
|
Packit Service |
b38f0b |
u_char *buf;
|
|
Packit Service |
b38f0b |
int if_index, pfx_len, scope, flags, rc = 0;
|
|
Packit Service |
b38f0b |
size_t in_len, out_len;
|
|
Packit Service |
b38f0b |
netsnmp_ipaddress_entry *entry;
|
|
Packit Service |
b38f0b |
_ioctl_extras *extras;
|
|
Packit Service |
b38f0b |
struct address_flag_info addr_info;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
netsnmp_assert(NULL != container);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#define PROCFILE "/proc/net/if_inet6"
|
|
Packit Service |
b38f0b |
if (!(in = fopen(PROCFILE, "r"))) {
|
|
Packit Service |
b30573 |
NETSNMP_LOGONCE((LOG_ERR, "ipaddress_linux: could not open " PROCFILE));
|
|
Packit Service |
b38f0b |
return -2;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* address index prefix_len scope status if_name
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
while (fgets(line, sizeof(line), in)) {
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
|
|
Packit Service |
b38f0b |
* A D P S F I
|
|
Packit Service |
b38f0b |
* A: address
|
|
Packit Service |
b38f0b |
* D: device number
|
|
Packit Service |
b38f0b |
* P: prefix len
|
|
Packit Service |
b38f0b |
* S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
|
|
Packit Service |
b38f0b |
* F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
|
|
Packit Service |
b38f0b |
* I: interface
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
rc = sscanf(line, "%39s %08x %08x %04x %02x %" SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n",
|
|
Packit Service |
b38f0b |
addr, &if_index, &pfx_len, &scope, &flags, if_name);
|
|
Packit Service |
b38f0b |
if( 6 != rc ) {
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
|
|
Packit Service |
b38f0b |
rc, line);
|
|
Packit Service |
b38f0b |
continue;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:container",
|
|
Packit Service |
b38f0b |
"addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
|
|
Packit Service |
b38f0b |
addr, if_index, pfx_len, scope, flags, if_name));
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
entry = netsnmp_access_ipaddress_entry_create();
|
|
Packit Service |
b38f0b |
if(NULL == entry) {
|
|
Packit Service |
b38f0b |
rc = -3;
|
|
Packit Service |
b38f0b |
break;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
in_len = entry->ia_address_len = sizeof(entry->ia_address);
|
|
Packit Service |
b38f0b |
netsnmp_assert(16 == in_len);
|
|
Packit Service |
b38f0b |
out_len = 0;
|
|
Packit Service |
b38f0b |
entry->flags = flags;
|
|
Packit Service |
b38f0b |
buf = entry->ia_address;
|
|
Packit Service |
b38f0b |
if(1 != netsnmp_hex_to_binary(&buf, &in_len,
|
|
Packit Service |
b38f0b |
&out_len, 0, addr, ":")) {
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR,"error parsing '%s', skipping\n", addr);
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_entry_free(entry);
|
|
Packit Service |
b38f0b |
continue;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
netsnmp_assert(16 == out_len);
|
|
Packit Service |
b38f0b |
entry->ia_address_len = out_len;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
entry->ns_ia_index = ++idx_offset;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* save if name
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
extras = netsnmp_ioctl_ipaddress_extras_get(entry);
|
|
Packit Service |
b38f0b |
memcpy(extras->name, if_name, sizeof(extras->name));
|
|
Packit Service |
b38f0b |
extras->flags = flags;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* yyy-rks: optimization: create a socket outside the loop and use
|
|
Packit Service |
b38f0b |
* netsnmp_access_interface_ioctl_ifindex_get() here, since
|
|
Packit Service |
b38f0b |
* netsnmp_access_interface_index_find will open/close a socket
|
|
Packit Service |
b38f0b |
* every time it is called.
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
entry->if_index = netsnmp_access_interface_index_find(if_name);
|
|
Packit Service |
b38f0b |
memset(&addr_info, 0, sizeof(struct address_flag_info));
|
|
Packit Service |
b38f0b |
addr_info = netsnmp_access_other_info_get(entry->if_index, AF_INET6);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_PREFERRED 1
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_DEPRECATED 2
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_INVALID 3
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_INACCESSIBLE 4
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_UNKNOWN 5
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_TENTATIVE 6
|
|
Packit Service |
b38f0b |
#define IPADDRESSSTATUSTC_DUPLICATE 7
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if((flags & IFA_F_PERMANENT) || (!flags))
|
|
Packit Service |
b38f0b |
entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
|
|
Packit Service |
b38f0b |
#ifdef IFA_F_TEMPORARY
|
|
Packit Service |
b38f0b |
else if(flags & IFA_F_TEMPORARY)
|
|
Packit Service |
b38f0b |
entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
else if(flags & IFA_F_DEPRECATED)
|
|
Packit Service |
b38f0b |
entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
|
|
Packit Service |
b38f0b |
else if(flags & IFA_F_TENTATIVE)
|
|
Packit Service |
b38f0b |
entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
|
|
Packit Service |
b38f0b |
else {
|
|
Packit Service |
b38f0b |
entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:ipv6",
|
|
Packit Service |
b38f0b |
"unknown flags 0x%x\n", flags));
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* if it's not multi, it must be uni.
|
|
Packit Service |
b38f0b |
* (an ipv6 address is never broadcast)
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if(addr_info.anycastflg)
|
|
Packit Service |
b38f0b |
entry->ia_type = IPADDRESSTYPE_ANYCAST;
|
|
Packit Service |
b38f0b |
else
|
|
Packit Service |
b38f0b |
entry->ia_type = IPADDRESSTYPE_UNICAST;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
entry->ia_prefix_len = pfx_len;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* can we figure out if an address is from DHCP?
|
|
Packit Service |
b38f0b |
* use manual until then...
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
*#define IPADDRESSORIGINTC_OTHER 1
|
|
Packit Service |
b38f0b |
*#define IPADDRESSORIGINTC_MANUAL 2
|
|
Packit Service |
b38f0b |
*#define IPADDRESSORIGINTC_DHCP 4
|
|
Packit Service |
b38f0b |
*#define IPADDRESSORIGINTC_LINKLAYER 5
|
|
Packit Service |
b38f0b |
*#define IPADDRESSORIGINTC_RANDOM 6
|
|
Packit Service |
b38f0b |
*
|
|
Packit Service |
b38f0b |
* are 'local' address assigned by link layer??
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (!flags)
|
|
Packit Service |
b38f0b |
entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
|
|
Packit Service |
b38f0b |
#ifdef IFA_F_TEMPORARY
|
|
Packit Service |
b38f0b |
else if (flags & IFA_F_TEMPORARY)
|
|
Packit Service |
b38f0b |
entry->ia_origin = IPADDRESSORIGINTC_RANDOM;
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
else if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address))
|
|
Packit Service |
b38f0b |
entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
|
|
Packit Service |
b38f0b |
else
|
|
Packit Service |
b38f0b |
entry->ia_origin = IPADDRESSORIGINTC_MANUAL;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if(entry->ia_origin == IPADDRESSORIGINTC_LINKLAYER)
|
|
Packit Service |
b38f0b |
entry->ia_storagetype = STORAGETYPE_PERMANENT;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/* xxx-rks: what can we do with scope? */
|
|
Packit Service |
b38f0b |
#ifdef HAVE_LINUX_RTNETLINK_H
|
|
Packit Service |
b38f0b |
if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime
|
|
Packit Service |
b38f0b |
,&entry->ia_valid_lifetime, addr) < 0){
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n"));
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#else
|
|
Packit Service |
b38f0b |
entry->ia_prefered_lifetime = 0;
|
|
Packit Service |
b38f0b |
entry->ia_valid_lifetime = 0;
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
#ifdef SUPPORT_PREFIX_FLAGS
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
prefix_cbx prefix_val;
|
|
Packit Service |
b38f0b |
memset(&prefix_val, 0, sizeof(prefix_cbx));
|
|
Packit Service |
b38f0b |
if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val) < 0) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n"));
|
|
Packit Service |
b38f0b |
entry->ia_onlink_flag = 1; /*Set by default as true*/
|
|
Packit Service |
b38f0b |
entry->ia_autonomous_flag = 2; /*Set by default as false*/
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
} else {
|
|
Packit Service |
b38f0b |
entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag;
|
|
Packit Service |
b38f0b |
entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#else
|
|
Packit Service |
b38f0b |
entry->ia_onlink_flag = 1; /*Set by default as true*/
|
|
Packit Service |
b38f0b |
entry->ia_autonomous_flag = 2; /*Set by default as false*/
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
/*
|
|
Packit Service |
b38f0b |
* add entry to container
|
|
Packit Service |
b38f0b |
*/
|
|
Packit Service |
b38f0b |
if (CONTAINER_INSERT(container, entry) < 0) {
|
|
Packit Service |
b38f0b |
DEBUGMSGTL(("access:ipaddress:container","error with ipaddress_entry: insert into container failed.\n"));
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_entry_free(entry);
|
|
Packit Service |
b38f0b |
continue;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
fclose(in);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if(rc<0)
|
|
Packit Service |
b38f0b |
return rc;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
return idx_offset;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
struct address_flag_info
|
|
Packit Service |
b38f0b |
netsnmp_access_other_info_get(int index, int family)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
struct {
|
|
Packit Service |
b38f0b |
struct nlmsghdr n;
|
|
Packit Service |
b38f0b |
struct ifaddrmsg r;
|
|
Packit Service |
b38f0b |
char buf[1024];
|
|
Packit Service |
b38f0b |
} req;
|
|
Packit Service |
b38f0b |
struct address_flag_info addr;
|
|
Packit Service |
b38f0b |
struct rtattr *rta;
|
|
Packit Service |
b38f0b |
int status;
|
|
Packit Service |
b38f0b |
char buf[16384];
|
|
Packit Service |
b38f0b |
struct nlmsghdr *nlmp;
|
|
Packit Service |
b38f0b |
struct ifaddrmsg *rtmp;
|
|
Packit Service |
b38f0b |
struct rtattr *rtatp;
|
|
Packit Service |
b38f0b |
int rtattrlen;
|
|
Packit Service |
b38f0b |
int sd;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
memset(&addr, 0, sizeof(struct address_flag_info));
|
|
Packit Service |
b38f0b |
sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
|
Packit Service |
b38f0b |
if(sd < 0) {
|
|
Packit Service |
b38f0b |
snmp_log_perror("ipaddress_linux: could not open netlink socket");
|
|
Packit Service |
b38f0b |
return addr;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
b38f0b |
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
|
Packit Service |
b38f0b |
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
|
|
Packit Service |
b38f0b |
req.n.nlmsg_type = RTM_GETADDR;
|
|
Packit Service |
b38f0b |
req.r.ifa_family = family;
|
|
Packit Service |
b38f0b |
rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
|
|
Packit Service |
b38f0b |
if(family == AF_INET)
|
|
Packit Service |
b38f0b |
rta->rta_len = RTA_LENGTH(4);
|
|
Packit Service |
b38f0b |
else
|
|
Packit Service |
b38f0b |
rta->rta_len = RTA_LENGTH(16);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
status = send(sd, &req, req.n.nlmsg_len, 0);
|
|
Packit Service |
b38f0b |
if (status < 0) {
|
|
Packit Service |
b38f0b |
snmp_log_perror("ipadress_linux: could not send netlink request");
|
|
Packit Service |
b38f0b |
goto out;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
status = recv(sd, buf, sizeof(buf), 0);
|
|
Packit Service |
b38f0b |
if (status < 0) {
|
|
Packit Service |
b38f0b |
snmp_log_perror("ipadress_linux: could not receive netlink request");
|
|
Packit Service |
b38f0b |
goto out;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if(status == 0) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "ipadress_linux: nothing to read\n");
|
|
Packit Service |
b38f0b |
goto out;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
for(nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp);) {
|
|
Packit Service |
b38f0b |
int len = nlmp->nlmsg_len;
|
|
Packit Service |
b38f0b |
int req_len = len - sizeof(*nlmp);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (req_len < 0 || len > status) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "invalid netlink message\n");
|
|
Packit Service |
b38f0b |
goto out;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (!NLMSG_OK(nlmp, status)) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "invalid NLMSG message\n");
|
|
Packit Service |
b38f0b |
goto out;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
rtmp = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
|
|
Packit Service |
b38f0b |
rtatp = (struct rtattr *)IFA_RTA(rtmp);
|
|
Packit Service |
b38f0b |
rtattrlen = IFA_PAYLOAD(nlmp);
|
|
Packit Service |
b38f0b |
if(index == rtmp->ifa_index){
|
|
Packit Service |
b38f0b |
for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) {
|
|
Packit Service |
b38f0b |
if(rtatp->rta_type == IFA_BROADCAST){
|
|
Packit Service |
b38f0b |
addr.addr = ((struct in_addr *)RTA_DATA(rtatp))->s_addr;
|
|
Packit Service |
b38f0b |
addr.bcastflg = 1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
if(rtatp->rta_type == IFA_ANYCAST){
|
|
Packit Service |
b38f0b |
addr.addr = ((struct in_addr *)RTA_DATA(rtatp))->s_addr;
|
|
Packit Service |
b38f0b |
addr.anycastflg = 1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
status -= NLMSG_ALIGN(len);
|
|
Packit Service |
b38f0b |
nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
out:
|
|
Packit Service |
b38f0b |
close(sd);
|
|
Packit Service |
b38f0b |
return addr;
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
#ifdef HAVE_LINUX_RTNETLINK_H
|
|
Packit Service |
b38f0b |
int
|
|
Packit Service |
b38f0b |
netsnmp_access_ipaddress_extra_prefix_info(int index, u_long *preferedlt,
|
|
Packit Service |
b38f0b |
ulong *validlt, char *addr)
|
|
Packit Service |
b38f0b |
{
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
struct {
|
|
Packit Service |
b38f0b |
struct nlmsghdr nlhdr;
|
|
Packit Service |
b38f0b |
struct ifaddrmsg ifaceinfo;
|
|
Packit Service |
b38f0b |
char buf[1024];
|
|
Packit Service |
b38f0b |
} req;
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
struct rtattr *rta;
|
|
Packit Service |
b38f0b |
int status;
|
|
Packit Service |
b38f0b |
char buf[16384];
|
|
Packit Service |
b38f0b |
char tmpaddr[40];
|
|
Packit Service |
b38f0b |
struct nlmsghdr *nlmp;
|
|
Packit Service |
b38f0b |
struct ifaddrmsg *rtmp;
|
|
Packit Service |
b38f0b |
struct rtattr *rtatp;
|
|
Packit Service |
b38f0b |
struct ifa_cacheinfo *cache_info;
|
|
Packit Service |
b38f0b |
struct in6_addr *in6p;
|
|
Packit Service |
b38f0b |
int rtattrlen;
|
|
Packit Service |
b38f0b |
int sd;
|
|
Packit Service |
b38f0b |
int reqaddr = 0;
|
|
Packit Service |
b38f0b |
sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
|
Packit Service |
b38f0b |
if(sd < 0) {
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR, "could not open netlink socket\n");
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
b38f0b |
req.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
|
Packit Service |
b38f0b |
req.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
|
|
Packit Service |
b38f0b |
req.nlhdr.nlmsg_type = RTM_GETADDR;
|
|
Packit Service |
b38f0b |
req.ifaceinfo.ifa_family = AF_INET6;
|
|
Packit Service |
b38f0b |
rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.nlhdr.nlmsg_len));
|
|
Packit Service |
b38f0b |
rta->rta_len = RTA_LENGTH(16); /*For ipv6*/
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
status = send (sd, &req, req.nlhdr.nlmsg_len, 0);
|
|
Packit Service |
b38f0b |
if (status < 0) {
|
|
Packit Service |
b38f0b |
snmp_log(LOG_ERR, "could not send netlink request\n");
|
|
Packit Service |
22af3c |
close(sd);
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
status = recv (sd, buf, sizeof(buf), 0);
|
|
Packit Service |
b38f0b |
if (status < 0) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "could not recieve netlink request\n");
|
|
Packit Service |
22af3c |
close(sd);
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
if (status == 0) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "nothing to read\n");
|
|
Packit Service |
22af3c |
close(sd);
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
for (nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp); ){
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
int len = nlmp->nlmsg_len;
|
|
Packit Service |
b38f0b |
int req_len = len - sizeof(*nlmp);
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (req_len < 0 || len > status) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "invalid netlink message\n");
|
|
Packit Service |
22af3c |
close(sd);
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
if (!NLMSG_OK (nlmp, status)) {
|
|
Packit Service |
b38f0b |
snmp_log (LOG_ERR, "invalid NLMSG message\n");
|
|
Packit Service |
22af3c |
close(sd);
|
|
Packit Service |
b38f0b |
return -1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
rtmp = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
|
|
Packit Service |
b38f0b |
rtatp = (struct rtattr *)IFA_RTA(rtmp);
|
|
Packit Service |
b38f0b |
rtattrlen = IFA_PAYLOAD(nlmp);
|
|
Packit Service |
b38f0b |
if(index == rtmp->ifa_index) {
|
|
Packit Service |
b38f0b |
for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) {
|
|
Packit Service |
b38f0b |
if(rtatp->rta_type == IFA_ADDRESS) {
|
|
Packit Service |
b38f0b |
in6p = (struct in6_addr *)RTA_DATA(rtatp);
|
|
Packit Service |
b38f0b |
sprintf(tmpaddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
|
|
Packit Service |
b38f0b |
if(!strcmp(tmpaddr ,addr))
|
|
Packit Service |
b38f0b |
reqaddr = 1;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
if(rtatp->rta_type == IFA_CACHEINFO) {
|
|
Packit Service |
b38f0b |
cache_info = (struct ifa_cacheinfo *)RTA_DATA(rtatp);
|
|
Packit Service |
b38f0b |
if(reqaddr) {
|
|
Packit Service |
b38f0b |
reqaddr = 0;
|
|
Packit Service |
b38f0b |
*validlt = cache_info->ifa_valid;
|
|
Packit Service |
b38f0b |
*preferedlt = cache_info->ifa_prefered;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
status -= NLMSG_ALIGN(len);
|
|
Packit Service |
b38f0b |
nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
close(sd);
|
|
Packit Service |
b38f0b |
return 0;
|
|
Packit Service |
b38f0b |
}
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
#endif
|
|
Packit Service |
b38f0b |
|