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"
24 static struct lua_State *lua_instance;
26 static int l_mask(lua_State *L)
30 if (lua_gettop(L) != 2) {
31 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
33 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
34 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
36 val = lua_tonumber(L, -1);
37 mask = lua_tonumber(L, -2);
39 lua_pushinteger(L, val & mask);
44 static int l_server_content(lua_State *L)
48 if (lua_gettop(L) != 2) {
49 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
51 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
52 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
54 len = lua_tonumber(L, -1);
55 beg = lua_tonumber(L, -2);
57 lua_createtable(L, 0, 3);
59 lua_pushinteger(L, beg);
60 lua_setfield(L, -2, "beg");
61 lua_pushinteger(L, len);
62 lua_setfield(L, -2, "len");
63 lua_pushinteger(L, 0);
64 lua_setfield(L, -2, "peer");
69 static int l_client_content(lua_State *L)
73 if (lua_gettop(L) != 2) {
74 return luaL_error(L, "Expecting 2 argument and got %d\n", lua_gettop(L));
76 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2)) {
77 return luaL_error(L, "Expecting (integer, integer) as arguments\n");
79 len = lua_tonumber(L, -1);
80 beg = lua_tonumber(L, -2);
82 lua_createtable(L, 0, 3);
84 lua_pushinteger(L, beg);
85 lua_setfield(L, -2, "beg");
86 lua_pushinteger(L, len);
87 lua_setfield(L, -2, "len");
88 lua_pushinteger(L, 1);
89 lua_setfield(L, -2, "peer");
94 static int l_bin_read(lua_State *L)
96 const char *file_name = lua_tostring(L, -1);
97 int beg = lua_tonumber(L, -2);
98 int len = lua_gettop(L) == 3? lua_tonumber(L, -3) : -1;
100 if (lua_gettop(L) == 2) {
101 if (!lua_isnumber(L, -1) || !lua_isstring(L, -2)) {
102 return luaL_error(L, "Expecting (string, integer) as arguments\n");
105 file_name = lua_tostring(L, -2);
106 beg = lua_tonumber(L, -1);
109 else if (lua_gettop(L) == 3) {
110 if (!lua_isnumber(L, -1) || !lua_isnumber(L, -2) || !lua_isstring(L, 3)) {
111 return luaL_error(L, "Expecting (string, integer, integer) as arguments\n");
114 file_name = lua_tostring(L, -3);
115 beg = lua_tonumber(L, -2);
116 len = lua_tonumber(L, -1);
119 return luaL_error(L, "Expecting 2 or 3 arguments\n");
121 lua_createtable(L, 0, 3);
123 lua_pushstring(L, file_name);
124 lua_setfield(L, -2, "file_name");
125 lua_pushinteger(L, beg);
126 lua_setfield(L, -2, "beg");
127 lua_pushinteger(L, len);
128 lua_setfield(L, -2, "len");
133 static int l_mac(lua_State *L)
137 if (lua_isstring(L, -1)) {
138 const char *arg = lua_tostring(L, -1);
140 strncpy(arg2, arg, sizeof(arg2));
145 while ((p = strchr(p, ':'))) {
151 return luaL_error(L, "Invalid MAC format\n");
153 lua_createtable(L, 6, 0);
154 for (size_t i = 0; i < 6; ++i) {
155 char *n = strchr(p, ':');
158 if (strlen(p) != 2) {
159 return luaL_error(L, "Invalid MAC format\n");
162 lua_pushinteger(L, strtol(p, NULL, 16));
163 lua_rawseti(L, -2, i + 1);
169 return luaL_error(L, "Invalid argument\n");
172 static int l_ip(lua_State *L)
175 if (lua_isnumber(L, -1)) {
176 uint32_t arg = lua_tointeger(L, -1);
178 ip[0] = arg >> 24 & 0xff;
179 ip[1] = arg >> 16 & 0xff;
180 ip[2] = arg >> 8 & 0xff;
181 ip[3] = arg >> 0 & 0xff;
183 lua_createtable(L, 4, 0);
184 for (size_t i = 0; i < 4; ++i) {
185 lua_pushinteger(L, ip[i]);
186 lua_rawseti(L, -2, i + 1);
191 if (lua_isstring(L, -1)) {
192 const char *arg = lua_tostring(L, -1);
194 if (sscanf(arg, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4) {
195 return luaL_error(L, "Invalid IP address format\n");
198 lua_createtable(L, 4, 0);
199 for (size_t i = 0; i < 4; ++i) {
200 lua_pushinteger(L, ip[i]);
201 lua_rawseti(L, -2, i + 1);
207 return luaL_error(L, "Invalid argument\n");
210 static int l_ip6(lua_State *L)
214 if (!lua_isstring(L, -1)) {
215 return luaL_error(L, "Invalid argument type\n");
218 const char *arg = lua_tostring(L, -1);
222 size_t str_len = strlen(arg);
226 strncpy(arg2, arg, sizeof(arg2));
228 for (size_t i = 0; i < str_len; ++i) {
231 return luaL_error(L, "IPv6 address can't be longer than 16 bytes\n");
232 addr_parts[n_parts++] = &arg2[i];
236 if (arg2[i] == ':') {
244 for (int i = 0, j = 0; i < n_parts; ++i) {
245 if (*addr_parts[i] == 0) {
247 return luaL_error(L, "Can omit zeros only once\n");
253 uint16_t w = strtoll(addr_parts[i], NULL, 16);
254 ip[j++] = (w >> 8) & 0xff;
259 lua_createtable(L, 16, 0);
260 for (size_t i = 0; i < 16; ++i) {
261 lua_pushinteger(L, ip[i]);
262 lua_rawseti(L, -2, i + 1);
268 static int l_cidr(lua_State *L)
270 const char *arg = lua_tostring(L, -1);
273 strncpy(tmp, arg, sizeof(tmp));
275 char *slash = strchr(tmp, '/');
279 lua_createtable(L, 0, 2);
280 lua_pushstring(L, "ip");
282 lua_pushstring(L, tmp);
288 lua_pushstring(L, "depth");
289 lua_pushinteger(L, atoi(slash));
294 static int l_cidr6(lua_State *L)
296 const char *arg = lua_tostring(L, -1);
299 strncpy(tmp, arg, sizeof(tmp));
301 char *slash = strchr(tmp, '/');
305 lua_createtable(L, 0, 2);
306 lua_pushstring(L, "ip6");
308 lua_pushstring(L, tmp);
314 lua_pushstring(L, "depth");
315 lua_pushinteger(L, atoi(slash));
320 static int l_val_mask(lua_State *L)
322 if (!lua_isinteger(L, -2))
323 return luaL_error(L, "Argument 1 is not an integer\n");
324 if (!lua_isinteger(L, -1))
325 return luaL_error(L, "Argument 2 is not an integer\n");
327 uint32_t val = lua_tointeger(L, -2);
328 uint32_t mask = lua_tointeger(L, -1);
330 lua_createtable(L, 0, 2);
331 lua_pushstring(L, "val");
332 lua_pushinteger(L, val);
335 lua_pushstring(L, "mask");
336 lua_pushinteger(L, mask);
342 static int l_val_range(lua_State *L)
344 if (!lua_isinteger(L, -2))
345 return luaL_error(L, "Argument 1 is not an integer\n");
346 if (!lua_isinteger(L, -1))
347 return luaL_error(L, "Argument 2 is not an integer\n");
349 uint32_t beg = lua_tointeger(L, -2);
350 uint32_t end = lua_tointeger(L, -1);
352 lua_createtable(L, 0, 2);
353 lua_pushstring(L, "beg");
354 lua_pushinteger(L, beg);
357 lua_pushstring(L, "end");
358 lua_pushinteger(L, end);
364 static int l_task_count(lua_State *L)
366 struct core_task_set cts;
369 if (!lua_isstring(L, -1))
370 return luaL_error(L, "Argument 1 is not an string\n");
371 str = lua_tostring(L, -1);
372 if (parse_task_set(&cts, str))
373 return luaL_error(L, "Invalid core task set syntax\n");
374 lua_pushinteger(L, cts.n_elems);
378 struct lua_State *prox_lua(void)
381 lua_instance = luaL_newstate();
383 luaL_openlibs(lua_instance);
385 lua_pushcfunction(lua_instance, l_ip);
386 lua_setglobal(lua_instance, "ip");
387 lua_pushcfunction(lua_instance, l_ip6);
388 lua_setglobal(lua_instance, "ip6");
389 lua_pushcfunction(lua_instance, l_cidr);
390 lua_setglobal(lua_instance, "cidr");
391 lua_pushcfunction(lua_instance, l_cidr6);
392 lua_setglobal(lua_instance, "cidr6");
393 lua_pushcfunction(lua_instance, l_mac);
394 lua_setglobal(lua_instance, "mac");
395 lua_pushcfunction(lua_instance, l_mask);
396 lua_setglobal(lua_instance, "mask");
397 lua_pushcfunction(lua_instance, l_val_mask);
398 lua_setglobal(lua_instance, "val_mask");
399 lua_pushcfunction(lua_instance, l_val_range);
400 lua_setglobal(lua_instance, "val_range");
401 lua_pushcfunction(lua_instance, l_bin_read);
402 lua_setglobal(lua_instance, "bin_read");
403 lua_pushcfunction(lua_instance, l_client_content);
404 lua_setglobal(lua_instance, "client_content");
405 lua_pushcfunction(lua_instance, l_server_content);
406 lua_setglobal(lua_instance, "server_content");
407 lua_pushcfunction(lua_instance, l_task_count);
408 lua_setglobal(lua_instance, "task_count");