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