WPS: Add initial part of External Registrar functionality
[libeap.git] / src / wps / wps_upnp_ssdp.c
index 71dcc96..3ffff09 100644 (file)
@@ -24,7 +24,6 @@
 #define UPNP_CACHE_SEC (UPNP_CACHE_SEC_MIN + 1) /* cache time we use */
 #define UPNP_CACHE_SEC_MIN 1800 /* min cachable time per UPnP standard */
 #define UPNP_ADVERTISE_REPEAT 2 /* no more than 3 */
-#define MULTICAST_MAX_READ 1600 /* max bytes we'll read for UPD request */
 #define MAX_MSEARCH 20          /* max simultaneous M-SEARCH replies ongoing */
 #define SSDP_TARGET  "239.0.0.0"
 #define SSDP_NETMASK "255.0.0.0"
@@ -51,7 +50,7 @@ static int token_eq(const char *s1, const char *s2)
                if (end1 || end2 || c1 != c2)
                        break;
        }
-       return (end1 && end2);  /* reached end of both words? */
+       return end1 && end2; /* reached end of both words? */
 }
 
 
@@ -359,10 +358,9 @@ void msearchreply_state_machine_stop(struct advertisement_state_machine *a)
        wpa_printf(MSG_DEBUG, "WPS UPnP: M-SEARCH stop");
        if (a->next == a) {
                sm->msearch_replies = NULL;
-       } else  {
-               if (sm->msearch_replies == a) {
+       } else {
+               if (sm->msearch_replies == a)
                        sm->msearch_replies = a->next;
-               }
                a->next->prev = a->prev;
                a->prev->next = a->next;
        }
@@ -462,7 +460,7 @@ static void msearchreply_state_machine_start(struct upnp_wps_device_sm *sm,
        a->type = MSEARCH_REPLY;
        a->state = 0;
        a->sm = sm;
-       os_memcpy(&a->client, client, sizeof(client));
+       os_memcpy(&a->client, client, sizeof(*client));
        /* Wait time depending on MX value */
        next_timeout_msec = (1000 * mx * (os_random() & 0xFF)) >> 8;
        next_timeout_sec = next_timeout_msec / 1000;
@@ -658,7 +656,7 @@ bad:
  * ssdp_listener_stop - Stop SSDP listered
  * @sm: WPS UPnP state machine from upnp_wps_device_init()
  *
- * This function stops the SSDP listerner that was started by calling
+ * This function stops the SSDP listener that was started by calling
  * ssdp_listener_start().
  */
 void ssdp_listener_stop(struct upnp_wps_device_sm *sm)
@@ -720,23 +718,16 @@ static void ssdp_listener_handler(int sd, void *eloop_ctx, void *sock_ctx)
 }
 
 
-/**
- * ssdp_listener_start - Set up for receiving discovery (UDP) packets
- * @sm: WPS UPnP state machine from upnp_wps_device_init()
- * Returns: 0 on success, -1 on failure
- *
- * The SSDP listerner is stopped by calling ssdp_listener_stop().
- */
-int ssdp_listener_start(struct upnp_wps_device_sm *sm)
+int ssdp_listener_open(void)
 {
-       int sd = -1;
        struct sockaddr_in addr;
        struct ip_mreq mcast_addr;
        int on = 1;
        /* per UPnP spec, keep IP packet time to live (TTL) small */
        unsigned char ttl = 4;
+       int sd;
 
-       sm->ssdp_sd = sd = socket(AF_INET, SOCK_DGRAM, 0);
+       sd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sd < 0)
                goto fail;
        if (fcntl(sd, F_SETFL, O_NONBLOCK) != 0)
@@ -758,8 +749,29 @@ int ssdp_listener_start(struct upnp_wps_device_sm *sm)
        if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL,
                       &ttl, sizeof(ttl)))
                goto fail;
