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