From d0b5d64c26c5b15733f6dd3f76d632e9de72cd41 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 5 May 2011 12:19:58 +0200 Subject: added skeleton for mmsnmptrapd --- Makefile.am | 5 + configure.ac | 17 ++++ plugins/mmsnmptrapd/Makefile.am | 8 ++ plugins/mmsnmptrapd/mmsnmptrapd.c | 207 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 plugins/mmsnmptrapd/Makefile.am create mode 100644 plugins/mmsnmptrapd/mmsnmptrapd.c diff --git a/Makefile.am b/Makefile.am index 2d73013b..de4777b2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -168,6 +168,10 @@ if ENABLE_OMTEMPLATE SUBDIRS += plugins/omtemplate endif +if ENABLE_MMSNMPTRAPD +SUBDIRS += plugins/mmsnmptrapd +endif + if ENABLE_IMFILE SUBDIRS += plugins/imfile endif @@ -239,5 +243,6 @@ DISTCHECK_CONFIGURE_FLAGS= --enable-gssapi_krb5 \ --enable-pmsnare \ --enable-imtemplate \ --enable-omtemplate \ + --enable-mmsnmptrapd \ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index d6082969..6ac6ff65 100644 --- a/configure.ac +++ b/configure.ac @@ -1135,6 +1135,19 @@ AM_CONDITIONAL(ENABLE_OMTEMPLATE, test x$enable_omtemplate = xyes) # end of copy template - be sure to search for omtemplate to find everything! +# settings for mmsnmptrapd message modification module +AC_ARG_ENABLE(mmsnmptrapd, + [AS_HELP_STRING([--enable-mmsnmptrapd],[Compiles mmsnmptrapd module @<:@default=no@:>@])], + [case "${enableval}" in + yes) enable_mmsnmptrapd="yes" ;; + no) enable_mmsnmptrapd="no" ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-mmsnmptrapd) ;; + esac], + [enable_mmsnmptrapd=no] +) +AM_CONDITIONAL(ENABLE_MMSNMPTRAPD, test x$enable_mmsnmptrapd = xyes) + + # settings for the omhdfs; AC_ARG_ENABLE(omhdfs, [AS_HELP_STRING([--enable-omhdfs],[Compiles omhdfs template module @<:@default=no@:>@])], @@ -1193,6 +1206,7 @@ AC_CONFIG_FILES([Makefile \ plugins/omoracle/Makefile \ plugins/omudpspoof/Makefile \ plugins/sm_cust_bindcdr/Makefile \ + plugins/mmsnmptrapd/Makefile \ plugins/cust1/Makefile \ java/Makefile \ tests/Makefile]) @@ -1238,6 +1252,9 @@ echo " pmcisconames module will be compiled: $enable_pmcisconames" echo " pmaixforwardedfrom module w.be compiled: $enable_pmaixforwardedfrom" echo " pmsnare module will be compiled: $enable_pmsnare" echo +echo "---{ message modification modules }---" +echo " mmsnmptrapd module will be compiled: $enable_mmsnmptrapd" +echo echo "---{ strgen modules }---" echo " sm_cust_bindcdr module will be compiled: $enable_sm_cust_bindcdr" echo diff --git a/plugins/mmsnmptrapd/Makefile.am b/plugins/mmsnmptrapd/Makefile.am new file mode 100644 index 00000000..ca027ca7 --- /dev/null +++ b/plugins/mmsnmptrapd/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = mmsnmptrapd.la + +mmsnmptrapd_la_SOURCES = mmsnmptrapd.c +mmsnmptrapd_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +mmsnmptrapd_la_LDFLAGS = -module -avoid-version +mmsnmptrapd_la_LIBADD = + +EXTRA_DIST = diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c new file mode 100644 index 00000000..80211496 --- /dev/null +++ b/plugins/mmsnmptrapd/mmsnmptrapd.c @@ -0,0 +1,207 @@ +/* mmsnmptrapd.c + * This is a message modification module. It takes messages generated + * from snmptrapd and modifies them so that the look like they + * originated from the real originator. + * + * NOTE: read comments in module-template.h for details on the calling interface! + * + * File begun on 2011-05-05 by RGerhards + * + * Copyright 2011 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include "rsyslog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "conf.h" +#include "syslogd-types.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" +#include "dirty.h" + +MODULE_TYPE_OUTPUT +MODULE_TYPE_NOKEEP + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); + +/* static data */ +DEFobjCurrIf(errmsg); + +/* internal structures + */ +DEF_OMOD_STATIC_DATA + +typedef struct _instanceData { + uchar *pszTagName; +} instanceData; + +typedef struct configSettings_s { + uchar *pszTagName; /**< name of tag start value that indicates snmptrapd initiated message */ +} configSettings_t; +configSettings_t cs; + +//TODO: enable for v6 +#if 0 +SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */ + +BEGINinitConfVars /* (re)set config variables to default values */ +CODESTARTinitConfVars + cs.pszTagName = NULL; + resetConfigVariables(NULL, NULL); +ENDinitConfVars +#endif + + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance +ENDfreeInstance + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo + dbgprintf("mmsnmptrapd\n"); +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + +BEGINdoAction + msg_t *pMsg; +CODESTARTdoAction + pMsg = (msg_t*) ppString[0]; + dbgprintf("XXXX: mmsnmptrapd called with pMsg %p\n", pMsg); +ENDdoAction + + +BEGINparseSelectorAct +CODESTARTparseSelectorAct +CODE_STD_STRING_REQUESTparseSelectorAct(1) + /* first check if this config line is actually for us */ + if(strncmp((char*) p, ":mmsnmptrapd:", sizeof(":mmsnmptrapd:") - 1)) { + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + } + + /* ok, if we reach this point, we have something for us */ + p += sizeof(":mmsnmptrapd:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ + CHKiRet(createInstance(&pData)); + + /* check if a non-standard template is to be applied */ + if(*(p-1) == ';') + --p; + /* we call the function below because we need to call it via our interface definition. However, + * the format specified (if any) is always ignored. + */ + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar*) "RSYSLOG_FileFormat")); + + /* finally build the instance */ + pData->pszTagName = cs.pszTagName; + + /* all config vars auto-reset! */ + cs.pszTagName = NULL; +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + + +BEGINmodExit +CODESTARTmodExit + objRelease(errmsg, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +ENDqueryEtryPt + + + +/* Reset config variables for this module to default values. + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + DEFiRet; + free(cs.pszTagName); + cs.pszTagName = NULL; + RETiRet; +} + + +BEGINmodInit() + rsRetVal localRet; + rsRetVal (*pomsrGetSupportedTplOpts)(unsigned long *pOpts); + unsigned long opts; + int bMsgPassingSupported; +CODESTARTmodInit +//TODO v6: add SCOPINGmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; + /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + /* check if the rsyslog core supports parameter passing code */ + bMsgPassingSupported = 0; + localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", + &pomsrGetSupportedTplOpts); + if(localRet == RS_RET_OK) { + /* found entry point, so let's see if core supports msg passing */ + CHKiRet((*pomsrGetSupportedTplOpts)(&opts)); + if(opts & OMSR_TPL_AS_MSG) + bMsgPassingSupported = 1; + } else if(localRet != RS_RET_ENTRY_POINT_NOT_FOUND) { + ABORT_FINALIZE(localRet); /* Something else went wrong, not acceptable */ + } + + if(!bMsgPassingSupported) { + DBGPRINTF("mmsnmptrapd: msg-passing is not supported by rsyslog core, " + "can not continue.\n"); + ABORT_FINALIZE(RS_RET_NO_MSG_PASSING); + } + + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + + CHKiRet(omsdRegCFSLineHdlr((uchar *)"mmsnmptrapdtag", 0, eCmdHdlrInt, + NULL, &cs.pszTagName, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit + +/* vi:set ai: + */ -- cgit From e06cebe1275421f4ed333b2564dcdb7d5924271e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 6 May 2011 08:11:44 +0200 Subject: mmsnmptrap: added TAG processing --- plugins/mmsnmptrapd/mmsnmptrapd.c | 78 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c index 80211496..c64994f6 100644 --- a/plugins/mmsnmptrapd/mmsnmptrapd.c +++ b/plugins/mmsnmptrapd/mmsnmptrapd.c @@ -40,11 +40,13 @@ #include #include #include "conf.h" +#include "msg.h" #include "syslogd-types.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" +#include "unicode-helper.h" #include "dirty.h" MODULE_TYPE_OUTPUT @@ -61,6 +63,8 @@ DEF_OMOD_STATIC_DATA typedef struct _instanceData { uchar *pszTagName; + uchar *pszTagID; /* chaced: name plus trailig shlash (for compares) */ + int lenTagID; /* cached length of tag ID, for performance reasons */ } instanceData; typedef struct configSettings_s { @@ -92,6 +96,8 @@ ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance + free(pData->pszTagName); + free(pData->pszTagID); ENDfreeInstance @@ -105,11 +111,66 @@ BEGINtryResume CODESTARTtryResume ENDtryResume +/* get string up to the next SP or '/'. Stops at max size. + * dst, lenDst (receive buffer) must be given. lenDst is + * max length on entry and actual length on exit. + */ +static int +getTagComponent(uchar *tag, uchar *dst, int *lenDst) +{ + int end = *lenDst - 1; /* -1 for NUL-char! */ + int i; + + i = 0; +dbgprintf("XXXX: getTagComponent tag on input: '%s'(%p)\n", tag, tag); + if(tag[i] != '/') + goto done; + ++tag; + while(i < end && tag[i] != '\0' && tag[i] != ' ' && tag[i] != '/') { + dst[i] = tag[i]; + ++i; + } + dst[i] = '\0'; +dbgprintf("XXXX: getTagComponent dst on output: '%s', len %d\n", dst, i); + *lenDst = i; +done: + return i; +} + + BEGINdoAction + int lenTAG; + int lenSever; + int lenHost; msg_t *pMsg; + uchar *pszTag; + uchar pszSever[512]; + uchar pszHost[512]; CODESTARTdoAction pMsg = (msg_t*) ppString[0]; dbgprintf("XXXX: mmsnmptrapd called with pMsg %p\n", pMsg); + getTAG(pMsg, &pszTag, &lenTAG); + if(strncmp((char*)pszTag, (char*)pData->pszTagID, pData->lenTagID)) { + DBGPRINTF("tag '%s' not matching, mmsnmptrapd ignoring this message\n", + pszTag); + FINALIZE; + } + + lenSever = sizeof(pszSever); +dbgprintf("XXXX: pszTag: '%s', lenID %d\n", pszTag, pData->lenTagID); + getTagComponent(pszTag+pData->lenTagID-1, pszSever, &lenSever); + lenHost = sizeof(pszHost); + getTagComponent(pszTag+pData->lenTagID+lenSever, pszHost, &lenHost); + dbgprintf("XXXX: mmsnmptrapd sever '%s'(%d), host '%s'(%d)\n", pszSever, lenSever, pszHost,lenHost); + + if(pszHost[lenHost-1] == ':') { + pszHost[lenHost-1] = '\0'; + --lenHost; + } + /* now apply new settings */ + MsgSetTAG(pMsg, pData->pszTagName, pData->lenTagID); + MsgSetHOSTNAME(pMsg, pszHost, lenHost); +finalize_it: ENDdoAction @@ -134,7 +195,22 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar*) "RSYSLOG_FileFormat")); /* finally build the instance */ - pData->pszTagName = cs.pszTagName; + if(cs.pszTagName == NULL) { + pData->pszTagName = (uchar*) strdup("snmptrapd:"); + pData->pszTagID = (uchar*) strdup("snmptrapd/"); + } else { + int lenTag = ustrlen(cs.pszTagName); + /* new tag value (with colon at the end) */ + CHKmalloc(pData->pszTagName = MALLOC(lenTag + 2)); + memcpy(pData->pszTagName, cs.pszTagName, lenTag); + memcpy(pData->pszTagName+lenTag, ":", 2); + /* tag ID for comparisions */ + CHKmalloc(pData->pszTagID = MALLOC(lenTag + 2)); + memcpy(pData->pszTagID, cs.pszTagName, lenTag); + memcpy(pData->pszTagID+lenTag, "/", 2); + free(cs.pszTagName); /* no longer needed */ + } + pData->lenTagID = ustrlen(pData->pszTagID); /* all config vars auto-reset! */ cs.pszTagName = NULL; -- cgit From d155c81057f66fe0e3acf5e79ba5dd7929416560 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 9 May 2011 11:37:26 +0200 Subject: mmsnmptrapd: added capability to specify severity mapping --- plugins/mmsnmptrapd/mmsnmptrapd.c | 156 +++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c index c64994f6..4a315ed9 100644 --- a/plugins/mmsnmptrapd/mmsnmptrapd.c +++ b/plugins/mmsnmptrapd/mmsnmptrapd.c @@ -36,9 +36,10 @@ #include #include #include +#include +#include #include #include -#include #include "conf.h" #include "msg.h" #include "syslogd-types.h" @@ -61,14 +62,22 @@ DEFobjCurrIf(errmsg); */ DEF_OMOD_STATIC_DATA +struct severMap_s { + uchar *name; + int code; + struct severMap_s *next; +}; + typedef struct _instanceData { uchar *pszTagName; - uchar *pszTagID; /* chaced: name plus trailig shlash (for compares) */ + uchar *pszTagID; /* chaced: name plus trailing shlash (for compares) */ int lenTagID; /* cached length of tag ID, for performance reasons */ + struct severMap_s *severMap; } instanceData; typedef struct configSettings_s { uchar *pszTagName; /**< name of tag start value that indicates snmptrapd initiated message */ + uchar *pszSeverityMapping; /**< severitystring to numerical code mapping for snmptrapd string */ } configSettings_t; configSettings_t cs; @@ -79,6 +88,7 @@ SCOPING_SUPPORT; /* must be set AFTER configSettings_t is defined */ BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars cs.pszTagName = NULL; + cs.pszSeverityMapping = NULL; resetConfigVariables(NULL, NULL); ENDinitConfVars #endif @@ -95,7 +105,14 @@ ENDisCompatibleWithFeature BEGINfreeInstance + struct severMap_s *node, *nodeDel; CODESTARTfreeInstance + for(node = pData->severMap ; node != NULL ; ) { + nodeDel = node; + node = node->next; + free(nodeDel->name); + free(nodeDel); + } free(pData->pszTagName); free(pData->pszTagID); ENDfreeInstance @@ -111,6 +128,57 @@ BEGINtryResume CODESTARTtryResume ENDtryResume + +/* check if a string is numeric (int) */ +static inline int +isNumeric(uchar *str) +{ + int r = 1; + if(*str == '-' || *str == '+') + ++str; + while(*str) { + if(!isdigit(*str)) { + r = 0; + goto done; + } + ++str; + } +done: + return r; +} + +/* get a substring delimited by a character (or end of string). The + * string is trimmed, that is leading and trailing spaces are removed. + * The caller must provide a buffer which shall receive the substring. + * String length is returned as result. The input string is updated + * on exit, so that it may be used for another query starting at that + * position. + */ +static int +getSubstring(uchar **psrc, uchar delim, uchar *dst, int lenDst) +{ + uchar *dstwrk = dst; + uchar *src = *psrc; + while(*src && isspace(*src)) { + ++src; /* trim leading spaces */ + } + while(*src && *src != delim && --lenDst > 0) { + *dstwrk++ = *src++; + } + dstwrk--; + while(dstwrk > dst && isspace(*dst)) + --dstwrk; /* trim trailing spaces */ + *++dstwrk = '\0'; +dbgprintf("XXXX: getSubstring out: '%s', out '%s', ret %d\n", src, dst, (int) (dstwrk -dst)); + + /* final results */ + if(*src == delim) + ++src; + *psrc = src; + return(dstwrk - dst); +} + + /* get string up to the next SP or '/'. Stops at max size. * dst, lenDst (receive buffer) must be given. lenDst is * max length on entry and actual length on exit. @@ -138,10 +206,30 @@ done: } +/* lookup severity code based on provided severity + * returns -1 if severity could not be found. + */ +static inline int +lookupSeverityCode(instanceData *pData, uchar *sever) +{ + struct severMap_s *node; + int sevCode = -1; + + for(node = pData->severMap ; node != NULL ; node = node->next) { + if(!ustrcmp(node->name, sever)) { + sevCode = node->code; + break; + } + } + return sevCode; +} + + BEGINdoAction int lenTAG; int lenSever; int lenHost; + int sevCode; msg_t *pMsg; uchar *pszTag; uchar pszSever[512]; @@ -167,13 +255,64 @@ dbgprintf("XXXX: pszTag: '%s', lenID %d\n", pszTag, pData->lenTagID); pszHost[lenHost-1] = '\0'; --lenHost; } + sevCode = lookupSeverityCode(pData, pszSever); +dbgprintf("XXXX: severity for message is %d\n", sevCode); /* now apply new settings */ MsgSetTAG(pMsg, pData->pszTagName, pData->lenTagID); MsgSetHOSTNAME(pMsg, pszHost, lenHost); + if(sevCode != -1) + pMsg->iSeverity = sevCode; /* we update like the parser does! */ finalize_it: ENDdoAction +/* Build the severity mapping table based on user-provided configuration + * settings. + */ +static inline rsRetVal +buildSeverityMapping(instanceData *pData) +{ + uchar pszSev[512]; + uchar pszSevCode[512]; + int sevCode; + uchar *mapping; + struct severMap_s *node; + DEFiRet; + + mapping = cs.pszSeverityMapping; + + while(1) { /* broken inside when all entries are processed */ + if(getSubstring(&mapping, '/', pszSev, sizeof(pszSev)) == 0) { + FINALIZE; + } + if(getSubstring(&mapping, ',', pszSevCode, sizeof(pszSevCode)) == 0) { + errmsg.LogError(0, RS_RET_ERR, "error: invalid severity mapping, cannot " + "extract code. given: '%s'\n", cs.pszSeverityMapping); + ABORT_FINALIZE(RS_RET_ERR); + } + sevCode = atoi((char*) pszSevCode); + if(!isNumeric(pszSevCode)) + sevCode = -1; + if(sevCode < 0 || sevCode > 7) { + errmsg.LogError(0, RS_RET_ERR, "error: severity code %d outside of valid " + "range 0..7 (was string '%s')\n", sevCode, pszSevCode); + ABORT_FINALIZE(RS_RET_ERR); + } + CHKmalloc(node = MALLOC(sizeof(struct severMap_s))); + CHKmalloc(node->name = ustrdup(pszSev)); + node->code = sevCode; + /* we enqueue at the top, so the two lines below do all we need! */ + node->next = pData->severMap; + pData->severMap = node; + DBGPRINTF("mmsnmptrapd: severity string '%s' mapped to code %d\n", + pszSev, sevCode); + } + +finalize_it: + RETiRet; +} + + BEGINparseSelectorAct CODESTARTparseSelectorAct CODE_STD_STRING_REQUESTparseSelectorAct(1) @@ -211,9 +350,14 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) free(cs.pszTagName); /* no longer needed */ } pData->lenTagID = ustrlen(pData->pszTagID); + if(cs.pszSeverityMapping != NULL) { + CHKiRet(buildSeverityMapping(pData)); + } /* all config vars auto-reset! */ cs.pszTagName = NULL; + free(cs.pszSeverityMapping); + cs.pszSeverityMapping = NULL; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct @@ -238,6 +382,8 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a DEFiRet; free(cs.pszTagName); cs.pszTagName = NULL; + free(cs.pszSeverityMapping); + cs.pszSeverityMapping = NULL; RETiRet; } @@ -272,9 +418,15 @@ CODEmodInit_QueryRegCFSLineHdlr } CHKiRet(objUse(errmsg, CORE_COMPONENT)); + + /* TODO: config vars ininit can be replaced by commented-out code above in v6 */ + cs.pszTagName = NULL; + cs.pszSeverityMapping = NULL; CHKiRet(omsdRegCFSLineHdlr((uchar *)"mmsnmptrapdtag", 0, eCmdHdlrInt, NULL, &cs.pszTagName, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"mmsnmptrapdseveritymapping", 0, eCmdHdlrGetWord, + NULL, &cs.pszSeverityMapping, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -- cgit From 1be2f42bdc961bbe1ae02feae3e078eeb775ea24 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 9 May 2011 12:06:32 +0200 Subject: cosmetic cleanup --- plugins/mmsnmptrapd/mmsnmptrapd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c index 4a315ed9..8f996832 100644 --- a/plugins/mmsnmptrapd/mmsnmptrapd.c +++ b/plugins/mmsnmptrapd/mmsnmptrapd.c @@ -169,7 +169,6 @@ getSubstring(uchar **psrc, uchar delim, uchar *dst, int lenDst) while(dstwrk > dst && isspace(*dst)) --dstwrk; /* trim trailing spaces */ *++dstwrk = '\0'; -dbgprintf("XXXX: getSubstring out: '%s', out '%s', ret %d\n", src, dst, (int) (dstwrk -dst)); /* final results */ if(*src == delim) @@ -190,7 +189,6 @@ getTagComponent(uchar *tag, uchar *dst, int *lenDst) int i; i = 0; -dbgprintf("XXXX: getTagComponent tag on input: '%s'(%p)\n", tag, tag); if(tag[i] != '/') goto done; ++tag; -- cgit From e8a71cd0d6ea72cb6495305286cb778b9d951e0c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 10 May 2011 09:04:23 +0200 Subject: mmsnmptrapd: added doc & mentioned in ChangeLog --- ChangeLog | 8 ++++ doc/Makefile.am | 1 + doc/mmsnmptrapd.html | 92 +++++++++++++++++++++++++++++++++++++ doc/rsyslog_conf_modules.html | 9 ++++ plugins/sm_cust_bindcdr/Makefile.am | 6 --- 5 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 doc/mmsnmptrapd.html delete mode 100644 plugins/sm_cust_bindcdr/Makefile.am diff --git a/ChangeLog b/ChangeLog index 9681d911..db296afa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ --------------------------------------------------------------------------- Version 5.8.1 [V5-stable] (rgerhards), 2011-04-?? +- new module mmsnmptrapd, a sample message modification module + This can be useful to reformat snmptrapd messages and also serves as + a sample for how to write message modification modules using the + output module interface. Note that we introduced this new + functionality directly into the stable release, as it does not + modify the core and as such cannot have any side-effects if it is + not used (and thus the risk is solely on users requiring that + functionality). - bugfix: rate-limiting inside imuxsock did not work 100% correct reason was that a global config variable was invalidly accessed where a listener variable should have been used. diff --git a/doc/Makefile.am b/doc/Makefile.am index a5393cbe..91d92afd 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -48,6 +48,7 @@ html_files = \ imuxsock.html \ imklog.html \ pmlastmsg.html \ + mmsnmptrapd.html \ queues.html \ src/queueWorkerLogic.dia \ queueWorkerLogic.jpg \ diff --git a/doc/mmsnmptrapd.html b/doc/mmsnmptrapd.html new file mode 100644 index 00000000..e69bc241 --- /dev/null +++ b/doc/mmsnmptrapd.html @@ -0,0 +1,92 @@ + + + + +mmsnmptrapd message modification module + + + +back to rsyslog module overview + +

