[pkg-wpa-devel] r1272 - in /iw/branches/upstream/current: .gitmodules Makefile debian/ genl.c info.c interface.c iw.c iw.h mesh.c nl80211.h version.sh

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Sun Oct 26 17:22:36 UTC 2008


Author: kelmo-guest
Date: Sun Oct 26 17:22:36 2008
New Revision: 1272

URL: http://svn.debian.org/wsvn/?sc=1&rev=1272
Log:
[svn-upgrade] Integrating new upstream version, iw (0.9.6)

Added:
    iw/branches/upstream/current/genl.c
    iw/branches/upstream/current/mesh.c
Removed:
    iw/branches/upstream/current/.gitmodules
    iw/branches/upstream/current/debian/
Modified:
    iw/branches/upstream/current/Makefile
    iw/branches/upstream/current/info.c
    iw/branches/upstream/current/interface.c
    iw/branches/upstream/current/iw.c
    iw/branches/upstream/current/iw.h
    iw/branches/upstream/current/nl80211.h
    iw/branches/upstream/current/version.sh

Modified: iw/branches/upstream/current/Makefile
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/Makefile?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/Makefile (original)
+++ iw/branches/upstream/current/Makefile Sun Oct 26 17:22:36 2008
@@ -11,7 +11,7 @@
 LDFLAGS += `pkg-config --libs libnl-1`
 NLVERSION = 1.0
 
-OBJS = iw.o info.o phy.o interface.o station.o util.o mpath.o reg.o
+OBJS = iw.o info.o phy.o interface.o station.o util.o mpath.o reg.o mesh.o genl.o
 ALL = iw
 
 ifeq ($(V),1)

Added: iw/branches/upstream/current/genl.c
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/genl.c?rev=1272&op=file
==============================================================================
--- iw/branches/upstream/current/genl.c (added)
+++ iw/branches/upstream/current/genl.c Sun Oct 26 17:22:36 2008
@@ -1,0 +1,120 @@
+/*
+ * This ought to be provided by libnl
+ */
+
+#include <asm/errno.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>  
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+			 void *arg)
+{
+	int *ret = arg;
+	*ret = err->error;
+	return NL_STOP;
+}
+
+static int finish_handler(struct nl_msg *msg, void *arg)
+{
+	return NL_SKIP;
+}
+
+static int ack_handler(struct nl_msg *msg, void *arg)
+{
+	int *ret = arg;
+	*ret = 0;
+	return NL_STOP;
+}
+
+struct handler_args {
+	const char *group;
+	int id;
+};
+
+static int family_handler(struct nl_msg *msg, void *arg)
+{
+	struct handler_args *grp = arg;
+	struct nlattr *tb[CTRL_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *mcgrp;
+	int rem_mcgrp;
+
+	nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+        if (!tb[CTRL_ATTR_MCAST_GROUPS])
+		return NL_SKIP;
+
+	nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
+		struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
+
+		nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX,
+			  nla_data(mcgrp), nla_len(mcgrp), NULL);
+
+		if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] ||
+		    !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
+			continue;
+		if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]),
+			    grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])))
+			continue;
+		grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
+		break;
+	}
+	
+	return NL_SKIP;
+}
+
+int nl_get_multicast_id(struct nl_handle *handle, const char *family, const char *group)
+{
+	struct nl_msg *msg;
+	struct nl_cb *cb;
+	int ret, ctrlid;
+	struct handler_args grp = {
+		.group = group,
+		.id = -ENOENT,
+	};
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		return -ENOMEM;
+
+	cb = nl_cb_alloc(NL_CB_DEFAULT);
+	if (!cb) {
+		ret = -ENOMEM;
+		goto out_fail_cb;
+	}
+
+	ctrlid = genl_ctrl_resolve(handle, "nlctrl");
+
+        genlmsg_put(msg, 0, 0, ctrlid, 0,
+		    0, CTRL_CMD_GETFAMILY, 0);
+
+	ret = -ENOBUFS;
+	NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
+
+	ret = nl_send_auto_complete(handle, msg);
+	if (ret < 0)
+		goto out;
+
+	ret = 1;
+
+	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &ret);
+	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, NULL);
+	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &ret);
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, family_handler, &grp);
+
+	while (ret > 0)
+		nl_recvmsgs(handle, cb);
+
+	if (ret == 0)
+		ret = grp.id;
+ nla_put_failure:
+ out:
+	nl_cb_put(cb);
+ out_fail_cb:
+	nlmsg_free(msg);
+	return ret;
+}

