Blame agent/mibgroup/ip-mib/data_access/ipaddress_linux.c

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