From aadf0a94b436990202cd2f13f1fe8528a9fd183c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 29 Mar 2012 01:28:55 +0200 Subject: Implement on-up commands; also fix log print conditions --- src/config.c | 13 +++++++++++++ src/config.l | 2 ++ src/config.y | 15 +++++++++++++++ src/fastd.c | 24 ++++++++++++++++++++++++ src/fastd.h | 12 ++++++++++-- 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 #include + #include } %union { @@ -63,6 +66,8 @@ %token TOK_ANY %token TOK_TAP %token TOK_TUN +%token TOK_ON +%token TOK_UP %token TOK_ADDR %token 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) -- cgit v1.2.3