3 #include <netlink/genl/genl.h>
4 #include <netlink/genl/family.h>
5 #include <netlink/genl/ctrl.h>
6 #include <netlink/msg.h>
7 #include <netlink/attr.h>
12 static int iw_conn(struct nl80211_state
*state
, struct nl_cb
*cb
,
13 struct nl_msg
*msg
, int argc
, char **argv
)
16 unsigned char bssid
[6];
23 NLA_PUT(msg
, NL80211_ATTR_SSID
, strlen(argv
[0]), argv
[0]);
29 freq
= strtoul(argv
[0], &end
, 10);
31 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
39 if (mac_addr_a2n(bssid
, argv
[0]) == 0) {
40 NLA_PUT(msg
, NL80211_ATTR_MAC
, 6, bssid
);
47 if (strcmp(*argv
, "key") != 0 && strcmp(*argv
, "keys") != 0)
53 err
= parse_keys(msg
, argv
, argc
);
58 return set_interface_up(state
->ifname
);
64 static int disconnect(struct nl80211_state
*state
,
67 int argc
, char **argv
)
71 TOPLEVEL(disconnect
, NULL
,
72 NL80211_CMD_DISCONNECT
, 0, CIB_NETDEV
, disconnect
,
73 "Disconnect from the current network.");
74 HIDDEN(conn
, establish
, "", NL80211_CMD_CONNECT
, 0, CIB_NETDEV
, iw_conn
);
76 static int iw_connect(struct nl80211_state
*state
, struct nl_cb
*cb
,
77 struct nl_msg
*msg
, int argc
, char **argv
)
79 char **conn_argv
, *dev
= argv
[0];
80 static const __u32 cmds
[] = {
83 struct print_event_args printargs
= { };
88 /* strip "wlan0 connect" */
93 if (argc
&& strcmp(argv
[0], "-w") == 0) {
100 conn_argv
= calloc(conn_argc
, sizeof(*conn_argv
));
104 conn_argv
[1] = "conn";
105 conn_argv
[2] = "establish";
106 for (i
= 0; i
< argc
; i
++)
107 conn_argv
[i
+ 3] = argv
[i
];
108 err
= handle_cmd(state
, II_NETDEV
, conn_argc
, conn_argv
);
117 * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION
119 * This code has a bug, which requires creating a separate
120 * nl80211 socket to fix:
121 * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or
122 * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel
123 * before (!) we listen to it, because we only start listening
124 * after we send our scan request.
126 * Doing it the other way around has a race condition as well,
127 * if you first open the events socket you may get a notification
128 * for a previous scan.
130 * The only proper way to fix this would be to listen to events
131 * before sending the command, and for the kernel to send the
132 * connect request along with the event, so that you can match
133 * up whether the connect _you_ requested was finished or aborted.
135 * Alas, the kernel doesn't do that (yet).
138 __listen_events(state
, ARRAY_SIZE(cmds
), cmds
, &printargs
);
141 TOPLEVEL(connect
, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]",
142 0, 0, CIB_NETDEV
, iw_connect
,
143 "Join the network with the given SSID (and frequency, BSSID).\n"
144 "With -w, wait for the connect to finish or fail.");