diff options
-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); |