diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 117f56b3c..f67535ea1 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2429,6 +2429,34 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "venue_name") == 0) { if (parse_venue_name(bss, pos, line) < 0) errors++; + } else if (os_strcmp(buf, "network_auth_type") == 0) { + u8 auth_type; + u16 redirect_url_len; + if (hexstr2bin(pos, &auth_type, 1)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid " + "network_auth_type '%s'", + line, pos); + errors++; + return errors; + } + if (auth_type == 0 || auth_type == 2) + redirect_url_len = os_strlen(pos + 2); + else + redirect_url_len = 0; + os_free(bss->network_auth_type); + bss->network_auth_type = + os_malloc(redirect_url_len + 3 + 1); + if (bss->network_auth_type == NULL) { + errors++; + return errors; + } + *bss->network_auth_type = auth_type; + WPA_PUT_LE16(bss->network_auth_type + 1, + redirect_url_len); + if (redirect_url_len) + os_memcpy(bss->network_auth_type + 3, + pos + 2, redirect_url_len); + bss->network_auth_type_len = 3 + redirect_url_len; } else if (os_strcmp(buf, "gas_frag_limit") == 0) { bss->gas_frag_limit = atoi(pos); } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 6ab3f127d..78287bb00 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1325,6 +1325,18 @@ own_ip_addr=127.0.0.1 #venue_name=eng:Example venue #venue_name=fin:Esimerkkipaikka +# Network Authentication Type +# This parameter indicates what type of network authentication is used in the +# network. +# format: [redirect URL] +# Network Authentication Type Indicator values: +# 00 = Acceptance of terms and conditions +# 01 = On-line enrollment supported +# 02 = http/https redirection +# 03 = DNS redirection +#network_auth_type=00 +#network_auth_type=02http://www.example.com/redirect/me/here/ + ##### Hotspot 2.0 ############################################################# # Enable Hotspot 2.0 support diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 2c633d9f5..0c25ab0ec 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -498,6 +498,7 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf) os_free(conf->roaming_consortium); os_free(conf->venue_name); + os_free(conf->network_auth_type); #ifdef CONFIG_RADIUS_TEST os_free(conf->dump_msk_file); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index caf01531f..c23fb77cf 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -391,6 +391,10 @@ struct hostapd_bss_config { unsigned int venue_name_count; struct hostapd_venue_name *venue_name; + /* IEEE 802.11u - Network Authentication Type */ + u8 *network_auth_type; + size_t network_auth_type_len; + u16 gas_comeback_delay; int gas_frag_limit; diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index 2177b02a3..7bfe8188f 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -137,6 +137,8 @@ static void anqp_add_capab_list(struct hostapd_data *hapd, wpabuf_put_le16(buf, ANQP_CAPABILITY_LIST); if (hapd->conf->venue_name) wpabuf_put_le16(buf, ANQP_VENUE_NAME); + if (hapd->conf->network_auth_type) + wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE); if (hapd->conf->roaming_consortium) wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM); gas_anqp_set_element_len(buf, len); @@ -163,6 +165,18 @@ static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf) } +static void anqp_add_network_auth_type(struct hostapd_data *hapd, + struct wpabuf *buf) +{ + if (hapd->conf->network_auth_type) { + wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE); + wpabuf_put_le16(buf, hapd->conf->network_auth_type_len); + wpabuf_put_data(buf, hapd->conf->network_auth_type, + hapd->conf->network_auth_type_len); + } +} + + static void anqp_add_roaming_consortium(struct hostapd_data *hapd, struct wpabuf *buf) { @@ -195,6 +209,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, anqp_add_capab_list(hapd, buf); if (request & ANQP_REQ_VENUE_NAME) anqp_add_venue_name(hapd, buf); + if (request & ANQP_REQ_NETWORK_AUTH_TYPE) + anqp_add_network_auth_type(hapd, buf); if (request & ANQP_REQ_ROAMING_CONSORTIUM) anqp_add_roaming_consortium(hapd, buf); @@ -252,6 +268,11 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id, set_anqp_req(ANQP_REQ_VENUE_NAME, "Venue Name", hapd->conf->venue_name != NULL, 0, 0, qi); break; + case ANQP_NETWORK_AUTH_TYPE: + set_anqp_req(ANQP_REQ_NETWORK_AUTH_TYPE, "Network Auth Type", + hapd->conf->network_auth_type != NULL, + 0, 0, qi); + break; case ANQP_ROAMING_CONSORTIUM: set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium", hapd->conf->roaming_consortium != NULL, 0, 0, qi); diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h index 0e2eaf66d..d445b53a8 100644 --- a/src/ap/gas_serv.h +++ b/src/ap/gas_serv.h @@ -13,6 +13,8 @@ (1 << (ANQP_CAPABILITY_LIST - ANQP_QUERY_LIST)) #define ANQP_REQ_VENUE_NAME \ (1 << (ANQP_VENUE_NAME - ANQP_QUERY_LIST)) +#define ANQP_REQ_NETWORK_AUTH_TYPE \ + (1 << (ANQP_NETWORK_AUTH_TYPE - ANQP_QUERY_LIST)) #define ANQP_REQ_ROAMING_CONSORTIUM \ (1 << (ANQP_ROAMING_CONSORTIUM - ANQP_QUERY_LIST))