Re: WPA status 2005-12-22



On Fri, Dec 23, 2005 at 04:11:33AM -0500, Dan Williams wrote:
> Quick update on WPA stuff...

...

> What's left to be done?
> -----------------------

...

> o Create a supplicant_manager object that controls invocations of
>     wpa_supplicant
>     o Write out correct wpa_supplicant config file and ask the
>         NMAPSecurity objects to write out their security information
>     o Connect to wpa_supplicant's control socket to monitor association
>         status

Here is a simple wrapper around wpa_supplicant that starts the daemon
and can request an interface to be handled by the wpa_supplicant daemon.
It connects an GIOChannel to the socket and receives "connected/disconnected"
messages. At the moment it's a simple standalone program, which runs as:
  $ ./wpa_supplicant_wrapper <essid> <passphrase>

and just prints "DOWN", "UP" lines to stdout at state changes.

I does not write a config file, all communication is done via the socket
interface. It only accepts pre shared keys at the moment. The wpa_ctrl.[ch]
files are copied from the wpa_supplicant sources.

Hope this is useful for integration into NM itself.

Thanks,
Kay
/*
 *	wpa_supplicant wrapper
 *
 *	Copyright (C) 2005 Kay Sievers <kay sievers vrfy org>
 *
 *	This program is free software; you can redistribute it and/or modify it
 *	under the terms of the GNU General Public License as published by the
 *	Free Software Foundation version 2 of the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <glib.h>

#include "wpa_ctrl.h"


#define WPA_SUPPLICANT_GLOBAL_SOCKET		"/var/run/wpa_supplicant-global"
#define WPA_SUPPLICANT_CONTROL_SOCKET		"/var/run/wpa_supplicant"

int wpa_supplicant_start (void);
struct wpa_ctrl *wpa_supplicant_interface_init (const char *interface);
int wpa_supplicant_psk_setup(struct wpa_ctrl *ctrl,
			     const char *essid,
			     const char *psk);


int wpa_supplicant_start (void)
{
	char *argv[5];
	int exit_status;

	argv[0] = "/usr/sbin/wpa_supplicant";
	argv[1] = "-g";
	argv[2] = "/var/run/wpa_supplicant-global";
	argv[3] = "-B";
	argv[4] = NULL;

	/* wpa_supplicant -g/var/run/wpa_supplicant-global -B */
	if (!g_spawn_sync ("/", argv, NULL, 0, NULL, NULL, NULL, NULL, &exit_status, NULL))
		return 1;

	if (exit_status != 0)
		return 2;

	return 0;
}

static gboolean monitor_data(GIOChannel *source, GIOCondition condition, gpointer user_data)
{
	char message[2048];
	size_t message_len;
	struct wpa_ctrl *ctrl;

	ctrl = user_data;
	if (ctrl == NULL)
		return FALSE;

	message_len = sizeof(message);
	wpa_ctrl_recv(ctrl, message, &message_len);
	message[message_len] = '\0';
	if (strstr (message, WPA_EVENT_CONNECTED) != NULL)
		printf("UP\n");
	else if (strstr (message, WPA_EVENT_DISCONNECTED) != NULL)
		printf("DOWN\n");

	return TRUE;
}

struct wpa_ctrl *wpa_supplicant_interface_init (const char *interface)
{
	struct wpa_ctrl *ctrl;
	struct wpa_ctrl *ctrl_if;
	char *command;
	char response[2048];
	size_t response_len;
	char *socket_path;
	int rc = 0;

	ctrl = wpa_ctrl_open (WPA_SUPPLICANT_GLOBAL_SOCKET);
	if (ctrl == NULL) {
		rc = -EIO;
		goto exit;
	}

	/* wpa_cli -g/var/run/wpa_supplicant-global interface_add eth1 "" wext /var/run/wpa_supplicant */
	command = g_strdup_printf ("INTERFACE_ADD %s\t\twext\t" WPA_SUPPLICANT_CONTROL_SOCKET "\t", interface);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	if (wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL) != 0) {
		rc = 1;
		goto exit;
	}
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}
	wpa_ctrl_close(ctrl);

	/* attach to interface socket */
	socket_path = g_strdup_printf (WPA_SUPPLICANT_CONTROL_SOCKET "/%s", interface);
	if (socket_path == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	ctrl_if = wpa_ctrl_open(socket_path);
	g_free (socket_path);
	if (ctrl_if == NULL) {
		rc = -ENOMEM;
		goto exit;
	}

exit:
	if (rc == 0)
		return ctrl_if;
	else
		return NULL;
}

