summaryrefslogtreecommitdiffstats
path: root/VNFs/DPPD-PROX/prox_lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'VNFs/DPPD-PROX/prox_lua.c')
-rw-r--r--VNFs/DPPD-PROX/prox_lua.c411
1 files changed, 411 insertions, 0 deletions
diff --git a/VNFs/DPPD-PROX/prox_lua.c b/VNFs/DPPD-PROX/prox_lua.c
new file mode 100644
index 00000000..b5c2fec9
--- /dev/null
+++ b/VNFs/DPPD-PROX/prox_lua.c
@@ -0,0 +1,411 @@
+/*
+// Copyright (c) 2010-2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "prox_lua.h"
+#include "lua_compat.h"
+#include "parse_utils.h"
+
+static struct lua_State *lua_instance;
+
+static int l_mask(lua_State *L)
+{
+ uint32_t val, mask;
+
+ if (lua_gettop(L) != 2) {
+ return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
+ }
+ if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
+ return luaL_error(L, "Expecting (integer, integer) as arguments\n");
+ }
+ val = lua_tonumber(L, -1);
+ mask = lua_tonumber(L, -2);
+
+ lua_pushinteger(L, val & mask);
+
+ return 1;
+}
+
+static int l_server_content(lua_State *L)
+{
+ uint32_t beg, len;
+
+ if (lua_gettop(L) != 2) {
+ return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
+ }
+ if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
+ return luaL_error(L, "Expecting (integer, integer) as arguments\n");
+ }
+ len = lua_tonumber(L, -1);
+ beg = lua_tonumber(L, -2);
+
+ lua_createtable(L, 0, 3);
+
+ lua_pushinteger(L, beg);
+ lua_setfield(L, -2, "beg");
+ lua_pushinteger(L, len);
+ lua_setfield(L, -2, "len");
+ lua_pushinteger(L, 0);
+ lua_setfield(L, -2, "peer");
+
+ return 1;
+}
+
+static int l_client_content(lua_State *L)
+{
+ uint32_t beg, len;
+
+ if (lua_gettop(L) != 2) {
+ return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
+ }
+ if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
+ return luaL_error(L, "Expecting (integer, integer) as arguments\n");
+ }
+ len = lua_tonumber(L, -1);
+ beg = lua_tonumber(L, -2);
+
+ lua_createtable(L, 0, 3);
+
+ lua_pushinteger(L, beg);
+ lua_setfield(L, -2, "beg");
+ lua_pushinteger(L, len);
+ lua_setfield(L, -2, "len");
+ lua_pushinteger(L, 1);
+ lua_setfield(L, -2, "peer");
+
+ return 1;
+}
+
+static int l_bin_read(lua_State *L)
+{
+ const char *file_name = lua_tostring(L, -1);
+ int beg = lua_tonumber(L, -2);
+ int len = lua_gettop(L) == 3? lua_tonumber(L, -3) : -1;
+
+ if (lua_gettop(L) == 2) {
+ if (!lua_isnumber(L, -1) || !lua_isstring(L, -2)) {
+ return luaL_error(L, "Expecting (string, integer) as arguments\n");
+ }
+
+ file_name = lua_tostring(L, -2);
+ beg = lua_tonumber(L, -1);
+ len = -1;
+ }
+ else if (lua_gettop(L) == 3) {
+ if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2) || !lua_isstring(L, 3)) {
+ return luaL_error(L, "Expecting (string, integer, integer) as arguments\n");
+ }
+
+ file_name = lua_tostring(L, -3);
+ beg = lua_tonumber(L, -2);
+ len = lua_tonumber(L, -1);
+ }
+ else
+ return luaL_error(L, "Expecting 2 or 3 arguments\n");
+
+ lua_createtable(L, 0, 3);
+
+ lua_pushstring(L, file_name);
+ lua_setfield(L, -2, "file_name");
+ lua_pushinteger(L, beg);
+ lua_setfield(L, -2, "beg");
+ lua_pushinteger(L, len);
+ lua_setfield(L, -2, "len");
+
+ return 1;
+}
+
+static int l_mac(lua_State *L)
+{
+ int mac[6];
+
+ if (lua_isstring(L, -1)) {
+ const char *arg = lua_tostring(L, -1);
+ char arg2[128];
+ strncpy(arg2, arg, sizeof(arg2));
+
+ char *p = arg2;
+ int count = 0;
+
+ while ((p = strchr(p, ':'))) {
+ count++;
+ p++;
+ }
+ p = arg2;
+ if (count != 5)
+ return luaL_error(L, "Invalid MAC format\n");
+
+ lua_createtable(L, 6, 0);
+ for (size_t i = 0; i < 6; ++i) {
+ char *n = strchr(p, ':');
+ if (n)
+ *n = 0;
+ if (strlen(p) != 2) {
+ return luaL_error(L, "Invalid MAC format\n");
+ }
+
+ lua_pushinteger(L, strtol(p, NULL, 16));
+ lua_rawseti(L, -2, i + 1);
+ p = n + 1;
+ }
+ return 1;
+ }
+
+ return luaL_error(L, "Invalid argument\n");
+}
+
+static int l_ip(lua_State *L)
+{
+ int ip[4];
+ if (lua_isnumber(L, -1)) {
+ uint32_t arg = lua_tointeger(L, -1);
+
+ ip[0] = arg >> 24 & 0xff;
+ ip[1] = arg >> 16 & 0xff;
+ ip[2] = arg >> 8 & 0xff;
+ ip[3] = arg >> 0 & 0xff;
+
+ lua_createtable(L, 4, 0);
+ for (size_t i = 0; i < 4; ++i) {
+ lua_pushinteger(L, ip[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ return 1;
+ }
+ if (lua_isstring(L, -1)) {
+ const char *arg = lua_tostring(L, -1);
+
+ if (sscanf(arg, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4) {
+ return luaL_error(L, "Invalid IP address format\n");
+ }
+
+ lua_createtable(L, 4, 0);
+ for (size_t i = 0; i < 4; ++i) {
+ lua_pushinteger(L, ip[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ return 1;
+ }
+
+ return luaL_error(L, "Invalid argument\n");
+}
+
+static int l_ip6(lua_State *L)
+{
+ int ip[16];
+
+ if (!lua_isstring(L, -1)) {
+ return luaL_error(L, "Invalid argument type\n");
+ }
+
+ const char *arg = lua_tostring(L, -1);
+ char arg2[64];
+ char *addr_parts[8];
+ int n_parts = 0;
+ size_t str_len = strlen(arg);
+ int next_str = 1;
+ int ret;
+
+ strncpy(arg2, arg, sizeof(arg2));
+
+ for (size_t i = 0; i < str_len; ++i) {
+ if (next_str) {
+ if (n_parts == 8)
+ return luaL_error(L, "IPv6 address can't be longer than 16 bytes\n");
+ addr_parts[n_parts++] = &arg2[i];
+ next_str = 0;
+
+ }
+ if (arg2[i] == ':') {
+ arg2[i] = 0;
+ next_str = 1;
+ }
+ }
+
+ int omitted = 0;
+
+ for (int i = 0, j = 0; i < n_parts; ++i) {
+ if (*addr_parts[i] == 0) {
+ if (omitted == 0) {
+ return luaL_error(L, "Can omit zeros only once\n");
+ }
+ omitted = 1;
+ j += 8 - n_parts;
+ }
+ else {
+ uint16_t w = strtoll(addr_parts[i], NULL, 16);
+ ip[j++] = (w >> 8) & 0xff;
+ ip[j++] = w & 0xff;
+ }
+ }
+
+ lua_createtable(L, 16, 0);
+ for (size_t i = 0; i < 16; ++i) {
+ lua_pushinteger(L, ip[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ return 1;
+}
+
+static int l_cidr(lua_State *L)
+{
+ const char *arg = lua_tostring(L, -1);
+
+ char tmp[128];
+ strncpy(tmp, arg, sizeof(tmp));
+
+ char *slash = strchr(tmp, '/');
+ *slash = 0;
+ slash++;
+
+ lua_createtable(L, 0, 2);
+ lua_pushstring(L, "ip");
+
+ lua_pushstring(L, tmp);
+ l_ip(L);
+ lua_remove(L, -2);
+
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "depth");
+ lua_pushinteger(L, atoi(slash));
+ lua_settable(L, -3);
+ return 1;
+}
+
+static int l_cidr6(lua_State *L)
+{
+ const char *arg = lua_tostring(L, -1);
+
+ char tmp[128];
+ strncpy(tmp, arg, sizeof(tmp));
+
+ char *slash = strchr(tmp, '/');
+ *slash = 0;
+ slash++;
+
+ lua_createtable(L, 0, 2);
+ lua_pushstring(L, "ip6");
+
+ lua_pushstring(L, tmp);
+ l_ip6(L);
+ lua_remove(L, -2);
+
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "depth");
+ lua_pushinteger(L, atoi(slash));
+ lua_settable(L, -3);
+ return 1;
+}
+
+static int l_val_mask(lua_State *L)
+{
+ if (!lua_isinteger(L, -2))
+ return luaL_error(L, "Argument 1 is not an integer\n");
+ if (!lua_isinteger(L, -1))
+ return luaL_error(L, "Argument 2 is not an integer\n");
+
+ uint32_t val = lua_tointeger(L, -2);
+ uint32_t mask = lua_tointeger(L, -1);
+
+ lua_createtable(L, 0, 2);
+ lua_pushstring(L, "val");
+ lua_pushinteger(L, val);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "mask");
+ lua_pushinteger(L, mask);
+ lua_settable(L, -3);
+
+ return 1;
+}
+
+static int l_val_range(lua_State *L)
+{
+ if (!lua_isinteger(L, -2))
+ return luaL_error(L, "Argument 1 is not an integer\n");
+ if (!lua_isinteger(L, -1))
+ return luaL_error(L, "Argument 2 is not an integer\n");
+
+ uint32_t beg = lua_tointeger(L, -2);
+ uint32_t end = lua_tointeger(L, -1);
+
+ lua_createtable(L, 0, 2);
+ lua_pushstring(L, "beg");
+ lua_pushinteger(L, beg);
+ lua_settable(L, -3);
+
+ lua_pushstring(L, "end");
+ lua_pushinteger(L, end);
+ lua_settable(L, -3);
+
+ return 1;
+}
+
+static int l_task_count(lua_State *L)
+{
+ struct core_task_set cts;
+ const char *str;
+
+ if (!lua_isstring(L, -1))
+ return luaL_error(L, "Argument 1 is not an string\n");
+ str = lua_tostring(L, -1);
+ if (parse_task_set(&cts, str))
+ return luaL_error(L, "Invalid core task set syntax\n");
+ lua_pushinteger(L, cts.n_elems);
+ return 1;
+}
+
+struct lua_State *prox_lua(void)
+{
+ if (!lua_instance) {
+ lua_instance = luaL_newstate();
+
+ luaL_openlibs(lua_instance);
+
+ lua_pushcfunction(lua_instance, l_ip);
+ lua_setglobal(lua_instance, "ip");
+ lua_pushcfunction(lua_instance, l_ip6);
+ lua_setglobal(lua_instance, "ip6");
+ lua_pushcfunction(lua_instance, l_cidr);
+ lua_setglobal(lua_instance, "cidr");
+ lua_pushcfunction(lua_instance, l_cidr6);
+ lua_setglobal(lua_instance, "cidr6");
+ lua_pushcfunction(lua_instance, l_mac);
+ lua_setglobal(lua_instance, "mac");
+ lua_pushcfunction(lua_instance, l_mask);
+ lua_setglobal(lua_instance, "mask");
+ lua_pushcfunction(lua_instance, l_val_mask);
+ lua_setglobal(lua_instance, "val_mask");
+ lua_pushcfunction(lua_instance, l_val_range);
+ lua_setglobal(lua_instance, "val_range");
+ lua_pushcfunction(lua_instance, l_bin_read);
+ lua_setglobal(lua_instance, "bin_read");
+ lua_pushcfunction(lua_instance, l_client_content);
+ lua_setglobal(lua_instance, "client_content");
+ lua_pushcfunction(lua_instance, l_server_content);
+ lua_setglobal(lua_instance, "server_content");
+ lua_pushcfunction(lua_instance, l_task_count);
+ lua_setglobal(lua_instance, "task_count");
+ }
+ return lua_instance;
+}