ctrl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /*
  2. * wlantest control interface
  3. * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "utils/includes.h"
  15. #include <sys/un.h>
  16. #include "utils/common.h"
  17. #include "utils/eloop.h"
  18. #include "common/ieee802_11_defs.h"
  19. #include "wlantest.h"
  20. #include "wlantest_ctrl.h"
  21. static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
  22. size_t *len)
  23. {
  24. u8 *pos = buf;
  25. while (pos + 8 <= buf + buflen) {
  26. enum wlantest_ctrl_attr a;
  27. size_t alen;
  28. a = WPA_GET_BE32(pos);
  29. pos += 4;
  30. alen = WPA_GET_BE32(pos);
  31. pos += 4;
  32. if (pos + alen > buf + buflen) {
  33. wpa_printf(MSG_DEBUG, "Invalid control message "
  34. "attribute");
  35. return NULL;
  36. }
  37. if (a == attr) {
  38. *len = alen;
  39. return pos;
  40. }
  41. pos += alen;
  42. }
  43. return NULL;
  44. }
  45. static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
  46. enum wlantest_ctrl_attr attr)
  47. {
  48. u8 *addr;
  49. size_t addr_len;
  50. addr = attr_get(buf, buflen, attr, &addr_len);
  51. if (addr && addr_len != ETH_ALEN)
  52. addr = NULL;
  53. return addr;
  54. }
  55. static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
  56. {
  57. u8 *pos;
  58. size_t len;
  59. pos = attr_get(buf, buflen, attr, &len);
  60. if (pos == NULL || len != 4)
  61. return -1;
  62. return WPA_GET_BE32(pos);
  63. }
  64. static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
  65. u32 val)
  66. {
  67. if (pos == NULL || end - pos < 12)
  68. return NULL;
  69. WPA_PUT_BE32(pos, attr);
  70. pos += 4;
  71. WPA_PUT_BE32(pos, 4);
  72. pos += 4;
  73. WPA_PUT_BE32(pos, val);
  74. pos += 4;
  75. return pos;
  76. }
  77. static void ctrl_disconnect(struct wlantest *wt, int sock)
  78. {
  79. int i;
  80. wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
  81. sock);
  82. for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
  83. if (wt->ctrl_socks[i] == sock) {
  84. close(wt->ctrl_socks[i]);
  85. eloop_unregister_read_sock(wt->ctrl_socks[i]);
  86. wt->ctrl_socks[i] = -1;
  87. break;
  88. }
  89. }
  90. }
  91. static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
  92. size_t len)
  93. {
  94. if (send(sock, buf, len, 0) < 0) {
  95. wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
  96. ctrl_disconnect(wt, sock);
  97. }
  98. }
  99. static void ctrl_send_simple(struct wlantest *wt, int sock,
  100. enum wlantest_ctrl_cmd cmd)
  101. {
  102. u8 buf[4];
  103. WPA_PUT_BE32(buf, cmd);
  104. ctrl_send(wt, sock, buf, sizeof(buf));
  105. }
  106. static void ctrl_list_bss(struct wlantest *wt, int sock)
  107. {
  108. u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
  109. struct wlantest_bss *bss;
  110. pos = buf;
  111. WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
  112. pos += 4;
  113. WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
  114. pos += 4;
  115. len = pos; /* to be filled */
  116. pos += 4;
  117. dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
  118. if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
  119. break;
  120. os_memcpy(pos, bss->bssid, ETH_ALEN);
  121. pos += ETH_ALEN;
  122. }
  123. WPA_PUT_BE32(len, pos - len - 4);
  124. ctrl_send(wt, sock, buf, pos - buf);
  125. }
  126. static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
  127. {
  128. u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
  129. u8 *bssid;
  130. size_t bssid_len;
  131. struct wlantest_bss *bss;
  132. struct wlantest_sta *sta;
  133. bssid = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &bssid_len);
  134. if (bssid == NULL || bssid_len != ETH_ALEN) {
  135. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  136. return;
  137. }
  138. bss = bss_get(wt, bssid);
  139. if (bss == NULL) {
  140. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  141. return;
  142. }
  143. pos = buf;
  144. WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
  145. pos += 4;
  146. WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
  147. pos += 4;
  148. len = pos; /* to be filled */
  149. pos += 4;
  150. dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
  151. if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
  152. break;
  153. os_memcpy(pos, sta->addr, ETH_ALEN);
  154. pos += ETH_ALEN;
  155. }
  156. WPA_PUT_BE32(len, pos - len - 4);
  157. ctrl_send(wt, sock, buf, pos - buf);
  158. }
  159. static void ctrl_flush(struct wlantest *wt, int sock)
  160. {
  161. wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
  162. bss_flush(wt);
  163. ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
  164. }
  165. static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
  166. size_t clen)
  167. {
  168. u8 *addr;
  169. size_t addr_len;
  170. struct wlantest_bss *bss;
  171. struct wlantest_sta *sta;
  172. addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
  173. if (addr == NULL || addr_len != ETH_ALEN) {
  174. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  175. return;
  176. }
  177. bss = bss_get(wt, addr);
  178. if (bss == NULL) {
  179. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  180. return;
  181. }
  182. addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
  183. if (addr == NULL || addr_len != ETH_ALEN) {
  184. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  185. return;
  186. }
  187. sta = sta_get(bss, addr);
  188. if (sta == NULL) {
  189. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  190. return;
  191. }
  192. os_memset(sta->counters, 0, sizeof(sta->counters));
  193. ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
  194. }
  195. static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
  196. size_t clen)
  197. {
  198. u8 *addr;
  199. size_t addr_len;
  200. struct wlantest_bss *bss;
  201. addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
  202. if (addr == NULL || addr_len != ETH_ALEN) {
  203. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  204. return;
  205. }
  206. bss = bss_get(wt, addr);
  207. if (bss == NULL) {
  208. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  209. return;
  210. }
  211. os_memset(bss->counters, 0, sizeof(bss->counters));
  212. ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
  213. }
  214. static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
  215. size_t clen)
  216. {
  217. u8 *addr;
  218. size_t addr_len;
  219. struct wlantest_bss *bss;
  220. struct wlantest_sta *sta;
  221. u32 counter;
  222. u8 buf[4 + 12], *end, *pos;
  223. addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
  224. if (addr == NULL || addr_len != ETH_ALEN) {
  225. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  226. return;
  227. }
  228. bss = bss_get(wt, addr);
  229. if (bss == NULL) {
  230. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  231. return;
  232. }
  233. addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
  234. if (addr == NULL || addr_len != ETH_ALEN) {
  235. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  236. return;
  237. }
  238. sta = sta_get(bss, addr);
  239. if (sta == NULL) {
  240. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  241. return;
  242. }
  243. addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
  244. if (addr == NULL || addr_len != 4) {
  245. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  246. return;
  247. }
  248. counter = WPA_GET_BE32(addr);
  249. if (counter >= NUM_WLANTEST_STA_COUNTER) {
  250. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  251. return;
  252. }
  253. pos = buf;
  254. end = buf + sizeof(buf);
  255. WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
  256. pos += 4;
  257. pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
  258. sta->counters[counter]);
  259. ctrl_send(wt, sock, buf, pos - buf);
  260. }
  261. static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
  262. size_t clen)
  263. {
  264. u8 *addr;
  265. size_t addr_len;
  266. struct wlantest_bss *bss;
  267. u32 counter;
  268. u8 buf[4 + 12], *end, *pos;
  269. addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
  270. if (addr == NULL || addr_len != ETH_ALEN) {
  271. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  272. return;
  273. }
  274. bss = bss_get(wt, addr);
  275. if (bss == NULL) {
  276. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  277. return;
  278. }
  279. addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
  280. if (addr == NULL || addr_len != 4) {
  281. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  282. return;
  283. }
  284. counter = WPA_GET_BE32(addr);
  285. if (counter >= NUM_WLANTEST_BSS_COUNTER) {
  286. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  287. return;
  288. }
  289. pos = buf;
  290. end = buf + sizeof(buf);
  291. WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
  292. pos += 4;
  293. pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
  294. bss->counters[counter]);
  295. ctrl_send(wt, sock, buf, pos - buf);
  296. }
  297. static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
  298. struct wlantest_bss *bss, struct wlantest_sta *sta,
  299. int sender_ap, int stype)
  300. {
  301. os_memset(mgmt, 0, 24);
  302. mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
  303. if (sender_ap) {
  304. if (sta)
  305. os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
  306. else
  307. os_memset(mgmt->da, 0xff, ETH_ALEN);
  308. os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
  309. } else {
  310. os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
  311. os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
  312. }
  313. os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
  314. }
  315. static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
  316. struct wlantest_sta *sta, int sender_ap,
  317. enum wlantest_inject_protection prot)
  318. {
  319. struct ieee80211_mgmt mgmt;
  320. if (prot != WLANTEST_INJECT_NORMAL &&
  321. prot != WLANTEST_INJECT_UNPROTECTED)
  322. return -1; /* Authentication frame is never protected */
  323. if (sta == NULL)
  324. return -1; /* No broadcast Authentication frames */
  325. if (sender_ap)
  326. wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
  327. MAC2STR(bss->bssid), MAC2STR(sta->addr));
  328. else
  329. wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
  330. MAC2STR(sta->addr), MAC2STR(bss->bssid));
  331. build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);
  332. mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
  333. mgmt.u.auth.auth_transaction = host_to_le16(1);
  334. mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
  335. return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
  336. WLANTEST_INJECT_UNPROTECTED);
  337. }
  338. static int ctrl_inject_saqueryreq(struct wlantest *wt,
  339. struct wlantest_bss *bss,
  340. struct wlantest_sta *sta, int sender_ap,
  341. enum wlantest_inject_protection prot)
  342. {
  343. struct ieee80211_mgmt mgmt;
  344. if (sta == NULL)
  345. return -1; /* No broadcast SA Query frames */
  346. if (sender_ap)
  347. wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
  348. MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
  349. else
  350. wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
  351. MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
  352. build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);
  353. mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
  354. mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
  355. mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
  356. mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
  357. os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
  358. mgmt.u.action.u.sa_query_req.trans_id,
  359. WLAN_SA_QUERY_TR_ID_LEN);
  360. return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
  361. }
  362. static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
  363. {
  364. u8 *bssid, *sta_addr;
  365. struct wlantest_bss *bss;
  366. struct wlantest_sta *sta;
  367. int frame, sender_ap, prot;
  368. int ret = 0;
  369. bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
  370. sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
  371. frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
  372. sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
  373. if (sender_ap < 0)
  374. sender_ap = 0;
  375. prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
  376. if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
  377. wpa_printf(MSG_INFO, "Invalid inject command parameters");
  378. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  379. return;
  380. }
  381. bss = bss_get(wt, bssid);
  382. if (bss == NULL) {
  383. wpa_printf(MSG_INFO, "BSS not found for inject command");
  384. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  385. return;
  386. }
  387. if (is_broadcast_ether_addr(sta_addr)) {
  388. if (!sender_ap) {
  389. wpa_printf(MSG_INFO, "Invalid broadcast inject "
  390. "command without sender_ap set");
  391. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  392. return;
  393. } sta = NULL;
  394. } else {
  395. sta = sta_get(bss, sta_addr);
  396. if (sta == NULL) {
  397. wpa_printf(MSG_INFO, "Station not found for inject "
  398. "command");
  399. ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
  400. return;
  401. }
  402. }
  403. switch (frame) {
  404. case WLANTEST_FRAME_AUTH:
  405. ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
  406. break;
  407. case WLANTEST_FRAME_SAQUERYREQ:
  408. ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
  409. break;
  410. default:
  411. wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
  412. frame);
  413. ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
  414. return;
  415. }
  416. if (ret)
  417. wpa_printf(MSG_INFO, "Failed to inject frame");
  418. else
  419. wpa_printf(MSG_INFO, "Frame injected successfully");
  420. ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
  421. WLANTEST_CTRL_FAILURE);
  422. }
  423. static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
  424. {
  425. struct wlantest *wt = eloop_ctx;
  426. u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
  427. int len;
  428. enum wlantest_ctrl_cmd cmd;
  429. wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
  430. sock);
  431. len = recv(sock, buf, sizeof(buf), 0);
  432. if (len < 0) {
  433. wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
  434. ctrl_disconnect(wt, sock);
  435. return;
  436. }
  437. if (len == 0) {
  438. ctrl_disconnect(wt, sock);
  439. return;
  440. }
  441. if (len < 4) {
  442. wpa_printf(MSG_INFO, "Too short control interface command "
  443. "from %d", sock);
  444. ctrl_disconnect(wt, sock);
  445. return;
  446. }
  447. cmd = WPA_GET_BE32(buf);
  448. wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
  449. cmd, sock);
  450. switch (cmd) {
  451. case WLANTEST_CTRL_PING:
  452. ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
  453. break;
  454. case WLANTEST_CTRL_TERMINATE:
  455. ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
  456. eloop_terminate();
  457. break;
  458. case WLANTEST_CTRL_LIST_BSS:
  459. ctrl_list_bss(wt, sock);
  460. break;
  461. case WLANTEST_CTRL_LIST_STA:
  462. ctrl_list_sta(wt, sock, buf + 4, len - 4);
  463. break;
  464. case WLANTEST_CTRL_FLUSH:
  465. ctrl_flush(wt, sock);
  466. break;
  467. case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
  468. ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
  469. break;
  470. case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
  471. ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
  472. break;
  473. case WLANTEST_CTRL_GET_STA_COUNTER:
  474. ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
  475. break;
  476. case WLANTEST_CTRL_GET_BSS_COUNTER:
  477. ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
  478. break;
  479. case WLANTEST_CTRL_INJECT:
  480. ctrl_inject(wt, sock, buf + 4, len - 4);
  481. break;
  482. default:
  483. ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
  484. break;
  485. }
  486. }
  487. static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
  488. {
  489. struct wlantest *wt = eloop_ctx;
  490. int conn, i;
  491. conn = accept(sock, NULL, NULL);
  492. if (conn < 0) {
  493. wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
  494. return;
  495. }
  496. wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);
  497. for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
  498. if (wt->ctrl_socks[i] < 0)
  499. break;
  500. }
  501. if (i == MAX_CTRL_CONNECTIONS) {
  502. wpa_printf(MSG_INFO, "No room for new control connection");
  503. close(conn);
  504. return;
  505. }
  506. wt->ctrl_socks[i] = conn;
  507. eloop_register_read_sock(conn, ctrl_read, wt, NULL);
  508. }
  509. int ctrl_init(struct wlantest *wt)
  510. {
  511. struct sockaddr_un addr;
  512. wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
  513. if (wt->ctrl_sock < 0) {
  514. wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
  515. return -1;
  516. }
  517. os_memset(&addr, 0, sizeof(addr));
  518. addr.sun_family = AF_UNIX;
  519. os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
  520. sizeof(addr.sun_path) - 1);
  521. if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  522. wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
  523. close(wt->ctrl_sock);
  524. wt->ctrl_sock = -1;
  525. return -1;
  526. }
  527. if (listen(wt->ctrl_sock, 5) < 0) {
  528. wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
  529. close(wt->ctrl_sock);
  530. wt->ctrl_sock = -1;
  531. return -1;
  532. }
  533. if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
  534. close(wt->ctrl_sock);
  535. wt->ctrl_sock = -1;
  536. return -1;
  537. }
  538. return 0;
  539. }
  540. void ctrl_deinit(struct wlantest *wt)
  541. {
  542. int i;
  543. if (wt->ctrl_sock < 0)
  544. return;
  545. for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
  546. if (wt->ctrl_socks[i] >= 0) {
  547. close(wt->ctrl_socks[i]);
  548. eloop_unregister_read_sock(wt->ctrl_socks[i]);
  549. wt->ctrl_socks[i] = -1;
  550. }
  551. }
  552. eloop_unregister_read_sock(wt->ctrl_sock);
  553. close(wt->ctrl_sock);
  554. wt->ctrl_sock = -1;
  555. }