blob: 703a60dd23231b3c3fe8d3dab27578a827004afb [file] [log] [blame]
Simon Kelley8c1b6a52018-07-21 22:12:32 +01001/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include "dnsmasq.h"
18
19#ifdef HAVE_UBUS
20
21#include <libubus.h>
22
Simon Kelley1dfed162018-07-29 22:16:41 +010023static struct ubus_context *ubus = NULL;
Simon Kelley8c1b6a52018-07-21 22:12:32 +010024static struct blob_buf b;
25
26static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
Simon Kelley6f835ed2018-07-29 22:15:36 +010027 struct ubus_request_data *req, const char *method,
28 struct blob_attr *msg);
Simon Kelley8c1b6a52018-07-21 22:12:32 +010029static struct ubus_method ubus_object_methods[] = {
Simon Kelley6f835ed2018-07-29 22:15:36 +010030 {.name = "metrics", .handler = ubus_handle_metrics},
Simon Kelley8c1b6a52018-07-21 22:12:32 +010031};
32
33static struct ubus_object_type ubus_object_type = UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
34
35static struct ubus_object ubus_object = {
Simon Kelley6f835ed2018-07-29 22:15:36 +010036 .name = "dnsmasq",
37 .type = &ubus_object_type,
38 .methods = ubus_object_methods,
39 .n_methods = ARRAY_SIZE(ubus_object_methods),
Simon Kelley8c1b6a52018-07-21 22:12:32 +010040};
41
42void set_ubus_listeners()
43{
Simon Kelley6f835ed2018-07-29 22:15:36 +010044 if (!ubus)
45 return;
Simon Kelley8c1b6a52018-07-21 22:12:32 +010046
Simon Kelley6f835ed2018-07-29 22:15:36 +010047 poll_listen(ubus->sock.fd, POLLIN);
48 poll_listen(ubus->sock.fd, POLLERR);
49 poll_listen(ubus->sock.fd, POLLHUP);
Simon Kelley8c1b6a52018-07-21 22:12:32 +010050}
51
52void check_ubus_listeners()
53{
Simon Kelley6f835ed2018-07-29 22:15:36 +010054 if (!ubus)
55 {
56 ubus = ubus_connect(NULL);
57 if (!ubus)
58 return;
59 ubus_add_object(ubus, &ubus_object);
60 }
61
62 if (poll_check(ubus->sock.fd, POLLIN))
63 ubus_handle_event(ubus);
64
65 if (poll_check(ubus->sock.fd, POLLHUP))
66 {
67 ubus_free(ubus);
68 ubus = NULL;
69 }
Simon Kelley8c1b6a52018-07-21 22:12:32 +010070}
71
72
73static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
Simon Kelley6f835ed2018-07-29 22:15:36 +010074 struct ubus_request_data *req, const char *method,
75 struct blob_attr *msg)
Simon Kelley8c1b6a52018-07-21 22:12:32 +010076{
Simon Kelley1dfed162018-07-29 22:16:41 +010077 int i;
Simon Kelley6f835ed2018-07-29 22:15:36 +010078 blob_buf_init(&b, 0);
Simon Kelley8c1b6a52018-07-21 22:12:32 +010079
Simon Kelley1dfed162018-07-29 22:16:41 +010080 for(i=0; i < __METRIC_MAX; i++)
Simon Kelley6f835ed2018-07-29 22:15:36 +010081 blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
82
83 ubus_send_reply(ctx, req, b.head);
84
85 return 0;
Simon Kelley8c1b6a52018-07-21 22:12:32 +010086}
87
88void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
89{
Simon Kelley6f835ed2018-07-29 22:15:36 +010090 if (!ubus || !ubus_object.has_subscribers)
91 return;
Simon Kelley8c1b6a52018-07-21 22:12:32 +010092
Simon Kelley6f835ed2018-07-29 22:15:36 +010093 blob_buf_init(&b, 0);
94 if (mac)
95 blobmsg_add_string(&b, "mac", mac);
96 if (ip)
97 blobmsg_add_string(&b, "ip", ip);
98 if (name)
99 blobmsg_add_string(&b, "name", name);
100 if (interface)
101 blobmsg_add_string(&b, "interface", interface);
102
103 ubus_notify(ubus, &ubus_object, type, b.head, -1);
Simon Kelley8c1b6a52018-07-21 22:12:32 +0100104}
105
106
107#endif /* HAVE_UBUS */