mmsnmptrapd message modification module

+

Module Name:    imtcp

+

Author: Rainer Gerhards <rgerhards@adiscon.com> (custom-created)

+

Multi-Ruleset Support: since 5.8.1 +

Description:

+

This module uses a specific configuration of snmptrapd's tag values to +obtain information of the original source system and the severity present inside the +original SNMP trap. It then replaces these fields inside the syslog message. +

Let's look at an example. Essentially, SNMPTT will invoke something like this: +

logger -t snmptrapd/warning/realhost Host 003c.abcd.ffff in vlan 17 is flapping between port Gi4/1 and port Gi3/2 
+
+

+This message modification module will change the tag (removing the additional information), +hostname and severity (not shown in example), so the log entry will look as follows: +

+2011-04-21T16:43:09.101633+02:00 realhost snmptrapd: Host 003c.abcd.ffff in vlan 122 is flapping between port Gi4/1 and port Gi3/2 
+
+The following logic is applied to all message being processed: +
    +
  1. The module checks incoming syslog entries. If their TAG field starts with "snmptrapd/" +(configurable), they are modified, otherwise not. If the are modified, this happens as follows: +
  2. It will derive the hostname from the tag field which has format snmptrapd/severity/hostname +
  3. It should derive the severity from the tag field which has format +snmptrapd/severity/hostname. A configurable mapping table will be used to drive a new +severity value from that severity string. If no mapping has been defined, the original +severity is not changed. +
  4. It replaces the "FromHost" value with the derived value from step2 +
  5. It replaces the "Severity" value with the derived value from step 3 +
