]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Add advertisement of Connection Capability
authorJay Katabathuni <jkatabat@qca.qualcomm.com>
Sat, 25 Aug 2012 13:12:40 +0000 (16:12 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 25 Aug 2012 16:16:09 +0000 (19:16 +0300)
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/gas_serv.c
src/ap/gas_serv.h

index 549bba9c4f0e418df1ecb54acd7aa365ca52bc63..8988bf9263fe184339208dd90514c9270ed711d9 100644 (file)
@@ -1408,6 +1408,42 @@ fail:
 #endif /* CONFIG_INTERWORKING */
 
 
+#ifdef CONFIG_HS20
+static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
+                                int line)
+{
+       u8 *conn_cap;
+       char *pos;
+
+       if (bss->hs20_connection_capability_len >= 0xfff0)
+               return -1;
+
+       conn_cap = os_realloc(bss->hs20_connection_capability,
+                             bss->hs20_connection_capability_len + 4);
+       if (conn_cap == NULL)
+               return -1;
+
+       bss->hs20_connection_capability = conn_cap;
+       conn_cap += bss->hs20_connection_capability_len;
+       pos = buf;
+       conn_cap[0] = atoi(pos);
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               return -1;
+       pos++;
+       WPA_PUT_LE16(conn_cap + 1, atoi(pos));
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               return -1;
+       pos++;
+       conn_cap[3] = atoi(pos);
+       bss->hs20_connection_capability_len += 4;
+
+       return 0;
+}
+#endif /* CONFIG_HS20 */
+
+
 #ifdef CONFIG_WPS_NFC
 static struct wpabuf * hostapd_parse_bin(const char *buf)
 {
@@ -2573,6 +2609,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        bss->hs20 = atoi(pos);
                } else if (os_strcmp(buf, "disable_dgaf") == 0) {
                        bss->disable_dgaf = atoi(pos);
+               } else if (os_strcmp(buf, "hs20_conn_capab") == 0) {
+                       if (hs20_parse_conn_capab(bss, pos, line) < 0) {
+                               errors++;
+                               return errors;
+                       }
                } else if (os_strcmp(buf, "hs20_operating_class") == 0) {
                        u8 *oper_class;
                        size_t oper_class_len;
index 04474ba9350a62071930117a4a865800ea37c49d..aa90d78bbb28517b0b8688e1182d0ab291efa8cb 100644 (file)
@@ -1400,6 +1400,19 @@ own_ip_addr=127.0.0.1
 # forging such frames to other stations in the BSS.
 #disable_dgaf=1
 
+# Connection Capability
+# This can be used to advertise what type of IP traffic can be sent through the
+# hotspot (e.g., due to firewall allowing/blocking protocols/ports).
+# format: <IP Protocol>:<Port Number>:<Status>
+# IP Protocol: 1 = ICMP, 6 = TCP, 17 = UDP
+# Port Number: 0..65535
+# Status: 0 = Closed, 1 = Open, 2 = Unknown
+# Each hs20_conn_capab line is added to the list of advertised tuples.
+#hs20_conn_capab=1:0:2
+#hs20_conn_capab=6:22:1
+#hs20_conn_capab=17:5060:0
+
+
 # Operating Class Indication
 # List of operating classes the BSSes in this ESS use. The Global operating
 # classes in Table E-4 of IEEE Std 802.11-2012 Annex E define the values that
index 8f6a6e844e8a1590a64758b0d2b5e9a7920f8c2a..c4aabdad4ce385bdcfc65c29941db589d70b109e 100644 (file)
@@ -507,6 +507,7 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 #endif /* CONFIG_RADIUS_TEST */
 
 #ifdef CONFIG_HS20
+       os_free(conf->hs20_connection_capability);
        os_free(conf->hs20_operating_class);
 #endif /* CONFIG_HS20 */
 }
index 221ebe2dfaf2f045709edfc1276101c0d9b44ef4..ebc1b95998c30c3b52b4479c594dc707aef64dc9 100644 (file)
@@ -410,6 +410,8 @@ struct hostapd_bss_config {
 #ifdef CONFIG_HS20
        int hs20;
        int disable_dgaf;
+       u8 *hs20_connection_capability;
+       size_t hs20_connection_capability_len;
        u8 *hs20_operating_class;
        u8 hs20_operating_class_len;
 #endif /* CONFIG_HS20 */
index c8bfa111fce53702eafaaf948fb46c44c51f54e8..f914eefefa083f846a038c7469330588357d18f7 100644 (file)
@@ -139,6 +139,8 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
        wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
        wpabuf_put_u8(buf, 0); /* Reserved */
        wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
+       if (hapd->conf->hs20_connection_capability)
+               wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
        if (hapd->conf->hs20_operating_class)
                wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
        gas_anqp_set_element_len(buf, len);
@@ -253,6 +255,22 @@ static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf)
 }
 
 
+static void anqp_add_connection_capability(struct hostapd_data *hapd,
+                                          struct wpabuf *buf)
+{
+       if (hapd->conf->hs20_connection_capability) {
+               u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
+               wpabuf_put_be24(buf, OUI_WFA);
+               wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
+               wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
+               wpabuf_put_u8(buf, 0); /* Reserved */
+               wpabuf_put_data(buf, hapd->conf->hs20_connection_capability,
+                               hapd->conf->hs20_connection_capability_len);
+               gas_anqp_set_element_len(buf, len);
+       }
+}
+
+
 static void anqp_add_operating_class(struct hostapd_data *hapd,
                                     struct wpabuf *buf)
 {
@@ -297,6 +315,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
 
        if (request & ANQP_REQ_HS_CAPABILITY_LIST)
                anqp_add_hs_capab_list(hapd, buf);
+       if (request & ANQP_REQ_CONNECTION_CAPABILITY)
+               anqp_add_connection_capability(hapd, buf);
        if (request & ANQP_REQ_OPERATING_CLASS)
                anqp_add_operating_class(hapd, buf);
 
@@ -410,6 +430,12 @@ static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
                set_anqp_req(ANQP_REQ_HS_CAPABILITY_LIST, "HS Capability List",
                             1, 0, 0, qi);
                break;
+       case HS20_STYPE_CONNECTION_CAPABILITY:
+               set_anqp_req(ANQP_REQ_CONNECTION_CAPABILITY,
+                            "Connection Capability",
+                            hapd->conf->hs20_connection_capability != NULL,
+                            0, 0, qi);
+               break;
        case HS20_STYPE_OPERATING_CLASS:
                set_anqp_req(ANQP_REQ_OPERATING_CLASS, "Operating Class",
                             hapd->conf->hs20_operating_class != NULL,
index 369daad48e123e0c36c731fd1e7c647479e83b46..e6e373995b0541821a4c313f5aa58779cbdc8191 100644 (file)
@@ -25,6 +25,8 @@
        (1 << (ANQP_DOMAIN_NAME - ANQP_QUERY_LIST))
 #define ANQP_REQ_HS_CAPABILITY_LIST \
        (0x10000 << HS20_STYPE_CAPABILITY_LIST)
+#define ANQP_REQ_CONNECTION_CAPABILITY \
+       (0x10000 << HS20_STYPE_CONNECTION_CAPABILITY)
 #define ANQP_REQ_OPERATING_CLASS \
        (0x10000 << HS20_STYPE_OPERATING_CLASS)