summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpd/mib.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/snmpd/mib.c')
-rw-r--r--usr.sbin/snmpd/mib.c237
1 files changed, 233 insertions, 4 deletions
diff --git a/usr.sbin/snmpd/mib.c b/usr.sbin/snmpd/mib.c
index fc9a31c07c4..7ac40315e5f 100644
--- a/usr.sbin/snmpd/mib.c
+++ b/usr.sbin/snmpd/mib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.c,v 1.48 2012/01/30 22:04:28 joel Exp $ */
+/* $OpenBSD: mib.c,v 1.49 2012/01/31 18:00:46 joel Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -27,13 +27,16 @@
#include <sys/sysctl.h>
#include <sys/sensors.h>
#include <sys/sched.h>
+#include <sys/socket.h>
#include <sys/mount.h>
+#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_types.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <netinet/ip_carp.h>
#include <netinet/ip_var.h>
#include <arpa/inet.h>
@@ -1210,14 +1213,27 @@ mib_ifrcvtable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
}
/*
- * Defined in OPENBSD-SENSORS-MIB.txt
- * (http://packetmischief.ca/openbsd/snmp/)
- */
+ * Defined in
+ * - 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_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_carpifnum(struct oid *, struct ber_oid *, struct ber_element **);
+struct carpif
+ *mib_carpifget(struct carpif *, u_int);
int mib_memiftable(struct oid *, struct ber_oid *, struct ber_element **);
static struct oid openbsd_mib[] = {
@@ -1230,6 +1246,33 @@ static struct oid openbsd_mib[] = {
{ 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(memMIBObjects), OID_MIB },
{ MIB(memMIBVersion), OID_RD, mps_getint, NULL, NULL,
OIDVER_OPENBSD_MEM },
@@ -1418,6 +1461,192 @@ mib_sensorvalue(struct sensor *s)
}
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 = ber_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 = ber_add_integer(*elm, *mapping[i].m_ptr);
+ ber_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 = ber_add_integer(*elm, c);
+ return (0);
+}
+
+struct carpif *
+mib_carpifget(struct carpif *cif, u_int idx)
+{
+ struct kif *kif;
+ 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)
+ return (NULL);
+
+ memset(cif, 0, sizeof(struct carpif));
+ 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;
+
+ if ((cif = malloc(sizeof(struct carpif))) == NULL)
+ return (1);
+
+ /* Get and verify the current row index */
+ idx = o->bo_id[OIDIDX_carpIfEntry];
+
+ if ((cif = mib_carpifget(cif, idx)) == NULL) {
+ free(cif);
+ return (1);
+ }
+
+ /* Tables need to prepend the OID on their own */
+ o->bo_id[OIDIDX_carpIfEntry] = cif->kif.if_index;
+ *elm = ber_add_oid(*elm, o);
+
+ switch (o->bo_id[OIDIDX_carpIf]) {
+ case 1:
+ *elm = ber_add_integer(*elm, cif->kif.if_index);
+ break;
+ case 2:
+ *elm = ber_add_string(*elm, cif->kif.if_name);
+ break;
+ case 3:
+ *elm = ber_add_integer(*elm, cif->carpr.carpr_vhids[0]);
+ break;
+ case 4:
+ *elm = ber_add_string(*elm, cif->carpr.carpr_carpdev);
+ break;
+ case 5:
+ *elm = ber_add_integer(*elm, cif->carpr.carpr_advbase);
+ break;
+ case 6:
+ *elm = ber_add_integer(*elm, cif->carpr.carpr_advskews[0]);
+ break;
+ case 7:
+ *elm = ber_add_integer(*elm, cif->carpr.carpr_states[0]);
+ break;
+ default:
+ free(cif);
+ return (1);
+ }
+
+ free(cif);
+ return (0);
+}
+
+int
mib_memiftable(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
{
struct ber_element *ber = *elm;