Modified: iw/branches/upstream/current/info.c
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/info.c?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/info.c (original)
+++ iw/branches/upstream/current/info.c Sun Oct 26 17:22:36 2008
@@ -66,6 +66,74 @@
 		nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
 			  nla_len(nl_band), NULL);
 
+#ifdef NL80211_BAND_ATTR_HT_CAPA
+		if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
+			unsigned short cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]);
+#define PCOM(fmt, args...) do { printf("\t\t\t * " fmt "\n", ##args); } while (0)
+#define PBCOM(bit, args...) if (cap & (bit)) PCOM(args)
+			printf("\t\tHT capabilities: 0x%.4x\n", cap);
+			PBCOM(0x0001, "LPDC coding");
+			if (cap & 0x0002)
+				PCOM("20/40 MHz operation");
+			else
+				PCOM("20 MHz operation");
+			switch ((cap & 0x000c) >> 2) {
+			case 0:
+				PCOM("static SM PS");
+				break;
+			case 1:
+				PCOM("dynamic SM PS");
+				break;
+			case 2:
+				PCOM("reserved SM PS");
+				break;
+			case 3:
+				PCOM("SM PS disabled");
+				break;
+			}
+			PBCOM(0x0010, "HT-greenfield");
+			PBCOM(0x0020, "20 MHz short GI");
+			PBCOM(0x0040, "40 MHz short GI");
+			PBCOM(0x0080, "TX STBC");
+			if (cap & 0x300)
+				PCOM("RX STBC %d streams", (cap & 0x0300) >> 8);
+			PBCOM(0x0400, "HT-delayed block-ack");
+			PCOM("max A-MSDU len %d", 0xeff + ((cap & 0x0800) << 1));
+			PBCOM(0x1000, "DSSS/CCK 40 MHz");
+			PBCOM(0x2000, "PSMP support");
+			PBCOM(0x4000, "40 MHz intolerant");
+			PBCOM(0x8000, "L-SIG TXOP protection support");
+		}
+		if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) {
+			unsigned char factor = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]);
+			printf("\t\tHT A-MPDU factor: 0x%.4x (%d bytes)\n", factor, (1<<(13+factor))-1);
+		}
+		if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) {
+			unsigned char dens = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]);
+			printf("\t\tHT A-MPDU density: 0x%.4x (", dens);
+			switch (dens) {
+			case 0:
+				printf("no restriction)\n");
+				break;
+			case 1:
+				printf("1/4 usec)\n");
+				break;
+			case 2:
+				printf("1/2 usec)\n");
+				break;
+			default:
+				printf("%d usec)\n", 1<<(dens - 3));
+			}
+		}
+		if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
+		    nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]) == 16) {
+			unsigned char *mcs = nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
+			printf("\t\tHT MCS set: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n",
+				mcs[0], mcs[1], mcs[2], mcs[3], mcs[4], mcs[5], mcs[6], mcs[7],
+				mcs[8], mcs[9], mcs[10], mcs[11], mcs[12], mcs[13], mcs[14], mcs[15]);
+		}
+#endif
+
 		printf("\t\tFrequencies:\n");
 
 		nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {

Modified: iw/branches/upstream/current/interface.c
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/interface.c?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/interface.c (original)
+++ iw/branches/upstream/current/interface.c Sun Oct 26 17:22:36 2008
@@ -12,7 +12,7 @@
 #include "iw.h"
 
 static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = {
-	NULL,
+	"none",
 	"fcsfail",
 	"plcpfail",
 	"control",
@@ -20,6 +20,56 @@
 	"cook",
 };
 
+static int parse_mntr_flags(int *_argc, char ***_argv,
+			    struct nl_msg *msg)
+{
+	struct nl_msg *flags;
+	int err = -ENOBUFS;
+	enum nl80211_mntr_flags flag;
+	int argc = *_argc;
+	char **argv = *_argv;
+
+	flags = nlmsg_alloc();
+	if (!flags)
+		return -ENOMEM;
+
+	while (argc) {
+		int ok = 0;
+		for (flag = __NL80211_MNTR_FLAG_INVALID;
+		     flag < NL80211_MNTR_FLAG_MAX; flag++) {
+			if (strcmp(*argv, mntr_flags[flag]) == 0) {
+				ok = 1;
+				/*
+				 * This shouldn't be adding "flag" if that is
+				 * zero, but due to a problem in the kernel's
+				 * nl80211 code (using NLA_NESTED policy) it
+				 * will reject an empty nested attribute but
+				 * not one that contains an invalid attribute
+				 */
+				NLA_PUT_FLAG(flags, flag);
+				break;
+			}
+		}
+		if (!ok) {
+			err = -EINVAL;
+			goto out;
+		}
+		argc--;
+		argv++;
+	}
+
+	nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
+	err = 0;
+ nla_put_failure:
+ out:
+	nlmsg_free(flags);
+
+	*_argc = argc;
+	*_argv = argv;
+
+	return err;
+}
+
 /* return 0 if not found, 1 if ok, -1 on error */
 static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type)
 {
@@ -86,16 +136,25 @@
 		return 1;
 
 	if (argc) {
-		if (strcmp(argv[0], "mesh_id") != 0)
+		if (strcmp(argv[0], "mesh_id") == 0) {
+			argc--;
+			argv++;
+
+			if (!argc)
+				return 1;
+			mesh_id = argv[0];
+			argc--;
+			argv++;
+		} else if (strcmp(argv[0], "flags") == 0) {
+			argc--;
+			argv++;
+			if (parse_mntr_flags(&argc, &argv, msg)) {
+				fprintf(stderr, "flags error\n");
+				return 2;
+			}
+		} else {
 			return 1;
-		argc--;
-		argv++;
-
-		if (!argc)
-			return 1;
-		mesh_id = argv[0];
-		argc--;
-		argv++;
+		}
 	}
 
 	if (argc)
@@ -111,9 +170,9 @@
  nla_put_failure:
 	return -ENOBUFS;
 }
-COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>]",
+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>]",
+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags ...]",
 	NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add);
 
 static int handle_interface_del(struct nl_cb *cb,
@@ -156,49 +215,25 @@
 				struct nl_msg *msg,
 				int argc, char **argv)
 {
-	enum nl80211_mntr_flags flag;
-	struct nl_msg *flags;
-	int err;
-
 	if (!argc)
 		return 1;
 
-	flags = nlmsg_alloc();
-	if (!flags) {
+	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
+
+	switch (parse_mntr_flags(&argc, &argv, msg)) {
+	case 0:
+		return 0;
+	case -ENOMEM:
 		fprintf(stderr, "failed to allocate flags\n");
 		return 2;
-	}
-
-	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR);
-
-	while (argc) {
-		int ok = 0;
-		for (flag = __NL80211_MNTR_FLAG_INVALID + 1;
-		     flag < NL80211_MNTR_FLAG_MAX; flag++) {
-			if (strcmp(*argv, mntr_flags[flag]) == 0) {
-				ok = 1;
-				NLA_PUT_FLAG(flags, flag);
-				break;
-			}
-		}
-		if (!ok) {
-			fprintf(stderr, "unknown flag %s\n", *argv);
-			err = 2;
-			goto out;
-		}
-		argc--;
-		argv++;
-	}
-
-	nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
-
-	err = 0;
-	goto out;
- nla_put_failure:
-	err = -ENOBUFS;
- out:
-	nlmsg_free(flags);
-	return err;
+	case -EINVAL:
+		fprintf(stderr, "unknown flag %s\n", *argv);
+		return 2;
+	default:
+		return 2;
+	}
+ nla_put_failure:
+	return -ENOBUFS;
 }
 COMMAND(set, monitor, "<flag> [...]",
 	NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set);

Modified: iw/branches/upstream/current/iw.c
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/iw.c?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/iw.c (original)
+++ iw/branches/upstream/current/iw.c Sun Oct 26 17:22:36 2008
@@ -85,6 +85,8 @@
 	fprintf(stderr, "\t--debug\t\tenable netlink debugging\n");
 	fprintf(stderr, "\t--version\tshow version\n");
 	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)
@@ -141,6 +143,8 @@
 
 static int finish_handler(struct nl_msg *msg, void *arg)
 {
+	int *ret = arg;
+	*ret = 0;
 	return NL_SKIP;
 }
 
@@ -248,11 +252,14 @@
 	if (err < 0)
 		goto out;
 
+	err = 1;
+
 	nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