-       if (eloop_register_sock(sd, EVENT_TYPE_READ, ssdp_listener_handler,
-                               NULL, sm))
+
+       return sd;
+
+fail:
+       if (sd >= 0)
+               close(sd);
+       return -1;
+}
+
+
+/**
+ * ssdp_listener_start - Set up for receiving discovery (UDP) packets
+ * @sm: WPS UPnP state machine from upnp_wps_device_init()
+ * Returns: 0 on success, -1 on failure
+ *
+ * The SSDP listener is stopped by calling ssdp_listener_stop().
+ */
+int ssdp_listener_start(struct upnp_wps_device_sm *sm)
+{
+       sm->ssdp_sd = ssdp_listener_open();
+
+       if (eloop_register_sock(sm->ssdp_sd, EVENT_TYPE_READ,
+                               ssdp_listener_handler, NULL, sm))
                goto fail;
        sm->ssdp_sd_registered = 1;
        return 0;
@@ -783,8 +795,9 @@ fail:
  * once after booting up, but it does not hurt to call this more frequently
  * "to be safe".
  */
-int add_ssdp_network(char *net_if)
+int add_ssdp_network(const char *net_if)
 {
+#ifdef __linux__
        int ret = -1;
        int sock = -1;
        struct rtentry rt;
@@ -798,12 +811,12 @@ int add_ssdp_network(char *net_if)
        if (sock < 0)
                goto fail;
 
-       rt.rt_dev = net_if;
-       sin = (struct sockaddr_in *) &rt.rt_dst;
+       rt.rt_dev = (char *) net_if;
+       sin = aliasing_hide_typecast(&rt.rt_dst, struct sockaddr_in);
        sin->sin_family = AF_INET;
        sin->sin_port = 0;
        sin->sin_addr.s_addr = inet_addr(SSDP_TARGET);
-       sin = (struct sockaddr_in *) &rt.rt_genmask;
+       sin = aliasing_hide_typecast(&rt.rt_genmask, struct sockaddr_in);
        sin->sin_family = AF_INET;
        sin->sin_port = 0;
        sin->sin_addr.s_addr = inet_addr(SSDP_NETMASK);
@@ -827,22 +840,20 @@ fail:
                close(sock);
 
        return ret;
+#else /* __linux__ */
+       return 0;
+#endif /* __linux__ */
 }
 
 
-/**
- * ssdp_open_multicast - Open socket for sending multicast SSDP messages
- * @sm: WPS UPnP state machine from upnp_wps_device_init()
- * Returns: 0 on success, -1 on failure
- */
-int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
+int ssdp_open_multicast_sock(u32 ip_addr)
 {
-       int sd = -1;
+       int sd;
         /* per UPnP-arch-DeviceArchitecture, 1. Discovery, keep IP packet
          * time to live (TTL) small */
        unsigned char ttl = 4;
 
-       sm->multicast_sd = sd = socket(AF_INET, SOCK_DGRAM, 0);
+       sd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sd < 0)
                return -1;
 
@@ -852,7 +863,7 @@ int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
 #endif
 
        if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF,
-                      &sm->ip_addr, sizeof(sm->ip_addr)))
+                      &ip_addr, sizeof(ip_addr)))
                return -1;
        if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL,
                       &ttl, sizeof(ttl)))
@@ -862,7 +873,7 @@ int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
        {
                struct ip_mreq mreq;
                mreq.imr_multiaddr.s_addr = inet_addr(UPNP_MULTICAST_ADDRESS);
-               mreq.imr_interface.s_addr = sm->ip_addr;
+               mreq.imr_interface.s_addr = ip_addr;
                wpa_printf(MSG_DEBUG, "WPS UPnP: Multicast addr 0x%x if addr "
                           "0x%x",
                           mreq.imr_multiaddr.s_addr,
@@ -883,5 +894,19 @@ int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
         * which aids debugging I suppose but isn't really necessary?
         */
 
+       return sd;
+}
+
+
+/**
+ * ssdp_open_multicast - Open socket for sending multicast SSDP messages
+ * @sm: WPS UPnP state machine from upnp_wps_device_init()
+ * Returns: 0 on success, -1 on failure
+ */
+int ssdp_open_multicast(struct upnp_wps_device_sm *sm)
+{
+       sm->multicast_sd = ssdp_open_multicast_sock(sm->ip_addr);
+       if (sm->multicast_sd < 0)
+               return -1;
        return 0;
 }