diff options
| author | Jonathan McCrohan <jmccrohan@gmail.com> | 2017-01-02 22:42:44 +0000 | 
|---|---|---|
| committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2017-01-02 22:42:44 +0000 | 
| commit | 500e758260355fec650c55e9235de7a721ca5761 (patch) | |
| tree | 3b9620186b9608d93c9ab89ad584e4f2b76094eb | |
| parent | 7ca6b0f4a7eea4cd8fc40a3fd60c8d616f31220a (diff) | |
| parent | 5744c3a0214950433c3a4375798c1c8eba1b398c (diff) | |
| download | wavemon-500e758260355fec650c55e9235de7a721ca5761.tar.gz | |
Merge tag 'upstream/0.8.1'
Upstream version 0.8.1
| -rw-r--r-- | README.md | 30 | ||||
| -rw-r--r-- | conf.c | 32 | ||||
| -rw-r--r-- | info_scr.c | 227 | ||||
| -rw-r--r-- | iw_if.c | 31 | ||||
| -rw-r--r-- | iw_if.h | 44 | ||||
| -rw-r--r-- | lhist_scr.c | 21 | ||||
| -rw-r--r-- | timer.c | 41 | ||||
| -rw-r--r-- | wavemon.1 | 10 | ||||
| -rw-r--r-- | wavemon.h | 12 | 
9 files changed, 178 insertions, 270 deletions
@@ -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? @@ -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); +	}  } @@ -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);  } @@ -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) @@ -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; -} @@ -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" @@ -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);  | 
