LCOV - code coverage report
Current view: top level - src/ap - accounting.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1393793999 Lines: 121 207 58.5 %
Date: 2014-03-02 Functions: 10 12 83.3 %
Branches: 61 124 49.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * hostapd / RADIUS Accounting
       3                 :            :  * Copyright (c) 2002-2009, 2012, Jouni Malinen <j@w1.fi>
       4                 :            :  *
       5                 :            :  * This software may be distributed under the terms of the BSD license.
       6                 :            :  * See README for more details.
       7                 :            :  */
       8                 :            : 
       9                 :            : #include "utils/includes.h"
      10                 :            : 
      11                 :            : #include "utils/common.h"
      12                 :            : #include "utils/eloop.h"
      13                 :            : #include "radius/radius.h"
      14                 :            : #include "radius/radius_client.h"
      15                 :            : #include "hostapd.h"
      16                 :            : #include "ieee802_1x.h"
      17                 :            : #include "ap_config.h"
      18                 :            : #include "sta_info.h"
      19                 :            : #include "ap_drv_ops.h"
      20                 :            : #include "accounting.h"
      21                 :            : 
      22                 :            : 
      23                 :            : /* Default interval in seconds for polling TX/RX octets from the driver if
      24                 :            :  * STA is not using interim accounting. This detects wrap arounds for
      25                 :            :  * input/output octets and updates Acct-{Input,Output}-Gigawords. */
      26                 :            : #define ACCT_DEFAULT_UPDATE_INTERVAL 300
      27                 :            : 
      28                 :            : static void accounting_sta_interim(struct hostapd_data *hapd,
      29                 :            :                                    struct sta_info *sta);
      30                 :            : 
      31                 :            : 
      32                 :         12 : static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
      33                 :            :                                           struct sta_info *sta,
      34                 :            :                                           int status_type)
      35                 :            : {
      36                 :            :         struct radius_msg *msg;
      37                 :            :         char buf[128];
      38                 :            :         u8 *val;
      39                 :            :         size_t len;
      40                 :            :         int i;
      41                 :            :         struct wpabuf *b;
      42                 :            : 
      43                 :         12 :         msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
      44                 :         12 :                              radius_client_get_id(hapd->radius));
      45         [ -  + ]:         12 :         if (msg == NULL) {
      46                 :          0 :                 wpa_printf(MSG_INFO, "Could not create new RADIUS packet");
      47                 :          0 :                 return NULL;
      48                 :            :         }
      49                 :            : 
      50         [ +  + ]:         12 :         if (sta) {
      51                 :          6 :                 radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta));
      52                 :            : 
      53                 :          6 :                 os_snprintf(buf, sizeof(buf), "%08X-%08X",
      54                 :            :                             sta->acct_session_id_hi, sta->acct_session_id_lo);
      55         [ -  + ]:          6 :                 if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
      56                 :            :                                          (u8 *) buf, os_strlen(buf))) {
      57                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Session-Id");
      58                 :          0 :                         goto fail;
      59                 :            :                 }
      60                 :            :         } else {
      61                 :          6 :                 radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd));
      62                 :            :         }
      63                 :            : 
      64         [ -  + ]:         12 :         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
      65                 :            :                                        status_type)) {
      66                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Acct-Status-Type");
      67                 :          0 :                 goto fail;
      68                 :            :         }
      69                 :            : 
      70         [ +  - ]:         12 :         if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
      71         [ -  + ]:         12 :                                             RADIUS_ATTR_ACCT_AUTHENTIC) &&
      72         [ +  - ]:         12 :             !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
      73                 :         12 :                                        hapd->conf->ieee802_1x ?
      74                 :            :                                        RADIUS_ACCT_AUTHENTIC_RADIUS :
      75                 :            :                                        RADIUS_ACCT_AUTHENTIC_LOCAL)) {
      76                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Acct-Authentic");
      77                 :          0 :                 goto fail;
      78                 :            :         }
      79                 :            : 
      80         [ +  + ]:         12 :         if (sta) {
      81                 :            :                 /* Use 802.1X identity if available */
      82                 :          6 :                 val = ieee802_1x_get_identity(sta->eapol_sm, &len);
      83                 :            : 
      84                 :            :                 /* Use RADIUS ACL identity if 802.1X provides no identity */
      85 [ #  # ][ -  + ]:          6 :                 if (!val && sta->identity) {
      86                 :          0 :                         val = (u8 *) sta->identity;
      87                 :          0 :                         len = os_strlen(sta->identity);
      88                 :            :                 }
      89                 :            : 
      90                 :            :                 /* Use STA MAC if neither 802.1X nor RADIUS ACL provided
      91                 :            :                  * identity */
      92         [ -  + ]:          6 :                 if (!val) {
      93                 :          0 :                         os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
      94                 :          0 :                                     MAC2STR(sta->addr));
      95                 :          0 :                         val = (u8 *) buf;
      96                 :          0 :                         len = os_strlen(buf);
      97                 :            :                 }
      98                 :            : 
      99         [ -  + ]:          6 :                 if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val,
     100                 :            :                                          len)) {
     101                 :          0 :                         wpa_printf(MSG_INFO, "Could not add User-Name");
     102                 :          0 :                         goto fail;
     103                 :            :                 }
     104                 :            :         }
     105                 :            : 
     106         [ -  + ]:         12 :         if (add_common_radius_attr(hapd, hapd->conf->radius_acct_req_attr, sta,
     107                 :            :                                    msg) < 0)
     108                 :          0 :                 goto fail;
     109                 :            : 
     110         [ +  + ]:         12 :         if (sta) {
     111                 :          6 :                 for (i = 0; ; i++) {
     112                 :          6 :                         val = ieee802_1x_get_radius_class(sta->eapol_sm, &len,
     113                 :            :                                                           i);
     114         [ +  - ]:          6 :                         if (val == NULL)
     115                 :          6 :                                 break;
     116                 :            : 
     117         [ #  # ]:          0 :                         if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS,
     118                 :            :                                                  val, len)) {
     119                 :          0 :                                 wpa_printf(MSG_INFO, "Could not add Class");
     120                 :          0 :                                 goto fail;
     121                 :            :                         }
     122                 :          0 :                 }
     123                 :            : 
     124                 :          6 :                 b = ieee802_1x_get_radius_cui(sta->eapol_sm);
     125   [ -  +  #  # ]:          6 :                 if (b &&
     126                 :          0 :                     !radius_msg_add_attr(msg,
     127                 :            :                                          RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
     128                 :          0 :                                          wpabuf_head(b), wpabuf_len(b))) {
     129                 :          0 :                         wpa_printf(MSG_ERROR, "Could not add CUI");
     130                 :          0 :                         goto fail;
     131                 :            :                 }
     132                 :            : 
     133         [ +  - ]:          6 :                 if (!b && sta->radius_cui &&
           [ -  +  #  # ]
     134                 :          0 :                     !radius_msg_add_attr(msg,
     135                 :            :                                          RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
     136                 :          0 :                                          (u8 *) sta->radius_cui,
     137                 :          0 :                                          os_strlen(sta->radius_cui))) {
     138                 :          0 :                         wpa_printf(MSG_ERROR, "Could not add CUI from ACL");
     139                 :          0 :                         goto fail;
     140                 :            :                 }
     141                 :            :         }
     142                 :            : 
     143                 :         12 :         return msg;
     144                 :            : 
     145                 :            :  fail:
     146                 :          0 :         radius_msg_free(msg);
     147                 :         12 :         return NULL;
     148                 :            : }
     149                 :            : 
     150                 :            : 
     151                 :          3 : static int accounting_sta_update_stats(struct hostapd_data *hapd,
     152                 :            :                                        struct sta_info *sta,
     153                 :            :                                        struct hostap_sta_driver_data *data)
     154                 :            : {
     155         [ -  + ]:          3 :         if (hostapd_drv_read_sta_data(hapd, data, sta->addr))
     156                 :          0 :                 return -1;
     157                 :            : 
     158         [ -  + ]:          3 :         if (sta->last_rx_bytes > data->rx_bytes)
     159                 :          0 :                 sta->acct_input_gigawords++;
     160         [ -  + ]:          3 :         if (sta->last_tx_bytes > data->tx_bytes)
     161                 :          0 :                 sta->acct_output_gigawords++;
     162                 :          3 :         sta->last_rx_bytes = data->rx_bytes;
     163                 :          3 :         sta->last_tx_bytes = data->tx_bytes;
     164                 :            : 
     165                 :          3 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
     166                 :            :                        HOSTAPD_LEVEL_DEBUG, "updated TX/RX stats: "
     167                 :            :                        "Acct-Input-Octets=%lu Acct-Input-Gigawords=%u "
     168                 :            :                        "Acct-Output-Octets=%lu Acct-Output-Gigawords=%u",
     169                 :            :                        sta->last_rx_bytes, sta->acct_input_gigawords,
     170                 :            :                        sta->last_tx_bytes, sta->acct_output_gigawords);
     171                 :            : 
     172                 :          3 :         return 0;
     173                 :            : }
     174                 :            : 
     175                 :            : 
     176                 :          0 : static void accounting_interim_update(void *eloop_ctx, void *timeout_ctx)
     177                 :            : {
     178                 :          0 :         struct hostapd_data *hapd = eloop_ctx;
     179                 :          0 :         struct sta_info *sta = timeout_ctx;
     180                 :            :         int interval;
     181                 :            : 
     182         [ #  # ]:          0 :         if (sta->acct_interim_interval) {
     183                 :          0 :                 accounting_sta_interim(hapd, sta);
     184                 :          0 :                 interval = sta->acct_interim_interval;
     185                 :            :         } else {
     186                 :            :                 struct hostap_sta_driver_data data;
     187                 :          0 :                 accounting_sta_update_stats(hapd, sta, &data);
     188                 :          0 :                 interval = ACCT_DEFAULT_UPDATE_INTERVAL;
     189                 :            :         }
     190                 :            : 
     191                 :          0 :         eloop_register_timeout(interval, 0, accounting_interim_update,
     192                 :            :                                hapd, sta);
     193                 :          0 : }
     194                 :            : 
     195                 :            : 
     196                 :            : /**
     197                 :            :  * accounting_sta_start - Start STA accounting
     198                 :            :  * @hapd: hostapd BSS data
     199                 :            :  * @sta: The station
     200                 :            :  */
     201                 :        415 : void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
     202                 :            : {
     203                 :            :         struct radius_msg *msg;
     204                 :            :         int interval;
     205                 :            : 
     206         [ -  + ]:        415 :         if (sta->acct_session_started)
     207                 :          0 :                 return;
     208                 :            : 
     209                 :        415 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
     210                 :            :                        HOSTAPD_LEVEL_INFO,
     211                 :            :                        "starting accounting session %08X-%08X",
     212                 :            :                        sta->acct_session_id_hi, sta->acct_session_id_lo);
     213                 :            : 
     214                 :        415 :         os_get_reltime(&sta->acct_session_start);
     215                 :        415 :         sta->last_rx_bytes = sta->last_tx_bytes = 0;
     216                 :        415 :         sta->acct_input_gigawords = sta->acct_output_gigawords = 0;
     217                 :        415 :         hostapd_drv_sta_clear_stats(hapd, sta->addr);
     218                 :            : 
     219         [ +  + ]:        415 :         if (!hapd->conf->radius->acct_server)
     220                 :        412 :                 return;
     221                 :            : 
     222         [ -  + ]:          3 :         if (sta->acct_interim_interval)
     223                 :          0 :                 interval = sta->acct_interim_interval;
     224                 :            :         else
     225                 :          3 :                 interval = ACCT_DEFAULT_UPDATE_INTERVAL;
     226                 :          3 :         eloop_register_timeout(interval, 0, accounting_interim_update,
     227                 :            :                                hapd, sta);
     228                 :            : 
     229                 :          3 :         msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START);
     230   [ +  -  -  + ]:          6 :         if (msg &&
     231                 :          3 :             radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0)
     232                 :          0 :                 radius_msg_free(msg);
     233                 :            : 
     234                 :        415 :         sta->acct_session_started = 1;
     235                 :            : }
     236                 :            : 
     237                 :            : 
     238                 :          3 : static void accounting_sta_report(struct hostapd_data *hapd,
     239                 :            :                                   struct sta_info *sta, int stop)
     240                 :            : {
     241                 :            :         struct radius_msg *msg;
     242                 :          3 :         int cause = sta->acct_terminate_cause;
     243                 :            :         struct hostap_sta_driver_data data;
     244                 :            :         struct os_reltime now_r, diff;
     245                 :            :         struct os_time now;
     246                 :            :         u32 gigawords;
     247                 :            : 
     248         [ -  + ]:          3 :         if (!hapd->conf->radius->acct_server)
     249                 :          0 :                 return;
     250                 :            : 
     251         [ +  - ]:          3 :         msg = accounting_msg(hapd, sta,
     252                 :            :                              stop ? RADIUS_ACCT_STATUS_TYPE_STOP :
     253                 :            :                              RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE);
     254         [ -  + ]:          3 :         if (!msg) {
     255                 :          0 :                 wpa_printf(MSG_INFO, "Could not create RADIUS Accounting message");
     256                 :          0 :                 return;
     257                 :            :         }
     258                 :            : 
     259                 :          3 :         os_get_reltime(&now_r);
     260                 :          3 :         os_get_time(&now);
     261                 :          3 :         os_reltime_sub(&now_r, &sta->acct_session_start, &diff);
     262         [ -  + ]:          3 :         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
     263                 :          3 :                                        diff.sec)) {
     264                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Acct-Session-Time");
     265                 :          0 :                 goto fail;
     266                 :            :         }
     267                 :            : 
     268         [ +  - ]:          3 :         if (accounting_sta_update_stats(hapd, sta, &data) == 0) {
     269         [ -  + ]:          3 :                 if (!radius_msg_add_attr_int32(msg,
     270                 :            :                                                RADIUS_ATTR_ACCT_INPUT_PACKETS,
     271                 :          3 :                                                data.rx_packets)) {
     272                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Input-Packets");
     273                 :          0 :                         goto fail;
     274                 :            :                 }
     275         [ -  + ]:          3 :                 if (!radius_msg_add_attr_int32(msg,
     276                 :            :                                                RADIUS_ATTR_ACCT_OUTPUT_PACKETS,
     277                 :          3 :                                                data.tx_packets)) {
     278                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Output-Packets");
     279                 :          0 :                         goto fail;
     280                 :            :                 }
     281         [ -  + ]:          3 :                 if (!radius_msg_add_attr_int32(msg,
     282                 :            :                                                RADIUS_ATTR_ACCT_INPUT_OCTETS,
     283                 :          3 :                                                data.rx_bytes)) {
     284                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Input-Octets");
     285                 :          0 :                         goto fail;
     286                 :            :                 }
     287                 :          3 :                 gigawords = sta->acct_input_gigawords;
     288                 :            : #if __WORDSIZE == 64
     289                 :          3 :                 gigawords += data.rx_bytes >> 32;
     290                 :            : #endif
     291   [ -  +  #  # ]:          3 :                 if (gigawords &&
     292                 :          0 :                     !radius_msg_add_attr_int32(
     293                 :            :                             msg, RADIUS_ATTR_ACCT_INPUT_GIGAWORDS,
     294                 :            :                             gigawords)) {
     295                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Input-Gigawords");
     296                 :          0 :                         goto fail;
     297                 :            :                 }
     298         [ -  + ]:          3 :                 if (!radius_msg_add_attr_int32(msg,
     299                 :            :                                                RADIUS_ATTR_ACCT_OUTPUT_OCTETS,
     300                 :          3 :                                                data.tx_bytes)) {
     301                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Output-Octets");
     302                 :          0 :                         goto fail;
     303                 :            :                 }
     304                 :          3 :                 gigawords = sta->acct_output_gigawords;
     305                 :            : #if __WORDSIZE == 64
     306                 :          3 :                 gigawords += data.tx_bytes >> 32;
     307                 :            : #endif
     308   [ -  +  #  # ]:          3 :                 if (gigawords &&
     309                 :          0 :                     !radius_msg_add_attr_int32(
     310                 :            :                             msg, RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS,
     311                 :            :                             gigawords)) {
     312                 :          0 :                         wpa_printf(MSG_INFO, "Could not add Acct-Output-Gigawords");
     313                 :          0 :                         goto fail;
     314                 :            :                 }
     315                 :            :         }
     316                 :            : 
     317         [ -  + ]:          3 :         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
     318                 :          3 :                                        now.sec)) {
     319                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Event-Timestamp");
     320                 :          0 :                 goto fail;
     321                 :            :         }
     322                 :            : 
     323         [ -  + ]:          3 :         if (eloop_terminated())
     324                 :          0 :                 cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
     325                 :            : 
     326         [ +  - ]:          6 :         if (stop && cause &&
           [ +  -  -  + ]
     327                 :          3 :             !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
     328                 :            :                                        cause)) {
     329                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause");
     330                 :          0 :                 goto fail;
     331                 :            :         }
     332                 :            : 
     333 [ +  - ][ -  + ]:          3 :         if (radius_client_send(hapd->radius, msg,
     334                 :            :                                stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
     335                 :          3 :                                sta->addr) < 0)
     336                 :          0 :                 goto fail;
     337                 :          3 :         return;
     338                 :            : 
     339                 :            :  fail:
     340                 :          3 :         radius_msg_free(msg);
     341                 :            : }
     342                 :            : 
     343                 :            : 
     344                 :            : /**
     345                 :            :  * accounting_sta_interim - Send a interim STA accounting report
     346                 :            :  * @hapd: hostapd BSS data
     347                 :            :  * @sta: The station
     348                 :            :  */
     349                 :          0 : static void accounting_sta_interim(struct hostapd_data *hapd,
     350                 :            :                                    struct sta_info *sta)
     351                 :            : {
     352         [ #  # ]:          0 :         if (sta->acct_session_started)
     353                 :          0 :                 accounting_sta_report(hapd, sta, 0);
     354                 :          0 : }
     355                 :            : 
     356                 :            : 
     357                 :            : /**
     358                 :            :  * accounting_sta_stop - Stop STA accounting
     359                 :            :  * @hapd: hostapd BSS data
     360                 :            :  * @sta: The station
     361                 :            :  */
     362                 :        978 : void accounting_sta_stop(struct hostapd_data *hapd, struct sta_info *sta)
     363                 :            : {
     364         [ +  + ]:        978 :         if (sta->acct_session_started) {
     365                 :          3 :                 accounting_sta_report(hapd, sta, 1);
     366                 :          3 :                 eloop_cancel_timeout(accounting_interim_update, hapd, sta);
     367                 :          3 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
     368                 :            :                                HOSTAPD_LEVEL_INFO,
     369                 :            :                                "stopped accounting session %08X-%08X",
     370                 :            :                                sta->acct_session_id_hi,
     371                 :            :                                sta->acct_session_id_lo);
     372                 :          3 :                 sta->acct_session_started = 0;
     373                 :            :         }
     374                 :        978 : }
     375                 :            : 
     376                 :            : 
     377                 :        463 : void accounting_sta_get_id(struct hostapd_data *hapd,
     378                 :            :                                   struct sta_info *sta)
     379                 :            : {
     380                 :        463 :         sta->acct_session_id_lo = hapd->acct_session_id_lo++;
     381         [ -  + ]:        463 :         if (hapd->acct_session_id_lo == 0) {
     382                 :          0 :                 hapd->acct_session_id_hi++;
     383                 :            :         }
     384                 :        463 :         sta->acct_session_id_hi = hapd->acct_session_id_hi;
     385                 :        463 : }
     386                 :            : 
     387                 :            : 
     388                 :            : /**
     389                 :            :  * accounting_receive - Process the RADIUS frames from Accounting Server
     390                 :            :  * @msg: RADIUS response message
     391                 :            :  * @req: RADIUS request message
     392                 :            :  * @shared_secret: RADIUS shared secret
     393                 :            :  * @shared_secret_len: Length of shared_secret in octets
     394                 :            :  * @data: Context data (struct hostapd_data *)
     395                 :            :  * Returns: Processing status
     396                 :            :  */
     397                 :            : static RadiusRxResult
     398                 :          6 : accounting_receive(struct radius_msg *msg, struct radius_msg *req,
     399                 :            :                    const u8 *shared_secret, size_t shared_secret_len,
     400                 :            :                    void *data)
     401                 :            : {
     402         [ -  + ]:          6 :         if (radius_msg_get_hdr(msg)->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
     403                 :          0 :                 wpa_printf(MSG_INFO, "Unknown RADIUS message code");
     404                 :          0 :                 return RADIUS_RX_UNKNOWN;
     405                 :            :         }
     406                 :            : 
     407         [ -  + ]:          6 :         if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
     408                 :          0 :                 wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have correct Authenticator - dropped");
     409                 :          0 :                 return RADIUS_RX_INVALID_AUTHENTICATOR;
     410                 :            :         }
     411                 :            : 
     412                 :          6 :         return RADIUS_RX_PROCESSED;
     413                 :            : }
     414                 :            : 
     415                 :            : 
     416                 :        686 : static void accounting_report_state(struct hostapd_data *hapd, int on)
     417                 :            : {
     418                 :            :         struct radius_msg *msg;
     419                 :            : 
     420 [ +  + ][ -  + ]:        686 :         if (!hapd->conf->radius->acct_server || hapd->radius == NULL)
     421                 :        680 :                 return;
     422                 :            : 
     423                 :            :         /* Inform RADIUS server that accounting will start/stop so that the
     424                 :            :          * server can close old accounting sessions. */
     425         [ +  + ]:          6 :         msg = accounting_msg(hapd, NULL,
     426                 :            :                              on ? RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON :
     427                 :            :                              RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF);
     428         [ -  + ]:          6 :         if (!msg)
     429                 :          0 :                 return;
     430                 :            : 
     431         [ -  + ]:          6 :         if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_TERMINATE_CAUSE,
     432                 :            :                                        RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT))
     433                 :            :         {
     434                 :          0 :                 wpa_printf(MSG_INFO, "Could not add Acct-Terminate-Cause");
     435                 :          0 :                 radius_msg_free(msg);
     436                 :          0 :                 return;
     437                 :            :         }
     438                 :            : 
     439         [ -  + ]:          6 :         if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
     440                 :        686 :                 radius_msg_free(msg);
     441                 :            : }
     442                 :            : 
     443                 :            : 
     444                 :            : /**
     445                 :            :  * accounting_init: Initialize accounting
     446                 :            :  * @hapd: hostapd BSS data
     447                 :            :  * Returns: 0 on success, -1 on failure
     448                 :            :  */
     449                 :        343 : int accounting_init(struct hostapd_data *hapd)
     450                 :            : {
     451                 :            :         struct os_time now;
     452                 :            : 
     453                 :            :         /* Acct-Session-Id should be unique over reboots. If reliable clock is
     454                 :            :          * not available, this could be replaced with reboot counter, etc. */
     455                 :        343 :         os_get_time(&now);
     456                 :        343 :         hapd->acct_session_id_hi = now.sec;
     457                 :            : 
     458         [ -  + ]:        343 :         if (radius_client_register(hapd->radius, RADIUS_ACCT,
     459                 :            :                                    accounting_receive, hapd))
     460                 :          0 :                 return -1;
     461                 :            : 
     462                 :        343 :         accounting_report_state(hapd, 1);
     463                 :            : 
     464                 :        343 :         return 0;
     465                 :            : }
     466                 :            : 
     467                 :            : 
     468                 :            : /**
     469                 :            :  * accounting_deinit: Deinitilize accounting
     470                 :            :  * @hapd: hostapd BSS data
     471                 :            :  */
     472                 :        343 : void accounting_deinit(struct hostapd_data *hapd)
     473                 :            : {
     474                 :        343 :         accounting_report_state(hapd, 0);
     475                 :        343 : }

Generated by: LCOV version 1.9