wlantest: Add functionality for fetching STA/BSS information
[mech_eap.git] / wlantest / ctrl.c
1 /*
2  * wlantest control interface
3  * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "utils/includes.h"
16 #include <sys/un.h>
17
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "common/defs.h"
21 #include "common/version.h"
22 #include "common/ieee802_11_defs.h"
23 #include "wlantest.h"
24 #include "wlantest_ctrl.h"
25
26
27 static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
28                      size_t *len)
29 {
30         u8 *pos = buf;
31
32         while (pos + 8 <= buf + buflen) {
33                 enum wlantest_ctrl_attr a;
34                 size_t alen;
35                 a = WPA_GET_BE32(pos);
36                 pos += 4;
37                 alen = WPA_GET_BE32(pos);
38                 pos += 4;
39                 if (pos + alen > buf + buflen) {
40                         wpa_printf(MSG_DEBUG, "Invalid control message "
41                                    "attribute");
42                         return NULL;
43                 }
44                 if (a == attr) {
45                         *len = alen;
46                         return pos;
47                 }
48                 pos += alen;
49         }
50
51         return NULL;
52 }
53
54
55 static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
56                              enum wlantest_ctrl_attr attr)
57 {
58         u8 *addr;
59         size_t addr_len;
60         addr = attr_get(buf, buflen, attr, &addr_len);
61         if (addr && addr_len != ETH_ALEN)
62                 addr = NULL;
63         return addr;
64 }
65
66
67 static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
68 {
69         u8 *pos;
70         size_t len;
71         pos = attr_get(buf, buflen, attr, &len);
72         if (pos == NULL || len != 4)
73                 return -1;
74         return WPA_GET_BE32(pos);
75 }
76
77
78 static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
79                          const char *str)
80 {
81         size_t len = os_strlen(str);
82
83         if (pos == NULL || end - pos < 8 + len)
84                 return NULL;
85         WPA_PUT_BE32(pos, attr);
86         pos += 4;
87         WPA_PUT_BE32(pos, len);
88         pos += 4;
89         os_memcpy(pos, str, len);
90         pos += len;
91         return pos;
92 }
93
94
95 static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
96                           u32 val)
97 {
98         if (pos == NULL || end - pos < 12)
99                 return NULL;
100         WPA_PUT_BE32(pos, attr);
101         pos += 4;
102         WPA_PUT_BE32(pos, 4);
103         pos += 4;
104         WPA_PUT_BE32(pos, val);
105         pos += 4;
106         return pos;
107 }
108
109
110 static void ctrl_disconnect(struct wlantest *wt, int sock)
111 {
112         int i;
113         wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
114                    sock);
115         for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
116                 if (wt->ctrl_socks[i] == sock) {
117                         close(wt->ctrl_socks[i]);
118                         eloop_unregister_read_sock(wt->ctrl_socks[i]);
119                         wt->ctrl_socks[i] = -1;
120                         break;
121                 }
122         }
123 }
124
125
126 static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
127                       size_t len)
128 {
129         if (send(sock, buf, len, 0) < 0) {
130                 wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
131                 ctrl_disconnect(wt, sock);
132         }
133 }
134
135
136 static void ctrl_send_simple(struct wlantest *wt, int sock,
137                              enum wlantest_ctrl_cmd cmd)
138 {
139         u8 buf[4];
140         WPA_PUT_BE32(buf, cmd);
141         ctrl_send(wt, sock, buf, sizeof(buf));
142 }
143
144
145 static void ctrl_list_bss(struct wlantest *wt, int sock)
146 {
147         u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
148         struct wlantest_bss *bss;
149
150         pos = buf;
151         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
152         pos += 4;
153         WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
154         pos += 4;
155         len = pos; /* to be filled */
156         pos += 4;
157
158         dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
159                 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
160                         break;
161                 os_memcpy(pos, bss->bssid, ETH_ALEN);
162                 pos += ETH_ALEN;
163         }
164
165         WPA_PUT_BE32(len, pos - len - 4);
166         ctrl_send(wt, sock, buf, pos - buf);
167 }
168
169
170 static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
171 {
172         u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
173         u8 *bssid;
174         size_t bssid_len;
175         struct wlantest_bss *bss;
176         struct wlantest_sta *sta;
177
178         bssid = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &bssid_len);
179         if (bssid == NULL || bssid_len != ETH_ALEN) {
180                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
181                 return;
182         }
183
184         bss = bss_find(wt, bssid);
185         if (bss == NULL) {
186                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
187                 return;
188         }
189
190         pos = buf;
191         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
192         pos += 4;
193         WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
194         pos += 4;
195         len = pos; /* to be filled */
196         pos += 4;
197
198         dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
199                 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
200                         break;
201                 os_memcpy(pos, sta->addr, ETH_ALEN);
202                 pos += ETH_ALEN;
203         }
204
205         WPA_PUT_BE32(len, pos - len - 4);
206         ctrl_send(wt, sock, buf, pos - buf);
207 }
208
209
210 static void ctrl_flush(struct wlantest *wt, int sock)
211 {
212         wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
213         bss_flush(wt);
214         ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
215 }
216
217
218 static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
219                                     size_t clen)
220 {
221         u8 *addr;
222         size_t addr_len;
223         struct wlantest_bss *bss;
224         struct wlantest_sta *sta;
225
226         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
227         if (addr == NULL || addr_len != ETH_ALEN) {
228                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
229                 return;
230         }
231
232         bss = bss_find(wt, addr);
233         if (bss == NULL) {
234                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
235                 return;
236         }
237
238         addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
239         if (addr == NULL || addr_len != ETH_ALEN) {
240                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
241                 return;
242         }
243
244         sta = sta_find(bss, addr);
245         if (sta == NULL) {
246                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
247                 return;
248         }
249
250         os_memset(sta->counters, 0, sizeof(sta->counters));
251         ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
252 }
253
254
255 static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
256                                     size_t clen)
257 {
258         u8 *addr;
259         size_t addr_len;
260         struct wlantest_bss *bss;
261
262         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
263         if (addr == NULL || addr_len != ETH_ALEN) {
264                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
265                 return;
266         }
267
268         bss = bss_find(wt, addr);
269         if (bss == NULL) {
270                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
271                 return;
272         }
273
274         os_memset(bss->counters, 0, sizeof(bss->counters));
275         ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
276 }
277
278
279 static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
280                                  size_t clen)
281 {
282         u8 *addr;
283         size_t addr_len;
284         struct wlantest_bss *bss;
285         struct wlantest_sta *sta;
286         u32 counter;
287         u8 buf[4 + 12], *end, *pos;
288
289         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
290         if (addr == NULL || addr_len != ETH_ALEN) {
291                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
292                 return;
293         }
294
295         bss = bss_find(wt, addr);
296         if (bss == NULL) {
297                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
298                 return;
299         }
300
301         addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
302         if (addr == NULL || addr_len != ETH_ALEN) {
303                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
304                 return;
305         }
306
307         sta = sta_find(bss, addr);
308         if (sta == NULL) {
309                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
310                 return;
311         }
312
313         addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
314         if (addr == NULL || addr_len != 4) {
315                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
316                 return;
317         }
318         counter = WPA_GET_BE32(addr);
319         if (counter >= NUM_WLANTEST_STA_COUNTER) {
320                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
321                 return;
322         }
323
324         pos = buf;
325         end = buf + sizeof(buf);
326         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
327         pos += 4;
328         pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
329                             sta->counters[counter]);
330         ctrl_send(wt, sock, buf, pos - buf);
331 }
332
333
334 static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
335                                  size_t clen)
336 {
337         u8 *addr;
338         size_t addr_len;
339         struct wlantest_bss *bss;
340         u32 counter;
341         u8 buf[4 + 12], *end, *pos;
342
343         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
344         if (addr == NULL || addr_len != ETH_ALEN) {
345                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
346                 return;
347         }
348
349         bss = bss_find(wt, addr);
350         if (bss == NULL) {
351                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
352                 return;
353         }
354
355         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
356         if (addr == NULL || addr_len != 4) {
357                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
358                 return;
359         }
360         counter = WPA_GET_BE32(addr);
361         if (counter >= NUM_WLANTEST_BSS_COUNTER) {
362                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
363                 return;
364         }
365
366         pos = buf;
367         end = buf + sizeof(buf);
368         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
369         pos += 4;
370         pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
371                             bss->counters[counter]);
372         ctrl_send(wt, sock, buf, pos - buf);
373 }
374
375
376 static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
377                            struct wlantest_bss *bss, struct wlantest_sta *sta,
378                            int sender_ap, int stype)
379 {
380         os_memset(mgmt, 0, 24);
381         mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
382         if (sender_ap) {
383                 if (sta)
384                         os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
385                 else
386                         os_memset(mgmt->da, 0xff, ETH_ALEN);
387                 os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
388         } else {
389                 os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
390                 os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
391         }
392         os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
393 }
394
395
396 static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
397                             struct wlantest_sta *sta, int sender_ap,
398                             enum wlantest_inject_protection prot)
399 {
400         struct ieee80211_mgmt mgmt;
401
402         if (prot != WLANTEST_INJECT_NORMAL &&
403             prot != WLANTEST_INJECT_UNPROTECTED)
404                 return -1; /* Authentication frame is never protected */
405         if (sta == NULL)
406                 return -1; /* No broadcast Authentication frames */
407
408         if (sender_ap)
409                 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
410                            MAC2STR(bss->bssid), MAC2STR(sta->addr));
411         else
412                 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
413                            MAC2STR(sta->addr), MAC2STR(bss->bssid));
414         build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);
415
416         mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
417         mgmt.u.auth.auth_transaction = host_to_le16(1);
418         mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
419
420         return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
421                                WLANTEST_INJECT_UNPROTECTED);
422 }
423
424
425 static int ctrl_inject_assocreq(struct wlantest *wt, struct wlantest_bss *bss,
426                                 struct wlantest_sta *sta, int sender_ap,
427                                 enum wlantest_inject_protection prot)
428 {
429         u8 *buf;
430         struct ieee80211_mgmt *mgmt;
431         int ret;
432
433         if (prot != WLANTEST_INJECT_NORMAL &&
434             prot != WLANTEST_INJECT_UNPROTECTED)
435                 return -1; /* Association Request frame is never protected */
436         if (sta == NULL)
437                 return -1; /* No broadcast Association Request frames */
438         if (sender_ap)
439                 return -1; /* No Association Request frame sent by AP */
440         if (sta->assocreq_ies == NULL) {
441                 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
442                            "Request available for " MACSTR,
443                            MAC2STR(sta->addr));
444                 return -1;
445         }
446
447         wpa_printf(MSG_INFO, "INJECT: AssocReq " MACSTR " -> " MACSTR,
448                    MAC2STR(sta->addr), MAC2STR(bss->bssid));
449         buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
450         if (buf == NULL)
451                 return -1;
452         mgmt = (struct ieee80211_mgmt *) buf;
453
454         build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ASSOC_REQ);
455
456         mgmt->u.assoc_req.capab_info = host_to_le16(sta->assocreq_capab_info);
457         mgmt->u.assoc_req.listen_interval =
458                 host_to_le16(sta->assocreq_listen_int);
459         os_memcpy(mgmt->u.assoc_req.variable, sta->assocreq_ies,
460                   sta->assocreq_ies_len);
461
462         ret = wlantest_inject(wt, bss, sta, buf,
463                               24 + 4 + sta->assocreq_ies_len,
464                               WLANTEST_INJECT_UNPROTECTED);
465         os_free(buf);
466         return ret;
467 }
468
469
470 static int ctrl_inject_reassocreq(struct wlantest *wt,
471                                   struct wlantest_bss *bss,
472                                   struct wlantest_sta *sta, int sender_ap,
473                                   enum wlantest_inject_protection prot)
474 {
475         u8 *buf;
476         struct ieee80211_mgmt *mgmt;
477         int ret;
478
479         if (prot != WLANTEST_INJECT_NORMAL &&
480             prot != WLANTEST_INJECT_UNPROTECTED)
481                 return -1; /* Reassociation Request frame is never protected */
482         if (sta == NULL)
483                 return -1; /* No broadcast Reassociation Request frames */
484         if (sender_ap)
485                 return -1; /* No Reassociation Request frame sent by AP */
486         if (sta->assocreq_ies == NULL) {
487                 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
488                            "Request available for " MACSTR,
489                            MAC2STR(sta->addr));
490                 return -1;
491         }
492
493         wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
494                    MAC2STR(sta->addr), MAC2STR(bss->bssid));
495         buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
496         if (buf == NULL)
497                 return -1;
498         mgmt = (struct ieee80211_mgmt *) buf;
499
500         build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);
501
502         mgmt->u.reassoc_req.capab_info =
503                 host_to_le16(sta->assocreq_capab_info);
504         mgmt->u.reassoc_req.listen_interval =
505                 host_to_le16(sta->assocreq_listen_int);
506         os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
507         os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
508                   sta->assocreq_ies_len);
509
510         ret = wlantest_inject(wt, bss, sta, buf,
511                               24 + 10 + sta->assocreq_ies_len,
512                               WLANTEST_INJECT_UNPROTECTED);
513         os_free(buf);
514         return ret;
515 }
516
517
518 static int ctrl_inject_deauth(struct wlantest *wt, struct wlantest_bss *bss,
519                               struct wlantest_sta *sta, int sender_ap,
520                               enum wlantest_inject_protection prot)
521 {
522         struct ieee80211_mgmt mgmt;
523
524         if (sender_ap) {
525                 if (sta)
526                         wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> "
527                                    MACSTR,
528                                    MAC2STR(bss->bssid), MAC2STR(sta->addr));
529                 else
530                         wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR
531                                    " -> broadcast", MAC2STR(bss->bssid));
532         } else
533                 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> " MACSTR,
534                            MAC2STR(sta->addr), MAC2STR(bss->bssid));
535         build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DEAUTH);
536
537         mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
538
539         return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
540 }
541
542
543 static int ctrl_inject_disassoc(struct wlantest *wt, struct wlantest_bss *bss,
544                                 struct wlantest_sta *sta, int sender_ap,
545                                 enum wlantest_inject_protection prot)
546 {
547         struct ieee80211_mgmt mgmt;
548
549         if (sender_ap) {
550                 if (sta)
551                         wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> "
552                                    MACSTR,
553                                    MAC2STR(bss->bssid), MAC2STR(sta->addr));
554                 else
555                         wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR
556                                    " -> broadcast", MAC2STR(bss->bssid));
557         } else
558                 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> " MACSTR,
559                            MAC2STR(sta->addr), MAC2STR(bss->bssid));
560         build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DISASSOC);
561
562         mgmt.u.disassoc.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
563
564         return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
565 }
566
567
568 static int ctrl_inject_saqueryreq(struct wlantest *wt,
569                                   struct wlantest_bss *bss,
570                                   struct wlantest_sta *sta, int sender_ap,
571                                   enum wlantest_inject_protection prot)
572 {
573         struct ieee80211_mgmt mgmt;
574
575         if (sta == NULL)
576                 return -1; /* No broadcast SA Query frames */
577
578         if (sender_ap)
579                 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
580                            MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
581         else
582                 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
583                            MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
584         build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);
585
586         mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
587         mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
588         mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
589         mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
590         os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
591                   mgmt.u.action.u.sa_query_req.trans_id,
592                   WLAN_SA_QUERY_TR_ID_LEN);
593         return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
594 }
595
596
597 static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
598 {
599         u8 *bssid, *sta_addr;
600         struct wlantest_bss *bss;
601         struct wlantest_sta *sta;
602         int frame, sender_ap, prot;
603         int ret = 0;
604
605         bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
606         sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
607         frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
608         sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
609         if (sender_ap < 0)
610                 sender_ap = 0;
611         prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
612         if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
613                 wpa_printf(MSG_INFO, "Invalid inject command parameters");
614                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
615                 return;
616         }
617
618         bss = bss_find(wt, bssid);
619         if (bss == NULL) {
620                 wpa_printf(MSG_INFO, "BSS not found for inject command");
621                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
622                 return;
623         }
624
625         if (is_broadcast_ether_addr(sta_addr)) {
626                 if (!sender_ap) {
627                         wpa_printf(MSG_INFO, "Invalid broadcast inject "
628                                    "command without sender_ap set");
629                         ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
630                         return;
631                 } sta = NULL;
632         } else {
633                 sta = sta_find(bss, sta_addr);
634                 if (sta == NULL) {
635                         wpa_printf(MSG_INFO, "Station not found for inject "
636                                    "command");
637                         ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
638                         return;
639                 }
640         }
641
642         switch (frame) {
643         case WLANTEST_FRAME_AUTH:
644                 ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
645                 break;
646         case WLANTEST_FRAME_ASSOCREQ:
647                 ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
648                 break;
649         case WLANTEST_FRAME_REASSOCREQ:
650                 ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
651                 break;
652         case WLANTEST_FRAME_DEAUTH:
653                 ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
654                 break;
655         case WLANTEST_FRAME_DISASSOC:
656                 ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
657                 break;
658         case WLANTEST_FRAME_SAQUERYREQ:
659                 ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
660                 break;
661         default:
662                 wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
663                            frame);
664                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
665                 return;
666         }
667
668         if (ret)
669                 wpa_printf(MSG_INFO, "Failed to inject frame");
670         else
671                 wpa_printf(MSG_INFO, "Frame injected successfully");
672         ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
673                          WLANTEST_CTRL_FAILURE);
674 }
675
676
677 static void ctrl_version(struct wlantest *wt, int sock)
678 {
679         u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos;
680
681         pos = buf;
682         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
683         pos += 4;
684         pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION,
685                            VERSION_STR);
686         ctrl_send(wt, sock, buf, pos - buf);
687 }
688
689
690 static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
691                                 size_t clen)
692 {
693         u8 *passphrase;
694         size_t len;
695         struct wlantest_passphrase *p, *pa;
696         u8 *bssid;
697
698         passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
699         if (passphrase == NULL || len < 8 || len > 63) {
700                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
701                 return;
702         }
703
704         p = os_zalloc(sizeof(*p));
705         if (p == NULL) {
706                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
707                 return;
708         }
709         os_memcpy(p->passphrase, passphrase, len);
710         wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);
711
712         bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
713         if (bssid) {
714                 os_memcpy(p->bssid, bssid, ETH_ALEN);
715                 wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
716                            MAC2STR(p->bssid));
717         }
718
719         dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
720         {
721                 if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
722                     os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
723                         wpa_printf(MSG_INFO, "Passphrase was already known");
724                         os_free(p);
725                         p = NULL;
726                         break;
727                 }
728         }
729
730         if (p) {
731                 struct wlantest_bss *bss;
732                 dl_list_add(&wt->passphrase, &p->list);
733                 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
734                         if (bssid &&
735                             os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
736                                 continue;
737                         bss_add_pmk_from_passphrase(bss, p->passphrase);
738                 }
739         }
740
741         ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
742 }
743
744
745 static void info_print_proto(char *buf, size_t len, int proto)
746 {
747         char *pos, *end;
748
749         if (proto == 0) {
750                 os_snprintf(buf, len, "OPEN");
751                 return;
752         }
753
754         pos = buf;
755         end = buf + len;
756
757         if (proto & WPA_PROTO_WPA)
758                 pos += os_snprintf(pos, end - pos, "%sWPA",
759                                    pos == buf ? "" : " ");
760         if (proto & WPA_PROTO_RSN)
761                 pos += os_snprintf(pos, end - pos, "%sWPA2",
762                                    pos == buf ? "" : " ");
763 }
764
765
766 static void info_print_cipher(char *buf, size_t len, int cipher)
767 {
768         char *pos, *end;
769
770         if (cipher == 0) {
771                 os_snprintf(buf, len, "N/A");
772                 return;
773         }
774
775         pos = buf;
776         end = buf + len;
777
778         if (cipher & WPA_CIPHER_NONE)
779                 pos += os_snprintf(pos, end - pos, "%sNONE",
780                                    pos == buf ? "" : " ");
781         if (cipher & WPA_CIPHER_WEP40)
782                 pos += os_snprintf(pos, end - pos, "%sWEP40",
783                                    pos == buf ? "" : " ");
784         if (cipher & WPA_CIPHER_WEP104)
785                 pos += os_snprintf(pos, end - pos, "%sWEP104",
786                                    pos == buf ? "" : " ");
787         if (cipher & WPA_CIPHER_TKIP)
788                 pos += os_snprintf(pos, end - pos, "%sTKIP",
789                                    pos == buf ? "" : " ");
790         if (cipher & WPA_CIPHER_CCMP)
791                 pos += os_snprintf(pos, end - pos, "%sCCMP",
792                                    pos == buf ? "" : " ");
793         if (cipher & WPA_CIPHER_AES_128_CMAC)
794                 pos += os_snprintf(pos, end - pos, "%sBIP",
795                                    pos == buf ? "" : " ");
796 }
797
798
799 static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
800 {
801         char *pos, *end;
802
803         if (key_mgmt == 0) {
804                 os_snprintf(buf, len, "N/A");
805                 return;
806         }
807
808         pos = buf;
809         end = buf + len;
810
811         if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
812                 pos += os_snprintf(pos, end - pos, "%sEAP",
813                                    pos == buf ? "" : " ");
814         if (key_mgmt & WPA_KEY_MGMT_PSK)
815                 pos += os_snprintf(pos, end - pos, "%sPSK",
816                                    pos == buf ? "" : " ");
817         if (key_mgmt & WPA_KEY_MGMT_WPA_NONE)
818                 pos += os_snprintf(pos, end - pos, "%sWPA-NONE",
819                                    pos == buf ? "" : " ");
820         if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
821                 pos += os_snprintf(pos, end - pos, "%sFT-EAP",
822                                    pos == buf ? "" : " ");
823         if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
824                 pos += os_snprintf(pos, end - pos, "%sFT-PSK",
825                                    pos == buf ? "" : " ");
826         if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
827                 pos += os_snprintf(pos, end - pos, "%sEAP-SHA256",
828                                    pos == buf ? "" : " ");
829         if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
830                 pos += os_snprintf(pos, end - pos, "%sPSK-SHA256",
831                                    pos == buf ? "" : " ");
832 }
833
834
835 static void info_print_rsn_capab(char *buf, size_t len, int capab)
836 {
837         char *pos, *end;
838
839         pos = buf;
840         end = buf + len;
841
842         if (capab & WPA_CAPABILITY_PREAUTH)
843                 pos += os_snprintf(pos, end - pos, "%sPREAUTH",
844                                    pos == buf ? "" : " ");
845         if (capab & WPA_CAPABILITY_NO_PAIRWISE)
846                 pos += os_snprintf(pos, end - pos, "%sNO_PAIRWISE",
847                                    pos == buf ? "" : " ");
848         if (capab & WPA_CAPABILITY_MFPR)
849                 pos += os_snprintf(pos, end - pos, "%sMFPR",
850                                    pos == buf ? "" : " ");
851         if (capab & WPA_CAPABILITY_MFPC)
852                 pos += os_snprintf(pos, end - pos, "%sMFPC",
853                                    pos == buf ? "" : " ");
854         if (capab & WPA_CAPABILITY_PEERKEY_ENABLED)
855                 pos += os_snprintf(pos, end - pos, "%sPEERKEY",
856                                    pos == buf ? "" : " ");
857 }
858
859
860 static void info_print_state(char *buf, size_t len, int state)
861 {
862         switch (state) {
863         case STATE1:
864                 os_strlcpy(buf, "NOT-AUTH", len);
865                 break;
866         case STATE2:
867                 os_strlcpy(buf, "AUTH", len);
868                 break;
869         case STATE3:
870                 os_strlcpy(buf, "AUTH+ASSOC", len);
871                 break;
872         }
873 }
874
875
876 static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
877 {
878         u8 *addr;
879         size_t addr_len;
880         struct wlantest_bss *bss;
881         struct wlantest_sta *sta;
882         enum wlantest_sta_info info;
883         u8 buf[4 + 108], *end, *pos;
884         char resp[100];
885
886         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
887         if (addr == NULL || addr_len != ETH_ALEN) {
888                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
889                 return;
890         }
891
892         bss = bss_find(wt, addr);
893         if (bss == NULL) {
894                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
895                 return;
896         }
897
898         addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
899         if (addr == NULL || addr_len != ETH_ALEN) {
900                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
901                 return;
902         }
903
904         sta = sta_find(bss, addr);
905         if (sta == NULL) {
906                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
907                 return;
908         }
909
910         addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
911         if (addr == NULL || addr_len != 4) {
912                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
913                 return;
914         }
915         info = WPA_GET_BE32(addr);
916
917         resp[0] = '\0';
918         switch (info) {
919         case WLANTEST_STA_INFO_PROTO:
920                 info_print_proto(resp, sizeof(resp), sta->proto);
921                 break;
922         case WLANTEST_STA_INFO_PAIRWISE:
923                 info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
924                 break;
925         case WLANTEST_STA_INFO_KEY_MGMT:
926                 info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
927                 break;
928         case WLANTEST_STA_INFO_RSN_CAPAB:
929                 info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
930                 break;
931         case WLANTEST_STA_INFO_STATE:
932                 info_print_state(resp, sizeof(resp), sta->state);
933                 break;
934         default:
935                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
936                 return;
937         }
938
939         pos = buf;
940         end = buf + sizeof(buf);
941         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
942         pos += 4;
943         pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
944         ctrl_send(wt, sock, buf, pos - buf);
945 }
946
947
948 static void ctrl_info_bss(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
949 {
950         u8 *addr;
951         size_t addr_len;
952         struct wlantest_bss *bss;
953         enum wlantest_bss_info info;
954         u8 buf[4 + 108], *end, *pos;
955         char resp[100];
956
957         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
958         if (addr == NULL || addr_len != ETH_ALEN) {
959                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
960                 return;
961         }
962
963         bss = bss_find(wt, addr);
964         if (bss == NULL) {
965                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
966                 return;
967         }
968
969         addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_INFO, &addr_len);
970         if (addr == NULL || addr_len != 4) {
971                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
972                 return;
973         }
974         info = WPA_GET_BE32(addr);
975
976         resp[0] = '\0';
977         switch (info) {
978         case WLANTEST_BSS_INFO_PROTO:
979                 info_print_proto(resp, sizeof(resp), bss->proto);
980                 break;
981         case WLANTEST_BSS_INFO_PAIRWISE:
982                 info_print_cipher(resp, sizeof(resp), bss->pairwise_cipher);
983                 break;
984         case WLANTEST_BSS_INFO_GROUP:
985                 info_print_cipher(resp, sizeof(resp), bss->group_cipher);
986                 break;
987         case WLANTEST_BSS_INFO_GROUP_MGMT:
988                 info_print_cipher(resp, sizeof(resp), bss->mgmt_group_cipher);
989                 break;
990         case WLANTEST_BSS_INFO_KEY_MGMT:
991                 info_print_key_mgmt(resp, sizeof(resp), bss->key_mgmt);
992                 break;
993         case WLANTEST_BSS_INFO_RSN_CAPAB:
994                 info_print_rsn_capab(resp, sizeof(resp), bss->rsn_capab);
995                 break;
996         default:
997                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
998                 return;
999         }
1000
1001         pos = buf;
1002         end = buf + sizeof(buf);
1003         WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
1004         pos += 4;
1005         pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
1006         ctrl_send(wt, sock, buf, pos - buf);
1007 }
1008
1009
1010 static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
1011 {
1012         struct wlantest *wt = eloop_ctx;
1013         u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
1014         int len;
1015         enum wlantest_ctrl_cmd cmd;
1016
1017         wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
1018                    sock);
1019         len = recv(sock, buf, sizeof(buf), 0);
1020         if (len < 0) {
1021                 wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
1022                 ctrl_disconnect(wt, sock);
1023                 return;
1024         }
1025         if (len == 0) {
1026                 ctrl_disconnect(wt, sock);
1027                 return;
1028         }
1029
1030         if (len < 4) {
1031                 wpa_printf(MSG_INFO, "Too short control interface command "
1032                            "from %d", sock);
1033                 ctrl_disconnect(wt, sock);
1034                 return;
1035         }
1036         cmd = WPA_GET_BE32(buf);
1037         wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
1038                    cmd, sock);
1039
1040         switch (cmd) {
1041         case WLANTEST_CTRL_PING:
1042                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
1043                 break;
1044         case WLANTEST_CTRL_TERMINATE:
1045                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
1046                 eloop_terminate();
1047                 break;
1048         case WLANTEST_CTRL_LIST_BSS:
1049                 ctrl_list_bss(wt, sock);
1050                 break;
1051         case WLANTEST_CTRL_LIST_STA:
1052                 ctrl_list_sta(wt, sock, buf + 4, len - 4);
1053                 break;
1054         case WLANTEST_CTRL_FLUSH:
1055                 ctrl_flush(wt, sock);
1056                 break;
1057         case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
1058                 ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
1059                 break;
1060         case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
1061                 ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
1062                 break;
1063         case WLANTEST_CTRL_GET_STA_COUNTER:
1064                 ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
1065                 break;
1066         case WLANTEST_CTRL_GET_BSS_COUNTER:
1067                 ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
1068                 break;
1069         case WLANTEST_CTRL_INJECT:
1070                 ctrl_inject(wt, sock, buf + 4, len - 4);
1071                 break;
1072         case WLANTEST_CTRL_VERSION:
1073                 ctrl_version(wt, sock);
1074                 break;
1075         case WLANTEST_CTRL_ADD_PASSPHRASE:
1076                 ctrl_add_passphrase(wt, sock, buf + 4, len - 4);
1077                 break;
1078         case WLANTEST_CTRL_INFO_STA:
1079                 ctrl_info_sta(wt, sock, buf + 4, len - 4);
1080                 break;
1081         case WLANTEST_CTRL_INFO_BSS:
1082                 ctrl_info_bss(wt, sock, buf + 4, len - 4);
1083                 break;
1084         default:
1085                 ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
1086                 break;
1087         }
1088 }
1089
1090
1091 static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
1092 {
1093         struct wlantest *wt = eloop_ctx;
1094         int conn, i;
1095
1096         conn = accept(sock, NULL, NULL);
1097         if (conn < 0) {
1098                 wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
1099                 return;
1100         }
1101         wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);
1102
1103         for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
1104                 if (wt->ctrl_socks[i] < 0)
1105                         break;
1106         }
1107
1108         if (i == MAX_CTRL_CONNECTIONS) {
1109                 wpa_printf(MSG_INFO, "No room for new control connection");
1110                 close(conn);
1111                 return;
1112         }
1113
1114         wt->ctrl_socks[i] = conn;
1115         eloop_register_read_sock(conn, ctrl_read, wt, NULL);
1116 }
1117
1118
1119 int ctrl_init(struct wlantest *wt)
1120 {
1121         struct sockaddr_un addr;
1122
1123         wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
1124         if (wt->ctrl_sock < 0) {
1125                 wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
1126                 return -1;
1127         }
1128
1129         os_memset(&addr, 0, sizeof(addr));
1130         addr.sun_family = AF_UNIX;
1131         os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
1132                    sizeof(addr.sun_path) - 1);
1133         if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1134                 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
1135                 close(wt->ctrl_sock);
1136                 wt->ctrl_sock = -1;
1137                 return -1;
1138         }
1139
1140         if (listen(wt->ctrl_sock, 5) < 0) {
1141                 wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
1142                 close(wt->ctrl_sock);
1143                 wt->ctrl_sock = -1;
1144                 return -1;
1145         }
1146
1147         if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
1148                 close(wt->ctrl_sock);
1149                 wt->ctrl_sock = -1;
1150                 return -1;
1151         }
1152
1153         return 0;
1154 }
1155
1156
1157 void ctrl_deinit(struct wlantest *wt)
1158 {
1159         int i;
1160
1161         if (wt->ctrl_sock < 0)
1162                 return;
1163
1164         for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
1165                 if (wt->ctrl_socks[i] >= 0) {
1166                         close(wt->ctrl_socks[i]);
1167                         eloop_unregister_read_sock(wt->ctrl_socks[i]);
1168                         wt->ctrl_socks[i] = -1;
1169                 }
1170         }
1171
1172         eloop_unregister_read_sock(wt->ctrl_sock);
1173         close(wt->ctrl_sock);
1174         wt->ctrl_sock = -1;
1175 }