return NL_SKIP;
}
-
-
-static int ack_wait_handler(struct nl_msg *msg, void *arg)
-{
- int *finished = arg;
-
- *finished = 1;
- return NL_STOP;
-}
-
-static int handle_info(struct nl80211_state *state,
+static int handle_info(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- int err = -ENOMEM;
- struct nl_cb *cb;
- int finished;
-
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if (nl_send_auto_complete(state->nl_handle, msg) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_phy_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
- out:
- nl_cb_put(cb);
- return err;
+ return 0;
}
TOPLEVEL(info, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_info);
TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info);
return -1;
}
-static int handle_interface_add(struct nl80211_state *state,
+static int handle_interface_add(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
char *name;
char *mesh_id = NULL;
enum nl80211_iftype type;
- int tpset, err = -ENOBUFS;
+ int tpset;
if (argc < 1)
return 1;
if (mesh_id)
NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id);
- err = nl_send_auto_complete(state->nl_handle, msg);
- if (err > 0)
- err = nl_wait_for_ack(state->nl_handle);
-
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>]",
NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add);
COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>]",
NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add);
-static int handle_interface_del(struct nl80211_state *state,
+static int handle_interface_del(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- int err;
-
- err = nl_send_auto_complete(state->nl_handle, msg);
- if (err > 0)
- err = nl_wait_for_ack(state->nl_handle);
-
- return err;
+ return 0;
}
TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del);
return NL_SKIP;
}
-static int ack_wait_handler(struct nl_msg *msg, void *arg)
-{
- int *finished = arg;
-
- *finished = 1;
- return NL_STOP;
-}
-
-static int handle_interface_info(struct nl80211_state *state,
+static int handle_interface_info(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- int err = -ENOBUFS;
- struct nl_cb *cb = NULL;
- int finished = 0;
-
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- err = nl_send_auto_complete(state->nl_handle, msg);
- if (err)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
- return err;
+ return 0;
}
TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info);
return atoi(buf);
}
+static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+ void *arg)
+{
+ int *ret = arg;
+ *ret = err->error;
+ return NL_STOP;
+}
+
+static int wait_handler(struct nl_msg *msg, void *arg)
+{
+ int *ret = arg;
+ *ret = 0;
+ return NL_STOP;
+}
+
static int handle_cmd(struct nl80211_state *state,
enum command_identify_by idby,
int argc, char **argv)
{
struct cmd *cmd;
+ struct nl_cb *cb = NULL;
struct nl_msg *msg;
int devidx = 0;
+ int err;
const char *command, *section;
if (argc <= 1 && idby != CIB_NONE)
msg = nlmsg_alloc();
if (!msg) {
- fprintf(stderr, "out of memory\n");
- return -ENOMEM;
+ fprintf(stderr, "failed to allocate netlink message\n");
+ return 2;
+ }
+
+ cb = nl_cb_alloc(NL_CB_CUSTOM);
+ if (!cb) {
+ fprintf(stderr, "failed to allocate netlink callbacks\n");
+ err = 2;
+ goto out_free_msg;
}
genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
break;
}
- return cmd->handler(state, msg, argc, argv);
+ err = cmd->handler(cb, msg, argc, argv);
+ if (err)
+ goto out;
+
+ err = nl_send_auto_complete(state->nl_handle, msg);
+ if (err < 0)
+ goto out;
+
+ nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+ nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &err);
+
+ err = 1;
+ nl_recvmsgs(state->nl_handle, cb);
+
+ if (err == 1)
+ err = nl_wait_for_ack(state->nl_handle);
+ out:
+ nl_cb_put(cb);
+ out_free_msg:
+ nlmsg_free(msg);
+ return err;
nla_put_failure:
fprintf(stderr, "building message failed\n");
- return -ENOMEM;
+ return 2;
}
int main(int argc, char **argv)
* zero on success, 1 if the arguments were wrong
* and the usage message should and 2 otherwise.
*/
- int (*handler)(struct nl80211_state *state,
+ int (*handler)(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv);
};
int mac_addr_a2n(unsigned char *mac_addr, char *arg);
int mac_addr_n2a(char *mac_addr, unsigned char *arg);
-int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
-
const char *iftype_name(enum nl80211_iftype iftype);
#endif /* __IW_H */
};
-static int wait_handler(struct nl_msg *msg, void *arg)
-{
- int *finished = arg;
-
- *finished = 1;
- return NL_STOP;
-}
-
static int print_mpath_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
return NL_SKIP;
}
-static int handle_mpath_get(struct nl80211_state *state,
+static int handle_mpath_get(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
unsigned char dst[ETH_ALEN];
if (argc < 1)
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if (nl_send_auto_complete(state->nl_handle, msg) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(mpath, get, "<MAC address>",
NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get);
COMMAND(mpath, del, "<MAC address>",
NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get);
-static int handle_mpath_set(struct nl80211_state *state,
+static int handle_mpath_set(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
unsigned char dst[ETH_ALEN];
unsigned char next_hop[ETH_ALEN];
if (argc)
return 1;
- msg = nlmsg_alloc();
- if (!msg)
- goto out;
-
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(mpath, new, "<destination MAC address> next_hop <next hop MAC address>",
NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set);
COMMAND(mpath, set, "<destination MAC address> next_hop <next hop MAC address>",
NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set);
-static int handle_mpath_dump(struct nl80211_state *state,
+static int handle_mpath_dump(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
-
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
- nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = finished;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
- return err;
+ return 0;
}
COMMAND(mpath, dump, NULL,
NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump);
#include "iw.h"
-static int handle_name(struct nl80211_state *state,
+static int handle_name(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- int err = -ENOMEM;
- struct nl_cb *cb;
-
if (argc != 1)
return 1;
NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, *argv);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
- goto out;
-
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name);
return 0;
}
-static int handle_reg_set(struct nl80211_state *state,
+static int handle_reg_set(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
char alpha2[3];
if (argc < 1)
NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- err = nl_send_auto_complete(state->nl_handle, msg);
-
- if (err < 0)
- goto out;
-
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>",
NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set);
};
-static int wait_handler(struct nl_msg *msg, void *arg)
-{
- int *finished = arg;
-
- *finished = 1;
- return NL_STOP;
-}
-
static int print_sta_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
return NL_SKIP;
}
-static int handle_station_get(struct nl80211_state *state,
+static int handle_station_get(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
unsigned char mac_addr[ETH_ALEN];
if (argc < 1)
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if (nl_send_auto_complete(state->nl_handle, msg) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(station, get, "<MAC address>",
NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get);
COMMAND(station, del, "<MAC address>",
NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get);
-static int handle_station_set(struct nl80211_state *state,
+static int handle_station_set(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
unsigned char plink_action;
unsigned char mac_addr[ETH_ALEN];
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action);
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
- goto out;
-
- nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
- nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = 0;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
+ return 0;
nla_put_failure:
- return err;
+ return -ENOBUFS;
}
COMMAND(station, set, "<MAC address> plink_action <open|block>",
NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set);
-static int handle_station_dump(struct nl80211_state *state,
+static int handle_station_dump(struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_cb *cb = NULL;
- int err = -ENOMEM;
- int finished = 0;
-
- if (argc)
- return 1;
-
- cb = nl_cb_alloc(NL_CB_CUSTOM);
- if (!cb)
- goto out;
-
- if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
- goto out;
-
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
- nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &finished);
- nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
-
- nl_recvmsgs(state->nl_handle, cb);
- err = finished;
-
- if (!finished)
- err = nl_wait_for_ack(state->nl_handle);
-
- out:
- nl_cb_put(cb);
- return err;
+ return 0;
}
COMMAND(station, dump, NULL,
NL80211_CMD_SET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump);