|
| 1 | +;;; Ifconfig.el --- EPOXIDE Ifconfig node definition file |
| 2 | + |
| 3 | +;; Copyright (C) 2015 István Pelle |
| 4 | + |
| 5 | +;; This program is free software; you can redistribute it and/or modify |
| 6 | +;; it under the terms of the GNU General Public License as published |
| 7 | +;; by the Free Software Foundation, either version 3 of the License, |
| 8 | +;; or (at your option) any later version. |
| 9 | + |
| 10 | +;; This program is distributed in the hope that it will be useful, but |
| 11 | +;; WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | +;; General Public License for more details. |
| 14 | + |
| 15 | +;; You should have received a copy of the GNU General Public License |
| 16 | +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 17 | + |
| 18 | +;;; Commentary: |
| 19 | + |
| 20 | +;; Node wraps the ifconfig shell command. It has an enable input: when |
| 21 | +;; there is any data on it, a new ifconfig call is executed. The node |
| 22 | +;; has indefinit number of configuration arguments. The first |
| 23 | +;; specifies the host where the call should be executed, when the |
| 24 | +;; second is non-nil the results are checked and the rest of the |
| 25 | +;; arguments denote the interfaces that should be left out of the |
| 26 | +;; check. The node has two outputs: the first holds the results of the |
| 27 | +;; ifconfig call while the second displays those interfaces that do |
| 28 | +;; not satisfy the check conditions. |
| 29 | +;; When checking the interfaces IP addresses and packet counts are |
| 30 | +;; checked. |
| 31 | + |
| 32 | +;;; Code: |
| 33 | + |
| 34 | +(require 'epoxide) |
| 35 | + |
| 36 | +(eval-when-compile |
| 37 | + (defvar epoxide-node-name) |
| 38 | + (defvar epoxide-node-class) |
| 39 | + (defvar epoxide-input-marker) |
| 40 | + (defvar epoxide-node-config-list) |
| 41 | + (defvar epoxide-node-inputs) |
| 42 | + (defvar epoxide-node-outputs)) |
| 43 | + |
| 44 | +(defun epoxide-ifconfig-input-info () |
| 45 | + "Provide documentation, value tips and validation for input fields." |
| 46 | + '(((doc-string . "enable signal")))) |
| 47 | + |
| 48 | +(defun epoxide-ifconfig-config-info () |
| 49 | + "Provide documentation, value tips and validation for config fields." |
| 50 | + '(((doc-string . "host")) |
| 51 | + ((doc-string . "check")) |
| 52 | + ((doc-string . "interfaces to exclude")))) |
| 53 | + |
| 54 | +(defun epoxide-ifconfig-output-info () |
| 55 | + "Provide documentation, value tips and validation for output fields." |
| 56 | + '(((doc-string . "result")) |
| 57 | + ((doc-string . "negative output")))) |
| 58 | + |
| 59 | +(defun epoxide-ifconfig-init () |
| 60 | + "Initialize input markers." |
| 61 | + (set (make-local-variable 'epoxide-input-marker) 1)) |
| 62 | + |
| 63 | +(defun epoxide-ifconfig-exec () |
| 64 | + "Run an ifconfig call." |
| 65 | + (let ((marker epoxide-input-marker) |
| 66 | + (enable-input (nth 0 epoxide-node-inputs)) |
| 67 | + (host (nth 0 epoxide-node-config-list)) |
| 68 | + (check (nth 1 epoxide-node-config-list)) |
| 69 | + (excludes (cddr epoxide-node-config-list)) |
| 70 | + (output (nth 0 epoxide-node-outputs)) |
| 71 | + (negative-output (nth 1 epoxide-node-outputs)) |
| 72 | + result enabled) |
| 73 | + (when enable-input |
| 74 | + (with-current-buffer enable-input |
| 75 | + (setq marker (point-max))) |
| 76 | + (when (> marker epoxide-input-marker) |
| 77 | + (setq enabled t)) |
| 78 | + (setq-local epoxide-input-marker marker)) |
| 79 | + (when enabled |
| 80 | + (setq result (epoxide-shell-command-to-string host "ifconfig")) |
| 81 | + (when (equal check nil) |
| 82 | + (setq check nil)) |
| 83 | + (when check |
| 84 | + (let ((check-result |
| 85 | + (mapconcat 'identity |
| 86 | + (epoxide-ifconfig-check-interfaces excludes result) |
| 87 | + "\n\n"))) |
| 88 | + (if (> (length check-result) 0) |
| 89 | + (setq result (concat check-result "\n\n")) |
| 90 | + (epoxide-write-node-output result negative-output)) |
| 91 | + (setq result check-result))) |
| 92 | + (epoxide-write-node-output result output)))) |
| 93 | + |
| 94 | +(defun epoxide-ifconfig-check-interfaces (interfaces-to-exclude text) |
| 95 | + "Check interfaces whether they have a valid configuration. |
| 96 | +Go through each interfaces excluding INTERFACES-TO-EXCLUDE and |
| 97 | +check each of them. TEXT holds the data descibing each |
| 98 | +interfaces." |
| 99 | + (when (stringp interfaces-to-exclude) |
| 100 | + (setq interfaces-to-exclude |
| 101 | + (split-string interfaces-to-exclude "[ \f\t\n\r\v]+" |
| 102 | + t "[ \f\t\n\r\v]+"))) |
| 103 | + (let ((interfaces (split-string text "\n\n")) |
| 104 | + ret) |
| 105 | + (dolist (i interfaces) |
| 106 | + (unless (member (car (split-string i " ")) interfaces-to-exclude) |
| 107 | + (when (epoxide-ifconfig--check-interface i) |
| 108 | + (setq ret (cons i ret))))) |
| 109 | + (nreverse (delq nil ret)))) |
| 110 | + |
| 111 | +(defun epoxide-ifconfig--check-interface (interface) |
| 112 | + "Check a single interface configuration contained in INTERFACE." |
| 113 | + (when (and (epoxide-ifconfig--check-ip-address interface) |
| 114 | + (epoxide-ifconfig--check-rx interface) |
| 115 | + (epoxide-ifconfig--check-rx interface)) |
| 116 | + t)) |
| 117 | + |
| 118 | +(defun epoxide-ifconfig--check-ip-address (interface) |
| 119 | + "Check whether INTERFACE has an IP address (either IPv4 or IPv6)." |
| 120 | + (when (or (string-match "inet addr:" interface) |
| 121 | + (string-match "inet6 addr:" interface)) |
| 122 | + t)) |
| 123 | + |
| 124 | +(defun epoxide-ifconfig--check-packets (interface type) |
| 125 | + "Check whether INTERFACE successfully relayed RX or TX traffic. |
| 126 | +TYPE specifies which direction should be checked. It has to be |
| 127 | +either rx or tx. Return t when the number of packets is greater |
| 128 | +than the number of errors, dropped or overruns." |
| 129 | + (let* ((exp (concat type " packets:")) |
| 130 | + (x-beg (string-match exp interface)) |
| 131 | + (x (if x-beg |
| 132 | + (car (split-string (substring interface |
| 133 | + (+ (length exp) x-beg)) "\n")) |
| 134 | + nil)) |
| 135 | + (parameters '("errors:" "dropped:" "overruns:")) |
| 136 | + (ret t) |
| 137 | + packets failures) |
| 138 | + (when x |
| 139 | + (setq packets (car (split-string x " "))) |
| 140 | + (setq x (cadr (split-string x (concat packets " ")))) |
| 141 | + (setq packets (string-to-number packets)) |
| 142 | + (dolist (p parameters) |
| 143 | + (let ((failure (cadr (split-string x p)))) |
| 144 | + (unless (equal failure x) |
| 145 | + (setq failure (car (split-string failure " "))) |
| 146 | + (setq x (cadr (split-string x (concat p failure " ")))) |
| 147 | + (when (< 0 (length failure)) |
| 148 | + (setq failures (cons failure failures)))))) |
| 149 | + (dolist (f failures) |
| 150 | + (when (<= packets (string-to-number f)) |
| 151 | + (setq ret nil)))) |
| 152 | + ret)) |
| 153 | + |
| 154 | +(defun epoxide-ifconfig--check-rx (interface) |
| 155 | + "Check RX traffic of INTERFACE." |
| 156 | + (epoxide-ifconfig--check-packets interface "rx")) |
| 157 | + |
| 158 | +(defun epoxide-ifconfig--check-tx (interface) |
| 159 | + "Check TX traffic of INTERFACE." |
| 160 | + (epoxide-ifconfig--check-packets interface "tx")) |
| 161 | + |
| 162 | +(defun epoxide-ifconfig-stop () |
| 163 | + "Dummy function." |
| 164 | + nil) |
| 165 | + |
| 166 | +(provide 'ifconfig) |
| 167 | + |
| 168 | +;;; Ifconfig.el ends here |
0 commit comments