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); } } }
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; }