Skip to content

Commit

Permalink
improve configuration and command line usage for meshd-nl80211
Browse files Browse the repository at this point in the history
Specifically, use libconfig to support a single unified config
file, add a meshd configuration structure similar to those of
ampe and sae, add a -h option, and improve usage message.
  • Loading branch information
bcavgnolo committed Aug 4, 2011
1 parent 9806e84 commit eac2699
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 40 deletions.
1 change: 1 addition & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#define MESHD_11a 1
#define MESHD_11b 2
#define MESHD_11g 3
#define MESHD_MAX_SSID_LEN 32
int parse_buffer(char *, char **);

#define SAE_DEBUG_ERR 0x01
Expand Down
23 changes: 23 additions & 0 deletions config/authsae.sample.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* this is a comment */
authsae:
{
sae:
{
debug = 480;
password = "thisisreallysecret";
group = [19, 26, 21, 25, 20];
blacklist = 5;
thresh = 5;
lifetime = 3600;
};
meshd:
{
meshid = "byteme";
interface = "wlan0";
passive = 0;
debug = 1;
mediaopt = 1;
band = "11g";
channel = 1;
};
};
7 changes: 3 additions & 4 deletions linux/Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
#
CC ?= gcc
CFLAGS += -g -DLINUX -Wall -Werror -I../../openssl-1.0.0-beta2/include -I..
LIBS= -L../../openssl-1.0.0-beta2
LDFLAGS +=-lnl -lnl-genl -lcrypto -L/usr/local/lib -L.
LDFLAGS += -L../../openssl-1.0.0-beta2 -L/usr/local/lib -L.
PREFIX ?= /usr/

all: meshd meshd-nl80211 mon

meshd: meshd.o ../common.o ../sae.o ../service.o ../ampe.o ../crypto/aes_siv.o
$(CC) -o meshd meshd.o ../common.o ../sae.o ../service.o ../ampe.o ../crypto/aes_siv.o $(LIBS) -lcrypto
$(CC) -o meshd meshd.o ../common.o ../sae.o ../service.o ../ampe.o ../crypto/aes_siv.o $(LDFLAGS) -lcrypto -lconfig

libsae.a: ../common.o ../sae.o ../service.o ../ampe.o ../crypto/aes_siv.o
ar rcs $@ $^

meshd-nl80211: meshd-nl80211.o nlutils.o libsae.a
$(CC) -o meshd-nl80211 meshd-nl80211.o nlutils.o -lsae $(LIBS) $(LDFLAGS)
$(CC) -o meshd-nl80211 meshd-nl80211.o nlutils.o $(LDFLAGS) -lsae -lnl -lnl-genl -lcrypto -lconfig

mon: mon.o ../service.o ../common.o
$(CC) -o mon mon.o ../service.o ../common.o
Expand Down
188 changes: 152 additions & 36 deletions linux/meshd-nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <libconfig.h>

#include "nlutils.h"

Expand Down Expand Up @@ -84,17 +85,23 @@
* callback when a station needs to change its state.
*/

/* Runtime config variables */
static char *ifname = NULL;

/* As defined in DATA_RATE row of table 6.5.5.2 of IEEE802.11mb */
static char default_sup_rates[] = { 2, 3, 4, 5, 6, 9, 11, 12, 18, 22, 24, 27, 36, 44, 48, 54, 66, 72, 96, 108 };


struct mesh_config {
unsigned char id[32];
unsigned char len;
} meshcfg;
/* TODO: this should be in a separate file where it can be used by all the
* meshd implementations.
*/
struct meshd_config {
char interface[IFNAMSIZ + 1];
char meshid[MESHD_MAX_SSID_LEN + 1];
int meshid_len;
int passive;
int beacon;
int mediaopt;
int channel;
int band;
int debug;
} meshd_conf;

static struct netlink_config_s nlcfg;
service_context srvctx;
Expand Down Expand Up @@ -238,8 +245,8 @@ static int new_candidate_handler(struct nl_msg *msg, void *arg)
sae_debug(MESHD_DEBUG, "No RSN IE from this candidate\n");
return NL_SKIP;
}
if (elems.mesh_id == NULL || elems.mesh_id_len != meshcfg.len ||
memcmp(elems.mesh_id, meshcfg.id, meshcfg.len) != 0) {
if (elems.mesh_id == NULL || elems.mesh_id_len != meshd_conf.meshid_len ||
memcmp(elems.mesh_id, meshd_conf.meshid, meshd_conf.meshid_len) != 0) {
sae_debug(MESHD_DEBUG, "Candidate from different Mesh ID\n");
return NL_SKIP;
}
Expand Down Expand Up @@ -527,8 +534,15 @@ static int install_key(struct netlink_config_s *nlcfg, unsigned char *peer, unsi
static void usage(void)
{
sae_debug(MESHD_DEBUG, "\n\n"
"usage:\n"
" meshd-nl80211 [-B] [-i<ifname>]\n\n");
"usage: meshd-nl80211 [options]\n\n"
" -h print this message\n"
" -c <conffile> configuration file (see authsae.sample.conf for examle)\n"
" -o <outfile> output log file\n"
" -B run in the background (i.e., daemonize)\n"
" -i <interface> override interface value in config file\n"
" -m <meshid> override mesh id provided in config file\n"
""
);
}

static int event_handler(struct nl_msg *msg, void *arg)
Expand Down Expand Up @@ -1000,27 +1014,82 @@ void term_handle(int i)
exit(1);
}

