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); }
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; }
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; }
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; }
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; }
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; }
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; }
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 }
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; }
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; }