18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / main() function for UNIX like OSes and MinGW
3b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt * Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <fcntl.h>
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
1734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#include "p2p_supplicant.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void)
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("%s\n\n%s\n"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "usage:\n"
251846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "  wpa_supplicant [-BddhKLqq"
261846323989242844f0e857458a8939fa5836429cDmitry Shmidt#ifdef CONFIG_DEBUG_SYSLOG
271846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "s"
281846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* CONFIG_DEBUG_SYSLOG */
291846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "t"
301846323989242844f0e857458a8939fa5836429cDmitry Shmidt#ifdef CONFIG_DBUS
311846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "u"
321846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* CONFIG_DBUS */
331846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "vW] [-P<pid file>] "
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "[-g<global ctrl>] \\\n"
35b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	       "        [-G<group>] \\\n"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "[-p<driver_param>] \\\n"
381846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       "        [-b<br_ifname>] [-e<entropy file>]"
391846323989242844f0e857458a8939fa5836429cDmitry Shmidt#ifdef CONFIG_DEBUG_FILE
401846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       " [-f<debug file>]"
411846323989242844f0e857458a8939fa5836429cDmitry Shmidt#endif /* CONFIG_DEBUG_FILE */
421846323989242844f0e857458a8939fa5836429cDmitry Shmidt	       " \\\n"
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "        [-o<override driver>] [-O<override ctrl>] \\\n"
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "        [-N -i<ifname> -c<conf> [-C<ctrl>] "
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "[-D<driver>] \\\n"
462ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#ifdef CONFIG_P2P
472ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	       "        [-m<P2P Device config file>] \\\n"
482ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#endif /* CONFIG_P2P */
495d1c8ad11de48ba5e449e83e1e5dcd844e9c35d1Jouni Malinen	       "        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] "
505d1c8ad11de48ba5e449e83e1e5dcd844e9c35d1Jouni Malinen	       "...]\n"
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "\n"
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "drivers:\n",
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_version, wpa_supplicant_license);
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i]; i++) {
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		printf("  %s = %s\n",
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       wpa_drivers[i]->name,
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       wpa_drivers[i]->desc);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("options:\n"
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -b = optional bridge interface name\n"
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -B = run daemon in the background\n"
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -c = Configuration file\n"
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -C = ctrl_interface parameter (only used if -c is not)\n"
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -i = interface name\n"
685d1c8ad11de48ba5e449e83e1e5dcd844e9c35d1Jouni Malinen	       "  -I = additional configuration file\n"
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -d = increase debugging verbosity (-dd even more)\n"
7075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	       "  -D = driver name (can be multiple drivers: nl80211,wext)\n"
7175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	       "  -e = entropy file\n");
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -f = log output to debug file instead of stdout\n");
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -g = global ctrl_interface\n"
76b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt	       "  -G = global ctrl_interface group\n"
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -K = include keys (passwords, etc.) in debug output\n");
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_SYSLOG
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -s = log output to syslog instead of stdout\n");
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_SYSLOG */
8104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
8204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	printf("  -T = record to Linux tracing in addition to logging\n");
8304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	printf("       (records all messages regardless of debug verbosity)\n");
8404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -t = include timestamp in debug messages\n"
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -h = show this help text\n"
87c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	       "  -L = show license (BSD)\n"
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -o = override driver parameter for new interfaces\n"
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -O = override ctrl_interface parameter for new interfaces\n"
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -p = driver parameters\n"
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -P = PID file\n"
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -q = decrease debugging verbosity (-qq even less)\n");
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DBUS
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -u = enable DBus control interface\n");
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DBUS */
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("  -v = show version\n"
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -W = wait for a control interface monitor before starting\n"
982ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#ifdef CONFIG_P2P
992ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt	       "  -m = Configuration file for the P2P Device interface\n"
1002ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#endif /* CONFIG_P2P */
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  -N = start describing new interface\n");
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("example:\n"
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       "  wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n",
1054b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	       wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211");
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void license(void)
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	printf("%s\n\n%s%s%s%s%s\n",
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_version,
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_full_license1,
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_full_license2,
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_full_license3,
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_full_license4,
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       wpa_supplicant_full_license5);
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void wpa_supplicant_fd_workaround(int start)
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __linux__
12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	static int fd[3] = { -1, -1, -1 };
12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int i;
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* When started from pcmcia-cs scripts, wpa_supplicant might start with
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * fd 0, 1, and 2 closed. This will cause some issues because many
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * places in wpa_supplicant are still printing out to stdout. As a
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * workaround, make sure that fd's 0, 1, and 2 are not used for other
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * sockets. */
13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (start) {
13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (i = 0; i < 3; i++) {
13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			fd[i] = open("/dev/null", O_RDWR);
13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (fd[i] > 2) {
13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				close(fd[i]);
13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				fd[i] = -1;
14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				break;
14161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
14261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
14361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else {
14461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		for (i = 0; i < 3; i++) {
14561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (fd[i] >= 0) {
14661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				close(fd[i]);
14761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				fd[i] = -1;
14861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __linux__ */
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[])
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int c, i;
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface *ifaces, *iface;
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int iface_count, exitcode = -1;
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_params params;
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_program_init())
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wpa_debug_level = MSG_INFO;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ifaces == NULL)
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface_count = 1;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_supplicant_fd_workaround(1);
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (;;) {
17704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		c = getopt(argc, argv,
1782ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt			   "b:Bc:C:D:de:f:g:G:hi:I:KLm:No:O:p:P:qsTtuvW");
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c < 0)
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (c) {
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'b':
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->bridge_ifname = optarg;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'B':
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.daemonize++;
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'c':
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->confname = optarg;
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'C':
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->ctrl_interface = optarg;
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'D':
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->driver = optarg;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'd':
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NO_STDOUT_DEBUG
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("Debugging disabled with "
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       "CONFIG_NO_STDOUT_DEBUG=y build time "
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       "option.\n");
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NO_STDOUT_DEBUG */
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_level--;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
20775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		case 'e':
20875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			params.entropy_file = optarg;
20975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			break;
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'f':
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_file_path = optarg;
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'g':
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.ctrl_interface = optarg;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
218b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt		case 'G':
219b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			params.ctrl_interface_group = optarg;
220b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt			break;
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'h':
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			usage();
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = 0;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'i':
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->ifname = optarg;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
22864f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt		case 'I':
22964f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt			iface->confanother = optarg;
23064f47c5c24428834677459e048420f86e3514c20Dmitry Shmidt			break;
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'K':
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_show_keys++;
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'L':
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			license();
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = 0;
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
2382ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#ifdef CONFIG_P2P
2392ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt		case 'm':
2402ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt			iface->conf_p2p_dev = optarg;
2412ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt			break;
2422ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt#endif /* CONFIG_P2P */
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'o':
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.override_driver = optarg;
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'O':
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.override_ctrl_interface = optarg;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'p':
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->driver_param = optarg;
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'P':
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(params.pid_file);
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.pid_file = os_rel2abs_path(optarg);
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'q':
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_level++;
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_SYSLOG
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 's':
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_syslog++;
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_SYSLOG */
26404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
26504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		case 'T':
26604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			params.wpa_debug_tracing++;
26704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			break;
26804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 't':
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wpa_debug_timestamp++;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DBUS
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'u':
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.dbus_ctrl_interface = 1;
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DBUS */
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'v':
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			printf("%s\n", wpa_supplicant_version);
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = 0;
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'W':
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wait_for_monitor++;
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'N':
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface_count++;
28661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			iface = os_realloc_array(ifaces, iface_count,
28761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						 sizeof(struct wpa_interface));
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (iface == NULL)
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto out;
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ifaces = iface;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface = &ifaces[iface_count - 1];
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(iface, 0, sizeof(*iface));
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		default:
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			usage();
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = 0;
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	exitcode = 0;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global = wpa_supplicant_init(&params);
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL) {
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		exitcode = -1;
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
30704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
30804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_INFO, "Successfully initialized "
30904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   "wpa_supplicant");
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; exitcode == 0 && i < iface_count; i++) {
31334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		struct wpa_supplicant *wpa_s;
31434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((ifaces[i].confname == NULL &&
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     ifaces[i].ctrl_interface == NULL) ||
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ifaces[i].ifname == NULL) {
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (iface_count == 1 && (params.ctrl_interface ||
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 params.dbus_ctrl_interface))
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			usage();
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = -1;
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
32534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);
32634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		if (wpa_s == NULL) {
32734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt			exitcode = -1;
32834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt			break;
32934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		}
33034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#ifdef CONFIG_P2P
33134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		if (wpa_s->global->p2p == NULL &&
33234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		    (wpa_s->drv_flags &
33334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt		     WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
3349ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt		    wpas_p2p_add_p2pdev_interface(wpa_s, iface->conf_p2p_dev) <
3359ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt		    0)
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exitcode = -1;
33734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#endif /* CONFIG_P2P */
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (exitcode == 0)
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		exitcode = wpa_supplicant_run(global);
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_deinit(global);
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
34661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_supplicant_fd_workaround(0);
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(ifaces);
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(params.pid_file);
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_program_deinit();
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return exitcode;
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
354