├── .github └── workflows │ └── makefile.yml ├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── NEWS ├── README ├── THANKS ├── acinclude.m4 ├── autogen.sh ├── bwm-ng.1 ├── bwm-ng.conf-example ├── bwm-ng.css ├── configure.ac └── src ├── Makefile.am ├── bwm-ng.c ├── bwm-ng.h ├── curses_tools.c ├── curses_tools.h ├── defines.h ├── global_vars.h ├── help.c ├── help.h ├── input ├── devstat.c ├── devstat.h ├── getifaddrs.c ├── getifaddrs.h ├── ioservice.c ├── ioservice.h ├── libkstat.c ├── libkstat.h ├── libstatgrab.c ├── libstatgrab.h ├── netstat.c ├── netstat.h ├── proc_diskstats.c ├── proc_diskstats.h ├── proc_net_dev.c ├── proc_net_dev.h ├── retrieve.c ├── retrieve.h ├── sysctl.c ├── sysctl.h ├── win32.c └── win32.h ├── options.c ├── options.h ├── output.c ├── output.h ├── process.c ├── process.h └── types.h /.github/workflows/makefile.yml: -------------------------------------------------------------------------------- 1 | name: Makefile CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: setup 17 | run: autoreconf -v -i -s -W all 18 | - name: configure 19 | run: ./configure 20 | - name: build 21 | run: make 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile.in 2 | aclocal.m4 3 | autom4te.cache/ 4 | compile 5 | config.h.in 6 | configure 7 | depcomp 8 | install-sh 9 | missing 10 | src/Makefile.in 11 | Makefile 12 | config.h 13 | config.log 14 | config.status 15 | src/.deps/ 16 | src/Makefile 17 | src/bwm-ng 18 | src/bwm-ng.o 19 | src/curses_tools.o 20 | src/help.o 21 | src/netstat.o 22 | src/options.o 23 | src/output.o 24 | src/proc_diskstats.o 25 | src/proc_net_dev.o 26 | src/process.o 27 | src/retrieve.o 28 | stamp-h1 29 | src/libstatgrab.o 30 | .idea -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | -- AUTHORS of bwm-ng 2 | 3 | Author/Project leader: 4 | Volker Gropp 5 | 6 | Main developers: 7 | Volker Gropp 8 | 9 | Contributors: 10 | all authors from github merge requests and: 11 | Tim Bishop 12 | Alexey Zakharov 13 | Ricardo 14 | James Westby 15 | Bastian Riehl 16 | - curses2 output 17 | Michael Eckhoff 18 | - bit/s display 19 | Daniel Elstner 20 | Daniel Holbach 21 | - autogen.sh 22 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, 5 | Inc. 6 | 7 | Copying and distribution of this file, with or without modification, 8 | are permitted in any medium without royalty provided the copyright 9 | notice and this notice are preserved. This file is offered as-is, 10 | without warranty of any kind. 11 | 12 | Basic Installation 13 | ================== 14 | 15 | Briefly, the shell command `./configure && make && make install' 16 | should configure, build, and install this package. The following 17 | more-detailed instructions are generic; see the `README' file for 18 | instructions specific to this package. Some packages provide this 19 | `INSTALL' file but do not implement all of the features documented 20 | below. The lack of an optional feature in a given package is not 21 | necessarily a bug. More recommendations for GNU packages can be found 22 | in *note Makefile Conventions: (standards)Makefile Conventions. 23 | 24 | The `configure' shell script attempts to guess correct values for 25 | various system-dependent variables used during compilation. It uses 26 | those values to create a `Makefile' in each directory of the package. 27 | It may also create one or more `.h' files containing system-dependent 28 | definitions. Finally, it creates a shell script `config.status' that 29 | you can run in the future to recreate the current configuration, and a 30 | file `config.log' containing compiler output (useful mainly for 31 | debugging `configure'). 32 | 33 | It can also use an optional file (typically called `config.cache' 34 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 35 | the results of its tests to speed up reconfiguring. Caching is 36 | disabled by default to prevent problems with accidental use of stale 37 | cache files. 38 | 39 | If you need to do unusual things to compile the package, please try 40 | to figure out how `configure' could check whether to do them, and mail 41 | diffs or instructions to the address given in the `README' so they can 42 | be considered for the next release. If you are using the cache, and at 43 | some point `config.cache' contains results you don't want to keep, you 44 | may remove or edit it. 45 | 46 | The file `configure.ac' (or `configure.in') is used to create 47 | `configure' by a program called `autoconf'. You need `configure.ac' if 48 | you want to change it or regenerate `configure' using a newer version 49 | of `autoconf'. 50 | 51 | The simplest way to compile this package is: 52 | 53 | 1. `cd' to the directory containing the package's source code and type 54 | `./configure' to configure the package for your system. 55 | 56 | Running `configure' might take a while. While running, it prints 57 | some messages telling which features it is checking for. 58 | 59 | 2. Type `make' to compile the package. 60 | 61 | 3. Optionally, type `make check' to run any self-tests that come with 62 | the package, generally using the just-built uninstalled binaries. 63 | 64 | 4. Type `make install' to install the programs and any data files and 65 | documentation. When installing into a prefix owned by root, it is 66 | recommended that the package be configured and built as a regular 67 | user, and only the `make install' phase executed with root 68 | privileges. 69 | 70 | 5. Optionally, type `make installcheck' to repeat any self-tests, but 71 | this time using the binaries in their final installed location. 72 | This target does not install anything. Running this target as a 73 | regular user, particularly if the prior `make install' required 74 | root privileges, verifies that the installation completed 75 | correctly. 76 | 77 | 6. You can remove the program binaries and object files from the 78 | source code directory by typing `make clean'. To also remove the 79 | files that `configure' created (so you can compile the package for 80 | a different kind of computer), type `make distclean'. There is 81 | also a `make maintainer-clean' target, but that is intended mainly 82 | for the package's developers. If you use it, you may have to get 83 | all sorts of other programs in order to regenerate files that came 84 | with the distribution. 85 | 86 | 7. Often, you can also type `make uninstall' to remove the installed 87 | files again. In practice, not all packages have tested that 88 | uninstallation works correctly, even though it is required by the 89 | GNU Coding Standards. 90 | 91 | 8. Some packages, particularly those that use Automake, provide `make 92 | distcheck', which can by used by developers to test that all other 93 | targets like `make install' and `make uninstall' work correctly. 94 | This target is generally not run by end users. 95 | 96 | Compilers and Options 97 | ===================== 98 | 99 | Some systems require unusual options for compilation or linking that 100 | the `configure' script does not know about. Run `./configure --help' 101 | for details on some of the pertinent environment variables. 102 | 103 | You can give `configure' initial values for configuration parameters 104 | by setting variables in the command line or in the environment. Here 105 | is an example: 106 | 107 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 108 | 109 | *Note Defining Variables::, for more details. 110 | 111 | Compiling For Multiple Architectures 112 | ==================================== 113 | 114 | You can compile the package for more than one kind of computer at the 115 | same time, by placing the object files for each architecture in their 116 | own directory. To do this, you can use GNU `make'. `cd' to the 117 | directory where you want the object files and executables to go and run 118 | the `configure' script. `configure' automatically checks for the 119 | source code in the directory that `configure' is in and in `..'. This 120 | is known as a "VPATH" build. 121 | 122 | With a non-GNU `make', it is safer to compile the package for one 123 | architecture at a time in the source code directory. After you have 124 | installed the package for one architecture, use `make distclean' before 125 | reconfiguring for another architecture. 126 | 127 | On MacOS X 10.5 and later systems, you can create libraries and 128 | executables that work on multiple system types--known as "fat" or 129 | "universal" binaries--by specifying multiple `-arch' options to the 130 | compiler but only a single `-arch' option to the preprocessor. Like 131 | this: 132 | 133 | ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 134 | CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ 135 | CPP="gcc -E" CXXCPP="g++ -E" 136 | 137 | This is not guaranteed to produce working output in all cases, you 138 | may have to build one architecture at a time and combine the results 139 | using the `lipo' tool if you have problems. 140 | 141 | Installation Names 142 | ================== 143 | 144 | By default, `make install' installs the package's commands under 145 | `/usr/local/bin', include files under `/usr/local/include', etc. You 146 | can specify an installation prefix other than `/usr/local' by giving 147 | `configure' the option `--prefix=PREFIX', where PREFIX must be an 148 | absolute file name. 149 | 150 | You can specify separate installation prefixes for 151 | architecture-specific files and architecture-independent files. If you 152 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 153 | PREFIX as the prefix for installing programs and libraries. 154 | Documentation and other data files still use the regular prefix. 155 | 156 | In addition, if you use an unusual directory layout you can give 157 | options like `--bindir=DIR' to specify different values for particular 158 | kinds of files. Run `configure --help' for a list of the directories 159 | you can set and what kinds of files go in them. In general, the 160 | default for these options is expressed in terms of `${prefix}', so that 161 | specifying just `--prefix' will affect all of the other directory 162 | specifications that were not explicitly provided. 163 | 164 | The most portable way to affect installation locations is to pass the 165 | correct locations to `configure'; however, many packages provide one or 166 | both of the following shortcuts of passing variable assignments to the 167 | `make install' command line to change installation locations without 168 | having to reconfigure or recompile. 169 | 170 | The first method involves providing an override variable for each 171 | affected directory. For example, `make install 172 | prefix=/alternate/directory' will choose an alternate location for all 173 | directory configuration variables that were expressed in terms of 174 | `${prefix}'. Any directories that were specified during `configure', 175 | but not in terms of `${prefix}', must each be overridden at install 176 | time for the entire installation to be relocated. The approach of 177 | makefile variable overrides for each directory variable is required by 178 | the GNU Coding Standards, and ideally causes no recompilation. 179 | However, some platforms have known limitations with the semantics of 180 | shared libraries that end up requiring recompilation when using this 181 | method, particularly noticeable in packages that use GNU Libtool. 182 | 183 | The second method involves providing the `DESTDIR' variable. For 184 | example, `make install DESTDIR=/alternate/directory' will prepend 185 | `/alternate/directory' before all installation names. The approach of 186 | `DESTDIR' overrides is not required by the GNU Coding Standards, and 187 | does not work on platforms that have drive letters. On the other hand, 188 | it does better at avoiding recompilation issues, and works well even 189 | when some directory options were not specified in terms of `${prefix}' 190 | at `configure' time. 191 | 192 | Optional Features 193 | ================= 194 | 195 | If the package supports it, you can cause programs to be installed 196 | with an extra prefix or suffix on their names by giving `configure' the 197 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 198 | 199 | Some packages pay attention to `--enable-FEATURE' options to 200 | `configure', where FEATURE indicates an optional part of the package. 201 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 202 | is something like `gnu-as' or `x' (for the X Window System). The 203 | `README' should mention any `--enable-' and `--with-' options that the 204 | package recognizes. 205 | 206 | For packages that use the X Window System, `configure' can usually 207 | find the X include and library files automatically, but if it doesn't, 208 | you can use the `configure' options `--x-includes=DIR' and 209 | `--x-libraries=DIR' to specify their locations. 210 | 211 | Some packages offer the ability to configure how verbose the 212 | execution of `make' will be. For these packages, running `./configure 213 | --enable-silent-rules' sets the default to minimal output, which can be 214 | overridden with `make V=1'; while running `./configure 215 | --disable-silent-rules' sets the default to verbose, which can be 216 | overridden with `make V=0'. 217 | 218 | Particular systems 219 | ================== 220 | 221 | On HP-UX, the default C compiler is not ANSI C compatible. If GNU 222 | CC is not installed, it is recommended to use the following options in 223 | order to use an ANSI C compiler: 224 | 225 | ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" 226 | 227 | and if that doesn't work, install pre-built binaries of GCC for HP-UX. 228 | 229 | HP-UX `make' updates targets which have the same time stamps as 230 | their prerequisites, which makes it generally unusable when shipped 231 | generated files such as `configure' are involved. Use GNU `make' 232 | instead. 233 | 234 | On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot 235 | parse its `' header file. The option `-nodtk' can be used as 236 | a workaround. If GNU CC is not installed, it is therefore recommended 237 | to try 238 | 239 | ./configure CC="cc" 240 | 241 | and if that doesn't work, try 242 | 243 | ./configure CC="cc -nodtk" 244 | 245 | On Solaris, don't put `/usr/ucb' early in your `PATH'. This 246 | directory contains several dysfunctional programs; working variants of 247 | these programs are available in `/usr/bin'. So, if you need `/usr/ucb' 248 | in your `PATH', put it _after_ `/usr/bin'. 249 | 250 | On Haiku, software installed for all users goes in `/boot/common', 251 | not `/usr/local'. It is recommended to use the following options: 252 | 253 | ./configure --prefix=/boot/common 254 | 255 | Specifying the System Type 256 | ========================== 257 | 258 | There may be some features `configure' cannot figure out 259 | automatically, but needs to determine by the type of machine the package 260 | will run on. Usually, assuming the package is built to be run on the 261 | _same_ architectures, `configure' can figure that out, but if it prints 262 | a message saying it cannot guess the machine type, give it the 263 | `--build=TYPE' option. TYPE can either be a short name for the system 264 | type, such as `sun4', or a canonical name which has the form: 265 | 266 | CPU-COMPANY-SYSTEM 267 | 268 | where SYSTEM can have one of these forms: 269 | 270 | OS 271 | KERNEL-OS 272 | 273 | See the file `config.sub' for the possible values of each field. If 274 | `config.sub' isn't included in this package, then this package doesn't 275 | need to know the machine type. 276 | 277 | If you are _building_ compiler tools for cross-compiling, you should 278 | use the option `--target=TYPE' to select the type of system they will 279 | produce code for. 280 | 281 | If you want to _use_ a cross compiler, that generates code for a 282 | platform different from the build platform, you should specify the 283 | "host" platform (i.e., that on which the generated programs will 284 | eventually be run) with `--host=TYPE'. 285 | 286 | Sharing Defaults 287 | ================ 288 | 289 | If you want to set default values for `configure' scripts to share, 290 | you can create a site shell script called `config.site' that gives 291 | default values for variables like `CC', `cache_file', and `prefix'. 292 | `configure' looks for `PREFIX/share/config.site' if it exists, then 293 | `PREFIX/etc/config.site' if it exists. Or, you can set the 294 | `CONFIG_SITE' environment variable to the location of the site script. 295 | A warning: not all `configure' scripts look for a site script. 296 | 297 | Defining Variables 298 | ================== 299 | 300 | Variables not defined in a site shell script can be set in the 301 | environment passed to `configure'. However, some packages may run 302 | configure again during the build, and the customized values of these 303 | variables may be lost. In order to avoid this problem, you should set 304 | them in the `configure' command line, using `VAR=value'. For example: 305 | 306 | ./configure CC=/usr/local2/bin/gcc 307 | 308 | causes the specified `gcc' to be used as the C compiler (unless it is 309 | overridden in the site shell script). 310 | 311 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 312 | an Autoconf limitation. Until the limitation is lifted, you can use 313 | this workaround: 314 | 315 | CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 316 | 317 | `configure' Invocation 318 | ====================== 319 | 320 | `configure' recognizes the following options to control how it 321 | operates. 322 | 323 | `--help' 324 | `-h' 325 | Print a summary of all of the options to `configure', and exit. 326 | 327 | `--help=short' 328 | `--help=recursive' 329 | Print a summary of the options unique to this package's 330 | `configure', and exit. The `short' variant lists options used 331 | only in the top level, while the `recursive' variant lists options 332 | also present in any nested packages. 333 | 334 | `--version' 335 | `-V' 336 | Print the version of Autoconf used to generate the `configure' 337 | script, and exit. 338 | 339 | `--cache-file=FILE' 340 | Enable the cache: use and save the results of the tests in FILE, 341 | traditionally `config.cache'. FILE defaults to `/dev/null' to 342 | disable caching. 343 | 344 | `--config-cache' 345 | `-C' 346 | Alias for `--cache-file=config.cache'. 347 | 348 | `--quiet' 349 | `--silent' 350 | `-q' 351 | Do not print messages saying which checks are being made. To 352 | suppress all normal output, redirect it to `/dev/null' (any error 353 | messages will still be shown). 354 | 355 | `--srcdir=DIR' 356 | Look for the package's source code in directory DIR. Usually 357 | `configure' can determine that directory automatically. 358 | 359 | `--prefix=DIR' 360 | Use DIR as the installation prefix. *note Installation Names:: 361 | for more details, including other options available for fine-tuning 362 | the installation locations. 363 | 364 | `--no-create' 365 | `-n' 366 | Run the configure checks, but stop before creating any output 367 | files. 368 | 369 | `configure' also accepts some other, not widely useful, options. Run 370 | `configure --help' for more details. 371 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | SUBDIRS = src 4 | 5 | # man page 6 | man_MANS = bwm-ng.1 7 | 8 | # we want these in the dist tarball 9 | EXTRA_DIST = bwm-ng.1 bwm-ng.conf-example bwm-ng.css autogen.sh 10 | 11 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Changes in 0.6.3: 2 | 3 | * remove outdated copyright and email 4 | * Merge pull request #25 from fweimer/patch-1 AC_QEF_C_NORETURN: Include for exit 5 | * Merge pull request #27 from ofalk/master Fix potential write to unallocated memory. 6 | * Merge pull request #28 from vgropp/#2-fix-csv-bits feat: #2 output bits in csv 7 | * Merge pull request #29 from vgropp/#2-fix-csv-bits fix(doc): #2 output bits in csv 8 | * Merge pull request #32 from vgropp/new-netstat-#5 feat: add support for newer (2016+) linux netstat #5 9 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | bwm-ng v0.6.3 2 | Copyright (C) 2004-2021 Volker Gropp (bwmng@gropp.org) 3 | http://www.gropp.org/?id=projects&sub=bwm-ng 4 | 5 | What is this? 6 | ============= 7 | 8 | Bandwidth Monitor NG is a small and simple console-based live network and disk 9 | io bandwidth monitor for Linux, BSD, Solaris, Mac OS X and others. 10 | 11 | Short list of features: 12 | - supports /proc/net/dev, netstat, getifaddr, sysctl, kstat, /proc/diskstats 13 | /proc/partitions, IOKit, devstat and libstatgrab 14 | - unlimited number of interfaces/devices supported 15 | - interfaces/devices are added or removed dynamically from list 16 | - white-/blacklist of interfaces/devices 17 | - output of KB/s, Kb/s, packets, errors, average, max and total sum 18 | - output in curses, plain console, CSV or HTML 19 | - configfile 20 | 21 | This was influenced by the old bwm util written by written by Barney 22 | (barney@freewill.tzo.com) which had some issues with faster interfaces and 23 | was very simple. Since i had almost all code done anyway for other projects, 24 | i decided to create my own version. 25 | 26 | I actually dont know if netstat input is usefull at all. I saw this elsewhere, 27 | so i added it. Its target is "netstat 1.42 (2001-04-15)" linux or 28 | Free/Open/NetBSD. If there are other formats i would be happy to add them. 29 | 30 | For info about libstatgrab please refer to http://www.i-scream.org/libstatgrab/ 31 | 32 | 33 | Supported Platforms 34 | =================== 35 | 36 | network routines sucessfully tested on: 37 | Linux 2.4 and above* 38 | FreeBSD 4.8, 5.3, 6.2* 39 | MacOS X 10.1 and above* 40 | Solaris 10 x86* 41 | SunOS 5.9 sparc Solaris 9 42 | OpenBSD 3.4, 3.6, 4.0* 43 | NetBSD 1.6.1, 2.0, 3.0* 44 | IRIX64 6.5 45 | Win2000, WinXP, Windows Vista 46 | 47 | *disk monitoring working aswell 48 | 49 | please email me of working or not working platforms. Disk IO might work only on a limited 50 | number of platforms. 51 | 52 | 53 | INSTALL 54 | ======= 55 | 56 | Autotools are used to build this. Run the autogen.sh to generate the configure script. 57 | 58 | For detailed decription please read INSTALL 59 | ./configure --help for a list of options 60 | 61 | ./configure 62 | make 63 | 64 | to install use as root: 65 | make install 66 | 67 | WIN32 68 | ===== 69 | 70 | To compile the Windows version in Linux (debian): 71 | ./configure --with-win32 --without-procnetdev --without-diskstats --without-curses --without-netstatlinux --build i686-pc-linux-gnu --host i586-mingw32msvc 72 | make 73 | 74 | get ansi.sys for better output: http://en.wikipedia.org/wiki/ANSI.SYS 75 | 76 | Specs 77 | ===== 78 | 79 | csv output format: 80 | Type rate: 81 | unix timestamp;iface_name;bytes_out/s;bytes_in/s;bytes_total/s;bytes_in;bytes_out;packets_out/s;packets_in/s;packets_total/s;packets_in;packets_out;errors_out/s;errors_in/s;errors_in;errors_out;bits_out/s;bits_in/s;bits_total/s;bits_in;bits_out\n 82 | Type svg, sum, max: 83 | unix timestamp;iface_name;bytes_out;bytes_in;bytes_total;packets_out;packets_in;packets_total;errors_out;errors_in\n 84 | Use --count 0 to skip the all zero output after start. 85 | 86 | html output format: 87 | edit the bwm-ng.css to modify the output. Please note the htmlrefresh only 88 | modifies the META refresh, you maybe wanna sync --timeout and --htmlrefresh 89 | 90 | 91 | USAGE 92 | ===== 93 | 94 | USAGE: bwm-ng [OPTION] ... [CONFIGFILE] 95 | Please read the manpage or `bwm-ng -h` for a list and explanation of options. 96 | 97 | 98 | Keybindings (curses only): 99 | 'h' show help 100 | 'q' exit 101 | '+' increases timeout by 100ms 102 | '-' decreases timeout by 100ms 103 | 'k','d' switch KB and auto assign Byte/KB/MB/GB 104 | 'a' cycle: show all interfaces, only those which are up, 105 | only up and not hidden 106 | 's' sum hidden ifaces to total aswell or not 107 | 'n' cycle: input methods 108 | 'u' cycle: bytes,bits,packets,errors 109 | 't' cycle: current rate, max, sum since start, average for last 30 sec 110 | 111 | 112 | Configfile 113 | ========== 114 | 115 | either via cmdline or /etc/bwm-ng.conf or ~/.bwm-ng.conf 116 | it consists of: 117 | longoption=value 118 | with 1 or 0 as values for keys without a value in cmdline options. 119 | 120 | For more help take a look at bwm-ng.conf-example 121 | 122 | 123 | Misc 124 | ==== 125 | 126 | Bugs/Known Problems: 127 | - curses output coredumps on netbsd 1.6.1 (maybe others) with unknown TERM 128 | set and configfile support compiled in 129 | - no other yet, wow ;) (please report if you found one) 130 | 131 | Todo: 132 | - Docs 133 | - checking options to be valid 134 | - mysql output (ipac-ng compatible) 135 | - setting which stats to output for csv/sql 136 | - distributed gathering of stats (client/server) 137 | - whatever you can think of 138 | 139 | 140 | ****************************************************************************** 141 | * This program is free software; you can redistribute it and/or modify * 142 | * it under the terms of the GNU General Public License as published by * 143 | * the Free Software Foundation; either version 2 of the License, or * 144 | * (at your option) any later version. * 145 | * * 146 | * This program is distributed in the hope that it will be useful, * 147 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 148 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 149 | * GNU General Public License for more details. * 150 | * * 151 | * You should have received a copy of the GNU General Public License * 152 | * along with this program; if not, write to the Free Software * 153 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 154 | ****************************************************************************** 155 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vgropp/bwm-ng/57821ec04a7b0551eff61615793ed85e155e1b02/THANKS -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | # aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*- 2 | 3 | # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 4 | # Free Software Foundation, Inc. 5 | # This file is free software; the Free Software Foundation 6 | # gives unlimited permission to copy and/or distribute it, 7 | # with or without modifications, as long as this notice is preserved. 8 | 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 11 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 12 | # PARTICULAR PURPOSE. 13 | 14 | 15 | AC_DEFUN([AC_CHECK_WORKING_GETIFADDRS], 16 | [ 17 | AC_MSG_CHECKING([whether getifaddrs returns correct values]) 18 | AC_RUN_IFELSE([AC_LANG_SOURCE([[ 19 | #include 20 | #if STDC_HEADERS 21 | # include 22 | # include 23 | #else 24 | # if HAVE_STDLIB_H 25 | # include 26 | # endif 27 | #endif 28 | #if HAVE_SYS_SOCKET_H 29 | # include 30 | #endif 31 | #include 32 | #include 33 | #include 34 | 35 | int main() { 36 | struct ifaddrs *net; 37 | if (getifaddrs(&net) != 0) return 1; 38 | if (net!=NULL) 39 | if (net->ifa_data==NULL) { 40 | freeifaddrs(net); 41 | return 1; 42 | } 43 | freeifaddrs(net); 44 | return 0; 45 | } 46 | ]])],[ 47 | AC_MSG_RESULT(yes) 48 | AC_DEFINE_UNQUOTED([HAVE_WORKING_GETIFADDRS],[1],[getifaddrs works as espected]) 49 | INPUT_FOUND=1 50 | INPUT_SYSTEM="$INPUT_SYSTEM getifaddrs.$OBJEXT" 51 | ],[ 52 | AC_MSG_RESULT(no) 53 | ],[ 54 | AC_MSG_RESULT(cross-compiling, assume yes) 55 | AC_DEFINE_UNQUOTED([HAVE_WORKING_GETIFADDRS],[1],[getifaddrs works as espected]) 56 | INPUT_FOUND=1 57 | INPUT_SYSTEM="$INPUT_SYSTEM getifaddrs.$OBJEXT" 58 | ]) 59 | ]) 60 | 61 | 62 | # AC_CHECK_CC_OPT 63 | # --------------------- 64 | # Check whether the C compiler accepts the given option 65 | AC_DEFUN([AC_CHECK_CC_OPT], 66 | [AC_MSG_CHECKING([whether ${CC-cc} accepts -[$1]]) 67 | echo 'void f(){}' > conftest.c 68 | if test -z "`${CC-cc} -c -$1 conftest.c 2>&1`"; then 69 | AC_MSG_RESULT(yes) 70 | CFLAGS="$CFLAGS -$1" 71 | else 72 | AC_MSG_RESULT(no) 73 | fi 74 | rm -f conftest* 75 | ]) 76 | 77 | 78 | # Usage: 79 | # AC_ASK_OPTLIB(library, function, header, description, packagename, libdefine, headerdefine) 80 | # Only the last argument is optional, because they will only be defined if both the lib 81 | # and header are found 82 | # Example: 83 | # AC_ASK_OPTLIB(z, compress2, zlib.h, [ Support zlib], zlib, HAVE_LIBZ, HAVE_ZLIB_H) 84 | AC_DEFUN([AC_ASK_OPTLIB], [ 85 | AC_ARG_WITH($5, [ --with-$5 $4], [ 86 | # Specified 87 | LIBSPEC=$withval 88 | ], [ 89 | # Not specified 90 | LIBSPECFLAGS=`pkg-config --libs $5 2>/dev/null` 91 | LIBSPECCFLAGS=`pkg-config --cflags $5 2>/dev/null` 92 | AC_CHECK_LIB($1, $2, [ 93 | OLDCPPFLAGS="$CPPFLAGS" 94 | OLDCFLAGS="$CFLAGS" 95 | CPPFLAGS="$CPPFLAGS $LIBSPECCFLAGS" 96 | CFLAGS="$CFLAGS $LIBSPECCFLAGS" 97 | AC_CHECK_HEADER($3, [ 98 | LIBSPEC=yes 99 | ], [ 100 | LIBSPEC=no 101 | ]) 102 | CPPFLAGS="$OLDCPPFLAGS" 103 | CFLAGS="$OLDCFLAGS" 104 | ], [ 105 | LIBSPEC=no 106 | dnl AC_MSG_WARN(Didn't find $5) 107 | ], $LIBSPECFLAGS) 108 | ]) 109 | case $LIBSPEC in 110 | no) 111 | dnl AC_MSG_WARN(Support for $5 disabled) 112 | ;; 113 | *) 114 | if test "${LIBSPEC}" = "yes"; then 115 | true 116 | else 117 | LIBSPECFLAGS="-L${LIBSPEC}/lib ${LIBSPECFLAGS}" 118 | LIBSPECCFLAGS="-I${LIBSPEC}/include ${LIBSPECCFLAGS}" 119 | fi 120 | AC_CHECK_LIB($1, $2, [ 121 | OLDCFLAGS="$CFLAGS" 122 | OLDCPPFLAGS="$CPPFLAGS" 123 | CPPFLAGS="$CPPFLAGS ${LIBSPECCFLAGS}" 124 | CFLAGS="$CFLAGS ${LIBSPECCFLAGS}" 125 | AC_CHECK_HEADER($3, [ 126 | if test -n "$7"; then 127 | AC_DEFINE($7, [1], [Define to 1 if you have the <$3> header file.]) 128 | fi 129 | if test -n "$6"; then 130 | AC_DEFINE($6, [1], [Define to 1 if you have $2 from $5]) 131 | fi 132 | LDFLAGS="$LDFLAGS $LIBSPECFLAGS" 133 | LIBS="$LIBS -l$1" 134 | ], [ 135 | CFLAGS="$OLDCFLAGS" 136 | CPPFLAGS="$OLDCPPFLAGS" 137 | AC_MSG_ERROR(Could not find $3) 138 | ]) 139 | ], [ 140 | AC_MSG_ERROR(Could not find $5) 141 | ], $LIBSPECFLAGS) 142 | ;; 143 | esac 144 | ]) 145 | 146 | AC_DEFUN([AC_QEF_C_NORETURN], 147 | [AC_REQUIRE([AC_PROG_CC]) 148 | AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts noreturn attribute) 149 | AC_CACHE_VAL(qef_cv_c_noreturn, 150 | [qef_cv_c_noreturn=no 151 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include 152 | void f (void) __attribute__ ((noreturn)); 153 | void f (void) 154 | { 155 | exit (1); 156 | } 157 | ]], [[ 158 | f (); 159 | ]])],[qef_cv_c_noreturn="yes"; FUNCATTR_NORETURN_VAL="__attribute__ ((noreturn))"],[qef_cv_c_noreturn="no"; FUNCATTR_NORETURN_VAL="/* will not return */"]) 160 | ]) 161 | 162 | AC_MSG_RESULT($qef_cv_c_noreturn) 163 | AC_DEFINE_UNQUOTED([FUNCATTR_NORETURN], [$FUNCATTR_NORETURN_VAL],[cc knows about noreturn]) 164 | ])dnl 165 | 166 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (c) 2002 Daniel Elstner 4 | # * minor changes by Daniel Holbach 5 | # 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License VERSION 2 as 8 | # published by the Free Software Foundation. You are not allowed to 9 | # use any other version of the license; unless you got the explicit 10 | # permission from the author to do so. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 | 21 | 22 | # Be Bourne compatible. (stolen from autoconf) 23 | if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then 24 | emulate sh 25 | NULLCMD=: 26 | # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which 27 | # is contrary to our usage. Disable this feature. 28 | alias -g '${1+"$@"}'='"$@"' 29 | elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then 30 | set -o posix 31 | fi 32 | 33 | PROJECT=bwm-ng 34 | autoconf=autoconf 35 | autoheader=autoheader 36 | aclocal= 37 | automake= 38 | auto_version=0 39 | 40 | 41 | srcdir=`dirname "$0"` 42 | test -n "$srcdir" || srcdir=. 43 | 44 | origdir=`pwd` 45 | cd "$srcdir" 46 | 47 | AUTOMAKE_FLAGS="--add-missing --gnu $AUTOMAKE_FLAGS" 48 | 49 | if test -z "$AUTOGEN_SUBDIR_MODE" && test "x$*" = x 50 | then 51 | echo "I am going to run ./configure with no arguments - if you wish " 52 | echo "to pass any to it, please specify them on the $0 command line." 53 | fi 54 | 55 | if test -n "$AUTOCONF_VERSION" 56 | then 57 | echo "test for autoconf version" 58 | for suffix in "" -2.62 -2.61 -2.60 -2.59 -2.58 -2.57 -2.56 -2.55 -2.54 -2.53 -2.52 -2.51 59 | do 60 | autoconf_version=`autoconf$suffix --version /dev/null | head -n1 | cut -d " " -f 4` 61 | autoheader_version=`autoheader$suffix --version /dev/null | head -n1 | cut -d " " -f 4` 62 | version=`echo "$autoconf_version" | cut -c-3 | tr -d .` 63 | if test -n "$autoconf_version" && test -n "$autoheader_version" && test "$autoconf_version" = "$autoheader_version" && \ 64 | test -n "$version" && \ 65 | test -z "`echo -n $version | sed -n s/[0-9]*//p`" 66 | then 67 | autoconf=autoconf$suffix 68 | autoheader=autoheader$suffix 69 | if test -n "$suffix" 70 | then 71 | echo "found version `echo $suffix | cut -c2-`" 72 | export AUTOCONF_VERSION=`echo $suffix | cut -c2-` 73 | fi 74 | break 75 | fi 76 | done 77 | fi 78 | 79 | if test -n "$AUTOMAKE_VERSION" 80 | then 81 | echo "test for automake version" 82 | for suffix in "" -1.9 -1.8 -1.7 83 | do 84 | aclocal_version=`aclocal$suffix --version /dev/null | head -n1 | cut -d " " -f 4` 85 | automake_version=`automake$suffix --version /dev/null | head -n1 | cut -d " " -f 4` 86 | if test -n "$aclocal_version" && test -n "$automake_version" && test "$aclocal_version" = "$automake_version" && \ 87 | test -n `echo "$aclocal_version" | cut -c-3 | tr -d .` 88 | then 89 | auto_version=`echo "$aclocal_version" | cut -c-3 | tr -d .` 90 | if test -z "`echo -n $auto_version | sed -n s/[0-9]*//p`" && test $auto_version -ge 16 91 | then 92 | aclocal=aclocal$suffix 93 | automake=automake$suffix 94 | if test -n "$suffix" 95 | then 96 | echo "found version `echo $suffix | cut -c2-`" 97 | export AUTOMAKE_VERSION=`echo $suffix | cut -c2-` 98 | fi 99 | break 100 | fi 101 | fi 102 | done 103 | else 104 | aclocal=aclocal 105 | automake=automake 106 | fi 107 | 108 | if test -z "$aclocal" || test -z "$automake" 109 | then 110 | echo "*******************************" 111 | echo "AT LEAST automake 1.7 REQUIRED!" 112 | echo "*******************************" 113 | exit 1 114 | fi 115 | 116 | set_option=':' 117 | test -n "${BASH_VERSION+set}" && set_option='set' 118 | 119 | $set_option -x 120 | 121 | echo trying autoreconf to setup build enviroment 122 | autoreconf -v -i -s -W all 123 | if test $? -eq 0 124 | then 125 | echo running configure now 126 | if test -z "$AUTOGEN_SUBDIR_MODE" 127 | then 128 | "$srcdir/configure" ${1+"$@"} || exit 1 129 | $set_option +x 130 | echo 131 | echo "Now type 'make' to compile $PROJECT." 132 | fi 133 | exit 0 134 | fi 135 | 136 | echo looks like there is no autoreconf, trying to setup all now 137 | 138 | 139 | rm -f config.guess config.sub depcomp install-sh missing mkinstalldirs 140 | rm -f config.cache acconfig.h 141 | rm -rf autom4te.cache 142 | 143 | WARNINGS=all 144 | export WARNINGS 145 | 146 | "$aclocal" $ACLOCAL_FLAGS || exit 1 147 | "$autoheader" || exit 1 148 | "$automake" $AUTOMAKE_FLAGS || exit 1 149 | "$autoconf" || exit 1 150 | cd "$origdir" || exit 1 151 | 152 | if test -z "$AUTOGEN_SUBDIR_MODE" 153 | then 154 | "$srcdir/configure" ${1+"$@"} || exit 1 155 | $set_option +x 156 | echo 157 | echo "Now type 'make' to compile $PROJECT." 158 | fi 159 | 160 | exit 0 161 | -------------------------------------------------------------------------------- /bwm-ng.1: -------------------------------------------------------------------------------- 1 | .TH bwm-ng 1 "2007-03-01" "" "Bandwidth Monitor NG" 2 | .\" 3 | .\" Man page written by Volker Gropp (Feb 2005) 4 | .\" It was inspired by the iptables manpage 5 | .\" 6 | .\" This program is free software; you can redistribute it and/or modify 7 | .\" it under the terms of the GNU General Public License as published by 8 | .\" the Free Software Foundation; either version 2 of the License, or 9 | .\" (at your option) any later version. 10 | .\" 11 | .\" This program is distributed in the hope that it will be useful, 12 | .\" but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | .\" GNU General Public License for more details. 15 | .\" 16 | .\" You should have received a copy of the GNU General Public License 17 | .\" along with this program; if not, write to the Free Software 18 | .\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 | .\" 20 | .\" 21 | .SH NAME 22 | bwm-ng \- Bandwidth Monitor NG (Next Generation), a live bandwidth monitor for network and disk io. 23 | .SH SYNOPSIS 24 | .BI "bwm-ng "[options] " ... "[configfile] " 25 | .SH DESCRIPTION 26 | .B bwm-ng 27 | can be used to monitor the current bandwidth of all or some specific 28 | network interfaces or disks (or partitions). It shows 29 | total of in and out as well as total of all interfaces/devices. Several 30 | different output methods are supported (curses, curses2, plain, csv and html). 31 | 32 | \fBbwm-ng\fP is not limited in the number of interfaces or disks and can handle 33 | new ones dynamically while its running or hide those which are not up. 34 | 35 | 36 | .SH INPUT METHODS 37 | The input methods used pretty much depends on your OS and system. 38 | You can choose the preferred method either at start or in curses during run-time. 39 | Each method can only be used if 40 | .B bwm-ng 41 | was compiled with support for it. 42 | 43 | Currently supported 44 | .B network input methods: 45 | .RS 46 | .TP .4i 47 | .BR "proc" : 48 | This is the default for \fILinux\fP based systems. It parses the special 49 | procfs file \fB/proc/net/dev\fP. This should be used if in doubt in 50 | \fILinux\fP. 51 | .TP 52 | .BR "getifaddrs" : 53 | This is the default on \fIBSD\fP systems like \fIFreeBSD\fP, \fINetBSD\fP, 54 | \fIOpenBSD\fP and recent \fIMac OS X\fP (>=10.3). This should be used if in 55 | doubt on those systems. It uses the getifaddrs systemcall. 56 | .TP 57 | .BR "kstat" : 58 | This is the default for \fISolaris\fP. It uses the kstat systemcall. 59 | .TP 60 | .BR "sysctl" : 61 | This is the default on Systems like \fIIRIX\fP and other \fIUNIX\fP. It can 62 | be used on many other systems like early \fIMac OS X\fP as well. It uses the 63 | sysctl systemcall. 64 | .TP 65 | .BR "netstat" : 66 | This is a Backup for systems without the above, or other problems. 67 | .TP 68 | .BR "libstatgrab" : 69 | .B bwm-ng 70 | can use the external library libstatgrab to gather the data. please 71 | refer to \fIhttp://www.i-scream.org/libstatgrab\fP for more info about 72 | this. 73 | .RE 74 | 75 | Currently supported 76 | .B disk input methods: 77 | .RS 78 | .TP .4i 79 | .BR "disk" : 80 | Shows the diskio on Linux 2.6+ systems using /proc/diskstats. Instead of packets 81 | the number of read/writes will be shown. 82 | .TP 83 | .BR "kstatdisk" : 84 | same as 85 | .B kstat 86 | network input but for disk io. It uses the kstat systemcall from Solaris. 87 | .TP 88 | .BR "sysctl" : 89 | Written for \fINetBSD\fP and \fIOpenBSD\fP, but maybe working on other Platforms 90 | aswell. 91 | .TP 92 | .BR "devstat" : 93 | devstat library based input. You can find this on FreeBSD based systems. 94 | .TP 95 | .BR "ioservice" : 96 | framework IOKit based input. You can find this on Darwin systems like MacOSX. 97 | .TP 98 | .BR "libstatdisk" : 99 | same as 100 | .B libstatgrab 101 | but for disk io (\fIhttp://www.i-scream.org/libstatgrab/\fP). 102 | 103 | .RE 104 | 105 | .SH OUTPUT METHODS 106 | You can select several different ways to output the data gathered by 107 | \fBbwm-ng\fP. 108 | 109 | You can use one of: 110 | 111 | .RS 112 | .TP .4i 113 | .BR "curses" : 114 | This is the default output method. Usually this fits you the most. 115 | In \fIcurses\fP mode you can control \fBbwm-ng\fP with several keys. 116 | Press 'h' for a online help. To quit using this mode either press 'q' 117 | or ctrl-c. 118 | .TP 119 | .BR "curses2" : 120 | Shows bar charts of the current IO, using curses output. 121 | .TP 122 | .BR "plain" : 123 | \fIPlain\fP or \fIASCII\fP is mostly a backup if curses is not 124 | available. You cannot control \fBbwm-ng\fP at all in this mode. To 125 | quit press ctrl-c. 126 | But for one single single output using 127 | .ns bwm-ng -o plain -c 1 128 | this is the mode that fits the best. 129 | .TP 130 | .BR "csv" : 131 | \fICSV\fP is designed to use with scripts for easy parsing. 132 | .sp 133 | .BR "Type rate" : 134 | .br 135 | .nf 136 | unix timestamp;iface_name;bytes_out/s;bytes_in/s;bytes_total/s;bytes_in;bytes_out;packets_out/s;packets_in/s;packets_total/s;packets_in;packets_out;errors_out/s;errors_in/s;errors_in;errors_out\\n 137 | .fi 138 | .sp 139 | .BR "Type svg, sum, max" : 140 | .br 141 | .nf 142 | unix timestamp;iface_name;bytes_out;bytes_in;bytes_total;packets_out;packets_in;packets_total;errors_out;errors_in\\n 143 | .fi 144 | .sp 145 | To skip the first output with only zeros use: 146 | .nf 147 | bwm-ng -o csv -c 0 148 | .fi 149 | .TP 150 | .BR "html" : 151 | This is designed for use in the WWW. It uses the CSS file bwm-ng.css in 152 | current working dir. "--htmlrefresh" only affects the refresh of the page 153 | by the browser. For best results use the same value for --timeout and 154 | --htmlrefresh. 155 | .RE 156 | 157 | .SH OPTIONS 158 | The options that are recognized by 159 | .B bwm-ng 160 | can be divided into 3 different groups. The long versions can only be used 161 | if bwm-ng was compiled with getopt_long. 162 | 163 | .SS INPUT 164 | These options specify the method to gather the data as well as different 165 | options for them. 166 | .TP 167 | .BI "-i, --input " "method" 168 | selects which method to use. It can be one of the above (see 169 | \fBINPUT METHODS\fP) if support for it was compiled in. 170 | .TP 171 | .BI "-f, --procfile " "filename" 172 | selects the file to parse in \fBproc input method\fP. This is usually 173 | \fI/proc/net/dev\fP. 174 | .TP 175 | .BI " --diskstatsfile " "filename" 176 | selects the file to parse in \fBdisk input method\fP. This is usually 177 | \fI/proc/diskstats\fP. 178 | .TP 179 | .BI " --partitionsfile " "filename" 180 | selects the file to parse in \fBdisk input method\fP on older Kernel. 181 | This is usually \fI/proc/partitions\fP. 182 | .TP 183 | .BI "-n, --netstat " "path" 184 | specifies the binary to execute for \fBnetstat input method\fP. Because 185 | this may be a security flaw support for this option is \fInot\fP compiled 186 | in 187 | .B bwm-ng 188 | by default. 189 | 190 | .SS OUTPUT 191 | These options select the way to output the data and several options for 192 | the output. 193 | .TP 194 | .BI "-o, --output " "method" 195 | selects which method to use for output. It can be one of the above (see 196 | \fBOUTPUT METHODS\fP) if support for it was compiled in. 197 | .TP 198 | .BI "-u, --unit " "value" 199 | selects which unit to show. It can be one of \fIbytes\fP, \fIbits\fP, 200 | \fIpackets\fP or \fIerrors\fP. 201 | .TP 202 | .BI "-T, --type " "value" 203 | specifies the type of stats to show. Use one of \fIrate\fP for the current 204 | rate/s, \fImax\fP for the maximal value achieved since startup of 205 | \fBbwm-ng\fP, \fIsum\fP for the total sum counted since startup of 206 | \fBbwm-ng\fP or \fIavg\fP for the average over the last 30 seconds. 207 | .TP 208 | .BI "-c, --count " "number" 209 | number of outputs for \fIPlain\fP and \fICSV\fP output mode. Use '1' for 210 | once single output. Using '0' in \fICSV\fP mode will skip first output 211 | that always consists of zero values. 212 | .TP 213 | .BI "-C, --csvchar " "char" 214 | specifies the delimiter char for \fICSV\fP mode. The default is ';'. 215 | .TP 216 | .BI "-F, --outfile " "filename" 217 | specifies the use of a \fIoutfile\fP instead of \fIstdout\fP. This option 218 | only affects \fICSV\fP and \fIHTML\fP mode. 219 | .TP 220 | .BI "-R, --htmlrefresh " "seconds" 221 | sets the \fIHTML\fP Meta refresh field to seconds in \fIHTML\fP mode. 222 | This will result in a reload of the page every \fIn\fP seconds by 223 | the browser. If this is set you want to use \fI--htmlheader\fP as well. 224 | .TP 225 | .BI "-H, --htmlheader " "[value]" 226 | if this option is used, \fBbwm-ng\fP will print the correct \fIHTML\fP 227 | header () including Meta fields before and after data. 228 | This is only useful in \fIHTML\fP mode. \fIvalue\fP can be 0 (off) 229 | or 1 (on), if the value is not given '1' is used. 230 | .TP 231 | .BI "-N, --ansiout " 232 | disable ANSI Codes for Plain output. 233 | .TP 234 | .BI " --longdisknames " 235 | show long realnames of disks in Darwin (ioservice input) 236 | 237 | .SS OTHER 238 | These options specify the general behavior of \fBbwm-ng\fP. 239 | .TP 240 | .BI "-t, --timeout " "msec" 241 | displays and gathers stats every \fIn\fP msec (1msec = 1/1000sec). The 242 | default is 500msec. 243 | .TP 244 | .BI "-d, --dynamic " "[value]" 245 | shows bytes and bits with dynamic unit like K, M or G (Kilo, Mega, Giga). 246 | \fIvalue\fP can be 0 (off) or 1 (on), without a value '1' is used. 247 | .TP 248 | .BI "-a, --allif " "[mode]" 249 | specifies whether only up and selected interfaces (\fImode\fP=0), all which 250 | are up but maybe not selected (\fImode\fP=1) or all, even down and not 251 | selected interfaces (\fImode\fP=2). If no interface list given 252 | (\fI--interfaces\fP) \fImode\fP=1 and \fImode\fP=2 are the same. 253 | .TP 254 | .BI "-I, --interfaces " "list" 255 | show only interfaces which are in this comma separated list (\fBwhitelist\fP). 256 | If the list is prefixed by a '%' its meaning is negated and interfaces in this 257 | list are hidden from output (\fBblacklist\fP). (Example: %eth0,tun0) 258 | .TP 259 | .BI "-S, --sumhidden " "[value]" 260 | if given and the optional value is not 0, count also hidden and not shown 261 | interfaces for total value. 262 | .TP 263 | .BI "-A, --avglength " "seconds" 264 | sets the span in which the stats for average mode are collected. Default 265 | is 30 seconds or 2*\fItimeout\fP. 266 | .TP 267 | .BI "-D, --daemon " "[value]" 268 | fork into background and daemonize if given and the optional value is not 0. 269 | This only affects \fIHTML\fP and \fICSV\fP mode and \fI--outfile\fP is 270 | required. 271 | .TP 272 | .BI "-h, --help " "" 273 | show a help of command line options. 274 | .TP 275 | .BI "-V, --version " "" 276 | print version info 277 | 278 | .SH CONFIGFILE 279 | The behavior of \fBbwm-ng\fP can be also controlled by a \fIconfigfile\fP. 280 | By default \fBbwm-ng\fP first reads /etc/bwm-ng.conf and then 281 | ~/.bwm-ng.conf. If specified on command line \fBbwm-ng\fP skips those. 282 | It consists of the same long-options as used for command line as keys 283 | followed by a '=' and the value. Lines starting with a # or unknown 284 | key will be ignored. 285 | 286 | For example: 287 | .nf 288 | DYNAMIC=1 289 | UNIT=bits 290 | PROCFILE=/proc/net/dev 291 | OUTPUT=plain 292 | .fi 293 | 294 | .SH OTHER FILES 295 | .BR "bwm-ng.css" 296 | the CSS file used for html output. 297 | 298 | .SH SEE ALSO 299 | bwm-ng.conf-example for an example of the configfile, README for other 300 | comments and hints about bwm-ng. 301 | .br 302 | \fIhttp://www.gropp.org/\fP for new version or further help and links. 303 | .SH AUTHORS 304 | Volker Gropp wrote bwm-ng and is current maintainer. 305 | .br 306 | For further Authors please refer to AUTHORS file which should come 307 | with \fBbwm-ng\fP. 308 | -------------------------------------------------------------------------------- /bwm-ng.conf-example: -------------------------------------------------------------------------------- 1 | DYNAMIC=1 2 | UNIT=bits 3 | PROCFILE=/proc/net/dev 4 | DISKSTATSFILE=/proc/diskstats 5 | PARTITIONSFILE=/proc/partitions 6 | LONGDISKNAMES=0 7 | ANSIOUT=0 8 | OUTPUT=plain 9 | TIMEOUT=666 10 | NETSTAT=netstat 11 | INPUT=proc 12 | ALLIF=0 13 | INTERFACES=eth0 14 | OUTPUT=curses 15 | CSVCHAR=; 16 | #OUTFILE= 17 | COUNT=0 18 | DAEMON=0 19 | HTMLREFRESH=5 20 | HTMLHEADER=0 21 | TYPE=rate 22 | AVGLENGTH=30 23 | -------------------------------------------------------------------------------- /bwm-ng.css: -------------------------------------------------------------------------------- 1 | 2 | BODY { 3 | font: 10pt Arial, Helvetica, sans-serif; 4 | text-decoration: none; 5 | } 6 | 7 | 8 | .bwm-ng-output { 9 | padding: 3px 10px 0.5ex 10px; 10 | margin: 10px; 11 | width: 50ex; 12 | border-width: 1px; 13 | border-style: solid; 14 | } 15 | 16 | .bwm-ng-header { 17 | margin: 10px; 18 | font: 12pt Arial, Helvetica, sans-serif; 19 | font-weight: bold; 20 | } 21 | 22 | .bwm-ng-head { 23 | font-weight: bold; 24 | } 25 | 26 | .bwm-ng-name { 27 | margin-left: 10px; 28 | width: 10ex; 29 | font-weight: bold; 30 | } 31 | 32 | .bwm-ng-in { 33 | width: 10ex; 34 | } 35 | 36 | .bwm-ng-out { 37 | width: 10ex; 38 | } 39 | 40 | .bwm-ng-total { 41 | width: 10ex; 42 | font-weight: bold; 43 | } 44 | 45 | .bwm-ng-errors { 46 | color: #FF0000; 47 | } 48 | 49 | .bwm-ng-dummy { 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | ## Process this file with automake to produce Makefile.in 2 | 3 | bin_PROGRAMS = bwm-ng 4 | 5 | bwm_ng_SOURCES = bwm-ng.c process.c output.c options.c help.c curses_tools.c 6 | 7 | EXTRA_bwm_ng_SOURCES = input/retrieve.c input/devstat.c input/libkstat.c input/netstat.c input/proc_net_dev.c input/sysctl.c input/ioservice.c input/libstatgrab.c input/proc_diskstats.c input/win32.c input/getifaddrs.c 8 | 9 | bwm_ng_LDADD = retrieve.$(OBJEXT) $(INPUT_SYSTEM) 10 | bwm_ng_DEPENDENCIES = retrieve.$(OBJEXT) $(INPUT_SYSTEM) 11 | 12 | noinst_HEADERS = bwm-ng.h process.h output.h options.h help.h curses_tools.h types.h defines.h global_vars.h input/devstat.h input/libkstat.h input/netstat.h input/proc_net_dev.h input/sysctl.h input/ioservice.h input/libstatgrab.h input/proc_diskstats.h input/retrieve.h input/win32.h input/getifaddrs.h 13 | 14 | -------------------------------------------------------------------------------- /src/bwm-ng.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "global_vars.h" 23 | #include "bwm-ng.h" 24 | 25 | /* handle interrupt signal */ 26 | void sigint(int sig) FUNCATTR_NORETURN; 27 | static inline void init(void); 28 | 29 | /* clear stuff and exit */ 30 | #ifdef __STDC__ 31 | void deinit(int code, const char *error_msg, ...) { 32 | #else 33 | void deinit(int code, ...) { 34 | #endif 35 | va_list ap; 36 | #if EXTENDED_STATS 37 | int local_if_count; 38 | struct double_list *list_p; 39 | #endif 40 | #ifdef HAVE_CURSES 41 | if (mywin!=NULL && (output_method==CURSES_OUT || output_method==CURSES2_OUT)) { 42 | /* first close curses, so we dont leave mess behind */ 43 | #if HAVE_CURS_SET 44 | curs_set(1); 45 | #endif 46 | endwin(); 47 | } 48 | #endif 49 | #ifdef IOCTL 50 | /* close socket if we opened it for ioctl */ 51 | if (skfd >= 0) { 52 | close(skfd); 53 | } 54 | #endif 55 | /* we should clean if_state, the data array */ 56 | if (if_stats!=NULL) { 57 | #if EXTENDED_STATS 58 | /* clean avg list for each iface */ 59 | for (local_if_count=0;local_if_countnext; 65 | free(list_p); 66 | } 67 | } 68 | #endif 69 | free(if_stats); 70 | } 71 | /* free the opt iface_list, ifaces to show or hide */ 72 | if (iface_list!=NULL) free(iface_list); 73 | #if CSV || HTML 74 | /* close the out_file */ 75 | if (out_file!=NULL) fclose(out_file); 76 | if (out_file_path!=NULL) free(out_file_path); 77 | #endif 78 | #ifdef __STDC__ 79 | /* output errormsg if given */ 80 | if (error_msg!=NULL) { 81 | va_start(ap, error_msg); 82 | vprintf(error_msg,ap); 83 | } 84 | #else 85 | va_start(ap); 86 | vprintf(ap); 87 | #endif 88 | /* we are done, say goodbye */ 89 | exit(code); 90 | } 91 | 92 | 93 | /* sigint handler */ 94 | void sigint(int sig) { 95 | /* we got a sigint, call deinit and exit */ 96 | deinit(0, NULL); 97 | } 98 | 99 | static inline void init(void) { 100 | if_count=0; 101 | delay=500; 102 | #if EXTENDED_STATS 103 | avg_length=0; 104 | #endif 105 | output_unit=BYTES_OUT; 106 | output_type=RATE_OUT; 107 | show_all_if=0; 108 | #ifdef HAVE_CURSES 109 | output_method=CURSES_OUT; 110 | mywin=NULL; 111 | max_rt=32; 112 | scale=0; 113 | show_only_if=0; 114 | #else 115 | output_method=PLAIN_OUT; 116 | #endif 117 | iface_list=NULL; 118 | #ifdef CSV 119 | csv_char=';'; 120 | #endif 121 | 122 | #if CSV || HTML 123 | out_file=NULL; 124 | out_file_path=NULL; 125 | #endif 126 | 127 | output_count=-1; 128 | daemonize=0; 129 | sumhidden=0; 130 | /* gcc doesnt support #elifdef so we have to use this ugly piece */ 131 | #ifdef PROC_NET_DEV 132 | input_method=PROC_IN; 133 | #elif defined(GETIFADDRS) 134 | input_method=GETIFADDRS_IN; 135 | #elif defined(LIBSTATGRAB) 136 | input_method=LIBSTAT_IN; 137 | #elif defined(SYSCTL) 138 | input_method=SYSCTL_IN; 139 | #elif defined(HAVE_LIBKSTAT) 140 | input_method=KSTAT_IN; 141 | #elif defined(NETSTAT) 142 | input_method=NETSTAT_IN; 143 | #elif defined(WIN32) 144 | input_method=WIN32_IN; 145 | #elif defined(HAVE_PROC_DISKSTATS) 146 | input_method=DISKLINUX_IN; 147 | #else 148 | #error "NO INPUT DEFINED!" 149 | input_method=0; 150 | #endif 151 | 152 | ansi_output=1; 153 | 154 | #ifdef HTML 155 | html_refresh=5; 156 | html_header=0; 157 | #endif 158 | #ifdef IOCTL 159 | skfd=-1; 160 | #endif 161 | if_stats=NULL; 162 | #ifdef PROC_NET_DEV 163 | strncpy(PROC_FILE,PROC_NET_DEV,PATH_MAX); 164 | #endif 165 | 166 | #ifdef PROC_DISKSTATS 167 | strncpy(PROC_DISKSTATS_FILE,PROC_DISKSTATS,PATH_MAX); 168 | #endif 169 | #ifdef PROC_PARTITIONS 170 | strncpy(PROC_PARTITIONS_FILE,PROC_PARTITIONS,PATH_MAX); 171 | #endif 172 | 173 | #if IOSERVICE_IN 174 | long_darwin_disk_names = 0; 175 | #endif 176 | time_t t = time(NULL); 177 | strftime(start_time, sizeof(start_time), "%c", localtime(&t)); 178 | } 179 | 180 | /* do the main thing */ 181 | int main (int argc, char *argv[]) { 182 | unsigned char idle_chars_p=0; 183 | char ch; 184 | 185 | init(); 186 | 187 | /* handle all cmd line and configfile options */ 188 | get_cmdln_options(argc,argv); 189 | /* check them */ 190 | if (output_method<0) 191 | deinit(1,"invalid output selected\n"); 192 | if (input_method<0) 193 | deinit(1,"invalid input selected\n"); 194 | 195 | #ifdef LIBSTATGRAB 196 | if (sg_init(0) != 0) { 197 | deinit(1,"libstatgrab failed to initialise\n"); 198 | } 199 | #endif 200 | 201 | /* init total stats to zero */ 202 | memset(&if_stats_total,0,(size_t)sizeof(t_iface_stats)); 203 | #ifdef HAVE_CURSES 204 | if (output_method==CURSES_OUT || output_method==CURSES2_OUT) { 205 | /* init curses */ 206 | if (init_curses()) 207 | signal(SIGWINCH,sigwinch); 208 | } 209 | #endif 210 | /* end of init curses, now set a sigint handler to deinit the screen on ctrl-break */ 211 | signal(SIGINT,sigint); 212 | signal(SIGTERM,sigint); 213 | #ifdef CSV 214 | /* get stats without verbose if cvs */ 215 | if (output_method==CSV_OUT && output_count>-1) { 216 | get_iface_stats(0); 217 | #ifdef HAVE_USLEEP 218 | if (usleep(delay*1000) != 0) { 219 | if (errno == EINVAL) { 220 | errno = 0; 221 | /* there seems to be systems where 1million usecs is max */ 222 | usleep(999999); 223 | } 224 | } 225 | #else 226 | Sleep(delay); 227 | #endif 228 | } 229 | #endif 230 | #ifdef HAVE_FORK 231 | if (daemonize) { 232 | int nbyt = 0; 233 | /* lets fork into background */ 234 | if ((nbyt = fork()) == -1) { 235 | deinit(1,"could not fork into background: %s\n",strerror(errno)); 236 | } 237 | if (nbyt != 0) { /* nbyt is the new child pid here */ 238 | deinit(1,"forking into background\n"); 239 | } 240 | setsid(); 241 | } 242 | #endif 243 | if (output_count==0) output_count=-1; 244 | if (output_method==PLAIN_OUT && output_count==1) output_method=PLAIN_OUT_ONCE; 245 | if (output_method==PLAIN_OUT) printf("\033[2J"); /* clear screen for plain out */ 246 | while (1) { /* do the main loop */ 247 | #ifdef HTML 248 | /* open the output file */ 249 | if (output_method==HTML_OUT && out_file_path) { 250 | if (out_file) fclose(out_file); 251 | out_file=fopen(out_file_path,"w"); 252 | } 253 | #endif 254 | /* check if we will output anything */ 255 | ch=!(output_method==PLAIN_OUT_ONCE 256 | #ifdef HTML 257 | || (output_method==HTML_OUT && !daemonize) 258 | #endif 259 | ); 260 | 261 | /* print the header (info) if verbose */ 262 | if (ch) idle_chars_p=print_header(idle_chars_p); 263 | /* do the actual work, get and print stats */ 264 | get_iface_stats(ch); 265 | 266 | #if HTML 267 | /* close html tags */ 268 | if (output_method==HTML_OUT && html_header && daemonize) 269 | fprintf((out_file==NULL ? stdout : out_file),"\n\n\n"); 270 | /* close the output file, so we dont sit on it and block it */ 271 | if (out_file && output_method==HTML_OUT && daemonize) { fclose(out_file); out_file=NULL; } 272 | #endif 273 | /* handle the number of max outputs if set */ 274 | if (( 275 | #ifdef CSV 276 | output_method==CSV_OUT || 277 | #endif 278 | output_method==PLAIN_OUT) && output_count>0) { 279 | output_count--; 280 | /* go to exit if we are done, will break the while(1) */ 281 | if (output_count==0) break; 282 | } 283 | /* either refresh the output and handle gui input */ 284 | #ifdef HAVE_CURSES 285 | if (output_method==CURSES_OUT || output_method==CURSES2_OUT) { 286 | refresh(); 287 | handle_gui_input(getch()); 288 | } else 289 | #endif 290 | /* or just wait delay ms */ 291 | #ifdef HAVE_USLEEP 292 | if (usleep(delay*1000)==EINVAL) { 293 | usleep(999999); 294 | delay=999; 295 | } 296 | #else 297 | Sleep(delay); 298 | #endif 299 | 300 | /* quit if we should only output once */ 301 | if (output_method==PLAIN_OUT_ONCE 302 | #ifdef HTML 303 | || (output_method==HTML_OUT && !daemonize) 304 | #endif 305 | ) break; /* dont loop when we have plain output */ 306 | } 307 | #ifdef HTML 308 | /* do we need to output for html? */ 309 | if (output_method==HTML_OUT && !daemonize) { 310 | print_header(0); 311 | get_iface_stats(1); 312 | if (html_header) fprintf(out_file==NULL ? stdout : out_file,"\n\n\n"); 313 | } 314 | #endif 315 | /* do we need to output for plain? */ 316 | if (output_method==PLAIN_OUT_ONCE) { 317 | print_header(0); 318 | get_iface_stats(1); 319 | } 320 | deinit(0,NULL); 321 | return 0; /* only to avoid gcc warning */ 322 | } 323 | -------------------------------------------------------------------------------- /src/bwm-ng.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __BWM_NG_H 23 | #define __BWM_NG_H 24 | 25 | #include "defines.h" 26 | #include "types.h" 27 | #include "curses_tools.h" 28 | #include "options.h" 29 | #include "output.h" 30 | #include "input/retrieve.h" 31 | #include "help.h" 32 | 33 | #ifdef WIN32 34 | #include 35 | #endif 36 | 37 | #ifdef __STDC__ 38 | #include 39 | void deinit(int code, const char *error_msg, ...) FUNCATTR_NORETURN; 40 | #else 41 | #include 42 | void deinit(int code, ...) FUNCATTR_NORETURN; 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/curses_tools.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng curses stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "global_vars.h" 23 | #include "curses_tools.h" 24 | 25 | #ifdef HAVE_CURSES 26 | 27 | /* handle key input by user in gui (curses) mode */ 28 | void handle_gui_input(char c) { 29 | switch (c) { 30 | /* lets check for known keys */ 31 | case '+': /* increase delay */ 32 | delay+=100; 33 | timeout(delay); 34 | break; 35 | case '-': /* decrease delay */ 36 | if (delay>100) { 37 | delay+=-100; 38 | timeout(delay); 39 | } 40 | break; 41 | case 'a': 42 | case 'A': 43 | show_all_if++; 44 | if (show_all_if>2) { 45 | show_all_if=0; 46 | clean_down_ifaces(); 47 | } 48 | if (iface_list==NULL && show_all_if==1) show_all_if=2; 49 | /* get stats so all values are uptodate */ 50 | get_iface_stats(0); 51 | break; 52 | case 's': 53 | case 'S': 54 | sumhidden=!sumhidden; 55 | /* get stats so all values are uptodate */ 56 | get_iface_stats(0); 57 | break; 58 | case 'n': 59 | case 'N': 60 | do { 61 | input_method=input_method<<1; 62 | if (input_method>INPUT_MASK) input_method=1; 63 | } while (!(input_method & INPUT_MASK)); 64 | /* switched input, reset iface stats */ 65 | free(if_stats); 66 | if_stats=NULL; 67 | if_count=0; 68 | memset(&if_stats_total,0,(size_t)sizeof(t_iface_stats)); 69 | break; 70 | case 'q': 71 | case 'Q': 72 | /* we are asked to exit */ 73 | deinit(0, NULL); 74 | break; 75 | case 'd': 76 | case 'D': 77 | case 'k': 78 | case 'K': 79 | if (output_method==CURSES2_OUT) 80 | /* cycle through interfaces */ 81 | show_only_if++; 82 | else 83 | /* switch kilobyte/autoassign */ 84 | dynamic=!dynamic; 85 | break; 86 | case 'u': 87 | case 'U': 88 | if (output_method==CURSES_OUT) { 89 | if (output_unit<(!net_input_method(input_method) ? (input_method==LIBSTATDISK_IN ? 2 : 3) : 4)) 90 | output_unit++; 91 | else 92 | output_unit=1; 93 | }; 94 | break; 95 | #if EXTENDED_STATS 96 | case 't': 97 | case 'T': 98 | if (output_type 33 | #endif 34 | #include 35 | #ifdef HAVE_LINUX_TTY_H 36 | #include 37 | #else 38 | #ifdef HAVE_SYS_TTY_H 39 | #include 40 | #endif 41 | #endif 42 | 43 | /* handle key input by user in gui (curses) mode */ 44 | void handle_gui_input(char c); 45 | int init_curses(void); 46 | void sigwinch(int sig); 47 | #endif 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/defines.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __HAVE_DEFINE_H 23 | #define __HAVE_DEFINE_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "../config.h" 35 | 36 | /* ugly defines to handle different compile time options */ 37 | 38 | #if HAVE_STRUCT_IF_MSGHDR_IFM_DATA 39 | #define SYSCTL 40 | #endif 41 | 42 | #if NETSTAT_LINUX_NEW || NETSTAT_LINUX || NETSTAT_BSD || NETSTAT_BSD_BYTES || NETSTAT_SOLARIS || NETSTAT_NETBSD 43 | #define NETSTAT 1 44 | #endif 45 | 46 | #if HAVE_LIBSTATGRAB 47 | #define LIBSTATGRAB 48 | #endif 49 | 50 | #if HAVE_LIBCURSES || HAVE_LIBNCURSES 51 | #define HAVE_CURSES 52 | #endif 53 | 54 | #if HAVE_WORKING_GETIFADDRS 55 | #define GETIFADDRS 56 | #endif 57 | 58 | #if HAVE_GETOPT_LONG 59 | #define LONG_OPTIONS 60 | #endif 61 | 62 | #if HAVE_IOCTL 63 | #include 64 | #ifdef SIOCGIFFLAGS 65 | #define IOCTL 66 | #endif 67 | #endif 68 | 69 | #ifdef HAVE_CURSES 70 | #include 71 | #ifndef ACS_VLINE 72 | #define ACS_VLINE '|' 73 | #endif 74 | #ifndef ACS_HLINE 75 | #define ACS_HLINE '-' 76 | #endif 77 | #endif 78 | 79 | #ifdef LONG_OPTIONS 80 | #include 81 | #endif 82 | 83 | #if HAVE_GETTIMEOFDAY 84 | #include 85 | #include 86 | #endif 87 | 88 | #ifdef NETSTAT 89 | #if HAVE_NETSTAT_PATH 90 | #define NETSTAT_PATH HAVE_NETSTAT_PATH 91 | #else 92 | #define NETSTAT_PATH "netstat" 93 | #endif 94 | #endif 95 | 96 | #if HAVE__PROC_NET_DEV 97 | #ifdef PROC_NET_DEV_PATH 98 | #define PROC_NET_DEV PROC_NET_DEV_PATH 99 | #else 100 | #define PROC_NET_DEV "/proc/net/dev" 101 | #endif 102 | #endif 103 | 104 | #if HAVE__PROC_DISKSTATS 105 | #ifdef PROC_DISKSTATS_PATH 106 | #define PROC_DISKSTATS PROC_DISKSTATS_PATH 107 | #else 108 | #define PROC_DISKSTATS "/proc/diskstats" 109 | #endif 110 | #ifdef PROC_PARTITIONS_PATH 111 | #define PROC_PARTITIONS PROC_PARTITIONS_PATH 112 | #else 113 | #define PROC_PARTITIONS "/proc/partitions" 114 | #endif 115 | #endif 116 | 117 | /* prepare input methods */ 118 | #ifdef NETSTAT 119 | #define NETSTAT_IN 1 120 | #define INPUT_METHODS_NETSTAT " netstat" 121 | #else 122 | #define NETSTAT_IN 0 123 | #define INPUT_METHODS_NETSTAT 124 | #endif 125 | 126 | #ifdef PROC_NET_DEV 127 | #define PROC_IN 2 128 | #define INPUT_METHODS_PROC " proc" 129 | #else 130 | #define PROC_IN 0 131 | #define INPUT_METHODS_PROC 132 | #endif 133 | 134 | #ifdef GETIFADDRS 135 | #define GETIFADDRS_IN 4 136 | #define INPUT_METHODS_GETIFADDRS " getifaddrs" 137 | #else 138 | #define GETIFADDRS_IN 0 139 | #define INPUT_METHODS_GETIFADDRS 140 | #endif 141 | 142 | #ifdef LIBSTATGRAB 143 | #define LIBSTAT_IN 8 144 | #define LIBSTATDISK_IN 256 145 | #define INPUT_METHODS_LIBSTATGRAB " libstatgrab" 146 | #define INPUT_METHODS_LIBSTATDISK " libstatdisk" 147 | #else 148 | #define LIBSTAT_IN 0 149 | #define INPUT_METHODS_LIBSTATGRAB 150 | #define LIBSTATDISK_IN 0 151 | #define INPUT_METHODS_LIBSTATDISK 152 | #endif 153 | 154 | #ifdef SYSCTL 155 | #define SYSCTL_IN 16 156 | #define INPUT_METHODS_SYSCTL " sysctl" 157 | #else 158 | #define SYSCTL_IN 0 159 | #define INPUT_METHODS_SYSCTL 160 | #endif 161 | 162 | #if defined(HAVE_STRUCT_DISKSTATS) || defined(HAVE_STRUCT_DISK_SYSCTL) 163 | #define SYSCTLDISK_IN 1024 164 | #define INPUT_METHODS_SYSCTLDISK " sysctldisk" 165 | #else 166 | #define SYSCTLDISK_IN 0 167 | #define INPUT_METHODS_SYSCTLDISK 168 | #endif 169 | 170 | 171 | #if HAVE_LIBKSTAT 172 | #define KSTAT_IN 32 173 | #define KSTATDISK_IN 512 174 | #define INPUT_METHODS_KSTAT " kstat" 175 | #define INPUT_METHODS_KSTATDISK " kstatdisk" 176 | #else 177 | #define KSTAT_IN 0 178 | #define KSTATDISK_IN 0 179 | #define INPUT_METHODS_KSTAT 180 | #define INPUT_METHODS_KSTATDISK 181 | #endif 182 | 183 | #ifdef WIN32 184 | #define WIN32_IN 64 185 | #define INPUT_METHODS_WIN32 " win32" 186 | #else 187 | #define WIN32_IN 0 188 | #define INPUT_METHODS_WIN32 189 | #endif 190 | 191 | #ifdef PROC_DISKSTATS 192 | #define DISKLINUX_IN 128 193 | #define INPUT_METHODS_DISK_LINUX " disk" 194 | #else 195 | #define DISKLINUX_IN 0 196 | #define INPUT_METHODS_DISK_LINUX 197 | #endif 198 | 199 | #if defined(HAVE_DEVSTAT_GETDEVS) || defined(HAVE_GETDEVS) 200 | #define DEVSTAT_IN 2048 201 | #define INPUT_METHODS_DEVSTAT " devstat" 202 | #else 203 | #define DEVSTAT_IN 0 204 | #define INPUT_METHODS_DEVSTAT 205 | #endif 206 | 207 | #ifdef HAVE_IOSERVICE 208 | #define IOSERVICE_IN 4096 209 | #define INPUT_METHODS_IOSERVICE " ioservice" 210 | #else 211 | #define IOSERVICE_IN 0 212 | #define INPUT_METHODS_IOSERVICE 213 | #endif 214 | 215 | #define INPUT_MASK (NETSTAT_IN | PROC_IN | GETIFADDRS_IN | LIBSTAT_IN | SYSCTL_IN | KSTAT_IN | KSTATDISK_IN | WIN32_IN | DISKLINUX_IN | LIBSTATDISK_IN | SYSCTLDISK_IN | DEVSTAT_IN | IOSERVICE_IN) 216 | #define NET_INPUT (NETSTAT_IN | PROC_IN | GETIFADDRS_IN | LIBSTAT_IN | SYSCTL_IN | KSTAT_IN | WIN32_IN) 217 | #define INPUT_METHODS INPUT_METHODS_PROC INPUT_METHODS_GETIFADDRS INPUT_METHODS_SYSCTL INPUT_METHODS_KSTAT INPUT_METHODS_NETSTAT INPUT_METHODS_WIN32 INPUT_METHODS_LIBSTATGRAB INPUT_METHODS_DISK_LINUX INPUT_METHODS_LIBSTATDISK INPUT_METHODS_KSTATDISK INPUT_METHODS_SYSCTLDISK INPUT_METHODS_DEVSTAT INPUT_METHODS_IOSERVICE 218 | 219 | #define net_input_method(_n) (_n & NET_INPUT) 220 | 221 | /* used for this nice spinning wheel */ 222 | #define IDLE_CHARS "-\\|/" 223 | 224 | 225 | /* build output methods string: curses, plain, csv, html */ 226 | #ifdef HAVE_CURSES 227 | #define CURSES_OUTPUT_METHODS ", curses, curses2" 228 | #define CURSES_OUT 0 229 | #define CURSES2_OUT 5 230 | #define IDLE_CHARS2 " >--< " 231 | #else 232 | #define CURSES_OUTPUT_METHODS 233 | #endif 234 | 235 | #ifdef CSV 236 | #define CSV_OUTPUT_METHODS ", csv" 237 | #define CSV_OUT 2 238 | #else 239 | #define CSV_OUTPUT_METHODS 240 | #endif 241 | 242 | #ifdef HTML 243 | #define HTML_OUTPUT_METHODS ", html" 244 | #define HTML_OUT 3 245 | #else 246 | #define HTML_OUTPUT_METHODS 247 | #endif 248 | 249 | #define OUTPUT_METHODS "plain" CURSES_OUTPUT_METHODS CSV_OUTPUT_METHODS HTML_OUTPUT_METHODS 250 | #define PLAIN_OUT 1 251 | #define PLAIN_OUT_ONCE 4 252 | 253 | /* build short options */ 254 | #ifdef PROC_NET_DEV 255 | #define PROC_SHORT_OPT "f:" 256 | #else 257 | #define PROC_SHORT_OPT 258 | #endif 259 | 260 | #ifdef HTML 261 | #define HTML_SHORT_OPT "H:R:" 262 | #else 263 | #define HTML_SHORT_OPT 264 | #endif 265 | 266 | #if NETSTAT && NETSTAT_OPTION 267 | #define NETSTAT_SHORT_OPT "n:" 268 | #else 269 | #define NETSTAT_SHORT_OPT 270 | #endif 271 | 272 | #ifdef CSV 273 | #define CSV_SHORT_OPT "C:F:" 274 | #else 275 | #define CSV_SHORT_OPT 276 | #endif 277 | 278 | #if EXTENDED_STATS 279 | #define EXTENDED_STATS_SHORT_OPT "A:T:" 280 | #else 281 | #define EXTENDED_STATS_SHORT_OPT 282 | #endif 283 | 284 | #define SHORT_OPTIONS ":ht:d:Va:u:I:i:o:c:D:S:N" EXTENDED_STATS_SHORT_OPT PROC_SHORT_OPT HTML_SHORT_OPT NETSTAT_SHORT_OPT CSV_SHORT_OPT 285 | 286 | #define BYTES_OUT 1 287 | #define BITS_OUT 2 288 | #define PACKETS_OUT 3 289 | #define ERRORS_OUT 4 290 | 291 | #define RATE_OUT 1 292 | #if EXTENDED_STATS 293 | #define MAX_OUT 2 294 | #define SUM_OUT 3 295 | #define AVG_OUT 4 296 | #define TYPE_OUT_MAX 4 297 | #else 298 | #define TYPE_OUT_MAX 1 299 | #endif 300 | 301 | /* default length of avg in 1/1000sec */ 302 | #define AVG_LENGTH 30000 303 | 304 | #ifndef PATH_MAX 305 | #define PATH_MAX 4096 306 | #endif 307 | 308 | #define WRAP_AROUND ULONG_MAX 309 | #define WRAP_32BIT 4294967295ul 310 | 311 | #ifdef SYS_64BIT 312 | #ifdef HAVE_UNSIGNED_LONG_LONG 313 | 314 | #undef WRAP_AROUND 315 | #define WRAP_AROUND 18446744073709551615ull 316 | 317 | #endif 318 | #endif 319 | 320 | #define print_version printf("Bandwidth Monitor NG (" PACKAGE_NAME ") v" VERSION); 321 | 322 | #ifndef EXIT_SUCCESS 323 | #define EXIT_SUCCESS 0 324 | #endif 325 | 326 | #ifndef EXIT_FAILURE 327 | #define EXIT_FAILURE 1 328 | #endif 329 | 330 | #ifndef HAVE_STRLCPY 331 | #define strlcpy(_a,_b,_c) strncpy((_a),(_b),(_c)); (_a)[(_c) - 1]='\0'; 332 | #endif 333 | 334 | #endif 335 | -------------------------------------------------------------------------------- /src/global_vars.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng global variables * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __GLOBAL_VARS 23 | #define __GLOBAL_VARS 24 | #ifndef EXTERN 25 | #define EXTERN extern 26 | #endif 27 | 28 | #include "defines.h" 29 | #include "types.h" 30 | 31 | EXTERN int if_count; 32 | #ifdef PROC_NET_DEV 33 | EXTERN char PROC_FILE[PATH_MAX]; 34 | #endif 35 | #ifdef PROC_DISKSTATS 36 | EXTERN char PROC_DISKSTATS_FILE[PATH_MAX]; 37 | EXTERN char PROC_PARTITIONS_FILE[PATH_MAX]; 38 | #endif 39 | #ifdef NETSTAT 40 | EXTERN char NETSTAT_FILE[PATH_MAX]; 41 | #endif 42 | EXTERN unsigned int delay; 43 | #if EXTENDED_STATS 44 | EXTERN unsigned int avg_length; 45 | #endif 46 | EXTERN char output_unit; 47 | EXTERN char output_type; 48 | EXTERN char dynamic; 49 | 50 | EXTERN char show_all_if; 51 | #ifdef HAVE_CURSES 52 | EXTERN int output_method; 53 | EXTERN WINDOW *mywin; 54 | EXTERN unsigned short cols; 55 | EXTERN unsigned short rows; 56 | EXTERN unsigned int max_rt; 57 | EXTERN unsigned int scale; 58 | EXTERN unsigned int show_only_if; 59 | #else 60 | EXTERN int output_method; 61 | #endif 62 | EXTERN char *iface_list; 63 | #ifdef CSV 64 | EXTERN char csv_char; 65 | #endif 66 | #if CSV || HTML 67 | EXTERN FILE *out_file; 68 | EXTERN char *out_file_path; 69 | #endif 70 | EXTERN int output_count; 71 | EXTERN char daemonize; 72 | EXTERN char sumhidden; 73 | EXTERN char ansi_output; 74 | 75 | EXTERN int input_method; 76 | 77 | #ifdef HTML 78 | EXTERN int html_refresh; 79 | EXTERN int html_header; 80 | #endif 81 | 82 | #ifdef IOCTL 83 | EXTERN int skfd; 84 | #endif 85 | 86 | #if IOSERVICE_IN 87 | EXTERN char long_darwin_disk_names; 88 | #endif 89 | 90 | EXTERN t_iface_stats *if_stats; 91 | /* total struct */ 92 | EXTERN t_iface_stats if_stats_total; 93 | 94 | #endif 95 | 96 | EXTERN char start_time[30]; 97 | -------------------------------------------------------------------------------- /src/help.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng online help * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "global_vars.h" 23 | #include "help.h" 24 | 25 | static inline void print_help_line(const char *short_c,const char * long_c,const char *descr); 26 | 27 | static inline void print_help_line(const char *short_c,const char * long_c,const char *descr) { 28 | #ifdef LONG_OPTIONS 29 | printf(" %-23s",long_c); 30 | #else 31 | printf(" %-23s",short_c); 32 | #endif 33 | printf(" %s\n",descr); 34 | } 35 | 36 | /* prints a helpscreen and exists */ 37 | inline void cmdln_printhelp(void) FUNCATTR_NORETURN; 38 | inline void cmdln_printhelp() { 39 | print_version; 40 | printf("USAGE: bwm-ng [OPTION] ..."); 41 | #if CONFIG_FILE 42 | printf(" [CONFIGFILE]\n"); 43 | #else 44 | printf("\n"); 45 | #endif 46 | printf("displays current ethernet interfaces stats\n\n"); 47 | printf("Options:\n"); 48 | print_help_line("-t ","-t, --timeout ","displays stats every (1msec = 1/1000sec)"); 49 | print_help_line("","","default: 500"); 50 | print_help_line("-d","-d, --dynamic [value]","show values dynamically (Byte KB or MB)"); 51 | print_help_line("-a [mode]","-a, --allif [mode]","where mode is one of:"); 52 | print_help_line("","","0=show only up (and selected) interfaces"); 53 | print_help_line("","","1=show all up interfaces (default)"); 54 | print_help_line("","","2=show all and down interfaces"); 55 | print_help_line("-I ","-I, --interfaces ","show only interfaces in (comma separated), or"); 56 | print_help_line("","","if list is prefaced with % show all but interfaces"); 57 | print_help_line("","","in list"); 58 | print_help_line("-S","-S, --sumhidden [value]","count hidden interfaces for total"); 59 | #if EXTENDED_STATS 60 | print_help_line("-A","-A, --avglength ","sets the span of average stats (Default 30s)"); 61 | #endif 62 | #ifdef HAVE_FORK 63 | print_help_line("-D","-D, --daemon [value]","fork into background and daemonize"); 64 | #endif 65 | print_help_line("-h","-h, --help","displays this help"); 66 | print_help_line("-V","-V, --version","print version info"); 67 | printf("\nInput:\n"); 68 | print_help_line("-i ","-i, --input ","input method, one of:" INPUT_METHODS); 69 | #ifdef PROC_NET_DEV 70 | print_help_line("-f ","-f, --procfile ","filename to read raw data from. (" PROC_NET_DEV ")"); 71 | #endif 72 | #ifdef PROC_DISKSTATS 73 | print_help_line(""," --diskstatsfile ","filename to read diskstats (Linux 2.6+) from. (" PROC_DISKSTATS ")"); 74 | print_help_line(""," --partitionsfile ","filename to read diskstats (Linux 2.4) from. (" PROC_PARTITIONS ")"); 75 | #endif 76 | #if ALLOW_NETSTATPATH 77 | #ifdef NETSTAT 78 | print_help_line("-n ","-n, --netstat ","use as netstat binary"); 79 | #endif 80 | #endif 81 | printf("\nOutput:\n"); 82 | print_help_line("-o ","-o, --output ","output method, one of: "); 83 | print_help_line("","",OUTPUT_METHODS); 84 | print_help_line("-u","-u, --unit ","unit to show. one of bytes, bits, packets, errors"); 85 | #if EXTENDED_STATS 86 | print_help_line("-T","-T, --type ","type of stats. one of rate, max, sum, avg"); 87 | #endif 88 | #ifdef CSV 89 | print_help_line("-C ","-C, --csvchar ","delimiter for csv"); 90 | #endif 91 | #if CSV || HTML 92 | print_help_line("-F ","-F, --outfile ","output file for csv and html (default stdout)"); 93 | #endif 94 | #ifdef HTML 95 | print_help_line("-R ","-R, --htmlrefresh ","meta refresh for html output"); 96 | print_help_line("-H","-H, --htmlheader","show and frame for html output"); 97 | #endif 98 | print_help_line("-c ","-c, --count ","number of query/output for plain & csv"); 99 | print_help_line("-N","-N, --ansiout","disable ansi codes for plain output"); 100 | print_help_line("","","(ie 1 for one single output)"); 101 | printf("\n"); 102 | exit(EXIT_SUCCESS); 103 | } 104 | 105 | #ifdef HAVE_CURSES 106 | void print_online_help() { 107 | WINDOW *helpwin; 108 | helpwin=newwin(15,76,0,1); 109 | box(helpwin,ACS_VLINE, ACS_HLINE); 110 | mvwprintw(helpwin,0,2,"bwm-ng v" VERSION " - Keybindings:"); 111 | mvwprintw(helpwin,2,2,"'h' show this help"); 112 | mvwprintw(helpwin,3,2,"'q' exit"); 113 | mvwprintw(helpwin,4,2,"'+' increases timeout by 100ms"); 114 | mvwprintw(helpwin,5,2,"'-' decreases timeout by 100ms"); 115 | if (output_method==CURSES_OUT) 116 | mvwprintw(helpwin,6,2,"'d' switch KB and auto assign Byte/KB/MB/GB"); 117 | else 118 | mvwprintw(helpwin,6,2,"'d' cycle: show interfaces step by step"); 119 | mvwprintw(helpwin,7,2,"'a' cycle: show all interfaces, only those which are up,"); 120 | mvwprintw(helpwin,8,2," only up and not hidden"); 121 | mvwprintw(helpwin,9,2,"'s' sum hidden ifaces to total aswell or not"); 122 | mvwprintw(helpwin,10,2,"'n' cycle: input methods"); 123 | if (output_method==CURSES_OUT) { mvwprintw(helpwin,11,2,"'u' cycle: bytes,bits,packets,errors"); 124 | #if EXTENDED_STATS 125 | mvwprintw(helpwin,12,2,"'t' cycle: current rate, max, sum since start, average for last 30s"); 126 | #endif 127 | } 128 | else { 129 | #if EXTENDED_STATS 130 | mvwprintw(helpwin,11,2,"'t' cycle: current rate, max, sum since start, average for last 30s"); 131 | #endif 132 | }; 133 | mvwprintw(helpwin,14,2," press any key to continue... "); 134 | wrefresh(helpwin); 135 | timeout(-1); 136 | getch(); 137 | timeout(delay); 138 | delwin(helpwin); 139 | } 140 | #endif 141 | -------------------------------------------------------------------------------- /src/help.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng help header * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __HELP_H 23 | #define __HELP_H 24 | 25 | #include "defines.h" 26 | #include "types.h" 27 | #include "options.h" 28 | 29 | /* print cmdline help */ 30 | void cmdln_printhelp(void); 31 | 32 | #ifdef HAVE_CURSES 33 | void print_online_help(void); 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/input/devstat.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "devstat.h" 23 | 24 | 25 | #if DEVSTAT_IN 26 | #ifndef HAVE_DEVSTAT_GETDEVS 27 | #define devstat_getdevs(_n,_m) getdevs(_m) 28 | #define devstat_selectdevs selectdevs 29 | #endif 30 | void get_iface_stats_devstat (char verbose) { 31 | int current_if_num=0,hidden_if=0; 32 | struct statinfo dev_stats; 33 | struct device_selection *dev_sel = NULL; 34 | int n_selected, n_selections; 35 | long sel_gen; 36 | struct devstat *dev_ptr; 37 | 38 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 39 | t_iface_speed_stats tmp_if_stats; 40 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 41 | 42 | if (!(dev_stats.dinfo=malloc(sizeof(struct devinfo)))) 43 | deinit(1,"malloc failure\n"); 44 | bzero(dev_stats.dinfo, sizeof(struct devinfo)); 45 | 46 | if ((devstat_getdevs(NULL, (struct statinfo *)&dev_stats)) < 0) { 47 | free(dev_stats.dinfo); 48 | deinit(1,"getdevs failed: %s\n",devstat_errbuf); 49 | } 50 | if (devstat_selectdevs(&dev_sel, &n_selected, &n_selections, &sel_gen, dev_stats.dinfo->generation, dev_stats.dinfo->devices, dev_stats.dinfo->numdevs, NULL, 0, NULL, 0, DS_SELECT_ONLY, dev_stats.dinfo->numdevs, 1) < 0) { 51 | free(dev_stats.dinfo); 52 | deinit(1,"selectdevs failed: %s\n",devstat_errbuf); 53 | } 54 | for(current_if_num=0;current_if_numnumdevs;current_if_num++){ 55 | dev_ptr=&dev_stats.dinfo->devices[dev_sel[current_if_num].position]; 56 | #ifdef HAVE_STRUCT_DEVSTAT_BYTES_READ 57 | tmp_if_stats.bytes.in=dev_ptr->bytes_read; 58 | tmp_if_stats.bytes.out=dev_ptr->bytes_written; 59 | tmp_if_stats.packets.in=dev_ptr->num_read; 60 | tmp_if_stats.packets.out=dev_ptr->num_written; 61 | #else 62 | tmp_if_stats.bytes.in=dev_ptr->bytes[DEVSTAT_READ]; 63 | tmp_if_stats.bytes.out=dev_ptr->bytes[DEVSTAT_WRITE]; 64 | tmp_if_stats.packets.in=dev_ptr->operations[DEVSTAT_READ]; 65 | tmp_if_stats.packets.out=dev_ptr->operations[DEVSTAT_WRITE]; 66 | #endif 67 | tmp_if_stats.errors.in = tmp_if_stats.errors.out = 0; 68 | 69 | size_t needed = snprintf(NULL, 0, "%s%d", dev_ptr->device_name,dev_ptr->unit_number); 70 | char *device_fullname = malloc(needed); 71 | sprintf(device_fullname,"%s%d", dev_ptr->device_name,dev_ptr->unit_number); 72 | 73 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, device_fullname, current_if_num, verbose,(tmp_if_stats.bytes.in != 0 || tmp_if_stats.bytes.out != 0)); 74 | free(device_fullname); 75 | 76 | } 77 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 78 | free(dev_stats.dinfo); 79 | return; 80 | } 81 | #endif 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/input/devstat.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __DEVSTAT_H 23 | #define __DEVSTAT_H 24 | 25 | #include "retrieve.h" 26 | 27 | 28 | #if DEVSTAT_IN 29 | #include 30 | #include 31 | 32 | void get_iface_stats_devstat (char verbose); 33 | #endif 34 | 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/input/getifaddrs.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "getifaddrs.h" 23 | 24 | #ifdef GETIFADDRS 25 | /* do the actual work, get and print stats if verbose */ 26 | void get_iface_stats_getifaddrs (char verbose) { 27 | char *name=NULL; 28 | 29 | struct ifaddrs *net, *net_ptr=NULL; 30 | struct if_data *net_data; 31 | 32 | int hidden_if=0,current_if_num=0; 33 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 34 | t_iface_speed_stats tmp_if_stats; 35 | 36 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 37 | 38 | /* dont open proc_net_dev if netstat_i is requested, else try to open and if it fails fallback */ 39 | if (getifaddrs(&net) != 0) { 40 | deinit(1, "getifaddr failed: %s\n",strerror(errno)); 41 | } 42 | net_ptr=net; 43 | /* loop either while netstat enabled and still lines to read 44 | * or still buffer (buf) left */ 45 | while (net_ptr!=NULL) { 46 | /* move getifaddr data to my struct */ 47 | if (net_ptr->ifa_addr==NULL || net_ptr->ifa_addr->sa_family != AF_LINK) { 48 | net_ptr=net_ptr->ifa_next; 49 | continue; 50 | } 51 | if (net_ptr->ifa_name!=NULL) 52 | name=strdup(net_ptr->ifa_name); 53 | else 54 | name=strdup(""); 55 | if (net_ptr->ifa_data!=NULL) { 56 | net_data=(struct if_data *)net_ptr->ifa_data; 57 | tmp_if_stats.bytes.in=net_data->ifi_ibytes; 58 | tmp_if_stats.bytes.out=net_data->ifi_obytes; 59 | tmp_if_stats.packets.in=net_data->ifi_ipackets; 60 | tmp_if_stats.packets.out=net_data->ifi_opackets; 61 | tmp_if_stats.errors.in=net_data->ifi_ierrors; 62 | tmp_if_stats.errors.out=net_data->ifi_oerrors; 63 | } else { 64 | net_ptr=net_ptr->ifa_next; 65 | continue; 66 | } 67 | /* init new interfaces and add fetched data to old or new one */ 68 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, (show_all_if || (net_ptr->ifa_flags & IFF_UP))); 69 | net_ptr=net_ptr->ifa_next; 70 | free(name); 71 | current_if_num++; 72 | } /* fgets done (while) */ 73 | /* add to total stats and output current stats if verbose */ 74 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 75 | /* close input stream */ 76 | freeifaddrs(net); 77 | return; 78 | } 79 | #endif 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/input/getifaddrs.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __GETIFADDRS_H 23 | #define __GETIFADDRS_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef GETIFADDRS 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | void get_iface_stats_getifaddrs (char verbose); 34 | 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/input/ioservice.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "ioservice.h" 23 | 24 | #if IOSERVICE_IN 25 | void get_disk_stats_ioservice (char verbose) { 26 | int current_if_num=0,hidden_if=0; 27 | io_iterator_t dlist = 0; 28 | mach_port_t port = 0; 29 | io_registry_entry_t disk = 0; 30 | CFDictionaryRef props = 0; 31 | CFDictionaryRef props2 = 0; 32 | CFDictionaryRef dstats = 0; 33 | CFNumberRef value = NULL; 34 | CFMutableDictionaryRef match; 35 | io_registry_entry_t parent; 36 | io_name_t name; 37 | char deviceFilePath[MAXPATHLEN]; //MAXPATHLEN is defined in sys/param.h 38 | CFStringRef name_str; 39 | 40 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 41 | t_iface_speed_stats tmp_if_stats; 42 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 43 | 44 | if (IOMasterPort(MACH_PORT_NULL, &port)) 45 | deinit(1,"failure while initializing disk port\n"); 46 | match = IOServiceMatching("IOMedia"); 47 | CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); 48 | if (IOServiceGetMatchingServices(port, match, &dlist)!=KERN_SUCCESS) 49 | deinit(1,"failure while getting disk list\n"); 50 | while ( (disk = IOIteratorNext(dlist)) ) { 51 | IORegistryEntryCreateCFProperties (disk,(CFMutableDictionaryRef *) &props,kCFAllocatorDefault,kNilOptions); 52 | if (props) { 53 | if (!long_darwin_disk_names) { 54 | name_str = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey)); 55 | if (name_str) { 56 | CFStringGetCString(name_str, deviceFilePath, MAXPATHLEN-1, CFStringGetSystemEncoding()); 57 | } else { 58 | snprintf((char *)deviceFilePath,MAXPATHLEN-1,"unknown%i",current_if_num); 59 | deviceFilePath[MAXPATHLEN-1]=0; 60 | } 61 | } else { 62 | if (IORegistryEntryGetName(disk, name )!=KERN_SUCCESS) { 63 | snprintf((char *)name,sizeof(name)-1,"unknown%i",current_if_num); 64 | name[sizeof(name)-1]=0; 65 | } 66 | } 67 | if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent)!=KERN_SUCCESS) { 68 | CFRelease(props); 69 | IOObjectRelease(disk); 70 | IOIteratorReset(dlist); 71 | deinit(1,"disk has no parent\n"); 72 | } 73 | IORegistryEntryCreateCFProperties(parent, (CFMutableDictionaryRef *)&props2,kCFAllocatorDefault, kNilOptions); 74 | if (props2) { 75 | dstats = CFDictionaryGetValue(props2, CFSTR(kIOBlockStorageDriverStatisticsKey)); 76 | if (dstats) { 77 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)); 78 | if (value) 79 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.bytes.in); 80 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)); 81 | if (value) 82 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.bytes.out); 83 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsReadsKey)); 84 | if (value) 85 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.packets.in); 86 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsWritesKey)); 87 | if (value) 88 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.packets.out); 89 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsReadErrorsKey)); 90 | if (value) 91 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.errors.in); 92 | value = CFDictionaryGetValue (dstats,CFSTR(kIOBlockStorageDriverStatisticsWriteErrorsKey)); 93 | if (value) 94 | CFNumberGetValue(value, kCFNumberSInt64Type, &tmp_if_stats.errors.out); 95 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, long_darwin_disk_names ? (char *)name : deviceFilePath 96 | , current_if_num, verbose,(tmp_if_stats.bytes.in != 0 || tmp_if_stats.bytes.out != 0)); 97 | current_if_num++; 98 | } 99 | CFRelease(props2); 100 | } 101 | IOObjectRelease(parent); 102 | CFRelease(props); 103 | props = 0; 104 | } 105 | IOObjectRelease(disk); 106 | disk = 0; 107 | } 108 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 109 | IOObjectRelease(dlist); 110 | } 111 | #endif 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/input/ioservice.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __IOSERVICE_H 23 | #define __IOSERVICE_H 24 | 25 | #include "retrieve.h" 26 | 27 | #if IOSERVICE_IN 28 | #include 29 | #include 30 | #include 31 | #include 32 | #ifndef LONG_DARWIN_DEV_NAMES 33 | #include 34 | #include 35 | #endif 36 | 37 | void get_disk_stats_ioservice (char verbose); 38 | #endif 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/input/libkstat.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "libkstat.h" 23 | 24 | #if HAVE_LIBKSTAT 25 | void get_iface_stats_kstat (char verbose) { 26 | kstat_ctl_t *kc; 27 | kstat_t *ksp; 28 | kstat_io_t kio; 29 | kstat_named_t *i_bytes=NULL,*o_bytes=NULL,*i_packets=NULL,*o_packets=NULL,*i_errors=NULL,*o_errors=NULL; 30 | char *name; 31 | int hidden_if=0,current_if_num=0,my_errno=0; 32 | t_iface_speed_stats tmp_if_stats; 33 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 34 | 35 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 36 | kc = kstat_open(); 37 | if (kc==NULL) deinit(1, "kstat failed: %s\n",strerror(my_errno)); 38 | name=(char *)malloc(KSTAT_STRLEN); 39 | if (!name) { 40 | kstat_close(kc); 41 | deinit(1,"mem alloc failed: %s\n",strerror(errno)); 42 | } 43 | 44 | /* loop for interfaces */ 45 | for (ksp = kc->kc_chain;ksp != NULL;ksp = ksp->ks_next) { 46 | if ((strcmp(ksp->ks_class, "net") != 0 && input_method==KSTAT_IN) || (strcmp(ksp->ks_class, "disk") != 0 && input_method==KSTATDISK_IN && ksp->ks_type != KSTAT_TYPE_IO)) 47 | continue; /* skip all other stats */ 48 | strncpy(name,ksp->ks_name,KSTAT_STRLEN); 49 | name[KSTAT_STRLEN-1]='\0'; 50 | if (KSTAT_IN==input_method) { 51 | kstat_read(kc, ksp, NULL); 52 | i_bytes=(kstat_named_t *)kstat_data_lookup(ksp, "rbytes"); 53 | o_bytes=(kstat_named_t *)kstat_data_lookup(ksp, "obytes"); 54 | i_packets=(kstat_named_t *)kstat_data_lookup(ksp, "ipackets"); 55 | o_packets=(kstat_named_t *)kstat_data_lookup(ksp, "opackets"); 56 | i_errors=(kstat_named_t *)kstat_data_lookup(ksp, "ierrors"); 57 | o_errors=(kstat_named_t *)kstat_data_lookup(ksp, "oerrors"); 58 | if (!i_bytes || !o_bytes || !i_packets || !o_packets || !i_errors || !o_errors) 59 | continue; 60 | /* use ui32 values, the 64 bit values return strange (very big) differences */ 61 | tmp_if_stats.bytes.in=i_bytes->value.ui32; 62 | tmp_if_stats.bytes.out=o_bytes->value.ui32; 63 | tmp_if_stats.packets.in=i_packets->value.ui32; 64 | tmp_if_stats.packets.out=o_packets->value.ui32; 65 | tmp_if_stats.errors.in=i_errors->value.ui32; 66 | tmp_if_stats.errors.out=o_errors->value.ui32; 67 | } else if (KSTATDISK_IN==input_method) { 68 | kstat_read(kc, ksp, &kio); 69 | tmp_if_stats.bytes.in=kio.nread; 70 | tmp_if_stats.bytes.out=kio.nwritten; 71 | tmp_if_stats.packets.in=kio.reads; 72 | tmp_if_stats.packets.out=kio.writes; 73 | tmp_if_stats.errors.in=tmp_if_stats.errors.out=0; 74 | } else { 75 | free(name); 76 | kstat_close(kc); 77 | deinit(1,"im confused about kstat input methods!\n"); 78 | } 79 | /* init new interfaces and add fetched data to old or new one */ 80 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, (tmp_if_stats.bytes.in != 0 || tmp_if_stats.bytes.out != 0)); 81 | current_if_num++; 82 | } 83 | /* add to total stats and output current stats if verbose */ 84 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 85 | /* clean buffers */ 86 | free(name); 87 | kstat_close(kc); 88 | return; 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /src/input/libkstat.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __LIBKSTAT_H 23 | #define __LIBKSTAT_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef HAVE_LIBKSTAT 28 | #include 29 | 30 | void get_iface_stats_kstat (char verbose); 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/input/libstatgrab.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "libstatgrab.h" 23 | 24 | #ifdef LIBSTATGRAB 25 | /* do the actual work, get and print stats if verbose */ 26 | void get_iface_stats_libstat (char verbose) { 27 | sg_network_io_stats *network_stats=NULL; 28 | size_t num_network_stats; 29 | int current_if_num=0,hidden_if=0; 30 | 31 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 32 | t_iface_speed_stats tmp_if_stats; 33 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 34 | 35 | network_stats = sg_get_network_io_stats(&num_network_stats); 36 | if (network_stats == NULL){ 37 | deinit(1, "libstatgrab error!\n"); 38 | } 39 | 40 | for (current_if_num=0;current_if_numrx; 42 | tmp_if_stats.bytes.out=network_stats->tx; 43 | tmp_if_stats.packets.in=network_stats->ipackets; 44 | tmp_if_stats.packets.out=network_stats->opackets; 45 | tmp_if_stats.errors.in=network_stats->ierrors; 46 | tmp_if_stats.errors.out=network_stats->oerrors; 47 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, network_stats->interface_name, current_if_num, verbose 48 | #ifdef IOCTL 49 | ,check_if_up(network_stats->interface_name) 50 | #else 51 | ,1 52 | #endif 53 | ); 54 | network_stats++; 55 | } 56 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 57 | 58 | return; 59 | } 60 | 61 | void get_iface_stats_libstatdisk (char verbose) { 62 | sg_disk_io_stats *disk_stats=NULL; 63 | size_t num_disk_stats; 64 | int current_if_num=0,hidden_if=0; 65 | 66 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 67 | t_iface_speed_stats tmp_if_stats; 68 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 69 | 70 | disk_stats = sg_get_disk_io_stats(&num_disk_stats); 71 | if (disk_stats == NULL){ 72 | deinit(1, "libstatgrab error!\n"); 73 | } 74 | 75 | for (current_if_num=0;current_if_numread_bytes; 77 | tmp_if_stats.bytes.out=disk_stats->write_bytes; 78 | tmp_if_stats.packets.in=0; 79 | tmp_if_stats.packets.out=0; 80 | tmp_if_stats.errors.in=0; 81 | tmp_if_stats.errors.out=0; 82 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, disk_stats->disk_name, current_if_num, verbose,1); 83 | disk_stats++; 84 | } 85 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 86 | 87 | return; 88 | } 89 | #endif 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/input/libstatgrab.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __LIBSTATGRAB_H 23 | #define __LIBSTATGRAB_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef LIBSTATGRAB 28 | #include 29 | 30 | void get_iface_stats_libstat (char verbose); 31 | void get_iface_stats_libstatdisk (char verbose); 32 | #endif 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/input/netstat.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "netstat.h" 23 | 24 | #if NETSTAT_BSD || NETSTAT_SOLARIS || NETSTAT_BSD_BYTES || NETSTAT_NETBSD 25 | /* counts the tokens in a string */ 26 | long count_tokens(char *in_str) { 27 | long tokens=0; 28 | long i=0; 29 | char in_a_token=0; 30 | char *str; 31 | 32 | if (in_str==NULL) return 0; 33 | str=in_str; 34 | while (str[i]!='\0') { 35 | if (str[i]>32) { 36 | if (!in_a_token) { 37 | tokens++; 38 | in_a_token=1; 39 | } 40 | } else { 41 | if (in_a_token) in_a_token=0; 42 | } 43 | i++; 44 | } 45 | return tokens; 46 | } 47 | #endif 48 | 49 | #ifdef NETSTAT 50 | /* do the actual work, get and print stats if verbose */ 51 | void get_iface_stats_netstat (char verbose) { 52 | int current_if_num=0,hidden_if=0; 53 | char *buffer=NULL,*name=NULL; 54 | #if NETSTAT_NETBSD 55 | char *str_buf=NULL; 56 | char *test_buf; 57 | char *buffer2=NULL; 58 | FILE *f2=NULL; 59 | #endif 60 | #if NETSTAT_BSD || NETSTAT_BSD_BYTES || NETSTAT_SOLARIS || NETSTAT_NETBSD 61 | char *last_name=NULL; 62 | #endif 63 | FILE *f=NULL; 64 | 65 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 66 | t_iface_speed_stats tmp_if_stats; 67 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 68 | if (!(f=(FILE *)popen( 69 | #if NETSTAT_BSD || NETSTAT_BSD_BYTES 70 | #if NETSTAT_BSD_LINK 71 | NETSTAT_PATH " -iW -f link" 72 | #else 73 | NETSTAT_PATH " -iW" 74 | #endif 75 | #if NETSTAT_BSD_BYTES 76 | " -b" 77 | #endif 78 | #endif 79 | #if NETSTAT_LINUX || NETSTAT_LINUX_NEW 80 | show_all_if ? NETSTAT_PATH " -ia" : NETSTAT_PATH " -i" 81 | #endif 82 | #if NETSTAT_SOLARIS 83 | NETSTAT_PATH " -i -f inet -f inet6" 84 | #endif 85 | #if NETSTAT_NETBSD 86 | NETSTAT_PATH " -ib" 87 | #endif 88 | ,"r"))) 89 | deinit(1, "no input stream found: %s\n",strerror(errno)); 90 | #if NETSTAT_NETBSD 91 | if (!(f2=popen( NETSTAT_PATH " -i","r"))) 92 | deinit(1, "no input stream found: %s\n",strerror(errno)); 93 | buffer2=(char *)malloc(MAX_LINE_BUFFER); 94 | if ((fgets(buffer2,MAX_LINE_BUFFER,f2) == NULL )) deinit(1, "read of netstat failed: %s\n",strerror(errno)); 95 | str_buf=(char *)malloc(MAX_LINE_BUFFER); 96 | #endif 97 | buffer=(char *)malloc(MAX_LINE_BUFFER); 98 | #if NETSTAT_LINUX || NETSTAT_LINUX_NEW 99 | /* we skip first 2 lines if not bsd at any mode */ 100 | if ((fgets(buffer,MAX_LINE_BUFFER,f) == NULL ) || (fgets(buffer,MAX_LINE_BUFFER,f) == NULL )) 101 | deinit(1, "read of netstat failed: %s\n",strerror(errno)); 102 | #endif 103 | #if NETSTAT_BSD || NETSTAT_BSD_BYTES || NETSTAT_SOLARIS || NETSTAT_NETBSD 104 | last_name=(char *)malloc(MAX_LINE_BUFFER); 105 | last_name[0]='\0'; /* init */ 106 | if ((fgets(buffer,MAX_LINE_BUFFER,f) == NULL )) deinit(1, "read of netstat failed: %s\n",strerror(errno)); 107 | #endif 108 | name=(char *)malloc(MAX_LINE_BUFFER); 109 | /* loop and read each line */ 110 | while ( (fgets(buffer,MAX_LINE_BUFFER,f) != NULL && buffer[0]!='\n') ) { 111 | memset(&tmp_if_stats,0,(size_t)sizeof(t_iface_speed_stats)); /* reinit it to zero */ 112 | #ifdef NETSTAT_LINUX 113 | sscanf(buffer,"%s%*i%*i%llu%llu%*i%*i%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 114 | #endif 115 | #ifdef NETSTAT_LINUX_NEW 116 | sscanf(buffer,"%s%*i%llu%llu%*i%*i%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 117 | #endif 118 | #if NETSTAT_BSD_BYTES 119 | if (count_tokens(buffer)>10) /* including address */ 120 | sscanf(buffer,"%s%*i%*s%*s%llu%llu%llu%llu%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.bytes.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out,&tmp_if_stats.bytes.out); 121 | else /* w/o address */ 122 | sscanf(buffer,"%s%*i%*s%llu%llu%llu%llu%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.bytes.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out,&tmp_if_stats.bytes.out); 123 | #endif 124 | #if NETSTAT_BSD || NETSTAT_SOLARIS 125 | if (count_tokens(buffer)>=8) /* including address */ 126 | sscanf(buffer,"%s%*i%*s%*s%llu%llu%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 127 | else /* w/o address */ 128 | sscanf(buffer,"%s%*i%*s%llu%llu%llu%llu",name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 129 | #endif 130 | #if NETSTAT_NETBSD 131 | test_buf=fgets(buffer2,MAX_LINE_BUFFER,f2); 132 | if (count_tokens(buffer)>=6) { /* including address */ 133 | if (test_buf) sscanf(buffer2,"%s%s%s%s%llu%llu%llu%llu",str_buf,str_buf,str_buf,str_buf,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 134 | sscanf(buffer,"%s%s%s%s%llu%llu",name,str_buf,str_buf,str_buf,&tmp_if_stats.bytes.in,&tmp_if_stats.bytes.out); 135 | } else { 136 | if (test_buf) sscanf(buffer2,"%s%s%s%llu%llu%llu%llu",str_buf,str_buf,str_buf,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 137 | sscanf(buffer,"%s%s%s%llu%llu",name,str_buf,str_buf,&tmp_if_stats.bytes.in,&tmp_if_stats.bytes.out); 138 | } 139 | #endif 140 | #if NETSTAT_BSD || NETSTAT_BSD_BYTES || NETSTAT_SOLARIS || NETSTAT_NETBSD 141 | /* check if we have a new iface or if its only a second line of the same one */ 142 | if (!strcmp(last_name,name)) continue; /* skip this line */ 143 | strlcpy(last_name,name,MAX_LINE_BUFFER); 144 | #endif 145 | /* init new interfaces and add fetched data to old or new one */ 146 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, 147 | #if NETSTAT_BSD || NETSTAT_BSD_BYTES || NETSTAT_NETBSD 148 | (name[strlen(name)-1]!='*') 149 | #else 150 | 1 151 | #endif 152 | ); 153 | 154 | current_if_num++; 155 | } /* fgets done (while) */ 156 | /* add to total stats and output current stats if verbose */ 157 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 158 | /* clean buffers */ 159 | free(buffer); 160 | #if NETSTAT_NETBSD 161 | free(buffer2); 162 | free(str_buf); 163 | pclose(f2); 164 | #endif 165 | #if NETSTAT_BSD || NETSTAT_NETBSD || NETSTAT_BSD_BYTES || NETSTAT_SOLARIS 166 | free(last_name); 167 | #endif 168 | free(name); 169 | /* close input stream */ 170 | pclose(f); 171 | return; 172 | } 173 | #endif 174 | 175 | 176 | -------------------------------------------------------------------------------- /src/input/netstat.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __NETSTAT_H 23 | #define __NETSTAT_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef NETSTAT 28 | void get_iface_stats_netstat (char verbose); 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/input/proc_diskstats.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "proc_diskstats.h" 23 | 24 | 25 | #ifdef PROC_DISKSTATS 26 | int get_short_devfs_name(char *devicename); 27 | 28 | /* convert devfs name to a short abr - some ugly code 29 | * return: 1 on success, -1 on nothing to be done, 0 on failure */ 30 | int get_short_devfs_name(char *devicename) { 31 | char *short_devicename=NULL; 32 | char *ptr=NULL; 33 | 34 | if ((ptr=strchr(devicename,'/'))) { 35 | if (!(short_devicename=(char *)malloc(MAX_LINE_BUFFER))) 36 | return 0; 37 | strncpy(short_devicename,devicename,(int)(ptr-devicename)); 38 | short_devicename[(int)(ptr-devicename)]=0; 39 | while ((ptr=strchr(ptr,'/'))) { 40 | ptr++; 41 | strncat(short_devicename,&ptr[0],1); 42 | while (tolower(ptr[0])>='a' && tolower(ptr[0])<='z') ptr++; 43 | while (ptr[0]>='0' && ptr[0]<='9') { 44 | strncat(short_devicename,&ptr[0],1); 45 | ptr++; 46 | } 47 | } 48 | strcpy(devicename,short_devicename); 49 | free(short_devicename); 50 | return 1; 51 | } 52 | return -1; 53 | } 54 | 55 | /* do the actual work, get and print stats if verbose */ 56 | void get_disk_stats_proc (char verbose) { 57 | FILE *f=NULL,*f_s=NULL; 58 | char *buffer=NULL,*name=NULL,*ptr; 59 | ullong tmp_long; 60 | int n,major,minor,maj_s,min_s; 61 | static char diskstats_works = 1; 62 | static char proc_stat[PATH_MAX] = ""; 63 | 64 | int hidden_if=0,current_if_num=0; 65 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 66 | t_iface_speed_stats tmp_if_stats; 67 | 68 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 69 | /* dont open proc_net_dev if netstat_i is requested, else try to open and if it fails fallback */ 70 | if (diskstats_works && !(f=fopen(PROC_DISKSTATS_FILE,"r"))) { 71 | diskstats_works = 0; 72 | } 73 | buffer=(char *)malloc(MAX_LINE_BUFFER); 74 | name=(char *)malloc(MAX_LINE_BUFFER); 75 | if (!name || !buffer) { 76 | if (name) free(name); 77 | if (buffer) free(buffer); 78 | if (f) fclose(f); 79 | deinit(1,"mem alloc failed: %s\n",strerror(errno)); 80 | } 81 | 82 | if (!diskstats_works) { 83 | if (!(f=fopen(PROC_PARTITIONS_FILE,"r"))) { 84 | diskstats_works = 1; 85 | } else { 86 | /* skip first two lines in /proc/partitions */ 87 | if (fgets(buffer,MAX_LINE_BUFFER,f) && 88 | fgets(buffer,MAX_LINE_BUFFER,f)) { 89 | /* read correctly */ 90 | ; 91 | } else { 92 | /* error or EOF while reading file, either way we can't continue */ 93 | deinit(1, "reading %s failed, or file was too short: %s\n", PROC_PARTITIONS_FILE, strerror(errno)); 94 | } 95 | } 96 | } 97 | 98 | while ( (fgets(buffer,MAX_LINE_BUFFER,f) != NULL) ) { 99 | n = sscanf(buffer, 100 | (diskstats_works ? "%i %i %s %llu%llu%llu%llu%llu%llu%llu%*i" : "%i %i %*i %s %llu%llu%llu%llu%llu%llu%llu%*i"), 101 | &major,&minor,name,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.bytes.in,&tmp_long,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out,&tmp_if_stats.bytes.out); 102 | /* skip loop devices, we dont see stats anyway */ 103 | if (major == 7) continue; 104 | if (n == 7) { 105 | /* its a partition with shorter stats, move all to correct fields */ 106 | tmp_if_stats.packets.out=tmp_if_stats.bytes.in; 107 | tmp_if_stats.bytes.in=tmp_if_stats.errors.in; 108 | tmp_if_stats.bytes.out=tmp_long; 109 | tmp_if_stats.errors.in=0; 110 | tmp_if_stats.errors.out=0; 111 | } else { 112 | /* having 10 fields all is just fine, else check for other formats */ 113 | if (n != 10) { 114 | if (diskstats_works == 0 && n == 3) { 115 | /* we are reading /proc/partitions and have the 116 | * old 2.4 partitions format, look in /proc/stat for block devince data */ 117 | if (proc_stat[0] == 0) { 118 | /* build /proc/stat path */ 119 | strcpy(proc_stat,PROC_PARTITIONS_FILE); 120 | if ((ptr=strrchr(proc_stat,'/'))) { 121 | ptr++; 122 | strcpy(ptr,"stat"); 123 | } else { 124 | free(name); 125 | free(buffer); 126 | deinit(1, "strange /proc/partitions name, couldnt build /proc/stats name\n"); 127 | } 128 | } 129 | if (!(f_s=fopen(proc_stat,"r"))) { 130 | free(name); 131 | free(buffer); 132 | deinit(1, "couldnt open %s: %s\n",proc_stat,strerror(errno)); 133 | } 134 | while ( (fgets(buffer,MAX_LINE_BUFFER,f_s) != NULL)) { 135 | if (!strncmp("disk_io:",buffer,8)) { 136 | ptr=buffer+9; 137 | while (ptr[0]!=0) { 138 | n = sscanf(ptr,"(%i,%i): (%*i,%llu,%llu,%llu,%llu)",&maj_s,&min_s,&tmp_if_stats.packets.in,&tmp_if_stats.bytes.in,&tmp_if_stats.packets.out,&tmp_if_stats.bytes.out); 139 | if (maj_s==major && min_s==minor) { 140 | /* we found the correct device */ 141 | fclose(f_s); 142 | f_s=NULL; 143 | break; 144 | } 145 | if (!(ptr=strchr(ptr,' '))) 146 | break; 147 | ptr++; 148 | } 149 | if (!f_s) 150 | break; 151 | } 152 | } 153 | if (f_s) { 154 | fclose(f_s); 155 | /* couldnt find the entry, prolly a partition */ 156 | continue; 157 | } 158 | } else { 159 | /* neither new nor old /proc/partitions nor /proc/diskstats */ 160 | free(name); 161 | deinit(1, "wrong format of procfile. %i: %s\n",n,buffer); 162 | free(buffer); 163 | } 164 | } 165 | } 166 | /* stats are in 512 byte blocks */ 167 | tmp_if_stats.bytes.in*=512; 168 | tmp_if_stats.bytes.out*=512; 169 | /* convert devfs name to a short abr */ 170 | get_short_devfs_name(name); 171 | /* init new interfaces and add fetched data to old or new one */ 172 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose,(n==10 || proc_stat[0] != 0)); 173 | current_if_num++; 174 | } /* fgets done (while) */ 175 | /* add to total stats and output current stats if verbose */ 176 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 177 | /* clean buffers */ 178 | free(buffer); 179 | free(name); 180 | /* close input stream */ 181 | fclose(f); 182 | return; 183 | } 184 | #endif 185 | 186 | 187 | -------------------------------------------------------------------------------- /src/input/proc_diskstats.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __PROC_DISKSTATS_H 23 | #define __PROC_DISKSTATS_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef PROC_DISKSTATS 28 | #define LOOP_MAJOR 7 29 | 30 | void get_disk_stats_proc (char verbose); 31 | #endif 32 | 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/input/proc_net_dev.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "proc_net_dev.h" 23 | 24 | #ifdef PROC_NET_DEV 25 | /* do the actual work, get and print stats if verbose */ 26 | void get_iface_stats_proc (char verbose) { 27 | char *ptr; 28 | 29 | FILE *f=NULL; 30 | char *buffer=NULL,*name=NULL; 31 | 32 | int hidden_if=0,current_if_num=0; 33 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 34 | t_iface_speed_stats tmp_if_stats; 35 | 36 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 37 | /* dont open proc_net_dev if netstat_i is requested, else try to open and if it fails fallback */ 38 | if (!(f=fopen(PROC_FILE,"r"))) { 39 | deinit(1, "open of procfile failed: %s\n",strerror(errno)); 40 | } 41 | buffer=(char *)malloc(MAX_LINE_BUFFER); 42 | 43 | /* we skip first 2 lines if not bsd at any mode */ 44 | if ((fgets(buffer,MAX_LINE_BUFFER,f) == NULL ) || 45 | (fgets(buffer,MAX_LINE_BUFFER,f) == NULL )) 46 | deinit(1, "read of proc failed: %s\n",strerror(errno)); 47 | 48 | name=(char *)malloc(MAX_LINE_BUFFER); 49 | while ( (fgets(buffer,MAX_LINE_BUFFER,f) != NULL) ) { 50 | /* get the name */ 51 | ptr=strchr(buffer,':'); 52 | /* wrong format */ 53 | if (ptr==NULL) { deinit(1, "wrong format of input stream\n"); } 54 | /* set : to end_of_string and move to first char of "next" string (to first data) */ 55 | *ptr++ = 0; 56 | sscanf(ptr,"%llu%llu%llu%*i%*i%*i%*i%*i%llu%llu%llu",&tmp_if_stats.bytes.in,&tmp_if_stats.packets.in,&tmp_if_stats.errors.in,&tmp_if_stats.bytes.out,&tmp_if_stats.packets.out,&tmp_if_stats.errors.out); 57 | sscanf(buffer,"%s",name); 58 | /* init new interfaces and add fetched data to old or new one */ 59 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose 60 | #ifdef IOCTL 61 | ,check_if_up(name) 62 | #else 63 | ,1 64 | #endif 65 | ); 66 | current_if_num++; 67 | } /* fgets done (while) */ 68 | /* add to total stats and output current stats if verbose */ 69 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 70 | /* clean buffers */ 71 | free(buffer); 72 | free(name); 73 | /* close input stream */ 74 | fclose(f); 75 | return; 76 | } 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /src/input/proc_net_dev.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __PROC_NET_DEV_H 23 | #define __PROC_NET_DEV_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef PROC_NET_DEV 28 | void get_iface_stats_proc (char verbose); 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/input/retrieve.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "retrieve.h" 23 | 24 | #ifdef IOCTL 25 | /* test whether the iface is up or not */ 26 | char check_if_up(char *ifname) { 27 | struct ifreq ifr; 28 | /* check if we already opened the file descriptor 29 | * if not open it now */ 30 | if (skfd < 0) { 31 | if ((skfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { 32 | deinit(1, "socket error: %s\n",strerror(errno)); 33 | } 34 | } 35 | /* setup the struct */ 36 | strncpy(ifr.ifr_name, ifname,sizeof(ifr.ifr_name)); 37 | ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; 38 | /* lookup the status */ 39 | if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) { 40 | return 0; /* return if as down if there was an error */ 41 | } 42 | /* check against IFF_UP and return */ 43 | return (ifr.ifr_flags & IFF_UP); 44 | } 45 | #endif 46 | 47 | /* chooses the correct get_iface_stats() to use */ 48 | void get_iface_stats(char _n) { 49 | switch (input_method) { 50 | #ifdef NETSTAT 51 | case NETSTAT_IN: 52 | get_iface_stats_netstat(_n); 53 | break; 54 | #endif 55 | #ifdef LIBSTATGRAB 56 | case LIBSTAT_IN: 57 | get_iface_stats_libstat(_n); 58 | break; 59 | case LIBSTATDISK_IN: 60 | get_iface_stats_libstatdisk(_n); 61 | break; 62 | #endif 63 | #ifdef PROC_NET_DEV 64 | case PROC_IN: 65 | get_iface_stats_proc(_n); 66 | break; 67 | #endif 68 | #ifdef GETIFADDRS 69 | case GETIFADDRS_IN: 70 | get_iface_stats_getifaddrs(_n); 71 | break; 72 | #endif 73 | #if DEVSTAT_IN 74 | case DEVSTAT_IN: 75 | get_iface_stats_devstat(_n); 76 | break; 77 | #endif 78 | #ifdef SYSCTL 79 | case SYSCTL_IN: 80 | get_iface_stats_sysctl(_n); 81 | break; 82 | #endif 83 | #if SYSCTLDISK_IN 84 | case SYSCTLDISK_IN: 85 | get_iface_stats_sysctldisk(_n); 86 | break; 87 | #endif 88 | #if HAVE_LIBKSTAT 89 | case KSTATDISK_IN: 90 | case KSTAT_IN: 91 | get_iface_stats_kstat(_n); 92 | break; 93 | #endif 94 | #ifdef WIN32 95 | case WIN32_IN: 96 | get_iface_stats_win32(_n); 97 | break; 98 | #endif 99 | #ifdef PROC_DISKSTATS 100 | case DISKLINUX_IN: 101 | get_disk_stats_proc(_n); 102 | break; 103 | #endif 104 | #if IOSERVICE_IN 105 | case IOSERVICE_IN: 106 | get_disk_stats_ioservice(_n); 107 | break; 108 | #endif 109 | } 110 | } 111 | 112 | -------------------------------------------------------------------------------- /src/input/retrieve.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __RETRIEVE_H 23 | #define __RETRIEVE_H 24 | 25 | #include "../global_vars.h" 26 | #include "../defines.h" 27 | #include "../types.h" 28 | #include "../process.h" 29 | #include "../bwm-ng.h" 30 | 31 | 32 | #ifdef IOCTL 33 | /* following only for check_if_up and ioctl */ 34 | #include 35 | #include 36 | #include 37 | #ifdef HAVE_LINUX_IF_H 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | char check_if_up(char *ifname); 44 | 45 | #endif 46 | 47 | 48 | #define MAX_LINE_BUFFER 1024 49 | 50 | 51 | #include "devstat.h" 52 | #include "ioservice.h" 53 | #include "getifaddrs.h" 54 | #include "libkstat.h" 55 | #include "libstatgrab.h" 56 | #include "netstat.h" 57 | #include "proc_diskstats.h" 58 | #include "proc_net_dev.h" 59 | #include "sysctl.h" 60 | #include "win32.h" 61 | 62 | void get_iface_stats(char _n); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/input/sysctl.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "sysctl.h" 23 | 24 | #ifdef SYSCTL 25 | /* do the actual work, get and print stats if verbose */ 26 | void get_iface_stats_sysctl (char verbose) { 27 | size_t size; 28 | int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; 29 | char *bsd_if_buf=NULL, *next=NULL, *lim=NULL; 30 | char iface_is_up=0; 31 | struct if_msghdr *ifmhdr, *nextifmhdr; 32 | struct sockaddr_dl *saddr; 33 | 34 | char *name=NULL; 35 | 36 | int hidden_if=0,current_if_num=0,my_errno=0; 37 | t_iface_speed_stats tmp_if_stats; 38 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 39 | 40 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 41 | 42 | if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) 43 | deinit(1, "sysctl failed: %s\n",strerror(errno)); 44 | if (!(bsd_if_buf = malloc(size))) deinit(1, "no memory: %s\n",strerror(errno)); 45 | memset(bsd_if_buf,0,size); 46 | if (sysctl(mib, 6, bsd_if_buf, &size, NULL, 0) < 0) { 47 | my_errno=errno; 48 | free(bsd_if_buf); 49 | deinit(1, "sysctl failed: %s\n",strerror(my_errno)); 50 | } 51 | 52 | lim = (bsd_if_buf + size); 53 | 54 | next = bsd_if_buf; 55 | /* loop either while netstat enabled and still lines to read 56 | * or still buffer (buf) left */ 57 | while (next < (bsd_if_buf + size)) { 58 | /* BSD sysctl code */ 59 | ifmhdr = (struct if_msghdr *) next; 60 | if (ifmhdr->ifm_type != RTM_IFINFO) break; 61 | next += ifmhdr->ifm_msglen; 62 | while (next < lim) { 63 | nextifmhdr = (struct if_msghdr *) next; 64 | if (nextifmhdr->ifm_type != RTM_NEWADDR) break; 65 | next += nextifmhdr->ifm_msglen; 66 | } 67 | saddr = (struct sockaddr_dl *) (ifmhdr + 1); 68 | if(saddr->sdl_family != AF_LINK) continue; 69 | iface_is_up= (show_all_if || (ifmhdr->ifm_flags & IFF_UP)); 70 | /* we have to copy here to use saddr->sdl_nlen */ 71 | name=(char *)malloc(saddr->sdl_nlen+1); 72 | if (!name) { 73 | deinit(1,"mem alloc failed: %s\n",strerror(errno)); 74 | } 75 | 76 | strncpy(name,saddr->sdl_data,saddr->sdl_nlen); 77 | name[saddr->sdl_nlen]='\0'; 78 | tmp_if_stats.bytes.in=ifmhdr->ifm_data.ifi_ibytes; 79 | tmp_if_stats.bytes.out=ifmhdr->ifm_data.ifi_obytes; 80 | tmp_if_stats.packets.in=ifmhdr->ifm_data.ifi_ipackets; 81 | tmp_if_stats.packets.out=ifmhdr->ifm_data.ifi_opackets; 82 | tmp_if_stats.errors.in=ifmhdr->ifm_data.ifi_ierrors; 83 | tmp_if_stats.errors.out=ifmhdr->ifm_data.ifi_oerrors; 84 | /* init new interfaces and add fetched data to old or new one */ 85 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, iface_is_up); 86 | free(name); 87 | current_if_num++; 88 | } /* fgets done (while) */ 89 | /* add to total stats and output current stats if verbose */ 90 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 91 | /* close input stream */ 92 | free(bsd_if_buf); 93 | return; 94 | } 95 | #endif 96 | 97 | #if SYSCTLDISK_IN 98 | #ifdef HAVE_STRUCT_SYSCTL 99 | #define MIBCOUNT 3 100 | #else 101 | #define MIBCOUNT 2 102 | #endif 103 | void get_iface_stats_sysctldisk (char verbose) { 104 | size_t size; 105 | int mib[MIBCOUNT]; 106 | #if defined(HW_DISKCOUNT) && !defined(HAVE_STRUCT_DISKSTATS_DS_NAME) && defined(HAVE_STRUCT_DISKSTATS) 107 | int diskcount = 0; 108 | char *name_str = NULL; 109 | char **name_arr = NULL; 110 | char *ptr = NULL; 111 | #endif 112 | #if defined(HAVE_STRUCT_DISKSTATS) 113 | #define DISK_STRUCT struct diskstats 114 | #elif defined(HAVE_STRUCT_DISK_SYSCTL) 115 | #define DISK_STRUCT struct disk_sysctl 116 | #endif 117 | DISK_STRUCT *dstats = NULL; 118 | int num,i; 119 | char *name=NULL; 120 | char free_name=0; 121 | 122 | int hidden_if=0,current_if_num=0; 123 | t_iface_speed_stats tmp_if_stats; 124 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 125 | 126 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 127 | 128 | mib[0]=CTL_HW; 129 | 130 | /* get name list on systems without dk_name */ 131 | #if defined(HW_DISKCOUNT) && !defined(HAVE_STRUCT_DISKSTATS_DS_NAME) && defined(HAVE_STRUCT_DISKSTATS) 132 | mib[1]=HW_DISKCOUNT; 133 | if (sysctl(mib, 2, &diskcount, &size, NULL, 0) < 0) 134 | deinit(1, "sysctl failed: %s\n",strerror(errno)); 135 | 136 | mib[1]=HW_DISKNAMES; 137 | if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) 138 | deinit(1, "sysctl failed: %s\n",strerror(errno)); 139 | if (!(name_str=(char *)malloc(size))) 140 | deinit(1, "malloc failed for name_str: %s\n",strerror(errno)); 141 | if (sysctl(mib, 2, name_str, &size, NULL, 0) < 0) { 142 | free(name_str); 143 | deinit(1, "malloc failed for name_str: %s\n",strerror(errno)); 144 | } 145 | /* assume comma seperated list as on OpenBSD */ 146 | if (!(name_arr = (char **)malloc(diskcount * sizeof(char *)))) { 147 | free(name_str); 148 | deinit(1, "malloc failed for name_arr: %s\n",strerror(errno)); 149 | } 150 | ptr = name_str; 151 | i = 0; 152 | while (i 30 | #include 31 | #include 32 | #endif 33 | 34 | #include /* netbsd fix */ 35 | #include 36 | 37 | #ifdef SYSCTL 38 | #include 39 | #include 40 | 41 | void get_iface_stats_sysctl (char verbose); 42 | 43 | #endif 44 | 45 | #ifdef HAVE_SYS_DISK_H 46 | #include 47 | #endif 48 | 49 | #if SYSCTLDISK_IN 50 | void get_iface_stats_sysctldisk (char verbose); 51 | #endif 52 | 53 | 54 | #endif 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/input/win32.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrieve stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "win32.h" 23 | 24 | #ifdef WIN32 25 | void get_iface_stats_win32 (char verbose) { 26 | PMIB_IFTABLE if_table,tmp; 27 | unsigned long tableSize; 28 | int i,current_if_num,hidden_if=0,err; 29 | char name[MAX_INTERFACE_NAME_LEN]; 30 | t_iface_speed_stats tmp_if_stats; 31 | t_iface_speed_stats stats; /* local struct, used to calc total values */ 32 | 33 | memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ 34 | tableSize=sizeof(MIB_IFTABLE); 35 | if_table = malloc(sizeof(MIB_IFTABLE)); 36 | if (if_table==NULL) return; 37 | 38 | /* get table size or data if table is big enough */ 39 | if ((err=GetIfTable(if_table, &tableSize, 0)==ERROR_INSUFFICIENT_BUFFER)) { 40 | tmp = realloc(if_table, tableSize); 41 | if (tmp==NULL) { 42 | free(if_table); 43 | return; 44 | } 45 | if_table=tmp; 46 | /* get data */ 47 | err=GetIfTable(if_table, &tableSize, 0); 48 | } 49 | if (err != NO_ERROR) { 50 | free(if_table); 51 | return; 52 | } 53 | 54 | current_if_num=0; 55 | 56 | for (i=0; idwNumEntries; i++) { 57 | strncpy(name,(char*)(if_table->table[i].bDescr),MAX_INTERFACE_NAME_LEN); 58 | name[MAX_INTERFACE_NAME_LEN-1]='\0'; 59 | tmp_if_stats.bytes.in=if_table->table[i].dwInOctets; 60 | tmp_if_stats.bytes.out=if_table->table[i].dwOutOctets; 61 | tmp_if_stats.packets.in=if_table->table[i].dwInUcastPkts + if_table->table[i].dwInNUcastPkts; 62 | tmp_if_stats.packets.out=if_table->table[i].dwOutUcastPkts + if_table->table[i].dwOutNUcastPkts; 63 | tmp_if_stats.errors.in=if_table->table[i].dwInErrors; 64 | tmp_if_stats.errors.out=if_table->table[i].dwOutErrors; 65 | /* init new interfaces and add fetched data to old or new one */ 66 | hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, 1); 67 | current_if_num++; 68 | } 69 | /* add to total stats and output current stats if verbose */ 70 | finish_iface_stats (verbose, stats, hidden_if,current_if_num); 71 | 72 | free(if_table); 73 | return; 74 | } 75 | #endif 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /src/input/win32.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng parsing and retrive stuff * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __WIN32_H 23 | #define __WIN32_H 24 | 25 | #include "retrieve.h" 26 | 27 | #ifdef WIN32 28 | #include 29 | #include 30 | 31 | void get_iface_stats_win32 (char verbose); 32 | 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/options.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng handle cmdline and config file options * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #define EXTERN 23 | #include "global_vars.h" 24 | #include "options.h" 25 | 26 | #ifdef CONFIG_FILE 27 | static char* getToken(char** str, const char* delims); 28 | char *trim_whitespace(char *str); 29 | int read_config(const char *config_file); 30 | #endif 31 | static inline int str2output_unit(char *optarg); 32 | #if EXTENDED_STATS 33 | static inline int str2output_type(char *optarg); 34 | #endif 35 | static inline int str2out_method(char *optarg); 36 | static inline int str2in_method(char *optarg); 37 | 38 | #ifdef CONFIG_FILE 39 | /****************************************************************************** 40 | * This is a replacement for strsep which is not portable (missing on Solaris). 41 | */ 42 | static char* getToken(char** str, const char* delims) { 43 | char* token; 44 | 45 | if (*str==NULL) { 46 | /* No more tokens */ 47 | return NULL; 48 | } 49 | 50 | token=*str; 51 | while (**str!='\0') { 52 | if (strchr(delims,**str)!=NULL) { 53 | **str='\0'; 54 | (*str)++; 55 | return token; 56 | } 57 | (*str)++; 58 | } 59 | /* There is no other token */ 60 | *str=NULL; 61 | return token; 62 | } 63 | /******************************************************************************/ 64 | #endif 65 | 66 | static inline int str2output_unit(char *optarg) { 67 | if (optarg) { 68 | if (!strcasecmp(optarg,"bytes")) return BYTES_OUT; 69 | if (!strcasecmp(optarg,"bits")) return BITS_OUT; 70 | if (!strcasecmp(optarg,"packets")) return PACKETS_OUT; 71 | if (!strcasecmp(optarg,"errors")) return ERRORS_OUT; 72 | } 73 | return BYTES_OUT; 74 | } 75 | 76 | #if EXTENDED_STATS 77 | static inline int str2output_type(char *optarg) { 78 | if (optarg) { 79 | if (!strcasecmp(optarg,"rate")) return RATE_OUT; 80 | if (!strcasecmp(optarg,"max")) return MAX_OUT; 81 | if (!strcasecmp(optarg,"sum")) return SUM_OUT; 82 | if (!strcasecmp(optarg,"avg")) return AVG_OUT; 83 | } 84 | return RATE_OUT; 85 | } 86 | #endif 87 | 88 | static inline int str2out_method(char *optarg) { 89 | if (optarg) { 90 | if (!strcasecmp(optarg,"plain")) return PLAIN_OUT; 91 | #ifdef HAVE_CURSES 92 | else 93 | if (!strcasecmp(optarg,"curses")) return CURSES_OUT; 94 | else 95 | if (!strcasecmp(optarg,"curses2")) return CURSES2_OUT; 96 | #endif 97 | #ifdef CSV 98 | else 99 | if (!strcasecmp(optarg,"csv")) return CSV_OUT; 100 | #endif 101 | #ifdef HTML 102 | else 103 | if (!strcasecmp(optarg,"html")) return HTML_OUT; 104 | #endif 105 | } 106 | return -1; 107 | } 108 | 109 | 110 | static inline int str2in_method(char *optarg) { 111 | if (optarg) { 112 | #ifdef PROC_NET_DEV 113 | if (!strcasecmp(optarg,"proc")) return PROC_IN; 114 | #endif 115 | #ifdef NETSTAT 116 | if (!strcasecmp(optarg,"netstat")) return NETSTAT_IN; 117 | #endif 118 | #ifdef LIBSTATGRAB 119 | if (!strcasecmp(optarg,"libstat") || !strcasecmp(optarg,"statgrab") || !strcasecmp(optarg,"libstatgrab")) return LIBSTAT_IN; 120 | if (!strcasecmp(optarg,"libstatdisk")) return LIBSTATDISK_IN; 121 | #endif 122 | #ifdef GETIFADDRS 123 | if (!strcasecmp(optarg,"getifaddrs")) return GETIFADDRS_IN; 124 | #endif 125 | #if DEVSTAT_IN 126 | if (!strcasecmp(optarg,"devstat")) return DEVSTAT_IN; 127 | #endif 128 | #ifdef SYSCTL 129 | if (!strcasecmp(optarg,"sysctl")) return SYSCTL_IN; 130 | #endif 131 | #if SYSCTLDISK_IN 132 | if (!strcasecmp(optarg,"sysctldisk")) return SYSCTLDISK_IN; 133 | #endif 134 | #ifdef PROC_DISKSTATS 135 | if (!strcasecmp(optarg,"disk")) return DISKLINUX_IN; 136 | #endif 137 | #ifdef WIN32 138 | if (!strcasecmp(optarg,"win32")) return WIN32_IN; 139 | #endif 140 | #ifdef HAVE_LIBKSTAT 141 | if (!strcasecmp(optarg,"kstat")) return KSTAT_IN; 142 | if (!strcasecmp(optarg,"kstatdisk")) return KSTATDISK_IN; 143 | #endif 144 | #if IOSERVICE_IN 145 | if (!strcasecmp(optarg,"ioservice")) return IOSERVICE_IN; 146 | #endif 147 | } 148 | return -1; 149 | } 150 | 151 | 152 | #ifdef CONFIG_FILE 153 | char *trim_whitespace(char *str) { 154 | char *dud = str; 155 | int i; 156 | 157 | /* beginning whitespace first */ 158 | while( (int)*dud && isspace((int)*dud) ) 159 | ++dud; 160 | /* now trailing whitespace */ 161 | i = strlen(dud) - 1; 162 | while( i>=0 && isspace((int)dud[i]) ) 163 | --i; 164 | dud[i+1] = 0; 165 | return dud; 166 | } 167 | 168 | 169 | int read_config(const char *config_file) { 170 | FILE *fp; 171 | char *buffer; 172 | char *token, *value; 173 | 174 | if (config_file==NULL) return -1; 175 | 176 | if( (fp = fopen( config_file, "r" ) ) == NULL ) { 177 | return -1; 178 | } 179 | 180 | buffer = (char*)malloc( sizeof(char) * 4096 ); 181 | 182 | while( fgets( buffer, 4096, fp ) ) { 183 | value = trim_whitespace( buffer ); 184 | token = getToken( &value, "=" ); 185 | if( token == NULL ) /* ignore this line if there isn't a token/value pair */ 186 | continue; 187 | token = trim_whitespace( token ); 188 | 189 | if( strcasecmp( token, "TIMEOUT" ) == 0 ) { 190 | if (value && atol(value)>0) { delay=atol(value); } 191 | #ifdef PROC_NET_DEV 192 | } else if( strcasecmp( token, "PROCFILE" ) == 0 ) { 193 | if (value && (strlen(value)0) { html_refresh=atol(value); } 256 | } else if( strcasecmp( token, "HTMLHEADER" ) == 0 ) { 257 | if (value) html_header=value[0]=='0' ? 0 : 1; 258 | #endif 259 | } 260 | } 261 | free(buffer); 262 | fclose(fp); 263 | 264 | return 0; 265 | } 266 | #endif 267 | 268 | 269 | 270 | void get_cmdln_options(int argc, char *argv[]) { 271 | int o; 272 | #if CONFIG_FILE && HAVE_GETPWUID 273 | static struct passwd *pwd_entry; 274 | char *str; 275 | #endif 276 | #ifdef LONG_OPTIONS 277 | int option_index = 0; 278 | static struct option long_options[] = { 279 | {"timeout", 1, 0, 't'}, 280 | #ifdef PROC_NET_DEV 281 | {"procfile",1,0,'f'}, 282 | #endif 283 | #ifdef PROC_DISKSTATS 284 | {"diskstatsfile",1,0,1000}, 285 | {"partitionsfile",1,0,1001}, 286 | #endif 287 | #if NETSTAT && ALLOW_NETSTATPATH 288 | {"netstat",1,0,'n'}, 289 | #endif 290 | #if IOSERVICE_IN 291 | {"longdisknames",0,0,1002}, 292 | #endif 293 | {"input",1,0,'i'}, 294 | {"dynamic",1,0,'d'}, 295 | {"help", 0, 0, 'h'}, 296 | {"version",0,0,'V'}, 297 | {"allif",1,0,'a'}, 298 | {"unit",1,0,'u'}, 299 | {"ansiout",0,0,'N'}, 300 | #if EXTENDED_STATS 301 | {"type",1,0,'T'}, 302 | {"avglength",1,0,'A'}, 303 | #endif 304 | {"interfaces",1,0,'I'}, 305 | {"sumhidden",1,0,'S'}, 306 | {"output",1,0,'o'}, 307 | #ifdef CSV 308 | {"csvchar",1,0,'C'}, 309 | {"csvfile",1,0,'F'}, 310 | #endif 311 | {"count",1,0,'c'}, 312 | #ifdef HAVE_FORK 313 | {"daemon",1,0,'D'}, 314 | #endif 315 | #ifdef HTML 316 | {"htmlrefresh",1,0,'R'}, 317 | {"htmlheader",1,0,'H'}, 318 | #endif 319 | {0,0,0,0} 320 | }; 321 | #endif 322 | #ifdef CONFIG_FILE 323 | /* loop till first non option argument */ 324 | opterr=0; 325 | while (1) { 326 | #ifdef LONG_OPTIONS 327 | o=getopt_long (argc,argv,SHORT_OPTIONS,long_options, &option_index); 328 | #else 329 | o=getopt (argc,argv,SHORT_OPTIONS); 330 | #endif 331 | if (o==-1) break; 332 | } 333 | opterr=1; 334 | if (optind < argc) { 335 | read_config(argv[optind]); 336 | } else { 337 | read_config("/etc/bwm-ng.conf"); 338 | #ifdef HAVE_GETPWUID 339 | pwd_entry=getpwuid(getuid()); 340 | if (pwd_entry!=NULL) { 341 | str=(char*)malloc(strlen(pwd_entry->pw_dir)+14); 342 | if(!str) { 343 | printf("Fatal: failed to allocate %zu bytes reading user directory for config file.\n", strlen(pwd_entry->pw_dir)+14); 344 | exit(EXIT_FAILURE); 345 | } 346 | snprintf(str,strlen(pwd_entry->pw_dir)+14,"%s/.bwm-ng.conf",pwd_entry->pw_dir); 347 | read_config(str); 348 | free(str); 349 | } 350 | #endif 351 | } 352 | /* reset getopt again */ 353 | optind=1; 354 | #endif 355 | /* get command line arguments, kinda ugly, wanna rewrite it? */ 356 | while (1) { 357 | #ifdef LONG_OPTIONS 358 | o=getopt_long (argc,argv,SHORT_OPTIONS,long_options, &option_index); 359 | #else 360 | o=getopt (argc,argv,SHORT_OPTIONS); 361 | #endif 362 | if (o==-1) break; 363 | switch (o) { 364 | case '?': printf("unknown option: %s\n",argv[optind-1]); 365 | exit(EXIT_FAILURE); 366 | break; 367 | /* ugly workaround to handle optional arguments for all platforms */ 368 | case ':': if (!strcmp(argv[optind-1],"-a") || !strcasecmp(argv[optind-1],"--allif")) 369 | show_all_if=1; 370 | else if (!strcmp(argv[optind-1],"-d") || !strcasecmp(argv[optind-1],"--dynamic")) 371 | dynamic=1; 372 | #ifdef HAVE_FORK 373 | else if (!strcmp(argv[optind-1],"-D") || !strcasecmp(argv[optind-1],"--daemon")) 374 | daemonize=1; 375 | #endif 376 | #ifdef HTML 377 | else if (!strcmp(argv[optind-1],"-H") || !strcasecmp(argv[optind-1],"--htmlheader")) 378 | html_header=1; 379 | #endif 380 | else if (!strcmp(argv[optind-1],"-S") || !strcasecmp(argv[optind-1],"--sumhidden")) 381 | sumhidden=1; 382 | else { 383 | printf("%s requires an argument!\n",argv[optind-1]); 384 | exit(EXIT_FAILURE); 385 | } 386 | break; 387 | #ifdef PROC_DISKSTATS 388 | case 1000: 389 | if (strlen(optarg)0) { html_refresh=atol(optarg); } 410 | break; 411 | case 'H': 412 | if (optarg) html_header=atoi(optarg); 413 | break; 414 | #endif 415 | case 'c': 416 | if (optarg) output_count=atol(optarg); 417 | break; 418 | #if CSV || HTML 419 | case 'F': 420 | if (optarg) { 421 | if (out_file) fclose(out_file); 422 | out_file=fopen(optarg,"a"); 423 | if (!out_file) deinit(1, "failed to open outfile\n"); 424 | if (out_file_path) free(out_file_path); 425 | out_file_path=(char *)strdup(optarg); 426 | } 427 | break; 428 | #endif 429 | #ifdef CSV 430 | case 'C': 431 | if (optarg) csv_char=optarg[0]; 432 | break; 433 | #endif 434 | case 'h': 435 | cmdln_printhelp(); 436 | break; 437 | #ifdef PROC_NET_DEV 438 | case 'f': 439 | if (optarg && (strlen(optarg)0) { delay=atol(optarg); } 465 | break; 466 | #if EXTENDED_STATS 467 | case 'T': 468 | output_type=str2output_type(optarg); 469 | break; 470 | case 'A': 471 | if (optarg) avg_length=atoi(optarg)*1000; 472 | break; 473 | #endif 474 | case 'd': 475 | if (optarg) dynamic=atoi(optarg); 476 | break; 477 | case 'u': 478 | output_unit=str2output_unit(optarg); 479 | break; 480 | #if NETSTAT && ALLOW_NETSTATPATH 481 | case 'n': 482 | if (optarg && (strlen(optarg)=avg_length) deinit(1, "avglength needs to be a least twice the value of timeout\n"); 501 | #endif 502 | if ((output_unit==ERRORS_OUT && !net_input_method(input_method)) || 503 | (output_unit==PACKETS_OUT && input_method==LIBSTATDISK_IN)) 504 | output_unit=BYTES_OUT; 505 | return; 506 | } 507 | -------------------------------------------------------------------------------- /src/options.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng options header * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | 23 | #ifndef __OPTIONS_H 24 | #define __OPTIONS_H 25 | 26 | #include "defines.h" 27 | #include "types.h" 28 | 29 | #ifdef CONFIG_FILE 30 | #include 31 | #include 32 | #ifdef HAVE_GETPWUID 33 | #include 34 | #include 35 | #include 36 | #endif 37 | #endif 38 | 39 | #include "help.h" 40 | #include "bwm-ng.h" 41 | 42 | void get_cmdln_options(int argc, char *argv[]); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/output.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng output * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #ifndef __OUTPUT_H 23 | #define __OUTPUT_H 24 | 25 | #include "defines.h" 26 | #include "types.h" 27 | 28 | /* for csv output and time() */ 29 | #include 30 | 31 | #include "options.h" 32 | 33 | int print_header(int option); 34 | void print_values(unsigned int y,unsigned int x,const char *if_name,t_iface_speed_stats stats,float multiplier,t_iface_stats full_stats); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/process.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * bwm-ng process data * 3 | * * 4 | * for more info read README. * 5 | * * 6 | * This program is free software; you can redistribute it and/or modify * 7 | * it under the terms of the GNU General Public License as published by * 8 | * the Free Software Foundation; either version 2 of the License, or * 9 | * (at your option) any later version. * 10 | * * 11 | * This program is distributed in the hope that it will be useful, * 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 | * GNU General Public License for more details. * 15 | * * 16 | * You should have received a copy of the GNU General Public License * 17 | * along with this program; if not, write to the Free Software * 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * 19 | * * 20 | *****************************************************************************/ 21 | 22 | #include "global_vars.h" 23 | #include "process.h" 24 | 25 | short show_iface(char *instr, char *searchstr,char iface_is_up); 26 | #if HAVE_GETTIMEOFDAY 27 | static inline long tvdiff(struct timeval newer, struct timeval older); 28 | float get_time_delay(int iface_num); 29 | #endif 30 | static inline ullong calc_new_values(ullong new, ullong old); 31 | t_iface_speed_stats convert2calced_values(t_iface_speed_stats new, t_iface_speed_stats old); 32 | t_iface_speed_stats convert2calced_disk_values(t_iface_speed_stats new, t_iface_speed_stats old); 33 | #if EXTENDED_STATS 34 | static inline void sub_avg_values(struct inouttotal_double *values,struct inouttotal_double data); 35 | static inline void add_avg_values(struct inouttotal_double *values,struct inouttotal_double data); 36 | static inline void save_avg_values(struct inouttotal_double *values,struct inouttotal_double *data,struct inout_long calced_stats,float multiplier); 37 | void save_avg(struct t_avg *avg,struct iface_speed_stats calced_stats,float multiplier); 38 | static inline void save_sum(struct inout_long *stats,struct inout_long new_stats_values); 39 | static inline void save_max(struct inouttotal_double *stats,struct inout_long calced_stats,float multiplier); 40 | #endif 41 | 42 | /* returns the whether to show the iface or not 43 | * if is in list return 1, if list is prefaced with ! or 44 | * name not found return 0 */ 45 | short show_iface(char *instr, char *searchstr,char iface_is_up) { 46 | int pos = 0,k,success_ret = 1; 47 | unsigned int i = 0; 48 | if (instr==NULL) return iface_is_up || (show_all_if==2); 49 | if (instr[0]=='%') { 50 | success_ret=!success_ret; 51 | i++; 52 | } 53 | k = strlen( searchstr ); 54 | for (;i<=strlen(instr);i++) { 55 | switch ( instr[i] ) { 56 | case 0: 57 | case ',': 58 | if ( k == pos && ! strncasecmp( &instr[i] - pos, searchstr, pos ) ) { 59 | return success_ret || (iface_is_up && show_all_if); 60 | } 61 | pos = 0; 62 | break; 63 | default: 64 | pos++; 65 | break; 66 | } 67 | } 68 | return !success_ret || (iface_is_up && show_all_if) || (show_all_if==2); 69 | } 70 | 71 | 72 | 73 | #if HAVE_GETTIMEOFDAY 74 | /* Returns: the time difference in milliseconds. */ 75 | static inline long tvdiff(struct timeval newer, struct timeval older) { 76 | return labs((newer.tv_sec-older.tv_sec)*1000+ 77 | (newer.tv_usec-older.tv_usec)/1000); 78 | } 79 | 80 | /* returns the milliseconds since old stat */ 81 | float get_time_delay(int iface_num) { 82 | struct timeval now; 83 | float ret = 0.0f; 84 | gettimeofday(&now,NULL); 85 | long diff = tvdiff(now,if_stats[iface_num].time); 86 | if (diff > 0) { 87 | ret=(float)1000/diff; 88 | } 89 | if_stats[iface_num].time.tv_sec=now.tv_sec; 90 | if_stats[iface_num].time.tv_usec=now.tv_usec; 91 | return ret; 92 | } 93 | #endif 94 | 95 | /* basically new-old, but handles "overflow" of source aswell */ 96 | static inline ullong calc_new_values(ullong new, ullong old) { 97 | /* FIXME: WRAP_AROUND _might_ be wrong for libstatgrab, where the type is always long long */ 98 | return (new>=old) ? (ullong)(new-old) : (ullong)(( 99 | #ifdef HAVE_LIBKSTAT 100 | (input_method==KSTAT_IN) ? 101 | WRAP_32BIT : 102 | #endif 103 | WRAP_AROUND) 104 | -old)+new; 105 | } 106 | 107 | 108 | /* calc actual new-old values */ 109 | t_iface_speed_stats convert2calced_values(t_iface_speed_stats new, t_iface_speed_stats old) { 110 | t_iface_speed_stats calced_stats; 111 | calced_stats.errors.in=calc_new_values(new.errors.in,old.errors.in); 112 | calced_stats.errors.out=calc_new_values(new.errors.out,old.errors.out); 113 | calced_stats.packets.out=calc_new_values(new.packets.out,old.packets.out); 114 | calced_stats.packets.in=calc_new_values(new.packets.in,old.packets.in); 115 | calced_stats.bytes.out=calc_new_values(new.bytes.out,old.bytes.out); 116 | calced_stats.bytes.in=calc_new_values(new.bytes.in,old.bytes.in); 117 | return calced_stats; 118 | } 119 | 120 | /* calc actual new-old values */ 121 | t_iface_speed_stats convert2calced_disk_values(t_iface_speed_stats new, t_iface_speed_stats old) { 122 | t_iface_speed_stats calced_stats; 123 | calced_stats.bytes.out=calc_new_values(new.bytes.out,old.bytes.out); 124 | calced_stats.bytes.in=calc_new_values(new.bytes.in,old.bytes.in); 125 | /* needed for linux stats, read and write count */ 126 | calced_stats.packets.out=calc_new_values(new.packets.out,old.packets.out)*(calc_new_values(new.errors.out,old.errors.out)+1); 127 | calced_stats.packets.in=calc_new_values(new.packets.in,old.packets.in)*(calc_new_values(new.errors.in,old.errors.in)+1); 128 | calced_stats.errors.in=0; 129 | calced_stats.errors.out=0; 130 | return calced_stats; 131 | } 132 | 133 | 134 | 135 | #if EXTENDED_STATS 136 | /* sub old values from cached for avg stats */ 137 | static inline void sub_avg_values(struct inouttotal_double *values,struct inouttotal_double data) { 138 | values->in-=data.in; 139 | values->out-=data.out; 140 | values->total-=data.total; 141 | } 142 | 143 | static inline void add_avg_values(struct inouttotal_double *values,struct inouttotal_double data) { 144 | values->in+=data.in; 145 | values->out+=data.out; 146 | values->total+=data.total; 147 | } 148 | 149 | 150 | /* put new-old bytes in inout_long struct into a inouttotal_double struct 151 | * and add values to cached .value struct */ 152 | static inline void save_avg_values(struct inouttotal_double *values,struct inouttotal_double *data,struct inout_long calced_stats,float multiplier) { 153 | data->in=calced_stats.in*multiplier; 154 | data->out=calced_stats.out*multiplier; 155 | data->total=(calced_stats.in+calced_stats.out)*multiplier; 156 | add_avg_values(values,*data); 157 | } 158 | 159 | 160 | /* manages the list of values for avg 161 | * saves data in list 162 | * removes old entries 163 | * calculates the current value */ 164 | void save_avg(struct t_avg *avg,struct iface_speed_stats calced_stats,float multiplier) { 165 | struct double_list *list_p; 166 | if (avg->first==NULL) { /* first element */ 167 | avg->first=avg->last=(struct double_list *)malloc(sizeof(struct double_list)); 168 | /* init it to zero and NULL */ 169 | memset(avg->first,0,sizeof(struct double_list)); 170 | /* save data and add to cache */ 171 | save_avg_values(&avg->item_sum.bytes,&avg->first->data.bytes,calced_stats.bytes,multiplier); 172 | save_avg_values(&avg->item_sum.errors,&avg->first->data.errors,calced_stats.errors,multiplier); 173 | save_avg_values(&avg->item_sum.packets,&avg->first->data.packets,calced_stats.packets,multiplier); 174 | avg->items=1; 175 | } else { /* we already have a list */ 176 | avg->last->next=(struct double_list *)malloc(sizeof(struct double_list)); 177 | memset(avg->last->next,0,sizeof(struct double_list)); 178 | avg->last=avg->last->next; 179 | /* save data and add to cache */ 180 | save_avg_values(&avg->item_sum.bytes,&avg->last->data.bytes,calced_stats.bytes,multiplier); 181 | save_avg_values(&avg->item_sum.errors,&avg->last->data.errors,calced_stats.errors,multiplier); 182 | save_avg_values(&avg->item_sum.packets,&avg->last->data.packets,calced_stats.packets,multiplier); 183 | avg->items++; 184 | /* remove only entries if at least two items added, 185 | * else we might leave an empty list 186 | * avg->first has to be != NULL at this point (if in 2nd line of this function) */ 187 | while (avg->first->next!=NULL && avg->items > avg_length/delay) { 188 | /* list is full, remove first entry */ 189 | list_p=avg->first; 190 | avg->first=avg->first->next; 191 | /* sub values from cache */ 192 | sub_avg_values(&avg->item_sum.bytes,list_p->data.bytes); 193 | sub_avg_values(&avg->item_sum.errors,list_p->data.errors); 194 | sub_avg_values(&avg->item_sum.packets,list_p->data.packets); 195 | free(list_p); 196 | avg->items--; 197 | } 198 | } 199 | } 200 | 201 | /* add current in and out bytes to totals struct */ 202 | static inline void save_sum(struct inout_long *stats,struct inout_long new_stats_values) { 203 | stats->in+=new_stats_values.in; 204 | stats->out+=new_stats_values.out; 205 | } 206 | 207 | /* lookup old max values and save new if higher */ 208 | static inline void save_max(struct inouttotal_double *stats,struct inout_long calced_stats,float multiplier) { 209 | if (multiplier*calced_stats.in > stats->in) 210 | stats->in=multiplier*calced_stats.in; 211 | if (multiplier*calced_stats.out>stats->out) 212 | stats->out=multiplier*calced_stats.out; 213 | if (multiplier*(calced_stats.out+calced_stats.in)>stats->total) 214 | stats->total=multiplier*(calced_stats.in+calced_stats.out); 215 | } 216 | #endif 217 | 218 | void clean_down_ifaces(void) { 219 | #ifdef IOCTL 220 | int local_if_count; 221 | t_iface_stats *new_if_stats = NULL; 222 | int new_if_count = 0; 223 | for (local_if_count=0;local_if_count