Home | History | Annotate | Download | only in hostapd
      1 /*
      2  * hostapd / State dump
      3  * Copyright (c) 2002-2009, Jouni Malinen <j (at) 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.
     13  */
     14 
     15 #include "utils/includes.h"
     16 
     17 #include "utils/common.h"
     18 #include "radius/radius_client.h"
     19 #include "radius/radius_server.h"
     20 #include "eapol_auth/eapol_auth_sm.h"
     21 #include "eapol_auth/eapol_auth_sm_i.h"
     22 #include "eap_server/eap.h"
     23 #include "ap/hostapd.h"
     24 #include "ap/ap_config.h"
     25 #include "ap/sta_info.h"
     26 #include "dump_state.h"
     27 
     28 
     29 static void fprint_char(FILE *f, char c)
     30 {
     31 	if (c >= 32 && c < 127)
     32 		fprintf(f, "%c", c);
     33 	else
     34 		fprintf(f, "<%02x>", c);
     35 }
     36 
     37 
     38 static void ieee802_1x_dump_state(FILE *f, const char *prefix,
     39 				  struct sta_info *sta)
     40 {
     41 	struct eapol_state_machine *sm = sta->eapol_sm;
     42 	if (sm == NULL)
     43 		return;
     44 
     45 	fprintf(f, "%sIEEE 802.1X:\n", prefix);
     46 
     47 	if (sm->identity) {
     48 		size_t i;
     49 		fprintf(f, "%sidentity=", prefix);
     50 		for (i = 0; i < sm->identity_len; i++)
     51 			fprint_char(f, sm->identity[i]);
     52 		fprintf(f, "\n");
     53 	}
     54 
     55 	fprintf(f, "%slast EAP type: Authentication Server: %d (%s) "
     56 		"Supplicant: %d (%s)\n", prefix,
     57 		sm->eap_type_authsrv,
     58 		eap_server_get_name(0, sm->eap_type_authsrv),
     59 		sm->eap_type_supp, eap_server_get_name(0, sm->eap_type_supp));
     60 
     61 	fprintf(f, "%scached_packets=%s\n", prefix,
     62 		sm->last_recv_radius ? "[RX RADIUS]" : "");
     63 
     64 	eapol_auth_dump_state(f, prefix, sm);
     65 }
     66 
     67 
     68 /**
     69  * hostapd_dump_state - SIGUSR1 handler to dump hostapd state to a text file
     70  */
     71 static void hostapd_dump_state(struct hostapd_data *hapd)
     72 {
     73 	FILE *f;
     74 	time_t now;
     75 	struct sta_info *sta;
     76 	int i;
     77 #ifndef CONFIG_NO_RADIUS
     78 	char *buf;
     79 #endif /* CONFIG_NO_RADIUS */
     80 
     81 	if (!hapd->conf->dump_log_name) {
     82 		wpa_printf(MSG_DEBUG, "Dump file not defined - ignoring dump "
     83 			   "request");
     84 		return;
     85 	}
     86 
     87 	wpa_printf(MSG_DEBUG, "Dumping hostapd state to '%s'",
     88 		   hapd->conf->dump_log_name);
     89 	f = fopen(hapd->conf->dump_log_name, "w");
     90 	if (f == NULL) {
     91 		wpa_printf(MSG_WARNING, "Could not open dump file '%s' for "
     92 			   "writing.", hapd->conf->dump_log_name);
     93 		return;
     94 	}
     95 
     96 	time(&now);
     97 	fprintf(f, "hostapd state dump - %s", ctime(&now));
     98 	fprintf(f, "num_sta=%d num_sta_non_erp=%d "
     99 		"num_sta_no_short_slot_time=%d\n"
    100 		"num_sta_no_short_preamble=%d\n",
    101 		hapd->num_sta, hapd->iface->num_sta_non_erp,
    102 		hapd->iface->num_sta_no_short_slot_time,
    103 		hapd->iface->num_sta_no_short_preamble);
    104 
    105 	for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
    106 		fprintf(f, "\nSTA=" MACSTR "\n", MAC2STR(sta->addr));
    107 
    108 		fprintf(f,
    109 			"  AID=%d flags=0x%x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
    110 			"  capability=0x%x listen_interval=%d\n",
    111 			sta->aid,
    112 			sta->flags,
    113 			(sta->flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
    114 			(sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
    115 			(sta->flags & WLAN_STA_PS ? "[PS]" : ""),
    116 			(sta->flags & WLAN_STA_TIM ? "[TIM]" : ""),
    117 			(sta->flags & WLAN_STA_PERM ? "[PERM]" : ""),
    118 			(ap_sta_is_authorized(sta) ? "[AUTHORIZED]" : ""),
    119 			(sta->flags & WLAN_STA_PENDING_POLL ? "[PENDING_POLL" :
    120 			 ""),
    121 			(sta->flags & WLAN_STA_SHORT_PREAMBLE ?
    122 			 "[SHORT_PREAMBLE]" : ""),
    123 			(sta->flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
    124 			(sta->flags & WLAN_STA_WMM ? "[WMM]" : ""),
    125 			(sta->flags & WLAN_STA_MFP ? "[MFP]" : ""),
    126 			(sta->flags & WLAN_STA_WPS ? "[WPS]" : ""),
    127 			(sta->flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
    128 			(sta->flags & WLAN_STA_WDS ? "[WDS]" : ""),
    129 			(sta->flags & WLAN_STA_NONERP ? "[NonERP]" : ""),
    130 			sta->capability,
    131 			sta->listen_interval);
    132 
    133 		fprintf(f, "  supported_rates=");
    134 		for (i = 0; i < sta->supported_rates_len; i++)
    135 			fprintf(f, "%02x ", sta->supported_rates[i]);
    136 		fprintf(f, "\n");
    137 
    138 		fprintf(f,
    139 			"  timeout_next=%s\n",
    140 			(sta->timeout_next == STA_NULLFUNC ? "NULLFUNC POLL" :
    141 			 (sta->timeout_next == STA_DISASSOC ? "DISASSOC" :
    142 			  "DEAUTH")));
    143 
    144 		ieee802_1x_dump_state(f, "  ", sta);
    145 	}
    146 
    147 #ifndef CONFIG_NO_RADIUS
    148 	buf = os_malloc(4096);
    149 	if (buf) {
    150 		int count = radius_client_get_mib(hapd->radius, buf, 4096);
    151 		if (count < 0)
    152 			count = 0;
    153 		else if (count > 4095)
    154 			count = 4095;
    155 		buf[count] = '\0';
    156 		fprintf(f, "%s", buf);
    157 
    158 #ifdef RADIUS_SERVER
    159 		count = radius_server_get_mib(hapd->radius_srv, buf, 4096);
    160 		if (count < 0)
    161 			count = 0;
    162 		else if (count > 4095)
    163 			count = 4095;
    164 		buf[count] = '\0';
    165 		fprintf(f, "%s", buf);
    166 #endif /* RADIUS_SERVER */
    167 
    168 		os_free(buf);
    169 	}
    170 #endif /* CONFIG_NO_RADIUS */
    171 	fclose(f);
    172 }
    173 
    174 
    175 int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx)
    176 {
    177 	size_t i;
    178 
    179 	for (i = 0; i < iface->num_bss; i++)
    180 		hostapd_dump_state(iface->bss[i]);
    181 
    182 	return 0;
    183 }
    184