--- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -19,6 +19,8 @@ #include "dnsmasq.h" +#include + struct daemon *daemon; static volatile pid_t pid = 0; @@ -32,6 +34,64 @@ static void fatal_event(struct event_des static int read_event(int fd, struct event_desc *evp, char **msg); static void poll_resolv(int force, int do_reload, time_t now); +static struct ubus_context *ubus; +static struct blob_buf b; + +static struct ubus_object_type ubus_object_type = { + .name = "dnsmasq", +}; + +static struct ubus_object ubus_object = { + .name = "dnsmasq", + .type = &ubus_object_type, +}; + +void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface) +{ + if (!ubus || !ubus_object.has_subscribers) + return; + + blob_buf_init(&b, 0); + if (mac) + blobmsg_add_string(&b, "mac", mac); + if (ip) + blobmsg_add_string(&b, "ip", ip); + if (name) + blobmsg_add_string(&b, "name", name); + if (interface) + blobmsg_add_string(&b, "interface", interface); + ubus_notify(ubus, &ubus_object, type, b.head, -1); +} + +static void set_ubus_listeners(void) +{ + if (!ubus) + return; + + poll_listen(ubus->sock.fd, POLLIN); + poll_listen(ubus->sock.fd, POLLERR); + poll_listen(ubus->sock.fd, POLLHUP); +} + +static void check_ubus_listeners() +{ + if (!ubus) { + ubus = ubus_connect(NULL); + if (ubus) + ubus_add_object(ubus, &ubus_object); + else + return; + } + + if (poll_check(ubus->sock.fd, POLLIN)) + ubus_handle_event(ubus); + + if (poll_check(ubus->sock.fd, POLLHUP)) { + ubus_free(ubus); + ubus = NULL; + } +} + int main (int argc, char **argv) { int bind_fallback = 0; @@ -911,6 +969,7 @@ int main (int argc, char **argv) set_dbus_listeners(); #endif + set_ubus_listeners(); #ifdef HAVE_DHCP if (daemon->dhcp || daemon->relay4) { @@ -1041,6 +1100,8 @@ int main (int argc, char **argv) check_dbus_listeners(); #endif + check_ubus_listeners(); + check_dns_listeners(now); #ifdef HAVE_TFTP --- a/Makefile +++ b/Makefile @@ -85,7 +85,7 @@ all : $(BUILDDIR) @cd $(BUILDDIR) && $(MAKE) \ top="$(top)" \ build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \ - build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \ + build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) -lubox -lubus" \ -f $(top)/Makefile dnsmasq mostly_clean : --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -1397,6 +1397,8 @@ void emit_dbus_signal(int action, struct # endif #endif +void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface); + /* ipset.c */ #ifdef HAVE_IPSET void ipset_init(void); --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -1621,6 +1621,10 @@ static void log_packet(char *type, void daemon->namebuff, string ? string : "", err ? err : ""); + if (!strcmp(type, "DHCPACK")) + ubus_event_bcast("dhcp.ack", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface); + else if (!strcmp(type, "DHCPRELEASE")) + ubus_event_bcast("dhcp.release", daemon->namebuff, addr ? inet_ntoa(a) : NULL, string ? string : NULL, interface); } static void log_options(unsigned char *start, u32 xid)