2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
21 #include "lua_compat.h"
22 #include "parse_utils.h"
23 #include "prox_compat.h"
25 static struct lua_State *lua_instance;
27 static int l_mask(lua_State *L)
31 if (lua_gettop(L) != 2) {
32 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
34 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
35 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
37 val = lua_tonumber(L, -1);
38 mask = lua_tonumber(L, -2);
40 lua_pushinteger(L, val & mask);
45 static int l_server_content(lua_State *L)
49 if (lua_gettop(L) != 2) {
50 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
52 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
53 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
55 len = lua_tonumber(L, -1);
56 beg = lua_tonumber(L, -2);
58 lua_createtable(L, 0, 3);
60 lua_pushinteger(L, beg);
61 lua_setfield(L, -2, "beg");
62 lua_pushinteger(L, len);
63 lua_setfield(L, -2, "len");
64 lua_pushinteger(L, 0);
65 lua_setfield(L, -2, "peer");
70 static int l_client_content(lua_State *L)
74 if (lua_gettop(L) != 2) {
75 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
77 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
78 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
80 len = lua_tonumber(L, -1);
81 beg = lua_tonumber(L, -2);
83 lua_createtable(L, 0, 3);
85 lua_pushinteger(L, beg);
86 lua_setfield(L, -2, "beg");
87 lua_pushinteger(L, len);
88 lua_setfield(L, -2, "len");
89 lua_pushinteger(L, 1);
90 lua_setfield(L, -2, "peer");
95 static int l_bin_read(lua_State *L)
97 const char *file_name = lua_tostring(L, -1);
98 int beg = lua_tonumber(L, -2);
99 int len = lua_gettop(L) == 3? lua_tonumber(L, -3) : -1;
101 if (lua_gettop(L) == 2) {
102 if (!lua_isnumber(L, -1) || !lua_isstring(L, -2)) {
103 return luaL_error(L, "Expecting (string, integer) as arguments\n");
106 file_name = lua_tostring(L, -2);
107 beg = lua_tonumber(L, -1);
110 else if (lua_gettop(L) == 3) {
111 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2) || !lua_isstring(L, 3)) {
112 return luaL_error(L, "Expecting (string, integer, integer) as arguments\n");
115 file_name = lua_tostring(L, -3);
116 beg = lua_tonumber(L, -2);
117 len = lua_tonumber(L, -1);
120 return luaL_error(L, "Expecting 2 or 3 arguments\n");
122 lua_createtable(L, 0, 3);
124 lua_pushstring(L, file_name);
125 lua_setfield(L, -2, "file_name");
126 lua_pushinteger(L, beg);
127 lua_setfield(L, -2, "beg");
128 lua_pushinteger(L, len);
129 lua_setfield(L, -2, "len");
134 static int l_mac(lua_State *L)
138 if (lua_isstring(L, -1)) {
139 const char *arg = lua_tostring(L, -1);
141 prox_strncpy(arg2, arg, sizeof(arg2));
146 while ((p = strchr(p, ':'))) {
152 return luaL_error(L, "Invalid MAC format\n");
154 lua_createtable(L, 6, 0);
155 for (size_t i = 0; i < 6; ++i) {
156 char *n = strchr(p, ':');
159 if (strlen(p) != 2) {
160 return luaL_error(L, "Invalid MAC format\n");
163 lua_pushinteger(L, strtol(p, NULL, 16));
164 lua_rawseti(L, -2, i + 1);
170 return luaL_error(L, "Invalid argument\n");
173 static int l_ip(lua_State *L)
176 if (lua_isnumber(L, -1)) {
177 uint32_t arg = lua_tointeger(L, -1);
179 ip[0] = arg >> 24 & 0xff;
180 ip[1] = arg >> 16 & 0xff;
181 ip[2] = arg >> 8 & 0xff;
182 ip[3] = arg >> 0 & 0xff;
184 lua_createtable(L, 4, 0);
185 for (size_t i = 0; i < 4; ++i) {
186 lua_pushinteger(L, ip[i]);
187 lua_rawseti(L, -2, i + 1);
192 if (lua_isstring(L, -1)) {
193 const char *arg = lua_tostring(L, -1);
195 if (sscanf(arg, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4) {
196 return luaL_error(L, "Invalid IP address format\n");
199 lua_createtable(L, 4, 0);
200 for (size_t i = 0; i < 4; ++i) {
201 lua_pushinteger(L, ip[i]);
202 lua_rawseti(L, -2, i + 1);
208 return luaL_error(L, "Invalid argument\n");
211 static int l_ip6(lua_State *L)
215 if (!lua_isstring(L, -1)) {
216 return luaL_error(L, "Invalid argument type\n");
219 const char *arg = lua_tostring(L, -1);
223 size_t str_len = strlen(arg);
227 prox_strncpy(arg2, arg, sizeof(arg2));
229 for (size_t i = 0; i < str_len; ++i) {
232 return luaL_error(L, "IPv6 address can't be longer than 16 bytes\n");
233 addr_parts[n_parts++] = &arg2[i];
237 if (arg2[i] == ':') {
245 for (int i = 0, j = 0; i < n_parts; ++i) {
246 if (*addr_parts[i] == 0) {
248 return luaL_error(L, "Can omit zeros only once\n");
254 uint16_t w = strtoll(addr_parts[i], NULL, 16);
255 ip[j++] = (w >> 8) & 0xff;
260 lua_createtable(L, 16, 0);
261 for (size_t i = 0; i < 16; ++i) {
262 lua_pushinteger(L, ip[i]);
263 lua_rawseti(L, -2, i + 1);
269 static int l_cidr(lua_State *L)
271 const char *arg = lua_tostring(L, -1);
274 prox_strncpy(tmp, arg, sizeof(tmp));
276 char *slash = strchr(tmp, '/');
280 lua_createtable(L, 0, 2);
281 lua_pushstring(L, "ip");
283 lua_pushstring(L, tmp);
289 lua_pushstring(L, "depth");
290 lua_pushinteger(L, atoi(slash));
295 static int l_cidr6(lua_State *L)
297 const char *arg = lua_tostring(L, -1);
300 prox_strncpy(tmp, arg, sizeof(tmp));
302 char *slash = strchr(tmp, '/');
306 lua_createtable(L, 0, 2);
307 lua_pushstring(L, "ip6");
309 lua_pushstring(L, tmp);
315 lua_pushstring(L, "depth");
316 lua_pushinteger(L, atoi(slash));
321 static int l_val_mask(lua_State *L)
323 if (!lua_isinteger(L, -2))
324 return luaL_error(L, "Argument 1 is not an integer\n");
325 if (!lua_isinteger(L, -1))
326 return luaL_error(L, "Argument 2 is not an integer\n");
328 uint32_t val = lua_tointeger(L, -2);
329 uint32_t mask = lua_tointeger(L, -1);
331 lua_createtable(L, 0, 2);
332 lua_pushstring(L, "val");
333 lua_pushinteger(L, val);
336 lua_pushstring(L, "mask");
337 lua_pushinteger(L, mask);
343 static int l_val_range(lua_State *L)
345 if (!lua_isinteger(L, -2))
346 return luaL_error(L, "Argument 1 is not an integer\n");
347 if (!lua_isinteger(L, -1))
348 return luaL_error(L, "Argument 2 is not an integer\n");
350 uint32_t beg = lua_tointeger(L, -2);
351 uint32_t end = lua_tointeger(L, -1);
353 lua_createtable(L, 0, 2);
354 lua_pushstring(L, "beg");
355 lua_pushinteger(L, beg);
358 lua_pushstring(L, "end");
359 lua_pushinteger(L, end);
365 static int l_task_count(lua_State *L)
367 struct core_task_set cts;
370 if (!lua_isstring(L, -1))
371 return luaL_error(L, "Argument 1 is not an string\n");
372 str = lua_tostring(L, -1);
373 if (parse_task_set(&cts, str))
374 return luaL_error(L, "Invalid core task set syntax\n");
375 lua_pushinteger(L, cts.n_elems);
379 struct lua_State *prox_lua(void)
382 lua_instance = luaL_newstate();
384 luaL_openlibs(lua_instance);
386 lua_pushcfunction(lua_instance, l_ip);
387 lua_setglobal(lua_instance, "ip");
388 lua_pushcfunction(lua_instance, l_ip6);
389 lua_setglobal(lua_instance, "ip6");
390 lua_pushcfunction(lua_instance, l_cidr);
391 lua_setglobal(lua_instance, "cidr");
392 lua_pushcfunction(lua_instance, l_cidr6);
393 lua_setglobal(lua_instance, "cidr6");
394 lua_pushcfunction(lua_instance, l_mac);
395 lua_setglobal(lua_instance, "mac");
396 lua_pushcfunction(lua_instance, l_mask);
397 lua_setglobal(lua_instance, "mask");
398 lua_pushcfunction(lua_instance, l_val_mask);
399 lua_setglobal(lua_instance, "val_mask");
400 lua_pushcfunction(lua_instance, l_val_range);
401 lua_setglobal(lua_instance, "val_range");
402 lua_pushcfunction(lua_instance, l_bin_read);
403 lua_setglobal(lua_instance, "bin_read");
404 lua_pushcfunction(lua_instance, l_client_content);
405 lua_setglobal(lua_instance, "client_content");
406 lua_pushcfunction(lua_instance, l_server_content);
407 lua_setglobal(lua_instance, "server_content");
408 lua_pushcfunction(lua_instance, l_task_count);
409 lua_setglobal(lua_instance, "task_count");