static struct radius_msg * accounting_msg(struct hostapd_data *hapd, struct sta_info *sta, int status_type) { struct radius_msg *msg; char buf[128]; u8 *val; size_t len; int i; struct wpabuf *b; msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST, radius_client_get_id(hapd->radius)); if (msg == NULL) { wpa_printf(MSG_INFO, "Could not create new RADIUS packet"); return NULL; } if (sta) { radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta)); os_snprintf(buf, sizeof(buf), "%08X-%08X", sta->acct_session_id_hi, sta->acct_session_id_lo); if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID, (u8 *) buf, os_strlen(buf))) { wpa_printf(MSG_INFO, "Could not add Acct-Session-Id"); goto fail; } } else { radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd)); } if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE, status_type)) { wpa_printf(MSG_INFO, "Could not add Acct-Status-Type"); goto fail; } if (!hostapd_config_get_radius_attr(hapd->conf->radius_acct_req_attr, RADIUS_ATTR_ACCT_AUTHENTIC) && !radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC, hapd->conf->ieee802_1x ? RADIUS_ACCT_AUTHENTIC_RADIUS : RADIUS_ACCT_AUTHENTIC_LOCAL)) { wpa_printf(MSG_INFO, "Could not add Acct-Authentic"); goto fail; } if (sta) { /* Use 802.1X identity if available */ val = ieee802_1x_get_identity(sta->eapol_sm, &len); /* Use RADIUS ACL identity if 802.1X provides no identity */ if (!val && sta->identity) { val = (u8 *) sta->identity; len = os_strlen(sta->identity); } /* Use STA MAC if neither 802.1X nor RADIUS ACL provided * identity */ if (!val) { os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(sta->addr)); val = (u8 *) buf; len = os_strlen(buf); } if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val, len)) { wpa_printf(MSG_INFO, "Could not add User-Name"); goto fail; } } if (add_common_radius_attr(hapd, hapd->conf->radius_acct_req_attr, sta, msg) < 0) goto fail; if (sta) { for (i = 0; ; i++) { val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, i); if (val == NULL) break; if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS, val, len)) { wpa_printf(MSG_INFO, "Could not add Class"); goto fail; } } b = ieee802_1x_get_radius_cui(sta->eapol_sm); if (b && !radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, wpabuf_head(b), wpabuf_len(b))) { wpa_printf(MSG_ERROR, "Could not add CUI"); goto fail; } if (!b && sta->radius_cui && !radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, (u8 *) sta->radius_cui, os_strlen(sta->radius_cui))) { wpa_printf(MSG_ERROR, "Could not add CUI from ACL"); goto fail; } } return msg; fail: radius_msg_free(msg); return NULL; }
static struct radius_msg * accounting_msg(struct hostapd_data *hapd, struct sta_info *sta, int status_type) { struct radius_msg *msg; char buf[128]; u8 *val; size_t len; int i; msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST, radius_client_get_id(hapd->radius)); if (msg == NULL) { printf("Could not create net RADIUS packet\n"); return NULL; } if (sta) { radius_msg_make_authenticator(msg, (u8 *) sta, sizeof(*sta)); os_snprintf(buf, sizeof(buf), "%08X-%08X", sta->acct_session_id_hi, sta->acct_session_id_lo); if (!radius_msg_add_attr(msg, RADIUS_ATTR_ACCT_SESSION_ID, (u8 *) buf, os_strlen(buf))) { printf("Could not add Acct-Session-Id\n"); goto fail; } } else { radius_msg_make_authenticator(msg, (u8 *) hapd, sizeof(*hapd)); } if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE, status_type)) { printf("Could not add Acct-Status-Type\n"); goto fail; } if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_AUTHENTIC, hapd->conf->ieee802_1x ? RADIUS_ACCT_AUTHENTIC_RADIUS : RADIUS_ACCT_AUTHENTIC_LOCAL)) { printf("Could not add Acct-Authentic\n"); goto fail; } if (sta) { val = ieee802_1x_get_identity(sta->eapol_sm, &len); if (!val) { os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(sta->addr)); val = (u8 *) buf; len = os_strlen(buf); } if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, val, len)) { printf("Could not add User-Name\n"); goto fail; } } if (hapd->conf->own_ip_addr.af == AF_INET && !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS, (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) { printf("Could not add NAS-IP-Address\n"); goto fail; } #ifdef CONFIG_IPV6 if (hapd->conf->own_ip_addr.af == AF_INET6 && !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS, (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) { printf("Could not add NAS-IPv6-Address\n"); goto fail; } #endif /* CONFIG_IPV6 */ if (hapd->conf->nas_identifier && !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER, (u8 *) hapd->conf->nas_identifier, os_strlen(hapd->conf->nas_identifier))) { printf("Could not add NAS-Identifier\n"); goto fail; } if (sta && !radius_msg_add_attr_int32(msg, RADIUS_ATTR_NAS_PORT, sta->aid)) { printf("Could not add NAS-Port\n"); goto fail; } os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT ":%s", MAC2STR(hapd->own_addr), hapd->conf->ssid.ssid); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLED_STATION_ID, (u8 *) buf, os_strlen(buf))) { printf("Could not add Called-Station-Id\n"); goto fail; } if (sta) { os_snprintf(buf, sizeof(buf), RADIUS_802_1X_ADDR_FORMAT, MAC2STR(sta->addr)); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CALLING_STATION_ID, (u8 *) buf, os_strlen(buf))) { printf("Could not add Calling-Station-Id\n"); goto fail; } if (!radius_msg_add_attr_int32( msg, RADIUS_ATTR_NAS_PORT_TYPE, RADIUS_NAS_PORT_TYPE_IEEE_802_11)) { printf("Could not add NAS-Port-Type\n"); goto fail; } os_snprintf(buf, sizeof(buf), "CONNECT %d%sMbps %s", radius_sta_rate(hapd, sta) / 2, (radius_sta_rate(hapd, sta) & 1) ? ".5" : "", radius_mode_txt(hapd)); if (!radius_msg_add_attr(msg, RADIUS_ATTR_CONNECT_INFO, (u8 *) buf, os_strlen(buf))) { printf("Could not add Connect-Info\n"); goto fail; } for (i = 0; ; i++) { val = ieee802_1x_get_radius_class(sta->eapol_sm, &len, i); if (val == NULL) break; if (!radius_msg_add_attr(msg, RADIUS_ATTR_CLASS, val, len)) { printf("Could not add Class\n"); goto fail; } } } return msg; fail: radius_msg_free(msg); os_free(msg); return NULL; }