int wpa_supplicant_psk_setup(struct wpa_ctrl *ctrl,
			     const char *essid,
			     const char *psk)
{
	char *command;
	char response[2048];
	size_t response_len;
	int network_id;
	int rc = 0;

	/* wpa_cli -ieth1 add_network */
	command = g_strdup_printf ("ADD_NETWORK");
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (sscanf (response, "%i\n", &network_id) != 1) {
		rc = 1;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 ssid '"$ESID"' */
	command = g_strdup_printf ("SET_NETWORK %i ssid \"%s\"", network_id, essid);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 key_mgmt WPA-PSK */
	command = g_strdup_printf ("SET_NETWORK %i key_mgmt WPA-PSK", network_id);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 psk '"$PSK"' */
	command = g_strdup_printf ("SET_NETWORK %i psk \"%s\"", network_id, psk);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 pairwise TKIP */
	command = g_strdup_printf ("SET_NETWORK %i pairwise TKIP", network_id);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 group TKIP */
	command = g_strdup_printf ("SET_NETWORK %i group TKIP", network_id);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 set_network 0 proto WPA */
	command = g_strdup_printf ("SET_NETWORK %i proto WPA", network_id);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 2;
		goto exit;
	}

	/* wpa_cli -ieth1 enable_network 0 */
	command = g_strdup_printf ("ENABLE_NETWORK %i", network_id);
	if (command == NULL) {
		rc = -ENOMEM;
		goto exit;
	}
	wpa_ctrl_request (ctrl, command, strlen(command), response, &response_len, NULL);
	g_free (command);
	response[response_len] = '\0';
	if (strncmp (response, "OK", 2) != 0) {
		rc = 3;
		goto exit;
	}

exit:
	return rc;
}

int main(int argc, char *argv[], char *envp[])
{
	struct wpa_ctrl *ctrl_if;
	GMainLoop *mainloop;
	GIOChannel *monitor_channel;
	int monitor_fd;
	int rc = 0;

	mainloop = g_main_loop_new (NULL, FALSE);

	/* start daemon */
	if (wpa_supplicant_start () != 0) {
		rc = 1;
		goto exit;
	}

	/* init network interface */
	ctrl_if = wpa_supplicant_interface_init ("eth1");
	if (ctrl_if == NULL) {
		rc = 2;
		goto exit;
	}

	/* setup network config */
	if (wpa_supplicant_psk_setup (ctrl_if, argv[1], argv[2]) != 0) {
		rc = 3;
		goto exit;
	}

	/* register network event monitor */
	if (wpa_ctrl_attach(ctrl_if) != 0) {
		rc = 4;
		goto exit;
	}
	monitor_fd = wpa_ctrl_get_fd(ctrl_if);
	monitor_channel = g_io_channel_unix_new(monitor_fd);
	g_io_add_watch(monitor_channel, G_IO_IN, monitor_data, ctrl_if);

	g_main_loop_run(mainloop);

exit:
	return rc;
}
all:
	gcc -Wall -DCONFIG_CTRL_IFACE -c wpa_ctrl.c
	gcc -Wall \
		$(shell pkg-config --cflags glib-2.0) \
		-o wpa_supplicant_wrapper wpa_supplicant_wrapper.c wpa_ctrl.o $(shell pkg-config --libs glib-2.0)

clean:
	-rm -f *.o
	-rm wpa_supplicant_wrapper
/*
 * wpa_supplicant/hostapd control interface library
 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline cc hut fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Alternatively, this software may be distributed under the terms of BSD
 * license.
 *
 * See README and COPYING for more details.
 */

//#include "includes.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>

#ifdef CONFIG_CTRL_IFACE

#ifndef CONFIG_CTRL_IFACE_UDP
#include <sys/un.h>
#endif /* CONFIG_CTRL_IFACE_UDP */

#include "wpa_ctrl.h"
//#include "common.h"

/**
 * struct wpa_ctrl - Internal structure for control interface library
 *
 * This structure is used by the wpa_supplicant/hostapd control interface
 * library to store internal data. Programs using the library should not touch
 * this data directly. They can only use the pointer to the data structure as
 * an identifier for the control interface connection and use this as one of
 * the arguments for most of the control interface library functions.
 */
struct wpa_ctrl {
	int s;
#ifdef CONFIG_CTRL_IFACE_UDP
	struct sockaddr_in local;
	struct sockaddr_in dest;
#else /* CONFIG_CTRL_IFACE_UDP */
	struct sockaddr_un local;
	struct sockaddr_un dest;
#endif /* CONFIG_CTRL_IFACE_UDP */
};


struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
{
	struct wpa_ctrl *ctrl;
#ifndef CONFIG_CTRL_IFACE_UDP
	static int counter = 0;
#endif /* CONFIG_CTRL_IFACE_UDP */

	ctrl = malloc(sizeof(*ctrl));
	if (ctrl == NULL)
		return NULL;
	memset(ctrl, 0, sizeof(*ctrl));

#ifdef CONFIG_CTRL_IFACE_UDP
	ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
	if (ctrl->s < 0) {
		perror("socket");
		free(ctrl);
		return NULL;
	}

	ctrl->local.sin_family = AF_INET;
	ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
		 sizeof(ctrl->local)) < 0) {
		close(ctrl->s);
		free(ctrl);
		return NULL;
	}

	ctrl->dest.sin_family = AF_INET;
	ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
	ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
		    sizeof(ctrl->dest)) < 0) {
		perror("connect");
		close(ctrl->s);
		free(ctrl);
		return NULL;
	}
#else /* CONFIG_CTRL_IFACE_UDP */
	ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
	if (ctrl->s < 0) {
		free(ctrl);
		return NULL;
	}

	ctrl->local.sun_family = AF_UNIX;
	snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
		 "/tmp/wpa_ctrl_%d-%d", getpid(), counter++);
	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
		    sizeof(ctrl->local)) < 0) {
		close(ctrl->s);
		free(ctrl);
		return NULL;
	}

	ctrl->dest.sun_family = AF_UNIX;
	snprintf(ctrl->dest.sun_path, sizeof(ctrl->dest.sun_path), "%s",
		 ctrl_path);
	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
		    sizeof(ctrl->dest)) < 0) {
		close(ctrl->s);
		unlink(ctrl->local.sun_path);
		free(ctrl);
		return NULL;
	}
#endif /* CONFIG_CTRL_IFACE_UDP */

	return ctrl;
}


void wpa_ctrl_close(struct wpa_ctrl *ctrl)
{
#ifndef CONFIG_CTRL_IFACE_UDP
	unlink(ctrl->local.sun_path);
#endif /* CONFIG_CTRL_IFACE_UDP */
	close(ctrl->s);
	free(ctrl);
}


int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
		     char *reply, size_t *reply_len,
		     void (*msg_cb)(char *msg, size_t len))
{
	struct timeval tv;
	int res;
	fd_set rfds;

	if (send(ctrl->s, cmd, cmd_len, 0) < 0)
		return -1;

	for (;;) {
		tv.tv_sec = 2;
		tv.tv_usec = 0;
		FD_ZERO(&rfds);
		FD_SET(ctrl->s, &rfds);
		res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
		if (FD_ISSET(ctrl->s, &rfds)) {
			res = recv(ctrl->s, reply, *reply_len, 0);
			if (res < 0)
				return res;
			if (res > 0 && reply[0] == '<') {
				/* This is an unsolicited message from
				 * wpa_supplicant, not the reply to the
				 * request. Use msg_cb to report this to the
				 * caller. */
				if (msg_cb) {
					/* Make sure the message is nul
					 * terminated. */
					if ((size_t) res == *reply_len)
						res = (*reply_len) - 1;
					reply[res] = '\0';
					msg_cb(reply, res);
				}
				continue;
			}
			*reply_len = res;
			break;
		} else {
			return -2;
		}
	}
	return 0;
}


static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
{
	char buf[10];
	int ret;
	size_t len = 10;

	ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
			       buf, &len, NULL);
	if (ret < 0)
		return ret;
	if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
		return 0;
	return -1;
}


int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
{
	return wpa_ctrl_attach_helper(ctrl, 1);
}


int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
{
	return wpa_ctrl_attach_helper(ctrl, 0);
}


int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
{
	int res;

	res = recv(ctrl->s, reply, *reply_len, 0);
	if (res < 0)
		return res;
	*reply_len = res;
	return 0;
}


int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
{
	struct timeval tv;
	int res;
	fd_set rfds;
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	FD_ZERO(&rfds);
	FD_SET(ctrl->s, &rfds);
	res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
	return FD_ISSET(ctrl->s, &rfds);
}


int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
{
	return ctrl->s;
}

#endif /* CONFIG_CTRL_IFACE */
/*
 * wpa_supplicant/hostapd control interface library
 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline cc hut fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * Alternatively, this software may be distributed under the terms of BSD
 * license.
 *
 * See README and COPYING for more details.
 */

#ifndef WPA_CTRL_H
#define WPA_CTRL_H

