aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan McCrohan <jmccrohan@gmail.com>2017-01-02 22:42:44 +0000
committerJonathan McCrohan <jmccrohan@gmail.com>2017-01-02 22:42:44 +0000
commit500e758260355fec650c55e9235de7a721ca5761 (patch)
tree3b9620186b9608d93c9ab89ad584e4f2b76094eb
parent7ca6b0f4a7eea4cd8fc40a3fd60c8d616f31220a (diff)
parent5744c3a0214950433c3a4375798c1c8eba1b398c (diff)
downloadwavemon-500e758260355fec650c55e9235de7a721ca5761.tar.gz
Merge tag 'upstream/0.8.1'
Upstream version 0.8.1
-rw-r--r--README.md30
-rw-r--r--conf.c32
-rw-r--r--info_scr.c227
-rw-r--r--iw_if.c31
-rw-r--r--iw_if.h44
-rw-r--r--lhist_scr.c21
-rw-r--r--timer.c41
-rw-r--r--wavemon.110
-rw-r--r--wavemon.h12
9 files changed, 178 insertions, 270 deletions
diff --git a/README.md b/README.md
index 637f639..e0167f1 100644
--- a/README.md
+++ b/README.md
@@ -12,13 +12,26 @@ See the man page for an in-depth description of operation and configuration.
### Where to obtain
-Apart from debian/ubuntu packages (apt-cache search wavemon) and slackbuild
-scripts for wavemon on slackbuilds.org, this repository contains the full
-source code.
+Apart from debian/ubuntu packages (`apt-cache search wavemon`) and [slackbuild scripts for wavemon](https://slackbuilds.org/result/?search=wavemon&sv=), this repository contains the full source code.
+
+Please check [this page](#) for updates and for further information.
-Please check this page for updates and for further information.
wavemon is distributed under the [GPLv3](http://www.gnu.org/licenses/gpl-3.0.en.html), refer to the file `COPYING`.
+### Dependencies
+
+wavemon requires a Linux Kernel with wireless extensions enabled. If your Kernel setup uses `CONFIG_CFG80211`, make sure that the config option `CONFIG_CFG80211_WEXT` is set.
+
+In addition, minimally the following are required:
+* Netlink `libnl` at least version 3.2,
+* including the Generic Netlink support (`libnl-genl`),
+* ncurses development files (`libncurses5-dev`),
+* the `pkg-config` package.
+
+On Debian/Ubuntu, this can be done using
+```bash
+ apt-get -y install pkg-config libncurses5-dev libnl-3-dev libnl-genl-3-dev
+```
## How to build
@@ -31,12 +44,6 @@ wavemon uses `autoconf`, so that in most cases you can simply run
to build and install the package. Type 'make uninstall' if not happy.
Refer to the file `INSTALL` for generic installation instructions.
-**Dependencies**: at least version 3.2 of `libnl`, including the Generic Netlink support (`libnl-genl`).
-On Debian/Ubuntu, this can be done using
-```bash
- apt-get -y install libnl-3-dev libnl-genl-3-dev
-```
-
To grant users access to restricted networking operations (scan operations), use additionally
```
sudo make install-suid-root
@@ -45,8 +52,7 @@ If you have changed some of the autoconf files or use a git version, run
```
./config/bootstrap
```
-(requires a recent installation of `autotools`).
-
+(This requires a recent installation of `autotools`.)
## Bugs?
diff --git a/conf.c b/conf.c
index 27c11dc..294564b 100644
--- a/conf.c
+++ b/conf.c
@@ -20,6 +20,7 @@
#include "wavemon.h"
#include <pwd.h>
#include <sys/types.h>
+#include <netlink/version.h>
/* GLOBALS */
#define MAX_IFLIST_ENTRIES 64
@@ -94,7 +95,7 @@ void conf_get_interface_list(void)
}
iw_get_interface_list(if_list, MAX_IFLIST_ENTRIES);
if (!if_list[0])
- err_quit("no supported wireless interfaces found!");
+ err_quit("no supported wireless interfaces found! Check manpage for help.");
conf.if_idx = 0;
if (old_if) {
@@ -529,10 +530,7 @@ static void init_conf_items(void)
void getconf(int argc, char *argv[])
{
int arg, help = 0, version = 0;
-
- conf_get_interface_list();
- init_conf_items();
- read_cf();
+ const char *iface = NULL;
while ((arg = getopt(argc, argv, "ghi:v")) >= 0) {
switch (arg) {
@@ -543,10 +541,7 @@ void getconf(int argc, char *argv[])
help++;
break;
case 'i':
- conf.if_idx = argv_find(if_list, optarg);
- if (conf.if_idx < 0)
- err_quit("no wireless extensions found on '%s'",
- optarg);
+ iface = optarg;
break;
case 'v':
version++;
@@ -557,8 +552,7 @@ void getconf(int argc, char *argv[])
}
if (version) {
- printf("wavemon %s", PACKAGE_VERSION);
- printf(" with %s.\n", curses_version());
+ printf("wavemon %s\n", PACKAGE_VERSION);
printf("Distributed under the terms of the GPLv3.\n%s", help ? "\n" : "");
}
if (help) {
@@ -566,9 +560,21 @@ void getconf(int argc, char *argv[])
printf(" -g Ensure screen is sufficiently dimensioned\n");
printf(" -h This help screen\n");
printf(" -i <ifname> Use specified network interface (default: auto)\n");
- printf(" -v Print version number\n");
+ printf(" -v Print version details\n");
}
- if (version || help)
+ if (version || help) {
exit(EXIT_SUCCESS);
+ }
+
+ /* Actual initialization. */
+ conf_get_interface_list();
+ init_conf_items();
+ read_cf();
+
+ if (iface) {
+ conf.if_idx = argv_find(if_list, iface);
+ if (conf.if_idx < 0)
+ err_quit("%s is not a usable wireless interface", iface);
+ }
}
diff --git a/info_scr.c b/info_scr.c
index 6a50b43..55a3bbc 100644
--- a/info_scr.c
+++ b/info_scr.c
@@ -22,29 +22,45 @@
/* GLOBALS */
static WINDOW *w_levels, *w_stats, *w_if, *w_info, *w_net;
-static struct timer dyn_updates;
-struct iw_range range;
-static struct iw_nl80211_linkstat ls;
-
-void sampling_init(void (*sampling_handler)(int))
+static pthread_t sampling_thread;
+static time_t last_update;
+// Global linkstat data, populated by sampling thread.
+static struct {
+ bool run; // enable/disable sampling
+ pthread_mutex_t mutex; // producer/consumer lock for @data
+ struct iw_nl80211_linkstat data;
+} linkstat;
+
+/** Sampling pthread shared by info and histogram screen. */
+static void *sampling_loop(void *arg)
{
- struct itimerval i;
- div_t d = div(conf.stat_iv, 1000); /* conf.stat_iv in msec */
+ sigset_t blockmask;
- xsignal(SIGALRM, SIG_IGN);
- iw_getinf_range(conf_ifname(), &range);
- i.it_interval.tv_sec = i.it_value.tv_sec = d.quot;
- i.it_interval.tv_usec = i.it_value.tv_usec = d.rem * 1000;
- xsignal(SIGALRM, sampling_handler);
+ /* See comment in scan_scr.c for rationale. */
+ sigemptyset(&blockmask);
+ sigaddset(&blockmask, SIGWINCH);
+ pthread_sigmask(SIG_BLOCK, &blockmask, NULL);
+
+ do {
+ pthread_mutex_lock(&linkstat.mutex);
+ iw_nl80211_get_linkstat(&linkstat.data);
+ pthread_mutex_unlock(&linkstat.mutex);
- (*sampling_handler)(0);
- setitimer(ITIMER_REAL, &i, NULL);
+ iw_cache_update(&linkstat.data);
+ } while (linkstat.run && usleep(conf.stat_iv * 1000) == 0);
+ return NULL;
}
-void sampling_do_poll(void)
+void sampling_init(void)
{
- iw_nl80211_get_linkstat(&ls);
- iw_cache_update(&ls);
+ linkstat.run = true;
+ pthread_create(&sampling_thread, NULL, sampling_loop, NULL);
+}
+
+void sampling_stop(void)
+{
+ linkstat.run = false;
+ pthread_join(sampling_thread, NULL);
}
static void display_levels(void)
@@ -59,21 +75,23 @@ static void display_levels(void)
lvlscale[2] = { -40, -20};
char tmp[0x100];
int line;
- bool noise_data_valid = iw_nl80211_have_survey_data(&ls);
- int sig_qual = -1;
- int sig_qual_max;
- int sig_level = ls.signal_avg ?: ls.signal;
+ bool noise_data_valid;
+ int sig_qual = -1, sig_qual_max, sig_level;
+
+
+ noise_data_valid = iw_nl80211_have_survey_data(&linkstat.data);
+ sig_level = linkstat.data.signal_avg ?: linkstat.data.signal;
/* See comments in iw_cache_update */
if (sig_level == 0)
- sig_level = ls.bss_signal;
+ sig_level = linkstat.data.bss_signal;
for (line = 1; line <= WH_LEVEL; line++)
mvwclrtoborder(w_levels, line, 1);
- if (ls.bss_signal_qual) {
+ if (linkstat.data.bss_signal_qual) {
/* BSS_SIGNAL_UNSPEC is scaled 0..100 */
- sig_qual = ls.bss_signal_qual;
+ sig_qual = linkstat.data.bss_signal_qual;
sig_qual_max = 100;
} else if (sig_level) {
if (sig_level < -110)
@@ -136,7 +154,7 @@ static void display_levels(void)
line++;
if (noise_data_valid) {
- noise = ewma(noise, ls.survey.noise, conf.meter_decay / 100.0);
+ noise = ewma(noise, linkstat.data.survey.noise, conf.meter_decay / 100.0);
mvwaddstr(w_levels, line++, 1, "noise level: ");
sprintf(tmp, "%.0f dBm (%s)", noise, dbm2units(noise));
@@ -147,7 +165,7 @@ static void display_levels(void)
}
if (noise_data_valid && sig_level) {
- ssnr = ewma(ssnr, sig_level - ls.survey.noise,
+ ssnr = ewma(ssnr, sig_level - linkstat.data.survey.noise,
conf.meter_decay / 100.0);
mvwaddstr(w_levels, line++, 1, "SNR: ");
@@ -161,42 +179,39 @@ done_levels:
static void display_stats(void)
{
- struct if_stat nstat;
char tmp[0x100];
- if_getstat(conf_ifname(), &nstat);
-
/*
* Interface RX stats
*/
mvwaddstr(w_stats, 1, 1, "RX: ");
- if (ls.rx_packets) {
- sprintf(tmp, "%'u (%s)", ls.rx_packets,
- byte_units(ls.rx_bytes));
+ if (linkstat.data.rx_packets) {
+ sprintf(tmp, "%'u (%s)", linkstat.data.rx_packets,
+ byte_units(linkstat.data.rx_bytes));
waddstr_b(w_stats, tmp);
} else {
waddstr(w_stats, "n/a");
}
- if (iw_nl80211_have_survey_data(&ls)) {
- if (ls.rx_bitrate[0]) {
+ if (iw_nl80211_have_survey_data(&linkstat.data)) {
+ if (linkstat.data.rx_bitrate[0]) {
waddstr(w_stats, ", rate: ");
- waddstr_b(w_stats, ls.rx_bitrate);
+ waddstr_b(w_stats, linkstat.data.rx_bitrate);
}
- if (ls.expected_thru) {
- if (ls.expected_thru >= 1024)
- sprintf(tmp, " (exp: %.1f MB/s)", ls.expected_thru/1024.0);
+ if (linkstat.data.expected_thru) {
+ if (linkstat.data.expected_thru >= 1024)
+ sprintf(tmp, " (expected: %.1f MB/s)", linkstat.data.expected_thru/1024.0);
else
- sprintf(tmp, " (exp: %u kB/s)", ls.expected_thru);
+ sprintf(tmp, " (expected: %u kB/s)", linkstat.data.expected_thru);
waddstr(w_stats, tmp);
}
}
- if (ls.rx_drop_misc) {
+ if (linkstat.data.rx_drop_misc) {
waddstr(w_stats, ", drop: ");
- sprintf(tmp, "%'llu", (unsigned long long)ls.rx_drop_misc);
+ sprintf(tmp, "%'llu", (unsigned long long)linkstat.data.rx_drop_misc);
waddstr_b(w_stats, tmp);
}
@@ -207,28 +222,28 @@ static void display_stats(void)
*/
mvwaddstr(w_stats, 2, 1, "TX: ");
- if (ls.tx_packets) {
- sprintf(tmp, "%'u (%s)", ls.tx_packets,
- byte_units(ls.tx_bytes));
+ if (linkstat.data.tx_packets) {
+ sprintf(tmp, "%'u (%s)", linkstat.data.tx_packets,
+ byte_units(linkstat.data.tx_bytes));
waddstr_b(w_stats, tmp);
} else {
waddstr(w_stats, "n/a");
}
- if (iw_nl80211_have_survey_data(&ls) && ls.tx_bitrate[0]) {
+ if (iw_nl80211_have_survey_data(&linkstat.data) && linkstat.data.tx_bitrate[0]) {
waddstr(w_stats, ", rate: ");
- waddstr_b(w_stats, ls.tx_bitrate);
+ waddstr_b(w_stats, linkstat.data.tx_bitrate);
}
- if (ls.tx_retries) {
+ if (linkstat.data.tx_retries) {
waddstr(w_stats, ", retries: ");
- sprintf(tmp, "%'u", ls.tx_retries);
+ sprintf(tmp, "%'u", linkstat.data.tx_retries);
waddstr_b(w_stats, tmp);
}
- if (ls.tx_failed) {
+ if (linkstat.data.tx_failed) {
waddstr(w_stats, ", failed: ");
- sprintf(tmp, "%'u", ls.tx_failed);
+ sprintf(tmp, "%'u", linkstat.data.tx_failed);
waddstr_b(w_stats, tmp);
}
wclrtoborder(w_stats);
@@ -238,11 +253,13 @@ static void display_stats(void)
static void display_info(WINDOW *w_if, WINDOW *w_info)
{
struct iw_dyn_info info;
+ struct iw_range range;
struct iw_nl80211_ifstat ifs;
struct iw_nl80211_reg ir;
char tmp[0x100];
int i;
+ iw_getinf_range(conf_ifname(), &range);
dyn_info_get(&info, conf_ifname(), &range);
iw_nl80211_getifstat(&ifs);
iw_nl80211_getreg(&ir);
@@ -252,10 +269,7 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
*/
wmove(w_if, 1, 1);
waddstr_b(w_if, conf_ifname());
- if (range.enc_capa & IW_WPA_MASK)
- sprintf(tmp, " (%s, %s)", info.name, format_wpa(&range));
- else
- sprintf(tmp, " (%s)", info.name);
+ sprintf(tmp, " (%s)", info.name);
waddstr(w_if, tmp);
/* PHY */
@@ -288,10 +302,10 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
waddstr(w_info, "mode: ");
waddstr_b(w_info, iftype_name(ifs.iftype));
- if (!ether_addr_is_zero(&ls.bssid)) {
+ if (!ether_addr_is_zero(&linkstat.data.bssid)) {
waddstr_b(w_info, ", ");
- switch (ls.status) {
+ switch (linkstat.data.status) {
case NL80211_BSS_STATUS_ASSOCIATED:
waddstr(w_info, "connected to: ");
break;
@@ -304,15 +318,15 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
default:
waddstr(w_info, "station: ");
}
- waddstr_b(w_info, ether_lookup(&ls.bssid));
+ waddstr_b(w_info, ether_lookup(&linkstat.data.bssid));
- if (ls.status == NL80211_BSS_STATUS_ASSOCIATED) {
+ if (linkstat.data.status == NL80211_BSS_STATUS_ASSOCIATED) {
waddstr_b(w_info, ",");
waddstr(w_info, " time: ");
- waddstr_b(w_info, pretty_time(ls.connected_time));
+ waddstr_b(w_info, pretty_time(linkstat.data.connected_time));
waddstr(w_info, ", inactive: ");
- sprintf(tmp, "%.1fs", (float)ls.inactive_time/1e3);
+ sprintf(tmp, "%.1fs", (float)linkstat.data.inactive_time/1e3);
waddstr_b(w_info, tmp);
}
}
@@ -326,8 +340,8 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
waddstr_b(w_info, tmp);
/* The following condition should in theory never happen */
- if (ls.survey.freq && ls.survey.freq != ifs.freq) {
- sprintf(tmp, " [survey freq: %d MHz]", ls.survey.freq);
+ if (linkstat.data.survey.freq && linkstat.data.survey.freq != ifs.freq) {
+ sprintf(tmp, " [survey freq: %d MHz]", linkstat.data.survey.freq);
waddstr(w_info, tmp);
}
@@ -353,9 +367,9 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
sprintf(tmp, " (%s)", channel_type_name(ifs.chan_type));
waddstr(w_info, tmp);
}
- } else if (iw_nl80211_have_survey_data(&ls)) {
+ } else if (iw_nl80211_have_survey_data(&linkstat.data)) {
waddstr(w_info, "freq: ");
- sprintf(tmp, "%d MHz", ls.survey.freq);
+ sprintf(tmp, "%d MHz", linkstat.data.survey.freq);
waddstr_b(w_info, tmp);
} else {
waddstr(w_info, "frequency/channel: n/a");
@@ -364,87 +378,87 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)
/* Channel data */
wmove(w_info, 3, 1);
- if (iw_nl80211_have_survey_data(&ls)) {
+ if (iw_nl80211_have_survey_data(&linkstat.data)) {
waddstr(w_info, "channel ");
waddstr(w_info, "active: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.active));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.active));
waddstr(w_info, ", busy: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.busy));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.busy));
- if (ls.survey.time.ext_busy) {
+ if (linkstat.data.survey.time.ext_busy) {
waddstr(w_info, ", ext-busy: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.ext_busy));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.ext_busy));
}
waddstr(w_info, ", rx: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.rx));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.rx));
waddstr(w_info, ", tx: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.tx));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.tx));
- if (ls.survey.time.scan) {
+ if (linkstat.data.survey.time.scan) {
waddstr(w_info, ", scan: ");
- waddstr_b(w_info, pretty_time_ms(ls.survey.time.scan));
+ waddstr_b(w_info, pretty_time_ms(linkstat.data.survey.time.scan));
}
- } else if (ls.tx_bitrate[0] && ls.rx_bitrate[0]) {
+ } else if (linkstat.data.tx_bitrate[0] && linkstat.data.rx_bitrate[0]) {
waddstr(w_info, "rx rate: ");
- waddstr_b(w_info, ls.rx_bitrate);
+ waddstr_b(w_info, linkstat.data.rx_bitrate);
- if (ls.expected_thru) {
- if (ls.expected_thru >= 1024)
- sprintf(tmp, " (exp: %.1f MB/s)", ls.expected_thru/1024.0);
+ if (linkstat.data.expected_thru) {
+ if (linkstat.data.expected_thru >= 1024)
+ sprintf(tmp, " (exp: %.1f MB/s)", linkstat.data.expected_thru/1024.0);
else
- sprintf(tmp, " (exp: %u kB/s)", ls.expected_thru);
+ sprintf(tmp, " (exp: %u kB/s)", linkstat.data.expected_thru);
waddstr(w_info, tmp);
}
waddstr(w_info, ", tx rate: ");
- waddstr_b(w_info, ls.tx_bitrate);
+ waddstr_b(w_info, linkstat.data.tx_bitrate);
}
/* Beacons */
wmove(w_info, 4, 1);
- if (ls.beacons) {
+ if (linkstat.data.beacons) {
waddstr(w_info, "beacons: ");
- sprintf(tmp, "%'llu", (unsigned long long)ls.beacons);
+ sprintf(tmp, "%'llu", (unsigned long long)linkstat.data.beacons);
waddstr_b(w_info, tmp);
- if (ls.beacon_loss) {
+ if (linkstat.data.beacon_loss) {
waddstr(w_info, ", lost: ");
- sprintf(tmp, "%'u", ls.beacon_loss);
+ sprintf(tmp, "%'u", linkstat.data.beacon_loss);
waddstr_b(w_info, tmp);
}
waddstr(w_info, ", avg sig: ");
- sprintf(tmp, "%d dBm", (int8_t)ls.beacon_avg_sig);
+ sprintf(tmp, "%d dBm", (int8_t)linkstat.data.beacon_avg_sig);
waddstr_b(w_info, tmp);
waddstr(w_info, ", interval: ");
- sprintf(tmp, "%.1fs", (ls.beacon_int * 1024.0)/1e6);
+ sprintf(tmp, "%.1fs", (linkstat.data.beacon_int * 1024.0)/1e6);
waddstr_b(w_info, tmp);
waddstr(w_info, ", DTIM: ");
- sprintf(tmp, "%u", ls.dtim_period);
+ sprintf(tmp, "%u", linkstat.data.dtim_period);
waddstr_b(w_info, tmp);
} else {
waddstr(w_info, "station flags:");
- if (ls.cts_protection)
+ if (linkstat.data.cts_protection)
waddstr_b(w_info, " CTS");
- if (ls.wme)
+ if (linkstat.data.wme)
waddstr_b(w_info, " WME");
- if (ls.tdls)
+ if (linkstat.data.tdls)
waddstr_b(w_info, " TDLS");
- if (ls.mfp)
+ if (linkstat.data.mfp)
waddstr_b(w_info, " MFP");
- if (!(ls.cts_protection | ls.wme | ls.tdls | ls.mfp))
+ if (!(linkstat.data.cts_protection | linkstat.data.wme | linkstat.data.tdls | linkstat.data.mfp))
waddstr_b(w_info, " (none)");
waddstr(w_info, ", preamble:");
- if (ls.long_preamble)
+ if (linkstat.data.long_preamble)
waddstr_b(w_info, " long");
else
waddstr_b(w_info, " short");
waddstr(w_info, ", slot:");
- if (ls.short_slot_time)
+ if (linkstat.data.short_slot_time)
waddstr_b(w_info, " short");
else
waddstr_b(w_info, " long");
@@ -657,6 +671,7 @@ static void display_netinfo(WINDOW *w_net)
waddstr_b(w_net, inet_ntoa(info.bcast));
}
}
+ wclrtoborder(w_net);
/* 802.11 MTU may be greater than Ethernet MTU (1500) */
if (info.mtu && info.mtu != ETH_DATA_LEN) {
@@ -668,13 +683,6 @@ static void display_netinfo(WINDOW *w_net)
wrefresh(w_net);
}
-static void redraw_stat_levels(int signum)
-{
- sampling_do_poll();
- display_levels();
- display_stats();
-}
-
void scr_info_init(void)
{
int line = 0;
@@ -692,18 +700,23 @@ void scr_info_init(void)
else
w_net = newwin_title(line, WH_NET_MAX, "Network", false);
- display_info(w_if, w_info);
- display_netinfo(w_net);
- start_timer(&dyn_updates, conf.info_iv * 1000000);
- sampling_init(redraw_stat_levels);
+ sampling_init();
}
int scr_info_loop(WINDOW *w_menu)
{
- if (end_timer(&dyn_updates)) {
+ time_t now = time(NULL);
+
+ if (!pthread_mutex_trylock(&linkstat.mutex)) {
+ display_levels();
+ display_stats();
+ pthread_mutex_unlock(&linkstat.mutex);
+ }
+
+ if (now - last_update >= conf.info_iv) {
+ last_update = now;
display_info(w_if, w_info);
display_netinfo(w_net);
- start_timer(&dyn_updates, conf.info_iv * 1000000);
}
return wgetch(w_menu);
}
diff --git a/iw_if.c b/iw_if.c
index 77fc5c2..ca7d3c5 100644
--- a/iw_if.c
+++ b/iw_if.c
@@ -148,35 +148,6 @@ void iw_get_interface_list(char** if_list, size_t max_entries)
fclose(fp);
}
-void if_getstat(const char *ifname, struct if_stat *stat)
-{
- char line[0x100];
- unsigned long long d;
- char *lp;
- size_t l = strlen(ifname);
- const char path[] = "/proc/net/dev";
- FILE *fp = fopen(path, "r");
-
- if (fp == NULL)
- err_sys("can not open %s", path);
- /*
- * Inter-| Receive | Transmit
- * face |bytes packets errs drop fifo frame compressed multicast|bytes packets
- */
- while (fgets(line, sizeof(line), fp)) {
- lp = line + strspn(line, " ");
- if (!strncmp(lp, ifname, l) && lp[l] == ':') {
- lp += l + 1;
- lp += strspn(lp, " ");
-
- sscanf(lp, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
- &stat->rx_bytes, &stat->rx_packets, &d, &d, &d, &d, &d, &d,
- &stat->tx_bytes, &stat->tx_packets);
- }
- }
- fclose(fp);
-}
-
/**
* iw_dyn_info_get - populate dynamic information
* @info: information to populate
@@ -192,7 +163,7 @@ void dyn_info_get(struct iw_dyn_info *info,
if (skfd < 0)
err_sys("%s: can not open socket", __func__);
- memset(info, 0, sizeof(struct iw_dyn_info));
+ memset(info, 0, sizeof(*info));
strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(skfd, SIOCGIWNAME, &iwr) < 0)
diff --git a/iw_if.h b/iw_if.h
index cc9e886..846e9f9 100644
--- a/iw_if.h
+++ b/iw_if.h
@@ -181,18 +181,6 @@ extern void dyn_info_get(struct iw_dyn_info *info,
extern void dyn_info_cleanup(struct iw_dyn_info *info);
-/**
- * struct if_stat - Packet/byte counts for interfaces
- */
-struct if_stat {
- unsigned long long rx_packets,
- tx_packets;
- unsigned long long rx_bytes,
- tx_bytes;
-};
-
-extern void if_getstat(const char *ifname, struct if_stat *stat);
-
/*
* Structs to communicate WiFi statistics
*/
@@ -206,11 +194,10 @@ struct iw_levelstat {
extern void iw_getinf_range(const char *ifname, struct iw_range *range);
/*
- * Periodic sampling of wireless statistics via timer alarm
+ * Periodic sampling of wireless statistics
*/
-extern void sampling_init(void (*sampling_handler)(int));
-extern void sampling_do_poll(void);
-static inline void sampling_stop(void) { alarm(0); }
+extern void sampling_init(void);
+extern void sampling_stop(void);
/*
* Organization of scan results
@@ -457,31 +444,6 @@ static inline char *format_key(const struct iw_key *const iwk)
return buf;
}
-/* Human-readable representation of IW_ENC_CAPA_ types */
-static inline const char *format_enc_capab(const uint32_t capa, const char *sep)
-{
- static char buf[32];
- size_t len = 0, max = sizeof(buf);
-
- if (capa & IW_ENC_CAPA_WPA)
- len = snprintf(buf, max, "WPA");
- if (capa & IW_ENC_CAPA_WPA2)
- len += snprintf(buf + len, max - len, "%sWPA2", len ? sep : "");
- if (capa & IW_ENC_CAPA_CIPHER_TKIP)
- len += snprintf(buf + len, max - len, "%sTKIP", len ? sep : "");
- if (capa & IW_ENC_CAPA_CIPHER_CCMP)
- len += snprintf(buf + len, max - len, "%sCCMP", len ? sep : "");
- buf[len] = '\0';
- return buf;
-}
-
-/* Display only the supported WPA type */
-#define IW_WPA_MASK (IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2)
-static inline const char *format_wpa(struct iw_range *ir)
-{
- return format_enc_capab(ir->enc_capa & IW_WPA_MASK, "/");
-}
-
static inline char *format_retry(const struct iw_param *retry,
const struct iw_range *range)
{
diff --git a/lhist_scr.c b/lhist_scr.c
index 2595b45..55d5d6b 100644
--- a/lhist_scr.c
+++ b/lhist_scr.c
@@ -317,18 +317,6 @@ static void display_key(WINDOW *w_key)
wrefresh(w_key);
}
-static void redraw_lhist(int signum)
-{
- static int vcount = 1;
-
- sampling_do_poll();
- if (!--vcount) {
- vcount = conf.slotsize;
- display_lhist();
- display_key(w_key);
- }
-}
-
void scr_lhist_init(void)
{
w_lhist = newwin_title(0, HIST_WIN_HEIGHT, "Level histogram", true);
@@ -337,13 +325,20 @@ void scr_lhist_init(void)
init_extrema(&e_signal);
init_extrema(&e_noise);
init_extrema(&e_snr);
- sampling_init(redraw_lhist);
+ sampling_init();
display_key(w_key);
}
int scr_lhist_loop(WINDOW *w_menu)
{
+ static int vcount = 1;
+
+ if (!--vcount) {
+ vcount = conf.slotsize;
+ display_lhist();
+ display_key(w_key);
+ }
return wgetch(w_menu);
}
diff --git a/timer.c b/timer.c
deleted file mode 100644
index cb6500c..0000000
--- a/timer.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * wavemon - a wireless network monitoring aplication
- *
- * Copyright (c) 2001-2002 Jan Morgenstern <jan@jm-music.de>
- *
- * wavemon is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2, or (at your option) any later
- * version.
- *
- * wavemon is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with wavemon; see the file COPYING. If not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-#include "wavemon.h"
-
-static unsigned long get_usecs(void)
-{
- struct timeval tv;
- struct timezone tz;
-
- gettimeofday(&tv, &tz);
-
- return tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
-void start_timer(struct timer *t, unsigned long duration)
-{
- t->stime = get_usecs();
- t->duration = duration;
-}
-
-bool end_timer(struct timer *t)
-{
- return get_usecs() >= t->stime + t->duration;
-}
diff --git a/wavemon.1 b/wavemon.1
index ccfba7d..b5a9e58 100644
--- a/wavemon.1
+++ b/wavemon.1
@@ -1,4 +1,4 @@
-.TH wavemon 1 "January 2015" Linux "User Manuals"
+.TH wavemon 1 "September 2016" Linux "User Manuals"
.SH NAME
wavemon \- a wireless network monitor
.SH SYNOPSIS
@@ -121,6 +121,12 @@ properly.
print help and exit.
.IP "\fB\-v\fR"
print version information and exit.
+.SH Troubleshooting
+wavemon will exit with \fB'no supported wireless interfaces found'\fR if no usable wireless interfaces
+were detected. Check if your wireless interfaces is otherwise usable, using e.g. \fIiw\fR, \fIiwconfig\fR,
+or similar tools. The interface should appear in /proc/net/dev and, if wireless extensions are supported,
+also in /proc/net/wireless. If the interface does not appear, causes can be a missing (or not loaded)
+kernel module, or missing firmware, which some cards need to operate.
.SH "ENVIRONMENT VARIABLES"
.IP "LC_NUMERIC"
@@ -131,7 +137,7 @@ The local per-user configuration file.
.SH "AUTHOR"
Written by Jan Morgenstern <jan@jm-music.de>.
.SH "REPORTING BUGS"
-Send bug reports and/or suggestions to Gerrit Renker <gerrit@erg.abdn.ac.uk>.
+Open an issue on \fIhttps://github.com/uoaerg/wavemon/issues\fR.
.SH "COPYRIGHT"
This is free software with ABSOLUTELY NO WARRANTY. See file COPYING for details.
.SH "SEE ALSO"
diff --git a/wavemon.h b/wavemon.h
index e7584f7..ee0cff4 100644
--- a/wavemon.h
+++ b/wavemon.h
@@ -18,6 +18,7 @@
* with wavemon; see the file COPYING. If not, write to the Free Software
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -284,17 +285,6 @@ extern void conf_get_interface_list(void);
extern void iw_get_interface_list(char** if_list, size_t max_entries);
/*
- * Timers
- */
-struct timer {
- unsigned long long stime;
- unsigned long duration;
-};
-
-extern void start_timer(struct timer *t, unsigned long d);
-extern bool end_timer(struct timer *t);
-
-/*
* Error handling
*/
extern bool has_net_admin_capability(void);