netsnmp_ipaddress_entry *
netsnmp_access_ipaddress_entry_create(void)
{
    netsnmp_ipaddress_entry *entry =
        SNMP_MALLOC_TYPEDEF(netsnmp_ipaddress_entry);
    int rc = 0;

    entry->oid_index.len = 1;
    entry->oid_index.oids = &entry->ns_ia_index;

    /*
     * set up defaults
     */
    entry->ia_type = IPADDRESSTYPE_UNICAST;
    entry->ia_status = IPADDRESSSTATUSTC_PREFERRED;
    entry->ia_storagetype = STORAGETYPE_VOLATILE;

    rc = netsnmp_arch_ipaddress_entry_init(entry);
    if (SNMP_ERR_NOERROR != rc) {
        DEBUGMSGT(("access:ipaddress:create","error %d in arch init\n", rc));
        netsnmp_access_ipaddress_entry_free(entry);
        entry = NULL;
    }

    return entry;
}
/**
 * add new entry
 */
static void
_add_new_entry(netsnmp_ipaddress_entry *ipaddress_entry,
               netsnmp_container *container)
{
    ipAddressTable_rowreq_ctx *rowreq_ctx;

    DEBUGMSGTL(("ipAddressTable:access", "creating new entry\n"));

    netsnmp_assert(NULL != ipaddress_entry);
    netsnmp_assert(NULL != container);

    /*
     * allocate an row context and set the index(es)
     */
    rowreq_ctx = ipAddressTable_allocate_rowreq_ctx(ipaddress_entry, NULL);
    if ((NULL != rowreq_ctx) &&
        (MFD_SUCCESS ==
         ipAddressTable_indexes_set(rowreq_ctx,
                                    ipaddress_entry->ia_address_len,
                                    ipaddress_entry->ia_address,
                                    ipaddress_entry->ia_address_len))) {
        if (CONTAINER_INSERT(container, rowreq_ctx) < 0) {
            DEBUGMSGTL (("ipAddressTable:access","container insert failed for new entry\n"));
            ipAddressTable_release_rowreq_ctx(rowreq_ctx);
            return;
        }
        rowreq_ctx->ipAddressLastChanged =
            rowreq_ctx->ipAddressCreated = netsnmp_get_agent_uptime();
    } else {
        if (NULL != rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "ipAddressTable cache.\n");
            ipAddressTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "ipAddressTable cache.\n");
            netsnmp_access_ipaddress_entry_free(ipaddress_entry);
        }

        return;
    }

    /*-------------------------------------------------------------------
     * handle data that isn't part of the data_access ipaddress structure
     */
    rowreq_ctx->ipAddressRowStatus = ROWSTATUS_ACTIVE;
}
/**
 * check entry for update
 */
static void
_check_entry_for_updates(ipAddressTable_rowreq_ctx * rowreq_ctx,
                         void **magic)
{
    netsnmp_container *ipaddress_container = (netsnmp_container*)magic[0];
    netsnmp_container *to_delete           = (netsnmp_container*)magic[1];

    /*
     * check for matching entry using secondary index.
     */
    netsnmp_ipaddress_entry *ipaddress_entry = (netsnmp_ipaddress_entry*)
        CONTAINER_FIND(ipaddress_container, rowreq_ctx->data);
    if (NULL == ipaddress_entry) {
        DEBUGMSGTL(("ipAddressTable:access", "removing missing entry\n"));

        if (NULL == to_delete) {
            magic[1] = to_delete = netsnmp_container_find("lifo");
            if (NULL == to_delete)
                snmp_log(LOG_ERR, "couldn't create delete container\n");
        }
        if (NULL != to_delete)
            CONTAINER_INSERT(to_delete, rowreq_ctx);
    } else {
        DEBUGMSGTL(("ipAddressTable:access", "updating existing entry\n"));

        /*
         * Check for changes & update
         */
        if (netsnmp_access_ipaddress_entry_update(rowreq_ctx->data,
                                                  ipaddress_entry) > 0)
            rowreq_ctx->ipAddressLastChanged = netsnmp_get_agent_uptime();

        /*
         * remove entry from ifcontainer
         */
        CONTAINER_REMOVE(ipaddress_container, ipaddress_entry);
        netsnmp_access_ipaddress_entry_free(ipaddress_entry);
    }
}
Example #4
0
int
_load_v6(netsnmp_container *container, int idx_offset)
{
    FILE           *in;
    char            line[80], addr[33], if_name[IFNAMSIZ];
    u_char          *buf;
    int             if_index, pfx_len, scope, flags, rc = 0;
    size_t          in_len, out_len;
    netsnmp_ipaddress_entry *entry;
    _ioctl_extras           *extras;
    static int      log_open_err = 1;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/if_inet6"
    if (!(in = fopen(PROCFILE, "r"))) {
        if (1 == log_open_err) {
            snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we hadn't been able to open file and turned of err logging,
     * turn it back on now that we opened the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;

    /*
     * address index prefix_len scope status if_name
     */
    while (fgets(line, sizeof(line), in)) {
        /*
         * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
         *             A                    D  P  S  F  I
         * A: address
         * D: device number
         * P: prefix len
         * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
         * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
         * I: interface
         */
        rc = sscanf(line, "%32s %02x %02x %02x %02x %8s\n",
                    addr, &if_index, &pfx_len, &scope, &flags, if_name);
        if( 6 != rc ) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
                     rc, line);
            continue;
        }
        DEBUGMSGTL(("access:ipaddress:container",
                    "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
                    addr, if_index, pfx_len, scope, flags, if_name));
        /*
         */
        entry = netsnmp_access_ipaddress_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        in_len = entry->ia_address_len = sizeof(entry->ia_address);
        netsnmp_assert(16 == in_len);
        out_len = 0;
        buf = entry->ia_address;
        if(1 != snmp_hex_to_binary(&buf,
                                   &in_len, &out_len, 0, addr)) {
            snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
                     entry->ia_address);
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
        netsnmp_assert(16 == out_len);
        entry->ia_address_len = out_len;

        entry->ns_ia_index = ++idx_offset;

        /*
         * save if name
         */
        extras = netsnmp_ioctl_ipaddress_extras_get(entry);
        memcpy(extras->name, if_name, sizeof(extras->name));
        extras->flags = flags;

        /*
         * yyy-rks: optimization: create a socket outside the loop and use
         * netsnmp_access_interface_ioctl_ifindex_get() here, since
         * netsnmp_access_interface_index_find will open/close a socket
         * every time it is called.
         */
        entry->if_index = netsnmp_access_interface_index_find(if_name);

        /*
          #define IPADDRESSSTATUSTC_PREFERRED  1
          #define IPADDRESSSTATUSTC_DEPRECATED  2
          #define IPADDRESSSTATUSTC_INVALID  3
          #define IPADDRESSSTATUSTC_INACCESSIBLE  4
          #define IPADDRESSSTATUSTC_UNKNOWN  5
          #define IPADDRESSSTATUSTC_TENTATIVE  6
          #define IPADDRESSSTATUSTC_DUPLICATE  7
        */
        if(flags & IFA_F_PERMANENT)
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
        else if(flags & IFA_F_DEPRECATED)
            entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
        else if(flags & IFA_F_TENTATIVE)
            entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
        else {
            entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
            DEBUGMSGTL(("access:ipaddress:ipv6",
                        "unknown flags 0x%x\n", flags));
        }

        /*
         * if it's not multi, it must be uni.
         *  (an ipv6 address is never broadcast)
         */
        if (IN6_IS_ADDR_MULTICAST(entry->ia_address))
            entry->ia_type = IPADDRESSTYPE_ANYCAST;
        else
            entry->ia_type = IPADDRESSTYPE_UNICAST;


        entry->ia_prefix_len = pfx_len;

        /*
         * can we figure out if an address is from DHCP?
         * use manual until then...
         *
         *#define IPADDRESSORIGINTC_OTHER  1
         *#define IPADDRESSORIGINTC_MANUAL  2
         *#define IPADDRESSORIGINTC_DHCP  4
         *#define IPADDRESSORIGINTC_LINKLAYER  5
         *#define IPADDRESSORIGINTC_RANDOM  6
         *
         * are 'local' address assigned by link layer??
         */
        if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address) ||
            IN6_IS_ADDR_SITELOCAL(entry->ia_address))
            entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
        else
            entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

        /* xxx-rks: what can we do with scope? */

        /*
         * add entry to container
         */
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return idx_offset;
}
void
_access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry, void *context)
{
    netsnmp_access_ipaddress_entry_free(entry);
}
Example #6
0
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
int
netsnmp_arch_ipaddress_container_load(netsnmp_container *container,
                                      u_int load_flags)
{
    netsnmp_ipaddress_entry *entry = NULL;
    u_char *if_list = NULL, *cp;
    size_t if_list_size = 0;
    int sysctl_oid[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
    struct ifa_msghdr *ifa;
    struct sockaddr *a;
    int amask;
    int rc = 0;
    int idx_offset = 0;

    DEBUGMSGTL(("access:ipaddress:container:sysctl",
                "load (flags %u)\n", load_flags));

    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for interface\n");
        return -1;
    }

    if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), 0,
               &if_list_size, 0, 0) == -1) {
        snmp_log(LOG_ERR, "could not get interface info (size)\n");
        return -2;
    }

    if_list = (u_char*)malloc(if_list_size);
    if (if_list == NULL) {
        snmp_log(LOG_ERR, "could not allocate memory for interface info "
                 "(%u bytes)\n", (unsigned) if_list_size);
        return -3;
    } else {
        DEBUGMSGTL(("access:ipaddress:container:sysctl",
                    "allocated %u bytes for if_list\n",
                    (unsigned) if_list_size));
    }

    if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), if_list,
               &if_list_size, 0, 0) == -1) {
        snmp_log(LOG_ERR, "could not get interface info\n");
        free(if_list);
        return -2;
    }

    /* pass 2: walk addresses */
    for (cp = if_list; cp < if_list + if_list_size; cp += ifa->ifam_msglen) {
        ifa = (struct ifa_msghdr *) cp;
        int rtax;

        if (ifa->ifam_type != RTM_NEWADDR)
            continue;

        DEBUGMSGTL(("access:ipaddress:container:sysctl",
                    "received 0x%x in RTM_NEWADDR for ifindex %u\n",
                    ifa->ifam_addrs, ifa->ifam_index));

        entry = netsnmp_access_ipaddress_entry_create();
        if (entry == NULL) {
            rc = -3;
            break;
        }

        a = (struct sockaddr *) (ifa + 1);
        entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
        entry->ia_origin = IPADDRESSORIGINTC_OTHER;
	entry->ia_address_len = 0;
        for (amask = ifa->ifam_addrs, rtax = 0; amask != 0; amask >>= 1, rtax++) {
            if ((amask & 1) != 0) {
                entry->ns_ia_index = ++idx_offset;
                entry->if_index = ifa->ifam_index;
                DEBUGMSGTL(("access:ipaddress:container:sysctl",
                            "%d: a=%p, sa_len=%d, sa_family=0x%x\n",
                            (int)entry->if_index, a, a->sa_len, a->sa_family));

                if (a->sa_family == AF_INET || a->sa_family == 0) {
                    struct sockaddr_in *a4 = (struct sockaddr_in *)a;
		    char str[128];
		    DEBUGMSGTL(("access:ipaddress:container:sysctl",
		                "IPv4 addr %s\n", inet_ntop(AF_INET, &a4->sin_addr.s_addr, str, 128)));
                    if (rtax == RTAX_IFA) {
			entry->ia_address_len = 4;
                        memcpy(entry->ia_address, &a4->sin_addr.s_addr, entry->ia_address_len);
		    }
                    else if (rtax == RTAX_NETMASK)
                        entry->ia_prefix_len = netsnmp_ipaddress_ipv4_prefix_len(a4->sin_addr.s_addr);
                }
                else if (a->sa_family == AF_INET6) {
                    struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)a;
		    char str[128];
		    DEBUGMSGTL(("access:ipaddress:container:sysctl",
		                "IPv6 addr %s\n", inet_ntop(AF_INET6, &a6->sin6_addr.s6_addr, str, 128)));
                    if (rtax == RTAX_IFA) {
			entry->ia_address_len = 16;
                        memcpy(entry->ia_address, &a6->sin6_addr, entry->ia_address_len);
		    }
                    else if (rtax == RTAX_NETMASK) {
                        entry->ia_prefix_len = netsnmp_ipaddress_ipv6_prefix_len(a6->sin6_addr);
			DEBUGMSGTL(("access:ipaddress:container:sysctl",
			            "prefix_len=%d\n", entry->ia_prefix_len));
		    }
                }
                a = (struct sockaddr *) ( ((char *) a) + ROUNDUP(a->sa_len) );
            }
        }
	if (entry->ia_address_len == 0) {
	    DEBUGMSGTL(("access:ipaddress:container:sysctl",
	                "entry skipped\n"));
	    netsnmp_access_ipaddress_entry_free(entry);
	}
	else if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:ipaddress:container","error with ipaddress_entry: insert into container failed.\n"));
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
    }

    if (if_list != NULL)
        free(if_list);

    return 0;
}
Example #7
0
int
_load_v6(netsnmp_container *container, int idx_offset)
{
#ifndef HAVE_LINUX_RTNETLINK_H
    DEBUGMSGTL(("access:ipaddress:container",
                "cannot get ip address information"
                "as netlink socket is not available\n"));
    return -1;
#else
    FILE           *in;
    char            line[80], addr[40];
    char            if_name[IFNAMSIZ+1];/* +1 for '\0' because of the ugly sscanf below */ 
    u_char          *buf;
    int             if_index, pfx_len, scope, flags, rc = 0;
    size_t          in_len, out_len;
    netsnmp_ipaddress_entry *entry;
    _ioctl_extras           *extras;
    struct address_flag_info addr_info;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/if_inet6"
    if (!(in = fopen(PROCFILE, "r"))) {
        DEBUGMSGTL(("access:ipaddress:container","could not open " PROCFILE "\n"));
        return -2;
    }

    /*
     * address index prefix_len scope status if_name
     */
    while (fgets(line, sizeof(line), in)) {
        /*
         * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
         *             A                    D  P  S  F  I
         * A: address
         * D: device number
         * P: prefix len
         * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
         * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
         * I: interface
         */
        rc = sscanf(line, "%39s %08x %08x %04x %02x %" SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n",
                    addr, &if_index, &pfx_len, &scope, &flags, if_name);
        if( 6 != rc ) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
                     rc, line);
            continue;
        }
        DEBUGMSGTL(("access:ipaddress:container",
                    "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
                    addr, if_index, pfx_len, scope, flags, if_name));
        /*
         */
        entry = netsnmp_access_ipaddress_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        in_len = entry->ia_address_len = sizeof(entry->ia_address);
        netsnmp_assert(16 == in_len);
        out_len = 0;
        entry->flags = flags;
        buf = entry->ia_address;
        if(1 != netsnmp_hex_to_binary(&buf, &in_len,
                                      &out_len, 0, addr, ":")) {
            snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
                     entry->ia_address);
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
        netsnmp_assert(16 == out_len);
        entry->ia_address_len = out_len;

        entry->ns_ia_index = ++idx_offset;

        /*
         * save if name
         */
        extras = netsnmp_ioctl_ipaddress_extras_get(entry);
        memcpy(extras->name, if_name, sizeof(extras->name));
        extras->flags = flags;

        /*
         * yyy-rks: optimization: create a socket outside the loop and use
         * netsnmp_access_interface_ioctl_ifindex_get() here, since
         * netsnmp_access_interface_index_find will open/close a socket
         * every time it is called.
         */
        entry->if_index = netsnmp_access_interface_index_find(if_name);
        memset(&addr_info, 0, sizeof(struct address_flag_info));
        addr_info = netsnmp_access_other_info_get(entry->if_index, AF_INET6);

        /*
          #define IPADDRESSSTATUSTC_PREFERRED  1
          #define IPADDRESSSTATUSTC_DEPRECATED  2
          #define IPADDRESSSTATUSTC_INVALID  3
          #define IPADDRESSSTATUSTC_INACCESSIBLE  4
          #define IPADDRESSSTATUSTC_UNKNOWN  5
          #define IPADDRESSSTATUSTC_TENTATIVE  6
          #define IPADDRESSSTATUSTC_DUPLICATE  7
        */
        if((flags & IFA_F_PERMANENT) || (!flags))
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
#ifdef IFA_F_TEMPORARY
        else if(flags & IFA_F_TEMPORARY)
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
#endif
        else if(flags & IFA_F_DEPRECATED)
            entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
        else if(flags & IFA_F_TENTATIVE)
            entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
        else {
            entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
            DEBUGMSGTL(("access:ipaddress:ipv6",
                        "unknown flags 0x%x\n", flags));
        }

        /*
         * if it's not multi, it must be uni.
         *  (an ipv6 address is never broadcast)
         */
        if(addr_info.anycastflg)
            entry->ia_type = IPADDRESSTYPE_ANYCAST;
        else
            entry->ia_type = IPADDRESSTYPE_UNICAST;


        entry->ia_prefix_len = pfx_len;

        /*
         * can we figure out if an address is from DHCP?
         * use manual until then...
         *
         *#define IPADDRESSORIGINTC_OTHER  1
         *#define IPADDRESSORIGINTC_MANUAL  2
         *#define IPADDRESSORIGINTC_DHCP  4
         *#define IPADDRESSORIGINTC_LINKLAYER  5
         *#define IPADDRESSORIGINTC_RANDOM  6
         *
         * are 'local' address assigned by link layer??
         */
         if (!flags)
             entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
#ifdef IFA_F_TEMPORARY
         else if (flags & IFA_F_TEMPORARY)
             entry->ia_origin = IPADDRESSORIGINTC_RANDOM;
#endif
         else if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address))
             entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
         else
             entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

         if(entry->ia_origin == IPADDRESSORIGINTC_LINKLAYER)
            entry->ia_storagetype = STORAGETYPE_PERMANENT;

        /* xxx-rks: what can we do with scope? */
#ifdef HAVE_LINUX_RTNETLINK_H
        if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime
                                                      ,&entry->ia_valid_lifetime, addr) < 0){
           DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n"));
        }
#else
        entry->ia_prefered_lifetime = 0;
        entry->ia_valid_lifetime = 0;
#endif
#ifdef SUPPORT_PREFIX_FLAGS
        {
        prefix_cbx      prefix_val;
        memset(&prefix_val, 0, sizeof(prefix_cbx));
        if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val) < 0) {
           DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n"));
           entry->ia_onlink_flag = 1;  /*Set by default as true*/
           entry->ia_autonomous_flag = 2; /*Set by default as false*/

        } else {
           entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag; 
           entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag;
        }
        }
#else
        entry->ia_onlink_flag = 1;  /*Set by default as true*/
        entry->ia_autonomous_flag = 2; /*Set by default as false*/
#endif

        /*
         * add entry to container
         */
        if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:ipaddress:container","error with ipaddress_entry: insert into container failed.\n"));
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
    }

    fclose(in);

    if(rc<0)
        return rc;

    return idx_offset;
}
Example #8
0
static int _load_v6 (netsnmp_container * container, int idx_offset)
{
    mib2_ipv6AddrEntry_t ip6ae;

    netsnmp_ipaddress_entry *entry;

    req_e req = GET_FIRST;

    int rc = 0;

    DEBUGMSGTL (("access:ipaddress:container", "loading v6... cache %d\n", MIB_IP6_ADDR));
    while ((rc = getMibstat (MIB_IP6_ADDR, &ip6ae, sizeof (ip6ae), req, &Get_everything, NULL)) == 0)
    {
        req = GET_NEXT;
        entry = netsnmp_access_ipaddress_entry_create ();
        if (entry == NULL)
            return (-1);
        if (memcmp ((const void *) &ip6ae.ipv6AddrAddress,
                    (const void *) &in6addr_any, sizeof (ip6ae.ipv6AddrAddress)) == 0)
            continue;

        ip6ae.ipv6AddrIfIndex.o_bytes[ip6ae.ipv6AddrIfIndex.o_length] = '\0';
        DEBUGMSGTL (("access:ipaddress:container", "found if %s\n", ip6ae.ipv6AddrIfIndex.o_bytes));

        /* Obtain interface index */
        entry->if_index = netsnmp_access_interface_index_find (ip6ae.ipv6AddrIfIndex.o_bytes);
        if (entry->if_index == 0)
        {
            DEBUGMSGTL (("access:ipaddress:container", "cannot find if %s\n", ip6ae.ipv6AddrIfIndex.o_bytes));
            netsnmp_access_ipaddress_entry_free (entry);
            return (-2);
        }

        /* Get the address */
        entry->ia_address_len = sizeof (ip6ae.ipv6AddrAddress);
        netsnmp_assert (entry->ia_address_len == 16 && entry->ia_address_len <= sizeof (entry->ia_address));
        memcpy (&entry->ia_address, &ip6ae.ipv6AddrAddress, entry->ia_address_len);

        /* prefix */
        entry->ia_prefix_len = ip6ae.ipv6AddrPfxLength;

        /* type is anycast? (mib2.h: 1 = yes, 2 = no) */
        entry->ia_type = (ip6ae.ipv6AddrAnycastFlag == 1) ? IPADDRESSTYPE_ANYCAST : IPADDRESSTYPE_UNICAST;

        /* origin (mib2.h: 1 = stateless, 2 = stateful, 3 = unknown) */
        DEBUGMSGTL (("access:ipaddress:container", "origin %d\n", ip6ae.ipv6AddrType));
        if (ip6ae.ipv6AddrType == 1)
            entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
        else if (ip6ae.ipv6AddrInfo.ae_flags & IFF_DHCPRUNNING)
            entry->ia_origin = IPADDRESSORIGINTC_DHCP;
        else
            entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

        /* status */
        entry->ia_status = ip6ae.ipv6AddrStatus;

        entry->ns_ia_index = ++idx_offset;

        DEBUGMSGTL (("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n",
                     entry->if_index, entry->ia_address_len));

        if (CONTAINER_INSERT (container, entry) < 0)
        {
            DEBUGMSGTL (("access:ipaddress:container", "unable to insert %s\n", ip6ae.ipv6AddrIfIndex.o_bytes));
            netsnmp_access_ipaddress_entry_free (entry);
            return (-3);
        }
    }
    return (idx_offset);
}
Example #9
0
/*
 * @retval >=idx_offset ok
 * @retval -1 memory allocation error
 * @retval -2 interface lookup error
 * @retval -3 container error
 */
