]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
ibss join/leave/event code
authorJohannes Berg <johannes@sipsolutions.net>
Sat, 18 Apr 2009 22:53:31 +0000 (00:53 +0200)
committerJohannes Berg <johannes@sipsolutions.net>
Sat, 18 Apr 2009 22:53:31 +0000 (00:53 +0200)
Makefile
ibss.c [new file with mode: 0644]
iw.c
nl80211.h

index 427a372a1aabcad8eeb2cea1104d8e991b66a81d..6ec41717290324a29722280ef2dbb6719e92ebc6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ CC ?= "gcc"
 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 station.o util.o mesh.o mpath.o scan.o reg.o
+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
 ALL = iw
 
 NL1FOUND := $(shell pkg-config --atleast-version=1 libnl-1 && echo Y)
diff --git a/ibss.c b/ibss.c
new file mode 100644 (file)
index 0000000..a9cc6fc
--- /dev/null
+++ b/ibss.c
@@ -0,0 +1,74 @@
+#include <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>
+
+#include "nl80211.h"
+#include "iw.h"
+
+static int join_ibss(struct nl80211_state *state,
+                    struct nl_cb *cb,
+                    struct nl_msg *msg,
+                    int argc, char **argv)
+{
+       int oargc;
+       char *bssid = NULL, *freq = NULL;
+       unsigned char abssid[6];
+
+       NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
+
+       argv++;
+       argc--;
+
+       oargc = argc;
+
+       while (argc) {
+               if (argc > 0 && strcmp(argv[0], "bssid") == 0) {
+                       bssid = argv[1];
+                       argv += 2;
+                       argc -= 2;
+               }
+
+               if (argc > 0 && strcmp(argv[0], "freq") == 0) {
+                       freq = argv[1];
+                       argv += 2;
+                       argc -= 2;
+               }
+               if (oargc == argc)
+                       return 1;
+               oargc = argc;
+       }
+
+       if (bssid) {
+               if (mac_addr_a2n(abssid, bssid))
+                       return 1;
+               NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
+       }
+
+       if (freq) {
+               char *end;
+               NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ,
+                           strtoul(freq, &end, 10));
+               if (*end != '\0')
+                       return 1;
+       }
+
+       return 0;
+ nla_put_failure:
+       return -ENOSPC;
+}
+
+static int leave_ibss(struct nl80211_state *state,
+                     struct nl_cb *cb,
+                     struct nl_msg *msg,
+                     int argc, char **argv)
+{
+       return 0;
+}
+COMMAND(ibss, leave, NULL,
+       NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss);
+COMMAND(ibss, join, "<SSID> [bssid <bssid>] [freq <freq in MHz>]",
+       NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss);
diff --git a/iw.c b/iw.c
index a811d54c38b350519ecaa9aa4436cfb00e091178..b8323ff02929c7356c81fc404ea54d5c72deda08 100644 (file)
--- a/iw.c
+++ b/iw.c
@@ -334,6 +334,7 @@ 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),
@@ -391,6 +392,12 @@ static int print_event(struct nl_msg *msg, void *arg)
 
                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;
@@ -457,6 +464,14 @@ __u32 listen_events(struct nl80211_state *state,
                        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);
 
index c01423888db9d36eb7754b49a81c674807930d31..321bfe6985881dfc5c4f9a6ae49e84b9d6e4eb62 100644 (file)
--- a/nl80211.h
+++ b/nl80211.h
  *     %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
  *     event matches with MLME-MICHAELMICFAILURE.indication() primitive
  *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID, and
+ *     optionally a MAC (as BSSID) and FREQ attribute if those should be
+ *     fixed rather than automatically determined. Can only be executed
+ *     on a network interface that is UP, and fixed BSSID/FREQ may be
+ *     rejected.
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *     determined by the network interface.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -288,6 +296,9 @@ enum nl80211_commands {
 
        NL80211_CMD_REG_BEACON_HINT,
 
+       NL80211_CMD_JOIN_IBSS,
+       NL80211_CMD_LEAVE_IBSS,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */