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