diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-02-07 11:45:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-02-07 11:45:55 +0000 |
commit | a8220ab2d293bb7f4b014b79d16b2fb05090fa93 (patch) | |
tree | 77f0a30f016c0925cf7ee9292e644bba183c2774 /collectors/node.d.plugin | |
parent | Adding upstream version 1.19.0. (diff) | |
download | netdata-a8220ab2d293bb7f4b014b79d16b2fb05090fa93.tar.xz netdata-a8220ab2d293bb7f4b014b79d16b2fb05090fa93.zip |
Adding upstream version 1.29.0.upstream/1.29.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collectors/node.d.plugin')
-rw-r--r-- | collectors/node.d.plugin/.keep | 0 | ||||
-rw-r--r-- | collectors/node.d.plugin/Makefile.am | 1 | ||||
-rw-r--r-- | collectors/node.d.plugin/Makefile.in | 865 | ||||
-rw-r--r-- | collectors/node.d.plugin/README.md | 12 | ||||
-rw-r--r-- | collectors/node.d.plugin/fronius/README.md | 10 | ||||
-rw-r--r-- | collectors/node.d.plugin/named/README.md | 10 | ||||
-rw-r--r-- | collectors/node.d.plugin/node.d.plugin | 303 | ||||
-rw-r--r-- | collectors/node.d.plugin/node_modules/net-snmp.js | 4411 | ||||
-rw-r--r-- | collectors/node.d.plugin/sma_webbox/README.md | 8 | ||||
-rw-r--r-- | collectors/node.d.plugin/snmp/README.md | 353 | ||||
-rw-r--r-- | collectors/node.d.plugin/snmp/snmp.node.js | 199 | ||||
-rw-r--r-- | collectors/node.d.plugin/stiebeleltron/README.md | 14 |
12 files changed, 3556 insertions, 2630 deletions
diff --git a/collectors/node.d.plugin/.keep b/collectors/node.d.plugin/.keep deleted file mode 100644 index e69de29bb..000000000 --- a/collectors/node.d.plugin/.keep +++ /dev/null diff --git a/collectors/node.d.plugin/Makefile.am b/collectors/node.d.plugin/Makefile.am index 411bce9ec..c3142d433 100644 --- a/collectors/node.d.plugin/Makefile.am +++ b/collectors/node.d.plugin/Makefile.am @@ -23,7 +23,6 @@ dist_noinst_DATA = \ usernodeconfigdir=$(configdir)/node.d dist_usernodeconfig_DATA = \ - .keep \ $(NULL) # Explicitly install directories to avoid permission issues due to umask diff --git a/collectors/node.d.plugin/Makefile.in b/collectors/node.d.plugin/Makefile.in deleted file mode 100644 index b057e1eb4..000000000 --- a/collectors/node.d.plugin/Makefile.in +++ /dev/null @@ -1,865 +0,0 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2017 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# SPDX-License-Identifier: GPL-3.0-or-later - -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - -# SPDX-License-Identifier: GPL-3.0-or-later - -# THIS IS NOT A COMPLETE Makefile -# IT IS INCLUDED BY ITS PARENT'S Makefile.am -# IT IS REQUIRED TO REFERENCE ALL FILES RELATIVE TO THE PARENT - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = collectors/node.d.plugin -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/build/m4/ax_c___atomic.m4 \ - $(top_srcdir)/build/m4/ax_c__generic.m4 \ - $(top_srcdir)/build/m4/ax_c_lto.m4 \ - $(top_srcdir)/build/m4/ax_c_mallinfo.m4 \ - $(top_srcdir)/build/m4/ax_c_mallopt.m4 \ - $(top_srcdir)/build/m4/ax_check_compile_flag.m4 \ - $(top_srcdir)/build/m4/ax_gcc_func_attribute.m4 \ - $(top_srcdir)/build/m4/ax_pthread.m4 \ - $(top_srcdir)/build/m4/jemalloc.m4 \ - $(top_srcdir)/build/m4/tcmalloc.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(dist_plugins_SCRIPTS) \ - $(dist_libconfig_DATA) $(dist_node_DATA) \ - $(dist_nodeconfig_DATA) $(dist_nodemodules_DATA) \ - $(dist_nodemoduleslibber_DATA) $(dist_noinst_DATA) \ - $(dist_usernodeconfig_DATA) $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(pluginsdir)" \ - "$(DESTDIR)$(libconfigdir)" "$(DESTDIR)$(nodedir)" \ - "$(DESTDIR)$(nodeconfigdir)" "$(DESTDIR)$(nodemodulesdir)" \ - "$(DESTDIR)$(nodemoduleslibberdir)" \ - "$(DESTDIR)$(usernodeconfigdir)" -SCRIPTS = $(dist_plugins_SCRIPTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -DATA = $(dist_libconfig_DATA) $(dist_node_DATA) \ - $(dist_nodeconfig_DATA) $(dist_nodemodules_DATA) \ - $(dist_nodemoduleslibber_DATA) $(dist_noinst_DATA) \ - $(dist_usernodeconfig_DATA) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/fronius/Makefile.inc \ - $(srcdir)/named/Makefile.inc $(srcdir)/sma_webbox/Makefile.inc \ - $(srcdir)/snmp/Makefile.inc \ - $(srcdir)/stiebeleltron/Makefile.inc \ - $(top_srcdir)/build/subst.inc -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ -CMOCKA_LIBS = @CMOCKA_LIBS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CUPSCONFIG = @CUPSCONFIG@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CXX_BINARY = @CXX_BINARY@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ENABLE_UNITTESTS = @ENABLE_UNITTESTS@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IPMIMONITORING_CFLAGS = @IPMIMONITORING_CFLAGS@ -IPMIMONITORING_LIBS = @IPMIMONITORING_LIBS@ -JSON_CFLAGS = @JSON_CFLAGS@ -JSON_LIBS = @JSON_LIBS@ -LDFLAGS = @LDFLAGS@ -LIBCAP_CFLAGS = @LIBCAP_CFLAGS@ -LIBCAP_LIBS = @LIBCAP_LIBS@ -LIBCRYPTO_CFLAGS = @LIBCRYPTO_CFLAGS@ -LIBCRYPTO_LIBS = @LIBCRYPTO_LIBS@ -LIBCURL_CFLAGS = @LIBCURL_CFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBMNL_CFLAGS = @LIBMNL_CFLAGS@ -LIBMNL_LIBS = @LIBMNL_LIBS@ -LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ -LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSSL_CFLAGS = @LIBSSL_CFLAGS@ -LIBSSL_LIBS = @LIBSSL_LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MATH_CFLAGS = @MATH_CFLAGS@ -MATH_LIBS = @MATH_LIBS@ -MKDIR_P = @MKDIR_P@ -NFACCT_CFLAGS = @NFACCT_CFLAGS@ -NFACCT_LIBS = @NFACCT_LIBS@ -OBJEXT = @OBJEXT@ -OPTIONAL_CUPS_CFLAGS = @OPTIONAL_CUPS_CFLAGS@ -OPTIONAL_CUPS_LIBS = @OPTIONAL_CUPS_LIBS@ -OPTIONAL_IPMIMONITORING_CFLAGS = @OPTIONAL_IPMIMONITORING_CFLAGS@ -OPTIONAL_IPMIMONITORING_LIBS = @OPTIONAL_IPMIMONITORING_LIBS@ -OPTIONAL_JSONC_LIBS = @OPTIONAL_JSONC_LIBS@ -OPTIONAL_JUDY_LIBS = @OPTIONAL_JUDY_LIBS@ -OPTIONAL_KINESIS_CFLAGS = @OPTIONAL_KINESIS_CFLAGS@ -OPTIONAL_KINESIS_LIBS = @OPTIONAL_KINESIS_LIBS@ -OPTIONAL_LIBCAP_CFLAGS = @OPTIONAL_LIBCAP_CFLAGS@ -OPTIONAL_LIBCAP_LIBS = @OPTIONAL_LIBCAP_LIBS@ -OPTIONAL_LZ4_LIBS = @OPTIONAL_LZ4_LIBS@ -OPTIONAL_MATH_CFLAGS = @OPTIONAL_MATH_CFLAGS@ -OPTIONAL_MATH_LIBS = @OPTIONAL_MATH_LIBS@ -OPTIONAL_MONGOC_CFLAGS = @OPTIONAL_MONGOC_CFLAGS@ -OPTIONAL_MONGOC_LIBS = @OPTIONAL_MONGOC_LIBS@ -OPTIONAL_NFACCT_CFLAGS = @OPTIONAL_NFACCT_CFLAGS@ -OPTIONAL_NFACCT_LIBS = @OPTIONAL_NFACCT_LIBS@ -OPTIONAL_PROMETHEUS_REMOTE_WRITE_CFLAGS = @OPTIONAL_PROMETHEUS_REMOTE_WRITE_CFLAGS@ -OPTIONAL_PROMETHEUS_REMOTE_WRITE_LIBS = @OPTIONAL_PROMETHEUS_REMOTE_WRITE_LIBS@ -OPTIONAL_SSL_LIBS = @OPTIONAL_SSL_LIBS@ -OPTIONAL_UUID_CFLAGS = @OPTIONAL_UUID_CFLAGS@ -OPTIONAL_UUID_LIBS = @OPTIONAL_UUID_LIBS@ -OPTIONAL_UV_LIBS = @OPTIONAL_UV_LIBS@ -OPTIONAL_XENSTAT_CFLAGS = @OPTIONAL_XENSTAT_CFLAGS@ -OPTIONAL_XENSTAT_LIBS = @OPTIONAL_XENSTAT_LIBS@ -OPTIONAL_ZLIB_CFLAGS = @OPTIONAL_ZLIB_CFLAGS@ -OPTIONAL_ZLIB_LIBS = @OPTIONAL_ZLIB_LIBS@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_RPM_VERSION = @PACKAGE_RPM_VERSION@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PROTOBUF_CFLAGS = @PROTOBUF_CFLAGS@ -PROTOBUF_LIBS = @PROTOBUF_LIBS@ -PROTOC = @PROTOC@ -PTHREAD_CC = @PTHREAD_CC@ -PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSE_CANDIDATE = @SSE_CANDIDATE@ -STRIP = @STRIP@ -TEST_CFLAGS = @TEST_CFLAGS@ -TEST_LIBS = @TEST_LIBS@ -UUID_CFLAGS = @UUID_CFLAGS@ -UUID_LIBS = @UUID_LIBS@ -VERSION = @VERSION@ -XENLIGHT_CFLAGS = @XENLIGHT_CFLAGS@ -XENLIGHT_LIBS = @XENLIGHT_LIBS@ -YAJL_CFLAGS = @YAJL_CFLAGS@ -YAJL_LIBS = @YAJL_LIBS@ -ZLIB_CFLAGS = @ZLIB_CFLAGS@ -ZLIB_LIBS = @ZLIB_LIBS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -ax_pthread_config = @ax_pthread_config@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_target = @build_target@ -build_vendor = @build_vendor@ -builddir = @builddir@ -cachedir = @cachedir@ -chartsdir = @chartsdir@ -configdir = @configdir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -has_jemalloc = @has_jemalloc@ -has_tcmalloc = @has_tcmalloc@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libconfigdir = @libconfigdir@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -logdir = @logdir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -nodedir = @nodedir@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pluginsdir = @pluginsdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -pythondir = @pythondir@ -registrydir = @registrydir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -varlibdir = @varlibdir@ -webdir = @webdir@ -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -CLEANFILES = \ - node.d.plugin \ - $(NULL) - -SUFFIXES = .in -dist_libconfig_DATA = \ - node.d.conf \ - $(NULL) - -dist_plugins_SCRIPTS = \ - node.d.plugin \ - $(NULL) - -# dist_nodeconfig_DATA += fronius/fronius.conf - -# do not install these files, but include them in the distribution -# dist_nodeconfig_DATA += named/named.conf - -# do not install these files, but include them in the distribution -# dist_nodeconfig_DATA += sma_webbox/sma_webbox.conf - -# do not install these files, but include them in the distribution -# dist_nodeconfig_DATA += snmp/snmp.conf - -# do not install these files, but include them in the distribution -# dist_nodeconfig_DATA += stiebeleltron/stiebeleltron.conf - -# do not install these files, but include them in the distribution -dist_noinst_DATA = node.d.plugin.in README.md $(NULL) \ - fronius/README.md fronius/Makefile.inc named/README.md \ - named/Makefile.inc sma_webbox/README.md \ - sma_webbox/Makefile.inc snmp/README.md snmp/Makefile.inc \ - stiebeleltron/README.md stiebeleltron/Makefile.inc -usernodeconfigdir = $(configdir)/node.d -dist_usernodeconfig_DATA = \ - .keep \ - $(NULL) - -nodeconfigdir = $(libconfigdir)/node.d -dist_nodeconfig_DATA = \ - $(NULL) - - -# install these files - -# install these files - -# install these files - -# install these files - -# install these files -dist_node_DATA = $(NULL) fronius/fronius.node.js named/named.node.js \ - sma_webbox/sma_webbox.node.js snmp/snmp.node.js \ - stiebeleltron/stiebeleltron.node.js -nodemodulesdir = $(nodedir)/node_modules -dist_nodemodules_DATA = \ - node_modules/netdata.js \ - node_modules/extend.js \ - node_modules/pixl-xml.js \ - node_modules/net-snmp.js \ - node_modules/asn1-ber.js \ - $(NULL) - -nodemoduleslibberdir = $(nodedir)/node_modules/lib/ber -dist_nodemoduleslibber_DATA = \ - node_modules/lib/ber/index.js \ - node_modules/lib/ber/errors.js \ - node_modules/lib/ber/reader.js \ - node_modules/lib/ber/types.js \ - node_modules/lib/ber/writer.js \ - $(NULL) - -all: all-am - -.SUFFIXES: -.SUFFIXES: .in -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/subst.inc $(srcdir)/fronius/Makefile.inc $(srcdir)/named/Makefile.inc $(srcdir)/sma_webbox/Makefile.inc $(srcdir)/snmp/Makefile.inc $(srcdir)/stiebeleltron/Makefile.inc $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu collectors/node.d.plugin/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu collectors/node.d.plugin/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/build/subst.inc $(srcdir)/fronius/Makefile.inc $(srcdir)/named/Makefile.inc $(srcdir)/sma_webbox/Makefile.inc $(srcdir)/snmp/Makefile.inc $(srcdir)/stiebeleltron/Makefile.inc $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-dist_pluginsSCRIPTS: $(dist_plugins_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(dist_plugins_SCRIPTS)'; test -n "$(pluginsdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pluginsdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pluginsdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(pluginsdir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(pluginsdir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-dist_pluginsSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(dist_plugins_SCRIPTS)'; test -n "$(pluginsdir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(pluginsdir)'; $(am__uninstall_files_from_dir) -install-dist_libconfigDATA: $(dist_libconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_libconfig_DATA)'; test -n "$(libconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(libconfigdir)" || exit $$?; \ - done - -uninstall-dist_libconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_libconfig_DATA)'; test -n "$(libconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libconfigdir)'; $(am__uninstall_files_from_dir) -install-dist_nodeDATA: $(dist_node_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_node_DATA)'; test -n "$(nodedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(nodedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(nodedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(nodedir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(nodedir)" || exit $$?; \ - done - -uninstall-dist_nodeDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_node_DATA)'; test -n "$(nodedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(nodedir)'; $(am__uninstall_files_from_dir) -install-dist_nodeconfigDATA: $(dist_nodeconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_nodeconfig_DATA)'; test -n "$(nodeconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(nodeconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(nodeconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(nodeconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(nodeconfigdir)" || exit $$?; \ - done - -uninstall-dist_nodeconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_nodeconfig_DATA)'; test -n "$(nodeconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(nodeconfigdir)'; $(am__uninstall_files_from_dir) -install-dist_nodemodulesDATA: $(dist_nodemodules_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_nodemodules_DATA)'; test -n "$(nodemodulesdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(nodemodulesdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(nodemodulesdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(nodemodulesdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(nodemodulesdir)" || exit $$?; \ - done - -uninstall-dist_nodemodulesDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_nodemodules_DATA)'; test -n "$(nodemodulesdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(nodemodulesdir)'; $(am__uninstall_files_from_dir) -install-dist_nodemoduleslibberDATA: $(dist_nodemoduleslibber_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_nodemoduleslibber_DATA)'; test -n "$(nodemoduleslibberdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(nodemoduleslibberdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(nodemoduleslibberdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(nodemoduleslibberdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(nodemoduleslibberdir)" || exit $$?; \ - done - -uninstall-dist_nodemoduleslibberDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_nodemoduleslibber_DATA)'; test -n "$(nodemoduleslibberdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(nodemoduleslibberdir)'; $(am__uninstall_files_from_dir) -install-dist_usernodeconfigDATA: $(dist_usernodeconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(dist_usernodeconfig_DATA)'; test -n "$(usernodeconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(usernodeconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(usernodeconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(usernodeconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(usernodeconfigdir)" || exit $$?; \ - done - -uninstall-dist_usernodeconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(dist_usernodeconfig_DATA)'; test -n "$(usernodeconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(usernodeconfigdir)'; $(am__uninstall_files_from_dir) -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(SCRIPTS) $(DATA) -installdirs: - for dir in "$(DESTDIR)$(pluginsdir)" "$(DESTDIR)$(libconfigdir)" "$(DESTDIR)$(nodedir)" "$(DESTDIR)$(nodeconfigdir)" "$(DESTDIR)$(nodemodulesdir)" "$(DESTDIR)$(nodemoduleslibberdir)" "$(DESTDIR)$(usernodeconfigdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-dist_libconfigDATA install-dist_nodeDATA \ - install-dist_nodeconfigDATA install-dist_nodemodulesDATA \ - install-dist_nodemoduleslibberDATA install-dist_pluginsSCRIPTS \ - install-dist_usernodeconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-exec-local - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-dist_libconfigDATA uninstall-dist_nodeDATA \ - uninstall-dist_nodeconfigDATA uninstall-dist_nodemodulesDATA \ - uninstall-dist_nodemoduleslibberDATA \ - uninstall-dist_pluginsSCRIPTS \ - uninstall-dist_usernodeconfigDATA - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ - ctags-am distclean distclean-generic distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dist_libconfigDATA \ - install-dist_nodeDATA install-dist_nodeconfigDATA \ - install-dist_nodemodulesDATA \ - install-dist_nodemoduleslibberDATA install-dist_pluginsSCRIPTS \ - install-dist_usernodeconfigDATA install-dvi install-dvi-am \ - install-exec install-exec-am install-exec-local install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am uninstall-dist_libconfigDATA \ - uninstall-dist_nodeDATA uninstall-dist_nodeconfigDATA \ - uninstall-dist_nodemodulesDATA \ - uninstall-dist_nodemoduleslibberDATA \ - uninstall-dist_pluginsSCRIPTS \ - uninstall-dist_usernodeconfigDATA - -.PRECIOUS: Makefile - -.in: - if sed \ - -e 's#[@]localstatedir_POST@#$(localstatedir)#g' \ - -e 's#[@]sbindir_POST@#$(sbindir)#g' \ - -e 's#[@]pluginsdir_POST@#$(pluginsdir)#g' \ - -e 's#[@]configdir_POST@#$(configdir)#g' \ - -e 's#[@]libconfigdir_POST@#$(libconfigdir)#g' \ - -e 's#[@]cachedir_POST@#$(cachedir)#g' \ - -e 's#[@]registrydir_POST@#$(registrydir)#g' \ - -e 's#[@]varlibdir_POST@#$(varlibdir)#g' \ - $< > $@.tmp; then \ - mv "$@.tmp" "$@"; \ - else \ - rm -f "$@.tmp"; \ - false; \ - fi - -# Explicitly install directories to avoid permission issues due to umask -install-exec-local: - $(INSTALL) -d $(DESTDIR)$(usernodeconfigdir) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/collectors/node.d.plugin/README.md b/collectors/node.d.plugin/README.md index 6d7c1f871..8db80d85b 100644 --- a/collectors/node.d.plugin/README.md +++ b/collectors/node.d.plugin/README.md @@ -1,3 +1,8 @@ +<!-- +title: "node.d.plugin" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/README.md +--> + # node.d.plugin `node.d.plugin` is a Netdata external plugin. It is an **orchestrator** for data collection modules written in `node.js`. @@ -33,19 +38,18 @@ collectors in node.js. It also manages all its data collectors (placed in `/usr/ instance of node, thus lowering the memory footprint of data collection. Of course, there can be independent plugins written in node.js (placed in `/usr/libexec/netdata/plugins`). -These will have to be developed using the guidelines of **[External Plugins](../plugins.d/)**. +These will have to be developed using the guidelines of **[External Plugins](/collectors/plugins.d/README.md)**. To run `node.js` plugins you need to have `node` installed in your system. In some older systems, the package named `node` is not node.js. It is a terminal emulation program called `ax25-node`. In this case the node.js package may be referred as `nodejs`. Once you install `nodejs`, we suggest to link `/usr/bin/nodejs` to `/usr/bin/node`, so that typing `node` in your terminal, opens node.js. -For more information check the **\[[Installation]]** guide. ## configuring `node.d.plugin` `node.d.plugin` can work even without any configuration. Its default configuration file is -[/etc/netdata/node.d.conf](node.d.conf) (to edit it on your system run `/etc/netdata/edit-config node.d.conf`). +`node.d.conf`. To edit it on your system, run `/etc/netdata/edit-config node.d.conf`. ## configuring `node.d.plugin` modules @@ -227,6 +231,6 @@ The `service` object defines a set of functions to allow you send information to --- _FIXME: document an operational node.d.plugin data collector - the best example is the -[snmp collector](snmp/snmp.node.js)_ +[snmp collector](https://raw.githubusercontent.com/netdata/netdata/master/collectors/node.d.plugin/snmp/snmp.node.js)_ [![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnode.d.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>) diff --git a/collectors/node.d.plugin/fronius/README.md b/collectors/node.d.plugin/fronius/README.md index f109f7995..746737d0b 100644 --- a/collectors/node.d.plugin/fronius/README.md +++ b/collectors/node.d.plugin/fronius/README.md @@ -1,6 +1,12 @@ -# fronius +<!-- +title: "Fronius Symo monitoring with Netdata" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/fronius/README.md +sidebar_label: "Fronius Symo" +--> -This module collects metrics from the configured solar power installation from Fronius Symo. +# Fronius Symo monitoring with Netdata + +Collects metrics from the configured solar power installation from Fronius Symo. **Requirements** diff --git a/collectors/node.d.plugin/named/README.md b/collectors/node.d.plugin/named/README.md index 288292ba8..acd03f687 100644 --- a/collectors/node.d.plugin/named/README.md +++ b/collectors/node.d.plugin/named/README.md @@ -1,6 +1,12 @@ -# ISC Bind Statistics +<!-- +title: "ISC BIND monitoring with Netdata" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/named/README.md +sidebar_label: "ISC BIND" +--> -Using this Netdata collector, you can monitor one or more ISC Bind servers. +# ISC BIND monitoring with Netdata + +Monitor one or more ISC Bind servers. ## Example Netdata charts diff --git a/collectors/node.d.plugin/node.d.plugin b/collectors/node.d.plugin/node.d.plugin deleted file mode 100644 index 57369d0d8..000000000 --- a/collectors/node.d.plugin/node.d.plugin +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env bash -':' //; exec "$(command -v nodejs || command -v node || echo "ERROR node IS NOT AVAILABLE IN THIS SYSTEM")" "$0" "$@" - -// shebang hack from: -// http://unix.stackexchange.com/questions/65235/universal-node-js-shebang - -// Initially this is run as a shell script. -// Then, the second line, finds nodejs or node or js in the system path -// and executes it with the shell parameters. - -// netdata -// real-time performance and health monitoring, done right! -// (C) 2017 Costa Tsaousis <costa@tsaousis.gr> -// SPDX-License-Identifier: GPL-3.0-or-later - -// -------------------------------------------------------------------------------------------------------------------- - -'use strict'; - -// -------------------------------------------------------------------------------------------------------------------- -// get NETDATA environment variables - -var NETDATA_PLUGINS_DIR = process.env.NETDATA_PLUGINS_DIR || __dirname; -var NETDATA_USER_CONFIG_DIR = process.env.NETDATA_USER_CONFIG_DIR || '/etc/netdata'; -var NETDATA_STOCK_CONFIG_DIR = process.env.NETDATA_STOCK_CONFIG_DIR || '/usr/lib/netdata/conf.d'; -var NETDATA_UPDATE_EVERY = process.env.NETDATA_UPDATE_EVERY || 1; -var NODE_D_DIR = NETDATA_PLUGINS_DIR + '/../node.d'; - -// make sure the modules are found -process.mainModule.paths.unshift(NODE_D_DIR + '/node_modules'); -process.mainModule.paths.unshift(NODE_D_DIR); - - -// -------------------------------------------------------------------------------------------------------------------- -// load required modules - -var fs = require('fs'); -var url = require('url'); -var util = require('util'); -var http = require('http'); -var path = require('path'); -var extend = require('extend'); -var netdata = require('netdata'); - - -// -------------------------------------------------------------------------------------------------------------------- -// configuration - -function netdata_read_json_config_file(module_filename) { - var f = path.basename(module_filename); - - var ufilename, sfilename; - - var m = f.match('.plugin' + '$'); - if(m !== null) { - ufilename = netdata.options.paths.config + '/' + f.substring(0, m.index) + '.conf'; - sfilename = netdata.options.paths.stock_config + '/' + f.substring(0, m.index) + '.conf'; - } - - m = f.match('.node.js' + '$'); - if(m !== null) { - ufilename = netdata.options.paths.config + '/node.d/' + f.substring(0, m.index) + '.conf'; - sfilename = netdata.options.paths.stock_config + '/node.d/' + f.substring(0, m.index) + '.conf'; - } - - try { - netdata.debug('loading module\'s ' + module_filename + ' user-config ' + ufilename); - return JSON.parse(fs.readFileSync(ufilename, 'utf8')); - } - catch(e) { - netdata.error('Cannot read user-configuration file ' + ufilename + ': ' + e.message + '.'); - dumpError(e); - } - - try { - netdata.debug('loading module\'s ' + module_filename + ' stock-config ' + sfilename); - return JSON.parse(fs.readFileSync(sfilename, 'utf8')); - } - catch(e) { - netdata.error('Cannot read stock-configuration file ' + sfilename + ': ' + e.message + ', using internal defaults.'); - dumpError(e); - } - - return {}; -} - -// internal defaults -extend(true, netdata.options, { - filename: path.basename(__filename), - - update_every: NETDATA_UPDATE_EVERY, - - paths: { - plugins: NETDATA_PLUGINS_DIR, - config: NETDATA_USER_CONFIG_DIR, - stock_config: NETDATA_STOCK_CONFIG_DIR, - modules: [] - }, - - modules_enable_autodetect: true, - modules_enable_all: true, - modules: {} -}); - -// load configuration file -netdata.options_loaded = netdata_read_json_config_file(__filename); -extend(true, netdata.options, netdata.options_loaded); - -if(!netdata.options.paths.plugins) - netdata.options.paths.plugins = NETDATA_PLUGINS_DIR; - -if(!netdata.options.paths.config) - netdata.options.paths.config = NETDATA_USER_CONFIG_DIR; - -if(!netdata.options.paths.stock_config) - netdata.options.paths.stock_config = NETDATA_STOCK_CONFIG_DIR; - -// console.error('merged netdata object:'); -// console.error(util.inspect(netdata, {depth: 10})); - - -// apply module paths to node.js process -function applyModulePaths() { - var len = netdata.options.paths.modules.length; - while(len--) - process.mainModule.paths.unshift(netdata.options.paths.modules[len]); -} -applyModulePaths(); - - -// -------------------------------------------------------------------------------------------------------------------- -// tracing - -function dumpError(err) { - if (typeof err === 'object') { - if (err.stack) { - netdata.debug(err.stack); - } - } -} - -// -------------------------------------------------------------------------------------------------------------------- -// get command line arguments -{ - var found_myself = false; - var found_number = false; - var found_modules = false; - process.argv.forEach(function (val, index, array) { - netdata.debug('PARAM: ' + val); - - if(!found_myself) { - if(val === __filename) - found_myself = true; - } - else { - switch(val) { - case 'debug': - netdata.options.DEBUG = true; - netdata.debug('DEBUG enabled'); - break; - - default: - if(found_number === true) { - if(found_modules === false) { - for(var i in netdata.options.modules) - netdata.options.modules[i].enabled = false; - } - - if(typeof netdata.options.modules[val] === 'undefined') - netdata.options.modules[val] = {}; - - netdata.options.modules[val].enabled = true; - netdata.options.modules_enable_all = false; - netdata.debug('enabled module ' + val); - } - else { - try { - var x = parseInt(val); - if(x > 0) { - netdata.options.update_every = x; - if(netdata.options.update_every < NETDATA_UPDATE_EVERY) { - netdata.options.update_every = NETDATA_UPDATE_EVERY; - netdata.debug('Update frequency ' + x + 's is too low'); - } - - found_number = true; - netdata.debug('Update frequency set to ' + netdata.options.update_every + ' seconds'); - } - else netdata.error('Ignoring parameter: ' + val); - } - catch(e) { - netdata.error('Cannot get value of parameter: ' + val); - dumpError(e); - } - } - break; - } - } - }); -} - -if(netdata.options.update_every < 1) { - netdata.debug('Adjusting update frequency to 1 second'); - netdata.options.update_every = 1; -} - -// -------------------------------------------------------------------------------------------------------------------- -// find modules - -function findModules() { - var found = 0; - - var files = fs.readdirSync(NODE_D_DIR); - var len = files.length; - while(len--) { - var m = files[len].match('.node.js' + '$'); - if(m !== null) { - var n = files[len].substring(0, m.index); - - if(typeof(netdata.options.modules[n]) === 'undefined') - netdata.options.modules[n] = { name: n, enabled: netdata.options.modules_enable_all }; - - if(netdata.options.modules[n].enabled === true) { - netdata.options.modules[n].name = n; - netdata.options.modules[n].filename = NODE_D_DIR + '/' + files[len]; - netdata.options.modules[n].loaded = false; - - // load the module - try { - netdata.debug('loading module ' + netdata.options.modules[n].filename); - netdata.options.modules[n].module = require(netdata.options.modules[n].filename); - netdata.options.modules[n].module.name = n; - netdata.debug('loaded module ' + netdata.options.modules[n].name + ' from ' + netdata.options.modules[n].filename); - } - catch(e) { - netdata.options.modules[n].enabled = false; - netdata.error('Cannot load module: ' + netdata.options.modules[n].filename + ' exception: ' + e); - dumpError(e); - continue; - } - - // load its configuration - var c = { - enable_autodetect: netdata.options.modules_enable_autodetect, - update_every: netdata.options.update_every - }; - - var c2 = netdata_read_json_config_file(files[len]); - extend(true, c, c2); - - // call module auto-detection / configuration - try { - netdata.modules_configuring++; - netdata.debug('Configuring module ' + netdata.options.modules[n].name); - var serv = netdata.configure(netdata.options.modules[n].module, c, function() { - netdata.debug('Configured module ' + netdata.options.modules[n].name); - netdata.modules_configuring--; - }); - - netdata.debug('Configuring module ' + netdata.options.modules[n].name + ' reports ' + serv + ' eligible services.'); - } - catch(e) { - netdata.modules_configuring--; - netdata.options.modules[n].enabled = false; - netdata.error('Failed module auto-detection: ' + netdata.options.modules[n].name + ' exception: ' + e + ', disabling module.'); - dumpError(e); - continue; - } - - netdata.options.modules[n].loaded = true; - found++; - } - } - } - - // netdata.debug(netdata.options.modules); - return found; -} - -if(findModules() === 0) { - netdata.error('Cannot load any .node.js module from: ' + NODE_D_DIR); - netdata.disableNodePlugin(); - process.exit(1); -} - - -// -------------------------------------------------------------------------------------------------------------------- -// start - -function start_when_configuring_ends() { - if(netdata.modules_configuring > 0) { - netdata.debug('Waiting modules configuration, still running ' + netdata.modules_configuring); - setTimeout(start_when_configuring_ends, 500); - return; - } - - netdata.modules_configuring = 0; - netdata.start(); -} -start_when_configuring_ends(); - -//netdata.debug('netdata object:') -//netdata.debug(netdata); diff --git a/collectors/node.d.plugin/node_modules/net-snmp.js b/collectors/node.d.plugin/node_modules/net-snmp.js index 484597dcb..6b5b754ea 100644 --- a/collectors/node.d.plugin/node_modules/net-snmp.js +++ b/collectors/node.d.plugin/node_modules/net-snmp.js @@ -1,66 +1,77 @@ - // Copyright 2013 Stephen Vickers <stephen.vickers.sv@gmail.com> // SPDX-License-Identifier: MIT -var ber = require ("asn1-ber").Ber; -var dgram = require ("dgram"); -var events = require ("events"); -var util = require ("util"); +var ber = require("asn1-ber").Ber; +var dgram = require("dgram"); +var events = require("events"); +var util = require("util"); +var crypto = require("crypto"); + +var DEBUG = false; + +var MAX_INT32 = 2147483647; + +function debug(line) { + if (DEBUG) { + console.debug(line); + } +} /***************************************************************************** ** Constants **/ -function _expandConstantObject (object) { - var keys = []; - for (var key in object) - keys.push (key); - for (var i = 0; i < keys.length; i++) - object[object[keys[i]]] = parseInt (keys[i]); + +function _expandConstantObject(object) { + var keys = []; + for (var key in object) + keys.push(key); + for (var i = 0; i < keys.length; i++) + object[object[keys[i]]] = parseInt(keys[i]); } var ErrorStatus = { - 0: "NoError", - 1: "TooBig", - 2: "NoSuchName", - 3: "BadValue", - 4: "ReadOnly", - 5: "GeneralError", - 6: "NoAccess", - 7: "WrongType", - 8: "WrongLength", - 9: "WrongEncoding", - 10: "WrongValue", - 11: "NoCreation", - 12: "InconsistentValue", - 13: "ResourceUnavailable", - 14: "CommitFailed", - 15: "UndoFailed", - 16: "AuthorizationError", - 17: "NotWritable", - 18: "InconsistentName" -}; - -_expandConstantObject (ErrorStatus); + 0: "NoError", + 1: "TooBig", + 2: "NoSuchName", + 3: "BadValue", + 4: "ReadOnly", + 5: "GeneralError", + 6: "NoAccess", + 7: "WrongType", + 8: "WrongLength", + 9: "WrongEncoding", + 10: "WrongValue", + 11: "NoCreation", + 12: "InconsistentValue", + 13: "ResourceUnavailable", + 14: "CommitFailed", + 15: "UndoFailed", + 16: "AuthorizationError", + 17: "NotWritable", + 18: "InconsistentName" +}; + +_expandConstantObject(ErrorStatus); var ObjectType = { - 1: "Boolean", - 2: "Integer", - 4: "OctetString", - 5: "Null", - 6: "OID", - 64: "IpAddress", - 65: "Counter", - 66: "Gauge", - 67: "TimeTicks", - 68: "Opaque", - 70: "Counter64", - 128: "NoSuchObject", - 129: "NoSuchInstance", - 130: "EndOfMibView" -}; - -_expandConstantObject (ObjectType); + 1: "Boolean", + 2: "Integer", + 4: "OctetString", + 5: "Null", + 6: "OID", + 64: "IpAddress", + 65: "Counter", + 66: "Gauge", + 67: "TimeTicks", + 68: "Opaque", + 70: "Counter64", + 128: "NoSuchObject", + 129: "NoSuchInstance", + 130: "EndOfMibView" +}; + +_expandConstantObject(ObjectType); ObjectType.Integer32 = ObjectType.Integer; ObjectType.Counter32 = ObjectType.Counter; @@ -68,132 +79,173 @@ ObjectType.Gauge32 = ObjectType.Gauge; ObjectType.Unsigned32 = ObjectType.Gauge32; var PduType = { - 160: "GetRequest", - 161: "GetNextRequest", - 162: "GetResponse", - 163: "SetRequest", - 164: "Trap", - 165: "GetBulkRequest", - 166: "InformRequest", - 167: "TrapV2", - 168: "Report" + 160: "GetRequest", + 161: "GetNextRequest", + 162: "GetResponse", + 163: "SetRequest", + 164: "Trap", + 165: "GetBulkRequest", + 166: "InformRequest", + 167: "TrapV2", + 168: "Report" }; -_expandConstantObject (PduType); +_expandConstantObject(PduType); var TrapType = { - 0: "ColdStart", - 1: "WarmStart", - 2: "LinkDown", - 3: "LinkUp", - 4: "AuthenticationFailure", - 5: "EgpNeighborLoss", - 6: "EnterpriseSpecific" + 0: "ColdStart", + 1: "WarmStart", + 2: "LinkDown", + 3: "LinkUp", + 4: "AuthenticationFailure", + 5: "EgpNeighborLoss", + 6: "EnterpriseSpecific" +}; + +_expandConstantObject(TrapType); + +var SecurityLevel = { + 1: "noAuthNoPriv", + 2: "authNoPriv", + 3: "authPriv" +}; + +_expandConstantObject(SecurityLevel); + +var AuthProtocols = { + "1": "none", + "2": "md5", + "3": "sha" +}; + +_expandConstantObject(AuthProtocols); + +var PrivProtocols = { + "1": "none", + "2": "des" +}; + +_expandConstantObject(PrivProtocols); + +var MibProviderType = { + "1": "Scalar", + "2": "Table" }; -_expandConstantObject (TrapType); +_expandConstantObject(MibProviderType); var Version1 = 0; var Version2c = 1; +var Version3 = 3; + +var Version = { + "1": Version1, + "2c": Version2c, + "3": Version3 +}; /***************************************************************************** ** Exception class definitions **/ -function ResponseInvalidError (message) { - this.name = "ResponseInvalidError"; - this.message = message; - Error.captureStackTrace(this, ResponseInvalidError); +function ResponseInvalidError(message) { + this.name = "ResponseInvalidError"; + this.message = message; + Error.captureStackTrace(this, ResponseInvalidError); } -util.inherits (ResponseInvalidError, Error); -function RequestInvalidError (message) { - this.name = "RequestInvalidError"; - this.message = message; - Error.captureStackTrace(this, RequestInvalidError); +util.inherits(ResponseInvalidError, Error); + +function RequestInvalidError(message) { + this.name = "RequestInvalidError"; + this.message = message; + Error.captureStackTrace(this, RequestInvalidError); } -util.inherits (RequestInvalidError, Error); -function RequestFailedError (message, status) { - this.name = "RequestFailedError"; - this.message = message; - this.status = status; - Error.captureStackTrace(this, RequestFailedError); +util.inherits(RequestInvalidError, Error); + +function RequestFailedError(message, status) { + this.name = "RequestFailedError"; + this.message = message; + this.status = status; + Error.captureStackTrace(this, RequestFailedError); } -util.inherits (RequestFailedError, Error); -function RequestTimedOutError (message) { - this.name = "RequestTimedOutError"; - this.message = message; - Error.captureStackTrace(this, RequestTimedOutError); +util.inherits(RequestFailedError, Error); + +function RequestTimedOutError(message) { + this.name = "RequestTimedOutError"; + this.message = message; + Error.captureStackTrace(this, RequestTimedOutError); } -util.inherits (RequestTimedOutError, Error); + +util.inherits(RequestTimedOutError, Error); /***************************************************************************** ** OID and varbind helper functions **/ -function isVarbindError (varbind) { - return !!(varbind.type == ObjectType.NoSuchObject - || varbind.type == ObjectType.NoSuchInstance - || varbind.type == ObjectType.EndOfMibView); +function isVarbindError(varbind) { + return !!(varbind.type == ObjectType.NoSuchObject + || varbind.type == ObjectType.NoSuchInstance + || varbind.type == ObjectType.EndOfMibView); } -function varbindError (varbind) { - return (ObjectType[varbind.type] || "NotAnError") + ": " + varbind.oid; +function varbindError(varbind) { + return (ObjectType[varbind.type] || "NotAnError") + ": " + varbind.oid; } -function oidFollowsOid (oidString, nextString) { - var oid = {str: oidString, len: oidString.length, idx: 0}; - var next = {str: nextString, len: nextString.length, idx: 0}; - var dotCharCode = ".".charCodeAt (0); - - function getNumber (item) { - var n = 0; - if (item.idx >= item.len) - return null; - while (item.idx < item.len) { - var charCode = item.str.charCodeAt (item.idx++); - if (charCode == dotCharCode) - return n; - n = (n ? (n * 10) : n) + (charCode - 48); - } - return n; - } - - while (1) { - var oidNumber = getNumber (oid); - var nextNumber = getNumber (next); - - if (oidNumber !== null) { - if (nextNumber !== null) { - if (nextNumber > oidNumber) { - return true; - } else if (nextNumber < oidNumber) { - return false; - } - } else { - return true; - } - } else { - return true; - } - } +function oidFollowsOid(oidString, nextString) { + var oid = {str: oidString, len: oidString.length, idx: 0}; + var next = {str: nextString, len: nextString.length, idx: 0}; + var dotCharCode = ".".charCodeAt(0); + + function getNumber(item) { + var n = 0; + if (item.idx >= item.len) + return null; + while (item.idx < item.len) { + var charCode = item.str.charCodeAt(item.idx++); + if (charCode == dotCharCode) + return n; + n = (n ? (n * 10) : n) + (charCode - 48); + } + return n; + } + + while (1) { + var oidNumber = getNumber(oid); + var nextNumber = getNumber(next); + + if (oidNumber !== null) { + if (nextNumber !== null) { + if (nextNumber > oidNumber) { + return true; + } else if (nextNumber < oidNumber) { + return false; + } + } else { + return true; + } + } else { + return true; + } + } } -function oidInSubtree (oidString, nextString) { - var oid = oidString.split ("."); - var next = nextString.split ("."); +function oidInSubtree(oidString, nextString) { + var oid = oidString.split("."); + var next = nextString.split("."); - if (oid.length > next.length) - return false; + if (oid.length > next.length) + return false; - for (var i = 0; i < oid.length; i++) { - if (next[i] != oid[i]) - return false; - } + for (var i = 0; i < oid.length; i++) { + if (next[i] != oid[i]) + return false; + } - return true; + return true; } /** @@ -207,1228 +259,3138 @@ function oidInSubtree (oidString, nextString) { ** an error since the integer is too large. **/ -function readInt (buffer) { - return readUint (buffer, true); +function readInt(buffer) { + return readUint(buffer, true); +} + +function readIpAddress(buffer) { + var bytes = buffer.readString(ObjectType.IpAddress, true); + if (bytes.length != 4) + throw new ResponseInvalidError("Length '" + bytes.length + + "' of IP address '" + bytes.toString("hex") + + "' is not 4"); + var value = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3]; + return value; } -function readUint (buffer, isSigned) { - buffer.readByte (); - var length = buffer.readByte (); - var value = 0; - var signedBitSet = false; - - if (length > 5) { - throw new RangeError ("Integer too long '" + length + "'"); - } else if (length == 5) { - if (buffer.readByte () !== 0) - throw new RangeError ("Integer too long '" + length + "'"); - length = 4; - } - - for (var i = 0; i < length; i++) { - value *= 256; - value += buffer.readByte (); - - if (isSigned && i <= 0) { - if ((value & 0x80) == 0x80) - signedBitSet = true; - } - } - - if (signedBitSet) - value -= (1 << (i * 8)); - - return value; +function readUint(buffer, isSigned) { + buffer.readByte(); + var length = buffer.readByte(); + var value = 0; + var signedBitSet = false; + + if (length > 5) { + throw new RangeError("Integer too long '" + length + "'"); + } else if (length == 5) { + if (buffer.readByte() !== 0) + throw new RangeError("Integer too long '" + length + "'"); + length = 4; + } + + for (var i = 0; i < length; i++) { + value *= 256; + value += buffer.readByte(); + + if (isSigned && i <= 0) { + if ((value & 0x80) == 0x80) + signedBitSet = true; + } + } + + if (signedBitSet) + value -= (1 << (i * 8)); + + return value; } -function readUint64 (buffer) { - var value = buffer.readString (ObjectType.Counter64, true); +function readUint64(buffer) { + var value = buffer.readString(ObjectType.Counter64, true); - return value; + return value; } -function readVarbinds (buffer, varbinds) { - buffer.readSequence (); - - while (1) { - buffer.readSequence (); - var oid = buffer.readOID (); - var type = buffer.peek (); - - if (type == null) - break; - - var value; - - if (type == ObjectType.Boolean) { - value = buffer.readBoolean (); - } else if (type == ObjectType.Integer) { - value = readInt (buffer); - } else if (type == ObjectType.OctetString) { - value = buffer.readString (null, true); - } else if (type == ObjectType.Null) { - buffer.readByte (); - buffer.readByte (); - value = null; - } else if (type == ObjectType.OID) { - value = buffer.readOID (); - } else if (type == ObjectType.IpAddress) { - var bytes = buffer.readString (ObjectType.IpAddress, true); - if (bytes.length != 4) - throw new ResponseInvalidError ("Length '" + bytes.length - + "' of IP address '" + bytes.toString ("hex") - + "' is not 4"); - value = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3]; - } else if (type == ObjectType.Counter) { - value = readUint (buffer); - } else if (type == ObjectType.Gauge) { - value = readUint (buffer); - } else if (type == ObjectType.TimeTicks) { - value = readUint (buffer); - } else if (type == ObjectType.Opaque) { - value = buffer.readString (ObjectType.Opaque, true); - } else if (type == ObjectType.Counter64) { - value = readUint64 (buffer); - } else if (type == ObjectType.NoSuchObject) { - buffer.readByte (); - buffer.readByte (); - value = null; - } else if (type == ObjectType.NoSuchInstance) { - buffer.readByte (); - buffer.readByte (); - value = null; - } else if (type == ObjectType.EndOfMibView) { - buffer.readByte (); - buffer.readByte (); - value = null; - } else { - throw new ResponseInvalidError ("Unknown type '" + type - + "' in response"); - } - - varbinds.push ({ - oid: oid, - type: type, - value: value - }); - } +function readVarbinds(buffer, varbinds) { + buffer.readSequence(); + + while (1) { + buffer.readSequence(); + if (buffer.peek() != ObjectType.OID) + break; + var oid = buffer.readOID(); + var type = buffer.peek(); + + if (type == null) + break; + + var value; + + if (type == ObjectType.Boolean) { + value = buffer.readBoolean(); + } else if (type == ObjectType.Integer) { + value = readInt(buffer); + } else if (type == ObjectType.OctetString) { + value = buffer.readString(null, true); + } else if (type == ObjectType.Null) { + buffer.readByte(); + buffer.readByte(); + value = null; + } else if (type == ObjectType.OID) { + value = buffer.readOID(); + } else if (type == ObjectType.IpAddress) { + var bytes = buffer.readString(ObjectType.IpAddress, true); + if (bytes.length != 4) + throw new ResponseInvalidError("Length '" + bytes.length + + "' of IP address '" + bytes.toString("hex") + + "' is not 4"); + value = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3]; + } else if (type == ObjectType.Counter) { + value = readUint(buffer); + } else if (type == ObjectType.Gauge) { + value = readUint(buffer); + } else if (type == ObjectType.TimeTicks) { + value = readUint(buffer); + } else if (type == ObjectType.Opaque) { + value = buffer.readString(ObjectType.Opaque, true); + } else if (type == ObjectType.Counter64) { + value = readUint64(buffer); + } else if (type == ObjectType.NoSuchObject) { + buffer.readByte(); + buffer.readByte(); + value = null; + } else if (type == ObjectType.NoSuchInstance) { + buffer.readByte(); + buffer.readByte(); + value = null; + } else if (type == ObjectType.EndOfMibView) { + buffer.readByte(); + buffer.readByte(); + value = null; + } else { + throw new ResponseInvalidError("Unknown type '" + type + + "' in response"); + } + + varbinds.push({ + oid: oid, + type: type, + value: value + }); + } } -function writeUint (buffer, type, value) { - var b = new Buffer (4); - b.writeUInt32BE (value, 0); - buffer.writeBuffer (b, type); +function writeUint(buffer, type, value) { + var b = Buffer.alloc(4); + b.writeUInt32BE(value, 0); + buffer.writeBuffer(b, type); } -function writeUint64 (buffer, value) { - buffer.writeBuffer (value, ObjectType.Counter64); +function writeUint64(buffer, value) { + buffer.writeBuffer(value, ObjectType.Counter64); } -function writeVarbinds (buffer, varbinds) { - buffer.startSequence (); - for (var i = 0; i < varbinds.length; i++) { - buffer.startSequence (); - buffer.writeOID (varbinds[i].oid); - - if (varbinds[i].type && varbinds[i].hasOwnProperty("value")) { - var type = varbinds[i].type; - var value = varbinds[i].value; - - if (type == ObjectType.Boolean) { - buffer.writeBoolean (value ? true : false); - } else if (type == ObjectType.Integer) { // also Integer32 - buffer.writeInt (value); - } else if (type == ObjectType.OctetString) { - if (typeof value == "string") - buffer.writeString (value); - else - buffer.writeBuffer (value, ObjectType.OctetString); - } else if (type == ObjectType.Null) { - buffer.writeNull (); - } else if (type == ObjectType.OID) { - buffer.writeOID (value); - } else if (type == ObjectType.IpAddress) { - var bytes = value.split ("."); - if (bytes.length != 4) - throw new RequestInvalidError ("Invalid IP address '" - + value + "'"); - buffer.writeBuffer (new Buffer (bytes), 64); - } else if (type == ObjectType.Counter) { // also Counter32 - writeUint (buffer, ObjectType.Counter, value); - } else if (type == ObjectType.Gauge) { // also Gauge32 & Unsigned32 - writeUint (buffer, ObjectType.Gauge, value); - } else if (type == ObjectType.TimeTicks) { - writeUint (buffer, ObjectType.TimeTicks, value); - } else if (type == ObjectType.Opaque) { - buffer.writeBuffer (value, ObjectType.Opaque); - } else if (type == ObjectType.Counter64) { - writeUint64 (buffer, value); - } else { - throw new RequestInvalidError ("Unknown type '" + type - + "' in request"); - } - } else { - buffer.writeNull (); - } - - buffer.endSequence (); - } - buffer.endSequence (); +function writeVarbinds(buffer, varbinds) { + buffer.startSequence(); + for (var i = 0; i < varbinds.length; i++) { + buffer.startSequence(); + buffer.writeOID(varbinds[i].oid); + + if (varbinds[i].type && varbinds[i].hasOwnProperty("value")) { + var type = varbinds[i].type; + var value = varbinds[i].value; + + if (type == ObjectType.Boolean) { + buffer.writeBoolean(value ? true : false); + } else if (type == ObjectType.Integer) { // also Integer32 + buffer.writeInt(value); + } else if (type == ObjectType.OctetString) { + if (typeof value == "string") + buffer.writeString(value); + else + buffer.writeBuffer(value, ObjectType.OctetString); + } else if (type == ObjectType.Null) { + buffer.writeNull(); + } else if (type == ObjectType.OID) { + buffer.writeOID(value); + } else if (type == ObjectType.IpAddress) { + var bytes = value.split("."); + if (bytes.length != 4) + throw new RequestInvalidError("Invalid IP address '" + + value + "'"); + buffer.writeBuffer(Buffer.from(bytes), 64); + } else if (type == ObjectType.Counter) { // also Counter32 + writeUint(buffer, ObjectType.Counter, value); + } else if (type == ObjectType.Gauge) { // also Gauge32 & Unsigned32 + writeUint(buffer, ObjectType.Gauge, value); + } else if (type == ObjectType.TimeTicks) { + writeUint(buffer, ObjectType.TimeTicks, value); + } else if (type == ObjectType.Opaque) { + buffer.writeBuffer(value, ObjectType.Opaque); + } else if (type == ObjectType.Counter64) { + writeUint64(buffer, value); + } else if (type == ObjectType.EndOfMibView) { + buffer.writeByte(130); + buffer.writeByte(0); + } else { + throw new RequestInvalidError("Unknown type '" + type + + "' in request"); + } + } else { + buffer.writeNull(); + } + + buffer.endSequence(); + } + buffer.endSequence(); } /***************************************************************************** ** PDU class definitions **/ -var SimplePdu = function (id, varbinds, options) { - this.id = id; - this.varbinds = varbinds; - this.options = options || {}; +var SimplePdu = function () { }; SimplePdu.prototype.toBuffer = function (buffer) { - buffer.startSequence (this.type); + buffer.startSequence(this.type); - buffer.writeInt (this.id); - buffer.writeInt ((this.type == PduType.GetBulkRequest) - ? (this.options.nonRepeaters || 0) - : 0); - buffer.writeInt ((this.type == PduType.GetBulkRequest) - ? (this.options.maxRepetitions || 0) - : 0); + buffer.writeInt(this.id); + buffer.writeInt((this.type == PduType.GetBulkRequest) + ? (this.options.nonRepeaters || 0) + : 0); + buffer.writeInt((this.type == PduType.GetBulkRequest) + ? (this.options.maxRepetitions || 0) + : 0); - writeVarbinds (buffer, this.varbinds); + writeVarbinds(buffer, this.varbinds); - buffer.endSequence (); + buffer.endSequence(); }; -var GetBulkRequestPdu = function () { - this.type = PduType.GetBulkRequest; - GetBulkRequestPdu.super_.apply (this, arguments); -}; +SimplePdu.prototype.initializeFromVariables = function (id, varbinds, options) { + this.id = id; + this.varbinds = varbinds; + this.options = options || {}; + this.contextName = (options && options.context) ? options.context : ""; +} -util.inherits (GetBulkRequestPdu, SimplePdu); +SimplePdu.prototype.initializeFromBuffer = function (reader) { + this.type = reader.peek(); + reader.readSequence(); + + this.id = reader.readInt(); + this.nonRepeaters = reader.readInt(); + this.maxRepetitions = reader.readInt(); + + this.varbinds = []; + readVarbinds(reader, this.varbinds); -var GetNextRequestPdu = function () { - this.type = PduType.GetNextRequest; - GetNextRequestPdu.super_.apply (this, arguments); }; -util.inherits (GetNextRequestPdu, SimplePdu); +SimplePdu.prototype.getResponsePduForRequest = function () { + var responsePdu = GetResponsePdu.createFromVariables(this.id, [], {}); + if (this.contextEngineID) { + responsePdu.contextEngineID = this.contextEngineID; + responsePdu.contextName = this.contextName; + } + return responsePdu; +}; + +SimplePdu.createFromVariables = function (pduClass, id, varbinds, options) { + var pdu = new pduClass(id, varbinds, options); + pdu.id = id; + pdu.varbinds = varbinds; + pdu.options = options || {}; + pdu.contextName = (options && options.context) ? options.context : ""; + return pdu; +}; -var GetResponsePdu = function (buffer) { - this.type = PduType.GetResponse; +var GetBulkRequestPdu = function () { + this.type = PduType.GetBulkRequest; + GetBulkRequestPdu.super_.apply(this, arguments); +}; - buffer.readSequence (this.type); +util.inherits(GetBulkRequestPdu, SimplePdu); - this.id = buffer.readInt (); +GetBulkRequestPdu.createFromBuffer = function (reader) { + var pdu = new GetBulkRequestPdu(); + pdu.initializeFromBuffer(reader); + return pdu; +}; - this.errorStatus = buffer.readInt (); - this.errorIndex = buffer.readInt (); +var GetNextRequestPdu = function () { + this.type = PduType.GetNextRequest; + GetNextRequestPdu.super_.apply(this, arguments); +}; - this.varbinds = []; +util.inherits(GetNextRequestPdu, SimplePdu); - readVarbinds (buffer, this.varbinds); +GetNextRequestPdu.createFromBuffer = function (reader) { + var pdu = new GetNextRequestPdu(); + pdu.initializeFromBuffer(reader); + return pdu; }; var GetRequestPdu = function () { - this.type = PduType.GetRequest; - GetRequestPdu.super_.apply (this, arguments); + this.type = PduType.GetRequest; + GetRequestPdu.super_.apply(this, arguments); +}; + +util.inherits(GetRequestPdu, SimplePdu); + +GetRequestPdu.createFromBuffer = function (reader) { + var pdu = new GetRequestPdu(); + pdu.initializeFromBuffer(reader); + return pdu; }; -util.inherits (GetRequestPdu, SimplePdu); +GetRequestPdu.createFromVariables = function (id, varbinds, options) { + var pdu = new GetRequestPdu(); + pdu.initializeFromVariables(id, varbinds, options); + return pdu; +}; var InformRequestPdu = function () { - this.type = PduType.InformRequest; - InformRequestPdu.super_.apply (this, arguments); + this.type = PduType.InformRequest; + InformRequestPdu.super_.apply(this, arguments); }; -util.inherits (InformRequestPdu, SimplePdu); +util.inherits(InformRequestPdu, SimplePdu); + +InformRequestPdu.createFromBuffer = function (reader) { + var pdu = new InformRequestPdu(); + pdu.initializeFromBuffer(reader); + return pdu; +}; var SetRequestPdu = function () { - this.type = PduType.SetRequest; - SetRequestPdu.super_.apply (this, arguments); + this.type = PduType.SetRequest; + SetRequestPdu.super_.apply(this, arguments); +}; + +util.inherits(SetRequestPdu, SimplePdu); + +SetRequestPdu.createFromBuffer = function (reader) { + var pdu = new SetRequestPdu(); + pdu.initializeFromBuffer(reader); + return pdu; }; -util.inherits (SetRequestPdu, SimplePdu); +var TrapPdu = function () { + this.type = PduType.Trap; +}; -var TrapPdu = function (typeOrOid, varbinds, options) { - this.type = PduType.Trap; +TrapPdu.prototype.toBuffer = function (buffer) { + buffer.startSequence(this.type); - this.agentAddr = options.agentAddr || "127.0.0.1"; - this.upTime = options.upTime; + buffer.writeOID(this.enterprise); + buffer.writeBuffer(Buffer.from(this.agentAddr.split(".")), + ObjectType.IpAddress); + buffer.writeInt(this.generic); + buffer.writeInt(this.specific); + writeUint(buffer, ObjectType.TimeTicks, + this.upTime || Math.floor(process.uptime() * 100)); - if (typeof typeOrOid == "string") { - this.generic = TrapType.EnterpriseSpecific; - this.specific = parseInt (typeOrOid.match (/\.(\d+)$/)[1]); - this.enterprise = typeOrOid.replace (/\.(\d+)$/, ""); - } else { - this.generic = typeOrOid; - this.specific = 0; - this.enterprise = "1.3.6.1.4.1"; - } + writeVarbinds(buffer, this.varbinds); - this.varbinds = varbinds; + buffer.endSequence(); }; -TrapPdu.prototype.toBuffer = function (buffer) { - buffer.startSequence (this.type); +TrapPdu.createFromBuffer = function (reader) { + var pdu = new TrapPdu(); + reader.readSequence(); + + pdu.enterprise = reader.readOID(); + pdu.agentAddr = readIpAddress(reader); + pdu.generic = reader.readInt(); + pdu.specific = reader.readInt(); + pdu.upTime = readUint(reader) + + pdu.varbinds = []; + readVarbinds(reader, pdu.varbinds); + + return pdu; +}; - buffer.writeOID (this.enterprise); - buffer.writeBuffer (new Buffer (this.agentAddr.split (".")), - ObjectType.IpAddress); - buffer.writeInt (this.generic); - buffer.writeInt (this.specific); - writeUint (buffer, ObjectType.TimeTicks, - this.upTime || Math.floor (process.uptime () * 100)); +TrapPdu.createFromVariables = function (typeOrOid, varbinds, options) { + var pdu = new TrapPdu(); + pdu.agentAddr = options.agentAddr || "127.0.0.1"; + pdu.upTime = options.upTime; - writeVarbinds (buffer, this.varbinds); + if (typeof typeOrOid == "string") { + pdu.generic = TrapType.EnterpriseSpecific; + pdu.specific = parseInt(typeOrOid.match(/\.(\d+)$/)[1]); + pdu.enterprise = typeOrOid.replace(/\.(\d+)$/, ""); + } else { + pdu.generic = typeOrOid; + pdu.specific = 0; + pdu.enterprise = "1.3.6.1.4.1"; + } - buffer.endSequence (); + pdu.varbinds = varbinds; + + return pdu; }; var TrapV2Pdu = function () { - this.type = PduType.TrapV2; - TrapV2Pdu.super_.apply (this, arguments); + this.type = PduType.TrapV2; + TrapV2Pdu.super_.apply(this, arguments); +}; + +util.inherits(TrapV2Pdu, SimplePdu); + +TrapV2Pdu.createFromBuffer = function (reader) { + var pdu = new TrapV2Pdu(); + pdu.initializeFromBuffer(reader); + return pdu; +}; + +TrapV2Pdu.createFromVariables = function (id, varbinds, options) { + var pdu = new TrapV2Pdu(); + pdu.initializeFromVariables(id, varbinds, options); + return pdu; +}; + +var SimpleResponsePdu = function () { +}; + +SimpleResponsePdu.prototype.toBuffer = function (writer) { + writer.startSequence(this.type); + + writer.writeInt(this.id); + writer.writeInt(this.errorStatus || 0); + writer.writeInt(this.errorIndex || 0); + writeVarbinds(writer, this.varbinds); + writer.endSequence(); + }; -util.inherits (TrapV2Pdu, SimplePdu); +SimpleResponsePdu.prototype.initializeFromBuffer = function (reader) { + reader.readSequence(this.type); + + this.id = reader.readInt(); + this.errorStatus = reader.readInt(); + this.errorIndex = reader.readInt(); + + this.varbinds = []; + readVarbinds(reader, this.varbinds); +}; + +SimpleResponsePdu.prototype.initializeFromVariables = function (id, varbinds, options) { + this.id = id; + this.varbinds = varbinds; + this.options = options || {}; +}; + +var GetResponsePdu = function () { + this.type = PduType.GetResponse; + GetResponsePdu.super_.apply(this, arguments); +}; + +util.inherits(GetResponsePdu, SimpleResponsePdu); + +GetResponsePdu.createFromBuffer = function (reader) { + var pdu = new GetResponsePdu(); + pdu.initializeFromBuffer(reader); + return pdu; +}; + +GetResponsePdu.createFromVariables = function (id, varbinds, options) { + var pdu = new GetResponsePdu(); + pdu.initializeFromVariables(id, varbinds, options); + return pdu; +}; + +var ReportPdu = function () { + this.type = PduType.Report; + ReportPdu.super_.apply(this, arguments); +}; + +util.inherits(ReportPdu, SimpleResponsePdu); + +ReportPdu.createFromBuffer = function (reader) { + var pdu = new ReportPdu(); + pdu.initializeFromBuffer(reader); + return pdu; +}; + +ReportPdu.createFromVariables = function (id, varbinds, options) { + var pdu = new ReportPdu(); + pdu.initializeFromVariables(id, varbinds, options); + return pdu; +}; + +var readPdu = function (reader, scoped) { + var pdu; + var contextEngineID; + var contextName; + if (scoped) { + reader.readSequence(); + contextEngineID = reader.readString(ber.OctetString, true); + contextName = reader.readString(); + } + var type = reader.peek(); + + if (type == PduType.GetResponse) { + pdu = GetResponsePdu.createFromBuffer(reader); + } else if (type == PduType.Report) { + pdu = ReportPdu.createFromBuffer(reader); + } else if (type == PduType.Trap) { + pdu = TrapPdu.createFromBuffer(reader); + } else if (type == PduType.TrapV2) { + pdu = TrapV2Pdu.createFromBuffer(reader); + } else if (type == PduType.InformRequest) { + pdu = InformRequestPdu.createFromBuffer(reader); + } else if (type == PduType.GetRequest) { + pdu = GetRequestPdu.createFromBuffer(reader); + } else if (type == PduType.SetRequest) { + pdu = SetRequestPdu.createFromBuffer(reader); + } else if (type == PduType.GetNextRequest) { + pdu = GetNextRequestPdu.createFromBuffer(reader); + } else if (type == PduType.GetBulkRequest) { + pdu = GetBulkRequestPdu.createFromBuffer(reader); + } else { + throw new ResponseInvalidError("Unknown PDU type '" + type + + "' in response"); + } + if (scoped) { + pdu.contextEngineID = contextEngineID; + pdu.contextName = contextName; + } + pdu.scoped = scoped; + return pdu; +}; + +var createDiscoveryPdu = function (context) { + return GetRequestPdu.createFromVariables(_generateId(), [], {context: context}); +}; + +var Authentication = {}; + +Authentication.HMAC_BUFFER_SIZE = 1024 * 1024; +Authentication.HMAC_BLOCK_SIZE = 64; +Authentication.AUTHENTICATION_CODE_LENGTH = 12; +Authentication.AUTH_PARAMETERS_PLACEHOLDER = Buffer.from('8182838485868788898a8b8c', 'hex'); + +Authentication.algorithms = {}; + +Authentication.algorithms[AuthProtocols.md5] = { + // KEY_LENGTH: 16, + CRYPTO_ALGORITHM: 'md5' +}; + +Authentication.algorithms[AuthProtocols.sha] = { + // KEY_LENGTH: 20, + CRYPTO_ALGORITHM: 'sha1' +}; + +// Adapted from RFC3414 Appendix A.2.1. Password to Key Sample Code for MD5 +Authentication.passwordToKey = function (authProtocol, authPasswordString, engineID) { + var hashAlgorithm; + var firstDigest; + var finalDigest; + var buf = Buffer.alloc(Authentication.HMAC_BUFFER_SIZE); + var bufOffset = 0; + var passwordIndex = 0; + var count = 0; + var password = Buffer.from(authPasswordString); + var cryptoAlgorithm = Authentication.algorithms[authProtocol].CRYPTO_ALGORITHM; + + while (count < Authentication.HMAC_BUFFER_SIZE) { + for (var i = 0; i < Authentication.HMAC_BLOCK_SIZE; i++) { + buf.writeUInt8(password[passwordIndex++ % password.length], bufOffset++); + } + count += Authentication.HMAC_BLOCK_SIZE; + } + hashAlgorithm = crypto.createHash(cryptoAlgorithm); + hashAlgorithm.update(buf); + firstDigest = hashAlgorithm.digest(); + // debug ("First digest: " + firstDigest.toString('hex')); + + hashAlgorithm = crypto.createHash(cryptoAlgorithm); + hashAlgorithm.update(firstDigest); + hashAlgorithm.update(engineID); + hashAlgorithm.update(firstDigest); + finalDigest = hashAlgorithm.digest(); + debug("Localized key: " + finalDigest.toString('hex')); + + return finalDigest; +}; + +Authentication.addParametersToMessageBuffer = function (messageBuffer, authProtocol, authPassword, engineID) { + var authenticationParametersOffset; + var digestToAdd; + + // clear the authenticationParameters field in message + authenticationParametersOffset = messageBuffer.indexOf(Authentication.AUTH_PARAMETERS_PLACEHOLDER); + messageBuffer.fill(0, authenticationParametersOffset, authenticationParametersOffset + Authentication.AUTHENTICATION_CODE_LENGTH); + + digestToAdd = Authentication.calculateDigest(messageBuffer, authProtocol, authPassword, engineID); + digestToAdd.copy(messageBuffer, authenticationParametersOffset, 0, Authentication.AUTHENTICATION_CODE_LENGTH); + debug("Added Auth Parameters: " + digestToAdd.toString('hex')); +}; + +Authentication.isAuthentic = function (messageBuffer, authProtocol, authPassword, engineID, digestInMessage) { + var authenticationParametersOffset; + var calculatedDigest; + + // clear the authenticationParameters field in message + authenticationParametersOffset = messageBuffer.indexOf(digestInMessage); + messageBuffer.fill(0, authenticationParametersOffset, authenticationParametersOffset + Authentication.AUTHENTICATION_CODE_LENGTH); + + calculatedDigest = Authentication.calculateDigest(messageBuffer, authProtocol, authPassword, engineID); + + // replace previously cleared authenticationParameters field in message + digestInMessage.copy(messageBuffer, authenticationParametersOffset, 0, Authentication.AUTHENTICATION_CODE_LENGTH); + + debug("Digest in message: " + digestInMessage.toString('hex')); + debug("Calculated digest: " + calculatedDigest.toString('hex')); + return calculatedDigest.equals(digestInMessage, Authentication.AUTHENTICATION_CODE_LENGTH); +}; + +Authentication.calculateDigest = function (messageBuffer, authProtocol, authPassword, engineID) { + var authKey = Authentication.passwordToKey(authProtocol, authPassword, engineID); + + // Adapted from RFC3147 Section 6.3.1. Processing an Outgoing Message + var hashAlgorithm; + var kIpad; + var kOpad; + var firstDigest; + var finalDigest; + var truncatedDigest; + var i; + var cryptoAlgorithm = Authentication.algorithms[authProtocol].CRYPTO_ALGORITHM; + + if (authKey.length > Authentication.HMAC_BLOCK_SIZE) { + hashAlgorithm = crypto.createHash(cryptoAlgorithm); + hashAlgorithm.update(authKey); + authKey = hashAlgorithm.digest(); + } + + // MD(K XOR opad, MD(K XOR ipad, msg)) + kIpad = Buffer.alloc(Authentication.HMAC_BLOCK_SIZE); + kOpad = Buffer.alloc(Authentication.HMAC_BLOCK_SIZE); + for (i = 0; i < authKey.length; i++) { + kIpad[i] = authKey[i] ^ 0x36; + kOpad[i] = authKey[i] ^ 0x5c; + } + kIpad.fill(0x36, authKey.length); + kOpad.fill(0x5c, authKey.length); + + // inner MD + hashAlgorithm = crypto.createHash(cryptoAlgorithm); + hashAlgorithm.update(kIpad); + hashAlgorithm.update(messageBuffer); + firstDigest = hashAlgorithm.digest(); + // outer MD + hashAlgorithm = crypto.createHash(cryptoAlgorithm); + hashAlgorithm.update(kOpad); + hashAlgorithm.update(firstDigest); + finalDigest = hashAlgorithm.digest(); + + truncatedDigest = Buffer.alloc(Authentication.AUTHENTICATION_CODE_LENGTH); + finalDigest.copy(truncatedDigest, 0, 0, Authentication.AUTHENTICATION_CODE_LENGTH); + return truncatedDigest; +}; + +var Encryption = {}; + +Encryption.INPUT_KEY_LENGTH = 16; +Encryption.DES_KEY_LENGTH = 8; +Encryption.DES_BLOCK_LENGTH = 8; +Encryption.CRYPTO_DES_ALGORITHM = 'des-cbc'; +Encryption.PRIV_PARAMETERS_PLACEHOLDER = Buffer.from('9192939495969798', 'hex'); + +Encryption.encryptPdu = function (scopedPdu, privProtocol, privPassword, authProtocol, engineID) { + var privLocalizedKey; + var encryptionKey; + var preIv; + var salt; + var iv; + var i; + var paddedScopedPduLength; + var paddedScopedPdu; + var encryptedPdu; + var cbcProtocol = Encryption.CRYPTO_DES_ALGORITHM; + + privLocalizedKey = Authentication.passwordToKey(authProtocol, privPassword, engineID); + encryptionKey = Buffer.alloc(Encryption.DES_KEY_LENGTH); + privLocalizedKey.copy(encryptionKey, 0, 0, Encryption.DES_KEY_LENGTH); + preIv = Buffer.alloc(Encryption.DES_BLOCK_LENGTH); + privLocalizedKey.copy(preIv, 0, Encryption.DES_KEY_LENGTH, Encryption.DES_KEY_LENGTH + Encryption.DES_BLOCK_LENGTH); + + salt = Buffer.alloc(Encryption.DES_BLOCK_LENGTH); + // set local SNMP engine boots part of salt to 1, as we have no persistent engine state + salt.fill('00000001', 0, 4, 'hex'); + // set local integer part of salt to random + salt.fill(crypto.randomBytes(4), 4, 8); + iv = Buffer.alloc(Encryption.DES_BLOCK_LENGTH); + for (i = 0; i < iv.length; i++) { + iv[i] = preIv[i] ^ salt[i]; + } + + if (scopedPdu.length % Encryption.DES_BLOCK_LENGTH == 0) { + paddedScopedPdu = scopedPdu; + } else { + paddedScopedPduLength = Encryption.DES_BLOCK_LENGTH * (Math.floor(scopedPdu.length / Encryption.DES_BLOCK_LENGTH) + 1); + paddedScopedPdu = Buffer.alloc(paddedScopedPduLength); + scopedPdu.copy(paddedScopedPdu, 0, 0, scopedPdu.length); + } + cipher = crypto.createCipheriv(cbcProtocol, encryptionKey, iv); + encryptedPdu = cipher.update(paddedScopedPdu); + encryptedPdu = Buffer.concat([encryptedPdu, cipher.final()]); + debug("Key: " + encryptionKey.toString('hex')); + debug("IV: " + iv.toString('hex')); + debug("Plain: " + paddedScopedPdu.toString('hex')); + debug("Encrypted: " + encryptedPdu.toString('hex')); + + return { + encryptedPdu: encryptedPdu, + msgPrivacyParameters: salt + }; +}; + +Encryption.decryptPdu = function (encryptedPdu, privProtocol, privParameters, privPassword, authProtocol, engineID, forceAutoPaddingDisable) { + var privLocalizedKey; + var decryptionKey; + var preIv; + var salt; + var iv; + var i; + var decryptedPdu; + var cbcProtocol = Encryption.CRYPTO_DES_ALGORITHM; + ; + + privLocalizedKey = Authentication.passwordToKey(authProtocol, privPassword, engineID); + decryptionKey = Buffer.alloc(Encryption.DES_KEY_LENGTH); + privLocalizedKey.copy(decryptionKey, 0, 0, Encryption.DES_KEY_LENGTH); + preIv = Buffer.alloc(Encryption.DES_BLOCK_LENGTH); + privLocalizedKey.copy(preIv, 0, Encryption.DES_KEY_LENGTH, Encryption.DES_KEY_LENGTH + Encryption.DES_BLOCK_LENGTH); + + salt = privParameters; + iv = Buffer.alloc(Encryption.DES_BLOCK_LENGTH); + for (i = 0; i < iv.length; i++) { + iv[i] = preIv[i] ^ salt[i]; + } + + decipher = crypto.createDecipheriv(cbcProtocol, decryptionKey, iv); + if (forceAutoPaddingDisable) { + decipher.setAutoPadding(false); + } + decryptedPdu = decipher.update(encryptedPdu); + // This try-catch is a workaround for a seemingly incorrect error condition + // - where sometimes a decrypt error is thrown with decipher.final() + // It replaces this line which should have been sufficient: + // decryptedPdu = Buffer.concat ([decryptedPdu, decipher.final()]); + try { + decryptedPdu = Buffer.concat([decryptedPdu, decipher.final()]); + } catch (error) { + // debug("Decrypt error: " + error); + decipher = crypto.createDecipheriv(cbcProtocol, decryptionKey, iv); + decipher.setAutoPadding(false); + decryptedPdu = decipher.update(encryptedPdu); + decryptedPdu = Buffer.concat([decryptedPdu, decipher.final()]); + } + debug("Key: " + decryptionKey.toString('hex')); + debug("IV: " + iv.toString('hex')); + debug("Encrypted: " + encryptedPdu.toString('hex')); + debug("Plain: " + decryptedPdu.toString('hex')); + + return decryptedPdu; + +}; + +Encryption.addParametersToMessageBuffer = function (messageBuffer, msgPrivacyParameters) { + privacyParametersOffset = messageBuffer.indexOf(Encryption.PRIV_PARAMETERS_PLACEHOLDER); + msgPrivacyParameters.copy(messageBuffer, privacyParametersOffset, 0, Encryption.DES_IV_LENGTH); +}; /***************************************************************************** - ** Message class definitions + ** Message class definition **/ -var RequestMessage = function (version, community, pdu) { - this.version = version; - this.community = community; - this.pdu = pdu; +var Message = function () { +} + +Message.prototype.getReqId = function () { + return this.version == Version3 ? this.msgGlobalData.msgID : this.pdu.id; +}; + +Message.prototype.toBuffer = function () { + if (this.version == Version3) { + return this.toBufferV3(); + } else { + return this.toBufferCommunity(); + } +} + +Message.prototype.toBufferCommunity = function () { + if (this.buffer) + return this.buffer; + + var writer = new ber.Writer(); + + writer.startSequence(); + + writer.writeInt(this.version); + writer.writeString(this.community); + + this.pdu.toBuffer(writer); + + writer.endSequence(); + + this.buffer = writer.buffer; + + return this.buffer; +}; + +Message.prototype.toBufferV3 = function () { + var encryptionResult; + + if (this.buffer) + return this.buffer; + + var writer = new ber.Writer(); + + writer.startSequence(); + + writer.writeInt(this.version); + + // HeaderData + writer.startSequence(); + writer.writeInt(this.msgGlobalData.msgID); + writer.writeInt(this.msgGlobalData.msgMaxSize); + writer.writeByte(ber.OctetString); + writer.writeByte(1); + writer.writeByte(this.msgGlobalData.msgFlags); + writer.writeInt(this.msgGlobalData.msgSecurityModel); + writer.endSequence(); + + // msgSecurityParameters + var msgSecurityParametersWriter = new ber.Writer(); + msgSecurityParametersWriter.startSequence(); + //msgSecurityParametersWriter.writeString (this.msgSecurityParameters.msgAuthoritativeEngineID); + // writing a zero-length buffer fails - should fix asn1-ber for this condition + if (this.msgSecurityParameters.msgAuthoritativeEngineID.length == 0) { + msgSecurityParametersWriter.writeString(""); + } else { + msgSecurityParametersWriter.writeBuffer(this.msgSecurityParameters.msgAuthoritativeEngineID, ber.OctetString); + } + msgSecurityParametersWriter.writeInt(this.msgSecurityParameters.msgAuthoritativeEngineBoots); + msgSecurityParametersWriter.writeInt(this.msgSecurityParameters.msgAuthoritativeEngineTime); + msgSecurityParametersWriter.writeString(this.msgSecurityParameters.msgUserName); + + if (this.hasAuthentication()) { + msgSecurityParametersWriter.writeBuffer(Authentication.AUTH_PARAMETERS_PLACEHOLDER, ber.OctetString); + // should never happen where msgFlags has no authentication but authentication parameters still present + } else if (this.msgSecurityParameters.msgAuthenticationParameters.length > 0) { + msgSecurityParametersWriter.writeBuffer(this.msgSecurityParameters.msgAuthenticationParameters, ber.OctetString); + } else { + msgSecurityParametersWriter.writeString(""); + } + + if (this.hasPrivacy()) { + msgSecurityParametersWriter.writeBuffer(Encryption.PRIV_PARAMETERS_PLACEHOLDER, ber.OctetString); + // should never happen where msgFlags has no privacy but privacy parameters still present + } else if (this.msgSecurityParameters.msgPrivacyParameters.length > 0) { + msgSecurityParametersWriter.writeBuffer(this.msgSecurityParameters.msgPrivacyParameters, ber.OctetString); + } else { + msgSecurityParametersWriter.writeString(""); + } + msgSecurityParametersWriter.endSequence(); + + writer.writeBuffer(msgSecurityParametersWriter.buffer, ber.OctetString); + + // ScopedPDU + var scopedPduWriter = new ber.Writer(); + scopedPduWriter.startSequence(); + var contextEngineID = this.pdu.contextEngineID ? this.pdu.contextEngineID : this.msgSecurityParameters.msgAuthoritativeEngineID; + if (contextEngineID.length == 0) { + scopedPduWriter.writeString(""); + } else { + scopedPduWriter.writeBuffer(contextEngineID, ber.OctetString); + } + scopedPduWriter.writeString(this.pdu.contextName); + this.pdu.toBuffer(scopedPduWriter); + scopedPduWriter.endSequence(); + + if (this.hasPrivacy()) { + encryptionResult = Encryption.encryptPdu(scopedPduWriter.buffer, this.user.privProtocol, this.user.privKey, this.user.authProtocol, this.msgSecurityParameters.msgAuthoritativeEngineID); + writer.writeBuffer(encryptionResult.encryptedPdu, ber.OctetString); + } else { + writer.writeBuffer(scopedPduWriter.buffer); + } + + writer.endSequence(); + + this.buffer = writer.buffer; + + if (this.hasPrivacy()) { + Encryption.addParametersToMessageBuffer(this.buffer, encryptionResult.msgPrivacyParameters); + } + + if (this.hasAuthentication()) { + Authentication.addParametersToMessageBuffer(this.buffer, this.user.authProtocol, this.user.authKey, + this.msgSecurityParameters.msgAuthoritativeEngineID); + } + + return this.buffer; +}; + +Message.prototype.processIncomingSecurity = function (user, responseCb) { + if (this.hasPrivacy()) { + if (!this.decryptPdu(user, responseCb)) { + return false; + } + } + + if (this.hasAuthentication() && !this.isAuthenticationDisabled()) { + return this.checkAuthentication(user, responseCb); + } else { + return true; + } +}; + +Message.prototype.decryptPdu = function (user, responseCb) { + var decryptedPdu; + var decryptedPduReader; + try { + decryptedPdu = Encryption.decryptPdu(this.encryptedPdu, user.privProtocol, + this.msgSecurityParameters.msgPrivacyParameters, user.privKey, user.authProtocol, + this.msgSecurityParameters.msgAuthoritativeEngineID); + decryptedPduReader = new ber.Reader(decryptedPdu); + this.pdu = readPdu(decryptedPduReader, true); + return true; + // really really occasionally the decrypt truncates a single byte + // causing an ASN read failure in readPdu() + // in this case, disabling auto padding decrypts the PDU correctly + // this try-catch provides the workaround for this condition + } catch (possibleTruncationError) { + try { + decryptedPdu = Encryption.decryptPdu(this.encryptedPdu, user.privProtocol, + this.msgSecurityParameters.msgPrivacyParameters, user.privKey, user.authProtocol, + this.msgSecurityParameters.msgAuthoritativeEngineID, true); + decryptedPduReader = new ber.Reader(decryptedPdu); + this.pdu = readPdu(decryptedPduReader, true); + return true; + } catch (error) { + responseCb(new ResponseInvalidError("Failed to decrypt PDU: " + error)); + return false; + } + } + +}; + +Message.prototype.checkAuthentication = function (user, responseCb) { + if (Authentication.isAuthentic(this.buffer, user.authProtocol, user.authKey, + this.msgSecurityParameters.msgAuthoritativeEngineID, this.msgSecurityParameters.msgAuthenticationParameters)) { + return true; + } else { + responseCb(new ResponseInvalidError("Authentication digest " + + this.msgSecurityParameters.msgAuthenticationParameters.toString('hex') + + " received in message does not match digest " + + Authentication.calculateDigest(buffer, user.authProtocol, user.authKey, + this.msgSecurityParameters.msgAuthoritativeEngineID).toString('hex') + + " calculated for message")); + return false; + } + +}; + +Message.prototype.hasAuthentication = function () { + return this.msgGlobalData && this.msgGlobalData.msgFlags && this.msgGlobalData.msgFlags & 1; }; -RequestMessage.prototype.toBuffer = function () { - if (this.buffer) - return this.buffer; +Message.prototype.hasPrivacy = function () { + return this.msgGlobalData && this.msgGlobalData.msgFlags && this.msgGlobalData.msgFlags & 2; +}; + +Message.prototype.isReportable = function () { + return this.msgGlobalData && this.msgGlobalData.msgFlags && this.msgGlobalData.msgFlags & 4; +}; - var writer = new ber.Writer (); +Message.prototype.setReportable = function (flag) { + if (this.msgGlobalData && this.msgGlobalData.msgFlags) { + if (flag) { + this.msgGlobalData.msgFlags = this.msgGlobalData.msgFlags | 4; + } else { + this.msgGlobalData.msgFlags = this.msgGlobalData.msgFlags & (255 - 4); + } + } +}; - writer.startSequence (); +Message.prototype.isAuthenticationDisabled = function () { + return this.disableAuthentication; +}; - writer.writeInt (this.version); - writer.writeString (this.community); +Message.prototype.hasAuthoritativeEngineID = function () { + return this.msgSecurityParameters && this.msgSecurityParameters.msgAuthoritativeEngineID && + this.msgSecurityParameters.msgAuthoritativeEngineID != ""; +}; - this.pdu.toBuffer (writer); +Message.prototype.createReportResponseMessage = function (engine, context) { + var user = { + name: "", + level: SecurityLevel.noAuthNoPriv + }; + var responseSecurityParameters = { + msgAuthoritativeEngineID: engine.engineID, + msgAuthoritativeEngineBoots: engine.engineBoots, + msgAuthoritativeEngineTime: engine.engineTime, + msgUserName: user.name, + msgAuthenticationParameters: "", + msgPrivacyParameters: "" + }; + var reportPdu = ReportPdu.createFromVariables(this.pdu.id, [], {}); + reportPdu.contextName = context; + var responseMessage = Message.createRequestV3(user, responseSecurityParameters, reportPdu); + responseMessage.msgGlobalData.msgID = this.msgGlobalData.msgID; + return responseMessage; +}; - writer.endSequence (); +Message.prototype.createResponseForRequest = function (responsePdu) { + if (this.version == Version3) { + return this.createV3ResponseFromRequest(responsePdu); + } else { + return this.createCommunityResponseFromRequest(responsePdu); + } +}; - this.buffer = writer.buffer; +Message.prototype.createCommunityResponseFromRequest = function (responsePdu) { + return Message.createCommunity(this.version, this.community, responsePdu); +}; - return this.buffer; +Message.prototype.createV3ResponseFromRequest = function (responsePdu) { + var responseUser = { + name: this.user.name, + level: this.user.name, + authProtocol: this.user.authProtocol, + authKey: this.user.authKey, + privProtocol: this.user.privProtocol, + privKey: this.user.privKey + }; + var responseSecurityParameters = { + msgAuthoritativeEngineID: this.msgSecurityParameters.msgAuthoritativeEngineID, + msgAuthoritativeEngineBoots: this.msgSecurityParameters.msgAuthoritativeEngineBoots, + msgAuthoritativeEngineTime: this.msgSecurityParameters.msgAuthoritativeEngineTime, + msgUserName: this.msgSecurityParameters.msgUserName, + msgAuthenticationParameters: "", + msgPrivacyParameters: "" + }; + var responseGlobalData = { + msgID: this.msgGlobalData.msgID, + msgMaxSize: 65507, + msgFlags: this.msgGlobalData.msgFlags & (255 - 4), + msgSecurityModel: 3 + }; + return Message.createV3(responseUser, responseGlobalData, responseSecurityParameters, responsePdu); }; -var ResponseMessage = function (buffer) { - var reader = new ber.Reader (buffer); +Message.createCommunity = function (version, community, pdu) { + var message = new Message(); + + message.version = version; + message.community = community; + message.pdu = pdu; + + return message; +}; - reader.readSequence (); +Message.createRequestV3 = function (user, msgSecurityParameters, pdu) { + var authFlag = user.level == SecurityLevel.authNoPriv || user.level == SecurityLevel.authPriv ? 1 : 0; + var privFlag = user.level == SecurityLevel.authPriv ? 1 : 0; + var reportableFlag = (pdu.type == PduType.GetResponse || pdu.type == PduType.TrapV2) ? 0 : 1; + var msgGlobalData = { + msgID: _generateId(), // random ID + msgMaxSize: 65507, + msgFlags: reportableFlag * 4 | privFlag * 2 | authFlag * 1, + msgSecurityModel: 3 + }; + return Message.createV3(user, msgGlobalData, msgSecurityParameters, pdu); +}; - this.version = reader.readInt (); - this.community = reader.readString (); +Message.createV3 = function (user, msgGlobalData, msgSecurityParameters, pdu) { + var message = new Message(); + + message.version = 3; + message.user = user; + message.msgGlobalData = msgGlobalData; + message.msgSecurityParameters = { + msgAuthoritativeEngineID: msgSecurityParameters.msgAuthoritativeEngineID || Buffer.from(""), + msgAuthoritativeEngineBoots: msgSecurityParameters.msgAuthoritativeEngineBoots || 0, + msgAuthoritativeEngineTime: msgSecurityParameters.msgAuthoritativeEngineTime || 0, + msgUserName: user.name || "", + msgAuthenticationParameters: "", + msgPrivacyParameters: "" + }; + message.pdu = pdu; + + return message; +}; - var type = reader.peek (); +Message.createDiscoveryV3 = function (pdu) { + var msgSecurityParameters = { + msgAuthoritativeEngineID: Buffer.from(""), + msgAuthoritativeEngineBoots: 0, + msgAuthoritativeEngineTime: 0 + }; + var emptyUser = { + name: "", + level: SecurityLevel.noAuthNoPriv + }; + return Message.createRequestV3(emptyUser, msgSecurityParameters, pdu); +} - if (type == PduType.GetResponse) { - this.pdu = new GetResponsePdu (reader); - } else { - throw new ResponseInvalidError ("Unknown PDU type '" + type - + "' in response"); - } +Message.createFromBuffer = function (buffer, user) { + var reader = new ber.Reader(buffer); + var message = new Message(); + + reader.readSequence(); + + message.version = reader.readInt(); + + if (message.version != 3) { + message.community = reader.readString(); + message.pdu = readPdu(reader, false); + } else { + // HeaderData + message.msgGlobalData = {}; + reader.readSequence(); + message.msgGlobalData.msgID = reader.readInt(); + message.msgGlobalData.msgMaxSize = reader.readInt(); + message.msgGlobalData.msgFlags = reader.readString(ber.OctetString, true)[0]; + message.msgGlobalData.msgSecurityModel = reader.readInt(); + + // msgSecurityParameters + message.msgSecurityParameters = {}; + var msgSecurityParametersReader = new ber.Reader(reader.readString(ber.OctetString, true)); + msgSecurityParametersReader.readSequence(); + message.msgSecurityParameters.msgAuthoritativeEngineID = msgSecurityParametersReader.readString(ber.OctetString, true); + message.msgSecurityParameters.msgAuthoritativeEngineBoots = msgSecurityParametersReader.readInt(); + message.msgSecurityParameters.msgAuthoritativeEngineTime = msgSecurityParametersReader.readInt(); + message.msgSecurityParameters.msgUserName = msgSecurityParametersReader.readString(); + message.msgSecurityParameters.msgAuthenticationParameters = Buffer.from(msgSecurityParametersReader.readString(ber.OctetString, true)); + message.msgSecurityParameters.msgPrivacyParameters = Buffer.from(msgSecurityParametersReader.readString(ber.OctetString, true)); + scopedPdu = true; + + if (message.hasPrivacy()) { + message.encryptedPdu = reader.readString(ber.OctetString, true); + message.pdu = null; + } else { + message.pdu = readPdu(reader, true); + } + } + + message.buffer = buffer; + + return message; }; + +var Req = function (session, message, feedCb, responseCb, options) { + + this.message = message; + this.responseCb = responseCb; + this.retries = session.retries; + this.timeout = session.timeout; + this.onResponse = session.onSimpleGetResponse; + this.feedCb = feedCb; + this.port = (options && options.port) ? options.port : session.port; + this.context = session.context; +}; + +Req.prototype.getId = function () { + return this.message.getReqId(); +}; + + /***************************************************************************** ** Session class definition **/ -var Session = function (target, community, options) { - this.target = target || "127.0.0.1"; - this.community = community || "public"; - - this.version = (options && options.version) - ? options.version - : Version1; - - this.transport = (options && options.transport) - ? options.transport - : "udp4"; - this.port = (options && options.port ) - ? options.port - : 161; - this.trapPort = (options && options.trapPort ) - ? options.trapPort - : 162; - - this.retries = (options && (options.retries || options.retries == 0)) - ? options.retries - : 1; - this.timeout = (options && options.timeout) - ? options.timeout - : 5000; - - this.sourceAddress = (options && options.sourceAddress ) - ? options.sourceAddress - : undefined; - this.sourcePort = (options && options.sourcePort ) - ? parseInt(options.sourcePort) - : undefined; - - this.idBitsSize = (options && options.idBitsSize) - ? parseInt(options.idBitsSize) - : 32; - - this.reqs = {}; - this.reqCount = 0; - - this.dgram = dgram.createSocket (this.transport); - this.dgram.unref(); - - var me = this; - this.dgram.on ("message", me.onMsg.bind (me)); - this.dgram.on ("close", me.onClose.bind (me)); - this.dgram.on ("error", me.onError.bind (me)); - - if (this.sourceAddress || this.sourcePort) - this.dgram.bind (this.sourcePort, this.sourceAddress); -}; - -util.inherits (Session, events.EventEmitter); +var Session = function (target, authenticator, options) { + this.target = target || "127.0.0.1"; + + this.version = (options && options.version) + ? options.version + : Version1; + + if (this.version == Version3) { + this.user = authenticator; + } else { + this.community = authenticator || "public"; + } + + this.transport = (options && options.transport) + ? options.transport + : "udp4"; + this.port = (options && options.port) + ? options.port + : 161; + this.trapPort = (options && options.trapPort) + ? options.trapPort + : 162; + + this.retries = (options && (options.retries || options.retries == 0)) + ? options.retries + : 1; + this.timeout = (options && options.timeout) + ? options.timeout + : 5000; + + this.sourceAddress = (options && options.sourceAddress) + ? options.sourceAddress + : undefined; + this.sourcePort = (options && options.sourcePort) + ? parseInt(options.sourcePort) + : undefined; + + this.idBitsSize = (options && options.idBitsSize) + ? parseInt(options.idBitsSize) + : 32; + + this.context = (options && options.context) ? options.context : ""; + + DEBUG = options.debug; + + this.reqs = {}; + this.reqCount = 0; + + this.dgram = dgram.createSocket(this.transport); + this.dgram.unref(); + + var me = this; + this.dgram.on("message", me.onMsg.bind(me)); + this.dgram.on("close", me.onClose.bind(me)); + this.dgram.on("error", me.onError.bind(me)); + + if (this.sourceAddress || this.sourcePort) + this.dgram.bind(this.sourcePort, this.sourceAddress); +}; + +util.inherits(Session, events.EventEmitter); Session.prototype.close = function () { - this.dgram.close (); - return this; + this.dgram.close(); + return this; }; Session.prototype.cancelRequests = function (error) { - var id; - for (id in this.reqs) { - var req = this.reqs[id]; - this.unregisterRequest (req.id); - req.responseCb (error); - } -}; - -function _generateId (bitSize) { - if (bitSize === 16) { - return Math.floor(Math.random() * 10000) % 65535; - } - return Math.floor(Math.random() * 100000000) % 4294967295; + var id; + for (id in this.reqs) { + var req = this.reqs[id]; + this.unregisterRequest(req.getId()); + req.responseCb(error); + } +}; + +function _generateId(bitSize) { + if (bitSize === 16) { + return Math.floor(Math.random() * 10000) % 65535; + } + return Math.floor(Math.random() * 100000000) % 4294967295; } Session.prototype.get = function (oids, responseCb) { - function feedCb (req, message) { - var pdu = message.pdu; - var varbinds = []; - - if (req.message.pdu.varbinds.length != pdu.varbinds.length) { - req.responseCb (new ResponseInvalidError ("Requested OIDs do not " - + "match response OIDs")); - } else { - for (var i = 0; i < req.message.pdu.varbinds.length; i++) { - if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[i].oid - + "' in request at positiion '" + i + "' does not " - + "match OID '" + pdu.varbinds[i].oid + "' in response " - + "at position '" + i + "'")); - return; - } else { - varbinds.push (pdu.varbinds[i]); - } - } - - req.responseCb (null, varbinds); - } - } - - var pduVarbinds = []; - - for (var i = 0; i < oids.length; i++) { - var varbind = { - oid: oids[i] - }; - pduVarbinds.push (varbind); - } - - this.simpleGet (GetRequestPdu, feedCb, pduVarbinds, responseCb); - - return this; + function feedCb(req, message) { + var pdu = message.pdu; + var varbinds = []; + + if (req.message.pdu.varbinds.length != pdu.varbinds.length) { + req.responseCb(new ResponseInvalidError("Requested OIDs do not " + + "match response OIDs")); + } else { + for (var i = 0; i < req.message.pdu.varbinds.length; i++) { + if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[i].oid + + "' in request at positiion '" + i + "' does not " + + "match OID '" + pdu.varbinds[i].oid + "' in response " + + "at position '" + i + "'")); + return; + } else { + varbinds.push(pdu.varbinds[i]); + } + } + + req.responseCb(null, varbinds); + } + } + + var pduVarbinds = []; + + for (var i = 0; i < oids.length; i++) { + var varbind = { + oid: oids[i] + }; + pduVarbinds.push(varbind); + } + + this.simpleGet(GetRequestPdu, feedCb, pduVarbinds, responseCb); + + return this; }; Session.prototype.getBulk = function () { - var oids, nonRepeaters, maxRepetitions, responseCb; - - if (arguments.length >= 4) { - oids = arguments[0]; - nonRepeaters = arguments[1]; - maxRepetitions = arguments[2]; - responseCb = arguments[3]; - } else if (arguments.length >= 3) { - oids = arguments[0]; - nonRepeaters = arguments[1]; - maxRepetitions = 10; - responseCb = arguments[2]; - } else { - oids = arguments[0]; - nonRepeaters = 0; - maxRepetitions = 10; - responseCb = arguments[1]; - } - - function feedCb (req, message) { - var pdu = message.pdu; - var varbinds = []; - var i = 0; - - // first walk through and grab non-repeaters - if (pdu.varbinds.length < nonRepeaters) { - req.responseCb (new ResponseInvalidError ("Varbind count in " - + "response '" + pdu.varbinds.length + "' is less than " - + "non-repeaters '" + nonRepeaters + "' in request")); - } else { - for ( ; i < nonRepeaters; i++) { - if (isVarbindError (pdu.varbinds[i])) { - varbinds.push (pdu.varbinds[i]); - } else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid, - pdu.varbinds[i].oid)) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[i].oid + "' in request at " - + "positiion '" + i + "' does not precede " - + "OID '" + pdu.varbinds[i].oid + "' in response " - + "at position '" + i + "'")); - return; - } else { - varbinds.push (pdu.varbinds[i]); - } - } - } - - var repeaters = req.message.pdu.varbinds.length - nonRepeaters; - - // secondly walk through and grab repeaters - if (pdu.varbinds.length % (repeaters)) { - req.responseCb (new ResponseInvalidError ("Varbind count in " - + "response '" + pdu.varbinds.length + "' is not a " - + "multiple of repeaters '" + repeaters - + "' plus non-repeaters '" + nonRepeaters + "' in request")); - } else { - while (i < pdu.varbinds.length) { - for (var j = 0; j < repeaters; j++, i++) { - var reqIndex = nonRepeaters + j; - var respIndex = i; - - if (isVarbindError (pdu.varbinds[respIndex])) { - if (! varbinds[reqIndex]) - varbinds[reqIndex] = []; - varbinds[reqIndex].push (pdu.varbinds[respIndex]); - } else if (! oidFollowsOid ( - req.message.pdu.varbinds[reqIndex].oid, - pdu.varbinds[respIndex].oid)) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[reqIndex].oid - + "' in request at positiion '" + (reqIndex) - + "' does not precede OID '" - + pdu.varbinds[respIndex].oid - + "' in response at position '" + (respIndex) + "'")); - return; - } else { - if (! varbinds[reqIndex]) - varbinds[reqIndex] = []; - varbinds[reqIndex].push (pdu.varbinds[respIndex]); - } - } - } - } - - req.responseCb (null, varbinds); - } - - var pduVarbinds = []; - - for (var i = 0; i < oids.length; i++) { - var varbind = { - oid: oids[i] - }; - pduVarbinds.push (varbind); - } - - var options = { - nonRepeaters: nonRepeaters, - maxRepetitions: maxRepetitions - }; - - this.simpleGet (GetBulkRequestPdu, feedCb, pduVarbinds, responseCb, - options); - - return this; + var oids, nonRepeaters, maxRepetitions, responseCb; + + if (arguments.length >= 4) { + oids = arguments[0]; + nonRepeaters = arguments[1]; + maxRepetitions = arguments[2]; + responseCb = arguments[3]; + } else if (arguments.length >= 3) { + oids = arguments[0]; + nonRepeaters = arguments[1]; + maxRepetitions = 10; + responseCb = arguments[2]; + } else { + oids = arguments[0]; + nonRepeaters = 0; + maxRepetitions = 10; + responseCb = arguments[1]; + } + + function feedCb(req, message) { + var pdu = message.pdu; + var varbinds = []; + var i = 0; + + // first walk through and grab non-repeaters + if (pdu.varbinds.length < nonRepeaters) { + req.responseCb(new ResponseInvalidError("Varbind count in " + + "response '" + pdu.varbinds.length + "' is less than " + + "non-repeaters '" + nonRepeaters + "' in request")); + } else { + for (; i < nonRepeaters; i++) { + if (isVarbindError(pdu.varbinds[i])) { + varbinds.push(pdu.varbinds[i]); + } else if (!oidFollowsOid(req.message.pdu.varbinds[i].oid, + pdu.varbinds[i].oid)) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[i].oid + "' in request at " + + "positiion '" + i + "' does not precede " + + "OID '" + pdu.varbinds[i].oid + "' in response " + + "at position '" + i + "'")); + return; + } else { + varbinds.push(pdu.varbinds[i]); + } + } + } + + var repeaters = req.message.pdu.varbinds.length - nonRepeaters; + + // secondly walk through and grab repeaters + if (pdu.varbinds.length % (repeaters)) { + req.responseCb(new ResponseInvalidError("Varbind count in " + + "response '" + pdu.varbinds.length + "' is not a " + + "multiple of repeaters '" + repeaters + + "' plus non-repeaters '" + nonRepeaters + "' in request")); + } else { + while (i < pdu.varbinds.length) { + for (var j = 0; j < repeaters; j++, i++) { + var reqIndex = nonRepeaters + j; + var respIndex = i; + + if (isVarbindError(pdu.varbinds[respIndex])) { + if (!varbinds[reqIndex]) + varbinds[reqIndex] = []; + varbinds[reqIndex].push(pdu.varbinds[respIndex]); + } else if (!oidFollowsOid( + req.message.pdu.varbinds[reqIndex].oid, + pdu.varbinds[respIndex].oid)) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[reqIndex].oid + + "' in request at positiion '" + (reqIndex) + + "' does not precede OID '" + + pdu.varbinds[respIndex].oid + + "' in response at position '" + (respIndex) + "'")); + return; + } else { + if (!varbinds[reqIndex]) + varbinds[reqIndex] = []; + varbinds[reqIndex].push(pdu.varbinds[respIndex]); + } + } + } + } + + req.responseCb(null, varbinds); + } + + var pduVarbinds = []; + + for (var i = 0; i < oids.length; i++) { + var varbind = { + oid: oids[i] + }; + pduVarbinds.push(varbind); + } + + var options = { + nonRepeaters: nonRepeaters, + maxRepetitions: maxRepetitions + }; + + this.simpleGet(GetBulkRequestPdu, feedCb, pduVarbinds, responseCb, + options); + + return this; }; Session.prototype.getNext = function (oids, responseCb) { - function feedCb (req, message) { - var pdu = message.pdu; - var varbinds = []; - - if (req.message.pdu.varbinds.length != pdu.varbinds.length) { - req.responseCb (new ResponseInvalidError ("Requested OIDs do not " - + "match response OIDs")); - } else { - for (var i = 0; i < req.message.pdu.varbinds.length; i++) { - if (isVarbindError (pdu.varbinds[i])) { - varbinds.push (pdu.varbinds[i]); - } else if (! oidFollowsOid (req.message.pdu.varbinds[i].oid, - pdu.varbinds[i].oid)) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[i].oid + "' in request at " - + "positiion '" + i + "' does not precede " - + "OID '" + pdu.varbinds[i].oid + "' in response " - + "at position '" + i + "'")); - return; - } else { - varbinds.push (pdu.varbinds[i]); - } - } - - req.responseCb (null, varbinds); - } - } - - var pduVarbinds = []; - - for (var i = 0; i < oids.length; i++) { - var varbind = { - oid: oids[i] - }; - pduVarbinds.push (varbind); - } - - this.simpleGet (GetNextRequestPdu, feedCb, pduVarbinds, responseCb); - - return this; + function feedCb(req, message) { + var pdu = message.pdu; + var varbinds = []; + + if (req.message.pdu.varbinds.length != pdu.varbinds.length) { + req.responseCb(new ResponseInvalidError("Requested OIDs do not " + + "match response OIDs")); + } else { + for (var i = 0; i < req.message.pdu.varbinds.length; i++) { + if (isVarbindError(pdu.varbinds[i])) { + varbinds.push(pdu.varbinds[i]); + } else if (!oidFollowsOid(req.message.pdu.varbinds[i].oid, + pdu.varbinds[i].oid)) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[i].oid + "' in request at " + + "positiion '" + i + "' does not precede " + + "OID '" + pdu.varbinds[i].oid + "' in response " + + "at position '" + i + "'")); + return; + } else { + varbinds.push(pdu.varbinds[i]); + } + } + + req.responseCb(null, varbinds); + } + } + + var pduVarbinds = []; + + for (var i = 0; i < oids.length; i++) { + var varbind = { + oid: oids[i] + }; + pduVarbinds.push(varbind); + } + + this.simpleGet(GetNextRequestPdu, feedCb, pduVarbinds, responseCb); + + return this; }; Session.prototype.inform = function () { - var typeOrOid = arguments[0]; - var varbinds, options = {}, responseCb; - - /** - ** Support the following signatures: - ** - ** typeOrOid, varbinds, options, callback - ** typeOrOid, varbinds, callback - ** typeOrOid, options, callback - ** typeOrOid, callback - **/ - if (arguments.length >= 4) { - varbinds = arguments[1]; - options = arguments[2]; - responseCb = arguments[3]; - } else if (arguments.length >= 3) { - if (arguments[1].constructor != Array) { - varbinds = []; - options = arguments[1]; - responseCb = arguments[2]; - } else { - varbinds = arguments[1]; - responseCb = arguments[2]; - } - } else { - varbinds = []; - responseCb = arguments[1]; - } - - function feedCb (req, message) { - var pdu = message.pdu; - var varbinds = []; - - if (req.message.pdu.varbinds.length != pdu.varbinds.length) { - req.responseCb (new ResponseInvalidError ("Inform OIDs do not " - + "match response OIDs")); - } else { - for (var i = 0; i < req.message.pdu.varbinds.length; i++) { - if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[i].oid - + "' in inform at positiion '" + i + "' does not " - + "match OID '" + pdu.varbinds[i].oid + "' in response " - + "at position '" + i + "'")); - return; - } else { - varbinds.push (pdu.varbinds[i]); - } - } - - req.responseCb (null, varbinds); - } - } - - if (typeof typeOrOid != "string") - typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1); - - var pduVarbinds = [ - { - oid: "1.3.6.1.2.1.1.3.0", - type: ObjectType.TimeTicks, - value: options.upTime || Math.floor (process.uptime () * 100) - }, - { - oid: "1.3.6.1.6.3.1.1.4.1.0", - type: ObjectType.OID, - value: typeOrOid - } - ]; - - for (var i = 0; i < varbinds.length; i++) { - var varbind = { - oid: varbinds[i].oid, - type: varbinds[i].type, - value: varbinds[i].value - }; - pduVarbinds.push (varbind); - } - - options.port = this.trapPort; - - this.simpleGet (InformRequestPdu, feedCb, pduVarbinds, responseCb, options); - - return this; + var typeOrOid = arguments[0]; + var varbinds, options = {}, responseCb; + + /** + ** Support the following signatures: + ** + ** typeOrOid, varbinds, options, callback + ** typeOrOid, varbinds, callback + ** typeOrOid, options, callback + ** typeOrOid, callback + **/ + if (arguments.length >= 4) { + varbinds = arguments[1]; + options = arguments[2]; + responseCb = arguments[3]; + } else if (arguments.length >= 3) { + if (arguments[1].constructor != Array) { + varbinds = []; + options = arguments[1]; + responseCb = arguments[2]; + } else { + varbinds = arguments[1]; + responseCb = arguments[2]; + } + } else { + varbinds = []; + responseCb = arguments[1]; + } + + if (this.version == Version1) { + responseCb(new RequestInvalidError("Inform not allowed for SNMPv1")); + return; + } + + function feedCb(req, message) { + var pdu = message.pdu; + var varbinds = []; + + if (req.message.pdu.varbinds.length != pdu.varbinds.length) { + req.responseCb(new ResponseInvalidError("Inform OIDs do not " + + "match response OIDs")); + } else { + for (var i = 0; i < req.message.pdu.varbinds.length; i++) { + if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[i].oid + + "' in inform at positiion '" + i + "' does not " + + "match OID '" + pdu.varbinds[i].oid + "' in response " + + "at position '" + i + "'")); + return; + } else { + varbinds.push(pdu.varbinds[i]); + } + } + + req.responseCb(null, varbinds); + } + } + + if (typeof typeOrOid != "string") + typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1); + + var pduVarbinds = [ + { + oid: "1.3.6.1.2.1.1.3.0", + type: ObjectType.TimeTicks, + value: options.upTime || Math.floor(process.uptime() * 100) + }, + { + oid: "1.3.6.1.6.3.1.1.4.1.0", + type: ObjectType.OID, + value: typeOrOid + } + ]; + + for (var i = 0; i < varbinds.length; i++) { + var varbind = { + oid: varbinds[i].oid, + type: varbinds[i].type, + value: varbinds[i].value + }; + pduVarbinds.push(varbind); + } + + options.port = this.trapPort; + + this.simpleGet(InformRequestPdu, feedCb, pduVarbinds, responseCb, options); + + return this; }; Session.prototype.onClose = function () { - this.cancelRequests (new Error ("Socket forcibly closed")); - this.emit ("close"); + this.cancelRequests(new Error("Socket forcibly closed")); + this.emit("close"); }; Session.prototype.onError = function (error) { - this.emit (error); -}; - -Session.prototype.onMsg = function (buffer, remote) { - try { - var message = new ResponseMessage (buffer); - - var req = this.unregisterRequest (message.pdu.id); - if (! req) - return; - - try { - if (message.version != req.message.version) { - req.responseCb (new ResponseInvalidError ("Version in request '" - + req.message.version + "' does not match version in " - + "response '" + message.version)); - } else if (message.community != req.message.community) { - req.responseCb (new ResponseInvalidError ("Community '" - + req.message.community + "' in request does not match " - + "community '" + message.community + "' in response")); - } else if (message.pdu.type == PduType.GetResponse) { - req.onResponse (req, message); - } else { - req.responseCb (new ResponseInvalidError ("Unknown PDU type '" - + message.pdu.type + "' in response")); - } - } catch (error) { - req.responseCb (error); - } - } catch (error) { - this.emit("error", error); - } + this.emit(error); +}; + +Session.prototype.onMsg = function (buffer) { + try { + var message = Message.createFromBuffer(buffer); + + var req = this.unregisterRequest(message.getReqId()); + if (!req) + return; + + if (!message.processIncomingSecurity(this.user, req.responseCb)) + return; + + try { + if (message.version != req.message.version) { + req.responseCb(new ResponseInvalidError("Version in request '" + + req.message.version + "' does not match version in " + + "response '" + message.version + "'")); + } else if (message.community != req.message.community) { + req.responseCb(new ResponseInvalidError("Community '" + + req.message.community + "' in request does not match " + + "community '" + message.community + "' in response")); + } else if (message.pdu.type == PduType.GetResponse) { + req.onResponse(req, message); + } else if (message.pdu.type == PduType.Report) { + if (!req.originalPdu) { + req.responseCb(new ResponseInvalidError("Unexpected Report PDU")); + return; + } + this.msgSecurityParameters = { + msgAuthoritativeEngineID: message.msgSecurityParameters.msgAuthoritativeEngineID, + msgAuthoritativeEngineBoots: message.msgSecurityParameters.msgAuthoritativeEngineBoots, + msgAuthoritativeEngineTime: message.msgSecurityParameters.msgAuthoritativeEngineTime + }; + req.originalPdu.contextName = this.context; + this.sendV3Req(req.originalPdu, req.feedCb, req.responseCb, req.options, req.port); + } else { + req.responseCb(new ResponseInvalidError("Unknown PDU type '" + + message.pdu.type + "' in response")); + } + } catch (error) { + req.responseCb(error); + } + } catch (error) { + this.emit("error", error); + } }; Session.prototype.onSimpleGetResponse = function (req, message) { - var pdu = message.pdu; - - if (pdu.errorStatus > 0) { - var statusString = ErrorStatus[pdu.errorStatus] - || ErrorStatus.GeneralError; - var statusCode = ErrorStatus[statusString] - || ErrorStatus[ErrorStatus.GeneralError]; - - if (pdu.errorIndex <= 0 || pdu.errorIndex > pdu.varbinds.length) { - req.responseCb (new RequestFailedError (statusString, statusCode)); - } else { - var oid = pdu.varbinds[pdu.errorIndex - 1].oid; - var error = new RequestFailedError (statusString + ": " + oid, - statusCode); - req.responseCb (error); - } - } else { - req.feedCb (req, message); - } + var pdu = message.pdu; + + if (pdu.errorStatus > 0) { + var statusString = ErrorStatus[pdu.errorStatus] + || ErrorStatus.GeneralError; + var statusCode = ErrorStatus[statusString] + || ErrorStatus[ErrorStatus.GeneralError]; + + if (pdu.errorIndex <= 0 || pdu.errorIndex > pdu.varbinds.length) { + req.responseCb(new RequestFailedError(statusString, statusCode)); + } else { + var oid = pdu.varbinds[pdu.errorIndex - 1].oid; + var error = new RequestFailedError(statusString + ": " + oid, + statusCode); + req.responseCb(error); + } + } else { + req.feedCb(req, message); + } }; Session.prototype.registerRequest = function (req) { - if (! this.reqs[req.id]) { - this.reqs[req.id] = req; - if (this.reqCount <= 0) - this.dgram.ref(); - this.reqCount++; - } - var me = this; - req.timer = setTimeout (function () { - if (req.retries-- > 0) { - me.send (req); - } else { - me.unregisterRequest (req.id); - req.responseCb (new RequestTimedOutError ( - "Request timed out")); - } - }, req.timeout); + if (!this.reqs[req.getId()]) { + this.reqs[req.getId()] = req; + if (this.reqCount <= 0) + this.dgram.ref(); + this.reqCount++; + } + var me = this; + req.timer = setTimeout(function () { + if (req.retries-- > 0) { + me.send(req); + } else { + me.unregisterRequest(req.getId()); + req.responseCb(new RequestTimedOutError( + "Request timed out")); + } + }, req.timeout); }; Session.prototype.send = function (req, noWait) { - try { - var me = this; - - var buffer = req.message.toBuffer (); - - this.dgram.send (buffer, 0, buffer.length, req.port, this.target, - function (error, bytes) { - if (error) { - req.responseCb (error); - } else { - if (noWait) { - req.responseCb (null); - } else { - me.registerRequest (req); - } - } - }); - } catch (error) { - req.responseCb (error); - } - - return this; + try { + var me = this; + + var buffer = req.message.toBuffer(); + + this.dgram.send(buffer, 0, buffer.length, req.port, this.target, + function (error, bytes) { + if (error) { + req.responseCb(error); + } else { + if (noWait) { + req.responseCb(null); + } else { + me.registerRequest(req); + } + } + }); + } catch (error) { + req.responseCb(error); + } + + return this; }; Session.prototype.set = function (varbinds, responseCb) { - function feedCb (req, message) { - var pdu = message.pdu; - var varbinds = []; - - if (req.message.pdu.varbinds.length != pdu.varbinds.length) { - req.responseCb (new ResponseInvalidError ("Requested OIDs do not " - + "match response OIDs")); - } else { - for (var i = 0; i < req.message.pdu.varbinds.length; i++) { - if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { - req.responseCb (new ResponseInvalidError ("OID '" - + req.message.pdu.varbinds[i].oid - + "' in request at positiion '" + i + "' does not " - + "match OID '" + pdu.varbinds[i].oid + "' in response " - + "at position '" + i + "'")); - return; - } else { - varbinds.push (pdu.varbinds[i]); - } - } - - req.responseCb (null, varbinds); - } - } - - var pduVarbinds = []; - - for (var i = 0; i < varbinds.length; i++) { - var varbind = { - oid: varbinds[i].oid, - type: varbinds[i].type, - value: varbinds[i].value - }; - pduVarbinds.push (varbind); - } - - this.simpleGet (SetRequestPdu, feedCb, pduVarbinds, responseCb); - - return this; + function feedCb(req, message) { + var pdu = message.pdu; + var varbinds = []; + + if (req.message.pdu.varbinds.length != pdu.varbinds.length) { + req.responseCb(new ResponseInvalidError("Requested OIDs do not " + + "match response OIDs")); + } else { + for (var i = 0; i < req.message.pdu.varbinds.length; i++) { + if (req.message.pdu.varbinds[i].oid != pdu.varbinds[i].oid) { + req.responseCb(new ResponseInvalidError("OID '" + + req.message.pdu.varbinds[i].oid + + "' in request at positiion '" + i + "' does not " + + "match OID '" + pdu.varbinds[i].oid + "' in response " + + "at position '" + i + "'")); + return; + } else { + varbinds.push(pdu.varbinds[i]); + } + } + + req.responseCb(null, varbinds); + } + } + + var pduVarbinds = []; + + for (var i = 0; i < varbinds.length; i++) { + var varbind = { + oid: varbinds[i].oid, + type: varbinds[i].type, + value: varbinds[i].value + }; + pduVarbinds.push(varbind); + } + + this.simpleGet(SetRequestPdu, feedCb, pduVarbinds, responseCb); + + return this; }; Session.prototype.simpleGet = function (pduClass, feedCb, varbinds, - responseCb, options) { - var req = {}; - - try { - var id = _generateId (this.idBitsSize); - var pdu = new pduClass (id, varbinds, options); - var message = new RequestMessage (this.version, this.community, pdu); - - req = { - id: id, - message: message, - responseCb: responseCb, - retries: this.retries, - timeout: this.timeout, - onResponse: this.onSimpleGetResponse, - feedCb: feedCb, - port: (options && options.port) ? options.port : this.port - }; - - this.send (req); - } catch (error) { - if (req.responseCb) - req.responseCb (error); - } -}; - -function subtreeCb (req, varbinds) { - var done = 0; - - for (var i = varbinds.length; i > 0; i--) { - if (! oidInSubtree (req.baseOid, varbinds[i - 1].oid)) { - done = 1; - varbinds.pop (); - } - } - - if (varbinds.length > 0) - req.feedCb (varbinds); - - if (done) - return true; + responseCb, options) { + try { + var id = _generateId(this.idBitsSize); + var pdu = SimplePdu.createFromVariables(pduClass, id, varbinds, options); + var message; + var req; + + if (this.version == Version3) { + if (this.msgSecurityParameters) { + this.sendV3Req(pdu, feedCb, responseCb, options, this.port); + } else { + // SNMPv3 discovery + var discoveryPdu = createDiscoveryPdu(this.context); + var discoveryMessage = Message.createDiscoveryV3(discoveryPdu); + var discoveryReq = new Req(this, discoveryMessage, feedCb, responseCb, options); + discoveryReq.originalPdu = pdu; + this.send(discoveryReq); + } + } else { + message = Message.createCommunity(this.version, this.community, pdu); + req = new Req(this, message, feedCb, responseCb, options); + this.send(req); + } + } catch (error) { + if (responseCb) + responseCb(error); + } } -Session.prototype.subtree = function () { - var me = this; - var oid = arguments[0]; - var maxRepetitions, feedCb, doneCb; - - if (arguments.length < 4) { - maxRepetitions = 20; - feedCb = arguments[1]; - doneCb = arguments[2]; - } else { - maxRepetitions = arguments[1]; - feedCb = arguments[2]; - doneCb = arguments[3]; - } - - var req = { - feedCb: feedCb, - doneCb: doneCb, - maxRepetitions: maxRepetitions, - baseOid: oid - }; - - this.walk (oid, maxRepetitions, subtreeCb.bind (me, req), doneCb); - - return this; -}; - -function tableColumnsResponseCb (req, error) { - if (error) { - req.responseCb (error); - } else if (req.error) { - req.responseCb (req.error); - } else { - if (req.columns.length > 0) { - var column = req.columns.pop (); - var me = this; - this.subtree (req.rowOid + column, req.maxRepetitions, - tableColumnsFeedCb.bind (me, req), - tableColumnsResponseCb.bind (me, req)); - } else { - req.responseCb (null, req.table); - } - } +function subtreeCb(req, varbinds) { + var done = 0; + + for (var i = varbinds.length; i > 0; i--) { + if (!oidInSubtree(req.baseOid, varbinds[i - 1].oid)) { + done = 1; + varbinds.pop(); + } + } + + if (varbinds.length > 0) + req.feedCb(varbinds); + + if (done) + return true; +} + +Session.prototype.subtree = function () { + var me = this; + var oid = arguments[0]; + var maxRepetitions, feedCb, doneCb; + + if (arguments.length < 4) { + maxRepetitions = 20; + feedCb = arguments[1]; + doneCb = arguments[2]; + } else { + maxRepetitions = arguments[1]; + feedCb = arguments[2]; + doneCb = arguments[3]; + } + + var req = { + feedCb: feedCb, + doneCb: doneCb, + maxRepetitions: maxRepetitions, + baseOid: oid + }; + + this.walk(oid, maxRepetitions, subtreeCb.bind(me, req), doneCb); + + return this; +}; + +function tableColumnsResponseCb(req, error) { + if (error) { + req.responseCb(error); + } else if (req.error) { + req.responseCb(req.error); + } else { + if (req.columns.length > 0) { + var column = req.columns.pop(); + var me = this; + this.subtree(req.rowOid + column, req.maxRepetitions, + tableColumnsFeedCb.bind(me, req), + tableColumnsResponseCb.bind(me, req)); + } else { + req.responseCb(null, req.table); + } + } } -function tableColumnsFeedCb (req, varbinds) { - for (var i = 0; i < varbinds.length; i++) { - if (isVarbindError (varbinds[i])) { - req.error = new RequestFailedError (varbindError (varbind[i])); - return true; - } - - var oid = varbinds[i].oid.replace (req.rowOid, ""); - if (oid && oid != varbinds[i].oid) { - var match = oid.match (/^(\d+)\.(.+)$/); - if (match && match[1] > 0) { - if (! req.table[match[2]]) - req.table[match[2]] = {}; - req.table[match[2]][match[1]] = varbinds[i].value; - } - } - } +function tableColumnsFeedCb(req, varbinds) { + for (var i = 0; i < varbinds.length; i++) { + if (isVarbindError(varbinds[i])) { + req.error = new RequestFailedError(varbindError(varbind[i])); + return true; + } + + var oid = varbinds[i].oid.replace(req.rowOid, ""); + if (oid && oid != varbinds[i].oid) { + var match = oid.match(/^(\d+)\.(.+)$/); + if (match && match[1] > 0) { + if (!req.table[match[2]]) + req.table[match[2]] = {}; + req.table[match[2]][match[1]] = varbinds[i].value; + } + } + } } Session.prototype.tableColumns = function () { - var me = this; - - var oid = arguments[0]; - var columns = arguments[1]; - var maxRepetitions, responseCb; - - if (arguments.length < 4) { - responseCb = arguments[2]; - maxRepetitions = 20; - } else { - maxRepetitions = arguments[2]; - responseCb = arguments[3]; - } - - var req = { - responseCb: responseCb, - maxRepetitions: maxRepetitions, - baseOid: oid, - rowOid: oid + ".1.", - columns: columns.slice(0), - table: {} - }; - - if (req.columns.length > 0) { - var column = req.columns.pop (); - this.subtree (req.rowOid + column, maxRepetitions, - tableColumnsFeedCb.bind (me, req), - tableColumnsResponseCb.bind (me, req)); - } - - return this; -}; - -function tableResponseCb (req, error) { - if (error) - req.responseCb (error); - else if (req.error) - req.responseCb (req.error); - else - req.responseCb (null, req.table); + var me = this; + + var oid = arguments[0]; + var columns = arguments[1]; + var maxRepetitions, responseCb; + + if (arguments.length < 4) { + responseCb = arguments[2]; + maxRepetitions = 20; + } else { + maxRepetitions = arguments[2]; + responseCb = arguments[3]; + } + + var req = { + responseCb: responseCb, + maxRepetitions: maxRepetitions, + baseOid: oid, + rowOid: oid + ".1.", + columns: columns.slice(0), + table: {} + }; + + if (req.columns.length > 0) { + var column = req.columns.pop(); + this.subtree(req.rowOid + column, maxRepetitions, + tableColumnsFeedCb.bind(me, req), + tableColumnsResponseCb.bind(me, req)); + } + + return this; +}; + +function tableResponseCb(req, error) { + if (error) + req.responseCb(error); + else if (req.error) + req.responseCb(req.error); + else + req.responseCb(null, req.table); } -function tableFeedCb (req, varbinds) { - for (var i = 0; i < varbinds.length; i++) { - if (isVarbindError (varbinds[i])) { - req.error = new RequestFailedError (varbindError (varbind[i])); - return true; - } - - var oid = varbinds[i].oid.replace (req.rowOid, ""); - if (oid && oid != varbinds[i].oid) { - var match = oid.match (/^(\d+)\.(.+)$/); - if (match && match[1] > 0) { - if (! req.table[match[2]]) - req.table[match[2]] = {}; - req.table[match[2]][match[1]] = varbinds[i].value; - } - } - } +function tableFeedCb(req, varbinds) { + for (var i = 0; i < varbinds.length; i++) { + if (isVarbindError(varbinds[i])) { + req.error = new RequestFailedError(varbindError(varbind[i])); + return true; + } + + var oid = varbinds[i].oid.replace(req.rowOid, ""); + if (oid && oid != varbinds[i].oid) { + var match = oid.match(/^(\d+)\.(.+)$/); + if (match && match[1] > 0) { + if (!req.table[match[2]]) + req.table[match[2]] = {}; + req.table[match[2]][match[1]] = varbinds[i].value; + } + } + } } Session.prototype.table = function () { - var me = this; + var me = this; + + var oid = arguments[0]; + var maxRepetitions, responseCb; + + if (arguments.length < 3) { + responseCb = arguments[1]; + maxRepetitions = 20; + } else { + maxRepetitions = arguments[1]; + responseCb = arguments[2]; + } + + var req = { + responseCb: responseCb, + maxRepetitions: maxRepetitions, + baseOid: oid, + rowOid: oid + ".1.", + table: {} + }; + + this.subtree(oid, maxRepetitions, tableFeedCb.bind(me, req), + tableResponseCb.bind(me, req)); + + return this; +}; - var oid = arguments[0]; - var maxRepetitions, responseCb; +Session.prototype.trap = function () { + var req = {}; + + try { + var typeOrOid = arguments[0]; + var varbinds, options = {}, responseCb; + var message; + + /** + ** Support the following signatures: + ** + ** typeOrOid, varbinds, options, callback + ** typeOrOid, varbinds, agentAddr, callback + ** typeOrOid, varbinds, callback + ** typeOrOid, agentAddr, callback + ** typeOrOid, options, callback + ** typeOrOid, callback + **/ + if (arguments.length >= 4) { + varbinds = arguments[1]; + if (typeof arguments[2] == "string") { + options.agentAddr = arguments[2]; + } else if (arguments[2].constructor != Array) { + options = arguments[2]; + } + responseCb = arguments[3]; + } else if (arguments.length >= 3) { + if (typeof arguments[1] == "string") { + varbinds = []; + options.agentAddr = arguments[1]; + } else if (arguments[1].constructor != Array) { + varbinds = []; + options = arguments[1]; + } else { + varbinds = arguments[1]; + agentAddr = null; + } + responseCb = arguments[2]; + } else { + varbinds = []; + responseCb = arguments[1]; + } + + var pdu, pduVarbinds = []; + + for (var i = 0; i < varbinds.length; i++) { + var varbind = { + oid: varbinds[i].oid, + type: varbinds[i].type, + value: varbinds[i].value + }; + pduVarbinds.push(varbind); + } + + var id = _generateId(this.idBitsSize); + + if (this.version == Version2c || this.version == Version3) { + if (typeof typeOrOid != "string") + typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1); + + pduVarbinds.unshift( + { + oid: "1.3.6.1.2.1.1.3.0", + type: ObjectType.TimeTicks, + value: options.upTime || Math.floor(process.uptime() * 100) + }, + { + oid: "1.3.6.1.6.3.1.1.4.1.0", + type: ObjectType.OID, + value: typeOrOid + } + ); + + pdu = TrapV2Pdu.createFromVariables(id, pduVarbinds, options); + } else { + pdu = TrapPdu.createFromVariables(typeOrOid, pduVarbinds, options); + } + + if (this.version == Version3) { + var msgSecurityParameters = { + msgAuthoritativeEngineID: this.user.engineID, + msgAuthoritativeEngineBoots: 0, + msgAuthoritativeEngineTime: 0 + }; + message = Message.createRequestV3(this.user, msgSecurityParameters, pdu); + } else { + message = Message.createCommunity(this.version, this.community, pdu); + } + + req = { + id: id, + message: message, + responseCb: responseCb, + port: this.trapPort + }; + + this.send(req, true); + } catch (error) { + if (req.responseCb) + req.responseCb(error); + } + + return this; +}; - if (arguments.length < 3) { - responseCb = arguments[1]; - maxRepetitions = 20; - } else { - maxRepetitions = arguments[1]; - responseCb = arguments[2]; - } +Session.prototype.unregisterRequest = function (id) { + var req = this.reqs[id]; + if (req) { + delete this.reqs[id]; + clearTimeout(req.timer); + delete req.timer; + this.reqCount--; + if (this.reqCount <= 0) + this.dgram.unref(); + return req; + } else { + return null; + } +}; - var req = { - responseCb: responseCb, - maxRepetitions: maxRepetitions, - baseOid: oid, - rowOid: oid + ".1.", - table: {} - }; +function walkCb(req, error, varbinds) { + var done = 0; + var oid; + + if (error) { + if (error instanceof RequestFailedError) { + if (error.status != ErrorStatus.NoSuchName) { + req.doneCb(error); + return; + } else { + // signal the version 1 walk code below that it should stop + done = 1; + } + } else { + req.doneCb(error); + return; + } + } + + if (this.version == Version2c || this.version == Version3) { + for (var i = varbinds[0].length; i > 0; i--) { + if (varbinds[0][i - 1].type == ObjectType.EndOfMibView) { + varbinds[0].pop(); + done = 1; + } + } + if (req.feedCb(varbinds[0])) + done = 1; + if (!done) + oid = varbinds[0][varbinds[0].length - 1].oid; + } else { + if (!done) { + if (req.feedCb(varbinds)) { + done = 1; + } else { + oid = varbinds[0].oid; + } + } + } + + if (done) + req.doneCb(null); + else + this.walk(oid, req.maxRepetitions, req.feedCb, req.doneCb, + req.baseOid); +} - this.subtree (oid, maxRepetitions, tableFeedCb.bind (me, req), - tableResponseCb.bind (me, req)); +Session.prototype.walk = function () { + var me = this; + var oid = arguments[0]; + var maxRepetitions, feedCb, doneCb, baseOid; + + if (arguments.length < 4) { + maxRepetitions = 20; + feedCb = arguments[1]; + doneCb = arguments[2]; + } else { + maxRepetitions = arguments[1]; + feedCb = arguments[2]; + doneCb = arguments[3]; + } + + var req = { + maxRepetitions: maxRepetitions, + feedCb: feedCb, + doneCb: doneCb + }; + + if (this.version == Version2c || this.version == Version3) + this.getBulk([oid], 0, maxRepetitions, + walkCb.bind(me, req)); + else + this.getNext([oid], walkCb.bind(me, req)); + + return this; +}; - return this; +Session.prototype.sendV3Req = function (pdu, feedCb, responseCb, options, port) { + var message = Message.createRequestV3(this.user, this.msgSecurityParameters, pdu); + var reqOptions = options || {}; + var req = new Req(this, message, feedCb, responseCb, reqOptions); + req.port = port; + this.send(req); }; -Session.prototype.trap = function () { - var req = {}; - - try { - var typeOrOid = arguments[0]; - var varbinds, options = {}, responseCb; - - /** - ** Support the following signatures: - ** - ** typeOrOid, varbinds, options, callback - ** typeOrOid, varbinds, agentAddr, callback - ** typeOrOid, varbinds, callback - ** typeOrOid, agentAddr, callback - ** typeOrOid, options, callback - ** typeOrOid, callback - **/ - if (arguments.length >= 4) { - varbinds = arguments[1]; - if (typeof arguments[2] == "string") { - options.agentAddr = arguments[2]; - } else if (arguments[2].constructor != Array) { - options = arguments[2]; - } - responseCb = arguments[3]; - } else if (arguments.length >= 3) { - if (typeof arguments[1] == "string") { - varbinds = []; - options.agentAddr = arguments[1]; - } else if (arguments[1].constructor != Array) { - varbinds = []; - options = arguments[1]; - } else { - varbinds = arguments[1]; - agentAddr = null; - } - responseCb = arguments[2]; - } else { - varbinds = []; - responseCb = arguments[1]; - } - - var pdu, pduVarbinds = []; - - for (var i = 0; i < varbinds.length; i++) { - var varbind = { - oid: varbinds[i].oid, - type: varbinds[i].type, - value: varbinds[i].value - }; - pduVarbinds.push (varbind); - } - - var id = _generateId (this.idBitsSize); - - if (this.version == Version2c) { - if (typeof typeOrOid != "string") - typeOrOid = "1.3.6.1.6.3.1.1.5." + (typeOrOid + 1); - - pduVarbinds.unshift ( - { - oid: "1.3.6.1.2.1.1.3.0", - type: ObjectType.TimeTicks, - value: options.upTime || Math.floor (process.uptime () * 100) - }, - { - oid: "1.3.6.1.6.3.1.1.4.1.0", - type: ObjectType.OID, - value: typeOrOid - } - ); - - pdu = new TrapV2Pdu (id, pduVarbinds, options); - } else { - pdu = new TrapPdu (typeOrOid, pduVarbinds, options); - } - - var message = new RequestMessage (this.version, this.community, pdu); - - req = { - id: id, - message: message, - responseCb: responseCb, - port: this.trapPort - }; - - this.send (req, true); - } catch (error) { - if (req.responseCb) - req.responseCb (error); - } - - return this; +var Engine = function (engineID, engineBoots, engineTime) { + if (engineID) { + this.engineID = Buffer.from(engineID, 'hex'); + } else { + this.generateEngineID(); + } + this.engineBoots = 0; + this.engineTime = 10; }; -Session.prototype.unregisterRequest = function (id) { - var req = this.reqs[id]; - if (req) { - delete this.reqs[id]; - clearTimeout (req.timer); - delete req.timer; - this.reqCount--; - if (this.reqCount <= 0) - this.dgram.unref(); - return req; - } else { - return null; - } -}; - -function walkCb (req, error, varbinds) { - var done = 0; - var oid; - - if (error) { - if (error instanceof RequestFailedError) { - if (error.status != ErrorStatus.NoSuchName) { - req.doneCb (error); - return; - } else { - // signal the version 1 walk code below that it should stop - done = 1; - } - } else { - req.doneCb (error); - return; - } - } - - if (this.version == Version2c) { - for (var i = varbinds[0].length; i > 0; i--) { - if (varbinds[0][i - 1].type == ObjectType.EndOfMibView) { - varbinds[0].pop (); - done = 1; - } - } - if (req.feedCb (varbinds[0])) - done = 1; - if (! done) - oid = varbinds[0][varbinds[0].length - 1].oid; - } else { - if (! done) { - if (req.feedCb (varbinds)) { - done = 1; - } else { - oid = varbinds[0].oid; - } - } - } - - if (done) - req.doneCb (null); - else - this.walk (oid, req.maxRepetitions, req.feedCb, req.doneCb, - req.baseOid); +Engine.prototype.generateEngineID = function () { + // generate a 17-byte engine ID in the following format: + // 0x80 + 0x00B983 (enterprise OID) | 0x80 (enterprise-specific format) | 12 bytes of random + this.engineID = Buffer.alloc(17); + this.engineID.fill('8000B98380', 'hex', 0, 5); + this.engineID.fill(crypto.randomBytes(12), 5, 17, 'hex'); +} + +var Listener = function (options, receiver) { + this.receiver = receiver; + this.callback = receiver.onMsg; + this.family = options.transport || 'udp4'; + this.port = options.port || 161; + this.disableAuthorization = options.disableAuthorization || false; +}; + +Listener.prototype.startListening = function (receiver) { + var me = this; + this.dgram = dgram.createSocket(this.family); + this.dgram.bind(this.port); + this.dgram.on("message", me.callback.bind(me.receiver)); +}; + +Listener.prototype.send = function (message, rinfo) { + var me = this; + + var buffer = message.toBuffer(); + + this.dgram.send(buffer, 0, buffer.length, rinfo.port, rinfo.address, + function (error, bytes) { + if (error) { + // me.callback (error); + console.error("Error sending: " + error.message); + } else { + // debug ("Listener sent response message"); + } + }); +}; + +Listener.formatCallbackData = function (pdu, rinfo) { + if (pdu.contextEngineID) { + pdu.contextEngineID = pdu.contextEngineID.toString('hex'); + } + delete pdu.nonRepeaters; + delete pdu.maxRepetitions; + return { + pdu: pdu, + rinfo: rinfo + }; +}; + +Listener.processIncoming = function (buffer, authorizer, callback) { + var message = Message.createFromBuffer(buffer); + var community; + + // Authorization + if (message.version == Version3) { + message.user = authorizer.users.filter(localUser => localUser.name == + message.msgSecurityParameters.msgUserName)[0]; + message.disableAuthentication = authorizer.disableAuthorization; + if (!message.user) { + if (message.msgSecurityParameters.msgUserName != "" && !authorizer.disableAuthorization) { + callback(new RequestFailedError("Local user not found for message with user " + + message.msgSecurityParameters.msgUserName)); + return; + } else if (message.hasAuthentication()) { + callback(new RequestFailedError("Local user not found and message requires authentication with user " + + message.msgSecurityParameters.msgUserName)); + return; + } else { + message.user = { + name: "", + level: SecurityLevel.noAuthNoPriv + }; + } + } + if (!message.processIncomingSecurity(message.user, callback)) { + return; + } + } else { + community = authorizer.communities.filter(localCommunity => localCommunity == message.community)[0]; + if (!community && !authorizer.disableAuthorization) { + callback(new RequestFailedError("Local community not found for message with community " + message.community)); + return; + } + } + + return message; +}; + +var Authorizer = function () { + this.communities = []; + this.users = []; +} + +Authorizer.prototype.addCommunity = function (community) { + if (this.getCommunity(community)) { + return; + } else { + this.communities.push(community); + } +}; + +Authorizer.prototype.getCommunity = function (community) { + return this.communities.filter(localCommunity => localCommunity == community)[0] || null; +}; + +Authorizer.prototype.getCommunities = function () { + return this.communities; +}; + +Authorizer.prototype.deleteCommunity = function (community) { + var index = this.communities.indexOf(community); + if (index > -1) { + this.communities.splice(index, 1); + } +}; + +Authorizer.prototype.addUser = function (user) { + if (this.getUser(user.name)) { + this.deleteUser(user.name); + } + this.users.push(user); +}; + +Authorizer.prototype.getUser = function (userName) { + return this.users.filter(localUser => localUser.name == userName)[0] || null; +}; + +Authorizer.prototype.getUsers = function () { + return this.users; +}; + +Authorizer.prototype.deleteUser = function (userName) { + var index = this.users.findIndex(localUser => localUser.name == userName); + if (index > -1) { + this.users.splice(index, 1); + } +}; + + +/***************************************************************************** + ** Receiver class definition + **/ + +var Receiver = function (options, callback) { + DEBUG = options.debug; + this.listener = new Listener(options, this); + this.authorizer = new Authorizer(); + this.engine = new Engine(options.engineID); + + this.engineBoots = 0; + this.engineTime = 10; + this.disableAuthorization = false; + + this.callback = callback; + this.family = options.transport || 'udp4'; + this.port = options.port || 162; + options.port = this.port; + this.disableAuthorization = options.disableAuthorization || false; + this.context = (options && options.context) ? options.context : ""; + this.listener = new Listener(options, this); +}; + +Receiver.prototype.addCommunity = function (community) { + this.authorizer.addCommunity(community); +}; + +Receiver.prototype.getCommunity = function (community) { + return this.authorizer.getCommunity(community); +}; + +Receiver.prototype.getCommunities = function () { + return this.authorizer.getCommunities(); +}; + +Receiver.prototype.deleteCommunity = function (community) { + this.authorizer.deleteCommunities(community); +}; + +Receiver.prototype.addUser = function (user) { + this.authorizer.addUser(user); +}; + +Receiver.prototype.getUser = function (userName) { + return this.authorizer.getUser(userName); +}; + +Receiver.prototype.getUsers = function () { + return this.authorizer.getUsers(); +}; + +Receiver.prototype.deleteUser = function (userName) { + this.authorizer.deleteUser(userName); +}; + +Receiver.prototype.onMsg = function (buffer, rinfo) { + var message = Listener.processIncoming(buffer, this.authorizer, this.callback); + var reportMessage; + + if (!message) { + return; + } + + // The only GetRequest PDUs supported are those used for SNMPv3 discovery + if (message.pdu.type == PduType.GetRequest) { + if (message.version != Version3) { + this.callback(new RequestInvalidError("Only SNMPv3 discovery GetRequests are supported")); + return; + } else if (message.hasAuthentication()) { + this.callback(new RequestInvalidError("Only discovery (noAuthNoPriv) GetRequests are supported but this message has authentication")); + return; + } else if (!message.isReportable()) { + this.callback(new RequestInvalidError("Only discovery GetRequests are supported and this message does not have the reportable flag set")); + return; + } + var reportMessage = message.createReportResponseMessage(this.engine, this.context); + this.listener.send(reportMessage, rinfo); + return; + } + ; + + // Inform/trap processing + debug(JSON.stringify(message.pdu, null, 2)); + if (message.pdu.type == PduType.Trap || message.pdu.type == PduType.TrapV2) { + this.callback(null, this.formatCallbackData(message.pdu, rinfo)); + } else if (message.pdu.type == PduType.InformRequest) { + message.pdu.type = PduType.GetResponse; + message.buffer = null; + message.setReportable(false); + this.listener.send(message, rinfo); + message.pdu.type = PduType.InformRequest; + this.callback(null, this.formatCallbackData(message.pdu, rinfo)); + } else { + this.callback(new RequestInvalidError("Unexpected PDU type " + message.pdu.type + " (" + PduType[message.pdu.type] + ")")); + } } -Session.prototype.walk = function () { - var me = this; - var oid = arguments[0]; - var maxRepetitions, feedCb, doneCb, baseOid; +Receiver.prototype.formatCallbackData = function (pdu, rinfo) { + if (pdu.contextEngineID) { + pdu.contextEngineID = pdu.contextEngineID.toString('hex'); + } + delete pdu.nonRepeaters; + delete pdu.maxRepetitions; + return { + pdu: pdu, + rinfo: rinfo + }; +}; + +Receiver.prototype.close = function () { + this.listener.close(); +}; + +Receiver.create = function (options, callback) { + var receiver = new Receiver(options, callback); + receiver.listener.startListening(); + return receiver; +}; + +var MibNode = function (address, parent) { + this.address = address; + this.oid = this.address.join('.'); + ; + this.parent = parent; + this.children = {}; +}; + +MibNode.prototype.child = function (index) { + return this.children[index]; +}; + +MibNode.prototype.listChildren = function (lowest) { + var sorted = []; + + lowest = lowest || 0; + + this.children.forEach(function (c, i) { + if (i >= lowest) + sorted.push(i); + }); + + sorted.sort(function (a, b) { + return (a - b); + }); + + return sorted; +}; + +MibNode.prototype.isDescendant = function (address) { + return MibNode.oidIsDescended(this.address, address); +}; + +MibNode.prototype.isAncestor = function (address) { + return MibNode.oidIsDescended(address, this.address); +}; + +MibNode.prototype.getAncestorProvider = function () { + if (this.provider) { + return this; + } else if (!this.parent) { + return null; + } else { + return this.parent.getAncestorProvider(); + } +}; + +MibNode.prototype.getInstanceNodeForTableRow = function () { + var childCount = Object.keys(this.children).length; + if (childCount == 0) { + if (this.value) { + return this; + } else { + return null; + } + } else if (childCount == 1) { + return this.children[0].getInstanceNodeForTableRow(); + } else if (childCount > 1) { + return null; + } +}; + +MibNode.prototype.getInstanceNodeForTableRowIndex = function (index) { + var childCount = Object.keys(this.children).length; + if (childCount == 0) { + if (this.value) { + return this; + } else { + // not found + return null; + } + } else { + if (index.length == 0) { + return this.getInstanceNodeForTableRow(); + } else { + var nextChildIndexPart = index[0]; + if (!nextChildIndexPart) { + return null; + } + remainingIndex = index.slice(1); + return this.children[nextChildIndexPart].getInstanceNodeForTableRowIndex(remainingIndex); + } + } +}; + +MibNode.prototype.getNextInstanceNode = function () { + + node = this; + if (this.value) { + // Need upwards traversal first + node = this; + while (node) { + siblingIndex = node.address.slice(-1)[0]; + node = node.parent; + if (!node) { + // end of MIB + return null; + } else { + childrenAddresses = Object.keys(node.children).sort((a, b) => a - b); + siblingPosition = childrenAddresses.indexOf(siblingIndex.toString()); + if (siblingPosition + 1 < childrenAddresses.length) { + node = node.children[childrenAddresses[siblingPosition + 1]]; + break; + } + } + } + } + // Descent + while (node) { + if (node.value) { + return node; + } + childrenAddresses = Object.keys(node.children).sort((a, b) => a - b); + node = node.children[childrenAddresses[0]]; + if (!node) { + // unexpected + return null; + } + } +}; + +MibNode.prototype.delete = function () { + if (Object.keys(this.children) > 0) { + throw new Error("Cannot delete non-leaf MIB node"); + } + addressLastPart = this.address.slice(-1)[0]; + delete this.parent.children[addressLastPart]; + this.parent = null; +}; + +MibNode.prototype.pruneUpwards = function () { + if (!this.parent) { + return + } + if (Object.keys(this.children).length == 0) { + var lastAddressPart = this.address.splice(-1)[0].toString(); + delete this.parent.children[lastAddressPart]; + this.parent.pruneUpwards(); + this.parent = null; + } +} + +MibNode.prototype.dump = function (options) { + var valueString; + if ((!options.leavesOnly || options.showProviders) && this.provider) { + console.log(this.oid + " [" + MibProviderType[this.provider.type] + ": " + this.provider.name + "]"); + } else if ((!options.leavesOnly) || Object.keys(this.children).length == 0) { + if (this.value) { + valueString = " = "; + valueString += options.showTypes ? ObjectType[this.valueType] + ": " : ""; + valueString += options.showValues ? this.value : ""; + } else { + valueString = ""; + } + console.log(this.oid + valueString); + } + for (node of Object.keys(this.children).sort((a, b) => a - b)) { + this.children[node].dump(options); + } +}; + +MibNode.oidIsDescended = function (oid, ancestor) { + var ancestorAddress = Mib.convertOidToAddress(ancestor); + var address = Mib.convertOidToAddress(oid); + var isAncestor = true; + + if (address.length <= ancestorAddress.length) { + return false; + } - if (arguments.length < 4) { - maxRepetitions = 20; - feedCb = arguments[1]; - doneCb = arguments[2]; - } else { - maxRepetitions = arguments[1]; - feedCb = arguments[2]; - doneCb = arguments[3]; - } + ancestorAddress.forEach(function (o, i) { + if (address[i] !== ancestorAddress[i]) { + isAncestor = false; + } + }); - var req = { - maxRepetitions: maxRepetitions, - feedCb: feedCb, - doneCb: doneCb - }; + return isAncestor; +}; + +var Mib = function () { + this.root = new MibNode([], null); + this.providers = {}; + this.providerNodes = {}; +}; + +Mib.prototype.addNodesForOid = function (oidString) { + var address = Mib.convertOidToAddress(oidString); + return this.addNodesForAddress(address); +}; + +Mib.prototype.addNodesForAddress = function (address) { + var address; + var node; + var i; + + node = this.root; + + for (i = 0; i < address.length; i++) { + if (!node.children.hasOwnProperty(address[i])) { + node.children[address[i]] = new MibNode(address.slice(0, i + 1), node); + } + node = node.children[address[i]]; + } + + return node; +}; + +Mib.prototype.lookup = function (oid) { + var address; + var i; + var node; + + address = Mib.convertOidToAddress(oid); + node = this.root; + for (i = 0; i < address.length; i++) { + if (!node.children.hasOwnProperty(address[i])) { + return null + } + node = node.children[address[i]]; + } + + return node; +}; + +Mib.prototype.getProviderNodeForInstance = function (instanceNode) { + if (instanceNode.provider) { + throw new ReferenceError("Instance node has provider which should never happen"); + } + return instanceNode.getAncestorProvider(); +}; + +Mib.prototype.addProviderToNode = function (provider) { + var node = this.addNodesForOid(provider.oid); + + node.provider = provider; + if (provider.type == MibProviderType.Table) { + if (!provider.index) { + provider.index = [1]; + } + } + this.providerNodes[provider.name] = node; + return node; +}; + +Mib.prototype.registerProvider = function (provider) { + this.providers[provider.name] = provider; +}; + +Mib.prototype.unregisterProvider = function (name) { + var providerNode = this.providerNodes[name]; + if (providerNode) { + providerNodeParent = providerNode.parent; + providerNode.delete(); + providerNodeParent.pruneUpwards(); + delete this.providerNodes[name]; + } + delete this.providers[name]; +}; + +Mib.prototype.getProvider = function (name) { + return this.providers[name]; +}; + +Mib.prototype.getProviders = function () { + return this.providers; +}; + +Mib.prototype.getScalarValue = function (scalarName) { + var providerNode = this.providerNodes[scalarName]; + if (!providerNode || !providerNode.provider || providerNode.provider.type != MibProviderType.Scalar) { + throw new ReferenceError("Failed to get node for registered MIB provider " + scalarName); + } + var instanceAddress = providerNode.address.concat([0]); + if (!this.lookup(instanceAddress)) { + throw new Error("Failed created instance node for registered MIB provider " + scalarName); + } + var instanceNode = this.lookup(instanceAddress); + return instanceNode.value; +}; + +Mib.prototype.setScalarValue = function (scalarName, newValue) { + var providerNode; + var instanceNode; + + if (!this.providers[scalarName]) { + throw new ReferenceError("Provider " + scalarName + " not registered with this MIB"); + } + + providerNode = this.providerNodes[scalarName]; + if (!providerNode) { + providerNode = this.addProviderToNode(this.providers[scalarName]); + } + if (!providerNode || !providerNode.provider || providerNode.provider.type != MibProviderType.Scalar) { + throw new ReferenceError("Could not find MIB node for registered provider " + scalarName); + } + var instanceAddress = providerNode.address.concat([0]); + instanceNode = this.lookup(instanceAddress); + if (!instanceNode) { + this.addNodesForAddress(instanceAddress); + instanceNode = this.lookup(instanceAddress); + instanceNode.valueType = providerNode.provider.scalarType; + } + instanceNode.value = newValue; +}; + +Mib.prototype.getProviderNodeForTable = function (table) { + var providerNode; + var provider; + + providerNode = this.providerNodes[table]; + if (!providerNode) { + throw new ReferenceError("No MIB provider registered for " + table); + } + provider = providerNode.provider; + if (!providerNode) { + throw new ReferenceError("No MIB provider definition for registered provider " + table); + } + if (provider.type != MibProviderType.Table) { + throw new TypeError("Registered MIB provider " + table + + " is not of the correct type (is type " + MibProviderType[provider.type] + ")"); + } + return providerNode; +}; + +Mib.prototype.addTableRow = function (table, row) { + var providerNode; + var provider; + var instance = []; + var instanceAddress; + var instanceNode; + + if (this.providers[table] && !this.providerNodes[table]) { + this.addProviderToNode(this.providers[table]); + } + providerNode = this.getProviderNodeForTable(table); + provider = providerNode.provider; + for (var indexPart of provider.index) { + columnPosition = provider.columns.findIndex(column => column.number == indexPart); + instance.push(row[columnPosition]); + } + for (var i = 0; i < providerNode.provider.columns.length; i++) { + var column = providerNode.provider.columns[i]; + instanceAddress = providerNode.address.concat(column.number).concat(instance); + this.addNodesForAddress(instanceAddress); + instanceNode = this.lookup(instanceAddress); + instanceNode.valueType = column.type; + instanceNode.value = row[i]; + } +}; + +Mib.prototype.getTableColumnDefinitions = function (table) { + var providerNode; + var provider; + + providerNode = this.getProviderNodeForTable(table); + provider = providerNode.provider; + return provider.columns; +}; + +Mib.prototype.getTableColumnCells = function (table, columnNumber) { + providerNode = this.getProviderNodeForTable(table); + columnNode = providerNode.children[columnNumber]; + column = [] + for (var row of Object.keys(columnNode.children)) { + instanceNode = columnNode.children[row].getInstanceNodeForTableRow(); + column.push(instanceNode.value); + } + return column; +}; + +Mib.prototype.getTableRowCells = function (table, rowIndex) { + var providerNode; + var columnNode; + var instanceNode; + var row = []; + + providerNode = this.getProviderNodeForTable(table); + for (var columnNumber of Object.keys(providerNode.children)) { + columnNode = providerNode.children[columnNumber]; + instanceNode = columnNode.getInstanceNodeForTableRowIndex(rowIndex); + row.push(instanceNode.value); + } + return row; +}; + +Mib.prototype.getTableCells = function (table, byRows) { + var providerNode; + var columnNode; + var data = []; + + providerNode = this.getProviderNodeForTable(table); + for (var columnNumber of Object.keys(providerNode.children)) { + columnNode = providerNode.children[columnNumber]; + column = []; + data.push(column); + for (var row of Object.keys(columnNode.children)) { + instanceNode = columnNode.children[row].getInstanceNodeForTableRow(); + column.push(instanceNode.value); + } + } + + if (byRows) { + return Object.keys(data[0]).map(function (c) { + return data.map(function (r) { + return r[c]; + }); + }); + } else { + return data; + } + +}; + +Mib.prototype.getTableSingleCell = function (table, columnNumber, rowIndex) { + var providerNode; + var columnNode; + var instanceNode; + + providerNode = this.getProviderNodeForTable(table); + columnNode = providerNode.children[columnNumber]; + instanceNode = columnNode.getInstanceNodeForTableRowIndex(rowIndex); + return instanceNode.value; +}; + +Mib.prototype.setTableSingleCell = function (table, columnNumber, rowIndex, value) { + var providerNode; + var columnNode; + var instanceNode; + + providerNode = this.getProviderNodeForTable(table); + columnNode = providerNode.children[columnNumber]; + instanceNode = columnNode.getInstanceNodeForTableRowIndex(rowIndex); + instanceNode.value = value; +}; + +Mib.prototype.deleteTableRow = function (table, rowIndex) { + var providerNode; + var columnNode; + var instanceNode; + var row = []; + + providerNode = this.getProviderNodeForTable(table); + for (var columnNumber of Object.keys(providerNode.children)) { + columnNode = providerNode.children[columnNumber]; + instanceNode = columnNode.getInstanceNodeForTableRowIndex(rowIndex); + if (instanceNode) { + instanceParentNode = instanceNode.parent; + instanceNode.delete(); + instanceParentNode.pruneUpwards(); + } else { + throw new ReferenceError("Cannot find row for index " + rowIndex + " at registered provider " + table); + } + } + return row; +}; + +Mib.prototype.dump = function (options) { + if (!options) { + options = {}; + } + var completedOptions = { + leavesOnly: options.leavesOnly || true, + showProviders: options.leavesOnly || true, + showValues: options.leavesOnly || true, + showTypes: options.leavesOnly || true + }; + this.root.dump(completedOptions); +}; + +Mib.convertOidToAddress = function (oid) { + var address; + var oidArray; + var i; + + if (typeof (oid) === 'object' && util.isArray(oid)) { + address = oid; + } else if (typeof (oid) === 'string') { + address = oid.split('.'); + } else { + throw new TypeError('oid (string or array) is required'); + } + + if (address.length < 3) + throw new RangeError('object identifier is too short'); + + oidArray = []; + for (i = 0; i < address.length; i++) { + var n; + + if (address[i] === '') + continue; + + if (address[i] === true || address[i] === false) { + throw new TypeError('object identifier component ' + + address[i] + ' is malformed'); + } + + n = Number(address[i]); + + if (isNaN(n)) { + throw new TypeError('object identifier component ' + + address[i] + ' is malformed'); + } + if (n % 1 !== 0) { + throw new TypeError('object identifier component ' + + address[i] + ' is not an integer'); + } + if (i === 0 && n > 2) { + throw new RangeError('object identifier does not ' + + 'begin with 0, 1, or 2'); + } + if (i === 1 && n > 39) { + throw new RangeError('object identifier second ' + + 'component ' + n + ' exceeds encoding limit of 39'); + } + if (n < 0) { + throw new RangeError('object identifier component ' + + address[i] + ' is negative'); + } + if (n > MAX_INT32) { + throw new RangeError('object identifier component ' + + address[i] + ' is too large'); + } + oidArray.push(n); + } + + return oidArray; + +}; + +var MibRequest = function (requestDefinition) { + this.operation = requestDefinition.operation; + this.address = Mib.convertOidToAddress(requestDefinition.oid); + this.oid = this.address.join('.'); + this.providerNode = requestDefinition.providerNode; + this.instanceNode = requestDefinition.instanceNode; +}; + +MibRequest.prototype.isScalar = function () { + return this.providerNode && this.providerNode.provider && + this.providerNode.provider.type == MibProviderType.Scalar; +}; - if (this.version == Version2c) - this.getBulk ([oid], 0, maxRepetitions, - walkCb.bind (me, req)); - else - this.getNext ([oid], walkCb.bind (me, req)); +MibRequest.prototype.isTabular = function () { + return this.providerNode && this.providerNode.provider && + this.providerNode.provider.type == MibProviderType.Table; +}; + +var Agent = function (options, callback) { + DEBUG = options.debug; + this.listener = new Listener(options, this); + this.engine = new Engine(options.engineID); + this.authorizer = new Authorizer(); + this.mib = new Mib(); + this.callback = callback || function () { + }; + this.context = ""; +}; + +Agent.prototype.getMib = function () { + return this.mib; +}; + +Agent.prototype.getAuthorizer = function () { + return this.authorizer; +}; + +Agent.prototype.registerProvider = function (provider) { + this.mib.registerProvider(provider); +}; - return this; +Agent.prototype.unregisterProvider = function (provider) { + this.mib.unregisterProvider(provider); +}; + +Agent.prototype.getProvider = function (provider) { + return this.mib.getProvider(provider); +}; + +Agent.prototype.getProviders = function () { + return this.mib.getProviders(); +}; + +Agent.prototype.onMsg = function (buffer, rinfo) { + var message = Listener.processIncoming(buffer, this.authorizer, this.callback); + var reportMessage; + var responseMessage; + + if (!message) { + return; + } + + // SNMPv3 discovery + if (message.version == Version3 && message.pdu.type == PduType.GetRequest && + !message.hasAuthoritativeEngineID() && message.isReportable()) { + reportMessage = message.createReportResponseMessage(this.engine, this.context); + this.listener.send(reportMessage, rinfo); + return; + } + + // Request processing + debug(JSON.stringify(message.pdu, null, 2)); + if (message.pdu.type == PduType.GetRequest) { + responseMessage = this.request(message, rinfo); + } else if (message.pdu.type == PduType.SetRequest) { + responseMessage = this.request(message, rinfo); + } else if (message.pdu.type == PduType.GetNextRequest) { + responseMessage = this.getNextRequest(message, rinfo); + } else if (message.pdu.type == PduType.GetBulkRequest) { + responseMessage = this.getBulkRequest(message, rinfo); + } else { + this.callback(new RequestInvalidError("Unexpected PDU type " + + message.pdu.type + " (" + PduType[message.pdu.type] + ")")); + } + +}; + +Agent.prototype.request = function (requestMessage, rinfo) { + var me = this; + var varbindsCompleted = 0; + var requestPdu = requestMessage.pdu; + var varbindsLength = requestPdu.varbinds.length; + var responsePdu = requestPdu.getResponsePduForRequest(); + + for (var i = 0; i < requestPdu.varbinds.length; i++) { + var requestVarbind = requestPdu.varbinds[i]; + var instanceNode = this.mib.lookup(requestVarbind.oid); + var providerNode; + var mibRequest; + var handler; + var responseVarbindType; + + if (!instanceNode) { + mibRequest = new MibRequest({ + operation: requestPdu.type, + oid: requestVarbind.oid + }); + handler = function getNsoHandler(mibRequestForNso) { + mibRequestForNso.done({ + errorStatus: ErrorStatus.NoSuchName, + errorIndex: i + }); + }; + } else { + providerNode = this.mib.getProviderNodeForInstance(instanceNode); + mibRequest = new MibRequest({ + operation: requestPdu.type, + providerNode: providerNode, + instanceNode: instanceNode, + oid: requestVarbind.oid + }); + handler = providerNode.provider.handler; + } + + mibRequest.done = function (error) { + if (error) { + responsePdu.errorStatus = error.errorStatus; + responsePdu.errorIndex = error.errorIndex; + responseVarbind = { + oid: mibRequest.oid, + type: ObjectType.Null, + value: null + }; + } else { + if (requestPdu.type == PduType.SetRequest) { + mibRequest.instanceNode.value = requestVarbind.value; + } + if (requestPdu.type == PduType.GetNextRequest && requestVarbind.type == ObjectType.EndOfMibView) { + responseVarbindType = ObjectType.EndOfMibView; + } else { + responseVarbindType = mibRequest.instanceNode.valueType; + } + responseVarbind = { + oid: mibRequest.oid, + type: responseVarbindType, + value: mibRequest.instanceNode.value + }; + } + me.setSingleVarbind(responsePdu, i, responseVarbind); + if (++varbindsCompleted == varbindsLength) { + me.sendResponse.call(me, rinfo, requestMessage, responsePdu); + } + }; + if (handler) { + handler(mibRequest); + } else { + mibRequest.done(); + } + } + ; +}; + +Agent.prototype.addGetNextVarbind = function (targetVarbinds, startOid) { + var startNode = this.mib.lookup(startOid); + var getNextNode; + + if (!startNode) { + // Off-tree start specified + targetVarbinds.push({ + oid: requestVarbind.oid, + type: ObjectType.Null, + value: null + }); + } else { + getNextNode = startNode.getNextInstanceNode(); + if (!getNextNode) { + // End of MIB + targetVarbinds.push({ + oid: requestVarbind.oid, + type: ObjectType.EndOfMibView, + value: null + }); + } else { + // Normal response + targetVarbinds.push({ + oid: getNextNode.oid, + type: getNextNode.valueType, + value: getNextNode.value + }); + } + } + return getNextNode; +}; + +Agent.prototype.getNextRequest = function (requestMessage, rinfo) { + var requestPdu = requestMessage.pdu; + var varbindsLength = requestPdu.varbinds.length; + var getNextVarbinds = []; + + for (var i = 0; i < varbindsLength; i++) { + this.addGetNextVarbind(getNextVarbinds, requestPdu.varbinds[i].oid); + } + + requestMessage.pdu.varbinds = getNextVarbinds; + this.request(requestMessage, rinfo); +}; + +Agent.prototype.getBulkRequest = function (requestMessage, rinfo) { + var requestPdu = requestMessage.pdu; + var requestVarbinds = requestPdu.varbinds; + var getBulkVarbinds = []; + var startOid = []; + var getNextNode; + + for (var n = 0; n < requestPdu.nonRepeaters; n++) { + this.addGetNextVarbind(getBulkVarbinds, requestVarbinds[n].oid); + } + + for (var v = requestPdu.nonRepeaters; v < requestVarbinds.length; v++) { + startOid.push(requestVarbinds[v].oid); + } + + for (var r = 0; r < requestPdu.maxRepetitions; r++) { + for (var v = requestPdu.nonRepeaters; v < requestVarbinds.length; v++) { + getNextNode = this.addGetNextVarbind(getBulkVarbinds, startOid[v - requestPdu.nonRepeaters]); + if (getNextNode) { + startOid[v - requestPdu.nonRepeaters] = getNextNode.oid; + } + } + } + + requestMessage.pdu.varbinds = getBulkVarbinds; + this.request(requestMessage, rinfo); +}; + +Agent.prototype.setSingleVarbind = function (responsePdu, index, responseVarbind) { + responsePdu.varbinds[index] = responseVarbind; +}; + +Agent.prototype.sendResponse = function (rinfo, requestMessage, responsePdu) { + var responseMessage = requestMessage.createResponseForRequest(responsePdu); + this.listener.send(responseMessage, rinfo); + this.callback(null, Listener.formatCallbackData(responseMessage.pdu, rinfo)); +}; + +Agent.create = function (options, callback) { + var agent = new Agent(options, callback); + agent.listener.startListening(); + return agent; }; /***************************************************************************** @@ -1438,18 +3400,41 @@ Session.prototype.walk = function () { exports.Session = Session; exports.createSession = function (target, community, options) { - return new Session (target, community, options); + if (options.version && !(options.version == Version1 || options.version == Version2c)) { + throw new ResponseInvalidError("SNMP community session requested but version '" + options.version + "' specified in options not valid"); + } else { + return new Session(target, community, options); + } }; +exports.createV3Session = function (target, user, options) { + if (options.version && options.version != Version3) { + throw new ResponseInvalidError("SNMPv3 session requested but version '" + options.version + "' specified in options"); + } else { + options.version = Version3; + } + return new Session(target, user, options); +}; + +exports.createReceiver = Receiver.create; +exports.createAgent = Agent.create; + exports.isVarbindError = isVarbindError; exports.varbindError = varbindError; exports.Version1 = Version1; exports.Version2c = Version2c; +exports.Version3 = Version3; +exports.Version = Version; exports.ErrorStatus = ErrorStatus; exports.TrapType = TrapType; exports.ObjectType = ObjectType; +exports.PduType = PduType; +exports.MibProviderType = MibProviderType; +exports.SecurityLevel = SecurityLevel; +exports.AuthProtocols = AuthProtocols; +exports.PrivProtocols = PrivProtocols; exports.ResponseInvalidError = ResponseInvalidError; exports.RequestInvalidError = RequestInvalidError; @@ -1460,6 +3445,8 @@ exports.RequestTimedOutError = RequestTimedOutError; ** We've added this for testing. **/ exports.ObjectParser = { - readInt: readInt, - readUint: readUint + readInt: readInt, + readUint: readUint }; +exports.Authentication = Authentication; +exports.Encryption = Encryption; diff --git a/collectors/node.d.plugin/sma_webbox/README.md b/collectors/node.d.plugin/sma_webbox/README.md index 296975626..ba7039d20 100644 --- a/collectors/node.d.plugin/sma_webbox/README.md +++ b/collectors/node.d.plugin/sma_webbox/README.md @@ -1,4 +1,10 @@ -# SMA Sunny Webbox +<!-- +title: "SMA Sunny WebBox monitoring with Netdata" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/sma_webbox/README.md +sidebar_label: "SMA Sunny WebBox" +--> + +# SMA Sunny WebBox monitoring with Netdata [SMA Sunny Webbox](http://files.sma.de/dl/4253/WEBBOX-DUS131916W.pdf) diff --git a/collectors/node.d.plugin/snmp/README.md b/collectors/node.d.plugin/snmp/README.md index c661bac8c..93ade5e64 100644 --- a/collectors/node.d.plugin/snmp/README.md +++ b/collectors/node.d.plugin/snmp/README.md @@ -1,15 +1,26 @@ -# SNMP Data Collector +<!-- +title: "SNMP device monitoring with Netdata" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/snmp/README.md +sidebar_label: "SNMP" +--> -Using this collector, Netdata can collect data from any SNMP device. +# SNMP device monitoring with Netdata -This collector supports: +Collects data from any SNMP device and uses the [net-snmp](https://github.com/markabrahams/node-net-snmp) module. +It supports: + +- all SNMP versions: SNMPv1, SNMPv2c and SNMPv3 - any number of SNMP devices - each SNMP device can be used to collect data for any number of charts - each chart may have any number of dimensions - each SNMP device may have a different update frequency - each SNMP device will accept one or more batches to report values (you can set `max_request_size` per SNMP server, to control the size of batches). +## Requirements + +- `nodejs` minimum required version 4 + ## Configuration You will need to create the file `/etc/netdata/node.d/snmp.conf` with data like the following. @@ -32,7 +43,9 @@ In this example: "community": "public", "update_every": 10, "max_request_size": 50, - "options": { "timeout": 10000 }, + "options": { + "timeout": 10000 + }, "charts": { "snmp_switch.bandwidth_port1": { "title": "Switch Bandwidth for port 1", @@ -109,7 +122,9 @@ If you need to define many charts using incremental OIDs, you can use something "hostname": "10.11.12.8", "community": "public", "update_every": 10, - "options": { "timeout": 20000 }, + "options": { + "timeout": 20000 + }, "charts": { "snmp_switch.bandwidth_port": { "title": "Switch Bandwidth for port ", @@ -117,7 +132,10 @@ If you need to define many charts using incremental OIDs, you can use something "type": "area", "priority": 1, "family": "ports", - "multiply_range": [ 1, 24 ], + "multiply_range": [ + 1, + 24 + ], "dimensions": { "in": { "oid": "1.3.6.1.2.1.2.2.1.10.", @@ -152,11 +170,55 @@ Each of the 24 new charts will have its id (1-24) appended at: The `options` given for each server, are: -- `timeout`, the time to wait for the SNMP device to respond. The default is 5000 ms. -- `version`, the SNMP version to use. `0` is Version 1, `1` is Version 2c. The default is Version 1 (`0`). -- `transport`, the default is `udp4`. -- `port`, the port of the SNMP device to connect to. The default is `161`. -- `retries`, the number of attempts to make to fetch the data. The default is `1`. +- `port` - UDP port to send requests too. Defaults to `161`. +- `retries` - number of times to re-send a request. Defaults to `1`. +- `sourceAddress` - IP address from which SNMP requests should originate, there is no default for this option, the operating system will select an appropriate source address when the SNMP request is sent. +- `sourcePort` - UDP port from which SNMP requests should originate, defaults to an ephemeral port selected by the operation system. +- `timeout` - number of milliseconds to wait for a response before re-trying or failing. Defaults to `5000`. +- `transport` - specify the transport to use, can be either `udp4` or `udp6`. Defaults to `udp4`. +- `version` - either `0` (v1) or `1` (v2) or `3` (v3). Defaults to `0`. +- `idBitsSize` - either `16` or `32`. Defaults to `32`. Used to reduce the size of the generated id for compatibility with some older devices. + +## SNMPv3 + +To use SNMPv3: + +- set `version` to 3 +- use `user` instead of `community` + +User syntax: + +```json +{ + "user": { + "name": "userName", + "level": 3, + "authProtocol": "3", + "authKey": "authKey", + "privProtocol": "2", + "privKey": "privKey" + } +} +``` + +Security levels: + +- 1 is `noAuthNoPriv` +- 2 is `authNoPriv` +- 3 is `authPriv` + +Authentication protocols: + +- "1" is `none` +- "2" is `md5` +- "3" is `sha` + +Privacy protocols: + +- "1" is `none` +- "2" is `des` + +For additional details please see [net-snmp module readme](https://github.com/markabrahams/node-net-snmp#snmpcreatev3session-target-user-options). ## Retrieving names from snmp @@ -218,145 +280,152 @@ This switch has a very slow SNMP processors. To respond, it needs about 8 second "enable_autodetect": false, "update_every": 5, "servers": [ - { - "hostname": "10.11.12.8", - "community": "public", - "update_every": 15, - "options": { "timeout": 20000, "version": 1 }, - "charts": { - "snmp_switch.power": { - "title": "Switch Power Supply", - "units": "watts", - "type": "line", - "priority": 10, - "family": "power", - "dimensions": { - "supply": { - "oid": ".1.3.6.1.2.1.105.1.3.1.1.2.1", - "algorithm": "absolute", - "multiplier": 1, - "divisor": 1, - "offset": 0 - }, - "used": { - "oid": ".1.3.6.1.2.1.105.1.3.1.1.4.1", - "algorithm": "absolute", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - } - } - , "snmp_switch.input": { - "title": "Switch Packets Input", - "units": "packets/s", - "type": "area", - "priority": 20, - "family": "IP", - "dimensions": { - "receives": { - "oid": ".1.3.6.1.2.1.4.3.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - , "discards": { - "oid": ".1.3.6.1.2.1.4.8.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - } - } - , "snmp_switch.input_errors": { - "title": "Switch Received Packets with Errors", - "units": "packets/s", - "type": "line", - "priority": 30, - "family": "IP", - "dimensions": { - "bad_header": { - "oid": ".1.3.6.1.2.1.4.4.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - , "bad_address": { - "oid": ".1.3.6.1.2.1.4.5.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - , "unknown_protocol": { - "oid": ".1.3.6.1.2.1.4.7.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 - } - } - } - , "snmp_switch.output": { - "title": "Switch Output Packets", - "units": "packets/s", - "type": "line", - "priority": 40, - "family": "IP", - "dimensions": { - "requests": { - "oid": ".1.3.6.1.2.1.4.10.0", - "algorithm": "incremental", - "multiplier": 1, - "divisor": 1, - "offset": 0 + { + "hostname": "10.11.12.8", + "community": "public", + "update_every": 15, + "options": { + "timeout": 20000, + "version": 1 + }, + "charts": { + "snmp_switch.power": { + "title": "Switch Power Supply", + "units": "watts", + "type": "line", + "priority": 10, + "family": "power", + "dimensions": { + "supply": { + "oid": ".1.3.6.1.2.1.105.1.3.1.1.2.1", + "algorithm": "absolute", + "multiplier": 1, + "divisor": 1, + "offset": 0 + }, + "used": { + "oid": ".1.3.6.1.2.1.105.1.3.1.1.4.1", + "algorithm": "absolute", + "multiplier": 1, + "divisor": 1, + "offset": 0 + } } - , "discards": { - "oid": ".1.3.6.1.2.1.4.11.0", - "algorithm": "incremental", - "multiplier": -1, - "divisor": 1, - "offset": 0 + }, + "snmp_switch.input": { + "title": "Switch Packets Input", + "units": "packets/s", + "type": "area", + "priority": 20, + "family": "IP", + "dimensions": { + "receives": { + "oid": ".1.3.6.1.2.1.4.3.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + }, + "discards": { + "oid": ".1.3.6.1.2.1.4.8.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + } } - , "no_route": { - "oid": ".1.3.6.1.2.1.4.12.0", - "algorithm": "incremental", - "multiplier": -1, - "divisor": 1, - "offset": 0 + }, + "snmp_switch.input_errors": { + "title": "Switch Received Packets with Errors", + "units": "packets/s", + "type": "line", + "priority": 30, + "family": "IP", + "dimensions": { + "bad_header": { + "oid": ".1.3.6.1.2.1.4.4.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + }, + "bad_address": { + "oid": ".1.3.6.1.2.1.4.5.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + }, + "unknown_protocol": { + "oid": ".1.3.6.1.2.1.4.7.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + } } - } - } - , "snmp_switch.bandwidth_port": { - "title": "Switch Bandwidth for port ", - "titleoid": ".1.3.6.1.2.1.31.1.1.1.18.", - "units": "kilobits/s", - "type": "area", - "priority": 100, - "family": "ports", - "multiply_range": [ 1, 24 ], - "dimensions": { - "in": { - "oid": ".1.3.6.1.2.1.2.2.1.10.", - "algorithm": "incremental", - "multiplier": 8, - "divisor": 1024, - "offset": 0 + }, + "snmp_switch.output": { + "title": "Switch Output Packets", + "units": "packets/s", + "type": "line", + "priority": 40, + "family": "IP", + "dimensions": { + "requests": { + "oid": ".1.3.6.1.2.1.4.10.0", + "algorithm": "incremental", + "multiplier": 1, + "divisor": 1, + "offset": 0 + }, + "discards": { + "oid": ".1.3.6.1.2.1.4.11.0", + "algorithm": "incremental", + "multiplier": -1, + "divisor": 1, + "offset": 0 + }, + "no_route": { + "oid": ".1.3.6.1.2.1.4.12.0", + "algorithm": "incremental", + "multiplier": -1, + "divisor": 1, + "offset": 0 + } } - , "out": { - "oid": ".1.3.6.1.2.1.2.2.1.16.", - "algorithm": "incremental", - "multiplier": -8, - "divisor": 1024, - "offset": 0 + }, + "snmp_switch.bandwidth_port": { + "title": "Switch Bandwidth for port ", + "titleoid": ".1.3.6.1.2.1.31.1.1.1.18.", + "units": "kilobits/s", + "type": "area", + "priority": 100, + "family": "ports", + "multiply_range": [ + 1, + 24 + ], + "dimensions": { + "in": { + "oid": ".1.3.6.1.2.1.2.2.1.10.", + "algorithm": "incremental", + "multiplier": 8, + "divisor": 1024, + "offset": 0 + }, + "out": { + "oid": ".1.3.6.1.2.1.2.2.1.16.", + "algorithm": "incremental", + "multiplier": -8, + "divisor": 1024, + "offset": 0 + } } } } } - }], + ] } ``` diff --git a/collectors/node.d.plugin/snmp/snmp.node.js b/collectors/node.d.plugin/snmp/snmp.node.js index 6b33ae0d5..ca3f0bfbc 100644 --- a/collectors/node.d.plugin/snmp/snmp.node.js +++ b/collectors/node.d.plugin/snmp/snmp.node.js @@ -117,53 +117,53 @@ var net_snmp = require('net-snmp'); var extend = require('extend'); var netdata = require('netdata'); -if(netdata.options.DEBUG === true) netdata.debug('loaded', __filename, ' plugin'); +if (netdata.options.DEBUG === true) netdata.debug('loaded', __filename, ' plugin'); netdata.processors.snmp = { name: 'snmp', - fixoid: function(oid) { - if(typeof oid !== 'string') + fixoid: function (oid) { + if (typeof oid !== 'string') return oid; - if(oid.charAt(0) === '.') + if (oid.charAt(0) === '.') return oid.substring(1, oid.length); return oid; }, - prepare: function(service) { + prepare: function (service) { var __DEBUG = netdata.options.DEBUG; - if(typeof service.snmp_oids === 'undefined' || service.snmp_oids === null || service.snmp_oids.length === 0) { + if (typeof service.snmp_oids === 'undefined' || service.snmp_oids === null || service.snmp_oids.length === 0) { // this is the first time we see this service - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': preparing ' + this.name + ' OIDs'); // build an index of all OIDs service.snmp_oids_index = {}; var chart_keys = Object.keys(service.request.charts); var chart_keys_len = chart_keys.length; - while(chart_keys_len--) { + while (chart_keys_len--) { var c = chart_keys[chart_keys_len]; var chart = service.request.charts[c]; // for each chart - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': indexing ' + this.name + ' chart: ' + c); - if(typeof chart.titleoid !== 'undefined') { - service.snmp_oids_index[this.fixoid(chart.titleoid)] = { - type: 'title', - link: chart - }; - } + if (typeof chart.titleoid !== 'undefined') { + service.snmp_oids_index[this.fixoid(chart.titleoid)] = { + type: 'title', + link: chart + }; + } var dim_keys = Object.keys(chart.dimensions); var dim_keys_len = dim_keys.length; - while(dim_keys_len--) { + while (dim_keys_len--) { var d = dim_keys[dim_keys_len]; var dim = chart.dimensions[d]; @@ -172,7 +172,7 @@ netdata.processors.snmp = { var oid = this.fixoid(dim.oid); var oidname = this.fixoid(dim.oidname); - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': indexing ' + this.name + ' chart: ' + c + ', dimension: ' + d + ', OID: ' + oid + ", OID name: " + oidname); // link it to the point we need to set the value to @@ -181,7 +181,7 @@ netdata.processors.snmp = { link: dim }; - if(typeof oidname !== 'undefined') + if (typeof oidname !== 'undefined') service.snmp_oids_index[oidname] = { type: 'name', link: dim @@ -192,18 +192,17 @@ netdata.processors.snmp = { } } - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': indexed ' + this.name + ' OIDs: ' + netdata.stringify(service.snmp_oids_index)); // now create the array of OIDs needed by net-snmp service.snmp_oids = Object.keys(service.snmp_oids_index); - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': final list of ' + this.name + ' OIDs: ' + netdata.stringify(service.snmp_oids)); service.snmp_oids_cleaned = 0; - } - else if(service.snmp_oids_cleaned === 0) { + } else if (service.snmp_oids_cleaned === 0) { service.snmp_oids_cleaned = 1; // the second time, keep only values @@ -211,87 +210,82 @@ netdata.processors.snmp = { service.snmp_oids = new Array(); var oid_keys = Object.keys(service.snmp_oids_index); var oid_keys_len = oid_keys.length; - while(oid_keys_len--) { + while (oid_keys_len--) { if (service.snmp_oids_index[oid_keys[oid_keys_len]].type === 'value') service.snmp_oids.push(oid_keys[oid_keys_len]); } } }, - getdata: function(service, index, ok, failed, callback) { + getdata: function (service, index, ok, failed, callback) { var __DEBUG = netdata.options.DEBUG; var that = this; - if(index >= service.snmp_oids.length) { - callback((ok > 0)?{ ok: ok, failed: failed }:null); + if (index >= service.snmp_oids.length) { + callback((ok > 0) ? {ok: ok, failed: failed} : null); return; } var slice; - if(service.snmp_oids.length <= service.request.max_request_size) { + if (service.snmp_oids.length <= service.request.max_request_size) { slice = service.snmp_oids; index = service.snmp_oids.length; - } - else if(service.snmp_oids.length - index <= service.request.max_request_size) { + } else if (service.snmp_oids.length - index <= service.request.max_request_size) { slice = service.snmp_oids.slice(index, service.snmp_oids.length); index = service.snmp_oids.length; - } - else { + } else { slice = service.snmp_oids.slice(index, index + service.request.max_request_size); index += service.request.max_request_size; } - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': making ' + slice.length + ' entries request, max is: ' + service.request.max_request_size); - service.snmp_session.get(slice, function(error, varbinds) { - if(error) { + service.snmp_session.get(slice, function (error, varbinds) { + if (error) { service.error('Received error = ' + netdata.stringify(error) + ' varbinds = ' + netdata.stringify(varbinds)); // make all values null var len = slice.length; - while(len--) + while (len--) service.snmp_oids_index[slice[len]].value = null; - } - else { - if(__DEBUG === true) + } else { + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': got valid ' + service.module.name + ' response: ' + netdata.stringify(varbinds)); var varbinds_len = varbinds.length; - for(var i = 0; i < varbinds_len ; i++) { + for (var i = 0; i < varbinds_len; i++) { var value = null; - if(net_snmp.isVarbindError(varbinds[i])) { - if(__DEBUG === true) + if (net_snmp.isVarbindError(varbinds[i])) { + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': failed ' + service.module.name + ' get for OIDs ' + varbinds[i].oid); service.error('OID ' + varbinds[i].oid + ' gave error: ' + net_snmp.varbindError(varbinds[i])); value = null; failed++; - } - else { + } else { // test fom Counter64 // varbinds[i].type = net_snmp.ObjectType.Counter64; // varbinds[i].value = new Buffer([0x34, 0x49, 0x2e, 0xdc, 0xd1]); - switch(varbinds[i].type) { + switch (varbinds[i].type) { case net_snmp.ObjectType.OctetString: if (service.snmp_oids_index[varbinds[i].oid].type !== 'title' && service.snmp_oids_index[varbinds[i].oid].type !== 'name') { // parse floating point values, exposed as strings value = parseFloat(varbinds[i].value) * 1000; - if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof(varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as float in string)"); - } - else { + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof (varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as float in string)"); + } else { // just use the string value = varbinds[i].value; - if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof(varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as string)"); + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof (varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as string)"); } break; case net_snmp.ObjectType.Counter64: // copy the buffer value = '0x' + varbinds[i].value.toString('hex'); - if(__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof(varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as buffer)"); + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof (varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as buffer)"); break; case net_snmp.ObjectType.Integer: @@ -299,55 +293,73 @@ netdata.processors.snmp = { case net_snmp.ObjectType.Gauge: default: value = varbinds[i].value; - if(__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof(varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as number)"); + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + ", ObjectType " + net_snmp.ObjectType[varbinds[i].type] + " (" + netdata.stringify(varbinds[i].type) + "), typeof(" + typeof (varbinds[i].value) + "), in JSON: " + netdata.stringify(varbinds[i].value) + ", value = " + value.toString() + " (parsed as number)"); break; } ok++; } - if(value !== null) { - switch(service.snmp_oids_index[varbinds[i].oid].type) { - case 'title': service.snmp_oids_index[varbinds[i].oid].link.title += ' ' + value; break; - case 'name' : service.snmp_oids_index[varbinds[i].oid].link.name = value.toString().replace(/\W/g, '_'); break; - case 'value': service.snmp_oids_index[varbinds[i].oid].link.value = value; break; + if (value !== null) { + switch (service.snmp_oids_index[varbinds[i].oid].type) { + case 'title': + service.snmp_oids_index[varbinds[i].oid].link.title += ' ' + value; + break; + case 'name' : + service.snmp_oids_index[varbinds[i].oid].link.name = value.toString().replace(/\W/g, '_'); + break; + case 'value': + service.snmp_oids_index[varbinds[i].oid].link.value = value; + break; } } } - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': finished ' + service.module.name + ' with ' + ok + ' successful and ' + failed + ' failed values'); } that.getdata(service, index, ok, failed, callback); }); }, - process: function(service, callback) { + process: function (service, callback) { var __DEBUG = netdata.options.DEBUG; this.prepare(service); - if(service.snmp_oids.length === 0) { + if (service.snmp_oids.length === 0) { // no OIDs found for this service - if(__DEBUG === true) + if (__DEBUG === true) service.error('no OIDs to process.'); callback(null); return; } - if(typeof service.snmp_session === 'undefined' || service.snmp_session === null) { + if (typeof service.snmp_session === 'undefined' || service.snmp_session === null) { // no SNMP session has been created for this service // the SNMP session is just the initialization of NET-SNMP - if(__DEBUG === true) - netdata.debug(service.module.name + ': ' + service.name + ': opening ' + this.name + ' session on ' + service.request.hostname + ' community ' + service.request.community + ' options ' + netdata.stringify(service.request.options)); + var snmp_version = (service.request.options && service.request.options.version) + ? service.request.options.version + : net_snmp.Version1; - // create the SNMP session - service.snmp_session = net_snmp.createSession (service.request.hostname, service.request.community, service.request.options); + if (snmp_version === net_snmp.Version3) { + if (__DEBUG === true) + netdata.debug(service.module.name + ': ' + service.name + ': opening ' + this.name + ' session on ' + service.request.hostname + ' user ' + service.request.user + ' options ' + netdata.stringify(service.request.options)); - if(__DEBUG === true) + // create the SNMP session + service.snmp_session = net_snmp.createV3Session(service.request.hostname, service.request.user, service.request.options); + } else { + if (__DEBUG === true) + netdata.debug(service.module.name + ': ' + service.name + ': opening ' + this.name + ' session on ' + service.request.hostname + ' community ' + service.request.community + ' options ' + netdata.stringify(service.request.options)); + + // create the SNMP session + service.snmp_session = net_snmp.createSession(service.request.hostname, service.request.community, service.request.options); + } + + if (__DEBUG === true) netdata.debug(service.module.name + ': ' + service.name + ': got ' + this.name + ' session: ' + netdata.stringify(service.snmp_session)); // if we later need traps, this is how to do it: @@ -369,18 +381,18 @@ var snmp = { charts: {}, - processResponse: function(service, data) { - if(data !== null) { - if(service.added !== true) + processResponse: function (service, data) { + if (data !== null) { + if (service.added !== true) service.commit(); var chart_keys = Object.keys(service.request.charts); var chart_keys_len = chart_keys.length; - for(var i = 0; i < chart_keys_len; i++) { + for (var i = 0; i < chart_keys_len; i++) { var c = chart_keys[i]; var chart = snmp.charts[c]; - if(typeof chart === 'undefined') { + if (typeof chart === 'undefined') { chart = service.chart(c, service.request.charts[c]); snmp.charts[c] = chart; } @@ -390,11 +402,11 @@ var snmp = { var dimensions = service.request.charts[c].dimensions; var dim_keys = Object.keys(dimensions); var dim_keys_len = dim_keys.length; - for(var j = 0; j < dim_keys_len ; j++) { + for (var j = 0; j < dim_keys_len; j++) { var d = dim_keys[j]; if (dimensions[d].value !== null) { - if(typeof dimensions[d].offset === 'number' && typeof dimensions[d].value === 'number') + if (typeof dimensions[d].offset === 'number' && typeof dimensions[d].value === 'number') service.set(d, dimensions[d].value + dimensions[d].offset); else service.set(d, dimensions[d].value); @@ -410,10 +422,10 @@ var snmp = { // this function is called only from this module // its purpose is to prepare the request and call // netdata.serviceExecute() - serviceExecute: function(conf) { + serviceExecute: function (conf) { var __DEBUG = netdata.options.DEBUG; - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(this.name + ': snmp hostname: ' + conf.hostname + ', update_every: ' + conf.update_every); var service = netdata.service({ @@ -427,41 +439,41 @@ var snmp = { // multiply the charts, if required var chart_keys = Object.keys(service.request.charts); var chart_keys_len = chart_keys.length; - for( var i = 0; i < chart_keys_len ; i++ ) { + for (var i = 0; i < chart_keys_len; i++) { var c = chart_keys[i]; var service_request_chart = service.request.charts[c]; - if(__DEBUG === true) + if (__DEBUG === true) netdata.debug(this.name + ': snmp hostname: ' + conf.hostname + ', examining chart: ' + c); - if(typeof service_request_chart.update_every === 'undefined') + if (typeof service_request_chart.update_every === 'undefined') service_request_chart.update_every = service.update_every; - if(typeof service_request_chart.multiply_range !== 'undefined') { + if (typeof service_request_chart.multiply_range !== 'undefined') { var from = service_request_chart.multiply_range[0]; var to = service_request_chart.multiply_range[1]; var prio = service_request_chart.priority || 1; - if(prio < snmp.base_priority) prio += snmp.base_priority; + if (prio < snmp.base_priority) prio += snmp.base_priority; - while(from <= to) { + while (from <= to) { var id = c + from.toString(); var chart = extend(true, {}, service_request_chart); chart.title += from.toString(); - if(typeof chart.titleoid !== 'undefined') + if (typeof chart.titleoid !== 'undefined') chart.titleoid += from.toString(); chart.priority = prio++; var dim_keys = Object.keys(chart.dimensions); var dim_keys_len = dim_keys.length; - for(var j = 0; j < dim_keys_len ; j++) { + for (var j = 0; j < dim_keys_len; j++) { var d = dim_keys[j]; chart.dimensions[d].oid += from.toString(); - if(typeof chart.dimensions[d].oidname !== 'undefined') + if (typeof chart.dimensions[d].oidname !== 'undefined') chart.dimensions[d].oidname += from.toString(); } service.request.charts[id] = chart; @@ -469,9 +481,8 @@ var snmp = { } delete service.request.charts[c]; - } - else { - if(service.request.charts[c].priority < snmp.base_priority) + } else { + if (service.request.charts[c].priority < snmp.base_priority) service.request.charts[c].priority += snmp.base_priority; } } @@ -479,19 +490,19 @@ var snmp = { service.execute(this.processResponse); }, - configure: function(config) { + configure: function (config) { var added = 0; - if(typeof config.max_request_size === 'undefined') + if (typeof config.max_request_size === 'undefined') config.max_request_size = 50; - if(typeof(config.servers) !== 'undefined') { + if (typeof (config.servers) !== 'undefined') { var len = config.servers.length; - while(len--) { - if(typeof config.servers[len].update_every === 'undefined') + while (len--) { + if (typeof config.servers[len].update_every === 'undefined') config.servers[len].update_every = this.update_every; - if(typeof config.servers[len].max_request_size === 'undefined') + if (typeof config.servers[len].max_request_size === 'undefined') config.servers[len].max_request_size = config.max_request_size; this.serviceExecute(config.servers[len]); @@ -505,8 +516,8 @@ var snmp = { // module.update() // this is called repeatidly to collect data, by calling // service.execute() - update: function(service, callback) { - service.execute(function(serv, data) { + update: function (service, callback) { + service.execute(function (serv, data) { service.module.processResponse(serv, data); callback(); }); diff --git a/collectors/node.d.plugin/stiebeleltron/README.md b/collectors/node.d.plugin/stiebeleltron/README.md index 80adc86b9..59bbf703c 100644 --- a/collectors/node.d.plugin/stiebeleltron/README.md +++ b/collectors/node.d.plugin/stiebeleltron/README.md @@ -1,6 +1,12 @@ -# stiebel eltron +<!-- +title: "Stiebel Eltron ISG monitoring with Netdata" +custom_edit_url: https://github.com/netdata/netdata/edit/master/collectors/node.d.plugin/stiebeleltron/README.md +sidebar_label: "Stiebel Eltron ISG" +--> -This module collects metrics from the configured heat pump and hot water installation from Stiebel Eltron ISG web. +# Stiebel Eltron ISG monitoring with Netdata + +Collects metrics from the configured heat pump and hot water installation from Stiebel Eltron ISG web. **Requirements** @@ -34,7 +40,7 @@ The charts are configurable, however, the provided default configuration collect - Heat circuit 1 room temperature in C (set/actual) - Heat circuit 2 room temperature in C (set/actual) -5. **Eletric Reheating** +5. **Electric Reheating** - Dual Mode Reheating temperature in C (hot water/heating) @@ -62,7 +68,7 @@ If no configuration is given, the module will be disabled. Each `update_every` i Original author: BrainDoctor (github) -The module supports any metrics that are parseable with RegEx. There is no API that gives direct access to the values (AFAIK), so the "workaround" is to parse the HTML output of the ISG. +The module supports any metrics that are parsable with RegEx. There is no API that gives direct access to the values (AFAIK), so the "workaround" is to parse the HTML output of the ISG. ### Testing |