summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c13
-rw-r--r--src/config.l2
-rw-r--r--src/config.y15
-rw-r--r--src/fastd.c24
-rw-r--r--src/fastd.h12
5 files changed, 64 insertions, 2 deletions
diff --git a/src/config.c b/src/config.c
index d0d8dbd..b63ade9 100644
--- a/src/config.c
+++ b/src/config.c
@@ -62,6 +62,9 @@ static void default_config(fastd_config *conf) {
conf->protocol = &fastd_protocol_null;
conf->secret = NULL;
conf->peers = NULL;
+
+ conf->on_up = NULL;
+ conf->on_up_dir = NULL;
}
static bool config_match(const char *opt, ...) {
@@ -319,6 +322,16 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
continue;
}
+ IF_OPTION_ARG("--on-up") {
+ free(conf->on_up);
+ free(conf->on_up_dir);
+
+ conf->on_up = strdup(arg);
+ conf->on_up_dir = get_current_dir_name();
+
+ continue;
+ }
+
IF_OPTION("--generate-key") {
keygen = true;
continue;
diff --git a/src/config.l b/src/config.l
index 808f96e..eeb20ae 100644
--- a/src/config.l
+++ b/src/config.l
@@ -55,6 +55,8 @@ as { return TOK_AS; }
any { return TOK_ANY; }
tap { return TOK_TAP; }
tun { return TOK_TUN; }
+on { return TOK_ON; }
+up { return TOK_UP; }
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
if (!inet_pton(AF_INET, yytext, &yylval->addr)) {
diff --git a/src/config.y b/src/config.y
index c1d6053..78c0833 100644
--- a/src/config.y
+++ b/src/config.y
@@ -32,8 +32,11 @@
%parse-param {int depth}
%code requires {
+ #define _GNU_SOURCE
+
#include <fastd.h>
#include <arpa/inet.h>
+ #include <unistd.h>
}
%union {
@@ -63,6 +66,8 @@
%token TOK_ANY
%token TOK_TAP
%token TOK_TUN
+%token TOK_ON
+%token TOK_UP
%token <addr> TOK_ADDR
%token <addr6> TOK_ADDR6
@@ -105,6 +110,7 @@ statement: TOK_INTERFACE interface ';'
| TOK_MODE mode ';'
| TOK_PROTOCOL protocol ';'
| TOK_SECRET secret ';'
+ | TOK_ON TOK_UP on_up ';'
| TOK_PEER peer '{' peer_conf '}'
| TOK_INCLUDE include ';'
;
@@ -154,6 +160,15 @@ protocol: TOK_STRING {
secret: TOK_STRING { free(conf->secret); conf->secret = $1; }
;
+on_up: TOK_STRING {
+ free(conf->on_up);
+ free(conf->on_up_dir);
+
+ conf->on_up = $1;
+ conf->on_up_dir = get_current_dir_name();
+ }
+ ;
+
peer: maybe_string {
fastd_peer_config_new(ctx, conf);
conf->peers->name = $1;
diff --git a/src/fastd.c b/src/fastd.c
index 423c8c2..2311ba8 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -24,6 +24,8 @@
*/
+#define _GNU_SOURCE
+
#include "fastd.h"
#include "handshake.h"
#include "peer.h"
@@ -69,6 +71,8 @@ static void init_tuntap(fastd_context *ctx) {
if (ioctl(ctx->tunfd, TUNSETIFF, (void *)&ifr) < 0)
exit_errno(ctx, "TUNSETIFF ioctl failed");
+ ctx->ifname = strdup(ifr.ifr_name);
+
pr_debug(ctx, "Tun/tap device initialized.");
}
@@ -113,6 +117,24 @@ static void init_socket(fastd_context *ctx) {
}
}
+static void on_up(fastd_context *ctx) {
+ if (!ctx->conf->on_up)
+ return;
+
+ char *cwd = get_current_dir_name();
+ chdir(ctx->conf->on_up_dir);
+
+ setenv("INTERFACE", ctx->ifname, 1);
+ int ret = system(ctx->conf->on_up);
+
+ if (WIFSIGNALED(ret))
+ pr_error(ctx, "on-up command exited with signal %i", WTERMSIG(ret));
+ else if(ret)
+ pr_warn(ctx, "on-up command exited with status %i", WEXITSTATUS(ret));
+
+ chdir(cwd);
+}
+
static void init_peers(fastd_context *ctx) {
fastd_peer_config *peer_conf;
for (peer_conf = ctx->conf->peers; peer_conf; peer_conf = peer_conf->next) {
@@ -400,6 +422,8 @@ int main(int argc, char *argv[]) {
init_tuntap(&ctx);
init_socket(&ctx);
+ on_up(&ctx);
+
while (1) {
handle_tasks(&ctx);
handle_input(&ctx);
diff --git a/src/fastd.h b/src/fastd.h
index fd6fead..dbf9e61 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -99,11 +99,16 @@ struct _fastd_config {
unsigned n_v6;
fastd_protocol_config *protocol_config;
+
+ char *on_up;
+ char *on_up_dir;
};
struct _fastd_context {
const fastd_config *conf;
+ char *ifname;
+
struct timespec now;
fastd_peer *peers;
@@ -126,8 +131,11 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
void fastd_random_bytes(fastd_context *ctx, void *buffer, size_t len, bool secure);
-#define pr_log(ctx, level, prefix, args...) if ((ctx)->conf == NULL || (level) <= (ctx)->conf->loglevel) \
- do { fputs(prefix, stderr); fastd_printf(ctx, args); fputs("\n", stderr); } while(0)
+#define pr_log(ctx, level, prefix, args...) do { \
+ if ((ctx)->conf == NULL || (level) <= (ctx)->conf->loglevel) { \
+ fputs(prefix, stderr); fastd_printf(ctx, args); fputs("\n", stderr); \
+ } \
+ } while(0)
#define is_error(ctx) ((ctx)->conf == NULL || LOG_ERROR <= (ctx)->conf->loglevel)
#define is_warn(ctx) ((ctx)->conf == NULL || LOG_WARN <= (ctx)->conf->loglevel)