+

Note that the placement of this module inside the configuration is important. All actions +before this modules is called will work on the unmodified message. All messages after it's call +will work on the modified message. Please also note that there is some extra power in case it +is required: as this module is implemented via the output module interface, a filter +can be used (actually must be used) in order to tell when it is called. Usually, the catch-all +filter (*.*) is used, but more specific filters are fully supported. So it is possible to define +different parameters for this module depending on different filters. It is also possible to +just run messages from one remote system through this module, with the help of filters or +multiple rulesets and ruleset bindings. In short words, all capabilities rsyslog offers +to control output modules are also available to mmsnmptrapd. +

Configuration Directives:

+
    +
  • $mmsnmptrapdTag [tagname]
    +tells the module which start string inside the tag to look for. The default is +"snmptrap/" +
  • $mmsnmptrapdSevertiyMapping [severtiymap]
    +This specifies the severity mapping table. It needs to be specified as a list. Note that +due to the current config system no whitespace is supported inside the list, so be +sure not to use any whitespace inside it.
    +The list is constructed of Severtiy-Name/Severity-Value pairs, delimited by comma. +Severity-Name is a case-sensitive string, e.g. "warning" and an associated +numerical value (e.g. 4). +Possible values are in the rage 0..7 and are defined in RFC5424, table 2. The +given sample would be specified as "warning/4".
    +If multiple instances of mmsnmptrapd are used, each instance uses the most recently +defined $mmsnmptrapdSeverityMapping before itself. +
