summaryrefslogtreecommitdiffhomepage
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/luci-lib-jsonc/src/jsonc.c9
-rw-r--r--libs/rpcd-mod-luci/Makefile2
-rw-r--r--libs/rpcd-mod-luci/src/luci.c158
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)