LCOV - code coverage report
Current view: top level - src/common - gas.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 83 93 89.2 %
Date: 2014-03-02 Functions: 15 15 100.0 %
Branches: 24 38 63.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Generic advertisement service (GAS) (IEEE 802.11u)
       3                 :            :  * Copyright (c) 2009, Atheros Communications
       4                 :            :  * Copyright (c) 2011-2012, Qualcomm Atheros
       5                 :            :  *
       6                 :            :  * This software may be distributed under the terms of the BSD license.
       7                 :            :  * See README for more details.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include "includes.h"
      11                 :            : 
      12                 :            : #include "common.h"
      13                 :            : #include "ieee802_11_defs.h"
      14                 :            : #include "gas.h"
      15                 :            : 
      16                 :            : 
      17                 :            : static struct wpabuf *
      18                 :        381 : gas_build_req(u8 action, u8 dialog_token, size_t size)
      19                 :            : {
      20                 :            :         struct wpabuf *buf;
      21                 :            : 
      22                 :        381 :         buf = wpabuf_alloc(100 + size);
      23         [ -  + ]:        381 :         if (buf == NULL)
      24                 :          0 :                 return NULL;
      25                 :            : 
      26                 :        381 :         wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
      27                 :        381 :         wpabuf_put_u8(buf, action);
      28                 :        381 :         wpabuf_put_u8(buf, dialog_token);
      29                 :            : 
      30                 :        381 :         return buf;
      31                 :            : }
      32                 :            : 
      33                 :            : 
      34                 :        197 : struct wpabuf * gas_build_initial_req(u8 dialog_token, size_t size)
      35                 :            : {
      36                 :        197 :         return gas_build_req(WLAN_PA_GAS_INITIAL_REQ, dialog_token,
      37                 :            :                              size);
      38                 :            : }
      39                 :            : 
      40                 :            : 
      41                 :        184 : struct wpabuf * gas_build_comeback_req(u8 dialog_token)
      42                 :            : {
      43                 :        184 :         return gas_build_req(WLAN_PA_GAS_COMEBACK_REQ, dialog_token, 0);
      44                 :            : }
      45                 :            : 
      46                 :            : 
      47                 :            : static struct wpabuf *
      48                 :        226 : gas_build_resp(u8 action, u8 dialog_token, u16 status_code, u8 frag_id,
      49                 :            :                u8 more, u16 comeback_delay, size_t size)
      50                 :            : {
      51                 :            :         struct wpabuf *buf;
      52                 :            : 
      53                 :        226 :         buf = wpabuf_alloc(100 + size);
      54         [ -  + ]:        226 :         if (buf == NULL)
      55                 :          0 :                 return NULL;
      56                 :            : 
      57                 :        226 :         wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
      58                 :        226 :         wpabuf_put_u8(buf, action);
      59                 :        226 :         wpabuf_put_u8(buf, dialog_token);
      60                 :        226 :         wpabuf_put_le16(buf, status_code);
      61         [ +  + ]:        226 :         if (action == WLAN_PA_GAS_COMEBACK_RESP)
      62         [ +  + ]:         43 :                 wpabuf_put_u8(buf, frag_id | (more ? 0x80 : 0));
      63                 :        226 :         wpabuf_put_le16(buf, comeback_delay);
      64                 :            : 
      65                 :        226 :         return buf;
      66                 :            : }
      67                 :            : 
      68                 :            : 
      69                 :            : struct wpabuf *
      70                 :        183 : gas_build_initial_resp(u8 dialog_token, u16 status_code, u16 comeback_delay,
      71                 :            :                        size_t size)
      72                 :            : {
      73                 :        183 :         return gas_build_resp(WLAN_PA_GAS_INITIAL_RESP, dialog_token,
      74                 :            :                               status_code, 0, 0, comeback_delay, size);
      75                 :            : }
      76                 :            : 
      77                 :            : 
      78                 :            : static struct wpabuf *
      79                 :         43 : gas_build_comeback_resp(u8 dialog_token, u16 status_code, u8 frag_id, u8 more,
      80                 :            :                         u16 comeback_delay, size_t size)
      81                 :            : {
      82                 :         43 :         return gas_build_resp(WLAN_PA_GAS_COMEBACK_RESP, dialog_token,
      83                 :            :                               status_code, frag_id, more, comeback_delay,
      84                 :            :                               size);
      85                 :            : }
      86                 :            : 
      87                 :            : 
      88                 :            : /**
      89                 :            :  * gas_add_adv_proto_anqp - Add an Advertisement Protocol element
      90                 :            :  * @buf: Buffer to which the element is added
      91                 :            :  * @query_resp_len_limit: Query Response Length Limit in units of 256 octets
      92                 :            :  * @pame_bi: Pre-Association Message Exchange BSSID Independent (0/1)
      93                 :            :  *
      94                 :            :  *
      95                 :            :  * @query_resp_len_limit is 0 for request and 1-0x7f for response. 0x7f means
      96                 :            :  * that the maximum limit is determined by the maximum allowable number of
      97                 :            :  * fragments in the GAS Query Response Fragment ID.
      98                 :            :  */
      99                 :        416 : static void gas_add_adv_proto_anqp(struct wpabuf *buf, u8 query_resp_len_limit,
     100                 :            :                                    u8 pame_bi)
     101                 :            : {
     102                 :            :         /* Advertisement Protocol IE */
     103                 :        416 :         wpabuf_put_u8(buf, WLAN_EID_ADV_PROTO);
     104                 :        416 :         wpabuf_put_u8(buf, 2); /* Length */
     105         [ -  + ]:        416 :         wpabuf_put_u8(buf, (query_resp_len_limit & 0x7f) |
     106                 :            :                       (pame_bi ? 0x80 : 0));
     107                 :            :         /* Advertisement Protocol */
     108                 :        416 :         wpabuf_put_u8(buf, ACCESS_NETWORK_QUERY_PROTOCOL);
     109                 :        416 : }
     110                 :            : 
     111                 :            : 
     112                 :        190 : struct wpabuf * gas_anqp_build_initial_req(u8 dialog_token, size_t size)
     113                 :            : {
     114                 :            :         struct wpabuf *buf;
     115                 :            : 
     116                 :        190 :         buf = gas_build_initial_req(dialog_token, 4 + size);
     117         [ -  + ]:        190 :         if (buf == NULL)
     118                 :          0 :                 return NULL;
     119                 :            : 
     120                 :        190 :         gas_add_adv_proto_anqp(buf, 0, 0);
     121                 :            : 
     122                 :        190 :         wpabuf_put(buf, 2); /* Query Request Length to be filled */
     123                 :            : 
     124                 :        190 :         return buf;
     125                 :            : }
     126                 :            : 
     127                 :            : 
     128                 :        183 : struct wpabuf * gas_anqp_build_initial_resp(u8 dialog_token, u16 status_code,
     129                 :            :                                             u16 comeback_delay, size_t size)
     130                 :            : {
     131                 :            :         struct wpabuf *buf;
     132                 :            : 
     133                 :        183 :         buf = gas_build_initial_resp(dialog_token, status_code, comeback_delay,
     134                 :            :                                      4 + size);
     135         [ -  + ]:        183 :         if (buf == NULL)
     136                 :          0 :                 return NULL;
     137                 :            : 
     138                 :        183 :         gas_add_adv_proto_anqp(buf, 0x7f, 0);
     139                 :            : 
     140                 :        183 :         wpabuf_put(buf, 2); /* Query Response Length to be filled */
     141                 :            : 
     142                 :        183 :         return buf;
     143                 :            : }
     144                 :            : 
     145                 :            : 
     146                 :        161 : struct wpabuf * gas_anqp_build_initial_resp_buf(u8 dialog_token,
     147                 :            :                                                 u16 status_code,
     148                 :            :                                                 u16 comeback_delay,
     149                 :            :                                                 struct wpabuf *payload)
     150                 :            : {
     151                 :            :         struct wpabuf *buf;
     152                 :            : 
     153         [ +  + ]:        161 :         buf = gas_anqp_build_initial_resp(dialog_token, status_code,
     154                 :            :                                           comeback_delay,
     155                 :            :                                           payload ? wpabuf_len(payload) : 0);
     156         [ -  + ]:        161 :         if (buf == NULL)
     157                 :          0 :                 return NULL;
     158                 :            : 
     159         [ +  + ]:        161 :         if (payload)
     160                 :        155 :                 wpabuf_put_buf(buf, payload);
     161                 :            : 
     162                 :        161 :         gas_anqp_set_len(buf);
     163                 :            : 
     164                 :        161 :         return buf;
     165                 :            : }
     166                 :            : 
     167                 :            : 
     168                 :         43 : struct wpabuf * gas_anqp_build_comeback_resp(u8 dialog_token, u16 status_code,
     169                 :            :                                              u8 frag_id, u8 more,
     170                 :            :                                              u16 comeback_delay, size_t size)
     171                 :            : {
     172                 :            :         struct wpabuf *buf;
     173                 :            : 
     174                 :         43 :         buf = gas_build_comeback_resp(dialog_token, status_code,
     175                 :            :                                       frag_id, more, comeback_delay, 4 + size);
     176         [ -  + ]:         43 :         if (buf == NULL)
     177                 :          0 :                 return NULL;
     178                 :            : 
     179                 :         43 :         gas_add_adv_proto_anqp(buf, 0x7f, 0);
     180                 :            : 
     181                 :         43 :         wpabuf_put(buf, 2); /* Query Response Length to be filled */
     182                 :            : 
     183                 :         43 :         return buf;
     184                 :            : }
     185                 :            : 
     186                 :            : 
     187                 :         30 : struct wpabuf * gas_anqp_build_comeback_resp_buf(u8 dialog_token,
     188                 :            :                                                  u16 status_code,
     189                 :            :                                                  u8 frag_id, u8 more,
     190                 :            :                                                  u16 comeback_delay,
     191                 :            :                                                  struct wpabuf *payload)
     192                 :            : {
     193                 :            :         struct wpabuf *buf;
     194                 :            : 
     195         [ +  - ]:         30 :         buf = gas_anqp_build_comeback_resp(dialog_token, status_code, frag_id,
     196                 :            :                                            more, comeback_delay,
     197                 :            :                                            payload ? wpabuf_len(payload) : 0);
     198         [ -  + ]:         30 :         if (buf == NULL)
     199                 :          0 :                 return NULL;
     200                 :            : 
     201         [ +  - ]:         30 :         if (payload)
     202                 :         30 :                 wpabuf_put_buf(buf, payload);
     203                 :            : 
     204                 :         30 :         gas_anqp_set_len(buf);
     205                 :            : 
     206                 :         30 :         return buf;
     207                 :            : }
     208                 :            : 
     209                 :            : 
     210                 :            : /**
     211                 :            :  * gas_anqp_set_len - Set Query Request/Response Length
     212                 :            :  * @buf: GAS message
     213                 :            :  *
     214                 :            :  * This function is used to update the Query Request/Response Length field once
     215                 :            :  * the payload has been filled.
     216                 :            :  */
     217                 :        416 : void gas_anqp_set_len(struct wpabuf *buf)
     218                 :            : {
     219                 :            :         u8 action;
     220                 :            :         size_t offset;
     221                 :            :         u8 *len;
     222                 :            : 
     223 [ +  - ][ -  + ]:        416 :         if (buf == NULL || wpabuf_len(buf) < 2)
     224                 :          0 :                 return;
     225                 :            : 
     226                 :        416 :         action = *(wpabuf_head_u8(buf) + 1);
     227   [ +  +  +  - ]:        416 :         switch (action) {
     228                 :            :         case WLAN_PA_GAS_INITIAL_REQ:
     229                 :        190 :                 offset = 3 + 4;
     230                 :        190 :                 break;
     231                 :            :         case WLAN_PA_GAS_INITIAL_RESP:
     232                 :        183 :                 offset = 7 + 4;
     233                 :        183 :                 break;
     234                 :            :         case WLAN_PA_GAS_COMEBACK_RESP:
     235                 :         43 :                 offset = 8 + 4;
     236                 :         43 :                 break;
     237                 :            :         default:
     238                 :          0 :                 return;
     239                 :            :         }
     240                 :            : 
     241         [ -  + ]:        416 :         if (wpabuf_len(buf) < offset + 2)
     242                 :          0 :                 return;
     243                 :            : 
     244                 :        416 :         len = wpabuf_mhead_u8(buf) + offset;
     245                 :        416 :         WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
     246                 :            : }
     247                 :            : 
     248                 :            : 
     249                 :            : /**
     250                 :            :  * gas_anqp_add_element - Add ANQP element header
     251                 :            :  * @buf: GAS message
     252                 :            :  * @info_id: ANQP Info ID
     253                 :            :  * Returns: Pointer to the Length field for gas_anqp_set_element_len()
     254                 :            :  */
     255                 :       1025 : u8 * gas_anqp_add_element(struct wpabuf *buf, u16 info_id)
     256                 :            : {
     257                 :       1025 :         wpabuf_put_le16(buf, info_id);
     258                 :       1025 :         return wpabuf_put(buf, 2); /* Length to be filled */
     259                 :            : }
     260                 :            : 
     261                 :            : 
     262                 :            : /**
     263                 :            :  * gas_anqp_set_element_len - Update ANQP element Length field
     264                 :            :  * @buf: GAS message
     265                 :            :  * @len_pos: Length field position from gas_anqp_add_element()
     266                 :            :  *
     267                 :            :  * This function is called after the ANQP element payload has been added to the
     268                 :            :  * buffer.
     269                 :            :  */
     270                 :       1264 : void gas_anqp_set_element_len(struct wpabuf *buf, u8 *len_pos)
     271                 :            : {
     272                 :       1264 :         WPA_PUT_LE16(len_pos, (u8 *) wpabuf_put(buf, 0) - len_pos - 2);
     273                 :       1264 : }

Generated by: LCOV version 1.9