diff options
author | Andre Lorbach <alorbach@adiscon.com> | 2008-02-11 16:28:29 +0000 |
---|---|---|
committer | Andre Lorbach <alorbach@adiscon.com> | 2008-02-11 16:28:29 +0000 |
commit | f4e7c64f91a65baa9d7872da15e07dec5cfd1278 (patch) | |
tree | ab3c3a460c9703a3da6750375367946fe2774c79 | |
parent | ecfc30551bebb4e5c8db8336eda143f53c020e10 (diff) | |
download | rsyslog-f4e7c64f91a65baa9d7872da15e07dec5cfd1278.tar.gz rsyslog-f4e7c64f91a65baa9d7872da15e07dec5cfd1278.tar.xz rsyslog-f4e7c64f91a65baa9d7872da15e07dec5cfd1278.zip |
Some major changes in the code. The SNMP Session is now stored in the
instance data. So this means we open and close the session only once
per session. If sending fails, we reinit the snmp session, so suspend
and resume is now fully and correctly supported. May need some more
testing against tcp based snmp receivers.
-rw-r--r-- | plugins/omsnmp/omsnmp.c | 147 |
1 files changed, 96 insertions, 51 deletions
diff --git a/plugins/omsnmp/omsnmp.c b/plugins/omsnmp/omsnmp.c index f31f071f..f7777523 100644 --- a/plugins/omsnmp/omsnmp.c +++ b/plugins/omsnmp/omsnmp.c @@ -82,15 +82,17 @@ static int iTrapType = SNMP_TRAP_ENTERPRISESPECIFIC;/*Default is SNMP_TRAP_ENTER typedef struct _instanceData { uchar szTransport[OMSNMP_MAXTRANSPORLENGTH+1]; /* Transport - Can be udp, tcp, udp6, tcp6 and other types supported by NET-SNMP */ - uchar szTarget[MAXHOSTNAMELEN+1]; /* IP/hostname of Snmp Target*/ - uchar szTargetAndPort[MAXHOSTNAMELEN+1]; /* IP/hostname + Port,needed format for SNMP LIB */ + uchar szTarget[MAXHOSTNAMELEN+1]; /* IP/hostname of Snmp Target*/ + uchar szTargetAndPort[MAXHOSTNAMELEN+1]; /* IP/hostname + Port,needed format for SNMP LIB */ uchar szCommunity[OMSNMP_MAXCOMMUNITYLENGHT+1]; /* Snmp Community */ uchar szEnterpriseOID[OMSNMP_MAXOIDLENGHT+1]; /* Snmp Enterprise OID - default is (1.3.6.1.4.1.3.1.1 = enterprises.cmu.1.1) */ uchar szSyslogMessageOID[OMSNMP_MAXOIDLENGHT+1]; /* Snmp OID used for the Syslog Message - default is 1.3.6.1.4.1 - .iso.org.dod.internet.private.enterprises */ - int iPort; /* Target Port */ - int iSNMPVersion; /* SNMP Version to use */ - int iTrapType; /* Snmp TrapType or GenericType */ - int iSpecificType; /* Snmp Specific Type */ + int iPort; /* Target Port */ + int iSNMPVersion; /* SNMP Version to use */ + int iTrapType; /* Snmp TrapType or GenericType */ + int iSpecificType; /* Snmp Specific Type */ + + netsnmp_session *snmpsession; /* Holds to SNMP Session, NULL if not initialized */ } instanceData; BEGINcreateInstance @@ -118,32 +120,41 @@ CODESTARTisCompatibleWithFeature /* we are not compatible with repeated msg reduction feature, so do not allow it */ ENDisCompatibleWithFeature +/* Exit SNMP Session + * alorbach, 2008-02-12 + */ +static rsRetVal omsnmp_exitSession(instanceData *pData) +{ + DEFiRet; -BEGINtryResume -CODESTARTtryResume -ENDtryResume + if(pData->snmpsession != NULL) { + dbgprintf( "omsnmp_exitSession: Clearing Session to '%s' on Port = '%d'\n", pData->szTarget, pData->iPort); + snmp_close(pData->snmpsession); + pData->snmpsession = NULL; + } -static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) + RETiRet; +} + +/* Init SNMP Session + * alorbach, 2008-02-12 + */ +static rsRetVal omsnmp_initSession(instanceData *pData) { DEFiRet; + + /* should not happen, but if session is not cleared yet - we do it now! */ + if (pData->snmpsession != NULL) + omsnmp_exitSession(pData); - netsnmp_session session, *ss; - netsnmp_pdu *pdu = NULL; - oid enterpriseoid[MAX_OID_LEN]; - size_t enterpriseoidlen = MAX_OID_LEN; - oid oidSyslogMessage[MAX_OID_LEN]; - size_t oLen = MAX_OID_LEN; - int status; - char *trap = NULL; - const char *strErr = NULL; + netsnmp_session session; - assert(psz != NULL); - dbgprintf( "omsnmp_sendsnmp: ENTER - Target = '%s' on Port = '%d' syslogmessage = '%s'\n", pData->szTarget, pData->iPort, (char*)psz); + dbgprintf( "omsnmp_initSession: ENTER - Target = '%s' on Port = '%d'\n", pData->szTarget, pData->iPort); putenv(strdup("POSIXLY_CORRECT=1")); - + snmp_sess_init(&session); - session.version = pData->iSNMPVersion; /* Sample SNMP_VERSION_1; */ + session.version = pData->iSNMPVersion; session.callback = NULL; /* NOT NEEDED */ session.callback_magic = NULL; session.peername = (char*) pData->szTargetAndPort; @@ -155,16 +166,50 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) session.community_len = strlen((char*) pData->szCommunity); } - ss = snmp_open(&session); - if (ss == NULL) + pData->snmpsession = snmp_open(&session); + if (pData->snmpsession == NULL) + { + logerrorVar("omsnmp_initSession: snmp_open to host '%s' on Port '%d' failed\n", pData->szTarget, pData->iPort); + /* Stay suspended */ + iRet = RS_RET_SUSPENDED; + } + else { - /*TODO diagnose snmp_open errors with the input netsnmp_session pointer */ - logerrorVar("omsnmp_sendsnmp: snmp_open to host '%s' on Port '%d' failed\n", pData->szTarget, pData->iPort); - ABORT_FINALIZE(RS_RET_ERR); + /* Report success */ + iRet = RS_RET_OK; + } + + RETiRet; +} + +static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) +{ + DEFiRet; + + netsnmp_pdu *pdu = NULL; + oid enterpriseoid[MAX_OID_LEN]; + size_t enterpriseoidlen = MAX_OID_LEN; + oid oidSyslogMessage[MAX_OID_LEN]; + size_t oLen = MAX_OID_LEN; + int status; + char *trap = NULL; + const char *strErr = NULL; + + /* Init SNMP Session if necessary */ + if (pData->snmpsession == NULL) + { + iRet = omsnmp_initSession(pData); + if (iRet != RS_RET_OK) { + ABORT_FINALIZE(iRet); /* This will most likely return RS_RET_SUSPENDED */ + } } + /* String should not be NULL */ + assert(psz != NULL); + dbgprintf( "omsnmp_sendsnmp: ENTER - Syslogmessage = '%s'\n", (char*)psz); + /* If SNMP Version1 is configured !*/ - if (session.version == SNMP_VERSION_1) + if ( pData->snmpsession->version == SNMP_VERSION_1) { pdu = snmp_pdu_create(SNMP_MSG_TRAP); @@ -174,7 +219,7 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) strErr = snmp_api_errstring(snmp_errno); logerrorVar("omsnmp_sendsnmp: Parsing EnterpriseOID failed '%s' with error '%s' \n", pData->szSyslogMessageOID, strErr); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_DISABLE_ACTION); } pdu->enterprise = (oid *) malloc(enterpriseoidlen * sizeof(oid)); memcpy(pdu->enterprise, enterpriseoid, enterpriseoidlen * sizeof(oid)); @@ -190,7 +235,7 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) pdu->time = get_uptime(); } /* If SNMP Version2c is configured !*/ - else if (session.version == SNMP_VERSION_2c) + else if (pData->snmpsession->version == SNMP_VERSION_2c) { long sysuptime; char csysuptime[20]; @@ -209,7 +254,7 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) { strErr = snmp_api_errstring(snmp_errno); logerrorVar("omsnmp_sendsnmp: Adding trap OID failed '%s' with error '%s' \n", pData->szSyslogMessageOID, strErr); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_DISABLE_ACTION); } } @@ -224,7 +269,7 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) { const char *str = snmp_api_errstring(iErrCode); logerrorVar( "omsnmp_sendsnmp: Invalid SyslogMessage OID, error code '%d' - '%s'\n", iErrCode, str ); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_DISABLE_ACTION); } } else @@ -232,22 +277,21 @@ static rsRetVal omsnmp_sendsnmp(instanceData *pData, uchar *psz) strErr = snmp_api_errstring(snmp_errno); logerrorVar("omsnmp_sendsnmp: Parsing SyslogMessageOID failed '%s' with error '%s' \n", pData->szSyslogMessageOID, strErr); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_DISABLE_ACTION); } /* Send the TRAP */ - status = snmp_send(ss, pdu) == 0; + status = snmp_send(pData->snmpsession, pdu) == 0; if (status) { - int iErrorCode = 0; - if (ss->s_snmp_errno != 0) - iErrorCode = ss->s_snmp_errno; - else - iErrorCode = session.s_snmp_errno; - /* Debug Output! */ + int iErrorCode = pData->snmpsession->s_snmp_errno; logerrorVar( "omsnmp_sendsnmp: snmp_send failed error '%d', Description='%s'\n", iErrorCode*(-1), api_errors[iErrorCode*(-1)]); - ABORT_FINALIZE(RS_RET_ERR); + + /* Clear Session */ + omsnmp_exitSession(pData); + + ABORT_FINALIZE(RS_RET_SUSPENDED); } finalize_it: @@ -257,14 +301,14 @@ finalize_it: } } - if(ss != NULL) { - snmp_close(ss); - } - dbgprintf( "omsnmp_sendsnmp: LEAVE\n"); RETiRet; } +BEGINtryResume +CODESTARTtryResume + iRet = omsnmp_initSession(pData); +ENDtryResume BEGINdoAction CODESTARTdoAction @@ -273,17 +317,16 @@ CODESTARTdoAction { ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } - -/* dbgprintf("omsnmp: Sending SNMP Trap to '%s' on Port '%d'\n", pData->szTarget, pData->iPort); */ + + /* This will generate and send the SNMP Trap */ iRet = omsnmp_sendsnmp(pData, ppString[0]); finalize_it: ENDdoAction BEGINfreeInstance CODESTARTfreeInstance - /* we do not have instance data, so we do not need to - * do anything here. -- rgerhards, 2007-07-25 - */ + /* free snmp Session here */ + omsnmp_exitSession(pData); ENDfreeInstance @@ -388,6 +431,8 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) /* Set some defaults in the NetSNMP library */ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DEFAULT_PORT, pData->iPort ); + /* Init Session Pointer */ + pData->snmpsession = NULL; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct |