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
,
13 struct nl_msg
*msg
, int argc
, char **argv
,
17 unsigned char bssid
[6];
18 bool need_key
= false;
26 NLA_PUT(msg
, NL80211_ATTR_SSID
, strlen(argv
[0]), argv
[0]);
32 freq
= strtoul(argv
[0], &end
, 10);
34 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
42 if (mac_addr_a2n(bssid
, argv
[0]) == 0) {
43 NLA_PUT(msg
, NL80211_ATTR_MAC
, 6, bssid
);
52 if (strcmp(*argv
, "auth") == 0) {
59 if (strcmp(argv
[0], "open") == 0) {
60 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
61 NL80211_AUTHTYPE_OPEN_SYSTEM
);
62 } else if (strcmp(argv
[0], "shared") == 0) {
63 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
64 NL80211_AUTHTYPE_SHARED_KEY
);
74 if (need_key
&& !argc
)
77 if (argc
&& strcmp(*argv
, "key") != 0 && strcmp(*argv
, "keys") != 0)
86 ret
= parse_keys(msg
, &argv
, &argc
);
93 if (!strcmp(*argv
, "mfp:req"))
94 NLA_PUT_U32(msg
, NL80211_ATTR_USE_MFP
, NL80211_MFP_REQUIRED
);
95 else if (!strcmp(*argv
, "mfp:opt"))
96 NLA_PUT_U32(msg
, NL80211_ATTR_USE_MFP
, NL80211_MFP_OPTIONAL
);
97 else if (!strcmp(*argv
, "mfp:no"))
98 NLA_PUT_U32(msg
, NL80211_ATTR_USE_MFP
, NL80211_MFP_NO
);
108 static int disconnect(struct nl80211_state
*state
,
110 int argc
, char **argv
,
115 TOPLEVEL(disconnect
, NULL
,
116 NL80211_CMD_DISCONNECT
, 0, CIB_NETDEV
, disconnect
,
117 "Disconnect from the current network.");
119 static int iw_connect(struct nl80211_state
*state
,
120 struct nl_msg
*msg
, int argc
, char **argv
,
123 char **conn_argv
, *dev
= argv
[0];
124 static const __u32 cmds
[] = {
127 struct print_event_args printargs
= { };
132 /* strip "wlan0 connect" */
137 if (argc
&& strcmp(argv
[0], "-w") == 0) {
143 err
= __prepare_listen_events(state
);
147 conn_argc
= 3 + argc
;
148 conn_argv
= calloc(conn_argc
, sizeof(*conn_argv
));
153 conn_argv
[1] = "connect";
154 conn_argv
[2] = "establish";
155 for (i
= 0; i
< argc
; i
++)
156 conn_argv
[i
+ 3] = argv
[i
];
157 err
= handle_cmd(state
, id
, conn_argc
, conn_argv
);
166 * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION
168 * This code has a bug:
170 * It is possible for a connect result message from another
171 * connect attempt to be processed here first, because we
172 * start listening to the multicast group before starting
173 * our own connect request, which may succeed but we get a
174 * fail message from a previous attempt that raced with us,
177 * The only proper way to fix this would be to listen to events
178 * before sending the command, and for the kernel to send the
179 * connect request or a cookie along with the event, so that you
180 * can match up whether the connect _you_ requested was finished
183 * Alas, the kernel doesn't do that (yet).
186 __do_listen_events(state
,
187 ARRAY_SIZE(cmds
), cmds
,
188 ARRAY_SIZE(cmds
), cmds
,
192 TOPLEVEL(connect
, "[-w] <SSID> [<freq in MHz>] [<bssid>] [auth open|shared] [key 0:abcde d:1:6162636465] [mfp:req/opt/no]",
193 0, 0, CIB_NETDEV
, iw_connect
,
194 "Join the network with the given SSID (and frequency, BSSID).\n"
195 "With -w, wait for the connect to finish or fail.");
196 HIDDEN(connect
, establish
, "", NL80211_CMD_CONNECT
, 0, CIB_NETDEV
, iw_conn
);
198 static int iw_auth(struct nl80211_state
*state
,
199 struct nl_msg
*msg
, int argc
, char **argv
,
203 unsigned char bssid
[6];
205 bool need_key
= false;
211 NLA_PUT(msg
, NL80211_ATTR_SSID
, strlen(argv
[0]), argv
[0]);
216 if (mac_addr_a2n(bssid
, argv
[0]) == 0) {
217 NLA_PUT(msg
, NL80211_ATTR_MAC
, 6, bssid
);
225 if (strcmp(argv
[0], "open") == 0) {
226 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
227 NL80211_AUTHTYPE_OPEN_SYSTEM
);
228 } else if (strcmp(argv
[0], "shared") == 0) {
229 NLA_PUT_U32(msg
, NL80211_ATTR_AUTH_TYPE
,
230 NL80211_AUTHTYPE_SHARED_KEY
);
238 freq
= strtoul(argv
[0], &end
, 10);
240 NLA_PUT_U32(msg
, NL80211_ATTR_WIPHY_FREQ
, freq
);
247 if (!argc
&& need_key
)
249 if (argc
&& !need_key
)
254 if (strcmp(*argv
, "key") != 0 && strcmp(*argv
, "keys") != 0)
260 return parse_keys(msg
, &argv
, &argc
);
265 TOPLEVEL(auth
, "<SSID> <bssid> <type:open|shared> <freq in MHz> [key 0:abcde d:1:6162636465]",
266 NL80211_CMD_AUTHENTICATE
, 0, CIB_NETDEV
, iw_auth
,
267 "Authenticate with the given network.\n");