aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-11-21 17:26:23 +0200
committerJouni Malinen <j@w1.fi>2009-11-21 17:26:23 +0200
commitec72bd0c77ca2e4a778d2962a81a00f41e6b6386 (patch)
treefaa84185ea8c7621f3b21a558f21bbf0f9a01781
parentd6211fbb2e8110955ab9d972fc8fd73ea98d4aa5 (diff)
downloadexternal_wpa_supplicant_8_ti-ec72bd0c77ca2e4a778d2962a81a00f41e6b6386.zip
external_wpa_supplicant_8_ti-ec72bd0c77ca2e4a778d2962a81a00f41e6b6386.tar.gz
external_wpa_supplicant_8_ti-ec72bd0c77ca2e4a778d2962a81a00f41e6b6386.tar.bz2
WPS ER: Move SSDP functionality into a separate file
-rw-r--r--src/wps/wps_er.c251
-rw-r--r--src/wps/wps_er.h84
-rw-r--r--src/wps/wps_er_ssdp.c193
-rw-r--r--wpa_supplicant/Makefile1
4 files changed, 284 insertions, 245 deletions
diff --git a/src/wps/wps_er.c b/src/wps/wps_er.c
index 21fec3d..3c94bec 100644
--- a/src/wps/wps_er.c
+++ b/src/wps/wps_er.c
@@ -25,89 +25,11 @@
#include "wps_i.h"
#include "wps_upnp.h"
#include "wps_upnp_i.h"
+#include "wps_er.h"
-/* TODO:
- * send notification of new AP device with wpa_msg
- * re-send notifications with wpa_msg if ER re-started (to update wpa_gui-qt4)
- * (also re-send SSDP M-SEARCH in this case to find new APs)
- * parse UPnP event messages
- */
-
static void wps_er_ap_timeout(void *eloop_data, void *user_ctx);
static void wps_er_sta_timeout(void *eloop_data, void *user_ctx);
-
-
-struct wps_er_sta {
- struct wps_er_sta *next;
- struct wps_er_ap *ap;
- u8 addr[ETH_ALEN];
- u16 config_methods;
- u8 uuid[WPS_UUID_LEN];
- u8 pri_dev_type[8];
- u16 dev_passwd_id;
- int m1_received;
- char *manufacturer;
- char *model_name;
- char *model_number;
- char *serial_number;
- char *dev_name;
- struct wps_data *wps;
- struct http_client *http;
-};
-
-struct wps_er_ap {
- struct wps_er_ap *next;
- struct wps_er *er;
- struct wps_er_sta *sta; /* list of STAs/Enrollees using this AP */
- struct in_addr addr;
- char *location;
- struct http_client *http;
- struct wps_data *wps;
-
- u8 uuid[WPS_UUID_LEN];
- u8 pri_dev_type[8];
- u8 wps_state;
- u8 mac_addr[ETH_ALEN];
- char *friendly_name;
- char *manufacturer;
- char *manufacturer_url;
- char *model_description;
- char *model_name;
- char *model_number;
- char *model_url;
- char *serial_number;
- char *udn;
- char *upc;
-
- char *scpd_url;
- char *control_url;
- char *event_sub_url;
-
- int subscribed;
- unsigned int id;
-
- struct wps_credential *ap_settings;
-
- void (*m1_handler)(struct wps_er_ap *ap, struct wpabuf *m1);
-};
-
-struct wps_er {
- struct wps_context *wps;
- char ifname[17];
- char *mac_addr_text; /* 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 */
- unsigned ip_addr; /* IP address of network i.f. we use (host order) */
- int multicast_sd;
- int ssdp_sd;
- struct wps_er_ap *ap;
- struct http_server *http_srv;
- int http_port;
- unsigned int next_ap_id;
-};
-
-
static void wps_er_ap_process(struct wps_er_ap *ap, struct wpabuf *msg);
static int wps_er_send_get_device_info(struct wps_er_ap *ap,
void (*m1_handler)(struct wps_er_ap *ap,
@@ -502,9 +424,8 @@ static void wps_er_http_dev_desc_cb(void *ctx, struct http_client *c,
}
-static void wps_er_ap_add(struct wps_er *er, const u8 *uuid,
- struct in_addr *addr,
- const char *location, int max_age)
+void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
+ const char *location, int max_age)
{
struct wps_er_ap *ap;
@@ -542,7 +463,7 @@ static void wps_er_ap_add(struct wps_er *er, const u8 *uuid,
}
-static void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr)
+void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr)
{
struct wps_er_ap *prev = NULL, *ap = er->ap;
@@ -576,138 +497,6 @@ static void wps_er_ap_remove_all(struct wps_er *er)
}
-static void wps_er_ssdp_rx(int sd, void *eloop_ctx, void *sock_ctx)
-{
- struct wps_er *er = eloop_ctx;
- struct sockaddr_in addr; /* client address */
- socklen_t addr_len;
- int nread;
- char buf[MULTICAST_MAX_READ], *pos, *pos2, *start;
- int wfa = 0, byebye = 0;
- int max_age = -1;
- char *location = NULL;
- u8 uuid[WPS_UUID_LEN];
-
- addr_len = sizeof(addr);
- nread = recvfrom(sd, buf, sizeof(buf) - 1, 0,
- (struct sockaddr *) &addr, &addr_len);
- if (nread <= 0)
- return;
- buf[nread] = '\0';
-
- wpa_printf(MSG_DEBUG, "WPS ER: Received SSDP from %s",
- inet_ntoa(addr.sin_addr));
- wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Received SSDP contents",
- (u8 *) buf, nread);
-
- if (sd == er->multicast_sd) {
- /* Reply to M-SEARCH */
- if (os_strncmp(buf, "HTTP/1.1 200 OK", 15) != 0)
- return; /* unexpected response header */
- } else {
- /* Unsolicited message (likely NOTIFY or M-SEARCH) */
- if (os_strncmp(buf, "NOTIFY ", 7) != 0)
- return; /* only process notifications */
- }
-
- os_memset(uuid, 0, sizeof(uuid));
-
- for (start = buf; start && *start; start = pos) {
- pos = os_strchr(start, '\n');
- if (pos) {
- if (pos[-1] == '\r')
- pos[-1] = '\0';
- *pos++ = '\0';
- }
- if (os_strstr(start, "schemas-wifialliance-org:device:"
- "WFADevice:1"))
- wfa = 1;
- if (os_strstr(start, "schemas-wifialliance-org:service:"
- "WFAWLANConfig:1"))
- wfa = 1;
- if (os_strncasecmp(start, "LOCATION:", 9) == 0) {
- start += 9;
- while (*start == ' ')
- start++;
- location = start;
- } else if (os_strncasecmp(start, "NTS:", 4) == 0) {
- if (os_strstr(start, "ssdp:byebye"))
- byebye = 1;
- } else if (os_strncasecmp(start, "CACHE-CONTROL:", 14) == 0) {
- start += 9;
- while (*start == ' ')
- start++;
- pos2 = os_strstr(start, "max-age=");
- if (pos2 == NULL)
- continue;
- pos2 += 8;
- max_age = atoi(pos2);
- } else if (os_strncasecmp(start, "USN:", 4) == 0) {
- start += 4;
- pos2 = os_strstr(start, "uuid:");
- if (pos2) {
- pos2 += 5;
- while (*pos2 == ' ')
- pos2++;
- uuid_str2bin(pos2, uuid);
- }
- }
- }
-
- if (!wfa)
- return; /* Not WPS advertisement/reply */
-
- if (byebye) {
- wps_er_ap_remove(er, &addr.sin_addr);
- return;
- }
-
- if (!location)
- return; /* Unknown location */
-
- if (max_age < 1)
- return; /* No max-age reported */
-
- wpa_printf(MSG_DEBUG, "WPS ER: AP discovered: %s "
- "(packet source: %s max-age: %d)",
- location, inet_ntoa(addr.sin_addr), max_age);
-
- wps_er_ap_add(er, uuid, &addr.sin_addr, location, max_age);
-}
-
-
-static void wps_er_send_ssdp_msearch(struct wps_er *er)
-{
- struct wpabuf *msg;
- struct sockaddr_in dest;
-
- msg = wpabuf_alloc(500);
- if (msg == NULL)
- return;
-
- wpabuf_put_str(msg,
- "M-SEARCH * HTTP/1.1\r\n"
- "HOST: 239.255.255.250:1900\r\n"
- "MAN: \"ssdp:discover\"\r\n"
- "MX: 3\r\n"
- "ST: urn:schemas-wifialliance-org:device:WFADevice:1"
- "\r\n"
- "\r\n");
-
- os_memset(&dest, 0, sizeof(dest));
- dest.sin_family = AF_INET;
- dest.sin_addr.s_addr = inet_addr(UPNP_MULTICAST_ADDRESS);
- dest.sin_port = htons(UPNP_MULTICAST_PORT);
-
- if (sendto(er->multicast_sd, wpabuf_head(msg), wpabuf_len(msg), 0,
- (struct sockaddr *) &dest, sizeof(dest)) < 0)
- wpa_printf(MSG_DEBUG, "WPS ER: M-SEARCH sendto failed: "
- "%d (%s)", errno, strerror(errno));
-
- wpabuf_free(msg);
-}
-
-
static void http_put_date(struct wpabuf *buf)
{
wpabuf_put_str(buf, "Date: ");
@@ -1261,26 +1050,7 @@ wps_er_init(struct wps_context *wps, const char *ifname)
return NULL;
}
- if (add_ssdp_network(ifname)) {
- wps_er_deinit(er);
- return NULL;
- }
-
- er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr);
- if (er->multicast_sd < 0) {
- wps_er_deinit(er);
- return NULL;
- }
-
- er->ssdp_sd = ssdp_listener_open();
- if (er->ssdp_sd < 0) {
- wps_er_deinit(er);
- return NULL;
- }
- if (eloop_register_sock(er->multicast_sd, EVENT_TYPE_READ,
- wps_er_ssdp_rx, er, NULL) ||
- eloop_register_sock(er->ssdp_sd, EVENT_TYPE_READ,
- wps_er_ssdp_rx, er, NULL)) {
+ if (wps_er_ssdp_init(er) < 0) {
wps_er_deinit(er);
return NULL;
}
@@ -1297,8 +1067,6 @@ wps_er_init(struct wps_context *wps, const char *ifname)
"mac_addr=%s)",
er->ifname, er->ip_addr_text, er->mac_addr_text);
- wps_er_send_ssdp_msearch(er);
-
return er;
}
@@ -1324,14 +1092,7 @@ void wps_er_deinit(struct wps_er *er)
return;
http_server_deinit(er->http_srv);
wps_er_ap_remove_all(er);
- if (er->multicast_sd >= 0) {
- eloop_unregister_sock(er->multicast_sd, EVENT_TYPE_READ);
- close(er->multicast_sd);
- }
- if (er->ssdp_sd >= 0) {
- eloop_unregister_sock(er->ssdp_sd, EVENT_TYPE_READ);
- close(er->ssdp_sd);
- }
+ wps_er_ssdp_deinit(er);
os_free(er->ip_addr_text);
os_free(er->mac_addr_text);
os_free(er);
diff --git a/src/wps/wps_er.h b/src/wps/wps_er.h
new file mode 100644
index 0000000..cf2048c
--- /dev/null
+++ b/src/wps/wps_er.h
@@ -0,0 +1,84 @@
+#ifndef WPS_ER_H
+#define WPS_ER_H
+
+struct wps_er_sta {
+ struct wps_er_sta *next;
+ struct wps_er_ap *ap;
+ u8 addr[ETH_ALEN];
+ u16 config_methods;
+ u8 uuid[WPS_UUID_LEN];
+ u8 pri_dev_type[8];
+ u16 dev_passwd_id;
+ int m1_received;
+ char *manufacturer;
+ char *model_name;
+ char *model_number;
+ char *serial_number;
+ char *dev_name;
+ struct wps_data *wps;
+ struct http_client *http;
+};
+
+struct wps_er_ap {
+ struct wps_er_ap *next;
+ struct wps_er *er;
+ struct wps_er_sta *sta; /* list of STAs/Enrollees using this AP */
+ struct in_addr addr;
+ char *location;
+ struct http_client *http;
+ struct wps_data *wps;
+
+ u8 uuid[WPS_UUID_LEN];
+ u8 pri_dev_type[8];
+ u8 wps_state;
+ u8 mac_addr[ETH_ALEN];
+ char *friendly_name;
+ char *manufacturer;
+ char *manufacturer_url;
+ char *model_description;
+ char *model_name;
+ char *model_number;
+ char *model_url;
+ char *serial_number;
+ char *udn;
+ char *upc;
+
+ char *scpd_url;
+ char *control_url;
+ char *event_sub_url;
+
+ int subscribed;
+ unsigned int id;
+
+ struct wps_credential *ap_settings;
+
+ void (*m1_handler)(struct wps_er_ap *ap, struct wpabuf *m1);
+};
+
+struct wps_er {
+ struct wps_context *wps;
+ char ifname[17];
+ char *mac_addr_text; /* 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 */
+ unsigned ip_addr; /* IP address of network i.f. we use (host order) */
+ int multicast_sd;
+ int ssdp_sd;
+ struct wps_er_ap *ap;
+ struct http_server *http_srv;
+ int http_port;
+ unsigned int next_ap_id;
+};
+
+
+/* wps_er.c */
+void wps_er_ap_add(struct wps_er *er, const u8 *uuid, struct in_addr *addr,
+ const char *location, int max_age);
+void wps_er_ap_remove(struct wps_er *er, struct in_addr *addr);
+
+/* wps_er_ssdp.c */
+int wps_er_ssdp_init(struct wps_er *er);
+void wps_er_ssdp_deinit(struct wps_er *er);
+void wps_er_send_ssdp_msearch(struct wps_er *er);
+
+#endif /* WPS_ER_H */
diff --git a/src/wps/wps_er_ssdp.c b/src/wps/wps_er_ssdp.c
new file mode 100644
index 0000000..83879db
--- /dev/null
+++ b/src/wps/wps_er_ssdp.c
@@ -0,0 +1,193 @@
+/*
+ * Wi-Fi Protected Setup - External Registrar (SSDP)
+ * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "uuid.h"
+#include "eloop.h"
+#include "wps_i.h"
+#include "wps_upnp.h"
+#include "wps_upnp_i.h"
+#include "wps_er.h"
+
+
+static void wps_er_ssdp_rx(int sd, void *eloop_ctx, void *sock_ctx)
+{
+ struct wps_er *er = eloop_ctx;
+ struct sockaddr_in addr; /* client address */
+ socklen_t addr_len;
+ int nread;
+ char buf[MULTICAST_MAX_READ], *pos, *pos2, *start;
+ int wfa = 0, byebye = 0;
+ int max_age = -1;
+ char *location = NULL;
+ u8 uuid[WPS_UUID_LEN];
+
+ addr_len = sizeof(addr);
+ nread = recvfrom(sd, buf, sizeof(buf) - 1, 0,
+ (struct sockaddr *) &addr, &addr_len);
+ if (nread <= 0)
+ return;
+ buf[nread] = '\0';
+
+ wpa_printf(MSG_DEBUG, "WPS ER: Received SSDP from %s",
+ inet_ntoa(addr.sin_addr));
+ wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Received SSDP contents",
+ (u8 *) buf, nread);
+
+ if (sd == er->multicast_sd) {
+ /* Reply to M-SEARCH */
+ if (os_strncmp(buf, "HTTP/1.1 200 OK", 15) != 0)
+ return; /* unexpected response header */
+ } else {
+ /* Unsolicited message (likely NOTIFY or M-SEARCH) */
+ if (os_strncmp(buf, "NOTIFY ", 7) != 0)
+ return; /* only process notifications */
+ }
+
+ os_memset(uuid, 0, sizeof(uuid));
+
+ for (start = buf; start && *start; start = pos) {
+ pos = os_strchr(start, '\n');
+ if (pos) {
+ if (pos[-1] == '\r')
+ pos[-1] = '\0';
+ *pos++ = '\0';
+ }
+ if (os_strstr(start, "schemas-wifialliance-org:device:"
+ "WFADevice:1"))
+ wfa = 1;
+ if (os_strstr(start, "schemas-wifialliance-org:service:"
+ "WFAWLANConfig:1"))
+ wfa = 1;
+ if (os_strncasecmp(start, "LOCATION:", 9) == 0) {
+ start += 9;
+ while (*start == ' ')
+ start++;
+ location = start;
+ } else if (os_strncasecmp(start, "NTS:", 4) == 0) {
+ if (os_strstr(start, "ssdp:byebye"))
+ byebye = 1;
+ } else if (os_strncasecmp(start, "CACHE-CONTROL:", 14) == 0) {
+ start += 9;
+ while (*start == ' ')
+ start++;
+ pos2 = os_strstr(start, "max-age=");
+ if (pos2 == NULL)
+ continue;
+ pos2 += 8;
+ max_age = atoi(pos2);
+ } else if (os_strncasecmp(start, "USN:", 4) == 0) {
+ start += 4;
+ pos2 = os_strstr(start, "uuid:");
+ if (pos2) {
+ pos2 += 5;
+ while (*pos2 == ' ')
+ pos2++;
+ uuid_str2bin(pos2, uuid);
+ }
+ }
+ }
+
+ if (!wfa)
+ return; /* Not WPS advertisement/reply */
+
+ if (byebye) {
+ wps_er_ap_remove(er, &addr.sin_addr);
+ return;
+ }
+
+ if (!location)
+ return; /* Unknown location */
+
+ if (max_age < 1)
+ return; /* No max-age reported */
+
+ wpa_printf(MSG_DEBUG, "WPS ER: AP discovered: %s "
+ "(packet source: %s max-age: %d)",
+ location, inet_ntoa(addr.sin_addr), max_age);
+
+ wps_er_ap_add(er, uuid, &addr.sin_addr, location, max_age);
+}
+
+
+void wps_er_send_ssdp_msearch(struct wps_er *er)
+{
+ struct wpabuf *msg;
+ struct sockaddr_in dest;
+
+ msg = wpabuf_alloc(500);
+ if (msg == NULL)
+ return;
+
+ wpabuf_put_str(msg,
+ "M-SEARCH * HTTP/1.1\r\n"
+ "HOST: 239.255.255.250:1900\r\n"
+ "MAN: \"ssdp:discover\"\r\n"
+ "MX: 3\r\n"
+ "ST: urn:schemas-wifialliance-org:device:WFADevice:1"
+ "\r\n"
+ "\r\n");
+
+ os_memset(&dest, 0, sizeof(dest));
+ dest.sin_family = AF_INET;
+ dest.sin_addr.s_addr = inet_addr(UPNP_MULTICAST_ADDRESS);
+ dest.sin_port = htons(UPNP_MULTICAST_PORT);
+
+ if (sendto(er->multicast_sd, wpabuf_head(msg), wpabuf_len(msg), 0,
+ (struct sockaddr *) &dest, sizeof(dest)) < 0)
+ wpa_printf(MSG_DEBUG, "WPS ER: M-SEARCH sendto failed: "
+ "%d (%s)", errno, strerror(errno));
+
+ wpabuf_free(msg);
+}
+
+
+int wps_er_ssdp_init(struct wps_er *er)
+{
+ if (add_ssdp_network(er->ifname))
+ return -1;
+
+ er->multicast_sd = ssdp_open_multicast_sock(er->ip_addr);
+ if (er->multicast_sd < 0)
+ return -1;
+
+ er->ssdp_sd = ssdp_listener_open();
+ if (er->ssdp_sd < 0)
+ return -1;
+
+ if (eloop_register_sock(er->multicast_sd, EVENT_TYPE_READ,
+ wps_er_ssdp_rx, er, NULL) ||
+ eloop_register_sock(er->ssdp_sd, EVENT_TYPE_READ,
+ wps_er_ssdp_rx, er, NULL))
+ return -1;
+
+ wps_er_send_ssdp_msearch(er);
+
+ return 0;
+}
+
+
+void wps_er_ssdp_deinit(struct wps_er *er)
+{
+ if (er->multicast_sd >= 0) {
+ eloop_unregister_sock(er->multicast_sd, EVENT_TYPE_READ);
+ close(er->multicast_sd);
+ }
+ if (er->ssdp_sd >= 0) {
+ eloop_unregister_sock(er->ssdp_sd, EVENT_TYPE_READ);
+ close(er->ssdp_sd);
+ }
+}
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 0879774..19621ec 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -501,6 +501,7 @@ ifdef CONFIG_WPS_ER
CONFIG_WPS_UPNP=y
CFLAGS += -DCONFIG_WPS_ER
OBJS += ../src/wps/wps_er.o
+OBJS += ../src/wps/wps_er_ssdp.o
endif
ifdef CONFIG_WPS_UPNP