1 /* 2 * wpa_supplicant ctrl_iface helpers 3 * Copyright (c) 2010-2011, Atheros Communications, Inc. 4 * Copyright (c) 2011-2012, Qualcomm Atheros, Inc. 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "includes.h" 11 #include <time.h> 12 13 #include "common.h" 14 #include "wpa_ctrl.h" 15 #include "wpa_helpers.h" 16 17 18 char *wpas_ctrl_path = "/var/run/wpa_supplicant/"; 19 static int default_timeout = 60; 20 21 22 static struct wpa_ctrl * wpa_open_ctrl(const char *ifname) 23 { 24 char buf[128]; 25 struct wpa_ctrl *ctrl; 26 27 os_snprintf(buf, sizeof(buf), "%s%s", wpas_ctrl_path, ifname); 28 ctrl = wpa_ctrl_open(buf); 29 if (ctrl == NULL) 30 printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf); 31 return ctrl; 32 } 33 34 35 int wpa_command(const char *ifname, const char *cmd) 36 { 37 struct wpa_ctrl *ctrl; 38 char buf[128]; 39 size_t len; 40 41 printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd); 42 ctrl = wpa_open_ctrl(ifname); 43 if (ctrl == NULL) 44 return -1; 45 len = sizeof(buf); 46 if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) { 47 printf("wpa_command: wpa_ctrl_request failed\n"); 48 wpa_ctrl_close(ctrl); 49 return -1; 50 } 51 wpa_ctrl_close(ctrl); 52 buf[len] = '\0'; 53 if (strncmp(buf, "FAIL", 4) == 0) { 54 printf("wpa_command: Command failed (FAIL received)\n"); 55 return -1; 56 } 57 return 0; 58 } 59 60 61 int wpa_command_resp(const char *ifname, const char *cmd, 62 char *resp, size_t resp_size) 63 { 64 struct wpa_ctrl *ctrl; 65 size_t len; 66 67 printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd); 68 ctrl = wpa_open_ctrl(ifname); 69 if (ctrl == NULL) 70 return -1; 71 len = resp_size; 72 if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) { 73 printf("wpa_command: wpa_ctrl_request failed\n"); 74 wpa_ctrl_close(ctrl); 75 return -1; 76 } 77 wpa_ctrl_close(ctrl); 78 resp[len] = '\0'; 79 return 0; 80 } 81 82 83 struct wpa_ctrl * open_wpa_mon(const char *ifname) 84 { 85 struct wpa_ctrl *ctrl; 86 87 ctrl = wpa_open_ctrl(ifname); 88 if (ctrl == NULL) 89 return NULL; 90 if (wpa_ctrl_attach(ctrl) < 0) { 91 wpa_ctrl_close(ctrl); 92 return NULL; 93 } 94 95 return ctrl; 96 } 97 98 99 int get_wpa_cli_event2(struct wpa_ctrl *mon, 100 const char *event, const char *event2, 101 char *buf, size_t buf_size) 102 { 103 int fd, ret; 104 fd_set rfd; 105 char *pos; 106 struct timeval tv; 107 time_t start, now; 108 109 printf("Waiting for wpa_cli event %s\n", event); 110 fd = wpa_ctrl_get_fd(mon); 111 if (fd < 0) 112 return -1; 113 114 time(&start); 115 while (1) { 116 size_t len; 117 118 FD_ZERO(&rfd); 119 FD_SET(fd, &rfd); 120 tv.tv_sec = default_timeout; 121 tv.tv_usec = 0; 122 ret = select(fd + 1, &rfd, NULL, NULL, &tv); 123 if (ret == 0) { 124 printf("Timeout on waiting for event %s\n", event); 125 return -1; 126 } 127 if (ret < 0) { 128 printf("select: %s\n", strerror(errno)); 129 return -1; 130 } 131 len = buf_size; 132 if (wpa_ctrl_recv(mon, buf, &len) < 0) { 133 printf("Failure while waiting for event %s\n", event); 134 return -1; 135 } 136 if (len == buf_size) 137 len--; 138 buf[len] = '\0'; 139 140 pos = strchr(buf, '>'); 141 if (pos && 142 (strncmp(pos + 1, event, strlen(event)) == 0 || 143 (event2 && 144 strncmp(pos + 1, event2, strlen(event2)) == 0))) 145 return 0; /* Event found */ 146 147 time(&now); 148 if ((int) (now - start) > default_timeout) { 149 printf("Timeout on waiting for event %s\n", event); 150 return -1; 151 } 152 } 153 } 154 155 156 int get_wpa_cli_event(struct wpa_ctrl *mon, 157 const char *event, char *buf, size_t buf_size) 158 { 159 return get_wpa_cli_event2(mon, event, NULL, buf, buf_size); 160 } 161 162 163 int get_wpa_status(const char *ifname, const char *field, char *obuf, 164 size_t obuf_size) 165 { 166 struct wpa_ctrl *ctrl; 167 char buf[4096]; 168 char *pos, *end; 169 size_t len, flen; 170 171 ctrl = wpa_open_ctrl(ifname); 172 if (ctrl == NULL) 173 return -1; 174 len = sizeof(buf); 175 if (wpa_ctrl_request(ctrl, "STATUS", 6, buf, &len, NULL) < 0) { 176 wpa_ctrl_close(ctrl); 177 return -1; 178 } 179 wpa_ctrl_close(ctrl); 180 buf[len] = '\0'; 181 182 flen = strlen(field); 183 pos = buf; 184 while (pos + flen < buf + len) { 185 if (pos > buf) { 186 if (*pos != '\n') { 187 pos++; 188 continue; 189 } 190 pos++; 191 } 192 if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') { 193 pos++; 194 continue; 195 } 196 pos += flen + 1; 197 end = strchr(pos, '\n'); 198 if (end == NULL) 199 return -1; 200 *end++ = '\0'; 201 if (end - pos > (int) obuf_size) 202 return -1; 203 memcpy(obuf, pos, end - pos); 204 return 0; 205 } 206 207 return -1; 208 } 209 210 211 int wait_ip_addr(const char *ifname, int timeout) 212 { 213 char ip[30]; 214 int count = timeout; 215 struct wpa_ctrl *ctrl; 216 217 while (count > 0) { 218 printf("%s: ifname='%s' - %d seconds remaining\n", 219 __func__, ifname, count); 220 count--; 221 if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0 222 && strlen(ip) > 0) { 223 printf("IP address found: '%s'\n", ip); 224 return 0; 225 } 226 ctrl = wpa_open_ctrl(ifname); 227 if (ctrl == NULL) 228 return -1; 229 wpa_ctrl_close(ctrl); 230 sleep(1); 231 } 232 printf("%s: Could not get IP address for ifname='%s'", __func__, 233 ifname); 234 return -1; 235 } 236 237 238 int add_network(const char *ifname) 239 { 240 char res[30]; 241 242 if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0) 243 return -1; 244 return atoi(res); 245 } 246 247 248 int set_network(const char *ifname, int id, const char *field, 249 const char *value) 250 { 251 char buf[200]; 252 snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value); 253 return wpa_command(ifname, buf); 254 } 255 256 257 int set_network_quoted(const char *ifname, int id, const char *field, 258 const char *value) 259 { 260 char buf[200]; 261 snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"", 262 id, field, value); 263 return wpa_command(ifname, buf); 264 } 265 266 267 int add_cred(const char *ifname) 268 { 269 char res[30]; 270 271 if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0) 272 return -1; 273 return atoi(res); 274 } 275 276 277 int set_cred(const char *ifname, int id, const char *field, const char *value) 278 { 279 char buf[200]; 280 snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value); 281 return wpa_command(ifname, buf); 282 } 283 284 285 int set_cred_quoted(const char *ifname, int id, const char *field, 286 const char *value) 287 { 288 char buf[200]; 289 snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"", 290 id, field, value); 291 return wpa_command(ifname, buf); 292 } 293