+Caveats/Known Bugs: +
    +
  • currently none known
  • +
+

Example:

+

This enables to rewrite messages from snmptrapd and configures error and warning +severities. The default tag is used.
+

+ +

+

[rsyslog.conf overview] +[manual index] [rsyslog site]

+

This documentation is part of the rsyslog +project.
+Copyright © 2011 by Rainer Gerhards and +Adiscon. +Released under the GNU GPL version 3 or higher.

+ + diff --git a/doc/rsyslog_conf_modules.html b/doc/rsyslog_conf_modules.html index 74aa319c..b03313f5 100644 --- a/doc/rsyslog_conf_modules.html +++ b/doc/rsyslog_conf_modules.html @@ -99,6 +99,15 @@ the methods the engine provides. They could be used, for example, to:
  • anonymize message content
  • add dynamically computed content to message (fields) +

    Message modification modules are usually written for one specific task and thus +usually are not generic enough to be reused. However, existing module's code is +probably an excellent starting base for writing a new module. Currently, the following +modules existin inside the source tree +

      +
    • mmsnmptrapd - uses information provided by snmptrapd inside +the tag to correct the original sender system and priority of messages. Implemented via +the output module interface. +

    String Generator Modules

    String generator modules are used, as the name implies, to generate strings based diff --git a/plugins/sm_cust_bindcdr/Makefile.am b/plugins/sm_cust_bindcdr/Makefile.am deleted file mode 100644 index 1f71d499..00000000 --- a/plugins/sm_cust_bindcdr/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -pkglib_LTLIBRARIES = sm_cust_bindcdr.la - -sm_cust_bindcdr_la_SOURCES = sm_cust_bindcdr.c -sm_cust_bindcdr_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) -sm_cust_bindcdr_la_LDFLAGS = -module -avoid-version -sm_cust_bindcdr_la_LIBADD = -- cgit