Пример #1
0
static netsnmp_session *snmp_init (const char *target)
{
	static netsnmp_session *session = NULL;
#ifndef NETSNMPV54
	char default_port[128];
	snprintf (default_port, sizeof (default_port), "%s:162", target);
#endif
	if (session) {
		return (session);
	}

	if (target == NULL) {
		return NULL;
	}

	session = malloc (sizeof (netsnmp_session));
	snmp_sess_init (session);
	session->version = SNMP_VERSION_2c;
	session->callback = NULL;
	session->callback_magic = NULL;

	session = snmp_add(session,
#ifdef NETSNMPV54
		netsnmp_transport_open_client ("snmptrap", target),
#else
		netsnmp_tdomain_transport (default_port, 0, "udp"),
#endif
		NULL, NULL);

	if (session == NULL) {
		qb_log(LOG_ERR, 0, "Could not create snmp transport");
	}
	return (session);
}
Пример #2
0
int
snmp_init(selector_t *sel)
{
    struct snmp_session session;
#ifdef HAVE_NETSNMP
    netsnmp_transport *transport = NULL;
    static char *snmp_default_port = "udp:162";

    netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
			   NETSNMP_DS_LIB_MIB_ERRORS,
			   0);

    init_snmp("ipmi_ui");

    transport = netsnmp_tdomain_transport(snmp_default_port, 1, "udp");
    if (!transport) {
        snmp_sess_perror("ipmi_ui", &session);
	return -1;
    }
#else
    void *transport = NULL;
#endif
    snmp_sess_init(&session);
    session.peername = SNMP_DEFAULT_PEERNAME;
    session.version = SNMP_DEFAULT_VERSION;
    session.community_len = SNMP_DEFAULT_COMMUNITY_LEN;
    session.retries = SNMP_DEFAULT_RETRIES;
    session.timeout = SNMP_DEFAULT_TIMEOUT;
    session.local_port = SNMP_TRAP_PORT;
    session.callback = snmp_input;
    session.callback_magic = transport;
    session.authenticator = NULL;
    session.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;

#ifdef HAVE_NETSNMP
    snmp_session = snmp_add(&session, transport, snmp_pre_parse, NULL);
#else
    snmp_session = snmp_open_ex(&session, snmp_pre_parse,
				NULL, NULL, NULL, NULL);
#endif
    if (snmp_session == NULL) {
        snmp_sess_perror("ipmi_ui", &session);
	return -1;
    }

    ipmi_sel_set_read_fds_handler(sel,
				  snmp_add_read_fds,
				  snmp_check_read_fds,
				  snmp_check_timeout,
				  NULL);

    return 0;
}
Пример #3
0
static int
create_trap_session2(const char *sink, const char* sinkport,
		     char *com, int version, int pdutype)
{
    netsnmp_transport *t;
    netsnmp_session session, *sesp;

    memset(&session, 0, sizeof(netsnmp_session));
    session.version = version;
    if (com) {
        session.community = (u_char *) com;
        session.community_len = strlen(com);
    }

    /*
     * for informs, set retries to default
     */
    if (SNMP_MSG_INFORM == pdutype) {
        session.timeout = SNMP_DEFAULT_TIMEOUT;
        session.retries = SNMP_DEFAULT_RETRIES;
    }

    /*
     * if the sink is localhost, bind to localhost, to reduce open ports.
     */
    if ((NULL == netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                       NETSNMP_DS_LIB_CLIENT_ADDR)) && 
        ((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink))))
        session.localname = "localhost";

    t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport);
    if (t != NULL) {
	sesp = snmp_add(&session, t, NULL, NULL);

	if (sesp) {
	    return add_trap_session(sesp, pdutype,
				    (pdutype == SNMP_MSG_INFORM), version);
	}
    }
    /*
     * diagnose snmp_open errors with the input netsnmp_session pointer 
     */
    snmp_sess_perror("snmpd: create_trap_session", &session);
    return 0;
}
Пример #4
0
static netsnmp_session *snmptrapd_add_session(netsnmp_transport *t) {
    netsnmp_session sess, *session = &sess, *rc = NULL;
    snmp_sess_init(session);
    session->peername = SNMP_DEFAULT_PEERNAME;  /* Original code had NULL here */
    session->version = SNMP_DEFAULT_VERSION;
    session->community_len = SNMP_DEFAULT_COMMUNITY_LEN;
    session->retries = SNMP_DEFAULT_RETRIES;
    session->timeout = SNMP_DEFAULT_TIMEOUT;
    session->callback = snmp_input;
    session->callback_magic = (void *) t;
    session->authenticator = NULL;
    sess.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;
    rc = snmp_add(session, t, pre_parse, NULL);
    if (rc == NULL) {
        snmp_sess_perror("snmptrapd", session);
    }
    return rc;
}
Пример #5
0
static int send_snmp_inform_or_trap(const GpErrorData * errorData, const char * subject, const char * severity)
{

	netsnmp_session session, *ss = NULL;
	netsnmp_pdu    *pdu, *response;
	int				status;
	char            csysuptime[20];
	static bool 	snmp_initialized = false;
	static char myhostname[255];	/* gethostname usually is limited to 65 chars out, but make this big to be safe */
	char	   *rawstring = NULL;
	List	   *elemlist = NIL;
	ListCell   *l = NULL;

	/*
	 * "inform" messages get a positive acknowledgement response from the SNMP manager.
	 * If it doesn't come, the message might be resent.
	 *
	 * "trap" messages are one-way, and we have no idea if the manager received it.
	 * But, it's faster and cheaper, and no need to retry.  So some people might prefer it.
	 */
	bool inform = strcmp(gp_snmp_use_inform_or_trap,"inform") == 0;


	if (gp_snmp_monitor_address == NULL || gp_snmp_monitor_address[0] == '\0')
	{
		static bool firsttime = 1;

		ereport(firsttime ? LOG : DEBUG1,(errmsg("SNMP inform/trap alerts are disabled")));
		firsttime = false;

		return -1;
	}


	/*
	 * SNMP managers are required to handle messages up to at least 484 bytes long, but I believe most existing
	 * managers support messages up to one packet (ethernet frame) in size, 1472 bytes.
	 *
	 * But, should we take that chance?  Or play it safe and limit the message to 484 bytes?
	 */

	elog(DEBUG2,"send_snmp_inform_or_trap");

	if (!snmp_initialized)
	{
		snmp_enable_stderrlog();

		if (gp_snmp_debug_log != NULL && gp_snmp_debug_log[0] != '\0')
		{
			snmp_enable_filelog(gp_snmp_debug_log, 1);

			//debug_register_tokens("ALL");
			snmp_set_do_debugging(1);
		}

		/*
		 * Initialize the SNMP library.  This also reads the MIB database.
		 */
		/* Add GPDB-MIB to the list to be loaded */
		putenv("MIBS=+GPDB-MIB:SNMP-FRAMEWORK-MIB:SNMPv2-CONF:SNMPv2-TC:SNMPv2-TC");

		init_snmp("sendalert");

		snmp_initialized = true;

		{
			char portnum[16];
			myhostname[0] = '\0';

			if (gethostname(myhostname, sizeof(myhostname)) == 0)
			{
				strcat(myhostname,":");
				pg_ltoa(PostPortNumber,portnum);
				strcat(myhostname,portnum);
			}
		}
	}

	/*
	 * Trap/Inform messages always start with the system up time. (SysUpTime.0)
	 *
	 * This presumably would be the uptime of GPDB, not the machine it is running on, I think.
	 *
	 * Use Postmaster's "MyStartTime" as a way to get that.
	 */

	sprintf(csysuptime, "%ld", (long)(time(NULL) - MyStartTime));


	/*
	// ERRCODE_DISK_FULL could be reported vi rbmsMIB rdbmsTraps rdbmsOutOfSpace trap.
	// But it appears we never generate that error?

	// ERRCODE_ADMIN_SHUTDOWN means SysAdmin aborted somebody's request.  Not interesting?

	// ERRCODE_CRASH_SHUTDOWN sounds interesting, but I don't see that we ever generate it.

	// ERRCODE_CANNOT_CONNECT_NOW means we are starting up, shutting down, in recovery, or Too many users are logged on.

	// abnormal database system shutdown
	*/



	/*
	 * The gpdbAlertSeverity is a crude attempt to classify some of these messages based on severity,
	 * where OK means everything is running normal, Down means everything is shut down, degraded would be
	 * for times when some segments are down, but the system is up, The others are maybe useful in the future
	 *
	 *  gpdbSevUnknown(0),
	 *	gpdbSevOk(1),
	 *	gpdbSevWarning(2),
	 *	gpdbSevError(3),
	 *	gpdbSevFatal(4),
	 *	gpdbSevPanic(5),
	 *	gpdbSevSystemDegraded(6),
	 *	gpdbSevSystemDown(7)
	 */


	char detail[MAX_ALERT_STRING+1];
	snprintf(detail, MAX_ALERT_STRING, "%s", errorData->error_detail);
	detail[127] = '\0';

	char sqlstmt[MAX_ALERT_STRING+1];
	char * sqlstmtp = errorData->debug_query_string;
	if (sqlstmtp == NULL || sqlstmtp[0] == '\0')
		sqlstmtp = errorData->internal_query;
	if (sqlstmtp == NULL)
		sqlstmtp = "";


	snprintf(sqlstmt, MAX_ALERT_STRING, "%s", sqlstmtp);
	sqlstmt[MAX_ALERT_STRING] = '\0';


	/* Need a modifiable copy of To list */
	rawstring = pstrdup(gp_snmp_monitor_address);

	/* Parse string into list of identifiers */
	if (!SplitMailString(rawstring, ',', &elemlist))
	{
		/* syntax error in list */
		ereport(LOG,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid list syntax for \"gp_snmp_monitor_address\"")));
		return -1;
	}


	/*
	 * This session is just a template, and doesn't need to be connected.
	 * It is used by snmp_add(), which copies this info, opens the new session, and assigns the transport.
	 */
	snmp_sess_init( &session );	/* Initialize session to default values */
	session.version = SNMP_VERSION_2c;
	session.timeout = SNMP_DEFAULT_TIMEOUT;
	session.retries = SNMP_DEFAULT_RETRIES;
	session.remote_port = 162; 							// I think this isn't used by net-snmp any more.

	/*if (strchr(session.peername,':')==NULL)
		strcat(session.peername,":162");*/
	session.community = (u_char *)gp_snmp_community;
	session.community_len = strlen((const char *)session.community);  // SNMP_DEFAULT_COMMUNITY_LEN means "public"
	session.callback_magic = NULL;

	foreach(l, elemlist)
	{
		char	   *cur_gp_snmp_monitor_address = (char *) lfirst(l);

		if (cur_gp_snmp_monitor_address == NULL || cur_gp_snmp_monitor_address[0] == '\0')
			continue;

		session.peername = cur_gp_snmp_monitor_address;
		/*
		 * If we try to "snmp_open( &session )", net-snmp will set up a connection to that
		 * endpoint on port 161, assuming we are the network monitor, and the other side is an agent.
		 *
		 * But we are pretending to be an agent, sending traps to the NM, so we don't need this.
		 */

		/*if (!snmp_open( &session ))   	// Don't open the session here!
		{
			const char     *str;
			int             xerr;
			xerr = snmp_errno;
			str = snmp_api_errstring(xerr);
			elog(LOG, "snmp_open: %s", str);
			return -1;
		}*/

		/*
		 * This call copies the info from "session" to "ss", assigns the transport, and opens the session.
		 * We must specify "snmptrap" so the transport will know we want port 162 by default.
		 */
		ss = snmp_add(&session,
					  netsnmp_transport_open_client("snmptrap", cur_gp_snmp_monitor_address),
					  NULL, NULL);
		if (ss == NULL) {
			/*
			 * diagnose netsnmp_transport_open_client and snmp_add errors with
			 * the input netsnmp_session pointer
			 */
			{
				char           *err;
				snmp_error(&session, NULL, NULL, &err);
				elog(LOG, "send_alert snmp_add of %s failed: %s", cur_gp_snmp_monitor_address, err);
				free(err);
			}
			return -1;
		}

		/*
		 * We need to create the pdu each time, as it gets freed when we send a trap.
		 */
		pdu = snmp_pdu_create(inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
		if (!pdu)
		{
			const char     *str;
			int             xerr;
			xerr = snmp_errno;
			str = snmp_api_errstring(xerr);
			elog(LOG, "Failed to create notification PDU: %s", str);
			return -1;
		}

		/*
		 * Trap/Inform messages always start with the system up time. (SysUpTime.0)
		 * We use Postmaster's "MyStartTime" as a way to get that.
		 */

		snmp_add_var(pdu, objid_sysuptime,
							sizeof(objid_sysuptime) / sizeof(oid),
							't', (const char *)csysuptime);

	#if 0
		/*
		 * In the future, we might want to send RDBMS-MIB::rdbmsStateChange when the system becomes unavailable or
		 * partially unavailable.  This code, which is not currently used, shows how to build the pdu for
		 * that trap.
		 */
		/* {iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) rdbmsMIB(39) rdbmsTraps(2) rdbmsStateChange(1)} */
		snmp_add_var(pdu, objid_snmptrap,
							sizeof(objid_snmptrap) / sizeof(oid),
							'o', "1.3.6.1.2.1.39.2.1");  // rdbmsStateChange


		snmp_add_var(pdu, objid_rdbmsrelstate,
							sizeof(objid_rdbmsrelstate) / sizeof(oid),
							'i', "5");  // 4 = restricted, 5 = unavailable
	#endif

		/* {iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprises(1) gpdbMIB(31327) gpdbTraps(5) gpdbTrapsList(0) gpdbAlert(1)} */

		/*
		 * We could specify this trap oid by name, rather than numeric oid, but then if the GPDB-MIB wasn't
		 * found, we'd get an error.  Using the numeric oid means we can still work without the MIB loaded.
		 */
		snmp_add_var(pdu, objid_snmptrap,
							sizeof(objid_snmptrap) / sizeof(oid),
							'o', "1.3.6.1.4.1.31327.5.0.1");  // gpdbAlert


		snmp_add_var(pdu, objid_gpdbAlertMsg,
							sizeof(objid_gpdbAlertMsg) / sizeof(oid),
							's', subject);  // SnmpAdminString = UTF-8 text
		snmp_add_var(pdu, objid_gpdbAlertSeverity,
							sizeof(objid_gpdbAlertSeverity) / sizeof(oid),
							'i', (char *)severity);

		snmp_add_var(pdu, objid_gpdbAlertSqlstate,
							sizeof(objid_gpdbAlertSqlstate) / sizeof(oid),
							's', errorData->sql_state);

		snmp_add_var(pdu, objid_gpdbAlertDetail,
							sizeof(objid_gpdbAlertDetail) / sizeof(oid),
							's', detail); // SnmpAdminString = UTF-8 text

		snmp_add_var(pdu, objid_gpdbAlertSqlStmt,
							sizeof(objid_gpdbAlertSqlStmt) / sizeof(oid),
							's', sqlstmt); // SnmpAdminString = UTF-8 text

		snmp_add_var(pdu, objid_gpdbAlertSystemName,
							sizeof(objid_gpdbAlertSystemName) / sizeof(oid),
							's', myhostname); // SnmpAdminString = UTF-8 text



		elog(DEBUG2,"ready to send to %s",cur_gp_snmp_monitor_address);
		if (inform)
			status = snmp_synch_response(ss, pdu, &response);
		else
			status = snmp_send(ss, pdu) == 0;

		elog(DEBUG2,"send, status %d",status);
		if (status != STAT_SUCCESS)
		{
			/* Something went wrong */
			if (ss)
			{
				char           *err;
				snmp_error(ss, NULL, NULL, &err);
				elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", err);
				free(err);
			}
			else
			{
				elog(LOG, "sendalert failed to send %s: %s", inform ? "inform" : "trap", "Something went wrong");
			}
			if (!inform)
				snmp_free_pdu(pdu);
		}
		else if (inform)
			snmp_free_pdu(response);

		snmp_close(ss);
		ss = NULL;

	}
Пример #6
0
     netsnmp_session *get_target_sessions (char *taglist, TargetFilterFunction * filterfunct, void *filterArg)
{
    netsnmp_session *ret = NULL, thissess;

    struct targetAddrTable_struct *targaddrs;

    char buf[SPRINT_MAX_LEN];

    char tags[MAX_TAGS][SPRINT_MAX_LEN], *cp;

    int numtags = 0, i;

#if defined(NETSNMP_TRANSPORT_DTLSUDP_DOMAIN) || defined(NETSNMP_TRANSPORT_TLSTCP_DOMAIN)
    int tls = 0;
#endif
    static struct targetParamTable_struct *param;

    DEBUGMSGTL (("target_sessions", "looking for: %s\n", taglist));
    for (cp = taglist; cp && numtags < MAX_TAGS;)
    {
        cp = copy_nword (cp, tags[numtags], sizeof (tags[numtags]));
        DEBUGMSGTL (("target_sessions", " for: %d=%s\n", numtags, tags[numtags]));
        numtags++;
    }

    for (targaddrs = get_addrTable (); targaddrs; targaddrs = targaddrs->next)
    {

        /*
         * legal row? 
         */
        if (targaddrs->tDomain == NULL || targaddrs->tAddress == NULL || targaddrs->rowStatus != SNMP_ROW_ACTIVE)
        {
            DEBUGMSGTL (("target_sessions", "  which is not ready yet\n"));
            continue;
        }

        if (netsnmp_tdomain_support (targaddrs->tDomain, targaddrs->tDomainLen, NULL, NULL) == 0)
        {
            snmp_log (LOG_ERR, "unsupported domain for target address table entry %s\n", targaddrs->name);
        }

        /*
         * check tag list to see if we match 
         */
        if (targaddrs->tagList)
        {
            int matched = 0;

            /*
             * loop through tag list looking for requested tags 
             */
            for (cp = targaddrs->tagList; cp && !matched;)
            {
                cp = copy_nword (cp, buf, sizeof (buf));
                for (i = 0; i < numtags && !matched; i++)
                {
                    if (strcmp (buf, tags[i]) == 0)
                    {
                        /*
                         * found a valid target table entry 
                         */
                        DEBUGMSGTL (("target_sessions", "found one: %s\n", tags[i]));

                        if (targaddrs->params)
                        {
                            param = get_paramEntry (targaddrs->params);
                            if (!param || param->rowStatus != SNMP_ROW_ACTIVE)
                            {
                                /*
                                 * parameter entry must exist and be active 
                                 */
                                continue;
                            }
                        }
                        else
                        {
                            /*
                             * parameter entry must be specified 
                             */
                            continue;
                        }

                        /*
                         * last chance for caller to opt-out.  Call
                         * filtering function 
                         */
                        if (filterfunct && (*(filterfunct)) (targaddrs, param, filterArg))
                        {
                            continue;
                        }

                        /*
                         * Only one notification per TargetAddrEntry,
                         * rather than one per tag
                         */
                        matched = 1;

                        if (targaddrs->storageType != ST_READONLY &&
                            targaddrs->sess && param->updateTime >= targaddrs->sessionCreationTime)
                        {
                            /*
                             * parameters have changed, nuke the old session 
                             */
                            snmp_close (targaddrs->sess);
                            targaddrs->sess = NULL;
                        }

                        /*
                         * target session already exists? 
                         */
                        if (targaddrs->sess == NULL)
                        {
                            /*
                             * create an appropriate snmp session and add
                             * it to our return list 
                             */
                            netsnmp_transport *t = NULL;

                            t = netsnmp_tdomain_transport_oid (targaddrs->tDomain,
                                                               targaddrs->tDomainLen,
                                                               targaddrs->tAddress, targaddrs->tAddressLen, 0);
                            if (t == NULL)
                            {
                                DEBUGMSGTL (("target_sessions", "bad dest \""));
                                DEBUGMSGOID (("target_sessions", targaddrs->tDomain, targaddrs->tDomainLen));
                                DEBUGMSG (("target_sessions", "\", \""));
                                DEBUGMSGHEX (("target_sessions", targaddrs->tAddress, targaddrs->tAddressLen));
                                DEBUGMSG (("target_sessions", "\n"));
                                continue;
                            }
                            else
                            {
                                char *dst_str = t->f_fmtaddr (t, NULL, 0);

                                if (dst_str != NULL)
                                {
                                    DEBUGMSGTL (("target_sessions", "  to: %s\n", dst_str));
                                    free (dst_str);
                                }
                            }
                            /*
                             * if tDomain is tls related, check for tls config
                             */
#ifdef NETSNMP_TRANSPORT_DTLSUDP_DOMAIN
                            tls = snmp_oid_compare (targaddrs->tDomain,
                                                    targaddrs->tDomainLen,
                                                    netsnmpDTLSUDPDomain, netsnmpDTLSUDPDomain_len);

#endif
#ifdef NETSNMP_TRANSPORT_TLSTCP_DOMAIN
                            if (tls)
                                tls = snmp_oid_compare (targaddrs->tDomain,
                                                        targaddrs->tDomainLen,
                                                        netsnmpTLSTCPDomain, netsnmpTLSTCPDomain_len);
#endif
#if defined(NETSNMP_TRANSPORT_DTLSUDP_DOMAIN) || defined(NETSNMP_TRANSPORT_TLSTCP_DOMAIN)
                            if (!tls)
                            {
                                netsnmp_cert *cert;

                                char *server_id = NULL;

                                DEBUGMSGTL (("target_sessions", "  looking up our id: %s\n", targaddrs->params));
                                cert = netsnmp_cert_find (NS_CERT_IDENTITY, NS_CERTKEY_TARGET_PARAM, targaddrs->params);
                                netsnmp_assert (t->f_config);
                                if (cert)
                                {
                                    DEBUGMSGTL (("target_sessions", "  found fingerprint: %s\n", cert->fingerprint));
                                    t->f_config (t, "localCert", cert->fingerprint);
                                }
                                DEBUGMSGTL (("target_sessions", "  looking up their id: %s\n", targaddrs->name));
                                cert = netsnmp_cert_find (NS_CERT_REMOTE_PEER, NS_CERTKEY_TARGET_ADDR, targaddrs->name);
                                if (cert)
                                {
                                    DEBUGMSGTL (("target_sessions", "  found fingerprint: %s\n", cert->fingerprint));
                                    t->f_config (t, "peerCert", cert->fingerprint);
                                }
#ifndef NETSNMP_FEATURE_REMOVE_TLSTMADDR_GET_SERVERID
                                server_id = netsnmp_tlstmAddr_get_serverId (targaddrs->name);
#endif                            /* NETSNMP_FEATURE_REMOVE_TLSTMADDR_GET_SERVERID */
                                if (server_id)
                                {
                                    DEBUGMSGTL (("target_sessions", "  found serverId: %s\n", server_id));
                                    t->f_config (t, "their_hostname", server_id);
                                }
                            }
#endif
                            memset (&thissess, 0, sizeof (thissess));
                            thissess.timeout = (targaddrs->timeout) * 1000;
                            thissess.retries = targaddrs->retryCount;
                            DEBUGMSGTL (("target_sessions",
                                         "timeout: %d -> %ld\n", targaddrs->timeout, thissess.timeout));

                            if (param->mpModel == SNMP_VERSION_3 &&
                                param->secModel != SNMP_SEC_MODEL_USM && param->secModel != SNMP_SEC_MODEL_TSM)
                            {
                                snmp_log (LOG_ERR,
                                          "unsupported mpModel/secModel combo %d/%d for target %s\n",
                                          param->mpModel, param->secModel, targaddrs->name);
                                /*
                                 * XXX: memleak 
                                 */
                                netsnmp_transport_free (t);
                                continue;
                            }
                            thissess.paramName = strdup (param->paramName);
                            thissess.version = param->mpModel;
                            if (param->mpModel == SNMP_VERSION_3)
                            {
                                thissess.securityName = strdup (param->secName);
                                thissess.securityNameLen = strlen (thissess.securityName);
                                thissess.securityLevel = param->secLevel;
                                thissess.securityModel = param->secModel;
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
                            }
                            else
                            {
                                thissess.community = (u_char *) strdup (param->secName);
                                thissess.community_len = strlen ((char *) thissess.community);
#endif
                            }

                            thissess.flags |= SNMP_FLAGS_DONT_PROBE;
                            targaddrs->sess = snmp_add (&thissess, t, NULL, NULL);
                            thissess.flags &= ~SNMP_FLAGS_DONT_PROBE;
                            targaddrs->sessionCreationTime = time (NULL);
                        }
                        if (targaddrs->sess)
                        {
                            if (NULL == targaddrs->sess->paramName)
                                targaddrs->sess->paramName = strdup (param->paramName);

                            targaddrs->sess->next = ret;
                            ret = targaddrs->sess;
                        }
                        else
                        {
                            snmp_sess_perror ("target session", &thissess);
                        }
                    }
                }
            }
        }
    }
    return ret;
}
Пример #7
0
int main (int argc, char *argv[])
{
    netsnmp_session session, *ss;

    netsnmp_pdu *pdu, *response;

    oid name[MAX_OID_LEN];

    size_t name_length;

    int arg;

    int status;

    char *trap = NULL;

    char *prognam;

    int exitval = 0;

#ifndef NETSNMP_DISABLE_SNMPV1
    char *specific = NULL, *description = NULL, *agent = NULL;

    in_addr_t *pdu_in_addr_t;
#endif

    prognam = strrchr (argv[0], '/');
    if (prognam)
        prognam++;
    else
        prognam = argv[0];

    putenv (strdup ("POSIXLY_CORRECT=1"));

    if (strcmp (prognam, "snmpinform") == 0)
        inform = 1;
    switch (arg = snmp_parse_args (argc, argv, &session, "C:", optProc))
    {
        case NETSNMP_PARSE_ARGS_ERROR:
            exit (1);
        case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
            exit (0);
        case NETSNMP_PARSE_ARGS_ERROR_USAGE:
            usage ();
            exit (1);
        default:
            break;
    }

    SOCK_STARTUP;

    session.callback = snmp_input;
    session.callback_magic = NULL;

    /*
     * setup the local engineID which may be for either or both of the
     * contextEngineID and/or the securityEngineID.
     */
    setup_engineID (NULL, NULL);

    /* if we don't have a contextEngineID set via command line
       arguments, use our internal engineID as the context. */
    if (session.contextEngineIDLen == 0 || session.contextEngineID == NULL)
    {
        session.contextEngineID = snmpv3_generate_engineID (&session.contextEngineIDLen);
    }

    if (session.version == SNMP_VERSION_3 && !inform)
    {
        /*
         * for traps, we use ourselves as the authoritative engine
         * which is really stupid since command line apps don't have a
         * notion of a persistent engine.  Hence, our boots and time
         * values are probably always really wacked with respect to what
         * a manager would like to see.
         * 
         * The following should be enough to:
         * 
         * 1) prevent the library from doing discovery for engineid & time.
         * 2) use our engineid instead of the remote engineid for
         * authoritative & privacy related operations.
         * 3) The remote engine must be configured with users for our engineID.
         * 
         * -- Wes 
         */

        /*
         * pick our own engineID 
         */
        if (session.securityEngineIDLen == 0 || session.securityEngineID == NULL)
        {
            session.securityEngineID = snmpv3_generate_engineID (&session.securityEngineIDLen);
        }

        /*
         * set boots and time, which will cause problems if this
         * machine ever reboots and a remote trap receiver has cached our
         * boots and time...  I'll cause a not-in-time-window report to
         * be sent back to this machine. 
         */
        if (session.engineBoots == 0)
            session.engineBoots = 1;
        if (session.engineTime == 0)    /* not really correct, */
            session.engineTime = get_uptime ();    /* but it'll work. Sort of. */
    }

    ss = snmp_add (&session, netsnmp_transport_open_client ("snmptrap", session.peername), NULL, NULL);
    if (ss == NULL)
    {
        /*
         * diagnose netsnmp_transport_open_client and snmp_add errors with
         * the input netsnmp_session pointer
         */
        snmp_sess_perror ("snmptrap", &session);
        SOCK_CLEANUP;
        exit (1);
    }

#ifndef NETSNMP_DISABLE_SNMPV1
    if (session.version == SNMP_VERSION_1)
    {
        if (inform)
        {
            fprintf (stderr, "Cannot send INFORM as SNMPv1 PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        pdu = snmp_pdu_create (SNMP_MSG_TRAP);
        if (!pdu)
        {
            fprintf (stderr, "Failed to create trap PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        pdu_in_addr_t = (in_addr_t *) pdu->agent_addr;
        if (arg == argc)
        {
            fprintf (stderr, "No enterprise oid\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        if (argv[arg][0] == 0)
        {
            pdu->enterprise = (oid *) malloc (sizeof (objid_enterprise));
            memcpy (pdu->enterprise, objid_enterprise, sizeof (objid_enterprise));
            pdu->enterprise_length = sizeof (objid_enterprise) / sizeof (oid);
        }
        else
        {
            name_length = MAX_OID_LEN;
            if (!snmp_parse_oid (argv[arg], name, &name_length))
            {
                snmp_perror (argv[arg]);
                usage ();
                SOCK_CLEANUP;
                exit (1);
            }
            pdu->enterprise = (oid *) malloc (name_length * sizeof (oid));
            memcpy (pdu->enterprise, name, name_length * sizeof (oid));
            pdu->enterprise_length = name_length;
        }
        if (++arg >= argc)
        {
            fprintf (stderr, "Missing agent parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        agent = argv[arg];
        if (agent != NULL && strlen (agent) != 0)
        {
            int ret = netsnmp_gethostbyname_v4 (agent, pdu_in_addr_t);

            if (ret < 0)
            {
                fprintf (stderr, "unknown host: %s\n", agent);
                exit (1);
            }
        }
        else
        {
            *pdu_in_addr_t = get_myaddr ();
        }
        if (++arg == argc)
        {
            fprintf (stderr, "Missing generic-trap parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        trap = argv[arg];
        pdu->trap_type = atoi (trap);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing specific-trap parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        specific = argv[arg];
        pdu->specific_type = atoi (specific);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing uptime parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        description = argv[arg];
        if (description == NULL || *description == 0)
            pdu->time = get_uptime ();
        else
            pdu->time = atol (description);
    }
    else
#endif
    {
        long sysuptime;

        char csysuptime[20];

        pdu = snmp_pdu_create (inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
        if (!pdu)
        {
            fprintf (stderr, "Failed to create notification PDU\n");
            SOCK_CLEANUP;
            exit (1);
        }
        if (arg == argc)
        {
            fprintf (stderr, "Missing up-time parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        trap = argv[arg];
        if (*trap == 0)
        {
            sysuptime = get_uptime ();
            sprintf (csysuptime, "%ld", sysuptime);
            trap = csysuptime;
        }
        snmp_add_var (pdu, objid_sysuptime, sizeof (objid_sysuptime) / sizeof (oid), 't', trap);
        if (++arg == argc)
        {
            fprintf (stderr, "Missing trap-oid parameter\n");
            usage ();
            SOCK_CLEANUP;
            exit (1);
        }
        if (snmp_add_var (pdu, objid_snmptrap, sizeof (objid_snmptrap) / sizeof (oid), 'o', argv[arg]) != 0)
        {
            snmp_perror (argv[arg]);
            SOCK_CLEANUP;
            exit (1);
        }
    }
    arg++;

    while (arg < argc)
    {
        arg += 3;
        if (arg > argc)
        {
            fprintf (stderr, "%s: Missing type/value for variable\n", argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
        name_length = MAX_OID_LEN;
        if (!snmp_parse_oid (argv[arg - 3], name, &name_length))
        {
            snmp_perror (argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
        if (snmp_add_var (pdu, name, name_length, argv[arg - 2][0], argv[arg - 1]) != 0)
        {
            snmp_perror (argv[arg - 3]);
            SOCK_CLEANUP;
            exit (1);
        }
    }

    if (inform)
        status = snmp_synch_response (ss, pdu, &response);
    else
        status = snmp_send (ss, pdu) == 0;
    if (status)
    {
        snmp_sess_perror (inform ? "snmpinform" : "snmptrap", ss);
        if (!inform)
            snmp_free_pdu (pdu);
        exitval = 1;
    }
    else if (inform)
        snmp_free_pdu (response);

    snmp_close (ss);
    snmp_shutdown ("snmpapp");
    SOCK_CLEANUP;
    return exitval;
}
Пример #8
0
void
snmpd_parse_config_trapsess(const char *word, char *cptr)
{
    char           *argv[MAX_ARGS], *cp = cptr, tmp[SPRINT_MAX_LEN];
    int             argn, arg;
    netsnmp_session session, *ss;
    size_t          len;

    /*
     * inform or trap?  default to trap 
     */
    traptype = SNMP_MSG_TRAP2;

    /*
     * create the argv[] like array 
     */
    argv[0] = strdup("snmpd-trapsess"); /* bogus entry for getopt() */
    for (argn = 1; cp && argn < MAX_ARGS; argn++) {
        cp = copy_nword(cp, tmp, SPRINT_MAX_LEN);
        argv[argn] = strdup(tmp);
    }

    arg = snmp_parse_args(argn, argv, &session, "C:", trapOptProc);

    ss = snmp_add(&session,
		  netsnmp_transport_open_client("snmptrap", session.peername),
		  NULL, NULL);
    for (; argn > 0; argn--) {
        free(argv[argn - 1]);
    }

    if (!ss) {
        config_perror
            ("snmpd: failed to parse this line or the remote trap receiver is down.  Possible cause:");
        snmp_sess_perror("snmpd: snmpd_parse_config_trapsess()", &session);
        return;
    }

    /*
     * If this is an SNMPv3 TRAP session, then the agent is
     *   the authoritative engine, so set the engineID accordingly
     */
    if (ss->version == SNMP_VERSION_3 &&
        traptype != SNMP_MSG_INFORM   &&
        ss->securityEngineIDLen == 0) {
            len = snmpv3_get_engineID( tmp, sizeof(tmp));
            memdup(&ss->securityEngineID, tmp, len);
            ss->securityEngineIDLen = len;
    }

#ifndef NETSNMP_DISABLE_SNMPV1
    if (ss->version == SNMP_VERSION_1) {
        add_trap_session(ss, SNMP_MSG_TRAP, 0, SNMP_VERSION_1);
    } else {
#endif
        add_trap_session(ss, traptype, (traptype == SNMP_MSG_INFORM),
                         ss->version);
#ifndef NETSNMP_DISABLE_SNMPV1
    }
#endif
}
Пример #9
0
netsnmp_session *
get_target_sessions(char *taglist, TargetFilterFunction * filterfunct,
                    void *filterArg)
{
    netsnmp_session *ret = NULL, thissess;
    struct targetAddrTable_struct *targaddrs;
    char            buf[SPRINT_MAX_LEN];
    char            tags[MAX_TAGS][SPRINT_MAX_LEN], *cp;
    int             numtags = 0, i;
    static struct targetParamTable_struct *param;

    DEBUGMSGTL(("target_sessions", "looking for: %s\n", taglist));
    for (cp = taglist; cp && numtags < MAX_TAGS;) {
        cp = copy_nword(cp, tags[numtags], sizeof(tags[numtags]));
        DEBUGMSGTL(("target_sessions", " for: %d=%s\n", numtags,
                    tags[numtags]));
        numtags++;
    }

    for (targaddrs = get_addrTable(); targaddrs;
         targaddrs = targaddrs->next) {

        /*
         * legal row? 
         */
        if (targaddrs->tDomain == NULL ||
            targaddrs->tAddress == NULL ||
            targaddrs->rowStatus != SNMP_ROW_ACTIVE) {
            DEBUGMSGTL(("target_sessions", "  which is not ready yet\n"));
            continue;
        }

        if (netsnmp_tdomain_support
            (targaddrs->tDomain, targaddrs->tDomainLen, NULL, NULL) == 0) {
            snmp_log(LOG_ERR,
                     "unsupported domain for target address table entry %s\n",
                     targaddrs->name);
        }

        /*
         * check tag list to see if we match 
         */
        if (targaddrs->tagList) {
            /*
             * loop through tag list looking for requested tags 
             */
            for (cp = targaddrs->tagList; cp;) {
                cp = copy_nword(cp, buf, sizeof(buf));
                for (i = 0; i < numtags; i++) {
                    if (strcmp(buf, tags[i]) == 0) {
                        /*
                         * found a valid target table entry 
                         */
                        DEBUGMSGTL(("target_sessions", "found one: %s\n",
                                    tags[i]));

                        if (targaddrs->params) {
                            param = get_paramEntry(targaddrs->params);
                            if (!param
                                || param->rowStatus != SNMP_ROW_ACTIVE) {
                                /*
                                 * parameter entry must exist and be active 
                                 */
                                continue;
                            }
                        } else {
                            /*
                             * parameter entry must be specified 
                             */
                            continue;
                        }

                        /*
                         * last chance for caller to opt-out.  Call
                         * filtering function 
                         */
                        if (filterfunct &&
                            (*(filterfunct)) (targaddrs, param,
                                              filterArg)) {
                            continue;
                        }

                        if (targaddrs->storageType != ST_READONLY &&
                            targaddrs->sess &&
                            param->updateTime >=
                            targaddrs->sessionCreationTime) {
                            /*
                             * parameters have changed, nuke the old session 
                             */
                            snmp_close(targaddrs->sess);
                            targaddrs->sess = NULL;
                        }

                        /*
                         * target session already exists? 
                         */
                        if (targaddrs->sess == NULL) {
                            /*
                             * create an appropriate snmp session and add
                             * it to our return list 
                             */
                            netsnmp_transport *t = NULL;

                            t = netsnmp_tdomain_transport_oid(targaddrs->
                                                              tDomain,
                                                              targaddrs->
                                                              tDomainLen,
                                                              targaddrs->
                                                              tAddress,
                                                              targaddrs->
                                                              tAddressLen,
                                                              0);
                            if (t == NULL) {
                                DEBUGMSGTL(("target_sessions",
                                            "bad dest \""));
                                DEBUGMSGOID(("target_sessions",
                                             targaddrs->tDomain,
                                             targaddrs->tDomainLen));
                                DEBUGMSG(("target_sessions", "\", \""));
                                DEBUGMSGHEX(("target_sessions",
                                             targaddrs->tAddress,
                                             targaddrs->tAddressLen));
                                DEBUGMSG(("target_sessions", "\n"));
                                continue;
                            } else {
                                char           *dst_str =
                                    t->f_fmtaddr(t, NULL, 0);
                                if (dst_str != NULL) {
                                    DEBUGMSGTL(("target_sessions",
                                                "  to: %s\n", dst_str));
                                    free(dst_str);
                                }
                            }
                            memset(&thissess, 0, sizeof(thissess));
                            thissess.timeout = (targaddrs->timeout) * 1000;
                            thissess.retries = targaddrs->retryCount;
                            DEBUGMSGTL(("target_sessions",
                                        "timeout: %d -> %d\n",
                                        targaddrs->timeout,
                                        thissess.timeout));

                            if (param->mpModel == SNMP_VERSION_3 &&
                                param->secModel != 3) {
                                snmp_log(LOG_ERR,
                                         "unsupported model/secmodel combo for target %s\n",
                                         targaddrs->name);
                                /*
                                 * XXX: memleak 
                                 */
                                netsnmp_transport_free(t);
                                continue;
                            }
                            thissess.version = param->mpModel;
                            if (param->mpModel == SNMP_VERSION_3) {
                                thissess.securityName = param->secName;
                                thissess.securityNameLen =
                                    strlen(thissess.securityName);
                                thissess.securityLevel = param->secLevel;
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
                            } else {
                                thissess.community =
                                    (u_char *) strdup(param->secName);
                                thissess.community_len =
                                    strlen((char *) thissess.community);
#endif
                            }

                            targaddrs->sess = snmp_add(&thissess, t,
                                                       NULL, NULL);
                            targaddrs->sessionCreationTime = time(NULL);
                        }
                        if (targaddrs->sess) {
                            if (ret) {
                                targaddrs->sess->next = ret;
                            }
                            ret = targaddrs->sess;
                        } else {
                            snmp_sess_perror("target session", &thissess);
                        }
                    }
                }
            }
        }
    }
    return ret;
}
Пример #10
0
int snmptrap2(char *ip, char *oidNO1, char *oidNO2, char type, char *text) {
	if (ip == NULL || strlen(ip) == 0) {
		fprintf(stderr, "No ip\n");
		return (1);
	}
	netsnmp_session session, *ss;
	netsnmp_pdu *pdu;
	oid anOID[MAX_OID_LEN];
	long sysuptime;
	char csysuptime[20];
	int status = 0;
	oid oid_sysuptime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
	char *community = "public";
	netsnmp_transport *transport = NULL;
	size_t anOID_len = MAX_OID_LEN;

	snmp_sess_init(&session);
	session.version = SNMP_VERSION_2c;
	session.peername = ip;
	session.remote_port = 162;
	session.community = (unsigned char*) community;
	session.community_len = strlen((char *) session.community);
	session.retries = 3;
	session.timeout = 2000;
	session.sessid = 0;

	SOCK_STARTUP;

	transport = netsnmp_transport_open_client("snmptrap", session.peername);
	if (NULL != transport)
		ss = snmp_add(&session, transport, NULL, NULL);

	if (ss == NULL) {
		snmp_sess_perror("snmptable", &session);
		SOCK_CLEANUP;
	}

	pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
	sysuptime = get_uptime();
	sprintf(csysuptime, "%ld", sysuptime);

	status = snmp_add_var(pdu, objid_sysuptime,
			sizeof(objid_sysuptime) / sizeof(oid), 't', csysuptime);
	if (status != 0) {
		snmp_sess_perror("snmptrap add sysuptime error!", &session);
		return -1;
	}
	if (snmp_add_var
	            (pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid),
	             'o', oidNO1) != 0) {
	            snmp_perror(oidNO1);
	            SOCK_CLEANUP;
	            exit(1);
	        }

	if (!snmp_parse_oid(oidNO2, anOID, &anOID_len)) {
		  snmp_perror(oidNO2);
		  SOCK_CLEANUP;
		  exit(1);
		}
	if(snmp_add_var(pdu, anOID, anOID_len, type,
			text)!= 0) {
        snmp_perror(text);
        SOCK_CLEANUP;
        exit(1);
    }
	status = snmp_send(ss, pdu);
	if (status == 0) {
		snmp_sess_perror("snmptrap send info error!", &session);
		snmp_free_pdu(pdu);
		return -2;
	}
	snmp_close(ss);
	snmp_shutdown("snmpapp");
	SOCK_CLEANUP;
	printf(stderr, "send snmptrap over %d... ", status);
	return 0;
}