#ifdef  __cplusplus
extern "C" {
#endif

/* wpa_supplicant control interface - fixed message prefixes */

/** Interactive request for identity/password/pin */
#define WPA_CTRL_REQ "CTRL-REQ-"

/** Response to identity/password/pin request */
#define WPA_CTRL_RSP "CTRL-RSP-"

/* Event messages with fixed prefix */
/** Authentication completed successfully and data connection enabled */
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
/** Disconnected, data connection is not available */
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
/** wpa_supplicant is exiting */
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
/** Password change was completed successfully */
#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
/** EAP-Request/Notification received */
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
/** EAP authentication started (EAP-Request/Identity received) */
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
/** EAP method selected */
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
/** EAP authentication completed successfully */
#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
/** EAP authentication failed (EAP-Failure received) */
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "


/* wpa_supplicant/hostapd control interface access */

/**
 * wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
 * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
 * Returns: Pointer to abstract control interface data or %NULL on failure
 *
 * This function is used to open a control interface to wpa_supplicant/hostapd.
 * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path
 * is configured in wpa_supplicant/hostapd and other programs using the control
 * interface need to use matching path configuration.
 */
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);


/**
 * wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd
 * @ctrl: Control interface data from wpa_ctrl_open()
 *
 * This function is used to close a control interface.
 */
void wpa_ctrl_close(struct wpa_ctrl *ctrl);


/**
 * wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
 * @ctrl: Control interface data from wpa_ctrl_open()
 * @cmd: Command; usually, ASCII text, e.g., "PING"
 * @cmd_len: Length of the cmd in bytes
 * @reply: Buffer for the response
 * @reply_len: Reply buffer length
 * @msg_cb: Callback function for unsolicited messages or %NULL if not used
 * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
 *
 * This function is used to send commands to wpa_supplicant/hostapd. Received
 * response will be written to reply and reply_len is set to the actual length
 * of the reply. This function will block for up to two seconds while waiting
 * for the reply. If unsolicited messages are received, the blocking time may
 * be longer.
 *
 * msg_cb can be used to register a callback function that will be called for
 * unsolicited messages received while waiting for the command response. These
 * messages may be received if wpa_ctrl_request() is called at the same time as
 * wpa_supplicant/hostapd is sending such a message. This can happen only if
 * the program has used wpa_ctrl_attach() to register itself as a monitor for
 * event messages. Alternatively to msg_cb, programs can register two control
 * interface connections and use one of them for commands and the other one for
 * receiving event messages, in other words, call wpa_ctrl_attach() only for
 * the control interface connection that will be used for event messages.
 */
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
		     char *reply, size_t *reply_len,
		     void (*msg_cb)(char *msg, size_t len));


/**
 * wpa_ctrl_attach - Register as an event monitor for the control interface
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: 0 on success, -1 on failure, -2 on timeout
 *
 * This function registers the control interface connection as a monitor for
 * wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the
 * control interface connection starts receiving event messages that can be
 * read with wpa_ctrl_recv().
 */
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);


/**
 * wpa_ctrl_detach - Unregister event monitor from the control interface
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: 0 on success, -1 on failure, -2 on timeout
 *
 * This function unregisters the control interface connection as a monitor for
 * wpa_supplicant/hostapd events, i.e., cancels the registration done with
 * wpa_ctrl_attach().
 */
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);


/**
 * wpa_ctrl_recv - Receive a pending control interface message
 * @ctrl: Control interface data from wpa_ctrl_open()
 * @reply: Buffer for the message data
 * @reply_len: Length of the reply buffer
 * Returns: 0 on success, -1 on failure
 *
 * This function will receive a pending control interface message. This
 * function will block if no messages are available. The received response will
 * be written to reply and reply_len is set to the actual length of the reply.
 * wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
 * must have been used to register the control interface as an event monitor.
 */
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);


/**
 * wpa_ctrl_pending - Check whether there are pending event messages
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: Non-zero if there are pending messages
 *
 * This function will check whether there are any pending control interface
 * message available to be received with wpa_ctrl_recv(). wpa_ctrl_pending() is
 * only used for event messages, i.e., wpa_ctrl_attach() must have been used to
 * register the control interface as an event monitor.
 */
int wpa_ctrl_pending(struct wpa_ctrl *ctrl);


/**
 * wpa_ctrl_get_fd - Get file descriptor used by the control interface
 * @ctrl: Control interface data from wpa_ctrl_open()
 * Returns: File descriptor used for the connection
 *
 * This function can be used to get the file descriptor that is used for the
 * control interface connection. The returned value can be used, e.g., with
 * select() while waiting for multiple events.
 *
 * The returned file descriptor must not be used directly for sending or
 * receiving packets; instead, the library functions wpa_ctrl_request() and
 * wpa_ctrl_recv() must be used for this.
 */
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);

#ifdef CONFIG_CTRL_IFACE_UDP
#define WPA_CTRL_IFACE_PORT 9877
#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
#endif /* CONFIG_CTRL_IFACE_UDP */


#ifdef  __cplusplus
}
#endif

#endif /* WPA_CTRL_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]