From ef661fe13c0ab5018afedb1cb5b8cffab05ad7c4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 4 Nov 2009 11:33:09 +0100 Subject: finalized parser module calling interface looks like we are almost done and need only to add the ruleset parser-specific config options. --- runtime/modules.c | 6 +++- runtime/parser.c | 93 +++++++++++++++++++++++++++++++++++-------------- runtime/parser.h | 2 ++ runtime/syslogd-types.h | 3 +- 4 files changed, 76 insertions(+), 28 deletions(-) (limited to 'runtime') diff --git a/runtime/modules.c b/runtime/modules.c index 41645a27..fd3468d8 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -493,10 +493,14 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ CHKiRet(parser.Construct(&pParser)); /* check some features */ - localRet = pNew->isCompatibleWithFeature(sFEATUREAtomaticSanitazion); + localRet = pNew->isCompatibleWithFeature(sFEATUREAutomaticSanitazion); if(localRet == RS_RET_OK){ CHKiRet(parser.SetDoSanitazion(pParser, TRUE)); } + localRet = pNew->isCompatibleWithFeature(sFEATUREAutomaticPRIParsing); + if(localRet == RS_RET_OK){ + CHKiRet(parser.SetDoPRIParsing(pParser, TRUE)); + } CHKiRet(parser.SetName(pParser, pParserName)); CHKiRet(parser.SetModPtr(pParser, pNew)); diff --git a/runtime/parser.c b/runtime/parser.c index 2c764739..e87068fc 100644 --- a/runtime/parser.c +++ b/runtime/parser.c @@ -376,36 +376,19 @@ finalize_it: RETiRet; } - -/* Parse a received message. The object's rawmsg property is taken and - * parsed according to the relevant standards. This can later be - * extended to support configured parsers. - * rgerhards, 2008-10-09 +/* A standard parser to parse out the PRI. This is made available in + * this module as it is expected that allmost all parsers will need + * that functionality and so they do not need to implement it themsleves. */ -static rsRetVal -ParseMsg(msg_t *pMsg) +static inline rsRetVal +ParsePRI(msg_t *pMsg) { - uchar *msg; int pri; + uchar *msg; int lenMsg; int iPriText; - rsRetVal localRet; - parserList_t *pParserList; - static int iErrMsgRateLimiter = 0; DEFiRet; - if(pMsg->iLenRawMsg == 0) - ABORT_FINALIZE(RS_RET_EMPTY_MSG); - -# ifdef USE_NETZIP - CHKiRet(uncompressMessage(pMsg)); -# endif - - CHKiRet(SanitizeMsg(pMsg)); - - /* we needed to sanitize first, because we otherwise do not have a C-string we can print... */ - DBGPRINTF("msg parser: flags %x, from '%s', msg '%s'\n", pMsg->msgFlags, getRcvFrom(pMsg), pMsg->pszRawMsg); - /* pull PRI */ lenMsg = pMsg->iLenRawMsg; msg = pMsg->pszRawMsg; @@ -428,9 +411,43 @@ ParseMsg(msg_t *pMsg) pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); MsgSetAfterPRIOffs(pMsg, msg - pMsg->pszRawMsg); + RETiRet; +} + + +/* Parse a received message. The object's rawmsg property is taken and + * parsed according to the relevant standards. This can later be + * extended to support configured parsers. + * rgerhards, 2008-10-09 + */ +static rsRetVal +ParseMsg(msg_t *pMsg) +{ + rsRetVal localRet; + parserList_t *pParserList; + parser_t *pParser; + bool bIsSanitized; + bool bPRIisParsed; + static int iErrMsgRateLimiter = 0; + DEFiRet; + + if(pMsg->iLenRawMsg == 0) + ABORT_FINALIZE(RS_RET_EMPTY_MSG); + +# ifdef USE_NETZIP + CHKiRet(uncompressMessage(pMsg)); +# endif + + /* we take the risk to print a non-sanitized string, because this is the best we can get + * (and that functionality is too important for debugging to drop it...). + */ + DBGPRINTF("msg parser: flags %x, from '%s', msg '%.50s'\n", pMsg->msgFlags, + getRcvFrom(pMsg), pMsg->pszRawMsg); /* we now need to go through our list of parsers and see which one is capable of - * parsing the message. + * parsing the message. Note that the first parser that requires message sanitization + * will cause it to happen. After that, access to the unsanitized message is no + * loger possible. */ pParserList = ruleset.GetParserList(pMsg); if(pParserList == NULL) @@ -438,7 +455,18 @@ ParseMsg(msg_t *pMsg) DBGPRINTF("Using parser list %p%s.\n", pParserList, (pParserList == pDfltParsLst) ? " (the default list)" : ""); + bIsSanitized = FALSE; + bPRIisParsed = FALSE; while(pParserList != NULL) { + pParser = pParserList->pParser; + if(pParser->bDoSanitazion && bIsSanitized == FALSE) { + CHKiRet(SanitizeMsg(pMsg)); + if(pParser->bDoPRIParsing && bPRIisParsed == FALSE) { + CHKiRet(ParsePRI(pMsg)); + bPRIisParsed = TRUE; + } + bIsSanitized = TRUE; + } localRet = pParserList->pParser->pModule->mod.pm.parse(pMsg); if(localRet != RS_RET_COULD_NOT_PARSE) break; @@ -453,14 +481,14 @@ ParseMsg(msg_t *pMsg) if(localRet != RS_RET_OK) { if(++iErrMsgRateLimiter > 1000) { errmsg.LogError(0, localRet, "Error: one message could not be processed by " - "any parser, message is being discarded (start of raw msg: '%50s')", + "any parser, message is being discarded (start of raw msg: '%.50s')", pMsg->pszRawMsg); } DBGPRINTF("No parser could process the message (state %d), we need to discard it.\n", localRet); ABORT_FINALIZE(localRet); } - /* finalize message object */ + /* "finalize" message object */ pMsg->msgFlags &= ~NEEDS_PARSING; /* this message is now parsed */ finalize_it: @@ -516,6 +544,18 @@ SetDoSanitazion(parser_t *pThis, int bDoIt) } +/* Specify if we should do standard PRI parsing before we pass the data + * down to the parser module. + */ +static rsRetVal +SetDoPRIParsing(parser_t *pThis, int bDoIt) +{ + ISOBJ_TYPE_assert(pThis, parser); + pThis->bDoPRIParsing = bDoIt; + return RS_RET_OK; +} + + /* queryInterface function-- rgerhards, 2009-11-03 */ BEGINobjQueryInterface(parser) @@ -535,6 +575,7 @@ CODESTARTobjQueryInterface(parser) pIf->SetName = SetName; pIf->SetModPtr = SetModPtr; pIf->SetDoSanitazion = SetDoSanitazion; + pIf->SetDoPRIParsing = SetDoPRIParsing; pIf->ParseMsg = ParseMsg; pIf->SanitizeMsg = SanitizeMsg; pIf->InitParserList = InitParserList; diff --git a/runtime/parser.h b/runtime/parser.h index d600fb19..a92b9920 100644 --- a/runtime/parser.h +++ b/runtime/parser.h @@ -39,6 +39,7 @@ struct parser_s { uchar *pName; /* name of this parser */ modInfo_t *pModule; /* pointer to parser's module */ bool bDoSanitazion; /* do standard message sanitazion before calling parser? */ + bool bDoPRIParsing; /* do standard PRI parsing before calling parser? */ }; /* interfaces */ @@ -50,6 +51,7 @@ BEGINinterface(parser) /* name must also be changed in ENDinterface macro! */ rsRetVal (*SetName)(parser_t *pThis, uchar *name); rsRetVal (*SetModPtr)(parser_t *pThis, modInfo_t *pMod); rsRetVal (*SetDoSanitazion)(parser_t *pThis, int); + rsRetVal (*SetDoPRIParsing)(parser_t *pThis, int); rsRetVal (*FindParser)(parser_t **ppThis, uchar*name); rsRetVal (*InitParserList)(parserList_t **pListRoot); rsRetVal (*AddParserToList)(parserList_t **pListRoot, parser_t *pParser); diff --git a/runtime/syslogd-types.h b/runtime/syslogd-types.h index 49eeaa6a..fcebd985 100644 --- a/runtime/syslogd-types.h +++ b/runtime/syslogd-types.h @@ -58,7 +58,8 @@ typedef enum _syslogFeature { sFEATURERepeatedMsgReduction = 1, /* for output modules */ sFEATURENonCancelInputTermination = 2, /* for input modules */ - sFEATUREAtomaticSanitazion = 3 /* for parser modules */ + sFEATUREAutomaticSanitazion = 3, /* for parser modules */ + sFEATUREAutomaticPRIParsing = 4 /* for parser modules */ } syslogFeature; /* we define our own facility and severities */ -- cgit