]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS ER: Allow UPnP interface to be forced
authorJouni Malinen <j@w1.fi>
Sun, 28 Apr 2013 18:56:24 +0000 (21:56 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 28 Apr 2013 18:56:24 +0000 (21:56 +0300)
"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>

src/wps/wps_er.c
src/wps/wps_er.h
src/wps/wps_er_ssdp.c
src/wps/wps_upnp_i.h
src/wps/wps_upnp_ssdp.c

index 18df20b39d31c1fa5e7b08cbb2341076ad18ec9a..56949970b424a17121788d3889ba4ff3b9f73056 100644 (file)
@@ -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() */
        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 "
@@ -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 "
                           "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;
        }
index 611964741e4b984ffd0dcc0ee7e63d4004a81b12..4b48ff6adf3a8a1c32d5f287a6a3110b4fe9182f 100644 (file)
@@ -76,6 +76,7 @@ struct wps_er_ap_settings {
 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) */
index f9f6e6c1a4b63ccf431df755180b4343544bbbeb..e381fecbdc86a51a4a4cacd46579340d20abefa5 100644 (file)
@@ -166,7 +166,9 @@ int wps_er_ssdp_init(struct wps_er *er)
                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");
index 7f3c56109e199c690cee3516d27fc239e4812baf..5c39f7efed1865c1a2cec89fcde4e6784a84c47b 100644 (file)
@@ -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_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 */
index 17a82074a7fb0b93731bbea9179265d47b217bfa..416961cc0f27a4458dfc9d8d89a9af103491b7a4 100644 (file)
@@ -3,7 +3,7 @@
  * 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.
  */
@@ -13,6 +13,9 @@
 #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"
@@ -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;
         /* per UPnP-arch-DeviceArchitecture, 1. Discovery, keep IP packet
@@ -865,6 +868,22 @@ int ssdp_open_multicast_sock(u32 ip_addr)
        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);
@@ -924,7 +943,7 @@ int ssdp_open_multicast_sock(u32 ip_addr)
  */
 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;