Beispiel #1
0
netsnmp_defaultrouter_entry *
netsnmp_access_defaultrouter_entry_create(void)
{
    int rc = 0;
    netsnmp_defaultrouter_entry *entry =
        SNMP_MALLOC_TYPEDEF(netsnmp_defaultrouter_entry);

    DEBUGMSGTL(("access:defaultrouter:entry", "create\n"));

    if(NULL == entry)
        return NULL;

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

    /*
     * set up defaults
     */
    entry->dr_lifetime   = IPDEFAULTROUTERLIFETIME_MAX;
    entry->dr_preference = IPDEFAULTROUTERPREFERENCE_MEDIUM;

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

    return entry;
}
/**
 * extra context cleanup
 *
 */
void
ipDefaultRouterTable_rowreq_ctx_cleanup(ipDefaultRouterTable_rowreq_ctx *
                                        rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipDefaultRouterTable:ipDefaultRouterTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra ipDefaultRouterTable rowreq cleanup.
     */
    netsnmp_access_defaultrouter_entry_free(rowreq_ctx->data);
    rowreq_ctx->data = NULL;
}                               /* ipDefaultRouterTable_rowreq_ctx_cleanup */
/**
 * add new entry
 */
static void
_add_new_entry(netsnmp_defaultrouter_entry *defaultrouter_entry,
               netsnmp_container *container)
{
    ipDefaultRouterTable_rowreq_ctx *rowreq_ctx;

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

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

    /*
     * allocate an row context and set the index(es)
     */
    rowreq_ctx = ipDefaultRouterTable_allocate_rowreq_ctx(defaultrouter_entry,
                                                          NULL);
    if ((NULL != rowreq_ctx) &&
            (MFD_SUCCESS ==
             ipDefaultRouterTable_indexes_set(rowreq_ctx,
                 defaultrouter_entry->dr_addresstype,
                 defaultrouter_entry->dr_address,
                 defaultrouter_entry->dr_address_len,
                 defaultrouter_entry->dr_if_index))) {
        if (CONTAINER_INSERT(container, rowreq_ctx) < 0) {
            DEBUGMSGTL(("ipAddressTable:access",
                         "container insert failed for new entry\n"));
            ipDefaultRouterTable_release_rowreq_ctx(rowreq_ctx);
            return;
        }
    } else {
        if (NULL != rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                    "ipDefaultRouterTable cache.\n");
            ipDefaultRouterTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "ipDefaultRouterTable cache.\n");
            netsnmp_access_defaultrouter_entry_free(defaultrouter_entry);
        }

        return;
    }
}
/**
 * check entry for update
 */
static void _check_entry_for_updates (ipDefaultRouterTable_rowreq_ctx * rowreq_ctx, void **magic)
{
    netsnmp_container *defaultrouter_container = magic[0];

    netsnmp_container *to_delete = (netsnmp_container *) magic[1];

    /*
     * check for matching entry using secondary index.
     */
    netsnmp_defaultrouter_entry *defaultrouter_entry = CONTAINER_FIND (defaultrouter_container, rowreq_ctx->data);

    if (NULL == defaultrouter_entry)
    {
        DEBUGMSGTL (("ipDefaultRouterTable: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 (("ipDefaultRouterTable:access", "updating existing entry\n"));

        /*
         * Check for changes & update
         */
        netsnmp_access_defaultrouter_entry_update (rowreq_ctx->data, defaultrouter_entry);

        /*
         * remove entry from ifcontainer
         */
        CONTAINER_REMOVE (defaultrouter_container, defaultrouter_entry);
        netsnmp_access_defaultrouter_entry_free (defaultrouter_entry);
    }
}
/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load_defaultrouter_from_sysctl(netsnmp_container *container, int family)
{
    netsnmp_defaultrouter_entry *entry;
    struct rt_msghdr *rtm;
    struct sockaddr *dst_sa, *gw_sa;
    char *buf, *lim, *newbuf, *next;
    char address[NETSNMP_ACCESS_DEFAULTROUTER_BUF_SIZE + 1];
    int mib[6];
    size_t address_len, needed;
    int address_type, err, preference, st;

    netsnmp_assert(NULL != container);

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = family;
    mib[4] = NET_RT_DUMP;
    mib[5] = 0;

    err = 0;

    buf = newbuf = NULL;

    if (family == AF_INET) {
        address_len = 4;
        address_type = INETADDRESSTYPE_IPV4;
#ifdef NETSNMP_ENABLE_IPV6
    } else if (family == AF_INET6) {
        address_len = 16;
        address_type = INETADDRESSTYPE_IPV6;
#endif
    } else {
        err = EINVAL;
        goto out;
    }

    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
        err = errno;
        goto out;
    }

    /* Empty arp table. */
    if (needed == 0)
        goto out;

    for (;;) {
        newbuf = realloc(buf, needed);
        if (newbuf == NULL) {
            err = ENOMEM;
            goto out;
        }
        buf = newbuf;
        st = sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0);
        if (st == 0 || errno != ENOMEM)
            break;
        else
            needed += needed / 8; /* XXX: why 8? */
    }
    if (st == -1) {
        err = errno;
        goto out;
    }

    lim = buf + needed;
    for (next = buf; next < lim; next += rtm->rtm_msglen) {
#ifdef NETSNMP_ENABLE_IPV6
	struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif

        rtm = (struct rt_msghdr *)next;

        if (!(rtm->rtm_addrs & RTA_GATEWAY))
            continue;

        dst_sa = (struct sockaddr*)(rtm + 1);
#ifdef SA_SIZE
        gw_sa = (struct sockaddr*)(SA_SIZE(dst_sa) + (char*)dst_sa);
#else
        gw_sa = (struct sockaddr*)(RT_ROUNDUP(dst_sa->sa_len) + (char*)dst_sa);
#endif

        switch (family) {
        case AF_INET:
            if (((struct sockaddr_in*)dst_sa)->sin_addr.s_addr != INADDR_ANY)
                continue;
	    memcpy(address, &((struct sockaddr_in*)gw_sa)->sin_addr.s_addr,
	           address_len);
            break;
#ifdef NETSNMP_ENABLE_IPV6
        case AF_INET6:
            if (memcmp(((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
			&in6addr_any, sizeof in6addr_any) != 0)
		continue; /* XXX: need to determine qualifying criteria for
                       * default gateways in IPv6. */
            memcpy(address, &((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
		   address_len);
            break;
#endif
        default:
            break;
        }

        entry = netsnmp_access_defaultrouter_entry_create();
        if (NULL == entry) {
            err = ENOMEM;
            break;
        }

        /* XXX: this is wrong (hardcoding the router preference to medium). */
        preference = 0;

        entry->ns_dr_index    = ++idx_offset;
        entry->dr_addresstype = address_type;
        entry->dr_address_len = address_len;
        memcpy(entry->dr_address, address, sizeof(address));
        entry->dr_if_index = rtm->rtm_index;
        entry->dr_lifetime    = rtm->rtm_rmx.rmx_expire;
        entry->dr_preference  = preference;

        if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:arp:container",
                        "error with defaultrouter_entry: "
                        "insert into container failed.\n"));
            netsnmp_access_defaultrouter_entry_free(entry);
            goto out;
        }
    }

out:
    free(buf);
    return err;
}
Beispiel #6
0
void
_access_defaultrouter_entry_release(netsnmp_defaultrouter_entry * entry, void *context)
{
    netsnmp_access_defaultrouter_entry_free(entry);
}