]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS ER: Parse WLANEvent notifications and send HTTP response
authorJouni Malinen <j@w1.fi>
Tue, 10 Nov 2009 22:23:22 +0000 (00:23 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 10 Nov 2009 22:23:22 +0000 (00:23 +0200)
The receive Probe Request and EAP-WSC notifications are now parsed
(including the TLVs in them) and contents is shown in the debug log.
Actual processing of the received information is still missing (TODO
comments indicate the needed functionality).

src/wps/wps_er.c

index bfa27e2a3cf6b6fbf433c099e9b0f15d147ebc47..2e11dd604dad584cb4107440f721a5a10bd2d3bd 100644 (file)
@@ -489,19 +489,169 @@ static void wps_er_send_ssdp_msearch(struct wps_er *er)
 }
 
 
+static void http_put_date(struct wpabuf *buf)
+{
+       wpabuf_put_str(buf, "Date: ");
+       format_date(buf);
+       wpabuf_put_str(buf, "\r\n");
+}
+
+
+static void wps_er_http_resp_not_found(struct http_request *req)
+{
+       struct wpabuf *buf;
+       buf = wpabuf_alloc(200);
+       if (buf == NULL) {
+               http_request_deinit(req);
+               return;
+       }
+
+       wpabuf_put_str(buf,
+                      "HTTP/1.1 404 Not Found\r\n"
+                      "Server: unspecified, UPnP/1.0, unspecified\r\n"
+                      "Connection: close\r\n");
+       http_put_date(buf);
+       wpabuf_put_str(buf, "\r\n");
+       http_request_send_and_deinit(req, buf);
+}
+
+
+static void wps_er_http_resp_ok(struct http_request *req)
+{
+       struct wpabuf *buf;
+       buf = wpabuf_alloc(200);
+       if (buf == NULL) {
+               http_request_deinit(req);
+               return;
+       }
+
+       wpabuf_put_str(buf,
+                      "HTTP/1.1 200 OK\r\n"
+                      "Server: unspecified, UPnP/1.0, unspecified\r\n"
+                      "Connection: close\r\n"
+                      "Content-Length: 0\r\n");
+       http_put_date(buf);
+       wpabuf_put_str(buf, "\r\n");
+       http_request_send_and_deinit(req, buf);
+}
+
+
+static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
+                                              const u8 *addr,
+                                              struct wpabuf *msg)
+{
+       struct wps_parse_attr attr;
+
+       wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - Probe Request - from "
+                  MACSTR, MAC2STR(addr));
+       wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
+                       "(TLVs from Probe Request)", msg);
+
+       if (wps_parse_msg(msg, &attr) < 0) {
+               wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
+                          "WLANEvent message");
+               return;
+       }
+
+       /* TODO: add STA table to the AP entry and wpa_msg indication if new
+        * STA */
+}
+
+
+static void wps_er_process_wlanevent_eap(struct wps_er_ap *ap, const u8 *addr,
+                                        struct wpabuf *msg)
+{
+       struct wps_parse_attr attr;
+
+       wpa_printf(MSG_DEBUG, "WPS ER: WLANEvent - EAP - from " MACSTR,
+                  MAC2STR(addr));
+       wpa_hexdump_buf(MSG_MSGDUMP, "WPS ER: WLANEvent - Enrollee's message "
+                       "(TLVs from EAP-WSC)", msg);
+
+       if (wps_parse_msg(msg, &attr) < 0) {
+               wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse TLVs in "
+                          "WLANEvent message");
+               return;
+       }
+
+       /* TODO: add STA table to the AP entry and wpa_msg indication if new
+        * STA; process message if it is part of ongoing protocol run */
+}
+
+
+static void wps_er_process_wlanevent(struct wps_er_ap *ap,
+                                    struct wpabuf *event)
+{
+       u8 *data;
+       u8 wlan_event_type;
+       u8 wlan_event_mac[ETH_ALEN];
+       struct wpabuf msg;
+
+       wpa_hexdump(MSG_MSGDUMP, "WPS ER: Received WLANEvent",
+                   wpabuf_head(event), wpabuf_len(event));
+       if (wpabuf_len(event) < 1 + 17) {
+               wpa_printf(MSG_DEBUG, "WPS ER: Too short WLANEvent");
+               return;
+       }
+
+       data = wpabuf_mhead(event);
+       wlan_event_type = data[0];
+       if (hwaddr_aton((char *) data + 1, wlan_event_mac) < 0) {
+               wpa_printf(MSG_DEBUG, "WPS ER: Invalid WLANEventMAC in "
+                          "WLANEvent");
+               return;
+       }
+
+       wpabuf_set(&msg, data + 1 + 17, wpabuf_len(event) - (1 + 17));
+
+       switch (wlan_event_type) {
+       case 1:
+               wps_er_process_wlanevent_probe_req(ap, wlan_event_mac, &msg);
+               break;
+       case 2:
+               wps_er_process_wlanevent_eap(ap, wlan_event_mac, &msg);
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "WPS ER: Unknown WLANEventType %d",
+                          wlan_event_type);
+               break;
+       }
+}
+
+
 static void wps_er_http_event(struct wps_er *er, struct http_request *req,
                              unsigned int ap_id)
 {
        struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id);
+       struct wpabuf *event;
+       enum http_reply_code ret;
+
        if (ap == NULL) {
                wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id "
                           "%u", ap_id);
+               wps_er_http_resp_not_found(req);
                return;
        }
        wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s",
                   ap_id, http_request_get_data(req));
-       /* TODO */
-       http_request_deinit(req);
+
+       event = xml_get_base64_item(http_request_get_data(req), "WLANEvent",
+                                   &ret);
+       if (event == NULL) {
+               wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent "
+                          "from the event notification");
+               /*
+                * Reply with OK anyway to avoid getting unregistered from
+                * events.
+                */
+               wps_er_http_resp_ok(req);
+               return;
+       }
+
+       wps_er_process_wlanevent(ap, event);
+
+       wpabuf_free(event);
+       wps_er_http_resp_ok(req);
 }
 
 
@@ -514,7 +664,7 @@ static void wps_er_http_notify(struct wps_er *er, struct http_request *req)
        } else {
                wpa_printf(MSG_DEBUG, "WPS ER: Unknown HTTP NOTIFY for '%s'",
                           uri);
-               http_request_deinit(req);
+               wps_er_http_resp_not_found(req);
        }
 }
 
@@ -524,6 +674,8 @@ static void wps_er_http_req(void *ctx, struct http_request *req)
        struct wps_er *er = ctx;
        struct sockaddr_in *cli = http_request_get_cli_addr(req);
        enum httpread_hdr_type type = http_request_get_type(req);
+       struct wpabuf *buf;
+
        wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from "
                   "%s:%d",
                   http_request_get_uri(req), type,
@@ -536,7 +688,17 @@ static void wps_er_http_req(void *ctx, struct http_request *req)
        default:
                wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type "
                           "%d", type);
-               http_request_deinit(req);
+               buf = wpabuf_alloc(200);
+               if (buf == NULL) {
+                       http_request_deinit(req);
+                       return;
+               }
+               wpabuf_put_str(buf,
+                              "HTTP/1.1 501 Unimplemented\r\n"
+                              "Connection: close\r\n");
+               http_put_date(buf);
+               wpabuf_put_str(buf, "\r\n");
+               http_request_send_and_deinit(req, buf);
                break;
        }
 }