2006-01-04 Dan Williams <dcbw@redhat.com>
First dump of wpa_supplicant-related code. It's not hooked up to anything yet though. Thanks to Kay Sievers for wpa_supplicant_wrapper.c, which formed the basis for this work, and to Jouni Malinen for writing wpa_ctrl.c and wpa_ctrl.h. * src/Makefile.am src/wpa_ctrl.[ch] - Add wpa_ctrl stuff from wpa_supplicant so we can talk to it * src/NetworkManagerUtils.[ch] - (nm_utils_supplicant_request, nm_utils_supplicant_request_with_check): Add convenience functions for talking to wpa_supplicant * src/nm-ap-security.[ch] src/nm-ap-security-wep.c src/nm-ap-security-wpa-psk.[ch] - Update and implement real_write_supplicant_config functions in all security types - (nm_ap_security_wpa_psk_new_from_ap): implement in nm-ap-security-wpa-psk.c * src/nm-device-802-11-wireless.c - (supplicant_cleanup, supplicant_watch_cb, supplicant_monitor_status_cb, wpa_supplicant_start, wpa_supplicant_interface_init, wpa_supplicant_send_network_config): add functions to talk to wpa_supplicant and write network config to it git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1267 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
29
ChangeLog
29
ChangeLog
@@ -1,3 +1,32 @@
|
||||
2006-01-04 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
First dump of wpa_supplicant-related code. It's not hooked up to
|
||||
anything yet though. Thanks to Kay Sievers for
|
||||
wpa_supplicant_wrapper.c, which formed the basis for this work,
|
||||
and to Jouni Malinen for writing wpa_ctrl.c and wpa_ctrl.h.
|
||||
|
||||
* src/Makefile.am
|
||||
src/wpa_ctrl.[ch]
|
||||
- Add wpa_ctrl stuff from wpa_supplicant so we can talk to it
|
||||
|
||||
* src/NetworkManagerUtils.[ch]
|
||||
- (nm_utils_supplicant_request, nm_utils_supplicant_request_with_check):
|
||||
Add convenience functions for talking to wpa_supplicant
|
||||
|
||||
* src/nm-ap-security.[ch]
|
||||
src/nm-ap-security-wep.c
|
||||
src/nm-ap-security-wpa-psk.[ch]
|
||||
- Update and implement real_write_supplicant_config functions
|
||||
in all security types
|
||||
- (nm_ap_security_wpa_psk_new_from_ap): implement in
|
||||
nm-ap-security-wpa-psk.c
|
||||
|
||||
* src/nm-device-802-11-wireless.c
|
||||
- (supplicant_cleanup, supplicant_watch_cb, supplicant_monitor_status_cb,
|
||||
wpa_supplicant_start, wpa_supplicant_interface_init,
|
||||
wpa_supplicant_send_network_config): add functions to talk to
|
||||
wpa_supplicant and write network config to it
|
||||
|
||||
2006-01-04 Robert Love <rml@novell.com>
|
||||
|
||||
* src/NetworkManagerDialup.h: add 'type' field and NM_DIALUP_TYPE
|
||||
|
@@ -59,7 +59,9 @@ NetworkManager_SOURCES = \
|
||||
nm-ap-security-wpa-psk.c \
|
||||
nm-ap-security-wpa-psk.h \
|
||||
wpa.c \
|
||||
wpa.h
|
||||
wpa.h \
|
||||
wpa_ctrl.c \
|
||||
wpa_ctrl.h
|
||||
|
||||
NetworkManager_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include "nm-device.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
#include "nm-device-802-3-ethernet.h"
|
||||
#include "wpa_ctrl.h"
|
||||
|
||||
#include <netlink/addr.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -698,3 +699,84 @@ int nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask)
|
||||
return (32 - (i-1));
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
nm_utils_supplicant_request (struct wpa_ctrl *ctrl,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
size_t len;
|
||||
char * response = NULL;
|
||||
char * command;
|
||||
|
||||
g_return_val_if_fail (ctrl != NULL, NULL);
|
||||
g_return_val_if_fail (format != NULL, NULL);
|
||||
|
||||
va_start (args, format);
|
||||
if (!(command = g_strdup_vprintf (format, args)))
|
||||
return NULL;
|
||||
va_end (args);
|
||||
|
||||
response = g_malloc (2048);
|
||||
wpa_ctrl_request (ctrl, command, strlen (command), response, &len, NULL);
|
||||
g_free (command);
|
||||
response[len] = '\0';
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nm_utils_supplicant_request_with_check (struct wpa_ctrl *ctrl,
|
||||
const char *expected,
|
||||
const char *func,
|
||||
const char *err_msg_cmd,
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
gboolean success = FALSE;
|
||||
size_t len;
|
||||
char * response = NULL;
|
||||
char * command;
|
||||
char * temp;
|
||||
|
||||
g_return_val_if_fail (ctrl != NULL, FALSE);
|
||||
g_return_val_if_fail (expected != NULL, FALSE);
|
||||
g_return_val_if_fail (format != NULL, FALSE);
|
||||
|
||||
va_start (args, format);
|
||||
if (!(command = g_strdup_vprintf (format, args)))
|
||||
goto out;
|
||||
|
||||
response = g_malloc (2048);
|
||||
wpa_ctrl_request (ctrl, command, strlen (command), response, &len, NULL);
|
||||
response[len] = '\0';
|
||||
|
||||
if (response)
|
||||
{
|
||||
if (strncmp (response, expected, strlen (expected)) == 0)
|
||||
success = TRUE;
|
||||
else
|
||||
{
|
||||
temp = g_strdup_printf ("%s: supplicant error for '%s'. Response: '%s'",
|
||||
func, err_msg_cmd ? err_msg_cmd : command, response);
|
||||
nm_warning_str (temp);
|
||||
g_free (temp);
|
||||
}
|
||||
g_free (response);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = g_strdup_printf ("%s: supplicant error for '%s'. No response.",
|
||||
func, err_msg_cmd ? err_msg_cmd : command);
|
||||
nm_warning_str (temp);
|
||||
g_free (temp);
|
||||
}
|
||||
g_free (command);
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@@ -106,4 +106,15 @@ struct nl_addr * nm_utils_ip4_addr_to_nl_addr (guint32 ip4_addr);
|
||||
|
||||
int nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask);
|
||||
|
||||
char * nm_utils_supplicant_request (struct wpa_ctrl *ctrl,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
gboolean nm_utils_supplicant_request_with_check (struct wpa_ctrl *ctrl,
|
||||
const char *expected,
|
||||
const char *func,
|
||||
const char *alt_cmd_for_err_msg,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
#endif
|
||||
|
@@ -29,6 +29,8 @@
|
||||
#include "nm-ap-security-private.h"
|
||||
#include "dbus-helpers.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
#include "nm-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#define NM_AP_SECURITY_WEP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP_SECURITY_WEP, NMAPSecurityWEPPrivate))
|
||||
|
||||
@@ -105,10 +107,38 @@ real_serialize (NMAPSecurity *instance, DBusMessageIter *iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
real_write_wpa_supplicant_config (NMAPSecurity *instance, int fd)
|
||||
static gboolean
|
||||
real_write_supplicant_config (NMAPSecurity *instance,
|
||||
struct wpa_ctrl *ctrl,
|
||||
int nwid)
|
||||
{
|
||||
NMAPSecurityWEP * self = NM_AP_SECURITY_WEP (instance);
|
||||
NMAPSecurityWEP * self = NM_AP_SECURITY_WEP (instance);
|
||||
gboolean success = FALSE;
|
||||
char * msg = NULL;
|
||||
const char * key = nm_ap_security_get_key (instance);
|
||||
|
||||
/* WEP network setup */
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i key_mgmt NONE", nwid))
|
||||
goto out;
|
||||
|
||||
msg = g_strdup_printf ("SET_NETWORK %i wep_key0 <key>", nwid);
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, msg,
|
||||
"SET_NETWORK %i wep_key0 %s", nwid, key))
|
||||
{
|
||||
g_free (msg);
|
||||
goto out;
|
||||
}
|
||||
g_free (msg);
|
||||
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i wep_tx_keyidx 0", nwid))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -147,7 +177,7 @@ nm_ap_security_wep_class_init (NMAPSecurityWEPClass *klass)
|
||||
|
||||
par_class->copy_constructor_func = real_copy_constructor;
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_wpa_supplicant_config_func = real_write_wpa_supplicant_config;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->device_setup_func = real_device_setup;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityWEPPrivate));
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "nm-ap-security-private.h"
|
||||
#include "dbus-helpers.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#define NM_AP_SECURITY_WPA_PSK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP_SECURITY_WPA_PSK, NMAPSecurityWPA_PSKPrivate))
|
||||
|
||||
@@ -38,6 +39,16 @@ struct _NMAPSecurityWPA_PSKPrivate
|
||||
int key_mgt;
|
||||
};
|
||||
|
||||
static void set_description (NMAPSecurityWPA_PSK *security)
|
||||
{
|
||||
NMAPSecurity * parent = NM_AP_SECURITY (security);
|
||||
|
||||
if (nm_ap_security_get_we_cipher (parent) == IW_AUTH_CIPHER_TKIP)
|
||||
nm_ap_security_set_description (parent, _("WPA TKIP"));
|
||||
else
|
||||
nm_ap_security_set_description (parent, _("WPA CCMP"));
|
||||
}
|
||||
|
||||
NMAPSecurityWPA_PSK *
|
||||
nm_ap_security_wpa_psk_new_deserialize (DBusMessageIter *iter, int we_cipher)
|
||||
{
|
||||
@@ -61,15 +72,36 @@ nm_ap_security_wpa_psk_new_deserialize (DBusMessageIter *iter, int we_cipher)
|
||||
security->priv->wpa_version = wpa_version;
|
||||
security->priv->key_mgt = key_mgt;
|
||||
|
||||
if (we_cipher == IW_AUTH_CIPHER_TKIP)
|
||||
nm_ap_security_set_description (NM_AP_SECURITY (security), _("WPA TKIP"));
|
||||
else
|
||||
nm_ap_security_set_description (NM_AP_SECURITY (security), _("WPA CCMP"));
|
||||
set_description (security);
|
||||
|
||||
out:
|
||||
return security;
|
||||
}
|
||||
|
||||
NMAPSecurityWPA_PSK *
|
||||
nm_ap_security_wpa_psk_new_from_ap (NMAccessPoint *ap, int we_cipher)
|
||||
{
|
||||
NMAPSecurityWPA_PSK * security = NULL;
|
||||
guint32 caps;
|
||||
|
||||
g_return_val_if_fail (ap != NULL, NULL);
|
||||
g_return_val_if_fail (we_cipher == IW_AUTH_CIPHER_TKIP || (we_cipher == IW_AUTH_CIPHER_CCMP), NULL);
|
||||
|
||||
security = g_object_new (NM_TYPE_AP_SECURITY_WPA_PSK, NULL);
|
||||
nm_ap_security_set_we_cipher (NM_AP_SECURITY (security), we_cipher);
|
||||
|
||||
caps = nm_ap_get_capabilities (ap);
|
||||
if (caps & NM_802_11_CAP_PROTO_WPA2)
|
||||
security->priv->wpa_version = IW_AUTH_WPA_VERSION_WPA2;
|
||||
else if (caps & NM_802_11_CAP_PROTO_WPA)
|
||||
security->priv->wpa_version = IW_AUTH_WPA_VERSION_WPA;
|
||||
security->priv->key_mgt = IW_AUTH_KEY_MGMT_PSK;
|
||||
|
||||
set_description (security);
|
||||
|
||||
return security;
|
||||
}
|
||||
|
||||
static int
|
||||
real_serialize (NMAPSecurity *instance, DBusMessageIter *iter)
|
||||
{
|
||||
@@ -83,10 +115,71 @@ real_serialize (NMAPSecurity *instance, DBusMessageIter *iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
real_write_wpa_supplicant_config (NMAPSecurity *instance, int fd)
|
||||
static gboolean
|
||||
real_write_supplicant_config (NMAPSecurity *instance,
|
||||
struct wpa_ctrl *ctrl,
|
||||
int nwid)
|
||||
{
|
||||
NMAPSecurityWPA_PSK * self = NM_AP_SECURITY_WPA_PSK (instance);
|
||||
gboolean success = FALSE;
|
||||
char * msg = NULL;
|
||||
const char * key = nm_ap_security_get_key (instance);
|
||||
int cipher = nm_ap_security_get_we_cipher (instance);
|
||||
|
||||
/* WPA-PSK network setup */
|
||||
|
||||
/* wpa_cli -ieth1 set_network 0 key_mgmt WPA-PSK */
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i key_mgmt WPA-PSK", nwid))
|
||||
goto out;
|
||||
|
||||
msg = g_strdup_printf ("SET_NETWORK %i psk <key>", nwid);
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, msg,
|
||||
"SET_NETWORK %i psk %s", nwid, key))
|
||||
{
|
||||
g_free (msg);
|
||||
goto out;
|
||||
}
|
||||
g_free (msg);
|
||||
|
||||
if (cipher == IW_AUTH_CIPHER_TKIP)
|
||||
{
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i pairwise TKIP", nwid))
|
||||
goto out;
|
||||
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i group TKIP", nwid))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i pairwise CCMP", nwid))
|
||||
goto out;
|
||||
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i group CCMP", nwid))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA)
|
||||
{
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i proto WPA", nwid))
|
||||
goto out;
|
||||
}
|
||||
else if (self->priv->wpa_version == IW_AUTH_WPA_VERSION_WPA2)
|
||||
{
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i proto WPA2", nwid))
|
||||
goto out;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -124,7 +217,7 @@ nm_ap_security_wpa_psk_class_init (NMAPSecurityWPA_PSKClass *klass)
|
||||
|
||||
par_class->copy_constructor_func = real_copy_constructor;
|
||||
par_class->serialize_func = real_serialize;
|
||||
par_class->write_wpa_supplicant_config_func = real_write_wpa_supplicant_config;
|
||||
par_class->write_supplicant_config_func = real_write_supplicant_config;
|
||||
par_class->device_setup_func = real_device_setup;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityWPA_PSKPrivate));
|
||||
|
@@ -55,4 +55,7 @@ GType nm_ap_security_wpa_psk_get_type (void);
|
||||
|
||||
NMAPSecurityWPA_PSK * nm_ap_security_wpa_psk_new_deserialize (DBusMessageIter *iter, int we_cipher);
|
||||
|
||||
struct NMAccessPoint;
|
||||
NMAPSecurityWPA_PSK * nm_ap_security_wpa_psk_new_from_ap (struct NMAccessPoint *ap, int we_cipher);
|
||||
|
||||
#endif /* NM_AP_SECURITY_WPA_PSK_H */
|
||||
|
@@ -29,6 +29,9 @@
|
||||
#include "nm-ap-security-wep.h"
|
||||
#include "nm-ap-security-wpa-psk.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
#include "wpa_ctrl.h"
|
||||
#include "nm-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#define NM_AP_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_AP_SECURITY, NMAPSecurityPrivate))
|
||||
|
||||
@@ -112,17 +115,11 @@ nm_ap_security_new_from_ap (NMAccessPoint *ap)
|
||||
|
||||
/* Deteremine best encryption algorithm to use */
|
||||
caps = nm_ap_get_capabilities (ap);
|
||||
|
||||
/*
|
||||
if (caps & WPA2_CCMP_PSK)
|
||||
stuff
|
||||
else if (caps & WPA2_TKIP_PSK)
|
||||
stuff
|
||||
else if (caps & WPA_TKIP_PSK)
|
||||
stuff
|
||||
else
|
||||
*/
|
||||
if (caps & WEP_WEP104)
|
||||
security = NM_AP_SECURITY (nm_ap_security_wpa_psk_new_from_ap (ap, IW_AUTH_CIPHER_CCMP));
|
||||
else if ((caps & WPA_TKIP_PSK) || (caps & WPA2_TKIP_PSK))
|
||||
security = NM_AP_SECURITY (nm_ap_security_wpa_psk_new_from_ap (ap, IW_AUTH_CIPHER_TKIP));
|
||||
else if (caps & WEP_WEP104)
|
||||
security = NM_AP_SECURITY (nm_ap_security_wep_new_from_ap (ap, IW_AUTH_CIPHER_WEP104));
|
||||
else if (caps & WEP_WEP40)
|
||||
security = NM_AP_SECURITY (nm_ap_security_wep_new_from_ap (ap, IW_AUTH_CIPHER_WEP40));
|
||||
@@ -132,16 +129,20 @@ nm_ap_security_new_from_ap (NMAccessPoint *ap)
|
||||
return security;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ap_security_write_wpa_supplicant_config (NMAPSecurity *self, int fd)
|
||||
|
||||
gboolean
|
||||
nm_ap_security_write_supplicant_config (NMAPSecurity *self,
|
||||
struct wpa_ctrl *ctrl,
|
||||
int nwid)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (fd >= 0);
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (ctrl != NULL, FALSE);
|
||||
g_return_val_if_fail (nwid >= 0, FALSE);
|
||||
|
||||
if (self->priv->dispose_has_run)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
NM_AP_SECURITY_GET_CLASS (self)->write_wpa_supplicant_config_func (self, fd);
|
||||
return NM_AP_SECURITY_GET_CLASS (self)->write_supplicant_config_func (self, ctrl, nwid);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -189,9 +190,17 @@ real_serialize (NMAPSecurity *self, DBusMessageIter *iter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
real_write_wpa_supplicant_config (NMAPSecurity *self, int fd)
|
||||
static gboolean
|
||||
real_write_supplicant_config (NMAPSecurity *self,
|
||||
struct wpa_ctrl *ctrl,
|
||||
int nwid)
|
||||
{
|
||||
/* Unencrypted network setup */
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i key_mgmt NONE", nwid))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -352,7 +361,7 @@ nm_ap_security_class_init (NMAPSecurityClass *klass)
|
||||
|
||||
klass->copy_constructor_func = real_copy_constructor;
|
||||
klass->serialize_func = real_serialize;
|
||||
klass->write_wpa_supplicant_config_func = real_write_wpa_supplicant_config;
|
||||
klass->write_supplicant_config_func = real_write_supplicant_config;
|
||||
klass->device_setup_func = real_device_setup;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (NMAPSecurityPrivate));
|
||||
|
@@ -53,6 +53,7 @@ struct _NMAPSecurity
|
||||
};
|
||||
|
||||
struct NMAccessPoint;
|
||||
struct wpa_ctrl;
|
||||
|
||||
struct _NMAPSecurityClass
|
||||
{
|
||||
@@ -63,7 +64,7 @@ struct _NMAPSecurityClass
|
||||
|
||||
int (*serialize_func) (NMAPSecurity *self, DBusMessageIter *iter);
|
||||
|
||||
void (*write_wpa_supplicant_config_func)(NMAPSecurity *self, int fd);
|
||||
gboolean (*write_supplicant_config_func)(NMAPSecurity *self, struct wpa_ctrl *ctrl, int nwid);
|
||||
|
||||
int (*device_setup_func) (NMAPSecurity *self, NMDevice80211Wireless * dev);
|
||||
};
|
||||
@@ -83,7 +84,7 @@ const char * nm_ap_security_get_key (NMAPSecurity *self);
|
||||
|
||||
int nm_ap_security_serialize (NMAPSecurity *self, DBusMessageIter *iter);
|
||||
|
||||
void nm_ap_security_write_wpa_supplicant_config (NMAPSecurity *self, int fd);
|
||||
gboolean nm_ap_security_write_supplicant_config (NMAPSecurity *self, struct wpa_ctrl *ctrl, int nwid);
|
||||
|
||||
int nm_ap_security_device_setup (NMAPSecurity *self, NMDevice80211Wireless *dev);
|
||||
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <string.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <iwlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "nm-device.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
@@ -37,6 +39,7 @@
|
||||
#include "NetworkManagerPolicy.h"
|
||||
#include "nm-activation-request.h"
|
||||
#include "nm-dbus-nmi.h"
|
||||
#include "wpa_ctrl.h"
|
||||
|
||||
/* #define IW_QUAL_DEBUG */
|
||||
|
||||
@@ -64,6 +67,12 @@ struct _NMDevice80211WirelessPrivate
|
||||
guint8 scan_interval; /* seconds */
|
||||
guint32 last_scan;
|
||||
|
||||
/* Supplicant control */
|
||||
GPid sup_pid;
|
||||
GSource * sup_watch;
|
||||
GSource * sup_status;
|
||||
struct wpa_ctrl * sup_ctrl;
|
||||
|
||||
/* Static options from driver */
|
||||
guint8 we_version;
|
||||
guint32 capabilities;
|
||||
@@ -207,6 +216,7 @@ nm_device_802_11_wireless_init (NMDevice80211Wireless * self)
|
||||
self->priv->dispose_has_run = FALSE;
|
||||
|
||||
memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr));
|
||||
self->priv->sup_pid = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2335,6 +2345,224 @@ wireless_configure_infra (NMDevice80211Wireless *self,
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* WPA Supplicant control stuff
|
||||
*
|
||||
* Originally from:
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define WPA_SUPPLICANT_GLOBAL_SOCKET "/var/run/wpa_supplicant-global"
|
||||
#define WPA_SUPPLICANT_CONTROL_SOCKET "/var/run/wpa_supplicant"
|
||||
#define WPA_SUPPLICANT_BINARY "/usr/sbin/wpa_supplicant"
|
||||
|
||||
static void
|
||||
supplicant_cleanup (NMDevice80211Wireless *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
self->priv->sup_pid = -1;
|
||||
if (self->priv->sup_watch)
|
||||
{
|
||||
g_source_destroy (self->priv->sup_watch);
|
||||
self->priv->sup_watch = NULL;
|
||||
}
|
||||
if (self->priv->sup_status)
|
||||
{
|
||||
g_source_destroy (self->priv->sup_status);
|
||||
self->priv->sup_status = NULL;
|
||||
}
|
||||
if (self->priv->sup_ctrl)
|
||||
{
|
||||
wpa_ctrl_close (self->priv->sup_ctrl);
|
||||
self->priv->sup_ctrl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_watch_cb (GPid pid,
|
||||
gint status,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
|
||||
|
||||
g_assert (self);
|
||||
|
||||
if (WIFEXITED (status))
|
||||
nm_warning ("wpa_supplicant exited with error code %d", WEXITSTATUS (status));
|
||||
else if (WIFSTOPPED (status))
|
||||
nm_warning ("wpa_supplicant stopped unexpectedly with signal %d", WSTOPSIG (status));
|
||||
else if (WIFSIGNALED (status))
|
||||
nm_warning ("wpa_supplicant died with signal %d", WTERMSIG (status));
|
||||
else
|
||||
nm_warning ("wpa_supplicant died from an unknown cause");
|
||||
|
||||
supplicant_cleanup (self);
|
||||
|
||||
/* FIXME: deal with disconnection; device no longer has a link */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supplicant_monitor_status_cb (GIOChannel *source,
|
||||
GIOCondition condition,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
|
||||
char message[2048];
|
||||
size_t message_len;
|
||||
struct wpa_ctrl * ctrl;
|
||||
|
||||
g_assert (self);
|
||||
|
||||
ctrl = self->priv->sup_ctrl;
|
||||
g_return_val_if_fail (ctrl != NULL, 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;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wpa_supplicant_start (NMDevice80211Wireless *self)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
char * argv[4];
|
||||
GError * error;
|
||||
GPid pid = -1;
|
||||
|
||||
argv[0] = WPA_SUPPLICANT_BINARY;
|
||||
argv[1] = "-g";
|
||||
argv[2] = WPA_SUPPLICANT_GLOBAL_SOCKET;
|
||||
argv[4] = NULL;
|
||||
|
||||
if (!(success = g_spawn_async ("/", argv, NULL, 0, NULL, NULL, &pid, &error)))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
nm_warning ("Couldn't start wpa_supplicant. Error: (%d) %s",
|
||||
error->code, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
nm_warning ("Couldn't start wpa_supplicant due to an unknown error.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->priv->sup_watch)
|
||||
g_source_destroy (self->priv->sup_watch);
|
||||
self->priv->sup_watch = g_child_watch_source_new (pid);
|
||||
g_source_set_callback (self->priv->sup_watch, (GSourceFunc) supplicant_watch_cb, self, NULL);
|
||||
g_source_attach (self->priv->sup_watch, nm_device_get_main_context (NM_DEVICE (self)));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
wpa_supplicant_interface_init (NMDevice80211Wireless *self)
|
||||
{
|
||||
struct wpa_ctrl * ctrl;
|
||||
struct wpa_ctrl * ctrl_if = NULL;
|
||||
char * socket_path;
|
||||
const char * iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
gboolean success = FALSE;
|
||||
|
||||
if (!(ctrl = wpa_ctrl_open (WPA_SUPPLICANT_GLOBAL_SOCKET)))
|
||||
goto exit;
|
||||
|
||||
/* wpa_cli -g/var/run/wpa_supplicant-global interface_add eth1 "" wext /var/run/wpa_supplicant */
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"INTERFACE_ADD %s\t\twext\t" WPA_SUPPLICANT_CONTROL_SOCKET "\t", iface))
|
||||
goto exit;
|
||||
|
||||
wpa_ctrl_close (ctrl);
|
||||
|
||||
/* attach to interface socket */
|
||||
if (!(socket_path = g_strdup_printf (WPA_SUPPLICANT_CONTROL_SOCKET "/%s", iface)))
|
||||
goto exit;
|
||||
self->priv->sup_ctrl = wpa_ctrl_open (socket_path);
|
||||
g_free (socket_path);
|
||||
success = TRUE;
|
||||
|
||||
exit:
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
wpa_supplicant_send_network_config (NMDevice80211Wireless *self,
|
||||
NMActRequest *req)
|
||||
{
|
||||
NMAccessPoint * ap = NULL;
|
||||
gboolean success = FALSE;
|
||||
char * response = NULL;
|
||||
int nwid;
|
||||
const char * essid;
|
||||
struct wpa_ctrl * ctrl;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (req != NULL, FALSE);
|
||||
|
||||
ap = nm_act_request_get_ap (req);
|
||||
g_assert (ap);
|
||||
|
||||
ctrl = self->priv->sup_ctrl;
|
||||
g_assert (ctrl);
|
||||
|
||||
/* Standard network setup info */
|
||||
if (!(response = nm_utils_supplicant_request (ctrl, "ADD_NETWORK")))
|
||||
{
|
||||
nm_warning ("Supplicant error for ADD_NETWORK.\n");
|
||||
goto out;
|
||||
}
|
||||
if (sscanf (response, "%i\n", &nwid) != 1)
|
||||
{
|
||||
nm_warning ("Supplicant error for ADD_NETWORK. Response: '%s'\n", response);
|
||||
g_free (response);
|
||||
goto out;
|
||||
}
|
||||
g_free (response);
|
||||
|
||||
if (nm_device_activation_should_cancel (NM_DEVICE (self)))
|
||||
goto out;
|
||||
|
||||
essid = nm_ap_get_essid (ap);
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"SET_NETWORK %i ssid \"%s\"", nwid, essid))
|
||||
goto out;
|
||||
|
||||
if (nm_device_activation_should_cancel (NM_DEVICE (self)))
|
||||
goto out;
|
||||
|
||||
if (!nm_ap_security_write_supplicant_config (nm_ap_get_security (ap), ctrl, nwid))
|
||||
goto out;
|
||||
|
||||
if (!nm_utils_supplicant_request_with_check (ctrl, "OK", __func__, NULL,
|
||||
"ENABLE_NETWORK %i", nwid, essid))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage2_config (NMDevice *dev,
|
||||
NMActRequest *req)
|
||||
|
240
src/wpa_ctrl.c
Normal file
240
src/wpa_ctrl.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* WHACK #include "includes.h" */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define CONFIG_CTRL_IFACE
|
||||
#ifdef CONFIG_CTRL_IFACE
|
||||
|
||||
#ifndef CONFIG_CTRL_IFACE_UDP
|
||||
#include <sys/un.h>
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
|
||||
#include "wpa_ctrl.h"
|
||||
/* WHACK #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 */
|
185
src/wpa_ctrl.h
Normal file
185
src/wpa_ctrl.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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 */
|
Reference in New Issue
Block a user