main.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. * WPA Supplicant / main() function for UNIX like OSes and MinGW
  3. * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #ifdef __linux__
  10. #include <fcntl.h>
  11. #endif /* __linux__ */
  12. #include "common.h"
  13. #include "wpa_supplicant_i.h"
  14. #include "driver_i.h"
  15. extern struct wpa_driver_ops *wpa_drivers[];
  16. static void usage(void)
  17. {
  18. int i;
  19. printf("%s\n\n%s\n"
  20. "usage:\n"
  21. " wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] "
  22. "[-g<global ctrl>] \\\n"
  23. " [-G<group>] \\\n"
  24. " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
  25. "[-p<driver_param>] \\\n"
  26. " [-b<br_ifname>] [-f<debug file>] [-e<entropy file>] "
  27. "\\\n"
  28. " [-o<override driver>] [-O<override ctrl>] \\\n"
  29. " [-N -i<ifname> -c<conf> [-C<ctrl>] "
  30. "[-D<driver>] \\\n"
  31. " [-p<driver_param>] [-b<br_ifname>] [-I<config file>] "
  32. "...]\n"
  33. "\n"
  34. "drivers:\n",
  35. wpa_supplicant_version, wpa_supplicant_license);
  36. for (i = 0; wpa_drivers[i]; i++) {
  37. printf(" %s = %s\n",
  38. wpa_drivers[i]->name,
  39. wpa_drivers[i]->desc);
  40. }
  41. #ifndef CONFIG_NO_STDOUT_DEBUG
  42. printf("options:\n"
  43. " -b = optional bridge interface name\n"
  44. " -B = run daemon in the background\n"
  45. " -c = Configuration file\n"
  46. " -C = ctrl_interface parameter (only used if -c is not)\n"
  47. " -i = interface name\n"
  48. " -I = additional configuration file\n"
  49. " -d = increase debugging verbosity (-dd even more)\n"
  50. " -D = driver name (can be multiple drivers: nl80211,wext)\n"
  51. " -e = entropy file\n");
  52. #ifdef CONFIG_DEBUG_FILE
  53. printf(" -f = log output to debug file instead of stdout\n");
  54. #endif /* CONFIG_DEBUG_FILE */
  55. printf(" -g = global ctrl_interface\n"
  56. " -G = global ctrl_interface group\n"
  57. " -K = include keys (passwords, etc.) in debug output\n");
  58. #ifdef CONFIG_DEBUG_SYSLOG
  59. printf(" -s = log output to syslog instead of stdout\n");
  60. #endif /* CONFIG_DEBUG_SYSLOG */
  61. #ifdef CONFIG_DEBUG_LINUX_TRACING
  62. printf(" -T = record to Linux tracing in addition to logging\n");
  63. printf(" (records all messages regardless of debug verbosity)\n");
  64. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  65. printf(" -t = include timestamp in debug messages\n"
  66. " -h = show this help text\n"
  67. " -L = show license (BSD)\n"
  68. " -o = override driver parameter for new interfaces\n"
  69. " -O = override ctrl_interface parameter for new interfaces\n"
  70. " -p = driver parameters\n"
  71. " -P = PID file\n"
  72. " -q = decrease debugging verbosity (-qq even less)\n");
  73. #ifdef CONFIG_DBUS
  74. printf(" -u = enable DBus control interface\n");
  75. #endif /* CONFIG_DBUS */
  76. printf(" -v = show version\n"
  77. " -W = wait for a control interface monitor before starting\n"
  78. " -N = start describing new interface\n");
  79. printf("example:\n"
  80. " wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n",
  81. wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211");
  82. #endif /* CONFIG_NO_STDOUT_DEBUG */
  83. }
  84. static void license(void)
  85. {
  86. #ifndef CONFIG_NO_STDOUT_DEBUG
  87. printf("%s\n\n%s%s%s%s%s\n",
  88. wpa_supplicant_version,
  89. wpa_supplicant_full_license1,
  90. wpa_supplicant_full_license2,
  91. wpa_supplicant_full_license3,
  92. wpa_supplicant_full_license4,
  93. wpa_supplicant_full_license5);
  94. #endif /* CONFIG_NO_STDOUT_DEBUG */
  95. }
  96. static void wpa_supplicant_fd_workaround(int start)
  97. {
  98. #ifdef __linux__
  99. static int fd[3] = { -1, -1, -1 };
  100. int i;
  101. /* When started from pcmcia-cs scripts, wpa_supplicant might start with
  102. * fd 0, 1, and 2 closed. This will cause some issues because many
  103. * places in wpa_supplicant are still printing out to stdout. As a
  104. * workaround, make sure that fd's 0, 1, and 2 are not used for other
  105. * sockets. */
  106. if (start) {
  107. for (i = 0; i < 3; i++) {
  108. fd[i] = open("/dev/null", O_RDWR);
  109. if (fd[i] > 2) {
  110. close(fd[i]);
  111. fd[i] = -1;
  112. break;
  113. }
  114. }
  115. } else {
  116. for (i = 0; i < 3; i++) {
  117. if (fd[i] >= 0) {
  118. close(fd[i]);
  119. fd[i] = -1;
  120. }
  121. }
  122. }
  123. #endif /* __linux__ */
  124. }
  125. int main(int argc, char *argv[])
  126. {
  127. int c, i;
  128. struct wpa_interface *ifaces, *iface;
  129. int iface_count, exitcode = -1;
  130. struct wpa_params params;
  131. struct wpa_global *global;
  132. if (os_program_init())
  133. return -1;
  134. os_memset(&params, 0, sizeof(params));
  135. params.wpa_debug_level = MSG_INFO;
  136. iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
  137. if (ifaces == NULL)
  138. return -1;
  139. iface_count = 1;
  140. wpa_supplicant_fd_workaround(1);
  141. for (;;) {
  142. c = getopt(argc, argv,
  143. "b:Bc:C:D:de:f:g:G:hi:I:KLNo:O:p:P:qsTtuvW");
  144. if (c < 0)
  145. break;
  146. switch (c) {
  147. case 'b':
  148. iface->bridge_ifname = optarg;
  149. break;
  150. case 'B':
  151. params.daemonize++;
  152. break;
  153. case 'c':
  154. iface->confname = optarg;
  155. break;
  156. case 'C':
  157. iface->ctrl_interface = optarg;
  158. break;
  159. case 'D':
  160. iface->driver = optarg;
  161. break;
  162. case 'd':
  163. #ifdef CONFIG_NO_STDOUT_DEBUG
  164. printf("Debugging disabled with "
  165. "CONFIG_NO_STDOUT_DEBUG=y build time "
  166. "option.\n");
  167. goto out;
  168. #else /* CONFIG_NO_STDOUT_DEBUG */
  169. params.wpa_debug_level--;
  170. break;
  171. #endif /* CONFIG_NO_STDOUT_DEBUG */
  172. case 'e':
  173. params.entropy_file = optarg;
  174. break;
  175. #ifdef CONFIG_DEBUG_FILE
  176. case 'f':
  177. params.wpa_debug_file_path = optarg;
  178. break;
  179. #endif /* CONFIG_DEBUG_FILE */
  180. case 'g':
  181. params.ctrl_interface = optarg;
  182. break;
  183. case 'G':
  184. params.ctrl_interface_group = optarg;
  185. break;
  186. case 'h':
  187. usage();
  188. exitcode = 0;
  189. goto out;
  190. case 'i':
  191. iface->ifname = optarg;
  192. break;
  193. case 'I':
  194. iface->confanother = optarg;
  195. break;
  196. case 'K':
  197. params.wpa_debug_show_keys++;
  198. break;
  199. case 'L':
  200. license();
  201. exitcode = 0;
  202. goto out;
  203. case 'o':
  204. params.override_driver = optarg;
  205. break;
  206. case 'O':
  207. params.override_ctrl_interface = optarg;
  208. break;
  209. case 'p':
  210. iface->driver_param = optarg;
  211. break;
  212. case 'P':
  213. os_free(params.pid_file);
  214. params.pid_file = os_rel2abs_path(optarg);
  215. break;
  216. case 'q':
  217. params.wpa_debug_level++;
  218. break;
  219. #ifdef CONFIG_DEBUG_SYSLOG
  220. case 's':
  221. params.wpa_debug_syslog++;
  222. break;
  223. #endif /* CONFIG_DEBUG_SYSLOG */
  224. #ifdef CONFIG_DEBUG_LINUX_TRACING
  225. case 'T':
  226. params.wpa_debug_tracing++;
  227. break;
  228. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  229. case 't':
  230. params.wpa_debug_timestamp++;
  231. break;
  232. #ifdef CONFIG_DBUS
  233. case 'u':
  234. params.dbus_ctrl_interface = 1;
  235. break;
  236. #endif /* CONFIG_DBUS */
  237. case 'v':
  238. printf("%s\n", wpa_supplicant_version);
  239. exitcode = 0;
  240. goto out;
  241. case 'W':
  242. params.wait_for_monitor++;
  243. break;
  244. case 'N':
  245. iface_count++;
  246. iface = os_realloc_array(ifaces, iface_count,
  247. sizeof(struct wpa_interface));
  248. if (iface == NULL)
  249. goto out;
  250. ifaces = iface;
  251. iface = &ifaces[iface_count - 1];
  252. os_memset(iface, 0, sizeof(*iface));
  253. break;
  254. default:
  255. usage();
  256. exitcode = 0;
  257. goto out;
  258. }
  259. }
  260. exitcode = 0;
  261. global = wpa_supplicant_init(&params);
  262. if (global == NULL) {
  263. wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
  264. exitcode = -1;
  265. goto out;
  266. } else {
  267. wpa_printf(MSG_INFO, "Successfully initialized "
  268. "wpa_supplicant");
  269. }
  270. for (i = 0; exitcode == 0 && i < iface_count; i++) {
  271. if ((ifaces[i].confname == NULL &&
  272. ifaces[i].ctrl_interface == NULL) ||
  273. ifaces[i].ifname == NULL) {
  274. if (iface_count == 1 && (params.ctrl_interface ||
  275. params.dbus_ctrl_interface))
  276. break;
  277. usage();
  278. exitcode = -1;
  279. break;
  280. }
  281. if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL)
  282. exitcode = -1;
  283. }
  284. if (exitcode == 0)
  285. exitcode = wpa_supplicant_run(global);
  286. wpa_supplicant_deinit(global);
  287. out:
  288. wpa_supplicant_fd_workaround(0);
  289. os_free(ifaces);
  290. os_free(params.pid_file);
  291. os_program_deinit();
  292. return exitcode;
  293. }