Пример #1
0
static void netsnmp_access_arp_read_netlink(int fd, void *data)
{
    netsnmp_arp_access *access = (netsnmp_arp_access *) data;
    netsnmp_arp_entry *entry;
    char buf[16384];
    struct nlmsghdr *h;
    int r, len;

    do {
        r = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        if (r < 0) {
            if (errno == EINTR)
                continue;
            if (errno == EAGAIN)
                return;
            snmp_log(LOG_WARNING, "netlink buffer overrun\n");
            access->synchronized = 0;
            if (access->cache_expired != NULL)
                *access->cache_expired = 1;
            return;
        }
    } while (0);
    len = r;

    for (h = (struct nlmsghdr *) buf; NLMSG_OK(h, len); h = NLMSG_NEXT(h, len)) {
        if (h->nlmsg_type == NLMSG_DONE) {
            access->synchronized = 1;
            continue;
        }

        entry = netsnmp_access_arp_entry_create();
        if (NULL == entry)
            break;

        DEBUGMSGTL(("access:netlink:arp", "arp netlink notification\n"));

        entry->generation = access->generation;
        r = fillup_entry_info (entry, h);
        if (r > 0) {
            access->update_hook(access, entry);
        } else {
            if (r < 0) {
                NETSNMP_LOGONCE((LOG_ERR, "filling entry info failed\n"));
                DEBUGMSGTL(("access:netlink:arp", "filling entry info failed\n"));
            }
            netsnmp_access_arp_entry_free(entry);
        }
    }
}
Пример #2
0
static int
_load_v6(netsnmp_container *container, int idx_offset)
{
    char              buffer[16384];
#if defined(HAVE_LINUX_RTNETLINK_H)
    struct nlmsghdr   *nlmp;
#endif
    int               sd = 0;
    int               status = 0;
    int               rc = 0;
    int               len, req_len;
    netsnmp_arp_entry *entry;

    netsnmp_assert(NULL != container);
#if defined(HAVE_LINUX_RTNETLINK_H)
    if((sd = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
        snmp_log(LOG_ERR,"Unable to create netlink socket\n");
        return -2;
    }

    if(get_translation_table_info (sd, &status, buffer, sizeof(buffer)) < 0) {
       snmp_log(LOG_ERR,"Unable to fetch translation table info\n");
       close(sd);
       return -2;
    }

    for (nlmp = (struct nlmsghdr *)buffer; status > sizeof(*nlmp); ) {
         len = nlmp->nlmsg_len;
         req_len = len - sizeof(*nlmp);
         if (req_len < 0 || len > status) {
             snmp_log(LOG_ERR,"invalid length\n");
             return -2;
         }
         if (!NLMSG_OK (nlmp, status)) {
             snmp_log(LOG_ERR,"NLMSG not OK\n");
             return -2;
         }
         entry = netsnmp_access_arp_entry_create();
         if(NULL == entry) {
            rc = -3;
            break;
         }
         entry->ns_arp_index = ++idx_offset;
         if(fillup_entry_info (entry, nlmp) < 0) {
            DEBUGMSGTL(("access:arp:load_v6", "skipping netlink message that"
                        " did not contain valid ARP information\n"));
            netsnmp_access_arp_entry_free(entry);
            status -= NLMSG_ALIGN(len);
            nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
            continue;
         }
         CONTAINER_INSERT(container, entry);
         status -= NLMSG_ALIGN(len);
         nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
    }

    close(sd);
#endif
    if(rc<0) {
        return rc;
    }

    return idx_offset;
}