LCOV - code coverage report
Current view: top level - wpa_supplicant - hs20_supplicant.c (source / functions) Hit Total Coverage
Test: wpa_supplicant hwsim test run 1388338050 Lines: 66 117 56.4 %
Date: 2013-12-29 Functions: 3 5 60.0 %
Branches: 19 54 35.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, Atheros Communications, Inc.
       3                 :            :  * Copyright (c) 2011-2012, Qualcomm Atheros, Inc.
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "includes.h"
      10                 :            : 
      11                 :            : #include "common.h"
      12                 :            : #include "eloop.h"
      13                 :            : #include "common/ieee802_11_common.h"
      14                 :            : #include "common/ieee802_11_defs.h"
      15                 :            : #include "common/gas.h"
      16                 :            : #include "common/wpa_ctrl.h"
      17                 :            : #include "wpa_supplicant_i.h"
      18                 :            : #include "driver_i.h"
      19                 :            : #include "config.h"
      20                 :            : #include "bss.h"
      21                 :            : #include "gas_query.h"
      22                 :            : #include "interworking.h"
      23                 :            : #include "hs20_supplicant.h"
      24                 :            : 
      25                 :            : 
      26                 :        116 : void wpas_hs20_add_indication(struct wpabuf *buf)
      27                 :            : {
      28                 :        116 :         wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
      29                 :        116 :         wpabuf_put_u8(buf, 5);
      30                 :        116 :         wpabuf_put_be24(buf, OUI_WFA);
      31                 :        116 :         wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE);
      32                 :        116 :         wpabuf_put_u8(buf, 0x00); /* Hotspot Configuration */
      33                 :        116 : }
      34                 :            : 
      35                 :            : 
      36                 :        431 : int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
      37                 :            :                     struct wpa_bss *bss)
      38                 :            : {
      39 [ +  + ][ -  + ]:        431 :         if (!wpa_s->conf->hs20 || !ssid)
      40                 :        343 :                 return 0;
      41                 :            : 
      42         [ +  + ]:         88 :         if (ssid->parent_cred)
      43                 :         27 :                 return 1;
      44                 :            : 
      45 [ +  - ][ +  - ]:         61 :         if (bss && !wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE))
      46                 :         61 :                 return 0;
      47                 :            : 
      48                 :            :         /*
      49                 :            :          * This may catch some non-Hotspot 2.0 cases, but it is safer to do that
      50                 :            :          * than cause Hotspot 2.0 connections without indication element getting
      51                 :            :          * added. Non-Hotspot 2.0 APs should ignore the unknown vendor element.
      52                 :            :          */
      53                 :            : 
      54         [ #  # ]:          0 :         if (!(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X))
      55                 :          0 :                 return 0;
      56         [ #  # ]:          0 :         if (!(ssid->pairwise_cipher & WPA_CIPHER_CCMP))
      57                 :          0 :                 return 0;
      58         [ #  # ]:          0 :         if (ssid->proto != WPA_PROTO_RSN)
      59                 :          0 :                 return 0;
      60                 :            : 
      61                 :        431 :         return 1;
      62                 :            : }
      63                 :            : 
      64                 :            : 
      65                 :          0 : struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
      66                 :            :                                     size_t payload_len)
      67                 :            : {
      68                 :            :         struct wpabuf *buf;
      69                 :            :         u8 *len_pos;
      70                 :            : 
      71                 :          0 :         buf = gas_anqp_build_initial_req(0, 100 + payload_len);
      72         [ #  # ]:          0 :         if (buf == NULL)
      73                 :          0 :                 return NULL;
      74                 :            : 
      75                 :          0 :         len_pos = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
      76                 :          0 :         wpabuf_put_be24(buf, OUI_WFA);
      77                 :          0 :         wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
      78         [ #  # ]:          0 :         if (stypes == BIT(HS20_STYPE_NAI_HOME_REALM_QUERY)) {
      79                 :          0 :                 wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY);
      80                 :          0 :                 wpabuf_put_u8(buf, 0); /* Reserved */
      81         [ #  # ]:          0 :                 if (payload)
      82                 :          0 :                         wpabuf_put_data(buf, payload, payload_len);
      83                 :            :         } else {
      84                 :            :                 u8 i;
      85                 :          0 :                 wpabuf_put_u8(buf, HS20_STYPE_QUERY_LIST);
      86                 :          0 :                 wpabuf_put_u8(buf, 0); /* Reserved */
      87         [ #  # ]:          0 :                 for (i = 0; i < 32; i++) {
      88         [ #  # ]:          0 :                         if (stypes & BIT(i))
      89                 :          0 :                                 wpabuf_put_u8(buf, i);
      90                 :            :                 }
      91                 :            :         }
      92                 :          0 :         gas_anqp_set_element_len(buf, len_pos);
      93                 :            : 
      94                 :          0 :         gas_anqp_set_len(buf);
      95                 :            : 
      96                 :          0 :         return buf;
      97                 :            : }
      98                 :            : 
      99                 :            : 
     100                 :          0 : int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
     101                 :            :                        const u8 *payload, size_t payload_len)
     102                 :            : {
     103                 :            :         struct wpabuf *buf;
     104                 :          0 :         int ret = 0;
     105                 :            :         int freq;
     106                 :            :         struct wpa_bss *bss;
     107                 :            :         int res;
     108                 :            : 
     109                 :          0 :         freq = wpa_s->assoc_freq;
     110                 :          0 :         bss = wpa_bss_get_bssid(wpa_s, dst);
     111         [ #  # ]:          0 :         if (bss) {
     112                 :          0 :                 wpa_bss_anqp_unshare_alloc(bss);
     113                 :          0 :                 freq = bss->freq;
     114                 :            :         }
     115         [ #  # ]:          0 :         if (freq <= 0)
     116                 :          0 :                 return -1;
     117                 :            : 
     118                 :          0 :         wpa_printf(MSG_DEBUG, "HS20: ANQP Query Request to " MACSTR " for "
     119                 :          0 :                    "subtypes 0x%x", MAC2STR(dst), stypes);
     120                 :            : 
     121                 :          0 :         buf = hs20_build_anqp_req(stypes, payload, payload_len);
     122         [ #  # ]:          0 :         if (buf == NULL)
     123                 :          0 :                 return -1;
     124                 :            : 
     125                 :          0 :         res = gas_query_req(wpa_s->gas, dst, freq, buf, anqp_resp_cb, wpa_s);
     126         [ #  # ]:          0 :         if (res < 0) {
     127                 :          0 :                 wpa_printf(MSG_DEBUG, "ANQP: Failed to send Query Request");
     128                 :          0 :                 wpabuf_free(buf);
     129                 :          0 :                 ret = -1;
     130                 :            :         } else
     131                 :          0 :                 wpa_printf(MSG_DEBUG, "ANQP: Query started with dialog token "
     132                 :            :                            "%u", res);
     133                 :            : 
     134                 :          0 :         return ret;
     135                 :            : }
     136                 :            : 
     137                 :            : 
     138                 :         55 : void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
     139                 :            :                                   const u8 *sa, const u8 *data, size_t slen)
     140                 :            : {
     141                 :         55 :         const u8 *pos = data;
     142                 :            :         u8 subtype;
     143                 :         55 :         struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
     144                 :         55 :         struct wpa_bss_anqp *anqp = NULL;
     145                 :            : 
     146         [ -  + ]:         55 :         if (slen < 2)
     147                 :         55 :                 return;
     148                 :            : 
     149         [ +  - ]:         55 :         if (bss)
     150                 :         55 :                 anqp = bss->anqp;
     151                 :            : 
     152                 :         55 :         subtype = *pos++;
     153                 :         55 :         slen--;
     154                 :            : 
     155                 :         55 :         pos++; /* Reserved */
     156                 :         55 :         slen--;
     157                 :            : 
     158   [ +  +  +  +  :         55 :         switch (subtype) {
                   +  - ]
     159                 :            :         case HS20_STYPE_CAPABILITY_LIST:
     160                 :         41 :                 wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
     161                 :        246 :                         " HS Capability List", MAC2STR(sa));
     162                 :         41 :                 wpa_hexdump_ascii(MSG_DEBUG, "HS Capability List", pos, slen);
     163                 :         41 :                 break;
     164                 :            :         case HS20_STYPE_OPERATOR_FRIENDLY_NAME:
     165                 :          2 :                 wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
     166                 :         12 :                         " Operator Friendly Name", MAC2STR(sa));
     167                 :          2 :                 wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen);
     168         [ +  - ]:          2 :                 if (anqp) {
     169                 :          2 :                         wpabuf_free(anqp->hs20_operator_friendly_name);
     170                 :          2 :                         anqp->hs20_operator_friendly_name =
     171                 :          2 :                                 wpabuf_alloc_copy(pos, slen);
     172                 :            :                 }
     173                 :          2 :                 break;
     174                 :            :         case HS20_STYPE_WAN_METRICS:
     175                 :          4 :                 wpa_hexdump(MSG_DEBUG, "WAN Metrics", pos, slen);
     176         [ -  + ]:          4 :                 if (slen < 13) {
     177                 :          0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short WAN "
     178                 :            :                                 "Metrics value from " MACSTR, MAC2STR(sa));
     179                 :          0 :                         break;
     180                 :            :                 }
     181                 :          4 :                 wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
     182                 :         24 :                         " WAN Metrics %02x:%u:%u:%u:%u:%u", MAC2STR(sa),
     183                 :          4 :                         pos[0], WPA_GET_LE32(pos + 1), WPA_GET_LE32(pos + 5),
     184                 :          4 :                         pos[9], pos[10], WPA_GET_LE16(pos + 11));
     185         [ +  - ]:          4 :                 if (anqp) {
     186                 :          4 :                         wpabuf_free(anqp->hs20_wan_metrics);
     187                 :          4 :                         anqp->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen);
     188                 :            :                 }
     189                 :          4 :                 break;
     190                 :            :         case HS20_STYPE_CONNECTION_CAPABILITY:
     191                 :          4 :                 wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
     192                 :         24 :                         " Connection Capability", MAC2STR(sa));
     193                 :          4 :                 wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen);
     194         [ +  - ]:          4 :                 if (anqp) {
     195                 :          4 :                         wpabuf_free(anqp->hs20_connection_capability);
     196                 :          4 :                         anqp->hs20_connection_capability =
     197                 :          4 :                                 wpabuf_alloc_copy(pos, slen);
     198                 :            :                 }
     199                 :          4 :                 break;
     200                 :            :         case HS20_STYPE_OPERATING_CLASS:
     201                 :          4 :                 wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
     202                 :         24 :                         " Operating Class", MAC2STR(sa));
     203                 :          4 :                 wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen);
     204         [ +  - ]:          4 :                 if (anqp) {
     205                 :          4 :                         wpabuf_free(anqp->hs20_operating_class);
     206                 :          4 :                         anqp->hs20_operating_class =
     207                 :          4 :                                 wpabuf_alloc_copy(pos, slen);
     208                 :            :                 }
     209                 :          4 :                 break;
     210                 :            :         default:
     211                 :          0 :                 wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype);
     212                 :          0 :                 break;
     213                 :            :         }
     214                 :            : }

Generated by: LCOV version 1.9