-	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, NULL);
+	nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
 	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
 
-	nl_recvmsgs(state->nl_handle, cb);
+	while (err > 0)
+		nl_recvmsgs(state->nl_handle, cb);
  out:
 	nl_cb_put(cb);
  out_free_msg:
@@ -263,6 +270,62 @@
 	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];
+
+	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;
+	}
+	}
+
+	return NL_SKIP;
+}
+
+static int listen_events(struct nl80211_state *state,
+			 int argc, char **argv)
+{
+	int mcid, ret;
+	struct nl_cb *cb = nl_cb_alloc(debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+
+	if (!cb) {
+		fprintf(stderr, "failed to allocate netlink callbacks\n");
+		return -ENOMEM;
+	}
+
+	mcid = nl_get_multicast_id(state->nl_handle, "nl80211", "config");
+	if (mcid < 0)
+		return mcid;
+
+	ret = nl_socket_add_membership(state->nl_handle, 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);
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, NULL);
+
+	while (1)
+		nl_recvmsgs(state->nl_handle, cb);
+
+	nl_cb_put(cb);
+
+	return 0;
+}
+
 int main(int argc, char **argv)
 {
 	struct nl80211_state nlstate;
@@ -296,7 +359,9 @@
 	if (err)
 		return 1;
 
-	if (strcmp(*argv, "dev") == 0) {
+	if (strcmp(*argv, "event") == 0) {
+		err = listen_events(&nlstate, argc, argv);
+	} else if (strcmp(*argv, "dev") == 0) {
 		argc--;
 		argv++;
 		err = handle_cmd(&nlstate, CIB_NETDEV, argc, argv);

Modified: iw/branches/upstream/current/iw.h
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/iw.h?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/iw.h (original)
+++ iw/branches/upstream/current/iw.h Sun Oct 26 17:22:36 2008
@@ -58,4 +58,6 @@
 
 const char *iftype_name(enum nl80211_iftype iftype);
 
+int nl_get_multicast_id(struct nl_handle *handle, const char *family, const char *group);
+
 #endif /* __IW_H */

Added: iw/branches/upstream/current/mesh.c
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/mesh.c?rev=1272&op=file
==============================================================================
--- iw/branches/upstream/current/mesh.c (added)
+++ iw/branches/upstream/current/mesh.c Sun Oct 26 17:22:36 2008
@@ -1,0 +1,297 @@
+#include <net/if.h>
+#include <errno.h>
+#include <string.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+typedef struct _any_t {
+	union {
+		uint32_t as_32;
+		uint16_t as_16;
+		uint8_t as_8;
+	} u;
+} _any;
+
+/* describes a mesh parameter */
+struct mesh_param_descr {
+	const char *name;
+	enum nl80211_meshconf_params mesh_param_num;
+	int (*nla_put_fn)(struct nl_msg*, int, _any*);
+	uint32_t (*parse_fn)(const char*, _any*);
+	void (*nla_print_fn)(struct nlattr *);
+};
+
+/* utility functions for manipulating and printing u8/u16/u32 values and
+ * timesouts. */
+static int _my_nla_put_u8(struct nl_msg *n, int mesh_param_num, _any *value)
+{
+	return nla_put(n, mesh_param_num, sizeof(uint8_t), &value->u.as_8);
+}
+
+static int _my_nla_put_u16(struct nl_msg *n, int mesh_param_num, _any *value)
+{
+	return nla_put(n, mesh_param_num, sizeof(uint16_t), &value->u.as_16);
+}
+
+static int _my_nla_put_u32(struct nl_msg *n, int mesh_param_num, _any *value)
+{
+	return nla_put(n, mesh_param_num, sizeof(uint32_t), &value->u.as_32);
+}
+
+static uint32_t _parse_u8(const char *str, _any *ret)
+{
+	char *endptr = NULL;
+	unsigned long int v = strtoul(str, &endptr, 10);
+	if (*endptr != '\0')
+		return 0xff;
+	if (v > 0xff)
+		return 0xff;
+	ret->u.as_8 = (uint8_t)v;
+	return 0;
+}
+
+static uint32_t _parse_u8_as_bool(const char *str, _any *ret)
+{
+	char *endptr = NULL;
+	unsigned long int v = strtoul(str, &endptr, 10);
+	if (*endptr != '\0')
+		return 0x1;
+	if (v > 0x1)
+		return 0x1;
+	ret->u.as_8 = (uint8_t)v;
+	return 0;
+}
+
+static uint32_t _parse_u16(const char *str, _any *ret)
+{
+	char *endptr = NULL;
+	long int v = strtol(str, &endptr, 10);
+	if (*endptr != '\0')
+		return 0xffff;
+	if ((v < 0) || (v > 0xffff))
+		return 0xffff;
+	ret->u.as_16 = (uint16_t)v;
+	return 0;
+}
+
+static uint32_t _parse_u32(const char *str, _any *ret)
+{
+	char *endptr = NULL;
+	long long int v = strtoll(str, &endptr, 10);
+	if (*endptr != '\0')
+		return 0xffffffff;
+	if ((v < 0) || (v > 0xffffffff))
+		return 0xffffffff;
+	ret->u.as_32 = (uint32_t)v;
+	return 0;
+}
+
+void _print_u8(struct nlattr *a)
+{
+	printf("%d", nla_get_u8(a));
+}
+
+void _print_u16(struct nlattr *a)
+{
+	printf("%d", nla_get_u16(a));
+}
+
+void _print_u16_timeout(struct nlattr *a)
+{
+	printf("%d milliseconds", nla_get_u16(a));
+}
+
+void _print_u16_in_TUs(struct nlattr *a)
+{
+	printf("%d TUs", nla_get_u16(a));
+}
+
+void _print_u32_timeout(struct nlattr *a)
+{
+	printf("%u milliseconds", nla_get_u32(a));
+}
+
+void _print_u32_in_TUs(struct nlattr *a)
+{
+	printf("%d TUs", nla_get_u32(a));
+}
+
+/* The current mesh parameters */
+const static struct mesh_param_descr _mesh_param_descrs[] =
+{
+	{"mesh_retry_timeout",
+	NL80211_MESHCONF_RETRY_TIMEOUT,
+	_my_nla_put_u16, _parse_u16, _print_u16_timeout},
+	{"mesh_confirm_timeout",
+	NL80211_MESHCONF_CONFIRM_TIMEOUT,
+	_my_nla_put_u16, _parse_u16, _print_u16_timeout},
+	{"mesh_holding_timeout",
+	NL80211_MESHCONF_HOLDING_TIMEOUT,
+	_my_nla_put_u16, _parse_u16, _print_u16_timeout},
+	{"mesh_max_peer_links",
+	NL80211_MESHCONF_MAX_PEER_LINKS,
+	_my_nla_put_u16, _parse_u16, _print_u16},
+	{"mesh_max_retries",
+	NL80211_MESHCONF_MAX_RETRIES,
+	_my_nla_put_u8, _parse_u8, _print_u8},
+	{"mesh_ttl",
+	NL80211_MESHCONF_TTL,
+	_my_nla_put_u8, _parse_u8, _print_u8},
+	{"mesh_auto_open_plinks",
+	NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+	_my_nla_put_u8, _parse_u8_as_bool, _print_u8},
+	{"mesh_hwmp_max_preq_retries",
+	NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+	_my_nla_put_u8, _parse_u8, _print_u8},
+	{"mesh_path_refresh_time",
+	NL80211_MESHCONF_PATH_REFRESH_TIME,
+	_my_nla_put_u32, _parse_u32, _print_u32_timeout},
+	{"mesh_min_discovery_timeout",
+	NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+	_my_nla_put_u16, _parse_u16, _print_u16_timeout},
+	{"mesh_hwmp_active_path_timeout",
+	NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+	_my_nla_put_u32, _parse_u32, _print_u32_in_TUs},
+	{"mesh_hwmp_preq_min_interval",
+	NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+	_my_nla_put_u16, _parse_u16, _print_u16_in_TUs},
+	{"mesh_hwmp_net_diameter_traversal_time",
+	NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+	_my_nla_put_u16, _parse_u16, _print_u16_in_TUs},
+};
+
+static void print_all_mesh_param_descr(void)
+{
+	int i;
+	const char *comma = "";
+
+	for (i = 0;
+	     i < sizeof(_mesh_param_descrs)/sizeof(_mesh_param_descrs[0]);
+	     ++i) {
+		printf("%s%s", comma, _mesh_param_descrs[i].name);
+		comma = ", ";
+	}
+}
+
+static const struct mesh_param_descr* find_mesh_param(int argc, char **argv,
+						const char *action_name)
+{
+	int i;
+	const struct mesh_param_descr *mdescr;
+
+	if (argc < 1) {
+		printf("You must specify which mesh parameter to %s.\n",
+		       action_name);
+		return NULL;
+	}
+
+	/* Find out what mesh parameter we want to change. */
+	mdescr = NULL;
+	for (i = 0;
+	     i < sizeof(_mesh_param_descrs)/sizeof(_mesh_param_descrs[0]);
+	     ++i) {
+		if (!strcmp(_mesh_param_descrs[i].name, argv[0]))
+			return _mesh_param_descrs + i;
+	}
+
+	if (!mdescr) {
+		printf("Mesh_param must be one of: ");
+		print_all_mesh_param_descr();
+		printf("\n");
+		return NULL;
+	}
+	return mdescr;
+}
+
+/* Setter */
+static int set_interface_meshparam(struct nl_cb *cb,
+				struct nl_msg *msg,
+				int argc, char **argv)
+{
+	int err;
+	uint32_t ret;
+	const struct mesh_param_descr *mdescr;
+	_any any;
+
+	mdescr = find_mesh_param(argc, argv, "change");
+	if (!mdescr)
+		return 2;
+	if (argc != 2) {
+		printf("Must specify a value for %s.\n", mdescr->name);
+		return 2;
+	}
+
+	/* Parse the new value */
+	memset(&any, 0, sizeof(_any));
+	ret = mdescr->parse_fn(argv[1], &any);
+	if (ret != 0) {
+		printf("%s must be set to a number "
+		       "between 0 and %u\n", mdescr->name, ret);
+		return 2;
+	}
+
+	/* Construct a netlink message */
+	struct nlattr *container =
+		nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
+	if (!container)
+		return -ENOBUFS;
+	err = mdescr->nla_put_fn(msg, mdescr->mesh_param_num, &any);
+	nla_nest_end(msg, container);
+
+	return err;
+}
+
+COMMAND(set, mesh_param, "<param> <value>",
+	NL80211_CMD_SET_MESH_PARAMS, 0, CIB_NETDEV, set_interface_meshparam);
+
+/* Getter */
+static int print_mesh_param_handler(struct nl_msg *msg, void *arg)
+{
+	const struct mesh_param_descr *mdescr = arg;
+	struct nlattr *attrs[NL80211_ATTR_MAX + 1];
+	struct nlattr *parent_attr;
+	struct nlattr *mesh_params[NL80211_MESHCONF_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+
+	/* locate NL80211_ATTR_MESH_PARAMS */
+	nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+	parent_attr = attrs[NL80211_ATTR_MESH_PARAMS];
+	if (!parent_attr)
+		return -EINVAL;
+
+	/* unpack the mesh parameters */
+	if (nla_parse_nested(mesh_params, NL80211_MESHCONF_ATTR_MAX,
+				parent_attr, NULL))
+		return -EINVAL;
+
+	/* print out the mesh parameter */
+	mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]);
+	printf("\n");
+	return NL_SKIP;
+}
+
+static int get_interface_meshparam(struct nl_cb *cb,
+				struct nl_msg *msg,
+				int argc, char **argv)
+{
+	const struct mesh_param_descr *mdescr;
+
+	mdescr = find_mesh_param(argc, argv, "get");
+	if (!mdescr)
+		return 2;
+
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
+		  print_mesh_param_handler, (void *)mdescr);
+	return 0;
+}
+
+COMMAND(get, mesh_param, "<param>",
+	NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam);

