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