Browse Source

Add smartsnmpd.

smartsnmpd is an implementation of SNMP Agent developed by Credo Semi. It
use Lua as script language to write SNMP MIB nodes to improve the efficiency
of developtment.

This package add native support for OpenWrt. Include using ubus and uci to
get status/info. And, it use uloop as low level event library. So it's
some sort of desgin for OpenWrt.

Website: https://github.com/credosemi/smartsnmp

Signed-off-by: Leo Ma <leoma@credosemi.com>
Signed-off-by: Xiongfei Guo <xfguo@credosemi.com>
Xiongfei Guo 10 years ago
parent
commit
6bfb2ef4bd

+ 75
- 0
net/smartsnmpd/Makefile View File

@@ -0,0 +1,75 @@
1
+#
2
+# Copyright (C) 2014 OpenWrt.org
3
+#
4
+# This is free software, licensed under the GNU General Public License v2.
5
+# See /LICENSE for more information.
6
+#
7
+
8
+include $(TOPDIR)/rules.mk
9
+
10
+PKG_NAME:=smartsnmpd
11
+PKG_VERSION:=2014-08-13
12
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
13
+
14
+PKG_SOURCE_PROTO:=git
15
+PKG_SOURCE_URL:=https://github.com/credosemi/smartsnmp.git
16
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
17
+PKG_SOURCE_VERSION:=fb93473d895f058b2d8975d3cfa280ae2a8ae98d
18
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
19
+PKG_MIRROR_MD5SUM:=
20
+
21
+
22
+PKG_MAINTAINER:=Xiongfei Guo <xfguo@credosemi.com>
23
+PKG_LICENSE:=GPL-2.0
24
+PKG_LICENSE_FILES:=LICENSE
25
+
26
+
27
+include $(INCLUDE_DIR)/package.mk
28
+include $(INCLUDE_DIR)/scons.mk
29
+
30
+define Package/smartsnmpd
31
+  SECTION:=net
32
+  CATEGORY:=Network
33
+  DEPENDS+=+lua +liblua +libubox +libuci-lua +libubus-lua
34
+  TITLE:=Smart-SNMP (Agent)
35
+  URL:=https://github.com/credosemi/smartsnmp
36
+endef
37
+
38
+define Package/smartsnmpd/description
39
+smartsnmpd is an implementation of SNMP Agent. Its goal is "Easily
40
+writing boring SNMP MIB with Lua". This package add native support
41
+for OpenWrt. Include using ubus and uci to get system info/status. 
42
+And, it use libubox/uloop as low level event-driven library.
43
+endef
44
+
45
+SCONS_OPTIONS += --transport=uloop
46
+
47
+define Build/Configure
48
+	(cd $(PKG_BUILD_DIR); \
49
+		$(SCONS_VARS) \
50
+		scons \
51
+			prefix=/usr \
52
+			$(SCONS_OPTIONS) \
53
+	)
54
+endef
55
+
56
+define Package/smartsnmpd/install
57
+	$(INSTALL_DIR) $(1)/usr/sbin
58
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/smartsnmpd $(1)/usr/sbin/smartsnmpd
59
+
60
+	$(INSTALL_DIR) $(1)/usr/lib/lua/smartsnmp
61
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/smartsnmp/core.so $(1)/usr/lib/lua/smartsnmp/core.so
62
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/lualib/smartsnmp/*.lua $(1)/usr/lib/lua/smartsnmp/
63
+
64
+	$(INSTALL_DIR) $(1)/usr/lib/lua/smartsnmp/mibs
65
+	$(INSTALL_BIN) ./files/mibs/*.lua $(1)/usr/lib/lua/smartsnmp/mibs/
66
+	
67
+	$(INSTALL_DIR) $(1)/etc/config
68
+	$(INSTALL_DATA) ./files/smartsnmpd.conf $(1)/etc/config/smartsnmpd
69
+
70
+	$(INSTALL_DIR) $(1)/etc/init.d
71
+	$(INSTALL_BIN) ./files/smartsnmpd.init $(1)/etc/init.d/smartsnmpd
72
+endef
73
+
74
+$(eval $(call BuildPackage,smartsnmpd))
75
+

+ 24
- 0
net/smartsnmpd/files/mibs/dummy.lua View File

@@ -0,0 +1,24 @@
1
+-- 
2
+-- This file is part of SmartSNMP
3
+-- Copyright (C) 2014, Credo Semiconductor Inc.
4
+-- 
5
+-- This program is free software; you can redistribute it and/or modify
6
+-- it under the terms of the GNU General Public License as published by
7
+-- the Free Software Foundation; either version 2 of the License, or
8
+-- (at your option) any later version.
9
+-- 
10
+-- This program is distributed in the hope that it will be useful,
11
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+-- GNU General Public License for more details.
14
+-- 
15
+-- You should have received a copy of the GNU General Public License along
16
+-- with this program; if not, write to the Free Software Foundation, Inc.,
17
+-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+-- 
19
+
20
+local mib = require "smartsnmp"
21
+
22
+local dummy = {}
23
+
24
+return dummy

+ 125
- 0
net/smartsnmpd/files/mibs/interfaces.lua View File

@@ -0,0 +1,125 @@
1
+-- 
2
+-- This file is part of SmartSNMP
3
+-- Copyright (C) 2014, Credo Semiconductor Inc.
4
+-- 
5
+-- This program is free software; you can redistribute it and/or modify
6
+-- it under the terms of the GNU General Public License as published by
7
+-- the Free Software Foundation; either version 2 of the License, or
8
+-- (at your option) any later version.
9
+-- 
10
+-- This program is distributed in the hope that it will be useful,
11
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+-- GNU General Public License for more details.
14
+-- 
15
+-- You should have received a copy of the GNU General Public License along
16
+-- with this program; if not, write to the Free Software Foundation, Inc.,
17
+-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+-- 
19
+
20
+local mib = require "smartsnmp"
21
+require "ubus"
22
+require "uloop"
23
+
24
+uloop.init()
25
+
26
+local conn = ubus.connect()
27
+if not conn then
28
+    error("Failed to connect to ubusd")
29
+end
30
+
31
+local if_cache = {}
32
+local if_status_cache = {}
33
+local if_index_cache = {}
34
+
35
+local last_load_time = os.time()
36
+local function need_to_reload()
37
+    if os.time() - last_load_time >= 3 then
38
+        last_load_time = os.time()
39
+        return true
40
+    else
41
+        return false
42
+    end
43
+end
44
+
45
+local function load_config()
46
+    if need_to_reload() == true then
47
+        if_cache = {}
48
+        if_status_cache = {}
49
+        if_index_cache = {}
50
+
51
+        -- if description
52
+        for k, v in pairs(conn:call("network.device", "status", {})) do
53
+            if_status_cache[k] = {}
54
+        end
55
+
56
+        for name_ in pairs(if_status_cache) do
57
+            for k, v in pairs(conn:call("network.device", "status", { name = name_ })) do
58
+                if k == 'mtu' then
59
+                    if_status_cache[name_].mtu = v
60
+                elseif k == 'macaddr' then
61
+                    if_status_cache[name_].macaddr = v
62
+                elseif k == 'up' then
63
+                    if v == true then            
64
+                        if_status_cache[name_].up = 1
65
+                    else
66
+                        if_status_cache[name_].up = 2
67
+                    end
68
+                elseif k == 'statistics' then
69
+                    for item, stat in pairs(v) do
70
+                        if item == 'rx_bytes' then
71
+                            if_status_cache[name_].in_octet = stat
72
+                        elseif item == 'tx_bytes' then
73
+                            if_status_cache[name_].out_octet = stat
74
+                        elseif item == 'rx_errors' then
75
+                            if_status_cache[name_].in_errors = stat
76
+                        elseif item == 'tx_errors' then
77
+                            if_status_cache[name_].out_errors = stat
78
+                        elseif item == 'rx_dropped' then
79
+                            if_status_cache[name_].in_discards = stat
80
+                        elseif item == 'tx_dropped' then
81
+                            if_status_cache[name_].out_discards = stat
82
+                        end
83
+                    end
84
+                end
85
+            end
86
+        end
87
+
88
+        if_cache['desc'] = {}
89
+        for name, status in pairs(if_status_cache) do
90
+            table.insert(if_cache['desc'], name)
91
+            for k, v in pairs(status) do
92
+                if if_cache[k] == nil then if_cache[k] = {} end
93
+                table.insert(if_cache[k], v)
94
+            end
95
+        end
96
+
97
+        -- if index
98
+        for i in ipairs(if_cache['desc']) do
99
+            table.insert(if_index_cache, i)
100
+        end
101
+    end
102
+end
103
+
104
+mib.module_methods.or_table_reg("1.3.6.1.2.1.2", "The MIB module for managing Interfaces implementations")
105
+
106
+local ifGroup = {
107
+    [1]  = mib.ConstInt(function () load_config() return #if_index_cache end),
108
+    [2] = {
109
+        [1] = {
110
+            [1] = mib.ConstIndex(function () load_config() return if_index_cache end),
111
+            [2] = mib.ConstString(function (i) load_config() return if_cache['desc'][i] end),
112
+            [4] = mib.ConstInt(function (i) load_config() return if_cache['mtu'][i] end),
113
+            [6] = mib.ConstString(function (i) load_config() return if_cache['macaddr'][i] end),
114
+            [8] = mib.ConstInt(function (i) load_config() return if_cache['up'][i] end),
115
+            [10] = mib.ConstCount(function (i) load_config() return if_cache['in_octet'][i] end),
116
+            [13] = mib.ConstCount(function (i) load_config() return if_cache['in_discards'][i] end),
117
+            [14] = mib.ConstCount(function (i) load_config() return if_cache['in_errors'][i] end),
118
+            [16] = mib.ConstCount(function (i) load_config() return if_cache['out_octet'][i] end),
119
+            [19] = mib.ConstCount(function (i) load_config() return if_cache['out_discards'][i] end),
120
+            [20] = mib.ConstCount(function (i) load_config() return if_cache['out_errors'][i] end),
121
+        }
122
+    }
123
+}
124
+
125
+return ifGroup

+ 176
- 0
net/smartsnmpd/files/mibs/system.lua View File

@@ -0,0 +1,176 @@
1
+-- 
2
+-- This file is part of SmartSNMP
3
+-- Copyright (C) 2014, Credo Semiconductor Inc.
4
+-- 
5
+-- This program is free software; you can redistribute it and/or modify
6
+-- it under the terms of the GNU General Public License as published by
7
+-- the Free Software Foundation; either version 2 of the License, or
8
+-- (at your option) any later version.
9
+-- 
10
+-- This program is distributed in the hope that it will be useful,
11
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+-- GNU General Public License for more details.
14
+-- 
15
+-- You should have received a copy of the GNU General Public License along
16
+-- with this program; if not, write to the Free Software Foundation, Inc.,
17
+-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+-- 
19
+
20
+local mib = require "smartsnmp"
21
+local uci = require "uci"
22
+
23
+-- System config
24
+local context = uci.cursor("/etc/config", "/tmp/.uci")
25
+
26
+-- scalar index
27
+local sysDesc             = 1
28
+local sysObjectID         = 2
29
+local sysUpTime           = 3
30
+local sysContact          = 4
31
+local sysName             = 5
32
+local sysLocation         = 6
33
+local sysServices         = 7
34
+local sysORLastChange     = 8
35
+
36
+-- table index
37
+local sysORTable          = 9
38
+
39
+-- entry index
40
+local sysOREntry          = 1
41
+
42
+-- list index
43
+local sysORIndex          = 1
44
+local sysORID             = 2
45
+local sysORDesc           = 3
46
+local sysORUpTime         = 4
47
+
48
+local startup_time = 0
49
+local or_last_changed_time = 0
50
+
51
+local function mib_system_startup(time)
52
+    startup_time = time
53
+    or_last_changed_time = time
54
+end
55
+
56
+mib_system_startup(os.time())
57
+
58
+local sysGroup = {}
59
+local or_oid_cache = {}
60
+local or_index_cache = {}
61
+local or_table_cache = {}
62
+
63
+local or_table_reg = function (oid, desc)
64
+    local row = {}
65
+    row['oid'] = {}
66
+    for i in string.gmatch(oid, "%d") do
67
+        table.insert(row['oid'], tonumber(i))
68
+    end
69
+    row['desc'] = desc
70
+    row['uptime'] = os.time()
71
+    table.insert(or_table_cache, row)
72
+    
73
+    or_last_changed_time = os.time()
74
+
75
+    or_oid_cache[oid] = #or_table_cache
76
+
77
+    or_index_cache = {}
78
+    for i in ipairs(or_table_cache) do
79
+        table.insert(or_index_cache, i)
80
+    end
81
+end
82
+
83
+local or_table_unreg = function (oid)
84
+    local or_idx = or_oid_cache[oid]
85
+
86
+    if or_table_cache[or_idx] ~= nil then
87
+        table.remove(or_table_cache, or_idx)
88
+        or_last_changed_time = os.time()
89
+
90
+        or_index_cache = {}
91
+        for i in ipairs(or_table_cache) do
92
+            table.insert(or_index_cache, i)
93
+        end
94
+    end
95
+end
96
+
97
+local last_load_time = os.time()
98
+local function need_to_reload()
99
+    if os.difftime(os.time(), last_load_time) < 3 then
100
+        return false
101
+    else
102
+        last_load_time = os.time()
103
+        return true
104
+    end
105
+end
106
+
107
+local function load_config()
108
+    if need_to_reload() == true then
109
+        context:load("smartsnmpd")
110
+    end
111
+end
112
+
113
+context:load("smartsnmpd")
114
+
115
+local sysMethods = {
116
+    ["or_table_reg"] = or_table_reg, 
117
+    ["or_table_unreg"] = or_table_unreg
118
+}
119
+mib.module_method_register(sysMethods)
120
+
121
+sysGroup = {
122
+    rocommunity = 'public',
123
+    [sysDesc]         = mib.ConstString(function () load_config() return mib.sh_call("uname -a") end),
124
+    [sysObjectID]     = mib.ConstOid(function ()
125
+                                         load_config()
126
+                                         local oid
127
+                                         local objectid
128
+                                         context:foreach("smartsnmpd", "smartsnmpd", function (s)
129
+                                             objectid = s.objectid
130
+                                         end)
131
+                                         if objectid ~= nil then
132
+                                            oid = {}
133
+                                            for i in string.gmatch(objectid, "%d+") do
134
+                                                table.insert(oid, tonumber(i))
135
+                                            end
136
+                                         end
137
+                                         return oid
138
+                                     end),
139
+    [sysUpTime]       = mib.ConstTimeticks(function () load_config() return os.difftime(os.time(), startup_time) * 100 end),
140
+    [sysContact]      = mib.ConstString(function () 
141
+                                            load_config()
142
+                                            local contact
143
+                                            context:foreach("smartsnmpd", "smartsnmpd", function (s)
144
+                                                contact = s.contact
145
+                                            end)
146
+                                            return contact
147
+                                        end),
148
+    [sysName]         = mib.ConstString(function () load_config() return mib.sh_call("uname -n") end),
149
+    [sysLocation]     = mib.ConstString(function ()
150
+                                            load_config()
151
+                                            local location
152
+                                            context:foreach("smartsnmpd", "smartsnmpd", function (s)
153
+                                                location = s.location
154
+                                            end)
155
+                                            return location
156
+                                        end),
157
+    [sysServices]     = mib.ConstInt(function ()
158
+                                         load_config()
159
+                                         local services
160
+                                         context:foreach("smartsnmpd", "smartsnmpd", function (s)
161
+                                             services = tonumber(s.services)
162
+                                         end)
163
+                                         return services
164
+                                     end),
165
+    [sysORLastChange] = mib.ConstTimeticks(function () load_config() return os.difftime(os.time(), or_last_changed_time) * 100 end),
166
+    [sysORTable]      = {
167
+        [sysOREntry]  = {
168
+            [sysORIndex]  = mib.UnaIndex(function () load_config() return or_index_cache end),
169
+            [sysORID]     = mib.ConstOid(function (i) load_config() return or_table_cache[i].oid end),
170
+            [sysORDesc]   = mib.ConstString(function (i) load_config() return or_table_cache[i].desc end),
171
+            [sysORUpTime] = mib.ConstTimeticks(function (i) load_config() return os.difftime(os.time(), or_table_cache[i].uptime) * 100 end),
172
+        }
173
+    }
174
+}
175
+
176
+return sysGroup

+ 21
- 0
net/smartsnmpd/files/smartsnmpd.conf View File

@@ -0,0 +1,21 @@
1
+config smartsnmpd
2
+	option port '161'
3
+	option ro_community 'public'
4
+	option rw_community 'private'
5
+	option mib_module_path 'mibs'
6
+	option objectid '1.2.3.4'
7
+	option contact 'Me <me@example.org>'
8
+	option location 'Shanghai'
9
+	option services '72'
10
+
11
+config smartsnmpd_module
12
+	option oid    "1.3.6.1.2.1.1" 
13
+	option module 'system'
14
+
15
+config smartsnmpd_module
16
+	option oid    "1.3.6.1.2.1.2" 
17
+	option module 'interfaces'
18
+
19
+config smartsnmpd_module
20
+	option oid    "1.3.6.1.1"     
21
+	option module 'dummy'

+ 47
- 0
net/smartsnmpd/files/smartsnmpd.init View File

@@ -0,0 +1,47 @@
1
+#!/bin/sh /etc/rc.common
2
+# Copyright (C) 2014 OpenWrt.org
3
+
4
+START=97
5
+
6
+USE_PROCD=1
7
+PROG=/usr/sbin/smartsnmpd
8
+CONFIGFILE=/etc/smartsnmpd.conf
9
+
10
+smartsnmpd_mib_module() {
11
+	local cfg="$1"
12
+	config_get OID "$cfg" oid
13
+	config_get MODULE "$cfg" module
14
+	echo "    ['$OID'] = '$MODULE'," >> $CONFIGFILE
15
+}
16
+
17
+start_service() {
18
+	include /lib/functions
19
+
20
+	config_load smartsnmpd
21
+
22
+	procd_open_instance
23
+	procd_set_param command $PROG -c $CONFIGFILE
24
+	procd_set_param file $CONFIGFILE
25
+	procd_set_param respawn
26
+	procd_close_instance
27
+	
28
+	# before we can call xappend
29
+	mkdir -p $(dirname $CONFIGFILE)
30
+
31
+	echo "-- auto-generated config file from /etc/config/smartsnmpd" > $CONFIGFILE
32
+	
33
+	config_get PORT smartsnmpd port 161
34
+	echo "port = $PORT" >> $CONFIGFILE
35
+	
36
+	config_get RO_COMMUNITY smartsnmpd ro_community 'public'
37
+	config_get RW_COMMUNITY smartsnmpd rw_community 'private'
38
+	echo "ro_community = '$RO_COMMUNITY'" >> $CONFIGFILE
39
+	echo "rw_community = '$RW_COMMUNITY'" >> $CONFIGFILE
40
+
41
+	config_get MIB_MODULE_PATH smartsnmpd mib_module_path '/usr/lib/lua/smartsnmp/mibs/'
42
+	echo "mib_module_path = '$MIB_MODULE_PATH'" >> $CONFIGFILE
43
+
44
+	echo "mib_modules = {" >> $CONFIGFILE
45
+	config_foreach smartsnmpd_mib_module smartsnmpd_module 
46
+	echo "}" >> $CONFIGFILE
47
+}