summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-03-24 20:55:27 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-03-24 20:55:27 +0100
commit4ffc28ecd6d914f9c1e5aaf5d5921ee4827bb289 (patch)
treeddd64c27220b75f45a6efdc162bbbe040a9ca001 /src
parent78fe2cda0572433e40889bcd7d64dd22707bfdd0 (diff)
downloadfastd-4ffc28ecd6d914f9c1e5aaf5d5921ee4827bb289.tar
fastd-4ffc28ecd6d914f9c1e5aaf5d5921ee4827bb289.zip
Partial implementation of a config files parser
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt18
-rw-r--r--src/config.c (renamed from src/configure.c)48
-rw-r--r--src/config.l57
-rw-r--r--src/config.y106
-rw-r--r--src/fastd.c12
-rw-r--r--src/fastd.h10
-rw-r--r--src/handshake.c12
-rw-r--r--src/packet.h2
-rw-r--r--src/peer.c12
-rw-r--r--src/types.h8
10 files changed, 242 insertions, 43 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 223c62a..1da7d13 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,5 @@
set(METHODS method_null.c)
-set(FASTD_INCLUDES ${FASTD_BINARY_DIR})
+set(FASTD_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${FASTD_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(FASTD_LIBS "")
if(WITH_METHOD_ECFXP)
@@ -10,5 +10,19 @@ endif(WITH_METHOD_ECFXP)
include_directories(${FASTD_INCLUDES})
-add_executable(fastd fastd.c configure.c handshake.c peer.c printf.c queue.c task.c ${METHODS})
+FLEX_TARGET(fastd_config_lex config.l ${CMAKE_CURRENT_BINARY_DIR}/config.ll.c)
+BISON_TARGET(fastd_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.c)
+
+add_executable(fastd
+ fastd.c
+ config.c
+ handshake.c
+ peer.c
+ printf.c
+ queue.c
+ task.c
+ ${FLEX_fastd_config_lex_OUTPUTS}
+ ${BISON_fastd_config_parse_OUTPUTS}
+ ${METHODS}
+)
target_link_libraries(fastd rt ${FASTD_LIBS})
diff --git a/src/configure.c b/src/config.c
index 7473696..18fe120 100644
--- a/src/configure.c
+++ b/src/config.c
@@ -27,6 +27,8 @@
#include "fastd.h"
#include "peer.h"
+#include <config.ll.h>
+#include <config.yy.h>
#include <config.h>
@@ -52,16 +54,16 @@ static void default_config(fastd_config *conf) {
memset(&conf->bind_addr_in, 0, sizeof(struct sockaddr_in));
conf->bind_addr_in.sin_family = AF_UNSPEC;
- conf->bind_addr_in.sin_port = htons(1337);
+ conf->bind_addr_in.sin_port = 0;
conf->bind_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&conf->bind_addr_in6, 0, sizeof(struct sockaddr_in6));
conf->bind_addr_in6.sin6_family = AF_UNSPEC;
- conf->bind_addr_in6.sin6_port = htons(1337);
+ conf->bind_addr_in6.sin6_port = 0;
conf->bind_addr_in6.sin6_addr = in6addr_any;
conf->mtu = 1500;
- conf->protocol = PROTOCOL_ETHERNET;
+ conf->mode = MODE_TAP;
conf->method = &fastd_method_null;
conf->peers = NULL;
}
@@ -85,6 +87,21 @@ static bool config_match(const char *opt, ...) {
return match;
}
+static void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename) {
+ yyscan_t scanner;
+ FILE *file;
+
+ file = fopen(filename, "r");
+ fastd_config_lex_init(&scanner);
+
+ fastd_config_set_in(file, scanner);
+
+ fastd_config_parse(ctx, conf, scanner);
+
+ fastd_config_lex_destroy(scanner);
+ fclose(file);
+}
+
#define IF_OPTION(args...) if(config_match(argv[i], args, NULL) && (++i))
#define IF_OPTION_ARG(args...) if(config_match(argv[i], args, NULL) && ({ \
arg = argv[i+1]; \
@@ -114,6 +131,11 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
while (i < argc) {
+ IF_OPTION_ARG("-c", "--config") {
+ fastd_read_config(ctx, conf, arg);
+ continue;
+ }
+
IF_OPTION_ARG("-i", "--interface") {
conf->ifname = arg;
continue;
@@ -180,18 +202,18 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
continue;
}
- IF_OPTION_ARG("-P", "--protocol") {
- if (!strcmp(arg, "ethernet"))
- conf->protocol = PROTOCOL_ETHERNET;
- else if (!strcmp(arg, "ip"))
- conf->protocol = PROTOCOL_IP;
+ IF_OPTION_ARG("-m", "--mode") {
+ if (!strcmp(arg, "tap"))
+ conf->mode = MODE_TAP;
+ else if (!strcmp(arg, "tun"))
+ conf->mode = MODE_TUN;
else
- exit_error(ctx, "invalid protocol `%s'", arg);
+ exit_error(ctx, "invalid mode `%s'", arg);
continue;
}
- IF_OPTION_ARG("-m", "--method") {
+ IF_OPTION_ARG("-P", "--protocol") {
if (!strcmp(arg, "null"))
conf->method = &fastd_method_null;
#ifdef WITH_METHOD_ECFXP
@@ -199,7 +221,7 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
conf->method = &fastd_method_ec25519_fhmqvc_xsalsa20_poly1305;
#endif
else
- exit_error(ctx, "invalid method `%s'", arg);
+ exit_error(ctx, "invalid protocol `%s'", arg);
continue;
}
@@ -281,8 +303,8 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con
}
bool ok = true;
- if (conf->protocol == PROTOCOL_IP && (!conf->peers || conf->peers->next)) {
- pr_error(ctx, "for protocol `ip' exactly one peer must be configured");
+ if (conf->mode == MODE_TUN && (!conf->peers || conf->peers->next)) {
+ pr_error(ctx, "for tun mode exactly one peer must be configured");
ok = false;
}
diff --git a/src/config.l b/src/config.l
new file mode 100644
index 0000000..e9dd235
--- /dev/null
+++ b/src/config.l
@@ -0,0 +1,57 @@
+%option prefix="fastd_config_"
+%option noyywrap
+%option bison-bridge
+%option reentrant
+
+%top {
+ #include <fastd.h>
+ #include <config.yy.h>
+ #define YY_DECL int fastd_config_lex(YYSTYPE *yylval_param, fastd_context *ctx, void *yyscanner)
+}
+
+%x STRING
+%x ADDR6
+
+%%
+[0-9]+ { yylval->num = atoi(yytext); return TOK_INTEGER; }
+
+interface { yylval->str = yytext; return TOK_INTERFACE; }
+bind { yylval->str = yytext; return TOK_BIND; }
+mtu { yylval->str = yytext; return TOK_MTU; }
+mode { yylval->str = yytext; return TOK_MODE; }
+protocol { yylval->str = yytext; return TOK_PROTOCOL; }
+peer { yylval->str = yytext; return TOK_PEER; }
+
+[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} {
+ if (!inet_pton(AF_INET, yytext, &yylval->addr))
+ exit_error(ctx, "config error: invalid address");
+
+ return TOK_ADDR;
+ }
+
+any { yylval->str = yytext; return TOK_ANY; }
+float { yylval->str = yytext; return TOK_FLOAT; }
+tap { yylval->str = yytext; return TOK_TAP; }
+tun { yylval->str = yytext; return TOK_TUN; }
+
+[A-Za-z_][A-Za-z0-9_]* { yylval->str = yytext; return TOK_IDENTIFIER; }
+
+[;:\{\}] { return *yytext; }
+
+[ \t\n] ;
+
+\" BEGIN(STRING);
+<STRING>[^"]* { yylval->str = yytext; return TOK_STRING; }
+<STRING>\" BEGIN(INITIAL);
+
+\[ BEGIN(ADDR6);
+<ADDR6>[^\]]+ {
+ if (!inet_pton(AF_INET6, yytext, &yylval->addr6))
+ exit_error(ctx, "config error: invalid address");
+
+ return TOK_ADDR6;
+ }
+<ADDR6>\] BEGIN(INITIAL);
+
+<INITIAL,STRING,ADDR6>. exit_error(ctx, "config error: invalid character");
+%%
diff --git a/src/config.y b/src/config.y
new file mode 100644
index 0000000..08c5050
--- /dev/null
+++ b/src/config.y
@@ -0,0 +1,106 @@
+%define api.pure
+%name-prefix "fastd_config_"
+%lex-param {fastd_context *ctx}
+%lex-param {yyscan_t scanner}
+%parse-param {fastd_context *ctx}
+%parse-param {fastd_config *config}
+%parse-param {yyscan_t scanner}
+
+%code requires {
+ #include <arpa/inet.h>
+}
+
+%union {
+ int num;
+ char* str;
+ struct in_addr addr;
+ struct in6_addr addr6;
+}
+
+%token <num> TOK_INTEGER
+%token <str> TOK_STRING
+%token <str> TOK_IDENTIFIER
+
+%token <str> TOK_INTERFACE
+%token <str> TOK_BIND
+%token <str> TOK_MTU
+%token <str> TOK_MODE
+%token <str> TOK_PROTOCOL
+%token <str> TOK_PEER
+
+%token <addr> TOK_ADDR
+%token <addr6> TOK_ADDR6
+
+%token <str> TOK_ANY
+%token <str> TOK_FLOAT
+%token <str> TOK_TAP
+%token <str> TOK_TUN
+
+/* %code top {
+ #define YY_DECL int fastd_config_lex(YYSTYPE *yylval_param, fastd_context *ctx, yyscan_t yyscanner)
+}*/
+
+
+%code {
+ #include <config.ll.h>
+ YY_DECL;
+
+ void fastd_config_error(fastd_context *ctx, fastd_config *config, void *scanner, char *s);
+}
+
+%code provides {
+ #include <fastd.h>
+ int fastd_config_parse (fastd_context *ctx, fastd_config *config, void *scanner);
+}
+
+%%
+config: config statement
+ |
+ ;
+
+statement: TOK_INTERFACE interface ';'
+ | TOK_BIND bind ';'
+ | TOK_MTU mtu ';'
+ | TOK_MODE mode ';'
+ | TOK_PROTOCOL protocol ';'
+ | TOK_PEER peer '{' peer_config '}'
+ ;
+
+interface: TOK_STRING { config->ifname = strdup($1); }
+ ;
+
+bind: TOK_ADDR
+ | TOK_ADDR ':' port
+ | TOK_ADDR6
+ | TOK_ADDR6 ':' port
+ | TOK_ANY
+ | TOK_ANY ':' port
+ ;
+
+mtu: TOK_INTEGER { config->mtu = $1; }
+ ;
+
+mode: TOK_TAP { config->mode = MODE_TAP; }
+ | TOK_TUN { config->mode = MODE_TUN; }
+ ;
+
+protocol: TOK_STRING
+ ;
+
+peer: TOK_STRING
+ |
+ ;
+
+peer_config: peer_config peer_statement
+ |
+ ;
+
+peer_statement: ':'
+ ;
+
+port: TOK_INTEGER
+ ;
+%%
+void fastd_config_error(fastd_context *ctx, fastd_config *config, yyscan_t scanner, char *s) {
+ exit_error(ctx, "config error: %s", s);
+}
diff --git a/src/fastd.c b/src/fastd.c
index cae7c64..3b27e98 100644
--- a/src/fastd.c
+++ b/src/fastd.c
@@ -53,17 +53,17 @@ static void init_tuntap(fastd_context *ctx) {
if (ctx->conf->ifname)
strncpy(ifr.ifr_name, ctx->conf->ifname, IF_NAMESIZE-1);
- switch (ctx->conf->protocol) {
- case PROTOCOL_ETHERNET:
+ switch (ctx->conf->mode) {
+ case MODE_TAP:
ifr.ifr_flags = IFF_TAP;
break;
- case PROTOCOL_IP:
+ case MODE_TUN:
ifr.ifr_flags = IFF_TUN;
break;
default:
- exit_bug(ctx, "invalid protocol");
+ exit_bug(ctx, "invalid mode");
}
ifr.ifr_flags |= IFF_NO_PI;
@@ -166,7 +166,7 @@ static void handle_tasks(fastd_context *ctx) {
break;
case TASK_HANDLE_RECV:
- if (ctx->conf->protocol == PROTOCOL_ETHERNET) {
+ if (ctx->conf->mode == MODE_TAP) {
const fastd_eth_addr *src_addr = fastd_get_source_address(ctx, task->handle_recv.buffer);
if (fastd_eth_addr_is_unicast(src_addr))
@@ -208,7 +208,7 @@ static void handle_tun(fastd_context *ctx) {
fastd_peer *peer = NULL;
- if (ctx->conf->protocol == PROTOCOL_ETHERNET) {
+ if (ctx->conf->mode == MODE_TAP) {
const fastd_eth_addr *dest_addr = fastd_get_dest_address(ctx, buffer);
if (fastd_eth_addr_is_unicast(dest_addr)) {
peer = fastd_peer_find_by_eth_addr(ctx, dest_addr);
diff --git a/src/fastd.h b/src/fastd.h
index c42baa3..4af9f20 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -87,7 +87,7 @@ struct _fastd_config {
struct sockaddr_in6 bind_addr_in6;
uint16_t mtu;
- fastd_protocol protocol;
+ fastd_mode mode;
fastd_method *method;
@@ -153,13 +153,13 @@ static inline void fastd_buffer_free(fastd_buffer buffer) {
}
static inline size_t fastd_max_packet_size(const fastd_context *ctx) {
- switch (ctx->conf->protocol) {
- case PROTOCOL_ETHERNET:
+ switch (ctx->conf->mode) {
+ case MODE_TAP:
return ctx->conf->mtu+ETH_HLEN;
- case PROTOCOL_IP:
+ case MODE_TUN:
return ctx->conf->mtu;
default:
- exit_bug(ctx, "invalid protocol");
+ exit_bug(ctx, "invalid mode");
}
}
diff --git a/src/handshake.c b/src/handshake.c
index e30ab9f..19f15a9 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -74,8 +74,8 @@ void fastd_handshake_send(fastd_context *ctx, fastd_peer *peer) {
request->req_id = ++peer->last_req_id;
request->rsv = 0;
- uint8_t protocol = ctx->conf->protocol;
- handshake_add(ctx, &buffer, RECORD_PROTOCOL, 1, &protocol);
+ uint8_t mode = ctx->conf->mode;
+ handshake_add(ctx, &buffer, RECORD_MODE, 1, &mode);
handshake_add(ctx, &buffer, RECORD_METHOD_NAME, method_len, ctx->conf->method->name);
@@ -119,15 +119,15 @@ void fastd_handshake_handle(fastd_context *ctx, fastd_peer *peer, fastd_buffer b
uint8_t reply_code = REPLY_SUCCESS;
uint8_t error_detail = 0;
- if (!records[RECORD_PROTOCOL]) {
+ if (!records[RECORD_MODE]) {
reply_code = REPLY_MANDATORY_MISSING;
- error_detail = RECORD_PROTOCOL;
+ error_detail = RECORD_MODE;
goto send_reply;
}
- if (lengths[RECORD_PROTOCOL] != 1 || *(uint8_t*)records[RECORD_PROTOCOL] != ctx->conf->protocol) {
+ if (lengths[RECORD_MODE] != 1 || *(uint8_t*)records[RECORD_MODE] != ctx->conf->mode) {
reply_code = REPLY_UNACCEPTABLE_VALUE;
- error_detail = RECORD_PROTOCOL;
+ error_detail = RECORD_MODE;
goto send_reply;
}
diff --git a/src/packet.h b/src/packet.h
index d442d18..b206663 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -42,7 +42,7 @@ typedef enum _fastd_handshake_record_type {
RECORD_REPLY_CODE = 0,
RECORD_ERROR_DETAIL,
RECORD_FLAGS,
- RECORD_PROTOCOL,
+ RECORD_MODE,
RECORD_METHOD_NAME,
RECORD_MAX,
} fastd_handshake_record_type;
diff --git a/src/peer.c b/src/peer.c
index ab09a1a..3aecdc0 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -32,20 +32,20 @@
const fastd_eth_addr* fastd_get_source_address(const fastd_context *ctx, fastd_buffer buffer) {
- switch (ctx->conf->protocol) {
- case PROTOCOL_ETHERNET:
+ switch (ctx->conf->mode) {
+ case MODE_TAP:
return (fastd_eth_addr*)&((struct ethhdr*)buffer.data)->h_source;
default:
- exit_bug(ctx, "invalid protocol");
+ exit_bug(ctx, "invalid mode");
}
}
const fastd_eth_addr* fastd_get_dest_address(const fastd_context *ctx, fastd_buffer buffer) {
- switch (ctx->conf->protocol) {
- case PROTOCOL_ETHERNET:
+ switch (ctx->conf->mode) {
+ case MODE_TAP:
return (fastd_eth_addr*)&((struct ethhdr*)buffer.data)->h_dest;
default:
- exit_bug(ctx, "invalid protocol");
+ exit_bug(ctx, "invalid mode");
}
}
diff --git a/src/types.h b/src/types.h
index af577e3..61417fc 100644
--- a/src/types.h
+++ b/src/types.h
@@ -42,10 +42,10 @@ typedef enum _fastd_loglevel {
LOG_DEBUG,
} fastd_loglevel;
-typedef enum _fastd_protocol {
- PROTOCOL_ETHERNET,
- PROTOCOL_IP,
-} fastd_protocol;
+typedef enum _fastd_mode {
+ MODE_TAP,
+ MODE_TUN,
+} fastd_mode;
typedef enum _fastd_peer_state {
STATE_WAIT,