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