$search
00001 /* 00002 * WPA Supplicant / UNIX domain socket -based control interface 00003 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 #include <sys/un.h> 00017 #include <sys/stat.h> 00018 #include <grp.h> 00019 #include <stddef.h> 00020 00021 #include "utils/common.h" 00022 #include "utils/eloop.h" 00023 #include "utils/list.h" 00024 #include "eapol_supp/eapol_supp_sm.h" 00025 #include "config.h" 00026 #include "wpa_supplicant_i.h" 00027 #include "ctrl_iface.h" 00028 00029 /* Per-interface ctrl_iface */ 00030 00038 struct wpa_ctrl_dst { 00039 struct dl_list list; 00040 struct sockaddr_un addr; 00041 socklen_t addrlen; 00042 int debug_level; 00043 int errors; 00044 }; 00045 00046 00047 struct ctrl_iface_priv { 00048 struct wpa_supplicant *wpa_s; 00049 int sock; 00050 struct dl_list ctrl_dst; 00051 }; 00052 00053 00054 static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 00055 int level, const char *buf, 00056 size_t len); 00057 00058 00059 static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv, 00060 struct sockaddr_un *from, 00061 socklen_t fromlen) 00062 { 00063 struct wpa_ctrl_dst *dst; 00064 00065 dst = os_zalloc(sizeof(*dst)); 00066 if (dst == NULL) 00067 return -1; 00068 os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un)); 00069 dst->addrlen = fromlen; 00070 dst->debug_level = MSG_INFO; 00071 dl_list_add(&priv->ctrl_dst, &dst->list); 00072 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached", 00073 (u8 *) from->sun_path, 00074 fromlen - offsetof(struct sockaddr_un, sun_path)); 00075 return 0; 00076 } 00077 00078 00079 static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv, 00080 struct sockaddr_un *from, 00081 socklen_t fromlen) 00082 { 00083 struct wpa_ctrl_dst *dst; 00084 00085 dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) { 00086 if (fromlen == dst->addrlen && 00087 os_memcmp(from->sun_path, dst->addr.sun_path, 00088 fromlen - offsetof(struct sockaddr_un, sun_path)) 00089 == 0) { 00090 dl_list_del(&dst->list); 00091 os_free(dst); 00092 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", 00093 (u8 *) from->sun_path, 00094 fromlen - 00095 offsetof(struct sockaddr_un, sun_path)); 00096 return 0; 00097 } 00098 } 00099 return -1; 00100 } 00101 00102 00103 static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, 00104 struct sockaddr_un *from, 00105 socklen_t fromlen, 00106 char *level) 00107 { 00108 struct wpa_ctrl_dst *dst; 00109 00110 wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 00111 00112 dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) { 00113 if (fromlen == dst->addrlen && 00114 os_memcmp(from->sun_path, dst->addr.sun_path, 00115 fromlen - offsetof(struct sockaddr_un, sun_path)) 00116 == 0) { 00117 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor " 00118 "level", (u8 *) from->sun_path, 00119 fromlen - 00120 offsetof(struct sockaddr_un, sun_path)); 00121 dst->debug_level = atoi(level); 00122 return 0; 00123 } 00124 } 00125 00126 return -1; 00127 } 00128 00129 00130 static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, 00131 void *sock_ctx) 00132 { 00133 struct wpa_supplicant *wpa_s = eloop_ctx; 00134 struct ctrl_iface_priv *priv = sock_ctx; 00135 char buf[256]; 00136 int res; 00137 struct sockaddr_un from; 00138 socklen_t fromlen = sizeof(from); 00139 char *reply = NULL; 00140 size_t reply_len = 0; 00141 int new_attached = 0; 00142 00143 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 00144 (struct sockaddr *) &from, &fromlen); 00145 if (res < 0) { 00146 perror("recvfrom(ctrl_iface)"); 00147 return; 00148 } 00149 buf[res] = '\0'; 00150 00151 if (os_strcmp(buf, "ATTACH") == 0) { 00152 if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen)) 00153 reply_len = 1; 00154 else { 00155 new_attached = 1; 00156 reply_len = 2; 00157 } 00158 } else if (os_strcmp(buf, "DETACH") == 0) { 00159 if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen)) 00160 reply_len = 1; 00161 else 00162 reply_len = 2; 00163 } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 00164 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen, 00165 buf + 6)) 00166 reply_len = 1; 00167 else 00168 reply_len = 2; 00169 } else { 00170 reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 00171 &reply_len); 00172 } 00173 00174 if (reply) { 00175 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 00176 fromlen); 00177 os_free(reply); 00178 } else if (reply_len == 1) { 00179 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 00180 fromlen); 00181 } else if (reply_len == 2) { 00182 sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, 00183 fromlen); 00184 } 00185 00186 if (new_attached) 00187 eapol_sm_notify_ctrl_attached(wpa_s->eapol); 00188 } 00189 00190 00191 static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s) 00192 { 00193 char *buf; 00194 size_t len; 00195 char *pbuf, *dir = NULL, *gid_str = NULL; 00196 int res; 00197 00198 if (wpa_s->conf->ctrl_interface == NULL) 00199 return NULL; 00200 00201 pbuf = os_strdup(wpa_s->conf->ctrl_interface); 00202 if (pbuf == NULL) 00203 return NULL; 00204 if (os_strncmp(pbuf, "DIR=", 4) == 0) { 00205 dir = pbuf + 4; 00206 gid_str = os_strstr(dir, " GROUP="); 00207 if (gid_str) { 00208 *gid_str = '\0'; 00209 gid_str += 7; 00210 } 00211 } else 00212 dir = pbuf; 00213 00214 len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2; 00215 buf = os_malloc(len); 00216 if (buf == NULL) { 00217 os_free(pbuf); 00218 return NULL; 00219 } 00220 00221 res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname); 00222 if (res < 0 || (size_t) res >= len) { 00223 os_free(pbuf); 00224 os_free(buf); 00225 return NULL; 00226 } 00227 #ifdef __CYGWIN__ 00228 { 00229 /* Windows/WinPcap uses interface names that are not suitable 00230 * as a file name - convert invalid chars to underscores */ 00231 char *pos = buf; 00232 while (*pos) { 00233 if (*pos == '\\') 00234 *pos = '_'; 00235 pos++; 00236 } 00237 } 00238 #endif /* __CYGWIN__ */ 00239 os_free(pbuf); 00240 return buf; 00241 } 00242 00243 00244 static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, 00245 const char *txt, size_t len) 00246 { 00247 struct wpa_supplicant *wpa_s = ctx; 00248 if (wpa_s == NULL || wpa_s->ctrl_iface == NULL) 00249 return; 00250 wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len); 00251 } 00252 00253 00254 struct ctrl_iface_priv * 00255 wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 00256 { 00257 struct ctrl_iface_priv *priv; 00258 struct sockaddr_un addr; 00259 char *fname = NULL; 00260 gid_t gid = 0; 00261 int gid_set = 0; 00262 char *buf, *dir = NULL, *gid_str = NULL; 00263 struct group *grp; 00264 char *endp; 00265 00266 priv = os_zalloc(sizeof(*priv)); 00267 if (priv == NULL) 00268 return NULL; 00269 dl_list_init(&priv->ctrl_dst); 00270 priv->wpa_s = wpa_s; 00271 priv->sock = -1; 00272 00273 if (wpa_s->conf->ctrl_interface == NULL) 00274 return priv; 00275 00276 buf = os_strdup(wpa_s->conf->ctrl_interface); 00277 if (buf == NULL) 00278 goto fail; 00279 if (os_strncmp(buf, "DIR=", 4) == 0) { 00280 dir = buf + 4; 00281 gid_str = os_strstr(dir, " GROUP="); 00282 if (gid_str) { 00283 *gid_str = '\0'; 00284 gid_str += 7; 00285 } 00286 } else { 00287 dir = buf; 00288 gid_str = wpa_s->conf->ctrl_interface_group; 00289 } 00290 00291 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { 00292 if (errno == EEXIST) { 00293 wpa_printf(MSG_DEBUG, "Using existing control " 00294 "interface directory."); 00295 } else { 00296 perror("mkdir[ctrl_interface]"); 00297 goto fail; 00298 } 00299 } 00300 00301 if (gid_str) { 00302 grp = getgrnam(gid_str); 00303 if (grp) { 00304 gid = grp->gr_gid; 00305 gid_set = 1; 00306 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 00307 " (from group name '%s')", 00308 (int) gid, gid_str); 00309 } else { 00310 /* Group name not found - try to parse this as gid */ 00311 gid = strtol(gid_str, &endp, 10); 00312 if (*gid_str == '\0' || *endp != '\0') { 00313 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 00314 "'%s'", gid_str); 00315 goto fail; 00316 } 00317 gid_set = 1; 00318 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 00319 (int) gid); 00320 } 00321 } 00322 00323 if (gid_set && chown(dir, -1, gid) < 0) { 00324 perror("chown[ctrl_interface]"); 00325 goto fail; 00326 } 00327 00328 /* Make sure the group can enter and read the directory */ 00329 if (gid_set && 00330 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) { 00331 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s", 00332 strerror(errno)); 00333 goto fail; 00334 } 00335 00336 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= 00337 sizeof(addr.sun_path)) { 00338 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded"); 00339 goto fail; 00340 } 00341 00342 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 00343 if (priv->sock < 0) { 00344 perror("socket(PF_UNIX)"); 00345 goto fail; 00346 } 00347 00348 os_memset(&addr, 0, sizeof(addr)); 00349 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 00350 addr.sun_len = sizeof(addr); 00351 #endif /* __FreeBSD__ */ 00352 addr.sun_family = AF_UNIX; 00353 fname = wpa_supplicant_ctrl_iface_path(wpa_s); 00354 if (fname == NULL) 00355 goto fail; 00356 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 00357 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 00358 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 00359 strerror(errno)); 00360 if (connect(priv->sock, (struct sockaddr *) &addr, 00361 sizeof(addr)) < 0) { 00362 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 00363 " allow connections - assuming it was left" 00364 "over from forced program termination"); 00365 if (unlink(fname) < 0) { 00366 perror("unlink[ctrl_iface]"); 00367 wpa_printf(MSG_ERROR, "Could not unlink " 00368 "existing ctrl_iface socket '%s'", 00369 fname); 00370 goto fail; 00371 } 00372 if (bind(priv->sock, (struct sockaddr *) &addr, 00373 sizeof(addr)) < 0) { 00374 perror("bind(PF_UNIX)"); 00375 goto fail; 00376 } 00377 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 00378 "ctrl_iface socket '%s'", fname); 00379 } else { 00380 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 00381 "be in use - cannot override it"); 00382 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 00383 "not used anymore", fname); 00384 os_free(fname); 00385 fname = NULL; 00386 goto fail; 00387 } 00388 } 00389 00390 if (gid_set && chown(fname, -1, gid) < 0) { 00391 perror("chown[ctrl_interface/ifname]"); 00392 goto fail; 00393 } 00394 00395 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 00396 perror("chmod[ctrl_interface/ifname]"); 00397 goto fail; 00398 } 00399 os_free(fname); 00400 00401 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, 00402 wpa_s, priv); 00403 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 00404 00405 os_free(buf); 00406 return priv; 00407 00408 fail: 00409 if (priv->sock >= 0) 00410 close(priv->sock); 00411 os_free(priv); 00412 if (fname) { 00413 unlink(fname); 00414 os_free(fname); 00415 } 00416 os_free(buf); 00417 return NULL; 00418 } 00419 00420 00421 void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) 00422 { 00423 struct wpa_ctrl_dst *dst, *prev; 00424 00425 if (priv->sock > -1) { 00426 char *fname; 00427 char *buf, *dir = NULL, *gid_str = NULL; 00428 eloop_unregister_read_sock(priv->sock); 00429 if (!dl_list_empty(&priv->ctrl_dst)) { 00430 /* 00431 * Wait a second before closing the control socket if 00432 * there are any attached monitors in order to allow 00433 * them to receive any pending messages. 00434 */ 00435 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " 00436 "monitors to receive messages"); 00437 os_sleep(1, 0); 00438 } 00439 close(priv->sock); 00440 priv->sock = -1; 00441 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); 00442 if (fname) { 00443 unlink(fname); 00444 os_free(fname); 00445 } 00446 00447 buf = os_strdup(priv->wpa_s->conf->ctrl_interface); 00448 if (buf == NULL) 00449 goto free_dst; 00450 if (os_strncmp(buf, "DIR=", 4) == 0) { 00451 dir = buf + 4; 00452 gid_str = os_strstr(dir, " GROUP="); 00453 if (gid_str) { 00454 *gid_str = '\0'; 00455 gid_str += 7; 00456 } 00457 } else 00458 dir = buf; 00459 00460 if (rmdir(dir) < 0) { 00461 if (errno == ENOTEMPTY) { 00462 wpa_printf(MSG_DEBUG, "Control interface " 00463 "directory not empty - leaving it " 00464 "behind"); 00465 } else { 00466 perror("rmdir[ctrl_interface]"); 00467 } 00468 } 00469 os_free(buf); 00470 } 00471 00472 free_dst: 00473 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 00474 list) 00475 os_free(dst); 00476 os_free(priv); 00477 } 00478 00479 00489 static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 00490 int level, const char *buf, 00491 size_t len) 00492 { 00493 struct wpa_ctrl_dst *dst, *next; 00494 char levelstr[10]; 00495 int idx, res; 00496 struct msghdr msg; 00497 struct iovec io[2]; 00498 00499 if (priv->sock < 0 || dl_list_empty(&priv->ctrl_dst)) 00500 return; 00501 00502 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 00503 if (res < 0 || (size_t) res >= sizeof(levelstr)) 00504 return; 00505 io[0].iov_base = levelstr; 00506 io[0].iov_len = os_strlen(levelstr); 00507 io[1].iov_base = (char *) buf; 00508 io[1].iov_len = len; 00509 os_memset(&msg, 0, sizeof(msg)); 00510 msg.msg_iov = io; 00511 msg.msg_iovlen = 2; 00512 00513 idx = 0; 00514 dl_list_for_each_safe(dst, next, &priv->ctrl_dst, struct wpa_ctrl_dst, 00515 list) { 00516 if (level >= dst->debug_level) { 00517 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", 00518 (u8 *) dst->addr.sun_path, dst->addrlen - 00519 offsetof(struct sockaddr_un, sun_path)); 00520 msg.msg_name = (void *) &dst->addr; 00521 msg.msg_namelen = dst->addrlen; 00522 if (sendmsg(priv->sock, &msg, 0) < 0) { 00523 int _errno = errno; 00524 wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: " 00525 "%d - %s", 00526 idx, errno, strerror(errno)); 00527 dst->errors++; 00528 if (dst->errors > 1000 || 00529 (_errno != ENOBUFS && dst->errors > 10) || 00530 _errno == ENOENT) { 00531 wpa_supplicant_ctrl_iface_detach( 00532 priv, &dst->addr, 00533 dst->addrlen); 00534 } 00535 } else 00536 dst->errors = 0; 00537 } 00538 idx++; 00539 } 00540 } 00541 00542 00543 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 00544 { 00545 char buf[256]; 00546 int res; 00547 struct sockaddr_un from; 00548 socklen_t fromlen = sizeof(from); 00549 00550 for (;;) { 00551 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " 00552 "attach", priv->wpa_s->ifname); 00553 eloop_wait_for_read_sock(priv->sock); 00554 00555 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, 00556 (struct sockaddr *) &from, &fromlen); 00557 if (res < 0) { 00558 perror("recvfrom(ctrl_iface)"); 00559 continue; 00560 } 00561 buf[res] = '\0'; 00562 00563 if (os_strcmp(buf, "ATTACH") == 0) { 00564 /* handle ATTACH signal of first monitor interface */ 00565 if (!wpa_supplicant_ctrl_iface_attach(priv, &from, 00566 fromlen)) { 00567 sendto(priv->sock, "OK\n", 3, 0, 00568 (struct sockaddr *) &from, fromlen); 00569 /* OK to continue */ 00570 return; 00571 } else { 00572 sendto(priv->sock, "FAIL\n", 5, 0, 00573 (struct sockaddr *) &from, fromlen); 00574 } 00575 } else { 00576 /* return FAIL for all other signals */ 00577 sendto(priv->sock, "FAIL\n", 5, 0, 00578 (struct sockaddr *) &from, fromlen); 00579 } 00580 } 00581 } 00582 00583 00584 /* Global ctrl_iface */ 00585 00586 struct ctrl_iface_global_priv { 00587 struct wpa_global *global; 00588 int sock; 00589 }; 00590 00591 00592 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, 00593 void *sock_ctx) 00594 { 00595 struct wpa_global *global = eloop_ctx; 00596 char buf[256]; 00597 int res; 00598 struct sockaddr_un from; 00599 socklen_t fromlen = sizeof(from); 00600 char *reply; 00601 size_t reply_len; 00602 00603 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 00604 (struct sockaddr *) &from, &fromlen); 00605 if (res < 0) { 00606 perror("recvfrom(ctrl_iface)"); 00607 return; 00608 } 00609 buf[res] = '\0'; 00610 00611 reply = wpa_supplicant_global_ctrl_iface_process(global, buf, 00612 &reply_len); 00613 00614 if (reply) { 00615 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 00616 fromlen); 00617 os_free(reply); 00618 } else if (reply_len) { 00619 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 00620 fromlen); 00621 } 00622 } 00623 00624 00625 struct ctrl_iface_global_priv * 00626 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 00627 { 00628 struct ctrl_iface_global_priv *priv; 00629 struct sockaddr_un addr; 00630 00631 priv = os_zalloc(sizeof(*priv)); 00632 if (priv == NULL) 00633 return NULL; 00634 priv->global = global; 00635 priv->sock = -1; 00636 00637 if (global->params.ctrl_interface == NULL) 00638 return priv; 00639 00640 wpa_printf(MSG_DEBUG, "Global control interface '%s'", 00641 global->params.ctrl_interface); 00642 00643 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 00644 if (priv->sock < 0) { 00645 perror("socket(PF_UNIX)"); 00646 goto fail; 00647 } 00648 00649 os_memset(&addr, 0, sizeof(addr)); 00650 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 00651 addr.sun_len = sizeof(addr); 00652 #endif /* __FreeBSD__ */ 00653 addr.sun_family = AF_UNIX; 00654 os_strlcpy(addr.sun_path, global->params.ctrl_interface, 00655 sizeof(addr.sun_path)); 00656 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 00657 perror("bind(PF_UNIX)"); 00658 if (connect(priv->sock, (struct sockaddr *) &addr, 00659 sizeof(addr)) < 0) { 00660 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 00661 " allow connections - assuming it was left" 00662 "over from forced program termination"); 00663 if (unlink(global->params.ctrl_interface) < 0) { 00664 perror("unlink[ctrl_iface]"); 00665 wpa_printf(MSG_ERROR, "Could not unlink " 00666 "existing ctrl_iface socket '%s'", 00667 global->params.ctrl_interface); 00668 goto fail; 00669 } 00670 if (bind(priv->sock, (struct sockaddr *) &addr, 00671 sizeof(addr)) < 0) { 00672 perror("bind(PF_UNIX)"); 00673 goto fail; 00674 } 00675 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 00676 "ctrl_iface socket '%s'", 00677 global->params.ctrl_interface); 00678 } else { 00679 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 00680 "be in use - cannot override it"); 00681 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 00682 "not used anymore", 00683 global->params.ctrl_interface); 00684 goto fail; 00685 } 00686 } 00687 00688 eloop_register_read_sock(priv->sock, 00689 wpa_supplicant_global_ctrl_iface_receive, 00690 global, NULL); 00691 00692 return priv; 00693 00694 fail: 00695 if (priv->sock >= 0) 00696 close(priv->sock); 00697 os_free(priv); 00698 return NULL; 00699 } 00700 00701 00702 void 00703 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 00704 { 00705 if (priv->sock >= 0) { 00706 eloop_unregister_read_sock(priv->sock); 00707 close(priv->sock); 00708 } 00709 if (priv->global->params.ctrl_interface) 00710 unlink(priv->global->params.ctrl_interface); 00711 os_free(priv); 00712 }