Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

liblognorm fixes and updates #276

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,11 @@ generate such messages (note the flags part)::

Aug 18 13:18:45 192.168.0.1 %ASA-6-106015: Deny TCP (no connection) from 10.252.88.66/443 to 10.79.249.222/52746 flags RST on interface outside

option.failOnDuplicate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If set to "True", causes parsers to fail if the name already exists
in the tree. A no-op unless using .. to cause a merger

cee-syslog
##########
This parses cee syslog from the message. This format has been defined
Expand Down
111 changes: 73 additions & 38 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ hParseInt(const unsigned char **buf, size_t *lenBuf)
* @param[in] npb->strLen length of the to-be-parsed string
* @param[in] offs an offset into the string
* @param[in] pointer to parser data block
* @param[in] pointer to current parser's name
* @param[out] parsed bytes
* @param[out] value ptr to json object containing parsed data
* (can be unused, but if used *value MUST be NULL on entry)
Expand All @@ -99,6 +100,7 @@ int ln_v2_parse##ParserName( \
npb_t *const npb, \
size_t *const offs, \
__attribute__((unused)) void *const pdata, \
__attribute__((unused)) const char *parser_name, \
size_t *parsed, \
struct json_object **value) \
{ \
Expand Down Expand Up @@ -1623,7 +1625,9 @@ PARSER_Parse(OpQuotedString)
/* create JSON value to save quoted string contents */
CHKN(cstr = strndup((char*)c + *offs + 1, *parsed - 2));
}
CHKN(*value = json_object_new_string(cstr));
if (value != NULL) {
CHKN(*value = json_object_new_string(cstr));
}

