ctrl_iface_unix.c revision 209158
1239310Sdim/* 2239310Sdim * WPA Supplicant / UNIX domain socket -based control interface 3239310Sdim * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> 4239310Sdim * 5239310Sdim * This program is free software; you can redistribute it and/or modify 6239310Sdim * it under the terms of the GNU General Public License version 2 as 7239310Sdim * published by the Free Software Foundation. 8239310Sdim * 9239310Sdim * Alternatively, this software may be distributed under the terms of BSD 10239310Sdim * license. 11239310Sdim * 12239310Sdim * See README and COPYING for more details. 13239310Sdim */ 14239310Sdim 15252723Sdim#include "includes.h" 16239310Sdim#include <sys/un.h> 17252723Sdim#include <sys/stat.h> 18252723Sdim#include <grp.h> 19239310Sdim#include <stddef.h> 20252723Sdim 21239310Sdim#include "common.h" 22239310Sdim#include "eloop.h" 23239310Sdim#include "config.h" 24239310Sdim#include "eapol_supp/eapol_supp_sm.h" 25239310Sdim#include "wpa_supplicant_i.h" 26239310Sdim#include "ctrl_iface.h" 27239310Sdim 28252723Sdim/* Per-interface ctrl_iface */ 29239310Sdim 30239310Sdim/** 31239310Sdim * struct wpa_ctrl_dst - Internal data structure of control interface monitors 32239310Sdim * 33252723Sdim * This structure is used to store information about registered control 34252723Sdim * interface monitors into struct wpa_supplicant. This data is private to 35252723Sdim * ctrl_iface_unix.c and should not be touched directly from other files. 36252723Sdim */ 37239310Sdimstruct wpa_ctrl_dst { 38239310Sdim struct wpa_ctrl_dst *next; 39239310Sdim struct sockaddr_un addr; 40239310Sdim socklen_t addrlen; 41239310Sdim int debug_level; 42239310Sdim int errors; 43239310Sdim}; 44239310Sdim 45239310Sdim 46239310Sdimstruct ctrl_iface_priv { 47239310Sdim struct wpa_supplicant *wpa_s; 48239310Sdim int sock; 49239310Sdim struct wpa_ctrl_dst *ctrl_dst; 50252723Sdim}; 51252723Sdim 52252723Sdim 53252723Sdimstatic void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 54239310Sdim int level, const char *buf, 55239310Sdim size_t len); 56239310Sdim 57239310Sdim 58239310Sdimstatic int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv, 59239310Sdim struct sockaddr_un *from, 60252723Sdim socklen_t fromlen) 61252723Sdim{ 62252723Sdim struct wpa_ctrl_dst *dst; 63252723Sdim 64239310Sdim dst = os_zalloc(sizeof(*dst)); 65239310Sdim if (dst == NULL) 66252723Sdim return -1; 67252723Sdim os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un)); 68252723Sdim dst->addrlen = fromlen; 69252723Sdim dst->debug_level = MSG_INFO; 70252723Sdim dst->next = priv->ctrl_dst; 71252723Sdim priv->ctrl_dst = dst; 72252723Sdim wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached", 73252723Sdim (u8 *) from->sun_path, 74263509Sdim fromlen - offsetof(struct sockaddr_un, sun_path)); 75263509Sdim return 0; 76263509Sdim} 77239310Sdim 78239310Sdim 79239310Sdimstatic int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv, 80252723Sdim struct sockaddr_un *from, 81252723Sdim socklen_t fromlen) 82252723Sdim{ 83252723Sdim struct wpa_ctrl_dst *dst, *prev = NULL; 84252723Sdim 85239310Sdim dst = priv->ctrl_dst; 86239310Sdim while (dst) { 87239310Sdim if (fromlen == dst->addrlen && 88252723Sdim os_memcmp(from->sun_path, dst->addr.sun_path, 89252723Sdim fromlen - offsetof(struct sockaddr_un, sun_path)) 90252723Sdim == 0) { 91252723Sdim if (prev == NULL) 92252723Sdim priv->ctrl_dst = dst->next; 93239310Sdim else 94263509Sdim prev->next = dst->next; 95239310Sdim os_free(dst); 96239310Sdim wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", 97239310Sdim (u8 *) from->sun_path, 98252723Sdim fromlen - 99239310Sdim offsetof(struct sockaddr_un, sun_path)); 100239310Sdim return 0; 101239310Sdim } 102239310Sdim prev = dst; 103239310Sdim dst = dst->next; 104252723Sdim } 105239310Sdim return -1; 106239310Sdim} 107263509Sdim 108263509Sdim 109263509Sdimstatic int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, 110263509Sdim struct sockaddr_un *from, 111263509Sdim socklen_t fromlen, 112239310Sdim char *level) 113263509Sdim{ 114239310Sdim struct wpa_ctrl_dst *dst; 115239310Sdim 116239310Sdim wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 117239310Sdim 118239310Sdim dst = priv->ctrl_dst; 119239310Sdim while (dst) { 120252723Sdim if (fromlen == dst->addrlen && 121263509Sdim os_memcmp(from->sun_path, dst->addr.sun_path, 122263509Sdim fromlen - offsetof(struct sockaddr_un, sun_path)) 123263509Sdim == 0) { 124263509Sdim wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor " 125263509Sdim "level", (u8 *) from->sun_path, 126263509Sdim fromlen - 127263509Sdim offsetof(struct sockaddr_un, sun_path)); 128263509Sdim dst->debug_level = atoi(level); 129263509Sdim return 0; 130263509Sdim } 131252723Sdim dst = dst->next; 132252723Sdim } 133252723Sdim 134252723Sdim return -1; 135239310Sdim} 136239310Sdim 137239310Sdim 138239310Sdimstatic void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, 139239310Sdim void *sock_ctx) 140239310Sdim{ 141239310Sdim struct wpa_supplicant *wpa_s = eloop_ctx; 142239310Sdim struct ctrl_iface_priv *priv = sock_ctx; 143252723Sdim char buf[256]; 144263509Sdim int res; 145263509Sdim struct sockaddr_un from; 146263509Sdim socklen_t fromlen = sizeof(from); 147263509Sdim char *reply = NULL; 148263509Sdim size_t reply_len = 0; 149263509Sdim int new_attached = 0; 150263509Sdim 151263509Sdim res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 152263509Sdim (struct sockaddr *) &from, &fromlen); 153263509Sdim if (res < 0) { 154263509Sdim perror("recvfrom(ctrl_iface)"); 155263509Sdim return; 156263509Sdim } 157263509Sdim buf[res] = '\0'; 158263509Sdim 159263509Sdim if (os_strcmp(buf, "ATTACH") == 0) { 160263509Sdim if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen)) 161263509Sdim reply_len = 1; 162263509Sdim else { 163263509Sdim new_attached = 1; 164263509Sdim reply_len = 2; 165263509Sdim } 166263509Sdim } else if (os_strcmp(buf, "DETACH") == 0) { 167263509Sdim if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen)) 168263509Sdim reply_len = 1; 169263509Sdim else 170263509Sdim reply_len = 2; 171263509Sdim } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 172263509Sdim if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen, 173263509Sdim buf + 6)) 174263509Sdim reply_len = 1; 175263509Sdim else 176263509Sdim reply_len = 2; 177263509Sdim } else { 178263509Sdim reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 179263509Sdim &reply_len); 180263509Sdim } 181263509Sdim 182 if (reply) { 183 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 184 fromlen); 185 os_free(reply); 186 } else if (reply_len == 1) { 187 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 188 fromlen); 189 } else if (reply_len == 2) { 190 sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, 191 fromlen); 192 } 193 194 if (new_attached) 195 eapol_sm_notify_ctrl_attached(wpa_s->eapol); 196} 197 198 199static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s) 200{ 201 char *buf; 202 size_t len; 203 char *pbuf, *dir = NULL, *gid_str = NULL; 204 int res; 205 206 if (wpa_s->conf->ctrl_interface == NULL) 207 return NULL; 208 209 pbuf = os_strdup(wpa_s->conf->ctrl_interface); 210 if (pbuf == NULL) 211 return NULL; 212 if (os_strncmp(pbuf, "DIR=", 4) == 0) { 213 dir = pbuf + 4; 214 gid_str = os_strstr(dir, " GROUP="); 215 if (gid_str) { 216 *gid_str = '\0'; 217 gid_str += 7; 218 } 219 } else 220 dir = pbuf; 221 222 len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2; 223 buf = os_malloc(len); 224 if (buf == NULL) { 225 os_free(pbuf); 226 return NULL; 227 } 228 229 res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname); 230 if (res < 0 || (size_t) res >= len) { 231 os_free(pbuf); 232 os_free(buf); 233 return NULL; 234 } 235#ifdef __CYGWIN__ 236 { 237 /* Windows/WinPcap uses interface names that are not suitable 238 * as a file name - convert invalid chars to underscores */ 239 char *pos = buf; 240 while (*pos) { 241 if (*pos == '\\') 242 *pos = '_'; 243 pos++; 244 } 245 } 246#endif /* __CYGWIN__ */ 247 os_free(pbuf); 248 return buf; 249} 250 251 252static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, 253 const char *txt, size_t len) 254{ 255 struct wpa_supplicant *wpa_s = ctx; 256 if (wpa_s == NULL || wpa_s->ctrl_iface == NULL) 257 return; 258 wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len); 259} 260 261 262struct ctrl_iface_priv * 263wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 264{ 265 struct ctrl_iface_priv *priv; 266 struct sockaddr_un addr; 267 char *fname = NULL; 268 gid_t gid = 0; 269 int gid_set = 0; 270 char *buf, *dir = NULL, *gid_str = NULL; 271 struct group *grp; 272 char *endp; 273 274 priv = os_zalloc(sizeof(*priv)); 275 if (priv == NULL) 276 return NULL; 277 priv->wpa_s = wpa_s; 278 priv->sock = -1; 279 280 if (wpa_s->conf->ctrl_interface == NULL) 281 return priv; 282 283 buf = os_strdup(wpa_s->conf->ctrl_interface); 284 if (buf == NULL) 285 goto fail; 286 if (os_strncmp(buf, "DIR=", 4) == 0) { 287 dir = buf + 4; 288 gid_str = os_strstr(dir, " GROUP="); 289 if (gid_str) { 290 *gid_str = '\0'; 291 gid_str += 7; 292 } 293 } else { 294 dir = buf; 295 gid_str = wpa_s->conf->ctrl_interface_group; 296 } 297 298 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { 299 if (errno == EEXIST) { 300 wpa_printf(MSG_DEBUG, "Using existing control " 301 "interface directory."); 302 } else { 303 perror("mkdir[ctrl_interface]"); 304 goto fail; 305 } 306 } 307 308 if (gid_str) { 309 grp = getgrnam(gid_str); 310 if (grp) { 311 gid = grp->gr_gid; 312 gid_set = 1; 313 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 314 " (from group name '%s')", 315 (int) gid, gid_str); 316 } else { 317 /* Group name not found - try to parse this as gid */ 318 gid = strtol(gid_str, &endp, 10); 319 if (*gid_str == '\0' || *endp != '\0') { 320 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 321 "'%s'", gid_str); 322 goto fail; 323 } 324 gid_set = 1; 325 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 326 (int) gid); 327 } 328 } 329 330 if (gid_set && chown(dir, -1, gid) < 0) { 331 perror("chown[ctrl_interface]"); 332 goto fail; 333 } 334 335 /* Make sure the group can enter and read the directory */ 336 if (gid_set && 337 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) { 338 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s", 339 strerror(errno)); 340 goto fail; 341 } 342 343 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= 344 sizeof(addr.sun_path)) { 345 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded"); 346 goto fail; 347 } 348 349 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 350 if (priv->sock < 0) { 351 perror("socket(PF_UNIX)"); 352 goto fail; 353 } 354 355 os_memset(&addr, 0, sizeof(addr)); 356#ifdef __FreeBSD__ 357 addr.sun_len = sizeof(addr); 358#endif /* __FreeBSD__ */ 359 addr.sun_family = AF_UNIX; 360 fname = wpa_supplicant_ctrl_iface_path(wpa_s); 361 if (fname == NULL) 362 goto fail; 363 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 364 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 365 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 366 strerror(errno)); 367 if (connect(priv->sock, (struct sockaddr *) &addr, 368 sizeof(addr)) < 0) { 369 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 370 " allow connections - assuming it was left" 371 "over from forced program termination"); 372 if (unlink(fname) < 0) { 373 perror("unlink[ctrl_iface]"); 374 wpa_printf(MSG_ERROR, "Could not unlink " 375 "existing ctrl_iface socket '%s'", 376 fname); 377 goto fail; 378 } 379 if (bind(priv->sock, (struct sockaddr *) &addr, 380 sizeof(addr)) < 0) { 381 perror("bind(PF_UNIX)"); 382 goto fail; 383 } 384 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 385 "ctrl_iface socket '%s'", fname); 386 } else { 387 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 388 "be in use - cannot override it"); 389 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 390 "not used anymore", fname); 391 os_free(fname); 392 fname = NULL; 393 goto fail; 394 } 395 } 396 397 if (gid_set && chown(fname, -1, gid) < 0) { 398 perror("chown[ctrl_interface/ifname]"); 399 goto fail; 400 } 401 402 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 403 perror("chmod[ctrl_interface/ifname]"); 404 goto fail; 405 } 406 os_free(fname); 407 408 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, 409 wpa_s, priv); 410 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 411 412 os_free(buf); 413 return priv; 414 415fail: 416 if (priv->sock >= 0) 417 close(priv->sock); 418 os_free(priv); 419 if (fname) { 420 unlink(fname); 421 os_free(fname); 422 } 423 os_free(buf); 424 return NULL; 425} 426 427 428void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) 429{ 430 struct wpa_ctrl_dst *dst, *prev; 431 432 if (priv->sock > -1) { 433 char *fname; 434 char *buf, *dir = NULL, *gid_str = NULL; 435 eloop_unregister_read_sock(priv->sock); 436 if (priv->ctrl_dst) { 437 /* 438 * Wait a second before closing the control socket if 439 * there are any attached monitors in order to allow 440 * them to receive any pending messages. 441 */ 442 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " 443 "monitors to receive messages"); 444 os_sleep(1, 0); 445 } 446 close(priv->sock); 447 priv->sock = -1; 448 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); 449 if (fname) { 450 unlink(fname); 451 os_free(fname); 452 } 453 454 buf = os_strdup(priv->wpa_s->conf->ctrl_interface); 455 if (buf == NULL) 456 goto free_dst; 457 if (os_strncmp(buf, "DIR=", 4) == 0) { 458 dir = buf + 4; 459 gid_str = os_strstr(dir, " GROUP="); 460 if (gid_str) { 461 *gid_str = '\0'; 462 gid_str += 7; 463 } 464 } else 465 dir = buf; 466 467 if (rmdir(dir) < 0) { 468 if (errno == ENOTEMPTY) { 469 wpa_printf(MSG_DEBUG, "Control interface " 470 "directory not empty - leaving it " 471 "behind"); 472 } else { 473 perror("rmdir[ctrl_interface]"); 474 } 475 } 476 os_free(buf); 477 } 478 479free_dst: 480 dst = priv->ctrl_dst; 481 while (dst) { 482 prev = dst; 483 dst = dst->next; 484 os_free(prev); 485 } 486 os_free(priv); 487} 488 489 490/** 491 * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors 492 * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init() 493 * @level: Priority level of the message 494 * @buf: Message data 495 * @len: Message length 496 * 497 * Send a packet to all monitor programs attached to the control interface. 498 */ 499static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 500 int level, const char *buf, 501 size_t len) 502{ 503 struct wpa_ctrl_dst *dst, *next; 504 char levelstr[10]; 505 int idx, res; 506 struct msghdr msg; 507 struct iovec io[2]; 508 509 dst = priv->ctrl_dst; 510 if (priv->sock < 0 || dst == NULL) 511 return; 512 513 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 514 if (res < 0 || (size_t) res >= sizeof(levelstr)) 515 return; 516 io[0].iov_base = levelstr; 517 io[0].iov_len = os_strlen(levelstr); 518 io[1].iov_base = (char *) buf; 519 io[1].iov_len = len; 520 os_memset(&msg, 0, sizeof(msg)); 521 msg.msg_iov = io; 522 msg.msg_iovlen = 2; 523 524 idx = 0; 525 while (dst) { 526 next = dst->next; 527 if (level >= dst->debug_level) { 528 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", 529 (u8 *) dst->addr.sun_path, dst->addrlen - 530 offsetof(struct sockaddr_un, sun_path)); 531 msg.msg_name = (void *) &dst->addr; 532 msg.msg_namelen = dst->addrlen; 533 if (sendmsg(priv->sock, &msg, 0) < 0) { 534 int _errno = errno; 535 wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: " 536 "%d - %s", 537 idx, errno, strerror(errno)); 538 dst->errors++; 539 if (dst->errors > 10 || _errno == ENOENT) { 540 wpa_supplicant_ctrl_iface_detach( 541 priv, &dst->addr, 542 dst->addrlen); 543 } 544 } else 545 dst->errors = 0; 546 } 547 idx++; 548 dst = next; 549 } 550} 551 552 553void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 554{ 555 char buf[256]; 556 int res; 557 struct sockaddr_un from; 558 socklen_t fromlen = sizeof(from); 559 560 for (;;) { 561 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " 562 "attach", priv->wpa_s->ifname); 563 eloop_wait_for_read_sock(priv->sock); 564 565 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, 566 (struct sockaddr *) &from, &fromlen); 567 if (res < 0) { 568 perror("recvfrom(ctrl_iface)"); 569 continue; 570 } 571 buf[res] = '\0'; 572 573 if (os_strcmp(buf, "ATTACH") == 0) { 574 /* handle ATTACH signal of first monitor interface */ 575 if (!wpa_supplicant_ctrl_iface_attach(priv, &from, 576 fromlen)) { 577 sendto(priv->sock, "OK\n", 3, 0, 578 (struct sockaddr *) &from, fromlen); 579 /* OK to continue */ 580 return; 581 } else { 582 sendto(priv->sock, "FAIL\n", 5, 0, 583 (struct sockaddr *) &from, fromlen); 584 } 585 } else { 586 /* return FAIL for all other signals */ 587 sendto(priv->sock, "FAIL\n", 5, 0, 588 (struct sockaddr *) &from, fromlen); 589 } 590 } 591} 592 593 594/* Global ctrl_iface */ 595 596struct ctrl_iface_global_priv { 597 struct wpa_global *global; 598 int sock; 599}; 600 601 602static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, 603 void *sock_ctx) 604{ 605 struct wpa_global *global = eloop_ctx; 606 char buf[256]; 607 int res; 608 struct sockaddr_un from; 609 socklen_t fromlen = sizeof(from); 610 char *reply; 611 size_t reply_len; 612 613 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 614 (struct sockaddr *) &from, &fromlen); 615 if (res < 0) { 616 perror("recvfrom(ctrl_iface)"); 617 return; 618 } 619 buf[res] = '\0'; 620 621 reply = wpa_supplicant_global_ctrl_iface_process(global, buf, 622 &reply_len); 623 624 if (reply) { 625 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 626 fromlen); 627 os_free(reply); 628 } else if (reply_len) { 629 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 630 fromlen); 631 } 632} 633 634 635struct ctrl_iface_global_priv * 636wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 637{ 638 struct ctrl_iface_global_priv *priv; 639 struct sockaddr_un addr; 640 641 priv = os_zalloc(sizeof(*priv)); 642 if (priv == NULL) 643 return NULL; 644 priv->global = global; 645 priv->sock = -1; 646 647 if (global->params.ctrl_interface == NULL) 648 return priv; 649 650 wpa_printf(MSG_DEBUG, "Global control interface '%s'", 651 global->params.ctrl_interface); 652 653 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 654 if (priv->sock < 0) { 655 perror("socket(PF_UNIX)"); 656 goto fail; 657 } 658 659 os_memset(&addr, 0, sizeof(addr)); 660#ifdef __FreeBSD__ 661 addr.sun_len = sizeof(addr); 662#endif /* __FreeBSD__ */ 663 addr.sun_family = AF_UNIX; 664 os_strlcpy(addr.sun_path, global->params.ctrl_interface, 665 sizeof(addr.sun_path)); 666 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 667 perror("bind(PF_UNIX)"); 668 if (connect(priv->sock, (struct sockaddr *) &addr, 669 sizeof(addr)) < 0) { 670 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 671 " allow connections - assuming it was left" 672 "over from forced program termination"); 673 if (unlink(global->params.ctrl_interface) < 0) { 674 perror("unlink[ctrl_iface]"); 675 wpa_printf(MSG_ERROR, "Could not unlink " 676 "existing ctrl_iface socket '%s'", 677 global->params.ctrl_interface); 678 goto fail; 679 } 680 if (bind(priv->sock, (struct sockaddr *) &addr, 681 sizeof(addr)) < 0) { 682 perror("bind(PF_UNIX)"); 683 goto fail; 684 } 685 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 686 "ctrl_iface socket '%s'", 687 global->params.ctrl_interface); 688 } else { 689 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 690 "be in use - cannot override it"); 691 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 692 "not used anymore", 693 global->params.ctrl_interface); 694 goto fail; 695 } 696 } 697 698 eloop_register_read_sock(priv->sock, 699 wpa_supplicant_global_ctrl_iface_receive, 700 global, NULL); 701 702 return priv; 703 704fail: 705 if (priv->sock >= 0) 706 close(priv->sock); 707 os_free(priv); 708 return NULL; 709} 710 711 712void 713wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 714{ 715 if (priv->sock >= 0) { 716 eloop_unregister_read_sock(priv->sock); 717 close(priv->sock); 718 } 719 if (priv->global->params.ctrl_interface) 720 unlink(priv->global->params.ctrl_interface); 721 os_free(priv); 722} 723