diff options
author | Daniel F. Dickinson <cshored@thecshore.com> | 2018-08-03 12:36:51 -0400 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2018-09-19 20:08:19 +0200 |
commit | 58d97b5e271bc0d7507eab5b9bd2902181864e02 (patch) | |
tree | 80e250346ad33c79b3f821daf7b7d9be90d99240 /modules/luci-mod-admin-full/src/luci-bwc.c | |
parent | 6ec0353201435e0d0d7d32820d8ba600b4ca7b5b (diff) |
modules: Split luci-mod-full
Move some common elements to luci-base, and otherwise make three
packages out of status, system, and network. They were mostly
separated already, but there were some shared elements between
status and network that are now in luci-base.
Signed-off-by: Daniel F. Dickinson <cshored@thecshore.com>
Diffstat (limited to 'modules/luci-mod-admin-full/src/luci-bwc.c')
-rw-r--r-- | modules/luci-mod-admin-full/src/luci-bwc.c | 778 |
1 files changed, 0 insertions, 778 deletions
diff --git a/modules/luci-mod-admin-full/src/luci-bwc.c b/modules/luci-mod-admin-full/src/luci-bwc.c deleted file mode 100644 index 8ddd91727..000000000 --- a/modules/luci-mod-admin-full/src/luci-bwc.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * luci-bwc - Very simple bandwidth collector cache for LuCI realtime graphs - * - * Copyright (C) 2010 Jo-Philipp Wich <jow@openwrt.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#include <unistd.h> -#include <signal.h> - -#include <sys/stat.h> -#include <sys/mman.h> -#include <arpa/inet.h> - -#include <dlfcn.h> -#include <iwinfo.h> - -#define STEP_COUNT 60 -#define STEP_TIME 1 -#define TIMEOUT 10 - -#define PID_PATH "/var/run/luci-bwc.pid" - -#define DB_PATH "/var/lib/luci-bwc" -#define DB_IF_FILE DB_PATH "/if/%s" -#define DB_RD_FILE DB_PATH "/radio/%s" -#define DB_CN_FILE DB_PATH "/connections" -#define DB_LD_FILE DB_PATH "/load" - -#define IF_SCAN_PATTERN \ - " %[^ :]:%u %u" \ - " %*d %*d %*d %*d %*d %*d" \ - " %u %u" - -#define LD_SCAN_PATTERN \ - "%f %f %f" - - -struct file_map { - int fd; - int size; - char *mmap; -}; - -struct traffic_entry { - uint32_t time; - uint32_t rxb; - uint32_t rxp; - uint32_t txb; - uint32_t txp; -}; - -struct conn_entry { - uint32_t time; - uint32_t udp; - uint32_t tcp; - uint32_t other; -}; - -struct load_entry { - uint32_t time; - uint16_t load1; - uint16_t load5; - uint16_t load15; -}; - -struct radio_entry { - uint32_t time; - uint16_t rate; - uint8_t rssi; - uint8_t noise; -}; - -static int readpid(void) -{ - int fd; - int pid = -1; - char buf[9] = { 0 }; - - if ((fd = open(PID_PATH, O_RDONLY)) > -1) - { - if (read(fd, buf, sizeof(buf))) - { - buf[8] = 0; - pid = atoi(buf); - } - - close(fd); - } - - return pid; -} - -static int writepid(void) -{ - int fd; - int wlen; - char buf[9] = { 0 }; - - if ((fd = open(PID_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0600)) > -1) - { - wlen = snprintf(buf, sizeof(buf), "%i", getpid()); - write(fd, buf, wlen); - close(fd); - - return 0; - } - - return -1; -} - -static int timeout = TIMEOUT; -static int countdown = -1; - -static void reset_countdown(int sig) -{ - countdown = timeout; - -} - - -static char *progname; -static int prognamelen; - -static struct iwinfo_ops *backend = NULL; - - -static int init_directory(char *path) -{ - char *p = path; - - for (p = &path[1]; *p; p++) - { - if (*p == '/') - { - *p = 0; - - if (mkdir(path, 0700) && (errno != EEXIST)) - return -1; - - *p = '/'; - } - } - - return 0; -} - -static int init_file(char *path, int esize) -{ - int i, file; - char buf[sizeof(struct traffic_entry)] = { 0 }; - - if (init_directory(path)) - return -1; - - if ((file = open(path, O_WRONLY | O_CREAT, 0600)) >= 0) - { - for (i = 0; i < STEP_COUNT; i++) - { - if (write(file, buf, esize) < 0) - break; - } - - close(file); - - return 0; - } - - return -1; -} - -static inline uint32_t timeof(void *entry) -{ - return ntohl(((struct traffic_entry *)entry)->time); -} - -static int update_file(const char *path, void *entry, int esize) -{ - int rv = -1; - int file; - char *map; - - if ((file = open(path, O_RDWR)) >= 0) - { - map = mmap(NULL, esize * STEP_COUNT, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_LOCKED, file, 0); - - if ((map != NULL) && (map != MAP_FAILED)) - { - if (timeof(entry) > timeof(map + esize * (STEP_COUNT-1))) - { - memmove(map, map + esize, esize * (STEP_COUNT-1)); - memcpy(map + esize * (STEP_COUNT-1), entry, esize); - } - - munmap(map, esize * STEP_COUNT); - - rv = 0; - } - - close(file); - } - - return rv; -} - -static int mmap_file(const char *path, int esize, struct file_map *m) -{ - m->fd = -1; - m->size = -1; - m->mmap = NULL; - - if ((m->fd = open(path, O_RDONLY)) >= 0) - { - m->size = STEP_COUNT * esize; - m->mmap = mmap(NULL, m->size, PROT_READ, - MAP_SHARED | MAP_LOCKED, m->fd, 0); - - if ((m->mmap != NULL) && (m->mmap != MAP_FAILED)) - return 0; - } - - return -1; -} - -static void umap_file(struct file_map *m) -{ - if ((m->mmap != NULL) && (m->mmap != MAP_FAILED)) - munmap(m->mmap, m->size); - - if (m->fd > -1) - close(m->fd); -} - -static void * iw_open(void) -{ - return dlopen("/usr/lib/libiwinfo.so", RTLD_LAZY); -} - -static int iw_update( - void *iw, const char *ifname, uint16_t *rate, uint8_t *rssi, uint8_t *noise -) { - struct iwinfo_ops *(*probe)(const char *); - int val; - - if (!backend) - { - probe = dlsym(iw, "iwinfo_backend"); - - if (!probe) - return 0; - - backend = probe(ifname); - - if (!backend) - return 0; - } - - *rate = (backend->bitrate && !backend->bitrate(ifname, &val)) ? val : 0; - *rssi = (backend->signal && !backend->signal(ifname, &val)) ? val : 0; - *noise = (backend->noise && !backend->noise(ifname, &val)) ? val : 0; - - return 1; -} - -static void iw_close(void *iw) -{ - void (*finish)(void); - - finish = dlsym(iw, "iwinfo_finish"); - - if (finish) - finish(); - - dlclose(iw); -} - - -static int update_ifstat( - const char *ifname, uint32_t rxb, uint32_t rxp, uint32_t txb, uint32_t txp -) { - char path[1024]; - - struct stat s; - struct traffic_entry e; - - snprintf(path, sizeof(path), DB_IF_FILE, ifname); - - if (stat(path, &s)) - { - if (init_file(path, sizeof(struct traffic_entry))) - { - fprintf(stderr, "Failed to init %s: %s\n", - path, strerror(errno)); - - return -1; - } - } - - e.time = htonl(time(NULL)); - e.rxb = htonl(rxb); - e.rxp = htonl(rxp); - e.txb = htonl(txb); - e.txp = htonl(txp); - - return update_file(path, &e, sizeof(struct traffic_entry)); -} - -static int update_radiostat( - const char *ifname, uint16_t rate, uint8_t rssi, uint8_t noise -) { - char path[1024]; - - struct stat s; - struct radio_entry e; - - snprintf(path, sizeof(path), DB_RD_FILE, ifname); - - if (stat(path, &s)) - { - if (init_file(path, sizeof(struct radio_entry))) - { - fprintf(stderr, "Failed to init %s: %s\n", - path, strerror(errno)); - - return -1; - } - } - - e.time = htonl(time(NULL)); - e.rate = htons(rate); - e.rssi = rssi; - e.noise = noise; - - return update_file(path, &e, sizeof(struct radio_entry)); -} - -static int update_cnstat(uint32_t udp, uint32_t tcp, uint32_t other) -{ - char path[1024]; - - struct stat s; - struct conn_entry e; - - snprintf(path, sizeof(path), DB_CN_FILE); - - if (stat(path, &s)) - { - if (init_file(path, sizeof(struct conn_entry))) - { - fprintf(stderr, "Failed to init %s: %s\n", - path, strerror(errno)); - - return -1; - } - } - - e.time = htonl(time(NULL)); - e.udp = htonl(udp); - e.tcp = htonl(tcp); - e.other = htonl(other); - - return update_file(path, &e, sizeof(struct conn_entry)); -} - -static int update_ldstat(uint16_t load1, uint16_t load5, uint16_t load15) -{ - char path[1024]; - - struct stat s; - struct load_entry e; - - snprintf(path, sizeof(path), DB_LD_FILE); - - if (stat(path, &s)) - { - if (init_file(path, sizeof(struct load_entry))) - { - fprintf(stderr, "Failed to init %s: %s\n", - path, strerror(errno)); - - return -1; - } - } - - e.time = htonl(time(NULL)); - e.load1 = htons(load1); - e.load5 = htons(load5); - e.load15 = htons(load15); - - return update_file(path, &e, sizeof(struct load_entry)); -} - -static int run_daemon(void) -{ - FILE *info; - uint32_t rxb, txb, rxp, txp; - uint32_t udp, tcp, other; - uint16_t rate; - uint8_t rssi, noise; - float lf1, lf5, lf15; - char line[1024]; - char ifname[16]; - int i; - void *iw; - struct sigaction sa; - - struct stat s; - const char *ipc = stat("/proc/net/nf_conntrack", &s) - ? "/proc/net/ip_conntrack" : "/proc/net/nf_conntrack"; - - switch (fork()) - { - case -1: - perror("fork()"); - return -1; - - case 0: - if (chdir("/") < 0) - { - perror("chdir()"); - exit(1); - } - - close(0); - close(1); - close(2); - break; - - default: - return 0; - } - - /* setup USR1 signal handler to reset timer */ - sa.sa_handler = reset_countdown; - sa.sa_flags = SA_RESTART; - sigemptyset(&sa.sa_mask); - sigaction(SIGUSR1, &sa, NULL); - - /* write pid */ - if (writepid()) - { - fprintf(stderr, "Failed to write pid file: %s\n", strerror(errno)); - return 1; - } - - /* initialize iwinfo */ - iw = iw_open(); - - /* go */ - for (reset_countdown(0); countdown >= 0; countdown--) - { - /* alter progname for ps, top */ - memset(progname, 0, prognamelen); - snprintf(progname, prognamelen, "luci-bwc %d", countdown); - - if ((info = fopen("/proc/net/dev", "r")) != NULL) - { - while (fgets(line, sizeof(line), info)) - { - if (strchr(line, '|')) - continue; - - if (sscanf(line, IF_SCAN_PATTERN, ifname, &rxb, &rxp, &txb, &txp)) - { - if (strncmp(ifname, "lo", sizeof(ifname))) - update_ifstat(ifname, rxb, rxp, txb, txp); - } - } - - fclose(info); - } - - if (iw) - { - for (i = 0; i < 5; i++) - { -#define iw_checkif(pattern) \ - do { \ - snprintf(ifname, sizeof(ifname), pattern, i); \ - if (iw_update(iw, ifname, &rate, &rssi, &noise)) \ - { \ - update_radiostat(ifname, rate, rssi, noise); \ - continue; \ - } \ - } while(0) - - iw_checkif("wlan%d"); - iw_checkif("ath%d"); - iw_checkif("wl%d"); - } - } - - if ((info = fopen(ipc, "r")) != NULL) - { - udp = 0; - tcp = 0; - other = 0; - - while (fgets(line, sizeof(line), info)) - { - if (strstr(line, "TIME_WAIT")) - continue; - - if ((strstr(line, "src=127.0.0.1 ") && strstr(line, "dst=127.0.0.1 ")) - || (strstr(line, "src=::1 ") && strstr(line, "dst=::1 "))) - continue; - - if (sscanf(line, "%*s %*d %s", ifname) || sscanf(line, "%s %*d", ifname)) - { - if (!strcmp(ifname, "tcp")) - tcp++; - else if (!strcmp(ifname, "udp")) - udp++; - else - other++; - } - } - - update_cnstat(udp, tcp, other); - - fclose(info); - } - - if ((info = fopen("/proc/loadavg", "r")) != NULL) - { - if (fscanf(info, LD_SCAN_PATTERN, &lf1, &lf5, &lf15)) - { - update_ldstat((uint16_t)(lf1 * 100), - (uint16_t)(lf5 * 100), - (uint16_t)(lf15 * 100)); - } - - fclose(info); - } - - sleep(STEP_TIME); - } - - unlink(PID_PATH); - - if (iw) - iw_close(iw); - - return 0; -} - -static void check_daemon(void) -{ - int pid; - - if ((pid = readpid()) < 0 || kill(pid, 0) < 0) - { - /* daemon ping failed, try to start it up */ - if (run_daemon()) - { - fprintf(stderr, - "Failed to ping daemon and unable to start it up: %s\n", - strerror(errno)); - - exit(1); - } - } - else if (kill(pid, SIGUSR1)) - { - fprintf(stderr, "Failed to send signal: %s\n", strerror(errno)); - exit(2); - } -} - -static int run_dump_ifname(const char *ifname) -{ - int i; - char path[1024]; - struct file_map m; - struct traffic_entry *e; - - check_daemon(); - snprintf(path, sizeof(path), DB_IF_FILE, ifname); - - if (mmap_file(path, sizeof(struct traffic_entry), &m)) - { - fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); - return 1; - } - - for (i = 0; i < m.size; i += sizeof(struct traffic_entry)) - { - e = (struct traffic_entry *) &m.mmap[i]; - - if (!e->time) - continue; - - printf("[ %u, %u, %" PRIu32 - ", %u, %u ]%s\n", - ntohl(e->time), - ntohl(e->rxb), ntohl(e->rxp), - ntohl(e->txb), ntohl(e->txp), - ((i + sizeof(struct traffic_entry)) < m.size) ? "," : ""); - } - - umap_file(&m); - - return 0; -} - -static int run_dump_radio(const char *ifname) -{ - int i; - char path[1024]; - struct file_map m; - struct radio_entry *e; - - check_daemon(); - snprintf(path, sizeof(path), DB_RD_FILE, ifname); - - if (mmap_file(path, sizeof(struct radio_entry), &m)) - { - fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); - return 1; - } - - for (i = 0; i < m.size; i += sizeof(struct radio_entry)) - { - e = (struct radio_entry *) &m.mmap[i]; - - if (!e->time) - continue; - - printf("[ %u, %d, %d, %d ]%s\n", - ntohl(e->time), - e->rate, e->rssi, e->noise, - ((i + sizeof(struct radio_entry)) < m.size) ? "," : ""); - } - - umap_file(&m); - - return 0; -} - -static int run_dump_conns(void) -{ - int i; - char path[1024]; - struct file_map m; - struct conn_entry *e; - - check_daemon(); - snprintf(path, sizeof(path), DB_CN_FILE); - - if (mmap_file(path, sizeof(struct conn_entry), &m)) - { - fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); - return 1; - } - - for (i = 0; i < m.size; i += sizeof(struct conn_entry)) - { - e = (struct conn_entry *) &m.mmap[i]; - - if (!e->time) - continue; - - printf("[ %u, %u, %u, %u ]%s\n", - ntohl(e->time), ntohl(e->udp), - ntohl(e->tcp), ntohl(e->other), - ((i + sizeof(struct conn_entry)) < m.size) ? "," : ""); - } - - umap_file(&m); - - return 0; -} - -static int run_dump_load(void) -{ - int i; - char path[1024]; - struct file_map m; - struct load_entry *e; - - check_daemon(); - snprintf(path, sizeof(path), DB_LD_FILE); - - if (mmap_file(path, sizeof(struct load_entry), &m)) - { - fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno)); - return 1; - } - - for (i = 0; i < m.size; i += sizeof(struct load_entry)) - { - e = (struct load_entry *) &m.mmap[i]; - - if (!e->time) - continue; - - printf("[ %u, %u, %u, %u ]%s\n", - ntohl(e->time), - ntohs(e->load1), ntohs(e->load5), ntohs(e->load15), - ((i + sizeof(struct load_entry)) < m.size) ? "," : ""); - } - - umap_file(&m); - - return 0; -} - - -int main(int argc, char *argv[]) -{ - int opt; - - progname = argv[0]; - prognamelen = -1; - - for (opt = 0; opt < argc; opt++) - prognamelen += 1 + strlen(argv[opt]); - - while ((opt = getopt(argc, argv, "t:i:r:cl")) > -1) - { - switch (opt) - { - case 't': - timeout = atoi(optarg); - break; - - case 'i': - if (optarg) - return run_dump_ifname(optarg); - break; - - case 'r': - if (optarg) - return run_dump_radio(optarg); - break; - - case 'c': - return run_dump_conns(); - - case 'l': - return run_dump_load(); - - default: - break; - } - } - - fprintf(stderr, - "Usage:\n" - " %s [-t timeout] -i ifname\n" - " %s [-t timeout] -r radiodev\n" - " %s [-t timeout] -c\n" - " %s [-t timeout] -l\n", - argv[0], argv[0], argv[0], argv[0] - ); - - return 1; -} |