/* TODO: This config stuff should be in a common file to be shared by other
* meshd implementations
*/

static int
meshd_parse_libconfig (struct config_setting_t *meshd_section,
struct meshd_config *config)
{
char *str;

memset(config, 0, sizeof(struct meshd_config));

if (config_setting_lookup_string(meshd_section, "interface", (const char **)&str)) {
strncpy(config->interface, str, IFNAMSIZ + 1);
if (config->interface[IFNAMSIZ] != 0) {
fprintf(stderr, "Interface name is too long\n");
return -1;
}
}

if (config_setting_lookup_string(meshd_section, "meshid", (const char **)&str)) {
strncpy(config->meshid, str, MESHD_MAX_SSID_LEN);
if (config->meshid[MESHD_MAX_SSID_LEN] != 0) {
fprintf(stderr, "WARNING: Truncating meshid\n");
config->meshid[MESHD_MAX_SSID_LEN] = 0;
}
config->meshid_len = strlen(config->meshid);
}

config_setting_lookup_int(meshd_section, "passive", (long int *)&config->passive);
config_setting_lookup_int(meshd_section, "beacon", (long int *)&config->beacon);
config_setting_lookup_int(meshd_section, "debug", (long int *)&config->debug);
config_setting_lookup_int(meshd_section, "mediaopt", (long int *)&config->mediaopt);
config_setting_lookup_int(meshd_section, "channel", (long int *)&config->channel);
config->band = MESHD_11b;

if (config_setting_lookup_string(meshd_section, "band", (const char **)&str)) {
if (strncmp(str, "11a", 3) == 0) {
config->band = MESHD_11a;
} else if (strncmp(str, "11b", 3) == 0) {
config->band = MESHD_11b;
} else if (strncmp(str, "11g", 3) == 0) {
config->band = MESHD_11g;
} else {
fprintf(stderr, "Invalid meshd band %s\n", str);
}
}

return 0;
}

