Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for authsae on adhoc interfaces #1

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ampe.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ struct meshd_config {
char interface[IFNAMSIZ + 1];
char meshid[MESHD_MAX_SSID_LEN + 1];
int meshid_len;
unsigned char bssid_string[MESHD_MAX_BSSID_LEN + 1];
unsigned char bssid[ETH_ALEN];
int using_bssid;
int using_adhoc;
int passive;
int beacon;
int mediaopt;
Expand Down
1 change: 1 addition & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#define MESHD_11b 2
#define MESHD_11g 3
#define MESHD_MAX_SSID_LEN 32
#define MESHD_MAX_BSSID_LEN 17
int parse_buffer(char *, char **);

#define SAE_DEBUG_ERR 0x01
Expand Down
181 changes: 132 additions & 49 deletions linux/meshd-nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,17 @@ static void srv_handler_wrapper(int fd, void *data)
static int tx_frame(struct netlink_config_s *nlcfg, struct mesh_node *mesh,
unsigned char *frame, int len)
{
struct ieee80211_mgmt_frame *sframe;
struct nl_msg *msg;
uint8_t cmd = NL80211_CMD_FRAME;
int ret = 0;
char *pret;

sframe = (struct ieee80211_mgmt_frame*)frame;

if (meshd_conf.using_bssid)
memcpy(sframe->bssid, meshd_conf.bssid, ETH_ALEN);

sae_debug(MESHD_DEBUG, "%s(%p, %p, %d)\n", __FUNCTION__, nlcfg, frame, len);
msg = nlmsg_alloc();
if (!msg)
Expand Down Expand Up @@ -556,7 +562,7 @@ static int new_candidate_handler(struct nl_msg *msg, void *arg)
return NL_SKIP;
}

static int register_for_plink_frames(struct netlink_config_s *nlcfg)
static int register_for_action_frames(struct netlink_config_s *nlcfg)
{
struct nl_msg *msg;
uint8_t cmd = NL80211_CMD_REGISTER_FRAME;
Expand Down Expand Up @@ -868,10 +874,12 @@ static int set_authenticated_flag(struct netlink_config_s *nlcfg, unsigned char

NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex);
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
flags.mask = flags.set = (1 << NL80211_STA_FLAG_AUTHENTICATED) |
if (!meshd_conf.using_adhoc)
flags.mask = flags.set = (1 << NL80211_STA_FLAG_AUTHENTICATED) |
(1 << NL80211_STA_FLAG_MFP) |
(1 << NL80211_STA_FLAG_AUTHORIZED);

else
flags.mask = flags.set = (1 << NL80211_STA_FLAG_AUTHORIZED);
NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(flags), &flags);


Expand Down Expand Up @@ -961,12 +969,32 @@ static int set_frequency(struct netlink_config_s *nlcfg, int freq)
}
#endif

static int leave_mesh(struct netlink_config_s *nlcfg)
/* given the channel, find the freq in megahertz. Borrowed from iw:
* Copyright (c) 2007, 2008 Johannes Berg
* Copyright (c) 2007 Andy Lutomirski
* Copyright (c) 2007 Mike Kershaw
* Copyright (c) 2008-2009 Luis R. Rodriguez
*/
static int channel_to_freq(int chan)
{
if (chan < 14)
return 2407 + chan * 5;

if (chan == 14)
return 2484;

/* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */
return (chan + 1000) * 5;
}

static int leave_network(struct netlink_config_s *nlcfg, struct meshd_config *mconf)
{
struct nl_msg *msg;
uint8_t cmd = NL80211_CMD_LEAVE_MESH;
uint8_t cmd = (!mconf->using_adhoc) ? NL80211_CMD_LEAVE_MESH :
NL80211_CMD_LEAVE_IBSS;
int ret;
char *pret;
char *network_kind = (!mconf->using_adhoc) ? "Mesh" : "IBSS";

msg = nlmsg_alloc();
if (!msg)
Expand All @@ -983,7 +1011,10 @@ static int leave_mesh(struct netlink_config_s *nlcfg)
nlcfg->supress_error = -ENOTCONN;
ret = send_nlmsg(nlcfg->nl_sock, msg);
if (ret < 0)
fprintf(stderr,"Mesh leave failed: %d (%s)\n", ret, strerror(-ret));
fprintf(stderr,"%s leave failed: %d (%s)\n",
network_kind,
ret,
strerror(-ret));
else
ret = 0;

Expand All @@ -992,14 +1023,18 @@ static int leave_mesh(struct netlink_config_s *nlcfg)
return -ENOBUFS;
}

