LCOV - code coverage report
Current view: top level - wpa_supplicant - ctrl_iface_unix.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 297 492 60.4 %
Date: 2014-05-28 Functions: 14 17 82.4 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant / UNIX domain socket -based control interface
       3             :  * Copyright (c) 2004-2014, 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             :  */
      37             : struct wpa_ctrl_dst {
      38             :         struct dl_list list;
      39             :         struct sockaddr_un addr;
      40             :         socklen_t addrlen;
      41             :         int debug_level;
      42             :         int errors;
      43             : };
      44             : 
      45             : 
      46             : struct ctrl_iface_priv {
      47             :         struct wpa_supplicant *wpa_s;
      48             :         int sock;
      49             :         struct dl_list ctrl_dst;
      50             : };
      51             : 
      52             : 
      53             : struct ctrl_iface_global_priv {
      54             :         struct wpa_global *global;
      55             :         int sock;
      56             :         struct dl_list ctrl_dst;
      57             : };
      58             : 
      59             : 
      60             : static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
      61             :                                            const char *ifname, int sock,
      62             :                                            struct dl_list *ctrl_dst,
      63             :                                            int level, const char *buf,
      64             :                                            size_t len,
      65             :                                            struct ctrl_iface_priv *priv,
      66             :                                            struct ctrl_iface_global_priv *gp);
      67             : static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
      68             :                                   struct ctrl_iface_priv *priv);
      69             : static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
      70             :                                          struct ctrl_iface_global_priv *priv);
      71             : 
      72             : 
      73         753 : static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst,
      74             :                                             struct sockaddr_un *from,
      75             :                                             socklen_t fromlen)
      76             : {
      77             :         struct wpa_ctrl_dst *dst;
      78             :         char addr_txt[200];
      79             : 
      80         753 :         dst = os_zalloc(sizeof(*dst));
      81         753 :         if (dst == NULL)
      82           0 :                 return -1;
      83         753 :         os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
      84         753 :         dst->addrlen = fromlen;
      85         753 :         dst->debug_level = MSG_INFO;
      86         753 :         dl_list_add(ctrl_dst, &dst->list);
      87        1506 :         printf_encode(addr_txt, sizeof(addr_txt),
      88         753 :                       (u8 *) from->sun_path,
      89             :                       fromlen - offsetof(struct sockaddr_un, sun_path));
      90         753 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s", addr_txt);
      91         753 :         return 0;
      92             : }
      93             : 
      94             : 
      95         753 : static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst,
      96             :                                             struct sockaddr_un *from,
      97             :                                             socklen_t fromlen)
      98             : {
      99             :         struct wpa_ctrl_dst *dst;
     100             : 
     101         780 :         dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
     102        1559 :                 if (fromlen == dst->addrlen &&
     103         779 :                     os_memcmp(from->sun_path, dst->addr.sun_path,
     104             :                               fromlen - offsetof(struct sockaddr_un, sun_path))
     105             :                     == 0) {
     106             :                         char addr_txt[200];
     107        1506 :                         printf_encode(addr_txt, sizeof(addr_txt),
     108         753 :                                       (u8 *) from->sun_path,
     109             :                                       fromlen -
     110             :                                       offsetof(struct sockaddr_un, sun_path));
     111         753 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached %s",
     112             :                                    addr_txt);
     113         753 :                         dl_list_del(&dst->list);
     114         753 :                         os_free(dst);
     115         753 :                         return 0;
     116             :                 }
     117             :         }
     118           0 :         return -1;
     119             : }
     120             : 
     121             : 
     122           3 : static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
     123             :                                            struct sockaddr_un *from,
     124             :                                            socklen_t fromlen,
     125             :                                            char *level)
     126             : {
     127             :         struct wpa_ctrl_dst *dst;
     128             : 
     129           3 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
     130             : 
     131           4 :         dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
     132           6 :                 if (fromlen == dst->addrlen &&
     133           3 :                     os_memcmp(from->sun_path, dst->addr.sun_path,
     134             :                               fromlen - offsetof(struct sockaddr_un, sun_path))
     135             :                     == 0) {
     136             :                         char addr_txt[200];
     137           2 :                         dst->debug_level = atoi(level);
     138           4 :                         printf_encode(addr_txt, sizeof(addr_txt),
     139           2 :                                       (u8 *) from->sun_path, fromlen -
     140             :                                       offsetof(struct sockaddr_un, sun_path));
     141           2 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor level to %d for %s",
     142             :                                    dst->debug_level, addr_txt);
     143           2 :                         return 0;
     144             :                 }
     145             :         }
     146             : 
     147           1 :         return -1;
     148             : }
     149             : 
     150             : 
     151       41104 : static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
     152             :                                               void *sock_ctx)
     153             : {
     154       41104 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     155       41104 :         struct ctrl_iface_priv *priv = sock_ctx;
     156             :         char buf[4096];
     157             :         int res;
     158             :         struct sockaddr_un from;
     159       41104 :         socklen_t fromlen = sizeof(from);
     160       41104 :         char *reply = NULL, *reply_buf = NULL;
     161       41104 :         size_t reply_len = 0;
     162       41104 :         int new_attached = 0;
     163             : 
     164       41104 :         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
     165             :                        (struct sockaddr *) &from, &fromlen);
     166       41104 :         if (res < 0) {
     167           0 :                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     168           0 :                            strerror(errno));
     169       41104 :                 return;
     170             :         }
     171       41104 :         buf[res] = '\0';
     172             : 
     173       41104 :         if (os_strcmp(buf, "ATTACH") == 0) {
     174          63 :                 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
     175             :                                                      fromlen))
     176           0 :                         reply_len = 1;
     177             :                 else {
     178          63 :                         new_attached = 1;
     179          63 :                         reply_len = 2;
     180             :                 }
     181       41041 :         } else if (os_strcmp(buf, "DETACH") == 0) {
     182          62 :                 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
     183             :                                                      fromlen))
     184           0 :                         reply_len = 1;
     185             :                 else
     186          62 :                         reply_len = 2;
     187       40979 :         } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
     188           3 :                 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
     189             :                                                     buf + 6))
     190           1 :                         reply_len = 1;
     191             :                 else
     192           2 :                         reply_len = 2;
     193             :         } else {
     194       40976 :                 reply_buf = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
     195             :                                                               &reply_len);
     196       40976 :                 reply = reply_buf;
     197             :         }
     198             : 
     199       41104 :         if (!reply && reply_len == 1) {
     200           1 :                 reply = "FAIL\n";
     201           1 :                 reply_len = 5;
     202       41103 :         } else if (!reply && reply_len == 2) {
     203         127 :                 reply = "OK\n";
     204         127 :                 reply_len = 3;
     205             :         }
     206             : 
     207       41104 :         if (reply) {
     208       41104 :                 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
     209             :                            fromlen) < 0) {
     210           4 :                         int _errno = errno;
     211           4 :                         wpa_dbg(wpa_s, MSG_DEBUG,
     212             :                                 "ctrl_iface sendto failed: %d - %s",
     213             :                                 _errno, strerror(_errno));
     214           4 :                         if (_errno == ENOBUFS || _errno == EAGAIN) {
     215             :                                 /*
     216             :                                  * The socket send buffer could be full. This
     217             :                                  * may happen if client programs are not
     218             :                                  * receiving their pending messages. Close and
     219             :                                  * reopen the socket as a workaround to avoid
     220             :                                  * getting stuck being unable to send any new
     221             :                                  * responses.
     222             :                                  */
     223           0 :                                 sock = wpas_ctrl_iface_reinit(wpa_s, priv);
     224           0 :                                 if (sock < 0) {
     225           0 :                                         wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket");
     226             :                                 }
     227             :                         }
     228           4 :                         if (new_attached) {
     229           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to send response to ATTACH - detaching");
     230           0 :                                 new_attached = 0;
     231           0 :                                 wpa_supplicant_ctrl_iface_detach(
     232             :                                         &priv->ctrl_dst, &from, fromlen);
     233             :                         }
     234             :                 }
     235             :         }
     236       41104 :         os_free(reply_buf);
     237             : 
     238       41104 :         if (new_attached)
     239          63 :                 eapol_sm_notify_ctrl_attached(wpa_s->eapol);
     240             : }
     241             : 
     242             : 
     243         138 : static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s)
     244             : {
     245             :         char *buf;
     246             :         size_t len;
     247         138 :         char *pbuf, *dir = NULL;
     248             :         int res;
     249             : 
     250         138 :         if (wpa_s->conf->ctrl_interface == NULL)
     251           0 :                 return NULL;
     252             : 
     253         138 :         pbuf = os_strdup(wpa_s->conf->ctrl_interface);
     254         138 :         if (pbuf == NULL)
     255           0 :                 return NULL;
     256         138 :         if (os_strncmp(pbuf, "DIR=", 4) == 0) {
     257             :                 char *gid_str;
     258         138 :                 dir = pbuf + 4;
     259         138 :                 gid_str = os_strstr(dir, " GROUP=");
     260         138 :                 if (gid_str)
     261         138 :                         *gid_str = '\0';
     262             :         } else
     263           0 :                 dir = pbuf;
     264             : 
     265         138 :         len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2;
     266         138 :         buf = os_malloc(len);
     267         138 :         if (buf == NULL) {
     268           0 :                 os_free(pbuf);
     269           0 :                 return NULL;
     270             :         }
     271             : 
     272         138 :         res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname);
     273         138 :         if (res < 0 || (size_t) res >= len) {
     274           0 :                 os_free(pbuf);
     275           0 :                 os_free(buf);
     276           0 :                 return NULL;
     277             :         }
     278             : #ifdef __CYGWIN__
     279             :         {
     280             :                 /* Windows/WinPcap uses interface names that are not suitable
     281             :                  * as a file name - convert invalid chars to underscores */
     282             :                 char *pos = buf;
     283             :                 while (*pos) {
     284             :                         if (*pos == '\\')
     285             :                                 *pos = '_';
     286             :                         pos++;
     287             :                 }
     288             :         }
     289             : #endif /* __CYGWIN__ */
     290         138 :         os_free(pbuf);
     291         138 :         return buf;
     292             : }
     293             : 
     294             : 
     295      252324 : static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, int global,
     296             :                                              const char *txt, size_t len)
     297             : {
     298      252324 :         struct wpa_supplicant *wpa_s = ctx;
     299             : 
     300      252324 :         if (wpa_s == NULL)
     301           1 :                 return;
     302             : 
     303      252323 :         if (global != 2 && wpa_s->global->ctrl_iface) {
     304      252297 :                 struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;
     305      252297 :                 if (!dl_list_empty(&priv->ctrl_dst)) {
     306      252240 :                         wpa_supplicant_ctrl_iface_send(wpa_s, global ? NULL :
     307             :                                                        wpa_s->ifname,
     308             :                                                        priv->sock,
     309             :                                                        &priv->ctrl_dst,
     310             :                                                        level, txt, len, NULL,
     311             :                                                        priv);
     312             :                 }
     313             :         }
     314             : 
     315      252323 :         if (wpa_s->ctrl_iface == NULL)
     316         297 :                 return;
     317      504052 :         wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock,
     318      252026 :                                        &wpa_s->ctrl_iface->ctrl_dst,
     319             :                                        level, txt, len, wpa_s->ctrl_iface,
     320             :                                        NULL);
     321             : }
     322             : 
     323             : 
     324          69 : static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s,
     325             :                                      struct ctrl_iface_priv *priv)
     326             : {
     327             :         struct sockaddr_un addr;
     328          69 :         char *fname = NULL;
     329          69 :         gid_t gid = 0;
     330          69 :         int gid_set = 0;
     331          69 :         char *buf, *dir = NULL, *gid_str = NULL;
     332             :         struct group *grp;
     333             :         char *endp;
     334             :         int flags;
     335             : 
     336          69 :         buf = os_strdup(wpa_s->conf->ctrl_interface);
     337          69 :         if (buf == NULL)
     338           0 :                 goto fail;
     339             : #ifdef ANDROID
     340             :         os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
     341             :                     wpa_s->conf->ctrl_interface);
     342             :         priv->sock = android_get_control_socket(addr.sun_path);
     343             :         if (priv->sock >= 0)
     344             :                 goto havesock;
     345             : #endif /* ANDROID */
     346          69 :         if (os_strncmp(buf, "DIR=", 4) == 0) {
     347          69 :                 dir = buf + 4;
     348          69 :                 gid_str = os_strstr(dir, " GROUP=");
     349          69 :                 if (gid_str) {
     350          69 :                         *gid_str = '\0';
     351          69 :                         gid_str += 7;
     352             :                 }
     353             :         } else {
     354           0 :                 dir = buf;
     355           0 :                 gid_str = wpa_s->conf->ctrl_interface_group;
     356             :         }
     357             : 
     358          69 :         if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
     359          68 :                 if (errno == EEXIST) {
     360          68 :                         wpa_printf(MSG_DEBUG, "Using existing control "
     361             :                                    "interface directory.");
     362             :                 } else {
     363           0 :                         wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s",
     364           0 :                                    dir, strerror(errno));
     365           0 :                         goto fail;
     366             :                 }
     367             :         }
     368             : 
     369             : #ifdef ANDROID
     370             :         /*
     371             :          * wpa_supplicant is started from /init.*.rc on Android and that seems
     372             :          * to be using umask 0077 which would leave the control interface
     373             :          * directory without group access. This breaks things since Wi-Fi
     374             :          * framework assumes that this directory can be accessed by other
     375             :          * applications in the wifi group. Fix this by adding group access even
     376             :          * if umask value would prevent this.
     377             :          */
     378             :         if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
     379             :                 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
     380             :                            strerror(errno));
     381             :                 /* Try to continue anyway */
     382             :         }
     383             : #endif /* ANDROID */
     384             : 
     385          69 :         if (gid_str) {
     386          69 :                 grp = getgrnam(gid_str);
     387          69 :                 if (grp) {
     388          69 :                         gid = grp->gr_gid;
     389          69 :                         gid_set = 1;
     390          69 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
     391             :                                    " (from group name '%s')",
     392             :                                    (int) gid, gid_str);
     393             :                 } else {
     394             :                         /* Group name not found - try to parse this as gid */
     395           0 :                         gid = strtol(gid_str, &endp, 10);
     396           0 :                         if (*gid_str == '\0' || *endp != '\0') {
     397           0 :                                 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
     398             :                                            "'%s'", gid_str);
     399           0 :                                 goto fail;
     400             :                         }
     401           0 :                         gid_set = 1;
     402           0 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
     403             :                                    (int) gid);
     404             :                 }
     405             :         }
     406             : 
     407          69 :         if (gid_set && chown(dir, -1, gid) < 0) {
     408           0 :                 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s",
     409           0 :                            dir, (int) gid, strerror(errno));
     410           0 :                 goto fail;
     411             :         }
     412             : 
     413             :         /* Make sure the group can enter and read the directory */
     414         138 :         if (gid_set &&
     415          69 :             chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
     416           0 :                 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
     417           0 :                            strerror(errno));
     418           0 :                 goto fail;
     419             :         }
     420             : 
     421          69 :         if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
     422             :             sizeof(addr.sun_path)) {
     423           0 :                 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
     424           0 :                 goto fail;
     425             :         }
     426             : 
     427          69 :         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
     428          69 :         if (priv->sock < 0) {
     429           0 :                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
     430           0 :                 goto fail;
     431             :         }
     432             : 
     433          69 :         os_memset(&addr, 0, sizeof(addr));
     434             : #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     435             :         addr.sun_len = sizeof(addr);
     436             : #endif /* __FreeBSD__ */
     437          69 :         addr.sun_family = AF_UNIX;
     438          69 :         fname = wpa_supplicant_ctrl_iface_path(wpa_s);
     439          69 :         if (fname == NULL)
     440           0 :                 goto fail;
     441          69 :         os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
     442          69 :         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
     443           0 :                 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
     444           0 :                            strerror(errno));
     445           0 :                 if (connect(priv->sock, (struct sockaddr *) &addr,
     446             :                             sizeof(addr)) < 0) {
     447           0 :                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
     448             :                                    " allow connections - assuming it was left"
     449             :                                    "over from forced program termination");
     450           0 :                         if (unlink(fname) < 0) {
     451           0 :                                 wpa_printf(MSG_ERROR,
     452             :                                            "Could not unlink existing ctrl_iface socket '%s': %s",
     453           0 :                                            fname, strerror(errno));
     454           0 :                                 goto fail;
     455             :                         }
     456           0 :                         if (bind(priv->sock, (struct sockaddr *) &addr,
     457             :                                  sizeof(addr)) < 0) {
     458           0 :                                 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s",
     459           0 :                                            strerror(errno));
     460           0 :                                 goto fail;
     461             :                         }
     462           0 :                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
     463             :                                    "ctrl_iface socket '%s'", fname);
     464             :                 } else {
     465           0 :                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
     466             :                                    "be in use - cannot override it");
     467           0 :                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
     468             :                                    "not used anymore", fname);
     469           0 :                         os_free(fname);
     470           0 :                         fname = NULL;
     471           0 :                         goto fail;
     472             :                 }
     473             :         }
     474             : 
     475          69 :         if (gid_set && chown(fname, -1, gid) < 0) {
     476           0 :                 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s",
     477           0 :                            fname, (int) gid, strerror(errno));
     478           0 :                 goto fail;
     479             :         }
     480             : 
     481          69 :         if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
     482           0 :                 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s",
     483           0 :                            fname, strerror(errno));
     484           0 :                 goto fail;
     485             :         }
     486          69 :         os_free(fname);
     487             : 
     488             : #ifdef ANDROID
     489             : havesock:
     490             : #endif /* ANDROID */
     491             : 
     492             :         /*
     493             :          * Make socket non-blocking so that we don't hang forever if
     494             :          * target dies unexpectedly.
     495             :          */
     496          69 :         flags = fcntl(priv->sock, F_GETFL);
     497          69 :         if (flags >= 0) {
     498          69 :                 flags |= O_NONBLOCK;
     499          69 :                 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
     500           0 :                         wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
     501           0 :                                    strerror(errno));
     502             :                         /* Not fatal, continue on.*/
     503             :                 }
     504             :         }
     505             : 
     506          69 :         eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
     507             :                                  wpa_s, priv);
     508          69 :         wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
     509             : 
     510          69 :         os_free(buf);
     511          69 :         return 0;
     512             : 
     513             : fail:
     514           0 :         if (priv->sock >= 0) {
     515           0 :                 close(priv->sock);
     516           0 :                 priv->sock = -1;
     517             :         }
     518           0 :         if (fname) {
     519           0 :                 unlink(fname);
     520           0 :                 os_free(fname);
     521             :         }
     522           0 :         os_free(buf);
     523           0 :         return -1;
     524             : }
     525             : 
     526             : 
     527             : struct ctrl_iface_priv *
     528          69 : wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
     529             : {
     530             :         struct ctrl_iface_priv *priv;
     531             : 
     532          69 :         priv = os_zalloc(sizeof(*priv));
     533          69 :         if (priv == NULL)
     534           0 :                 return NULL;
     535          69 :         dl_list_init(&priv->ctrl_dst);
     536          69 :         priv->wpa_s = wpa_s;
     537          69 :         priv->sock = -1;
     538             : 
     539          69 :         if (wpa_s->conf->ctrl_interface == NULL)
     540           0 :                 return priv;
     541             : 
     542          69 :         if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) {
     543           0 :                 os_free(priv);
     544           0 :                 return NULL;
     545             :         }
     546             : 
     547          69 :         return priv;
     548             : }
     549             : 
     550             : 
     551           0 : static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
     552             :                                   struct ctrl_iface_priv *priv)
     553             : {
     554             :         int res;
     555             : 
     556           0 :         if (priv->sock <= 0)
     557           0 :                 return -1;
     558             : 
     559           0 :         eloop_unregister_read_sock(priv->sock);
     560           0 :         close(priv->sock);
     561           0 :         priv->sock = -1;
     562           0 :         res = wpas_ctrl_iface_open_sock(wpa_s, priv);
     563           0 :         if (res < 0)
     564           0 :                 return -1;
     565           0 :         return priv->sock;
     566             : }
     567             : 
     568             : 
     569          69 : void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
     570             : {
     571             :         struct wpa_ctrl_dst *dst, *prev;
     572             : 
     573          69 :         if (priv->sock > -1) {
     574             :                 char *fname;
     575          69 :                 char *buf, *dir = NULL;
     576          69 :                 eloop_unregister_read_sock(priv->sock);
     577          69 :                 if (!dl_list_empty(&priv->ctrl_dst)) {
     578             :                         /*
     579             :                          * Wait before closing the control socket if
     580             :                          * there are any attached monitors in order to allow
     581             :                          * them to receive any pending messages.
     582             :                          */
     583           0 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
     584             :                                    "monitors to receive messages");
     585           0 :                         os_sleep(0, 100000);
     586             :                 }
     587          69 :                 close(priv->sock);
     588          69 :                 priv->sock = -1;
     589          69 :                 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
     590          69 :                 if (fname) {
     591          69 :                         unlink(fname);
     592          69 :                         os_free(fname);
     593             :                 }
     594             : 
     595          69 :                 if (priv->wpa_s->conf->ctrl_interface == NULL)
     596           0 :                         goto free_dst;
     597          69 :                 buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
     598          69 :                 if (buf == NULL)
     599           0 :                         goto free_dst;
     600          69 :                 if (os_strncmp(buf, "DIR=", 4) == 0) {
     601             :                         char *gid_str;
     602          69 :                         dir = buf + 4;
     603          69 :                         gid_str = os_strstr(dir, " GROUP=");
     604          69 :                         if (gid_str)
     605          69 :                                 *gid_str = '\0';
     606             :                 } else
     607           0 :                         dir = buf;
     608             : 
     609          69 :                 if (rmdir(dir) < 0) {
     610          68 :                         if (errno == ENOTEMPTY) {
     611          67 :                                 wpa_printf(MSG_DEBUG, "Control interface "
     612             :                                            "directory not empty - leaving it "
     613             :                                            "behind");
     614             :                         } else {
     615           1 :                                 wpa_printf(MSG_ERROR,
     616             :                                            "rmdir[ctrl_interface=%s]: %s",
     617           1 :                                            dir, strerror(errno));
     618             :                         }
     619             :                 }
     620          69 :                 os_free(buf);
     621             :         }
     622             : 
     623             : free_dst:
     624          69 :         dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
     625             :                               list)
     626           0 :                 os_free(dst);
     627          69 :         os_free(priv);
     628          69 : }
     629             : 
     630             : 
     631             : /**
     632             :  * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
     633             :  * @ifname: Interface name for global control socket or %NULL
     634             :  * @sock: Local socket fd
     635             :  * @ctrl_dst: List of attached listeners
     636             :  * @level: Priority level of the message
     637             :  * @buf: Message data
     638             :  * @len: Message length
     639             :  *
     640             :  * Send a packet to all monitor programs attached to the control interface.
     641             :  */
     642      504266 : static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
     643             :                                            const char *ifname, int sock,
     644             :                                            struct dl_list *ctrl_dst,
     645             :                                            int level, const char *buf,
     646             :                                            size_t len,
     647             :                                            struct ctrl_iface_priv *priv,
     648             :                                            struct ctrl_iface_global_priv *gp)
     649             : {
     650             :         struct wpa_ctrl_dst *dst, *next;
     651             :         char levelstr[10];
     652             :         int idx, res;
     653             :         struct msghdr msg;
     654             :         struct iovec io[5];
     655             : 
     656      504266 :         if (sock < 0 || dl_list_empty(ctrl_dst))
     657       10546 :                 return;
     658             : 
     659      498993 :         res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
     660      498993 :         if (res < 0 || (size_t) res >= sizeof(levelstr))
     661           0 :                 return;
     662      498993 :         idx = 0;
     663      498993 :         if (ifname) {
     664      200816 :                 io[idx].iov_base = "IFNAME=";
     665      200816 :                 io[idx].iov_len = 7;
     666      200816 :                 idx++;
     667      200816 :                 io[idx].iov_base = (char *) ifname;
     668      200816 :                 io[idx].iov_len = os_strlen(ifname);
     669      200816 :                 idx++;
     670      200816 :                 io[idx].iov_base = " ";
     671      200816 :                 io[idx].iov_len = 1;
     672      200816 :                 idx++;
     673             :         }
     674      498993 :         io[idx].iov_base = levelstr;
     675      498993 :         io[idx].iov_len = os_strlen(levelstr);
     676      498993 :         idx++;
     677      498993 :         io[idx].iov_base = (char *) buf;
     678      498993 :         io[idx].iov_len = len;
     679      498993 :         idx++;
     680      498993 :         os_memset(&msg, 0, sizeof(msg));
     681      498993 :         msg.msg_iov = io;
     682      498993 :         msg.msg_iovlen = idx;
     683             : 
     684     1002525 :         dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
     685             :                 int _errno;
     686             :                 char addr_txt[200];
     687             : 
     688      503532 :                 if (level < dst->debug_level)
     689      957523 :                         continue;
     690             : 
     691       99080 :                 printf_encode(addr_txt, sizeof(addr_txt),
     692       99080 :                               (u8 *) dst->addr.sun_path, dst->addrlen -
     693             :                               offsetof(struct sockaddr_un, sun_path));
     694       49540 :                 msg.msg_name = (void *) &dst->addr;
     695       49540 :                 msg.msg_namelen = dst->addrlen;
     696       49540 :                 if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) {
     697       49539 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor sent successfully to %s",
     698             :                                    addr_txt);
     699       49539 :                         dst->errors = 0;
     700       49539 :                         continue;
     701             :                 }
     702             : 
     703           1 :                 _errno = errno;
     704           2 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor[%s]: %d - %s",
     705           2 :                            addr_txt, errno, strerror(errno));
     706           1 :                 dst->errors++;
     707             : 
     708           1 :                 if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) {
     709           1 :                         wpa_printf(MSG_INFO, "CTRL_IFACE: Detach monitor %s that cannot receive messages",
     710             :                                 addr_txt);
     711           1 :                         wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr,
     712             :                                                          dst->addrlen);
     713             :                 }
     714             : 
     715           1 :                 if (_errno == ENOBUFS || _errno == EAGAIN) {
     716             :                         /*
     717             :                          * The socket send buffer could be full. This may happen
     718             :                          * if client programs are not receiving their pending
     719             :                          * messages. Close and reopen the socket as a workaround
     720             :                          * to avoid getting stuck being unable to send any new
     721             :                          * responses.
     722             :                          */
     723           0 :                         if (priv)
     724           0 :                                 sock = wpas_ctrl_iface_reinit(wpa_s, priv);
     725           0 :                         else if (gp)
     726           0 :                                 sock = wpas_ctrl_iface_global_reinit(
     727             :                                         wpa_s->global, gp);
     728             :                         else
     729           0 :                                 break;
     730           0 :                         if (sock < 0) {
     731           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
     732             :                                         "Failed to reinitialize ctrl_iface socket");
     733           0 :                                 break;
     734             :                         }
     735             :                 }
     736             :         }
     737             : }
     738             : 
     739             : 
     740           0 : void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
     741             : {
     742             :         char buf[256];
     743             :         int res;
     744             :         struct sockaddr_un from;
     745           0 :         socklen_t fromlen = sizeof(from);
     746             : 
     747             :         for (;;) {
     748           0 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
     749           0 :                            "attach", priv->wpa_s->ifname);
     750           0 :                 eloop_wait_for_read_sock(priv->sock);
     751             : 
     752           0 :                 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
     753             :                                (struct sockaddr *) &from, &fromlen);
     754           0 :                 if (res < 0) {
     755           0 :                         wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     756           0 :                                    strerror(errno));
     757           0 :                         continue;
     758             :                 }
     759           0 :                 buf[res] = '\0';
     760             : 
     761           0 :                 if (os_strcmp(buf, "ATTACH") == 0) {
     762             :                         /* handle ATTACH signal of first monitor interface */
     763           0 :                         if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
     764             :                                                               &from, fromlen)) {
     765           0 :                                 if (sendto(priv->sock, "OK\n", 3, 0,
     766             :                                            (struct sockaddr *) &from, fromlen) <
     767             :                                     0) {
     768           0 :                                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     769           0 :                                                    strerror(errno));
     770             :                                 }
     771             :                                 /* OK to continue */
     772           0 :                                 return;
     773             :                         } else {
     774           0 :                                 if (sendto(priv->sock, "FAIL\n", 5, 0,
     775             :                                            (struct sockaddr *) &from, fromlen) <
     776             :                                     0) {
     777           0 :                                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     778           0 :                                                    strerror(errno));
     779             :                                 }
     780             :                         }
     781             :                 } else {
     782             :                         /* return FAIL for all other signals */
     783           0 :                         if (sendto(priv->sock, "FAIL\n", 5, 0,
     784             :                                    (struct sockaddr *) &from, fromlen) < 0) {
     785           0 :                                 wpa_printf(MSG_DEBUG,
     786             :                                            "ctrl_iface sendto failed: %s",
     787           0 :                                            strerror(errno));
     788             :                         }
     789             :                 }
     790           0 :         }
     791             : }
     792             : 
     793             : 
     794             : /* Global ctrl_iface */
     795             : 
     796        5281 : static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
     797             :                                                      void *sock_ctx)
     798             : {
     799        5281 :         struct wpa_global *global = eloop_ctx;
     800        5281 :         struct ctrl_iface_global_priv *priv = sock_ctx;
     801             :         char buf[4096];
     802             :         int res;
     803             :         struct sockaddr_un from;
     804        5281 :         socklen_t fromlen = sizeof(from);
     805        5281 :         char *reply = NULL, *reply_buf = NULL;
     806             :         size_t reply_len;
     807             : 
     808        5281 :         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
     809             :                        (struct sockaddr *) &from, &fromlen);
     810        5281 :         if (res < 0) {
     811           0 :                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     812           0 :                            strerror(errno));
     813        5281 :                 return;
     814             :         }
     815        5281 :         buf[res] = '\0';
     816             : 
     817        5281 :         if (os_strcmp(buf, "ATTACH") == 0) {
     818         690 :                 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
     819             :                                                      fromlen))
     820           0 :                         reply_len = 1;
     821             :                 else
     822         690 :                         reply_len = 2;
     823        4591 :         } else if (os_strcmp(buf, "DETACH") == 0) {
     824         690 :                 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
     825             :                                                      fromlen))
     826           0 :                         reply_len = 1;
     827             :                 else
     828         690 :                         reply_len = 2;
     829             :         } else {
     830        3901 :                 reply_buf = wpa_supplicant_global_ctrl_iface_process(
     831             :                         global, buf, &reply_len);
     832        3901 :                 reply = reply_buf;
     833             :         }
     834             : 
     835        5281 :         if (!reply && reply_len == 1) {
     836           0 :                 reply = "FAIL\n";
     837           0 :                 reply_len = 5;
     838        5281 :         } else if (!reply && reply_len == 2) {
     839        1380 :                 reply = "OK\n";
     840        1380 :                 reply_len = 3;
     841             :         }
     842             : 
     843        5281 :         if (reply) {
     844        5281 :                 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
     845             :                            fromlen) < 0) {
     846           1 :                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     847           1 :                                 strerror(errno));
     848             :                 }
     849             :         }
     850        5281 :         os_free(reply_buf);
     851             : }
     852             : 
     853             : 
     854           4 : static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global,
     855             :                                             struct ctrl_iface_global_priv *priv)
     856             : {
     857             :         struct sockaddr_un addr;
     858           4 :         const char *ctrl = global->params.ctrl_interface;
     859             :         int flags;
     860             : 
     861           4 :         wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl);
     862             : 
     863             : #ifdef ANDROID
     864             :         if (os_strncmp(ctrl, "@android:", 9) == 0) {
     865             :                 priv->sock = android_get_control_socket(ctrl + 9);
     866             :                 if (priv->sock < 0) {
     867             :                         wpa_printf(MSG_ERROR, "Failed to open Android control "
     868             :                                    "socket '%s'", ctrl + 9);
     869             :                         goto fail;
     870             :                 }
     871             :                 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'",
     872             :                            ctrl + 9);
     873             :                 goto havesock;
     874             :         }
     875             : 
     876             :         if (os_strncmp(ctrl, "@abstract:", 10) != 0) {
     877             :                 /*
     878             :                  * Backwards compatibility - try to open an Android control
     879             :                  * socket and if that fails, assume this was a UNIX domain
     880             :                  * socket instead.
     881             :                  */
     882             :                 priv->sock = android_get_control_socket(ctrl);
     883             :                 if (priv->sock >= 0) {
     884             :                         wpa_printf(MSG_DEBUG,
     885             :                                    "Using Android control socket '%s'",
     886             :                                    ctrl);
     887             :                         goto havesock;
     888             :                 }
     889             :         }
     890             : #endif /* ANDROID */
     891             : 
     892           4 :         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
     893           4 :         if (priv->sock < 0) {
     894           0 :                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
     895           0 :                 goto fail;
     896             :         }
     897             : 
     898           4 :         os_memset(&addr, 0, sizeof(addr));
     899             : #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     900             :         addr.sun_len = sizeof(addr);
     901             : #endif /* __FreeBSD__ */
     902           4 :         addr.sun_family = AF_UNIX;
     903             : 
     904           4 :         if (os_strncmp(ctrl, "@abstract:", 10) == 0) {
     905           0 :                 addr.sun_path[0] = '\0';
     906           0 :                 os_strlcpy(addr.sun_path + 1, ctrl + 10,
     907             :                            sizeof(addr.sun_path) - 1);
     908           0 :                 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) <
     909             :                     0) {
     910           0 :                         wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: "
     911             :                                    "bind(PF_UNIX;%s) failed: %s",
     912           0 :                                    ctrl, strerror(errno));
     913           0 :                         goto fail;
     914             :                 }
     915           0 :                 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'",
     916             :                            ctrl + 10);
     917           0 :                 goto havesock;
     918             :         }
     919             : 
     920           4 :         os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
     921           4 :         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
     922           0 :                 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s",
     923           0 :                            ctrl, strerror(errno));
     924           0 :                 if (connect(priv->sock, (struct sockaddr *) &addr,
     925             :                             sizeof(addr)) < 0) {
     926           0 :                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
     927             :                                    " allow connections - assuming it was left"
     928             :                                    "over from forced program termination");
     929           0 :                         if (unlink(ctrl) < 0) {
     930           0 :                                 wpa_printf(MSG_ERROR,
     931             :                                            "Could not unlink existing ctrl_iface socket '%s': %s",
     932           0 :                                            ctrl, strerror(errno));
     933           0 :                                 goto fail;
     934             :                         }
     935           0 :                         if (bind(priv->sock, (struct sockaddr *) &addr,
     936             :                                  sizeof(addr)) < 0) {
     937           0 :                                 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s",
     938           0 :                                            ctrl, strerror(errno));
     939           0 :                                 goto fail;
     940             :                         }
     941           0 :                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
     942             :                                    "ctrl_iface socket '%s'",
     943             :                                    ctrl);
     944             :                 } else {
     945           0 :                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
     946             :                                    "be in use - cannot override it");
     947           0 :                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
     948             :                                    "not used anymore",
     949             :                                    ctrl);
     950           0 :                         goto fail;
     951             :                 }
     952             :         }
     953             : 
     954           4 :         wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl);
     955             : 
     956           4 :         if (global->params.ctrl_interface_group) {
     957           4 :                 char *gid_str = global->params.ctrl_interface_group;
     958           4 :                 gid_t gid = 0;
     959             :                 struct group *grp;
     960             :                 char *endp;
     961             : 
     962           4 :                 grp = getgrnam(gid_str);
     963           4 :                 if (grp) {
     964           4 :                         gid = grp->gr_gid;
     965           4 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
     966             :                                    " (from group name '%s')",
     967             :                                    (int) gid, gid_str);
     968             :                 } else {
     969             :                         /* Group name not found - try to parse this as gid */
     970           0 :                         gid = strtol(gid_str, &endp, 10);
     971           0 :                         if (*gid_str == '\0' || *endp != '\0') {
     972           0 :                                 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
     973             :                                            "'%s'", gid_str);
     974           0 :                                 goto fail;
     975             :                         }
     976           0 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
     977             :                                    (int) gid);
     978             :                 }
     979           4 :                 if (chown(ctrl, -1, gid) < 0) {
     980           0 :                         wpa_printf(MSG_ERROR,
     981             :                                    "chown[global_ctrl_interface=%s,gid=%d]: %s",
     982           0 :                                    ctrl, (int) gid, strerror(errno));
     983           0 :                         goto fail;
     984             :                 }
     985             : 
     986           4 :                 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) {
     987           0 :                         wpa_printf(MSG_ERROR,
     988             :                                    "chmod[global_ctrl_interface=%s]: %s",
     989           0 :                                    ctrl, strerror(errno));
     990           0 :                         goto fail;
     991             :                 }
     992             :         } else {
     993           0 :                 chmod(ctrl, S_IRWXU);
     994             :         }
     995             : 
     996             : havesock:
     997             : 
     998             :         /*
     999             :          * Make socket non-blocking so that we don't hang forever if
    1000             :          * target dies unexpectedly.
    1001             :          */
    1002           4 :         flags = fcntl(priv->sock, F_GETFL);
    1003           4 :         if (flags >= 0) {
    1004           4 :                 flags |= O_NONBLOCK;
    1005           4 :                 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
    1006           0 :                         wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
    1007           0 :                                    strerror(errno));
    1008             :                         /* Not fatal, continue on.*/
    1009             :                 }
    1010             :         }
    1011             : 
    1012           4 :         eloop_register_read_sock(priv->sock,
    1013             :                                  wpa_supplicant_global_ctrl_iface_receive,
    1014             :                                  global, priv);
    1015             : 
    1016           4 :         return 0;
    1017             : 
    1018             : fail:
    1019           0 :         if (priv->sock >= 0) {
    1020           0 :                 close(priv->sock);
    1021           0 :                 priv->sock = -1;
    1022             :         }
    1023           0 :         return -1;
    1024             : }
    1025             : 
    1026             : 
    1027             : struct ctrl_iface_global_priv *
    1028           4 : wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
    1029             : {
    1030             :         struct ctrl_iface_global_priv *priv;
    1031             : 
    1032           4 :         priv = os_zalloc(sizeof(*priv));
    1033           4 :         if (priv == NULL)
    1034           0 :                 return NULL;
    1035           4 :         dl_list_init(&priv->ctrl_dst);
    1036           4 :         priv->global = global;
    1037           4 :         priv->sock = -1;
    1038             : 
    1039           4 :         if (global->params.ctrl_interface == NULL)
    1040           0 :                 return priv;
    1041             : 
    1042           4 :         if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) {
    1043           0 :                 os_free(priv);
    1044           0 :                 return NULL;
    1045             :         }
    1046             : 
    1047           4 :         wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
    1048             : 
    1049           4 :         return priv;
    1050             : }
    1051             : 
    1052             : 
    1053           0 : static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
    1054             :                                          struct ctrl_iface_global_priv *priv)
    1055             : {
    1056             :         int res;
    1057             : 
    1058           0 :         if (priv->sock <= 0)
    1059           0 :                 return -1;
    1060             : 
    1061           0 :         eloop_unregister_read_sock(priv->sock);
    1062           0 :         close(priv->sock);
    1063           0 :         priv->sock = -1;
    1064           0 :         res = wpas_global_ctrl_iface_open_sock(global, priv);
    1065           0 :         if (res < 0)
    1066           0 :                 return -1;
    1067           0 :         return priv->sock;
    1068             : }
    1069             : 
    1070             : 
    1071             : void
    1072           4 : wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
    1073             : {
    1074             :         struct wpa_ctrl_dst *dst, *prev;
    1075             : 
    1076           4 :         if (priv->sock >= 0) {
    1077           4 :                 eloop_unregister_read_sock(priv->sock);
    1078           4 :                 close(priv->sock);
    1079             :         }
    1080           4 :         if (priv->global->params.ctrl_interface)
    1081           4 :                 unlink(priv->global->params.ctrl_interface);
    1082           4 :         dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
    1083             :                               list)
    1084           0 :                 os_free(dst);
    1085           4 :         os_free(priv);
    1086           4 : }

Generated by: LCOV version 1.10