driver_prism54.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449
  1. /*
  2. * WPA Supplicant - driver interaction with Linux Prism54.org driver
  3. * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
  4. * Copyright (c) 2004, Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
  5. * Copyright (c) 2004, Bell Kin <bell_kin@pek.com.tw>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * Alternatively, this software may be distributed under the terms of BSD
  12. * license.
  13. *
  14. * See README and COPYING for more details.
  15. */
  16. #include "includes.h"
  17. #include <sys/ioctl.h>
  18. #include "wireless_copy.h"
  19. #include "common.h"
  20. #include "driver.h"
  21. #include "driver_wext.h"
  22. #include "driver_hostap.h"
  23. #ifdef HOSTAPD
  24. #include <net/if_arp.h>
  25. #include <netpacket/packet.h>
  26. #include "driver.h"
  27. #include "eloop.h"
  28. #include "prism54.h"
  29. #include "radius/radius.h"
  30. #include "../../hostapd/hostapd.h"
  31. #include "../../hostapd/config.h"
  32. #include "../../hostapd/ieee802_1x.h"
  33. #include "../../hostapd/ieee802_11.h"
  34. #include "../../hostapd/wpa.h"
  35. #include "../../hostapd/sta_flags.h"
  36. #include "../../hostapd/sta_info.h"
  37. const int PIM_BUF_SIZE = 4096;
  38. struct prism54_driver_data {
  39. struct hostapd_data *hapd;
  40. char iface[IFNAMSIZ + 1];
  41. int sock; /* raw packet socket for 802.3 access */
  42. int pim_sock; /* socket for pimfor packet */
  43. char macs[2007][6];
  44. };
  45. static int mac_id_refresh(struct prism54_driver_data *data, int id, char *mac)
  46. {
  47. if (id < 0 || id > 2006) {
  48. return -1;
  49. }
  50. memcpy(&data->macs[id][0], mac, ETH_ALEN);
  51. return 0;
  52. }
  53. static char * mac_id_get(struct prism54_driver_data *data, int id)
  54. {
  55. if (id < 0 || id > 2006) {
  56. return NULL;
  57. }
  58. return &data->macs[id][0];
  59. }
  60. /* wait for a specific pimfor, timeout in 10ms resolution */
  61. /* pim_sock must be non-block to prevent dead lock from no response */
  62. /* or same response type in series */
  63. static int prism54_waitpim(void *priv, unsigned long oid, void *buf, int len,
  64. int timeout)
  65. {
  66. struct prism54_driver_data *drv = priv;
  67. struct timeval tv, stv, ctv;
  68. fd_set pfd;
  69. int rlen;
  70. pimdev_hdr *pkt;
  71. pkt = malloc(8192);
  72. if (pkt == NULL)
  73. return -1;
  74. FD_ZERO(&pfd);
  75. gettimeofday(&stv, NULL);
  76. do {
  77. FD_SET(drv->pim_sock, &pfd);
  78. tv.tv_sec = 0;
  79. tv.tv_usec = 10000;
  80. if (select(drv->pim_sock + 1, &pfd, NULL, NULL, &tv)) {
  81. rlen = recv(drv->pim_sock, pkt, 8192, 0);
  82. if (rlen > 0) {
  83. if (pkt->oid == htonl(oid)) {
  84. if (rlen <= len) {
  85. if (buf != NULL) {
  86. memcpy(buf, pkt, rlen);
  87. }
  88. free(pkt);
  89. return rlen;
  90. } else {
  91. printf("buffer too small\n");
  92. free(pkt);
  93. return -1;
  94. }
  95. } else {
  96. gettimeofday(&ctv, NULL);
  97. continue;
  98. }
  99. }
  100. }
  101. gettimeofday(&ctv, NULL);
  102. } while (((ctv.tv_sec - stv.tv_sec) * 100 +
  103. (ctv.tv_usec - stv.tv_usec) / 10000) > timeout);
  104. free(pkt);
  105. return 0;
  106. }
  107. /* send an eapol packet */
  108. static int prism54_send_eapol(void *priv, const u8 *addr,
  109. const u8 *data, size_t data_len, int encrypt,
  110. const u8 *own_addr)
  111. {
  112. struct prism54_driver_data *drv = priv;
  113. ieee802_3_hdr *hdr;
  114. size_t len;
  115. u8 *pos;
  116. int res;
  117. len = sizeof(*hdr) + data_len;
  118. hdr = os_zalloc(len);
  119. if (hdr == NULL) {
  120. printf("malloc() failed for prism54_send_data(len=%lu)\n",
  121. (unsigned long) len);
  122. return -1;
  123. }
  124. memcpy(&hdr->da[0], addr, ETH_ALEN);
  125. memcpy(&hdr->sa[0], own_addr, ETH_ALEN);
  126. hdr->type = htons(ETH_P_PAE);
  127. pos = (u8 *) (hdr + 1);
  128. memcpy(pos, data, data_len);
  129. res = send(drv->sock, hdr, len, 0);
  130. free(hdr);
  131. if (res < 0) {
  132. perror("hostapd_send_eapol: send");
  133. printf("hostapd_send_eapol - packet len: %lu - failed\n",
  134. (unsigned long) len);
  135. }
  136. return res;
  137. }
  138. /* open data channel(auth-1) or eapol only(unauth-0) */
  139. static int prism54_set_sta_authorized(void *priv, const u8 *addr,
  140. int authorized)
  141. {
  142. struct prism54_driver_data *drv = priv;
  143. pimdev_hdr *hdr;
  144. char *pos;
  145. hdr = os_zalloc(sizeof(*hdr) + ETH_ALEN);
  146. if (hdr == NULL)
  147. return -1;
  148. hdr->op = htonl(PIMOP_SET);
  149. if (authorized) {
  150. hdr->oid = htonl(DOT11_OID_EAPAUTHSTA);
  151. } else {
  152. hdr->oid = htonl(DOT11_OID_EAPUNAUTHSTA);
  153. }
  154. pos = (char *) (hdr + 1);
  155. memcpy(pos, addr, ETH_ALEN);
  156. send(drv->pim_sock, hdr, sizeof(*hdr) + ETH_ALEN, 0);
  157. prism54_waitpim(priv, hdr->oid, hdr, sizeof(*hdr) + ETH_ALEN, 10);
  158. free(hdr);
  159. return 0;
  160. }
  161. static int
  162. prism54_sta_set_flags(void *priv, const u8 *addr, int total_flags,
  163. int flags_or, int flags_and)
  164. {
  165. /* For now, only support setting Authorized flag */
  166. if (flags_or & WLAN_STA_AUTHORIZED)
  167. return prism54_set_sta_authorized(priv, addr, 1);
  168. if (flags_and & WLAN_STA_AUTHORIZED)
  169. return prism54_set_sta_authorized(priv, addr, 0);
  170. return 0;
  171. }
  172. static int wpa_driver_prism54_set_key(const char *ifname, void *priv,
  173. wpa_alg alg, const u8 *addr, int key_idx,
  174. int set_tx,
  175. const u8 *seq, size_t seq_len,
  176. const u8 *key, size_t key_len)
  177. {
  178. struct prism54_driver_data *drv = priv;
  179. pimdev_hdr *hdr;
  180. struct obj_stakey *keys;
  181. u8 *buf;
  182. size_t blen;
  183. int ret = 0;
  184. blen = sizeof(struct obj_stakey) + sizeof(pimdev_hdr);
  185. hdr = os_zalloc(blen);
  186. if (hdr == NULL) {
  187. printf("memory low\n");
  188. return -1;
  189. }
  190. keys = (struct obj_stakey *) &hdr[1];
  191. if (!addr) {
  192. memset(&keys->address[0], 0xff, ETH_ALEN);
  193. } else {
  194. memcpy(&keys->address[0], addr, ETH_ALEN);
  195. }
  196. switch (alg) {
  197. case WPA_ALG_WEP:
  198. keys->type = DOT11_PRIV_WEP;
  199. break;
  200. case WPA_ALG_TKIP:
  201. keys->type = DOT11_PRIV_TKIP;
  202. break;
  203. case WPA_ALG_NONE:
  204. /* the only way to clear the key is to deauth it */
  205. /* and prism54 is capable to receive unencrypted packet */
  206. /* so we do nothing here */
  207. free(hdr);
  208. return 0;
  209. default:
  210. printf("bad auth type: %d\n", alg);
  211. free(hdr);
  212. return -1;
  213. }
  214. buf = (u8 *) &keys->key[0];
  215. keys->length = key_len;
  216. keys->keyid = key_idx;
  217. keys->options = htons(DOT11_STAKEY_OPTION_DEFAULTKEY);
  218. keys->reserved = 0;
  219. hdr->op = htonl(PIMOP_SET);
  220. hdr->oid = htonl(DOT11_OID_STAKEY);
  221. memcpy(buf, key, key_len);
  222. ret = send(drv->pim_sock, hdr, blen, 0);
  223. if (ret < 0) {
  224. free(hdr);
  225. return ret;
  226. }
  227. prism54_waitpim(priv, hdr->oid, hdr, blen, 10);
  228. free(hdr);
  229. return 0;
  230. }
  231. /* get TKIP station sequence counter, prism54 is only 6 bytes */
  232. static int prism54_get_seqnum(const char *ifname, void *priv, const u8 *addr,
  233. int idx, u8 *seq)
  234. {
  235. struct prism54_driver_data *drv = priv;
  236. struct obj_stasc *stasc;
  237. pimdev_hdr *hdr;
  238. size_t blen;
  239. int ret = 0;
  240. blen = sizeof(*stasc) + sizeof(*hdr);
  241. hdr = os_zalloc(blen);
  242. if (hdr == NULL)
  243. return -1;
  244. stasc = (struct obj_stasc *) &hdr[1];
  245. if (addr == NULL)
  246. memset(&stasc->address[0], 0xff, ETH_ALEN);
  247. else
  248. memcpy(&stasc->address[0], addr, ETH_ALEN);
  249. hdr->oid = htonl(DOT11_OID_STASC);
  250. hdr->op = htonl(PIMOP_GET);
  251. stasc->keyid = idx;
  252. if (send(drv->pim_sock,hdr,blen,0) <= 0) {
  253. free(hdr);
  254. return -1;
  255. }
  256. if (prism54_waitpim(priv, DOT11_OID_STASC, hdr, blen, 10) <= 0) {
  257. ret = -1;
  258. } else {
  259. if (hdr->op == (int) htonl(PIMOP_RESPONSE)) {
  260. memcpy(seq + 2, &stasc->sc_high, ETH_ALEN);
  261. memset(seq, 0, 2);
  262. } else {
  263. ret = -1;
  264. }
  265. }
  266. free(hdr);
  267. return ret;
  268. }
  269. /* include unencrypted, set mlme autolevel to extended */
  270. static int prism54_init_1x(void *priv)
  271. {
  272. struct prism54_driver_data *drv = priv;
  273. pimdev_hdr *hdr;
  274. unsigned long *ul;
  275. int blen = sizeof(*hdr) + sizeof(*ul);
  276. hdr = os_zalloc(blen);
  277. if (hdr == NULL)
  278. return -1;
  279. ul = (unsigned long *) &hdr[1];
  280. hdr->op = htonl(PIMOP_SET);
  281. hdr->oid = htonl(DOT11_OID_EXUNENCRYPTED);
  282. *ul = htonl(DOT11_BOOL_TRUE); /* not accept */
  283. send(drv->pim_sock, hdr, blen, 0);
  284. prism54_waitpim(priv, DOT11_OID_EXUNENCRYPTED, hdr, blen, 10);
  285. hdr->op = htonl(PIMOP_SET);
  286. hdr->oid = htonl(DOT11_OID_MLMEAUTOLEVEL);
  287. *ul = htonl(DOT11_MLME_EXTENDED);
  288. send(drv->pim_sock, hdr, blen, 0);
  289. prism54_waitpim(priv, DOT11_OID_MLMEAUTOLEVEL, hdr, blen, 10);
  290. hdr->op = htonl(PIMOP_SET);
  291. hdr->oid = htonl(DOT11_OID_DOT1XENABLE);
  292. *ul = htonl(DOT11_BOOL_TRUE);
  293. send(drv->pim_sock, hdr, blen, 0);
  294. prism54_waitpim(priv, DOT11_OID_DOT1XENABLE, hdr, blen, 10);
  295. hdr->op = htonl(PIMOP_SET);
  296. hdr->oid = htonl(DOT11_OID_AUTHENABLE);
  297. *ul = htonl(DOT11_AUTH_OS); /* OS */
  298. send(drv->pim_sock, hdr, blen, 0);
  299. prism54_waitpim(priv, DOT11_OID_AUTHENABLE, hdr, blen, 10);
  300. free(hdr);
  301. return 0;
  302. }
  303. static int prism54_set_privacy_invoked(const char *ifname, void *priv,
  304. int flag)
  305. {
  306. struct prism54_driver_data *drv = priv;
  307. pimdev_hdr *hdr;
  308. unsigned long *ul;
  309. int ret;
  310. int blen = sizeof(*hdr) + sizeof(*ul);
  311. hdr = os_zalloc(blen);
  312. if (hdr == NULL)
  313. return -1;
  314. ul = (unsigned long *) &hdr[1];
  315. hdr->op = htonl(PIMOP_SET);
  316. hdr->oid = htonl(DOT11_OID_PRIVACYINVOKED);
  317. if (flag) {
  318. *ul = htonl(DOT11_BOOL_TRUE); /* has privacy */
  319. } else {
  320. *ul = 0;
  321. }
  322. ret = send(drv->pim_sock, hdr, blen, 0);
  323. if (ret >= 0) {
  324. ret = prism54_waitpim(priv, DOT11_OID_PRIVACYINVOKED, hdr,
  325. blen, 10);
  326. }
  327. free(hdr);
  328. return ret;
  329. }
  330. static int prism54_ioctl_setiwessid(const char *ifname, void *priv,
  331. const u8 *buf, int len)
  332. {
  333. #if 0
  334. struct prism54_driver_data *drv = priv;
  335. struct iwreq iwr;
  336. memset(&iwr, 0, sizeof(iwr));
  337. os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
  338. iwr.u.essid.flags = 1; /* SSID active */
  339. iwr.u.essid.pointer = (caddr_t) buf;
  340. iwr.u.essid.length = len + 1;
  341. if (ioctl(drv->pim_sock, SIOCSIWESSID, &iwr) < 0) {
  342. perror("ioctl[SIOCSIWESSID]");
  343. printf("len=%d\n", len);
  344. return -1;
  345. }
  346. #endif
  347. return 0;
  348. }
  349. /* kick all stations */
  350. /* does not work during init, but at least it won't crash firmware */
  351. static int prism54_flush(void *priv)
  352. {
  353. struct prism54_driver_data *drv = priv;
  354. struct obj_mlmeex *mlme;
  355. pimdev_hdr *hdr;
  356. int ret;
  357. unsigned int i;
  358. long *nsta;
  359. int blen = sizeof(*hdr) + sizeof(*mlme);
  360. char *mac_id;
  361. hdr = os_zalloc(blen);
  362. if (hdr == NULL)
  363. return -1;
  364. mlme = (struct obj_mlmeex *) &hdr[1];
  365. nsta = (long *) &hdr[1];
  366. hdr->op = htonl(PIMOP_GET);
  367. hdr->oid = htonl(DOT11_OID_CLIENTS);
  368. ret = send(drv->pim_sock, hdr, sizeof(*hdr) + sizeof(long), 0);
  369. ret = prism54_waitpim(priv, DOT11_OID_CLIENTS, hdr, blen, 10);
  370. if ((ret < 0) || (hdr->op != (int) htonl(PIMOP_RESPONSE)) ||
  371. (le_to_host32(*nsta) > 2007)) {
  372. free(hdr);
  373. return 0;
  374. }
  375. for (i = 0; i < le_to_host32(*nsta); i++) {
  376. mlme->id = -1;
  377. mac_id = mac_id_get(drv, i);
  378. if (mac_id)
  379. memcpy(&mlme->address[0], mac_id, ETH_ALEN);
  380. mlme->code = host_to_le16(WLAN_REASON_UNSPECIFIED);
  381. mlme->state = htons(DOT11_STATE_NONE);
  382. mlme->size = 0;
  383. hdr->op = htonl(PIMOP_SET);
  384. hdr->oid = htonl(DOT11_OID_DISASSOCIATEEX);
  385. ret = send(drv->pim_sock, hdr, blen, 0);
  386. prism54_waitpim(priv, DOT11_OID_DISASSOCIATEEX, hdr, blen,
  387. 100);
  388. }
  389. for (i = 0; i < le_to_host32(*nsta); i++) {
  390. mlme->id = -1;
  391. mac_id = mac_id_get(drv, i);
  392. if (mac_id)
  393. memcpy(&mlme->address[0], mac_id, ETH_ALEN);
  394. mlme->code = host_to_le16(WLAN_REASON_UNSPECIFIED);
  395. mlme->state = htons(DOT11_STATE_NONE);
  396. mlme->size = 0;
  397. hdr->op = htonl(PIMOP_SET);
  398. hdr->oid = htonl(DOT11_OID_DEAUTHENTICATEEX);
  399. ret = send(drv->pim_sock, hdr, blen, 0);
  400. prism54_waitpim(priv, DOT11_OID_DEAUTHENTICATEEX, hdr, blen,
  401. 100);
  402. }
  403. free(hdr);
  404. return 0;
  405. }
  406. static int prism54_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
  407. int reason)
  408. {
  409. struct prism54_driver_data *drv = priv;
  410. pimdev_hdr *hdr;
  411. struct obj_mlmeex *mlme;
  412. int ret;
  413. int blen = sizeof(*hdr) + sizeof(*mlme);
  414. hdr = os_zalloc(blen);
  415. if (hdr == NULL)
  416. return -1;
  417. mlme = (struct obj_mlmeex *) &hdr[1];
  418. hdr->op = htonl(PIMOP_SET);
  419. hdr->oid = htonl(DOT11_OID_DEAUTHENTICATEEX);
  420. memcpy(&mlme->address[0], addr, ETH_ALEN);
  421. mlme->id = -1;
  422. mlme->state = htons(DOT11_STATE_NONE);
  423. mlme->code = host_to_le16(reason);
  424. mlme->size = 0;
  425. ret = send(drv->pim_sock, hdr, blen, 0);
  426. prism54_waitpim(priv, DOT11_OID_DEAUTHENTICATEEX, hdr, blen, 10);
  427. free(hdr);
  428. return ret;
  429. }
  430. static int prism54_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
  431. int reason)
  432. {
  433. struct prism54_driver_data *drv = priv;
  434. pimdev_hdr *hdr;
  435. struct obj_mlmeex *mlme;
  436. int ret;
  437. int blen = sizeof(*hdr) + sizeof(*mlme);
  438. hdr = os_zalloc(blen);
  439. if (hdr == NULL)
  440. return -1;
  441. mlme = (struct obj_mlmeex *) &hdr[1];
  442. hdr->op = htonl(PIMOP_SET);
  443. hdr->oid = htonl(DOT11_OID_DISASSOCIATEEX);
  444. memcpy(&mlme->address[0], addr, ETH_ALEN);
  445. mlme->id = -1;
  446. mlme->state = htons(DOT11_STATE_NONE);
  447. mlme->code = host_to_le16(reason);
  448. mlme->size = 0;
  449. ret = send(drv->pim_sock, hdr, blen, 0);
  450. prism54_waitpim(priv, DOT11_OID_DISASSOCIATEEX, hdr, blen, 10);
  451. free(hdr);
  452. return ret;
  453. }
  454. static int prism54_get_inact_sec(void *priv, const u8 *addr)
  455. {
  456. struct prism54_driver_data *drv = priv;
  457. pimdev_hdr *hdr;
  458. struct obj_sta *sta;
  459. int blen = sizeof(*hdr) + sizeof(*sta);
  460. int ret;
  461. hdr = os_zalloc(blen);
  462. if (hdr == NULL)
  463. return -1;
  464. hdr->op = htonl(PIMOP_GET);
  465. hdr->oid = htonl(DOT11_OID_CLIENTFIND);
  466. sta = (struct obj_sta *) &hdr[1];
  467. memcpy(&sta->address[0], addr, ETH_ALEN);
  468. ret = send(drv->pim_sock, hdr, blen, 0);
  469. ret = prism54_waitpim(priv, DOT11_OID_CLIENTFIND, hdr, blen, 10);
  470. if (ret != blen) {
  471. printf("get_inact_sec: bad return %d\n", ret);
  472. free(hdr);
  473. return -1;
  474. }
  475. if (hdr->op != (int) htonl(PIMOP_RESPONSE)) {
  476. printf("get_inact_sec: bad resp\n");
  477. free(hdr);
  478. return -1;
  479. }
  480. free(hdr);
  481. return le_to_host16(sta->age);
  482. }
  483. /* set attachments */
  484. static int prism54_set_generic_elem(const char *ifname, void *priv,
  485. const u8 *elem, size_t elem_len)
  486. {
  487. struct prism54_driver_data *drv = priv;
  488. pimdev_hdr *hdr;
  489. char *pos;
  490. struct obj_attachment_hdr *attach;
  491. size_t blen = sizeof(*hdr) + sizeof(*attach) + elem_len;
  492. hdr = os_zalloc(blen);
  493. if (hdr == NULL) {
  494. printf("%s: memory low\n", __func__);
  495. return -1;
  496. }
  497. hdr->op = htonl(PIMOP_SET);
  498. hdr->oid = htonl(DOT11_OID_ATTACHMENT);
  499. attach = (struct obj_attachment_hdr *)&hdr[1];
  500. attach->type = DOT11_PKT_BEACON;
  501. attach->id = -1;
  502. attach->size = host_to_le16((short)elem_len);
  503. pos = ((char*) attach) + sizeof(*attach);
  504. if (elem)
  505. memcpy(pos, elem, elem_len);
  506. send(drv->pim_sock, hdr, blen, 0);
  507. attach->type = DOT11_PKT_PROBE_RESP;
  508. send(drv->pim_sock, hdr, blen, 0);
  509. free(hdr);
  510. return 0;
  511. }
  512. /* tell the card to auth the sta */
  513. static void prism54_handle_probe(struct prism54_driver_data *drv,
  514. void *buf, size_t len)
  515. {
  516. struct obj_mlmeex *mlme;
  517. pimdev_hdr *hdr;
  518. struct sta_info *sta;
  519. hdr = (pimdev_hdr *)buf;
  520. mlme = (struct obj_mlmeex *) &hdr[1];
  521. sta = ap_get_sta(drv->hapd, (u8 *) &mlme->address[0]);
  522. if (sta != NULL) {
  523. if (sta->flags & (WLAN_STA_AUTH | WLAN_STA_ASSOC))
  524. return;
  525. }
  526. if (len < sizeof(*mlme)) {
  527. printf("bad probe packet\n");
  528. return;
  529. }
  530. mlme->state = htons(DOT11_STATE_AUTHING);
  531. mlme->code = 0;
  532. hdr->op = htonl(PIMOP_SET);
  533. hdr->oid = htonl(DOT11_OID_AUTHENTICATEEX);
  534. mlme->size = 0;
  535. send(drv->pim_sock, hdr, sizeof(*hdr)+sizeof(*mlme), 0);
  536. }
  537. static void prism54_handle_deauth(struct prism54_driver_data *drv,
  538. void *buf, size_t len)
  539. {
  540. struct obj_mlme *mlme;
  541. pimdev_hdr *hdr;
  542. struct sta_info *sta;
  543. char *mac_id;
  544. hdr = (pimdev_hdr *) buf;
  545. mlme = (struct obj_mlme *) &hdr[1];
  546. sta = ap_get_sta(drv->hapd, (u8 *) &mlme->address[0]);
  547. mac_id = mac_id_get(drv, mlme->id);
  548. if (sta == NULL || mac_id == NULL)
  549. return;
  550. memcpy(&mlme->address[0], mac_id, ETH_ALEN);
  551. sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
  552. wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
  553. sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
  554. ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
  555. ap_free_sta(drv->hapd, sta);
  556. }
  557. static void prism54_handle_disassoc(struct prism54_driver_data *drv,
  558. void *buf, size_t len)
  559. {
  560. struct obj_mlme *mlme;
  561. pimdev_hdr *hdr;
  562. char *mac_id;
  563. hdr = (pimdev_hdr *) buf;
  564. mlme = (struct obj_mlme *) &hdr[1];
  565. mac_id = mac_id_get(drv, mlme->id);
  566. if (mac_id == NULL)
  567. return;
  568. hostapd_notif_disassoc(drv->hapd, (u8 *) mac_id);
  569. }
  570. /* to auth it, just allow it now, later for os/sk */
  571. static void prism54_handle_auth(struct prism54_driver_data *drv,
  572. void *buf, size_t len)
  573. {
  574. struct obj_mlmeex *mlme;
  575. pimdev_hdr *hdr;
  576. struct sta_info *sta;
  577. int resp;
  578. hdr = (pimdev_hdr *) buf;
  579. mlme = (struct obj_mlmeex *) &hdr[1];
  580. if (len < sizeof(*mlme)) {
  581. printf("bad auth packet\n");
  582. return;
  583. }
  584. if (mlme->state == htons(DOT11_STATE_AUTHING)) {
  585. sta = ap_sta_add(drv->hapd, (u8 *) &mlme->address[0]);
  586. if (drv->hapd->tkip_countermeasures) {
  587. resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
  588. goto fail;
  589. }
  590. mac_id_refresh(drv, mlme->id, &mlme->address[0]);
  591. if (!sta) {
  592. resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  593. goto fail;
  594. }
  595. sta->flags &= ~WLAN_STA_PREAUTH;
  596. ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
  597. sta->flags |= WLAN_STA_AUTH;
  598. wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
  599. mlme->code = 0;
  600. mlme->state=htons(DOT11_STATE_AUTH);
  601. hdr->op = htonl(PIMOP_SET);
  602. hdr->oid = htonl(DOT11_OID_AUTHENTICATEEX);
  603. mlme->size = 0;
  604. sta->timeout_next = STA_NULLFUNC;
  605. send(drv->pim_sock, hdr, sizeof(*hdr) + sizeof(*mlme), 0);
  606. }
  607. return;
  608. fail:
  609. printf("auth fail: %x\n", resp);
  610. mlme->code = host_to_le16(resp);
  611. mlme->size = 0;
  612. if (sta)
  613. sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
  614. hdr->oid = htonl(DOT11_OID_DEAUTHENTICATEEX);
  615. hdr->op = htonl(PIMOP_SET);
  616. send(drv->pim_sock, hdr, sizeof(*hdr)+sizeof(*mlme), 0);
  617. }
  618. /* do the wpa thing */
  619. static void prism54_handle_assoc(struct prism54_driver_data *drv,
  620. void *buf, size_t len)
  621. {
  622. pimdev_hdr *hdr;
  623. struct obj_mlmeex *mlme;
  624. struct ieee802_11_elems elems;
  625. struct sta_info *sta;
  626. u8 *wpa_ie;
  627. u8 *cb;
  628. int ieofs = 0;
  629. size_t wpa_ie_len;
  630. int resp, new_assoc;
  631. char *mac_id;
  632. resp = 0;
  633. hdr = (pimdev_hdr *) buf;
  634. mlme = (struct obj_mlmeex *) &hdr[1];
  635. switch (ntohl(hdr->oid)) {
  636. case DOT11_OID_ASSOCIATE:
  637. case DOT11_OID_REASSOCIATE:
  638. mlme->size = 0;
  639. default:
  640. break;
  641. }
  642. if ((mlme->state == (int) htonl(DOT11_STATE_ASSOCING)) ||
  643. (mlme->state == (int) htonl(DOT11_STATE_REASSOCING))) {
  644. if (len < sizeof(pimdev_hdr) + sizeof(struct obj_mlme)) {
  645. printf("bad assoc packet\n");
  646. return;
  647. }
  648. mac_id = mac_id_get(drv, mlme->id);
  649. if (mac_id == NULL)
  650. return;
  651. memcpy(&mlme->address[0], mac_id, ETH_ALEN);
  652. sta = ap_get_sta(drv->hapd, (u8 *) &mlme->address[0]);
  653. if (sta == NULL) {
  654. printf("cannot get sta\n");
  655. return;
  656. }
  657. cb = (u8 *) &mlme->data[0];
  658. if (hdr->oid == htonl(DOT11_OID_ASSOCIATEEX)) {
  659. ieofs = 4;
  660. } else if (hdr->oid == htonl(DOT11_OID_REASSOCIATEEX)) {
  661. ieofs = 10;
  662. }
  663. if (le_to_host16(mlme->size) <= ieofs) {
  664. printf("attach too small\n");
  665. resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  666. goto fail;
  667. }
  668. if (ieee802_11_parse_elems(cb + ieofs,
  669. le_to_host16(mlme->size) - ieofs,
  670. &elems, 1) == ParseFailed) {
  671. printf("STA " MACSTR " sent invalid association "
  672. "request\n", MAC2STR(sta->addr));
  673. resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  674. goto fail;
  675. }
  676. if ((drv->hapd->conf->wpa & WPA_PROTO_RSN) &&
  677. elems.rsn_ie) {
  678. wpa_ie = elems.rsn_ie;
  679. wpa_ie_len = elems.rsn_ie_len;
  680. } else if ((drv->hapd->conf->wpa & WPA_PROTO_WPA) &&
  681. elems.wpa_ie) {
  682. wpa_ie = elems.wpa_ie;
  683. wpa_ie_len = elems.wpa_ie_len;
  684. } else {
  685. wpa_ie = NULL;
  686. wpa_ie_len = 0;
  687. }
  688. if (drv->hapd->conf->wpa && wpa_ie == NULL) {
  689. printf("STA " MACSTR ": No WPA/RSN IE in association "
  690. "request\n", MAC2STR(sta->addr));
  691. resp = WLAN_STATUS_INVALID_IE;
  692. goto fail;
  693. }
  694. if (drv->hapd->conf->wpa) {
  695. int res;
  696. wpa_ie -= 2;
  697. wpa_ie_len += 2;
  698. if (sta->wpa_sm == NULL)
  699. sta->wpa_sm = wpa_auth_sta_init(
  700. drv->hapd->wpa_auth, sta->addr);
  701. if (sta->wpa_sm == NULL) {
  702. printf("Failed to initialize WPA state "
  703. "machine\n");
  704. resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  705. goto fail;
  706. }
  707. res = wpa_validate_wpa_ie(drv->hapd->wpa_auth,
  708. sta->wpa_sm,
  709. wpa_ie, wpa_ie_len,
  710. NULL, 0);
  711. if (res == WPA_INVALID_GROUP)
  712. resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
  713. else if (res == WPA_INVALID_PAIRWISE)
  714. resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
  715. else if (res == WPA_INVALID_AKMP)
  716. resp = WLAN_STATUS_AKMP_NOT_VALID;
  717. else if (res == WPA_ALLOC_FAIL)
  718. resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
  719. else if (res != WPA_IE_OK)
  720. resp = WLAN_STATUS_INVALID_IE;
  721. if (resp != WLAN_STATUS_SUCCESS)
  722. goto fail;
  723. }
  724. hdr->oid = (hdr->oid == htonl(DOT11_OID_ASSOCIATEEX)) ?
  725. htonl(DOT11_OID_ASSOCIATEEX) :
  726. htonl(DOT11_OID_REASSOCIATEEX);
  727. hdr->op = htonl(PIMOP_SET);
  728. mlme->code = 0;
  729. mlme->state = htons(DOT11_STATE_ASSOC);
  730. mlme->size = 0;
  731. send(drv->pim_sock, hdr, sizeof(*hdr) + sizeof(*mlme), 0);
  732. return;
  733. } else if (mlme->state==htons(DOT11_STATE_ASSOC)) {
  734. if (len < sizeof(pimdev_hdr) + sizeof(struct obj_mlme)) {
  735. printf("bad assoc packet\n");
  736. return;
  737. }
  738. mac_id = mac_id_get(drv, mlme->id);
  739. if (mac_id == NULL)
  740. return;
  741. memcpy(&mlme->address[0], mac_id, ETH_ALEN);
  742. sta = ap_get_sta(drv->hapd, (u8 *) &mlme->address[0]);
  743. if (sta == NULL) {
  744. printf("cannot get sta\n");
  745. return;
  746. }
  747. new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
  748. sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
  749. wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
  750. hostapd_new_assoc_sta(drv->hapd, sta, !new_assoc);
  751. ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
  752. sta->timeout_next = STA_NULLFUNC;
  753. return;
  754. }
  755. return;
  756. fail:
  757. printf("Prism54: assoc fail: %x\n", resp);
  758. mlme->code = host_to_le16(resp);
  759. mlme->size = 0;
  760. mlme->state = htons(DOT11_STATE_ASSOCING);
  761. hdr->oid = htonl(DOT11_OID_DISASSOCIATEEX);
  762. hdr->op = htonl(PIMOP_SET);
  763. sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
  764. send(drv->pim_sock, hdr, sizeof(*hdr) + sizeof(*mlme), 0);
  765. }
  766. static void handle_pim(int sock, void *eloop_ctx, void *sock_ctx)
  767. {
  768. struct prism54_driver_data *drv = eloop_ctx;
  769. int len;
  770. pimdev_hdr *hdr;
  771. hdr = malloc(PIM_BUF_SIZE);
  772. if (hdr == NULL)
  773. return;
  774. len = recv(sock, hdr, PIM_BUF_SIZE, 0);
  775. if (len < 0) {
  776. perror("recv");
  777. free(hdr);
  778. return;
  779. }
  780. if (len < 8) {
  781. printf("handle_pim: too short (%d)\n", len);
  782. free(hdr);
  783. return;
  784. }
  785. if (hdr->op != (int) htonl(PIMOP_TRAP)) {
  786. free(hdr);
  787. return;
  788. }
  789. switch (ntohl(hdr->oid)) {
  790. case DOT11_OID_PROBE:
  791. prism54_handle_probe(drv, hdr, len);
  792. break;
  793. case DOT11_OID_DEAUTHENTICATEEX:
  794. case DOT11_OID_DEAUTHENTICATE:
  795. prism54_handle_deauth(drv, hdr, len);
  796. break;
  797. case DOT11_OID_DISASSOCIATEEX:
  798. case DOT11_OID_DISASSOCIATE:
  799. prism54_handle_disassoc(drv, hdr, len);
  800. break;
  801. case DOT11_OID_AUTHENTICATEEX:
  802. case DOT11_OID_AUTHENTICATE:
  803. prism54_handle_auth(drv, hdr, len);
  804. break;
  805. case DOT11_OID_ASSOCIATEEX:
  806. case DOT11_OID_REASSOCIATEEX:
  807. case DOT11_OID_ASSOCIATE:
  808. case DOT11_OID_REASSOCIATE:
  809. prism54_handle_assoc(drv, hdr, len);
  810. default:
  811. break;
  812. }
  813. free(hdr);
  814. }
  815. static void handle_802_3(int sock, void *eloop_ctx, void *sock_ctx)
  816. {
  817. struct hostapd_data *hapd = (struct hostapd_data *) eloop_ctx;
  818. int len;
  819. ieee802_3_hdr *hdr;
  820. hdr = malloc(PIM_BUF_SIZE);
  821. if (hdr == NULL)
  822. return;
  823. len = recv(sock, hdr, PIM_BUF_SIZE, 0);
  824. if (len < 0) {
  825. perror("recv");
  826. free(hdr);
  827. return;
  828. }
  829. if (len < 14) {
  830. wpa_printf(MSG_MSGDUMP, "handle_802_3: too short (%d)", len);
  831. free(hdr);
  832. return;
  833. }
  834. if (hdr->type == htons(ETH_P_PAE)) {
  835. hostapd_eapol_receive(hapd, (u8 *) &hdr->sa[0], (u8 *) &hdr[1],
  836. len - sizeof(*hdr));
  837. }
  838. free(hdr);
  839. }
  840. static int prism54_init_sockets(struct prism54_driver_data *drv,
  841. struct wpa_init_params *params)
  842. {
  843. struct ifreq ifr;
  844. struct sockaddr_ll addr;
  845. drv->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE));
  846. if (drv->sock < 0) {
  847. perror("socket[PF_PACKET,SOCK_RAW]");
  848. return -1;
  849. }
  850. if (eloop_register_read_sock(drv->sock, handle_802_3, drv->hapd, NULL))
  851. {
  852. printf("Could not register read socket\n");
  853. return -1;
  854. }
  855. memset(&ifr, 0, sizeof(ifr));
  856. if (params->num_bridge && params->bridge[0]) {
  857. printf("opening bridge: %s\n", params->bridge[0]);
  858. os_strlcpy(ifr.ifr_name, params->bridge[0],
  859. sizeof(ifr.ifr_name));
  860. } else {
  861. os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
  862. }
  863. if (ioctl(drv->sock, SIOCGIFINDEX, &ifr) != 0) {
  864. perror("ioctl(SIOCGIFINDEX)");
  865. return -1;
  866. }
  867. memset(&addr, 0, sizeof(addr));
  868. addr.sll_family = AF_PACKET;
  869. addr.sll_ifindex = ifr.ifr_ifindex;
  870. addr.sll_protocol = htons(ETH_P_PAE);
  871. wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
  872. addr.sll_ifindex);
  873. if (bind(drv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  874. perror("bind");
  875. return -1;
  876. }
  877. memset(&ifr, 0, sizeof(ifr));
  878. os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
  879. if (ioctl(drv->sock, SIOCGIFHWADDR, &ifr) != 0) {
  880. perror("ioctl(SIOCGIFHWADDR)");
  881. return -1;
  882. }
  883. if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
  884. printf("Invalid HW-addr family 0x%04x\n",
  885. ifr.ifr_hwaddr.sa_family);
  886. return -1;
  887. }
  888. memcpy(params->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
  889. drv->pim_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  890. if (drv->pim_sock < 0) {
  891. perror("socket[PF_PACKET,SOCK_RAW]");
  892. return -1;
  893. }
  894. if (eloop_register_read_sock(drv->pim_sock, handle_pim, drv, NULL)) {
  895. printf("Could not register read socket\n");
  896. return -1;
  897. }
  898. memset(&ifr, 0, sizeof(ifr));
  899. snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%sap", drv->iface);
  900. if (ioctl(drv->pim_sock, SIOCGIFINDEX, &ifr) != 0) {
  901. perror("ioctl(SIOCGIFINDEX)");
  902. return -1;
  903. }
  904. memset(&addr, 0, sizeof(addr));
  905. addr.sll_family = AF_PACKET;
  906. addr.sll_ifindex = ifr.ifr_ifindex;
  907. addr.sll_protocol = htons(ETH_P_ALL);
  908. wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d",
  909. addr.sll_ifindex);
  910. if (bind(drv->pim_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  911. perror("bind");
  912. return -1;
  913. }
  914. return 0;
  915. }
  916. static void * prism54_driver_init(struct hostapd_data *hapd,
  917. struct wpa_init_params *params)
  918. {
  919. struct prism54_driver_data *drv;
  920. drv = os_zalloc(sizeof(struct prism54_driver_data));
  921. if (drv == NULL) {
  922. printf("Could not allocate memory for hostapd Prism54 driver "
  923. "data\n");
  924. return NULL;
  925. }
  926. drv->hapd = hapd;
  927. drv->pim_sock = drv->sock = -1;
  928. memcpy(drv->iface, params->ifname, sizeof(drv->iface));
  929. if (prism54_init_sockets(drv, params)) {
  930. free(drv);
  931. return NULL;
  932. }
  933. prism54_init_1x(drv);
  934. /* must clean previous elems */
  935. prism54_set_generic_elem(drv->iface, drv, NULL, 0);
  936. return drv;
  937. }
  938. static void prism54_driver_deinit(void *priv)
  939. {
  940. struct prism54_driver_data *drv = priv;
  941. if (drv->pim_sock >= 0)
  942. close(drv->pim_sock);
  943. if (drv->sock >= 0)
  944. close(drv->sock);
  945. free(drv);
  946. }
  947. #else /* HOSTAPD */
  948. struct wpa_driver_prism54_data {
  949. void *wext; /* private data for driver_wext */
  950. void *ctx;
  951. char ifname[IFNAMSIZ + 1];
  952. int sock;
  953. };
  954. #define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
  955. #define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
  956. #define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
  957. static void show_set_key_error(struct prism2_hostapd_param *);
  958. static int hostapd_ioctl_prism54(struct wpa_driver_prism54_data *drv,
  959. struct prism2_hostapd_param *param,
  960. int len, int show_err)
  961. {
  962. struct iwreq iwr;
  963. os_memset(&iwr, 0, sizeof(iwr));
  964. os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
  965. iwr.u.data.pointer = (caddr_t) param;
  966. iwr.u.data.length = len;
  967. if (ioctl(drv->sock, PRISM54_HOSTAPD, &iwr) < 0) {
  968. int ret = errno;
  969. if (show_err)
  970. perror("ioctl[PRISM54_HOSTAPD]");
  971. return ret;
  972. }
  973. return 0;
  974. }
  975. static int wpa_driver_prism54_set_wpa_ie(struct wpa_driver_prism54_data *drv,
  976. const u8 *wpa_ie,
  977. size_t wpa_ie_len)
  978. {
  979. struct prism2_hostapd_param *param;
  980. int res;
  981. size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len;
  982. if (blen < sizeof(*param))
  983. blen = sizeof(*param);
  984. param = os_zalloc(blen);
  985. if (param == NULL)
  986. return -1;
  987. param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT;
  988. param->u.generic_elem.len = wpa_ie_len;
  989. os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len);
  990. res = hostapd_ioctl_prism54(drv, param, blen, 1);
  991. os_free(param);
  992. return res;
  993. }
  994. /* This is called at wpa_supplicant daemon init time */
  995. static int wpa_driver_prism54_set_wpa(void *priv, int enabled)
  996. {
  997. struct wpa_driver_prism54_data *drv = priv;
  998. struct prism2_hostapd_param *param;
  999. int res;
  1000. size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
  1001. if (blen < sizeof(*param))
  1002. blen = sizeof(*param);
  1003. param = os_zalloc(blen);
  1004. if (param == NULL)
  1005. return -1;
  1006. param->cmd = PRISM54_SET_WPA;
  1007. param->u.generic_elem.len = 0;
  1008. res = hostapd_ioctl_prism54(drv, param, blen, 1);
  1009. os_free(param);
  1010. return res;
  1011. }
  1012. static int wpa_driver_prism54_set_key(const char *ifname, void *priv,
  1013. wpa_alg alg,
  1014. const u8 *addr, int key_idx, int set_tx,
  1015. const u8 *seq, size_t seq_len,
  1016. const u8 *key, size_t key_len)
  1017. {
  1018. struct wpa_driver_prism54_data *drv = priv;
  1019. struct prism2_hostapd_param *param;
  1020. u8 *buf;
  1021. size_t blen;
  1022. int ret = 0;
  1023. char *alg_name;
  1024. switch (alg) {
  1025. case WPA_ALG_NONE:
  1026. alg_name = "none";
  1027. return -1;
  1028. break;
  1029. case WPA_ALG_WEP:
  1030. alg_name = "WEP";
  1031. return -1;
  1032. break;
  1033. case WPA_ALG_TKIP:
  1034. alg_name = "TKIP";
  1035. break;
  1036. case WPA_ALG_CCMP:
  1037. alg_name = "CCMP";
  1038. return -1;
  1039. break;
  1040. default:
  1041. return -1;
  1042. }
  1043. wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
  1044. "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
  1045. (unsigned long) seq_len, (unsigned long) key_len);
  1046. if (seq_len > 8)
  1047. return -2;
  1048. blen = sizeof(*param) + key_len;
  1049. buf = os_zalloc(blen);
  1050. if (buf == NULL)
  1051. return -1;
  1052. param = (struct prism2_hostapd_param *) buf;
  1053. param->cmd = PRISM2_SET_ENCRYPTION;
  1054. /* TODO: In theory, STA in client mode can use five keys; four default
  1055. * keys for receiving (with keyidx 0..3) and one individual key for
  1056. * both transmitting and receiving (keyidx 0) _unicast_ packets. Now,
  1057. * keyidx 0 is reserved for this unicast use and default keys can only
  1058. * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported).
  1059. * This should be fine for more or less all cases, but for completeness
  1060. * sake, the driver could be enhanced to support the missing key. */
  1061. #if 0
  1062. if (addr == NULL)
  1063. os_memset(param->sta_addr, 0xff, ETH_ALEN);
  1064. else
  1065. os_memcpy(param->sta_addr, addr, ETH_ALEN);
  1066. #else
  1067. os_memset(param->sta_addr, 0xff, ETH_ALEN);
  1068. #endif
  1069. os_strlcpy((char *) param->u.crypt.alg, alg_name,
  1070. HOSTAP_CRYPT_ALG_NAME_LEN);
  1071. param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
  1072. param->u.crypt.idx = key_idx;
  1073. os_memcpy(param->u.crypt.seq, seq, seq_len);
  1074. param->u.crypt.key_len = key_len;
  1075. os_memcpy((u8 *) (param + 1), key, key_len);
  1076. if (hostapd_ioctl_prism54(drv, param, blen, 1)) {
  1077. wpa_printf(MSG_WARNING, "Failed to set encryption.");
  1078. show_set_key_error(param);
  1079. ret = -1;
  1080. }
  1081. os_free(buf);
  1082. return ret;
  1083. }
  1084. static int wpa_driver_prism54_set_countermeasures(void *priv,
  1085. int enabled)
  1086. {
  1087. /* FIX */
  1088. printf("wpa_driver_prism54_set_countermeasures - not yet "
  1089. "implemented\n");
  1090. return 0;
  1091. }
  1092. static int wpa_driver_prism54_set_drop_unencrypted(void *priv,
  1093. int enabled)
  1094. {
  1095. struct wpa_driver_prism54_data *drv = priv;
  1096. struct prism2_hostapd_param *param;
  1097. int res;
  1098. size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
  1099. if (blen < sizeof(*param))
  1100. blen = sizeof(*param);
  1101. param = os_zalloc(blen);
  1102. if (param == NULL)
  1103. return -1;
  1104. param->cmd = PRISM54_DROP_UNENCRYPTED;
  1105. param->u.generic_elem.len = 0;
  1106. res = hostapd_ioctl_prism54(drv, param, blen, 1);
  1107. os_free(param);
  1108. return res;
  1109. }
  1110. static int wpa_driver_prism54_deauthenticate(void *priv, const u8 *addr,
  1111. int reason_code)
  1112. {
  1113. /* FIX */
  1114. printf("wpa_driver_prism54_deauthenticate - not yet implemented\n");
  1115. return 0;
  1116. }
  1117. static int wpa_driver_prism54_disassociate(void *priv, const u8 *addr,
  1118. int reason_code)
  1119. {
  1120. /* FIX */
  1121. printf("wpa_driver_prism54_disassociate - not yet implemented\n");
  1122. return 0;
  1123. }
  1124. static int
  1125. wpa_driver_prism54_associate(void *priv,
  1126. struct wpa_driver_associate_params *params)
  1127. {
  1128. struct wpa_driver_prism54_data *drv = priv;
  1129. int ret = 0;
  1130. if (wpa_driver_prism54_set_drop_unencrypted(drv,
  1131. params->drop_unencrypted)
  1132. < 0)
  1133. ret = -1;
  1134. if (wpa_driver_prism54_set_wpa_ie(drv, params->wpa_ie,
  1135. params->wpa_ie_len) < 0)
  1136. ret = -1;
  1137. if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0)
  1138. ret = -1;
  1139. if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
  1140. params->ssid_len) < 0)
  1141. ret = -1;
  1142. if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0)
  1143. ret = -1;
  1144. return ret;
  1145. }
  1146. static void show_set_key_error(struct prism2_hostapd_param *param)
  1147. {
  1148. switch (param->u.crypt.err) {
  1149. case HOSTAP_CRYPT_ERR_UNKNOWN_ALG:
  1150. wpa_printf(MSG_INFO, "Unknown algorithm '%s'.",
  1151. param->u.crypt.alg);
  1152. wpa_printf(MSG_INFO, "You may need to load kernel module to "
  1153. "register that algorithm.");
  1154. wpa_printf(MSG_INFO, "E.g., 'modprobe hostap_crypt_wep' for "
  1155. "WEP.");
  1156. break;
  1157. case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR:
  1158. wpa_printf(MSG_INFO, "Unknown address " MACSTR ".",
  1159. MAC2STR(param->sta_addr));
  1160. break;
  1161. case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED:
  1162. wpa_printf(MSG_INFO, "Crypt algorithm initialization failed.");
  1163. break;
  1164. case HOSTAP_CRYPT_ERR_KEY_SET_FAILED:
  1165. wpa_printf(MSG_INFO, "Key setting failed.");
  1166. break;
  1167. case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED:
  1168. wpa_printf(MSG_INFO, "TX key index setting failed.");
  1169. break;
  1170. case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED:
  1171. wpa_printf(MSG_INFO, "Card configuration failed.");
  1172. break;
  1173. }
  1174. }
  1175. static int wpa_driver_prism54_get_bssid(void *priv, u8 *bssid)
  1176. {
  1177. struct wpa_driver_prism54_data *drv = priv;
  1178. return wpa_driver_wext_get_bssid(drv->wext, bssid);
  1179. }
  1180. static int wpa_driver_prism54_get_ssid(void *priv, u8 *ssid)
  1181. {
  1182. struct wpa_driver_prism54_data *drv = priv;
  1183. return wpa_driver_wext_get_ssid(drv->wext, ssid);
  1184. }
  1185. static int wpa_driver_prism54_scan(void *priv,
  1186. struct wpa_driver_scan_params *params)
  1187. {
  1188. struct wpa_driver_prism54_data *drv = priv;
  1189. return wpa_driver_wext_scan(drv->wext, params);
  1190. }
  1191. static struct wpa_scan_results *
  1192. wpa_driver_prism54_get_scan_results(void *priv)
  1193. {
  1194. struct wpa_driver_prism54_data *drv = priv;
  1195. return wpa_driver_wext_get_scan_results(drv->wext);
  1196. }
  1197. static int wpa_driver_prism54_set_operstate(void *priv, int state)
  1198. {
  1199. struct wpa_driver_prism54_data *drv = priv;
  1200. return wpa_driver_wext_set_operstate(drv->wext, state);
  1201. }
  1202. static void * wpa_driver_prism54_init(void *ctx, const char *ifname)
  1203. {
  1204. struct wpa_driver_prism54_data *drv;
  1205. drv = os_zalloc(sizeof(*drv));
  1206. if (drv == NULL)
  1207. return NULL;
  1208. drv->wext = wpa_driver_wext_init(ctx, ifname);
  1209. if (drv->wext == NULL) {
  1210. os_free(drv);
  1211. return NULL;
  1212. }
  1213. drv->ctx = ctx;
  1214. os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
  1215. drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
  1216. if (drv->sock < 0) {
  1217. wpa_driver_wext_deinit(drv->wext);
  1218. os_free(drv);
  1219. return NULL;
  1220. }
  1221. wpa_driver_prism54_set_wpa(drv, 1);
  1222. return drv;
  1223. }
  1224. static void wpa_driver_prism54_deinit(void *priv)
  1225. {
  1226. struct wpa_driver_prism54_data *drv = priv;
  1227. wpa_driver_prism54_set_wpa(drv, 0);
  1228. wpa_driver_wext_deinit(drv->wext);
  1229. close(drv->sock);
  1230. os_free(drv);
  1231. }
  1232. #endif /* HOSTAPD */
  1233. const struct wpa_driver_ops wpa_driver_prism54_ops = {
  1234. .name = "prism54",
  1235. .desc = "Prism54.org driver (Intersil Prism GT/Duette/Indigo)",
  1236. .set_key = wpa_driver_prism54_set_key,
  1237. #ifdef HOSTAPD
  1238. .hapd_init = prism54_driver_init,
  1239. .hapd_deinit = prism54_driver_deinit,
  1240. /* .set_ieee8021x = prism54_init_1x, */
  1241. .set_privacy = prism54_set_privacy_invoked,
  1242. .get_seqnum = prism54_get_seqnum,
  1243. .flush = prism54_flush,
  1244. .set_generic_elem = prism54_set_generic_elem,
  1245. .hapd_send_eapol = prism54_send_eapol,
  1246. .sta_set_flags = prism54_sta_set_flags,
  1247. .sta_deauth = prism54_sta_deauth,
  1248. .sta_disassoc = prism54_sta_disassoc,
  1249. .hapd_set_ssid = prism54_ioctl_setiwessid,
  1250. .get_inact_sec = prism54_get_inact_sec,
  1251. #else /* HOSTAPD */
  1252. .get_bssid = wpa_driver_prism54_get_bssid,
  1253. .get_ssid = wpa_driver_prism54_get_ssid,
  1254. .set_countermeasures = wpa_driver_prism54_set_countermeasures,
  1255. .scan2 = wpa_driver_prism54_scan,
  1256. .get_scan_results2 = wpa_driver_prism54_get_scan_results,
  1257. .deauthenticate = wpa_driver_prism54_deauthenticate,
  1258. .disassociate = wpa_driver_prism54_disassociate,
  1259. .associate = wpa_driver_prism54_associate,
  1260. .init = wpa_driver_prism54_init,
  1261. .deinit = wpa_driver_prism54_deinit,
  1262. .set_operstate = wpa_driver_prism54_set_operstate,
  1263. #endif /* HOSTAPD */
  1264. };