aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/examples
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/snmp/examples
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/snmp/examples')
-rw-r--r--lib/snmp/examples/Makefile35
-rw-r--r--lib/snmp/examples/ex1/EX1-MIB.funcs2
-rw-r--r--lib/snmp/examples/ex1/EX1-MIB.mib90
-rw-r--r--lib/snmp/examples/ex1/EX1-MIBv2.funcs2
-rw-r--r--lib/snmp/examples/ex1/EX1-MIBv2.mib104
-rw-r--r--lib/snmp/examples/ex1/Makefile97
-rw-r--r--lib/snmp/examples/ex1/ex1.erl256
-rw-r--r--lib/snmp/examples/ex2/Makefile93
-rw-r--r--lib/snmp/examples/ex2/snmp_ex2_manager.erl407
-rw-r--r--lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl287
-rw-r--r--lib/snmp/examples/mcli/.gitignore0
-rw-r--r--lib/snmp/examples/subdirs.mk21
12 files changed, 1394 insertions, 0 deletions
diff --git a/lib/snmp/examples/Makefile b/lib/snmp/examples/Makefile
new file mode 100644
index 0000000000..341107ce30
--- /dev/null
+++ b/lib/snmp/examples/Makefile
@@ -0,0 +1,35 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Common Macros
+# ----------------------------------------------------
+
+include subdirs.mk
+
+SPECIAL_TARGETS =
+
+# ----------------------------------------------------
+# Default Subdir Targets
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_subdir.mk
+
diff --git a/lib/snmp/examples/ex1/EX1-MIB.funcs b/lib/snmp/examples/ex1/EX1-MIB.funcs
new file mode 100644
index 0000000000..0ae1db6541
--- /dev/null
+++ b/lib/snmp/examples/ex1/EX1-MIB.funcs
@@ -0,0 +1,2 @@
+{myName, {ex1, my_name, []}}.
+{friendsTable, {ex1, friends_table, []}}.
diff --git a/lib/snmp/examples/ex1/EX1-MIB.mib b/lib/snmp/examples/ex1/EX1-MIB.mib
new file mode 100644
index 0000000000..5d9979d0b4
--- /dev/null
+++ b/lib/snmp/examples/ex1/EX1-MIB.mib
@@ -0,0 +1,90 @@
+ EX1-MIB DEFINITIONS ::= BEGIN
+
+ IMPORTS
+ experimental FROM RFC1155-SMI
+ RowStatus FROM STANDARD-MIB
+ DisplayString FROM RFC1213-MIB
+ OBJECT-TYPE FROM RFC-1212
+ ;
+
+ example1 OBJECT IDENTIFIER ::= { experimental 7 }
+
+
+ myName OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "My own name"
+ ::= { example1 1 }
+
+ friendsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF FriendsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A list of friends."
+ ::= { example1 4 }
+
+ friendsEntry OBJECT-TYPE
+ SYNTAX FriendsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ ""
+ INDEX { fIndex }
+ ::= { friendsTable 1 }
+
+ FriendsEntry ::=
+ SEQUENCE {
+ fIndex
+ INTEGER,
+ fName
+ DisplayString,
+ fAddress
+ DisplayString,
+ fStatus
+ RowStatus }
+
+ fIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "number of friend"
+ ::= { friendsEntry 1 }
+
+ fName OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "Name of friend"
+ ::= { friendsEntry 2 }
+
+ fAddress OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "Address of friend"
+ ::= { friendsEntry 3 }
+
+ fStatus OBJECT-TYPE
+ SYNTAX RowStatus
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The status of this conceptual row."
+ ::= { friendsEntry 4 }
+
+
+ fTrap TRAP-TYPE
+ ENTERPRISE example1
+ VARIABLES { myName, fIndex }
+ DESCRIPTION
+ "This trap is sent something happens to
+ the friend specified by fIndex."
+ ::= 1
+
+ END
diff --git a/lib/snmp/examples/ex1/EX1-MIBv2.funcs b/lib/snmp/examples/ex1/EX1-MIBv2.funcs
new file mode 100644
index 0000000000..0ae1db6541
--- /dev/null
+++ b/lib/snmp/examples/ex1/EX1-MIBv2.funcs
@@ -0,0 +1,2 @@
+{myName, {ex1, my_name, []}}.
+{friendsTable, {ex1, friends_table, []}}.
diff --git a/lib/snmp/examples/ex1/EX1-MIBv2.mib b/lib/snmp/examples/ex1/EX1-MIBv2.mib
new file mode 100644
index 0000000000..e7250c4a63
--- /dev/null
+++ b/lib/snmp/examples/ex1/EX1-MIBv2.mib
@@ -0,0 +1,104 @@
+EX1-MIBv2 DEFINITIONS ::= BEGIN
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
+ Integer32, snmpModules ,experimental
+ FROM SNMPv2-SMI
+ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP
+ FROM SNMPv2-CONF
+ DisplayString
+ FROM SNMPv2-TC
+ RowStatus
+ FROM STANDARD-MIB;
+
+
+exampleModule MODULE-IDENTITY
+ LAST-UPDATED "0005290000Z"
+ ORGANIZATION "Erlang"
+ CONTACT-INFO " test mib
+ Ericsson Utvecklings AB
+ Open System
+ Box 1505
+ SE-125 25 �LVSJ�"
+
+ DESCRIPTION
+ " Objects for management "
+ REVISION "0005290000Z"
+ DESCRIPTION
+ "The initial version"
+ ::= { snmpModules 1 }
+
+example1 OBJECT IDENTIFIER ::= { experimental 7}
+
+
+ myName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "My own name"
+ ::= { example1 1 }
+
+ friendsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF FriendsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of friends."
+ ::= { example1 4 }
+
+ friendsEntry OBJECT-TYPE
+ SYNTAX FriendsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ ""
+ INDEX { fIndex }
+ ::= { friendsTable 1 }
+
+ FriendsEntry ::= SEQUENCE {
+ fIndex INTEGER,
+ fName DisplayString,
+ fAddress DisplayString,
+ fStatus RowStatus
+ }
+
+ fIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "number of friend"
+ ::= { friendsEntry 1 }
+
+ fName OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ MAX-ACCESS read-write
+ STATUS deprecated
+ DESCRIPTION
+ "Name of a friend"
+ ::= { friendsEntry 2 }
+
+ fAddress OBJECT-TYPE
+ SYNTAX DisplayString (SIZE (0..255))
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "Address of a friend"
+ ::= { friendsEntry 3 }
+
+ fStatus OBJECT-TYPE
+ SYNTAX RowStatus
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The status of this conceptual row."
+ ::= { friendsEntry 4 }
+
+friendGroup OBJECT-GROUP
+ OBJECTS { myName, fIndex, fName,fAddress, fStatus }
+ STATUS current
+ DESCRIPTION " A object group"
+ ::= { example1 2 }
+
+END
diff --git a/lib/snmp/examples/ex1/Makefile b/lib/snmp/examples/ex1/Makefile
new file mode 100644
index 0000000000..1a55ba0470
--- /dev/null
+++ b/lib/snmp/examples/ex1/Makefile
@@ -0,0 +1,97 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+
+VSN = $(SNMP_VSN)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ifneq ($(MIBS_VERBOSITY),)
+SNMP_FLAGS += +'{verbosity,$(MIBS_VERBOSITY)}'
+endif
+
+ERL_COMPILE_FLAGS += -I../include \
+ -Dversion=\"$(VSN)$(PRE_VSN)\" \
+ +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ -I$(ERL_TOP)/lib/stdlib \
+ $(SNMP_FLAGS)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
+EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples
+EX1_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/ex1
+
+# ----------------------------------------------------
+# Common macros
+# ----------------------------------------------------
+
+ERL_FILES = ex1.erl
+MIB_FILES = EX1-MIB.funcs EX1-MIB.mib
+BUILD_MIBS = EX1-MIB
+
+TARGET_FILES= \
+ $(BUILD_MIBS:%=%.bin) \
+ $(ERL_FILES:%.erl=%.$(EMULATOR))
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+debug opt: build
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+build: $(TARGET_FILES)
+
+
+info:
+ @echo "TARGET_FILES: $(TARGET_FILES)"
+ @echo "EXAMPLE_FILES: $(EXAMPLE_FILES)"
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(EXAMPLE_RELSYSDIR)
+ $(INSTALL_DIR) $(EX1_RELSYSDIR)
+ $(INSTALL_DATA) $(MIB_FILES) $(EX1_RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(EX1_RELSYSDIR)
+ $(INSTALL_DATA) $(TARGET_FILES) $(EX1_RELSYSDIR)
+
+release_docs_spec:
diff --git a/lib/snmp/examples/ex1/ex1.erl b/lib/snmp/examples/ex1/ex1.erl
new file mode 100644
index 0000000000..3618cd3b8c
--- /dev/null
+++ b/lib/snmp/examples/ex1/ex1.erl
@@ -0,0 +1,256 @@
+%%<copyright>
+%% <year>1996-2007</year>
+%% <holder>Ericsson AB, All Rights Reserved</holder>
+%%</copyright>
+%%<legalnotice>
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% The Initial Developer of the Original Code is Ericsson AB.
+%%</legalnotice>
+%%
+-module(ex1).
+
+%% External exports
+-export([start/0, my_name/1, my_name/2, friends_table/3]).
+
+%% Internal exports
+-export([init/0]).
+
+-define(status_col, 4).
+
+-define(active, 1).
+-define(notInService, 2).
+-define(notReady, 3).
+-define(createAndGo, 4). % Action; written, not read
+-define(createAndWait, 5). % Action; written, not read
+-define(destroy, 6). % Action; written, not read
+
+start() ->
+ spawn(ex1, init, []).
+
+
+%%----------------------------------------------------------------
+%% Instrumentation function for variable myName.
+%% Returns: (get) {value, Name}
+%% (set) noError
+%%----------------------------------------------------------------
+my_name(get) ->
+ ex1_server ! {self(), get_my_name},
+ Name = wait_answer(),
+ {value, Name}.
+
+my_name(set, NewName) ->
+ ex1_server ! {self(), {set_my_name, NewName}},
+ noError.
+
+%%----------------------------------------------------------------
+%% Instrumentation function for table friendsTable.
+%%----------------------------------------------------------------
+friends_table(get, RowIndex, Cols) ->
+ case get_row(RowIndex) of
+ {ok, Row} ->
+ get_cols(Cols, Row);
+ _ ->
+ {noValue, noSuchInstance}
+ end;
+
+friends_table(get_next, RowIndex, Cols) ->
+ case get_next_row(RowIndex) of
+ {ok, Row} ->
+ get_next_cols(Cols, Row);
+ _ ->
+ case get_next_row([]) of
+ {ok, Row} ->
+ % Get next cols from first row.
+ NewCols = add_one_to_cols(Cols),
+ get_next_cols(NewCols, Row);
+ _ ->
+ end_of_table(Cols)
+ end
+ end;
+
+%%----------------------------------------------------------------
+%% If RowStatus is set, then:
+%% *) If set to destroy, check that row does exist
+%% *) If set to createAndGo, check that row doesn't exist AND
+%% that all columns are given values.
+%% *) Otherwise, error (for simplicity).
+%% Otherwise, row is modified; check that row exists.
+%%----------------------------------------------------------------
+friends_table(is_set_ok, RowIndex, Cols) ->
+ RowExists =
+ case get_row(RowIndex) of
+ {ok, _Row} -> true;
+ _ -> false
+ end,
+ case is_row_status_col_changed(Cols) of
+ {true, ?destroy} when RowExists == true ->
+ {noError, 0};
+ {true, ?createAndGo} when RowExists == false,
+ length(Cols) == 3 ->
+ {noError, 0};
+ {true, _} ->
+ {inconsistentValue, ?status_col};
+ false when RowExists == true ->
+ {noError, 0};
+ _ ->
+ [{Col, _NewVal} | _Cols] = Cols,
+ {inconsistentName, Col}
+ end;
+
+friends_table(set, RowIndex, Cols) ->
+ case is_row_status_col_changed(Cols) of
+ {true, ?destroy} ->
+ ex1_server ! {self(), {delete_row, RowIndex}};
+ {true, ?createAndGo} ->
+ NewRow = make_row(RowIndex, Cols),
+ ex1_server ! {self(), {add_row, NewRow}};
+ false ->
+ {ok, Row} = get_row(RowIndex),
+ NewRow = merge_rows(Row, Cols),
+ ex1_server ! {self(), {delete_row, RowIndex}},
+ ex1_server ! {self(), {add_row, NewRow}}
+ end,
+ {noError, 0}.
+
+%%----------------------------------------------------------------
+%% Make a list of {value, Val} of the Row and Cols list.
+%%----------------------------------------------------------------
+get_cols([Col | Cols], Row) ->
+ [{value, element(Col, Row)} | get_cols(Cols, Row)];
+get_cols([], _Row) ->
+ [].
+
+%%----------------------------------------------------------------
+%% As get_cols, but the Cols list may contain invalid column
+%% numbers. If it does, we must find the next valid column,
+%% or return endOfTable.
+%%----------------------------------------------------------------
+get_next_cols([Col | Cols], Row) when Col < 2 ->
+ [{[2, element(1, Row)], element(2, Row)} |
+ get_next_cols(Cols, Row)];
+get_next_cols([Col | Cols], Row) when Col > 4 ->
+ [endOfTable |
+ get_next_cols(Cols, Row)];
+get_next_cols([Col | Cols], Row) ->
+ [{[Col, element(1, Row)], element(Col, Row)} |
+ get_next_cols(Cols, Row)];
+get_next_cols([], _Row) ->
+ [].
+
+%%----------------------------------------------------------------
+%% Make a list of endOfTable with as many elems as Cols list.
+%%----------------------------------------------------------------
+end_of_table([_Col | Cols]) ->
+ [endOfTable | end_of_table(Cols)];
+end_of_table([]) ->
+ [].
+
+add_one_to_cols([Col | Cols]) ->
+ [Col + 1 | add_one_to_cols(Cols)];
+add_one_to_cols([]) ->
+ [].
+
+is_row_status_col_changed(Cols) ->
+ case lists:keysearch(?status_col, 1, Cols) of
+ {value, {?status_col, StatusVal}} ->
+ {true, StatusVal};
+ _ -> false
+ end.
+
+get_row(RowIndex) ->
+ ex1_server ! {self(), {get_row, RowIndex}},
+ wait_answer().
+
+get_next_row(RowIndex) ->
+ ex1_server ! {self(), {get_next_row, RowIndex}},
+ wait_answer().
+
+wait_answer() ->
+ receive
+ {ex1_server, Answer} ->
+ Answer
+ end.
+
+%%%----------------------------------------------------------------
+%%% Server code follows
+%%%----------------------------------------------------------------
+init() ->
+ register(ex1_server, self()),
+ loop("", []).
+
+loop(MyName, Table) ->
+ receive
+ {From, get_my_name} ->
+ From ! {ex1_server, MyName},
+ loop(MyName, Table);
+ {_From, {set_my_name, NewName}} ->
+ loop(NewName, Table);
+ {From, {get_row, RowIndex}} ->
+ Res = table_get_row(Table, RowIndex),
+ From ! {ex1_server, Res},
+ loop(MyName, Table);
+ {From, {get_next_row, RowIndex}} ->
+ Res = table_get_next_row(Table, RowIndex),
+ From ! {ex1_server, Res},
+ loop(MyName, Table);
+ {_From, {delete_row, RowIndex}} ->
+ NewTable = table_delete_row(Table, RowIndex),
+ loop(MyName, NewTable);
+ {_From, {add_row, NewRow}} ->
+ NewTable = table_add_row(Table, NewRow),
+ loop(MyName, NewTable)
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Implementation of the table.
+%%-----------------------------------------------------------------
+table_get_row([{Index, Name, Address, Status} | _], [Index]) ->
+ {ok, {Index, Name, Address, Status}};
+table_get_row([_H | T], RowIndex) ->
+ table_get_row(T, RowIndex);
+table_get_row([], _RowIndex) ->
+ no_such_row.
+
+table_get_next_row([Row | _T], []) ->
+ {ok, Row};
+table_get_next_row([Row | _T], [Index | _]) when element(1, Row) > Index ->
+ {ok, Row};
+table_get_next_row([_Row | T], RowIndex) ->
+ table_get_next_row(T, RowIndex);
+table_get_next_row([], _RowIndex) ->
+ endOfTable.
+
+table_delete_row([{Index, _, _, _} | T], [Index]) ->
+ T;
+table_delete_row([H | T], RowIndex) ->
+ [H | table_delete_row(T, RowIndex)];
+table_delete_row([], _RowIndex) ->
+ [].
+
+table_add_row([Row | T], NewRow) when element(1, Row) > element(1, NewRow) ->
+ [NewRow, Row | T];
+table_add_row([H | T], NewRow) ->
+ [H | table_add_row(T, NewRow)];
+table_add_row([], NewRow) ->
+ [NewRow].
+
+make_row([Index], [{2, Name}, {3, Address} | _]) ->
+ {Index, Name, Address, ?active}.
+
+merge_rows(Row, [{Col, NewVal} | T]) ->
+ merge_rows(setelement(Col, Row, NewVal), T);
+merge_rows(Row, []) ->
+ Row.
+
+
diff --git a/lib/snmp/examples/ex2/Makefile b/lib/snmp/examples/ex2/Makefile
new file mode 100644
index 0000000000..7fbd7f530b
--- /dev/null
+++ b/lib/snmp/examples/ex2/Makefile
@@ -0,0 +1,93 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2006-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+
+VSN = $(SNMP_VSN)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ifneq ($(MIBS_VERBOSITY),)
+SNMP_FLAGS += +'{verbosity,$(MIBS_VERBOSITY)}'
+endif
+
+ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/snmp/ebin
+ERL_COMPILE_FLAGS += -I../include \
+ -Dversion=\"$(VSN)$(PRE_VSN)\" \
+ +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ -I$(ERL_TOP)/lib/stdlib \
+ $(SNMP_FLAGS)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
+EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples
+EX2_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/ex2
+
+# ----------------------------------------------------
+# Common macros
+# ----------------------------------------------------
+
+MODULES = \
+ snmp_ex2_manager \
+ snmp_ex2_simple_standard_test
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+TARGET_FILES= \
+ $(ERL_FILES:%.erl=%.$(EMULATOR))
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+debug opt: build
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+build: $(TARGET_FILES)
+
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(EXAMPLE_RELSYSDIR)
+ $(INSTALL_DIR) $(EX2_RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(EX2_RELSYSDIR)
+ $(INSTALL_DATA) $(TARGET_FILES) $(EX2_RELSYSDIR)
+
+release_docs_spec:
diff --git a/lib/snmp/examples/ex2/snmp_ex2_manager.erl b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
new file mode 100644
index 0000000000..79cfd94469
--- /dev/null
+++ b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
@@ -0,0 +1,407 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% This module examplifies how to write test suites for your SNMP agent.
+%%----------------------------------------------------------------------
+
+-module(snmp_ex2_manager).
+
+-behaviour(gen_server).
+-behaviour(snmpm_user).
+
+-export([start_link/0, start_link/1, stop/0,
+ agent/2,
+ sync_get/2,
+ sync_get_next/2,
+ sync_get_bulk/4,
+ sync_set/2,
+
+ oid_to_name/1
+ ]).
+
+%% Manager callback API:
+-export([handle_error/3,
+ handle_agent/4,
+ handle_pdu/4,
+ handle_trap/3,
+ handle_inform/3,
+ handle_report/3]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ code_change/3, terminate/2]).
+
+-include_lib("snmp/include/snmp_types.hrl").
+
+
+-define(SERVER, ?MODULE).
+-define(USER, ?MODULE).
+-define(USER_MOD, ?MODULE).
+
+-record(state, {parent}).
+
+
+%%%-------------------------------------------------------------------
+%%% API
+%%%-------------------------------------------------------------------
+
+start_link() ->
+ start_link([]).
+
+start_link(Opts) when is_list(Opts) ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [self(), Opts], []).
+
+stop() ->
+ cast(stop).
+
+
+%% --- Instruct manager to handle an agent ---
+
+agent(TargetName, Conf) ->
+ call({agent, TargetName, Conf}).
+
+
+%% --- Various SNMP operations ----
+
+sync_get(TargetName, Oids) ->
+ call({sync_get, TargetName, Oids}).
+
+sync_get_next(TargetName, Oids) ->
+ call({sync_get_next, TargetName, Oids}).
+
+sync_get_bulk(TargetName, NR, MR, Oids) ->
+ call({sync_get_bulk, TargetName, NR, MR, Oids}).
+
+sync_set(TargetName, VarsAndVals) ->
+ call({sync_set, TargetName, VarsAndVals}).
+
+
+%% --- Misc utility functions ---
+
+oid_to_name(Oid) ->
+ call({oid_to_name, Oid}).
+
+
+%%%-------------------------------------------------------------------
+%%% Callback functions from gen_server
+%%%-------------------------------------------------------------------
+
+init([Parent, Opts]) ->
+ process_flag(trap_exit, true),
+ case (catch do_init(Opts)) of
+ {ok, State} ->
+ {ok, State#state{parent = Parent}};
+ {error, Reason} ->
+ {stop, Reason};
+ Crap ->
+ {stop, Crap}
+ end.
+
+do_init(Opts) ->
+ {Dir, MgrConf, MgrOpts} = parse_opts(Opts),
+ write_config(Dir, MgrConf),
+ start_manager(MgrOpts),
+ register_user(),
+ {ok, #state{}}.
+
+write_config(Dir, Conf) ->
+ case snmp_config:write_manager_config(Dir, "", Conf) of
+ ok ->
+ ok;
+ Error ->
+ error({failed_writing_config, Error})
+ end.
+
+start_manager(Opts) ->
+ case snmpm:start_link(Opts) of
+ ok ->
+ ok;
+ Error ->
+ error({failed_starting_manager, Error})
+ end.
+
+register_user() ->
+ case snmpm:register_user(?USER, ?USER_MOD, self()) of
+ ok ->
+ ok;
+ Error ->
+ error({failed_register_user, Error})
+ end.
+
+parse_opts(Opts) ->
+ Port = get_opt(port, Opts, 5000),
+ EngineId = get_opt(engine_id, Opts, "mgrEngine"),
+ MMS = get_opt(max_message_size, Opts, 484),
+
+ MgrConf = [{port, Port},
+ {engine_id, EngineId},
+ {max_message_size, MMS}],
+
+ %% Manager options
+ Mibs = get_opt(mibs, Opts, []),
+ Vsns = get_opt(versions, Opts, [v1, v2, v3]),
+ {ok, Cwd} = file:get_cwd(),
+ Dir = get_opt(dir, Opts, Cwd),
+ MgrOpts = [{mibs, Mibs},
+ {versions, Vsns},
+ %% {server, [{verbosity, trace}]},
+ {config, [% {verbosity, trace},
+ {dir, Dir}, {db_dir, Dir}]}],
+
+ {Dir, MgrConf, MgrOpts}.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_call/3
+%% Returns: {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} | (terminate/2 is called)
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+
+handle_call({agent, TargetName, Conf}, _From, S) ->
+ Reply = (catch snmpm:register_agent(?USER, TargetName, Conf)),
+ {reply, Reply, S};
+
+handle_call({oid_to_name, Oid}, _From, S) ->
+ Reply = (catch snmpm:oid_to_name(Oid)),
+ {reply, Reply, S};
+
+handle_call({sync_get, TargetName, Oids}, _From, S) ->
+ Reply = (catch snmpm:sync_get(?USER, TargetName, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_get_next, TargetName, Oids}, _From, S) ->
+ Reply = (catch snmpm:sync_get_next(?USER, TargetName, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_get_bulk, TargetName, NR, MR, Oids}, _From, S) ->
+ Reply = (catch snmpm:sync_get_bulk(?USER, TargetName, NR, MR, Oids)),
+ {reply, Reply, S};
+
+handle_call({sync_set, TargetName, VarsAndVals}, _From, S) ->
+ Reply = (catch snmpm:sync_set(?USER, TargetName, VarsAndVals)),
+ {reply, Reply, S};
+
+handle_call(Req, From, State) ->
+ error_msg("received unknown request ~n~p~nFrom ~p", [Req, From]),
+ {reply, {error, {unknown_request, Req}}, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_cast/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+handle_cast(stop, S) ->
+ (catch snmpm:stop()),
+ {stop, normal, S};
+
+handle_cast(Msg, State) ->
+ error_msg("received unknown message ~n~p", [Msg]),
+ {noreply, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: handle_info/2
+%% Returns: {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State} (terminate/2 is called)
+%%--------------------------------------------------------------------
+handle_info({snmp_callback, Tag, Info}, State) ->
+ handle_snmp_callback(Tag, Info),
+ {noreply, State};
+
+handle_info(Info, State) ->
+ error_msg("received unknown info: "
+ "~n Info: ~p", [Info]),
+ {noreply, State}.
+
+
+%%--------------------------------------------------------------------
+%% Func: terminate/2
+%% Purpose: Shutdown the server
+%% Returns: any (ignored by gen_server)
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+
+code_change({down, _Vsn}, State, _Extra) ->
+ {ok, State};
+
+% upgrade
+code_change(_Vsn, State, _Extra) ->
+ {ok, State}.
+
+
+%% ========================================================================
+%% ========================================================================
+
+handle_snmp_callback(handle_error, {ReqId, Reason}) ->
+ io:format("*** FAILURE ***"
+ "~n Request Id: ~p"
+ "~n Reason: ~p"
+ "~n", [ReqId, Reason]),
+ ok;
+handle_snmp_callback(handle_agent, {Addr, Port, SnmpInfo}) ->
+ {ES, EI, VBs} = SnmpInfo,
+ io:format("*** UNKNOWN AGENT ***"
+ "~n Address: ~p"
+ "~n Port: ~p"
+ "~n SNMP Info: "
+ "~n Error Status: ~w"
+ "~n Error Index: ~w"
+ "~n Varbinds: ~p"
+ "~n", [Addr, Port, ES, EI, VBs]),
+ ok;
+handle_snmp_callback(handle_pdu, {TargetName, ReqId, SnmpResponse}) ->
+ {ES, EI, VBs} = SnmpResponse,
+ io:format("*** Received PDU ***"
+ "~n TargetName: ~p"
+ "~n Request Id: ~p"
+ "~n SNMP response:"
+ "~n Error Status: ~w"
+ "~n Error Index: ~w"
+ "~n Varbinds: ~p"
+ "~n", [TargetName, ReqId, ES, EI, VBs]),
+ ok;
+handle_snmp_callback(handle_trap, {TargetName, SnmpTrap}) ->
+ TrapStr =
+ case SnmpTrap of
+ {Enteprise, Generic, Spec, Timestamp, Varbinds} ->
+ io_lib:format("~n Generic: ~w"
+ "~n Exterprise: ~w"
+ "~n Specific: ~w"
+ "~n Timestamp: ~w"
+ "~n Varbinds: ~p",
+ [Generic, Enteprise, Spec, Timestamp, Varbinds]);
+ {ErrorStatus, ErrorIndex, Varbinds} ->
+ io_lib:format("~n Error Status: ~w"
+ "~n Error Index: ~w"
+ "~n Varbinds: ~p"
+ "~n", [ErrorStatus, ErrorIndex, Varbinds])
+ end,
+ io:format("*** Received TRAP ***"
+ "~n TargetName: ~p"
+ "~n SNMP trap: ~s"
+ "~n", [TargetName, lists:flatten(TrapStr)]),
+ ok;
+handle_snmp_callback(handle_inform, {TargetName, SnmpInform}) ->
+ {ES, EI, VBs} = SnmpInform,
+ io:format("*** Received INFORM ***"
+ "~n TargetName: ~p"
+ "~n SNMP inform: "
+ "~n Error Status: ~w"
+ "~n Error Index: ~w"
+ "~n Varbinds: ~p"
+ "~n", [TargetName, ES, EI, VBs]),
+ ok;
+handle_snmp_callback(handle_report, {TargetName, SnmpReport}) ->
+ {ES, EI, VBs} = SnmpReport,
+ io:format("*** Received REPORT ***"
+ "~n TargetName: ~p"
+ "~n SNMP report: "
+ "~n Error Status: ~w"
+ "~n Error Index: ~w"
+ "~n Varbinds: ~p"
+ "~n", [TargetName, ES, EI, VBs]),
+ ok;
+handle_snmp_callback(BadTag, Crap) ->
+ io:format("*** Received crap ***"
+ "~n ~p"
+ "~n ~p"
+ "~n", [BadTag, Crap]),
+ ok.
+
+
+
+error(Reason) ->
+ throw({error, Reason}).
+
+
+error_msg(F, A) ->
+ catch error_logger:error_msg("*** TEST-MANAGER: " ++ F ++ "~n", A).
+
+
+call(Req) ->
+ gen_server:call(?SERVER, Req, infinity).
+
+cast(Msg) ->
+ gen_server:cast(?SERVER, Msg).
+
+
+%% ========================================================================
+%% Misc internal utility functions
+%% ========================================================================
+
+%% get_opt(Key, Opts) ->
+%% case lists:keysearch(Key, 1, Opts) of
+%% {value, {Key, Val}} ->
+%% Val;
+%% false ->
+%% throw({error, {missing_mandatory, Key}})
+%% end.
+
+get_opt(Key, Opts, Def) ->
+ case lists:keysearch(Key, 1, Opts) of
+ {value, {Key, Val}} ->
+ Val;
+ false ->
+ Def
+ end.
+
+
+%% ========================================================================
+%% SNMPM user callback functions
+%% ========================================================================
+
+handle_error(ReqId, Reason, Server) when is_pid(Server) ->
+ report_callback(Server, handle_error, {ReqId, Reason}),
+ ignore.
+
+
+handle_agent(Addr, Port, SnmpInfo, Server) when is_pid(Server) ->
+ report_callback(Server, handle_agent, {Addr, Port, SnmpInfo}),
+ ignore.
+
+
+handle_pdu(TargetName, ReqId, SnmpResponse, Server) when is_pid(Server) ->
+ report_callback(Server, handle_pdu, {TargetName, ReqId, SnmpResponse}),
+ ignore.
+
+
+handle_trap(TargetName, SnmpTrap, Server) when is_pid(Server) ->
+ report_callback(Server, handle_trap, {TargetName, SnmpTrap}),
+ ok.
+
+handle_inform(TargetName, SnmpInform, Server) when is_pid(Server) ->
+ report_callback(Server, handle_inform, {TargetName, SnmpInform}),
+ ok.
+
+
+handle_report(TargetName, SnmpReport, Server) when is_pid(Server) ->
+ report_callback(Server, handle_inform, {TargetName, SnmpReport}),
+ ok.
+
+report_callback(Pid, Tag, Info) ->
+ Pid ! {snmp_callback, Tag, Info}.
diff --git a/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl
new file mode 100644
index 0000000000..16fe79d1a5
--- /dev/null
+++ b/lib/snmp/examples/ex2/snmp_ex2_simple_standard_test.erl
@@ -0,0 +1,287 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%%----------------------------------------------------------------------
+%% This module examplifies how to write test suites for your SNMP agent.
+%%----------------------------------------------------------------------
+
+-module(snmp_ex2_simple_standard_test).
+
+-export([start/0, start/1, start/3]).
+
+-include_lib("snmp/include/snmp_types.hrl").
+
+%% -define(USER, agent_tester).
+%% -define(USER_MOD, ?MODULE).
+%% -define(USER_MOD, snmpm_user_default).
+
+-record(command, {tag, desc, cmd, verify}).
+
+start() ->
+ {ok, Hostname} = inet:gethostname(),
+ {ok, Addr} = inet:getaddr(Hostname, inet),
+ start(Addr).
+
+start(Addr) ->
+ start([std_mib("STANDARD-MIB")], Addr, [{community, "public"}]).
+
+start(Mibs, AgentAddr, AgentConfig) ->
+ Conf = [{mibs, Mibs}],
+ {ok, _Pid} = snmp_ex2_manager:start_link(Conf),
+ snmp_ex2_manager:agent(AgentAddr, AgentConfig),
+ simple_standard_test(AgentAddr),
+ snmp_ex2_manager:stop().
+
+simple_standard_test(AgentAddr) ->
+ Commands =
+ [
+ #command{tag = 1,
+ desc = "get-next [1,1]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,1])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 2,
+ desc = "get-next [1,3]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 3,
+ desc = "get-next [1,3,6]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 4,
+ desc = "get-next [1,3,6]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6,1])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 5,
+ desc = "get-next [1,3,6,1,2]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 6,
+ desc = "get-next [1,3,6,1,2,1]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 7,
+ desc = "get-next [1,3,6,1,2,1,1]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 8,
+ desc = "get-next [1,3,6,1,2,1,1,1]",
+ cmd = fun() ->
+ gn(AgentAddr, [1,3,6])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 9,
+ desc = "get [sysDescr,0]",
+ cmd = fun() ->
+ g(AgentAddr, [sysDescr,0])
+ end,
+ verify = fun({ok, Res, _}) ->
+ verify_vbs(Res,
+ [{sysDescr, 'OCTET STRING'}]);
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end},
+ #command{tag = 10,
+ desc = "get [1,3,6,1,2,1,1,1]",
+ cmd = fun() ->
+ g(AgentAddr, [1,3,6,1,2,1,1,1])
+ end,
+ verify = fun({ok, {noError, 0, [Vb]}, _}) ->
+ case Vb of
+ #varbind{oid = [1,3,6,1,2,1,1,1],
+ value = noSuchInstance} ->
+ {ok,
+ lists:flatten(
+ io_lib:format("~n noSuchInstance", []))};
+ #varbind{oid = [1,3,6,1,2,1,1,1],
+ value = noSuchName} ->
+ {ok,
+ lists:flatten(
+ io_lib:format("~n noSuchName",
+ []))};
+ _ ->
+ {error, {unexpected_vb, Vb}}
+ end;
+ ({error, Reason}) ->
+ {error, {command_failed, Reason}};
+ (Crap) ->
+ {error, {unexpected_command_result, Crap}}
+ end}
+ ],
+ ok = commands(Commands),
+ io:format("Test completed.~n").
+
+
+commands([]) ->
+ ok;
+commands([#command{tag = Tag,
+ desc = Desc,
+ cmd = Cmd,
+ verify = Verify}|Commands]) ->
+ io:format("Command ~2w (~s): ", [Tag, Desc]),
+ case Verify((catch Cmd())) of
+ {ok, Val} ->
+ io:format("ok~s~n", [Val]),
+ ok;
+ {error, Reason} ->
+ io:format("error"
+ "~n ~p"
+ "~n", [Reason])
+ end,
+ commands(Commands).
+
+
+%% --- Command shorts ---
+
+gn(Addr, [H|_] = Oids) when is_list(H) ->
+ snmp_ex2_manager:sync_get_next(Addr, Oids);
+gn(Addr, Oid) ->
+ gn(Addr, [Oid]).
+
+g(Addr, [H|_] = Oids) when is_list(H) ->
+ snmp_ex2_manager:sync_get(Addr, Oids);
+g(Addr, Oid) ->
+ g(Addr, [Oid]).
+
+
+%% Verify that all varbinds have the expected name and type
+verify_vbs({noError, 0, Vbs}, NameAndTypes) ->
+ (catch verify_vbs(Vbs, NameAndTypes, ""));
+verify_vbs(Res, _) ->
+ {error, {unexpected_result, Res}}.
+
+verify_vbs([], _, Acc) ->
+ {ok, Acc};
+verify_vbs([Vb|T], NameAndTypes, Acc) ->
+ Val = verify_vb(Vb, NameAndTypes),
+ Acc2 = lists:flatten(io_lib:format("~s~n ~s", [Acc, Val])),
+ verify_vbs(T, NameAndTypes, Acc2).
+
+verify_vb(#varbind{oid = Oid, variabletype = Type, value = Val} = Vb,
+ NameAndTypes) ->
+ case lists:reverse(Oid) of
+ [0|RevOid] ->
+ case snmp_ex2_manager:oid_to_name(lists:reverse(RevOid)) of
+ {ok, Name} ->
+ case lists:keysearch(Name, 1, NameAndTypes) of
+ {value, {Name, Type}} ->
+ Val;
+ {value, {Name, WrongType}} ->
+ error({wrong_type, {WrongType, Vb}});
+ false ->
+ error({unexpected_name, {Name, Vb}})
+ end;
+ {error, Reason} ->
+ error({unexpected_oid, {Reason, Vb}})
+ end;
+ _ ->
+ case lists:keysearch(Oid, 1, NameAndTypes) of
+ {value, {Oid, Type}} ->
+ Val;
+ {value, {Oid, WrongType}} ->
+ error({wrong_type, {WrongType, Vb}});
+ false ->
+ error({unexpected_oid, Vb})
+ end
+ end.
+
+
+std_mib(MibName) ->
+ j(std_dir(), MibName).
+
+std_dir() -> j(code:priv_dir(snmp), "mibs").
+
+j(Dir, Filename) ->
+ filename:join(Dir, Filename).
+
+
+error(Reason) ->
+ throw({error, Reason}).
+
+
diff --git a/lib/snmp/examples/mcli/.gitignore b/lib/snmp/examples/mcli/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/snmp/examples/mcli/.gitignore
diff --git a/lib/snmp/examples/subdirs.mk b/lib/snmp/examples/subdirs.mk
new file mode 100644
index 0000000000..9f4b69951e
--- /dev/null
+++ b/lib/snmp/examples/subdirs.mk
@@ -0,0 +1,21 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+
+SUB_DIRECTORIES = ex1 ex2
+