int main(int argc, char *argv[])
{
int c;
int exitcode = 0;
char *mesh_id;
char *mesh_id = NULL;
struct nl_sock *nlsock;
int daemonize = 0;
char *outfile = NULL;
char confdir[80];
struct sae_config config;
char *conffile = NULL;
struct sae_config sae_conf;
struct ampe_config ampe_conf;
char *ifname = NULL;

signal(SIGTERM, term_handle);

memset(&nlcfg, 0, sizeof(nlcfg));

for (;;) {
c = getopt(argc, argv, "I:o:Bi:s:f:");
c = getopt(argc, argv, "hc:o:Bi:s:");
if (c < 0)
break;
switch (c) {
case 'h':
usage();
return 0;
case 'B':
daemonize = 1;
break;
Expand All @@ -1029,42 +1098,88 @@ int main(int argc, char *argv[])
break;
case 'i':
ifname = optarg;
nlcfg.ifindex = if_nametoindex(ifname);
break;
case 'f':
nlcfg.freq = atoi(optarg);
break;
case 's':
mesh_id = optarg;
break;
case 'I':
strncpy(confdir, optarg, sizeof(confdir));
case 'c':
conffile = optarg;
break;
default:
usage();
goto out;
}
}

if (ifname == NULL || confdir == NULL) {
usage();
exitcode = -EINVAL;
goto out;
if (conffile) {
struct config_t cfg;
struct config_setting_t *section;

config_init(&cfg);
if (!config_read_file(&cfg, conffile)) {
fprintf(stderr, "Failed to load config file %s: %s\n", conffile,
config_error_text(&cfg));
return -1;
}
section = config_lookup(&cfg, "authsae.sae");
if (section == NULL) {
fprintf(stderr, "Config file has not sae section\n");
return -1;
}

if (sae_parse_libconfig(section, &sae_conf) != 0) {
fprintf(stderr, "Failed to parse SAE configuration.\n");
return -1;
}

section = config_lookup(&cfg, "authsae.meshd");
if (section == NULL) {
fprintf(stderr, "Config file has not meshd section\n");
return -1;
}
if (meshd_parse_libconfig(section, &meshd_conf) != 0) {
fprintf(stderr, "Failed to parse meshd configuration.\n");
return -1;
}

config_destroy(&cfg);
}

/* command line args override config file */
if (mesh_id) {
if (strlen(mesh_id) > MESHD_MAX_SSID_LEN) {
fprintf(stderr, "mesh id %s is too long\n", mesh_id);
return -1;
}
strcpy(meshd_conf.meshid, mesh_id);
meshd_conf.meshid_len = strlen(mesh_id);
}

if (ifname) {
if (strlen(ifname) > IFNAMSIZ) {
fprintf(stderr, "ifname %s is too long\n", ifname);
return -1;
}
strcpy(meshd_conf.interface, ifname);
}
nlcfg.ifindex = if_nametoindex(meshd_conf.interface);

/* default to channel 1 */
if (meshd_conf.channel == 0)
meshd_conf.channel = 1;

if (! nlcfg.freq)
nlcfg.freq = 2412; /* default to channel 1 */
nlcfg.freq = 2412;

/* TODO: Check if ifname is of type mesh and if it's up.
* For now this is assumed to be true.
*/

exitcode = get_mac_addr(ifname, nlcfg.mymacaddr);
exitcode = get_mac_addr(meshd_conf.interface, nlcfg.mymacaddr);
if (exitcode)
goto out;

sae_parse_config(confdir, &config);
if (sae_initialize(mesh_id, &config) < 0) {
if (sae_initialize(meshd_conf.meshid, &sae_conf) < 0) {
fprintf(stderr, "%s: cannot configure SAE, check config file!\n", argv[0]);
exit(1);
}
Expand All @@ -1078,7 +1193,7 @@ int main(int argc, char *argv[])
memset(ampe_conf.rates, 0, sizeof(ampe_conf.rates));
memcpy(ampe_conf.rates, default_sup_rates, sizeof(default_sup_rates));

if (ampe_initialize((unsigned char *) mesh_id, strlen(mesh_id),
if (ampe_initialize((unsigned char *)meshd_conf.meshid, meshd_conf.meshid_len,
&ampe_conf) < 0) {
fprintf(stderr, "%s: cannot configure AMPE!\n", argv[0]);
exit(1);
Expand Down Expand Up @@ -1121,16 +1236,17 @@ int main(int argc, char *argv[])
}

leave_mesh(&nlcfg);
exitcode = join_mesh_rsn(&nlcfg, mesh_id, strlen(mesh_id));
if (exitcode)
exitcode = join_mesh_rsn(&nlcfg, meshd_conf.meshid, meshd_conf.meshid_len);
if (exitcode) {
fprintf(stderr, "Failed to join mesh\n");
goto out;

meshcfg.len = strlen(mesh_id);
memcpy(meshcfg.id, mesh_id, meshcfg.len);
}

request_mesh_caps(&nlcfg);

srv_main_loop(srvctx);
out:
if (exitcode != 0)
fprintf(stderr, "Failed: %d\n", exitcode);
return exitcode;
}
36 changes: 36 additions & 0 deletions sae.c
Original file line number Diff line number Diff line change
Expand Up @@ -2003,6 +2003,42 @@ sae_parse_config (char *confdir, struct sae_config* config)
return 0;
}

int
sae_parse_libconfig (struct config_setting_t *sae_section, struct sae_config* config)
{
struct config_setting_t *setting, *group;
char *pwd;

memset(config, 0, sizeof(struct sae_config));
config_setting_lookup_int(sae_section, "debug", (long int *)&config->debug);
setting = config_setting_get_member(sae_section, "group");
if (setting != NULL) {
while (1) {
group = config_setting_get_elem(setting, config->num_groups);
if (!group)
break;
config->group[config->num_groups] =
config_setting_get_int_elem(setting, config->num_groups);
config->num_groups++;
if (config->num_groups == SAE_MAX_EC_GROUPS)
break;
}
}
if (config_setting_lookup_string(sae_section, "password", (const char **)&pwd)) {
strncpy(config->pwd, pwd, SAE_MAX_PASSWORD_LEN);
if (config->pwd[SAE_MAX_PASSWORD_LEN - 1] != 0) {
fprintf(stderr, "WARNING: Truncating password\n");
config->pwd[SAE_MAX_PASSWORD_LEN - 1] = 0;
}
}
config_setting_lookup_int(sae_section, "retrans", (long int *)&config->retrans);
config_setting_lookup_int(sae_section, "lifetime", (long int *)&config->pmk_expiry);
config_setting_lookup_int(sae_section, "thresh", (long int *)&config->open_threshold);
config_setting_lookup_int(sae_section, "blacklist", (long int *)&config->blacklist_timeout);
config_setting_lookup_int(sae_section, "giveup", (long int *)&config->giveup_threshold);
return 0;
}

void
sae_dump_db (int unused)
{
Expand Down
Loading

0 comments on commit eac2699

Please sign in to comment.