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 9 #include "includes.h" 10 #ifdef __linux__ 11 #include <fcntl.h> 12 #endif /* __linux__ */ 13 14 #include "common.h" 15 #include "crypto/crypto.h" 16 #include "fst/fst.h" 17 #include "wpa_supplicant_i.h" 18 #include "driver_i.h" 19 #include "p2p_supplicant.h" 20 21 usage(void)22 static void usage(void) 23 { 24 int i; 25 printf("%s\n\n%s\n" 26 "usage:\n" 27 " wpa_supplicant [-BddhKLqq" 28 #ifdef CONFIG_DEBUG_SYSLOG 29 "s" 30 #endif /* CONFIG_DEBUG_SYSLOG */ 31 "t" 32 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW 33 "u" 34 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ 35 "vW] [-P<pid file>] " 36 "[-g<global ctrl>] \\\n" 37 " [-G<group>] \\\n" 38 " -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] " 39 "[-p<driver_param>] \\\n" 40 " [-b<br_ifname>] [-e<entropy file>]" 41 #ifdef CONFIG_DEBUG_FILE 42 " [-f<debug file>]" 43 #endif /* CONFIG_DEBUG_FILE */ 44 " \\\n" 45 " [-o<override driver>] [-O<override ctrl>] \\\n" 46 " [-N -i<ifname> -c<conf> [-C<ctrl>] " 47 "[-D<driver>] \\\n" 48 #ifdef CONFIG_P2P 49 " [-m<P2P Device config file>] \\\n" 50 #endif /* CONFIG_P2P */ 51 " [-p<driver_param>] [-b<br_ifname>] [-I<config file>] " 52 "...]\n" 53 "\n" 54 "drivers:\n", 55 wpa_supplicant_version, wpa_supplicant_license); 56 57 for (i = 0; wpa_drivers[i]; i++) { 58 printf(" %s = %s\n", 59 wpa_drivers[i]->name, 60 wpa_drivers[i]->desc); 61 } 62 63 #ifndef CONFIG_NO_STDOUT_DEBUG 64 printf("options:\n" 65 " -b = optional bridge interface name\n" 66 " -B = run daemon in the background\n" 67 " -c = Configuration file\n" 68 " -C = ctrl_interface parameter (only used if -c is not)\n" 69 " -d = increase debugging verbosity (-dd even more)\n" 70 " -D = driver name (can be multiple drivers: nl80211,wext)\n" 71 " -e = entropy file\n" 72 #ifdef CONFIG_DEBUG_FILE 73 " -f = log output to debug file instead of stdout\n" 74 #endif /* CONFIG_DEBUG_FILE */ 75 " -g = global ctrl_interface\n" 76 " -G = global ctrl_interface group\n" 77 " -h = show this help text\n" 78 " -i = interface name\n" 79 " -I = additional configuration file\n" 80 " -K = include keys (passwords, etc.) in debug output\n" 81 " -L = show license (BSD)\n" 82 #ifdef CONFIG_P2P 83 " -m = Configuration file for the P2P Device interface\n" 84 #endif /* CONFIG_P2P */ 85 #ifdef CONFIG_MATCH_IFACE 86 " -M = start describing new matching interface\n" 87 #endif /* CONFIG_MATCH_IFACE */ 88 " -N = start describing new interface\n" 89 " -o = override driver parameter for new interfaces\n" 90 " -O = override ctrl_interface parameter for new interfaces\n" 91 " -p = driver parameters\n" 92 " -P = PID file\n" 93 " -q = decrease debugging verbosity (-qq even less)\n" 94 #ifdef CONFIG_DEBUG_SYSLOG 95 " -s = log output to syslog instead of stdout\n" 96 #endif /* CONFIG_DEBUG_SYSLOG */ 97 " -t = include timestamp in debug messages\n" 98 #ifdef CONFIG_DEBUG_LINUX_TRACING 99 " -T = record to Linux tracing in addition to logging\n" 100 " (records all messages regardless of debug verbosity)\n" 101 #endif /* CONFIG_DEBUG_LINUX_TRACING */ 102 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW 103 " -u = enable DBus control interface\n" 104 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ 105 " -v = show version\n" 106 " -W = wait for a control interface monitor before starting\n"); 107 108 printf("example:\n" 109 " wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n", 110 wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211"); 111 #endif /* CONFIG_NO_STDOUT_DEBUG */ 112 } 113 114 license(void)115 static void license(void) 116 { 117 #ifndef CONFIG_NO_STDOUT_DEBUG 118 printf("%s\n\n%s%s%s%s%s\n", 119 wpa_supplicant_version, 120 wpa_supplicant_full_license1, 121 wpa_supplicant_full_license2, 122 wpa_supplicant_full_license3, 123 wpa_supplicant_full_license4, 124 wpa_supplicant_full_license5); 125 #endif /* CONFIG_NO_STDOUT_DEBUG */ 126 } 127 128 wpa_supplicant_fd_workaround(int start)129 static void wpa_supplicant_fd_workaround(int start) 130 { 131 #ifdef __linux__ 132 static int fd[3] = { -1, -1, -1 }; 133 int i; 134 /* When started from pcmcia-cs scripts, wpa_supplicant might start with 135 * fd 0, 1, and 2 closed. This will cause some issues because many 136 * places in wpa_supplicant are still printing out to stdout. As a 137 * workaround, make sure that fd's 0, 1, and 2 are not used for other 138 * sockets. */ 139 if (start) { 140 for (i = 0; i < 3; i++) { 141 fd[i] = open("/dev/null", O_RDWR); 142 if (fd[i] > 2) { 143 close(fd[i]); 144 fd[i] = -1; 145 break; 146 } 147 } 148 } else { 149 for (i = 0; i < 3; i++) { 150 if (fd[i] >= 0) { 151 close(fd[i]); 152 fd[i] = -1; 153 } 154 } 155 } 156 #endif /* __linux__ */ 157 } 158 159 160 #ifdef CONFIG_MATCH_IFACE wpa_supplicant_init_match(struct wpa_global * global)161 static int wpa_supplicant_init_match(struct wpa_global *global) 162 { 163 /* 164 * The assumption is that the first driver is the primary driver and 165 * will handle the arrival / departure of interfaces. 166 */ 167 if (wpa_drivers[0]->global_init && !global->drv_priv[0]) { 168 global->drv_priv[0] = wpa_drivers[0]->global_init(global); 169 if (!global->drv_priv[0]) { 170 wpa_printf(MSG_ERROR, 171 "Failed to initialize driver '%s'", 172 wpa_drivers[0]->name); 173 return -1; 174 } 175 } 176 177 return 0; 178 } 179 #endif /* CONFIG_MATCH_IFACE */ 180 181 main(int argc,char * argv[])182 int main(int argc, char *argv[]) 183 { 184 int c, i; 185 struct wpa_interface *ifaces, *iface; 186 int iface_count, exitcode = -1; 187 struct wpa_params params; 188 struct wpa_global *global; 189 190 if (os_program_init()) 191 return -1; 192 193 os_memset(¶ms, 0, sizeof(params)); 194 params.wpa_debug_level = MSG_INFO; 195 196 iface = ifaces = os_zalloc(sizeof(struct wpa_interface)); 197 if (ifaces == NULL) 198 return -1; 199 iface_count = 1; 200 201 wpa_supplicant_fd_workaround(1); 202 203 for (;;) { 204 c = getopt(argc, argv, 205 "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW"); 206 if (c < 0) 207 break; 208 switch (c) { 209 case 'b': 210 iface->bridge_ifname = optarg; 211 break; 212 case 'B': 213 params.daemonize++; 214 break; 215 case 'c': 216 iface->confname = optarg; 217 break; 218 case 'C': 219 iface->ctrl_interface = optarg; 220 break; 221 case 'D': 222 iface->driver = optarg; 223 break; 224 case 'd': 225 #ifdef CONFIG_NO_STDOUT_DEBUG 226 printf("Debugging disabled with " 227 "CONFIG_NO_STDOUT_DEBUG=y build time " 228 "option.\n"); 229 goto out; 230 #else /* CONFIG_NO_STDOUT_DEBUG */ 231 params.wpa_debug_level--; 232 break; 233 #endif /* CONFIG_NO_STDOUT_DEBUG */ 234 case 'e': 235 params.entropy_file = optarg; 236 break; 237 #ifdef CONFIG_DEBUG_FILE 238 case 'f': 239 params.wpa_debug_file_path = optarg; 240 break; 241 #endif /* CONFIG_DEBUG_FILE */ 242 case 'g': 243 params.ctrl_interface = optarg; 244 break; 245 case 'G': 246 params.ctrl_interface_group = optarg; 247 break; 248 case 'h': 249 usage(); 250 exitcode = 0; 251 goto out; 252 case 'i': 253 iface->ifname = optarg; 254 break; 255 case 'I': 256 iface->confanother = optarg; 257 break; 258 case 'K': 259 params.wpa_debug_show_keys++; 260 break; 261 case 'L': 262 license(); 263 exitcode = 0; 264 goto out; 265 #ifdef CONFIG_P2P 266 case 'm': 267 params.conf_p2p_dev = optarg; 268 break; 269 #endif /* CONFIG_P2P */ 270 case 'o': 271 params.override_driver = optarg; 272 break; 273 case 'O': 274 params.override_ctrl_interface = optarg; 275 break; 276 case 'p': 277 iface->driver_param = optarg; 278 break; 279 case 'P': 280 os_free(params.pid_file); 281 params.pid_file = os_rel2abs_path(optarg); 282 break; 283 case 'q': 284 params.wpa_debug_level++; 285 break; 286 #ifdef CONFIG_DEBUG_SYSLOG 287 case 's': 288 params.wpa_debug_syslog++; 289 break; 290 #endif /* CONFIG_DEBUG_SYSLOG */ 291 #ifdef CONFIG_DEBUG_LINUX_TRACING 292 case 'T': 293 params.wpa_debug_tracing++; 294 break; 295 #endif /* CONFIG_DEBUG_LINUX_TRACING */ 296 case 't': 297 params.wpa_debug_timestamp++; 298 break; 299 #ifdef CONFIG_CTRL_IFACE_DBUS_NEW 300 case 'u': 301 params.dbus_ctrl_interface = 1; 302 break; 303 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ 304 case 'v': 305 printf("%s\n", wpa_supplicant_version); 306 exitcode = 0; 307 goto out; 308 case 'W': 309 params.wait_for_monitor++; 310 break; 311 #ifdef CONFIG_MATCH_IFACE 312 case 'M': 313 params.match_iface_count++; 314 iface = os_realloc_array(params.match_ifaces, 315 params.match_iface_count, 316 sizeof(struct wpa_interface)); 317 if (!iface) 318 goto out; 319 params.match_ifaces = iface; 320 iface = ¶ms.match_ifaces[params.match_iface_count - 321 1]; 322 os_memset(iface, 0, sizeof(*iface)); 323 break; 324 #endif /* CONFIG_MATCH_IFACE */ 325 case 'N': 326 iface_count++; 327 iface = os_realloc_array(ifaces, iface_count, 328 sizeof(struct wpa_interface)); 329 if (iface == NULL) 330 goto out; 331 ifaces = iface; 332 iface = &ifaces[iface_count - 1]; 333 os_memset(iface, 0, sizeof(*iface)); 334 break; 335 default: 336 usage(); 337 exitcode = 0; 338 goto out; 339 } 340 } 341 342 exitcode = 0; 343 global = wpa_supplicant_init(¶ms); 344 if (global == NULL) { 345 wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant"); 346 exitcode = -1; 347 goto out; 348 } else { 349 wpa_printf(MSG_INFO, "Successfully initialized " 350 "wpa_supplicant"); 351 } 352 353 if (fst_global_init()) { 354 wpa_printf(MSG_ERROR, "Failed to initialize FST"); 355 exitcode = -1; 356 goto out; 357 } 358 359 #if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE) 360 if (!fst_global_add_ctrl(fst_ctrl_cli)) 361 wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl"); 362 #endif 363 364 for (i = 0; exitcode == 0 && i < iface_count; i++) { 365 struct wpa_supplicant *wpa_s; 366 367 if ((ifaces[i].confname == NULL && 368 ifaces[i].ctrl_interface == NULL) || 369 ifaces[i].ifname == NULL) { 370 if (iface_count == 1 && (params.ctrl_interface || 371 #ifdef CONFIG_MATCH_IFACE 372 params.match_iface_count || 373 #endif /* CONFIG_MATCH_IFACE */ 374 params.dbus_ctrl_interface)) 375 break; 376 usage(); 377 exitcode = -1; 378 break; 379 } 380 wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL); 381 if (wpa_s == NULL) { 382 exitcode = -1; 383 break; 384 } 385 } 386 387 #ifdef CONFIG_MATCH_IFACE 388 if (exitcode == 0) 389 exitcode = wpa_supplicant_init_match(global); 390 #endif /* CONFIG_MATCH_IFACE */ 391 392 if (exitcode == 0) 393 exitcode = wpa_supplicant_run(global); 394 395 wpa_supplicant_deinit(global); 396 397 fst_global_deinit(); 398 399 out: 400 wpa_supplicant_fd_workaround(0); 401 os_free(ifaces); 402 #ifdef CONFIG_MATCH_IFACE 403 os_free(params.match_ifaces); 404 #endif /* CONFIG_MATCH_IFACE */ 405 os_free(params.pid_file); 406 407 crypto_unload(); 408 os_program_deinit(); 409 410 return exitcode; 411 } 412