Modified: iw/branches/upstream/current/nl80211.h
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/nl80211.h?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/nl80211.h (original)
+++ iw/branches/upstream/current/nl80211.h Sun Oct 26 17:22:36 2008
@@ -106,6 +106,12 @@
  * 	to the the specified ISO/IEC 3166-1 alpha2 country code. The core will
  * 	store this as a valid request and then query userspace for it.
  *
+ * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ *	interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ *      interface identified by %NL80211_ATTR_IFINDEX
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -147,6 +153,9 @@
 
 	NL80211_CMD_SET_REG,
 	NL80211_CMD_REQ_SET_REG,
+
+	NL80211_CMD_GET_MESH_PARAMS,
+	NL80211_CMD_SET_MESH_PARAMS,
 
 	/* add new commands above here */
 
@@ -296,6 +305,8 @@
 	NL80211_ATTR_REG_ALPHA2,
 	NL80211_ATTR_REG_RULES,
 
+	NL80211_ATTR_MESH_PARAMS,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -452,16 +463,28 @@
  *	an array of nested frequency attributes
  * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
  *	an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ *	defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
  */
 enum nl80211_band_attr {
 	__NL80211_BAND_ATTR_INVALID,
 	NL80211_BAND_ATTR_FREQS,
 	NL80211_BAND_ATTR_RATES,
 
+	NL80211_BAND_ATTR_HT_MCS_SET,
+	NL80211_BAND_ATTR_HT_CAPA,
+	NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+	NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
 	/* keep last */
 	__NL80211_BAND_ATTR_AFTER_LAST,
 	NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
 };
