From ab4c4bb9d7c4e163a5b3780e69fc99a55b1eb21b Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Wed, 1 Apr 2020 12:28:15 +0300 Subject: [PATCH] Support a script to be executed when the device goes up This adds the `ifup_script` config option. The script receives the following environment variables as input: - NET_DEVICE: The name of the network device of the VPN. - DNS_SUFFIX: DNS domain search prefix, if provided by the VPN server. - DNS_SERVERS: A list of the DNS server addresses if provided by the VPN server. --- src/config.c | 3 +++ src/config.h | 3 +++ src/tunnel.c | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 968853ad..7726130e 100644 --- a/src/config.c +++ b/src/config.c @@ -267,6 +267,9 @@ int load_config(struct vpn_config *cfg, const char *filename) } else if (strcmp(key, "realm") == 0) { strncpy(cfg->realm, val, FIELD_SIZE - 1); cfg->realm[FIELD_SIZE] = '\0'; + } else if (strcmp(key, "ifup-script") == 0) { + strncpy(cfg->ifup_script, val, MAXPATHLEN - 1); + cfg->ifup_script[MAXPATHLEN] = '\0'; } else if (strcmp(key, "set-dns") == 0) { int set_dns = strtob(val); diff --git a/src/config.h b/src/config.h index 03efd46a..2c3d21b2 100644 --- a/src/config.h +++ b/src/config.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #define ERR_CFG_UNKNOWN -1 @@ -57,6 +58,7 @@ struct x509_digest { }; #define FIELD_SIZE 64 +#define SCRIPT_PATH MAXPATHLEN #define COOKIE_SIZE 4096 struct vpn_config { @@ -70,6 +72,7 @@ struct vpn_config { unsigned int otp_delay; char *pinentry; char realm[FIELD_SIZE + 1]; + char ifup_script[SCRIPT_PATH + 1]; int set_routes; int set_dns; diff --git a/src/tunnel.c b/src/tunnel.c index fcefd54c..45665bd8 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -101,13 +101,39 @@ static int ofv_append_varr(struct ofv_varr *p, const char *x) return 0; } +static int ipv4_run_ifup_script(struct tunnel *tunnel) +{ + char ns[32]; + + setenv("NET_DEVICE", tunnel->ppp_iface, 0); + + ns[0] = '\0'; + + if (tunnel->ipv4.ns1_addr.s_addr != 0) + strncat(ns, inet_ntoa(tunnel->ipv4.ns1_addr), 15); + + if (tunnel->ipv4.ns2_addr.s_addr != 0) { + strcpy(ns, " "); + strncat(ns, inet_ntoa(tunnel->ipv4.ns2_addr), 15); + } + + setenv("DNS_SERVERS", ns, 0); + + if (tunnel->ipv4.dns_suffix != NULL) + setenv("DNS_SUFFIX", tunnel->ipv4.dns_suffix, 0); + else + setenv("DNS_SUFFIX", "", 0); + + return system(tunnel->config->ifup_script); +} + static int on_ppp_if_up(struct tunnel *tunnel) { + int ret; + log_info("Interface %s is UP.\n", tunnel->ppp_iface); if (tunnel->config->set_routes) { - int ret; - log_info("Setting new routes...\n"); ret = ipv4_set_tunnel_routes(tunnel); @@ -121,6 +147,13 @@ static int on_ppp_if_up(struct tunnel *tunnel) ipv4_add_nameservers_to_resolv_conf(tunnel); } + if (tunnel->config->ifup_script) { + log_info("Running `ifup` script...\n"); + ret = ipv4_run_ifup_script(tunnel); + if (ret != 0) + log_warn("The `ifup` script failed. Please check your logs.\n"); + } + log_info("Tunnel is up and running.\n"); #if HAVE_SYSTEMD