WPS: Add support for setting timeout for PIN
[wpasupplicant] / src / wps / wps_upnp.c
index bebecc2..da488bc 100644 (file)
@@ -465,7 +465,7 @@ static void subscr_addr_list_create(struct subscription *s,
 
 int send_wpabuf(int fd, struct wpabuf *buf)
 {
-       wpa_printf(MSG_DEBUG, "WPS UPnP: %lu byte response",
+       wpa_printf(MSG_DEBUG, "WPS UPnP: Send %lu byte message",
                   (unsigned long) wpabuf_len(buf));
        errno = 0;
        if (write(fd, wpabuf_head(buf), wpabuf_len(buf)) !=
@@ -567,9 +567,8 @@ void subscription_unlink(struct subscription *s)
                /* only one? */
                sm->subscriptions = NULL;
        } else  {
-               if (sm->subscriptions == s) {
+               if (sm->subscriptions == s)
                        sm->subscriptions = s->next;
-               }
                s->next->prev = s->prev;
                s->prev->next = s->next;
        }
@@ -703,7 +702,7 @@ static int subscription_first_event(struct subscription *s)
 struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
                                         char *callback_urls)
 {
-       struct subscription *s = NULL;
+       struct subscription *s;
        time_t now = time(NULL);
        time_t expire = now + UPNP_SUBSCRIBE_SEC;
 
@@ -712,7 +711,7 @@ struct subscription * subscription_start(struct upnp_wps_device_sm *sm,
 
        /* If too many subscriptions, remove oldest */
        if (sm->n_subscriptions >= MAX_SUBSCRIPTIONS) {
-               struct subscription *s = sm->subscriptions;
+               s = sm->subscriptions;
                wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, "
                           "trashing oldest");
                subscription_unlink(s);
@@ -833,6 +832,50 @@ fail:
 }
 
 
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+
+static int eth_get(const char *device, u8 ea[ETH_ALEN])
+{
+       struct if_msghdr *ifm;
+       struct sockaddr_dl *sdl;
+       u_char *p, *buf;
+       size_t len;
+       int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
+
+       if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
+               return -1;
+       if ((buf = os_malloc(len)) == NULL)
+               return -1;
+       if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+               os_free(buf);
+               return -1;
+       }
+       for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
+               ifm = (struct if_msghdr *)p;
+               sdl = (struct sockaddr_dl *)(ifm + 1);
+               if (ifm->ifm_type != RTM_IFINFO ||
+                   (ifm->ifm_addrs & RTA_IFP) == 0)
+                       continue;
+               if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
+                   os_memcmp(sdl->sdl_data, device, sdl->sdl_nlen) != 0)
+                       continue;
+               os_memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
+               break;
+       }
+       os_free(buf);
+
+       if (p >= buf + len) {
+               errno = ESRCH;
+               return -1;
+       }
+       return 0;
+}
+#endif /* __FreeBSD__ */
+
+
 /**
  * get_netif_info - Get hw and IP addresses for network device
  * @net_if: Selected network interface name
@@ -856,10 +899,11 @@ static int get_netif_info(const char *net_if, unsigned *ip_addr,
        if (*ip_addr_text == NULL || *mac_addr_text == NULL)
                goto fail;
 
-       if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0)
                goto fail;
 
-       os_strncpy(req.ifr_name, net_if, sizeof(req.ifr_name));
+       os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name));
        if (ioctl(sock, SIOCGIFADDR, &req) < 0) {
                wpa_printf(MSG_ERROR, "WPS UPnP: SIOCGIFADDR failed: %d (%s)",
                           errno, strerror(errno));
@@ -870,13 +914,22 @@ static int get_netif_info(const char *net_if, unsigned *ip_addr,
        in_addr.s_addr = *ip_addr;
        os_snprintf(*ip_addr_text, 16, "%s", inet_ntoa(in_addr));
 
-       os_strncpy(req.ifr_name, net_if, sizeof(req.ifr_name));
+#ifdef __linux__
+       os_strlcpy(req.ifr_name, net_if, sizeof(req.ifr_name));
        if (ioctl(sock, SIOCGIFHWADDR, &req) < 0) {
                wpa_printf(MSG_ERROR, "WPS UPnP: SIOCGIFHWADDR failed: "
                           "%d (%s)", errno, strerror(errno));
                goto fail;
        }
        os_memcpy(mac, req.ifr_addr.sa_data, 6);
+#elif defined(__FreeBSD__)
+       if (eth_get(net_if, mac) < 0) {
+               wpa_printf(MSG_ERROR, "WPS UPnP: Failed to get MAC address");
+               goto fail;
+       }
+#else
+#error MAC address fetch not implemented
+#endif
        os_snprintf(*mac_addr_text, 18, MACSTR, MAC2STR(req.ifr_addr.sa_data));
 
        close(sock);