f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER START
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The contents of this file are subject to the terms of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Common Development and Distribution License (the "License").
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You may not use this file except in compliance with the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * or http://www.opensolaris.org/os/licensing.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * See the License for the specific language governing permissions
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * and limitations under the License.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * When distributing Covered Code, include this CDDL HEADER in each
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If applicable, add the following below this CDDL HEADER, with the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * fields enclosed by brackets "[]" replaced with your own identifying
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * information: Portions Copyright [yyyy] [name of copyright owner]
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * CDDL HEADER END
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <sys/fm/protocol.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/fmd_snmp.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/fmd_msg.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <fm/libfmevent.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <net-snmp/net-snmp-config.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <net-snmp/net-snmp-includes.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <net-snmp/agent/net-snmp-agent-includes.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <errno.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <locale.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <netdb.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <signal.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <strings.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <stdlib.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <unistd.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <limits.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <alloca.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <priv_utils.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include <zone.h>
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#include "libfmnotify.h"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Debug messages can be enabled by setting the debug property to true
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * # svccfg -s svc:/system/fm/snmp-notify setprop config/debug=true
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby#define SVCNAME "system/fm/snmp-notify"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbytypedef struct ireport_trap {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *host;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *msgid;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *desc;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby long long tstamp;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *fmri;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint32_t from_state;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint32_t to_state;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *reason;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t is_stn_event;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby} ireport_trap_t;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic nd_hdl_t *nhdl;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char optstr[] = "dfR:";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic const char SNMP_SUPPCONF[] = "fmd-trapgen";
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic char hostname[MAXHOSTNAMELEN + 1];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyusage(const char *pname)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr, "Usage: %s [-df] [-R <altroot>]\n", pname);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-d enable debug mode\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-f stay in foreground\n"
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "\t-R specify alternate root\n");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If someone does an "svcadm refresh" on us, then this function gets called,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * which rereads our service configuration.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_svc_config()
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int s = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint8_t val;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s = nd_get_boolean_prop(nhdl, SVCNAME, "config", "debug", &val);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_debug = val;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby s += nd_get_astring_prop(nhdl, SVCNAME, "config", "rootdir",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &(nhdl->nh_rootdir));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (s != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to read retrieve service "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "properties");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbynd_sighandler(int sig)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (sig == SIGHUP)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_svc_config();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_cleanup(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyget_snmp_prefs(nd_hdl_t *nhdl, nvlist_t **pref_nvl, uint_t npref)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t *a1, *a2;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t n;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int r;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * For SMF state transition events, pref_nvl contain two sets of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * preferences, which will have to be merged.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The "snmp" nvlist currently only supports a single boolean member,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * "active" which will be set to true, if it is true in either set
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (npref == 2) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r = nvlist_lookup_boolean_array(pref_nvl[0], "active", &a1, &n);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby r += nvlist_lookup_boolean_array(pref_nvl[1], "active", &a2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &n);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (r != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Malformed snmp notification "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "preferences");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, pref_nvl[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, pref_nvl[1]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (!a1[0] && !a2[0]) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "SNMP notification is disabled");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_boolean_array(pref_nvl[0], "active",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &a1, &n)) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Malformed snmp notification "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "preferences");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, pref_nvl[0]);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (!a1[0]) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "SNMP notification is disabled");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbysend_ireport_trap(ireport_trap_t *t)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportTrap_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTTRAP_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const size_t sunIreportTrap_len =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby OID_LENGTH(sunIreportTrap_oid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportHostname_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTHOSTNAME_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportMsgid_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTMSGID_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportDescription_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTDESCRIPTION_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportTime_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTTIME_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportSmfFmri_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTSMFFMRI_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportSmfFromState_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTSMFFROMSTATE_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportSmfToState_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTSMFTOSTATE_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunIreportSmfTransitionReason_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNIREPORTTRANSITIONREASON_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const size_t
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len = OID_LENGTH(sunIreportHostname_oid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t var_len = sunIreport_base_len + 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby oid var_name[MAX_OID_LEN];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby netsnmp_variable_list *notification_vars = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t dt_len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uchar_t dt[11], *tdt;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby time_t ts = t->tstamp;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby tdt = date_n_time(&ts, &dt_len);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We know date_n_time is broken, it returns a buffer from
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * its stack. So we copy before we step over it!
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < dt_len; ++i)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby dt[i] = tdt[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (var_len > MAX_OID_LEN) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "var_len %d > MAX_OID_LEN %d\n", var_len,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby MAX_OID_LEN);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportHostname_oid, sunIreport_base_len *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->host,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strlen(t->host));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportMsgid_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->msgid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strlen(t->msgid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportDescription_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->desc,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strlen(t->desc));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportTime_oid, sunIreport_base_len *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR, dt, dt_len);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (t->is_stn_event) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportSmfFmri_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR, (uchar_t *)t->fmri,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby strlen(t->fmri));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportSmfFromState_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_INTEGER,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (uchar_t *)&t->from_state, sizeof (uint32_t));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportSmfToState_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_INTEGER,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (uchar_t *)&t->to_state, sizeof (uint32_t));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunIreportSmfTransitionReason_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreport_base_len + 1, ASN_OCTET_STR,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (uchar_t *)t->reason, strlen(t->reason));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function is capable of sending both v1 and v2/v3 traps.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Which is sent to a specific destination is determined by the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * configuration file(s).
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_enterprise_trap_vars(SNMP_TRAP_ENTERPRISESPECIFIC,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunIreportTrap_oid[sunIreportTrap_len - 1],
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (oid *)sunIreportTrap_oid, sunIreportTrap_len - 2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby notification_vars);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Sent SNMP trap for %s", t->msgid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmp_free_varbind(notification_vars);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbysend_fm_trap(const char *uuid, const char *code, const char *url)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunFmProblemTrap_oid[] = { SUNFMPROBLEMTRAP_OID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const size_t sunFmProblemTrap_len = OID_LENGTH(sunFmProblemTrap_oid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunFmProblemUUID_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_UUID };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunFmProblemCode_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_CODE };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby static const oid sunFmProblemURL_oid[] =
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_URL };
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby const size_t sunFmProblem_base_len = OID_LENGTH(sunFmProblemUUID_oid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t uuid_len = strlen(uuid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby size_t var_len = sunFmProblem_base_len + 1 + uuid_len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby oid var_name[MAX_OID_LEN];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby netsnmp_variable_list *notification_vars = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The format of our trap varbinds' oids is as follows:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * +-----------------------+---+--------+----------+------+
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * | SUNFMPROBLEMTABLE_OID | 1 | column | uuid_len | uuid |
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * +-----------------------+---+--------+----------+------+
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * \---- index ----/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * A common mistake here is to send the trap with varbinds that
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * do not contain the index. All the indices are the same, and
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * all the oids are the same length, so the only thing we need to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * do for each varbind is set the table and column parts of the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * variable name.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (var_len > MAX_OID_LEN)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby var_name[sunFmProblem_base_len] = (oid)uuid_len;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby for (int i = 0; i < uuid_len; i++)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby var_name[i + sunFmProblem_base_len + 1] = (oid)uuid[i];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Ordinarily, we would need to add the OID of the trap itself
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * to the head of the variable list; this is required by SNMP v2.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * However, send_enterprise_trap_vars does this for us as a part
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * of converting between v1 and v2 traps, so we skip directly to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * the objects we're sending.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunFmProblemUUID_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunFmProblem_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ASN_OCTET_STR, (uchar_t *)uuid, strlen(uuid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunFmProblemCode_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunFmProblem_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ASN_OCTET_STR, (uchar_t *)code, strlen(code));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) memcpy(var_name, sunFmProblemURL_oid,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunFmProblem_base_len * sizeof (oid));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ASN_OCTET_STR, (uchar_t *)url, strlen(url));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function is capable of sending both v1 and v2/v3 traps.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Which is sent to a specific destination is determined by the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * configuration file(s).
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_enterprise_trap_vars(SNMP_TRAP_ENTERPRISESPECIFIC,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sunFmProblemTrap_oid[sunFmProblemTrap_len - 1],
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (oid *)sunFmProblemTrap_oid, sunFmProblemTrap_len - 2,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby notification_vars);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Sent SNMP trap for %s", code);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmp_free_varbind(notification_vars);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The SUN-IREPORT-MIB declares the following enum to represent SMF service
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * states.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * offline(0), online(1), degraded(2), disabled(3), maintenance(4),
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * uninitialized(5)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * This function converts a string representation of an SMF service state
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * to it's corresponding enum val.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystate_to_val(char *statestr, uint32_t *stateval)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strcmp(statestr, "offline") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (strcmp(statestr, "online") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 1;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (strcmp(statestr, "degraded") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 2;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (strcmp(statestr, "disabled") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 3;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (strcmp(statestr, "maintenance") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 4;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else if (strcmp(statestr, "uninitialized") == 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *stateval = 5;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (-1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyireport_cb(fmev_t ev, const char *class, nvlist_t *nvl, void *arg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t **pref_nvl = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t *ev_info = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ireport_trap_t swtrap;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t npref;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Received event of class %s", class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = nd_get_notify_prefs(nhdl, "snmp", ev, &pref_nvl, &npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ret == SCF_ERROR_NOT_FOUND) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * No snmp notification preferences specified for this type of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event, so we're done
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (ret != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to retrieve notification preferences "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (get_snmp_prefs(nhdl, pref_nvl, npref) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_get_event_info(nhdl, class, ev, &ev_info) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.host = hostname;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.msgid = ev_info->ei_diagcode;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.desc = ev_info->ei_descr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.tstamp = (time_t)fmev_time_sec(ev);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strncmp(class, "ireport.os.smf", 14) == 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.fmri = ev_info->ei_fmri;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (state_to_val(ev_info->ei_from_state, &swtrap.from_state)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby < 0 ||
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby state_to_val(ev_info->ei_to_state, &swtrap.to_state) < 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Malformed event - invalid svc state");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_dump_nvlist(nhdl, ev_info->ei_payload);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto irpt_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.reason = ev_info->ei_reason;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby swtrap.is_stn_event = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_ireport_trap(&swtrap);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyirpt_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(ev_info);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_nvlarray(pref_nvl, npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby/*ARGSUSED*/
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic void
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbylist_cb(fmev_t ev, const char *class, nvlist_t *nvl, void *arg)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char *uuid;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint8_t version;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_ev_info_t *ev_info = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nvlist_t **pref_nvl = NULL;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby uint_t npref;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int ret;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t domsg;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Received event of class %s", class);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ret = nd_get_notify_prefs(nhdl, "snmp", ev, &pref_nvl, &npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ret == SCF_ERROR_NOT_FOUND) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * No snmp notification preferences specified for this type of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * event, so we're done
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else if (ret != 0) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "Failed to retrieve notification preferences "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (get_snmp_prefs(nhdl, pref_nvl, npref) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nd_get_event_info(nhdl, class, ev, &ev_info) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If the message payload member is set to 0, then it's an event we
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * typically suppress messaging on, so we won't send a trap for it.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_boolean_value(ev_info->ei_payload, FM_SUSPECT_MESSAGE,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &domsg) == 0 && !domsg) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Messaging suppressed for this event");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nvlist_lookup_uint8(ev_info->ei_payload, FM_VERSION, &version)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby != 0 || version > FM_SUSPECT_VERSION) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "invalid event version: %u", version);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby goto listcb_done;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) nvlist_lookup_string(ev_info->ei_payload, FM_SUSPECT_UUID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby &uuid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (strcmp(ev_info->ei_url, ND_UNKNOWN) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby send_fm_trap(uuid, ev_info->ei_diagcode, ev_info->ei_url);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_error(nhdl, "failed to format url for %s", uuid);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbylistcb_done:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_nvlarray(pref_nvl, npref);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (ev_info)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_free_event_info(ev_info);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbystatic int
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyinit_sma(void)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby int err;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * The only place we could possibly log is syslog, but the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * full agent doesn't normally log there. It would be confusing
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * if this agent did so; therefore we disable logging entirely.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmp_disable_log();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Net-SNMP has a provision for reading an arbitrary number of
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * configuration files. A configuration file is read if it has
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * had any handlers registered for it, or if it's the value in
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * of NETSNMP_DS_LIB_APPTYPE. Our objective here is to read
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * both snmpd.conf and fmd-trapgen.conf.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((err = netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NETSNMP_DS_AGENT_ROLE, 0 /* MASTER_AGENT */)) != SNMPERR_SUCCESS)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (err);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby init_agent_read_config("snmpd");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((err = netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NETSNMP_DS_LIB_APPTYPE, SNMP_SUPPCONF)) != SNMPERR_SUCCESS)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (err);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (register_app_config_handler("trapsink", snmpd_parse_config_trapsink,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmpd_free_trapsinks, "host [community] [port]") == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (SNMPERR_MALLOC);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (register_app_config_handler("trap2sink",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmpd_parse_config_trap2sink, NULL, "host [community] [port]") ==
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (SNMPERR_MALLOC);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (register_app_config_handler("trapsess", snmpd_parse_config_trapsess,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL, "[snmpcmdargs] host") == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (SNMPERR_MALLOC);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby init_traps();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby init_snmp(SNMP_SUPPCONF);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (SNMPERR_SUCCESS);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbyint
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltbymain(int argc, char *argv[])
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby{
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct rlimit rlim;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby struct sigaction act;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby sigset_t set;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby char c;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby boolean_t run_fg = B_FALSE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if ((nhdl = malloc(sizeof (nd_hdl_t))) == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) fprintf(stderr, "Failed to allocate space for notifyd "
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby "handle (%s)", strerror(errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby bzero(nhdl, sizeof (nd_hdl_t));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_keep_running = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_log_fd = stderr;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_pname = argv[0];
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby get_svc_config();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * In the case where we get started outside of SMF, args passed on the
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * command line override SMF property setting
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (optind < argc) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while ((c = getopt(argc, argv, optstr)) != -1) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby switch (c) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'd':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_debug = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'f':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby run_fg = B_TRUE;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby case 'R':
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_rootdir = strdup(optarg);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby break;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby default:
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (usage(nhdl->nh_pname));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Set up a signal handler for SIGTERM (and SIGINT if we'll
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * be running in the foreground) to ensure sure we get a chance to exit
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * in an orderly fashion. We also catch SIGHUP, which will be sent to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * us by SMF if the service is refreshed.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigfillset(&set);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigfillset(&act.sa_mask);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby act.sa_handler = nd_sighandler;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby act.sa_flags = 0;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGTERM, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGTERM);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGHUP, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGHUP);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (run_fg) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigaction(SIGINT, &act, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigdelset(&set, SIGINT);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby } else
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_daemonize(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rlim.rlim_cur = RLIM_INFINITY;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby rlim.rlim_max = RLIM_INFINITY;
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) setrlimit(RLIMIT_CORE, &rlim);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We need to be root initialize our libfmevent handle (because that
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * involves reading/writing to /dev/sysevent), so we do this before
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * calling __init_daemon_priv.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_evhdl = fmev_shdl_init(LIBFMEVENT_VERSION_2, NULL, NULL, NULL);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_evhdl == NULL) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sleep(5);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "failed to initialize libfmevent: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * If we're in the global zone, reset all of our privilege sets to
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * the minimum set of required privileges. We also change our
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * uid/gid to noaccess/noaccess
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * __init_daemon_priv will also set the process core path for us
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby *
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (getzoneid() == GLOBAL_ZONEID)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (__init_daemon_priv(
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby PU_RESETGROUPS | PU_LIMITPRIVS | PU_INHERITPRIVS,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby 60002, 60002, PRIV_FILE_DAC_READ, NULL) != 0)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "additional privileges required to run");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nhdl->nh_msghdl = fmd_msg_init(nhdl->nh_rootdir, FMD_MSG_VERSION);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (nhdl->nh_msghdl == NULL)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "failed to initialize libfmd_msg");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (init_sma() != SNMPERR_SUCCESS)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "SNMP initialization failed");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) gethostname(hostname, MAXHOSTNAMELEN + 1);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * Set up our event subscriptions. We subscribe to everything and then
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * consult libscf when we receive an event to determine what (if any)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * notification to send.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Subscribing to ireport.os.smf.* events");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmev_shdl_subscribe(nhdl->nh_evhdl, "ireport.os.smf.*",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby ireport_cb, NULL) != FMEV_SUCCESS) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "fmev_shdl_subscribe failed: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_debug(nhdl, "Subscribing to list.* events");
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby if (fmev_shdl_subscribe(nhdl->nh_evhdl, "list.*", list_cb,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby NULL) != FMEV_SUCCESS) {
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby nd_abort(nhdl, "fmev_shdl_subscribe failed: %s",
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby fmev_strerror(fmev_errno));
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby }
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * We run until someone kills us
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby while (nhdl->nh_keep_running)
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) sigsuspend(&set);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby /*
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * snmp_shutdown, which we would normally use here, calls free_slots,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * a callback that is supposed to tear down the pkcs11 state; however,
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * it abuses C_Finalize, causing fmd to drop core on shutdown. Avoid
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby * this by shutting down the library piecemeal.
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby */
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmp_store(SNMP_SUPPCONF);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby snmp_alarm_unregister_all();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby (void) snmp_close_sessions();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby shutdown_mib();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby unregister_all_config_handlers();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby netsnmp_ds_shutdown();
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl->nh_rootdir);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby free(nhdl);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby return (0);
f6e214c7418f43af38bd8c3a557e3d0a1d311cfaGavin Maltby}