From 26fac8b6a0368dd5db3316250ef39660122f6bb7 Mon Sep 17 00:00:00 2001 From: Jay Katabathuni Date: Mon, 30 Jul 2012 21:55:46 +0300 Subject: [PATCH] Interworking: Add Domain Name element (AP) Signed-hostap: Jouni Malinen --- hostapd/config_file.c | 41 +++++++++++++++++++++++++++++++++++++++++ hostapd/hostapd.conf | 4 ++++ src/ap/ap_config.c | 1 + src/ap/ap_config.h | 4 ++++ src/ap/gas_serv.c | 20 ++++++++++++++++++++ src/ap/gas_serv.h | 2 ++ 6 files changed, 72 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index d4c7d2b03..42c1ccbcf 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2468,6 +2468,47 @@ static int hostapd_config_fill(struct hostapd_config *conf, return errors; } bss->ipaddr_type_configured = 1; + } else if (os_strcmp(buf, "domain_name") == 0) { + int j, num_domains, domain_len, domain_list_len = 0; + char *tok_start, *tok_prev; + u8 *domain_list, *domain_ptr; + + domain_list_len = os_strlen(pos) + 1; + domain_list = os_malloc(domain_list_len); + if (domain_list == NULL) { + errors++; + return errors; + } + + domain_ptr = domain_list; + tok_prev = pos; + num_domains = 1; + while ((tok_prev = os_strchr(tok_prev, ','))) { + num_domains++; + tok_prev++; + } + tok_prev = pos; + for (j = 0; j < num_domains; j++) { + tok_start = os_strchr(tok_prev, ','); + if (tok_start) { + domain_len = tok_start - tok_prev; + *domain_ptr = domain_len; + os_memcpy(domain_ptr + 1, tok_prev, + domain_len); + domain_ptr += domain_len + 1; + tok_prev = ++tok_start; + } else { + domain_len = os_strlen(tok_prev); + *domain_ptr = domain_len; + os_memcpy(domain_ptr + 1, tok_prev, + domain_len); + domain_ptr += domain_len + 1; + } + } + + os_free(bss->domain_name); + bss->domain_name = domain_list; + bss->domain_name_len = domain_list_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 5ed655c50..74f64d0e4 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1355,6 +1355,10 @@ own_ip_addr=127.0.0.1 # 2 = Availability of the address type not known #ipaddr_type_availability=14 +# Domain Name +# format: [,] +#domain_name=example.com,another.example.com,yet-another.example.com + ##### Hotspot 2.0 ############################################################# # Enable Hotspot 2.0 support diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 0c25ab0ec..f6038f9bd 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -499,6 +499,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); + os_free(conf->domain_name); #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 b02313ade..98c6f9539 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -399,6 +399,10 @@ struct hostapd_bss_config { u8 ipaddr_type_availability; u8 ipaddr_type_configured; + /* IEEE 802.11u - Domain Name */ + u8 *domain_name; + size_t domain_name_len; + u16 gas_comeback_delay; int gas_frag_limit; diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index e304b5240..00272d1d7 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -143,6 +143,8 @@ static void anqp_add_capab_list(struct hostapd_data *hapd, wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM); if (hapd->conf->ipaddr_type_configured) wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY); + if (hapd->conf->domain_name) + wpabuf_put_le16(buf, ANQP_DOMAIN_NAME); gas_anqp_set_element_len(buf, len); } @@ -207,6 +209,17 @@ static void anqp_add_ip_addr_type_availability(struct hostapd_data *hapd, } +static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf) +{ + if (hapd->conf->domain_name) { + wpabuf_put_le16(buf, ANQP_DOMAIN_NAME); + wpabuf_put_le16(buf, hapd->conf->domain_name_len); + wpabuf_put_data(buf, hapd->conf->domain_name, + hapd->conf->domain_name_len); + } +} + + static struct wpabuf * gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, unsigned int request, @@ -228,6 +241,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, anqp_add_roaming_consortium(hapd, buf); if (request & ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY) anqp_add_ip_addr_type_availability(hapd, buf); + if (request & ANQP_REQ_DOMAIN_NAME) + anqp_add_domain_name(hapd, buf); return buf; } @@ -297,6 +312,11 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id, "IP Addr Type Availability", hapd->conf->ipaddr_type_configured, 0, 0, qi); + case ANQP_DOMAIN_NAME: + set_anqp_req(ANQP_REQ_DOMAIN_NAME, "Domain Name", + hapd->conf->domain_name != NULL, + 0, 0, qi); + break; default: wpa_printf(MSG_DEBUG, "ANQP: Unsupported Info Id %u", info_id); diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h index e12b432dc..5ca6b8d57 100644 --- a/src/ap/gas_serv.h +++ b/src/ap/gas_serv.h @@ -19,6 +19,8 @@ (1 << (ANQP_ROAMING_CONSORTIUM - ANQP_QUERY_LIST)) #define ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY \ (1 << (ANQP_IP_ADDR_TYPE_AVAILABILITY - ANQP_QUERY_LIST)) +#define ANQP_REQ_DOMAIN_NAME \ + (1 << (ANQP_DOMAIN_NAME - ANQP_QUERY_LIST)) /* To account for latencies between hostapd and external ANQP processor */ #define GAS_SERV_COMEBACK_DELAY_FUDGE 10