You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

277 lines
7.2 KiB

  1. /* Wireless support using iwlib for netcfg.
  2. * (C) 2004 Joshua Kwan, Bastian Blank
  3. *
  4. * Licensed under the GNU General Public License
  5. */
  6. #include "netcfg.h"
  7. #ifdef WIRELESS
  8. #include <debian-installer/log.h>
  9. #include <iwlib.h>
  10. #include <sys/types.h>
  11. #include <assert.h>
  12. #endif
  13. /* Wireless mode */
  14. wifimode_t mode = MANAGED;
  15. /* wireless config */
  16. char* wepkey = NULL;
  17. char* essid = NULL;
  18. #ifdef WIRELESS
  19. int is_wireless_iface (const char* iface)
  20. {
  21. wireless_config wc;
  22. return (iw_get_basic_config (wfd, (char*)iface, &wc) == 0);
  23. }
  24. int netcfg_wireless_set_essid (struct debconfclient * client, char *iface, char* priority)
  25. {
  26. int ret, couldnt_associate = 0;
  27. wireless_config wconf;
  28. char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;
  29. iw_get_basic_config (wfd, iface, &wconf);
  30. debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
  31. debconf_subst(client, "netcfg/wireless_essid_again", "iface", iface);
  32. debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);
  33. debconf_input(client, priority ? priority : "low", "netcfg/wireless_adhoc_managed");
  34. if (debconf_go(client) == 30)
  35. return GO_BACK;
  36. debconf_get(client, "netcfg/wireless_adhoc_managed");
  37. if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
  38. mode = ADHOC;
  39. wconf.has_mode = 1;
  40. wconf.mode = mode;
  41. debconf_input(client, priority ? priority : "high", "netcfg/wireless_essid");
  42. if (debconf_go(client) == 30)
  43. return GO_BACK;
  44. debconf_get(client, "netcfg/wireless_essid");
  45. tf = strdup(client->value);
  46. automatic:
  47. /* question not asked or user doesn't care or we're successfully associated */
  48. if (!empty_str(wconf.essid) || empty_str(client->value))
  49. {
  50. int i, success = 0;
  51. /* Default to any AP */
  52. wconf.essid[0] = '\0';
  53. wconf.essid_on = 0;
  54. iw_set_basic_config (wfd, iface, &wconf);
  55. /* Wait for association.. (MAX_SECS seconds)*/
  56. #define MAX_SECS 3
  57. debconf_capb(client, "backup progresscancel");
  58. debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");
  59. if (debconf_progress_info(client, "netcfg/wifi_progress_info") == 30)
  60. goto stop;
  61. netcfg_progress_displayed = 1;
  62. for (i = 0; i <= MAX_SECS; i++) {
  63. int progress_ret;
  64. interface_up(iface);
  65. sleep (1);
  66. iw_get_basic_config (wfd, iface, &wconf);
  67. if (!empty_str(wconf.essid)) {
  68. /* Save for later */
  69. debconf_set(client, "netcfg/wireless_essid", wconf.essid);
  70. debconf_progress_set(client, MAX_SECS);
  71. success = 1;
  72. break;
  73. }
  74. progress_ret = debconf_progress_step(client, 1);
  75. interface_down(iface);
  76. if (progress_ret == 30)
  77. break;
  78. }
  79. stop:
  80. debconf_progress_stop(client);
  81. debconf_capb(client, "backup");
  82. netcfg_progress_displayed = 0;
  83. if (success)
  84. return 0;
  85. couldnt_associate = 1;
  86. }
  87. /* yes, wants to set an essid by himself */
  88. if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
  89. user_essid = tf;
  90. while (!user_essid || empty_str(user_essid) ||
  91. strlen(user_essid) > IW_ESSID_MAX_SIZE) {
  92. /* Misnomer of a check. Basically, if we went through autodetection,
  93. * we want to enter this loop, but we want to suppress anything that
  94. * relied on the checking of tf/user_essid (i.e. "", in most cases.) */
  95. if (!couldnt_associate) {
  96. debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
  97. debconf_input(client, "high", "netcfg/invalid_essid");
  98. debconf_go(client);
  99. }
  100. if (couldnt_associate)
  101. ret = debconf_input(client, "critical", "netcfg/wireless_essid_again");
  102. else
  103. ret = debconf_input(client, "low", "netcfg/wireless_essid");
  104. /* we asked the question once, why can't we ask it again? */
  105. if (ret == 30)
  106. /* maybe netcfg/wireless_essid was preseeded; if so, give up */
  107. break;
  108. if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
  109. return GO_BACK;
  110. if (couldnt_associate)
  111. debconf_get(client, "netcfg/wireless_essid_again");
  112. else
  113. debconf_get(client, "netcfg/wireless_essid");
  114. if (empty_str(client->value)) {
  115. if (couldnt_associate)
  116. /* we've already tried the empty string here, so give up */
  117. break;
  118. else
  119. goto automatic;
  120. }
  121. /* But now we'd not like to suppress any MORE errors */
  122. couldnt_associate = 0;
  123. free(user_essid);
  124. user_essid = strdup(client->value);
  125. }
  126. essid = user_essid;
  127. memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
  128. snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
  129. wconf.has_essid = 1;
  130. wconf.essid_on = 1;
  131. iw_set_basic_config (wfd, iface, &wconf);
  132. return 0;
  133. }
  134. static void unset_wep_key (char* iface)
  135. {
  136. wireless_config wconf;
  137. int ret;
  138. iw_get_basic_config(wfd, iface, &wconf);
  139. wconf.has_key = 1;
  140. wconf.key[0] = '\0';
  141. wconf.key_flags = IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
  142. wconf.key_size = 0;
  143. ret = iw_set_basic_config (wfd, iface, &wconf);
  144. }
  145. int netcfg_wireless_set_wep (struct debconfclient * client, char* iface)
  146. {
  147. wireless_config wconf;
  148. char* rv = NULL;
  149. int ret, keylen, err = 0;
  150. unsigned char buf [IW_ENCODING_TOKEN_MAX + 1];
  151. struct iwreq wrq;
  152. iw_get_basic_config (wfd, iface, &wconf);
  153. debconf_subst(client, "netcfg/wireless_wep", "iface", iface);
  154. debconf_input (client, "high", "netcfg/wireless_wep");
  155. ret = debconf_go(client);
  156. if (ret == 30)
  157. return GO_BACK;
  158. debconf_get(client, "netcfg/wireless_wep");
  159. rv = client->value;
  160. if (empty_str(rv)) {
  161. unset_wep_key (iface);
  162. if (wepkey != NULL) {
  163. free(wepkey);
  164. wepkey = NULL;
  165. }
  166. return 0;
  167. }
  168. while ((keylen = iw_in_key (rv, buf)) == -1) {
  169. debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
  170. debconf_input(client, "critical", "netcfg/invalid_wep");
  171. debconf_go(client);
  172. debconf_input (client, "high", "netcfg/wireless_wep");
  173. ret = debconf_go(client);
  174. if (ret == 30)
  175. return GO_BACK;
  176. debconf_get(client, "netcfg/wireless_wep");
  177. rv = client->value;
  178. }
  179. /* Now rv is safe to store since it parsed fine */
  180. wepkey = strdup(rv);
  181. wrq.u.data.pointer = buf;
  182. wrq.u.data.flags = 0;
  183. wrq.u.data.length = keylen;
  184. if ((err = iw_set_ext(skfd, iface, SIOCSIWENCODE, &wrq)) < 0) {
  185. di_warning("setting WEP key on %s failed with code %d", iface, err);
  186. return -1;
  187. }
  188. return 0;
  189. }
  190. #else
  191. int is_wireless_iface (const char *iface)
  192. {
  193. (void) iface;
  194. return 0;
  195. }
  196. int netcfg_wireless_set_essid (struct debconfclient *client, char *iface, char *priority)
  197. {
  198. (void) client;
  199. (void) iface;
  200. (void) priority;
  201. return 0;
  202. }
  203. int netcfg_wireless_set_wep (struct debconfclient *client, char *iface)
  204. {
  205. (void) client;
  206. (void) iface;
  207. return 0;
  208. }
  209. #endif