OSDN Git Service

Add ANDROID-related changes
[android-x86/external-wpa_supplicant_6.git] / wpa_supplicant / ctrl_iface_unix.c
1 /*
2  * WPA Supplicant / UNIX domain socket -based control interface
3  * Copyright (c) 2004-2005, Jouni Malinen <j@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         if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
346             sizeof(addr.sun_path)) {
347                 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
348                 goto fail;
349         }
350
351         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
352         if (priv->sock < 0) {
353                 perror("socket(PF_UNIX)");
354                 goto fail;
355         }
356
357         os_memset(&addr, 0, sizeof(addr));
358 #ifdef __FreeBSD__
359         addr.sun_len = sizeof(addr);
360 #endif /* __FreeBSD__ */
361         addr.sun_family = AF_UNIX;
362         fname = wpa_supplicant_ctrl_iface_path(wpa_s);
363         if (fname == NULL)
364                 goto fail;
365         os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
366         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
367                 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
368                            strerror(errno));
369                 if (connect(priv->sock, (struct sockaddr *) &addr,
370                             sizeof(addr)) < 0) {
371                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
372                                    " allow connections - assuming it was left"
373                                    "over from forced program termination");
374                         if (unlink(fname) < 0) {
375                                 perror("unlink[ctrl_iface]");
376                                 wpa_printf(MSG_ERROR, "Could not unlink "
377                                            "existing ctrl_iface socket '%s'",
378                                            fname);
379                                 goto fail;
380                         }
381                         if (bind(priv->sock, (struct sockaddr *) &addr,
382                                  sizeof(addr)) < 0) {
383                                 perror("bind(PF_UNIX)");
384                                 goto fail;
385                         }
386                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
387                                    "ctrl_iface socket '%s'", fname);
388                 } else {
389                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
390                                    "be in use - cannot override it");
391                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
392                                    "not used anymore", fname);
393                         os_free(fname);
394                         fname = NULL;
395                         goto fail;
396                 }
397         }
398
399         if (gid_set && chown(fname, -1, gid) < 0) {
400                 perror("chown[ctrl_interface/ifname]");
401                 goto fail;
402         }
403
404         if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
405                 perror("chmod[ctrl_interface/ifname]");
406                 goto fail;
407         }
408         os_free(fname);
409
410 havesock:
411         eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
412                                  wpa_s, priv);
413         wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
414
415         os_free(buf);
416         return priv;
417
418 fail:
419         if (priv->sock >= 0)
420                 close(priv->sock);
421         os_free(priv);
422         if (fname) {
423                 unlink(fname);
424                 os_free(fname);
425         }
426         os_free(buf);
427         return NULL;
428 }
429
430
431 void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
432 {
433         struct wpa_ctrl_dst *dst, *prev;
434
435         if (priv->sock > -1) {
436                 char *fname;
437                 char *buf, *dir = NULL, *gid_str = NULL;
438                 eloop_unregister_read_sock(priv->sock);
439                 if (priv->ctrl_dst) {
440                         /*
441                          * Wait a second before closing the control socket if
442                          * there are any attached monitors in order to allow
443                          * them to receive any pending messages.
444                          */
445                         wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
446                                    "monitors to receive messages");
447                         os_sleep(1, 0);
448                 }
449                 close(priv->sock);
450                 priv->sock = -1;
451                 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
452                 if (fname) {
453                         unlink(fname);
454                         os_free(fname);
455                 }
456
457                 buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
458                 if (buf == NULL)
459                         goto free_dst;
460                 if (os_strncmp(buf, "DIR=", 4) == 0) {
461                         dir = buf + 4;
462                         gid_str = os_strstr(dir, " GROUP=");
463                         if (gid_str) {
464                                 *gid_str = '\0';
465                                 gid_str += 7;
466                         }
467                 } else
468                         dir = buf;
469
470                 if (rmdir(dir) < 0) {
471                         if (errno == ENOTEMPTY) {
472                                 wpa_printf(MSG_DEBUG, "Control interface "
473                                            "directory not empty - leaving it "
474                                            "behind");
475                         } else {
476                                 perror("rmdir[ctrl_interface]");
477                         }
478                 }
479                 os_free(buf);
480         }
481
482 free_dst:
483         dst = priv->ctrl_dst;
484         while (dst) {
485                 prev = dst;
486                 dst = dst->next;
487                 os_free(prev);
488         }
489         os_free(priv);
490 }
491
492
493 /**
494  * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
495  * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
496  * @level: Priority level of the message
497  * @buf: Message data
498  * @len: Message length
499  *
500  * Send a packet to all monitor programs attached to the control interface.
501  */
502 static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
503                                            int level, const char *buf,
504                                            size_t len)
505 {
506         struct wpa_ctrl_dst *dst, *next;
507         char levelstr[10];
508         int idx, res;
509         struct msghdr msg;
510         struct iovec io[2];
511
512         dst = priv->ctrl_dst;
513         if (priv->sock < 0 || dst == NULL)
514                 return;
515
516         res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
517         if (res < 0 || (size_t) res >= sizeof(levelstr))
518                 return;
519         io[0].iov_base = levelstr;
520         io[0].iov_len = os_strlen(levelstr);
521         io[1].iov_base = (char *) buf;
522         io[1].iov_len = len;
523         os_memset(&msg, 0, sizeof(msg));
524         msg.msg_iov = io;
525         msg.msg_iovlen = 2;
526
527         idx = 0;
528         while (dst) {
529                 next = dst->next;
530                 if (level >= dst->debug_level) {
531                         wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
532                                     (u8 *) dst->addr.sun_path, dst->addrlen -
533                                     offsetof(struct sockaddr_un, sun_path));
534                         msg.msg_name = (void *) &dst->addr;
535                         msg.msg_namelen = dst->addrlen;
536                         if (sendmsg(priv->sock, &msg, 0) < 0) {
537                                 int _errno = errno;
538                                 wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
539                                            "%d - %s",
540                                            idx, errno, strerror(errno));
541                                 dst->errors++;
542                                 if (dst->errors > 10 || _errno == ENOENT) {
543                                         wpa_supplicant_ctrl_iface_detach(
544                                                 priv, &dst->addr,
545                                                 dst->addrlen);
546                                 }
547                         } else
548                                 dst->errors = 0;
549                 }
550                 idx++;
551                 dst = next;
552         }
553 }
554
555
556 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
557 {
558         char buf[256];
559         int res;
560         struct sockaddr_un from;
561         socklen_t fromlen = sizeof(from);
562
563         for (;;) {
564                 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
565                            "attach", priv->wpa_s->ifname);
566                 eloop_wait_for_read_sock(priv->sock);
567
568                 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
569                                (struct sockaddr *) &from, &fromlen);
570                 if (res < 0) {
571                         perror("recvfrom(ctrl_iface)");
572                         continue;
573                 }
574                 buf[res] = '\0';
575
576                 if (os_strcmp(buf, "ATTACH") == 0) {
577                         /* handle ATTACH signal of first monitor interface */
578                         if (!wpa_supplicant_ctrl_iface_attach(priv, &from,
579                                                               fromlen)) {
580                                 sendto(priv->sock, "OK\n", 3, 0,
581                                        (struct sockaddr *) &from, fromlen);
582                                 /* OK to continue */
583                                 return;
584                         } else {
585                                 sendto(priv->sock, "FAIL\n", 5, 0,
586                                        (struct sockaddr *) &from, fromlen);
587                         }
588                 } else {
589                         /* return FAIL for all other signals */
590                         sendto(priv->sock, "FAIL\n", 5, 0,
591                                (struct sockaddr *) &from, fromlen);
592                 }
593         }
594 }
595
596
597 /* Global ctrl_iface */
598
599 struct ctrl_iface_global_priv {
600         struct wpa_global *global;
601         int sock;
602 };
603
604
605 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
606                                                      void *sock_ctx)
607 {
608         struct wpa_global *global = eloop_ctx;
609         char buf[256];
610         int res;
611         struct sockaddr_un from;
612         socklen_t fromlen = sizeof(from);
613         char *reply;
614         size_t reply_len;
615
616         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
617                        (struct sockaddr *) &from, &fromlen);
618         if (res < 0) {
619                 perror("recvfrom(ctrl_iface)");
620                 return;
621         }
622         buf[res] = '\0';
623
624         reply = wpa_supplicant_global_ctrl_iface_process(global, buf,
625                                                          &reply_len);
626
627         if (reply) {
628                 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
629                        fromlen);
630                 os_free(reply);
631         } else if (reply_len) {
632                 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
633                        fromlen);
634         }
635 }
636
637
638 struct ctrl_iface_global_priv *
639 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
640 {
641         struct ctrl_iface_global_priv *priv;
642         struct sockaddr_un addr;
643
644         priv = os_zalloc(sizeof(*priv));
645         if (priv == NULL)
646                 return NULL;
647         priv->global = global;
648         priv->sock = -1;
649
650         if (global->params.ctrl_interface == NULL)
651                 return priv;
652
653 #ifdef ANDROID
654         priv->sock = android_get_control_socket(global->params.ctrl_interface);
655         if (priv->sock >= 0)
656                 goto havesock;
657 #endif
658
659         wpa_printf(MSG_DEBUG, "Global control interface '%s'",
660                    global->params.ctrl_interface);
661
662         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
663         if (priv->sock < 0) {
664                 perror("socket(PF_UNIX)");
665                 goto fail;
666         }
667
668         os_memset(&addr, 0, sizeof(addr));
669 #ifdef __FreeBSD__
670         addr.sun_len = sizeof(addr);
671 #endif /* __FreeBSD__ */
672         addr.sun_family = AF_UNIX;
673         os_strlcpy(addr.sun_path, global->params.ctrl_interface,
674                    sizeof(addr.sun_path));
675         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
676                 perror("bind(PF_UNIX)");
677                 if (connect(priv->sock, (struct sockaddr *) &addr,
678                             sizeof(addr)) < 0) {
679                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
680                                    " allow connections - assuming it was left"
681                                    "over from forced program termination");
682                         if (unlink(global->params.ctrl_interface) < 0) {
683                                 perror("unlink[ctrl_iface]");
684                                 wpa_printf(MSG_ERROR, "Could not unlink "
685                                            "existing ctrl_iface socket '%s'",
686                                            global->params.ctrl_interface);
687                                 goto fail;
688                         }
689                         if (bind(priv->sock, (struct sockaddr *) &addr,
690                                  sizeof(addr)) < 0) {
691                                 perror("bind(PF_UNIX)");
692                                 goto fail;
693                         }
694                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
695                                    "ctrl_iface socket '%s'",
696                                    global->params.ctrl_interface);
697                 } else {
698                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
699                                    "be in use - cannot override it");
700                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
701                                    "not used anymore",
702                                    global->params.ctrl_interface);
703                         goto fail;
704                 }
705         }
706
707 havesock:
708         eloop_register_read_sock(priv->sock,
709                                  wpa_supplicant_global_ctrl_iface_receive,
710                                  global, NULL);
711
712         return priv;
713
714 fail:
715         if (priv->sock >= 0)
716                 close(priv->sock);
717         os_free(priv);
718         return NULL;
719 }
720
721
722 void
723 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
724 {
725         if (priv->sock >= 0) {
726                 eloop_unregister_read_sock(priv->sock);
727                 close(priv->sock);
728         }
729         if (priv->global->params.ctrl_interface)
730                 unlink(priv->global->params.ctrl_interface);
731         os_free(priv);
732 }