[pkg-wpa-devel] r1377 - in /iw/trunk: Makefile debian/changelog event.c ibss.c info.c interface.c iw.c iw.h mesh.c mpath.c phy.c reason.c reg.c scan.c station.c status.c version.sh
kelmo-guest at users.alioth.debian.org
kelmo-guest at users.alioth.debian.org
Wed May 13 18:51:40 UTC 2009
Author: kelmo-guest
Date: Wed May 13 18:51:40 2009
New Revision: 1377
URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=1377
Log:
New upstream release.
Added:
iw/trunk/event.c
- copied unchanged from r1376, iw/branches/upstream/current/event.c
iw/trunk/reason.c
- copied unchanged from r1376, iw/branches/upstream/current/reason.c
iw/trunk/status.c
- copied unchanged from r1376, iw/branches/upstream/current/status.c
Modified:
iw/trunk/Makefile
iw/trunk/debian/changelog
iw/trunk/ibss.c
iw/trunk/info.c
iw/trunk/interface.c
iw/trunk/iw.c
iw/trunk/iw.h
iw/trunk/mesh.c
iw/trunk/mpath.c
iw/trunk/phy.c
iw/trunk/reg.c
iw/trunk/scan.c
iw/trunk/station.c
iw/trunk/version.sh
Modified: iw/trunk/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/Makefile?rev=1377&op=diff
==============================================================================
--- iw/trunk/Makefile (original)
+++ iw/trunk/Makefile Wed May 13 18:51:40 2009
@@ -13,7 +13,7 @@
CFLAGS ?= -O2 -g
CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration
-OBJS = iw.o genl.o info.o phy.o interface.o ibss.o station.o util.o mesh.o mpath.o scan.o reg.o version.o
+OBJS = iw.o genl.o event.o info.o phy.o interface.o ibss.o station.o util.o mesh.o mpath.o scan.o reg.o version.o reason.o status.o
ALL = iw
NL1FOUND := $(shell pkg-config --atleast-version=1 libnl-1 && echo Y)
Modified: iw/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/debian/changelog?rev=1377&op=diff
==============================================================================
--- iw/trunk/debian/changelog (original)
+++ iw/trunk/debian/changelog Wed May 13 18:51:40 2009
@@ -1,4 +1,4 @@
-iw (0.9.13-1) unstable; urgency=low
+iw (0.9.14-1) UNRELEASED; urgency=low
* New upstream release.
* Use minimal dh-centric debian/rules.
Modified: iw/trunk/ibss.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/ibss.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/ibss.c (original)
+++ iw/trunk/ibss.c Wed May 13 18:51:40 2009
@@ -63,6 +63,12 @@
return 0;
}
COMMAND(ibss, leave, NULL,
- NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss);
+ NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
+ "Leave the current IBSS cell.");
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,
+ "Join the IBSS cell with the given SSID, if it doesn't exist create\n"
+ "it on the given frequency. When fixed frequency is requested, don't\n"
+ "join/create a cell on a different frequency. When a fixed BSSID is\n"
+ "requested use that BSSID and do not adopt another cell's BSSID even\n"
+ "if it has higher TSF and the same SSID.");
Modified: iw/trunk/info.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/info.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/info.c (original)
+++ iw/trunk/info.c Wed May 13 18:51:40 2009
@@ -266,6 +266,8 @@
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,
+ "Show capabilities for the specified wireless device.");
+TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info,
+ "List all wireless devices and their capabilities.");
+TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL);
Modified: iw/trunk/interface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/interface.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/interface.c (original)
+++ iw/trunk/interface.c Wed May 13 18:51:40 2009
@@ -11,6 +11,12 @@
#include "nl80211.h"
#include "iw.h"
+
+#define VALID_FLAGS "none: no special flags\n"\
+ "fcsfail: show frames with FCS errors\n"\
+ "control: show control frames\n"\
+ "otherbss: show frames from other BSSes\n"\
+ "cook: use cooked mode"
static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = {
"none",
@@ -71,6 +77,9 @@
return err;
}
+/* for help */
+#define IFACE_TYPES "Valid interface types are: managed, ibss, monitor, mesh, wds."
+
/* return 0 if ok, internal error otherwise */
static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type,
bool need_type)
@@ -181,10 +190,15 @@
nla_put_failure:
return -ENOBUFS;
}
-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags ...]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add);
-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags ...]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add);
+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags <flag>*]",
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add,
+ "Add a new virtual interface with the given configuration.\n"
+ IFACE_TYPES "\n\n"
+ "The flags are only used for monitor interfaces, valid flags are:\n"
+ VALID_FLAGS "\n\n"
+ "The mesh_id is used only for mesh mode.");
+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags <flag>*]",
+ NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL);
static int handle_interface_del(struct nl80211_state *state,
struct nl_cb *cb,
@@ -193,7 +207,8 @@
{
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,
+ "Remove this virtual interface");
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)
@@ -232,7 +247,8 @@
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,
+ "Show information for this interface.");
static int handle_interface_set(struct nl80211_state *state,
struct nl_cb *cb,
@@ -259,8 +275,10 @@
nla_put_failure:
return -ENOBUFS;
}
-COMMAND(set, monitor, "<flag> [...]",
- NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set);
+COMMAND(set, monitor, "<flag>*",
+ NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set,
+ "Set monitor flags. Valid flags are:\n"
+ VALID_FLAGS);
static int handle_interface_meshid(struct nl80211_state *state,
struct nl_cb *cb,
@@ -281,7 +299,7 @@
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;
@@ -294,7 +312,8 @@
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,
+ "List all network interfaces for wireless hardware.");
static int handle_interface_type(struct nl80211_state *state,
struct nl_cb *cb,
@@ -318,4 +337,6 @@
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,
+ "Set interface type/mode.\n"
+ IFACE_TYPES);
Modified: iw/trunk/iw.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/iw.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/iw.c (original)
+++ iw/trunk/iw.c Wed May 13 18:51:40 2009
@@ -12,6 +12,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <stdbool.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
@@ -46,7 +47,7 @@
#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
#endif /* CONFIG_LIBNL20 */
-static int debug = 0;
+int iw_debug = 0;
static int nl80211_init(struct nl80211_state *state)
{
@@ -93,44 +94,97 @@
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(const char *argv0)
-{
- struct cmd *cmd;
-
- fprintf(stderr, "Usage:\t%s [options] command\n", argv0);
+static void __usage_cmd(struct cmd *cmd, char *indent, bool full)
+{
+ const char *start, *lend, *end;
+
+ fprintf(stderr, "%s", indent);
+
+ switch (cmd->idby) {
+ case CIB_NONE:
+ break;
+ case CIB_PHY:
+ fprintf(stderr, "phy <phyname> ");
+ break;
+ case CIB_NETDEV:
+ fprintf(stderr, "dev <devname> ");
+ break;
+ }
+ if (cmd->section)
+ fprintf(stderr, "%s ", cmd->section);
+ fprintf(stderr, "%s", cmd->name);
+ 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, "Options:\n");
fprintf(stderr, "\t--debug\t\tenable netlink debugging\n");
- fprintf(stderr, "\t--version\tshow version\n");
+}
+
+static const char *argv0;
+
+static void usage(bool full)
+{
+ struct cmd *cmd;
+
+ fprintf(stderr, "Usage:\t%s [options] command\n", argv0);
+ usage_options();
+ fprintf(stderr, "\t--version\tshow version (%s)\n", iw_version);
fprintf(stderr, "Commands:\n");
- fprintf(stderr, "\thelp\n");
- fprintf(stderr, "\tevent\n");
for (cmd = &__start___cmd; cmd < &__stop___cmd;
cmd = (struct cmd *)((char *)cmd + cmd_size)) {
if (!cmd->handler || cmd->hidden)
continue;
- switch (cmd->idby) {
- case CIB_NONE:
- fprintf(stderr, "\t");
- break;
- case CIB_PHY:
- fprintf(stderr, "\tphy <phyname> ");
- break;
- case CIB_NETDEV:
- fprintf(stderr, "\tdev <devname> ");
- break;
- }
- if (cmd->section)
- fprintf(stderr, "%s ", cmd->section);
- fprintf(stderr, "%s", cmd->name);
- if (cmd->args)
- fprintf(stderr, " %s", cmd->args);
- fprintf(stderr, "\n");
- }
+ __usage_cmd(cmd, "\t", full);
+ }
+}
+
+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, "", true);
+ usage_options();
}
static void version(void)
@@ -177,8 +231,8 @@
return NL_STOP;
}
-int handle_cmd(struct nl80211_state *state, enum id_input idby,
- int argc, char **argv)
+static int __handle_cmd(struct nl80211_state *state, enum id_input idby,
+ int argc, char **argv, struct cmd **cmdout)
{
struct cmd *cmd, *match = NULL;
struct nl_cb *cb;
@@ -264,6 +318,9 @@
if (!cmd)
return 1;
+ if (cmdout)
+ *cmdout = cmd;
+
if (!cmd->cmd) {
argc = o_argc;
argv = o_argv;
@@ -276,7 +333,7 @@
return 2;
}
- cb = nl_cb_alloc(debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+ cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
if (!cb) {
fprintf(stderr, "failed to allocate netlink callbacks\n");
err = 2;
@@ -323,180 +380,17 @@
return 2;
}
-static int no_seq_check(struct nl_msg *msg, void *arg)
-{
- return NL_OK;
-}
-
-static int print_event(struct nl_msg *msg, void *arg)
-{
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct nlattr *tb[NL80211_ATTR_MAX + 1];
- char ifname[100];
- char macbuf[6*3];
- __u8 reg_type;
-
- nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0), NULL);
-
- switch (gnlh->cmd) {
- case NL80211_CMD_NEW_WIPHY:
- printf("wiphy rename: phy #%d to %s\n",
- nla_get_u32(tb[NL80211_ATTR_WIPHY]),
- nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]));
- break;
- case NL80211_CMD_NEW_SCAN_RESULTS:
- if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname);
- printf("scan finished on %s (phy #%d)\n",
- ifname, nla_get_u32(tb[NL80211_ATTR_WIPHY]));
- break;
- case NL80211_CMD_SCAN_ABORTED:
- if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname);
- printf("scan aborted on %s (phy #%d)\n",
- ifname, nla_get_u32(tb[NL80211_ATTR_WIPHY]));
- break;
- case NL80211_CMD_REG_CHANGE:
-
- printf("regulatory domain change: ");
-
- reg_type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
-
- switch (reg_type) {
- case NL80211_REGDOM_TYPE_COUNTRY:
- printf("set to %s by %s request",
- nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
- reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])));
- if (tb[NL80211_ATTR_WIPHY])
- printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY]));
- break;
- case NL80211_REGDOM_TYPE_WORLD:
- printf("set to world roaming by %s request",
- reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])));
- break;
- case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
- printf("custom world roaming rules in place on phy%d by %s request",
- nla_get_u32(tb[NL80211_ATTR_WIPHY]),
- reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR])));
- break;
- case NL80211_REGDOM_TYPE_INTERSECTION:
- printf("intersection used due to a request made by %s",
- reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR])));
- if (tb[NL80211_ATTR_WIPHY])
- printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY]));
- break;
- default:
- printf("unknown source (upgrade this utility)");
- break;
- }
-
- printf("\n");
- break;
- case NL80211_CMD_JOIN_IBSS:
- if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname);
- mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC]));
- printf("IBSS %s joined on %s (phy #%d)\n",
- macbuf, ifname, nla_get_u32(tb[NL80211_ATTR_WIPHY]));
- break;
- default:
- printf("unknown event: %d\n", gnlh->cmd);
- break;
- }
-
- return NL_SKIP;
-}
-
-struct wait_event {
- int n_cmds;
- const __u32 *cmds;
- __u32 cmd;
-};
-
-static int wait_event(struct nl_msg *msg, void *arg)
-{
- struct wait_event *wait = arg;
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- int i;
-
- for (i = 0; i < wait->n_cmds; i++) {
- if (gnlh->cmd == wait->cmds[i]) {
- wait->cmd = gnlh->cmd;
- }
- }
-
- return NL_SKIP;
-}
-
-__u32 listen_events(struct nl80211_state *state,
- const int n_waits, const __u32 *waits)
-{
- int mcid, ret;
- struct nl_cb *cb = nl_cb_alloc(debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
- struct wait_event wait_ev;
-
- if (!cb) {
- fprintf(stderr, "failed to allocate netlink callbacks\n");
- return -ENOMEM;
- }
-
- /* Configuration multicast group */
- mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "config");
- if (mcid < 0)
- return mcid;
-
- ret = nl_socket_add_membership(state->nl_sock, mcid);
- if (ret)
- return ret;
-
- /* Scan multicast group */
- mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "scan");
- if (mcid >= 0) {
- ret = nl_socket_add_membership(state->nl_sock, mcid);
- if (ret)
- return ret;
- }
-
- /* Regulatory multicast group */
- mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "regulatory");
- if (mcid >= 0) {
- ret = nl_socket_add_membership(state->nl_sock, mcid);
- if (ret)
- return ret;
- }
-
- /* MLME multicast group */
- mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "mlme");
- if (mcid >= 0) {
- ret = nl_socket_add_membership(state->nl_sock, mcid);
- if (ret)
- return ret;
- }
-
- /* no sequence checking for multicast messages */
- nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
-
- if (n_waits && waits) {
- wait_ev.cmds = waits;
- wait_ev.n_cmds = n_waits;
- nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev);
- } else {
- nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, NULL);
- }
-
- wait_ev.cmd = 0;
-
- while (!wait_ev.cmd)
- nl_recvmsgs(state->nl_sock, cb);
-
- nl_cb_put(cb);
-
- return wait_ev.cmd;
+int handle_cmd(struct nl80211_state *state, enum id_input idby,
+ int argc, char **argv)
+{
+ return __handle_cmd(state, idby, argc, argv, NULL);
}
int main(int argc, char **argv)
{
struct nl80211_state nlstate;
int err;
- const char *argv0;
+ struct cmd *cmd = NULL;
/* calculate command size including padding */
cmd_size = abs((long)&__cmd_NULL_NULL_1_CIB_NONE_0
@@ -506,7 +400,7 @@
argv0 = *argv++;
if (argc > 0 && strcmp(*argv, "--debug") == 0) {
- debug = 1;
+ iw_debug = 1;
argc--;
argv++;
}
@@ -516,8 +410,9 @@
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;
}
@@ -525,30 +420,28 @@
if (err)
return 1;
- if (strcmp(*argv, "event") == 0) {
- if (argc != 1)
- err = 1;
- else
- err = listen_events(&nlstate, 0, NULL);
- } else if (strcmp(*argv, "dev") == 0 && argc > 1) {
+ if (strcmp(*argv, "dev") == 0 && argc > 1) {
argc--;
argv++;
- err = handle_cmd(&nlstate, II_NETDEV, argc, argv);
+ err = __handle_cmd(&nlstate, II_NETDEV, argc, argv, &cmd);
} else if (strncmp(*argv, "phy", 3) == 0 && argc > 1) {
if (strlen(*argv) == 3) {
argc--;
argv++;
- err = handle_cmd(&nlstate, II_PHY_NAME, argc, argv);
+ err = __handle_cmd(&nlstate, II_PHY_NAME, argc, argv, &cmd);
} else if (*(*argv + 3) == '#')
- err = handle_cmd(&nlstate, II_PHY_IDX, argc, argv);
+ err = __handle_cmd(&nlstate, II_PHY_IDX, argc, argv, &cmd);
else
err = 1;
} else
- err = handle_cmd(&nlstate, II_NONE, argc, argv);
-
- if (err == 1)
- usage(argv0);
- if (err < 0)
+ err = __handle_cmd(&nlstate, II_NONE, argc, argv, &cmd);
+
+ if (err == 1) {
+ if (cmd)
+ usage_cmd(cmd);
+ else
+ usage(false);
+ } else if (err < 0)
fprintf(stderr, "command failed: %s (%d)\n", strerror(-err), err);
nl80211_cleanup(&nlstate);
Modified: iw/trunk/iw.h
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/iw.h?rev=1377&op=diff
==============================================================================
--- iw/trunk/iw.h (original)
+++ iw/trunk/iw.h Wed May 13 18:51:40 2009
@@ -37,6 +37,7 @@
const char *section;
const char *name;
const char *args;
+ const char *help;
const enum nl80211_commands cmd;
int nl_msg_flags;
int hidden;
@@ -54,21 +55,32 @@
#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0]))
-#define __COMMAND(sect, 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"))) \
- = { sect, name, args, nlcmd, flags, hidden, idby, handler }
-#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)
+ __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\
+ __attribute__((used)) __attribute__((section("__cmd"))) = { \
+ .section = (_section), \
+ .name = (_name), \
+ .args = (_args), \
+ .cmd = (_nlcmd), \
+ .nl_msg_flags = (_flags), \
+ .hidden = (_hidden), \
+ .idby = (_idby), \
+ .handler = (_handler), \
+ .help = (_help), \
+ }
+#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;
extern const char iw_version[];
+
+extern int iw_debug;
int handle_cmd(struct nl80211_state *state, enum id_input idby,
int argc, char **argv);
@@ -87,4 +99,7 @@
char *reg_initiator_to_string(__u8 initiator);
+const char *get_reason_str(uint16_t reason);
+const char *get_status_str(uint16_t status);
+
#endif /* __IW_H */
Modified: iw/trunk/mesh.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/mesh.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/mesh.c (original)
+++ iw/trunk/mesh.c Wed May 13 18:51:40 2009
@@ -244,7 +244,8 @@
}
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,
+ "Set mesh parameter (run command without any to see available ones).");
/* Getter */
static int print_mesh_param_handler(struct nl_msg *msg, void *arg)
@@ -290,4 +291,5 @@
}
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,
+ "Retrieve mesh parameter (run command without any to see available ones).");
Modified: iw/trunk/mpath.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/mpath.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/mpath.c (original)
+++ iw/trunk/mpath.c Wed May 13 18:51:40 2009
@@ -123,9 +123,11 @@
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,
+ "Get information on mesh path to the given node.");
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,
+ "Remove the mesh path to the given node.");
static int handle_mpath_set(struct nl80211_state *state,
struct nl_cb *cb,
@@ -169,9 +171,11 @@
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,
+ "Create a new mesh path (instead of relying on automatic discovery).");
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,
+ "Set an existing mesh path's next hop.");
static int handle_mpath_dump(struct nl80211_state *state,
struct nl_cb *cb,
@@ -182,4 +186,5 @@
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,
+ "List known mesh paths.");
Modified: iw/trunk/phy.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/phy.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/phy.c (original)
+++ iw/trunk/phy.c Wed May 13 18:51:40 2009
@@ -25,7 +25,8 @@
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,
+ "Rename this wireless device.");
static int handle_freqchan(struct nl_msg *msg, bool chan,
int argc, char **argv)
@@ -75,9 +76,11 @@
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,
+ "Set frequency/channel the hardware is using, including HT\n"
+ "configuration.");
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,
@@ -86,6 +89,6 @@
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);
Modified: iw/trunk/reg.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/reg.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/reg.c (original)
+++ iw/trunk/reg.c Wed May 13 18:51:40 2009
@@ -91,7 +91,8 @@
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,
+ "Notify the kernel about the current regulatory domain.");
static int print_reg_handler(struct nl_msg *msg, void *arg)
@@ -184,4 +185,5 @@
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,
+ "Print out the kernel's current regulatory domain information.");
Modified: iw/trunk/scan.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/scan.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/scan.c (original)
+++ iw/trunk/scan.c Wed May 13 18:51:40 2009
@@ -13,6 +13,23 @@
#include "nl80211.h"
#include "iw.h"
+#define WLAN_CAPABILITY_ESS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
+#define WLAN_CAPABILITY_APSD (1<<11)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+static unsigned char wifi_oui[3] = { 0x00, 0x50, 0xf2 };
+static unsigned char ieee80211_oui[3] = { 0x00, 0x0f, 0xac };
+
struct scan_params {
bool unknown;
};
@@ -22,30 +39,94 @@
struct nl_msg *msg,
int argc, char **argv)
{
- struct nl_msg *ssids = NULL;
+ struct nl_msg *ssids = NULL, *freqs = NULL;
+ char *eptr;
int err = -ENOBUFS;
+ int i;
+ enum {
+ NONE,
+ FREQ,
+ SSID,
+ DONE,
+ } parse = NONE;
+ int freq;
+ bool passive = false, have_ssids = false, have_freqs = false;
ssids = nlmsg_alloc();
if (!ssids)
return -ENOMEM;
- NLA_PUT(ssids, 1, 0, "");
- nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
+
+ freqs = nlmsg_alloc();
+ if (!freqs) {
+ nlmsg_free(ssids);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < argc; i++) {
+ if (parse == NONE && strcmp(argv[i], "freq") == 0) {
+ parse = FREQ;
+ have_freqs = true;
+ continue;
+ } else if (parse < SSID && strcmp(argv[i], "ssid") == 0) {
+ parse = SSID;
+ have_ssids = true;
+ continue;
+ } else if (parse < SSID && strcmp(argv[i], "passive") == 0) {
+ parse = DONE;
+ passive = true;
+ continue;
+ }
+
+ switch (parse) {
+ case NONE:
+ case DONE:
+ return 1;
+ case FREQ:
+ freq = strtoul(argv[i], &eptr, 10);
+ if (eptr != argv[i] + strlen(argv[i]))
+ return 1;
+ NLA_PUT_U32(freqs, i, freq);
+ break;
+ case SSID:
+ NLA_PUT(ssids, i, strlen(argv[i]), argv[i]);
+ break;
+ }
+ }
+
+ if (!have_ssids)
+ NLA_PUT(ssids, 1, 0, "");
+ if (!passive)
+ nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
+
+ if (have_freqs)
+ nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
err = 0;
nla_put_failure:
nlmsg_free(ssids);
+ nlmsg_free(freqs);
return err;
}
-COMMAND(scan, trigger, NULL,
- NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan);
-
-typedef void (*printfn)(unsigned char type, unsigned char len, unsigned char *data);
-
-static void print_ssid(unsigned char type, unsigned char len, unsigned char *data)
+COMMAND(scan, trigger, "[freq <freq>*] [ssid <ssid>*|passive]",
+ NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
+ "Trigger a scan on the given frequencies with probing for the given\n"
+ "SSIDs (or wildcard if not given) unless passive scanning is requested.");
+
+static void tab_on_first(bool *first)
+{
+ if (!*first)
+ printf("\t");
+ else
+ *first = false;
+}
+
+static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data)
{
int i;
- printf("\tSSID: ");
- for (i=0; i<len; i++) {
+
+ printf(" ");
+
+ for (i = 0; i < len; i++) {
if (isprint(data[i]))
printf("%c", data[i]);
else
@@ -54,38 +135,512 @@
printf("\n");
}
-static void print_supprates(unsigned char type, unsigned char len, unsigned char *data)
+static void print_supprates(const uint8_t type, uint8_t len, const uint8_t *data)
{
int i;
- if (type == 1)
- printf("\tSupported rates: ");
- else
- printf("\tExtended supported rates: ");
-
- for (i=0; i<len; i++) {
+ printf(" ");
+
+ for (i = 0; i < len; i++) {
int r = data[i] & 0x7f;
printf("%d.%d%s ", r/2, 5*(r&1), data[i] & 0x80 ? "*":"");
}
printf("\n");
}
-static void print_ds(unsigned char type, unsigned char len, unsigned char *data)
-{
- printf("\tDS Parameter set: channel %d\n", data[0]);
-}
-
-static void print_ign(unsigned char type, unsigned char len, unsigned char *data)
-{
- /* ignore for now, not too useful */
-}
-
-static const printfn ieprinters[] = {
- [0] = print_ssid,
- [1] = print_supprates,
- [3] = print_ds,
- [5] = print_ign,
- [50] = print_supprates,
+static void print_ds(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ printf(" channel %d\n", data[0]);
+}
+
+static void print_country(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ int i;
+
+ printf(" %.*s", 2, data);
+ switch (data[2]) {
+ case 'I':
+ printf(" (indoor)");
+ break;
+ case 'O':
+ printf(" (outdoor)");
+ break;
+ case ' ':
+ printf(" (in/outdoor)");
+ break;
+ default:
+ printf(" (invalid environment)");
+ break;
+ }
+ printf(", data:");
+ for(i=0; i<len-3; i++)
+ printf(" %.02x", data[i + 3]);
+ printf("\n");
+}
+
+static void print_powerconstraint(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ printf(" %d dB\n", data[0]);
+}
+
+static void print_erp(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ if (data[0] == 0x00)
+ printf(" <no flags>");
+ if (data[0] & 0x01)
+ printf(" NonERP_Present");
+ if (data[0] & 0x02)
+ printf(" Use_Protection");
+ if (data[0] & 0x04)
+ printf(" Barker_Preamble_Mode");
+ printf("\n");
+}
+
+static void print_cipher(const uint8_t *data)
+{
+ if (memcmp(data, wifi_oui, 3) == 0) {
+ switch (data[3]) {
+ case 0:
+ printf("Use group cipher suite");
+ break;
+ case 1:
+ printf("WEP-40");
+ break;
+ case 2:
+ printf("TKIP");
+ break;
+ case 4:
+ printf("CCMP");
+ break;
+ case 5:
+ printf("WEP-104");
+ break;
+ default:
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+ break;
+ }
+ } else if (memcmp(data, ieee80211_oui, 3) == 0) {
+ switch (data[3]) {
+ case 0:
+ printf("Use group cipher suite");
+ break;
+ case 1:
+ printf("WEP-40");
+ break;
+ case 2:
+ printf("TKIP");
+ break;
+ case 4:
+ printf("CCMP");
+ break;
+ case 5:
+ printf("WEP-104");
+ break;
+ case 6:
+ printf("AES-128-CMAC");
+ break;
+ default:
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+ break;
+ }
+ } else
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+}
+
+static void print_auth(const uint8_t *data)
+{
+ if (memcmp(data, wifi_oui, 3) == 0) {
+ switch (data[3]) {
+ case 1:
+ printf("IEEE 802.1X");
+ break;
+ case 2:
+ printf("PSK");
+ break;
+ default:
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+ break;
+ }
+ } else if (memcmp(data, ieee80211_oui, 3) == 0) {
+ switch (data[3]) {
+ case 1:
+ printf("IEEE 802.1X");
+ break;
+ case 2:
+ printf("PSK");
+ break;
+ case 3:
+ printf("FT/IEEE 802.1X");
+ break;
+ case 4:
+ printf("FT/PSK");
+ break;
+ case 5:
+ printf("IEEE 802.1X/SHA-256");
+ break;
+ case 6:
+ printf("PSK/SHA-256");
+ break;
+ default:
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+ break;
+ }
+ } else
+ printf("%.02x-%.02x-%.02x:%d",
+ data[0], data[1] ,data[2], data[3]);
+}
+
+static void print_rsn_ie(const char *defcipher, const char *defauth,
+ uint8_t len, const uint8_t *data)
+{
+ bool first = true;
+ __u16 version, count, capa;
+ int i;
+
+ version = data[0] + (data[1] << 8);
+ tab_on_first(&first);
+ printf("\t * Version: %d\n", version);
+
+ data += 2;
+ len -= 2;
+
+ if (len < 4) {
+ tab_on_first(&first);
+ printf("\t * Group cipher: %s\n", defcipher);
+ printf("\t * Pairwise ciphers: %s\n", defcipher);
+ return;
+ }
+
+ tab_on_first(&first);
+ printf("\t * Group cipher: ");
+ print_cipher(data);
+ printf("\n");
+
+ data += 4;
+ len -= 4;
+
+ if (len < 2) {
+ tab_on_first(&first);
+ printf("\t * Pairwise ciphers: %s\n", defcipher);
+ return;
+ }
+
+ count = data[0] | (data[1] << 8);
+ if (2 + (count * 4) > len)
+ goto invalid;
+
+ tab_on_first(&first);
+ printf("\t * Pairwise ciphers:");
+ for (i = 0; i < count; i++) {
+ printf(" ");
+ print_cipher(data + 2 + (i * 4));
+ }
+ printf("\n");
+
+ data += 2 + (count * 4);
+ len -= 2 + (count * 4);
+
+ if (len < 2) {
+ tab_on_first(&first);
+ printf("\t * Authentication suites: %s\n", defauth);
+ return;
+ }
+
+ count = data[0] | (data[1] << 8);
+ if (2 + (count * 4) > len)
+ goto invalid;
+
+ tab_on_first(&first);
+ printf("\t * Authentication suites:");
+ for (i = 0; i < count; i++) {
+ printf(" ");
+ print_auth(data + 2 + (i * 4));
+ }
+ printf("\n");
+
+ data += 2 + (count * 4);
+ len -= 2 + (count * 4);
+
+ if (len >= 2) {
+ capa = data[0] | (data[1] << 8);
+ tab_on_first(&first);
+ printf("\t * Capabilities:");
+ if (capa & 0x0001)
+ printf(" PreAuth");
+ if (capa & 0x0002)
+ printf(" NoPairwise");
+ switch ((capa & 0x000c) >> 2) {
+ case 0:
+ break;
+ case 1:
+ printf(" 2-PTKSA-RC");
+ break;
+ case 2:
+ printf(" 4-PTKSA-RC");
+ break;
+ case 3:
+ printf(" 16-PTKSA-RC");
+ break;
+ }
+ switch ((capa & 0x0030) >> 4) {
+ case 0:
+ break;
+ case 1:
+ printf(" 2-GTKSA-RC");
+ break;
+ case 2:
+ printf(" 4-GTKSA-RC");
+ break;
+ case 3:
+ printf(" 16-GTKSA-RC");
+ break;
+ }
+ if (capa & 0x0040)
+ printf(" MFP-required");
+ if (capa & 0x0080)
+ printf(" MFP-capable");
+ if (capa & 0x0200)
+ printf(" Peerkey-enabled");
+ if (capa & 0x0400)
+ printf(" SPP-AMSDU-capable");
+ if (capa & 0x0800)
+ printf(" SPP-AMSDU-required");
+ printf(" (0x%.4x)\n", capa);
+ data += 2;
+ len -= 2;
+ }
+
+ invalid:
+ if (len != 0) {
+ printf("\t\t * bogus tail data (%d):", len);
+ while (len) {
+ printf(" %.2x", *data);
+ data++;
+ len--;
+ }
+ printf("\n");
+ }
+}
+
+static void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ print_rsn_ie("CCMP", "IEEE 802.1X", len, data);
+}
+
+static void print_capabilities(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ int i, base, bit;
+ bool first = true;
+
+
+ for (i = 0; i < len; i++) {
+ base = i * 8;
+
+ for (bit = 0; bit < 8; bit++) {
+ if (!(data[i] & (1 << bit)))
+ continue;
+
+ if (!first)
+ printf(",");
+ else
+ first = false;
+
+ switch (bit + base) {
+ case 0:
+ printf(" HT Information Exchange Supported");
+ break;
+ case 1:
+ printf(" On-demand Beacon");
+ break;
+ case 2:
+ printf(" Extended Channel Switching");
+ break;
+ case 3:
+ printf(" Wave Indication");
+ break;
+ case 4:
+ printf(" PSMP Capability");
+ break;
+ case 5:
+ printf(" Service Interval Granularity");
+ break;
+ case 6:
+ printf(" S-PSMP Capability");
+ break;
+ default:
+ printf(" %d", bit);
+ break;
+ }
+ }
+ }
+
+ printf("\n");
+}
+
+struct ie_print {
+ const char *name;
+ void (*print)(const uint8_t type, uint8_t len, const uint8_t *data);
+ uint8_t minlen, maxlen;
+};
+
+static void print_ie(const struct ie_print *p, const uint8_t type,
+ uint8_t len, const uint8_t *data)
+{
+ int i;
+
+ if (!p->print)
+ return;
+
+ printf("\t%s:", p->name);
+ if (len < p->minlen || len > p->maxlen) {
+ if (len > 1) {
+ printf(" <invalid: %d bytes:", len);
+ for (i = 0; i < len; i++)
+ printf(" %.02x", data[i]);
+ printf(">\n");
+ } else if (len)
+ printf(" <invalid: 1 byte: %.02x>\n", data[0]);
+ else
+ printf(" <invalid: no data>\n");
+ return;
+ }
+
+ p->print(type, len, data);
+}
+
+#define PRINT_IGN { \
+ .name = "IGNORE", \
+ .print = NULL, \
+ .minlen = 0, \
+ .maxlen = 255, \
+}
+
+static const struct ie_print ieprinters[] = {
+ [0] = { "SSID", print_ssid, 0, 32, },
+ [1] = { "Supported rates", print_supprates, 0, 255, },
+ [3] = { "DS Paramater set", print_ds, 1, 1, },
+ [5] = PRINT_IGN,
+ [7] = { "Country", print_country, 3, 255, },
+ [32] = { "Power constraint", print_powerconstraint, 1, 1, },
+ [42] = { "ERP", print_erp, 1, 255, },
+ [48] = { "RSN", print_rsn, 2, 255, },
+ [50] = { "Extended supported rates", print_supprates, 0, 255, },
+ [127] = { "Extended capabilities", print_capabilities, 0, 255, },
+};
+
+static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ print_rsn_ie("TKIP", "IEEE 802.1X", len, data);
+}
+
+static void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ int i;
+
+ switch (data[0]) {
+ case 0x00:
+ printf(" information:");
+ break;
+ case 0x01:
+ printf(" parameter:");
+ break;
+ default:
+ printf(" type %d:", data[0]);
+ break;
+ }
+
+ for(i = 0; i < len - 1; i++)
+ printf(" %.02x", data[i + 1]);
+ printf("\n");
+}
+
+static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data)
+{
+ bool first = true;
+ __u16 subtype, sublen;
+
+ while (len >= 4) {
+ subtype = (data[0] << 8) + data[1];
+ sublen = (data[2] << 8) + data[3];
+ if (sublen > len)
+ break;
+
+ switch (subtype) {
+ case 0x104a:
+ tab_on_first(&first);
+ printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF);
+ break;
+ case 0x1011:
+ tab_on_first(&first);
+ printf("\t * Device name: %.*s\n", sublen, data + 4);
+ break;
+ case 0x1021:
+ tab_on_first(&first);
+ printf("\t * Manufacturer: %.*s\n", sublen, data + 4);
+ break;
+ case 0x1023:
+ tab_on_first(&first);
+ printf("\t * Model: %.*s\n", sublen, data + 4);
+ break;
+ case 0x1057: {
+ __u16 val = (data[4] << 8) | data[5];
+ tab_on_first(&first);
+ printf("\t * AP setup locked: 0x%.4x\n", val);
+ break;
+ }
+ case 0x1008: {
+ __u16 meth = (data[4] << 8) + data[5];
+ bool comma = false;
+ tab_on_first(&first);
+ printf("\t * Config methods:");
+#define T(bit, name) do { \
+ if (meth & (1<<bit)) { \
+ if (comma) \
+ printf(","); \
+ comma = true; \
+ printf(" " name); \
+ } } while (0)
+ T(0, "USB");
+ T(1, "Ethernet");
+ T(2, "Label");
+ T(3, "Display");
+ T(4, "Ext. NFC");
+ T(5, "Int. NFC");
+ T(6, "NFC Intf.");
+ T(7, "PBC");
+ T(8, "Keypad");
+ printf("\n");
+ break;
+#undef T
+ }
+ default:
+ break;
+ }
+
+ data += sublen + 4;
+ len -= sublen + 4;
+ }
+
+ if (len != 0) {
+ printf("\t\t * bogus tail data (%d):", len);
+ while (len) {
+ printf(" %.2x", *data);
+ data++;
+ len--;
+ }
+ printf("\n");
+ }
+}
+
+static const struct ie_print wifiprinters[] = {
+ [1] = { "WPA", print_wifi_wpa, 2, 255, },
+ [2] = { "WMM", print_wifi_wmm, 1, 255, },
+ [4] = { "WPS", print_wifi_wps, 0, 255, },
};
static void print_vendor(unsigned char len, unsigned char *data,
@@ -93,30 +648,51 @@
{
int i;
- /* currently _all_ vendor IEs are unknown (not parsed) */
+ if (len < 3) {
+ printf("\tVendor specific: <too short> data:");
+ for(i = 0; i < len; i++)
+ printf(" %.02x", data[i]);
+ printf("\n");
+ return;
+ }
+
+ if (len >= 4 && memcmp(data, wifi_oui, 3) == 0) {
+ if (data[3] < ARRAY_SIZE(wifiprinters) && wifiprinters[data[3]].name) {
+ print_ie(&wifiprinters[data[3]], data[3], len - 4, data + 4);
+ return;
+ }
+ if (!params->unknown)
+ return;
+ printf("\tWiFi OUI %#.2x, data:", data[3]);
+ for(i = 0; i < len - 4; i++)
+ printf(" %.02x", data[i + 4]);
+ printf("\n");
+ return;
+ }
+
if (!params->unknown)
return;
- printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data: ",
+ printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data:",
data[0], data[1], data[2]);
- for (i=3; i<len; i++)
- printf("\\x%.2x", data[i]);
+ for (i = 3; i < len; i++)
+ printf(" %.2x", data[i]);
printf("\n");
}
static void print_ies(unsigned char *ie, int ielen, struct scan_params *params)
{
while (ielen >= 2 && ielen >= ie[1]) {
- if (ie[0] < ARRAY_SIZE(ieprinters) && ieprinters[ie[0]]) {
- ieprinters[ie[0]](ie[0], ie[1], ie + 2);
+ if (ie[0] < ARRAY_SIZE(ieprinters) && ieprinters[ie[0]].name) {
+ print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2);
} else if (ie[0] == 221 /* vendor */) {
print_vendor(ie[1], ie + 2, params);
} else if (params->unknown) {
int i;
- printf("\tUnknown IE (%d): ", ie[0]);
+ printf("\tUnknown IE (%d):", ie[0]);
for (i=0; i<ie[1]; i++)
- printf("\\x%.2x", ie[2+i]);
+ printf(" %.2x", ie[2+i]);
printf("\n");
}
ielen -= ie[1] + 2;
@@ -175,9 +751,33 @@
if (bss[NL80211_BSS_BEACON_INTERVAL])
printf("\tbeacon interval: %d\n",
nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]));
- if (bss[NL80211_BSS_CAPABILITY])
- printf("\tcapability: 0x%.4x\n",
- nla_get_u16(bss[NL80211_BSS_CAPABILITY]));
+ if (bss[NL80211_BSS_CAPABILITY]) {
+ __u16 capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
+ printf("\tcapability:");
+ if (capa & WLAN_CAPABILITY_ESS)
+ printf(" ESS");
+ if (capa & WLAN_CAPABILITY_IBSS)
+ printf(" IBSS");
+ if (capa & WLAN_CAPABILITY_PRIVACY)
+ printf(" Privacy");
+ if (capa & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ printf(" ShortPreamble");
+ if (capa & WLAN_CAPABILITY_PBCC)
+ printf(" PBCC");
+ if (capa & WLAN_CAPABILITY_CHANNEL_AGILITY)
+ printf(" ChannelAgility");
+ if (capa & WLAN_CAPABILITY_SPECTRUM_MGMT)
+ printf(" SpectrumMgmt");
+ if (capa & WLAN_CAPABILITY_QOS)
+ printf(" QoS");
+ if (capa & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ printf(" ShortSlotTime");
+ if (capa & WLAN_CAPABILITY_APSD)
+ printf(" APSD");
+ if (capa & WLAN_CAPABILITY_DSSS_OFDM)
+ printf(" DSSS-OFDM");
+ printf(" (0x%.4x)\n", capa);
+ }
if (bss[NL80211_BSS_SIGNAL_MBM]) {
int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
printf("\tsignal: %d.%.2d dBm\n", s/100, s%100);
@@ -213,33 +813,72 @@
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,
+ "Dump the current scan results. If -u is specified, print unknown\n"
+ "data in scan results.");
static int handle_scan_combined(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
int argc, char **argv)
{
- static char *trig_argv[] = {
- NULL,
- "scan",
- "trigger",
- };
+ char **trig_argv;
static char *dump_argv[] = {
NULL,
"scan",
"dump",
+ NULL,
};
static const __u32 cmds[] = {
NL80211_CMD_NEW_SCAN_RESULTS,
NL80211_CMD_SCAN_ABORTED,
};
- int err;
-
+ int trig_argc, dump_argc, err;
+
+ if (argc >= 3 && !strcmp(argv[2], "-u")) {
+ dump_argc = 4;
+ dump_argv[3] = "-u";
+ } else
+ dump_argc = 3;
+
+ trig_argc = 3 + (argc - 2) + (3 - dump_argc);
+ trig_argv = calloc(trig_argc, sizeof(*trig_argv));
+ if (!trig_argv)
+ return -ENOMEM;
trig_argv[0] = argv[0];
- err = handle_cmd(state, II_NETDEV, ARRAY_SIZE(trig_argv), trig_argv);
+ trig_argv[1] = "scan";
+ trig_argv[2] = "trigger";
+ int i;
+ for (i = 0; i < argc - 2 - (dump_argc - 3); i++)
+ trig_argv[i + 3] = argv[i + 2 + (dump_argc - 3)];
+ err = handle_cmd(state, II_NETDEV, trig_argc, trig_argv);
+ free(trig_argv);
if (err)
return err;
+
+ /*
+ * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION
+ *
+ * This code has a bug, which requires creating a separate
+ * nl80211 socket to fix:
+ * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or
+ * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel
+ * before (!) we listen to it, because we only start listening
+ * after we send our scan request.
+ *
+ * Doing it the other way around has a race condition as well,
+ * if you first open the events socket you may get a notification
+ * for a previous scan.
+ *
+ * The only proper way to fix this would be to listen to events
+ * before sending the command, and for the kernel to send the
+ * scan request along with the event, so that you can match up
+ * whether the scan you requested was finished or aborted (this
+ * may result in processing a scan that another application
+ * requested, but that doesn't seem to be a problem).
+ *
+ * Alas, the kernel doesn't do that (yet).
+ */
if (listen_events(state, ARRAY_SIZE(cmds), cmds) ==
NL80211_CMD_SCAN_ABORTED) {
@@ -248,6 +887,10 @@
}
dump_argv[0] = argv[0];
- return handle_cmd(state, II_NETDEV, ARRAY_SIZE(dump_argv), dump_argv);
-}
-TOPLEVEL(scan, NULL, 0, 0, CIB_NETDEV, handle_scan_combined);
+ 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,
+ "Scan on the given frequencies and probe for the given SSIDs\n"
+ "(or wildcard if not given) unless passive scanning is requested.\n"
+ "If -u is specified print unknown data in the scan results.");
Modified: iw/trunk/station.c
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/station.c?rev=1377&op=diff
==============================================================================
--- iw/trunk/station.c (original)
+++ iw/trunk/station.c Wed May 13 18:51:40 2009
@@ -188,9 +188,11 @@
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,
+ "Get information for a specific station.");
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,
+ "Remove the given station entry (use with caution!)");
static int handle_station_set(struct nl80211_state *state,
struct nl_cb *cb,
@@ -237,7 +239,8 @@
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,
+ "Set mesh peer link action for this station (peer).");
static int handle_station_dump(struct nl80211_state *state,
struct nl_cb *cb,
@@ -248,4 +251,5 @@
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,
+ "List all stations known, e.g. the AP on managed interfaces");
Modified: iw/trunk/version.sh
URL: http://svn.debian.org/wsvn/pkg-wpa/iw/trunk/version.sh?rev=1377&op=diff
==============================================================================
--- iw/trunk/version.sh (original)
+++ iw/trunk/version.sh Wed May 13 18:51:40 2009
@@ -1,6 +1,6 @@
#!/bin/sh
-VERSION="0.9.13"
+VERSION="0.9.14"
OUT="$1"
if head=`git rev-parse --verify HEAD 2>/dev/null`; then
More information about the Pkg-wpa-devel
mailing list