[OpenWrt-Devel] [PATCH] hostapd: Add client association log file
Stefan Tomanek
stefan.tomanek+openwrt at wertarbyte.de
Wed Jan 21 08:59:12 EST 2015
This change adds the configuration option "assoc_log_file" to hostapd, making
it possible to specify a log file to which clients joining and parting the
corresponding BSS are written.
Every BSS can have an individual log file, and each entry written contains a
timestamp, an indicator whether the client is associating (+) or disassociating
(-), the client and the bss hardware addresses as well as the device and SSID
identifiers of the affected network. This makes it easy to join the file with
the leases database of an DHCP server like dnsmasq.
To use a logfile with OpenWrt, simply add an assoc_log_file entry to the
wireless network:
config wifi-iface
option device 'radio1'
option network 'hotspot'
option ssid 'MyNetwork'
option mode 'ap'
option encryption 'none'
option assoc_log_file '/tmp/assoc_log-hotspot'
Signed-off-by: Stefan Tomanek <stefan.tomanek+openwrt at wertarbyte.de>
---
package/network/services/hostapd/files/netifd.sh | 7 +-
...rite-client-dis-associations-to-a-logfile.patch | 231 ++++++++++++++++++++
2 files changed, 237 insertions(+), 1 deletions(-)
create mode 100644 package/network/services/hostapd/patches/720-Write-client-dis-associations-to-a-logfile.patch
diff --git a/package/network/services/hostapd/files/netifd.sh b/package/network/services/hostapd/files/netifd.sh
index ed2a631..be94398 100644
--- a/package/network/services/hostapd/files/netifd.sh
+++ b/package/network/services/hostapd/files/netifd.sh
@@ -159,6 +159,8 @@ hostapd_common_add_bss_config() {
config_add_int mcast_rate
config_add_array basic_rate
config_add_array supported_rates
+
+ config_add_string assoc_log_file
}
hostapd_set_bss_options() {
@@ -177,7 +179,7 @@ hostapd_set_bss_options() {
wps_pushbutton wps_label ext_registrar wps_pbc_in_m1 \
wps_device_type wps_device_name wps_manufacturer wps_pin \
macfilter ssid wmm uapsd hidden short_preamble rsn_preauth \
- iapp_interface
+ iapp_interface assoc_log_file
set_default isolate 0
set_default maxassoc 0
@@ -189,6 +191,9 @@ hostapd_set_bss_options() {
set_default uapsd 1
append bss_conf "ctrl_interface=/var/run/hostapd"
+ if [ "$assoc_log_file" ]; then
+ append bss_conf "assoc_log_file=$assoc_log_file" "$N"
+ fi
if [ "$isolate" -gt 0 ]; then
append bss_conf "ap_isolate=$isolate" "$N"
fi
diff --git a/package/network/services/hostapd/patches/720-Write-client-dis-associations-to-a-logfile.patch b/package/network/services/hostapd/patches/720-Write-client-dis-associations-to-a-logfile.patch
new file mode 100644
index 0000000..7a87529
--- /dev/null
+++ b/package/network/services/hostapd/patches/720-Write-client-dis-associations-to-a-logfile.patch
@@ -0,0 +1,231 @@
+Write client (dis)associations to a logfile
+
+This change adds the configuration option "assoc_log_file" to hostapd, making
+it possible to specify a log file to which clients joining and parting the
+corresponding BSS are written.
+
+Every BSS can have an individual log file, and each entry written contains a
+timestamp, an indicator whether the client is associating (+) or disassociating
+(-), the client and the bss hardware addresses as well as the device and SSID
+identifiers of the affected network. This makes it easy to join the file with
+the leases database of an DHCP server like dnsmasq.
+---
+ hostapd/config_file.c | 3 +++
+ hostapd/hostapd.conf | 3 +++
+ hostapd/main.c | 6 ++++++
+ src/ap/ap_config.c | 27 +++++++++++++++++++++++++++
+ src/ap/ap_config.h | 5 +++++
+ src/ap/ap_mlme.c | 26 ++++++++++++++++++++++++++
+ src/ap/hostapd.c | 4 ++++
+ src/ap/hostapd.h | 2 ++
+ 8 files changed, 76 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index ddebf1f..827f9b4 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -1876,6 +1876,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ bss->logger_syslog = atoi(pos);
+ } else if (os_strcmp(buf, "logger_stdout") == 0) {
+ bss->logger_stdout = atoi(pos);
++ } else if (os_strcmp(buf, "assoc_log_file") == 0) {
++ os_free(bss->assoc_log_file);
++ bss->assoc_log_file = os_strdup(pos);
+ } else if (os_strcmp(buf, "dump_file") == 0) {
+ wpa_printf(MSG_INFO, "Line %d: DEPRECATED: 'dump_file' configuration variable is not used anymore",
+ line);
+diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
+index 2e6f841..31b2193 100644
+--- a/hostapd/hostapd.conf
++++ b/hostapd/hostapd.conf
+@@ -51,6 +51,9 @@ logger_syslog_level=2
+ logger_stdout=-1
+ logger_stdout_level=2
+
++# Clients joining or departing the AP can be logged to a separate file.
++assoc_log_file=/tmp/assoc_log-wlan0
++
+ # Interface for separate control program. If this is specified, hostapd
+ # will create this directory and a UNIX domain socket for listening to requests
+ # from external programs (CLI/GUI, etc.) for status information and
+diff --git a/hostapd/main.c b/hostapd/main.c
+index 5a47711..38a9ab2 100644
+--- a/hostapd/main.c
++++ b/hostapd/main.c
+@@ -258,6 +258,12 @@ hostapd_interface_init(struct hapd_interfaces *interfaces,
+ return NULL;
+ }
+
++ for (k = 0; k < iface->conf->num_bss; k++) {
++ int r = hostapd_open_assoc_log(iface->bss[k]);
++ if (r < 0)
++ return NULL;
++ }
++
+ return iface;
+ }
+
+diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
+index 90f1630..6d7389f 100644
+--- a/src/ap/ap_config.c
++++ b/src/ap/ap_config.c
+@@ -6,6 +6,8 @@
+ * See README for more details.
+ */
+
++#include <fcntl.h>
++
+ #include "utils/includes.h"
+
+ #include "utils/common.h"
+@@ -18,6 +20,7 @@
+ #include "wpa_auth.h"
+ #include "sta_info.h"
+ #include "ap_config.h"
++#include "hostapd.h"
+
+
+ static void hostapd_config_free_vlan(struct hostapd_bss_config *bss)
+@@ -201,6 +204,30 @@ int hostapd_mac_comp_empty(const void *a)
+ return os_memcmp(a, empty, sizeof(macaddr));
+ }
+
++int hostapd_open_assoc_log(struct hostapd_data *bss)
++{
++ char *alog = bss->conf->assoc_log_file;
++ if (alog) {
++ int fd = open(alog, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW, 0600);
++ if (fd < 0) {
++ wpa_printf(MSG_ERROR, "Error opening association log file '%s'\n", alog);
++ return -1;
++ }
++ bss->assoc_log_fd = fd;
++ return 1;
++ } else {
++ bss->assoc_log_fd = -1;
++ }
++ return 0;
++}
++
++void hostapd_close_assoc_log(struct hostapd_data *bss)
++{
++ if (bss->assoc_log_fd != -1) {
++ close(bss->assoc_log_fd);
++ bss->assoc_log_fd = -1;
++ }
++}
+
+ static int hostapd_config_read_wpa_psk(const char *fname,
+ struct hostapd_ssid *ssid)
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 18538c9..205ff42 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -217,6 +217,8 @@ struct hostapd_bss_config {
+ unsigned int logger_syslog; /* module bitfield */
+ unsigned int logger_stdout; /* module bitfield */
+
++ char *assoc_log_file;
++
+ int max_num_sta; /* maximum number of STAs in station table */
+
+ int dtim_period;
+@@ -629,6 +631,9 @@ struct hostapd_config {
+ #endif /* CONFIG_ACS */
+ };
+
++struct hostapd_data;
++int hostapd_open_assoc_log(struct hostapd_data *bss);
++void hostapd_close_assoc_log(struct hostapd_data *bss);
+
+ int hostapd_mac_comp(const void *a, const void *b);
+ int hostapd_mac_comp_empty(const void *a);
+diff --git a/src/ap/ap_mlme.c b/src/ap/ap_mlme.c
+index 13604ed..2dd7d72 100644
+--- a/src/ap/ap_mlme.c
++++ b/src/ap/ap_mlme.c
+@@ -35,6 +35,23 @@ static const char * mlme_auth_alg_str(int alg)
+ }
+ #endif /* CONFIG_NO_HOSTAPD_LOGGER */
+
++static void write_assoc_log(struct hostapd_data *hapd, struct sta_info *sta, char op) {
++ struct os_time now;
++ int fd = hapd->assoc_log_fd;
++ if (fd >= 0) {
++ os_get_time(&now);
++ char msg[100];
++ sprintf(msg,
++ "%lu\t" MACSTR "\t%c\t%s\t" MACSTR "\t'%s'\n",
++ now.sec,
++ MAC2STR(sta->addr),
++ op,
++ hapd->conf->iface,
++ MAC2STR(hapd->own_addr),
++ wpa_ssid_txt(sta->ssid->ssid, sta->ssid->ssid_len));
++ write(fd, msg, strlen(msg));
++ }
++}
+
+ /**
+ * mlme_authenticate_indication - Report the establishment of an authentication
+@@ -104,6 +121,9 @@ void mlme_associate_indication(struct hostapd_data *hapd, struct sta_info *sta)
+ HOSTAPD_LEVEL_DEBUG,
+ "MLME-ASSOCIATE.indication(" MACSTR ")",
+ MAC2STR(sta->addr));
++
++ write_assoc_log(hapd, sta, '+');
++
+ if (sta->auth_alg != WLAN_AUTH_FT)
+ mlme_deletekeys_request(hapd, sta);
+ }
+@@ -128,6 +148,9 @@ void mlme_reassociate_indication(struct hostapd_data *hapd,
+ HOSTAPD_LEVEL_DEBUG,
+ "MLME-REASSOCIATE.indication(" MACSTR ")",
+ MAC2STR(sta->addr));
++
++ write_assoc_log(hapd, sta, '@');
++
+ if (sta->auth_alg != WLAN_AUTH_FT)
+ mlme_deletekeys_request(hapd, sta);
+ }
+@@ -152,6 +175,9 @@ void mlme_disassociate_indication(struct hostapd_data *hapd,
+ HOSTAPD_LEVEL_DEBUG,
+ "MLME-DISASSOCIATE.indication(" MACSTR ", %d)",
+ MAC2STR(sta->addr), reason_code);
++
++ write_assoc_log(hapd, sta, '-');
++
+ mlme_deletekeys_request(hapd, sta);
+ }
+
+diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
+index 9fda339..8157a08 100644
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -70,6 +70,10 @@ static void hostapd_reload_bss(struct hostapd_data *hapd)
+ radius_client_reconfig(hapd->radius, hapd->conf->radius);
+ #endif /* CONFIG_NO_RADIUS */
+
++ /* close and reopen assoc_log */
++ hostapd_close_assoc_log(hapd);
++ hostapd_open_assoc_log(hapd);
++
+ ssid = &hapd->conf->ssid;
+ if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
+ ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
+diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
+index 3f79413..891c453 100644
+--- a/src/ap/hostapd.h
++++ b/src/ap/hostapd.h
+@@ -113,6 +113,8 @@ struct hostapd_data {
+ #define STA_HASH(sta) (sta[5])
+ struct sta_info *sta_hash[STA_HASH_SIZE];
+
++ int assoc_log_fd;
++
+ /*
+ * Bitfield for indicating which AIDs are allocated. Only AID values
+ * 1-2007 are used and as such, the bit at index 0 corresponds to AID
+--
+2.1.3
+
--
1.7.2.5
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list