+++ /dev/null
-/* $OpenBSD: kroute.c,v 1.38 2019/01/22 09:25:29 krw Exp $ */
-
-/*
- * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/tree.h>
-#include <sys/uio.h>
-#include <sys/ioctl.h>
-
-#include <net/if.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <arpa/inet.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <event.h>
-
-#include "snmpd.h"
-
-struct ktable **krt;
-u_int krt_size;
-
-struct {
- struct event ks_ev;
- u_long ks_iflastchange;
- u_long ks_nroutes; /* 4 billions enough? */
- int ks_fd;
- int ks_ifd;
- u_short ks_nkif;
-} kr_state;
-
-struct kroute_node {
- RB_ENTRY(kroute_node) entry;
- struct kroute r;
- struct kroute_node *next;
-};
-
-struct kroute6_node {
- RB_ENTRY(kroute6_node) entry;
- struct kroute6 r;
- struct kroute6_node *next;
-};
-
-struct kif_node {
- RB_ENTRY(kif_node) entry;
- TAILQ_HEAD(, kif_addr) addrs;
- TAILQ_HEAD(, kif_arp) arps;
- struct kif k;
-};
-
-int kroute_compare(struct kroute_node *, struct kroute_node *);
-int kroute6_compare(struct kroute6_node *, struct kroute6_node *);
-int kif_compare(struct kif_node *, struct kif_node *);
-
-void ktable_init(void);
-int ktable_new(u_int, u_int);
-void ktable_free(u_int);
-int ktable_exists(u_int, u_int *);
-struct ktable *ktable_get(u_int);
-int ktable_update(u_int);
-
-struct kroute_node *kroute_find(struct ktable *, in_addr_t, u_int8_t,
- u_int8_t);
-struct kroute_node *kroute_matchgw(struct kroute_node *,
- struct sockaddr_in *);
-int kroute_insert(struct ktable *, struct kroute_node *);
-int kroute_remove(struct ktable *, struct kroute_node *);
-void kroute_clear(struct ktable *);
-
-struct kroute6_node *kroute6_find(struct ktable *, const struct in6_addr *,
- u_int8_t, u_int8_t);
-struct kroute6_node *kroute6_matchgw(struct kroute6_node *,
- struct sockaddr_in6 *);
-int kroute6_insert(struct ktable *, struct kroute6_node *);
-int kroute6_remove(struct ktable *, struct kroute6_node *);
-void kroute6_clear(struct ktable *);
-
-struct kif_arp *karp_find(struct sockaddr *, u_short);
-int karp_insert(struct kif_node *, struct kif_arp *);
-int karp_remove(struct kif_node *, struct kif_arp *);
-
-struct kif_node *kif_find(u_short);
-struct kif_node *kif_insert(u_short);
-int kif_remove(struct kif_node *);
-void kif_clear(void);
-struct kif *kif_update(u_short, int, struct if_data *,
- struct sockaddr_dl *);
-
-int ka_compare(struct kif_addr *, struct kif_addr *);
-void ka_insert(u_short, struct kif_addr *);
-struct kif_addr *ka_find(struct sockaddr *);
-int ka_remove(struct kif_addr *);
-
-u_int8_t prefixlen_classful(in_addr_t);
-u_int8_t mask2prefixlen(in_addr_t);
-in_addr_t prefixlen2mask(u_int8_t);
-u_int8_t mask2prefixlen6(struct sockaddr_in6 *);
-struct in6_addr *prefixlen2mask6(u_int8_t);
-void get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
-void if_change(u_short, int, struct if_data *, struct sockaddr_dl *);
-void if_newaddr(u_short, struct sockaddr *, struct sockaddr *,
- struct sockaddr *);
-void if_deladdr(u_short, struct sockaddr *, struct sockaddr *,
- struct sockaddr *);
-void if_announce(void *);
-
-int fetchtable(struct ktable *);
-int fetchifs(u_short);
-int fetcharp(struct ktable *);
-void dispatch_rtmsg(int, short, void *);
-int rtmsg_process(char *, int);
-int dispatch_rtmsg_addr(struct ktable *, struct rt_msghdr *,
- struct sockaddr *[RTAX_MAX]);
-
-RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare)
-RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare)
-
-RB_PROTOTYPE(kroute6_tree, kroute6_node, entry, kroute6_compare)
-RB_GENERATE(kroute6_tree, kroute6_node, entry, kroute6_compare)
-
-RB_HEAD(kif_tree, kif_node) kit;
-RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare)
-RB_GENERATE(kif_tree, kif_node, entry, kif_compare)
-
-RB_HEAD(ka_tree, kif_addr) kat;
-RB_PROTOTYPE(ka_tree, kif_addr, node, ka_compare)
-RB_GENERATE(ka_tree, kif_addr, node, ka_compare)
-
-void
-kr_init(void)
-{
- int opt = 0, rcvbuf, default_rcvbuf;
- unsigned int tid = RTABLE_ANY;
- socklen_t optlen;
-
- if ((kr_state.ks_ifd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- fatal("kr_init: ioctl socket");
-
- if ((kr_state.ks_fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
- fatal("kr_init: route socket");
-
- /* not interested in my own messages */
- if (setsockopt(kr_state.ks_fd, SOL_SOCKET, SO_USELOOPBACK,
- &opt, sizeof(opt)) == -1)
- log_warn("%s: SO_USELOOPBACK", __func__); /* not fatal */
-
- if (snmpd_env->sc_rtfilter && setsockopt(kr_state.ks_fd, AF_ROUTE,
- ROUTE_MSGFILTER, &snmpd_env->sc_rtfilter,
- sizeof(snmpd_env->sc_rtfilter)) == -1)
- log_warn("%s: ROUTE_MSGFILTER", __func__);
-
- /* grow receive buffer, don't wanna miss messages */
- optlen = sizeof(default_rcvbuf);
- if (getsockopt(kr_state.ks_fd, SOL_SOCKET, SO_RCVBUF,
- &default_rcvbuf, &optlen) == -1)
- log_warn("%s: SO_RCVBUF", __func__);
- else
- for (rcvbuf = MAX_RTSOCK_BUF;
- rcvbuf > default_rcvbuf &&
- setsockopt(kr_state.ks_fd, SOL_SOCKET, SO_RCVBUF,
- &rcvbuf, sizeof(rcvbuf)) == -1 && errno == ENOBUFS;
- rcvbuf /= 2)
- ; /* nothing */
-
- if (setsockopt(kr_state.ks_fd, AF_ROUTE, ROUTE_TABLEFILTER, &tid,
- sizeof(tid)) == -1)
- log_warn("%s: ROUTE_TABLEFILTER", __func__);
-
- RB_INIT(&kit);
- RB_INIT(&kat);
-
- if (fetchifs(0) == -1)
- fatalx("kr_init: fetchifs");
-
- ktable_init();
-
- event_set(&kr_state.ks_ev, kr_state.ks_fd, EV_READ | EV_PERSIST,
- dispatch_rtmsg, NULL);
- event_add(&kr_state.ks_ev, NULL);
-}
-
-void
-ktable_init(void)
-{
- u_int i;
-
- for (i = 0; i <= RT_TABLEID_MAX; i++)
- if (ktable_exists(i, NULL))
- ktable_update(i);
-}
-
-int
-ktable_new(u_int rtableid, u_int rdomid)
-{
- struct ktable **xkrt;
- struct ktable *kt;
- size_t newsize, oldsize;
-
- /* resize index table if needed */
- if (rtableid >= krt_size) {
- if ((xkrt = reallocarray(krt, rtableid + 1,
- sizeof(struct ktable *))) == NULL) {
- log_warn("%s: realloc", __func__);
- return (-1);
- }
- krt = xkrt;
- oldsize = krt_size * sizeof(struct ktable *);
- krt_size = rtableid + 1;
- newsize = krt_size * sizeof(struct ktable *);
- bzero((char *)krt + oldsize, newsize - oldsize);
- }
-
- if (krt[rtableid])
- fatalx("ktable_new: table already exists");
-
- /* allocate new element */
- kt = krt[rtableid] = calloc(1, sizeof(struct ktable));
- if (kt == NULL) {
- log_warn("%s: calloc", __func__);
- return (-1);
- }
-
- /* initialize structure ... */
- RB_INIT(&kt->krt);
- RB_INIT(&kt->krt6);
- kt->rtableid = rtableid;
- kt->rdomain = rdomid;
-
- /* ... and load it */
- if (fetchtable(kt) == -1)
- return (-1);
- /* load arp information */
- if (fetcharp(kt) == -1)
- return (-1);
-
- log_debug("%s: new ktable for rtableid %d", __func__, rtableid);
- return (0);
-}
-
-void
-ktable_free(u_int rtableid)
-{
- struct ktable *kt;
-
- if ((kt = ktable_get(rtableid)) == NULL)
- return;
-
- log_debug("%s: freeing ktable rtableid %u", __func__, kt->rtableid);
- kroute_clear(kt);
- kroute6_clear(kt);
-
- krt[kt->rtableid] = NULL;
- free(kt);
-}
-
-struct ktable *
-ktable_get(u_int rtableid)
-{
- if (rtableid >= krt_size)
- return (NULL);
- return (krt[rtableid]);
-}
-
-int
-ktable_update(u_int rtableid)
-{
- struct ktable *kt;
- u_int rdomid;
-
- if (!ktable_exists(rtableid, &rdomid))
- fatalx("ktable_update: table doesn't exist");
-
- if (rdomid != rtableid) {
- if (ktable_get(rdomid) == NULL &&
- ktable_new(rdomid, rdomid) != 0)
- return (-1);
- }
-
- kt = ktable_get(rtableid);
- if (kt == NULL) {
- if (ktable_new(rtableid, rdomid))
- return (-1);
- }
- return (0);
-}
-
-int
-ktable_exists(u_int rtableid, u_int *rdomid)
-{
- size_t len;
- struct rt_tableinfo info;
- int mib[6];
-
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = 0;
- mib[4] = NET_RT_TABLE;
- mib[5] = rtableid;
-
- len = sizeof(info);
- if (sysctl(mib, 6, &info, &len, NULL, 0) == -1) {
- if (errno == ENOENT)
- /* table nonexistent */
- return (0);
- log_warn("%s: sysctl", __func__);
- /* must return 0 so that the table is considered non-existent */
- return (0);
- }
- if (rdomid)
- *rdomid = info.rti_domainid;
- return (1);
-}
-
-void
-kr_shutdown(void)
-{
- u_int i;
-
- for (i = krt_size; i > 0; i--)
- ktable_free(i - 1);
- kif_clear();
-}
-
-u_int
-kr_ifnumber(void)
-{
- return (kr_state.ks_nkif);
-}
-
-u_long
-kr_iflastchange(void)
-{
- return (kr_state.ks_iflastchange);
-}
-
-int
-kr_updateif(u_int if_index)
-{
- return (fetchifs(if_index));
-}
-
-u_long
-kr_routenumber(void)
-{
- return (kr_state.ks_nroutes);
-}
-
-/* rb-tree compare */
-int
-kroute_compare(struct kroute_node *a, struct kroute_node *b)
-{
- if (ntohl(a->r.prefix.s_addr) < ntohl(b->r.prefix.s_addr))
- return (-1);
- if (ntohl(a->r.prefix.s_addr) > ntohl(b->r.prefix.s_addr))
- return (1);
- if (a->r.prefixlen < b->r.prefixlen)
- return (-1);
- if (a->r.prefixlen > b->r.prefixlen)
- return (1);
-
- /* if the priority is RTP_ANY finish on the first address hit */
- if (a->r.priority == RTP_ANY || b->r.priority == RTP_ANY)
- return (0);
- if (a->r.priority < b->r.priority)
- return (-1);
- if (a->r.priority > b->r.priority)
- return (1);
- return (0);
-}
-
-int
-kroute6_compare(struct kroute6_node *a, struct kroute6_node *b)
-{
- int i;
-
- for (i = 0; i < 16; i++) {
- if (a->r.prefix.s6_addr[i] < b->r.prefix.s6_addr[i])
- return (-1);
- if (a->r.prefix.s6_addr[i] > b->r.prefix.s6_addr[i])
- return (1);
- }
-
- if (a->r.prefixlen < b->r.prefixlen)
- return (-1);
- if (a->r.prefixlen > b->r.prefixlen)
- return (1);
-
- /* if the priority is RTP_ANY finish on the first address hit */
- if (a->r.priority == RTP_ANY || b->r.priority == RTP_ANY)
- return (0);
- if (a->r.priority < b->r.priority)
- return (-1);
- if (a->r.priority > b->r.priority)
- return (1);
- return (0);
-}
-
-int
-kif_compare(struct kif_node *a, struct kif_node *b)
-{
- return (a->k.if_index - b->k.if_index);
-}
-
-int
-ka_compare(struct kif_addr *a, struct kif_addr *b)
-{
- if (a->addr.sa.sa_family < b->addr.sa.sa_family)
- return (-1);
- if (a->addr.sa.sa_family > b->addr.sa.sa_family)
- return (1);
- return (memcmp(&a->addr.sa, &b->addr.sa, a->addr.sa.sa_len));
-}
-
-/* tree management */
-struct kroute_node *
-kroute_find(struct ktable *kt, in_addr_t prefix, u_int8_t prefixlen,
- u_int8_t prio)
-{
- struct kroute_node s;
- struct kroute_node *kn, *tmp;
-
- s.r.prefix.s_addr = prefix;
- s.r.prefixlen = prefixlen;
- s.r.priority = prio;
-
- kn = RB_FIND(kroute_tree, &kt->krt, &s);
- if (kn && prio == RTP_ANY) {
- tmp = RB_PREV(kroute_tree, &kt->krt, kn);
- while (tmp) {
- if (kroute_compare(&s, tmp) == 0)
- kn = tmp;
- else
- break;
- tmp = RB_PREV(kroute_tree, &kt->krt, kn);
- }
- }
- return (kn);
-}
-
-struct kroute_node *
-kroute_matchgw(struct kroute_node *kr, struct sockaddr_in *sa_in)
-{
- in_addr_t nexthop;
-
- if (sa_in == NULL) {
- log_warnx("%s: no nexthop defined", __func__);
- return (NULL);
- }
- nexthop = sa_in->sin_addr.s_addr;
-
- while (kr) {
- if (kr->r.nexthop.s_addr == nexthop)
- return (kr);
- kr = kr->next;
- }
-
- return (NULL);
-}
-
-int
-kroute_insert(struct ktable *kt, struct kroute_node *kr)
-{
- struct kroute_node *krm;
-
- if ((krm = RB_INSERT(kroute_tree, &kt->krt, kr)) != NULL) {
- /* multipath route, add at end of list */
- while (krm->next != NULL)
- krm = krm->next;
- krm->next = kr;
- kr->next = NULL; /* to be sure */
- }
-
- kr_state.ks_nroutes++;
- return (0);
-}
-
-int
-kroute_remove(struct ktable *kt, struct kroute_node *kr)
-{
- struct kroute_node *krm;
-
- if ((krm = RB_FIND(kroute_tree, &kt->krt, kr)) == NULL) {
- log_warnx("%s: failed to find %s/%u", __func__,
- inet_ntoa(kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
-
- if (krm == kr) {
- /* head element */
- if (RB_REMOVE(kroute_tree, &kt->krt, kr) == NULL) {
- log_warnx("%s: failed for %s/%u", __func__,
- inet_ntoa(kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
- if (kr->next != NULL) {
- if (RB_INSERT(kroute_tree, &kt->krt, kr->next)
- != NULL) {
- log_warnx("%s: failed to add %s/%u", __func__,
- inet_ntoa(kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
- }
- } else {
- /* somewhere in the list */
- while (krm->next != kr && krm->next != NULL)
- krm = krm->next;
- if (krm->next == NULL) {
- log_warnx("%s: multipath list corrupted for %s/%u",
- __func__, inet_ntoa(kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
- krm->next = kr->next;
- }
-
- kr_state.ks_nroutes--;
- free(kr);
- return (0);
-}
-
-void
-kroute_clear(struct ktable *kt)
-{
- struct kroute_node *kr;
-
- while ((kr = RB_MIN(kroute_tree, &kt->krt)) != NULL)
- kroute_remove(kt, kr);
-}
-
-struct kroute6_node *
-kroute6_find(struct ktable *kt, const struct in6_addr *prefix,
- u_int8_t prefixlen, u_int8_t prio)
-{
- struct kroute6_node s;
- struct kroute6_node *kn6, *tmp;
-
- memcpy(&s.r.prefix, prefix, sizeof(struct in6_addr));
- s.r.prefixlen = prefixlen;
- s.r.priority = prio;
-
- kn6 = RB_FIND(kroute6_tree, &kt->krt6, &s);
- if (kn6 && prio == RTP_ANY) {
- tmp = RB_PREV(kroute6_tree, &kt->krt6, kn6);
- while (tmp) {
- if (kroute6_compare(&s, tmp) == 0)
- kn6 = tmp;
- else
- break;
- tmp = RB_PREV(kroute6_tree, &kt->krt6, kn6);
- }
- }
- return (kn6);
-}
-
-struct kroute6_node *
-kroute6_matchgw(struct kroute6_node *kr, struct sockaddr_in6 *sa_in6)
-{
- struct in6_addr nexthop;
-
- if (sa_in6 == NULL) {
- log_warnx("%s: no nexthop defined", __func__);
- return (NULL);
- }
- memcpy(&nexthop, &sa_in6->sin6_addr, sizeof(nexthop));
-
- while (kr) {
- if (memcmp(&kr->r.nexthop, &nexthop, sizeof(nexthop)) == 0)
- return (kr);
- kr = kr->next;
- }
-
- return (NULL);
-}
-
-int
-kroute6_insert(struct ktable *kt, struct kroute6_node *kr)
-{
- struct kroute6_node *krm;
-
- if ((krm = RB_INSERT(kroute6_tree, &kt->krt6, kr)) != NULL) {
- /* multipath route, add at end of list */
- while (krm->next != NULL)
- krm = krm->next;
- krm->next = kr;
- kr->next = NULL; /* to be sure */
- }
-
- kr_state.ks_nroutes++;
- return (0);
-}
-
-int
-kroute6_remove(struct ktable *kt, struct kroute6_node *kr)
-{
- struct kroute6_node *krm;
-
- if ((krm = RB_FIND(kroute6_tree, &kt->krt6, kr)) == NULL) {
- log_warnx("%s: failed for %s/%u", __func__,
- log_in6addr(&kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
-
- if (krm == kr) {
- /* head element */
- if (RB_REMOVE(kroute6_tree, &kt->krt6, kr) == NULL) {
- log_warnx("%s: failed for %s/%u", __func__,
- log_in6addr(&kr->r.prefix), kr->r.prefixlen);
- return (-1);
- }
- if (kr->next != NULL) {
- if (RB_INSERT(kroute6_tree, &kt->krt6, kr->next) !=
- NULL) {
- log_warnx("%s: failed to add %s/%u", __func__,
- log_in6addr(&kr->r.prefix),
- kr->r.prefixlen);
- return (-1);
- }
- }
- } else {
- /* somewhere in the list */
- while (krm->next != kr && krm->next != NULL)
- krm = krm->next;
- if (krm->next == NULL) {
- log_warnx("%s: multipath list corrupted for %s/%u",
- __func__, log_in6addr(&kr->r.prefix),
- kr->r.prefixlen);
- return (-1);
- }
- krm->next = kr->next;
- }
-
- kr_state.ks_nroutes--;
- free(kr);
- return (0);
-}
-
-void
-kroute6_clear(struct ktable *kt)
-{
- struct kroute6_node *kr;
-
- while ((kr = RB_MIN(kroute6_tree, &kt->krt6)) != NULL)
- kroute6_remove(kt, kr);
-}
-
-static inline int
-karp_compare(struct kif_arp *a, struct kif_arp *b)
-{
- /* Interface indices are assumed equal */
- if (ntohl(a->addr.sin.sin_addr.s_addr) >
- ntohl(b->addr.sin.sin_addr.s_addr))
- return (1);
- if (ntohl(a->addr.sin.sin_addr.s_addr) <
- ntohl(b->addr.sin.sin_addr.s_addr))
- return (-1);
- return (0);
-}
-
-static inline struct kif_arp *
-karp_search(struct kif_node *kn, struct kif_arp *ka)
-{
- struct kif_arp *pivot;
-
- TAILQ_FOREACH(pivot, &kn->arps, entry) {
- switch (karp_compare(ka, pivot)) {
- case 0: /* found */
- return (pivot);
- case -1: /* ka < pivot, end the search */
- return (NULL);
- }
- }
- /* looped through the whole list and didn't find */
- return (NULL);
-}
-
-struct kif_arp *
-karp_find(struct sockaddr *sa, u_short ifindex)
-{
- struct kif_node *kn;
- struct kif_arp *ka = NULL, s;
-
- memcpy(&s.addr.sa, sa, sa->sa_len);
-
- if (ifindex == 0) {
- /*
- * We iterate manually to handle zero ifindex special
- * case differently from kif_find, in particular we
- * want to look for the address on all available
- * interfaces.
- */
- RB_FOREACH(kn, kif_tree, &kit) {
- if ((ka = karp_search(kn, &s)) != NULL)
- break;
- }
- } else {
- if ((kn = kif_find(ifindex)) == NULL)
- return (NULL);
- ka = karp_search(kn, &s);
- }
- return (ka);
-}
-
-int
-karp_insert(struct kif_node *kn, struct kif_arp *ka)
-{
- struct kif_arp *pivot;
-
- if (ka->if_index == 0)
- return (-1);
- if (!kn && (kn = kif_find(ka->if_index)) == NULL)
- return (-1);
- /* Put entry on the list in the ascending lexical order */
- TAILQ_FOREACH(pivot, &kn->arps, entry) {
- switch (karp_compare(ka, pivot)) {
- case 0: /* collision */
- return (-1);
- case -1: /* ka < pivot */
- TAILQ_INSERT_BEFORE(pivot, ka, entry);
- return (0);
- }
- }
- /* ka is larger than any other element on the list */
- TAILQ_INSERT_TAIL(&kn->arps, ka, entry);
- return (0);
-}
-
-int
-karp_remove(struct kif_node *kn, struct kif_arp *ka)
-{
- if (ka->if_index == 0)
- return (-1);
- if (!kn && (kn = kif_find(ka->if_index)) == NULL)
- return (-1);
- TAILQ_REMOVE(&kn->arps, ka, entry);
- free(ka);
- return (0);
-}
-
-struct kif_arp *
-karp_first(u_short ifindex)
-{
- struct kif_node *kn;
-
- if ((kn = kif_find(ifindex)) == NULL)
- return (NULL);
- return (TAILQ_FIRST(&kn->arps));
-}
-
-struct kif_arp *
-karp_getaddr(struct sockaddr *sa, u_short ifindex, int next)
-{
- struct kif_arp *ka;
-
- if ((ka = karp_find(sa, ifindex)) == NULL)
- return (NULL);
- return (next ? TAILQ_NEXT(ka, entry) : ka);
-}
-
-struct kif_node *
-kif_find(u_short if_index)
-{
- struct kif_node s;
-
- if (if_index == 0)
- return (RB_MIN(kif_tree, &kit));
-
- bzero(&s, sizeof(s));
- s.k.if_index = if_index;
-
- return (RB_FIND(kif_tree, &kit, &s));
-}
-
-struct kif *
-kr_getif(u_short if_index)
-{
- struct kif_node *kn;
-
- kn = kif_find(if_index);
- if (kn == NULL)
- return (NULL);
-
- return (&kn->k);
-}
-
-struct kif *
-kr_getnextif(u_short if_index)
-{
- struct kif_node *kn;
-
- if ((kn = kif_find(if_index)) == NULL)
- return (NULL);
- if (if_index)
- kn = RB_NEXT(kif_tree, &kit, kn);
- if (kn == NULL)
- return (NULL);
-
- return (&kn->k);
-}
-
-struct kif_node *
-kif_insert(u_short if_index)
-{
- struct kif_node *kif;
-
- if ((kif = calloc(1, sizeof(struct kif_node))) == NULL)
- return (NULL);
-
- kif->k.if_index = if_index;
- TAILQ_INIT(&kif->addrs);
- TAILQ_INIT(&kif->arps);
-
- if (RB_INSERT(kif_tree, &kit, kif) != NULL)
- fatalx("kif_insert: RB_INSERT");
-
- kr_state.ks_nkif++;
- kr_state.ks_iflastchange = smi_getticks();
-
- return (kif);
-}
-
-int
-kif_remove(struct kif_node *kif)
-{
- struct kif_addr *ka;
- struct kif_arp *kr;
-
- if (RB_REMOVE(kif_tree, &kit, kif) == NULL) {
- log_warnx("%s: RB_REMOVE failed", __func__);
- return (-1);
- }
-
- while ((ka = TAILQ_FIRST(&kif->addrs)) != NULL) {
- TAILQ_REMOVE(&kif->addrs, ka, entry);
- ka_remove(ka);
- }
- while ((kr = TAILQ_FIRST(&kif->arps)) != NULL) {
- karp_remove(kif, kr);
- }
- free(kif);
-
- kr_state.ks_nkif--;
- kr_state.ks_iflastchange = smi_getticks();
-
- return (0);
-}
-
-void
-kif_clear(void)
-{
- struct kif_node *kif;
-
- while ((kif = RB_MIN(kif_tree, &kit)) != NULL)
- kif_remove(kif);
- kr_state.ks_nkif = 0;
- kr_state.ks_iflastchange = smi_getticks();
-}
-
-struct kif *
-kif_update(u_short if_index, int flags, struct if_data *ifd,
- struct sockaddr_dl *sdl)
-{
- struct kif_node *kif;
- struct ether_addr *ea;
- struct ifreq ifr;
-
- if ((kif = kif_find(if_index)) == NULL)
- if ((kif = kif_insert(if_index)) == NULL)
- return (NULL);
-
- kif->k.if_flags = flags;
- bcopy(ifd, &kif->k.if_data, sizeof(struct if_data));
- kif->k.if_ticks = smi_getticks();
-
- if (sdl && sdl->sdl_family == AF_LINK) {
- if (sdl->sdl_nlen >= sizeof(kif->k.if_name))
- memcpy(kif->k.if_name, sdl->sdl_data,
- sizeof(kif->k.if_name) - 1);
- else if (sdl->sdl_nlen > 0)
- memcpy(kif->k.if_name, sdl->sdl_data,
- sdl->sdl_nlen);
- /* string already terminated via calloc() */
-
- if ((ea = (struct ether_addr *)LLADDR(sdl)) != NULL)
- bcopy(&ea->ether_addr_octet, kif->k.if_lladdr,
- ETHER_ADDR_LEN);
- }
-
- bzero(&ifr, sizeof(ifr));
- strlcpy(ifr.ifr_name, kif->k.if_name, sizeof(ifr.ifr_name));
- ifr.ifr_data = (caddr_t)&kif->k.if_descr;
- if (ioctl(kr_state.ks_ifd, SIOCGIFDESCR, &ifr) == -1)
- bzero(&kif->k.if_descr, sizeof(kif->k.if_descr));
-
- return (&kif->k);
-}
-
-void
-ka_insert(u_short if_index, struct kif_addr *ka)
-{
- if (ka->addr.sa.sa_len == 0)
- return;
-
- ka->if_index = if_index;
- RB_INSERT(ka_tree, &kat, ka);
-}
-
-struct kif_addr *
-ka_find(struct sockaddr *sa)
-{
- struct kif_addr ka;
-
- if (sa == NULL)
- return (RB_MIN(ka_tree, &kat));
- bzero(&ka.addr, sizeof(ka.addr));
- bcopy(sa, &ka.addr.sa, sa->sa_len);
- return (RB_FIND(ka_tree, &kat, &ka));
-}
-
-int
-ka_remove(struct kif_addr *ka)
-{
- RB_REMOVE(ka_tree, &kat, ka);
- free(ka);
- return (0);
-}
-
-struct kif_addr *
-kr_getaddr(struct sockaddr *sa)
-{
- return (ka_find(sa));
-}
-
-struct kif_addr *
-kr_getnextaddr(struct sockaddr *sa)
-{
- struct kif_addr *ka;
-
- if ((ka = ka_find(sa)) == NULL)
- return (NULL);
- if (sa)
- ka = RB_NEXT(ka_tree, &kat, ka);
-
- return (ka);
-}
-
-/* misc */
-u_int8_t
-prefixlen_classful(in_addr_t ina)
-{
- /* it hurt to write this. */
-
- if (ina >= 0xf0000000U) /* class E */
- return (32);
- else if (ina >= 0xe0000000U) /* class D */
- return (4);
- else if (ina >= 0xc0000000U) /* class C */
- return (24);
- else if (ina >= 0x80000000U) /* class B */
- return (16);
- else /* class A */
- return (8);
-}
-
-u_int8_t
-mask2prefixlen(in_addr_t ina)
-{
- if (ina == 0)
- return (0);
- else
- return (33 - ffs(ntohl(ina)));
-}
-
-in_addr_t
-prefixlen2mask(u_int8_t prefixlen)
-{
- if (prefixlen == 0)
- return (0);
-
- return (htonl(0xffffffff << (32 - prefixlen)));
-}
-
-u_int8_t
-mask2prefixlen6(struct sockaddr_in6 *sa_in6)
-{
- unsigned int l = 0;
- u_int8_t *ap, *ep;
-
- /*
- * sin6_len is the size of the sockaddr so substract the offset of
- * the possibly truncated sin6_addr struct.
- */
- ap = (u_int8_t *)&sa_in6->sin6_addr;
- ep = (u_int8_t *)sa_in6 + sa_in6->sin6_len;
- for (; ap < ep; ap++) {
- /* this "beauty" is adopted from sbin/route/show.c ... */
- switch (*ap) {
- case 0xff:
- l += 8;
- break;
- case 0xfe:
- l += 7;
- goto done;
- case 0xfc:
- l += 6;
- goto done;
- case 0xf8:
- l += 5;
- goto done;
- case 0xf0:
- l += 4;
- goto done;
- case 0xe0:
- l += 3;
- goto done;
- case 0xc0:
- l += 2;
- goto done;
- case 0x80:
- l += 1;
- goto done;
- case 0x00:
- goto done;
- default:
- fatalx("non contiguous inet6 netmask");
- }
- }
-
-done:
- if (l > sizeof(struct in6_addr) * 8)
- fatalx("inet6 prefixlen out of bound");
- return (l);
-}
-
-struct in6_addr *
-prefixlen2mask6(u_int8_t prefixlen)
-{
- static struct in6_addr mask;
- int i;
-
- bzero(&mask, sizeof(mask));
- for (i = 0; i < prefixlen / 8; i++)
- mask.s6_addr[i] = 0xff;
- i = prefixlen % 8;
- if (i)
- mask.s6_addr[prefixlen / 8] = 0xff00 >> i;
-
- return (&mask);
-}
-
-#define ROUNDUP(a) \
- ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-void
-get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
-{
- int i;
-
- for (i = 0; i < RTAX_MAX; i++) {
- if (addrs & (1 << i)) {
- rti_info[i] = sa;
- sa = (struct sockaddr *)((char *)(sa) +
- ROUNDUP(sa->sa_len));
- } else
- rti_info[i] = NULL;
-
- }
-}
-
-void
-if_change(u_short if_index, int flags, struct if_data *ifd,
- struct sockaddr_dl *sdl)
-{
- if (kif_update(if_index, flags, ifd, sdl) == NULL)
- log_warn("%s: interface %u update failed", __func__, if_index);
-}
-
-void
-if_newaddr(u_short if_index, struct sockaddr *ifa, struct sockaddr *mask,
- struct sockaddr *brd)
-{
- struct kif_node *kif;
- struct kif_addr *ka;
-
- if (ifa == NULL)
- return;
- if ((kif = kif_find(if_index)) == NULL) {
- log_warnx("%s: corresponding if %u not found", __func__,
- if_index);
- return;
- }
- if ((ka = ka_find(ifa)) == NULL) {
- if ((ka = calloc(1, sizeof(struct kif_addr))) == NULL)
- fatal("if_newaddr");
- bcopy(ifa, &ka->addr.sa, ifa->sa_len);
- TAILQ_INSERT_TAIL(&kif->addrs, ka, entry);
- ka_insert(if_index, ka);
- }
-
- if (mask)
- bcopy(mask, &ka->mask.sa, mask->sa_len);
- else
- bzero(&ka->mask, sizeof(ka->mask));
- if (brd)
- bcopy(brd, &ka->dstbrd.sa, brd->sa_len);
- else
- bzero(&ka->dstbrd, sizeof(ka->dstbrd));
-}
-
-void
-if_deladdr(u_short if_index, struct sockaddr *ifa, struct sockaddr *mask,
- struct sockaddr *brd)
-{
- struct kif_node *kif;
- struct kif_addr *ka;
-
- if (ifa == NULL)
- return;
- if ((kif = kif_find(if_index)) == NULL) {
- log_warnx("%s: corresponding if %u not found", __func__,
- if_index);
- return;
- }
- if ((ka = ka_find(ifa)) == NULL)
- return;
-
- TAILQ_REMOVE(&kif->addrs, ka, entry);
- ka_remove(ka);
-}
-
-void
-if_announce(void *msg)
-{
- struct if_announcemsghdr *ifan;
- struct kif_node *kif;
-
- ifan = msg;
-
- switch (ifan->ifan_what) {
- case IFAN_ARRIVAL:
- kif = kif_insert(ifan->ifan_index);
- strlcpy(kif->k.if_name, ifan->ifan_name,
- sizeof(kif->k.if_name));
- break;
- case IFAN_DEPARTURE:
- kif = kif_find(ifan->ifan_index);
- kif_remove(kif);
- break;
- }
-}
-
-int
-fetchtable(struct ktable *kt)
-{
- int mib[7];
- size_t len;
- char *buf;
- int rv;
-
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = AF_INET;
- mib[4] = NET_RT_DUMP;
- mib[5] = 0;
- mib[6] = kt->rtableid;
-
- if (sysctl(mib, 7, NULL, &len, NULL, 0) == -1) {
- if (kt->rtableid != 0 && errno == EINVAL)
- /* table nonexistent */
- return (0);
- log_warn("%s: failed to fetch routing table %u size", __func__,
- kt->rtableid);
- return (-1);
- }
- if (len == 0)
- return (0);
- if ((buf = malloc(len)) == NULL) {
- log_warn("%s: malloc", __func__);
- return (-1);
- }
- if (sysctl(mib, 7, buf, &len, NULL, 0) == -1) {
- log_warn("%s: failed to fetch routing table %u", __func__,
- kt->rtableid);
- free(buf);
- return (-1);
- }
-
- rv = rtmsg_process(buf, len);
- free(buf);
-
- return (rv);
-}
-
-int
-fetchifs(u_short if_index)
-{
- size_t len;
- int mib[6];
- char *buf;
- int rv;
-
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = 0; /* wildcard address family */
- mib[4] = NET_RT_IFLIST;
- mib[5] = if_index;
-
- if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
- log_warn("%s: failed to fetch address table size for %u",
- __func__, if_index);
- return (-1);
- }
- if ((buf = malloc(len)) == NULL) {
- log_warn("%s: malloc", __func__);
- return (-1);
- }
- if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) {
- log_warn("%s: failed to fetch address table for %u",
- __func__, if_index);
- free(buf);
- return (-1);
- }
-
- rv = rtmsg_process(buf, len);
- free(buf);
-
- return (rv);
-}
-
-int
-fetcharp(struct ktable *kt)
-{
- size_t len;
- int mib[7];
- char *buf;
- int rv;
-
- mib[0] = CTL_NET;
- mib[1] = PF_ROUTE;
- mib[2] = 0;
- mib[3] = AF_INET;
- mib[4] = NET_RT_FLAGS;
- mib[5] = RTF_LLINFO;
- mib[6] = kt->rtableid;
-
- if (sysctl(mib, 7, NULL, &len, NULL, 0) == -1) {
- log_warn("%s: failed to fetch arp table %u size", __func__,
- kt->rtableid);
- return (-1);
- }
- /* Empty table? */
- if (len == 0)
- return (0);
- if ((buf = malloc(len)) == NULL) {
- log_warn("%s: malloc", __func__);
- return (-1);
- }
- if (sysctl(mib, 7, buf, &len, NULL, 0) == -1) {
- log_warn("%s: failed to fetch arp table %u", __func__,
- kt->rtableid);
- free(buf);
- return (-1);
- }
-
- rv = rtmsg_process(buf, len);
- free(buf);
-
- return (rv);
-}
-
-/* ARGSUSED */
-void
-dispatch_rtmsg(int fd, short event, void *arg)
-{
- char buf[RT_BUF_SIZE];
- ssize_t n;
-
- if ((n = read(fd, &buf, sizeof(buf))) == -1) {
- log_warn("%s: read error", __func__);
- return;
- }
-
- if (n == 0) {
- log_warnx("%s: routing socket closed", __func__);
- return;
- }
-
- rtmsg_process(buf, n);
-}
-
-int
-rtmsg_process(char *buf, int len)
-{
- struct ktable *kt;
- struct rt_msghdr *rtm;
- struct if_msghdr ifm;
- struct ifa_msghdr *ifam;
- struct sockaddr *sa, *rti_info[RTAX_MAX];
- int offset;
- char *next;
-
- for (offset = 0; offset < len; offset += rtm->rtm_msglen) {
- next = buf + offset;
- rtm = (struct rt_msghdr *)next;
- if (rtm->rtm_version != RTM_VERSION)
- continue;
-
- sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
- get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
-
- switch (rtm->rtm_type) {
- case RTM_ADD:
- case RTM_GET:
- case RTM_CHANGE:
- case RTM_DELETE:
- case RTM_RESOLVE:
- if (rtm->rtm_errno) /* failed attempts */
- continue;
-
- if ((kt = ktable_get(rtm->rtm_tableid)) == NULL)
- continue;
-
- if (dispatch_rtmsg_addr(kt, rtm, rti_info) == -1)
- return (-1);
- break;
- case RTM_IFINFO:
- memcpy(&ifm, next, sizeof(ifm));
- if_change(ifm.ifm_index, ifm.ifm_flags, &ifm.ifm_data,
- (struct sockaddr_dl *)rti_info[RTAX_IFP]);
- break;
- case RTM_DELADDR:
- ifam = (struct ifa_msghdr *)rtm;
- if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
- RTA_BRD)) == 0)
- break;
-
- if_deladdr(ifam->ifam_index, rti_info[RTAX_IFA],
- rti_info[RTAX_NETMASK], rti_info[RTAX_BRD]);
- break;
- case RTM_NEWADDR:
- ifam = (struct ifa_msghdr *)rtm;
- if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
- RTA_BRD)) == 0)
- break;
-
- if_newaddr(ifam->ifam_index, rti_info[RTAX_IFA],
- rti_info[RTAX_NETMASK], rti_info[RTAX_BRD]);
- break;
- case RTM_IFANNOUNCE:
- if_announce(next);
- break;
- case RTM_DESYNC:
- kr_shutdown();
- if (fetchifs(0) == -1)
- fatalx("rtmsg_process: fetchifs");
- ktable_init();
- break;
- default:
- /* ignore for now */
- break;
- }
- }
-
- return (offset);
-}
-
-int
-dispatch_rtmsg_addr(struct ktable *kt, struct rt_msghdr *rtm,
- struct sockaddr *rti_info[RTAX_MAX])
-{
- struct sockaddr *sa, *psa;
- struct sockaddr_in *sa_in, *psa_in = NULL;
- struct sockaddr_in6 *sa_in6, *psa_in6 = NULL;
- struct sockaddr_dl *sa_dl;
- struct kroute_node *kr;
- struct kroute6_node *kr6;
- struct kif_arp *ka;
- int flags, mpath = 0;
- u_int16_t ifindex;
- u_int8_t prefixlen;
- u_int8_t prio;
-
- flags = 0;
- ifindex = 0;
- prefixlen = 0;
-
- if ((psa = rti_info[RTAX_DST]) == NULL)
- return (-1);
-
- if (rtm->rtm_flags & RTF_STATIC)
- flags |= F_STATIC;
- if (rtm->rtm_flags & RTF_BLACKHOLE)
- flags |= F_BLACKHOLE;
- if (rtm->rtm_flags & RTF_REJECT)
- flags |= F_REJECT;
- if (rtm->rtm_flags & RTF_DYNAMIC)
- flags |= F_DYNAMIC;
-#ifdef RTF_MPATH
- if (rtm->rtm_flags & RTF_MPATH)
- mpath = 1;
-#endif
-
- prio = rtm->rtm_priority;
- switch (psa->sa_family) {
- case AF_INET:
- psa_in = (struct sockaddr_in *)psa;
- sa_in = (struct sockaddr_in *)rti_info[RTAX_NETMASK];
- if (sa_in != NULL) {
- if (sa_in->sin_len != 0)
- prefixlen = mask2prefixlen(
- sa_in->sin_addr.s_addr);
- } else if (rtm->rtm_flags & RTF_HOST)
- prefixlen = 32;
- else
- prefixlen =
- prefixlen_classful(psa_in->sin_addr.s_addr);
- break;
- case AF_INET6:
- psa_in6 = (struct sockaddr_in6 *)psa;
- sa_in6 = (struct sockaddr_in6 *)rti_info[RTAX_NETMASK];
- if (sa_in6 != NULL) {
- if (sa_in6->sin6_len != 0)
- prefixlen = mask2prefixlen6(sa_in6);
- } else if (rtm->rtm_flags & RTF_HOST)
- prefixlen = 128;
- else
- fatalx("in6 net addr without netmask");
- break;
- default:
- return (0);
- }
-
- if ((sa = rti_info[RTAX_GATEWAY]) != NULL)
- switch (sa->sa_family) {
- case AF_INET:
- case AF_INET6:
- if (rtm->rtm_flags & RTF_CONNECTED) {
- flags |= F_CONNECTED;
- ifindex = rtm->rtm_index;
- }
- mpath = 0; /* link local stuff can't be mpath */
- break;
- case AF_LINK:
- /*
- * Traditional BSD connected routes have
- * a gateway of type AF_LINK.
- */
- flags |= F_CONNECTED;
- ifindex = rtm->rtm_index;
- mpath = 0; /* link local stuff can't be mpath */
- break;
- }
-
- if (rtm->rtm_type == RTM_DELETE) {
- if (sa != NULL && sa->sa_family == AF_LINK &&
- (rtm->rtm_flags & RTF_HOST) &&
- psa->sa_family == AF_INET) {
- if ((ka = karp_find(psa, ifindex)) == NULL)
- return (0);
- if (karp_remove(NULL, ka) == -1)
- return (-1);
- return (0);
- } else if (sa == NULL && (rtm->rtm_flags & RTF_HOST) &&
- psa->sa_family == AF_INET) {
- if ((ka = karp_find(psa, ifindex)) != NULL)
- karp_remove(NULL, ka);
- /* Continue to the route section below */
- }
- switch (psa->sa_family) {
- case AF_INET:
- sa_in = (struct sockaddr_in *)sa;
- if ((kr = kroute_find(kt, psa_in->sin_addr.s_addr,
- prefixlen, prio)) == NULL)
- return (0);
-
- if (mpath)
- /* get the correct route */
- if ((kr = kroute_matchgw(kr, sa_in)) == NULL) {
- log_warnx("%s[delete]: "
- "mpath route not found", __func__);
- return (0);
- }
-
- if (kroute_remove(kt, kr) == -1)
- return (-1);
- break;
- case AF_INET6:
- sa_in6 = (struct sockaddr_in6 *)sa;
- if ((kr6 = kroute6_find(kt, &psa_in6->sin6_addr,
- prefixlen, prio)) == NULL)
- return (0);
-
- if (mpath)
- /* get the correct route */
- if ((kr6 = kroute6_matchgw(kr6, sa_in6)) ==
- NULL) {
- log_warnx("%s[delete]: "
- "IPv6 mpath route not found",
- __func__);
- return (0);
- }
-
- if (kroute6_remove(kt, kr6) == -1)
- return (-1);
- break;
- }
- return (0);
- }
-
- if (sa == NULL && !(flags & F_CONNECTED))
- return (0);
-
- /* Add or update an ARP entry */
- if ((rtm->rtm_flags & RTF_LLINFO) && (rtm->rtm_flags & RTF_HOST) &&
- sa != NULL && sa->sa_family == AF_LINK &&
- psa->sa_family == AF_INET) {
- sa_dl = (struct sockaddr_dl *)sa;
- /* ignore incomplete entries */
- if (!sa_dl->sdl_alen)
- return (0);
- /* ignore entries that do not specify an interface */
- if (ifindex == 0)
- return (0);
- if ((ka = karp_find(psa, ifindex)) != NULL) {
- memcpy(&ka->target.sdl, sa_dl, sa_dl->sdl_len);
- if (rtm->rtm_flags & RTF_PERMANENT_ARP)
- flags |= F_STATIC;
- ka->flags = flags;
- } else {
- if ((ka = calloc(1, sizeof(struct kif_arp))) == NULL) {
- log_warn("%s: calloc", __func__);
- return (-1);
- }
- memcpy(&ka->addr.sa, psa, psa->sa_len);
- memcpy(&ka->target.sdl, sa_dl, sa_dl->sdl_len);
- if (rtm->rtm_flags & RTF_PERMANENT_ARP)
- flags |= F_STATIC;
- ka->flags = flags;
- ka->if_index = ifindex;
- if (karp_insert(NULL, ka)) {
- free(ka);
- log_warnx("%s: failed to insert", __func__);
- return (-1);
- }
- }
- return (0);
- }
-
- switch (psa->sa_family) {
- case AF_INET:
- sa_in = (struct sockaddr_in *)sa;
- if ((kr = kroute_find(kt, psa_in->sin_addr.s_addr, prefixlen,
- prio)) != NULL) {
- /* get the correct route */
- if (mpath && rtm->rtm_type == RTM_CHANGE &&
- (kr = kroute_matchgw(kr, sa_in)) == NULL) {
- log_warnx("%s[change]: "
- "mpath route not found", __func__);
- return (-1);
- } else if (mpath && rtm->rtm_type == RTM_ADD)
- goto add4;
-
- if (sa_in != NULL)
- kr->r.nexthop.s_addr =
- sa_in->sin_addr.s_addr;
- else
- kr->r.nexthop.s_addr = 0;
- kr->r.flags = flags;
- kr->r.if_index = ifindex;
- kr->r.ticks = smi_getticks();
- } else {
-add4:
- if ((kr = calloc(1,
- sizeof(struct kroute_node))) == NULL) {
- log_warn("%s: calloc", __func__);
- return (-1);
- }
- kr->r.prefix.s_addr = psa_in->sin_addr.s_addr;
- kr->r.prefixlen = prefixlen;
- if (sa_in != NULL)
- kr->r.nexthop.s_addr = sa_in->sin_addr.s_addr;
- else
- kr->r.nexthop.s_addr = 0;
- kr->r.flags = flags;
- kr->r.if_index = ifindex;
- kr->r.ticks = smi_getticks();
- kr->r.priority = prio;
-
- kroute_insert(kt, kr);
- }
- break;
- case AF_INET6:
- sa_in6 = (struct sockaddr_in6 *)sa;
- if ((kr6 = kroute6_find(kt, &psa_in6->sin6_addr, prefixlen,
- prio)) != NULL) {
- /* get the correct route */
- if (mpath && rtm->rtm_type == RTM_CHANGE &&
- (kr6 = kroute6_matchgw(kr6, sa_in6)) ==
- NULL) {
- log_warnx("%s[change]: "
- "IPv6 mpath route not found", __func__);
- return (-1);
- } else if (mpath && rtm->rtm_type == RTM_ADD)
- goto add6;
-
- if (sa_in6 != NULL)
- memcpy(&kr6->r.nexthop,
- &sa_in6->sin6_addr,
- sizeof(struct in6_addr));
- else
- memcpy(&kr6->r.nexthop,
- &in6addr_any,
- sizeof(struct in6_addr));
-
- kr6->r.flags = flags;
- kr6->r.if_index = ifindex;
- kr6->r.ticks = smi_getticks();
- } else {
-add6:
- if ((kr6 = calloc(1,
- sizeof(struct kroute6_node))) == NULL) {
- log_warn("%s: calloc", __func__);
- return (-1);
- }
- memcpy(&kr6->r.prefix, &psa_in6->sin6_addr,
- sizeof(struct in6_addr));
- kr6->r.prefixlen = prefixlen;
- if (sa_in6 != NULL)
- memcpy(&kr6->r.nexthop, &sa_in6->sin6_addr,
- sizeof(struct in6_addr));
- else
- memcpy(&kr6->r.nexthop, &in6addr_any,
- sizeof(struct in6_addr));
- kr6->r.flags = flags;
- kr6->r.if_index = ifindex;
- kr6->r.ticks = smi_getticks();
- kr6->r.priority = prio;
-
- kroute6_insert(kt, kr6);
- }
- break;
- }
-
- return (0);
-}
-
-struct kroute *
-kroute_first(void)
-{
- struct kroute_node *kn;
- struct ktable *kt;
-
- if ((kt = ktable_get(0)) == NULL)
- return (NULL);
- kn = RB_MIN(kroute_tree, &kt->krt);
- return (&kn->r);
-}
-
-struct kroute *
-kroute_getaddr(in_addr_t prefix, u_int8_t prefixlen, u_int8_t prio, int next)
-{
- struct kroute_node *kn;
- struct ktable *kt;
-
- if ((kt = ktable_get(0)) == NULL)
- return (NULL);
- kn = kroute_find(kt, prefix, prefixlen, prio);
- if (kn != NULL && next)
- kn = RB_NEXT(kroute_tree, &kt->krt, kn);
- if (kn != NULL)
- return (&kn->r);
- else
- return (NULL);
-}
-/* $OpenBSD: mib.c,v 1.104 2022/09/01 14:34:17 martijn Exp $ */
+/* $OpenBSD: mib.c,v 1.105 2022/10/06 14:41:08 martijn Exp $ */
/*
* Copyright (c) 2012 Joel Knight <joel@openbsd.org>
int mib_setsnmp(struct oid *, struct ber_oid *, struct ber_element **);
static struct oid mib_tree[] = MIB_TREE;
-static struct ber_oid zerodotzero = { { 0, 0 }, 2 };
/* base MIB tree */
static struct oid base_mib[] = {
{ MIB(sysDescr), OID_RD, mib_getsys },
{ MIB(sysOID), OID_RD, mib_getsys },
{ MIB(sysUpTime), OID_RD, mib_getsys },
- { MIB(sysContact), OID_RW, mib_getsys, mps_setstr },
- { MIB(sysName), OID_RW, mib_getsys, mps_setstr },
- { MIB(sysLocation), OID_RW, mib_getsys, mps_setstr },
+ { MIB(sysContact), OID_RD, mib_getsys },
+ { MIB(sysName), OID_RD, mib_getsys },
+ { MIB(sysLocation), OID_RD, mib_getsys },
{ MIB(sysServices), OID_RS, mib_getsys },
{ MIB(sysORLastChange), OID_RD, mps_getts },
{ MIB(sysORIndex), OID_TRD, mib_sysor },
{ MIB(snmpOutSetRequests), OID_RD, mib_getsnmp },
{ MIB(snmpOutGetResponses), OID_RD, mib_getsnmp },
{ MIB(snmpOutTraps), OID_RD, mib_getsnmp },
- { MIB(snmpEnableAuthenTraps), OID_RW, mib_getsnmp, mib_setsnmp },
+ { MIB(snmpEnableAuthenTraps), OID_RD, mib_getsnmp },
{ MIB(snmpSilentDrops), OID_RD, mib_getsnmp },
{ MIB(snmpProxyDrops), OID_RD, mib_getsnmp },
{ MIBEND }
return (-1);
}
-/*
- * Defined in HOST-RESOURCES-MIB.txt (RFC 2790)
- */
-
-int mib_hrsystemuptime(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrsystemdate(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrsystemprocs(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrmemory(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrstorage(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrdevice(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrprocessor(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_hrswrun(struct oid *, struct ber_oid *, struct ber_element **);
-
-int kinfo_proc_comp(const void *, const void *);
-int kinfo_proc(u_int32_t, struct kinfo_proc **);
-void kinfo_timer_cb(int, short, void *);
-void kinfo_proc_free(void);
-int kinfo_args(struct kinfo_proc *, char **);
-
-static struct oid hr_mib[] = {
- { MIB(host), OID_MIB },
- { MIB(hrSystemUptime), OID_RD, mib_hrsystemuptime },
- { MIB(hrSystemDate), OID_RD, mib_hrsystemdate },
- { MIB(hrSystemProcesses), OID_RD, mib_hrsystemprocs },
- { MIB(hrSystemMaxProcesses), OID_RD, mib_hrsystemprocs },
- { MIB(hrMemorySize), OID_RD, mib_hrmemory },
- { MIB(hrStorageIndex), OID_TRD, mib_hrstorage },
- { MIB(hrStorageType), OID_TRD, mib_hrstorage },
- { MIB(hrStorageDescr), OID_TRD, mib_hrstorage },
- { MIB(hrStorageAllocationUnits), OID_TRD, mib_hrstorage },
- { MIB(hrStorageSize), OID_TRD, mib_hrstorage },
- { MIB(hrStorageUsed), OID_TRD, mib_hrstorage },
- { MIB(hrStorageAllocationFailures), OID_TRD, mib_hrstorage },
- { MIB(hrDeviceIndex), OID_TRD, mib_hrdevice },
- { MIB(hrDeviceType), OID_TRD, mib_hrdevice },
- { MIB(hrDeviceDescr), OID_TRD, mib_hrdevice },
- { MIB(hrDeviceID), OID_TRD, mib_hrdevice },
- { MIB(hrDeviceStatus), OID_TRD, mib_hrdevice },
- { MIB(hrDeviceErrors), OID_TRD, mib_hrdevice },
- { MIB(hrProcessorFrwID), OID_TRD, mib_hrprocessor },
- { MIB(hrProcessorLoad), OID_TRD, mib_hrprocessor },
- { MIB(hrSWRunIndex), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunName), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunID), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunPath), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunParameters), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunType), OID_TRD, mib_hrswrun },
- { MIB(hrSWRunStatus), OID_TRD, mib_hrswrun },
- { MIBEND }
-};
-
-int
-mib_hrsystemuptime(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct timespec uptime;
- long long ticks;
-
- if (clock_gettime(CLOCK_BOOTTIME, &uptime) == -1)
- return (-1);
- ticks = uptime.tv_sec * 100 + uptime.tv_nsec / 10000000;
- *elm = ober_add_integer(*elm, ticks);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
-
- return (0);
-}
-
-int
-mib_hrsystemdate(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct tm *ptm;
- u_char s[11];
- time_t now;
- int tzoffset;
- unsigned short year;
-
- (void)time(&now);
- ptm = localtime(&now);
-
- year = htons(ptm->tm_year + 1900);
- memcpy(s, &year, 2);
- s[2] = ptm->tm_mon + 1;
- s[3] = ptm->tm_mday;
- s[4] = ptm->tm_hour;
- s[5] = ptm->tm_min;
- s[6] = ptm->tm_sec;
- s[7] = 0;
-
- tzoffset = ptm->tm_gmtoff;
- if (tzoffset < 0)
- s[8] = '-';
- else
- s[8] = '+';
-
- s[9] = abs(tzoffset) / 3600;
- s[10] = (abs(tzoffset) - (s[9] * 3600)) / 60;
-
- *elm = ober_add_nstring(*elm, s, sizeof(s));
-
- return (0);
-}
-
-int
-mib_hrsystemprocs(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- char errbuf[_POSIX2_LINE_MAX];
- int val;
- int mib[] = { CTL_KERN, KERN_MAXPROC };
- kvm_t *kd;
- size_t len;
-
- switch (oid->o_oid[OIDIDX_hrsystem]) {
- case 6:
- if ((kd = kvm_openfiles(NULL, NULL, NULL,
- KVM_NO_FILES, errbuf)) == NULL)
- return (-1);
-
- if (kvm_getprocs(kd, KERN_PROC_ALL, 0,
- sizeof(struct kinfo_proc), &val) == NULL) {
- kvm_close(kd);
- return (-1);
- }
-
- *elm = ober_add_integer(*elm, val);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
-
- kvm_close(kd);
- break;
- case 7:
- len = sizeof(val);
- if (sysctl(mib, 2, &val, &len, NULL, 0) == -1)
- return (-1);
-
- *elm = ober_add_integer(*elm, val);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_hrmemory(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- int mib[] = { CTL_HW, HW_PHYSMEM64 };
- u_int64_t physmem;
- size_t len = sizeof(physmem);
-
- if (sysctl(mib, nitems(mib), &physmem, &len, NULL, 0) == -1)
- return (-1);
-
- ber = ober_add_integer(ber, physmem / 1024);
-
- return (0);
-}
-
-int
-mib_hrstorage(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx;
- struct statfs *mntbuf, *mnt;
- int mntsize, maxsize;
- u_int64_t units, size, used, fail = 0;
- const char *descr = NULL;
- int mib[] = { CTL_HW, 0 };
- u_int64_t physmem, realmem;
- struct uvmexp uvm;
- size_t len;
- static struct ber_oid *sop, so[] = {
- { { MIB_hrStorageOther } },
- { { MIB_hrStorageRam } },
- { { MIB_hrStorageVirtualMemory } },
- { { MIB_hrStorageFixedDisk } }
- };
-
- /* Physical memory, real memory, swap */
- mib[1] = HW_PHYSMEM64;
- len = sizeof(physmem);
- if (sysctl(mib, nitems(mib), &physmem, &len, NULL, 0) == -1)
- return (-1);
- mib[1] = HW_USERMEM64;
- len = sizeof(realmem);
- if (sysctl(mib, nitems(mib), &realmem, &len, NULL, 0) == -1)
- return (-1);
- mib[0] = CTL_VM;
- mib[1] = VM_UVMEXP;
- len = sizeof(uvm);
- if (sysctl(mib, nitems(mib), &uvm, &len, NULL, 0) == -1)
- return (-1);
- maxsize = 10;
-
- /* Disks */
- mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
- if (mntsize)
- maxsize = 30 + mntsize;
-
- /*
- * Get and verify the current row index.
- *
- * We use a special mapping here that is inspired by other SNMP
- * agents: index 1 + 2 for RAM, index 10 for swap, index 31 and
- * higher for disk storage.
- */
- idx = o->bo_id[OIDIDX_hrStorageEntry];
- if (idx > (u_int)maxsize)
- return (1);
- else if (idx > 2 && idx < 10)
- idx = 10;
- else if (idx > 10 && idx < 31)
- idx = 31;
-
- sop = &so[0];
- switch (idx) {
- case 0:
- return (-1);
- case 1:
- descr = "Physical memory";
- units = uvm.pagesize;
- size = physmem / uvm.pagesize;
- used = size - uvm.free;
- sop = &so[1];
- break;
- case 2:
- descr = "Real memory";
- units = uvm.pagesize;
- size = realmem / uvm.pagesize;
- used = size - uvm.free;
- sop = &so[1];
- break;
- case 10:
- descr = "Swap space";
- units = uvm.pagesize;
- size = uvm.swpages;
- used = uvm.swpginuse;
- sop = &so[2];
- break;
- default:
- mnt = &mntbuf[idx - 31];
- descr = mnt->f_mntonname;
- units = mnt->f_bsize;
- size = mnt->f_blocks;
- used = mnt->f_blocks - mnt->f_bfree;
- sop = &so[3];
- break;
- }
-
- while (size > INT32_MAX) {
- units *= 2;
- size /= 2;
- used /= 2;
- }
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_hrStorageEntry] = idx;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_hrStorage]) {
- case 1: /* hrStorageIndex */
- ber = ober_add_integer(ber, idx);
- break;
- case 2: /* hrStorageType */
- smi_oidlen(sop);
- ber = ober_add_oid(ber, sop);
- break;
- case 3: /* hrStorageDescr */
- ber = ober_add_string(ber, descr);
- break;
- case 4: /* hrStorageAllocationUnits */
- ber = ober_add_integer(ber, units);
- break;
- case 5: /* hrStorageSize */
- ber = ober_add_integer(ber, size);
- break;
- case 6: /* hrStorageUsed */
- ber = ober_add_integer(ber, used);
- break;
- case 7: /* hrStorageAllocationFailures */
- ber = ober_add_integer(ber, fail);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_hrdevice(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx, fail = 0;
- int status;
- int mib[] = { CTL_HW, HW_MODEL };
- size_t len;
- char descr[BUFSIZ];
- static struct ber_oid *sop, so[] = {
- { { MIB_hrDeviceProcessor } },
- };
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_hrDeviceEntry];
- if (idx > (u_int)snmpd_env->sc_ncpu)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_hrDeviceEntry] = idx;
- ber = ober_add_oid(ber, o);
-
- len = sizeof(descr);
- if (sysctl(mib, nitems(mib), &descr, &len, NULL, 0) == -1)
- return (-1);
- /* unknown(1), running(2), warning(3), testing(4), down(5) */
- status = 2;
- sop = &so[0];
-
- switch (o->bo_id[OIDIDX_hrDevice]) {
- case 1: /* hrDeviceIndex */
- ber = ober_add_integer(ber, idx);
- break;
- case 2: /* hrDeviceType */
- smi_oidlen(sop);
- ber = ober_add_oid(ber, sop);
- break;
- case 3: /* hrDeviceDescr */
- ber = ober_add_string(ber, descr);
- break;
- case 4: /* hrDeviceID */
- ber = ober_add_oid(ber, &zerodotzero);
- break;
- case 5: /* hrDeviceStatus */
- ber = ober_add_integer(ber, status);
- break;
- case 6: /* hrDeviceErrors */
- ber = ober_add_integer(ber, fail);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_hrprocessor(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx;
- int64_t *cptime2, val;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_hrDeviceEntry];
- if (idx > (u_int)snmpd_env->sc_ncpu)
- return (1);
- else if (idx < 1)
- idx = 1;
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_hrDeviceEntry] = idx;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_hrDevice]) {
- case 1: /* hrProcessorFrwID */
- ber = ober_add_oid(ber, &zerodotzero);
- break;
- case 2: /* hrProcessorLoad */
- /*
- * The percentage of time that the system was not
- * idle during the last minute.
- */
- if (snmpd_env->sc_cpustates == NULL)
- return (-1);
- cptime2 = snmpd_env->sc_cpustates + (CPUSTATES * (idx - 1));
- val = 100 -
- (cptime2[CP_IDLE] > 1000 ? 1000 : (cptime2[CP_IDLE] / 10));
- ber = ober_add_integer(ber, val);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_hrswrun(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct kinfo_proc *kinfo;
- char *s;
-
- /* Get and verify the current row index */
- if (kinfo_proc(o->bo_id[OIDIDX_hrSWRunEntry], &kinfo) == -1)
- return (1);
-
- if (kinfo == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_hrSWRunEntry] = kinfo->p_pid;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_hrSWRun]) {
- case 1: /* hrSWRunIndex */
- ber = ober_add_integer(ber, kinfo->p_pid);
- break;
- case 2: /* hrSWRunName */
- case 4: /* hrSWRunPath */
- ber = ober_add_string(ber, kinfo->p_comm);
- break;
- case 3: /* hrSWRunID */
- ber = ober_add_oid(ber, &zerodotzero);
- break;
- case 5: /* hrSWRunParameters */
- if (kinfo_args(kinfo, &s) == -1)
- return (-1);
-
- ber = ober_add_string(ber, s);
- break;
- case 6: /* hrSWRunType */
- if (kinfo->p_flag & P_SYSTEM) {
- /* operatingSystem(2) */
- ber = ober_add_integer(ber, 2);
- } else {
- /* application(4) */
- ber = ober_add_integer(ber, 4);
- }
- break;
- case 7: /* hrSWRunStatus */
- switch (kinfo->p_stat) {
- case SONPROC:
- /* running(1) */
- ber = ober_add_integer(ber, 1);
- break;
- case SIDL:
- case SRUN:
- case SSLEEP:
- /* runnable(2) */
- ber = ober_add_integer(ber, 2);
- break;
- case SSTOP:
- /* notRunnable(3) */
- ber = ober_add_integer(ber, 3);
- break;
- case SDEAD:
- default:
- /* invalid(4) */
- ber = ober_add_integer(ber, 4);
- break;
- }
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-kinfo_proc_comp(const void *a, const void *b)
-{
- struct kinfo_proc * const *k1 = a;
- struct kinfo_proc * const *k2 = b;
-
- return (((*k1)->p_pid > (*k2)->p_pid) ? 1 : -1);
-}
-
-static struct event kinfo_timer;
-static struct kinfo_proc *kp = NULL;
-static struct kinfo_proc **klist = NULL;
-static size_t nkp = 0, nklist = 0;
-
-int
-kinfo_proc(u_int32_t idx, struct kinfo_proc **kinfo)
-{
- int mib[] = { CTL_KERN, KERN_PROC,
- KERN_PROC_ALL, 0, sizeof(*kp), 0 };
- size_t size, count, i;
- struct timeval timer;
-
- if (kp != NULL && klist != NULL)
- goto cached;
-
- kinfo_proc_free();
- for (;;) {
- size = nkp * sizeof(*kp);
- mib[5] = nkp;
- if (sysctl(mib, nitems(mib), kp, &size, NULL, 0) == -1) {
- if (errno == ENOMEM) {
- kinfo_proc_free();
- continue;
- }
-
- return (-1);
- }
-
- count = size / sizeof(*kp);
- if (count <= nkp)
- break;
-
- kp = malloc(size);
- if (kp == NULL) {
- kinfo_proc_free();
- return (-1);
- }
- nkp = count;
- }
-
- klist = calloc(count, sizeof(*klist));
- if (klist == NULL) {
- kinfo_proc_free();
- return (-1);
- }
- nklist = count;
-
- for (i = 0; i < nklist; i++)
- klist[i] = &kp[i];
- qsort(klist, nklist, sizeof(*klist), kinfo_proc_comp);
-
- evtimer_set(&kinfo_timer, kinfo_timer_cb, NULL);
- timer.tv_sec = 5;
- timer.tv_usec = 0;
- evtimer_add(&kinfo_timer, &timer);
-
-cached:
- *kinfo = NULL;
- for (i = 0; i < nklist; i++) {
- if (klist[i]->p_pid >= (int32_t)idx) {
- *kinfo = klist[i];
- break;
- }
- }
-
- return (0);
-}
-
-void
-kinfo_timer_cb(int fd, short event, void *arg)
-{
- kinfo_proc_free();
-}
-
-void
-kinfo_proc_free(void)
-{
- free(kp);
- kp = NULL;
- nkp = 0;
- free(klist);
- klist = NULL;
- nklist = 0;
-}
-
-int
-kinfo_args(struct kinfo_proc *kinfo, char **s)
-{
- static char str[128];
- static char *buf = NULL;
- static size_t buflen = 128;
-
- int mib[] = { CTL_KERN, KERN_PROC_ARGS,
- kinfo->p_pid, KERN_PROC_ARGV };
- char *nbuf, **argv;
-
- if (buf == NULL) {
- buf = malloc(buflen);
- if (buf == NULL)
- return (-1);
- }
-
- str[0] = '\0';
- *s = str;
-
- while (sysctl(mib, nitems(mib), buf, &buflen, NULL, 0) == -1) {
- if (errno != ENOMEM) {
- /* some errors are expected, dont get too upset */
- return (0);
- }
-
- nbuf = realloc(buf, buflen + 128);
- if (nbuf == NULL)
- return (-1);
-
- buf = nbuf;
- buflen += 128;
- }
-
- argv = (char **)buf;
- if (argv[0] == NULL)
- return (0);
-
- argv++;
- while (*argv != NULL) {
- strlcat(str, *argv, sizeof(str));
- argv++;
- if (*argv != NULL)
- strlcat(str, " ", sizeof(str));
- }
-
- return (0);
-}
-
-/*
- * Defined in IF-MIB.txt (RFCs 1229, 1573, 2233, 2863)
- */
-
-int mib_ifnumber(struct oid *, struct ber_oid *, struct ber_element **);
-struct kif
- *mib_ifget(u_int);
-int mib_iftable(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ifxtable(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ifstacklast(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ifrcvtable(struct oid *, struct ber_oid *, struct ber_element **);
-
-static u_int8_t ether_zeroaddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-static struct oid if_mib[] = {
- { MIB(ifMIB), OID_MIB },
- { MIB(ifName), OID_TRD, mib_ifxtable },
- { MIB(ifInMulticastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifInBroadcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifOutMulticastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifOutBroadcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCInOctets), OID_TRD, mib_ifxtable },
- { MIB(ifHCInUcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCInMulticastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCInBroadcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCOutOctets), OID_TRD, mib_ifxtable },
- { MIB(ifHCOutUcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCOutMulticastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifHCOutBroadcastPkts), OID_TRD, mib_ifxtable },
- { MIB(ifLinkUpDownTrapEnable), OID_TRD, mib_ifxtable },
- { MIB(ifHighSpeed), OID_TRD, mib_ifxtable },
- { MIB(ifPromiscuousMode), OID_TRD, mib_ifxtable },
- { MIB(ifConnectorPresent), OID_TRD, mib_ifxtable },
- { MIB(ifAlias), OID_TRD, mib_ifxtable },
- { MIB(ifCounterDiscontinuityTime), OID_TRD, mib_ifxtable },
- { MIB(ifRcvAddressStatus), OID_TRD, mib_ifrcvtable },
- { MIB(ifRcvAddressType), OID_TRD, mib_ifrcvtable },
- { MIB(ifStackLastChange), OID_RD, mib_ifstacklast },
- { MIB(ifNumber), OID_RD, mib_ifnumber },
- { MIB(ifIndex), OID_TRD, mib_iftable },
- { MIB(ifDescr), OID_TRD, mib_iftable },
- { MIB(ifType), OID_TRD, mib_iftable },
- { MIB(ifMtu), OID_TRD, mib_iftable },
- { MIB(ifSpeed), OID_TRD, mib_iftable },
- { MIB(ifPhysAddress), OID_TRD, mib_iftable },
- { MIB(ifAdminStatus), OID_TRD, mib_iftable },
- { MIB(ifOperStatus), OID_TRD, mib_iftable },
- { MIB(ifLastChange), OID_TRD, mib_iftable },
- { MIB(ifInOctets), OID_TRD, mib_iftable },
- { MIB(ifInUcastPkts), OID_TRD, mib_iftable },
- { MIB(ifInNUcastPkts), OID_TRD, mib_iftable },
- { MIB(ifInDiscards), OID_TRD, mib_iftable },
- { MIB(ifInErrors), OID_TRD, mib_iftable },
- { MIB(ifInUnknownProtos), OID_TRD, mib_iftable },
- { MIB(ifOutOctets), OID_TRD, mib_iftable },
- { MIB(ifOutUcastPkts), OID_TRD, mib_iftable },
- { MIB(ifOutNUcastPkts), OID_TRD, mib_iftable },
- { MIB(ifOutDiscards), OID_TRD, mib_iftable },
- { MIB(ifOutErrors), OID_TRD, mib_iftable },
- { MIB(ifOutQLen), OID_TRD, mib_iftable },
- { MIB(ifSpecific), OID_TRD, mib_iftable },
- { MIBEND }
-};
-
-int
-mib_ifnumber(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- *elm = ober_add_integer(*elm, kr_ifnumber());
- return (0);
-}
-
-struct kif *
-mib_ifget(u_int idx)
-{
- struct kif *kif;
-
- if ((kif = kr_getif(idx)) == NULL) {
- /*
- * It may happen that an interface with a specific index
- * does not exist or has been removed. Jump to the next
- * available interface index.
- */
- for (kif = kr_getif(0); kif != NULL;
- kif = kr_getnextif(kif->if_index))
- if (kif->if_index > idx)
- break;
- if (kif == NULL)
- return (NULL);
- }
- idx = kif->if_index;
-
- /* Update interface information */
- kr_updateif(idx);
- if ((kif = kr_getif(idx)) == NULL) {
- log_debug("mib_ifxtable: interface %d disappeared?", idx);
- return (NULL);
- }
-
- return (kif);
-}
-
-int
-mib_iftable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 0;
- struct kif *kif;
- long long i;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_ifEntry];
- if ((kif = mib_ifget(idx)) == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_ifEntry] = kif->if_index;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_if]) {
- case 1:
- ber = ober_add_integer(ber, kif->if_index);
- break;
- case 2:
- /*
- * The ifDescr should contain a vendor, product, etc.
- * but we just use the interface name (like ifName).
- * The interface name includes the driver name on OpenBSD.
- */
- ber = ober_add_string(ber, kif->if_name);
- break;
- case 3:
- if (kif->if_type >= 0xf0) {
- /*
- * It does not make sense to announce the private
- * interface types for CARP, ENC, PFSYNC, etc.
- */
- ber = ober_add_integer(ber, IFT_OTHER);
- } else
- ber = ober_add_integer(ber, kif->if_type);
- break;
- case 4:
- ber = ober_add_integer(ber, kif->if_mtu);
- break;
- case 5:
- if (kif->if_baudrate > UINT32_MAX) {
- /* speed should be obtained from ifHighSpeed instead */
- ber = ober_add_integer(ber, UINT32_MAX);
- } else
- ber = ober_add_integer(ber, kif->if_baudrate);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
- break;
- case 6:
- if (bcmp(kif->if_lladdr, ether_zeroaddr,
- sizeof(kif->if_lladdr)) == 0) {
- ber = ober_add_string(ber, "");
- } else {
- ber = ober_add_nstring(ber, kif->if_lladdr,
- sizeof(kif->if_lladdr));
- }
- break;
- case 7:
- /* ifAdminStatus up(1), down(2), testing(3) */
- i = (kif->if_flags & IFF_UP) ? 1 : 2;
- ber = ober_add_integer(ber, i);
- break;
- case 8:
- /* ifOperStatus */
- if ((kif->if_flags & IFF_UP) == 0)
- i = 2; /* down(2) */
- else if (kif->if_link_state == LINK_STATE_UNKNOWN)
- i = 4; /* unknown(4) */
- else if (LINK_STATE_IS_UP(kif->if_link_state))
- i = 1; /* up(1) */
- else
- i = 7; /* lowerLayerDown(7) or dormant(5)? */
- ber = ober_add_integer(ber, i);
- break;
- case 9:
- ber = ober_add_integer(ber, kif->if_ticks);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- case 10:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_ibytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 11:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_ipackets);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 12:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_imcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 13:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_iqdrops);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 14:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_ierrors);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 15:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_noproto);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 16:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_obytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 17:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_opackets);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 18:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_omcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 19:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_oqdrops);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 20:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_oerrors);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 21:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
- break;
- case 22:
- ber = ober_add_oid(ber, &zerodotzero);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_ifxtable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 0;
- struct kif *kif;
- int i = 0;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_ifXEntry];
- if ((kif = mib_ifget(idx)) == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_ifXEntry] = kif->if_index;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_ifX]) {
- case 1:
- ber = ober_add_string(ber, kif->if_name);
- break;
- case 2:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_imcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 3:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 4:
- ber = ober_add_integer(ber, (u_int32_t)kif->if_omcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 5:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 6:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_ibytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 7:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_ipackets);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 8:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_imcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 9:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 10:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_obytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 11:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_opackets);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 12:
- ber = ober_add_integer(ber, (u_int64_t)kif->if_omcasts);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 13:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 14:
- ber = ober_add_integer(ber, 0); /* enabled(1), disabled(2) */
- break;
- case 15:
- i = kif->if_baudrate >= 1000000 ?
- kif->if_baudrate / 1000000 : 0;
- ber = ober_add_integer(ber, i);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
- break;
- case 16:
- /* ifPromiscuousMode: true(1), false(2) */
- i = kif->if_flags & IFF_PROMISC ? 1 : 2;
- ber = ober_add_integer(ber, i);
- break;
- case 17:
- /* ifConnectorPresent: false(2), true(1) */
- i = kif->if_type == IFT_ETHER ? 1 : 2;
- ber = ober_add_integer(ber, i);
- break;
- case 18:
- ber = ober_add_string(ber, kif->if_descr);
- break;
- case 19:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_ifstacklast(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- ber = ober_add_integer(ber, kr_iflastchange());
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- return (0);
-}
-
-int
-mib_ifrcvtable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 0;
- struct kif *kif;
- u_int i = 0;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_ifRcvAddressEntry];
- if ((kif = mib_ifget(idx)) == NULL)
- return (1);
-
- /*
- * The lladdr of the interface will be encoded in the returned OID
- * ifRcvAddressX.ifindex.6.x.x.x.x.x.x = val
- * Thanks to the virtual cloner interfaces, it is an easy 1:1
- * mapping in OpenBSD; only one lladdr (MAC) address per interface.
- */
-
- /* first set the base OID and caluculate the length */
- idx = 0;
- o->bo_id[OIDIDX_ifRcvAddressEntry + idx++] = kif->if_index;
- o->bo_id[OIDIDX_ifRcvAddressEntry + idx] = 0;
- smi_oidlen(o);
-
- /* extend the OID with the lladdr length and octets */
- o->bo_id[OIDIDX_ifRcvAddressEntry + idx++] = sizeof(kif->if_lladdr);
- o->bo_n++;
- for (i = 0; i < sizeof(kif->if_lladdr); i++, o->bo_n++)
- o->bo_id[OIDIDX_ifRcvAddressEntry + idx++] = kif->if_lladdr[i];
-
- /* write OID */
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_ifRcvAddress]) {
- case 2:
- /* ifRcvAddressStatus: RowStatus active(1), notInService(2) */
- i = kif->if_flags & IFF_UP ? 1 : 2;
- ber = ober_add_integer(ber, i);
- break;
- case 3:
- /* ifRcvAddressType: other(1), volatile(2), nonVolatile(3) */
- ber = ober_add_integer(ber, 1);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Defined in
- * - OPENBSD-PF-MIB.txt
- * - OPENBSD-SENSORS-MIB.txt
- * - OPENBSD-CARP-MIB.txt
- * (http://www.packetmischief.ca/openbsd-snmp-mibs/)
- */
-
-struct carpif {
- struct carpreq carpr;
- struct kif kif;
-};
-
-int mib_pfinfo(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfcounters(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfscounters(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pflogif(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfsrctrack(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pflimits(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pftimeouts(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfifnum(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfiftable(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pftablenum(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pftables(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pftableaddrs(struct oid *, struct ber_oid *, struct ber_element **);
-struct ber_oid *
- mib_pftableaddrstable(struct oid *, struct ber_oid *, struct ber_oid *);
-int mib_pflabelnum(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pflabels(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_pfsyncstats(struct oid *, struct ber_oid *, struct ber_element **);
-
-int mib_sensornum(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_sensors(struct oid *, struct ber_oid *, struct ber_element **);
-const char *mib_sensorunit(struct sensor *);
-char *mib_sensorvalue(struct sensor *);
-
-int mib_carpsysctl(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_carpstats(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_carpiftable(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_carpgrouptable(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_carpifnum(struct oid *, struct ber_oid *, struct ber_element **);
-struct carpif
- *mib_carpifget(u_int);
-int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element **);
-
-static struct oid openbsd_mib[] = {
- { MIB(pfMIBObjects), OID_MIB },
- { MIB(pfRunning), OID_RD, mib_pfinfo },
- { MIB(pfRuntime), OID_RD, mib_pfinfo },
- { MIB(pfDebug), OID_RD, mib_pfinfo },
- { MIB(pfHostid), OID_RD, mib_pfinfo },
- { MIB(pfCntMatch), OID_RD, mib_pfcounters },
- { MIB(pfCntBadOffset), OID_RD, mib_pfcounters },
- { MIB(pfCntFragment), OID_RD, mib_pfcounters },
- { MIB(pfCntShort), OID_RD, mib_pfcounters },
- { MIB(pfCntNormalize), OID_RD, mib_pfcounters },
- { MIB(pfCntMemory), OID_RD, mib_pfcounters },
- { MIB(pfCntTimestamp), OID_RD, mib_pfcounters },
- { MIB(pfCntCongestion), OID_RD, mib_pfcounters },
- { MIB(pfCntIpOptions), OID_RD, mib_pfcounters },
- { MIB(pfCntProtoCksum), OID_RD, mib_pfcounters },
- { MIB(pfCntStateMismatch), OID_RD, mib_pfcounters },
- { MIB(pfCntStateInsert), OID_RD, mib_pfcounters },
- { MIB(pfCntStateLimit), OID_RD, mib_pfcounters },
- { MIB(pfCntSrcLimit), OID_RD, mib_pfcounters },
- { MIB(pfCntSynproxy), OID_RD, mib_pfcounters },
- { MIB(pfCntTranslate), OID_RD, mib_pfcounters },
- { MIB(pfCntNoRoute), OID_RD, mib_pfcounters },
- { MIB(pfStateCount), OID_RD, mib_pfscounters },
- { MIB(pfStateSearches), OID_RD, mib_pfscounters },
- { MIB(pfStateInserts), OID_RD, mib_pfscounters },
- { MIB(pfStateRemovals), OID_RD, mib_pfscounters },
- { MIB(pfLogIfName), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpBytesIn), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpBytesOut), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpPktsInPass), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpPktsInDrop), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpPktsOutPass), OID_RD, mib_pflogif },
- { MIB(pfLogIfIpPktsOutDrop), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6BytesIn), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6BytesOut), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6PktsInPass), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6PktsInDrop), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6PktsOutPass), OID_RD, mib_pflogif },
- { MIB(pfLogIfIp6PktsOutDrop), OID_RD, mib_pflogif },
- { MIB(pfSrcTrackCount), OID_RD, mib_pfsrctrack },
- { MIB(pfSrcTrackSearches), OID_RD, mib_pfsrctrack },
- { MIB(pfSrcTrackInserts), OID_RD, mib_pfsrctrack },
- { MIB(pfSrcTrackRemovals), OID_RD, mib_pfsrctrack },
- { MIB(pfLimitStates), OID_RD, mib_pflimits },
- { MIB(pfLimitSourceNodes), OID_RD, mib_pflimits },
- { MIB(pfLimitFragments), OID_RD, mib_pflimits },
- { MIB(pfLimitMaxTables), OID_RD, mib_pflimits },
- { MIB(pfLimitMaxTableEntries), OID_RD, mib_pflimits },
- { MIB(pfTimeoutTcpFirst), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutTcpOpening), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutTcpEstablished), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutTcpClosing), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutTcpFinWait), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutTcpClosed), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutUdpFirst), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutUdpSingle), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutUdpMultiple), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutIcmpFirst), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutIcmpError), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutOtherFirst), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutOtherSingle), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutOtherMultiple), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutFragment), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutInterval), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutAdaptiveStart), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutAdaptiveEnd), OID_RD, mib_pftimeouts },
- { MIB(pfTimeoutSrcTrack), OID_RD, mib_pftimeouts },
- { MIB(pfIfNumber), OID_RD, mib_pfifnum },
- { MIB(pfIfIndex), OID_TRD, mib_pfiftable },
- { MIB(pfIfDescr), OID_TRD, mib_pfiftable },
- { MIB(pfIfType), OID_TRD, mib_pfiftable },
- { MIB(pfIfRefs), OID_TRD, mib_pfiftable },
- { MIB(pfIfRules), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn4PassPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn4PassBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn4BlockPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn4BlockBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut4PassPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut4PassBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut4BlockPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut4BlockBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn6PassPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn6PassBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn6BlockPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfIn6BlockBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut6PassPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut6PassBytes), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut6BlockPkts), OID_TRD, mib_pfiftable },
- { MIB(pfIfOut6BlockBytes), OID_TRD, mib_pfiftable },
- { MIB(pfTblNumber), OID_RD, mib_pftablenum },
- { MIB(pfTblIndex), OID_TRD, mib_pftables },
- { MIB(pfTblName), OID_TRD, mib_pftables },
- { MIB(pfTblAddresses), OID_TRD, mib_pftables },
- { MIB(pfTblAnchorRefs), OID_TRD, mib_pftables },
- { MIB(pfTblRuleRefs), OID_TRD, mib_pftables },
- { MIB(pfTblEvalsMatch), OID_TRD, mib_pftables },
- { MIB(pfTblEvalsNoMatch), OID_TRD, mib_pftables },
- { MIB(pfTblInPassPkts), OID_TRD, mib_pftables },
- { MIB(pfTblInPassBytes), OID_TRD, mib_pftables },
- { MIB(pfTblInBlockPkts), OID_TRD, mib_pftables },
- { MIB(pfTblInBlockBytes), OID_TRD, mib_pftables },
- { MIB(pfTblInXPassPkts), OID_TRD, mib_pftables },
- { MIB(pfTblInXPassBytes), OID_TRD, mib_pftables },
- { MIB(pfTblOutPassPkts), OID_TRD, mib_pftables },
- { MIB(pfTblOutPassBytes), OID_TRD, mib_pftables },
- { MIB(pfTblOutBlockPkts), OID_TRD, mib_pftables },
- { MIB(pfTblOutBlockBytes), OID_TRD, mib_pftables },
- { MIB(pfTblOutXPassPkts), OID_TRD, mib_pftables },
- { MIB(pfTblOutXPassBytes), OID_TRD, mib_pftables },
- { MIB(pfTblStatsCleared), OID_TRD, mib_pftables },
- { MIB(pfTblInMatchPkts), OID_TRD, mib_pftables },
- { MIB(pfTblInMatchBytes), OID_TRD, mib_pftables },
- { MIB(pfTblOutMatchPkts), OID_TRD, mib_pftables },
- { MIB(pfTblOutMatchBytes), OID_TRD, mib_pftables },
- { MIB(pfTblAddrTblIndex), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrNet), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrMask), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrCleared), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInBlockPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInBlockBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInPassPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInPassBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutBlockPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutBlockBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutPassPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutPassBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInMatchPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrInMatchBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutMatchPkts), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfTblAddrOutMatchBytes), OID_TRD, mib_pftableaddrs,
- NULL, mib_pftableaddrstable },
- { MIB(pfLabelNumber), OID_RD, mib_pflabelnum },
- { MIB(pfLabelIndex), OID_TRD, mib_pflabels },
- { MIB(pfLabelName), OID_TRD, mib_pflabels },
- { MIB(pfLabelEvals), OID_TRD, mib_pflabels },
- { MIB(pfLabelPkts), OID_TRD, mib_pflabels },
- { MIB(pfLabelBytes), OID_TRD, mib_pflabels },
- { MIB(pfLabelInPkts), OID_TRD, mib_pflabels },
- { MIB(pfLabelInBytes), OID_TRD, mib_pflabels },
- { MIB(pfLabelOutPkts), OID_TRD, mib_pflabels },
- { MIB(pfLabelOutBytes), OID_TRD, mib_pflabels },
- { MIB(pfLabelTotalStates), OID_TRD, mib_pflabels },
- { MIB(pfsyncIpPktsRecv), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncIp6PktsRecv), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadInterface), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadTtl), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktShorterThanHeader), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadVersion), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadAction), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadLength), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadAuth), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForStaleState), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadValues), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncPktDiscardsForBadState), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncIpPktsSent), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncIp6PktsSent), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncNoMemory), OID_RD, mib_pfsyncstats },
- { MIB(pfsyncOutputErrors), OID_RD, mib_pfsyncstats },
- { MIB(sensorsMIBObjects), OID_MIB },
- { MIB(sensorNumber), OID_RD, mib_sensornum },
- { MIB(sensorIndex), OID_TRD, mib_sensors },
- { MIB(sensorDescr), OID_TRD, mib_sensors },
- { MIB(sensorType), OID_TRD, mib_sensors },
- { MIB(sensorDevice), OID_TRD, mib_sensors },
- { MIB(sensorValue), OID_TRD, mib_sensors },
- { MIB(sensorUnits), OID_TRD, mib_sensors },
- { MIB(sensorStatus), OID_TRD, mib_sensors },
- { MIB(carpMIBObjects), OID_MIB },
- { MIB(carpAllow), OID_RD, mib_carpsysctl },
- { MIB(carpPreempt), OID_RD, mib_carpsysctl },
- { MIB(carpLog), OID_RD, mib_carpsysctl },
- { MIB(carpIpPktsRecv), OID_RD, mib_carpstats },
- { MIB(carpIp6PktsRecv), OID_RD, mib_carpstats },
- { MIB(carpPktDiscardsBadIface), OID_RD, mib_carpstats },
- { MIB(carpPktDiscardsBadTtl), OID_RD, mib_carpstats },
- { MIB(carpPktShorterThanHdr), OID_RD, mib_carpstats },
- { MIB(carpDiscardsBadCksum), OID_RD, mib_carpstats },
- { MIB(carpDiscardsBadVersion), OID_RD, mib_carpstats },
- { MIB(carpDiscardsTooShort), OID_RD, mib_carpstats },
- { MIB(carpDiscardsBadAuth), OID_RD, mib_carpstats },
- { MIB(carpDiscardsBadVhid), OID_RD, mib_carpstats },
- { MIB(carpDiscardsBadAddrList), OID_RD, mib_carpstats },
- { MIB(carpIpPktsSent), OID_RD, mib_carpstats },
- { MIB(carpIp6PktsSent), OID_RD, mib_carpstats },
- { MIB(carpNoMemory), OID_RD, mib_carpstats },
- { MIB(carpTransitionsToMaster), OID_RD, mib_carpstats },
- { MIB(carpIfNumber), OID_RD, mib_carpifnum },
- { MIB(carpIfIndex), OID_TRD, mib_carpiftable },
- { MIB(carpIfDescr), OID_TRD, mib_carpiftable },
- { MIB(carpIfVhid), OID_TRD, mib_carpiftable },
- { MIB(carpIfDev ), OID_TRD, mib_carpiftable },
- { MIB(carpIfAdvbase), OID_TRD, mib_carpiftable },
- { MIB(carpIfAdvskew), OID_TRD, mib_carpiftable },
- { MIB(carpIfState), OID_TRD, mib_carpiftable },
- { MIB(carpGroupName), OID_TRD, mib_carpgrouptable },
- { MIB(carpGroupDemote), OID_TRD, mib_carpgrouptable },
- { MIB(memMIBObjects), OID_MIB },
- { MIB(memMIBVersion), OID_RD, mps_getint, NULL, NULL,
- OIDVER_OPENBSD_MEM },
- { MIB(memIfName), OID_TRD, mib_memiftable },
- { MIB(memIfLiveLocks), OID_TRD, mib_memiftable },
- { MIBEND }
-};
-
-int
-mib_pfinfo(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pf_status s;
- time_t runtime = 0;
- struct timespec uptime;
- char str[11];
-
- if (pf_get_stats(&s))
- return (-1);
-
- switch (oid->o_oid[OIDIDX_pfstatus]) {
- case 1:
- *elm = ober_add_integer(*elm, s.running);
- break;
- case 2:
- if (!clock_gettime(CLOCK_BOOTTIME, &uptime))
- runtime = uptime.tv_sec - s.since;
- runtime *= 100;
- *elm = ober_add_integer(*elm, runtime);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- case 3:
- *elm = ober_add_integer(*elm, s.debug);
- break;
- case 4:
- snprintf(str, sizeof(str), "0x%08x", ntohl(s.hostid));
- *elm = ober_add_string(*elm, str);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_pfcounters(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pf_status s;
- int i;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 1, &s.counters[PFRES_MATCH] },
- { 2, &s.counters[PFRES_BADOFF] },
- { 3, &s.counters[PFRES_FRAG] },
- { 4, &s.counters[PFRES_SHORT] },
- { 5, &s.counters[PFRES_NORM] },
- { 6, &s.counters[PFRES_MEMORY] },
- { 7, &s.counters[PFRES_TS] },
- { 8, &s.counters[PFRES_CONGEST] },
- { 9, &s.counters[PFRES_IPOPTIONS] },
- { 10, &s.counters[PFRES_PROTCKSUM] },
- { 11, &s.counters[PFRES_BADSTATE] },
- { 12, &s.counters[PFRES_STATEINS] },
- { 13, &s.counters[PFRES_MAXSTATES] },
- { 14, &s.counters[PFRES_SRCLIMIT] },
- { 15, &s.counters[PFRES_SYNPROXY] },
- { 16, &s.counters[PFRES_TRANSLATE] },
- { 17, &s.counters[PFRES_NOROUTE] }
- };
-
- if (pf_get_stats(&s))
- return (-1);
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
- return (-1);
-}
-
-int
-mib_pfscounters(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pf_status s;
- int i;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 2, &s.fcounters[FCNT_STATE_SEARCH] },
- { 3, &s.fcounters[FCNT_STATE_INSERT] },
- { 4, &s.fcounters[FCNT_STATE_REMOVALS] },
- };
-
- if (pf_get_stats(&s))
- return (-1);
-
- switch (oid->o_oid[OIDIDX_pfstatus]) {
- case 1:
- *elm = ober_add_integer(*elm, s.states);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32);
- break;
- default:
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_pflogif(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pf_status s;
- int i;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 2, &s.bcounters[IPV4][IN] },
- { 3, &s.bcounters[IPV4][OUT] },
- { 4, &s.pcounters[IPV4][IN][PF_PASS] },
- { 5, &s.pcounters[IPV4][IN][PF_DROP] },
- { 6, &s.pcounters[IPV4][OUT][PF_PASS] },
- { 7, &s.pcounters[IPV4][OUT][PF_DROP] },
- { 8, &s.bcounters[IPV6][IN] },
- { 9, &s.bcounters[IPV6][OUT] },
- { 10, &s.pcounters[IPV6][IN][PF_PASS] },
- { 11, &s.pcounters[IPV6][IN][PF_DROP] },
- { 12, &s.pcounters[IPV6][OUT][PF_PASS] },
- { 13, &s.pcounters[IPV6][OUT][PF_DROP] }
- };
-
- if (pf_get_stats(&s))
- return (-1);
-
- switch (oid->o_oid[OIDIDX_pfstatus]) {
- case 1:
- *elm = ober_add_string(*elm, s.ifname);
- break;
- default:
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_pfsrctrack(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pf_status s;
- int i;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 2, &s.scounters[SCNT_SRC_NODE_SEARCH] },
- { 3, &s.scounters[SCNT_SRC_NODE_INSERT] },
- { 4, &s.scounters[SCNT_SRC_NODE_REMOVALS] }
- };
-
- if (pf_get_stats(&s))
- return (-1);
-
- switch (oid->o_oid[OIDIDX_pfstatus]) {
- case 1:
- *elm = ober_add_integer(*elm, s.src_nodes);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32);
- break;
- default:
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
- return (-1);
- }
-
- return (0);
-}
-
-int
-mib_pflimits(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pfioc_limit pl;
- int i;
- extern int devpf;
- struct statsmap {
- u_int8_t m_id;
- u_int8_t m_limit;
- } mapping[] = {
- { 1, PF_LIMIT_STATES },
- { 2, PF_LIMIT_SRC_NODES },
- { 3, PF_LIMIT_FRAGS },
- { 4, PF_LIMIT_TABLES },
- { 5, PF_LIMIT_TABLE_ENTRIES }
- };
-
- memset(&pl, 0, sizeof(pl));
- pl.index = PF_LIMIT_MAX;
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- pl.index = mapping[i].m_limit;
- break;
- }
- }
-
- if (pl.index == PF_LIMIT_MAX)
- return (-1);
-
- if (ioctl(devpf, DIOCGETLIMIT, &pl) == -1) {
- log_warn("DIOCGETLIMIT");
- return (-1);
- }
-
- *elm = ober_add_integer(*elm, pl.limit);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32);
-
- return (0);
-}
-
-int
-mib_pftimeouts(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pfioc_tm pt;
- int i;
- extern int devpf;
- struct statsmap {
- u_int8_t m_id;
- u_int8_t m_tm;
- } mapping[] = {
- { 1, PFTM_TCP_FIRST_PACKET },
- { 2, PFTM_TCP_OPENING },
- { 3, PFTM_TCP_ESTABLISHED },
- { 4, PFTM_TCP_CLOSING },
- { 5, PFTM_TCP_FIN_WAIT },
- { 6, PFTM_TCP_CLOSED },
- { 7, PFTM_UDP_FIRST_PACKET },
- { 8, PFTM_UDP_SINGLE },
- { 9, PFTM_UDP_MULTIPLE },
- { 10, PFTM_ICMP_FIRST_PACKET },
- { 11, PFTM_ICMP_ERROR_REPLY },
- { 12, PFTM_OTHER_FIRST_PACKET },
- { 13, PFTM_OTHER_SINGLE },
- { 14, PFTM_OTHER_MULTIPLE },
- { 15, PFTM_FRAG },
- { 16, PFTM_INTERVAL },
- { 17, PFTM_ADAPTIVE_START },
- { 18, PFTM_ADAPTIVE_END },
- { 19, PFTM_SRC_NODE }
- };
-
- memset(&pt, 0, sizeof(pt));
- pt.timeout = PFTM_MAX;
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- pt.timeout = mapping[i].m_tm;
- break;
- }
- }
-
- if (pt.timeout == PFTM_MAX)
- return (-1);
-
- if (ioctl(devpf, DIOCGETTIMEOUT, &pt) == -1) {
- log_warn("DIOCGETTIMEOUT");
- return (-1);
- }
-
- *elm = ober_add_integer(*elm, pt.seconds);
-
- return (0);
-}
-
-int
-mib_pfifnum(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int c;
-
- if ((c = pfi_count()) == -1)
- return (-1);
-
- *elm = ober_add_integer(*elm, c);
-
- return (0);
-}
-
-int
-mib_pfiftable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct pfi_kif pif;
- int idx, iftype;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_pfIfEntry];
-
- if (pfi_get_if(&pif, idx))
- return (1);
-
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_pfInterface]) {
- case 1:
- ber = ober_add_integer(ber, idx);
- break;
- case 2:
- ber = ober_add_string(ber, pif.pfik_name);
- break;
- case 3:
- iftype = (pif.pfik_ifp == NULL ? PFI_IFTYPE_GROUP
- : PFI_IFTYPE_INSTANCE);
- ber = ober_add_integer(ber, iftype);
- break;
- case 4:
- ber = ober_add_integer(ber, pif.pfik_states);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32);
- break;
- case 5:
- ber = ober_add_integer(ber, pif.pfik_rules);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32);
- break;
- case 6:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV4][IN][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 7:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV4][IN][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 8:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV4][IN][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 9:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV4][IN][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 10:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV4][OUT][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 11:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV4][OUT][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 12:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV4][OUT][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 13:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV4][OUT][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 14:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV6][IN][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 15:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV6][IN][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 16:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV6][IN][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 17:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV6][IN][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 18:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV6][OUT][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 19:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV6][OUT][PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 20:
- ber = ober_add_integer(ber, pif.pfik_packets[IPV6][OUT][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 21:
- ber = ober_add_integer(ber, pif.pfik_bytes[IPV6][OUT][BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- default:
- return (1);
- }
-
- return (0);
-}
-
-int
-mib_pftablenum(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int c;
-
- if ((c = pft_count()) == -1)
- return (-1);
-
- *elm = ober_add_integer(*elm, c);
-
- return (0);
-}
-
-int
-mib_pftables(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct pfr_tstats ts;
- time_t tzero;
- int idx;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_pfTableEntry];
-
- if (pft_get_table(&ts, idx))
- return (1);
-
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_pfTable]) {
- case 1:
- ber = ober_add_integer(ber, idx);
- break;
- case 2:
- ber = ober_add_string(ber, ts.pfrts_name);
- break;
- case 3:
- ber = ober_add_integer(ber, ts.pfrts_cnt);
- break;
- case 4:
- ber = ober_add_integer(ber, ts.pfrts_refcnt[PFR_REFCNT_ANCHOR]);
- break;
- case 5:
- ber = ober_add_integer(ber, ts.pfrts_refcnt[PFR_REFCNT_RULE]);
- break;
- case 6:
- ber = ober_add_integer(ber, ts.pfrts_match);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 7:
- ber = ober_add_integer(ber, ts.pfrts_nomatch);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 8:
- ber = ober_add_integer(ber, ts.pfrts_packets[IN][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 9:
- ber = ober_add_integer(ber, ts.pfrts_bytes[IN][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 10:
- ber = ober_add_integer(ber, ts.pfrts_packets[IN][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 11:
- ber = ober_add_integer(ber, ts.pfrts_bytes[IN][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 12:
- ber = ober_add_integer(ber, ts.pfrts_packets[IN][PFR_OP_XPASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 13:
- ber = ober_add_integer(ber, ts.pfrts_bytes[IN][PFR_OP_XPASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 14:
- ber = ober_add_integer(ber, ts.pfrts_packets[OUT][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 15:
- ber = ober_add_integer(ber, ts.pfrts_bytes[OUT][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 16:
- ber = ober_add_integer(ber, ts.pfrts_packets[OUT][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 17:
- ber = ober_add_integer(ber, ts.pfrts_bytes[OUT][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 18:
- ber = ober_add_integer(ber, ts.pfrts_packets[OUT][PFR_OP_XPASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 19:
- ber = ober_add_integer(ber, ts.pfrts_bytes[OUT][PFR_OP_XPASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 20:
- tzero = (time(NULL) - ts.pfrts_tzero) * 100;
- ber = ober_add_integer(ber, tzero);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- case 21:
- ber = ober_add_integer(ber, ts.pfrts_packets[IN][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 22:
- ber = ober_add_integer(ber, ts.pfrts_bytes[IN][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 23:
- ber = ober_add_integer(ber, ts.pfrts_packets[OUT][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 24:
- ber = ober_add_integer(ber, ts.pfrts_bytes[OUT][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- default:
- return (1);
- }
-
- return (0);
-}
-
-int
-mib_pftableaddrs(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct pfr_astats as;
- int tblidx;
-
- tblidx = o->bo_id[OIDIDX_pfTblAddr + 1];
- mps_decodeinaddr(o, &as.pfras_a.pfra_ip4addr, OIDIDX_pfTblAddr + 2);
- as.pfras_a.pfra_net = o->bo_id[OIDIDX_pfTblAddr + 6];
-
- if (pfta_get_addr(&as, tblidx))
- return (-1);
-
- /* write OID */
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_pfTblAddr]) {
- case 1:
- ber = ober_add_integer(ber, tblidx);
- break;
- case 2:
- ber = ober_add_nstring(ber, (char *)&as.pfras_a.pfra_ip4addr,
- sizeof(u_int32_t));
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
- break;
- case 3:
- ber = ober_add_integer(ber, as.pfras_a.pfra_net);
- break;
- case 4:
- ber = ober_add_integer(ber, (time(NULL) - as.pfras_tzero) * 100);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
- break;
- case 5:
- ber = ober_add_integer(ber, as.pfras_packets[IN][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 6:
- ber = ober_add_integer(ber, as.pfras_bytes[IN][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 7:
- ber = ober_add_integer(ber, as.pfras_packets[IN][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 8:
- ber = ober_add_integer(ber, as.pfras_bytes[IN][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 9:
- ber = ober_add_integer(ber, as.pfras_packets[OUT][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 10:
- ber = ober_add_integer(ber, as.pfras_bytes[OUT][PFR_OP_BLOCK]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 11:
- ber = ober_add_integer(ber, as.pfras_packets[OUT][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 12:
- ber = ober_add_integer(ber, as.pfras_bytes[OUT][PFR_OP_PASS]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 13:
- ber = ober_add_integer(ber, as.pfras_packets[IN][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 14:
- ber = ober_add_integer(ber, as.pfras_bytes[IN][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 15:
- ber = ober_add_integer(ber, as.pfras_packets[OUT][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 16:
- ber = ober_add_integer(ber, as.pfras_bytes[OUT][PFR_OP_MATCH]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-struct ber_oid *
-mib_pftableaddrstable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
-{
- struct pfr_astats as;
- struct oid a, b;
- u_int32_t id, tblidx;
-
- bcopy(&oid->o_id, no, sizeof(*no));
- id = oid->o_oidlen - 1;
-
- if (o->bo_n >= oid->o_oidlen) {
- /*
- * Compare the requested and the matched OID to see
- * if we have to iterate to the next element.
- */
- bzero(&a, sizeof(a));
- bcopy(o, &a.o_id, sizeof(struct ber_oid));
- bzero(&b, sizeof(b));
- bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
- b.o_oidlen--;
- b.o_flags |= OID_TABLE;
- if (smi_oid_cmp(&a, &b) == 0) {
- o->bo_id[id] = oid->o_oid[id];
- bcopy(o, no, sizeof(*no));
- }
- }
-
- tblidx = no->bo_id[OIDIDX_pfTblAddr + 1];
- mps_decodeinaddr(no, &as.pfras_a.pfra_ip4addr, OIDIDX_pfTblAddr + 2);
- as.pfras_a.pfra_net = no->bo_id[OIDIDX_pfTblAddr + 6];
-
- if (tblidx == 0) {
- if (pfta_get_first(&as))
- return (NULL);
- tblidx = 1;
- } else {
- if (pfta_get_nextaddr(&as, &tblidx)) {
- /* We reached the last addr in the last table.
- * When the next OIDIDX_pfTblAddr'th OID is requested,
- * get the first table address again.
- */
- o->bo_id[OIDIDX_pfTblAddr + 1] = 0;
- smi_oidlen(o);
- return (NULL);
- }
- }
-
- no->bo_id[OIDIDX_pfTblAddr + 1] = tblidx;
- mps_encodeinaddr(no, &as.pfras_a.pfra_ip4addr, OIDIDX_pfTblAddr + 2);
- no->bo_id[OIDIDX_pfTblAddr + 6] = as.pfras_a.pfra_net;
- no->bo_n += 1;
-
- smi_oidlen(o);
-
- return (no);
-}
-
-int
-mib_pflabelnum(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct pfioc_rule pr;
- u_int32_t nr, mnr, lnr;
- extern int devpf;
-
- memset(&pr, 0, sizeof(pr));
- if (ioctl(devpf, DIOCGETRULES, &pr) == -1) {
- log_warn("DIOCGETRULES");
- return (-1);
- }
-
- mnr = pr.nr;
- lnr = 0;
- for (nr = 0; nr < mnr; ++nr) {
- pr.nr = nr;
- if (ioctl(devpf, DIOCGETRULE, &pr) == -1) {
- log_warn("DIOCGETRULE");
- return (-1);
- }
-
- if (pr.rule.label[0])
- lnr++;
- }
-
- *elm = ober_add_integer(*elm, lnr);
-
- return (0);
-}
-
-int
-mib_pflabels(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct pfioc_rule pr;
- struct pf_rule *r = NULL;
- u_int32_t nr, mnr, lnr;
- u_int32_t idx;
- extern int devpf;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_pfLabelEntry];
-
- memset(&pr, 0, sizeof(pr));
- if (ioctl(devpf, DIOCGETRULES, &pr) == -1) {
- log_warn("DIOCGETRULES");
- return (-1);
- }
-
- mnr = pr.nr;
- lnr = 0;
- for (nr = 0; nr < mnr; ++nr) {
- pr.nr = nr;
- if (ioctl(devpf, DIOCGETRULE, &pr) == -1) {
- log_warn("DIOCGETRULE");
- return (-1);
- }
-
- if (pr.rule.label[0] && ++lnr == idx) {
- r = &pr.rule;
- break;
- }
- }
-
- if (r == NULL)
- return (1);
-
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_pfLabel]) {
- case 1:
- ber = ober_add_integer(ber, lnr);
- break;
- case 2:
- ber = ober_add_string(ber, r->label);
- break;
- case 3:
- ber = ober_add_integer(ber, r->evaluations);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 4:
- ber = ober_add_integer(ber, r->packets[IN] + r->packets[OUT]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 5:
- ber = ober_add_integer(ber, r->bytes[IN] + r->bytes[OUT]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 6:
- ber = ober_add_integer(ber, r->packets[IN]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 7:
- ber = ober_add_integer(ber, r->bytes[IN]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 8:
- ber = ober_add_integer(ber, r->packets[OUT]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 9:
- ber = ober_add_integer(ber, r->bytes[OUT]);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 10:
- ber = ober_add_integer(ber, r->states_tot);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- default:
- return (1);
- }
-
- return (0);
-}
-
-int
-mib_pfsyncstats(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int i;
- int mib[] = { CTL_NET, PF_INET, IPPROTO_PFSYNC,
- PFSYNCCTL_STATS };
- size_t len = sizeof(struct pfsyncstats);
- struct pfsyncstats s;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 1, &s.pfsyncs_ipackets },
- { 2, &s.pfsyncs_ipackets6 },
- { 3, &s.pfsyncs_badif },
- { 4, &s.pfsyncs_badttl },
- { 5, &s.pfsyncs_hdrops },
- { 6, &s.pfsyncs_badver },
- { 7, &s.pfsyncs_badact },
- { 8, &s.pfsyncs_badlen },
- { 9, &s.pfsyncs_badauth },
- { 10, &s.pfsyncs_stale },
- { 11, &s.pfsyncs_badval },
- { 12, &s.pfsyncs_badstate },
- { 13, &s.pfsyncs_opackets },
- { 14, &s.pfsyncs_opackets6 },
- { 15, &s.pfsyncs_onomem },
- { 16, &s.pfsyncs_oerrors }
- };
-
- if (sysctl(mib, 4, &s, &len, NULL, 0) == -1) {
- log_warn("sysctl");
- return (-1);
- }
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_pfstatus] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
-
- return (-1);
-}
-
-int
-mib_sensornum(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct sensordev sensordev;
- size_t len = sizeof(sensordev);
- int mib[] = { CTL_HW, HW_SENSORS, 0 };
- int i, c;
-
- for (i = c = 0; ; i++) {
- mib[2] = i;
- if (sysctl(mib, nitems(mib),
- &sensordev, &len, NULL, 0) == -1) {
- if (errno == ENXIO)
- continue;
- if (errno == ENOENT)
- break;
- return (-1);
- }
- c += sensordev.sensors_count;
- }
-
- *elm = ober_add_integer(*elm, c);
- return (0);
-}
-
-int
-mib_sensors(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct sensordev sensordev;
- size_t len = sizeof(sensordev);
- struct sensor sensor;
- size_t slen = sizeof(sensor);
- char desc[32];
- int mib[] = { CTL_HW, HW_SENSORS, 0, 0, 0 };
- int i, j, k;
- u_int32_t idx = 0, n;
- char *s;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_sensorEntry];
-
- for (i = 0, n = 1; ; i++) {
- mib[2] = i;
- if (sysctl(mib, 3, &sensordev, &len, NULL, 0) == -1) {
- if (errno == ENXIO)
- continue;
- if (errno == ENOENT)
- break;
- return (-1);
- }
- for (j = 0; j < SENSOR_MAX_TYPES; j++) {
- mib[3] = j;
- for (k = 0; k < sensordev.maxnumt[j]; k++) {
- mib[4] = k;
- if (sysctl(mib, 5,
- &sensor, &slen, NULL, 0) == -1) {
- if (errno == ENXIO)
- continue;
- if (errno == ENOENT)
- break;
- return (-1);
- }
- if (sensor.flags & SENSOR_FINVALID)
- continue;
- if (n == idx)
- goto found;
- n++;
- }
- }
- }
- return (1);
-
- found:
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_sensor]) {
- case 1:
- ber = ober_add_integer(ber, (int32_t)n);
- break;
- case 2:
- if (sensor.desc[0] == '\0') {
- snprintf(desc, sizeof(desc), "%s%d",
- sensor_type_s[sensor.type],
- sensor.numt);
- ber = ober_add_string(ber, desc);
- } else
- ber = ober_add_string(ber, sensor.desc);
- break;
- case 3:
- ber = ober_add_integer(ber, sensor.type);
- break;
- case 4:
- ber = ober_add_string(ber, sensordev.xname);
- break;
- case 5:
- if ((s = mib_sensorvalue(&sensor)) == NULL)
- return (-1);
- ber = ober_add_string(ber, s);
- free(s);
- break;
- case 6:
- ber = ober_add_string(ber, mib_sensorunit(&sensor));
- break;
- case 7:
- ber = ober_add_integer(ber, sensor.status);
- break;
- }
-
- return (0);
-}
-
-#define SENSOR_DRIVE_STATES (SENSOR_DRIVE_PFAIL + 1)
-static const char * const sensor_drive_s[SENSOR_DRIVE_STATES] = {
- NULL, "empty", "ready", "powerup", "online", "idle", "active",
- "rebuild", "powerdown", "fail", "pfail"
-};
-
-static const char * const sensor_unit_s[SENSOR_MAX_TYPES + 1] = {
- "degC", "RPM", "V DC", "V AC", "Ohm", "W", "A", "Wh", "Ah",
- "", "", "%", "lx", "", "sec", "%RH", "Hz", "degree",
- "m", "Pa", "m/s^2", "m/s", ""
-};
-
-const char *
-mib_sensorunit(struct sensor *s)
-{
- u_int idx;
- idx = s->type > SENSOR_MAX_TYPES ?
- SENSOR_MAX_TYPES : s->type;
- return (sensor_unit_s[idx]);
-}
-
-char *
-mib_sensorvalue(struct sensor *s)
-{
- char *v;
- int ret = -1;
-
- switch (s->type) {
- case SENSOR_TEMP:
- ret = asprintf(&v, "%.2f",
- (s->value - 273150000) / 1000000.0);
- break;
- case SENSOR_VOLTS_DC:
- case SENSOR_VOLTS_AC:
- case SENSOR_WATTS:
- case SENSOR_AMPS:
- case SENSOR_WATTHOUR:
- case SENSOR_AMPHOUR:
- case SENSOR_LUX:
- case SENSOR_FREQ:
- case SENSOR_ACCEL:
- case SENSOR_VELOCITY:
- case SENSOR_DISTANCE:
- ret = asprintf(&v, "%.2f", s->value / 1000000.0);
- break;
- case SENSOR_INDICATOR:
- ret = asprintf(&v, "%s", s->value ? "on" : "off");
- break;
- case SENSOR_PERCENT:
- case SENSOR_HUMIDITY:
- ret = asprintf(&v, "%.2f", s->value / 1000.0);
- break;
- case SENSOR_PRESSURE:
- ret = asprintf(&v, "%.2f", s->value / 1000.0);
- break;
- case SENSOR_TIMEDELTA:
- ret = asprintf(&v, "%.6f", s->value / 1000000000.0);
- break;
- case SENSOR_DRIVE:
- if (s->value > 0 && s->value < SENSOR_DRIVE_STATES) {
- ret = asprintf(&v, "%s", sensor_drive_s[s->value]);
- break;
- }
- /* FALLTHROUGH */
- case SENSOR_FANRPM:
- case SENSOR_OHMS:
- case SENSOR_INTEGER:
- default:
- ret = asprintf(&v, "%lld", s->value);
- break;
- }
-
- if (ret == -1)
- return (NULL);
- return (v);
-}
-
-int
-mib_carpsysctl(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- size_t len;
- int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP, 0 };
- int v;
-
- mib[3] = oid->o_oid[OIDIDX_carpsysctl];
- len = sizeof(v);
-
- if (sysctl(mib, 4, &v, &len, NULL, 0) == -1)
- return (1);
-
- *elm = ober_add_integer(*elm, v);
- return (0);
-}
-
-int
-mib_carpstats(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int mib[] = { CTL_NET, PF_INET, IPPROTO_CARP,
- CARPCTL_STATS };
- size_t len;
- struct carpstats stats;
- int i;
- struct statsmap {
- u_int8_t m_id;
- u_int64_t *m_ptr;
- } mapping[] = {
- { 1, &stats.carps_ipackets },
- { 2, &stats.carps_ipackets6 },
- { 3, &stats.carps_badif },
- { 4, &stats.carps_badttl },
- { 5, &stats.carps_hdrops },
- { 6, &stats.carps_badsum },
- { 7, &stats.carps_badver },
- { 8, &stats.carps_badlen },
- { 9, &stats.carps_badauth },
- { 10, &stats.carps_badvhid },
- { 11, &stats.carps_badaddrs },
- { 12, &stats.carps_opackets },
- { 13, &stats.carps_opackets6 },
- { 14, &stats.carps_onomem },
- { 15, &stats.carps_preempt }
- };
-
- len = sizeof(stats);
-
- if (sysctl(mib, 4, &stats, &len, NULL, 0) == -1)
- return (1);
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_carpstats] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm, BER_CLASS_APPLICATION,
- SNMP_T_COUNTER64);
- return (0);
- }
- }
-
- return (-1);
-}
-
-int
-mib_carpifnum(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct kif *kif;
- int c = 0;
-
- for (kif = kr_getif(0); kif != NULL;
- kif = kr_getnextif(kif->if_index))
- if (kif->if_type == IFT_CARP)
- c++;
-
- *elm = ober_add_integer(*elm, c);
- return (0);
-}
-
-struct carpif *
-mib_carpifget(u_int idx)
-{
- struct kif *kif;
- struct carpif *cif;
- int s;
- struct ifreq ifr;
- struct carpreq carpr;
-
- if ((kif = kr_getif(idx)) == NULL || kif->if_type != IFT_CARP) {
- /*
- * It may happen that an interface with a specific index
- * does not exist, has been removed, or is not a carp(4)
- * interface. Jump to the next available carp(4) interface
- * index.
- */
- for (kif = kr_getif(0); kif != NULL;
- kif = kr_getnextif(kif->if_index)) {
- if (kif->if_type != IFT_CARP)
- continue;
- if (kif->if_index > idx)
- break;
-
- }
- if (kif == NULL)
- return (NULL);
- }
- idx = kif->if_index;
-
- /* Update interface information */
- kr_updateif(idx);
- if ((kif = kr_getif(idx)) == NULL) {
- log_debug("mib_carpifget: interface %d disappeared?", idx);
- return (NULL);
- }
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
- return (NULL);
-
- memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, kif->if_name, sizeof(ifr.ifr_name));
- memset((char *)&carpr, 0, sizeof(carpr));
- ifr.ifr_data = (caddr_t)&carpr;
-
- if (ioctl(s, SIOCGVH, (caddr_t)&ifr) == -1) {
- close(s);
- return (NULL);
- }
-
- cif = calloc(1, sizeof(struct carpif));
- if (cif != NULL) {
- memcpy(&cif->carpr, &carpr, sizeof(struct carpreq));
- memcpy(&cif->kif, kif, sizeof(struct kif));
- }
-
- close(s);
-
- return (cif);
-}
-
-int
-mib_carpiftable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t idx;
- struct carpif *cif;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_carpIfEntry];
-
- if ((cif = mib_carpifget(idx)) == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_carpIfEntry] = cif->kif.if_index;
- *elm = ober_add_oid(*elm, o);
-
- switch (o->bo_id[OIDIDX_carpIf]) {
- case 1:
- *elm = ober_add_integer(*elm, cif->kif.if_index);
- break;
- case 2:
- *elm = ober_add_string(*elm, cif->kif.if_name);
- break;
- case 3:
- *elm = ober_add_integer(*elm, cif->carpr.carpr_vhids[0]);
- break;
- case 4:
- *elm = ober_add_string(*elm, cif->carpr.carpr_carpdev);
- break;
- case 5:
- *elm = ober_add_integer(*elm, cif->carpr.carpr_advbase);
- break;
- case 6:
- *elm = ober_add_integer(*elm, cif->carpr.carpr_advskews[0]);
- break;
- case 7:
- *elm = ober_add_integer(*elm, cif->carpr.carpr_states[0]);
- break;
- default:
- free(cif);
- return (1);
- }
-
- free(cif);
- return (0);
-}
-
-static struct ifg_req *
-mib_carpgroupget(u_int idx)
-{
- struct ifgroupreq ifgr;
- struct ifg_req *ifg = NULL;
- u_int len;
- int s = -1;
-
- bzero(&ifgr, sizeof(ifgr));
-
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- log_warn("socket");
- return (NULL);
- }
-
- if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
- log_warn("SIOCGIFGLIST");
- goto err;
- }
- len = ifgr.ifgr_len;
-
- if (len / sizeof(*ifgr.ifgr_groups) <= idx-1)
- goto err;
-
- if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) {
- log_warn("alloc");
- goto err;
- }
- if (ioctl(s, SIOCGIFGLIST, (caddr_t)&ifgr) == -1) {
- log_warn("SIOCGIFGLIST");
- goto err;
- }
- close(s);
-
- if ((ifg = calloc(1, sizeof *ifg)) == NULL) {
- log_warn("alloc");
- goto err;
- }
-
- memcpy(ifg, &ifgr.ifgr_groups[idx-1], sizeof *ifg);
- free(ifgr.ifgr_groups);
- return ifg;
- err:
- free(ifgr.ifgr_groups);
- close(s);
- return (NULL);
-}
-
-int
-mib_carpgrouptable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ifgroupreq ifgr;
- struct ifg_req *ifg;
- uint32_t idx;
- int s;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_carpGroupIndex];
-
- if ((ifg = mib_carpgroupget(idx)) == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_carpGroupIndex] = idx;
- *elm = ober_add_oid(*elm, o);
-
- switch (o->bo_id[OIDIDX_carpGroupEntry]) {
- case 2:
- *elm = ober_add_string(*elm, ifg->ifgrq_group);
- break;
- case 3:
- if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
- log_warn("socket");
- free(ifg);
- return (1);
- }
-
- bzero(&ifgr, sizeof(ifgr));
- strlcpy(ifgr.ifgr_name, ifg->ifgrq_group, sizeof(ifgr.ifgr_name));
- if (ioctl(s, SIOCGIFGATTR, (caddr_t)&ifgr) == -1) {
- log_warn("SIOCGIFGATTR");
- close(s);
- free(ifg);
- return (1);
- }
-
- close(s);
- *elm = ober_add_integer(*elm, ifgr.ifgr_attrib.ifg_carp_demoted);
- break;
- default:
- free(ifg);
- return (1);
- }
-
- free(ifg);
- return (0);
-}
-
-int
-mib_memiftable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 0;
- struct kif *kif;
-
- idx = o->bo_id[OIDIDX_memIfEntry];
- if ((kif = mib_ifget(idx)) == NULL)
- return (1);
-
- o->bo_id[OIDIDX_memIfEntry] = kif->if_index;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_memIf]) {
- case 1:
- ber = ober_add_string(ber, kif->if_name);
- break;
- case 2:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Defined in IP-MIB.txt
- */
-
-int mib_getipstat(struct ipstat *);
-int mib_ipstat(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipforwarding(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipdefaultttl(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipinhdrerrs(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipinaddrerrs(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipforwdgrams(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipindiscards(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipreasmfails(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_ipfragfails(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_iproutingdiscards(struct oid *, struct ber_oid *,
- struct ber_element **);
-int mib_ipaddr(struct oid *, struct ber_oid *, struct ber_element **);
-struct ber_oid *
- mib_ipaddrtable(struct oid *, struct ber_oid *, struct ber_oid *);
-int mib_physaddr(struct oid *, struct ber_oid *, struct ber_element **);
-struct ber_oid *
- mib_physaddrtable(struct oid *, struct ber_oid *, struct ber_oid *);
-
-static struct oid ip_mib[] = {
- { MIB(ipMIB), OID_MIB },
- { MIB(ipForwarding), OID_RD, mib_ipforwarding },
- { MIB(ipDefaultTTL), OID_RD, mib_ipdefaultttl },
- { MIB(ipInReceives), OID_RD, mib_ipstat },
- { MIB(ipInHdrErrors), OID_RD, mib_ipinhdrerrs },
- { MIB(ipInAddrErrors), OID_RD, mib_ipinaddrerrs },
- { MIB(ipForwDatagrams), OID_RD, mib_ipforwdgrams },
- { MIB(ipInUnknownProtos), OID_RD, mib_ipstat },
-#ifdef notyet
- { MIB(ipInDiscards) },
-#endif
- { MIB(ipInDelivers), OID_RD, mib_ipstat },
- { MIB(ipOutRequests), OID_RD, mib_ipstat },
- { MIB(ipOutDiscards), OID_RD, mib_ipstat },
- { MIB(ipOutNoRoutes), OID_RD, mib_ipstat },
- { MIB(ipReasmTimeout), OID_RD, mps_getint, NULL,
- NULL, IPFRAGTTL },
- { MIB(ipReasmReqds), OID_RD, mib_ipstat },
- { MIB(ipReasmOKs), OID_RD, mib_ipstat },
- { MIB(ipReasmFails), OID_RD, mib_ipreasmfails },
- { MIB(ipFragOKs), OID_RD, mib_ipstat },
- { MIB(ipFragFails), OID_RD, mib_ipfragfails },
- { MIB(ipFragCreates), OID_RD, mib_ipstat },
- { MIB(ipAdEntAddr), OID_TRD, mib_ipaddr, NULL,
- mib_ipaddrtable },
- { MIB(ipAdEntIfIndex), OID_TRD, mib_ipaddr, NULL,
- mib_ipaddrtable },
- { MIB(ipAdEntNetMask), OID_TRD, mib_ipaddr, NULL,
- mib_ipaddrtable },
- { MIB(ipAdEntBcastAddr), OID_TRD, mib_ipaddr, NULL,
- mib_ipaddrtable },
- { MIB(ipAdEntReasmMaxSize), OID_TRD, mib_ipaddr, NULL,
- mib_ipaddrtable },
- { MIB(ipNetToMediaIfIndex), OID_TRD, mib_physaddr, NULL,
- mib_physaddrtable },
- { MIB(ipNetToMediaPhysAddress), OID_TRD, mib_physaddr, NULL,
- mib_physaddrtable },
- { MIB(ipNetToMediaNetAddress), OID_TRD, mib_physaddr, NULL,
- mib_physaddrtable },
- { MIB(ipNetToMediaType), OID_TRD, mib_physaddr, NULL,
- mib_physaddrtable },
-#ifdef notyet
- { MIB(ipRoutingDiscards) },
-#endif
- { MIBEND }
-};
-
-int
-mib_ipforwarding(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_FORWARDING };
- int v;
- size_t len = sizeof(v);
-
- if (sysctl(mib, nitems(mib), &v, &len, NULL, 0) == -1)
- return (-1);
-
- /* ipForwarding: forwarding(1), notForwarding(2) */
- *elm = ober_add_integer(*elm, (v == 0) ? 2 : 1);
-
- return (0);
-}
-
-int
-mib_ipdefaultttl(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
- int v;
- size_t len = sizeof(v);
-
- if (sysctl(mib, nitems(mib), &v, &len, NULL, 0) == -1)
- return (-1);
-
- *elm = ober_add_integer(*elm, v);
-
- return (0);
-}
-
-int
-mib_getipstat(struct ipstat *ipstat)
-{
- int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS };
- size_t len = sizeof(*ipstat);
-
- return (sysctl(mib, nitems(mib), ipstat, &len, NULL, 0));
-}
-
-int
-mib_ipstat(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ipstat ipstat;
- long long i;
- struct statsmap {
- u_int8_t m_id;
- u_long *m_ptr;
- } mapping[] = {
- { 3, &ipstat.ips_total },
- { 7, &ipstat.ips_noproto },
- { 9, &ipstat.ips_delivered },
- { 10, &ipstat.ips_localout },
- { 11, &ipstat.ips_odropped },
- { 12, &ipstat.ips_noroute },
- { 14, &ipstat.ips_fragments },
- { 15, &ipstat.ips_reassembled },
- { 17, &ipstat.ips_fragmented },
- { 19, &ipstat.ips_ofragments }
- };
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- for (i = 0;
- (u_int)i < (sizeof(mapping) / sizeof(mapping[0])); i++) {
- if (oid->o_oid[OIDIDX_ip] == mapping[i].m_id) {
- *elm = ober_add_integer(*elm, *mapping[i].m_ptr);
- ober_set_header(*elm,
- BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- return (0);
- }
- }
-
- return (-1);
-}
-
-int
-mib_ipinhdrerrs(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t errors;
- struct ipstat ipstat;
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- errors = ipstat.ips_badsum + ipstat.ips_badvers +
- ipstat.ips_tooshort + ipstat.ips_toosmall +
- ipstat.ips_badhlen + ipstat.ips_badlen +
- ipstat.ips_badoptions + ipstat.ips_toolong +
- ipstat.ips_badaddr;
-
- *elm = ober_add_integer(*elm, errors);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
-
- return (0);
-}
-
-int
-mib_ipinaddrerrs(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t errors;
- struct ipstat ipstat;
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- errors = ipstat.ips_cantforward + ipstat.ips_badaddr;
-
- *elm = ober_add_integer(*elm, errors);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
-
- return (0);
-}
-
-int
-mib_ipforwdgrams(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t counter;
- struct ipstat ipstat;
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- counter = ipstat.ips_forward + ipstat.ips_redirectsent;
-
- *elm = ober_add_integer(*elm, counter);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
-
- return (0);
-}
-
-int
-mib_ipindiscards(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- return (0);
-}
-
-int
-mib_ipreasmfails(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t counter;
- struct ipstat ipstat;
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- counter = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
-
- *elm = ober_add_integer(*elm, counter);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
-
- return (0);
-}
-
-int
-mib_ipfragfails(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- u_int32_t counter;
- struct ipstat ipstat;
-
- if (mib_getipstat(&ipstat) == -1)
- return (-1);
-
- counter = ipstat.ips_badfrags + ipstat.ips_cantfrag;
- *elm = ober_add_integer(*elm, counter);
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
-
- return (0);
-}
-
-int
-mib_iproutingdiscards(struct oid *oid, struct ber_oid *o,
- struct ber_element **elm)
-{
- return (0);
-}
-
-struct ber_oid *
-mib_ipaddrtable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
-{
- struct sockaddr_in addr;
- u_int32_t col, id;
- struct oid a, b;
- struct kif_addr *ka;
-
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
-
- bcopy(&oid->o_id, no, sizeof(*no));
- id = oid->o_oidlen - 1;
-
- if (o->bo_n >= oid->o_oidlen) {
- /*
- * Compare the requested and the matched OID to see
- * if we have to iterate to the next element.
- */
- bzero(&a, sizeof(a));
- bcopy(o, &a.o_id, sizeof(struct ber_oid));
- bzero(&b, sizeof(b));
- bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
- b.o_oidlen--;
- b.o_flags |= OID_TABLE;
- if (smi_oid_cmp(&a, &b) == 0) {
- col = oid->o_oid[id];
- o->bo_id[id] = col;
- bcopy(o, no, sizeof(*no));
- }
- }
-
- mps_decodeinaddr(no, &addr.sin_addr, OIDIDX_ipAddr + 1);
- if (o->bo_n <= (OIDIDX_ipAddr + 1))
- ka = kr_getaddr(NULL);
- else
- ka = kr_getnextaddr((struct sockaddr *)&addr);
- if (ka == NULL || ka->addr.sa.sa_family != AF_INET) {
- /*
- * Encode invalid "last address" marker which will tell
- * mib_ipaddr() to fail and the SNMP engine to find the
- * next OID.
- */
- mps_encodeinaddr(no, NULL, OIDIDX_ipAddr + 1);
- } else {
- /* Encode real IPv4 address */
- addr.sin_addr.s_addr = ka->addr.sin.sin_addr.s_addr;
- mps_encodeinaddr(no, &addr.sin_addr, OIDIDX_ipAddr + 1);
- }
- smi_oidlen(o);
-
- return (no);
-}
-
-int
-mib_ipaddr(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct sockaddr_in addr;
- struct ber_element *ber = *elm;
- struct kif_addr *ka;
- u_int32_t val;
-
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
-
- if (mps_decodeinaddr(o, &addr.sin_addr, OIDIDX_ipAddr + 1) == -1) {
- /* Strip invalid address and fail */
- o->bo_n = OIDIDX_ipAddr + 1;
- return (1);
- }
- ka = kr_getaddr((struct sockaddr *)&addr);
- if (ka == NULL || ka->addr.sa.sa_family != AF_INET)
- return (1);
-
- /* write OID */
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_ipAddr]) {
- case 1:
- val = addr.sin_addr.s_addr;
- ber = ober_add_nstring(ber, (char *)&val, sizeof(u_int32_t));
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
- break;
- case 2:
- ber = ober_add_integer(ber, ka->if_index);
- break;
- case 3:
- val = ka->mask.sin.sin_addr.s_addr;
- ber = ober_add_nstring(ber, (char *)&val, sizeof(u_int32_t));
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
- break;
- case 4:
- ber = ober_add_integer(ber, ka->dstbrd.sa.sa_len ? 1 : 0);
- break;
- case 5:
- ber = ober_add_integer(ber, IP_MAXPACKET);
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-struct ber_oid *
-mib_physaddrtable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
-{
- struct sockaddr_in addr;
- struct oid a, b;
- struct kif *kif;
- struct kif_arp *ka;
- u_int32_t id, idx = 0;
-
- bcopy(&oid->o_id, no, sizeof(*no));
- id = oid->o_oidlen - 1;
-
- if (o->bo_n >= oid->o_oidlen) {
- /*
- * Compare the requested and the matched OID to see
- * if we have to iterate to the next element.
- */
- bzero(&a, sizeof(a));
- bcopy(o, &a.o_id, sizeof(struct ber_oid));
- bzero(&b, sizeof(b));
- bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
- b.o_oidlen--;
- b.o_flags |= OID_TABLE;
- if (smi_oid_cmp(&a, &b) == 0) {
- o->bo_id[id] = oid->o_oid[id];
- bcopy(o, no, sizeof(*no));
- }
- }
-
- if (o->bo_n > OIDIDX_ipNetToMedia + 1)
- idx = o->bo_id[OIDIDX_ipNetToMedia + 1];
-
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
- if (o->bo_n > OIDIDX_ipNetToMedia + 2)
- mps_decodeinaddr(no, &addr.sin_addr, OIDIDX_ipNetToMedia + 2);
-
- if ((kif = kr_getif(idx)) == NULL) {
- /* No configured interfaces */
- if (idx == 0)
- return (NULL);
- /*
- * It may happen that an interface with a specific index
- * does not exist or has been removed. Jump to the next
- * available interface.
- */
- kif = kr_getif(0);
- nextif:
- for (; kif != NULL; kif = kr_getnextif(kif->if_index))
- if (kif->if_index > idx &&
- (ka = karp_first(kif->if_index)) != NULL)
- break;
- if (kif == NULL) {
- /* No more interfaces with addresses on them */
- o->bo_id[OIDIDX_ipNetToMedia + 1] = 0;
- mps_encodeinaddr(no, NULL, OIDIDX_ipNetToMedia + 2);
- smi_oidlen(o);
- return (NULL);
- }
- } else {
- if (idx == 0 || addr.sin_addr.s_addr == 0)
- ka = karp_first(kif->if_index);
- else
- ka = karp_getaddr((struct sockaddr *)&addr, idx, 1);
- if (ka == NULL) {
- /* Try next interface */
- goto nextif;
- }
- }
- idx = kif->if_index;
-
- no->bo_id[OIDIDX_ipNetToMedia + 1] = idx;
- /* Encode real IPv4 address */
- memcpy(&addr, &ka->addr.sin, ka->addr.sin.sin_len);
- mps_encodeinaddr(no, &addr.sin_addr, OIDIDX_ipNetToMedia + 2);
-
- smi_oidlen(o);
- return (no);
-}
-
-int
-mib_physaddr(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct sockaddr_in addr;
- struct kif_arp *ka;
- u_int32_t val, idx = 0;
-
- idx = o->bo_id[OIDIDX_ipNetToMedia + 1];
- if (idx == 0) {
- /* Strip invalid interface index and fail */
- o->bo_n = OIDIDX_ipNetToMedia + 1;
- return (1);
- }
-
- /* Get the IP address */
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
-
- if (mps_decodeinaddr(o, &addr.sin_addr,
- OIDIDX_ipNetToMedia + 2) == -1) {
- /* Strip invalid address and fail */
- o->bo_n = OIDIDX_ipNetToMedia + 2;
- return (1);
- }
- if ((ka = karp_getaddr((struct sockaddr *)&addr, idx, 0)) == NULL)
- return (1);
-
- /* write OID */
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_ipNetToMedia]) {
- case 1: /* ipNetToMediaIfIndex */
- ber = ober_add_integer(ber, ka->if_index);
- break;
- case 2: /* ipNetToMediaPhysAddress */
- if (bcmp(LLADDR(&ka->target.sdl), ether_zeroaddr,
- sizeof(ether_zeroaddr)) == 0)
- ber = ober_add_nstring(ber, ether_zeroaddr,
- sizeof(ether_zeroaddr));
- else
- ber = ober_add_nstring(ber, LLADDR(&ka->target.sdl),
- ka->target.sdl.sdl_alen);
- break;
- case 3: /* ipNetToMediaNetAddress */
- val = addr.sin_addr.s_addr;
- ber = ober_add_nstring(ber, (char *)&val, sizeof(u_int32_t));
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_IPADDR);
- break;
- case 4: /* ipNetToMediaType */
- if (ka->flags & F_STATIC)
- ber = ober_add_integer(ber, 4); /* static */
- else
- ber = ober_add_integer(ber, 3); /* dynamic */
- break;
- default:
- return (-1);
- }
- return (0);
-}
-
-/*
- * Defined in IP-FORWARD-MIB.txt (rfc4292)
- */
-
-int mib_ipfnroutes(struct oid *, struct ber_oid *, struct ber_element **);
-struct ber_oid *
-mib_ipfroutetable(struct oid *oid, struct ber_oid *o, struct ber_oid *no);
-int mib_ipfroute(struct oid *, struct ber_oid *, struct ber_element **);
-
-static struct oid ipf_mib[] = {
- { MIB(ipfMIB), OID_MIB },
- { MIB(ipfInetCidrRouteNumber), OID_RD, mib_ipfnroutes },
-
- { MIB(ipfRouteEntIfIndex), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntType), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntProto), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntAge), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntNextHopAS), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntRouteMetric1), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntRouteMetric2), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntRouteMetric3), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntRouteMetric4), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntRouteMetric5), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIB(ipfRouteEntStatus), OID_TRD, mib_ipfroute, NULL,
- mib_ipfroutetable },
- { MIBEND }
-};
-
-int
-mib_ipfnroutes(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- *elm = ober_add_integer(*elm, kr_routenumber());
- ober_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
-
- return (0);
-}
-
-struct ber_oid *
-mib_ipfroutetable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
-{
- u_int32_t col, id;
- struct oid a, b;
- struct sockaddr_in addr;
- struct kroute *kr;
- int af, atype, idx;
- u_int8_t prefixlen;
- u_int8_t prio;
-
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
-
- bcopy(&oid->o_id, no, sizeof(*no));
- id = oid->o_oidlen - 1;
-
- if (o->bo_n >= oid->o_oidlen) {
- /*
- * Compare the requested and the matched OID to see
- * if we have to iterate to the next element.
- */
- bzero(&a, sizeof(a));
- bcopy(o, &a.o_id, sizeof(struct ber_oid));
- bzero(&b, sizeof(b));
- bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
- b.o_oidlen--;
- b.o_flags |= OID_TABLE;
- if (smi_oid_cmp(&a, &b) == 0) {
- col = oid->o_oid[id];
- o->bo_id[id] = col;
- bcopy(o, no, sizeof(*no));
- }
- }
-
- af = no->bo_id[OIDIDX_ipfInetCidrRoute + 1];
- mps_decodeinaddr(no, &addr.sin_addr, OIDIDX_ipfInetCidrRoute + 3);
- prefixlen = o->bo_id[OIDIDX_ipfInetCidrRoute + 7];
- prio = o->bo_id[OIDIDX_ipfInetCidrRoute + 10];
-
- if (af == 0)
- kr = kroute_first();
- else
- kr = kroute_getaddr(addr.sin_addr.s_addr, prefixlen, prio, 1);
-
- if (kr == NULL) {
- addr.sin_addr.s_addr = 0;
- prefixlen = 0;
- prio = 0;
- addr.sin_family = 0;
- } else {
- addr.sin_addr.s_addr = kr->prefix.s_addr;
- prefixlen = kr->prefixlen;
- prio = kr->priority;
- }
-
- switch (addr.sin_family) {
- case AF_INET:
- atype = 1;
- break;
- case AF_INET6:
- atype = 2;
- break;
- default:
- atype = 0;
- break;
- }
- idx = OIDIDX_ipfInetCidrRoute + 1;
- no->bo_id[idx++] = atype;
- no->bo_id[idx++] = 0x04;
- no->bo_n++;
-
- mps_encodeinaddr(no, &addr.sin_addr, idx);
- no->bo_id[no->bo_n++] = prefixlen;
- no->bo_id[no->bo_n++] = 0x02;
- no->bo_n += 2; /* policy */
- no->bo_id[OIDIDX_ipfInetCidrRoute + 10] = prio;
-
- if (kr != NULL) {
- no->bo_id[no->bo_n++] = atype;
- no->bo_id[no->bo_n++] = 0x04;
- mps_encodeinaddr(no, &kr->nexthop, no->bo_n);
- } else
- no->bo_n += 2;
-
- smi_oidlen(o);
-
- return (no);
-}
-
-int
-mib_ipfroute(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- struct kroute *kr;
- struct sockaddr_in addr, nhaddr;
- int idx = o->bo_id[OIDIDX_ipfInetCidrRoute];
- int af;
- u_int8_t prefixlen, prio, type, proto;
-
-
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
-
- af = o->bo_id[OIDIDX_ipfInetCidrRoute + 1];
- mps_decodeinaddr(o, &addr.sin_addr, OIDIDX_ipfInetCidrRoute + 3);
- mps_decodeinaddr(o, &nhaddr.sin_addr, OIDIDX_ipfInetCidrRoute + 23);
- prefixlen = o->bo_id[OIDIDX_ipfInetCidrRoute + 7];
- prio = o->bo_id[OIDIDX_ipfInetCidrRoute + 10];
- kr = kroute_getaddr(addr.sin_addr.s_addr, prefixlen, prio, 0);
- if (kr == NULL || af == 0) {
- return (1);
- }
-
- /* write OID */
- ber = ober_add_oid(ber, o);
-
- switch (idx) {
- case 7: /* IfIndex */
- ber = ober_add_integer(ber, kr->if_index);
- break;
- case 8: /* Type */
- if (kr->flags & F_REJECT)
- type = 2;
- else if (kr->flags & F_BLACKHOLE)
- type = 5;
- else if (kr->flags & F_CONNECTED)
- type = 3;
- else
- type = 4;
- ber = ober_add_integer(ber, type);
- break;
- case 9: /* Proto */
- switch (kr->priority) {
- case RTP_CONNECTED:
- proto = 2;
- break;
- case RTP_STATIC:
- proto = 3;
- break;
- case RTP_OSPF:
- proto = 13;
- break;
- case RTP_ISIS:
- proto = 9;
- break;
- case RTP_RIP:
- proto = 8;
- break;
- case RTP_BGP:
- proto = 14;
- break;
- default:
- if (kr->flags & F_DYNAMIC)
- proto = 4;
- else
- proto = 1; /* not specified */
- break;
- }
- ber = ober_add_integer(ber, proto);
- break;
- case 10: /* Age */
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
- break;
- case 11: /* NextHopAS */
- ber = ober_add_integer(ber, 0); /* unknown */
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
- break;
- case 12: /* Metric1 */
- ber = ober_add_integer(ber, -1); /* XXX */
- break;
- case 13: /* Metric2 */
- ber = ober_add_integer(ber, -1); /* XXX */
- break;
- case 14: /* Metric3 */
- ber = ober_add_integer(ber, -1); /* XXX */
- break;
- case 15: /* Metric4 */
- ber = ober_add_integer(ber, -1); /* XXX */
- break;
- case 16: /* Metric5 */
- ber = ober_add_integer(ber, -1); /* XXX */
- break;
- case 17: /* Status */
- ber = ober_add_integer(ber, 1); /* XXX */
- break;
- default:
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * Defined in UCD-DISKIO-MIB.txt.
- */
-
-int mib_diskio(struct oid *oid, struct ber_oid *o, struct ber_element **elm);
-
-static struct oid diskio_mib[] = {
- { MIB(ucdDiskIOMIB), OID_MIB },
- { MIB(diskIOIndex), OID_TRD, mib_diskio },
- { MIB(diskIODevice), OID_TRD, mib_diskio },
- { MIB(diskIONRead), OID_TRD, mib_diskio },
- { MIB(diskIONWritten), OID_TRD, mib_diskio },
- { MIB(diskIOReads), OID_TRD, mib_diskio },
- { MIB(diskIOWrites), OID_TRD, mib_diskio },
- { MIB(diskIONReadX), OID_TRD, mib_diskio },
- { MIB(diskIONWrittenX), OID_TRD, mib_diskio },
- { MIBEND }
-};
-
-int
-mib_diskio(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx;
- int mib[] = { CTL_HW, 0 };
- unsigned int diskcount;
- struct diskstats *stats;
- size_t len;
-
- len = sizeof(diskcount);
- mib[1] = HW_DISKCOUNT;
- if (sysctl(mib, nitems(mib), &diskcount, &len, NULL, 0) == -1)
- return (-1);
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_diskIOEntry];
- if (idx > diskcount)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_diskIOEntry] = idx;
- ber = ober_add_oid(ber, o);
-
- stats = calloc(diskcount, sizeof(*stats));
- if (stats == NULL)
- return (-1);
- /* We know len won't overflow, otherwise calloc() would have failed. */
- len = diskcount * sizeof(*stats);
- mib[1] = HW_DISKSTATS;
- if (sysctl(mib, nitems(mib), stats, &len, NULL, 0) == -1) {
- free(stats);
- return (-1);
- }
-
- switch (o->bo_id[OIDIDX_diskIO]) {
- case 1: /* diskIOIndex */
- ber = ober_add_integer(ber, idx);
- break;
- case 2: /* diskIODevice */
- ber = ober_add_string(ber, stats[idx - 1].ds_name);
- break;
- case 3: /* diskIONRead */
- ber = ober_add_integer(ber, (u_int32_t)stats[idx - 1].ds_rbytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 4: /* diskIONWritten */
- ber = ober_add_integer(ber, (u_int32_t)stats[idx - 1].ds_wbytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 5: /* diskIOReads */
- ber = ober_add_integer(ber, (u_int32_t)stats[idx - 1].ds_rxfer);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 6: /* diskIOWrites */
- ber = ober_add_integer(ber, (u_int32_t)stats[idx - 1].ds_wxfer);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- case 12: /* diskIONReadX */
- ber = ober_add_integer(ber, stats[idx - 1].ds_rbytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- case 13: /* diskIONWrittenX */
- ber = ober_add_integer(ber, stats[idx - 1].ds_wbytes);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER64);
- break;
- default:
- free(stats);
- return (-1);
- }
-
- free(stats);
- return (0);
-}
-
-/*
- * Defined in BRIDGE-MIB.txt (rfc1493)
- *
- * This MIB is required by some NMS to accept the device because
- * the RFC says that mostly any network device has to provide this MIB... :(
- */
-
-int mib_dot1dtable(struct oid *, struct ber_oid *, struct ber_element **);
-
-static struct oid bridge_mib[] = {
- { MIB(dot1dBridge), OID_MIB },
- { MIB(dot1dBaseBridgeAddress) },
- { MIB(dot1dBaseNumPorts), OID_RD, mib_ifnumber },
- { MIB(dot1dBaseType), OID_RD, mps_getint, NULL,
- NULL, 4 /* srt (sourceroute + transparent) */ },
- { MIB(dot1dBasePort), OID_TRD, mib_dot1dtable },
- { MIB(dot1dBasePortIfIndex), OID_TRD, mib_dot1dtable },
- { MIB(dot1dBasePortCircuit), OID_TRD, mib_dot1dtable},
- { MIB(dot1dBasePortDelayExceededDiscards), OID_TRD, mib_dot1dtable },
- { MIB(dot1dBasePortMtuExceededDiscards), OID_TRD, mib_dot1dtable },
- { MIBEND }
-};
-
-int
-mib_dot1dtable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
- struct ber_element *ber = *elm;
- u_int32_t idx = 0;
- struct kif *kif;
-
- /* Get and verify the current row index */
- idx = o->bo_id[OIDIDX_dot1dEntry];
- if ((kif = mib_ifget(idx)) == NULL)
- return (1);
-
- /* Tables need to prepend the OID on their own */
- o->bo_id[OIDIDX_dot1dEntry] = kif->if_index;
- ber = ober_add_oid(ber, o);
-
- switch (o->bo_id[OIDIDX_dot1d]) {
- case 1:
- case 2:
- ber = ober_add_integer(ber, kif->if_index);
- break;
- case 3:
- ber = ober_add_oid(ber, &zerodotzero);
- break;
- case 4:
- case 5:
- ber = ober_add_integer(ber, 0);
- ober_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_COUNTER32);
- break;
- }
-
- return (0);
-}
-
/*
* Import all MIBs
*/
/* SNMP-USER-BASED-SM-MIB */
smi_mibtree(usm_mib);
-
-#if 0
- /* HOST-RESOURCES-MIB */
- smi_mibtree(hr_mib);
-
- /* IF-MIB */
- smi_mibtree(if_mib);
-
- /* IP-MIB */
- smi_mibtree(ip_mib);
-
- /* IP-FORWARD-MIB */
- smi_mibtree(ipf_mib);
-
- /* BRIDGE-MIB */
- smi_mibtree(bridge_mib);
-
- /* UCD-DISKIO-MIB */
- smi_mibtree(diskio_mib);
-
- /* OPENBSD-MIB */
- smi_mibtree(openbsd_mib);
-#endif
}