Home | History | Annotate | Line # | Download | only in common
      1 /*
      2  * wpa_supplicant/hostapd control interface library
      3  * Copyright (c) 2004-2007, Jouni Malinen <j (at) w1.fi>
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #ifdef CONFIG_CTRL_IFACE
     12 
     13 #ifdef CONFIG_CTRL_IFACE_UNIX
     14 #include <sys/stat.h>
     15 #include <fcntl.h>
     16 #include <sys/un.h>
     17 #include <unistd.h>
     18 #include <fcntl.h>
     19 #endif /* CONFIG_CTRL_IFACE_UNIX */
     20 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
     21 #include <netdb.h>
     22 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
     23 
     24 #ifdef ANDROID
     25 #include <dirent.h>
     26 #include <sys/stat.h>
     27 #include <cutils/sockets.h>
     28 #include "private/android_filesystem_config.h"
     29 #endif /* ANDROID */
     30 
     31 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
     32 #include <net/if.h>
     33 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
     34 
     35 #include "wpa_ctrl.h"
     36 #include "common.h"
     37 
     38 
     39 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
     40 #define CTRL_IFACE_SOCKET
     41 #endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */
     42 
     43 
     44 /**
     45  * struct wpa_ctrl - Internal structure for control interface library
     46  *
     47  * This structure is used by the wpa_supplicant/hostapd control interface
     48  * library to store internal data. Programs using the library should not touch
     49  * this data directly. They can only use the pointer to the data structure as
     50  * an identifier for the control interface connection and use this as one of
     51  * the arguments for most of the control interface library functions.
     52  */
     53 struct wpa_ctrl {
     54 #ifdef CONFIG_CTRL_IFACE_UDP
     55 	int s;
     56 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
     57 	struct sockaddr_in6 local;
     58 	struct sockaddr_in6 dest;
     59 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
     60 	struct sockaddr_in local;
     61 	struct sockaddr_in dest;
     62 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
     63 	char *cookie;
     64 	char *remote_ifname;
     65 	char *remote_ip;
     66 #endif /* CONFIG_CTRL_IFACE_UDP */
     67 #ifdef CONFIG_CTRL_IFACE_UNIX
     68 	int s;
     69 	struct sockaddr_un local;
     70 	struct sockaddr_un dest;
     71 #endif /* CONFIG_CTRL_IFACE_UNIX */
     72 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
     73 	HANDLE pipe;
     74 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
     75 };
     76 
     77 
     78 #ifdef CONFIG_CTRL_IFACE_UNIX
     79 
     80 #ifndef CONFIG_CTRL_IFACE_CLIENT_DIR
     81 #define CONFIG_CTRL_IFACE_CLIENT_DIR "/tmp"
     82 #endif /* CONFIG_CTRL_IFACE_CLIENT_DIR */
     83 #ifndef CONFIG_CTRL_IFACE_CLIENT_PREFIX
     84 #define CONFIG_CTRL_IFACE_CLIENT_PREFIX "wpa_ctrl_"
     85 #endif /* CONFIG_CTRL_IFACE_CLIENT_PREFIX */
     86 
     87 
     88 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
     89 {
     90 	return wpa_ctrl_open2(ctrl_path, NULL);
     91 }
     92 
     93 
     94 struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path,
     95 				 const char *cli_path)
     96 {
     97 	struct wpa_ctrl *ctrl;
     98 	static int counter = 0;
     99 	int ret;
    100 	size_t res;
    101 	int tries = 0;
    102 	int flags;
    103 
    104 	if (ctrl_path == NULL)
    105 		return NULL;
    106 
    107 	ctrl = os_zalloc(sizeof(*ctrl));
    108 	if (ctrl == NULL)
    109 		return NULL;
    110 
    111 	ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
    112 	if (ctrl->s < 0) {
    113 		os_free(ctrl);
    114 		return NULL;
    115 	}
    116 
    117 	ctrl->local.sun_family = AF_UNIX;
    118 	counter++;
    119 try_again:
    120 	if (cli_path && cli_path[0] == '/') {
    121 		ret = os_snprintf(ctrl->local.sun_path,
    122 				  sizeof(ctrl->local.sun_path),
    123 				  "%s/" CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
    124 				  cli_path, (int) getpid(), counter);
    125 	} else {
    126 		ret = os_snprintf(ctrl->local.sun_path,
    127 				  sizeof(ctrl->local.sun_path),
    128 				  CONFIG_CTRL_IFACE_CLIENT_DIR "/"
    129 				  CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
    130 				  (int) getpid(), counter);
    131 	}
    132 	if (os_snprintf_error(sizeof(ctrl->local.sun_path), ret)) {
    133 		close(ctrl->s);
    134 		os_free(ctrl);
    135 		return NULL;
    136 	}
    137 	tries++;
    138 #ifdef ANDROID
    139 	/* Set client socket file permissions so that bind() creates the client
    140 	 * socket with these permissions and there is no need to try to change
    141 	 * them with chmod() after bind() which would have potential issues with
    142 	 * race conditions. These permissions are needed to make sure the server
    143 	 * side (wpa_supplicant or hostapd) can reply to the control interface
    144 	 * messages.
    145 	 *
    146 	 * The lchown() calls below after bind() are also part of the needed
    147 	 * operations to allow the response to go through. Those are using the
    148 	 * no-deference-symlinks version to avoid races. */
    149 	fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    150 #endif /* ANDROID */
    151 	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
    152 		    sizeof(ctrl->local)) < 0) {
    153 		if (errno == EADDRINUSE && tries < 2) {
    154 			/*
    155 			 * getpid() returns unique identifier for this instance
    156 			 * of wpa_ctrl, so the existing socket file must have
    157 			 * been left by unclean termination of an earlier run.
    158 			 * Remove the file and try again.
    159 			 */
    160 			unlink(ctrl->local.sun_path);
    161 			goto try_again;
    162 		}
    163 		close(ctrl->s);
    164 		os_free(ctrl);
    165 		return NULL;
    166 	}
    167 
    168 #ifdef ANDROID
    169 	/* Set group even if we do not have privileges to change owner */
    170 	lchown(ctrl->local.sun_path, -1, AID_WIFI);
    171 	lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
    172 
    173 	if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
    174 		if (socket_local_client_connect(
    175 			    ctrl->s, ctrl_path + 9,
    176 			    ANDROID_SOCKET_NAMESPACE_RESERVED,
    177 			    SOCK_DGRAM) < 0) {
    178 			close(ctrl->s);
    179 			unlink(ctrl->local.sun_path);
    180 			os_free(ctrl);
    181 			return NULL;
    182 		}
    183 		return ctrl;
    184 	}
    185 
    186 	/*
    187 	 * If the ctrl_path isn't an absolute pathname, assume that
    188 	 * it's the name of a socket in the Android reserved namespace.
    189 	 * Otherwise, it's a normal UNIX domain socket appearing in the
    190 	 * filesystem.
    191 	 */
    192 	if (*ctrl_path != '/') {
    193 		char buf[21];
    194 		os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
    195 		if (socket_local_client_connect(
    196 			    ctrl->s, buf,
    197 			    ANDROID_SOCKET_NAMESPACE_RESERVED,
    198 			    SOCK_DGRAM) < 0) {
    199 			close(ctrl->s);
    200 			unlink(ctrl->local.sun_path);
    201 			os_free(ctrl);
    202 			return NULL;
    203 		}
    204 		return ctrl;
    205 	}
    206 #endif /* ANDROID */
    207 
    208 	ctrl->dest.sun_family = AF_UNIX;
    209 	if (os_strncmp(ctrl_path, "@abstract:", 10) == 0) {
    210 		ctrl->dest.sun_path[0] = '\0';
    211 		os_strlcpy(ctrl->dest.sun_path + 1, ctrl_path + 10,
    212 			   sizeof(ctrl->dest.sun_path) - 1);
    213 	} else {
    214 		res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
    215 				 sizeof(ctrl->dest.sun_path));
    216 		if (res >= sizeof(ctrl->dest.sun_path)) {
    217 			close(ctrl->s);
    218 			os_free(ctrl);
    219 			return NULL;
    220 		}
    221 	}
    222 	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
    223 		    sizeof(ctrl->dest)) < 0) {
    224 		close(ctrl->s);
    225 		unlink(ctrl->local.sun_path);
    226 		os_free(ctrl);
    227 		return NULL;
    228 	}
    229 
    230 	/*
    231 	 * Make socket non-blocking so that we don't hang forever if
    232 	 * target dies unexpectedly.
    233 	 */
    234 	flags = fcntl(ctrl->s, F_GETFL);
    235 	if (flags >= 0) {
    236 		flags |= O_NONBLOCK;
    237 		if (fcntl(ctrl->s, F_SETFL, flags) < 0) {
    238 			perror("fcntl(ctrl->s, O_NONBLOCK)");
    239 			/* Not fatal, continue on.*/
    240 		}
    241 	}
    242 
    243 	return ctrl;
    244 }
    245 
    246 
    247 void wpa_ctrl_close(struct wpa_ctrl *ctrl)
    248 {
    249 	if (ctrl == NULL)
    250 		return;
    251 	unlink(ctrl->local.sun_path);
    252 	if (ctrl->s >= 0)
    253 		close(ctrl->s);
    254 	os_free(ctrl);
    255 }
    256 
    257 
    258 #ifdef ANDROID
    259 /**
    260  * wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that
    261  * may be left over from clients that were previously connected to
    262  * wpa_supplicant. This keeps these files from being orphaned in the
    263  * event of crashes that prevented them from being removed as part
    264  * of the normal orderly shutdown.
    265  */
    266 void wpa_ctrl_cleanup(void)
    267 {
    268 	DIR *dir;
    269 	struct dirent *result;
    270 	size_t dirnamelen;
    271 	size_t maxcopy;
    272 	char pathname[PATH_MAX];
    273 	char *namep;
    274 
    275 	if ((dir = opendir(CONFIG_CTRL_IFACE_CLIENT_DIR)) == NULL)
    276 		return;
    277 
    278 	dirnamelen = (size_t) os_snprintf(pathname, sizeof(pathname), "%s/",
    279 					  CONFIG_CTRL_IFACE_CLIENT_DIR);
    280 	if (dirnamelen >= sizeof(pathname)) {
    281 		closedir(dir);
    282 		return;
    283 	}
    284 	namep = pathname + dirnamelen;
    285 	maxcopy = PATH_MAX - dirnamelen;
    286 	while ((result = readdir(dir)) != NULL) {
    287 		if (os_strlcpy(namep, result->d_name, maxcopy) < maxcopy)
    288 			unlink(pathname);
    289 	}
    290 	closedir(dir);
    291 }
    292 #endif /* ANDROID */
    293 
    294 #else /* CONFIG_CTRL_IFACE_UNIX */
    295 
    296 #ifdef ANDROID
    297 void wpa_ctrl_cleanup(void)
    298 {
    299 }
    300 #endif /* ANDROID */
    301 
    302 #endif /* CONFIG_CTRL_IFACE_UNIX */
    303 
    304 
    305 #ifdef CONFIG_CTRL_IFACE_UDP
    306 
    307 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
    308 {
    309 	struct wpa_ctrl *ctrl;
    310 	char buf[128];
    311 	size_t len;
    312 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
    313 	struct hostent *h;
    314 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    315 
    316 	ctrl = os_zalloc(sizeof(*ctrl));
    317 	if (ctrl == NULL)
    318 		return NULL;
    319 
    320 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    321 	ctrl->s = socket(PF_INET6, SOCK_DGRAM, 0);
    322 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    323 	ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
    324 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    325 	if (ctrl->s < 0) {
    326 		perror("socket");
    327 		os_free(ctrl);
    328 		return NULL;
    329 	}
    330 
    331 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    332 	ctrl->local.sin6_family = AF_INET6;
    333 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
    334 	ctrl->local.sin6_addr = in6addr_any;
    335 #else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    336 	inet_pton(AF_INET6, "::1", &ctrl->local.sin6_addr);
    337 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    338 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    339 	ctrl->local.sin_family = AF_INET;
    340 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
    341 	ctrl->local.sin_addr.s_addr = INADDR_ANY;
    342 #else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    343 	ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
    344 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    345 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    346 
    347 	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
    348 		 sizeof(ctrl->local)) < 0) {
    349 		close(ctrl->s);
    350 		os_free(ctrl);
    351 		return NULL;
    352 	}
    353 
    354 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    355 	ctrl->dest.sin6_family = AF_INET6;
    356 	inet_pton(AF_INET6, "::1", &ctrl->dest.sin6_addr);
    357 	ctrl->dest.sin6_port = htons(WPA_CTRL_IFACE_PORT);
    358 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    359 	ctrl->dest.sin_family = AF_INET;
    360 	ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
    361 	ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
    362 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    363 
    364 #ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
    365 	if (ctrl_path) {
    366 		char *port, *name;
    367 		int port_id;
    368 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    369 		char *scope;
    370 		int scope_id = 0;
    371 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    372 
    373 		name = os_strdup(ctrl_path);
    374 		if (name == NULL) {
    375 			close(ctrl->s);
    376 			os_free(ctrl);
    377 			return NULL;
    378 		}
    379 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    380 		port = os_strchr(name, ',');
    381 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    382 		port = os_strchr(name, ':');
    383 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    384 
    385 		if (port) {
    386 			port_id = atoi(&port[1]);
    387 			port[0] = '\0';
    388 		} else
    389 			port_id = WPA_CTRL_IFACE_PORT;
    390 
    391 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    392 		scope = os_strchr(name, '%');
    393 		if (scope) {
    394 			scope_id = if_nametoindex(&scope[1]);
    395 			scope[0] = '\0';
    396 		}
    397 		h = gethostbyname2(name, AF_INET6);
    398 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    399 		h = gethostbyname(name);
    400 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    401 		ctrl->remote_ip = os_strdup(name);
    402 		os_free(name);
    403 		if (h == NULL) {
    404 			perror("gethostbyname");
    405 			close(ctrl->s);
    406 			os_free(ctrl->remote_ip);
    407 			os_free(ctrl);
    408 			return NULL;
    409 		}
    410 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    411 		ctrl->dest.sin6_scope_id = scope_id;
    412 		ctrl->dest.sin6_port = htons(port_id);
    413 		os_memcpy(&ctrl->dest.sin6_addr, h->h_addr, h->h_length);
    414 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    415 		ctrl->dest.sin_port = htons(port_id);
    416 		os_memcpy(&ctrl->dest.sin_addr.s_addr, h->h_addr, h->h_length);
    417 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    418 	} else
    419 		ctrl->remote_ip = os_strdup("localhost");
    420 #endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
    421 
    422 	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
    423 		    sizeof(ctrl->dest)) < 0) {
    424 #ifdef CONFIG_CTRL_IFACE_UDP_IPV6
    425 		char addr[INET6_ADDRSTRLEN];
    426 		wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
    427 			   inet_ntop(AF_INET6, &ctrl->dest.sin6_addr, addr,
    428 				     sizeof(ctrl->dest)),
    429 			   ntohs(ctrl->dest.sin6_port),
    430 			   strerror(errno));
    431 #else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    432 		wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
    433 			   inet_ntoa(ctrl->dest.sin_addr),
    434 			   ntohs(ctrl->dest.sin_port),
    435 			   strerror(errno));
    436 #endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
    437 		close(ctrl->s);
    438 		os_free(ctrl->remote_ip);
    439 		os_free(ctrl);
    440 		return NULL;
    441 	}
    442 
    443 	len = sizeof(buf) - 1;
    444 	if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) {
    445 		buf[len] = '\0';
    446 		ctrl->cookie = os_strdup(buf);
    447 	}
    448 
    449 	if (wpa_ctrl_request(ctrl, "IFNAME", 6, buf, &len, NULL) == 0) {
    450 		buf[len] = '\0';
    451 		ctrl->remote_ifname = os_strdup(buf);
    452 	}
    453 
    454 	return ctrl;
    455 }
    456 
    457 
    458 char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl)
    459 {
    460 #define WPA_CTRL_MAX_PS_NAME 100
    461 	static char ps[WPA_CTRL_MAX_PS_NAME] = {};
    462 	os_snprintf(ps, WPA_CTRL_MAX_PS_NAME, "%s/%s",
    463 		    ctrl->remote_ip, ctrl->remote_ifname);
    464 	return ps;
    465 }
    466 
    467 
    468 void wpa_ctrl_close(struct wpa_ctrl *ctrl)
    469 {
    470 	close(ctrl->s);
    471 	os_free(ctrl->cookie);
    472 	os_free(ctrl->remote_ifname);
    473 	os_free(ctrl->remote_ip);
    474 	os_free(ctrl);
    475 }
    476 
    477 #endif /* CONFIG_CTRL_IFACE_UDP */
    478 
    479 
    480 #ifdef CTRL_IFACE_SOCKET
    481 int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
    482 		     char *reply, size_t *reply_len,
    483 		     void (*msg_cb)(char *msg, size_t len))
    484 {
    485 	struct timeval tv;
    486 	struct os_reltime started_at, ending_at;
    487 	int res;
    488 	fd_set rfds;
    489 	const char *_cmd;
    490 	char *cmd_buf = NULL;
    491 	size_t _cmd_len;
    492 
    493 #ifdef CONFIG_CTRL_IFACE_UDP
    494 	if (ctrl->cookie) {
    495 		char *pos;
    496 		_cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len;
    497 		cmd_buf = os_malloc(_cmd_len);
    498 		if (cmd_buf == NULL)
    499 			return -1;
    500 		_cmd = cmd_buf;
    501 		pos = cmd_buf;
    502 		os_strlcpy(pos, ctrl->cookie, _cmd_len);
    503 		pos += os_strlen(ctrl->cookie);
    504 		*pos++ = ' ';
    505 		os_memcpy(pos, cmd, cmd_len);
    506 	} else
    507 #endif /* CONFIG_CTRL_IFACE_UDP */
    508 	{
    509 		_cmd = cmd;
    510 		_cmd_len = cmd_len;
    511 	}
    512 
    513 	errno = 0;
    514 	started_at.sec = 0;
    515 	started_at.usec = 0;
    516 retry_send:
    517 	if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
    518 		if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK)
    519 		{
    520 			/*
    521 			 * Must be a non-blocking socket... Try for a bit
    522 			 * longer before giving up.
    523 			 */
    524 			if (started_at.sec == 0)
    525 				os_get_reltime(&started_at);
    526 			else {
    527 				struct os_reltime n;
    528 				os_get_reltime(&n);
    529 				/* Try for a few seconds. */
    530 				if (os_reltime_expired(&n, &started_at, 5))
    531 					goto send_err;
    532 			}
    533 			os_sleep(1, 0);
    534 			goto retry_send;
    535 		}
    536 	send_err:
    537 		os_free(cmd_buf);
    538 		return -1;
    539 	}
    540 	os_free(cmd_buf);
    541 
    542 	os_get_reltime(&ending_at);
    543 	ending_at.sec += 10;
    544 
    545 	for (;;) {
    546 		struct os_reltime diff;
    547 
    548 		os_get_reltime(&started_at);
    549 		if (os_reltime_before(&ending_at, &started_at))
    550 			return -2;
    551 		os_reltime_sub(&ending_at, &started_at, &diff);
    552 		tv.tv_sec = diff.sec;
    553 		tv.tv_usec = diff.usec;
    554 
    555 		FD_ZERO(&rfds);
    556 		FD_SET(ctrl->s, &rfds);
    557 		res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
    558 		if (res < 0 && errno == EINTR)
    559 			continue;
    560 		if (res < 0)
    561 			return res;
    562 		if (FD_ISSET(ctrl->s, &rfds)) {
    563 			res = recv(ctrl->s, reply, *reply_len, 0);
    564 			if (res < 0)
    565 				return res;
    566 			if ((res > 0 && reply[0] == '<') ||
    567 			    (res > 6 && strncmp(reply, "IFNAME=", 7) == 0)) {
    568 				/* This is an unsolicited message from
    569 				 * wpa_supplicant, not the reply to the
    570 				 * request. Use msg_cb to report this to the
    571 				 * caller. */
    572 				if (msg_cb) {
    573 					/* Make sure the message is nul
    574 					 * terminated. */
    575 					if ((size_t) res == *reply_len)
    576 						res = (*reply_len) - 1;
    577 					reply[res] = '\0';
    578 					msg_cb(reply, res);
    579 				}
    580 				continue;
    581 			}
    582 			*reply_len = res;
    583 			break;
    584 		} else {
    585 			return -2;
    586 		}
    587 	}
    588 	return 0;
    589 }
    590 #endif /* CTRL_IFACE_SOCKET */
    591 
    592 
    593 static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
    594 {
    595 	char buf[10];
    596 	int ret;
    597 	size_t len = 10;
    598 
    599 	ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
    600 			       buf, &len, NULL);
    601 	if (ret < 0)
    602 		return ret;
    603 	if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0)
    604 		return 0;
    605 	return -1;
    606 }
    607 
    608 
    609 int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
    610 {
    611 	return wpa_ctrl_attach_helper(ctrl, 1);
    612 }
    613 
    614 
    615 int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
    616 {
    617 	return wpa_ctrl_attach_helper(ctrl, 0);
    618 }
    619 
    620 
    621 #ifdef CTRL_IFACE_SOCKET
    622 
    623 int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
    624 {
    625 	int res;
    626 
    627 	res = recv(ctrl->s, reply, *reply_len, 0);
    628 	if (res < 0)
    629 		return res;
    630 	*reply_len = res;
    631 	return 0;
    632 }
    633 
    634 
    635 int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
    636 {
    637 	struct timeval tv;
    638 	fd_set rfds;
    639 	tv.tv_sec = 0;
    640 	tv.tv_usec = 0;
    641 	FD_ZERO(&rfds);
    642 	FD_SET(ctrl->s, &rfds);
    643 	select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
    644 	return FD_ISSET(ctrl->s, &rfds);
    645 }
    646 
    647 
    648 int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
    649 {
    650 	return ctrl->s;
    651 }
    652 
    653 #endif /* CTRL_IFACE_SOCKET */
    654 
    655 
    656 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
    657 
    658 #ifndef WPA_SUPPLICANT_NAMED_PIPE
    659 #define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
    660 #endif
    661 #define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)
    662 
    663 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
    664 {
    665 	struct wpa_ctrl *ctrl;
    666 	DWORD mode;
    667 	TCHAR name[256];
    668 	int i, ret;
    669 
    670 	ctrl = os_malloc(sizeof(*ctrl));
    671 	if (ctrl == NULL)
    672 		return NULL;
    673 	os_memset(ctrl, 0, sizeof(*ctrl));
    674 
    675 #ifdef UNICODE
    676 	if (ctrl_path == NULL)
    677 		ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX);
    678 	else
    679 		ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
    680 				 ctrl_path);
    681 #else /* UNICODE */
    682 	if (ctrl_path == NULL)
    683 		ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX);
    684 	else
    685 		ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
    686 				  ctrl_path);
    687 #endif /* UNICODE */
    688 	if (os_snprintf_error(256, ret)) {
    689 		os_free(ctrl);
    690 		return NULL;
    691 	}
    692 
    693 	for (i = 0; i < 10; i++) {
    694 		ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0,
    695 					NULL, OPEN_EXISTING, 0, NULL);
    696 		/*
    697 		 * Current named pipe server side in wpa_supplicant is
    698 		 * re-opening the pipe for new clients only after the previous
    699 		 * one is taken into use. This leaves a small window for race
    700 		 * conditions when two connections are being opened at almost
    701 		 * the same time. Retry if that was the case.
    702 		 */
    703 		if (ctrl->pipe != INVALID_HANDLE_VALUE ||
    704 		    GetLastError() != ERROR_PIPE_BUSY)
    705 			break;
    706 		WaitNamedPipe(name, 1000);
    707 	}
    708 	if (ctrl->pipe == INVALID_HANDLE_VALUE) {
    709 		os_free(ctrl);
    710 		return NULL;
    711 	}
    712 
    713 	mode = PIPE_READMODE_MESSAGE;
    714 	if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) {
    715 		CloseHandle(ctrl->pipe);
    716 		os_free(ctrl);
    717 		return NULL;
    718 	}
    719 
    720 	return ctrl;
    721 }
    722 
    723 
    724 void wpa_ctrl_close(struct wpa_ctrl *ctrl)
    725 {
    726 	CloseHandle(ctrl->pipe);
    727 	os_free(ctrl);
    728 }
    729 
    730 
    731 int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
    732 		     char *reply, size_t *reply_len,
    733 		     void (*msg_cb)(char *msg, size_t len))
    734 {
    735 	DWORD written;
    736 	DWORD readlen = *reply_len;
    737 
    738 	if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL))
    739 		return -1;
    740 
    741 	if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL))
    742 		return -1;
    743 	*reply_len = readlen;
    744 
    745 	return 0;
    746 }
    747 
    748 
    749 int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
    750 {
    751 	DWORD len = *reply_len;
    752 	if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL))
    753 		return -1;
    754 	*reply_len = len;
    755 	return 0;
    756 }
    757 
    758 
    759 int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
    760 {
    761 	DWORD left;
    762 
    763 	if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL))
    764 		return -1;
    765 	return left ? 1 : 0;
    766 }
    767 
    768 
    769 int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
    770 {
    771 	return -1;
    772 }
    773 
    774 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
    775 
    776 #endif /* CONFIG_CTRL_IFACE */
    777