|
|
a856a8 |
diff -up ./configure.ac.pmrfc3164sd ./configure.ac
|
|
|
a856a8 |
--- ./configure.ac.pmrfc3164sd 2017-01-10 10:01:24.000000000 +0100
|
|
|
a856a8 |
+++ ./configure.ac 2017-04-03 10:10:40.912388923 +0200
|
|
|
a856a8 |
@@ -1559,6 +1559,18 @@ AC_ARG_ENABLE(pmpanngfw,
|
|
|
a856a8 |
)
|
|
|
a856a8 |
AM_CONDITIONAL(ENABLE_PMPANNGFW, test x$enable_pmpanngfw = xyes)
|
|
|
a856a8 |
|
|
|
a856a8 |
+# settings for pmrfc3164sd
|
|
|
a856a8 |
+AC_ARG_ENABLE(pmrfc3164sd,
|
|
|
a856a8 |
+ [AS_HELP_STRING([--enable-pmrfc3164sd],[Compiles rfc3164sd parser module @<:@default=no@:>@])],
|
|
|
a856a8 |
+ [case "${enableval}" in
|
|
|
a856a8 |
+ yes) enable_pmrfc3164sd="yes" ;;
|
|
|
a856a8 |
+ no) enable_pmrfc3164sd="no" ;;
|
|
|
a856a8 |
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-pmrfc3164sd) ;;
|
|
|
a856a8 |
+ esac],
|
|
|
a856a8 |
+ [enable_pmrfc3164sd=no]
|
|
|
a856a8 |
+)
|
|
|
a856a8 |
+AM_CONDITIONAL(ENABLE_PMRFC3164SD, test x$enable_pmrfc3164sd = xyes)
|
|
|
a856a8 |
+
|
|
|
a856a8 |
|
|
|
a856a8 |
# settings for omruleset
|
|
|
a856a8 |
AC_ARG_ENABLE(omruleset,
|
|
|
a856a8 |
@@ -1953,6 +1965,7 @@ AC_CONFIG_FILES([Makefile \
|
|
|
a856a8 |
plugins/mmexternal/Makefile \
|
|
|
a856a8 |
plugins/omstdout/Makefile \
|
|
|
a856a8 |
plugins/omjournal/Makefile \
|
|
|
a856a8 |
+ plugins/pmrfc3164sd/Makefile \
|
|
|
a856a8 |
plugins/pmciscoios/Makefile \
|
|
|
a856a8 |
plugins/pmnull/Makefile \
|
|
|
a856a8 |
plugins/omruleset/Makefile \
|
|
|
a856a8 |
@@ -2057,6 +2070,7 @@ echo " omamqp1 module will be compile
|
|
|
a856a8 |
echo " omtcl module will be compiled: $enable_omtcl"
|
|
|
a856a8 |
echo
|
|
|
a856a8 |
echo "---{ parser modules }---"
|
|
|
a856a8 |
+echo " pmrfc3164sd module will be compiled: $enable_pmrfc3164sd"
|
|
|
a856a8 |
echo " pmlastmsg module will be compiled: $enable_pmlastmsg"
|
|
|
a856a8 |
echo " pmcisconames module will be compiled: $enable_pmcisconames"
|
|
|
a856a8 |
echo " pmciscoios module will be compiled: $enable_pmciscoios"
|
|
|
a856a8 |
diff -up ./Makefile.am.pmrfc3164sd ./Makefile.am
|
|
|
a856a8 |
--- ./Makefile.am.pmrfc3164sd 2017-01-10 10:00:04.000000000 +0100
|
|
|
a856a8 |
+++ ./Makefile.am 2017-04-03 10:10:40.912388923 +0200
|
|
|
a856a8 |
@@ -115,6 +115,10 @@ if ENABLE_PMLASTMSG
|
|
|
a856a8 |
SUBDIRS += plugins/pmlastmsg
|
|
|
a856a8 |
endif
|
|
|
a856a8 |
|
|
|
a856a8 |
+if ENABLE_PMRFC3164SD
|
|
|
a856a8 |
+SUBDIRS += plugins/pmrfc3164sd
|
|
|
a856a8 |
+endif
|
|
|
a856a8 |
+
|
|
|
a856a8 |
if ENABLE_OMRULESET
|
|
|
a856a8 |
SUBDIRS += plugins/omruleset
|
|
|
a856a8 |
endif
|
|
|
a856a8 |
diff -up ./plugins/pmrfc3164sd/Makefile.am.pmrfc3164sd ./plugins/pmrfc3164sd/Makefile.am
|
|
|
a856a8 |
--- ./plugins/pmrfc3164sd/Makefile.am.pmrfc3164sd 2017-04-03 10:10:40.912388923 +0200
|
|
|
a856a8 |
+++ ./plugins/pmrfc3164sd/Makefile.am 2017-04-03 10:10:40.912388923 +0200
|
|
|
a856a8 |
@@ -0,0 +1,8 @@
|
|
|
a856a8 |
+pkglib_LTLIBRARIES = pmrfc3164sd.la
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+pmrfc3164sd_la_SOURCES = pmrfc3164sd.c
|
|
|
a856a8 |
+pmrfc3164sd_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools
|
|
|
a856a8 |
+pmrfc3164sd_la_LDFLAGS = -module -avoid-version
|
|
|
a856a8 |
+pmrfc3164sd_la_LIBADD =
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+EXTRA_DIST =
|
|
|
a856a8 |
diff -up ./plugins/pmrfc3164sd/pmrfc3164sd.c.pmrfc3164sd ./plugins/pmrfc3164sd/pmrfc3164sd.c
|
|
|
a856a8 |
--- ./plugins/pmrfc3164sd/pmrfc3164sd.c.pmrfc3164sd 2017-04-03 10:10:40.913388923 +0200
|
|
|
a856a8 |
+++ ./plugins/pmrfc3164sd/pmrfc3164sd.c 2017-04-03 10:26:52.012341658 +0200
|
|
|
a856a8 |
@@ -0,0 +1,345 @@
|
|
|
a856a8 |
+/* pmrfc3164sd.c
|
|
|
a856a8 |
+ * This is a parser module for RFC3164(legacy syslog)-formatted messages.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * NOTE: read comments in module-template.h to understand how this file
|
|
|
a856a8 |
+ * works!
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * File begun on 2009-11-04 by RGerhards
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * This file is part of rsyslog.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * Rsyslog is free software: you can redistribute it and/or modify
|
|
|
a856a8 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
a856a8 |
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
a856a8 |
+ * (at your option) any later version.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * Rsyslog is distributed in the hope that it will be useful,
|
|
|
a856a8 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
a856a8 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
a856a8 |
+ * GNU General Public License for more details.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * You should have received a copy of the GNU General Public License
|
|
|
a856a8 |
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
|
|
|
a856a8 |
+ *
|
|
|
a856a8 |
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+#include "config.h"
|
|
|
a856a8 |
+#include "rsyslog.h"
|
|
|
a856a8 |
+#include <stdlib.h>
|
|
|
a856a8 |
+#include <string.h>
|
|
|
a856a8 |
+#include <assert.h>
|
|
|
a856a8 |
+#include <errno.h>
|
|
|
a856a8 |
+#include <ctype.h>
|
|
|
a856a8 |
+#include "syslogd.h"
|
|
|
a856a8 |
+#include "conf.h"
|
|
|
a856a8 |
+#include "syslogd-types.h"
|
|
|
a856a8 |
+#include "template.h"
|
|
|
a856a8 |
+#include "msg.h"
|
|
|
a856a8 |
+#include "module-template.h"
|
|
|
a856a8 |
+#include "glbl.h"
|
|
|
a856a8 |
+#include "errmsg.h"
|
|
|
a856a8 |
+#include "parser.h"
|
|
|
a856a8 |
+#include "datetime.h"
|
|
|
a856a8 |
+#include "unicode-helper.h"
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+MODULE_TYPE_PARSER
|
|
|
a856a8 |
+MODULE_TYPE_NOKEEP
|
|
|
a856a8 |
+MODULE_CNFNAME("pmrfc3164sd")
|
|
|
a856a8 |
+PARSER_NAME("contrib.rfc3164sd")
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+/* internal structures
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+DEF_PMOD_STATIC_DATA
|
|
|
a856a8 |
+DEFobjCurrIf(errmsg)
|
|
|
a856a8 |
+DEFobjCurrIf(glbl)
|
|
|
a856a8 |
+DEFobjCurrIf(parser)
|
|
|
a856a8 |
+DEFobjCurrIf(datetime)
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+/* static data */
|
|
|
a856a8 |
+static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+BEGINisCompatibleWithFeature
|
|
|
a856a8 |
+CODESTARTisCompatibleWithFeature
|
|
|
a856a8 |
+ if(eFeat == sFEATUREAutomaticSanitazion)
|
|
|
a856a8 |
+ iRet = RS_RET_OK;
|
|
|
a856a8 |
+ if(eFeat == sFEATUREAutomaticPRIParsing)
|
|
|
a856a8 |
+ iRet = RS_RET_OK;
|
|
|
a856a8 |
+ENDisCompatibleWithFeature
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+/* Helper to parseRFCSyslogMsg. This function parses the structured
|
|
|
a856a8 |
+ * data field of a message. It does NOT parse inside structured data,
|
|
|
a856a8 |
+ * just gets the field as whole. Parsing the single entities is left
|
|
|
a856a8 |
+ * to other functions. The parsepointer is advanced
|
|
|
a856a8 |
+ * to after the terminating SP. The caller must ensure that the
|
|
|
a856a8 |
+ * provided buffer is large enough to hold the to be extracted value.
|
|
|
a856a8 |
+ * Returns 0 if everything is fine or 1 if either the field is not
|
|
|
a856a8 |
+ * SP-terminated or any other error occurs. -- rger, 2005-11-24
|
|
|
a856a8 |
+ * The function now receives the size of the string and makes sure
|
|
|
a856a8 |
+ * that it does not process more than that. The *pLenStr counter is
|
|
|
a856a8 |
+ * updated on exit. -- rgerhards, 2009-09-23
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr)
|
|
|
a856a8 |
+{
|
|
|
a856a8 |
+ uchar *p2parse;
|
|
|
a856a8 |
+ int bCont = 1;
|
|
|
a856a8 |
+ int iRet = 0;
|
|
|
a856a8 |
+ int lenStr;
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ assert(pp2parse != NULL);
|
|
|
a856a8 |
+ assert(*pp2parse != NULL);
|
|
|
a856a8 |
+ assert(pResult != NULL);
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ p2parse = *pp2parse;
|
|
|
a856a8 |
+ lenStr = *pLenStr;
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* this is the actual parsing loop
|
|
|
a856a8 |
+ * Remeber: structured data starts with [ and includes any characters
|
|
|
a856a8 |
+ * until the first ] followed by a SP. There may be spaces inside
|
|
|
a856a8 |
+ * structured data. There may also be \] inside the structured data, which
|
|
|
a856a8 |
+ * do NOT terminate an element.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* trim */
|
|
|
a856a8 |
+ while(lenStr > 0 && *p2parse == ' ') {
|
|
|
a856a8 |
+ ++p2parse; /* eat SP, but only if not at end of string */
|
|
|
a856a8 |
+ --lenStr;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ if(lenStr == 0 || *p2parse != '[')
|
|
|
a856a8 |
+ return 1; /* this is NOT structured data! */
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ if(*p2parse == '-') { /* empty structured data? */
|
|
|
a856a8 |
+ *pResult++ = '-';
|
|
|
a856a8 |
+ ++p2parse;
|
|
|
a856a8 |
+ --lenStr;
|
|
|
a856a8 |
+ } else {
|
|
|
a856a8 |
+ while(bCont) {
|
|
|
a856a8 |
+ if(lenStr < 2) {
|
|
|
a856a8 |
+ /* we now need to check if we have only structured data */
|
|
|
a856a8 |
+ if(lenStr > 0 && *p2parse == ']') {
|
|
|
a856a8 |
+ *pResult++ = *p2parse;
|
|
|
a856a8 |
+ p2parse++;
|
|
|
a856a8 |
+ lenStr--;
|
|
|
a856a8 |
+ bCont = 0;
|
|
|
a856a8 |
+ } else {
|
|
|
a856a8 |
+ iRet = 1; /* this is not valid! */
|
|
|
a856a8 |
+ bCont = 0;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ } else if(*p2parse == '\\' && *(p2parse+1) == ']') {
|
|
|
a856a8 |
+ /* this is escaped, need to copy both */
|
|
|
a856a8 |
+ *pResult++ = *p2parse++;
|
|
|
a856a8 |
+ *pResult++ = *p2parse++;
|
|
|
a856a8 |
+ lenStr -= 2;
|
|
|
a856a8 |
+ } else if(*p2parse == ']' && *(p2parse+1) == ' ') {
|
|
|
a856a8 |
+ /* found end, just need to copy the ] and eat the SP */
|
|
|
a856a8 |
+ *pResult++ = *p2parse;
|
|
|
a856a8 |
+ p2parse += 2;
|
|
|
a856a8 |
+ lenStr -= 2;
|
|
|
a856a8 |
+ bCont = 0;
|
|
|
a856a8 |
+ } else {
|
|
|
a856a8 |
+ *pResult++ = *p2parse++;
|
|
|
a856a8 |
+ --lenStr;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ if(lenStr > 0 && *p2parse == ' ') {
|
|
|
a856a8 |
+ ++p2parse; /* eat SP, but only if not at end of string */
|
|
|
a856a8 |
+ --lenStr;
|
|
|
a856a8 |
+ } else {
|
|
|
a856a8 |
+ iRet = 1; /* there MUST be an SP! */
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ *pResult = '\0';
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* set the new parse pointer */
|
|
|
a856a8 |
+ *pp2parse = p2parse;
|
|
|
a856a8 |
+ *pLenStr = lenStr;
|
|
|
a856a8 |
+ return 0;
|
|
|
a856a8 |
+}
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+/* parse a legay-formatted syslog message.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+BEGINparse
|
|
|
a856a8 |
+ uchar *p2parse;
|
|
|
a856a8 |
+ int lenMsg;
|
|
|
a856a8 |
+ int bTAGCharDetected;
|
|
|
a856a8 |
+ int i; /* general index for parsing */
|
|
|
a856a8 |
+ uchar bufParseTAG[CONF_TAG_MAXSIZE];
|
|
|
a856a8 |
+ uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE];
|
|
|
a856a8 |
+ uchar *pBuf = NULL;
|
|
|
a856a8 |
+CODESTARTparse
|
|
|
a856a8 |
+ dbgprintf("Message will now be parsed by the legacy syslog parser with structured-data support.\n");
|
|
|
a856a8 |
+ assert(pMsg != NULL);
|
|
|
a856a8 |
+ assert(pMsg->pszRawMsg != NULL);
|
|
|
a856a8 |
+ lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */
|
|
|
a856a8 |
+ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */
|
|
|
a856a8 |
+ setProtocolVersion(pMsg, MSG_LEGACY_PROTOCOL);
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* Check to see if msg contains a timestamp. We start by assuming
|
|
|
a856a8 |
+ * that the message timestamp is the time of reception (which we
|
|
|
a856a8 |
+ * generated ourselfs and then try to actually find one inside the
|
|
|
a856a8 |
+ * message. There we go from high-to low precison and are done
|
|
|
a856a8 |
+ * when we find a matching one. -- rgerhards, 2008-09-16
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) {
|
|
|
a856a8 |
+ /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */;
|
|
|
a856a8 |
+ } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg, NO_PARSE3164_TZSTRING, NO_PERMIT_YEAR_AFTER_TIME) == RS_RET_OK) {
|
|
|
a856a8 |
+ /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */;
|
|
|
a856a8 |
+ } else if(*p2parse == ' ' && lenMsg > 1) { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */
|
|
|
a856a8 |
+ ++p2parse; /* move over space */
|
|
|
a856a8 |
+ --lenMsg;
|
|
|
a856a8 |
+ if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg, NO_PARSE3164_TZSTRING, NO_PERMIT_YEAR_AFTER_TIME) == RS_RET_OK) {
|
|
|
a856a8 |
+ /* indeed, we got it! */
|
|
|
a856a8 |
+ /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */;
|
|
|
a856a8 |
+ } else {/* parse pointer needs to be restored, as we moved it off-by-one
|
|
|
a856a8 |
+ * for this try.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ --p2parse;
|
|
|
a856a8 |
+ ++lenMsg;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ if(pMsg->msgFlags & IGNDATE) {
|
|
|
a856a8 |
+ /* we need to ignore the msg data, so simply copy over reception date */
|
|
|
a856a8 |
+ memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime));
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we
|
|
|
a856a8 |
+ * do this only when the user has not forbidden this. I now introduce some
|
|
|
a856a8 |
+ * code that allows a user to configure rsyslogd to treat the rest of the
|
|
|
a856a8 |
+ * message as MSG part completely. In this case, the hostname will be the
|
|
|
a856a8 |
+ * machine that we received the message from and the tag will be empty. This
|
|
|
a856a8 |
+ * is meant to be an interim solution, but for now it is in the code.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ if(bParseHOSTNAMEandTAG && !(pMsg->msgFlags & INTERNAL_MSG)) {
|
|
|
a856a8 |
+ /* parse HOSTNAME - but only if this is network-received!
|
|
|
a856a8 |
+ * rger, 2005-11-14: we still have a problem with BSD messages. These messages
|
|
|
a856a8 |
+ * do NOT include a host name. In most cases, this leads to the TAG to be treated
|
|
|
a856a8 |
+ * as hostname and the first word of the message as the TAG. Clearly, this is not
|
|
|
a856a8 |
+ * of advantage ;) I think I have now found a way to handle this situation: there
|
|
|
a856a8 |
+ * are certain characters which are frequently used in TAG (e.g. ':'), which are
|
|
|
a856a8 |
+ * *invalid* in host names. So while parsing the hostname, I check for these characters.
|
|
|
a856a8 |
+ * If I find them, I set a simple flag but continue. After parsing, I check the flag.
|
|
|
a856a8 |
+ * If it was set, then we most probably do not have a hostname but a TAG. Thus, I change
|
|
|
a856a8 |
+ * the fields. I think this logic shall work with any type of syslog message.
|
|
|
a856a8 |
+ * rgerhards, 2009-06-23: and I now have extended this logic to every character
|
|
|
a856a8 |
+ * that is not a valid hostname.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ bTAGCharDetected = 0;
|
|
|
a856a8 |
+ if(lenMsg > 0 && pMsg->msgFlags & PARSE_HOSTNAME) {
|
|
|
a856a8 |
+ i = 0;
|
|
|
a856a8 |
+ while(i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '.'
|
|
|
a856a8 |
+ || p2parse[i] == '_' || p2parse[i] == '-') && i < (CONF_HOSTNAME_MAXSIZE - 1)) {
|
|
|
a856a8 |
+ bufParseHOSTNAME[i] = p2parse[i];
|
|
|
a856a8 |
+ ++i;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ if(i == lenMsg) {
|
|
|
a856a8 |
+ /* we have a message that is empty immediately after the hostname,
|
|
|
a856a8 |
+ * but the hostname thus is valid! -- rgerhards, 2010-02-22
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ p2parse += i;
|
|
|
a856a8 |
+ lenMsg -= i;
|
|
|
a856a8 |
+ bufParseHOSTNAME[i] = '\0';
|
|
|
a856a8 |
+ MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i);
|
|
|
a856a8 |
+ } else if(i > 0 && p2parse[i] == ' ' && isalnum(p2parse[i-1])) {
|
|
|
a856a8 |
+ /* we got a hostname! */
|
|
|
a856a8 |
+ p2parse += i + 1; /* "eat" it (including SP delimiter) */
|
|
|
a856a8 |
+ lenMsg -= i + 1;
|
|
|
a856a8 |
+ bufParseHOSTNAME[i] = '\0';
|
|
|
a856a8 |
+ MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i);
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* now parse TAG - that should be present in message from all sources.
|
|
|
a856a8 |
+ * This code is somewhat not compliant with RFC 3164. As of 3164,
|
|
|
a856a8 |
+ * the TAG field is ended by any non-alphanumeric character. In
|
|
|
a856a8 |
+ * practice, however, the TAG often contains dashes and other things,
|
|
|
a856a8 |
+ * which would end the TAG. So it is not desirable. As such, we only
|
|
|
a856a8 |
+ * accept colon and SP to be terminators. Even there is a slight difference:
|
|
|
a856a8 |
+ * a colon is PART of the TAG, while a SP is NOT part of the tag
|
|
|
a856a8 |
+ * (it is CONTENT). Starting 2008-04-04, we have removed the 32 character
|
|
|
a856a8 |
+ * size limit (from RFC3164) on the tag. This had bad effects on existing
|
|
|
a856a8 |
+ * envrionments, as sysklogd didn't obey it either (probably another bug
|
|
|
a856a8 |
+ * in RFC3164...). We now receive the full size, but will modify the
|
|
|
a856a8 |
+ * outputs so that only 32 characters max are used by default.
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ i = 0;
|
|
|
a856a8 |
+ while(lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE) {
|
|
|
a856a8 |
+ bufParseTAG[i++] = *p2parse++;
|
|
|
a856a8 |
+ --lenMsg;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ if(lenMsg > 0 && *p2parse == ':') {
|
|
|
a856a8 |
+ ++p2parse;
|
|
|
a856a8 |
+ --lenMsg;
|
|
|
a856a8 |
+ bufParseTAG[i++] = ':';
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* no TAG can only be detected if the message immediatly ends, in which case an empty TAG
|
|
|
a856a8 |
+ * is considered OK. So we do not need to check for empty TAG. -- rgerhards, 2009-06-23
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ bufParseTAG[i] = '\0'; /* terminate string */
|
|
|
a856a8 |
+ MsgSetTAG(pMsg, bufParseTAG, i);
|
|
|
a856a8 |
+ } else {/* we enter this code area when the user has instructed rsyslog NOT
|
|
|
a856a8 |
+ * to parse HOSTNAME and TAG - rgerhards, 2006-03-13
|
|
|
a856a8 |
+ */
|
|
|
a856a8 |
+ if(!(pMsg->msgFlags & INTERNAL_MSG)) {
|
|
|
a856a8 |
+ DBGPRINTF("HOSTNAME and TAG not parsed by user configuraton.\n");
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ CHKmalloc(pBuf = MALLOC(sizeof(uchar) * (lenMsg + 1)));
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* STRUCTURED-DATA */
|
|
|
a856a8 |
+ if (parseRFCStructuredData(&p2parse, pBuf, &lenMsg) == 0)
|
|
|
a856a8 |
+ MsgSetStructuredData(pMsg, (char*)pBuf);
|
|
|
a856a8 |
+ else
|
|
|
a856a8 |
+ MsgSetStructuredData(pMsg, "-");
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ /* The rest is the actual MSG */
|
|
|
a856a8 |
+ MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg);
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+finalize_it:
|
|
|
a856a8 |
+ if(pBuf != NULL)
|
|
|
a856a8 |
+ free(pBuf);
|
|
|
a856a8 |
+ENDparse
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+BEGINmodExit
|
|
|
a856a8 |
+CODESTARTmodExit
|
|
|
a856a8 |
+ /* release what we no longer need */
|
|
|
a856a8 |
+ objRelease(errmsg, CORE_COMPONENT);
|
|
|
a856a8 |
+ objRelease(glbl, CORE_COMPONENT);
|
|
|
a856a8 |
+ objRelease(parser, CORE_COMPONENT);
|
|
|
a856a8 |
+ objRelease(datetime, CORE_COMPONENT);
|
|
|
a856a8 |
+ENDmodExit
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+BEGINqueryEtryPt
|
|
|
a856a8 |
+CODESTARTqueryEtryPt
|
|
|
a856a8 |
+CODEqueryEtryPt_STD_PMOD_QUERIES
|
|
|
a856a8 |
+CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
|
|
|
a856a8 |
+ENDqueryEtryPt
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+BEGINmodInit()
|
|
|
a856a8 |
+CODESTARTmodInit
|
|
|
a856a8 |
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
|
|
|
a856a8 |
+CODEmodInit_QueryRegCFSLineHdlr
|
|
|
a856a8 |
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
|
|
|
a856a8 |
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
|
|
|
a856a8 |
+ CHKiRet(objUse(parser, CORE_COMPONENT));
|
|
|
a856a8 |
+ CHKiRet(objUse(datetime, CORE_COMPONENT));
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ dbgprintf("rfc3164sd parser init called\n");
|
|
|
a856a8 |
+ bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(); /* cache value, is set only during rsyslogd option processing */
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+ENDmodInit
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+/* vim:set ai:
|
|
|
a856a8 |
+ */
|