From ecc319801ecbc6a1b3d47569837371d6fbf8c301 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 | 2 ++ src/tunnel.c | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 8c6f0a16..7d0abf6f 100644 --- a/src/config.c +++ b/src/config.c @@ -289,6 +289,9 @@ int load_config(struct vpn_config *cfg, const char *filename) } else if (strcmp(key, "realm") == 0) { strncpy(cfg->realm, val, REALM_SIZE); cfg->realm[REALM_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 445d89c3..b33b9e98 100644 --- a/src/config.h +++ b/src/config.h @@ -18,6 +18,7 @@ #ifndef OPENFORTIVPN_CONFIG_H #define OPENFORTIVPN_CONFIG_H +#include #include #include @@ -97,6 +98,7 @@ struct vpn_config { char *pinentry; char iface_name[IF_NAMESIZE]; char realm[REALM_SIZE + 1]; + char ifup_script[MAXPATHLEN + 1]; int set_routes; int set_dns; diff --git a/src/tunnel.c b/src/tunnel.c index 64a6ceb1..d91ca167 100644 --- a/src/tunnel.c +++ b/src/tunnel.c @@ -105,13 +105,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); @@ -125,6 +151,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