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.
 
 
 
 

358 lines
12 KiB

  1. /*
  2. netcfg.c - Configure a network via DHCP or manual configuration
  3. for debian-installer
  4. Copyright (C) 2000-2002 David Kimdon <dwhedon@debian.org>
  5. and others (see debian/copyright)
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "netcfg.h"
  19. #include "nm-conf.h"
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <cdebconf/debconfclient.h>
  26. #include <debian-installer.h>
  27. #ifdef WIRELESS
  28. #include <iwlib.h>
  29. #endif
  30. static method_t netcfg_method = DHCP;
  31. response_t netcfg_get_method(struct debconfclient *client)
  32. {
  33. int iret;
  34. iret = debconf_input(client, "medium", "netcfg/use_autoconfig");
  35. if (debconf_go(client) == CMD_GOBACK)
  36. return GO_BACK;
  37. debconf_get(client, "netcfg/use_autoconfig");
  38. if (strcmp(client->value, "true") == 0)
  39. netcfg_method = DHCP;
  40. else
  41. netcfg_method = STATIC;
  42. if (iret == CMD_INPUTINVISIBLE)
  43. return NOT_ASKED;
  44. return 0;
  45. }
  46. int main(int argc, char *argv[])
  47. {
  48. int num_interfaces = 0;
  49. enum { BACKUP,
  50. GET_INTERFACE,
  51. GET_HOSTNAME_ONLY,
  52. GET_METHOD,
  53. GET_DHCP,
  54. GET_STATIC,
  55. WCONFIG,
  56. WCONFIG_ESSID,
  57. WCONFIG_SECURITY_TYPE,
  58. WCONFIG_WEP,
  59. WCONFIG_WPA,
  60. START_WPA,
  61. QUIT } state = GET_INTERFACE;
  62. static struct debconfclient *client;
  63. static int requested_wireless_tools = 0;
  64. char **ifaces;
  65. char *defiface = NULL, *defwireless = NULL;
  66. response_t res;
  67. struct netcfg_interface interface;
  68. #ifdef NM
  69. struct nm_config_info nmconf;
  70. #endif
  71. /* initialize libd-i */
  72. di_system_init("netcfg");
  73. netcfg_interface_init(&interface);
  74. if (strcmp(basename(argv[0]), "ptom") != 0)
  75. di_info("Starting netcfg v.%s", NETCFG_VERSION);
  76. parse_args (argc, argv);
  77. reap_old_files ();
  78. open_sockets();
  79. /* initialize debconf */
  80. client = debconfclient_new();
  81. debconf_capb(client, "backup");
  82. /* Check to see if netcfg should be run at all */
  83. debconf_get(client, "netcfg/enable");
  84. if (!strcmp(client->value, "false")) {
  85. netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0);
  86. netcfg_write_common("", hostname, NULL);
  87. return 0;
  88. }
  89. /* always always always default back to autoconfig, unless you've specified
  90. * disable_autoconfig on the command line. */
  91. debconf_get(client, "netcfg/disable_autoconfig");
  92. if (!strcmp(client->value, "true"))
  93. debconf_set(client, "netcfg/use_autoconfig", "false");
  94. else
  95. debconf_set(client, "netcfg/use_autoconfig", "true");
  96. /* also support disable_dhcp for compatibility */
  97. debconf_get(client, "netcfg/disable_dhcp");
  98. if (!strcmp(client->value, "true"))
  99. debconf_set(client, "netcfg/use_autoconfig", "false");
  100. for (;;) {
  101. switch(state) {
  102. case BACKUP:
  103. return RETURN_TO_MAIN;
  104. case GET_INTERFACE:
  105. /* If we have returned from outside of netcfg and want to
  106. * reconfigure networking, check to see if wpasupplicant is
  107. * running, and kill it if it is. If left running when
  108. * the interfaces are taken up and down, it appears to
  109. * leave it in an inconsistant state */
  110. kill_wpa_supplicant();
  111. /* Choose a default by looking for link */
  112. if (get_all_ifs(1, &ifaces) > 1) {
  113. while (*ifaces) {
  114. struct netcfg_interface link_interface;
  115. if (check_kill_switch(*ifaces)) {
  116. debconf_subst(client, "netcfg/kill_switch_enabled", "iface", *ifaces);
  117. debconf_input(client, "high", "netcfg/kill_switch_enabled");
  118. if (debconf_go(client) == CMD_GOBACK) {
  119. state = BACKUP;
  120. break;
  121. }
  122. /* Is it still enabled? */
  123. if (check_kill_switch(*ifaces)) {
  124. ifaces++;
  125. continue;
  126. }
  127. }
  128. interface_up(*ifaces);
  129. netcfg_interface_init(&link_interface);
  130. link_interface.name = strdup(*ifaces);
  131. if (netcfg_detect_link (client, &link_interface) == 1) /* CONNECTED */ {
  132. /* CONNECTED */
  133. di_info("found link on interface %s, making it the default.", *ifaces);
  134. defiface = strdup(*ifaces);
  135. free(link_interface.name);
  136. break;
  137. } else {
  138. #ifdef WIRELESS
  139. struct wireless_config wc;
  140. #endif /* WIRELESS */
  141. di_info("found no link on interface %s.", *ifaces);
  142. #ifdef WIRELESS
  143. if (iw_get_basic_config(wfd, *ifaces, &wc) == 0) {
  144. wc.essid[0] = '\0';
  145. wc.essid_on = 0;
  146. iw_set_basic_config(wfd, *ifaces, &wc);
  147. sleep(1);
  148. iw_get_basic_config(wfd, *ifaces, &wc);
  149. if (!empty_str(wc.essid)) {
  150. di_info("%s is associated with %s. Selecting as default", *ifaces, wc.essid);
  151. defiface = strdup(*ifaces);
  152. interface_down(*ifaces);
  153. break;
  154. } else {
  155. di_info("%s is not associated. Relegating to defwireless", *ifaces);
  156. if (defwireless != NULL)
  157. free (defwireless);
  158. defwireless = strdup(*ifaces);
  159. }
  160. }
  161. else
  162. di_info("%s is not a wireless interface. Continuing.", *ifaces);
  163. interface_down(*ifaces);
  164. #endif
  165. }
  166. free(link_interface.name);
  167. interface_down(*ifaces);
  168. ifaces++;
  169. }
  170. }
  171. if (state == BACKUP)
  172. break;
  173. if (!defiface && defwireless)
  174. defiface = defwireless;
  175. if(netcfg_get_interface(client, &(interface.name), &num_interfaces, defiface))
  176. state = BACKUP;
  177. else if (! interface.name || ! num_interfaces)
  178. state = GET_HOSTNAME_ONLY;
  179. else {
  180. if (is_wireless_iface (interface.name))
  181. state = WCONFIG;
  182. else
  183. state = GET_METHOD;
  184. }
  185. break;
  186. case GET_HOSTNAME_ONLY:
  187. if(netcfg_get_hostname(client, "netcfg/get_hostname", hostname, 0))
  188. state = BACKUP;
  189. else {
  190. netcfg_write_common("", hostname, NULL);
  191. state = QUIT;
  192. }
  193. break;
  194. case GET_METHOD:
  195. if ((res = netcfg_get_method(client)) == GO_BACK)
  196. state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
  197. else {
  198. if (netcfg_method == DHCP)
  199. state = GET_DHCP;
  200. else
  201. state = GET_STATIC;
  202. }
  203. break;
  204. case GET_DHCP:
  205. switch (netcfg_activate_dhcp(client, &interface)) {
  206. case 0:
  207. state = QUIT;
  208. break;
  209. case RETURN_TO_MAIN:
  210. /*
  211. * It doesn't make sense to go back to GET_METHOD because
  212. * the user has already been asked whether they want to
  213. * try an alternate method.
  214. */
  215. state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
  216. break;
  217. case CONFIGURE_MANUALLY:
  218. state = GET_STATIC;
  219. break;
  220. default:
  221. return 1;
  222. }
  223. break;
  224. case GET_STATIC:
  225. {
  226. int ret;
  227. /* Misnomer - this should actually take care of activation */
  228. if ((ret = netcfg_get_static(client, &interface)) == RETURN_TO_MAIN)
  229. state = GET_INTERFACE;
  230. else if (ret)
  231. state = GET_METHOD;
  232. else
  233. state = QUIT;
  234. break;
  235. }
  236. case WCONFIG:
  237. if (requested_wireless_tools == 0) {
  238. di_exec_shell_log("apt-install iw wireless-tools");
  239. requested_wireless_tools = 1;
  240. }
  241. state = WCONFIG_ESSID;
  242. break;
  243. case WCONFIG_ESSID:
  244. if (netcfg_wireless_set_essid(client, &interface) == GO_BACK)
  245. state = BACKUP;
  246. else {
  247. init_wpa_supplicant_support(&interface);
  248. if (interface.wpa_supplicant_status == WPA_UNAVAIL)
  249. state = WCONFIG_WEP;
  250. else
  251. state = WCONFIG_SECURITY_TYPE;
  252. }
  253. break;
  254. case WCONFIG_SECURITY_TYPE:
  255. {
  256. int ret;
  257. ret = wireless_security_type(client, interface.name);
  258. if (ret == GO_BACK)
  259. state = WCONFIG_ESSID;
  260. else if (ret == REPLY_WPA) {
  261. state = WCONFIG_WPA;
  262. interface.wifi_security = REPLY_WPA;
  263. }
  264. else {
  265. state = WCONFIG_WEP;
  266. interface.wifi_security = REPLY_WEP;
  267. }
  268. break;
  269. }
  270. case WCONFIG_WEP:
  271. if (netcfg_wireless_set_wep(client, &interface) == GO_BACK)
  272. if (interface.wpa_supplicant_status == WPA_UNAVAIL)
  273. state = WCONFIG_ESSID;
  274. else
  275. state = WCONFIG_SECURITY_TYPE;
  276. else
  277. state = GET_METHOD;
  278. break;
  279. case WCONFIG_WPA:
  280. if (interface.wpa_supplicant_status == WPA_OK) {
  281. di_exec_shell_log("apt-install wpasupplicant");
  282. interface.wpa_supplicant_status = WPA_QUEUED;
  283. }
  284. if (netcfg_set_passphrase(client, &interface) == GO_BACK)
  285. state = WCONFIG_SECURITY_TYPE;
  286. else
  287. state = START_WPA;
  288. break;
  289. case START_WPA:
  290. if (wpa_supplicant_start(client, &interface) == GO_BACK)
  291. state = WCONFIG_ESSID;
  292. else
  293. state = GET_METHOD;
  294. break;
  295. case QUIT:
  296. #ifdef NM
  297. if (num_interfaces > 0) {
  298. nm_get_configuration(&interface, &nmconf);
  299. nm_write_configuration(nmconf);
  300. }
  301. #endif
  302. netcfg_update_entropy();
  303. return 0;
  304. }
  305. }
  306. }