From 8c1b6a5fd7bd23fe8391eb774e419c30e8cc4b8a Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sat, 21 Jul 2018 22:12:32 +0100 Subject: [PATCH] New metrics and ubus files. --- src/metrics.c | 44 +++++++++++++++++++++ src/metrics.h | 27 +++++++++++++ src/ubus.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 src/metrics.c create mode 100644 src/metrics.h create mode 100644 src/ubus.c diff --git a/src/metrics.c b/src/metrics.c new file mode 100644 index 0000000..8672807 --- /dev/null +++ b/src/metrics.c @@ -0,0 +1,44 @@ +/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991, or + (at your option) version 3 dated 29 June, 2007. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "dnsmasq.h" + +const char * metric_names[] = { + "dns_cache_inserted", + "dns_cache_live_freed", + "dns_queries_forwarded", + "dns_auth_answered", + "dns_local_answered", + "bootp", + "pxe", + "dhcp_ack", + "dhcp_decline", + "dhcp_discover", + "dhcp_inform", + "dhcp_nak", + "dhcp_offer", + "dhcp_release", + "dhcp_request", + "noanswer", + "leases_allocated_4", + "leases_pruned_4", + "leases_allocated_6", + "leases_pruned_6", +}; + +const char* get_metric_name(int i) { + return metric_names[i]; +} diff --git a/src/metrics.h b/src/metrics.h new file mode 100644 index 0000000..f13b8c8 --- /dev/null +++ b/src/metrics.h @@ -0,0 +1,27 @@ +// If you modify this list, please keep the labels in metrics.c in sync. +enum { + METRIC_DNS_CACHE_INSERTED, + METRIC_DNS_CACHE_LIVE_FREED, + METRIC_DNS_QUERIES_FORWARDED, + METRIC_DNS_AUTH_ANSWERED, + METRIC_DNS_LOCAL_ANSWERED, + METRIC_BOOTP, + METRIC_PXE, + METRIC_DHCPACK, + METRIC_DHCPDECLINE, + METRIC_DHCPDISCOVER, + METRIC_DHCPINFORM, + METRIC_DHCPNAK, + METRIC_DHCPOFFER, + METRIC_DHCPRELEASE, + METRIC_DHCPREQUEST, + METRIC_NOANSWER, + METRIC_LEASES_ALLOCATED_4, + METRIC_LEASES_PRUNED_4, + METRIC_LEASES_ALLOCATED_6, + METRIC_LEASES_PRUNED_6, + + __METRIC_MAX, +}; + +const char* get_metric_name(int); diff --git a/src/ubus.c b/src/ubus.c new file mode 100644 index 0000000..2b19593 --- /dev/null +++ b/src/ubus.c @@ -0,0 +1,105 @@ +/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991, or + (at your option) version 3 dated 29 June, 2007. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "dnsmasq.h" + +#ifdef HAVE_UBUS + +#include + +static struct ubus_context *ubus; +static struct blob_buf b; + +static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg); +static struct ubus_method ubus_object_methods[] = { + {.name = "metrics", .handler = ubus_handle_metrics}, +}; + +static struct ubus_object_type ubus_object_type = UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods); + +static struct ubus_object ubus_object = { + .name = "dnsmasq", + .type = &ubus_object_type, + .methods = ubus_object_methods, + .n_methods = ARRAY_SIZE(ubus_object_methods), +}; + +void set_ubus_listeners() +{ + if (!ubus) + return; + + poll_listen(ubus->sock.fd, POLLIN); + poll_listen(ubus->sock.fd, POLLERR); + poll_listen(ubus->sock.fd, POLLHUP); +} + +void check_ubus_listeners() +{ + if (!ubus) { + ubus = ubus_connect(NULL); + if (!ubus) + return; + ubus_add_object(ubus, &ubus_object); + } + + if (poll_check(ubus->sock.fd, POLLIN)) + ubus_handle_event(ubus); + + if (poll_check(ubus->sock.fd, POLLHUP)) { + ubus_free(ubus); + ubus = NULL; + } +} + + +static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + blob_buf_init(&b, 0); + + for(int i=0; i < __METRIC_MAX; i++) { + blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]); + } + + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +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); +} + + +#endif /* HAVE_UBUS */