wpa_supplicant: Add support for IPv6 with UDP ctrl_iface
Add IPv6 support when using udp/udp-remote control interface using the following new build configuration options: CONFIG_CTRL_IFACE=udp6 CONFIG_CTRL_IFACE=udp6-remote This is useful for testing, while we don't need to assign IPv4 address (static or using DHCP) and can just use auto configured IPv6 addresses (link local, which is based on the MAC address). Also add scope id support for link local case. For example, ./wpa_cli ./wpa_cli -i ::1,9877 ./wpa_cli -i fe80::203:7fff:fe05:69%wlan0,9877 Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
This commit is contained in:
parent
e2364d162a
commit
4db216fcf7
4 changed files with 177 additions and 6 deletions
|
@ -25,6 +25,10 @@
|
||||||
#include "private/android_filesystem_config.h"
|
#include "private/android_filesystem_config.h"
|
||||||
#endif /* ANDROID */
|
#endif /* ANDROID */
|
||||||
|
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
#include <net/if.h>
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
#include "wpa_ctrl.h"
|
#include "wpa_ctrl.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
@ -46,8 +50,13 @@
|
||||||
struct wpa_ctrl {
|
struct wpa_ctrl {
|
||||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||||
int s;
|
int s;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 local;
|
||||||
|
struct sockaddr_in6 dest;
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in local;
|
struct sockaddr_in local;
|
||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
char *cookie;
|
char *cookie;
|
||||||
char *remote_ifname;
|
char *remote_ifname;
|
||||||
char *remote_ip;
|
char *remote_ip;
|
||||||
|
@ -279,19 +288,33 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
return NULL;
|
return NULL;
|
||||||
os_memset(ctrl, 0, sizeof(*ctrl));
|
os_memset(ctrl, 0, sizeof(*ctrl));
|
||||||
|
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
ctrl->s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
|
ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (ctrl->s < 0) {
|
if (ctrl->s < 0) {
|
||||||
perror("socket");
|
perror("socket");
|
||||||
os_free(ctrl);
|
os_free(ctrl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
ctrl->local.sin6_family = AF_INET6;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
|
ctrl->local.sin6_addr = in6addr_any;
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
inet_pton(AF_INET6, "::1", &ctrl->local.sin6_addr);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
ctrl->local.sin_family = AF_INET;
|
ctrl->local.sin_family = AF_INET;
|
||||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
ctrl->local.sin_addr.s_addr = INADDR_ANY;
|
ctrl->local.sin_addr.s_addr = INADDR_ANY;
|
||||||
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
|
ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
|
||||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
|
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
|
||||||
sizeof(ctrl->local)) < 0) {
|
sizeof(ctrl->local)) < 0) {
|
||||||
close(ctrl->s);
|
close(ctrl->s);
|
||||||
|
@ -299,14 +322,24 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
ctrl->dest.sin6_family = AF_INET6;
|
||||||
|
inet_pton(AF_INET6, "::1", &ctrl->dest.sin6_addr);
|
||||||
|
ctrl->dest.sin6_port = htons(WPA_CTRL_IFACE_PORT);
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
ctrl->dest.sin_family = AF_INET;
|
ctrl->dest.sin_family = AF_INET;
|
||||||
ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
|
ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
|
||||||
ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
|
ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
if (ctrl_path) {
|
if (ctrl_path) {
|
||||||
char *port, *name;
|
char *port, *name;
|
||||||
int port_id;
|
int port_id;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char *scope;
|
||||||
|
int scope_id = 0;
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
name = os_strdup(ctrl_path);
|
name = os_strdup(ctrl_path);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
|
@ -314,7 +347,11 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
os_free(ctrl);
|
os_free(ctrl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
port = os_strchr(name, ',');
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
port = os_strchr(name, ':');
|
port = os_strchr(name, ':');
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
if (port) {
|
if (port) {
|
||||||
port_id = atoi(&port[1]);
|
port_id = atoi(&port[1]);
|
||||||
|
@ -322,7 +359,16 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
} else
|
} else
|
||||||
port_id = WPA_CTRL_IFACE_PORT;
|
port_id = WPA_CTRL_IFACE_PORT;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
scope = os_strchr(name, '%');
|
||||||
|
if (scope) {
|
||||||
|
scope_id = if_nametoindex(&scope[1]);
|
||||||
|
scope[0] = '\0';
|
||||||
|
}
|
||||||
|
h = gethostbyname2(name, AF_INET6);
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
h = gethostbyname(name);
|
h = gethostbyname(name);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
ctrl->remote_ip = os_strdup(name);
|
ctrl->remote_ip = os_strdup(name);
|
||||||
os_free(name);
|
os_free(name);
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
|
@ -332,16 +378,33 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
os_free(ctrl);
|
os_free(ctrl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
ctrl->dest.sin6_scope_id = scope_id;
|
||||||
|
ctrl->dest.sin6_port = htons(port_id);
|
||||||
|
os_memcpy(&ctrl->dest.sin6_addr, h->h_addr, h->h_length);
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
ctrl->dest.sin_port = htons(port_id);
|
ctrl->dest.sin_port = htons(port_id);
|
||||||
os_memcpy(h->h_addr, (char *) &ctrl->dest.sin_addr.s_addr,
|
os_memcpy(&ctrl->dest.sin_addr.s_addr, h->h_addr, h->h_length);
|
||||||
h->h_length);
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
} else
|
} else
|
||||||
ctrl->remote_ip = os_strdup("localhost");
|
ctrl->remote_ip = os_strdup("localhost");
|
||||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
|
||||||
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
||||||
sizeof(ctrl->dest)) < 0) {
|
sizeof(ctrl->dest)) < 0) {
|
||||||
perror("connect");
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
|
||||||
|
inet_ntop(AF_INET6, &ctrl->dest.sin6_addr, addr,
|
||||||
|
sizeof(ctrl->dest)),
|
||||||
|
ntohs(ctrl->dest.sin6_port),
|
||||||
|
strerror(errno));
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
|
||||||
|
inet_ntoa(ctrl->dest.sin_addr),
|
||||||
|
ntohs(ctrl->dest.sin_port),
|
||||||
|
strerror(errno));
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
close(ctrl->s);
|
close(ctrl->s);
|
||||||
os_free(ctrl->remote_ip);
|
os_free(ctrl->remote_ip);
|
||||||
os_free(ctrl);
|
os_free(ctrl);
|
||||||
|
|
|
@ -1267,6 +1267,11 @@ endif
|
||||||
ifeq ($(CONFIG_CTRL_IFACE), udp)
|
ifeq ($(CONFIG_CTRL_IFACE), udp)
|
||||||
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CONFIG_CTRL_IFACE), udp6)
|
||||||
|
CONFIG_CTRL_IFACE=udp
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
endif
|
||||||
ifeq ($(CONFIG_CTRL_IFACE), named_pipe)
|
ifeq ($(CONFIG_CTRL_IFACE), named_pipe)
|
||||||
CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE
|
CFLAGS += -DCONFIG_CTRL_IFACE_NAMED_PIPE
|
||||||
endif
|
endif
|
||||||
|
@ -1275,6 +1280,12 @@ CONFIG_CTRL_IFACE=udp
|
||||||
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
||||||
CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(CONFIG_CTRL_IFACE), udp6-remote)
|
||||||
|
CONFIG_CTRL_IFACE=udp
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
|
CFLAGS += -DCONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
endif
|
||||||
OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
|
OBJS += ctrl_iface.o ctrl_iface_$(CONFIG_CTRL_IFACE).o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,11 @@
|
||||||
*/
|
*/
|
||||||
struct wpa_ctrl_dst {
|
struct wpa_ctrl_dst {
|
||||||
struct wpa_ctrl_dst *next;
|
struct wpa_ctrl_dst *next;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
int debug_level;
|
int debug_level;
|
||||||
int errors;
|
int errors;
|
||||||
|
@ -51,38 +55,68 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv,
|
static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv,
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 *from,
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in *from,
|
struct sockaddr_in *from,
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
socklen_t fromlen)
|
socklen_t fromlen)
|
||||||
{
|
{
|
||||||
struct wpa_ctrl_dst *dst;
|
struct wpa_ctrl_dst *dst;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
#endif /* CONFIG_UDP_IPV6 */
|
||||||
|
|
||||||
dst = os_zalloc(sizeof(*dst));
|
dst = os_zalloc(sizeof(*dst));
|
||||||
if (dst == NULL)
|
if (dst == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(&dst->addr, from, sizeof(struct sockaddr_in));
|
os_memcpy(&dst->addr, from, sizeof(*from));
|
||||||
dst->addrlen = fromlen;
|
dst->addrlen = fromlen;
|
||||||
dst->debug_level = MSG_INFO;
|
dst->debug_level = MSG_INFO;
|
||||||
dst->next = priv->ctrl_dst;
|
dst->next = priv->ctrl_dst;
|
||||||
priv->ctrl_dst = dst;
|
priv->ctrl_dst = dst;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",
|
||||||
|
inet_ntop(AF_INET6, &from->sin6_addr, addr, sizeof(*from)),
|
||||||
|
ntohs(from->sin6_port));
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached %s:%d",
|
||||||
inet_ntoa(from->sin_addr), ntohs(from->sin_port));
|
inet_ntoa(from->sin_addr), ntohs(from->sin_port));
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv,
|
static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv,
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 *from,
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in *from,
|
struct sockaddr_in *from,
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
socklen_t fromlen)
|
socklen_t fromlen)
|
||||||
{
|
{
|
||||||
struct wpa_ctrl_dst *dst, *prev = NULL;
|
struct wpa_ctrl_dst *dst, *prev = NULL;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
dst = priv->ctrl_dst;
|
dst = priv->ctrl_dst;
|
||||||
while (dst) {
|
while (dst) {
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
if (from->sin6_port == dst->addr.sin6_port &&
|
||||||
|
!os_memcmp(&from->sin6_addr, &dst->addr.sin6_addr,
|
||||||
|
sizeof(from->sin6_addr))) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached %s:%d",
|
||||||
|
inet_ntop(AF_INET6, &from->sin6_addr, addr,
|
||||||
|
sizeof(*from)),
|
||||||
|
ntohs(from->sin6_port));
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
|
if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
|
||||||
from->sin_port == dst->addr.sin_port) {
|
from->sin_port == dst->addr.sin_port) {
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached "
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached "
|
||||||
"%s:%d", inet_ntoa(from->sin_addr),
|
"%s:%d", inet_ntoa(from->sin_addr),
|
||||||
ntohs(from->sin_port));
|
ntohs(from->sin_port));
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (prev == NULL)
|
if (prev == NULL)
|
||||||
priv->ctrl_dst = dst->next;
|
priv->ctrl_dst = dst->next;
|
||||||
else
|
else
|
||||||
|
@ -98,21 +132,38 @@ static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv,
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
|
static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 *from,
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in *from,
|
struct sockaddr_in *from,
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
socklen_t fromlen,
|
socklen_t fromlen,
|
||||||
char *level)
|
char *level)
|
||||||
{
|
{
|
||||||
struct wpa_ctrl_dst *dst;
|
struct wpa_ctrl_dst *dst;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
|
||||||
|
|
||||||
dst = priv->ctrl_dst;
|
dst = priv->ctrl_dst;
|
||||||
while (dst) {
|
while (dst) {
|
||||||
|
#if CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
if (from->sin6_port == dst->addr.sin6_port &&
|
||||||
|
!os_memcmp(&from->sin6_addr, &dst->addr.sin6_addr,
|
||||||
|
sizeof(from->sin6_addr))) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor level %s:%d",
|
||||||
|
inet_ntop(AF_INET6, &from->sin6_addr, addr,
|
||||||
|
sizeof(*from)),
|
||||||
|
ntohs(from->sin6_port));
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
|
if (from->sin_addr.s_addr == dst->addr.sin_addr.s_addr &&
|
||||||
from->sin_port == dst->addr.sin_port) {
|
from->sin_port == dst->addr.sin_port) {
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor "
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor "
|
||||||
"level %s:%d", inet_ntoa(from->sin_addr),
|
"level %s:%d", inet_ntoa(from->sin_addr),
|
||||||
ntohs(from->sin_port));
|
ntohs(from->sin_port));
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
dst->debug_level = atoi(level);
|
dst->debug_level = atoi(level);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +201,14 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||||
struct ctrl_iface_priv *priv = sock_ctx;
|
struct ctrl_iface_priv *priv = sock_ctx;
|
||||||
char buf[256], *pos;
|
char buf[256], *pos;
|
||||||
int res;
|
int res;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 from;
|
||||||
|
#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
socklen_t fromlen = sizeof(from);
|
socklen_t fromlen = sizeof(from);
|
||||||
char *reply = NULL;
|
char *reply = NULL;
|
||||||
size_t reply_len = 0;
|
size_t reply_len = 0;
|
||||||
|
@ -165,6 +223,13 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
|
#ifndef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
inet_ntop(AF_INET6, &from.sin6_addr, addr, sizeof(from));
|
||||||
|
if (os_strcmp(addr, "::1")) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected source %s",
|
||||||
|
addr);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
|
if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) {
|
||||||
/*
|
/*
|
||||||
* The OS networking stack is expected to drop this kind of
|
* The OS networking stack is expected to drop this kind of
|
||||||
|
@ -176,6 +241,7 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
|
||||||
"source %s", inet_ntoa(from.sin_addr));
|
"source %s", inet_ntoa(from.sin_addr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
|
||||||
buf[res] = '\0';
|
buf[res] = '\0';
|
||||||
|
@ -269,8 +335,14 @@ struct ctrl_iface_priv *
|
||||||
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct ctrl_iface_priv *priv;
|
struct ctrl_iface_priv *priv;
|
||||||
struct sockaddr_in addr;
|
|
||||||
int port = WPA_CTRL_IFACE_PORT;
|
int port = WPA_CTRL_IFACE_PORT;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
int domain = PF_INET6;
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
int domain = PF_INET;
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
priv = os_zalloc(sizeof(*priv));
|
priv = os_zalloc(sizeof(*priv));
|
||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
|
@ -282,21 +354,34 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
|
||||||
if (wpa_s->conf->ctrl_interface == NULL)
|
if (wpa_s->conf->ctrl_interface == NULL)
|
||||||
return priv;
|
return priv;
|
||||||
|
|
||||||
priv->sock = socket(PF_INET, SOCK_DGRAM, 0);
|
priv->sock = socket(domain, SOCK_DGRAM, 0);
|
||||||
if (priv->sock < 0) {
|
if (priv->sock < 0) {
|
||||||
perror("socket(PF_INET)");
|
perror("socket(PF_INET)");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_memset(&addr, 0, sizeof(addr));
|
os_memset(&addr, 0, sizeof(addr));
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
addr.sin6_family = AF_INET6;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
|
addr.sin6_addr = in6addr_any;
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
inet_pton(AF_INET6, "::1", &addr.sin6_addr);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
addr.sin_addr.s_addr = htonl((127 << 24) | 1);
|
addr.sin_addr.s_addr = htonl((127 << 24) | 1);
|
||||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
try_again:
|
try_again:
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
addr.sin6_port = htons(port);
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
port--;
|
port--;
|
||||||
if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT)
|
if ((WPA_CTRL_IFACE_PORT - port) < WPA_CTRL_IFACE_PORT_LIMIT)
|
||||||
|
@ -362,6 +447,9 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
|
||||||
int idx;
|
int idx;
|
||||||
char *sbuf;
|
char *sbuf;
|
||||||
int llen;
|
int llen;
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
char addr[INET6_ADDRSTRLEN];
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
|
|
||||||
dst = priv->ctrl_dst;
|
dst = priv->ctrl_dst;
|
||||||
if (priv->sock < 0 || dst == NULL)
|
if (priv->sock < 0 || dst == NULL)
|
||||||
|
@ -381,9 +469,16 @@ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
|
||||||
while (dst) {
|
while (dst) {
|
||||||
next = dst->next;
|
next = dst->next;
|
||||||
if (level >= dst->debug_level) {
|
if (level >= dst->debug_level) {
|
||||||
|
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %s:%d",
|
||||||
|
inet_ntop(AF_INET6, &dst->addr.sin6_addr,
|
||||||
|
addr, sizeof(dst->addr)),
|
||||||
|
ntohs(dst->addr.sin6_port));
|
||||||
|
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %s:%d",
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %s:%d",
|
||||||
inet_ntoa(dst->addr.sin_addr),
|
inet_ntoa(dst->addr.sin_addr),
|
||||||
ntohs(dst->addr.sin_port));
|
ntohs(dst->addr.sin_port));
|
||||||
|
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||||
if (sendto(priv->sock, sbuf, llen + len, 0,
|
if (sendto(priv->sock, sbuf, llen + len, 0,
|
||||||
(struct sockaddr *) &dst->addr,
|
(struct sockaddr *) &dst->addr,
|
||||||
sizeof(dst->addr)) < 0) {
|
sizeof(dst->addr)) < 0) {
|
||||||
|
|
|
@ -192,8 +192,10 @@ CONFIG_SMARTCARD=y
|
||||||
# Select control interface backend for external programs, e.g, wpa_cli:
|
# Select control interface backend for external programs, e.g, wpa_cli:
|
||||||
# unix = UNIX domain sockets (default for Linux/*BSD)
|
# unix = UNIX domain sockets (default for Linux/*BSD)
|
||||||
# udp = UDP sockets using localhost (127.0.0.1)
|
# udp = UDP sockets using localhost (127.0.0.1)
|
||||||
|
# udp6 = UDP IPv6 sockets using localhost (::1)
|
||||||
# named_pipe = Windows Named Pipe (default for Windows)
|
# named_pipe = Windows Named Pipe (default for Windows)
|
||||||
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
|
# udp-remote = UDP sockets with remote access (only for tests systems/purpose)
|
||||||
|
# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
|
||||||
# y = use default (backwards compatibility)
|
# y = use default (backwards compatibility)
|
||||||
# If this option is commented out, control interface is not included in the
|
# If this option is commented out, control interface is not included in the
|
||||||
# build.
|
# build.
|
||||||
|
|
Loading…
Reference in a new issue