Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant / UNIX domain socket -based control interface
      3  * Copyright (c) 2004-2009, 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 #include <sys/un.h>
     11 #include <sys/stat.h>
     12 #include <grp.h>
     13 #include <stddef.h>
     14 #include <unistd.h>
     15 #include <fcntl.h>
     16 #ifdef ANDROID
     17 #include <cutils/sockets.h>
     18 #endif /* ANDROID */
     19 
     20 #include "utils/common.h"
     21 #include "utils/eloop.h"
     22 #include "utils/list.h"
     23 #include "eapol_supp/eapol_supp_sm.h"
     24 #include "config.h"
     25 #include "wpa_supplicant_i.h"
     26 #include "ctrl_iface.h"
     27 
     28 /* Per-interface ctrl_iface */
     29 
     30 /**
     31  * struct wpa_ctrl_dst - Internal data structure of control interface monitors
     32  *
     33  * This structure is used to store information about registered control
     34  * interface monitors into struct wpa_supplicant. This data is private to
     35  * ctrl_iface_unix.c and should not be touched directly from other files.
     36  */
     37 struct wpa_ctrl_dst {
     38 	struct dl_list list;
     39 	struct sockaddr_un addr;
     40 	socklen_t addrlen;
     41 	int debug_level;
     42 	int errors;
     43 };
     44 
     45 
     46 struct ctrl_iface_priv {
     47 	struct wpa_supplicant *wpa_s;
     48 	int sock;
     49 	struct dl_list ctrl_dst;
     50 };
     51 
     52 
     53 static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
     54 					   int level, const char *buf,
     55 					   size_t len);
     56 
     57 
     58 static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv,
     59 					    struct sockaddr_un *from,
     60 					    socklen_t fromlen)
     61 {
     62 	struct wpa_ctrl_dst *dst;
     63 
     64 	dst = os_zalloc(sizeof(*dst));
     65 	if (dst == NULL)
     66 		return -1;
     67 	os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
     68 	dst->addrlen = fromlen;
     69 	dst->debug_level = MSG_INFO;
     70 	dl_list_add(&priv->ctrl_dst, &dst->list);
     71 	wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",
     72 		    (u8 *) from->sun_path,
     73 		    fromlen - offsetof(struct sockaddr_un, sun_path));
     74 	return 0;
     75 }
     76 
     77 
     78 static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv,
     79 					    struct sockaddr_un *from,
     80 					    socklen_t fromlen)
     81 {
     82 	struct wpa_ctrl_dst *dst;
     83 
     84 	dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
     85 		if (fromlen == dst->addrlen &&
     86 		    os_memcmp(from->sun_path, dst->addr.sun_path,
     87 			      fromlen - offsetof(struct sockaddr_un, sun_path))
     88 		    == 0) {
     89 			dl_list_del(&dst->list);
     90 			os_free(dst);
     91 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",
     92 				    (u8 *) from->sun_path,
     93 				    fromlen -
     94 				    offsetof(struct sockaddr_un, sun_path));
     95 			return 0;
     96 		}
     97 	}
     98 	return -1;
     99 }
    100 
    101 
    102 static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
    103 					   struct sockaddr_un *from,
    104 					   socklen_t fromlen,
    105 					   char *level)
    106 {
    107 	struct wpa_ctrl_dst *dst;
    108 
    109 	wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
    110 
    111 	dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
    112 		if (fromlen == dst->addrlen &&
    113 		    os_memcmp(from->sun_path, dst->addr.sun_path,
    114 			      fromlen - offsetof(struct sockaddr_un, sun_path))
    115 		    == 0) {
    116 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "
    117 				    "level", (u8 *) from->sun_path,
    118 				    fromlen -
    119 				    offsetof(struct sockaddr_un, sun_path));
    120 			dst->debug_level = atoi(level);
    121 			return 0;
    122 		}
    123 	}
    124 
    125 	return -1;
    126 }
    127 
    128 
    129 static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
    130 					      void *sock_ctx)
    131 {
    132 	struct wpa_supplicant *wpa_s = eloop_ctx;
    133 	struct ctrl_iface_priv *priv = sock_ctx;
    134 	char buf[4096];
    135 	int res;
    136 	struct sockaddr_un from;
    137 	socklen_t fromlen = sizeof(from);
    138 	char *reply = NULL;
    139 	size_t reply_len = 0;
    140 	int new_attached = 0;
    141 
    142 	res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
    143 		       (struct sockaddr *) &from, &fromlen);
    144 	if (res < 0) {
    145 		perror("recvfrom(ctrl_iface)");
    146 		return;
    147 	}
    148 	buf[res] = '\0';
    149 
    150 	if (os_strcmp(buf, "ATTACH") == 0) {
    151 		if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen))
    152 			reply_len = 1;
    153 		else {
    154 			new_attached = 1;
    155 			reply_len = 2;
    156 		}
    157 	} else if (os_strcmp(buf, "DETACH") == 0) {
    158 		if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen))
    159 			reply_len = 1;
    160 		else
    161 			reply_len = 2;
    162 	} else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
    163 		if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
    164 						    buf + 6))
    165 			reply_len = 1;
    166 		else
    167 			reply_len = 2;
    168 	} else {
    169 #if defined(CONFIG_P2P) && defined(ANDROID_P2P)
    170 		char *ifname, *ifend;
    171 
    172 		ifname = os_strstr(buf, "interface=");
    173 		if (ifname != NULL) {
    174 			ifend = os_strchr(ifname + 10, ' ');
    175 			if (ifend != NULL)
    176 				*ifend++ = '\0';
    177 			else
    178 				*(ifname - 1) = '\0';
    179 			wpa_printf(MSG_DEBUG, "Found %s", ifname);
    180 			for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
    181 				if (os_strcmp(wpa_s->ifname, ifname + 10) == 0)
    182 					break;
    183 			}
    184 			if (wpa_s == NULL) {
    185 				wpa_printf(MSG_ERROR, "P2P: %s does not exist", ifname);
    186 				wpa_s = eloop_ctx;
    187 			}
    188 			if (ifend != NULL)
    189 				os_memmove(ifname, ifend, strlen(ifend) + 1);
    190 			wpa_printf(MSG_INFO, "wpa_s->ifname %s cmd %s", wpa_s ? wpa_s->ifname : "NULL", buf);
    191 		}
    192 #endif /* defined CONFIG_P2P && defined ANDROID_P2P */
    193 		reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
    194 							  &reply_len);
    195 	}
    196 
    197 	if (reply) {
    198 		sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
    199 		       fromlen);
    200 		os_free(reply);
    201 	} else if (reply_len == 1) {
    202 		sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
    203 		       fromlen);
    204 	} else if (reply_len == 2) {
    205 		sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
    206 		       fromlen);
    207 	}
    208 
    209 	if (new_attached)
    210 		eapol_sm_notify_ctrl_attached(wpa_s->eapol);
    211 }
    212 
    213 
    214 static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s)
    215 {
    216 	char *buf;
    217 	size_t len;
    218 	char *pbuf, *dir = NULL, *gid_str = NULL;
    219 	int res;
    220 
    221 	if (wpa_s->conf->ctrl_interface == NULL)
    222 		return NULL;
    223 
    224 	pbuf = os_strdup(wpa_s->conf->ctrl_interface);
    225 	if (pbuf == NULL)
    226 		return NULL;
    227 	if (os_strncmp(pbuf, "DIR=", 4) == 0) {
    228 		dir = pbuf + 4;
    229 		gid_str = os_strstr(dir, " GROUP=");
    230 		if (gid_str) {
    231 			*gid_str = '\0';
    232 			gid_str += 7;
    233 		}
    234 	} else
    235 		dir = pbuf;
    236 
    237 	len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2;
    238 	buf = os_malloc(len);
    239 	if (buf == NULL) {
    240 		os_free(pbuf);
    241 		return NULL;
    242 	}
    243 
    244 	res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname);
    245 	if (res < 0 || (size_t) res >= len) {
    246 		os_free(pbuf);
    247 		os_free(buf);
    248 		return NULL;
    249 	}
    250 #ifdef __CYGWIN__
    251 	{
    252 		/* Windows/WinPcap uses interface names that are not suitable
    253 		 * as a file name - convert invalid chars to underscores */
    254 		char *pos = buf;
    255 		while (*pos) {
    256 			if (*pos == '\\')
    257 				*pos = '_';
    258 			pos++;
    259 		}
    260 	}
    261 #endif /* __CYGWIN__ */
    262 	os_free(pbuf);
    263 	return buf;
    264 }
    265 
    266 
    267 static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
    268 					     const char *txt, size_t len)
    269 {
    270 	struct wpa_supplicant *wpa_s = ctx;
    271 	if (wpa_s == NULL || wpa_s->ctrl_iface == NULL)
    272 		return;
    273 	wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len);
    274 }
    275 
    276 
    277 struct ctrl_iface_priv *
    278 wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
    279 {
    280 	struct ctrl_iface_priv *priv;
    281 	struct sockaddr_un addr;
    282 	char *fname = NULL;
    283 	gid_t gid = 0;
    284 	int gid_set = 0;
    285 	char *buf, *dir = NULL, *gid_str = NULL;
    286 	struct group *grp;
    287 	char *endp;
    288 	int flags;
    289 
    290 	priv = os_zalloc(sizeof(*priv));
    291 	if (priv == NULL)
    292 		return NULL;
    293 	dl_list_init(&priv->ctrl_dst);
    294 	priv->wpa_s = wpa_s;
    295 	priv->sock = -1;
    296 
    297 	if (wpa_s->conf->ctrl_interface == NULL)
    298 		return priv;
    299 
    300 	buf = os_strdup(wpa_s->conf->ctrl_interface);
    301 	if (buf == NULL)
    302 		goto fail;
    303 #ifdef ANDROID
    304 	os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
    305 		    wpa_s->conf->ctrl_interface);
    306 	priv->sock = android_get_control_socket(addr.sun_path);
    307 	if (priv->sock >= 0)
    308 		goto havesock;
    309 #endif /* ANDROID */
    310 	if (os_strncmp(buf, "DIR=", 4) == 0) {
    311 		dir = buf + 4;
    312 		gid_str = os_strstr(dir, " GROUP=");
    313 		if (gid_str) {
    314 			*gid_str = '\0';
    315 			gid_str += 7;
    316 		}
    317 	} else {
    318 		dir = buf;
    319 		gid_str = wpa_s->conf->ctrl_interface_group;
    320 	}
    321 
    322 	if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
    323 		if (errno == EEXIST) {
    324 			wpa_printf(MSG_DEBUG, "Using existing control "
    325 				   "interface directory.");
    326 		} else {
    327 			perror("mkdir[ctrl_interface]");
    328 			goto fail;
    329 		}
    330 	}
    331 
    332 #ifdef ANDROID
    333 	/*
    334 	 * wpa_supplicant is started from /init.*.rc on Android and that seems
    335 	 * to be using umask 0077 which would leave the control interface
    336 	 * directory without group access. This breaks things since Wi-Fi
    337 	 * framework assumes that this directory can be accessed by other
    338 	 * applications in the wifi group. Fix this by adding group access even
    339 	 * if umask value would prevent this.
    340 	 */
    341 	if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
    342 		wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
    343 			   strerror(errno));
    344 		/* Try to continue anyway */
    345 	}
    346 #endif /* ANDROID */
    347 
    348 	if (gid_str) {
    349 		grp = getgrnam(gid_str);
    350 		if (grp) {
    351 			gid = grp->gr_gid;
    352 			gid_set = 1;
    353 			wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
    354 				   " (from group name '%s')",
    355 				   (int) gid, gid_str);
    356 		} else {
    357 			/* Group name not found - try to parse this as gid */
    358 			gid = strtol(gid_str, &endp, 10);
    359 			if (*gid_str == '\0' || *endp != '\0') {
    360 				wpa_printf(MSG_ERROR, "CTRL: Invalid group "
    361 					   "'%s'", gid_str);
    362 				goto fail;
    363 			}
    364 			gid_set = 1;
    365 			wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
    366 				   (int) gid);
    367 		}
    368 	}
    369 
    370 	if (gid_set && chown(dir, -1, gid) < 0) {
    371 		perror("chown[ctrl_interface]");
    372 		goto fail;
    373 	}
    374 
    375 	/* Make sure the group can enter and read the directory */
    376 	if (gid_set &&
    377 	    chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
    378 		wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
    379 			   strerror(errno));
    380 		goto fail;
    381 	}
    382 
    383 	if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
    384 	    sizeof(addr.sun_path)) {
    385 		wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
    386 		goto fail;
    387 	}
    388 
    389 	priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
    390 	if (priv->sock < 0) {
    391 		perror("socket(PF_UNIX)");
    392 		goto fail;
    393 	}
    394 
    395 	os_memset(&addr, 0, sizeof(addr));
    396 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    397 	addr.sun_len = sizeof(addr);
    398 #endif /* __FreeBSD__ */
    399 	addr.sun_family = AF_UNIX;
    400 	fname = wpa_supplicant_ctrl_iface_path(wpa_s);
    401 	if (fname == NULL)
    402 		goto fail;
    403 	os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
    404 	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    405 		wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
    406 			   strerror(errno));
    407 		if (connect(priv->sock, (struct sockaddr *) &addr,
    408 			    sizeof(addr)) < 0) {
    409 			wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
    410 				   " allow connections - assuming it was left"
    411 				   "over from forced program termination");
    412 			if (unlink(fname) < 0) {
    413 				perror("unlink[ctrl_iface]");
    414 				wpa_printf(MSG_ERROR, "Could not unlink "
    415 					   "existing ctrl_iface socket '%s'",
    416 					   fname);
    417 				goto fail;
    418 			}
    419 			if (bind(priv->sock, (struct sockaddr *) &addr,
    420 				 sizeof(addr)) < 0) {
    421 				perror("supp-ctrl-iface-init: bind(PF_UNIX)");
    422 				goto fail;
    423 			}
    424 			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
    425 				   "ctrl_iface socket '%s'", fname);
    426 		} else {
    427 			wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
    428 				   "be in use - cannot override it");
    429 			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
    430 				   "not used anymore", fname);
    431 			os_free(fname);
    432 			fname = NULL;
    433 			goto fail;
    434 		}
    435 	}
    436 
    437 	if (gid_set && chown(fname, -1, gid) < 0) {
    438 		perror("chown[ctrl_interface/ifname]");
    439 		goto fail;
    440 	}
    441 
    442 	if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
    443 		perror("chmod[ctrl_interface/ifname]");
    444 		goto fail;
    445 	}
    446 	os_free(fname);
    447 
    448 #ifdef ANDROID
    449 havesock:
    450 #endif /* ANDROID */
    451 
    452 	/*
    453 	 * Make socket non-blocking so that we don't hang forever if
    454 	 * target dies unexpectedly.
    455 	 */
    456 	flags = fcntl(priv->sock, F_GETFL);
    457 	if (flags >= 0) {
    458 		flags |= O_NONBLOCK;
    459 		if (fcntl(priv->sock, F_SETFL, flags) < 0) {
    460 			perror("fcntl(ctrl, O_NONBLOCK)");
    461 			/* Not fatal, continue on.*/
    462 		}
    463 	}
    464 
    465 	eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
    466 				 wpa_s, priv);
    467 	wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
    468 
    469 	os_free(buf);
    470 	return priv;
    471 
    472 fail:
    473 	if (priv->sock >= 0)
    474 		close(priv->sock);
    475 	os_free(priv);
    476 	if (fname) {
    477 		unlink(fname);
    478 		os_free(fname);
    479 	}
    480 	os_free(buf);
    481 	return NULL;
    482 }
    483 
    484 
    485 void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
    486 {
    487 	struct wpa_ctrl_dst *dst, *prev;
    488 
    489 	if (priv->sock > -1) {
    490 		char *fname;
    491 		char *buf, *dir = NULL, *gid_str = NULL;
    492 		eloop_unregister_read_sock(priv->sock);
    493 		if (!dl_list_empty(&priv->ctrl_dst)) {
    494 			/*
    495 			 * Wait a second before closing the control socket if
    496 			 * there are any attached monitors in order to allow
    497 			 * them to receive any pending messages.
    498 			 */
    499 			wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
    500 				   "monitors to receive messages");
    501 			os_sleep(1, 0);
    502 		}
    503 		close(priv->sock);
    504 		priv->sock = -1;
    505 		fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
    506 		if (fname) {
    507 			unlink(fname);
    508 			os_free(fname);
    509 		}
    510 
    511 		buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
    512 		if (buf == NULL)
    513 			goto free_dst;
    514 		if (os_strncmp(buf, "DIR=", 4) == 0) {
    515 			dir = buf + 4;
    516 			gid_str = os_strstr(dir, " GROUP=");
    517 			if (gid_str) {
    518 				*gid_str = '\0';
    519 				gid_str += 7;
    520 			}
    521 		} else
    522 			dir = buf;
    523 
    524 		if (rmdir(dir) < 0) {
    525 			if (errno == ENOTEMPTY) {
    526 				wpa_printf(MSG_DEBUG, "Control interface "
    527 					   "directory not empty - leaving it "
    528 					   "behind");
    529 			} else {
    530 				perror("rmdir[ctrl_interface]");
    531 			}
    532 		}
    533 		os_free(buf);
    534 	}
    535 
    536 free_dst:
    537 	dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
    538 			      list)
    539 		os_free(dst);
    540 	os_free(priv);
    541 }
    542 
    543 
    544 /**
    545  * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
    546  * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
    547  * @level: Priority level of the message
    548  * @buf: Message data
    549  * @len: Message length
    550  *
    551  * Send a packet to all monitor programs attached to the control interface.
    552  */
    553 static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
    554 					   int level, const char *buf,
    555 					   size_t len)
    556 {
    557 	struct wpa_ctrl_dst *dst, *next;
    558 	char levelstr[10];
    559 	int idx, res;
    560 	struct msghdr msg;
    561 	struct iovec io[2];
    562 
    563 	if (priv->sock < 0 || dl_list_empty(&priv->ctrl_dst))
    564 		return;
    565 
    566 	res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
    567 	if (res < 0 || (size_t) res >= sizeof(levelstr))
    568 		return;
    569 	io[0].iov_base = levelstr;
    570 	io[0].iov_len = os_strlen(levelstr);
    571 	io[1].iov_base = (char *) buf;
    572 	io[1].iov_len = len;
    573 	os_memset(&msg, 0, sizeof(msg));
    574 	msg.msg_iov = io;
    575 	msg.msg_iovlen = 2;
    576 
    577 	idx = 0;
    578 	dl_list_for_each_safe(dst, next, &priv->ctrl_dst, struct wpa_ctrl_dst,
    579 			      list) {
    580 		if (level >= dst->debug_level) {
    581 			wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
    582 				    (u8 *) dst->addr.sun_path, dst->addrlen -
    583 				    offsetof(struct sockaddr_un, sun_path));
    584 			msg.msg_name = (void *) &dst->addr;
    585 			msg.msg_namelen = dst->addrlen;
    586 			if (sendmsg(priv->sock, &msg, 0) < 0) {
    587 				int _errno = errno;
    588 				wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
    589 					   "%d - %s",
    590 					   idx, errno, strerror(errno));
    591 				dst->errors++;
    592 				if (dst->errors > 1000 ||
    593 				    (_errno != ENOBUFS && dst->errors > 10) ||
    594 				    _errno == ENOENT) {
    595 					wpa_supplicant_ctrl_iface_detach(
    596 						priv, &dst->addr,
    597 						dst->addrlen);
    598 				}
    599 			} else
    600 				dst->errors = 0;
    601 		}
    602 		idx++;
    603 	}
    604 }
    605 
    606 
    607 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
    608 {
    609 	char buf[256];
    610 	int res;
    611 	struct sockaddr_un from;
    612 	socklen_t fromlen = sizeof(from);
    613 
    614 	for (;;) {
    615 		wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
    616 			   "attach", priv->wpa_s->ifname);
    617 		eloop_wait_for_read_sock(priv->sock);
    618 
    619 		res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
    620 			       (struct sockaddr *) &from, &fromlen);
    621 		if (res < 0) {
    622 			perror("recvfrom(ctrl_iface)");
    623 			continue;
    624 		}
    625 		buf[res] = '\0';
    626 
    627 		if (os_strcmp(buf, "ATTACH") == 0) {
    628 			/* handle ATTACH signal of first monitor interface */
    629 			if (!wpa_supplicant_ctrl_iface_attach(priv, &from,
    630 							      fromlen)) {
    631 				sendto(priv->sock, "OK\n", 3, 0,
    632 				       (struct sockaddr *) &from, fromlen);
    633 				/* OK to continue */
    634 				return;
    635 			} else {
    636 				sendto(priv->sock, "FAIL\n", 5, 0,
    637 				       (struct sockaddr *) &from, fromlen);
    638 			}
    639 		} else {
    640 			/* return FAIL for all other signals */
    641 			sendto(priv->sock, "FAIL\n", 5, 0,
    642 			       (struct sockaddr *) &from, fromlen);
    643 		}
    644 	}
    645 }
    646 
    647 
    648 /* Global ctrl_iface */
    649 
    650 struct ctrl_iface_global_priv {
    651 	struct wpa_global *global;
    652 	int sock;
    653 };
    654 
    655 
    656 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
    657 						     void *sock_ctx)
    658 {
    659 	struct wpa_global *global = eloop_ctx;
    660 	char buf[256];
    661 	int res;
    662 	struct sockaddr_un from;
    663 	socklen_t fromlen = sizeof(from);
    664 	char *reply;
    665 	size_t reply_len;
    666 
    667 	res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
    668 		       (struct sockaddr *) &from, &fromlen);
    669 	if (res < 0) {
    670 		perror("recvfrom(ctrl_iface)");
    671 		return;
    672 	}
    673 	buf[res] = '\0';
    674 
    675 	reply = wpa_supplicant_global_ctrl_iface_process(global, buf,
    676 							 &reply_len);
    677 
    678 	if (reply) {
    679 		sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
    680 		       fromlen);
    681 		os_free(reply);
    682 	} else if (reply_len) {
    683 		sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
    684 		       fromlen);
    685 	}
    686 }
    687 
    688 
    689 struct ctrl_iface_global_priv *
    690 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
    691 {
    692 	struct ctrl_iface_global_priv *priv;
    693 	struct sockaddr_un addr;
    694 
    695 	priv = os_zalloc(sizeof(*priv));
    696 	if (priv == NULL)
    697 		return NULL;
    698 	priv->global = global;
    699 	priv->sock = -1;
    700 
    701 	if (global->params.ctrl_interface == NULL)
    702 		return priv;
    703 
    704 #ifdef ANDROID
    705 	priv->sock = android_get_control_socket(global->params.ctrl_interface);
    706 	if (priv->sock >= 0)
    707 		goto havesock;
    708 #endif /* ANDROID */
    709 
    710 	wpa_printf(MSG_DEBUG, "Global control interface '%s'",
    711 		   global->params.ctrl_interface);
    712 
    713 	priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
    714 	if (priv->sock < 0) {
    715 		perror("socket(PF_UNIX)");
    716 		goto fail;
    717 	}
    718 
    719 	os_memset(&addr, 0, sizeof(addr));
    720 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    721 	addr.sun_len = sizeof(addr);
    722 #endif /* __FreeBSD__ */
    723 	addr.sun_family = AF_UNIX;
    724 	os_strlcpy(addr.sun_path, global->params.ctrl_interface,
    725 		   sizeof(addr.sun_path));
    726 	if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    727 		perror("supp-global-ctrl-iface-init (will try fixup): "
    728 		       "bind(PF_UNIX)");
    729 		if (connect(priv->sock, (struct sockaddr *) &addr,
    730 			    sizeof(addr)) < 0) {
    731 			wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
    732 				   " allow connections - assuming it was left"
    733 				   "over from forced program termination");
    734 			if (unlink(global->params.ctrl_interface) < 0) {
    735 				perror("unlink[ctrl_iface]");
    736 				wpa_printf(MSG_ERROR, "Could not unlink "
    737 					   "existing ctrl_iface socket '%s'",
    738 					   global->params.ctrl_interface);
    739 				goto fail;
    740 			}
    741 			if (bind(priv->sock, (struct sockaddr *) &addr,
    742 				 sizeof(addr)) < 0) {
    743 				perror("supp-glb-iface-init: bind(PF_UNIX)");
    744 				goto fail;
    745 			}
    746 			wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
    747 				   "ctrl_iface socket '%s'",
    748 				   global->params.ctrl_interface);
    749 		} else {
    750 			wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
    751 				   "be in use - cannot override it");
    752 			wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
    753 				   "not used anymore",
    754 				   global->params.ctrl_interface);
    755 			goto fail;
    756 		}
    757 	}
    758 
    759 #ifdef ANDROID
    760 havesock:
    761 #endif /* ANDROID */
    762 	eloop_register_read_sock(priv->sock,
    763 				 wpa_supplicant_global_ctrl_iface_receive,
    764 				 global, NULL);
    765 
    766 	return priv;
    767 
    768 fail:
    769 	if (priv->sock >= 0)
    770 		close(priv->sock);
    771 	os_free(priv);
    772 	return NULL;
    773 }
    774 
    775 
    776 void
    777 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
    778 {
    779 	if (priv->sock >= 0) {
    780 		eloop_unregister_read_sock(priv->sock);
    781 		close(priv->sock);
    782 	}
    783 	if (priv->global->params.ctrl_interface)
    784 		unlink(priv->global->params.ctrl_interface);
    785 	os_free(priv);
    786 }
    787