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