static int join_mesh_rsn(struct netlink_config_s *nlcfg, struct meshd_config *mconf)
static int join_network(struct netlink_config_s *nlcfg,
struct meshd_config *mconf)
{
struct nl_msg *msg;
uint8_t cmd = NL80211_CMD_JOIN_MESH;
uint8_t cmd = (!mconf->using_adhoc) ? NL80211_CMD_JOIN_MESH :
NL80211_CMD_JOIN_IBSS;
uint8_t basic_rates[MAX_SUPP_RATES];
int rates = 0, i;
int ret;
char *pret;
struct nlattr *container = NULL;
char *network_kind = (!mconf->using_adhoc) ? "Mesh" : "IBSS";

assert(rsn_ie[1] == sizeof(rsn_ie) - 2);

Expand All @@ -1010,7 +1045,10 @@ static int join_mesh_rsn(struct netlink_config_s *nlcfg, struct meshd_config *mc
if (!mconf->meshid || !mconf->meshid_len)
return -EINVAL;

sae_debug(MESHD_DEBUG, "meshd: Starting mesh with mesh id = %s\n", mconf->meshid);
sae_debug(MESHD_DEBUG, "meshd: Starting %s with %s id = %s\n",
network_kind,
network_kind,
mconf->meshid);

pret = genlmsg_put(msg, 0, 0,
genl_family_get_id(nlcfg->nl80211), 0, 0, cmd, 0);
Expand All @@ -1029,36 +1067,58 @@ static int join_mesh_rsn(struct netlink_config_s *nlcfg, struct meshd_config *mc
sae_hexdump(MESHD_DEBUG, "basic rates:", basic_rates, rates);
NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates, basic_rates);

struct nlattr *container = nla_nest_start(msg,
if (!mconf->using_adhoc)
{
/*
* configure appropriately for mesh mode.
*/
container = nla_nest_start(msg,
NL80211_ATTR_MESH_CONFIG);
if (!container)
return -ENOBUFS;

if (!container)
return -ENOBUFS;
NLA_PUT_U32(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 0);
nla_nest_end(msg, container);

NLA_PUT_U32(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 0);
nla_nest_end(msg, container);
container = nla_nest_start(msg,
NL80211_ATTR_MESH_SETUP);

container = nla_nest_start(msg,
NL80211_ATTR_MESH_SETUP);

if (!container)
return -ENOBUFS;
if (!container)
return -ENOBUFS;

/* We'll be creating stations, not the kernel */
NLA_PUT_FLAG(msg, NL80211_MESH_SETUP_USERSPACE_AUTH);
/* We'll be creating stations, not the kernel */
NLA_PUT_FLAG(msg, NL80211_MESH_SETUP_USERSPACE_AUTH);

/* We'll handle peer state transitions */
NLA_PUT_FLAG(msg, NL80211_MESH_SETUP_USERSPACE_AMPE);
/* We'll handle peer state transitions */
NLA_PUT_FLAG(msg, NL80211_MESH_SETUP_USERSPACE_AMPE);

NLA_PUT(msg, NL80211_MESH_SETUP_IE, sizeof(rsn_ie), rsn_ie);
nla_nest_end(msg, container);
NLA_PUT(msg, NL80211_MESH_SETUP_IE, sizeof(rsn_ie), rsn_ie);
nla_nest_end(msg, container);

NLA_PUT(msg, NL80211_ATTR_MESH_ID, mconf->meshid_len, mconf->meshid);
}
else
{
/*
* configure appropriately for adhoc mode.
*/
NLA_PUT_U32(msg,
NL80211_ATTR_WIPHY_FREQ,
channel_to_freq(mconf->channel));
NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
NLA_PUT(msg, NL80211_ATTR_SSID, mconf->meshid_len, mconf->meshid);
NLA_PUT(msg, NL80211_ATTR_MAC, 6, mconf->bssid);
NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
}

NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, nlcfg->ifindex);
NLA_PUT(msg, NL80211_ATTR_MESH_ID, mconf->meshid_len, mconf->meshid);

ret = send_nlmsg(nlcfg->nl_sock, msg);
if (ret < 0)
fprintf(stderr,"Mesh start failed: %d (%s)\n", ret, strerror(-ret));
fprintf(stderr,"%s start failed: %d (%s)\n",
network_kind,
ret,
strerror(-ret));
else
ret = 0;

Expand Down Expand Up @@ -1153,6 +1213,46 @@ meshd_parse_libconfig (struct config_setting_t *meshd_section,
config->meshid_len = strlen(config->meshid);
}

if (config_setting_lookup_string(meshd_section, "bssid", (const char**)&str)) {
char *str_copy = NULL;
char *tok = NULL;
unsigned int pos = 0;

config->using_bssid = 1;
config->using_adhoc = 1;

str_copy = (char*)malloc(sizeof(char)*(strlen(str)+1));
memset(str_copy, 0, sizeof(char)*(strlen(str)+1));
memcpy(str_copy, str, sizeof(char)*(strlen(str)+1));
if (tok = strtok(str_copy, ":"))
{
do {
/*
* add the tok.
*/
long unsigned int conversion = 0;
unsigned char byte;

conversion = strtol(tok, NULL, 16);
if (conversion > 0xff)
{
config->using_bssid = 0;
config->using_adhoc = 0;
fprintf(stderr,"Invalid BSSID (%s). Not using one.\n", tok);
break;
}

byte = (unsigned char)conversion;
config->bssid[pos++] = byte;
} while ((tok = strtok(NULL, ":")) && pos < 6);
}
if (config->using_bssid)
{
memcpy(config->bssid_string,str_copy,sizeof(char)*(strlen(str)+1));
}
free(str_copy);
}

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);
Expand Down Expand Up @@ -1190,24 +1290,6 @@ meshd_parse_libconfig (struct config_setting_t *meshd_section,
return 0;
}

/* given the channel, find the freq in megahertz. Borrowed from iw:
* Copyright (c) 2007, 2008 Johannes Berg
* Copyright (c) 2007 Andy Lutomirski
* Copyright (c) 2007 Mike Kershaw
* Copyright (c) 2008-2009 Luis R. Rodriguez
*/
static int channel_to_freq(int chan)
{
if (chan < 14)
return 2407 + chan * 5;

if (chan == 14)
return 2484;

/* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */
return (chan + 1000) * 5;
}

static int init(struct netlink_config_s *nlcfg, struct mesh_node *mesh)
{
int exitcode = 0;
Expand All @@ -1233,18 +1315,19 @@ static int init(struct netlink_config_s *nlcfg, struct mesh_node *mesh)
exit(EXIT_FAILURE);
}

leave_mesh(nlcfg);
exitcode = join_mesh_rsn(nlcfg, mesh->conf);
leave_network(nlcfg, mesh->conf);
exitcode = join_network(nlcfg, mesh->conf);

if (exitcode) {
fprintf(stderr, "Failed to join mesh\n");
fprintf(stderr, "Failed to join network\n");
goto out;
}

exitcode = register_for_auth_frames(nlcfg);
if (exitcode)
goto out;

exitcode = register_for_plink_frames(nlcfg);
exitcode = register_for_action_frames(nlcfg);
if (exitcode) {
fprintf(stderr, "cannot register for plink frame!\n");
goto out;
Expand Down
28 changes: 27 additions & 1 deletion linux/nlutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,32 @@

#include "nlutils.h"

static char *cmd_to_string(uint8_t cmd)
{
#define CASE(X) \
case X: \
return #X;

switch (cmd)
{
CASE(NL80211_CMD_FRAME)
CASE(NL80211_CMD_SET_MESH_CONFIG)
CASE(NL80211_CMD_SET_CHANNEL)
CASE(NL80211_CMD_NEW_STATION)
CASE(NL80211_CMD_REGISTER_FRAME)
CASE(NL80211_CMD_GET_WIPHY)
CASE(NL80211_CMD_NEW_KEY)
CASE(NL80211_CMD_SET_KEY)
CASE(NL80211_CMD_SET_STATION)
CASE(NL80211_CMD_LEAVE_MESH)
CASE(NL80211_CMD_JOIN_MESH)
CASE(NL80211_CMD_JOIN_IBSS)
CASE(NL80211_CMD_LEAVE_IBSS)
default:
return "No match";
}
}

static int ack_handler(struct nl_msg *msg, void *arg)
{
int *err = arg;
Expand All @@ -45,7 +71,7 @@ static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
fprintf(stderr, "Unexpected error %d ", err->error);
fprintf(stderr, "(expected %d)\n", nlcfg->supress_error);
} else {
fprintf(stderr, "nlerror, cmd %d, seq %d: %s\n", gnlh->cmd, err->msg.nlmsg_seq,
fprintf(stderr, "nlerror, cmd %s, seq %d: %s\n", cmd_to_string(gnlh->cmd), err->msg.nlmsg_seq,
strerror(abs(err->error)));
}
nlcfg->supress_error = 0;
Expand Down