dbus: Use strdup instead of malloc+strncpy
[hostap-gosc2009.git] / wpa_supplicant / ctrl_iface.c
blob3bcf6e3045d7ffd89855f1e42c396b78cdbd4e80
1 /*
2 * WPA Supplicant / Control interface (shared code for all backends)
3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/wpa_ctrl.h"
21 #include "eap_peer/eap.h"
22 #include "eapol_supp/eapol_supp_sm.h"
23 #include "rsn_supp/wpa.h"
24 #include "rsn_supp/preauth.h"
25 #include "rsn_supp/pmksa_cache.h"
26 #include "l2_packet/l2_packet.h"
27 #include "wps/wps.h"
28 #include "config.h"
29 #include "wpa_supplicant_i.h"
30 #include "driver_i.h"
31 #include "wps_supplicant.h"
32 #include "ibss_rsn.h"
33 #include "ap.h"
34 #include "notify.h"
35 #include "bss.h"
36 #include "ctrl_iface.h"
38 extern struct wpa_driver_ops *wpa_drivers[];
40 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
41 char *buf, int len);
42 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
43 char *buf, int len);
46 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
47 char *cmd)
49 char *value;
50 int ret = 0;
52 value = os_strchr(cmd, ' ');
53 if (value == NULL)
54 return -1;
55 *value++ = '\0';
57 wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
58 if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
59 eapol_sm_configure(wpa_s->eapol,
60 atoi(value), -1, -1, -1);
61 } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
62 eapol_sm_configure(wpa_s->eapol,
63 -1, atoi(value), -1, -1);
64 } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
65 eapol_sm_configure(wpa_s->eapol,
66 -1, -1, atoi(value), -1);
67 } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
68 eapol_sm_configure(wpa_s->eapol,
69 -1, -1, -1, atoi(value));
70 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
71 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
72 atoi(value)))
73 ret = -1;
74 } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
75 0) {
76 if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
77 atoi(value)))
78 ret = -1;
79 } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
80 if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
81 ret = -1;
82 } else
83 ret = -1;
85 return ret;
89 #ifdef IEEE8021X_EAPOL
90 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
91 char *addr)
93 u8 bssid[ETH_ALEN];
94 struct wpa_ssid *ssid = wpa_s->current_ssid;
96 if (hwaddr_aton(addr, bssid)) {
97 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
98 "'%s'", addr);
99 return -1;
102 wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
103 rsn_preauth_deinit(wpa_s->wpa);
104 if (rsn_preauth_init(wpa_s->wpa, bssid, ssid ? &ssid->eap : NULL))
105 return -1;
107 return 0;
109 #endif /* IEEE8021X_EAPOL */
112 #ifdef CONFIG_PEERKEY
113 /* MLME-STKSTART.request(peer) */
114 static int wpa_supplicant_ctrl_iface_stkstart(
115 struct wpa_supplicant *wpa_s, char *addr)
117 u8 peer[ETH_ALEN];
119 if (hwaddr_aton(addr, peer)) {
120 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
121 "address '%s'", peer);
122 return -1;
125 wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
126 MAC2STR(peer));
128 return wpa_sm_stkstart(wpa_s->wpa, peer);
130 #endif /* CONFIG_PEERKEY */
133 #ifdef CONFIG_IEEE80211R
134 static int wpa_supplicant_ctrl_iface_ft_ds(
135 struct wpa_supplicant *wpa_s, char *addr)
137 u8 target_ap[ETH_ALEN];
139 if (hwaddr_aton(addr, target_ap)) {
140 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS: invalid "
141 "address '%s'", target_ap);
142 return -1;
145 wpa_printf(MSG_DEBUG, "CTRL_IFACE FT_DS " MACSTR, MAC2STR(target_ap));
147 return wpa_ft_start_over_ds(wpa_s->wpa, target_ap);
149 #endif /* CONFIG_IEEE80211R */
152 #ifdef CONFIG_WPS
153 static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
154 char *cmd)
156 u8 bssid[ETH_ALEN], *_bssid = bssid;
158 if (cmd == NULL || os_strcmp(cmd, "any") == 0)
159 _bssid = NULL;
160 else if (hwaddr_aton(cmd, bssid)) {
161 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
162 cmd);
163 return -1;
166 #ifdef CONFIG_AP
167 if (wpa_s->ap_iface)
168 return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
169 #endif /* CONFIG_AP */
171 return wpas_wps_start_pbc(wpa_s, _bssid);
175 static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
176 char *cmd, char *buf,
177 size_t buflen)
179 u8 bssid[ETH_ALEN], *_bssid = bssid;
180 char *pin;
181 int ret;
183 pin = os_strchr(cmd, ' ');
184 if (pin)
185 *pin++ = '\0';
187 if (os_strcmp(cmd, "any") == 0)
188 _bssid = NULL;
189 else if (hwaddr_aton(cmd, bssid)) {
190 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
191 cmd);
192 return -1;
195 #ifdef CONFIG_AP
196 if (wpa_s->ap_iface)
197 return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
198 buf, buflen);
199 #endif /* CONFIG_AP */
201 if (pin) {
202 ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
203 if (ret < 0)
204 return -1;
205 ret = os_snprintf(buf, buflen, "%s", pin);
206 if (ret < 0 || (size_t) ret >= buflen)
207 return -1;
208 return ret;
211 ret = wpas_wps_start_pin(wpa_s, _bssid, NULL);
212 if (ret < 0)
213 return -1;
215 /* Return the generated PIN */
216 ret = os_snprintf(buf, buflen, "%08d", ret);
217 if (ret < 0 || (size_t) ret >= buflen)
218 return -1;
219 return ret;
223 #ifdef CONFIG_WPS_OOB
224 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
225 char *cmd)
227 char *path, *method, *name;
229 path = os_strchr(cmd, ' ');
230 if (path == NULL)
231 return -1;
232 *path++ = '\0';
234 method = os_strchr(path, ' ');
235 if (method == NULL)
236 return -1;
237 *method++ = '\0';
239 name = os_strchr(method, ' ');
240 if (name != NULL)
241 *name++ = '\0';
243 return wpas_wps_start_oob(wpa_s, cmd, path, method, name);
245 #endif /* CONFIG_WPS_OOB */
248 static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
249 char *cmd)
251 u8 bssid[ETH_ALEN], *_bssid = bssid;
252 char *pin;
253 char *new_ssid;
254 char *new_auth;
255 char *new_encr;
256 char *new_key;
257 struct wps_new_ap_settings ap;
259 pin = os_strchr(cmd, ' ');
260 if (pin == NULL)
261 return -1;
262 *pin++ = '\0';
264 if (os_strcmp(cmd, "any") == 0)
265 _bssid = NULL;
266 else if (hwaddr_aton(cmd, bssid)) {
267 wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
268 cmd);
269 return -1;
272 new_ssid = os_strchr(pin, ' ');
273 if (new_ssid == NULL)
274 return wpas_wps_start_reg(wpa_s, _bssid, pin, NULL);
275 *new_ssid++ = '\0';
277 new_auth = os_strchr(new_ssid, ' ');
278 if (new_auth == NULL)
279 return -1;
280 *new_auth++ = '\0';
282 new_encr = os_strchr(new_auth, ' ');
283 if (new_encr == NULL)
284 return -1;
285 *new_encr++ = '\0';
287 new_key = os_strchr(new_encr, ' ');
288 if (new_key == NULL)
289 return -1;
290 *new_key++ = '\0';
292 os_memset(&ap, 0, sizeof(ap));
293 ap.ssid_hex = new_ssid;
294 ap.auth = new_auth;
295 ap.encr = new_encr;
296 ap.key_hex = new_key;
297 return wpas_wps_start_reg(wpa_s, _bssid, pin, &ap);
301 #ifdef CONFIG_WPS_ER
302 static int wpa_supplicant_ctrl_iface_wps_er_pin(struct wpa_supplicant *wpa_s,
303 char *cmd)
305 char *uuid = cmd, *pin;
306 pin = os_strchr(uuid, ' ');
307 if (pin == NULL)
308 return -1;
309 *pin++ = '\0';
310 return wpas_wps_er_add_pin(wpa_s, uuid, pin);
314 static int wpa_supplicant_ctrl_iface_wps_er_learn(struct wpa_supplicant *wpa_s,
315 char *cmd)
317 char *uuid = cmd, *pin;
318 pin = os_strchr(uuid, ' ');
319 if (pin == NULL)
320 return -1;
321 *pin++ = '\0';
322 return wpas_wps_er_learn(wpa_s, uuid, pin);
324 #endif /* CONFIG_WPS_ER */
326 #endif /* CONFIG_WPS */
329 #ifdef CONFIG_IBSS_RSN
330 static int wpa_supplicant_ctrl_iface_ibss_rsn(
331 struct wpa_supplicant *wpa_s, char *addr)
333 u8 peer[ETH_ALEN];
335 if (hwaddr_aton(addr, peer)) {
336 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN: invalid "
337 "address '%s'", peer);
338 return -1;
341 wpa_printf(MSG_DEBUG, "CTRL_IFACE IBSS_RSN " MACSTR,
342 MAC2STR(peer));
344 return ibss_rsn_start(wpa_s->ibss_rsn, peer);
346 #endif /* CONFIG_IBSS_RSN */
349 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
350 char *rsp)
352 #ifdef IEEE8021X_EAPOL
353 char *pos, *id_pos;
354 int id;
355 struct wpa_ssid *ssid;
356 struct eap_peer_config *eap;
358 pos = os_strchr(rsp, '-');
359 if (pos == NULL)
360 return -1;
361 *pos++ = '\0';
362 id_pos = pos;
363 pos = os_strchr(pos, ':');
364 if (pos == NULL)
365 return -1;
366 *pos++ = '\0';
367 id = atoi(id_pos);
368 wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
369 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
370 (u8 *) pos, os_strlen(pos));
372 ssid = wpa_config_get_network(wpa_s->conf, id);
373 if (ssid == NULL) {
374 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
375 "to update", id);
376 return -1;
378 eap = &ssid->eap;
380 if (os_strcmp(rsp, "IDENTITY") == 0) {
381 os_free(eap->identity);
382 eap->identity = (u8 *) os_strdup(pos);
383 eap->identity_len = os_strlen(pos);
384 eap->pending_req_identity = 0;
385 if (ssid == wpa_s->current_ssid)
386 wpa_s->reassociate = 1;
387 } else if (os_strcmp(rsp, "PASSWORD") == 0) {
388 os_free(eap->password);
389 eap->password = (u8 *) os_strdup(pos);
390 eap->password_len = os_strlen(pos);
391 eap->pending_req_password = 0;
392 if (ssid == wpa_s->current_ssid)
393 wpa_s->reassociate = 1;
394 } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
395 os_free(eap->new_password);
396 eap->new_password = (u8 *) os_strdup(pos);
397 eap->new_password_len = os_strlen(pos);
398 eap->pending_req_new_password = 0;
399 if (ssid == wpa_s->current_ssid)
400 wpa_s->reassociate = 1;
401 } else if (os_strcmp(rsp, "PIN") == 0) {
402 os_free(eap->pin);
403 eap->pin = os_strdup(pos);
404 eap->pending_req_pin = 0;
405 if (ssid == wpa_s->current_ssid)
406 wpa_s->reassociate = 1;
407 } else if (os_strcmp(rsp, "OTP") == 0) {
408 os_free(eap->otp);
409 eap->otp = (u8 *) os_strdup(pos);
410 eap->otp_len = os_strlen(pos);
411 os_free(eap->pending_req_otp);
412 eap->pending_req_otp = NULL;
413 eap->pending_req_otp_len = 0;
414 } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
415 os_free(eap->private_key_passwd);
416 eap->private_key_passwd = (u8 *) os_strdup(pos);
417 eap->pending_req_passphrase = 0;
418 if (ssid == wpa_s->current_ssid)
419 wpa_s->reassociate = 1;
420 } else {
421 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
422 return -1;
425 return 0;
426 #else /* IEEE8021X_EAPOL */
427 wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
428 return -1;
429 #endif /* IEEE8021X_EAPOL */
433 static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
434 const char *params,
435 char *buf, size_t buflen)
437 char *pos, *end, tmp[30];
438 int res, verbose, ret;
440 verbose = os_strcmp(params, "-VERBOSE") == 0;
441 pos = buf;
442 end = buf + buflen;
443 if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
444 struct wpa_ssid *ssid = wpa_s->current_ssid;
445 ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
446 MAC2STR(wpa_s->bssid));
447 if (ret < 0 || ret >= end - pos)
448 return pos - buf;
449 pos += ret;
450 if (ssid) {
451 u8 *_ssid = ssid->ssid;
452 size_t ssid_len = ssid->ssid_len;
453 u8 ssid_buf[MAX_SSID_LEN];
454 if (ssid_len == 0) {
455 int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
456 if (_res < 0)
457 ssid_len = 0;
458 else
459 ssid_len = _res;
460 _ssid = ssid_buf;
462 ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
463 wpa_ssid_txt(_ssid, ssid_len),
464 ssid->id);
465 if (ret < 0 || ret >= end - pos)
466 return pos - buf;
467 pos += ret;
469 if (ssid->id_str) {
470 ret = os_snprintf(pos, end - pos,
471 "id_str=%s\n",
472 ssid->id_str);
473 if (ret < 0 || ret >= end - pos)
474 return pos - buf;
475 pos += ret;
478 switch (ssid->mode) {
479 case WPAS_MODE_INFRA:
480 ret = os_snprintf(pos, end - pos,
481 "mode=station\n");
482 break;
483 case WPAS_MODE_IBSS:
484 ret = os_snprintf(pos, end - pos,
485 "mode=IBSS\n");
486 break;
487 case WPAS_MODE_AP:
488 ret = os_snprintf(pos, end - pos,
489 "mode=AP\n");
490 break;
491 default:
492 ret = 0;
493 break;
495 if (ret < 0 || ret >= end - pos)
496 return pos - buf;
497 pos += ret;
500 #ifdef CONFIG_AP
501 if (wpa_s->ap_iface) {
502 pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
503 end - pos,
504 verbose);
505 } else
506 #endif /* CONFIG_AP */
507 pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
509 ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
510 wpa_supplicant_state_txt(wpa_s->wpa_state));
511 if (ret < 0 || ret >= end - pos)
512 return pos - buf;
513 pos += ret;
515 if (wpa_s->l2 &&
516 l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
517 ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
518 if (ret < 0 || ret >= end - pos)
519 return pos - buf;
520 pos += ret;
523 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
524 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
525 res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
526 verbose);
527 if (res >= 0)
528 pos += res;
531 res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
532 if (res >= 0)
533 pos += res;
535 return pos - buf;
539 static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
540 char *cmd)
542 char *pos;
543 int id;
544 struct wpa_ssid *ssid;
545 u8 bssid[ETH_ALEN];
547 /* cmd: "<network id> <BSSID>" */
548 pos = os_strchr(cmd, ' ');
549 if (pos == NULL)
550 return -1;
551 *pos++ = '\0';
552 id = atoi(cmd);
553 wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
554 if (hwaddr_aton(pos, bssid)) {
555 wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
556 return -1;
559 ssid = wpa_config_get_network(wpa_s->conf, id);
560 if (ssid == NULL) {
561 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
562 "to update", id);
563 return -1;
566 os_memcpy(ssid->bssid, bssid, ETH_ALEN);
567 ssid->bssid_set = !is_zero_ether_addr(bssid);
569 return 0;
573 static int wpa_supplicant_ctrl_iface_list_networks(
574 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
576 char *pos, *end;
577 struct wpa_ssid *ssid;
578 int ret;
580 pos = buf;
581 end = buf + buflen;
582 ret = os_snprintf(pos, end - pos,
583 "network id / ssid / bssid / flags\n");
584 if (ret < 0 || ret >= end - pos)
585 return pos - buf;
586 pos += ret;
588 ssid = wpa_s->conf->ssid;
589 while (ssid) {
590 ret = os_snprintf(pos, end - pos, "%d\t%s",
591 ssid->id,
592 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
593 if (ret < 0 || ret >= end - pos)
594 return pos - buf;
595 pos += ret;
596 if (ssid->bssid_set) {
597 ret = os_snprintf(pos, end - pos, "\t" MACSTR,
598 MAC2STR(ssid->bssid));
599 } else {
600 ret = os_snprintf(pos, end - pos, "\tany");
602 if (ret < 0 || ret >= end - pos)
603 return pos - buf;
604 pos += ret;
605 ret = os_snprintf(pos, end - pos, "\t%s%s",
606 ssid == wpa_s->current_ssid ?
607 "[CURRENT]" : "",
608 ssid->disabled ? "[DISABLED]" : "");
609 if (ret < 0 || ret >= end - pos)
610 return pos - buf;
611 pos += ret;
612 ret = os_snprintf(pos, end - pos, "\n");
613 if (ret < 0 || ret >= end - pos)
614 return pos - buf;
615 pos += ret;
617 ssid = ssid->next;
620 return pos - buf;
624 static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
626 int first = 1, ret;
627 ret = os_snprintf(pos, end - pos, "-");
628 if (ret < 0 || ret >= end - pos)
629 return pos;
630 pos += ret;
631 if (cipher & WPA_CIPHER_NONE) {
632 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
633 if (ret < 0 || ret >= end - pos)
634 return pos;
635 pos += ret;
636 first = 0;
638 if (cipher & WPA_CIPHER_WEP40) {
639 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
640 if (ret < 0 || ret >= end - pos)
641 return pos;
642 pos += ret;
643 first = 0;
645 if (cipher & WPA_CIPHER_WEP104) {
646 ret = os_snprintf(pos, end - pos, "%sWEP104",
647 first ? "" : "+");
648 if (ret < 0 || ret >= end - pos)
649 return pos;
650 pos += ret;
651 first = 0;
653 if (cipher & WPA_CIPHER_TKIP) {
654 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
655 if (ret < 0 || ret >= end - pos)
656 return pos;
657 pos += ret;
658 first = 0;
660 if (cipher & WPA_CIPHER_CCMP) {
661 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
662 if (ret < 0 || ret >= end - pos)
663 return pos;
664 pos += ret;
665 first = 0;
667 return pos;
671 static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
672 const u8 *ie, size_t ie_len)
674 struct wpa_ie_data data;
675 int first, ret;
677 ret = os_snprintf(pos, end - pos, "[%s-", proto);
678 if (ret < 0 || ret >= end - pos)
679 return pos;
680 pos += ret;
682 if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
683 ret = os_snprintf(pos, end - pos, "?]");
684 if (ret < 0 || ret >= end - pos)
685 return pos;
686 pos += ret;
687 return pos;
690 first = 1;
691 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
692 ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
693 if (ret < 0 || ret >= end - pos)
694 return pos;
695 pos += ret;
696 first = 0;
698 if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
699 ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
700 if (ret < 0 || ret >= end - pos)
701 return pos;
702 pos += ret;
703 first = 0;
705 if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
706 ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
707 if (ret < 0 || ret >= end - pos)
708 return pos;
709 pos += ret;
710 first = 0;
712 #ifdef CONFIG_IEEE80211R
713 if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
714 ret = os_snprintf(pos, end - pos, "%sFT/EAP",
715 first ? "" : "+");
716 if (ret < 0 || ret >= end - pos)
717 return pos;
718 pos += ret;
719 first = 0;
721 if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) {
722 ret = os_snprintf(pos, end - pos, "%sFT/PSK",
723 first ? "" : "+");
724 if (ret < 0 || ret >= end - pos)
725 return pos;
726 pos += ret;
727 first = 0;
729 #endif /* CONFIG_IEEE80211R */
730 #ifdef CONFIG_IEEE80211W
731 if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
732 ret = os_snprintf(pos, end - pos, "%sEAP-SHA256",
733 first ? "" : "+");
734 if (ret < 0 || ret >= end - pos)
735 return pos;
736 pos += ret;
737 first = 0;
739 if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
740 ret = os_snprintf(pos, end - pos, "%sPSK-SHA256",
741 first ? "" : "+");
742 if (ret < 0 || ret >= end - pos)
743 return pos;
744 pos += ret;
745 first = 0;
747 #endif /* CONFIG_IEEE80211W */
749 pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
751 if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
752 ret = os_snprintf(pos, end - pos, "-preauth");
753 if (ret < 0 || ret >= end - pos)
754 return pos;
755 pos += ret;
758 ret = os_snprintf(pos, end - pos, "]");
759 if (ret < 0 || ret >= end - pos)
760 return pos;
761 pos += ret;
763 return pos;
767 #ifdef CONFIG_WPS
768 static char * wpa_supplicant_wps_ie_txt_buf(char *pos, char *end,
769 struct wpabuf *wps_ie)
771 int ret;
772 const char *txt;
774 if (wps_ie == NULL)
775 return pos;
776 if (wps_is_selected_pbc_registrar(wps_ie))
777 txt = "[WPS-PBC]";
778 else if (wps_is_selected_pin_registrar(wps_ie))
779 txt = "[WPS-PIN]";
780 else
781 txt = "[WPS]";
783 ret = os_snprintf(pos, end - pos, "%s", txt);
784 if (ret >= 0 && ret < end - pos)
785 pos += ret;
786 wpabuf_free(wps_ie);
787 return pos;
789 #endif /* CONFIG_WPS */
792 static char * wpa_supplicant_wps_ie_txt(char *pos, char *end,
793 const struct wpa_scan_res *res)
795 #ifdef CONFIG_WPS
796 struct wpabuf *wps_ie;
797 wps_ie = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
798 return wpa_supplicant_wps_ie_txt_buf(pos, end, wps_ie);
799 #else /* CONFIG_WPS */
800 return pos;
801 #endif /* CONFIG_WPS */
805 static char * wpa_supplicant_wps_ie_txt_bss(char *pos, char *end,
806 const struct wpa_bss *bss)
808 #ifdef CONFIG_WPS
809 struct wpabuf *wps_ie;
810 wps_ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
811 return wpa_supplicant_wps_ie_txt_buf(pos, end, wps_ie);
812 #else /* CONFIG_WPS */
813 return pos;
814 #endif /* CONFIG_WPS */
818 /* Format one result on one text line into a buffer. */
819 static int wpa_supplicant_ctrl_iface_scan_result(
820 const struct wpa_scan_res *res, char *buf, size_t buflen)
822 char *pos, *end;
823 int ret;
824 const u8 *ie, *ie2;
826 pos = buf;
827 end = buf + buflen;
829 ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
830 MAC2STR(res->bssid), res->freq, res->level);
831 if (ret < 0 || ret >= end - pos)
832 return pos - buf;
833 pos += ret;
834 ie = wpa_scan_get_vendor_ie(res, WPA_IE_VENDOR_TYPE);
835 if (ie)
836 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
837 ie2 = wpa_scan_get_ie(res, WLAN_EID_RSN);
838 if (ie2)
839 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
840 pos = wpa_supplicant_wps_ie_txt(pos, end, res);
841 if (!ie && !ie2 && res->caps & IEEE80211_CAP_PRIVACY) {
842 ret = os_snprintf(pos, end - pos, "[WEP]");
843 if (ret < 0 || ret >= end - pos)
844 return pos - buf;
845 pos += ret;
847 if (res->caps & IEEE80211_CAP_IBSS) {
848 ret = os_snprintf(pos, end - pos, "[IBSS]");
849 if (ret < 0 || ret >= end - pos)
850 return pos - buf;
851 pos += ret;
853 if (res->caps & IEEE80211_CAP_ESS) {
854 ret = os_snprintf(pos, end - pos, "[ESS]");
855 if (ret < 0 || ret >= end - pos)
856 return pos - buf;
857 pos += ret;
860 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
861 ret = os_snprintf(pos, end - pos, "\t%s",
862 ie ? wpa_ssid_txt(ie + 2, ie[1]) : "");
863 if (ret < 0 || ret >= end - pos)
864 return pos - buf;
865 pos += ret;
867 ret = os_snprintf(pos, end - pos, "\n");
868 if (ret < 0 || ret >= end - pos)
869 return pos - buf;
870 pos += ret;
872 return pos - buf;
876 static int wpa_supplicant_ctrl_iface_scan_results(
877 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
879 char *pos, *end;
880 struct wpa_scan_res *res;
881 int ret;
882 size_t i;
884 if (wpa_s->scan_res == NULL &&
885 wpa_supplicant_get_scan_results(wpa_s) < 0)
886 return 0;
888 pos = buf;
889 end = buf + buflen;
890 ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
891 "flags / ssid\n");
892 if (ret < 0 || ret >= end - pos)
893 return pos - buf;
894 pos += ret;
896 for (i = 0; i < wpa_s->scan_res->num; i++) {
897 res = wpa_s->scan_res->res[i];
898 ret = wpa_supplicant_ctrl_iface_scan_result(res, pos,
899 end - pos);
900 if (ret < 0 || ret >= end - pos)
901 return pos - buf;
902 pos += ret;
905 return pos - buf;
909 static int wpa_supplicant_ctrl_iface_select_network(
910 struct wpa_supplicant *wpa_s, char *cmd)
912 int id;
913 struct wpa_ssid *ssid;
915 /* cmd: "<network id>" or "any" */
916 if (os_strcmp(cmd, "any") == 0) {
917 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
918 ssid = NULL;
919 } else {
920 id = atoi(cmd);
921 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
923 ssid = wpa_config_get_network(wpa_s->conf, id);
924 if (ssid == NULL) {
925 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
926 "network id=%d", id);
927 return -1;
931 wpa_supplicant_select_network(wpa_s, ssid);
933 return 0;
937 static int wpa_supplicant_ctrl_iface_enable_network(
938 struct wpa_supplicant *wpa_s, char *cmd)
940 int id;
941 struct wpa_ssid *ssid;
943 /* cmd: "<network id>" or "all" */
944 if (os_strcmp(cmd, "all") == 0) {
945 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all");
946 ssid = NULL;
947 } else {
948 id = atoi(cmd);
949 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
951 ssid = wpa_config_get_network(wpa_s->conf, id);
952 if (ssid == NULL) {
953 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
954 "network id=%d", id);
955 return -1;
958 wpa_supplicant_enable_network(wpa_s, ssid);
960 return 0;
964 static int wpa_supplicant_ctrl_iface_disable_network(
965 struct wpa_supplicant *wpa_s, char *cmd)
967 int id;
968 struct wpa_ssid *ssid;
970 /* cmd: "<network id>" or "all" */
971 if (os_strcmp(cmd, "all") == 0) {
972 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK all");
973 ssid = NULL;
974 } else {
975 id = atoi(cmd);
976 wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
978 ssid = wpa_config_get_network(wpa_s->conf, id);
979 if (ssid == NULL) {
980 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find "
981 "network id=%d", id);
982 return -1;
985 wpa_supplicant_disable_network(wpa_s, ssid);
987 return 0;
991 static int wpa_supplicant_ctrl_iface_add_network(
992 struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
994 struct wpa_ssid *ssid;
995 int ret;
997 wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
999 ssid = wpa_config_add_network(wpa_s->conf);
1000 if (ssid == NULL)
1001 return -1;
1003 wpas_notify_network_added(wpa_s, ssid);
1005 ssid->disabled = 1;
1006 wpa_config_set_network_defaults(ssid);
1008 ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
1009 if (ret < 0 || (size_t) ret >= buflen)
1010 return -1;
1011 return ret;
1015 static int wpa_supplicant_ctrl_iface_remove_network(
1016 struct wpa_supplicant *wpa_s, char *cmd)
1018 int id;
1019 struct wpa_ssid *ssid;
1021 /* cmd: "<network id>" or "all" */
1022 if (os_strcmp(cmd, "all") == 0) {
1023 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK all");
1024 ssid = wpa_s->conf->ssid;
1025 while (ssid) {
1026 struct wpa_ssid *remove_ssid = ssid;
1027 id = ssid->id;
1028 ssid = ssid->next;
1029 wpas_notify_network_removed(wpa_s, remove_ssid);
1030 wpa_config_remove_network(wpa_s->conf, id);
1032 if (wpa_s->current_ssid) {
1033 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1034 wpa_supplicant_disassociate(wpa_s,
1035 WLAN_REASON_DEAUTH_LEAVING);
1037 return 0;
1040 id = atoi(cmd);
1041 wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
1043 ssid = wpa_config_get_network(wpa_s->conf, id);
1044 if (ssid == NULL ||
1045 wpa_config_remove_network(wpa_s->conf, id) < 0) {
1046 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1047 "id=%d", id);
1048 return -1;
1051 if (ssid == wpa_s->current_ssid) {
1053 * Invalidate the EAP session cache if the current network is
1054 * removed.
1056 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1058 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1061 return 0;
1065 static int wpa_supplicant_ctrl_iface_set_network(
1066 struct wpa_supplicant *wpa_s, char *cmd)
1068 int id;
1069 struct wpa_ssid *ssid;
1070 char *name, *value;
1072 /* cmd: "<network id> <variable name> <value>" */
1073 name = os_strchr(cmd, ' ');
1074 if (name == NULL)
1075 return -1;
1076 *name++ = '\0';
1078 value = os_strchr(name, ' ');
1079 if (value == NULL)
1080 return -1;
1081 *value++ = '\0';
1083 id = atoi(cmd);
1084 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
1085 id, name);
1086 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
1087 (u8 *) value, os_strlen(value));
1089 ssid = wpa_config_get_network(wpa_s->conf, id);
1090 if (ssid == NULL) {
1091 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1092 "id=%d", id);
1093 return -1;
1096 if (wpa_config_set(ssid, name, value, 0) < 0) {
1097 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
1098 "variable '%s'", name);
1099 return -1;
1102 if (wpa_s->current_ssid == ssid) {
1104 * Invalidate the EAP session cache if anything in the current
1105 * configuration changes.
1107 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1110 if ((os_strcmp(name, "psk") == 0 &&
1111 value[0] == '"' && ssid->ssid_len) ||
1112 (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
1113 wpa_config_update_psk(ssid);
1115 return 0;
1119 static int wpa_supplicant_ctrl_iface_get_network(
1120 struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
1122 int id;
1123 size_t res;
1124 struct wpa_ssid *ssid;
1125 char *name, *value;
1127 /* cmd: "<network id> <variable name>" */
1128 name = os_strchr(cmd, ' ');
1129 if (name == NULL || buflen == 0)
1130 return -1;
1131 *name++ = '\0';
1133 id = atoi(cmd);
1134 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
1135 id, name);
1137 ssid = wpa_config_get_network(wpa_s->conf, id);
1138 if (ssid == NULL) {
1139 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
1140 "id=%d", id);
1141 return -1;
1144 value = wpa_config_get_no_key(ssid, name);
1145 if (value == NULL) {
1146 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
1147 "variable '%s'", name);
1148 return -1;
1151 res = os_strlcpy(buf, value, buflen);
1152 if (res >= buflen) {
1153 os_free(value);
1154 return -1;
1157 os_free(value);
1159 return res;
1163 #ifndef CONFIG_NO_CONFIG_WRITE
1164 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
1166 int ret;
1168 if (!wpa_s->conf->update_config) {
1169 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
1170 "to update configuration (update_config=0)");
1171 return -1;
1174 ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
1175 if (ret) {
1176 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
1177 "update configuration");
1178 } else {
1179 wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
1180 " updated");
1183 return ret;
1185 #endif /* CONFIG_NO_CONFIG_WRITE */
1188 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
1189 struct wpa_driver_capa *capa,
1190 char *buf, size_t buflen)
1192 int ret, first = 1;
1193 char *pos, *end;
1194 size_t len;
1196 pos = buf;
1197 end = pos + buflen;
1199 if (res < 0) {
1200 if (strict)
1201 return 0;
1202 len = os_strlcpy(buf, "CCMP TKIP NONE", buflen);
1203 if (len >= buflen)
1204 return -1;
1205 return len;
1208 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1209 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1210 if (ret < 0 || ret >= end - pos)
1211 return pos - buf;
1212 pos += ret;
1213 first = 0;
1216 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1217 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1218 if (ret < 0 || ret >= end - pos)
1219 return pos - buf;
1220 pos += ret;
1221 first = 0;
1224 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1225 ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : " ");
1226 if (ret < 0 || ret >= end - pos)
1227 return pos - buf;
1228 pos += ret;
1229 first = 0;
1232 return pos - buf;
1236 static int ctrl_iface_get_capability_group(int res, char *strict,
1237 struct wpa_driver_capa *capa,
1238 char *buf, size_t buflen)
1240 int ret, first = 1;
1241 char *pos, *end;
1242 size_t len;
1244 pos = buf;
1245 end = pos + buflen;
1247 if (res < 0) {
1248 if (strict)
1249 return 0;
1250 len = os_strlcpy(buf, "CCMP TKIP WEP104 WEP40", buflen);
1251 if (len >= buflen)
1252 return -1;
1253 return len;
1256 if (capa->enc & WPA_DRIVER_CAPA_ENC_CCMP) {
1257 ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : " ");
1258 if (ret < 0 || ret >= end - pos)
1259 return pos - buf;
1260 pos += ret;
1261 first = 0;
1264 if (capa->enc & WPA_DRIVER_CAPA_ENC_TKIP) {
1265 ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : " ");
1266 if (ret < 0 || ret >= end - pos)
1267 return pos - buf;
1268 pos += ret;
1269 first = 0;
1272 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP104) {
1273 ret = os_snprintf(pos, end - pos, "%sWEP104",
1274 first ? "" : " ");
1275 if (ret < 0 || ret >= end - pos)
1276 return pos - buf;
1277 pos += ret;
1278 first = 0;
1281 if (capa->enc & WPA_DRIVER_CAPA_ENC_WEP40) {
1282 ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : " ");
1283 if (ret < 0 || ret >= end - pos)
1284 return pos - buf;
1285 pos += ret;
1286 first = 0;
1289 return pos - buf;
1293 static int ctrl_iface_get_capability_key_mgmt(int res, char *strict,
1294 struct wpa_driver_capa *capa,
1295 char *buf, size_t buflen)
1297 int ret;
1298 char *pos, *end;
1299 size_t len;
1301 pos = buf;
1302 end = pos + buflen;
1304 if (res < 0) {
1305 if (strict)
1306 return 0;
1307 len = os_strlcpy(buf, "WPA-PSK WPA-EAP IEEE8021X WPA-NONE "
1308 "NONE", buflen);
1309 if (len >= buflen)
1310 return -1;
1311 return len;
1314 ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
1315 if (ret < 0 || ret >= end - pos)
1316 return pos - buf;
1317 pos += ret;
1319 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1320 WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
1321 ret = os_snprintf(pos, end - pos, " WPA-EAP");
1322 if (ret < 0 || ret >= end - pos)
1323 return pos - buf;
1324 pos += ret;
1327 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1328 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1329 ret = os_snprintf(pos, end - pos, " WPA-PSK");
1330 if (ret < 0 || ret >= end - pos)
1331 return pos - buf;
1332 pos += ret;
1335 if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
1336 ret = os_snprintf(pos, end - pos, " WPA-NONE");
1337 if (ret < 0 || ret >= end - pos)
1338 return pos - buf;
1339 pos += ret;
1342 return pos - buf;
1346 static int ctrl_iface_get_capability_proto(int res, char *strict,
1347 struct wpa_driver_capa *capa,
1348 char *buf, size_t buflen)
1350 int ret, first = 1;
1351 char *pos, *end;
1352 size_t len;
1354 pos = buf;
1355 end = pos + buflen;
1357 if (res < 0) {
1358 if (strict)
1359 return 0;
1360 len = os_strlcpy(buf, "RSN WPA", buflen);
1361 if (len >= buflen)
1362 return -1;
1363 return len;
1366 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1367 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
1368 ret = os_snprintf(pos, end - pos, "%sRSN", first ? "" : " ");
1369 if (ret < 0 || ret >= end - pos)
1370 return pos - buf;
1371 pos += ret;
1372 first = 0;
1375 if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1376 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
1377 ret = os_snprintf(pos, end - pos, "%sWPA", first ? "" : " ");
1378 if (ret < 0 || ret >= end - pos)
1379 return pos - buf;
1380 pos += ret;
1381 first = 0;
1384 return pos - buf;
1388 static int ctrl_iface_get_capability_auth_alg(int res, char *strict,
1389 struct wpa_driver_capa *capa,
1390 char *buf, size_t buflen)
1392 int ret, first = 1;
1393 char *pos, *end;
1394 size_t len;
1396 pos = buf;
1397 end = pos + buflen;
1399 if (res < 0) {
1400 if (strict)
1401 return 0;
1402 len = os_strlcpy(buf, "OPEN SHARED LEAP", buflen);
1403 if (len >= buflen)
1404 return -1;
1405 return len;
1408 if (capa->auth & (WPA_DRIVER_AUTH_OPEN)) {
1409 ret = os_snprintf(pos, end - pos, "%sOPEN", first ? "" : " ");
1410 if (ret < 0 || ret >= end - pos)
1411 return pos - buf;
1412 pos += ret;
1413 first = 0;
1416 if (capa->auth & (WPA_DRIVER_AUTH_SHARED)) {
1417 ret = os_snprintf(pos, end - pos, "%sSHARED",
1418 first ? "" : " ");
1419 if (ret < 0 || ret >= end - pos)
1420 return pos - buf;
1421 pos += ret;
1422 first = 0;
1425 if (capa->auth & (WPA_DRIVER_AUTH_LEAP)) {
1426 ret = os_snprintf(pos, end - pos, "%sLEAP", first ? "" : " ");
1427 if (ret < 0 || ret >= end - pos)
1428 return pos - buf;
1429 pos += ret;
1430 first = 0;
1433 return pos - buf;
1437 static int wpa_supplicant_ctrl_iface_get_capability(
1438 struct wpa_supplicant *wpa_s, const char *_field, char *buf,
1439 size_t buflen)
1441 struct wpa_driver_capa capa;
1442 int res;
1443 char *strict;
1444 char field[30];
1445 size_t len;
1447 /* Determine whether or not strict checking was requested */
1448 len = os_strlcpy(field, _field, sizeof(field));
1449 if (len >= sizeof(field))
1450 return -1;
1451 strict = os_strchr(field, ' ');
1452 if (strict != NULL) {
1453 *strict++ = '\0';
1454 if (os_strcmp(strict, "strict") != 0)
1455 return -1;
1458 wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
1459 field, strict ? strict : "");
1461 if (os_strcmp(field, "eap") == 0) {
1462 return eap_get_names(buf, buflen);
1465 res = wpa_drv_get_capa(wpa_s, &capa);
1467 if (os_strcmp(field, "pairwise") == 0)
1468 return ctrl_iface_get_capability_pairwise(res, strict, &capa,
1469 buf, buflen);
1471 if (os_strcmp(field, "group") == 0)
1472 return ctrl_iface_get_capability_group(res, strict, &capa,
1473 buf, buflen);
1475 if (os_strcmp(field, "key_mgmt") == 0)
1476 return ctrl_iface_get_capability_key_mgmt(res, strict, &capa,
1477 buf, buflen);
1479 if (os_strcmp(field, "proto") == 0)
1480 return ctrl_iface_get_capability_proto(res, strict, &capa,
1481 buf, buflen);
1483 if (os_strcmp(field, "auth_alg") == 0)
1484 return ctrl_iface_get_capability_auth_alg(res, strict, &capa,
1485 buf, buflen);
1487 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
1488 field);
1490 return -1;
1494 static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s,
1495 const char *cmd, char *buf,
1496 size_t buflen)
1498 u8 bssid[ETH_ALEN];
1499 size_t i;
1500 struct wpa_bss *bss;
1501 int ret;
1502 char *pos, *end;
1503 const u8 *ie, *ie2;
1505 if (os_strcmp(cmd, "FIRST") == 0)
1506 bss = dl_list_first(&wpa_s->bss, struct wpa_bss, list);
1507 else if (os_strncmp(cmd, "ID-", 3) == 0) {
1508 i = atoi(cmd + 3);
1509 bss = wpa_bss_get_id(wpa_s, i);
1510 } else if (os_strncmp(cmd, "NEXT-", 5) == 0) {
1511 i = atoi(cmd + 5);
1512 bss = wpa_bss_get_id(wpa_s, i);
1513 if (bss) {
1514 struct dl_list *next = bss->list_id.next;
1515 if (next == &wpa_s->bss_id)
1516 bss = NULL;
1517 else
1518 bss = dl_list_entry(next, struct wpa_bss,
1519 list_id);
1521 } else if (hwaddr_aton(cmd, bssid) == 0)
1522 bss = wpa_bss_get_bssid(wpa_s, bssid);
1523 else {
1524 struct wpa_bss *tmp;
1525 i = atoi(cmd);
1526 bss = NULL;
1527 dl_list_for_each(tmp, &wpa_s->bss_id, struct wpa_bss, list_id)
1529 if (i-- == 0) {
1530 bss = tmp;
1531 break;
1536 if (bss == NULL)
1537 return 0;
1539 pos = buf;
1540 end = buf + buflen;
1541 ret = os_snprintf(pos, end - pos,
1542 "id=%u\n"
1543 "bssid=" MACSTR "\n"
1544 "freq=%d\n"
1545 "beacon_int=%d\n"
1546 "capabilities=0x%04x\n"
1547 "qual=%d\n"
1548 "noise=%d\n"
1549 "level=%d\n"
1550 "tsf=%016llu\n"
1551 "ie=",
1552 bss->id,
1553 MAC2STR(bss->bssid), bss->freq, bss->beacon_int,
1554 bss->caps, bss->qual, bss->noise, bss->level,
1555 (unsigned long long) bss->tsf);
1556 if (ret < 0 || ret >= end - pos)
1557 return pos - buf;
1558 pos += ret;
1560 ie = (const u8 *) (bss + 1);
1561 for (i = 0; i < bss->ie_len; i++) {
1562 ret = os_snprintf(pos, end - pos, "%02x", *ie++);
1563 if (ret < 0 || ret >= end - pos)
1564 return pos - buf;
1565 pos += ret;
1568 ret = os_snprintf(pos, end - pos, "\n");
1569 if (ret < 0 || ret >= end - pos)
1570 return pos - buf;
1571 pos += ret;
1573 ret = os_snprintf(pos, end - pos, "flags=");
1574 if (ret < 0 || ret >= end - pos)
1575 return pos - buf;
1576 pos += ret;
1578 ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1579 if (ie)
1580 pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
1581 ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1582 if (ie2)
1583 pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
1584 pos = wpa_supplicant_wps_ie_txt_bss(pos, end, bss);
1585 if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
1586 ret = os_snprintf(pos, end - pos, "[WEP]");
1587 if (ret < 0 || ret >= end - pos)
1588 return pos - buf;
1589 pos += ret;
1591 if (bss->caps & IEEE80211_CAP_IBSS) {
1592 ret = os_snprintf(pos, end - pos, "[IBSS]");
1593 if (ret < 0 || ret >= end - pos)
1594 return pos - buf;
1595 pos += ret;
1597 if (bss->caps & IEEE80211_CAP_ESS) {
1598 ret = os_snprintf(pos, end - pos, "[ESS]");
1599 if (ret < 0 || ret >= end - pos)
1600 return pos - buf;
1601 pos += ret;
1604 ret = os_snprintf(pos, end - pos, "\n");
1605 if (ret < 0 || ret >= end - pos)
1606 return pos - buf;
1607 pos += ret;
1609 ret = os_snprintf(pos, end - pos, "ssid=%s\n",
1610 wpa_ssid_txt(bss->ssid, bss->ssid_len));
1611 if (ret < 0 || ret >= end - pos)
1612 return pos - buf;
1613 pos += ret;
1615 #ifdef CONFIG_WPS
1616 ie = (const u8 *) (bss + 1);
1617 ret = wpas_wps_scan_result_text(ie, bss->ie_len, pos, end);
1618 if (ret < 0 || ret >= end - pos)
1619 return pos - buf;
1620 pos += ret;
1621 #endif /* CONFIG_WPS */
1623 return pos - buf;
1627 static int wpa_supplicant_ctrl_iface_ap_scan(
1628 struct wpa_supplicant *wpa_s, char *cmd)
1630 int ap_scan = atoi(cmd);
1631 return wpa_supplicant_set_ap_scan(wpa_s, ap_scan);
1635 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
1636 char *buf, size_t *resp_len)
1638 char *reply;
1639 const int reply_size = 2048;
1640 int ctrl_rsp = 0;
1641 int reply_len;
1643 if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
1644 os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1645 wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
1646 (const u8 *) buf, os_strlen(buf));
1647 } else {
1648 wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
1649 (const u8 *) buf, os_strlen(buf));
1652 reply = os_malloc(reply_size);
1653 if (reply == NULL) {
1654 *resp_len = 1;
1655 return NULL;
1658 os_memcpy(reply, "OK\n", 3);
1659 reply_len = 3;
1661 if (os_strcmp(buf, "PING") == 0) {
1662 os_memcpy(reply, "PONG\n", 5);
1663 reply_len = 5;
1664 } else if (os_strcmp(buf, "MIB") == 0) {
1665 reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
1666 if (reply_len >= 0) {
1667 int res;
1668 res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
1669 reply_size - reply_len);
1670 if (res < 0)
1671 reply_len = -1;
1672 else
1673 reply_len += res;
1675 } else if (os_strncmp(buf, "STATUS", 6) == 0) {
1676 reply_len = wpa_supplicant_ctrl_iface_status(
1677 wpa_s, buf + 6, reply, reply_size);
1678 } else if (os_strcmp(buf, "PMKSA") == 0) {
1679 reply_len = wpa_sm_pmksa_cache_list(wpa_s->wpa, reply,
1680 reply_size);
1681 } else if (os_strncmp(buf, "SET ", 4) == 0) {
1682 if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
1683 reply_len = -1;
1684 } else if (os_strcmp(buf, "LOGON") == 0) {
1685 eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
1686 } else if (os_strcmp(buf, "LOGOFF") == 0) {
1687 eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
1688 } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
1689 wpa_s->disconnected = 0;
1690 wpa_s->reassociate = 1;
1691 wpa_supplicant_req_scan(wpa_s, 0, 0);
1692 } else if (os_strcmp(buf, "RECONNECT") == 0) {
1693 if (wpa_s->disconnected) {
1694 wpa_s->disconnected = 0;
1695 wpa_s->reassociate = 1;
1696 wpa_supplicant_req_scan(wpa_s, 0, 0);
1698 #ifdef IEEE8021X_EAPOL
1699 } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
1700 if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
1701 reply_len = -1;
1702 #endif /* IEEE8021X_EAPOL */
1703 #ifdef CONFIG_PEERKEY
1704 } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
1705 if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
1706 reply_len = -1;
1707 #endif /* CONFIG_PEERKEY */
1708 #ifdef CONFIG_IEEE80211R
1709 } else if (os_strncmp(buf, "FT_DS ", 6) == 0) {
1710 if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
1711 reply_len = -1;
1712 #endif /* CONFIG_IEEE80211R */
1713 #ifdef CONFIG_WPS
1714 } else if (os_strcmp(buf, "WPS_PBC") == 0) {
1715 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
1716 reply_len = -1;
1717 } else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
1718 if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
1719 reply_len = -1;
1720 } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
1721 reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
1722 reply,
1723 reply_size);
1724 #ifdef CONFIG_WPS_OOB
1725 } else if (os_strncmp(buf, "WPS_OOB ", 8) == 0) {
1726 if (wpa_supplicant_ctrl_iface_wps_oob(wpa_s, buf + 8))
1727 reply_len = -1;
1728 #endif /* CONFIG_WPS_OOB */
1729 } else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
1730 if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
1731 reply_len = -1;
1732 #ifdef CONFIG_WPS_ER
1733 } else if (os_strcmp(buf, "WPS_ER_START") == 0) {
1734 if (wpas_wps_er_start(wpa_s))
1735 reply_len = -1;
1736 } else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
1737 if (wpas_wps_er_stop(wpa_s))
1738 reply_len = -1;
1739 } else if (os_strncmp(buf, "WPS_ER_PIN ", 11) == 0) {
1740 if (wpa_supplicant_ctrl_iface_wps_er_pin(wpa_s, buf + 11))
1741 reply_len = -1;
1742 } else if (os_strncmp(buf, "WPS_ER_PBC ", 11) == 0) {
1743 if (wpas_wps_er_pbc(wpa_s, buf + 11))
1744 reply_len = -1;
1745 } else if (os_strncmp(buf, "WPS_ER_LEARN ", 13) == 0) {
1746 if (wpa_supplicant_ctrl_iface_wps_er_learn(wpa_s, buf + 13))
1747 reply_len = -1;
1748 #endif /* CONFIG_WPS_ER */
1749 #endif /* CONFIG_WPS */
1750 #ifdef CONFIG_IBSS_RSN
1751 } else if (os_strncmp(buf, "IBSS_RSN ", 9) == 0) {
1752 if (wpa_supplicant_ctrl_iface_ibss_rsn(wpa_s, buf + 9))
1753 reply_len = -1;
1754 #endif /* CONFIG_IBSS_RSN */
1755 } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
1757 if (wpa_supplicant_ctrl_iface_ctrl_rsp(
1758 wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
1759 reply_len = -1;
1760 else
1761 ctrl_rsp = 1;
1762 } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
1763 if (wpa_supplicant_reload_configuration(wpa_s))
1764 reply_len = -1;
1765 } else if (os_strcmp(buf, "TERMINATE") == 0) {
1766 wpa_supplicant_terminate_proc(wpa_s->global);
1767 } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
1768 if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
1769 reply_len = -1;
1770 } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
1771 reply_len = wpa_supplicant_ctrl_iface_list_networks(
1772 wpa_s, reply, reply_size);
1773 } else if (os_strcmp(buf, "DISCONNECT") == 0) {
1774 wpa_s->reassociate = 0;
1775 wpa_s->disconnected = 1;
1776 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1777 } else if (os_strcmp(buf, "SCAN") == 0) {
1778 wpa_s->scan_req = 2;
1779 wpa_supplicant_req_scan(wpa_s, 0, 0);
1780 } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
1781 reply_len = wpa_supplicant_ctrl_iface_scan_results(
1782 wpa_s, reply, reply_size);
1783 } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
1784 if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
1785 reply_len = -1;
1786 } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
1787 if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
1788 reply_len = -1;
1789 } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
1790 if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
1791 reply_len = -1;
1792 } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
1793 reply_len = wpa_supplicant_ctrl_iface_add_network(
1794 wpa_s, reply, reply_size);
1795 } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
1796 if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
1797 reply_len = -1;
1798 } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
1799 if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
1800 reply_len = -1;
1801 } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
1802 reply_len = wpa_supplicant_ctrl_iface_get_network(
1803 wpa_s, buf + 12, reply, reply_size);
1804 #ifndef CONFIG_NO_CONFIG_WRITE
1805 } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
1806 if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
1807 reply_len = -1;
1808 #endif /* CONFIG_NO_CONFIG_WRITE */
1809 } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
1810 reply_len = wpa_supplicant_ctrl_iface_get_capability(
1811 wpa_s, buf + 15, reply, reply_size);
1812 } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
1813 if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
1814 reply_len = -1;
1815 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
1816 reply_len = wpa_supplicant_global_iface_list(
1817 wpa_s->global, reply, reply_size);
1818 } else if (os_strcmp(buf, "INTERFACES") == 0) {
1819 reply_len = wpa_supplicant_global_iface_interfaces(
1820 wpa_s->global, reply, reply_size);
1821 } else if (os_strncmp(buf, "BSS ", 4) == 0) {
1822 reply_len = wpa_supplicant_ctrl_iface_bss(
1823 wpa_s, buf + 4, reply, reply_size);
1824 #ifdef CONFIG_AP
1825 } else if (os_strcmp(buf, "STA-FIRST") == 0) {
1826 reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
1827 } else if (os_strncmp(buf, "STA ", 4) == 0) {
1828 reply_len = ap_ctrl_iface_sta(wpa_s, buf + 4, reply,
1829 reply_size);
1830 } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
1831 reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
1832 reply_size);
1833 #endif /* CONFIG_AP */
1834 } else {
1835 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
1836 reply_len = 16;
1839 if (reply_len < 0) {
1840 os_memcpy(reply, "FAIL\n", 5);
1841 reply_len = 5;
1844 if (ctrl_rsp)
1845 eapol_sm_notify_ctrl_response(wpa_s->eapol);
1847 *resp_len = reply_len;
1848 return reply;
1852 static int wpa_supplicant_global_iface_add(struct wpa_global *global,
1853 char *cmd)
1855 struct wpa_interface iface;
1856 char *pos;
1859 * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
1860 * TAB<bridge_ifname>
1862 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
1864 os_memset(&iface, 0, sizeof(iface));
1866 do {
1867 iface.ifname = pos = cmd;
1868 pos = os_strchr(pos, '\t');
1869 if (pos)
1870 *pos++ = '\0';
1871 if (iface.ifname[0] == '\0')
1872 return -1;
1873 if (pos == NULL)
1874 break;
1876 iface.confname = pos;
1877 pos = os_strchr(pos, '\t');
1878 if (pos)
1879 *pos++ = '\0';
1880 if (iface.confname[0] == '\0')
1881 iface.confname = NULL;
1882 if (pos == NULL)
1883 break;
1885 iface.driver = pos;
1886 pos = os_strchr(pos, '\t');
1887 if (pos)
1888 *pos++ = '\0';
1889 if (iface.driver[0] == '\0')
1890 iface.driver = NULL;
1891 if (pos == NULL)
1892 break;
1894 iface.ctrl_interface = pos;
1895 pos = os_strchr(pos, '\t');
1896 if (pos)
1897 *pos++ = '\0';
1898 if (iface.ctrl_interface[0] == '\0')
1899 iface.ctrl_interface = NULL;
1900 if (pos == NULL)
1901 break;
1903 iface.driver_param = pos;
1904 pos = os_strchr(pos, '\t');
1905 if (pos)
1906 *pos++ = '\0';
1907 if (iface.driver_param[0] == '\0')
1908 iface.driver_param = NULL;
1909 if (pos == NULL)
1910 break;
1912 iface.bridge_ifname = pos;
1913 pos = os_strchr(pos, '\t');
1914 if (pos)
1915 *pos++ = '\0';
1916 if (iface.bridge_ifname[0] == '\0')
1917 iface.bridge_ifname = NULL;
1918 if (pos == NULL)
1919 break;
1920 } while (0);
1922 if (wpa_supplicant_get_iface(global, iface.ifname))
1923 return -1;
1925 return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
1929 static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
1930 char *cmd)
1932 struct wpa_supplicant *wpa_s;
1934 wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
1936 wpa_s = wpa_supplicant_get_iface(global, cmd);
1937 if (wpa_s == NULL)
1938 return -1;
1939 return wpa_supplicant_remove_iface(global, wpa_s);
1943 static void wpa_free_iface_info(struct wpa_interface_info *iface)
1945 struct wpa_interface_info *prev;
1947 while (iface) {
1948 prev = iface;
1949 iface = iface->next;
1951 os_free(prev->ifname);
1952 os_free(prev->desc);
1953 os_free(prev);
1958 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
1959 char *buf, int len)
1961 int i, res;
1962 struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
1963 char *pos, *end;
1965 for (i = 0; wpa_drivers[i]; i++) {
1966 struct wpa_driver_ops *drv = wpa_drivers[i];
1967 if (drv->get_interfaces == NULL)
1968 continue;
1969 tmp = drv->get_interfaces(global->drv_priv);
1970 if (tmp == NULL)
1971 continue;
1973 if (last == NULL)
1974 iface = last = tmp;
1975 else
1976 last->next = tmp;
1977 while (last->next)
1978 last = last->next;
1981 pos = buf;
1982 end = buf + len;
1983 for (tmp = iface; tmp; tmp = tmp->next) {
1984 res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
1985 tmp->drv_name, tmp->ifname,
1986 tmp->desc ? tmp->desc : "");
1987 if (res < 0 || res >= end - pos) {
1988 *pos = '\0';
1989 break;
1991 pos += res;
1994 wpa_free_iface_info(iface);
1996 return pos - buf;
2000 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
2001 char *buf, int len)
2003 int res;
2004 char *pos, *end;
2005 struct wpa_supplicant *wpa_s;
2007 wpa_s = global->ifaces;
2008 pos = buf;
2009 end = buf + len;
2011 while (wpa_s) {
2012 res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
2013 if (res < 0 || res >= end - pos) {
2014 *pos = '\0';
2015 break;
2017 pos += res;
2018 wpa_s = wpa_s->next;
2020 return pos - buf;
2024 char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
2025 char *buf, size_t *resp_len)
2027 char *reply;
2028 const int reply_size = 2048;
2029 int reply_len;
2031 wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
2032 (const u8 *) buf, os_strlen(buf));
2034 reply = os_malloc(reply_size);
2035 if (reply == NULL) {
2036 *resp_len = 1;
2037 return NULL;
2040 os_memcpy(reply, "OK\n", 3);
2041 reply_len = 3;
2043 if (os_strcmp(buf, "PING") == 0) {
2044 os_memcpy(reply, "PONG\n", 5);
2045 reply_len = 5;
2046 } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
2047 if (wpa_supplicant_global_iface_add(global, buf + 14))
2048 reply_len = -1;
2049 } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
2050 if (wpa_supplicant_global_iface_remove(global, buf + 17))
2051 reply_len = -1;
2052 } else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
2053 reply_len = wpa_supplicant_global_iface_list(
2054 global, reply, reply_size);
2055 } else if (os_strcmp(buf, "INTERFACES") == 0) {
2056 reply_len = wpa_supplicant_global_iface_interfaces(
2057 global, reply, reply_size);
2058 } else if (os_strcmp(buf, "TERMINATE") == 0) {
2059 wpa_supplicant_terminate_proc(global);
2060 } else {
2061 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
2062 reply_len = 16;
2065 if (reply_len < 0) {
2066 os_memcpy(reply, "FAIL\n", 5);
2067 reply_len = 5;
2070 *resp_len = reply_len;
2071 return reply;