ctrl_iface_unix.c revision 70fd8a038c4b825f7585881cb26c68db516ad77a
1/*
2 * WPA Supplicant / UNIX domain socket -based control interface
3 * Copyright (c) 2004-2009, Jouni Malinen <j@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 */
37struct 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
46struct ctrl_iface_priv {
47	struct wpa_supplicant *wpa_s;
48	int sock;
49	struct dl_list ctrl_dst;
50};
51
52
53static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
54					   int level, const char *buf,
55					   size_t len);
56
57
58static 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
78static 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
102static 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
129static 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
214static 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
267static 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
277struct ctrl_iface_priv *
278wpa_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
449havesock:
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
472fail:
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
485void 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
536free_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 */
553static 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
607void 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
650struct ctrl_iface_global_priv {
651	struct wpa_global *global;
652	int sock;
653};
654
655
656static 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
689struct ctrl_iface_global_priv *
690wpa_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
760havesock:
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
768fail:
769	if (priv->sock >= 0)
770		close(priv->sock);
771	os_free(priv);
772	return NULL;
773}
774
775
776void
777wpa_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