WPS: Add support for adding WPS Vendor Extensions
This adds the ability to add WPS vendor extensions to an AP (or GO). They will be added to the WSC IE(s) in Beacon and Probe Response frames. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
f3cb52fb90
commit
4028a7fd43
6 changed files with 71 additions and 4 deletions
|
@ -316,6 +316,7 @@ struct hostapd_bss_config {
|
|||
char *model_description;
|
||||
char *model_url;
|
||||
char *upc;
|
||||
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||
#endif /* CONFIG_WPS */
|
||||
|
||||
#define P2P_ENABLED BIT(0)
|
||||
|
|
|
@ -657,6 +657,31 @@ static int interface_count(struct hostapd_iface *iface)
|
|||
}
|
||||
|
||||
|
||||
static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
|
||||
struct wps_context *wps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
|
||||
wpabuf_free(wps->dev.vendor_ext[i]);
|
||||
wps->dev.vendor_ext[i] = NULL;
|
||||
|
||||
if (hapd->conf->wps_vendor_ext[i] == NULL)
|
||||
continue;
|
||||
|
||||
wps->dev.vendor_ext[i] =
|
||||
wpabuf_dup(hapd->conf->wps_vendor_ext[i]);
|
||||
if (wps->dev.vendor_ext[i] == NULL) {
|
||||
while (--i >= 0)
|
||||
wpabuf_free(wps->dev.vendor_ext[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int hostapd_init_wps(struct hostapd_data *hapd,
|
||||
struct hostapd_bss_config *conf)
|
||||
{
|
||||
|
@ -731,6 +756,11 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
|
||||
WPS_DEV_TYPE_LEN);
|
||||
|
||||
if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) {
|
||||
os_free(wps);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
|
||||
wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
|
||||
WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */
|
||||
|
@ -900,6 +930,8 @@ void hostapd_update_wps(struct hostapd_data *hapd)
|
|||
hapd->wps->upc = hapd->conf->upc;
|
||||
#endif /* CONFIG_WPS_UPNP */
|
||||
|
||||
hostapd_wps_set_vendor_ext(hapd, hapd->wps);
|
||||
|
||||
if (hapd->conf->wps_state)
|
||||
wps_registrar_update_ie(hapd->wps->registrar);
|
||||
else
|
||||
|
|
|
@ -64,6 +64,8 @@ struct wps_credential {
|
|||
#define WPS_DEV_TYPE_LEN 8
|
||||
#define WPS_DEV_TYPE_BUFSIZE 21
|
||||
#define WPS_SEC_DEV_TYPE_MAX_LEN 128
|
||||
/* maximum number of advertised WPS vendor extension attributes */
|
||||
#define MAX_WPS_VENDOR_EXTENSIONS 10
|
||||
|
||||
/**
|
||||
* struct wps_device_data - WPS Device Data
|
||||
|
@ -93,6 +95,7 @@ struct wps_device_data {
|
|||
u8 num_sec_dev_types;
|
||||
u32 os_version;
|
||||
u8 rf_bands;
|
||||
struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
|
||||
|
||||
int p2p;
|
||||
};
|
||||
|
|
|
@ -199,6 +199,25 @@ int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg)
|
|||
}
|
||||
|
||||
|
||||
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
|
||||
if (dev->vendor_ext[i] == NULL)
|
||||
continue;
|
||||
wpa_hexdump(MSG_DEBUG, "WPS: * Vendor Extension",
|
||||
wpabuf_head_u8(dev->vendor_ext[i]),
|
||||
wpabuf_len(dev->vendor_ext[i]));
|
||||
wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
|
||||
wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext[i]));
|
||||
wpabuf_put_buf(msg, dev->vendor_ext[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int wps_process_manufacturer(struct wps_device_data *dev, const u8 *str,
|
||||
size_t str_len)
|
||||
{
|
||||
|
|
|
@ -36,5 +36,6 @@ int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
|
|||
void wps_device_data_dup(struct wps_device_data *dst,
|
||||
const struct wps_device_data *src);
|
||||
void wps_device_data_free(struct wps_device_data *dev);
|
||||
int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
|
||||
|
||||
#endif /* WPS_DEV_ATTR_H */
|
||||
|
|
|
@ -1113,14 +1113,23 @@ static int wps_set_ie(struct wps_registrar *reg)
|
|||
struct wpabuf *probe;
|
||||
const u8 *auth_macs;
|
||||
size_t count;
|
||||
size_t vendor_len = 0;
|
||||
int i;
|
||||
|
||||
if (reg->set_ie_cb == NULL)
|
||||
return 0;
|
||||
|
||||
beacon = wpabuf_alloc(400);
|
||||
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
|
||||
if (reg->wps->dev.vendor_ext[i]) {
|
||||
vendor_len += 2 + 2;
|
||||
vendor_len += wpabuf_len(reg->wps->dev.vendor_ext[i]);
|
||||
}
|
||||
}
|
||||
|
||||
beacon = wpabuf_alloc(400 + vendor_len);
|
||||
if (beacon == NULL)
|
||||
return -1;
|
||||
probe = wpabuf_alloc(500);
|
||||
probe = wpabuf_alloc(500 + vendor_len);
|
||||
if (probe == NULL) {
|
||||
wpabuf_free(beacon);
|
||||
return -1;
|
||||
|
@ -1138,7 +1147,8 @@ static int wps_set_ie(struct wps_registrar *reg)
|
|||
wps_build_sel_reg_config_methods(reg, beacon) ||
|
||||
wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
|
||||
(reg->dualband && wps_build_rf_bands(®->wps->dev, beacon)) ||
|
||||
wps_build_wfa_ext(beacon, 0, auth_macs, count)) {
|
||||
wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
|
||||
wps_build_vendor_ext(®->wps->dev, beacon)) {
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(probe);
|
||||
return -1;
|
||||
|
@ -1167,7 +1177,8 @@ static int wps_set_ie(struct wps_registrar *reg)
|
|||
wps_build_device_attrs(®->wps->dev, probe) ||
|
||||
wps_build_probe_config_methods(reg, probe) ||
|
||||
wps_build_rf_bands(®->wps->dev, probe) ||
|
||||
wps_build_wfa_ext(probe, 0, auth_macs, count)) {
|
||||
wps_build_wfa_ext(probe, 0, auth_macs, count) ||
|
||||
wps_build_vendor_ext(®->wps->dev, probe)) {
|
||||
wpabuf_free(beacon);
|
||||
wpabuf_free(probe);
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue