diff options
author | Martijn van Duren <martijn@cvs.openbsd.org> | 2022-10-06 14:41:09 +0000 |
---|---|---|
committer | Martijn van Duren <martijn@cvs.openbsd.org> | 2022-10-06 14:41:09 +0000 |
commit | 2bdc1047b2b18a409741f27fc38ef02b484fb8b9 (patch) | |
tree | 15dd61250d6fe7a8cd310581a38ef21f0f3e37c6 /usr.sbin | |
parent | 5221852c45a7e231c4fe9d58551aff2754d5bf8a (diff) |
Remove a lot of old (dead) code that's either been superseded, or moved to
snmpd_metrics.
OK benno@ sthen@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/snmpd/Makefile | 6 | ||||
-rw-r--r-- | usr.sbin/snmpd/kroute.c | 1702 | ||||
-rw-r--r-- | usr.sbin/snmpd/mib.c | 3555 | ||||
-rw-r--r-- | usr.sbin/snmpd/mps.c | 94 | ||||
-rw-r--r-- | usr.sbin/snmpd/parse.y | 6 | ||||
-rw-r--r-- | usr.sbin/snmpd/pf.c | 494 | ||||
-rw-r--r-- | usr.sbin/snmpd/smi.c | 6 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.c | 9 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 217 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpe.c | 118 | ||||
-rw-r--r-- | usr.sbin/snmpd/timer.c | 169 | ||||
-rw-r--r-- | usr.sbin/snmpd/util.c | 27 |
12 files changed, 16 insertions, 6387 deletions
diff --git a/usr.sbin/snmpd/Makefile b/usr.sbin/snmpd/Makefile index c112d9212f0..5a6aa45ab2e 100644 --- a/usr.sbin/snmpd/Makefile +++ b/usr.sbin/snmpd/Makefile @@ -1,12 +1,12 @@ -# $OpenBSD: Makefile,v 1.20 2022/08/23 08:56:20 martijn Exp $ +# $OpenBSD: Makefile,v 1.21 2022/10/06 14:41:08 martijn Exp $ PROG= snmpd MAN= snmpd.8 snmpd.conf.5 SRCS= parse.y log.c snmpe.c application.c application_legacy.c \ application_blocklist.c \ application_agentx.c ax.c \ - mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \ - pf.c proc.c usm.c traphandler.c util.c + mps.c trap.c mib.c smi.c snmpd.c \ + proc.c usm.c traphandler.c util.c LDADD= -levent -lutil -lkvm -lcrypto DPADD= ${LIBEVENT} ${LIBUTIL} diff --git a/usr.sbin/snmpd/kroute.c b/usr.sbin/snmpd/kroute.c deleted file mode 100644 index c1af1548b71..00000000000 --- a/usr.sbin/snmpd/kroute.c +++ /dev/null @@ -1,1702 +0,0 @@ -/* $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); -} diff --git a/usr.sbin/snmpd/mib.c b/usr.sbin/snmpd/mib.c index 35eae856ea6..086978dd1f7 100644 --- a/usr.sbin/snmpd/mib.c +++ b/usr.sbin/snmpd/mib.c @@ -1,4 +1,4 @@ -/* $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> @@ -70,7 +70,6 @@ int mib_sysor(struct oid *, struct ber_oid *, struct ber_element **); 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[] = { @@ -78,9 +77,9 @@ 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 }, @@ -115,7 +114,7 @@ static struct oid base_mib[] = { { 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 } @@ -399,3527 +398,6 @@ mib_usmstats(struct oid *oid, struct ber_oid *o, struct ber_element **elm) } /* - * 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 */ @@ -3940,27 +418,4 @@ mib_init(void) /* 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 } diff --git a/usr.sbin/snmpd/mps.c b/usr.sbin/snmpd/mps.c index c602d630147..8af55a71aef 100644 --- a/usr.sbin/snmpd/mps.c +++ b/usr.sbin/snmpd/mps.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mps.c,v 1.29 2020/06/30 17:11:49 martijn Exp $ */ +/* $OpenBSD: mps.c,v 1.30 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -60,29 +60,6 @@ mps_getstr(struct oid *oid, struct ber_oid *o, struct ber_element **elm) } int -mps_setstr(struct oid *oid, struct ber_oid *o, struct ber_element **elm) -{ - struct ber_element *ber = *elm; - char *s, *v; - - if ((oid->o_flags & OID_WR) == 0) - return (-1); - - if (ber->be_class != BER_CLASS_UNIVERSAL || - ber->be_type != BER_TYPE_OCTETSTRING) - return (-1); - if (ober_get_string(ber, &s) == -1) - return (-1); - if ((v = (void *)strdup(s)) == NULL) - return (-1); - free(oid->o_data); - oid->o_data = v; - oid->o_val = strlen(v); - - return (0); -} - -int mps_getint(struct oid *oid, struct ber_oid *o, struct ber_element **elm) { *elm = ober_add_integer(*elm, oid->o_val); @@ -90,18 +67,6 @@ mps_getint(struct oid *oid, struct ber_oid *o, struct ber_element **elm) } int -mps_setint(struct oid *oid, struct ber_oid *o, struct ber_element **elm) -{ - long long i; - - if (ober_get_integer(*elm, &i) == -1) - return (-1); - oid->o_val = i; - - return (0); -} - -int mps_getts(struct oid *oid, struct ber_oid *o, struct ber_element **elm) { *elm = ober_add_integer(*elm, oid->o_val); @@ -157,26 +122,6 @@ fail: } int -mps_setreq(struct snmp_message *msg, struct ber_element *ber, - struct ber_oid *o) -{ - struct oid key, *value; - - smi_oidlen(o); - if (o->bo_n > BER_MAX_OID_LEN) - return (-1); - bzero(&key, sizeof(key)); - bcopy(o, &key.o_id, sizeof(struct ber_oid)); - value = smi_find(&key); - if (value == NULL) - return (-1); - if ((value->o_flags & OID_WR) == 0 || - value->o_set == NULL) - return (-1); - return (value->o_set(value, o, &ber)); -} - -int mps_getnextreq(struct snmp_message *msg, struct ber_element *root, struct ber_oid *o) { @@ -380,40 +325,3 @@ mps_table(struct oid *oid, struct ber_oid *o, struct ber_oid *no) return (no); } - -void -mps_encodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset) -{ - u_int32_t a, i; - - o->bo_n = offset; - if (addr != NULL) { - a = htole32(addr->s_addr); - o->bo_id[o->bo_n++] = a & 0xff; - o->bo_id[o->bo_n++] = (a >> 8) & 0xff; - o->bo_id[o->bo_n++] = (a >> 16) & 0xff; - o->bo_id[o->bo_n++] = (a >> 24) & 0xff; - } else { - /* Create an invalid "last address" marker (5 bytes) */ - for (i = 0; i < 5; i++) - o->bo_id[o->bo_n++] = 0xff; - } -} - -int -mps_decodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset) -{ - u_int32_t a; - - a = ((o->bo_id[offset] & 0xff)) | - ((o->bo_id[offset + 1] & 0xff) << 8) | - ((o->bo_id[offset + 2] & 0xff) << 16) | - ((o->bo_id[offset + 3] & 0xff) << 24); - addr->s_addr = letoh32(a); - - /* Detect invalid address */ - if ((o->bo_n - offset) > 4) - return (-1); - - return (0); -} diff --git a/usr.sbin/snmpd/parse.y b/usr.sbin/snmpd/parse.y index f0562637e1a..2f04e8803db 100644 --- a/usr.sbin/snmpd/parse.y +++ b/usr.sbin/snmpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.77 2022/08/23 08:56:20 martijn Exp $ */ +/* $OpenBSD: parse.y,v 1.78 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -824,16 +824,12 @@ mib : OBJECTID oid NAME STRING optwrite objtype { switch ($6.type) { case 1: oid->o_get = mps_getint; - oid->o_set = mps_setint; break; case 2: oid->o_get = mps_getstr; - oid->o_set = mps_setstr; break; } oid->o_flags = OID_RD|OID_DYNAMIC; - if ($5) - oid->o_flags |= OID_WR; if (smi_insert(oid) == -1) { yyerror("duplicate oid"); diff --git a/usr.sbin/snmpd/pf.c b/usr.sbin/snmpd/pf.c deleted file mode 100644 index 41e54e73d46..00000000000 --- a/usr.sbin/snmpd/pf.c +++ /dev/null @@ -1,494 +0,0 @@ -/* $OpenBSD: pf.c,v 1.12 2022/01/30 13:26:14 martijn Exp $ */ - -/* - * Copyright (c) 2012 Joel Knight <joel@openbsd.org> - * Copyright (c) 2002 Cedric Berger - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <net/pfvar.h> - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <event.h> - -#include "snmpd.h" - -int devpf = 0; - -size_t buf_esize[PFRB_MAX] = { 0, - sizeof(struct pfr_table), sizeof(struct pfr_tstats), - sizeof(struct pfr_addr), sizeof(struct pfr_astats), - sizeof(struct pfi_kif), sizeof(struct pfioc_trans_e) -}; - -void -pf_init(void) -{ - if ((devpf = open("/dev/pf", O_RDONLY)) == -1) - fatal("pf_init"); -} - -int -pf_get_stats(struct pf_status *s) -{ - extern int devpf; - - memset(s, 0, sizeof(*s)); - if (ioctl(devpf, DIOCGETSTATUS, s) == -1) { - log_warn("DIOCGETSTATUS"); - return (-1); - } - - return (0); -} - -int -pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, - int flags) -{ - struct pfioc_table io; - extern int devpf; - - if (tbl == NULL || size == NULL || *size < 0 || - (*size && addr == NULL)) - return (-1); - - bzero(&io, sizeof io); - io.pfrio_flags = flags; - io.pfrio_table = *tbl; - io.pfrio_buffer = addr; - io.pfrio_esize = sizeof(*addr); - io.pfrio_size = *size; - if (ioctl(devpf, DIOCRGETASTATS, &io) == -1) - return (-1); - *size = io.pfrio_size; - return (0); -} - -int -pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size, - int flags) -{ - struct pfioc_table io; - extern int devpf; - - if (size == NULL || *size < 0 || (*size && tbl == NULL)) - return (-1); - bzero(&io, sizeof io); - io.pfrio_flags = flags; - if (filter != NULL) - io.pfrio_table = *filter; - io.pfrio_buffer = tbl; - io.pfrio_esize = sizeof(*tbl); - io.pfrio_size = *size; - if (ioctl(devpf, DIOCRGETTSTATS, &io) == -1) - return (-1); - *size = io.pfrio_size; - return (0); -} - -int -pfr_buf_grow(struct pfr_buffer *b, int minsize) -{ - caddr_t p; - size_t bs; - - if (minsize != 0 && minsize <= b->pfrb_msize) - return (0); - bs = buf_esize[b->pfrb_type]; - if (!b->pfrb_msize) { - if (minsize < 64) - minsize = 64; - b->pfrb_caddr = calloc(bs, minsize); - if (b->pfrb_caddr == NULL) - return (-1); - b->pfrb_msize = minsize; - } else { - if (minsize == 0) - minsize = b->pfrb_msize * 2; - if (minsize < 0 || (size_t)minsize >= SIZE_MAX / bs) { - /* msize overflow */ - return (-1); - } - p = reallocarray(b->pfrb_caddr, minsize, bs); - if (p == NULL) - return (-1); - bzero(p + b->pfrb_msize * bs, (minsize - b->pfrb_msize) * bs); - b->pfrb_caddr = p; - b->pfrb_msize = minsize; - } - return (0); -} - -const void * -pfr_buf_next(struct pfr_buffer *b, const void *prev) -{ - size_t bs; - - if (b == NULL) - return (NULL); - if (b->pfrb_size == 0) - return (NULL); - if (prev == NULL) - return (b->pfrb_caddr); - bs = buf_esize[b->pfrb_type]; - if ((((const char *)prev)-((char *)b->pfrb_caddr)) / bs >= - (size_t)b->pfrb_size-1) - return (NULL); - - return (((const char *)prev) + bs); -} - -int -pfi_get_ifaces(const char *filter, struct pfi_kif *buf, int *size) -{ - struct pfioc_iface io; - extern int devpf; - - if (size == NULL || *size < 0 || (*size && buf == NULL)) { - errno = EINVAL; - return (-1); - } - bzero(&io, sizeof io); - if (filter != NULL) - if (strlcpy(io.pfiio_name, filter, sizeof(io.pfiio_name)) >= - sizeof(io.pfiio_name)) { - errno = EINVAL; - return (-1); - } - io.pfiio_buffer = buf; - io.pfiio_esize = sizeof(*buf); - io.pfiio_size = *size; - if (ioctl(devpf, DIOCIGETIFACES, &io) == -1) - return (-1); - *size = io.pfiio_size; - return (0); -} - -int -pfi_get(struct pfr_buffer *b, const char *filter) -{ - bzero(b, sizeof(struct pfr_buffer)); - b->pfrb_type = PFRB_IFACES; - for (;;) { - pfr_buf_grow(b, b->pfrb_size); - b->pfrb_size = b->pfrb_msize; - if (pfi_get_ifaces(filter, b->pfrb_caddr, &(b->pfrb_size))) - return (1); - if (b->pfrb_size <= b->pfrb_msize) - break; - } - - return (0); -} - -int -pfi_count(void) -{ - struct pfr_buffer b; - const struct pfi_kif *p; - int c = 0; - - if (pfi_get(&b, NULL)) { - free(b.pfrb_caddr); - return (-1); - } - - PFRB_FOREACH(p, &b) - c++; - - free(b.pfrb_caddr); - return (c); -} - -int -pfi_get_if(struct pfi_kif *rp, int idx) -{ - struct pfr_buffer b; - const struct pfi_kif *p; - int i = 1; - - if (pfi_get(&b, NULL)) { - free(b.pfrb_caddr); - return (-1); - } - - PFRB_FOREACH(p, &b) { - if (i == idx) - break; - i++; - } - - if (p == NULL) { - free(b.pfrb_caddr); - return (-1); - } - - bcopy(p, rp, sizeof(struct pfi_kif)); - free(b.pfrb_caddr); - - return (0); -} - -int -pft_get(struct pfr_buffer *b, struct pfr_table *filter) -{ - bzero(b, sizeof(struct pfr_buffer)); - b->pfrb_type = PFRB_TSTATS; - - for (;;) { - pfr_buf_grow(b, b->pfrb_size); - b->pfrb_size = b->pfrb_msize; - if (pfr_get_tstats(filter, b->pfrb_caddr, &(b->pfrb_size), 0)) - return (1); - if (b->pfrb_size <= b->pfrb_msize) - break; - } - - return (0); -} - -int -pft_get_table(struct pfr_tstats *rts, int idx) -{ - struct pfr_buffer b; - const struct pfr_tstats *ts; - int i = 1; - - if (pft_get(&b, NULL)) { - free(b.pfrb_caddr); - return (-1); - } - - PFRB_FOREACH(ts, &b) { - if (!(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) - continue; - if (i == idx) - break; - i++; - } - - if (ts == NULL) { - free(b.pfrb_caddr); - return (-1); - } - - bcopy(ts, rts, sizeof(struct pfr_tstats)); - free(b.pfrb_caddr); - - return (0); -} - -int -pft_count(void) -{ - struct pfr_buffer b; - const struct pfr_tstats *ts; - int c = 0; - - if (pft_get(&b, NULL)) { - free(b.pfrb_caddr); - return (-1); - } - - PFRB_FOREACH(ts, &b) { - if (!(ts->pfrts_flags & PFR_TFLAG_ACTIVE)) - continue; - c++; - } - - free(b.pfrb_caddr); - return (c); -} - -int -pfta_get(struct pfr_buffer *b, struct pfr_table *filter) -{ - bzero(b, sizeof(struct pfr_buffer)); - b->pfrb_type = PFRB_ASTATS; - - for (;;) { - pfr_buf_grow(b, b->pfrb_size); - b->pfrb_size = b->pfrb_msize; - if (pfr_get_astats(filter, b->pfrb_caddr, &(b->pfrb_size), 0)) { - return (1); - } - if (b->pfrb_size <= b->pfrb_msize) - break; - } - - return (0); -} - -int -pfta_get_addr(struct pfr_astats *ras, int tblidx) -{ - struct pfr_buffer ba; - struct pfr_tstats ts; - struct pfr_table filter; - const struct pfr_astats *as; - - if (pft_get_table(&ts, tblidx)) - return (-1); - - bzero(&filter, sizeof(filter)); - if (strlcpy(filter.pfrt_name, ts.pfrts_name, - sizeof(filter.pfrt_name)) >= sizeof(filter.pfrt_name)) { - return (-1); - } - - if (pfta_get(&ba, &filter) || ba.pfrb_size == 0) { - free(ba.pfrb_caddr); - return (-1); - } - - PFRB_FOREACH(as, &ba) { - if (as->pfras_a.pfra_af != AF_INET) - continue; - if ((memcmp(&as->pfras_a.pfra_ip4addr, &ras->pfras_a.pfra_ip4addr, - sizeof(as->pfras_a.pfra_ip4addr)) == 0) - && (as->pfras_a.pfra_net == ras->pfras_a.pfra_net)) - break; - } - - if (as == NULL) { - free(ba.pfrb_caddr); - return (-1); - } - - bcopy(as, ras, sizeof(struct pfr_astats)); - free(ba.pfrb_caddr); - - return (0); -} - -int -pfta_get_nextaddr(struct pfr_astats *ras, int *tblidx) -{ - struct pfr_buffer ba; - struct pfr_tstats ts; - struct pfr_table filter; - const struct pfr_astats *as; - int i, found = 0; - - ba.pfrb_caddr = NULL; - - for (i = *tblidx; !pft_get_table(&ts, i); i++) { - bzero(&filter, sizeof(filter)); - if (strlcpy(filter.pfrt_name, ts.pfrts_name, - sizeof(filter.pfrt_name)) >= sizeof(filter.pfrt_name)) - goto fail; - - if (pfta_get(&ba, &filter) || ba.pfrb_size == 0) - goto fail; - - PFRB_FOREACH(as, &ba) { - if (as->pfras_a.pfra_af != AF_INET) - continue; - if (found) - goto found; - if ((memcmp(&as->pfras_a.pfra_ip4addr, - &ras->pfras_a.pfra_ip4addr, - sizeof(as->pfras_a.pfra_ip4addr)) == 0) - && (as->pfras_a.pfra_net == ras->pfras_a.pfra_net)) - found = 1; - } - - free(ba.pfrb_caddr); - ba.pfrb_caddr = NULL; - } - - - fail: - free(ba.pfrb_caddr); - - return (-1); - - found: - bcopy(as, ras, sizeof(struct pfr_astats)); - *tblidx = i; - - free(ba.pfrb_caddr); - - return (0); -} - -int -pfta_get_first(struct pfr_astats *ras) -{ - struct pfr_buffer ba; - struct pfr_tstats ts; - struct pfr_table filter; - const struct pfr_astats *as; - - if (pft_get_table(&ts, 1)) - return (-1); - - bzero(&filter, sizeof(filter)); - if (strlcpy(filter.pfrt_name, ts.pfrts_name, - sizeof(filter.pfrt_name)) >= sizeof(filter.pfrt_name)) { - return (-1); - } - - if (pfta_get(&ba, &filter) || ba.pfrb_size == 0) { - free(ba.pfrb_caddr); - return (-1); - } - - /* take the first AF_INET addr */ - PFRB_FOREACH(as, &ba) { - if (as->pfras_a.pfra_af != AF_INET) - continue; - break; - } - - if (as == NULL) { - free(ba.pfrb_caddr); - return (-1); - } - - bcopy(as, ras, sizeof(struct pfr_astats)); - free(ba.pfrb_caddr); - - return (0); -} - diff --git a/usr.sbin/snmpd/smi.c b/usr.sbin/snmpd/smi.c index f37443dfda4..3a5b3badf74 100644 --- a/usr.sbin/snmpd/smi.c +++ b/usr.sbin/snmpd/smi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smi.c,v 1.31 2022/06/30 09:42:19 martijn Exp $ */ +/* $OpenBSD: smi.c,v 1.32 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008 Reyk Floeter <reyk@openbsd.org> @@ -220,7 +220,6 @@ smi_mibtree(struct oid *oids) fatalx("smi_mibtree: undeclared MIB"); decl->o_flags = oid->o_flags; decl->o_get = oid->o_get; - decl->o_set = oid->o_set; decl->o_table = oid->o_table; decl->o_val = oid->o_val; decl->o_data = oid->o_data; @@ -701,8 +700,7 @@ smi_oid_cmp(struct oid *a, struct oid *b) * or a MIB registered by a subagent * (it will match any sub-elements) */ - if ((b->o_flags & OID_TABLE || - b->o_flags & OID_REGISTERED) && + if (b->o_flags & OID_TABLE && (a->o_flags & OID_KEY) == 0 && (a->o_oidlen > b->o_oidlen)) return (0); diff --git a/usr.sbin/snmpd/snmpd.c b/usr.sbin/snmpd/snmpd.c index 627ac94e9d9..6a1f4e5bc97 100644 --- a/usr.sbin/snmpd/snmpd.c +++ b/usr.sbin/snmpd/snmpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpd.c,v 1.47 2022/09/01 14:34:17 martijn Exp $ */ +/* $OpenBSD: snmpd.c,v 1.48 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -228,11 +228,6 @@ main(int argc, char *argv[]) gettimeofday(&env->sc_starttime, NULL); env->sc_engine_boots = 0; -/* Remove after 7.2 */ -#if 0 - pf_init(); -#endif - proc_init(ps, procs, nitems(procs), debug, argc0, argv0, proc_id); if (!debug && daemon(0, 0) == -1) err(1, "failed to daemonize"); @@ -306,8 +301,6 @@ snmpd_dispatch_snmpe(int fd, struct privsep_proc *p, struct imsg *imsg) switch (imsg->hdr.type) { case IMSG_TRAP_EXEC: return (traphandler_priv_recvmsg(p, imsg)); - case IMSG_CTL_RELOAD: - /* XXX notyet */ default: break; } diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h index 5f3f2716fa5..7abeeea0adf 100644 --- a/usr.sbin/snmpd/snmpd.h +++ b/usr.sbin/snmpd/snmpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpd.h,v 1.105 2022/09/01 14:34:17 martijn Exp $ */ +/* $OpenBSD: snmpd.h,v 1.106 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -49,7 +49,6 @@ */ #define CONF_FILE "/etc/snmpd.conf" -#define SNMPD_SOCKET "/var/run/snmpd.sock" #define SNMPD_BACKEND "/usr/libexec/snmpd" #define SNMPD_USER "_snmpd" #define SNMP_PORT "161" @@ -90,12 +89,7 @@ enum imsg_type { IMSG_NONE, - IMSG_CTL_OK, /* answer to snmpctl requests */ - IMSG_CTL_FAIL, - IMSG_CTL_END, - IMSG_CTL_NOTIFY, IMSG_CTL_VERBOSE, - IMSG_CTL_RELOAD, IMSG_CTL_PROCFD, IMSG_TRAP_EXEC, IMSG_AX_FD @@ -125,9 +119,6 @@ enum privsep_procid { extern enum privsep_procid privsep_process; -/* Attach the control socket to the following process */ -#define PROC_CONTROL PROC_SNMPE - struct privsep_pipes { int *pp_pipes[PROC_MAX]; }; @@ -184,106 +175,6 @@ struct privsep_fd { #endif /* - * kroute - */ - -struct kroute_node; -struct kroute6_node; -RB_HEAD(kroute_tree, kroute_node); -RB_HEAD(kroute6_tree, kroute6_node); - -struct ktable { - struct kroute_tree krt; - struct kroute6_tree krt6; - u_int rtableid; - u_int rdomain; -}; - -union kaddr { - struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr_dl sdl; - char pad[32]; -}; - -struct kroute { - struct in_addr prefix; - struct in_addr nexthop; - u_long ticks; - u_int16_t flags; - u_short if_index; - u_int8_t prefixlen; - u_int8_t priority; -}; - -struct kroute6 { - struct in6_addr prefix; - struct in6_addr nexthop; - u_long ticks; - u_int16_t flags; - u_short if_index; - u_int8_t prefixlen; - u_int8_t priority; -}; - -struct kif_addr { - u_short if_index; - union kaddr addr; - union kaddr mask; - union kaddr dstbrd; - - TAILQ_ENTRY(kif_addr) entry; - RB_ENTRY(kif_addr) node; -}; - -struct kif_arp { - u_short flags; - u_short if_index; - union kaddr addr; - union kaddr target; - - TAILQ_ENTRY(kif_arp) entry; -}; - -struct kif { - char if_name[IF_NAMESIZE]; - char if_descr[IFDESCRSIZE]; - u_int8_t if_lladdr[ETHER_ADDR_LEN]; - struct if_data if_data; - u_long if_ticks; - int if_flags; - u_short if_index; -}; -#define if_mtu if_data.ifi_mtu -#define if_type if_data.ifi_type -#define if_addrlen if_data.ifi_addrlen -#define if_hdrlen if_data.ifi_hdrlen -#define if_metric if_data.ifi_metric -#define if_link_state if_data.ifi_link_state -#define if_baudrate if_data.ifi_baudrate -#define if_ipackets if_data.ifi_ipackets -#define if_ierrors if_data.ifi_ierrors -#define if_opackets if_data.ifi_opackets -#define if_oerrors if_data.ifi_oerrors -#define if_collisions if_data.ifi_collisions -#define if_ibytes if_data.ifi_ibytes -#define if_obytes if_data.ifi_obytes -#define if_imcasts if_data.ifi_imcasts -#define if_omcasts if_data.ifi_omcasts -#define if_iqdrops if_data.ifi_iqdrops -#define if_oqdrops if_data.ifi_oqdrops -#define if_noproto if_data.ifi_noproto -#define if_lastchange if_data.ifi_lastchange -#define if_capabilities if_data.ifi_capabilities - -#define F_CONNECTED 0x0001 -#define F_STATIC 0x0002 -#define F_BLACKHOLE 0x0004 -#define F_REJECT 0x0008 -#define F_DYNAMIC 0x0010 - -/* * Message Processing Subsystem (mps) */ @@ -298,23 +189,16 @@ struct oid { int (*o_get)(struct oid *, struct ber_oid *, struct ber_element **); - int (*o_set)(struct oid *, struct ber_oid *, - struct ber_element **); struct ber_oid *(*o_table)(struct oid *, struct ber_oid *, struct ber_oid *); long long o_val; void *o_data; - struct ctl_conn *o_session; - RB_ENTRY(oid) o_element; RB_ENTRY(oid) o_keyword; - TAILQ_ENTRY(oid) o_list; }; -TAILQ_HEAD(oidlist, oid); -#define OID_ROOT 0x00 #define OID_RD 0x01 #define OID_WR 0x02 #define OID_IFSET 0x04 /* only if user-specified value */ @@ -322,19 +206,10 @@ TAILQ_HEAD(oidlist, oid); #define OID_TABLE 0x10 /* dynamic sub-elements */ #define OID_MIB 0x20 /* root-OID of a supported MIB */ #define OID_KEY 0x40 /* lookup tables */ -#define OID_REGISTERED 0x80 /* OID registered by subagent */ #define OID_RS (OID_RD|OID_IFSET) -#define OID_WS (OID_WR|OID_IFSET) -#define OID_RW (OID_RD|OID_WR) -#define OID_RWS (OID_RW|OID_IFSET) #define OID_TRD (OID_RD|OID_TABLE) -#define OID_TWR (OID_WR|OID_TABLE) -#define OID_TRS (OID_RD|OID_IFSET|OID_TABLE) -#define OID_TWS (OID_WR|OID_IFSET|OID_TABLE) -#define OID_TRW (OID_RD|OID_WR|OID_TABLE) -#define OID_TRWS (OID_RW|OID_IFSET|OID_TABLE) #define OID_NOTSET(_oid) \ (((_oid)->o_flags & OID_IFSET) && \ @@ -345,40 +220,6 @@ TAILQ_HEAD(oidlist, oid); #define MIB(...) { { MIB_##__VA_ARGS__ } }, NULL #define MIBEND { { 0 } }, NULL -struct ctl_conn { - TAILQ_ENTRY(ctl_conn) entry; - u_int8_t flags; -#define CTL_CONN_NOTIFY 0x01 -#define CTL_CONN_LOCKED 0x02 /* restricted mode */ - struct imsgev iev; - struct oidlist oids; -}; - -/* - * pf - */ - -enum { PFRB_TABLES = 1, PFRB_TSTATS, PFRB_ADDRS, PFRB_ASTATS, - PFRB_IFACES, PFRB_TRANS, PFRB_MAX }; - -enum { IN, OUT }; -enum { IPV4, IPV6 }; -enum { PASS, BLOCK }; - -enum { PFI_IFTYPE_GROUP, PFI_IFTYPE_INSTANCE }; - -struct pfr_buffer { - int pfrb_type; /* type of content, see enum above */ - int pfrb_size; /* number of objects in buffer */ - int pfrb_msize; /* maximum number of objects in buffer */ - void *pfrb_caddr; /* malloc'ated memory area */ -}; - -#define PFRB_FOREACH(var, buf) \ - for ((var) = pfr_buf_next((buf), NULL); \ - (var) != NULL; \ - (var) = pfr_buf_next((buf), (var))) - /* * daemon structures */ @@ -609,8 +450,6 @@ struct snmpd { struct trap_addresslist sc_trapreceivers; - int sc_ncpu; - int64_t *sc_cpustates; struct ber_oid *sc_blocklist; size_t sc_nblocklist; int sc_rtfilter; @@ -640,26 +479,6 @@ extern struct snmpd *snmpd_env; struct snmpd *parse_config(const char *, u_int); int cmdline_symset(char *); -/* kroute.c */ -void kr_init(void); -void kr_shutdown(void); - -u_int kr_ifnumber(void); -u_long kr_iflastchange(void); -int kr_updateif(u_int); -u_long kr_routenumber(void); - -struct kif *kr_getif(u_short); -struct kif *kr_getnextif(u_short); -struct kif_addr *kr_getaddr(struct sockaddr *); -struct kif_addr *kr_getnextaddr(struct sockaddr *); - -struct kroute *kroute_first(void); -struct kroute *kroute_getaddr(in_addr_t, u_int8_t, u_int8_t, int); - -struct kif_arp *karp_first(u_short); -struct kif_arp *karp_getaddr(struct sockaddr *, u_short, int); - /* snmpe.c */ void snmpe(struct privsep *, struct privsep_proc *); void snmpe_shutdown(void); @@ -680,43 +499,13 @@ int mps_getnextreq(struct snmp_message *, struct ber_element *, struct ber_oid *); int mps_getbulkreq(struct snmp_message *, struct ber_element **, struct ber_element **, struct ber_oid *, int); -int mps_setreq(struct snmp_message *, struct ber_element *, - struct ber_oid *); int mps_set(struct ber_oid *, void *, long long); int mps_getstr(struct oid *, struct ber_oid *, struct ber_element **); -int mps_setstr(struct oid *, struct ber_oid *, - struct ber_element **); int mps_getint(struct oid *, struct ber_oid *, struct ber_element **); -int mps_setint(struct oid *, struct ber_oid *, - struct ber_element **); int mps_getts(struct oid *, struct ber_oid *, struct ber_element **); -void mps_encodeinaddr(struct ber_oid *, struct in_addr *, int); -int mps_decodeinaddr(struct ber_oid *, struct in_addr *, int); -struct ber_oid *mps_table(struct oid *, struct ber_oid *, struct ber_oid *); - -/* pf.c */ -void pf_init(void); -int pf_get_stats(struct pf_status *); -int pfr_get_astats(struct pfr_table *, struct pfr_astats *, - int *, int); -int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, - int *, int); -int pfr_buf_grow(struct pfr_buffer *, int); -const void *pfr_buf_next(struct pfr_buffer *, const void *); -int pfi_get_ifaces(const char *, struct pfi_kif *, int *); -int pfi_get(struct pfr_buffer *, const char *); -int pfi_count(void); -int pfi_get_if(struct pfi_kif *, int); -int pft_get(struct pfr_buffer *, struct pfr_table *); -int pft_count(void); -int pft_get_table(struct pfr_tstats *, int); -int pfta_get(struct pfr_buffer *, struct pfr_table *); -int pfta_get_addr(struct pfr_astats *, int); -int pfta_get_nextaddr(struct pfr_astats *, int *); -int pfta_get_first(struct pfr_astats *); /* smi.c */ int smi_init(void); @@ -736,9 +525,6 @@ int smi_key_cmp(struct oid *, struct oid *); unsigned int smi_application(struct ber_element *); void smi_debug_elements(struct ber_element *); -/* timer.c */ -void timer_init(void); - /* snmpd.c */ int snmpd_socket_af(struct sockaddr_storage *, int); u_long snmpd_engine_time(void); @@ -802,7 +588,6 @@ ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *, socklen_t, struct sockaddr *, socklen_t); ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *, socklen_t *, struct sockaddr *, socklen_t *); -const char *log_in6addr(const struct in6_addr *); const char *print_host(struct sockaddr_storage *, char *, size_t); char *tohexstr(u_int8_t *, int); uint8_t *fromhexstr(uint8_t *, const char *, size_t); diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c index 366604e9aff..263e1a10058 100644 --- a/usr.sbin/snmpd/snmpe.c +++ b/usr.sbin/snmpd/snmpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpe.c,v 1.84 2022/09/01 14:34:17 martijn Exp $ */ +/* $OpenBSD: snmpe.c,v 1.85 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -103,11 +103,6 @@ snmpe_init(struct privsep *ps, struct privsep_proc *p, void *arg) struct snmpd *env = ps->ps_env; struct address *h; -/* Remove after 7.2 */ -#if 0 - kr_init(); - timer_init(); -#endif usm_generate_keys(); appl_init(); @@ -147,10 +142,6 @@ snmpe_shutdown(void) event_del(&h->evt); close(h->fd); } -/* Remove after 7.2 */ -#if 0 - kr_shutdown(); -#endif appl_shutdown(); } @@ -492,115 +483,8 @@ badversion: int snmpe_parsevarbinds(struct snmp_message *msg) { - struct snmp_stats *stats = &snmpd_env->sc_stats; - struct ber_element *varbind, *value, *rvarbind = NULL; - struct ber_element *pvarbind = NULL, *end; - char buf[BUFSIZ]; - struct ber_oid o; - int i; - appl_processpdu(msg, msg->sm_ctxname, msg->sm_version, msg->sm_pdu); return 0; - /* - * Leave code here for now so it's easier to switch back in case of - * issues. - */ - - msg->sm_errstr = "invalid varbind element"; - - varbind = msg->sm_varbind; - msg->sm_varbindresp = NULL; - end = NULL; - - for (i = 1; varbind != NULL && i < SNMPD_MAXVARBIND; - varbind = varbind->be_next, i++) { - if (ober_scanf_elements(varbind, "{oeS$}", &o, &value) == -1) { - stats->snmp_inasnparseerrs++; - msg->sm_errstr = "invalid varbind"; - goto varfail; - } - if (o.bo_n < BER_MIN_OID_LEN || o.bo_n > BER_MAX_OID_LEN) - goto varfail; - - log_debug("%s: %s:%hd: oid %s", __func__, msg->sm_host, - msg->sm_port, smi_oid2string(&o, buf, sizeof(buf), 0)); - - /* - * XXX intotalreqvars should only be incremented after all are - * succeeded - */ - switch (msg->sm_pdutype) { - case SNMP_C_GETNEXTREQ: - if ((rvarbind = ober_add_sequence(NULL)) == NULL) - goto varfail; - if (mps_getnextreq(msg, rvarbind, &o) != 0) { - msg->sm_error = SNMP_ERROR_NOSUCHNAME; - ober_free_elements(rvarbind); - goto varfail; - } - stats->snmp_intotalreqvars++; - break; - case SNMP_C_GETREQ: - if ((rvarbind = ober_add_sequence(NULL)) == NULL) - goto varfail; - if (mps_getreq(msg, rvarbind, &o, - msg->sm_version) != 0) { - msg->sm_error = SNMP_ERROR_NOSUCHNAME; - ober_free_elements(rvarbind); - goto varfail; - } - stats->snmp_intotalreqvars++; - break; - case SNMP_C_SETREQ: - /* - * XXX A set varbind should only be committed if - * all variables are staged - */ - if (mps_setreq(msg, value, &o) == 0) { - stats->snmp_intotalsetvars++; - break; - } - msg->sm_error = SNMP_ERROR_READONLY; - goto varfail; - case SNMP_C_GETBULKREQ: - rvarbind = NULL; - if (mps_getbulkreq(msg, &rvarbind, &end, &o, - (i <= msg->sm_nonrepeaters) - ? 1 : msg->sm_maxrepetitions) != 0) { - msg->sm_error = SNMP_ERROR_NOSUCHNAME; - goto varfail; - } - /* - * XXX This should be the amount of returned - * vars - */ - stats->snmp_intotalreqvars++; - break; - - default: - goto varfail; - } - if (rvarbind == NULL) - break; - if (pvarbind == NULL) - msg->sm_varbindresp = rvarbind; - else - ober_link_elements(pvarbind, rvarbind); - pvarbind = end == NULL ? rvarbind : end; - } - - msg->sm_errstr = "none"; - msg->sm_error = 0; - msg->sm_errorindex = 0; - - return 0; - varfail: - log_debug("%s: %s:%hd: %s, error index %d", __func__, - msg->sm_host, msg->sm_port, msg->sm_errstr, i); - if (msg->sm_error == 0) - msg->sm_error = SNMP_ERROR_GENERR; - msg->sm_errorindex = i; - return -1; } void diff --git a/usr.sbin/snmpd/timer.c b/usr.sbin/snmpd/timer.c deleted file mode 100644 index 26d22b8d9f0..00000000000 --- a/usr.sbin/snmpd/timer.c +++ /dev/null @@ -1,169 +0,0 @@ -/* $OpenBSD: timer.c,v 1.7 2016/10/28 08:01:53 rzalamena Exp $ */ - -/* - * Copyright (c) 2008 Reyk Floeter <reyk@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/queue.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/sched.h> -#include <sys/socket.h> -#include <sys/sysctl.h> - -#include <net/if.h> -#include <net/if_types.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/ip_var.h> -#include <arpa/inet.h> - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <pwd.h> - -#include "snmpd.h" -#include "mib.h" - -void timer_cpu(int, short, void *); -int percentages(int, int64_t *, int64_t *, int64_t *, int64_t *); - -static int64_t **cp_time; -static int64_t **cp_old; -static int64_t **cp_diff; -struct event cpu_ev; - -void -timer_cpu(int fd, short event, void *arg) -{ - struct event *ev = (struct event *)arg; - struct timeval tv = { 60, 0 }; /* every 60 seconds */ - int mib[3] = { CTL_KERN, KERN_CPTIME2, 0 }, n; - size_t len; - int64_t *cptime2; - - len = CPUSTATES * sizeof(int64_t); - for (n = 0; n < snmpd_env->sc_ncpu; n++) { - mib[2] = n; - cptime2 = snmpd_env->sc_cpustates + (CPUSTATES * n); - if (sysctl(mib, 3, cp_time[n], &len, NULL, 0) == -1) - continue; - (void)percentages(CPUSTATES, cptime2, cp_time[n], - cp_old[n], cp_diff[n]); -#ifdef DEBUG - log_debug("timer_cpu: cpu%d %lld%% idle in %llds", n, - (cptime2[CP_IDLE] > 1000 ? - 1000 : (cptime2[CP_IDLE] / 10)), (long long) tv.tv_sec); -#endif - } - - evtimer_add(ev, &tv); -} - -void -timer_init(void) -{ - int mib[] = { CTL_HW, HW_NCPU }, i; - size_t len; - - len = sizeof(snmpd_env->sc_ncpu); - if (sysctl(mib, 2, &snmpd_env->sc_ncpu, &len, NULL, 0) == -1) - fatal("sysctl"); - - snmpd_env->sc_cpustates = calloc(snmpd_env->sc_ncpu, - CPUSTATES * sizeof(int64_t)); - cp_time = calloc(snmpd_env->sc_ncpu, sizeof(int64_t *)); - cp_old = calloc(snmpd_env->sc_ncpu, sizeof(int64_t *)); - cp_diff = calloc(snmpd_env->sc_ncpu, sizeof(int64_t *)); - if (snmpd_env->sc_cpustates == NULL || - cp_time == NULL || cp_old == NULL || cp_diff == NULL) - fatal("calloc"); - for (i = 0; i < snmpd_env->sc_ncpu; i++) { - cp_time[i] = calloc(CPUSTATES, sizeof(int64_t)); - cp_old[i] = calloc(CPUSTATES, sizeof(int64_t)); - cp_diff[i] = calloc(CPUSTATES, sizeof(int64_t)); - if (cp_time[i] == NULL || cp_old[i] == NULL || - cp_diff[i] == NULL) - fatal("calloc"); - } - - evtimer_set(&cpu_ev, timer_cpu, &cpu_ev); - timer_cpu(0, EV_TIMEOUT, &cpu_ev); -} - -/* - * percentages() function to calculate CPU utilization. - * Source code derived from the top(1) utility: - * - * Copyright (c) 1984, 1989, William LeFebvre, Rice University - * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR OR HIS EMPLOYER BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -int -percentages(int cnt, int64_t *out, int64_t *new, int64_t *old, int64_t *diffs) -{ - int64_t change, total_change, *dp, half_total; - int i; - - /* initialization */ - total_change = 0; - dp = diffs; - - /* calculate changes for each state and the overall change */ - for (i = 0; i < cnt; i++) { - if ((change = *new - *old) < 0) { - /* this only happens when the counter wraps */ - change = (*new - *old); - } - total_change += (*dp++ = change); - *old++ = *new++; - } - - /* avoid divide by zero potential */ - if (total_change == 0) - total_change = 1; - - /* calculate percentages based on overall change, rounding up */ - half_total = total_change / 2l; - for (i = 0; i < cnt; i++) - *out++ = ((*diffs++ * 1000 + half_total) / total_change); - - /* return the total in case the caller wants to use it */ - return (total_change); -} diff --git a/usr.sbin/snmpd/util.c b/usr.sbin/snmpd/util.c index e0a798fbcd7..d4b970908e5 100644 --- a/usr.sbin/snmpd/util.c +++ b/usr.sbin/snmpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.12 2021/08/09 18:14:53 martijn Exp $ */ +/* $OpenBSD: util.c,v 1.13 2022/10/06 14:41:08 martijn Exp $ */ /* * Copyright (c) 2014 Bret Stephen Lambert <blambert@openbsd.org> * @@ -155,31 +155,6 @@ recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from, } const char * -log_in6addr(const struct in6_addr *addr) -{ - static char buf[NI_MAXHOST]; - struct sockaddr_in6 sa_in6; - u_int16_t tmp16; - - bzero(&sa_in6, sizeof(sa_in6)); - sa_in6.sin6_len = sizeof(sa_in6); - sa_in6.sin6_family = AF_INET6; - memcpy(&sa_in6.sin6_addr, addr, sizeof(sa_in6.sin6_addr)); - - /* XXX thanks, KAME, for this ugliness... adopted from route/show.c */ - if (IN6_IS_ADDR_LINKLOCAL(&sa_in6.sin6_addr) || - IN6_IS_ADDR_MC_LINKLOCAL(&sa_in6.sin6_addr)) { - memcpy(&tmp16, &sa_in6.sin6_addr.s6_addr[2], sizeof(tmp16)); - sa_in6.sin6_scope_id = ntohs(tmp16); - sa_in6.sin6_addr.s6_addr[2] = 0; - sa_in6.sin6_addr.s6_addr[3] = 0; - } - - return (print_host((struct sockaddr_storage *)&sa_in6, buf, - NI_MAXHOST)); -} - -const char * print_host(struct sockaddr_storage *ss, char *buf, size_t len) { if (getnameinfo((struct sockaddr *)ss, ss->ss_len, |