📄 ctrl_iface_unix.c
字号:
"over from forced program termination"); if (unlink(fname) < 0) { perror("unlink[ctrl_iface]"); wpa_printf(MSG_ERROR, "Could not unlink " "existing ctrl_iface socket '%s'", fname); goto fail; } if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); goto fail; } wpa_printf(MSG_DEBUG, "Successfully replaced leftover " "ctrl_iface socket '%s'", fname); } else { wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " "be in use - cannot override it"); wpa_printf(MSG_INFO, "Delete '%s' manually if it is " "not used anymore", fname); os_free(fname); fname = NULL; goto fail; } } if (gid_set && chown(fname, -1, gid) < 0) { perror("chown[ctrl_interface/ifname]"); goto fail; } if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { perror("chmod[ctrl_interface/ifname]"); goto fail; } os_free(fname); eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, wpa_s, priv); wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); os_free(buf); return priv;fail: if (priv->sock >= 0) close(priv->sock); os_free(priv); if (fname) { unlink(fname); os_free(fname); } os_free(buf); return NULL;}void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv){ struct wpa_ctrl_dst *dst, *prev; if (priv->sock > -1) { char *fname; char *buf, *dir = NULL, *gid_str = NULL; eloop_unregister_read_sock(priv->sock); if (priv->ctrl_dst) { /* * Wait a second before closing the control socket if * there are any attached monitors in order to allow * them to receive any pending messages. */ wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " "monitors to receive messages"); os_sleep(1, 0); } close(priv->sock); priv->sock = -1; fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); if (fname) { unlink(fname); os_free(fname); } buf = os_strdup(priv->wpa_s->conf->ctrl_interface); if (buf == NULL) goto free_dst; if (os_strncmp(buf, "DIR=", 4) == 0) { dir = buf + 4; gid_str = os_strstr(dir, " GROUP="); if (gid_str) { *gid_str = '\0'; gid_str += 7; } } else dir = buf; if (rmdir(dir) < 0) { if (errno == ENOTEMPTY) { wpa_printf(MSG_DEBUG, "Control interface " "directory not empty - leaving it " "behind"); } else { perror("rmdir[ctrl_interface]"); } } os_free(buf); }free_dst: dst = priv->ctrl_dst; while (dst) { prev = dst; dst = dst->next; os_free(prev); } os_free(priv);}/** * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init() * @level: Priority level of the message * @buf: Message data * @len: Message length * * Send a packet to all monitor programs attached to the control interface. */static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, int level, const char *buf, size_t len){ struct wpa_ctrl_dst *dst, *next; char levelstr[10]; int idx; struct msghdr msg; struct iovec io[2]; dst = priv->ctrl_dst; if (priv->sock < 0 || dst == NULL) return; os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); io[0].iov_base = levelstr; io[0].iov_len = os_strlen(levelstr); io[1].iov_base = (char *) buf; io[1].iov_len = len; os_memset(&msg, 0, sizeof(msg)); msg.msg_iov = io; msg.msg_iovlen = 2; idx = 0; while (dst) { next = dst->next; if (level >= dst->debug_level) { wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", (u8 *) dst->addr.sun_path, dst->addrlen - sizeof(dst->addr.sun_family)); msg.msg_name = (void *) &dst->addr; msg.msg_namelen = dst->addrlen; if (sendmsg(priv->sock, &msg, 0) < 0) { perror("sendmsg(CTRL_IFACE monitor)"); dst->errors++; if (dst->errors > 10) { wpa_supplicant_ctrl_iface_detach( priv, &dst->addr, dst->addrlen); } } else dst->errors = 0; } idx++; dst = next; }}void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv){ char buf[256]; int res; struct sockaddr_un from; socklen_t fromlen = sizeof(from); for (;;) { wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " "attach", priv->wpa_s->ifname); eloop_wait_for_read_sock(priv->sock); res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(ctrl_iface)"); continue; } buf[res] = '\0'; if (os_strcmp(buf, "ATTACH") == 0) { /* handle ATTACH signal of first monitor interface */ if (!wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen)) { sendto(priv->sock, "OK\n", 3, 0, (struct sockaddr *) &from, fromlen); /* OK to continue */ return; } else { sendto(priv->sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, fromlen); } } else { /* return FAIL for all other signals */ sendto(priv->sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, fromlen); } }}/* Global ctrl_iface */struct ctrl_iface_global_priv { struct wpa_global *global; int sock;};static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, void *sock_ctx){ struct wpa_global *global = eloop_ctx; char buf[256]; int res; struct sockaddr_un from; socklen_t fromlen = sizeof(from); char *reply; size_t reply_len; res = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(ctrl_iface)"); return; } buf[res] = '\0'; reply = wpa_supplicant_global_ctrl_iface_process(global, buf, &reply_len); if (reply) { sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen); os_free(reply); } else if (reply_len) { sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, fromlen); }}struct ctrl_iface_global_priv *wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global){ struct ctrl_iface_global_priv *priv; struct sockaddr_un addr; priv = os_zalloc(sizeof(*priv)); if (priv == NULL) return NULL; priv->global = global; priv->sock = -1; if (global->params.ctrl_interface == NULL) return priv; wpa_printf(MSG_DEBUG, "Global control interface '%s'", global->params.ctrl_interface); priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); if (priv->sock < 0) { perror("socket(PF_UNIX)"); goto fail; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strncpy(addr.sun_path, global->params.ctrl_interface, sizeof(addr.sun_path)); if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); if (connect(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" " allow connections - assuming it was left" "over from forced program termination"); if (unlink(global->params.ctrl_interface) < 0) { perror("unlink[ctrl_iface]"); wpa_printf(MSG_ERROR, "Could not unlink " "existing ctrl_iface socket '%s'", global->params.ctrl_interface); goto fail; } if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); goto fail; } wpa_printf(MSG_DEBUG, "Successfully replaced leftover " "ctrl_iface socket '%s'", global->params.ctrl_interface); } else { wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " "be in use - cannot override it"); wpa_printf(MSG_INFO, "Delete '%s' manually if it is " "not used anymore", global->params.ctrl_interface); goto fail; } } eloop_register_read_sock(priv->sock, wpa_supplicant_global_ctrl_iface_receive, global, NULL); return priv;fail: if (priv->sock >= 0) close(priv->sock); os_free(priv); return NULL;}voidwpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv){ if (priv->sock >= 0) { eloop_unregister_read_sock(priv->sock); close(priv->sock); } if (priv->global->params.ctrl_interface) unlink(priv->global->params.ctrl_interface); os_free(priv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -