diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/luci-lib-jsonc/src/jsonc.c | 9 | ||||
-rw-r--r-- | libs/rpcd-mod-luci/Makefile | 2 | ||||
-rw-r--r-- | libs/rpcd-mod-luci/src/luci.c | 158 |
3 files changed, 134 insertions, 35 deletions
diff --git a/libs/luci-lib-jsonc/src/jsonc.c b/libs/luci-lib-jsonc/src/jsonc.c index 9ff8520dbc..2f56a4a688 100644 --- a/libs/luci-lib-jsonc/src/jsonc.c +++ b/libs/luci-lib-jsonc/src/jsonc.c @@ -17,6 +17,7 @@ limitations under the License. #define _GNU_SOURCE #include <math.h> +#include <stdint.h> #include <stdbool.h> #include <json-c/json.h> @@ -145,6 +146,7 @@ static int json_parse_chunk(lua_State *L) static void _json_to_lua(lua_State *L, struct json_object *obj) { + int64_t v; int n; switch (json_object_get_type(obj)) @@ -172,7 +174,12 @@ static void _json_to_lua(lua_State *L, struct json_object *obj) break; case json_type_int: - lua_pushinteger(L, json_object_get_int(obj)); + v = json_object_get_int64(obj); + if (sizeof(lua_Integer) > sizeof(int32_t) || + (v >= INT32_MIN && v <= INT32_MAX)) + lua_pushinteger(L, (lua_Integer)v); + else + lua_pushnumber(L, (lua_Number)v); break; case json_type_double: diff --git a/libs/rpcd-mod-luci/Makefile b/libs/rpcd-mod-luci/Makefile index 51e311e7f3..63b6faac73 100644 --- a/libs/rpcd-mod-luci/Makefile +++ b/libs/rpcd-mod-luci/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=rpcd-mod-luci -PKG_VERSION:=20191103 +PKG_VERSION:=20191114 PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io> PKG_LICENSE:=Apache-2.0 diff --git a/libs/rpcd-mod-luci/src/luci.c b/libs/rpcd-mod-luci/src/luci.c index 12a22c8891..5dc436164d 100644 --- a/libs/rpcd-mod-luci/src/luci.c +++ b/libs/rpcd-mod-luci/src/luci.c @@ -321,16 +321,16 @@ static struct { } lease_state = { }; struct lease_entry { - int af; + int af, n_addr; char buf[512]; int32_t expire; struct ether_addr mac; + char *hostname; + char *duid; union { struct in_addr in; struct in6_addr in6; - } addr; - char *hostname; - char *duid; + } addr[10]; }; static char * @@ -420,6 +420,7 @@ lease_next(void) static struct lease_entry e; struct ether_addr *ea; char *p; + int n; memset(&e, 0, sizeof(e)); @@ -430,8 +431,14 @@ lease_next(void) if (!p) continue; - e.expire = strtol(p, NULL, 10); - e.expire = (e.expire >= 0) ? e.expire - lease_state.now : 0; + n = strtol(p, NULL, 10); + + if (n > lease_state.now) + e.expire = n - lease_state.now; + else if (n > 0) + e.expire = 0; + else + e.expire = -1; p = strtok(NULL, " \t\n"); @@ -442,12 +449,17 @@ lease_next(void) p = strtok(NULL, " \t\n"); - if (p && inet_pton(AF_INET6, p, &e.addr.in6)) + if (p && inet_pton(AF_INET6, p, &e.addr[0].in6)) { e.af = AF_INET6; - else if (p && inet_pton(AF_INET, p, &e.addr.in)) + e.n_addr = 1; + } + else if (p && inet_pton(AF_INET, p, &e.addr[0].in)) { e.af = AF_INET; - else + e.n_addr = 1; + } + else { continue; + } if (!ea && e.af != AF_INET6) continue; @@ -504,16 +516,24 @@ lease_next(void) if (!p) continue; - e.expire = strtol(p, NULL, 10); - e.expire = (e.expire > 0) ? e.expire - lease_state.now : e.expire; + n = strtol(p, NULL, 10); + + if (n > lease_state.now) + e.expire = n - lease_state.now; + else if (n >= 0) + e.expire = 0; + else + e.expire = -1; strtok(NULL, " \t\n"); /* id */ strtok(NULL, " \t\n"); /* length */ - p = strtok(NULL, "/ \t\n"); /* ip */ - - if (!p || !inet_pton(e.af, p, &e.addr.in6)) - continue; + for (e.n_addr = 0, p = strtok(NULL, "/ \t\n"); + e.n_addr < ARRAY_SIZE(e.addr) && p != NULL; + p = strtok(NULL, "/ \t\n")) { + if (inet_pton(e.af, p, &e.addr[e.n_addr].in6)) + e.n_addr++; + } ea = duid2ea(e.duid); @@ -1327,11 +1347,11 @@ rpc_luci_get_host_hints_uci(struct reply_context *rctx) if (!hint) continue; - if (lease->af == AF_INET && hint->ip.s_addr == 0) - hint->ip = lease->addr.in; - else if (lease->af == AF_INET6 && + if (lease->af == AF_INET && lease->n_addr && hint->ip.s_addr == 0) + hint->ip = lease->addr[0].in; + else if (lease->af == AF_INET6 && lease->n_addr && !memcmp(&hint->ip6, &empty, sizeof(empty))) - hint->ip6 = lease->addr.in6; + hint->ip6 = lease->addr[0].in6; if (lease->hostname && !hint->hostname) hint->hostname = strdup(lease->hostname); @@ -1403,7 +1423,7 @@ rpc_luci_get_host_hints_ifaddrs(struct reply_context *rctx) freeifaddrs(ifaddr); - avl_for_each_element_safe(&devices, device, avl, nextdevice) { + avl_remove_all_elements(&devices, device, avl, nextdevice) { if (memcmp(&device->ea, &empty_ea, sizeof(empty_ea)) && (memcmp(&device->in6, &empty_in6, sizeof(empty_in6)) || device->in.s_addr != 0)) { @@ -1419,7 +1439,6 @@ rpc_luci_get_host_hints_ifaddrs(struct reply_context *rctx) } } - avl_delete(&devices, &device->avl); free(device); } } @@ -1524,7 +1543,7 @@ rpc_luci_get_host_hints_finish(struct reply_context *rctx) struct in_addr in = {}; void *o; - avl_for_each_element_safe(&rctx->avl, hint, avl, nexthint) { + avl_remove_all_elements(&rctx->avl, hint, avl, nexthint) { o = blobmsg_open_table(&rctx->blob, hint->avl.key); if (memcmp(&hint->ip, &in, sizeof(in))) { @@ -1542,8 +1561,6 @@ rpc_luci_get_host_hints_finish(struct reply_context *rctx) blobmsg_close_table(&rctx->blob, o); - avl_delete(&rctx->avl, &hint->avl); - if (hint->hostname) free(hint->hostname); @@ -1573,6 +1590,75 @@ rpc_luci_get_host_hints(struct ubus_context *ctx, struct ubus_object *obj, } static int +rpc_luci_get_duid_hints(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct { struct avl_node avl; } *e, *next; + char s[INET6_ADDRSTRLEN], *p; + struct ether_addr empty = {}; + struct lease_entry *lease; + struct avl_tree avl; + void *o, *a; + int n; + + avl_init(&avl, avl_strcmp, false, NULL); + blob_buf_init(&blob, 0); + + lease_open(); + + while ((lease = lease_next()) != NULL) { + if (lease->af != AF_INET6 || lease->duid == NULL) + continue; + + e = avl_find_element(&avl, lease->duid, e, avl); + + if (e) + continue; + + e = calloc_a(sizeof(*e), &p, strlen(lease->duid) + 1); + + if (!e) + continue; + + o = blobmsg_open_table(&blob, lease->duid); + + inet_ntop(AF_INET6, &lease->addr[0].in6, s, sizeof(s)); + blobmsg_add_string(&blob, "ip6addr", s); + + a = blobmsg_open_array(&blob, "ip6addrs"); + + for (n = 0; n < lease->n_addr; n++) { + inet_ntop(AF_INET6, &lease->addr[n].in6, s, sizeof(s)); + blobmsg_add_string(&blob, NULL, s); + } + + blobmsg_close_array(&blob, a); + + if (lease->hostname) + blobmsg_add_string(&blob, "hostname", lease->hostname); + + if (memcmp(&lease->mac, &empty, sizeof(empty))) + blobmsg_add_string(&blob, "macaddr", ea2str(&lease->mac)); + + blobmsg_close_table(&blob, o); + + e->avl.key = strcpy(p, lease->duid); + avl_insert(&avl, &e->avl); + } + + lease_close(); + + avl_remove_all_elements(&avl, e, avl, next) { + free(e); + } + + ubus_send_reply(ctx, req, blob.head); + + return UBUS_STATUS_OK; +} + +static int rpc_luci_get_board_json(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) @@ -1658,9 +1744,9 @@ rpc_luci_get_dhcp_leases(struct ubus_context *ctx, struct ubus_object *obj, struct ether_addr emptymac = {}; struct lease_entry *lease; char s[INET6_ADDRSTRLEN]; - struct uci_context *uci; int af, family = 0; - void *a, *o; + void *a, *a2, *o; + int n; blobmsg_parse(rpc_get_leases_policy, __RPC_L_MAX, tb, blob_data(msg), blob_len(msg)); @@ -1682,11 +1768,6 @@ rpc_luci_get_dhcp_leases(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_INVALID_ARGUMENT; } - uci = uci_alloc_context(); - - if (!uci) - return UBUS_STATUS_UNKNOWN_ERROR; - blob_buf_init(&blob, 0); for (af = family ? family : AF_INET; @@ -1718,10 +1799,21 @@ rpc_luci_get_dhcp_leases(struct ubus_context *ctx, struct ubus_object *obj, if (lease->duid) blobmsg_add_string(&blob, "duid", lease->duid); - inet_ntop(lease->af, &lease->addr.in6, s, sizeof(s)); + inet_ntop(lease->af, &lease->addr[0].in6, s, sizeof(s)); blobmsg_add_string(&blob, (af == AF_INET) ? "ipaddr" : "ip6addr", s); + if (af == AF_INET6) { + a2 = blobmsg_open_array(&blob, "ip6addrs"); + + for (n = 0; n < lease->n_addr; n++) { + inet_ntop(lease->af, &lease->addr[n].in6, s, sizeof(s)); + blobmsg_add_string(&blob, NULL, s); + } + + blobmsg_close_array(&blob, a2); + } + blobmsg_close_table(&blob, o); } @@ -1730,7 +1822,6 @@ rpc_luci_get_dhcp_leases(struct ubus_context *ctx, struct ubus_object *obj, blobmsg_close_array(&blob, a); } - uci_free_context(uci); ubus_send_reply(ctx, req, blob.head); return UBUS_STATUS_OK; @@ -1743,6 +1834,7 @@ rpc_luci_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx) UBUS_METHOD_NOARG("getNetworkDevices", rpc_luci_get_network_devices), UBUS_METHOD_NOARG("getWirelessDevices", rpc_luci_get_wireless_devices), UBUS_METHOD_NOARG("getHostHints", rpc_luci_get_host_hints), + UBUS_METHOD_NOARG("getDUIDHints", rpc_luci_get_duid_hints), UBUS_METHOD_NOARG("getBoardJSON", rpc_luci_get_board_json), UBUS_METHOD_NOARG("getDSLStatus", rpc_luci_get_dsl_status), UBUS_METHOD("getDHCPLeases", rpc_luci_get_dhcp_leases, rpc_get_leases_policy) |