WPS ER: Allow UPnP interface to be forced
"WPS_ER_START ifname=<interace>" can now be used to force a specific interface to be used for UPnP operations. This is especially useful for automated test cases where the lo interface can now be used easily to perform ER operations. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
728d97171b
commit
c64686229f
5 changed files with 45 additions and 7 deletions
|
@ -1271,6 +1271,22 @@ wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
|
||||||
/* Limit event_id to < 32 bits to avoid issues with atoi() */
|
/* Limit event_id to < 32 bits to avoid issues with atoi() */
|
||||||
er->event_id &= 0x0fffffff;
|
er->event_id &= 0x0fffffff;
|
||||||
|
|
||||||
|
if (filter && os_strncmp(filter, "ifname=", 7) == 0) {
|
||||||
|
const char *pos, *end;
|
||||||
|
pos = filter + 7;
|
||||||
|
end = os_strchr(pos, ' ');
|
||||||
|
if (end) {
|
||||||
|
size_t len = end - pos;
|
||||||
|
os_strlcpy(er->ifname, pos, len < sizeof(er->ifname) ?
|
||||||
|
len + 1 : sizeof(er->ifname));
|
||||||
|
filter = end + 1;
|
||||||
|
} else {
|
||||||
|
os_strlcpy(er->ifname, pos, sizeof(er->ifname));
|
||||||
|
filter = NULL;
|
||||||
|
}
|
||||||
|
er->forced_ifname = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
if (inet_aton(filter, &er->filter_addr) == 0) {
|
if (inet_aton(filter, &er->filter_addr) == 0) {
|
||||||
wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
|
wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
|
||||||
|
@ -1281,10 +1297,10 @@ wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
|
||||||
wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
|
wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
|
||||||
"with %s", filter);
|
"with %s", filter);
|
||||||
}
|
}
|
||||||
if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text,
|
if (get_netif_info(er->ifname, &er->ip_addr, &er->ip_addr_text,
|
||||||
er->mac_addr)) {
|
er->mac_addr)) {
|
||||||
wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
|
wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
|
||||||
"for %s. Does it have IP address?", ifname);
|
"for %s. Does it have IP address?", er->ifname);
|
||||||
wps_er_deinit(er, NULL, NULL);
|
wps_er_deinit(er, NULL, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct wps_er_ap_settings {
|
||||||
struct wps_er {
|
struct wps_er {
|
||||||
struct wps_context *wps;
|
struct wps_context *wps;
|
||||||
char ifname[17];
|
char ifname[17];
|
||||||
|
int forced_ifname;
|
||||||
u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */
|
u8 mac_addr[ETH_ALEN]; /* mac addr of network i.f. we use */
|
||||||
char *ip_addr_text; /* IP address of network i.f. we use */
|
char *ip_addr_text; /* IP address of network i.f. we use */
|
||||||
unsigned ip_addr; /* IP address of network i.f. we use (host order) */
|
unsigned ip_addr; /* IP address of network i.f. we use (host order) */
|
||||||
|
|
|
@ -166,7 +166,9 @@ int wps_er_ssdp_init(struct wps_er *er)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr);
|
er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr,
|
||||||
|
er->forced_ifname ?
|
||||||
|
er->ifname : NULL);
|
||||||
if (er->multicast_sd < 0) {
|
if (er->multicast_sd < 0) {
|
||||||
wpa_printf(MSG_INFO, "WPS ER: Failed to open multicast socket "
|
wpa_printf(MSG_INFO, "WPS ER: Failed to open multicast socket "
|
||||||
"for SSDP");
|
"for SSDP");
|
||||||
|
|
|
@ -171,7 +171,7 @@ void ssdp_listener_stop(struct upnp_wps_device_sm *sm);
|
||||||
int ssdp_listener_start(struct upnp_wps_device_sm *sm);
|
int ssdp_listener_start(struct upnp_wps_device_sm *sm);
|
||||||
int ssdp_listener_open(void);
|
int ssdp_listener_open(void);
|
||||||
int add_ssdp_network(const char *net_if);
|
int add_ssdp_network(const char *net_if);
|
||||||
int ssdp_open_multicast_sock(u32 ip_addr);
|
int ssdp_open_multicast_sock(u32 ip_addr, const char *forced_ifname);
|
||||||
int ssdp_open_multicast(struct upnp_wps_device_sm *sm);
|
int ssdp_open_multicast(struct upnp_wps_device_sm *sm);
|
||||||
|
|
||||||
/* wps_upnp_web.c */
|
/* wps_upnp_web.c */
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
* Copyright (c) 2006-2007 Sony Corporation
|
* Copyright (c) 2006-2007 Sony Corporation
|
||||||
* Copyright (c) 2008-2009 Atheros Communications
|
* Copyright (c) 2008-2009 Atheros Communications
|
||||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2009-2013, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* See wps_upnp.c for more details on licensing and code history.
|
* See wps_upnp.c for more details on licensing and code history.
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,9 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <net/if.h>
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
|
@ -854,7 +857,7 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ssdp_open_multicast_sock(u32 ip_addr)
|
int ssdp_open_multicast_sock(u32 ip_addr, const char *forced_ifname)
|
||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
/* per UPnP-arch-DeviceArchitecture, 1. Discovery, keep IP packet
|
/* per UPnP-arch-DeviceArchitecture, 1. Discovery, keep IP packet
|
||||||
|
@ -865,6 +868,22 @@ int ssdp_open_multicast_sock(u32 ip_addr)
|
||||||
if (sd < 0)
|
if (sd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (forced_ifname) {
|
||||||
|
#ifdef __linux__
|
||||||
|
struct ifreq req;
|
||||||
|
os_memset(&req, 0, sizeof(req));
|
||||||
|
os_strlcpy(req.ifr_name, forced_ifname, sizeof(req.ifr_name));
|
||||||
|
if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, &req,
|
||||||
|
sizeof(req)) < 0) {
|
||||||
|
wpa_printf(MSG_INFO, "WPS UPnP: Failed to bind "
|
||||||
|
"multicast socket to ifname %s: %s",
|
||||||
|
forced_ifname, strerror(errno));
|
||||||
|
close(sd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* __linux__ */
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* maybe ok if we sometimes block on writes */
|
#if 0 /* maybe ok if we sometimes block on writes */
|
||||||
if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0) {
|
if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0) {
|
||||||
close(sd);
|
close(sd);
|
||||||
|
@ -924,7 +943,7 @@ int ssdp_open_multicast_sock(u32 ip_addr)
|
||||||
*/
|
*/
|
||||||
int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
|
int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
|
||||||
{
|
{
|
||||||
sm->multicast_sd = ssdp_open_multicast_sock(sm->ip_addr);
|
sm->multicast_sd = ssdp_open_multicast_sock(sm->ip_addr, NULL);
|
||||||
if (sm->multicast_sd < 0)
|
if (sm->multicast_sd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue