/* Limit event_id to < 32 bits to avoid issues with atoi() */
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 (inet_aton(filter, &er->filter_addr) == 0) {
wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
"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)) {
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);
return NULL;
}
struct wps_er {
struct wps_context *wps;
char ifname[17];
+ int forced_ifname;
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 */
unsigned ip_addr; /* IP address of network i.f. we use (host order) */
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) {
wpa_printf(MSG_INFO, "WPS ER: Failed to open multicast socket "
"for SSDP");
int ssdp_listener_start(struct upnp_wps_device_sm *sm);
int ssdp_listener_open(void);
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);
/* wps_upnp_web.c */
* Copyright (c) 2000-2003 Intel Corporation
* Copyright (c) 2006-2007 Sony Corporation
* 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.
*/
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/route.h>
+#ifdef __linux__
+#include <net/if.h>
+#endif /* __linux__ */
#include "common.h"
#include "uuid.h"
}
-int ssdp_open_multicast_sock(u32 ip_addr)
+int ssdp_open_multicast_sock(u32 ip_addr, const char *forced_ifname)
{
int sd;
/* per UPnP-arch-DeviceArchitecture, 1. Discovery, keep IP packet
if (sd < 0)
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 (fcntl(sd, F_SETFL, O_NONBLOCK) != 0) {
close(sd);
*/
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)
return -1;
return 0;