|
|
a856a8 |
From d6f180ec175f3660e36478b9e32ec6ca73e33604 Mon Sep 17 00:00:00 2001
|
|
|
a856a8 |
From: Jan Gerhards <jgerhards@adiscon.com>
|
|
|
a856a8 |
Date: Fri, 10 Feb 2017 14:30:01 +0100
|
|
|
a856a8 |
Subject: [PATCH] add num2ipv4 function and test
|
|
|
a856a8 |
|
|
|
a856a8 |
closes https://github.com/rsyslog/rsyslog/issues/1322
|
|
|
a856a8 |
|
|
|
a856a8 |
testbench: add testcase empty string for num2ipv4 function
|
|
|
a856a8 |
|
|
|
a856a8 |
see https://github.com/rsyslog/rsyslog/issues/1412
|
|
|
a856a8 |
---
|
|
|
a856a8 |
grammar/rainerscript.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
a856a8 |
grammar/rainerscript.h | 4 +-
|
|
|
a856a8 |
tests/Makefile.am | 2 +
|
|
|
a856a8 |
tests/rscript_num2ipv4.sh | 41 +++++++++++++++++
|
|
|
a856a8 |
4 files changed, 161 insertions(+), 1 deletion(-)
|
|
|
a856a8 |
create mode 100755 tests/rscript_num2ipv4.sh
|
|
|
a856a8 |
|
|
|
a856a8 |
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
|
|
|
a856a8 |
index 30af5e7b..2f0fc2d8 100644
|
|
|
a856a8 |
--- a/grammar/rainerscript.c
|
|
|
a856a8 |
+++ b/grammar/rainerscript.c
|
|
|
a856a8 |
@@ -1710,6 +1710,113 @@ doRandomGen(struct svar *__restrict__ const sourceVal) {
|
|
|
a856a8 |
return x % max;
|
|
|
a856a8 |
}
|
|
|
a856a8 |
|
|
|
a856a8 |
+static long long
|
|
|
a856a8 |
+ipv42num(char *str)
|
|
|
a856a8 |
+{
|
|
|
a856a8 |
+ unsigned num[4] = {0, 0, 0, 0};
|
|
|
a856a8 |
+ long long value = -1;
|
|
|
a856a8 |
+ size_t len = strlen(str);
|
|
|
a856a8 |
+ int cyc = 0;
|
|
|
a856a8 |
+ int prevdot = 0;
|
|
|
a856a8 |
+ int startblank = 0;
|
|
|
a856a8 |
+ int endblank = 0;
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) arg: '%s'\n", str);
|
|
|
a856a8 |
+ for(unsigned int i = 0 ; i < len ; i++) {
|
|
|
a856a8 |
+ switch(str[i]){
|
|
|
a856a8 |
+ case '0':
|
|
|
a856a8 |
+ case '1':
|
|
|
a856a8 |
+ case '2':
|
|
|
a856a8 |
+ case '3':
|
|
|
a856a8 |
+ case '4':
|
|
|
a856a8 |
+ case '5':
|
|
|
a856a8 |
+ case '6':
|
|
|
a856a8 |
+ case '7':
|
|
|
a856a8 |
+ case '8':
|
|
|
a856a8 |
+ case '9':
|
|
|
a856a8 |
+ if(endblank == 1){
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (invalid space(1))\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ prevdot = 0;
|
|
|
a856a8 |
+ startblank = 0;
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) cycle: %d\n", cyc);
|
|
|
a856a8 |
+ num[cyc] = num[cyc]*10+(str[i]-'0');
|
|
|
a856a8 |
+ break;
|
|
|
a856a8 |
+ case ' ':
|
|
|
a856a8 |
+ prevdot = 0;
|
|
|
a856a8 |
+ if(i == 0 || startblank == 1){
|
|
|
a856a8 |
+ startblank = 1;
|
|
|
a856a8 |
+ break;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ else{
|
|
|
a856a8 |
+ endblank = 1;
|
|
|
a856a8 |
+ break;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ case '.':
|
|
|
a856a8 |
+ if(endblank == 1){
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (inalid space(2))\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ startblank = 0;
|
|
|
a856a8 |
+ if(prevdot == 1){
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (two dots after one another)\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ prevdot = 1;
|
|
|
a856a8 |
+ cyc++;
|
|
|
a856a8 |
+ if(cyc > 3){
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (too many dots)\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ break;
|
|
|
a856a8 |
+ default:
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (invalid charakter)\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ if(cyc != 3){
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num) error: wrong IP-Address format (wrong number of dots)\n");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ value = num[0]*256*256*256+num[1]*256*256+num[2]*256+num[3];
|
|
|
a856a8 |
+done:
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (ipv42num): return value:'%lld'\n",value);
|
|
|
a856a8 |
+ return(value);
|
|
|
a856a8 |
+}
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+static es_str_t*
|
|
|
a856a8 |
+num2ipv4(struct svar *__restrict__ const sourceVal) {
|
|
|
a856a8 |
+ int success = 0;
|
|
|
a856a8 |
+ int numip[4];
|
|
|
a856a8 |
+ char str[16];
|
|
|
a856a8 |
+ size_t len;
|
|
|
a856a8 |
+ es_str_t *estr;
|
|
|
a856a8 |
+ long long num = var2Number(sourceVal, &success);
|
|
|
a856a8 |
+ DBGPRINTF("rainrescript: (num2ipv4) var2Number output: '%lld\n'", num);
|
|
|
a856a8 |
+ if (! success) {
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (num2ipv4) couldn't access number\n");
|
|
|
a856a8 |
+ len = snprintf(str, 16, "-1");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ if(num < 0 || num > 4294967295) {
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (num2ipv4) invalid number(too big/negative); does not represent IPv4 address\n");
|
|
|
a856a8 |
+ len = snprintf(str, 16, "-1");
|
|
|
a856a8 |
+ goto done;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ for(int i = 0 ; i < 4 ; i++){
|
|
|
a856a8 |
+ numip[i] = num % 256;
|
|
|
a856a8 |
+ num = num / 256;
|
|
|
a856a8 |
+ }
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (num2ipv4) Numbers: 1:'%d' 2:'%d' 3:'%d' 4:'%d'\n", numip[0], numip[1], numip[2], numip[3]);
|
|
|
a856a8 |
+ len = snprintf(str, 16, "%d.%d.%d.%d", numip[3], numip[2], numip[1], numip[0]);
|
|
|
a856a8 |
+done:
|
|
|
a856a8 |
+ DBGPRINTF("rainerscript: (num2ipv4) ipv4-Address: %s, lengh: %zu\n", str, len);
|
|
|
a856a8 |
+ estr = es_newStrFromCStr(str, len);
|
|
|
a856a8 |
+ return(estr);
|
|
|
a856a8 |
+}
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
/* Perform a function call. This has been moved out of cnfExprEval in order
|
|
|
a856a8 |
* to keep the code small and easier to maintain.
|
|
|
a856a8 |
*/
|
|
|
a856a8 |
@@ -1775,6 +1882,12 @@ doFuncCall(struct cnffunc *__restrict__ const func, struct svar *__restrict__ co
|
|
|
a856a8 |
ret->datatype = 'N';
|
|
|
a856a8 |
varFreeMembers(&r[0]);
|
|
|
a856a8 |
break;
|
|
|
a856a8 |
+ case CNFFUNC_NUM2IPV4:
|
|
|
a856a8 |
+ cnfexprEval(func->expr[0], &r[0], usrptr);
|
|
|
a856a8 |
+ ret->d.estr = num2ipv4(&r[0]);
|
|
|
a856a8 |
+ ret->datatype = 'S';
|
|
|
a856a8 |
+ varFreeMembers(&r[0]);
|
|
|
a856a8 |
+ break;
|
|
|
a856a8 |
case CNFFUNC_GETENV:
|
|
|
a856a8 |
/* note: the optimizer shall have replaced calls to getenv()
|
|
|
a856a8 |
* with a constant argument to a single string (once obtained via
|
|
|
a856a8 |
@@ -3958,6 +4071,8 @@ funcName2ID(es_str_t *fname, unsigned short nParams)
|
|
|
a856a8 |
GENERATE_FUNC("strlen", 1, CNFFUNC_STRLEN);
|
|
|
a856a8 |
} else if(FUNC_NAME("getenv")) {
|
|
|
a856a8 |
GENERATE_FUNC("getenv", 1, CNFFUNC_GETENV);
|
|
|
a856a8 |
+ } else if(FUNC_NAME("num2ipv4")) {
|
|
|
a856a8 |
+ GENERATE_FUNC("num2ipv4", 1, CNFFUNC_NUM2IPV4);
|
|
|
a856a8 |
} else if(FUNC_NAME("tolower")) {
|
|
|
a856a8 |
GENERATE_FUNC("tolower", 1, CNFFUNC_TOLOWER);
|
|
|
a856a8 |
} else if(FUNC_NAME("cstr")) {
|
|
|
a856a8 |
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
|
|
|
a856a8 |
index 7bac7566..0fdbdc72 100644
|
|
|
a856a8 |
--- a/grammar/rainerscript.h
|
|
|
a856a8 |
+++ b/grammar/rainerscript.h
|
|
|
a856a8 |
@@ -232,7 +232,9 @@ enum cnffuncid {
|
|
|
a856a8 |
CNFFUNC_REPLACE,
|
|
|
a856a8 |
CNFFUNC_WRAP,
|
|
|
a856a8 |
CNFFUNC_RANDOM,
|
|
|
a856a8 |
- CNFFUNC_DYN_INC
|
|
|
a856a8 |
+ CNFFUNC_DYN_INC,
|
|
|
a856a8 |
+ CNFFUNC_IPV42NUM,
|
|
|
a856a8 |
+ CNFFUNC_NUM2IPV4
|
|
|
a856a8 |
};
|
|
|
a856a8 |
|
|
|
a856a8 |
struct cnffunc {
|
|
|
a856a8 |
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
|
|
a856a8 |
index f792b44a..572c6250 100644
|
|
|
a856a8 |
--- a/tests/Makefile.am
|
|
|
a856a8 |
+++ b/tests/Makefile.am
|
|
|
a856a8 |
@@ -206,6 +206,7 @@ TESTS += \
|
|
|
a856a8 |
rscript_lt_var.sh \
|
|
|
a856a8 |
rscript_ne.sh \
|
|
|
a856a8 |
rscript_ne_var.sh \
|
|
|
a856a8 |
+ rscript_num2ipv4.sh \
|
|
|
a856a8 |
empty-prop-comparison.sh \
|
|
|
a856a8 |
rs_optimizer_pri.sh \
|
|
|
a856a8 |
cee_simple.sh \
|
|
|
a856a8 |
@@ -728,6 +729,7 @@ EXTRA_DIST= \
|
|
|
a856a8 |
rscript_ne.sh \
|
|
|
a856a8 |
testsuites/rscript_ne.conf \
|
|
|
a856a8 |
rscript_ne_var.sh \
|
|
|
a856a8 |
+ rscript_num2ipv4.sh \
|
|
|
a856a8 |
testsuites/rscript_ne_var.conf \
|
|
|
a856a8 |
rscript_eq.sh \
|
|
|
a856a8 |
testsuites/rscript_eq.conf \
|
|
|
a856a8 |
diff --git a/tests/rscript_num2ipv4.sh b/tests/rscript_num2ipv4.sh
|
|
|
a856a8 |
new file mode 100755
|
|
|
a856a8 |
index 00000000..6e0026a9
|
|
|
a856a8 |
--- /dev/null
|
|
|
a856a8 |
+++ b/tests/rscript_num2ipv4.sh
|
|
|
a856a8 |
@@ -0,0 +1,41 @@
|
|
|
a856a8 |
+#!/bin/bash
|
|
|
a856a8 |
+# add 2017-02-09 by Jan Gerhards, released under ASL 2.0
|
|
|
a856a8 |
+. $srcdir/diag.sh init
|
|
|
a856a8 |
+. $srcdir/diag.sh generate-conf
|
|
|
a856a8 |
+. $srcdir/diag.sh add-conf '
|
|
|
a856a8 |
+module(load="../plugins/imtcp/.libs/imtcp")
|
|
|
a856a8 |
+input(type="imtcp" port="13514")
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+set $!ip!v1 = num2ipv4("0");
|
|
|
a856a8 |
+set $!ip!v2 = num2ipv4("1");
|
|
|
a856a8 |
+set $!ip!v3 = num2ipv4("256");
|
|
|
a856a8 |
+set $!ip!v4 = num2ipv4("65536");
|
|
|
a856a8 |
+set $!ip!v5 = num2ipv4("16777216");
|
|
|
a856a8 |
+set $!ip!v6 = num2ipv4("135");
|
|
|
a856a8 |
+set $!ip!v7 = num2ipv4("16843009");
|
|
|
a856a8 |
+set $!ip!v8 = num2ipv4("3777036554");
|
|
|
a856a8 |
+set $!ip!v9 = num2ipv4("2885681153");
|
|
|
a856a8 |
+set $!ip!v10 = num2ipv4("4294967295");
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+set $!ip!e1 = num2ipv4("a");
|
|
|
a856a8 |
+set $!ip!e2 = num2ipv4("-123");
|
|
|
a856a8 |
+set $!ip!e3 = num2ipv4("1725464567890");
|
|
|
a856a8 |
+set $!ip!e4 = num2ipv4("4294967296");
|
|
|
a856a8 |
+set $!ip!e5 = num2ipv4("2839.");
|
|
|
a856a8 |
+set $!ip!e6 = num2ipv4("");
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+
|
|
|
a856a8 |
+template(name="outfmt" type="string" string="%!ip%\n")
|
|
|
a856a8 |
+local4.* action(type="omfile" file="rsyslog.out.log" template="outfmt")
|
|
|
a856a8 |
+'
|
|
|
a856a8 |
+. $srcdir/diag.sh startup
|
|
|
a856a8 |
+. $srcdir/diag.sh tcpflood -m1 -y
|
|
|
a856a8 |
+. $srcdir/diag.sh shutdown-when-empty
|
|
|
a856a8 |
+. $srcdir/diag.sh wait-shutdown
|
|
|
a856a8 |
+echo '{ "v1": "0.0.0.0", "v2": "0.0.0.1", "v3": "0.0.1.0", "v4": "0.1.0.0", "v5": "1.0.0.0", "v6": "0.0.0.135", "v7": "1.1.1.1", "v8": "225.33.1.10", "v9": "172.0.0.1", "v10": "255.255.255.255", "e1": "-1", "e2": "-1", "e3": "-1", "e4": "-1", "e5": "-1", "e6": "-1" }' | cmp rsyslog.out.log
|
|
|
a856a8 |
+if [ ! $? -eq 0 ]; then
|
|
|
a856a8 |
+ echo "invalid function output detected, rsyslog.out.log is:"
|
|
|
a856a8 |
+ cat rsyslog.out.log
|
|
|
a856a8 |
+ . $srcdir/diag.sh error-exit 1
|
|
|
a856a8 |
+fi;
|
|
|
a856a8 |
+. $srcdir/diag.sh exit
|
|
|
a856a8 |
--
|
|
|
a856a8 |
2.12.2
|
|
|
a856a8 |
|