r = 0; /* success */
done:
Expand Down Expand Up @@ -1763,7 +1767,7 @@ PARSER_Parse(CiscoInterfaceSpec)
int bHaveIP = 0;
size_t lenIP;
size_t idxIP = i;
if(ln_v2_parseIPv4(npb, &i, NULL, &lenIP, NULL) == 0) {
if(ln_v2_parseIPv4(npb, &i, NULL, parser_name, &lenIP, NULL) == 0) {
bHaveIP = 1;
i += lenIP - 1; /* position on delimiter */
} else {
Expand All @@ -1783,14 +1787,14 @@ PARSER_Parse(CiscoInterfaceSpec)
/* we now utilize our other parser helpers */
if(!bHaveIP) {
idxIP = i;
if(ln_v2_parseIPv4(npb, &i, NULL, &lenIP, NULL) != 0) goto done;
if(ln_v2_parseIPv4(npb, &i, NULL, parser_name, &lenIP, NULL) != 0) goto done;
i += lenIP;
}
if(i == npb->strLen || c[i] != '/') goto done;
++i; /* skip slash */
const size_t idxPort = i;
size_t lenPort;
if(ln_v2_parseNumber(npb, &i, NULL, &lenPort, NULL) != 0) goto done;
if(ln_v2_parseNumber(npb, &i, NULL, parser_name, &lenPort, NULL) != 0) goto done;
i += lenPort;
if(i == npb->strLen) goto success;

Expand All @@ -1803,12 +1807,12 @@ PARSER_Parse(CiscoInterfaceSpec)
if(i+5 < npb->strLen && c[i] == ' ' && c[i+1] == '(') {
size_t iTmp = i+2; /* skip over " (" */
idxIP2 = iTmp;
if(ln_v2_parseIPv4(npb, &iTmp, NULL, &lenIP2, NULL) == 0) {
if(ln_v2_parseIPv4(npb, &iTmp, NULL, parser_name, &lenIP2, NULL) == 0) {
iTmp += lenIP2;
if(i < npb->strLen || c[iTmp] == '/') {
++iTmp; /* skip slash */
idxPort2 = iTmp;
if(ln_v2_parseNumber(npb, &iTmp, NULL, &lenPort2, NULL) == 0) {
if(ln_v2_parseNumber(npb, &iTmp, NULL, parser_name, &lenPort2, NULL) == 0) {
iTmp += lenPort2;
if(iTmp < npb->strLen && c[iTmp] == ')') {
i = iTmp + 1; /* match, so use new index */
Expand Down Expand Up @@ -2141,11 +2145,14 @@ PARSER_Parse(IPv6)
if(skipIPv6AddrBlock(npb, &i) != 0) goto done;
nBlocks++;
if(i == npb->strLen) goto chk_ok;
if(isspace(c[i])) goto chk_ok;
/* no more valid chars, check address */
if(c[i] != ':' && c[i] != '.') goto chk_ok;
if(c[i] == '.'){ /* IPv4 processing! */
hasIPv4 = 1;
break;
}
/* maximum blocks consumed and not ipv4, check if valid */
if (nBlocks == 8) goto chk_ok;
if(c[i] != ':') goto done;
i++; /* "eat" ':' */
if(i == npb->strLen) goto chk_ok;
Expand All @@ -2167,7 +2174,7 @@ PARSER_Parse(IPv6)
/* prevent pure IPv4 address to be recognized */
if(beginBlock == *offs) goto done;
i = beginBlock;
if(ln_v2_parseIPv4(npb, &i, NULL, &ipv4_parsed, NULL) != 0)
if(ln_v2_parseIPv4(npb, &i, NULL, parser_name, &ipv4_parsed, NULL) != 0)
goto done;
i += ipv4_parsed;
}
Expand Down Expand Up @@ -3003,61 +3010,77 @@ PARSER_Parse(Repeat)
struct data_Repeat *const data = (struct data_Repeat*) pdata;
struct ln_pdag *endNode = NULL;
size_t strtoffs = *offs;
size_t lastMatch = strtoffs;
size_t lastKnownGood = strtoffs;
struct json_object *json_arr = NULL;
struct json_object *parsed_value = NULL;
const size_t parsedTo_save = npb->parsedTo;
const size_t longestParsedTo_save = npb->longestParsedTo;
int mergeResults = parser_name != NULL && parser_name[0] == '.' && parser_name[1] == '\0';

do {
struct json_object *parsed_value = json_object_new_object();
if(parsed_value == NULL) {
parsed_value = json_object_new_object();
}
r = ln_normalizeRec(npb, data->parser, strtoffs, 1,
parsed_value, &endNode);
parsed_value, &endNode, data->failOnDuplicate, NULL, parser_name);
strtoffs = npb->parsedTo;
LN_DBGPRINTF(npb->ctx, "repeat parser returns %d, parsed %zu, json: %s",
r, npb->parsedTo, json_object_to_json_string(parsed_value));

if(r != 0) {
json_object_put(parsed_value);
parsed_value = NULL;
if(data->permitMismatchInParser) {
strtoffs = lastKnownGood; /* go back to final match */
LN_DBGPRINTF(npb->ctx, "mismatch in repeat, "
"parse ptr back to %zd", strtoffs);
goto success;
} else {
// Reset longest match
npb->longestParsedTo = lastMatch > longestParsedTo_save ? lastMatch : longestParsedTo_save;
goto done;
}
}

if(json_arr == NULL) {
json_arr = json_object_new_array();
}
if (!mergeResults) {
if(json_arr == NULL) {
json_arr = json_object_new_array();
}

/* check for name=".", which means we need to place the
* value only into to array. As we do not have direct
* access to the key, we loop over our result as a work-
* around.
*/
struct json_object *toAdd = parsed_value;
struct json_object_iterator it = json_object_iter_begin(parsed_value);
struct json_object_iterator itEnd = json_object_iter_end(parsed_value);
while (!json_object_iter_equal(&it, &itEnd)) {
const char *key = json_object_iter_peek_name(&it);
struct json_object *const val = json_object_iter_peek_value(&it);
if(key[0] == '.' && key[1] == '\0') {
json_object_get(val); /* inc refcount! */
toAdd = val;
/* check for name=".", which means we need to place the
* value only into to array. As we do not have direct
* access to the key, we loop over our result as a work-
* around.
*/
struct json_object *toAdd = parsed_value;
struct json_object_iterator it = json_object_iter_begin(parsed_value);
struct json_object_iterator itEnd = json_object_iter_end(parsed_value);
while (!json_object_iter_equal(&it, &itEnd)) {
const char *key = json_object_iter_peek_name(&it);
struct json_object *const val = json_object_iter_peek_value(&it);
if(key[0] == '.' && key[1] == '\0') {
json_object_get(val); /* inc refcount! */
toAdd = val;
}
json_object_iter_next(&it);
}
json_object_iter_next(&it);
}

json_object_array_add(json_arr, toAdd);
if(toAdd != parsed_value)
json_object_put(parsed_value);
LN_DBGPRINTF(npb->ctx, "arr: %s", json_object_to_json_string(json_arr));
json_object_array_add(json_arr, toAdd);

if(toAdd != parsed_value)
json_object_put(parsed_value);
LN_DBGPRINTF(npb->ctx, "arr: %s", json_object_to_json_string(json_arr));

// If we are an array, we need to get a new value and we don't want to free at end
parsed_value = NULL;
}

/* now check if we shall continue */
npb->parsedTo = 0;
lastMatch = lastKnownGood;
lastKnownGood = strtoffs; /* record pos in case of fail in while */
r = ln_normalizeRec(npb, data->while_cond, strtoffs, 1, NULL, &endNode);
r = ln_normalizeRec(npb, data->while_cond, strtoffs, 1, NULL, &endNode, 0, NULL, parser_name);
LN_DBGPRINTF(npb->ctx, "repeat while returns %d, parsed %zu",
r, npb->parsedTo);
if(r == 0)
Expand All @@ -3068,15 +3091,25 @@ PARSER_Parse(Repeat)
/* success, persist */
*parsed = strtoffs - *offs;
if(value == NULL) {
json_object_put(json_arr);
if (json_arr != NULL) {
json_object_put(json_arr);
}
if (parsed_value != NULL) {
json_object_put(parsed_value);
}
} else {
*value = json_arr;
*value = !mergeResults ? json_arr : parsed_value;
}
npb->parsedTo = parsedTo_save;
r = 0; /* success */
done:
if(r != 0 && json_arr != NULL) {
json_object_put(json_arr);
if(r != 0) {
if (json_arr != NULL) {
json_object_put(json_arr);
}
if (parsed_value != NULL) {
json_object_put(parsed_value);
}
}
return r;
}
Expand Down Expand Up @@ -3110,6 +3143,8 @@ PARSER_Construct(Repeat)
endnode->flags.isTerminal = 1;
} else if(!strcasecmp(key, "option.permitMismatchInParser")) {
data->permitMismatchInParser = json_object_get_boolean(val);
} else if(!strcasecmp(key, "option.failOnDuplicate")) {
data->failOnDuplicate = json_object_get_boolean(val);
} else {
ln_errprintf(ctx, 0, "invalid param for hexnumber: %s",
json_object_to_json_string(val));
Expand Down
7 changes: 5 additions & 2 deletions src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@
// TODO #warning check how to handle "value" - does it need to be set to NULL?

#define PARSERDEF_NO_DATA(parser) \
int ln_v2_parse##parser(npb_t *npb, size_t *offs, void *const, size_t *parsed, struct json_object **value)
int ln_v2_parse##parser(npb_t *npb, size_t *offs, void *const, const char *parser_name, \
size_t *parsed, struct json_object **value)

#define PARSERDEF(parser) \
int ln_construct##parser(ln_ctx ctx, json_object *const json, void **pdata); \
int ln_v2_parse##parser(npb_t *npb, size_t *offs, void *const, size_t *parsed, struct json_object **value); \
int ln_v2_parse##parser(npb_t *npb, size_t *offs, void *const, const char *parser_name, \
size_t *parsed, struct json_object **value); \
void ln_destruct##parser(ln_ctx ctx, void *const pdata)

PARSERDEF(RFC5424Date);
Expand Down Expand Up @@ -89,6 +91,7 @@ struct data_Repeat {
ln_pdag *parser;
ln_pdag *while_cond;
int permitMismatchInParser;
int failOnDuplicate;
};

#endif /* #ifndef LIBLOGNORM_PARSER_H_INCLUDED */
Loading