return __listen_events(state, 0, NULL, &args);
}
-TOPLEVEL(event, "[-t] [-f]", 0, 0, CIB_NONE, print_events);
+TOPLEVEL(event, "[-t] [-f]", 0, 0, CIB_NONE, print_events,
+ "Monitor events from the kernel.\n"
+ "-t - print timestamp\n"
+ "-f - print full frame for auth/assoc etc.");
return 0;
}
COMMAND(ibss, leave, NULL,
- NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss);
+ NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss, NULL);
COMMAND(ibss, join, "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>]",
- NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss);
+ NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss, NULL);
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);
-TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info);
+TOPLEVEL(info, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_info, NULL);
+TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL);
+TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL);
return -ENOBUFS;
}
COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags ...]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add);
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add, NULL);
COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags ...]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add);
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL);
static int handle_interface_del(struct nl80211_state *state,
struct nl_cb *cb,
{
return 0;
}
-TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del);
+TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del, NULL);
HIDDEN(interface, del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del);
static int print_iface_handler(struct nl_msg *msg, void *arg)
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL);
return 0;
}
-TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info);
+TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info, NULL);
static int handle_interface_set(struct nl80211_state *state,
struct nl_cb *cb,
return -ENOBUFS;
}
COMMAND(set, monitor, "<flag> [...]",
- NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set);
+ NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set, NULL);
static int handle_interface_meshid(struct nl80211_state *state,
struct nl_cb *cb,
return -ENOBUFS;
}
COMMAND(set, meshid, "<meshid>",
- NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_meshid);
+ NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_meshid, NULL);
static unsigned int dev_dump_wiphy;
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, &dev_dump_wiphy);
return 0;
}
-TOPLEVEL(dev, NULL, NL80211_CMD_GET_INTERFACE, NLM_F_DUMP, CIB_NONE, handle_dev_dump);
+TOPLEVEL(dev, NULL, NL80211_CMD_GET_INTERFACE, NLM_F_DUMP, CIB_NONE, handle_dev_dump, NULL);
static int handle_interface_type(struct nl80211_state *state,
struct nl_cb *cb,
return -ENOBUFS;
}
COMMAND(set, type, "<type>",
- NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_type);
+ NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_type, NULL);
nl_socket_free(state->nl_sock);
}
-__COMMAND(NULL, NULL, "", NULL, 0, 0, 0, CIB_NONE, NULL);
-__COMMAND(NULL, NULL, "", NULL, 1, 0, 0, CIB_NONE, NULL);
+__COMMAND(NULL, NULL, "", NULL, 0, 0, 0, CIB_NONE, NULL, NULL);
+__COMMAND(NULL, NULL, "", NULL, 1, 0, 0, CIB_NONE, NULL, NULL);
static int cmd_size;
-static void __usage_cmd(struct cmd *cmd, char *indent)
+static void __usage_cmd(struct cmd *cmd, char *indent, bool full)
{
+ const char *start, *lend, *end;
+
fprintf(stderr, "%s", indent);
switch (cmd->idby) {
if (cmd->args)
fprintf(stderr, " %s", cmd->args);
fprintf(stderr, "\n");
+
+ if (!full || !cmd->help)
+ return;
+
+ /* hack */
+ if (strlen(indent))
+ indent = "\t\t";
+ else
+ fprintf(stderr, "\n");
+
+ /* print line by line */
+ start = cmd->help;
+ end = strchr(start, '\0');
+ do {
+ lend = strchr(start, '\n');
+ if (!lend)
+ lend = end;
+ fprintf(stderr, "%s", indent);
+ fprintf(stderr, "%.*s\n", (int)(lend - start), start);
+ start = lend + 1;
+ } while (end != lend);
+
+ fprintf(stderr, "\n");
}
static void usage_options(void)
fprintf(stderr, "\t--debug\t\tenable netlink debugging\n");
}
-static void usage(const char *argv0)
+static const char *argv0;
+
+static void usage(bool full)
{
struct cmd *cmd;
usage_options();
fprintf(stderr, "\t--version\tshow version\n");
fprintf(stderr, "Commands:\n");
- fprintf(stderr, "\thelp\n");
for (cmd = &__start___cmd; cmd < &__stop___cmd;
cmd = (struct cmd *)((char *)cmd + cmd_size)) {
if (!cmd->handler || cmd->hidden)
continue;
- __usage_cmd(cmd, "\t");
+ __usage_cmd(cmd, "\t", full);
}
}
-static void usage_cmd(const char *argv0, struct cmd *cmd)
+static int print_help(struct nl80211_state *state,
+ struct nl_cb *cb,
+ struct nl_msg *msg,
+ int argc, char **argv)
+{
+ exit(3);
+}
+TOPLEVEL(help, NULL, 0, 0, CIB_NONE, print_help,
+ "Print usage for each command.");
+
+static void usage_cmd(struct cmd *cmd)
{
fprintf(stderr, "Usage:\t%s [options] ", argv0);
- __usage_cmd(cmd, "");
+ __usage_cmd(cmd, "", true);
usage_options();
}
{
struct nl80211_state nlstate;
int err;
- const char *argv0;
struct cmd *cmd = NULL;
/* calculate command size including padding */
return 0;
}
+ /* need to treat "help" command specially so it works w/o nl80211 */
if (argc == 0 || strcmp(*argv, "help") == 0) {
- usage(argv0);
+ usage(argc != 0);
return 0;
}
if (err == 1) {
if (cmd)
- usage_cmd(argv0, cmd);
+ usage_cmd(cmd);
else
- usage(argv0);
+ usage(false);
} else if (err < 0)
fprintf(stderr, "command failed: %s (%d)\n", strerror(-err), err);
const char *section;
const char *name;
const char *args;
+ const char *help;
const enum nl80211_commands cmd;
int nl_msg_flags;
int hidden;
#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0]))
-#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler)\
+#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help)\
static const struct cmd \
__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
__attribute__((used)) __attribute__((section("__cmd"))) = { \
.hidden = (_hidden), \
.idby = (_idby), \
.handler = (_handler), \
+ .help = (_help), \
}
-#define COMMAND(section, name, args, cmd, flags, idby, handler) \
- __COMMAND(#section, name, #name, args, cmd, flags, 0, idby, handler)
-#define HIDDEN(section, name, args, cmd, flags, idby, handler) \
- __COMMAND(#section, name, #name, args, cmd, flags, 1, idby, handler)
-#define TOPLEVEL(name, args, cmd, flags, idby, handler) \
- __COMMAND(NULL, name, #name, args, cmd, flags, 0, idby, handler)
+#define COMMAND(section, name, args, cmd, flags, idby, handler, help) \
+ __COMMAND(#section, name, #name, args, cmd, flags, 0, idby, handler, help)
+#define HIDDEN(section, name, args, cmd, flags, idby, handler) \
+ __COMMAND(#section, name, #name, args, cmd, flags, 1, idby, handler, NULL)
+#define TOPLEVEL(name, args, cmd, flags, idby, handler, help) \
+ __COMMAND(NULL, name, #name, args, cmd, flags, 0, idby, handler, help)
extern struct cmd __start___cmd;
extern struct cmd __stop___cmd;
}
COMMAND(set, mesh_param, "<param> <value>",
- NL80211_CMD_SET_MESH_PARAMS, 0, CIB_NETDEV, set_interface_meshparam);
+ NL80211_CMD_SET_MESH_PARAMS, 0, CIB_NETDEV, set_interface_meshparam, NULL);
/* Getter */
static int print_mesh_param_handler(struct nl_msg *msg, void *arg)
}
COMMAND(get, mesh_param, "<param>",
- NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam);
+ NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam, NULL);
return -ENOBUFS;
}
COMMAND(mpath, get, "<MAC address>",
- NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get);
+ NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get, NULL);
COMMAND(mpath, del, "<MAC address>",
- NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get);
+ NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get, NULL);
static int handle_mpath_set(struct nl80211_state *state,
struct nl_cb *cb,
return -ENOBUFS;
}
COMMAND(mpath, new, "<destination MAC address> next_hop <next hop MAC address>",
- NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set);
+ NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set, NULL);
COMMAND(mpath, set, "<destination MAC address> next_hop <next hop MAC address>",
- NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set);
+ NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set, NULL);
static int handle_mpath_dump(struct nl80211_state *state,
struct nl_cb *cb,
return 0;
}
COMMAND(mpath, dump, NULL,
- NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump);
+ NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump, NULL);
nla_put_failure:
return -ENOBUFS;
}
-COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name);
+COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name, NULL);
static int handle_freqchan(struct nl_msg *msg, bool chan,
int argc, char **argv)
return handle_freqchan(msg, false, argc, argv);
}
COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]",
- NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq);
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq, NULL);
COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]",
- NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq);
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL);
static int handle_chan(struct nl80211_state *state,
struct nl_cb *cb, struct nl_msg *msg,
return handle_freqchan(msg, true, argc, argv);
}
COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]",
- NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan);
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan, NULL);
COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]",
- NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan);
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL);
return -ENOBUFS;
}
COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>",
- NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set);
+ NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set, NULL);
static int print_reg_handler(struct nl_msg *msg, void *arg)
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_reg_handler, NULL);
return 0;
}
-COMMAND(reg, get, NULL, NL80211_CMD_GET_REG, 0, CIB_NONE, handle_reg_get);
+COMMAND(reg, get, NULL, NL80211_CMD_GET_REG, 0, CIB_NONE, handle_reg_get, NULL);
return err;
}
COMMAND(scan, trigger, "[freq <freq>*] [ssid <ssid>*|passive]",
- NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan);
+ NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan, NULL);
static void tab_on_first(bool *first)
{
return 0;
}
COMMAND(scan, dump, "[-u]",
- NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump);
+ NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump, NULL);
static int handle_scan_combined(struct nl80211_state *state,
struct nl_cb *cb,
dump_argv[0] = argv[0];
return handle_cmd(state, II_NETDEV, dump_argc, dump_argv);
}
-TOPLEVEL(scan, "[-u] [freq <freq>*] [ssid <ssid>*|passive]", 0, 0, CIB_NETDEV, handle_scan_combined);
+TOPLEVEL(scan, "[-u] [freq <freq>*] [ssid <ssid>*|passive]", 0, 0, CIB_NETDEV, handle_scan_combined, NULL);
return -ENOBUFS;
}
COMMAND(station, get, "<MAC address>",
- NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get);
+ NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get, NULL);
COMMAND(station, del, "<MAC address>",
- NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get);
+ NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get, NULL);
static int handle_station_set(struct nl80211_state *state,
struct nl_cb *cb,
return -ENOBUFS;
}
COMMAND(station, set, "<MAC address> plink_action <open|block>",
- NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set);
+ NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set, NULL);
static int handle_station_dump(struct nl80211_state *state,
struct nl_cb *cb,
return 0;
}
COMMAND(station, dump, NULL,
- NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump);
+ NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump, NULL);