static void request_stats_reply(REQUEST *request) { VALUE_PAIR *flag, *vp; /* * Statistics are available ONLY on a "status" port. */ rad_assert(request->packet->code == PW_STATUS_SERVER); rad_assert(request->listener->type == RAD_LISTEN_NONE); flag = pairfind(request->packet->vps, FR2ATTR(127)); if (!flag || (flag->vp_integer == 0)) return; /* * Authentication. */ if (((flag->vp_integer & 0x01) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, authvp, &radius_auth_stats); } #ifdef WITH_ACCOUNTING /* * Accounting */ if (((flag->vp_integer & 0x02) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, acctvp, &radius_acct_stats); } #endif #ifdef WITH_PROXY /* * Proxied authentication requests. */ if (((flag->vp_integer & 0x04) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_authvp, &proxy_auth_stats); } #ifdef WITH_ACCOUNTING /* * Proxied accounting requests. */ if (((flag->vp_integer & 0x08) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats); } #endif #endif /* * Internal server statistics */ if ((flag->vp_integer & 0x10) != 0) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(176), PW_TYPE_DATE); if (vp) vp->vp_date = radius_start_time.tv_sec; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(177), PW_TYPE_DATE); if (vp) vp->vp_date = radius_hup_time.tv_sec; #ifdef HAVE_PTHREAD_H int i, array[RAD_LISTEN_MAX]; thread_pool_queue_stats(array); for (i = 0; i <= RAD_LISTEN_DETAIL; i++) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(162 + i), PW_TYPE_INTEGER); if (!vp) continue; vp->vp_integer = array[i]; } #endif } /* * For a particular client. */ if ((flag->vp_integer & 0x20) != 0) { fr_ipaddr_t ipaddr; VALUE_PAIR *server_ip, *server_port = NULL; RADCLIENT *client = NULL; RADCLIENT_LIST *cl = NULL; /* * See if we need to look up the client by server * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (server_ip) { server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (server_port) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; cl = listener_find_client_list(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!cl) return; } } vp = pairfind(request->packet->vps, FR2ATTR(167)); if (vp) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; client = client_find(cl, &ipaddr); /* * Else look it up by number. */ } else if ((vp = pairfind(request->packet->vps, FR2ATTR(168))) != NULL) { client = client_findbynumber(cl, vp->vp_integer); } if (client) { /* * If found, echo it back, along with * the requested statistics. */ pairadd(&request->reply->vps, paircopyvp(vp)); /* * When retrieving client by number, also * echo back it's IP address. */ if ((vp->type == PW_TYPE_INTEGER) && (client->ipaddr.af == AF_INET)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(167), PW_TYPE_IPADDR); if (vp) { vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr; } if (client->prefix != 32) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(169), PW_TYPE_INTEGER); if (vp) { vp->vp_integer = client->prefix; } } } if (server_ip) { pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); } if (client->auth && ((flag->vp_integer & 0x01) != 0)) { request_stats_addvp(request, client_authvp, client->auth); } #ifdef WITH_ACCOUNTING if (client->acct && ((flag->vp_integer & 0x01) != 0)) { request_stats_addvp(request, client_acctvp, client->acct); } #endif } /* else client wasn't found, don't echo it back */ } /* * For a particular "listen" socket. */ if (((flag->vp_integer & 0x40) != 0) && ((flag->vp_integer & 0x03) != 0)) { rad_listen_t *this; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (!server_ip) return; server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; this = listener_find_byipaddr(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!this) return; pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); if (((flag->vp_integer & 0x01) != 0) && ((request->listener->type == RAD_LISTEN_AUTH) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, authvp, &this->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && ((request->listener->type == RAD_LISTEN_ACCT) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, acctvp, &this->stats); } #endif } /* * Home servers. */ if (((flag->vp_integer & 0x80) != 0) && ((flag->vp_integer & 0x03) != 0)) { home_server *home; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (!server_ip) return; server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; home = home_server_find(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!home) return; pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(172), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->currently_outstanding; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(173), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->state; if ((home->state == HOME_STATE_ALIVE) && (home->revive_time.tv_sec != 0)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(175), PW_TYPE_DATE); if (vp) vp->vp_date = home->revive_time.tv_sec; } if ((home->state == HOME_STATE_ALIVE) && (home->ema.window > 0)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(178), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.window; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(179), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(180), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE; } if (home->state == HOME_STATE_IS_DEAD) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(174), PW_TYPE_DATE); if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period; } if (((flag->vp_integer & 0x01) != 0) && (home->type == HOME_TYPE_AUTH)) { request_stats_addvp(request, proxy_authvp, &home->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && (home->type == HOME_TYPE_ACCT)) { request_stats_addvp(request, proxy_acctvp, &home->stats); } #endif } }
void request_stats_reply(REQUEST *request) { VALUE_PAIR *flag, *vp; /* * Statistics are available ONLY on a "status" port. */ rad_assert(request->packet->code == PW_CODE_STATUS_SERVER); rad_assert(request->listener->type == RAD_LISTEN_NONE); flag = pairfind(request->packet->vps, 127, VENDORPEC_FREERADIUS, TAG_ANY); if (!flag || (flag->vp_integer == 0)) return; /* * Authentication. */ if (((flag->vp_integer & 0x01) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, authvp, &radius_auth_stats); } #ifdef WITH_ACCOUNTING /* * Accounting */ if (((flag->vp_integer & 0x02) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, acctvp, &radius_acct_stats); } #endif #ifdef WITH_PROXY /* * Proxied authentication requests. */ if (((flag->vp_integer & 0x04) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_authvp, &proxy_auth_stats); } #ifdef WITH_ACCOUNTING /* * Proxied accounting requests. */ if (((flag->vp_integer & 0x08) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats); } #endif #endif /* * Internal server statistics */ if ((flag->vp_integer & 0x10) != 0) { vp = radius_paircreate(request->reply, &request->reply->vps, 176, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = start_time.tv_sec; vp = radius_paircreate(request->reply, &request->reply->vps, 177, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = hup_time.tv_sec; #ifdef HAVE_PTHREAD_H int i, array[RAD_LISTEN_MAX], pps[2]; thread_pool_queue_stats(array, pps); for (i = 0; i <= 4; i++) { vp = radius_paircreate(request->reply, &request->reply->vps, 162 + i, VENDORPEC_FREERADIUS); if (!vp) continue; vp->vp_integer = array[i]; } for (i = 0; i < 2; i++) { vp = radius_paircreate(request->reply, &request->reply->vps, 181 + i, VENDORPEC_FREERADIUS); if (!vp) continue; vp->vp_integer = pps[i]; } #endif } /* * For a particular client. */ if ((flag->vp_integer & 0x20) != 0) { fr_ipaddr_t ipaddr; VALUE_PAIR *server_ip, *server_port = NULL; RADCLIENT *client = NULL; RADCLIENT_LIST *cl = NULL; /* * See if we need to look up the client by server * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (server_ip) { server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (server_port) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; cl = listener_find_client_list(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!cl) return; } } vp = pairfind(request->packet->vps, 167, VENDORPEC_FREERADIUS, TAG_ANY); if (vp) { memset(&ipaddr, 0, sizeof(ipaddr)); ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; client = client_find(cl, &ipaddr, IPPROTO_UDP); #ifdef WITH_TCP if (!client) { client = client_find(cl, &ipaddr, IPPROTO_TCP); } #endif /* * Else look it up by number. */ } else if ((vp = pairfind(request->packet->vps, 168, VENDORPEC_FREERADIUS, TAG_ANY)) != NULL) { client = client_findbynumber(cl, vp->vp_integer); } if (client) { /* * If found, echo it back, along with * the requested statistics. */ pairadd(&request->reply->vps, paircopyvp(request->reply, vp)); /* * When retrieving client by number, also * echo back it's IP address. */ if ((vp->da->type == PW_TYPE_INTEGER) && (client->ipaddr.af == AF_INET)) { vp = radius_paircreate(request->reply, &request->reply->vps, 167, VENDORPEC_FREERADIUS); if (vp) { vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr; } if (client->ipaddr.prefix != 32) { vp = radius_paircreate(request->reply, &request->reply->vps, 169, VENDORPEC_FREERADIUS); if (vp) { vp->vp_integer = client->ipaddr.prefix; } } } if (server_ip) { pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); } if (server_port) { pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); } if ((flag->vp_integer & 0x01) != 0) { request_stats_addvp(request, client_authvp, &client->auth); } #ifdef WITH_ACCOUNTING if ((flag->vp_integer & 0x01) != 0) { request_stats_addvp(request, client_acctvp, &client->acct); } #endif } /* else client wasn't found, don't echo it back */ } /* * For a particular "listen" socket. */ if (((flag->vp_integer & 0x40) != 0) && ((flag->vp_integer & 0x03) != 0)) { rad_listen_t *this; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_ip) return; server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; this = listener_find_byipaddr(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!this) return; pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); if (((flag->vp_integer & 0x01) != 0) && ((request->listener->type == RAD_LISTEN_AUTH) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, authvp, &this->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && ((request->listener->type == RAD_LISTEN_ACCT) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, acctvp, &this->stats); } #endif } #ifdef WITH_PROXY /* * Home servers. */ if (((flag->vp_integer & 0x80) != 0) && ((flag->vp_integer & 0x03) != 0)) { home_server_t *home; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_ip) return; server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_port) return; #ifndef NDEBUG memset(&ipaddr, 0, sizeof(ipaddr)); #endif ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; home = home_server_find(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!home) return; pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); vp = radius_paircreate(request->reply, &request->reply->vps, 172, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->currently_outstanding; vp = radius_paircreate(request->reply, &request->reply->vps, 173, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->state; if ((home->state == HOME_STATE_ALIVE) && (home->revive_time.tv_sec != 0)) { vp = radius_paircreate(request->reply, &request->reply->vps, 175, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->revive_time.tv_sec; } if ((home->state == HOME_STATE_ALIVE) && (home->ema.window > 0)) { vp = radius_paircreate(request->reply, &request->reply->vps, 178, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.window; vp = radius_paircreate(request->reply, &request->reply->vps, 179, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE; vp = radius_paircreate(request->reply, &request->reply->vps, 180, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE; } if (home->state == HOME_STATE_IS_DEAD) { vp = radius_paircreate(request->reply, &request->reply->vps, 174, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period; } /* * Show more information... * * FIXME: do this for clients, too! */ vp = radius_paircreate(request->reply, &request->reply->vps, 184, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->last_packet_recv; vp = radius_paircreate(request->reply, &request->reply->vps, 185, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->last_packet_sent; if (((flag->vp_integer & 0x01) != 0) && (home->type == HOME_TYPE_AUTH)) { request_stats_addvp(request, proxy_authvp, &home->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && (home->type == HOME_TYPE_ACCT)) { request_stats_addvp(request, proxy_acctvp, &home->stats); } #endif } #endif /* WITH_PROXY */ }