|
8 | 8 |
|
9 | 9 | #include "ctrl_iface_zephyr.h" |
10 | 10 |
|
| 11 | + |
| 12 | +static int wpa_supplicant_ctrl_mon_iface_attach(struct wpa_ctrl_mon **head, int sock) |
| 13 | +{ |
| 14 | + struct wpa_ctrl_mon *dst; |
| 15 | + |
| 16 | + dst = os_zalloc(sizeof(*dst)); |
| 17 | + if (dst == NULL) |
| 18 | + return -1; |
| 19 | + |
| 20 | + dst->sock = sock; |
| 21 | + dst->debug_level = MSG_INFO; |
| 22 | + dst->next = *head; |
| 23 | + *head = dst; |
| 24 | + return 0; |
| 25 | +} |
| 26 | + |
| 27 | + |
| 28 | +static int wpa_supplicant_ctrl_mon_iface_detach(struct wpa_ctrl_mon **head, int sock) |
| 29 | +{ |
| 30 | + struct wpa_ctrl_mon *dst, *prev = NULL; |
| 31 | + |
| 32 | + dst = *head; |
| 33 | + while (dst) { |
| 34 | + if (dst->sock == sock) { |
| 35 | + if (prev == NULL) { |
| 36 | + *head = dst->next; |
| 37 | + } else { |
| 38 | + prev->next = dst->next; |
| 39 | + } |
| 40 | + os_free(dst); |
| 41 | + return 0; |
| 42 | + } |
| 43 | + prev = dst; |
| 44 | + dst = dst->next; |
| 45 | + } |
| 46 | + return -1; |
| 47 | +} |
| 48 | + |
| 49 | +static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, |
| 50 | + const char *ifname, int sock, |
| 51 | + struct wpa_ctrl_mon **head, |
| 52 | + int level, const char *buf, |
| 53 | + size_t len) |
| 54 | +{ |
| 55 | + struct wpa_ctrl_mon *dst, *next; |
| 56 | + char levelstr[64]; |
| 57 | + int idx; |
| 58 | + struct conn_msg msg; |
| 59 | + |
| 60 | + dst = *head; |
| 61 | + if (sock < 0 || dst == NULL) |
| 62 | + return; |
| 63 | + |
| 64 | + if (ifname) |
| 65 | + os_snprintf(levelstr, sizeof(levelstr), "IFNAME=%s <%d>", |
| 66 | + ifname, level); |
| 67 | + else |
| 68 | + os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); |
| 69 | + |
| 70 | + idx = 0; |
| 71 | + while (dst) { |
| 72 | + next = dst->next; |
| 73 | + if (level >= dst->debug_level) { |
| 74 | + memcpy(&msg.msg, buf, len); |
| 75 | + msg.msg_len = len; |
| 76 | + if (send(dst->sock, &msg, sizeof(msg), 0) < 0) { |
| 77 | + wpa_printf(MSG_ERROR, |
| 78 | + "sendto(CTRL_IFACE monitor): %s", |
| 79 | + strerror(errno)); |
| 80 | + dst->errors++; |
| 81 | + } else { |
| 82 | + dst->errors = 0; |
| 83 | + } |
| 84 | + } |
| 85 | + idx++; |
| 86 | + dst = next; |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, |
| 91 | + enum wpa_msg_type type, |
| 92 | + const char *txt, size_t len) |
| 93 | +{ |
| 94 | + struct wpa_supplicant *wpa_s = ctx; |
| 95 | + |
| 96 | + if (!wpa_s) |
| 97 | + return; |
| 98 | + |
| 99 | + if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) { |
| 100 | + struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface; |
| 101 | + |
| 102 | + if (priv->ctrl_dst) { |
| 103 | + wpa_supplicant_ctrl_iface_send(wpa_s, type != WPA_MSG_PER_INTERFACE ? |
| 104 | + NULL : wpa_s->ifname, |
| 105 | + priv->sock_pair[0], |
| 106 | + &priv->ctrl_dst, level, txt, len); |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + if (type == WPA_MSG_ONLY_GLOBAL || !wpa_s->ctrl_iface) |
| 111 | + return; |
| 112 | + |
| 113 | + wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock_pair[0], |
| 114 | + &wpa_s->ctrl_iface->ctrl_dst, |
| 115 | + level, txt, len); |
| 116 | +} |
| 117 | + |
| 118 | + |
11 | 119 | static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, |
12 | 120 | void *sock_ctx) |
13 | 121 | { |
@@ -39,8 +147,26 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, |
39 | 147 | while (*pos == ' ') |
40 | 148 | pos++; |
41 | 149 |
|
42 | | - reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos, |
| 150 | + if (os_strcmp(pos, "ATTACH") == 0) { |
| 151 | + if (wpa_supplicant_ctrl_mon_iface_attach(&wpa_s->ctrl_iface->ctrl_dst, |
| 152 | + wpa_s->ctrl_iface->mon_sock_pair[1])){ |
| 153 | + reply_len = 1; |
| 154 | + } |
| 155 | + else { |
| 156 | + reply_len = 2; |
| 157 | + } |
| 158 | + } else if (os_strcmp(pos, "DETACH") == 0) { |
| 159 | + if (wpa_supplicant_ctrl_mon_iface_detach(&wpa_s->ctrl_iface->ctrl_dst, |
| 160 | + wpa_s->ctrl_iface->mon_sock_pair[1])) { |
| 161 | + reply_len = 1; |
| 162 | + } |
| 163 | + else { |
| 164 | + reply_len = 2; |
| 165 | + } |
| 166 | + } else { |
| 167 | + reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos, |
43 | 168 | &reply_len); |
| 169 | + } |
44 | 170 |
|
45 | 171 | if (reply) { |
46 | 172 | send(sock, reply, reply_len, 0); |
@@ -86,6 +212,8 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) |
86 | 212 | eloop_register_read_sock(priv->sock_pair[1], wpa_supplicant_ctrl_iface_receive, |
87 | 213 | wpa_s, priv); |
88 | 214 |
|
| 215 | + wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); |
| 216 | + |
89 | 217 | return priv; |
90 | 218 |
|
91 | 219 | fail: |
@@ -154,8 +282,26 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, |
154 | 282 | while (*pos == ' ') |
155 | 283 | pos++; |
156 | 284 |
|
| 285 | + if (os_strcmp(pos, "ATTACH") == 0) { |
| 286 | + if (wpa_supplicant_ctrl_mon_iface_attach(&global->ctrl_iface->ctrl_dst, |
| 287 | + global->ctrl_iface->mon_sock_pair[1])) { |
| 288 | + reply_len = 1; |
| 289 | + } |
| 290 | + else { |
| 291 | + reply_len = 2; |
| 292 | + } |
| 293 | + } else if (os_strcmp(pos, "DETACH") == 0) { |
| 294 | + if (wpa_supplicant_ctrl_mon_iface_detach(&global->ctrl_iface->ctrl_dst, |
| 295 | + global->ctrl_iface->mon_sock_pair[1])) { |
| 296 | + reply_len = 1; |
| 297 | + } |
| 298 | + else { |
| 299 | + reply_len = 2; |
| 300 | + } |
| 301 | + } else { |
157 | 302 | reply = wpa_supplicant_global_ctrl_iface_process(global, pos, |
158 | 303 | &reply_len); |
| 304 | + } |
159 | 305 |
|
160 | 306 | if (reply) { |
161 | 307 | send(sock, reply, reply_len, 0); |
|
0 commit comments