2 * Host AP (software wireless LAN access point) user space daemon for
3 * Host AP kernel driver / RADIUS client
4 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
19 #include <netinet/in.h>
22 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <arpa/inet.h>
30 #include "radius_client.h"
33 /* Defaults for RADIUS retransmit values (exponential backoff) */
34 #define RADIUS_CLIENT_FIRST_WAIT 3 /* seconds */
35 #define RADIUS_CLIENT_MAX_WAIT 120 /* seconds */
36 #define RADIUS_CLIENT_MAX_RETRIES 10 /* maximum number of retransmit attempts
37 * before entry is removed from retransmit
39 #define RADIUS_CLIENT_MAX_ENTRIES 30 /* maximum number of entries in retransmit
40 * list (oldest will be removed, if this
41 * limit is exceeded) */
42 #define RADIUS_CLIENT_NUM_FAILOVER 4 /* try to change RADIUS server after this
43 * many failed retry attempts */
46 struct radius_rx_handler {
47 RadiusRxResult (*handler)(struct radius_msg *msg,
48 struct radius_msg *req,
49 u8 *shared_secret, size_t shared_secret_len,
55 /* RADIUS message retransmit list */
56 struct radius_msg_list {
57 u8 addr[ETH_ALEN]; /* STA/client address; used to find RADIUS messages
58 * for the same STA. */
59 struct radius_msg *msg;
65 struct timeval last_attempt;
68 size_t shared_secret_len;
70 /* TODO: server config with failover to backup server(s) */
72 struct radius_msg_list *next;
76 struct radius_client_data {
77 struct hostapd_data *hapd;
79 int auth_serv_sock; /* socket for authentication RADIUS messages */
80 int acct_serv_sock; /* socket for accounting RADIUS messages */
82 struct radius_rx_handler *auth_handlers;
83 size_t num_auth_handlers;
84 struct radius_rx_handler *acct_handlers;
85 size_t num_acct_handlers;
87 struct radius_msg_list *msgs;
90 u8 next_radius_identifier;
95 radius_change_server(struct radius_client_data *radius,
96 struct hostapd_radius_server *nserv,
97 struct hostapd_radius_server *oserv,
99 static int radius_client_init_acct(struct radius_client_data *radius);
100 static int radius_client_init_auth(struct radius_client_data *radius);
103 static void radius_client_msg_free(struct radius_msg_list *req)
105 radius_msg_free(req->msg);
111 int radius_client_register(struct radius_client_data *radius,
113 RadiusRxResult (*handler)(struct radius_msg *msg,
114 struct radius_msg *req,
116 size_t shared_secret_len,
120 struct radius_rx_handler **handlers, *newh;
123 if (msg_type == RADIUS_ACCT) {
124 handlers = &radius->acct_handlers;
125 num = &radius->num_acct_handlers;
127 handlers = &radius->auth_handlers;
128 num = &radius->num_auth_handlers;
131 newh = (struct radius_rx_handler *)
133 (*num + 1) * sizeof(struct radius_rx_handler));
137 newh[*num].handler = handler;
138 newh[*num].data = data;
146 static void radius_client_handle_send_error(struct radius_client_data *radius,
147 int s, RadiusType msg_type)
149 struct hostapd_data *hapd = radius->hapd;
151 perror("send[RADIUS]");
152 if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL) {
153 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_RADIUS,
155 "Send failed - maybe interface status changed -"
156 " try to connect again");
157 eloop_unregister_read_sock(s);
159 if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM)
160 radius_client_init_acct(radius);
162 radius_client_init_auth(radius);
167 static int radius_client_retransmit(struct radius_client_data *radius,
168 struct radius_msg_list *entry, time_t now)
170 struct hostapd_data *hapd = radius->hapd;
173 if (entry->msg_type == RADIUS_ACCT ||
174 entry->msg_type == RADIUS_ACCT_INTERIM) {
175 s = radius->acct_serv_sock;
176 if (entry->attempts == 0)
177 hapd->conf->acct_server->requests++;
179 hapd->conf->acct_server->timeouts++;
180 hapd->conf->acct_server->retransmissions++;
183 s = radius->auth_serv_sock;
184 if (entry->attempts == 0)
185 hapd->conf->auth_server->requests++;
187 hapd->conf->auth_server->timeouts++;
188 hapd->conf->auth_server->retransmissions++;
192 /* retransmit; remove entry if too many attempts */
194 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Resending RADIUS message (id=%d)"
195 "\n", entry->msg->hdr->identifier);
197 gettimeofday(&entry->last_attempt, NULL);
198 if (send(s, entry->msg->buf, entry->msg->buf_used, 0) < 0)
199 radius_client_handle_send_error(radius, s, entry->msg_type);
201 entry->next_try = now + entry->next_wait;
202 entry->next_wait *= 2;
203 if (entry->next_wait > RADIUS_CLIENT_MAX_WAIT)
204 entry->next_wait = RADIUS_CLIENT_MAX_WAIT;
205 if (entry->attempts >= RADIUS_CLIENT_MAX_RETRIES) {
206 printf("Removing un-ACKed RADIUS message due to too many "
207 "failed retransmit attempts\n");
215 static void radius_client_timer(void *eloop_ctx, void *timeout_ctx)
217 struct radius_client_data *radius = eloop_ctx;
218 struct hostapd_data *hapd = radius->hapd;
220 struct radius_msg_list *entry, *prev, *tmp;
221 int auth_failover = 0, acct_failover = 0;
223 entry = radius->msgs;
232 if (now >= entry->next_try &&
233 radius_client_retransmit(radius, entry, now)) {
235 prev->next = entry->next;
237 radius->msgs = entry->next;
241 radius_client_msg_free(tmp);
246 if (entry->attempts > RADIUS_CLIENT_NUM_FAILOVER) {
247 if (entry->msg_type == RADIUS_ACCT ||
248 entry->msg_type == RADIUS_ACCT_INTERIM)
254 if (first == 0 || entry->next_try < first)
255 first = entry->next_try;
264 eloop_register_timeout(first - now, 0,
265 radius_client_timer, radius, NULL);
266 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Next RADIUS client "
267 "retransmit in %ld seconds\n",
268 (long int) (first - now));
272 if (auth_failover && hapd->conf->num_auth_servers > 1) {
273 struct hostapd_radius_server *next, *old;
274 old = hapd->conf->auth_server;
275 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_RADIUS,
276 HOSTAPD_LEVEL_NOTICE,
277 "No response from Authentication server "
279 inet_ntoa(old->addr), old->port);
281 for (entry = radius->msgs; entry; entry = entry->next) {
282 if (entry->msg_type == RADIUS_AUTH)
287 if (next > &(hapd->conf->auth_servers
288 [hapd->conf->num_auth_servers - 1]))
289 next = hapd->conf->auth_servers;
290 hapd->conf->auth_server = next;
291 radius_change_server(radius, next, old,
292 radius->auth_serv_sock, 1);
295 if (acct_failover && hapd->conf->num_acct_servers > 1) {
296 struct hostapd_radius_server *next, *old;
297 old = hapd->conf->acct_server;
298 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_RADIUS,
299 HOSTAPD_LEVEL_NOTICE,
300 "No response from Accounting server "
302 inet_ntoa(old->addr), old->port);
304 for (entry = radius->msgs; entry; entry = entry->next) {
305 if (entry->msg_type == RADIUS_ACCT ||
306 entry->msg_type == RADIUS_ACCT_INTERIM)
311 if (next > &hapd->conf->acct_servers
312 [hapd->conf->num_acct_servers - 1])
313 next = hapd->conf->acct_servers;
314 hapd->conf->acct_server = next;
315 radius_change_server(radius, next, old,
316 radius->acct_serv_sock, 0);
321 static void radius_client_update_timeout(struct radius_client_data *radius)
323 struct hostapd_data *hapd = radius->hapd;
325 struct radius_msg_list *entry;
327 eloop_cancel_timeout(radius_client_timer, radius, NULL);
329 if (radius->msgs == NULL) {
334 for (entry = radius->msgs; entry; entry = entry->next) {
335 if (first == 0 || entry->next_try < first)
336 first = entry->next_try;
342 eloop_register_timeout(first - now, 0, radius_client_timer, radius,
344 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Next RADIUS client retransmit in"
345 " %ld seconds\n", (long int) (first - now));
349 static void radius_client_list_add(struct radius_client_data *radius,
350 struct radius_msg *msg,
351 RadiusType msg_type, u8 *shared_secret,
352 size_t shared_secret_len, u8 *addr)
354 struct radius_msg_list *entry, *prev;
356 if (eloop_terminated()) {
357 /* No point in adding entries to retransmit queue since event
358 * loop has already been terminated. */
359 radius_msg_free(msg);
364 entry = malloc(sizeof(*entry));
366 printf("Failed to add RADIUS packet into retransmit list\n");
367 radius_msg_free(msg);
372 memset(entry, 0, sizeof(*entry));
374 memcpy(entry->addr, addr, ETH_ALEN);
376 entry->msg_type = msg_type;
377 entry->shared_secret = shared_secret;
378 entry->shared_secret_len = shared_secret_len;
379 time(&entry->first_try);
380 entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
382 gettimeofday(&entry->last_attempt, NULL);
383 entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
384 entry->next = radius->msgs;
385 radius->msgs = entry;
386 radius_client_update_timeout(radius);
388 if (radius->num_msgs >= RADIUS_CLIENT_MAX_ENTRIES) {
389 printf("Removing the oldest un-ACKed RADIUS packet due to "
390 "retransmit list limits.\n");
392 while (entry->next) {
398 radius_client_msg_free(entry);
405 static void radius_client_list_del(struct radius_client_data *radius,
406 RadiusType msg_type, u8 *addr)
408 struct hostapd_data *hapd = radius->hapd;
409 struct radius_msg_list *entry, *prev, *tmp;
414 entry = radius->msgs;
417 if (entry->msg_type == msg_type &&
418 memcmp(entry->addr, addr, ETH_ALEN) == 0) {
420 prev->next = entry->next;
422 radius->msgs = entry->next;
425 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
426 "Removing matching RADIUS message for "
427 MACSTR "\n", MAC2STR(addr));
428 radius_client_msg_free(tmp);
438 int radius_client_send(struct radius_client_data *radius,
439 struct radius_msg *msg, RadiusType msg_type, u8 *addr)
441 struct hostapd_data *hapd = radius->hapd;
443 size_t shared_secret_len;
447 if (msg_type == RADIUS_ACCT_INTERIM) {
448 /* Remove any pending interim acct update for the same STA. */
449 radius_client_list_del(radius, msg_type, addr);
452 if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) {
453 shared_secret = hapd->conf->acct_server->shared_secret;
454 shared_secret_len = hapd->conf->acct_server->shared_secret_len;
455 radius_msg_finish_acct(msg, shared_secret, shared_secret_len);
457 s = radius->acct_serv_sock;
458 hapd->conf->acct_server->requests++;
460 shared_secret = hapd->conf->auth_server->shared_secret;
461 shared_secret_len = hapd->conf->auth_server->shared_secret_len;
462 radius_msg_finish(msg, shared_secret, shared_secret_len);
463 name = "authentication";
464 s = radius->auth_serv_sock;
465 hapd->conf->auth_server->requests++;
468 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
469 "Sending RADIUS message to %s server\n", name);
470 if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS))
471 radius_msg_dump(msg);
473 res = send(s, msg->buf, msg->buf_used, 0);
475 radius_client_handle_send_error(radius, s, msg_type);
477 radius_client_list_add(radius, msg, msg_type, shared_secret,
478 shared_secret_len, addr);
484 static void radius_client_receive(int sock, void *eloop_ctx, void *sock_ctx)
486 struct radius_client_data *radius = eloop_ctx;
487 struct hostapd_data *hapd = radius->hapd;
488 RadiusType msg_type = (RadiusType) sock_ctx;
489 int len, i, roundtrip;
490 unsigned char buf[3000];
491 struct radius_msg *msg;
492 struct radius_rx_handler *handlers;
494 struct radius_msg_list *req, *prev_req;
496 struct hostapd_radius_server *rconf;
497 int invalid_authenticator = 0;
499 if (msg_type == RADIUS_ACCT) {
500 handlers = radius->acct_handlers;
501 num_handlers = radius->num_acct_handlers;
502 rconf = hapd->conf->acct_server;
504 handlers = radius->auth_handlers;
505 num_handlers = radius->num_auth_handlers;
506 rconf = hapd->conf->auth_server;
509 len = recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
511 perror("recv[RADIUS]");
514 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
515 "Received %d bytes from RADIUS server\n", len);
516 if (len == sizeof(buf)) {
517 printf("Possibly too long UDP frame for our buffer - "
522 msg = radius_msg_parse(buf, len);
524 printf("Parsing incoming RADIUS frame failed\n");
525 rconf->malformed_responses++;
529 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
530 "Received RADIUS message\n");
531 if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS))
532 radius_msg_dump(msg);
534 switch (msg->hdr->code) {
535 case RADIUS_CODE_ACCESS_ACCEPT:
536 rconf->access_accepts++;
538 case RADIUS_CODE_ACCESS_REJECT:
539 rconf->access_rejects++;
541 case RADIUS_CODE_ACCESS_CHALLENGE:
542 rconf->access_challenges++;
544 case RADIUS_CODE_ACCOUNTING_RESPONSE:
552 /* TODO: also match by src addr:port of the packet when using
553 * alternative RADIUS servers (?) */
554 if ((req->msg_type == msg_type ||
555 (req->msg_type == RADIUS_ACCT_INTERIM &&
556 msg_type == RADIUS_ACCT)) &&
557 req->msg->hdr->identifier == msg->hdr->identifier)
565 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
566 "No matching RADIUS request found (type=%d "
567 "id=%d) - dropping packet\n",
568 msg_type, msg->hdr->identifier);
572 gettimeofday(&tv, NULL);
573 roundtrip = (tv.tv_sec - req->last_attempt.tv_sec) * 100 +
574 (tv.tv_usec - req->last_attempt.tv_usec) / 10000;
575 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "Received RADIUS packet matched "
576 "with a pending request, round trip time %d.%02d sec\n",
577 roundtrip / 100, roundtrip % 100);
578 rconf->round_trip_time = roundtrip;
580 /* Remove ACKed RADIUS packet from retransmit list */
582 prev_req->next = req->next;
584 radius->msgs = req->next;
587 for (i = 0; i < num_handlers; i++) {
589 res = handlers[i].handler(msg, req->msg, req->shared_secret,
590 req->shared_secret_len,
593 case RADIUS_RX_PROCESSED:
594 radius_msg_free(msg);
597 case RADIUS_RX_QUEUED:
598 radius_client_msg_free(req);
600 case RADIUS_RX_INVALID_AUTHENTICATOR:
601 invalid_authenticator++;
603 case RADIUS_RX_UNKNOWN:
604 /* continue with next handler */
609 if (invalid_authenticator)
610 rconf->bad_authenticators++;
612 rconf->unknown_types++;
613 hostapd_logger(hapd, req->addr, HOSTAPD_MODULE_RADIUS,
614 HOSTAPD_LEVEL_DEBUG, "No RADIUS RX handler found "
615 "(type=%d code=%d id=%d)%s - dropping packet",
616 msg_type, msg->hdr->code, msg->hdr->identifier,
617 invalid_authenticator ? " [INVALID AUTHENTICATOR]" :
619 radius_client_msg_free(req);
622 radius_msg_free(msg);
627 u8 radius_client_get_id(struct radius_client_data *radius)
629 struct hostapd_data *hapd = radius->hapd;
630 struct radius_msg_list *entry, *prev, *remove;
631 u8 id = radius->next_radius_identifier++;
633 /* remove entries with matching id from retransmit list to avoid
634 * using new reply from the RADIUS server with an old request */
635 entry = radius->msgs;
638 if (entry->msg->hdr->identifier == id) {
639 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
640 "Removing pending RADIUS message, since "
641 "its id (%d) is reused\n", id);
643 prev->next = entry->next;
645 radius->msgs = entry->next;
653 radius_client_msg_free(remove);
660 void radius_client_flush(struct radius_client_data *radius)
662 struct radius_msg_list *entry, *prev;
667 eloop_cancel_timeout(radius_client_timer, radius, NULL);
669 entry = radius->msgs;
671 radius->num_msgs = 0;
675 radius_client_msg_free(prev);
681 radius_change_server(struct radius_client_data *radius,
682 struct hostapd_radius_server *nserv,
683 struct hostapd_radius_server *oserv,
686 struct hostapd_data *hapd = radius->hapd;
687 struct sockaddr_in serv;
689 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO,
691 auth ? "Authentication" : "Accounting",
692 inet_ntoa(nserv->addr), nserv->port);
694 if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
695 memcmp(nserv->shared_secret, oserv->shared_secret,
696 nserv->shared_secret_len) != 0) {
697 /* Pending RADIUS packets used different shared
698 * secret, so they would need to be modified. Could
699 * update all message authenticators and
700 * User-Passwords, etc. and retry with new server. For
701 * now, just drop all pending packets. */
702 radius_client_flush(radius);
704 /* Reset retry counters for the new server */
705 struct radius_msg_list *entry;
706 entry = radius->msgs;
708 entry->next_try = entry->first_try +
709 RADIUS_CLIENT_FIRST_WAIT;
711 entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
715 eloop_cancel_timeout(radius_client_timer, radius,
717 eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
718 radius_client_timer, radius,
723 memset(&serv, 0, sizeof(serv));
724 serv.sin_family = AF_INET;
725 serv.sin_addr.s_addr = nserv->addr.s_addr;
726 serv.sin_port = htons(nserv->port);
728 if (connect(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) {
729 perror("connect[radius]");
737 static void radius_retry_primary_timer(void *eloop_ctx, void *timeout_ctx)
739 struct radius_client_data *radius = eloop_ctx;
740 struct hostapd_data *hapd = radius->hapd;
741 struct hostapd_radius_server *oserv;
743 if (radius->auth_serv_sock >= 0 && hapd->conf->auth_servers &&
744 hapd->conf->auth_server != hapd->conf->auth_servers) {
745 oserv = hapd->conf->auth_server;
746 hapd->conf->auth_server = hapd->conf->auth_servers;
747 radius_change_server(radius, hapd->conf->auth_server, oserv,
748 radius->auth_serv_sock, 1);
751 if (radius->acct_serv_sock >= 0 && hapd->conf->acct_servers &&
752 hapd->conf->acct_server != hapd->conf->acct_servers) {
753 oserv = hapd->conf->acct_server;
754 hapd->conf->acct_server = hapd->conf->acct_servers;
755 radius_change_server(radius, hapd->conf->acct_server, oserv,
756 radius->acct_serv_sock, 0);
759 if (hapd->conf->radius_retry_primary_interval)
760 eloop_register_timeout(hapd->conf->
761 radius_retry_primary_interval, 0,
762 radius_retry_primary_timer, radius,
767 static int radius_client_init_auth(struct radius_client_data *radius)
769 struct hostapd_data *hapd = radius->hapd;
770 radius->auth_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
771 if (radius->auth_serv_sock < 0) {
772 perror("socket[PF_INET,SOCK_DGRAM]");
776 radius_change_server(radius, hapd->conf->auth_server, NULL,
777 radius->auth_serv_sock, 1);
779 if (eloop_register_read_sock(radius->auth_serv_sock,
780 radius_client_receive, radius,
781 (void *) RADIUS_AUTH)) {
782 printf("Could not register read socket for authentication "
791 static int radius_client_init_acct(struct radius_client_data *radius)
793 struct hostapd_data *hapd = radius->hapd;
794 radius->acct_serv_sock = socket(PF_INET, SOCK_DGRAM, 0);
795 if (radius->acct_serv_sock < 0) {
796 perror("socket[PF_INET,SOCK_DGRAM]");
800 radius_change_server(radius, hapd->conf->acct_server, NULL,
801 radius->acct_serv_sock, 0);
803 if (eloop_register_read_sock(radius->acct_serv_sock,
804 radius_client_receive, radius,
805 (void *) RADIUS_ACCT)) {
806 printf("Could not register read socket for accounting "
815 struct radius_client_data * radius_client_init(struct hostapd_data *hapd)
817 struct radius_client_data *radius;
819 radius = malloc(sizeof(struct radius_client_data));
823 memset(radius, 0, sizeof(struct radius_client_data));
825 radius->auth_serv_sock = radius->acct_serv_sock = -1;
827 if (hapd->conf->auth_server && radius_client_init_auth(radius)) {
828 radius_client_deinit(radius);
832 if (hapd->conf->acct_server && radius_client_init_acct(radius)) {
833 radius_client_deinit(radius);
837 if (hapd->conf->radius_retry_primary_interval)
838 eloop_register_timeout(hapd->conf->
839 radius_retry_primary_interval, 0,
840 radius_retry_primary_timer, radius,
847 void radius_client_deinit(struct radius_client_data *radius)
852 eloop_cancel_timeout(radius_retry_primary_timer, radius, NULL);
854 radius_client_flush(radius);
855 free(radius->auth_handlers);
856 free(radius->acct_handlers);
861 void radius_client_flush_auth(struct radius_client_data *radius, u8 *addr)
863 struct hostapd_data *hapd = radius->hapd;
864 struct radius_msg_list *entry, *prev, *tmp;
867 entry = radius->msgs;
869 if (entry->msg_type == RADIUS_AUTH &&
870 memcmp(entry->addr, addr, ETH_ALEN) == 0) {
871 hostapd_logger(hapd, addr, HOSTAPD_MODULE_RADIUS,
873 "Removing pending RADIUS authentication"
874 " message for removed client");
877 prev->next = entry->next;
879 radius->msgs = entry->next;
883 radius_client_msg_free(tmp);
894 static int radius_client_dump_auth_server(char *buf, size_t buflen,
895 struct hostapd_radius_server *serv,
896 struct radius_client_data *cli)
899 struct radius_msg_list *msg;
902 for (msg = cli->msgs; msg; msg = msg->next) {
903 if (msg->msg_type == RADIUS_AUTH)
908 return snprintf(buf, buflen,
909 "radiusAuthServerIndex=%d\n"
910 "radiusAuthServerAddress=%s\n"
911 "radiusAuthClientServerPortNumber=%d\n"
912 "radiusAuthClientRoundTripTime=%d\n"
913 "radiusAuthClientAccessRequests=%u\n"
914 "radiusAuthClientAccessRetransmissions=%u\n"
915 "radiusAuthClientAccessAccepts=%u\n"
916 "radiusAuthClientAccessRejects=%u\n"
917 "radiusAuthClientAccessChallenges=%u\n"
918 "radiusAuthClientMalformedAccessResponses=%u\n"
919 "radiusAuthClientBadAuthenticators=%u\n"
920 "radiusAuthClientPendingRequests=%u\n"
921 "radiusAuthClientTimeouts=%u\n"
922 "radiusAuthClientUnknownTypes=%u\n"
923 "radiusAuthClientPacketsDropped=%u\n",
925 inet_ntoa(serv->addr),
927 serv->round_trip_time,
929 serv->retransmissions,
930 serv->access_accepts,
931 serv->access_rejects,
932 serv->access_challenges,
933 serv->malformed_responses,
934 serv->bad_authenticators,
938 serv->packets_dropped);
942 static int radius_client_dump_acct_server(char *buf, size_t buflen,
943 struct hostapd_radius_server *serv,
944 struct radius_client_data *cli)
947 struct radius_msg_list *msg;
950 for (msg = cli->msgs; msg; msg = msg->next) {
951 if (msg->msg_type == RADIUS_ACCT ||
952 msg->msg_type == RADIUS_ACCT_INTERIM)
957 return snprintf(buf, buflen,
958 "radiusAccServerIndex=%d\n"
959 "radiusAccServerAddress=%s\n"
960 "radiusAccClientServerPortNumber=%d\n"
961 "radiusAccClientRoundTripTime=%d\n"
962 "radiusAccClientRequests=%u\n"
963 "radiusAccClientRetransmissions=%u\n"
964 "radiusAccClientResponses=%u\n"
965 "radiusAccClientMalformedResponses=%u\n"
966 "radiusAccClientBadAuthenticators=%u\n"
967 "radiusAccClientPendingRequests=%u\n"
968 "radiusAccClientTimeouts=%u\n"
969 "radiusAccClientUnknownTypes=%u\n"
970 "radiusAccClientPacketsDropped=%u\n",
972 inet_ntoa(serv->addr),
974 serv->round_trip_time,
976 serv->retransmissions,
978 serv->malformed_responses,
979 serv->bad_authenticators,
983 serv->packets_dropped);
987 int radius_client_get_mib(struct radius_client_data *radius, char *buf,
990 struct hostapd_data *hapd = radius->hapd;
992 struct hostapd_radius_server *serv;
995 if (hapd->conf->auth_servers) {
996 for (i = 0; i < hapd->conf->num_auth_servers; i++) {
997 serv = &hapd->conf->auth_servers[i];
998 count += radius_client_dump_auth_server(
999 buf + count, buflen - count, serv,
1000 serv == hapd->conf->auth_server ?
1005 if (hapd->conf->acct_servers) {
1006 for (i = 0; i < hapd->conf->num_acct_servers; i++) {
1007 serv = &hapd->conf->acct_servers[i];
1008 count += radius_client_dump_acct_server(
1009 buf + count, buflen - count, serv,
1010 serv == hapd->conf->acct_server ?