ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/vendor/wpa/dist/src/ap/accounting.c
(Generate patch)

Comparing vendor/wpa/dist/src/ap/accounting.c (file contents):
Revision 9638 by laffer1, Sun Oct 22 18:04:47 2017 UTC vs.
Revision 9639 by laffer1, Sun Oct 22 18:11:47 2017 UTC

# Line 1 | Line 1
1   /*
2   * hostapd / RADIUS Accounting
3 < * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
3 > * Copyright (c) 2002-2009, 2012, Jouni Malinen <j@w1.fi>
4   *
5 < * This program is free software; you can redistribute it and/or modify
6 < * it under the terms of the GNU General Public License version 2 as
7 < * published by the Free Software Foundation.
8 < *
9 < * Alternatively, this software may be distributed under the terms of BSD
10 < * license.
11 < *
12 < * See README and COPYING for more details.
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"
# Line 23 | Line 17
17   #include "ieee802_1x.h"
18   #include "ap_config.h"
19   #include "sta_info.h"
20 + #include "ap_drv_ops.h"
21   #include "accounting.h"
22  
23  
# Line 31 | Line 26
26   * input/output octets and updates Acct-{Input,Output}-Gigawords. */
27   #define ACCT_DEFAULT_UPDATE_INTERVAL 300
28  
29 < static void accounting_sta_get_id(struct hostapd_data *hapd,
30 <                                  struct sta_info *sta);
29 > static void accounting_sta_interim(struct hostapd_data *hapd,
30 >                                   struct sta_info *sta);
31  
32  
33   static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
# Line 44 | Line 39 | static struct radius_msg * accounting_msg(struct hosta
39          u8 *val;
40          size_t len;
41          int i;
42 +        struct wpabuf *b;
43  
44          msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
45                               radius_client_get_id(hapd->radius));
# Line 72 | Line 68 | static struct radius_msg * accounting_msg(struct hosta
68                  goto fail;
69          }
70  
71 <        if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
71 >        if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr,
72 >                                            RADIUS_ATTR_ACCT_AUTHENTIC) &&
73 >            !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC,
74                                         hapd->conf->ieee802_1x ?
75                                         RADIUS_ACCT_AUTHENTIC_RADIUS :
76                                         RADIUS_ACCT_AUTHENTIC_LOCAL)) {
# Line 81 | Line 79 | static struct radius_msg * accounting_msg(struct hosta
79          }
80  
81          if (sta) {
82 +                /* Use 802.1X identity if available */
83                  val = ieee802_1x_get_identity(sta->eapol_sm, &len);
84 +
85 +                /* Use RADIUS ACL identity if 802.1X provides no identity */
86 +                if (!val && sta->identity) {
87 +                        val = (u8 *) sta->identity;
88 +                        len = os_strlen(sta->identity);
89 +                }
90 +
91 +                /* Use STA MAC if neither 802.1X nor RADIUS ACL provided
92 +                 * identity */
93                  if (!val) {
94                          os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
95                                      MAC2STR(sta->addr));
# Line 96 | Line 104 | static struct radius_msg * accounting_msg(struct hosta
104                  }
105          }
106  
107 <        if (hapd->conf->own_ip_addr.af == AF_INET &&
108 <            !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
101 <                                 (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
102 <                printf("Could not add NAS-IP-Address\n");
107 >        if (add_common_radius_attr(hapd, hapd->conf->radius_acct_req_attr, sta,
108 >                                   msg) < 0)
109                  goto fail;
104        }
110  
106 #ifdef CONFIG_IPV6
107        if (hapd->conf->own_ip_addr.af == AF_INET6 &&
108            !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
109                                 (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
110                printf("Could not add NAS-IPv6-Address\n");
111                goto fail;
112        }
113 #endif /* CONFIG_IPV6 */
114
115        if (hapd->conf->nas_identifier &&
116            !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
117                                 (u8 *) hapd->conf->nas_identifier,
118                                 os_strlen(hapd->conf->nas_identifier))) {
119                printf("Could not add NAS-Identifier\n");
120                goto fail;
121        }
122
123        if (sta &&
124            !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) {
125                printf("Could not add NAS-Port\n");
126                goto fail;
127        }
128
129        os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s",
130                    MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid);
131        if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID,
132                                 (u8 *) buf, os_strlen(buf))) {
133                printf("Could not add Called-Station-Id\n");
134                goto fail;
135        }
136
111          if (sta) {
138                os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT,
139                            MAC2STR(sta->addr));
140                if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID,
141                                         (u8 *) buf, os_strlen(buf))) {
142                        printf("Could not add Calling-Station-Id\n");
143                        goto fail;
144                }
145
146                if (!radius_msg_add_attr_int32(
147                            msg, RADIUS_ATTR_NAS_PORT_TYPE,
148                            RADIUS_NAS_PORT_TYPE_IEEE_802_11)) {
149                        printf("Could not add NAS-Port-Type\n");
150                        goto fail;
151                }
152
153                os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s",
154                            radius_sta_rate(hapd, sta) / 2,
155                            (radius_sta_rate(hapd, sta) & 1) ? ".5" : "",
156                            radius_mode_txt(hapd));
157                if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO,
158                                         (u8 *) buf, os_strlen(buf))) {
159                        printf("Could not add Connect-Info\n");
160                        goto fail;
161                }
162
112                  for (i = 0; ; i++) {
113                          val = ieee802_1x_get_radius_class(sta->eapol_sm, &len,
114                                                            i);
# Line 172 | Line 121 | static struct radius_msg * accounting_msg(struct hosta
121                                  goto fail;
122                          }
123                  }
124 +
125 +                b = ieee802_1x_get_radius_cui(sta->eapol_sm);
126 +                if (b &&
127 +                    !radius_msg_add_attr(msg,
128 +                                         RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
129 +                                         wpabuf_head(b), wpabuf_len(b))) {
130 +                        wpa_printf(MSG_ERROR, "Could not add CUI");
131 +                        goto fail;
132 +                }
133 +
134 +                if (!b && sta->radius_cui &&
135 +                    !radius_msg_add_attr(msg,
136 +                                         RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
137 +                                         (u8 *) sta->radius_cui,
138 +                                         os_strlen(sta->radius_cui))) {
139 +                        wpa_printf(MSG_ERROR, "Could not add CUI from ACL");
140 +                        goto fail;
141 +                }
142          }
143  
144          return msg;
# Line 186 | Line 153 | static int accounting_sta_update_stats(struct hostapd_
153                                         struct sta_info *sta,
154                                         struct hostap_sta_driver_data *data)
155   {
156 <        if (hapd->drv.read_sta_data(hapd, data, sta->addr))
156 >        if (hostapd_drv_read_sta_data(hapd, data, sta->addr))
157                  return -1;
158  
159          if (sta->last_rx_bytes > data->rx_bytes)
# Line 235 | Line 202 | static void accounting_interim_update(void *eloop_ctx,
202   void accounting_sta_start(struct hostapd_data *hapd, struct sta_info *sta)
203   {
204          struct radius_msg *msg;
205 +        struct os_time t;
206          int interval;
207  
208          if (sta->acct_session_started)
209                  return;
210  
243        accounting_sta_get_id(hapd, sta);
211          hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
212                         HOSTAPD_LEVEL_INFO,
213                         "starting accounting session %08X-%08X",
214                         sta->acct_session_id_hi, sta->acct_session_id_lo);
215  
216 <        time(&sta->acct_session_start);
216 >        os_get_time(&t);
217 >        sta->acct_session_start = t.sec;
218          sta->last_rx_bytes = sta->last_tx_bytes = 0;
219          sta->acct_input_gigawords = sta->acct_output_gigawords = 0;
220 <        hapd->drv.sta_clear_stats(hapd, sta->addr);
220 >        hostapd_drv_sta_clear_stats(hapd, sta->addr);
221  
222          if (!hapd->conf->radius->acct_server)
223                  return;
# Line 262 | Line 230 | void accounting_sta_start(struct hostapd_data *hapd, s
230                                 hapd, sta);
231  
232          msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START);
233 <        if (msg)
234 <                radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr);
233 >        if (msg &&
234 >            radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0)
235 >                radius_msg_free(msg);
236  
237          sta->acct_session_started = 1;
238   }
# Line 275 | Line 244 | static void accounting_sta_report(struct hostapd_data
244          struct radius_msg *msg;
245          int cause = sta->acct_terminate_cause;
246          struct hostap_sta_driver_data data;
247 +        struct os_time now;
248          u32 gigawords;
249  
250          if (!hapd->conf->radius->acct_server)
# Line 288 | Line 258 | static void accounting_sta_report(struct hostapd_data
258                  return;
259          }
260  
261 +        os_get_time(&now);
262          if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_SESSION_TIME,
263 <                                       time(NULL) - sta->acct_session_start)) {
263 >                                       now.sec - sta->acct_session_start)) {
264                  printf("Could not add Acct-Session-Time\n");
265                  goto fail;
266          }
# Line 344 | Line 315 | static void accounting_sta_report(struct hostapd_data
315          }
316  
317          if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
318 <                                       time(NULL))) {
318 >                                       now.sec)) {
319                  printf("Could not add Event-Timestamp\n");
320                  goto fail;
321          }
# Line 359 | Line 330 | static void accounting_sta_report(struct hostapd_data
330                  goto fail;
331          }
332  
333 <        radius_client_send(hapd->radius, msg,
334 <                           stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
335 <                           sta->addr);
333 >        if (radius_client_send(hapd->radius, msg,
334 >                               stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
335 >                               sta->addr) < 0)
336 >                goto fail;
337          return;
338  
339   fail:
# Line 374 | Line 346 | static void accounting_sta_report(struct hostapd_data
346   * @hapd: hostapd BSS data
347   * @sta: The station
348   */
349 < void accounting_sta_interim(struct hostapd_data *hapd, struct sta_info *sta)
349 > static void accounting_sta_interim(struct hostapd_data *hapd,
350 >                                   struct sta_info *sta)
351   {
352          if (sta->acct_session_started)
353                  accounting_sta_report(hapd, sta, 0);
# Line 401 | Line 374 | void accounting_sta_stop(struct hostapd_data *hapd, st
374   }
375  
376  
377 < static void accounting_sta_get_id(struct hostapd_data *hapd,
377 > void accounting_sta_get_id(struct hostapd_data *hapd,
378                                    struct sta_info *sta)
379   {
380          sta->acct_session_id_lo = hapd->acct_session_id_lo++;
# Line 464 | Line 437 | static void accounting_report_state(struct hostapd_dat
437                  return;
438          }
439  
440 <        radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL);
440 >        if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
441 >                radius_msg_free(msg);
442   }
443  
444  
# Line 475 | Line 449 | static void accounting_report_state(struct hostapd_dat
449   */
450   int accounting_init(struct hostapd_data *hapd)
451   {
452 +        struct os_time now;
453 +
454          /* Acct-Session-Id should be unique over reboots. If reliable clock is
455           * not available, this could be replaced with reboot counter, etc. */
456 <        hapd->acct_session_id_hi = time(NULL);
456 >        os_get_time(&now);
457 >        hapd->acct_session_id_hi = now.sec;
458  
459          if (radius_client_register(hapd->radius, RADIUS_ACCT,
460                                     accounting_receive, hapd))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines