1 /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
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.
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.
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/>.
23 static struct blob_buf b;
24 static int error_logged = 0;
26 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
27 struct ubus_request_data *req, const char *method,
28 struct blob_attr *msg);
32 SET_CONNMARK_ALLOWLIST_MARK,
33 SET_CONNMARK_ALLOWLIST_MASK,
34 SET_CONNMARK_ALLOWLIST_PATTERNS
36 static const struct blobmsg_policy set_connmark_allowlist_policy[] = {
37 [SET_CONNMARK_ALLOWLIST_MARK] = {
39 .type = BLOBMSG_TYPE_INT32
41 [SET_CONNMARK_ALLOWLIST_MASK] = {
43 .type = BLOBMSG_TYPE_INT32
45 [SET_CONNMARK_ALLOWLIST_PATTERNS] = {
47 .type = BLOBMSG_TYPE_ARRAY
50 static int ubus_handle_set_connmark_allowlist(struct ubus_context *ctx, struct ubus_object *obj,
51 struct ubus_request_data *req, const char *method,
52 struct blob_attr *msg);
55 static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
57 static const struct ubus_method ubus_object_methods[] = {
58 UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
60 UBUS_METHOD("set_connmark_allowlist", ubus_handle_set_connmark_allowlist, set_connmark_allowlist_policy),
64 static struct ubus_object_type ubus_object_type =
65 UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
67 static struct ubus_object ubus_object = {
69 .type = &ubus_object_type,
70 .methods = ubus_object_methods,
71 .n_methods = ARRAY_SIZE(ubus_object_methods),
72 .subscribe_cb = ubus_subscribe_cb,
75 static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
79 my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
82 static void ubus_destroy(struct ubus_context *ubus)
87 /* Forces re-initialization when we're reusing the same definitions later on. */
89 ubus_object_type.id = 0;
92 static void ubus_disconnect_cb(struct ubus_context *ubus)
96 ret = ubus_reconnect(ubus, NULL);
99 my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));
107 struct ubus_context *ubus = NULL;
110 if (!(ubus = ubus_connect(NULL)))
113 ubus_object.name = daemon->ubus_name;
114 ret = ubus_add_object(ubus, &ubus_object);
118 return (char *)ubus_strerror(ret);
121 ubus->connection_lost = ubus_disconnect_cb;
128 void set_ubus_listeners()
130 struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
135 my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
143 poll_listen(ubus->sock.fd, POLLIN);
144 poll_listen(ubus->sock.fd, POLLERR);
145 poll_listen(ubus->sock.fd, POLLHUP);
148 void check_ubus_listeners()
150 struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
155 my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
163 if (poll_check(ubus->sock.fd, POLLIN))
164 ubus_handle_event(ubus);
166 if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
168 my_syslog(LOG_INFO, _("Disconnecting from UBus"));
174 #define CHECK(stmt) \
179 my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
180 return (UBUS_STATUS_UNKNOWN_ERROR); \
184 static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
185 struct ubus_request_data *req, const char *method,
186 struct blob_attr *msg)
194 CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
196 for (i=0; i < __METRIC_MAX; i++)
197 CHECK(blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]));
199 CHECK(ubus_send_reply(ctx, req, b.head));
200 return UBUS_STATUS_OK;
203 #ifdef HAVE_CONNTRACK
204 static int ubus_handle_set_connmark_allowlist(struct ubus_context *ctx, struct ubus_object *obj,
205 struct ubus_request_data *req, const char *method,
206 struct blob_attr *msg)
208 const struct blobmsg_policy *policy = set_connmark_allowlist_policy;
209 size_t policy_len = countof(set_connmark_allowlist_policy);
210 struct allowlist *allowlists = NULL, **allowlists_pos;
211 char **patterns = NULL, **patterns_pos;
212 u32 mark, mask = UINT32_MAX;
213 size_t num_patterns = 0;
214 struct blob_attr *tb[policy_len];
215 struct blob_attr *attr;
217 if (blobmsg_parse(policy, policy_len, tb, blob_data(msg), blob_len(msg)))
218 return UBUS_STATUS_INVALID_ARGUMENT;
220 if (!tb[SET_CONNMARK_ALLOWLIST_MARK])
221 return UBUS_STATUS_INVALID_ARGUMENT;
222 mark = blobmsg_get_u32(tb[SET_CONNMARK_ALLOWLIST_MARK]);
224 return UBUS_STATUS_INVALID_ARGUMENT;
226 if (tb[SET_CONNMARK_ALLOWLIST_MASK])
228 mask = blobmsg_get_u32(tb[SET_CONNMARK_ALLOWLIST_MASK]);
229 if (!mask || (mark & ~mask))
230 return UBUS_STATUS_INVALID_ARGUMENT;
233 if (tb[SET_CONNMARK_ALLOWLIST_PATTERNS])
235 struct blob_attr *head = blobmsg_data(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
236 size_t len = blobmsg_data_len(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
237 __blob_for_each_attr(attr, head, len)
240 if (blob_id(attr) != BLOBMSG_TYPE_STRING)
241 return UBUS_STATUS_INVALID_ARGUMENT;
242 if (!(pattern = blobmsg_get_string(attr)))
243 return UBUS_STATUS_INVALID_ARGUMENT;
244 if (strcmp(pattern, "*") && !is_valid_dns_name_pattern(pattern))
245 return UBUS_STATUS_INVALID_ARGUMENT;
250 for (allowlists_pos = &daemon->allowlists; *allowlists_pos; allowlists_pos = &(*allowlists_pos)->next)
251 if ((*allowlists_pos)->mark == mark && (*allowlists_pos)->mask == mask)
253 struct allowlist *allowlists_next = (*allowlists_pos)->next;
254 for (patterns_pos = (*allowlists_pos)->patterns; *patterns_pos; patterns_pos++)
257 *patterns_pos = NULL;
259 free((*allowlists_pos)->patterns);
260 (*allowlists_pos)->patterns = NULL;
261 free(*allowlists_pos);
262 *allowlists_pos = allowlists_next;
267 return UBUS_STATUS_OK;
269 patterns = whine_malloc((num_patterns + 1) * sizeof(char *));
272 patterns_pos = patterns;
273 if (tb[SET_CONNMARK_ALLOWLIST_PATTERNS])
275 struct blob_attr *head = blobmsg_data(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
276 size_t len = blobmsg_data_len(tb[SET_CONNMARK_ALLOWLIST_PATTERNS]);
277 __blob_for_each_attr(attr, head, len)
280 if (!(pattern = blobmsg_get_string(attr)))
282 if (!(*patterns_pos = whine_malloc(strlen(pattern) + 1)))
284 strcpy(*patterns_pos++, pattern);
288 allowlists = whine_malloc(sizeof(struct allowlist));
291 memset(allowlists, 0, sizeof(struct allowlist));
292 allowlists->mark = mark;
293 allowlists->mask = mask;
294 allowlists->patterns = patterns;
295 allowlists->next = daemon->allowlists;
296 daemon->allowlists = allowlists;
297 return UBUS_STATUS_OK;
302 for (patterns_pos = patterns; *patterns_pos; patterns_pos++)
305 *patterns_pos = NULL;
315 return UBUS_STATUS_UNKNOWN_ERROR;
321 #define CHECK(stmt) \
326 my_syslog(LOG_ERR, _("UBus command failed: %d (%s)"), e, #stmt); \
331 void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
333 struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
335 if (!ubus || !ubus_object.has_subscribers)
338 CHECK(blob_buf_init(&b, BLOBMSG_TYPE_TABLE));
340 CHECK(blobmsg_add_string(&b, "mac", mac));
342 CHECK(blobmsg_add_string(&b, "ip", ip));
344 CHECK(blobmsg_add_string(&b, "name", name));
346 CHECK(blobmsg_add_string(&b, "interface", interface));
348 CHECK(ubus_notify(ubus, &ubus_object, type, b.head, -1));
351 #ifdef HAVE_CONNTRACK
352 void ubus_event_bcast_connmark_allowlist_refused(u32 mark, const char *name)
354 struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
356 if (!ubus || !ubus_object.has_subscribers)
359 CHECK(blob_buf_init(&b, 0));
360 CHECK(blobmsg_add_u32(&b, "mark", mark));
361 CHECK(blobmsg_add_string(&b, "name", name));
363 CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.refused", b.head, -1));
366 void ubus_event_bcast_connmark_allowlist_resolved(u32 mark, const char *name, const char *value, u32 ttl)
368 struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
370 if (!ubus || !ubus_object.has_subscribers)
373 CHECK(blob_buf_init(&b, 0));
374 CHECK(blobmsg_add_u32(&b, "mark", mark));
375 CHECK(blobmsg_add_string(&b, "name", name));
376 CHECK(blobmsg_add_string(&b, "value", value));
377 CHECK(blobmsg_add_u32(&b, "ttl", ttl));
379 /* Set timeout to allow UBus subscriber to configure firewall rules before returning. */
380 CHECK(ubus_notify(ubus, &ubus_object, "connmark-allowlist.resolved", b.head, /* timeout: */ 1000));
386 #endif /* HAVE_UBUS */