+
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
 
 /**
  * enum nl80211_frequency_attr - frequency attributes
@@ -594,4 +617,79 @@
 	NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_meshconf_params - mesh configuration parameters
+ *
+ * Mesh configuration parameters
+ *
+ * @__NL80211_MESHCONF_INVALID: internal use
+ *
+ * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
+ * millisecond units, used by the Peer Link Open message
+ *
+ * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the inital confirm timeout, in
+ * millisecond units, used by the peer link management to close a peer link
+ *
+ * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
+ * millisecond units
+ *
+ * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
+ * on this mesh interface
+ *
+ * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
+ * open retries that can be sent to establish a new peer link instance in a
+ * mesh
+ *
+ * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
+ * point.
+ *
+ * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
+ * open peer links when we detect compatible mesh peers.
+ *
+ * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
+ * containing a PREQ that an MP can send to a particular destination (path
+ * target)
+ *
+ * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
+ * (in milliseconds)
+ *
+ * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
+ * until giving up on a path discovery (in milliseconds)
+ *
+ * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
+ * points receiving a PREQ shall consider the forwarding information from the
+ * root to be valid. (TU = time unit)
+ *
+ * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which an MP can send only one action frame containing a PREQ
+ * reference element
+ *
+ * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
+ * that it takes for an HWMP information element to propagate across the mesh
+ *
+ * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
+ *
+ * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_meshconf_params {
+	__NL80211_MESHCONF_INVALID,
+	NL80211_MESHCONF_RETRY_TIMEOUT,
+	NL80211_MESHCONF_CONFIRM_TIMEOUT,
+	NL80211_MESHCONF_HOLDING_TIMEOUT,
+	NL80211_MESHCONF_MAX_PEER_LINKS,
+	NL80211_MESHCONF_MAX_RETRIES,
+	NL80211_MESHCONF_TTL,
+	NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+	NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+	NL80211_MESHCONF_PATH_REFRESH_TIME,
+	NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+	NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+	NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+	NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+
+	/* keep last */
+	__NL80211_MESHCONF_ATTR_AFTER_LAST,
+	NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */

Modified: iw/branches/upstream/current/version.sh
URL: http://svn.debian.org/wsvn/iw/branches/upstream/current/version.sh?rev=1272&op=diff
==============================================================================
--- iw/branches/upstream/current/version.sh (original)
+++ iw/branches/upstream/current/version.sh Sun Oct 26 17:22:36 2008
@@ -1,8 +1,8 @@
 #!/bin/sh
 
-VERSION="0.9.5"
+VERSION="0.9.6"
+OUT="version.h"
 
-(
 if head=`git rev-parse --verify HEAD 2>/dev/null`; then
 	git update-index --refresh --unmerged > /dev/null
 	descr=$(git describe)
@@ -11,13 +11,12 @@
 	# is correct...
 	[ "${descr%%-*}" = "v$VERSION" ] || exit 2
 	
-	echo -n '#define IW_VERSION "'
-	echo -n "${descr#v}"
+	echo -n '#define IW_VERSION "' > "$OUT"
+	echo -n "${descr#v}" >> "$OUT"
 	if git diff-index --name-only HEAD | read dummy ; then
-		echo -n "-dirty"
+		echo -n "-dirty" >> "$OUT"
 	fi
-	echo '"'
+	echo '"' >> "$OUT"
 else
-echo "#define IW_VERSION \"$VERSION-nogit\""
+echo "#define IW_VERSION \"$VERSION-nogit\"" > "$OUT"
 fi
-) > version.h




More information about the Pkg-wpa-devel mailing list