[PATCH wireguard-tools] wg-quick: android: add support for {Pre, Post}{Up, Down} hooks
Claire Elaina
git at claire.sharkgirl.ing
Sun May 25 08:04:57 UTC 2025
---
src/wg-quick/android.c | 96 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 7 deletions(-)
diff --git a/src/wg-quick/android.c b/src/wg-quick/android.c
index 1263ee4..8a8df47 100644
--- a/src/wg-quick/android.c
+++ b/src/wg-quick/android.c
@@ -60,6 +60,15 @@ static void *xcalloc(size_t nmemb, size_t size)
exit(errno);
}
+static void *xrealloc(void *ptr, size_t size)
+{
+ void *ret = realloc(ptr, size);
+ if (ret)
+ return ret;
+ perror("Error: realloc");
+ exit(errno);
+}
+
static void *xstrdup(const char *str)
{
char *ret = strdup(str);
@@ -126,6 +135,27 @@ static void free_command_buffer(struct command_buffer *c)
free(c->line);
}
+struct str_list {
+ char **items;
+ size_t len;
+};
+
+static void append_str_list(struct str_list *l, char *item)
+{
+ l->len++;
+ l->items = xrealloc(l->items, sizeof(char*) * l->len);
+ l->items[l->len - 1] = item;
+}
+
+static void free_str_list(struct str_list *l)
+{
+ if (!l)
+ return;
+ for (size_t i = 0; i < l->len; ++i)
+ free(l->items[i]);
+ free(l->items);
+}
+
static void freep(void *p)
{
free(*(void **)p);
@@ -140,6 +170,7 @@ static void fclosep(FILE **f)
#define _cleanup_regfree_ _cleanup_(regfree)
#define DEFINE_CMD(name) _cleanup_(free_command_buffer) struct command_buffer name = { 0 };
+#define DEFINE_STR_LIST(name) _cleanup_(free_str_list) struct str_list name = { 0 };
static char *vcmd_ret(struct command_buffer *c, const char *cmd_fmt, va_list args)
{
@@ -239,6 +270,12 @@ _printf_(1, 2) static void cndc(const char *cmd_fmt, ...)
}
}
+static void execute_hooks(const struct str_list *hooks)
+{
+ for (size_t i = 0; i < hooks->len; ++i)
+ cmd("%s", hooks->items[i]);
+}
+
/* Values are from AOSP repository platform/frameworks/native in libs/binder/ndk/include_ndk/android/binder_status.h. */
enum {
STATUS_OK = 0,
@@ -1112,7 +1149,7 @@ static void cmd_up_cleanup(void)
free(cleanup_iface);
}
-static void cmd_up(const char *iface, const char *config, unsigned int mtu, const char *addrs, const char *dnses, const char *excluded_applications, const char *included_applications)
+static void cmd_up(const char *iface, const char *config, unsigned int mtu, const char *addrs, const char *dnses, const char *excluded_applications, const char *included_applications, const struct str_list *pre_up, const struct str_list *post_up)
{
DEFINE_CMD(c);
unsigned int netid = 0;
@@ -1127,6 +1164,7 @@ static void cmd_up(const char *iface, const char *config, unsigned int mtu, cons
atexit(cmd_up_cleanup);
add_if(iface);
+ execute_hooks(pre_up);
set_config(iface, config);
listen_port = determine_listen_port(iface);
up_if(&netid, iface, listen_port);
@@ -1135,6 +1173,7 @@ static void cmd_up(const char *iface, const char *config, unsigned int mtu, cons
set_routes(iface, netid);
set_mtu(iface, mtu);
set_users(netid, excluded_applications, included_applications);
+ execute_hooks(post_up);
broadcast_change();
free(cleanup_iface);
@@ -1142,7 +1181,7 @@ static void cmd_up(const char *iface, const char *config, unsigned int mtu, cons
exit(EXIT_SUCCESS);
}
-static void cmd_down(const char *iface)
+static void cmd_down(const char *iface, const struct str_list *pre_down, const struct str_list *post_down)
{
DEFINE_CMD(c);
bool found = false;
@@ -1161,12 +1200,14 @@ static void cmd_down(const char *iface)
exit(EMEDIUMTYPE);
}
+ execute_hooks(pre_down);
del_if(iface);
+ execute_hooks(post_down);
broadcast_change();
exit(EXIT_SUCCESS);
}
-static void parse_options(char **iface, char **config, unsigned int *mtu, char **addrs, char **dnses, char **excluded_applications, char **included_applications, const char *arg)
+static void parse_options(char **iface, char **config, unsigned int *mtu, char **addrs, char **dnses, char **excluded_applications, char **included_applications, struct str_list *pre_up, struct str_list *post_up, struct str_list *pre_down, struct str_list *post_down, const char *arg)
{
_cleanup_fclose_ FILE *file = NULL;
_cleanup_free_ char *line = NULL;
@@ -1236,6 +1277,27 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char *
}
clean[j] = '\0';
+ char *line_value = strchr(line, '=');
+ _cleanup_free_ char *unstripped_value = NULL;
+ if (line_value) {
+ /* Skip equal sign. */
+ line_value++;
+
+ /* Skip leading whitespace. */
+ while (isspace(line_value[0]))
+ line_value++;
+
+ /* Calculate length of the value without trailing whitespace. */
+ size_t line_value_len = strlen(line_value);
+ while (line_value_len && isspace(line_value[line_value_len - 1]))
+ line_value_len--;
+
+ /* Create the string. */
+ unstripped_value = xmalloc(line_value_len + 1);
+ memcpy(unstripped_value, line_value, line_value_len);
+ unstripped_value[line_value_len] = '\0';
+ }
+
if (clean[0] == '[')
in_interface_section = false;
if (!strcasecmp(clean, "[Interface]"))
@@ -1256,6 +1318,22 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char *
} else if (!strncasecmp(clean, "MTU=", 4) && j > 4) {
*mtu = atoi(clean + 4);
continue;
+ } else if (!strncasecmp(clean, "PreUp=", 6) && j > 6) {
+ append_str_list(pre_up, unstripped_value);
+ unstripped_value = NULL;
+ continue;
+ } else if (!strncasecmp(clean, "PostUp=", 7) && j > 7) {
+ append_str_list(post_up, unstripped_value);
+ unstripped_value = NULL;
+ continue;
+ } else if (!strncasecmp(clean, "PreDown=", 8) && j > 8) {
+ append_str_list(pre_down, unstripped_value);
+ unstripped_value = NULL;
+ continue;
+ } else if (!strncasecmp(clean, "PostDown=", 9) && j > 9) {
+ append_str_list(post_down, unstripped_value);
+ unstripped_value = NULL;
+ continue;
}
}
*config = concat_and_free(*config, "", line);
@@ -1279,6 +1357,10 @@ int main(int argc, char *argv[])
_cleanup_free_ char *dnses = NULL;
_cleanup_free_ char *excluded_applications = NULL;
_cleanup_free_ char *included_applications = NULL;
+ DEFINE_STR_LIST(pre_up);
+ DEFINE_STR_LIST(post_up);
+ DEFINE_STR_LIST(pre_down);
+ DEFINE_STR_LIST(post_down);
unsigned int mtu;
char prop[PROP_VALUE_MAX + 1];
@@ -1289,12 +1371,12 @@ int main(int argc, char *argv[])
cmd_usage(argv[0]);
else if (argc == 3 && !strcmp(argv[1], "up")) {
auto_su(argc, argv);
- parse_options(&iface, &config, &mtu, &addrs, &dnses, &excluded_applications, &included_applications, argv[2]);
- cmd_up(iface, config, mtu, addrs, dnses, excluded_applications, included_applications);
+ parse_options(&iface, &config, &mtu, &addrs, &dnses, &excluded_applications, &included_applications, &pre_up, &post_up, &pre_down, &post_down, argv[2]);
+ cmd_up(iface, config, mtu, addrs, dnses, excluded_applications, included_applications, &pre_up, &post_up);
} else if (argc == 3 && !strcmp(argv[1], "down")) {
auto_su(argc, argv);
- parse_options(&iface, &config, &mtu, &addrs, &dnses, &excluded_applications, &included_applications, argv[2]);
- cmd_down(iface);
+ parse_options(&iface, &config, &mtu, &addrs, &dnses, &excluded_applications, &included_applications, &pre_up, &post_up, &pre_down, &post_down, argv[2]);
+ cmd_down(iface, &pre_down, &post_down);
} else {
cmd_usage(argv[0]);
return 1;
--
2.49.0
More information about the WireGuard
mailing list