static int _load_v4 (netsnmp_container * container, int idx_offset)
{
    mib2_ipAddrEntry_t ipae;

    netsnmp_ipaddress_entry *entry;

    req_e req = GET_FIRST;

    int rc = 0;

    DEBUGMSGTL (("access:ipaddress:container", "loading v4\n"));
    while ((rc = getMibstat (MIB_IP_ADDR, &ipae, sizeof (ipae), req, &Get_everything, NULL)) == 0)
    {
        req = GET_NEXT;
        entry = netsnmp_access_ipaddress_entry_create ();
        if (entry == NULL)
            return (-1);
        if (ipae.ipAdEntAddr == INADDR_ANY)
            continue;

        ipae.ipAdEntIfIndex.o_bytes[ipae.ipAdEntIfIndex.o_length] = '\0';
        DEBUGMSGTL (("access:ipaddress:container", "found if %s\n", ipae.ipAdEntIfIndex.o_bytes));
        /* Obtain interface index */
        entry->if_index = netsnmp_access_interface_index_find (ipae.ipAdEntIfIndex.o_bytes);
        if (entry->if_index == 0)
        {
            DEBUGMSGTL (("access:ipaddress:container", "cannot find if %s\n", ipae.ipAdEntIfIndex.o_bytes));
            netsnmp_access_ipaddress_entry_free (entry);
            return (-2);
        }

        if (strchr ((const char *) &ipae.ipAdEntIfIndex.o_bytes, ':') != 0)
            entry->flags |= NETSNMP_ACCESS_IPADDRESS_ISALIAS;

        /* Get the address */
        entry->ia_address_len = sizeof (ipae.ipAdEntAddr);
        netsnmp_assert (entry->ia_address_len == 4 && entry->ia_address_len <= sizeof (entry->ia_address));
        memcpy (&entry->ia_address, &ipae.ipAdEntAddr, entry->ia_address_len);

        /* prefix */
        entry->ia_prefix_len = ipae.ipAdEntInfo.ae_subnet_len;

        /* set the Origin */
        if (ipae.ipAdEntInfo.ae_flags & IFF_DHCPRUNNING)
            entry->ia_origin = IPADDRESSORIGINTC_DHCP;
        else
            entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

        /* set ipv4 constants */
        entry->ia_type = IPADDRESSTYPE_UNICAST;
        entry->ia_status = IPADDRESSSTATUSTC_PREFERRED;

        entry->ns_ia_index = ++idx_offset;

        DEBUGMSGTL (("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n",
                     entry->if_index, entry->ia_address_len));

        if (CONTAINER_INSERT (container, entry) < 0)
        {
            DEBUGMSGTL (("access:ipaddress:container", "unable to insert %s\n", ipae.ipAdEntIfIndex.o_bytes));
            netsnmp_access_ipaddress_entry_free (entry);
            return (-3);
        }
    }
    return (idx_offset);
}