diff options
Diffstat (limited to 'src/ubus.c')
-rw-r--r-- | src/ubus.c | 57 |
1 files changed, 57 insertions, 0 deletions
@@ -360,6 +360,63 @@ void ubus_bcast_dhcp_event(const char *type, const uint8_t *mac, ubus_notify(ubus, &main_object, type, b.head, -1); } +void ubus_bcast_dhcpv6_event(const char *type, const struct dhcp_assignment *a, const struct odhcpd_ipaddr *addrs, ssize_t addr_len) +{ + char buf[INET6_ADDRSTRLEN] = ""; + + if (!ubus || !main_object.has_subscribers || !type || !a || !addrs || !addr_len) + return; + + blob_buf_init(&b, 0); + + if (a->hostname) + blobmsg_add_string(&b, "name", a->hostname); + + blobmsg_add_string(&b, "type", a->flags & OAF_DHCPV6_NA ? "IA_NA" : "IA_PD"); + + if (a->iaid) + blobmsg_add_u32(&b, "iaid", ntohl(a->iaid)); + + if (a->iface->ifname) + blobmsg_add_string(&b, "interface", a->iface->ifname); + + if (a->clid_data && a->clid_len) { + char *duid = blobmsg_alloc_string_buffer(&b, "duid", a->clid_len * 2 + 1); + odhcpd_hexlify(duid, a->clid_data, a->clid_len); + blobmsg_add_string_buffer(&b); + } + + char *peer = blobmsg_alloc_string_buffer(&b, "peer", INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, &a->peer.sin6_addr, peer, INET6_ADDRSTRLEN); + blobmsg_add_string_buffer(&b); + + void *i = blobmsg_open_array(&b, "ips"); + for (int j=0; j < addr_len; j++) { + const size_t IP_SIZE = sizeof(buf) + 4; + struct in6_addr prefix = addrs[j].addr.in6; + + if (!(a->flags & OAF_DHCPV6_PD)) { + prefix.s6_addr32[2] = htonl(a->assigned_host_id >> 32); + prefix.s6_addr32[3] = htonl(a->assigned_host_id & UINT32_MAX); + } else { + prefix.s6_addr32[1] |= htonl(a->assigned_subnet_id); + prefix.s6_addr32[2] = prefix.s6_addr32[3] = 0; + } + + void *k = blobmsg_open_table(&b, NULL); + + char *ip = blobmsg_alloc_string_buffer(&b, "ip", IP_SIZE); + inet_ntop(AF_INET6, &prefix, buf, INET6_ADDRSTRLEN); + snprintf(ip, IP_SIZE, "%s/%d", buf, a->length); + blobmsg_add_string_buffer(&b); + + blobmsg_close_table(&b, k); + } + blobmsg_close_array(&b, i); + + ubus_notify(ubus, &main_object, type, b.head, -1); +} + static void handle_event(_unused struct ubus_context *ctx, _unused struct ubus_event_handler *ev, _unused const char *type, struct blob_attr *msg) { |