From 34320ea5a34e53ede384dd408f3484cb872337cc Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Feb 2012 18:13:11 +0100 Subject: Add config parsing --- src/fastd.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/fastd.h | 18 ++++---- 2 files changed, 137 insertions(+), 16 deletions(-) diff --git a/src/fastd.c b/src/fastd.c index 9798496..7bcfdd8 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -82,7 +83,7 @@ static void init_socket(fastd_context *ctx) { pr_debug(ctx, "UDP socket initialized."); } -static void configure(fastd_context *ctx, fastd_config *conf) { +static void default_config(fastd_config *conf) { conf->loglevel = LOG_DEBUG; conf->ifname = NULL; conf->bind_address = htonl(INADDR_ANY); @@ -90,13 +91,131 @@ static void configure(fastd_context *ctx, fastd_config *conf) { conf->mtu = 1500; conf->protocol = PROTOCOL_ETHERNET; conf->method = &fastd_method_null; + conf->peers = NULL; +} + +static void configure(fastd_context *ctx, fastd_config *conf, int argc, char *argv[]) { + default_config(conf); + + fastd_peer_config **current_peer = &conf->peers; + + static const struct option long_options[] = { + {"dev", required_argument, 0, 'i'}, + {"bind", required_argument, 0, 'b'}, + {"mtu", required_argument, 0, 'M'}, + {"protocol", required_argument, 0, 'P'}, + {"method", required_argument, 0, 'm'}, + {"peer", required_argument, 0, 'p'}, + {0, 0, 0, 0} + }; + + int c; + int option_index = 0; + struct in_addr addr; + long l; + char *charptr; + char *endptr; + char *addrstr; + + while ((c = getopt_long (argc, argv, "i:b:M:P:m:p:", long_options, &option_index)) != -1) { + switch(c) { + case 'i': + conf->ifname = optarg; + break; + + case 'b': + charptr = strchr(optarg, ':'); + if (charptr) { + addrstr = strndup(optarg, charptr-optarg); + } + else { + addrstr = optarg; + } + + if (inet_pton(AF_INET, addrstr, &addr) != 1) { + exit_error(ctx, "invalid bind address `%s'", addrstr); + } + + conf->bind_address = addr.s_addr; + + if (charptr) { + l = strtol(charptr+1, &endptr, 10); + if (*endptr || l > 65535) + exit_error(ctx, "invalid bind port `%s'", charptr+1); + conf->bind_port = htons(l); + + free(addrstr); + } + + break; + + case 'M': + conf->mtu = strtol(optarg, &endptr, 10); + if (*endptr || conf->mtu < 576) + exit_error(ctx, "invalid mtu `%s'", optarg); + break; + + case 'P': + if (!strcmp(optarg, "ethernet")) + conf->protocol = PROTOCOL_ETHERNET; + else if (!strcmp(optarg, "ip")) + conf->protocol = PROTOCOL_IP; + else + exit_error(ctx, "invalid protocol `%s'", optarg); + break; + + case 'm': + if (!strcmp(optarg, "null")) + conf->method = &fastd_method_null; + else + exit_error(ctx, "invalid method `%s'", optarg); + break; - conf->peers = malloc(sizeof(fastd_peer_config)); - conf->peers->next = NULL; - conf->peers->address = inet_addr("172.22.184.1"); - conf->peers->port = htons(1337); + case 'p': + *current_peer = malloc(sizeof(fastd_peer_config)); + (*current_peer)->next = NULL; - ctx->peers = NULL; + charptr = strchr(optarg, ':'); + if (charptr) { + addrstr = strndup(optarg, charptr-optarg); + } + else { + addrstr = optarg; + } + + if (inet_pton(AF_INET, addrstr, &addr) != 1) { + exit_error(ctx, "invalid bind address `%s'", addrstr); + } + + (*current_peer)->address = addr.s_addr; + + if (charptr) { + l = strtol(charptr+1, &endptr, 10); + if (*endptr || l > 65535) + exit_error(ctx, "invalid bind port `%s'", charptr+1); + (*current_peer)->port = htons(l); + + free(addrstr); + } + else { + (*current_peer)->port = htons(1337); // Default port + } + + current_peer = &(*current_peer)->next; + + break; + + case '?': + exit(1); + + default: + abort(); + } + } + + if (!conf->peers) { + exit_error(ctx, "no peers have been configured"); + } } static void init_peers(fastd_context *ctx) { @@ -277,12 +396,12 @@ static void handle_input(fastd_context *ctx) { } -int main() { +int main(int argc, char *argv[]) { fastd_context ctx; memset(&ctx, 0, sizeof(ctx)); fastd_config conf; - configure(&ctx, &conf); + configure(&ctx, &conf, argc, argv); ctx.conf = &conf; init_peers(&ctx); diff --git a/src/fastd.h b/src/fastd.h index 2d372a2..59fdf90 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -127,17 +127,19 @@ struct _fastd_context { }; -#define pr_log(context, level, args...) if ((context)->conf == NULL || (level) <= (context)->conf->loglevel) do { fprintf(stderr, args); fputs("\n", stderr); } while(0) +#define pr_log(context, level, prefix, args...) if ((context)->conf == NULL || (level) <= (context)->conf->loglevel) \ + do { fputs(prefix, stderr); fprintf(stderr, args); fputs("\n", stderr); } while(0) -#define pr_fatal(context, args...) pr_log(context, LOG_FATAL, args) -#define pr_error(context, args...) pr_log(context, LOG_ERROR, args) -#define pr_warn(context, args...) pr_log(context, LOG_WARN, args) -#define pr_info(context, args...) pr_log(context, LOG_INFO, args) -#define pr_debug(context, args...) pr_log(context, LOG_DEBUG, args) +#define pr_fatal(context, args...) pr_log(context, LOG_FATAL, "Fatal: ", args) +#define pr_error(context, args...) pr_log(context, LOG_ERROR, "Error: ", args) +#define pr_warn(context, args...) pr_log(context, LOG_WARN, "Warning: ", args) +#define pr_info(context, args...) pr_log(context, LOG_INFO, "", args) +#define pr_debug(context, args...) pr_log(context, LOG_DEBUG, "DEBUG: ", args) -#define exit_fatal(context, args...) do { pr_fatal(context, args); exit(1); } while(0) +#define exit_fatal(context, args...) do { pr_fatal(context, args); abort(); } while(0) #define exit_bug(context, message) exit_fatal(context, "BUG: %s", message) -#define exit_errno(context, message) exit_fatal(context, "%s: %s", message, strerror(errno)) +#define exit_error(context, args...) do { pr_error(context, args); exit(1); } while(0) +#define exit_errno(context, message) exit_error(context, "%s: %s", message, strerror(errno)) static inline fastd_buffer fastd_buffer_alloc(size_t len, size_t head_space) { -- cgit v1.2.3