Browse Source

Convert WPS IE concat routine to a generic helper

This may also be needed in wpa_supplicant and potentially for other
IE types, too.
Jouni Malinen 15 years ago
parent
commit
abad3ccb1e
3 changed files with 49 additions and 31 deletions
  1. 2 31
      hostapd/wps_hostapd.c
  2. 45 0
      src/common/ieee802_11_common.c
  3. 2 0
      src/common/ieee802_11_common.h

+ 2 - 31
hostapd/wps_hostapd.c

@@ -20,6 +20,7 @@
 #include "uuid.h"
 #include "wpa_ctrl.h"
 #include "ieee802_11_defs.h"
+#include "ieee802_11_common.h"
 #include "sta_info.h"
 #include "eapol_sm.h"
 #include "wps/wps.h"
@@ -793,44 +794,14 @@ static void hostapd_wps_probe_req_rx(void *ctx, const u8 *addr,
 {
 	struct hostapd_data *hapd = ctx;
 	struct wpabuf *wps_ie;
-	const u8 *end, *pos, *wps;
 
 	if (hapd->wps == NULL)
 		return;
 
-	pos = ie;
-	end = ie + ie_len;
-	wps = NULL;
-
-	while (pos + 1 < end) {
-		if (pos + 2 + pos[1] > end)
-			return;
-		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
-		    WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA) {
-			wps = pos;
-			break;
-		}
-		pos += 2 + pos[1];
-	}
-
-	if (wps == NULL)
-		return; /* No WPS IE in Probe Request */
-
-	wps_ie = wpabuf_alloc(ie_len);
+	wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
 	if (wps_ie == NULL)
 		return;
 
-	/* There may be multiple WPS IEs in the message, so need to concatenate
-	 * their WPS Data fields */
-	while (pos + 1 < end) {
-		if (pos + 2 + pos[1] > end)
-			break;
-		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
-		    WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA)
-			wpabuf_put_data(wps_ie, pos + 6, pos[1] - 4);
-		pos += 2 + pos[1];
-	}
-
 	if (wpabuf_len(wps_ie) > 0) {
 		wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie);
 #ifdef CONFIG_WPS_UPNP

+ 45 - 0
src/common/ieee802_11_common.c

@@ -279,3 +279,48 @@ int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
 
 	return count;
 }
+
+
+struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
+					    u32 oui_type)
+{
+	struct wpabuf *buf;
+	const u8 *end, *pos, *ie;
+
+	pos = ies;
+	end = ies + ies_len;
+	ie = NULL;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			return NULL;
+		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+		    WPA_GET_BE32(&pos[2]) == oui_type) {
+			ie = pos;
+			break;
+		}
+		pos += 2 + pos[1];
+	}
+
+	if (ie == NULL)
+		return NULL; /* No specified vendor IE found */
+
+	buf = wpabuf_alloc(ies_len);
+	if (buf == NULL)
+		return NULL;
+
+	/*
+	 * There may be multiple vendor IEs in the message, so need to
+	 * concatenate their data fields.
+	 */
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+		    WPA_GET_BE32(&pos[2]) == oui_type)
+			wpabuf_put_data(buf, pos + 6, pos[1] - 4);
+		pos += 2 + pos[1];
+	}
+
+	return buf;
+}

+ 2 - 0
src/common/ieee802_11_common.h

@@ -71,5 +71,7 @@ ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
 				struct ieee802_11_elems *elems,
 				int show_errors);
 int ieee802_11_ie_count(const u8 *ies, size_t ies_len);
+struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
+					    u32 oui_type);
 
 #endif /* IEEE802_11_COMMON_H */