summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/Makefile.depend2081
-rw-r--r--apps/Makefile.in230
-rw-r--r--apps/agentxtrap.c607
-rw-r--r--apps/encode_keychange.c803
-rw-r--r--apps/snmp_perl_trapd.pl15
-rw-r--r--apps/snmpbulkget.c250
-rw-r--r--apps/snmpbulkwalk.c386
-rw-r--r--apps/snmpdelta.c748
-rw-r--r--apps/snmpdf.c389
-rw-r--r--apps/snmpget.c255
-rw-r--r--apps/snmpgetnext.c236
-rw-r--r--apps/snmpnetstat/Makefile.depend425
-rw-r--r--apps/snmpnetstat/Makefile.in38
-rw-r--r--apps/snmpnetstat/ffs.c38
-rw-r--r--apps/snmpnetstat/if.c870
-rw-r--r--apps/snmpnetstat/inet.c649
-rw-r--r--apps/snmpnetstat/inet6.c516
-rw-r--r--apps/snmpnetstat/main.c539
-rw-r--r--apps/snmpnetstat/main.h23
-rw-r--r--apps/snmpnetstat/netstat.h94
-rw-r--r--apps/snmpnetstat/route.c487
-rw-r--r--apps/snmpnetstat/winstub.c285
-rw-r--r--apps/snmpnetstat/winstub.h50
-rw-r--r--apps/snmpset.c284
-rw-r--r--apps/snmpstatus.c382
-rw-r--r--apps/snmptable.c1010
-rw-r--r--apps/snmptest.c535
-rw-r--r--apps/snmptls.c559
-rw-r--r--apps/snmptranslate.c367
-rw-r--r--apps/snmptrap.c392
-rw-r--r--apps/snmptrapd.c1464
-rw-r--r--apps/snmptrapd_auth.c182
-rw-r--r--apps/snmptrapd_auth.h16
-rw-r--r--apps/snmptrapd_ds.h19
-rw-r--r--apps/snmptrapd_handlers.c1109
-rw-r--r--apps/snmptrapd_handlers.h68
-rw-r--r--apps/snmptrapd_log.c1802
-rw-r--r--apps/snmptrapd_log.h18
-rw-r--r--apps/snmptrapd_sql.c1118
-rw-r--r--apps/snmpusm.c1023
-rw-r--r--apps/snmpvacm.c711
-rw-r--r--apps/snmpwalk.c432
-rw-r--r--apps/sshtosnmp.c233
43 files changed, 21738 insertions, 0 deletions
diff --git a/apps/Makefile.depend b/apps/Makefile.depend
new file mode 100644
index 0000000..b507930
--- /dev/null
+++ b/apps/Makefile.depend
@@ -0,0 +1,2081 @@
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+./agentxtrap.lo: ../include/net-snmp/net-snmp-config.h
+./agentxtrap.lo: ../include/net-snmp/system/linux.h
+./agentxtrap.lo: ../include/net-snmp/system/sysv.h
+./agentxtrap.lo: ../include/net-snmp/system/generic.h
+./agentxtrap.lo: ../include/net-snmp/net-snmp-features.h
+./agentxtrap.lo: ../include/net-snmp/net-snmp-includes.h
+./agentxtrap.lo: ../include/net-snmp/definitions.h
+./agentxtrap.lo: ../include/net-snmp/types.h
+./agentxtrap.lo: ../include/net-snmp/library/oid.h
+./agentxtrap.lo: ../include/net-snmp/library/types.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_api.h
+./agentxtrap.lo: ../include/net-snmp/varbind_api.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_client.h
+./agentxtrap.lo: ../include/net-snmp/pdu_api.h
+./agentxtrap.lo: ../include/net-snmp/library/asn1.h
+./agentxtrap.lo: ../include/net-snmp/output_api.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_debug.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_logging.h
+./agentxtrap.lo: ../include/net-snmp/session_api.h
+./agentxtrap.lo: ../include/net-snmp/library/callback.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_transport.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_service.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./agentxtrap.lo: ../include/net-snmp/library/ucd_compat.h
+./agentxtrap.lo: ../include/net-snmp/library/mib.h
+./agentxtrap.lo: ../include/net-snmp/mib_api.h
+./agentxtrap.lo: ../include/net-snmp/library/parse.h
+./agentxtrap.lo: ../include/net-snmp/library/oid_stash.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_impl.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp-tc.h
+./agentxtrap.lo: ../include/net-snmp/library/getopt.h
+./agentxtrap.lo: ../include/net-snmp/utilities.h
+./agentxtrap.lo: ../include/net-snmp/library/system.h
+./agentxtrap.lo: ../include/net-snmp/library/tools.h
+./agentxtrap.lo: ../include/net-snmp/library/int64.h
+./agentxtrap.lo: ../include/net-snmp/library/mt_support.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_alarm.h
+./agentxtrap.lo: ../include/net-snmp/library/data_list.h
+./agentxtrap.lo: ../include/net-snmp/library/check_varbind.h
+./agentxtrap.lo: ../include/net-snmp/library/container.h
+./agentxtrap.lo: ../include/net-snmp/library/factory.h
+./agentxtrap.lo: ../include/net-snmp/library/container_binary_array.h
+./agentxtrap.lo: ../include/net-snmp/library/container_list_ssll.h
+./agentxtrap.lo: ../include/net-snmp/library/container_iterator.h
+./agentxtrap.lo: ../include/net-snmp/library/container.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_assert.h
+./agentxtrap.lo: ../include/net-snmp/version.h
+./agentxtrap.lo: ../include/net-snmp/config_api.h
+./agentxtrap.lo: ../include/net-snmp/library/read_config.h
+./agentxtrap.lo: ../include/net-snmp/library/default_store.h
+./agentxtrap.lo: ../include/net-snmp/net-snmp-config.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_parse_args.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_enum.h
+./agentxtrap.lo: ../include/net-snmp/library/vacm.h
+./agentxtrap.lo: ../include/net-snmp/snmpv3_api.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpv3.h
+./agentxtrap.lo: ../include/net-snmp/library/transform_oids.h
+./agentxtrap.lo: ../include/net-snmp/library/keytools.h
+./agentxtrap.lo: ../include/net-snmp/library/scapi.h
+./agentxtrap.lo: ../include/net-snmp/library/lcd_time.h
+./agentxtrap.lo: ../include/net-snmp/library/snmp_secmod.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./agentxtrap.lo: ../include/net-snmp/library/snmptsm.h
+./agentxtrap.lo: ../include/net-snmp/library/snmpusm.h
+./agentxtrap.lo: ../include/net-snmp/agent/ds_agent.h
+./agentxtrap.lo: ../agent/mibgroup/agentx/agentx_config.h
+./agentxtrap.lo: ../agent/mibgroup/agentx/client.h
+./agentxtrap.lo: ../agent/mibgroup/agentx/protocol.h
+./encode_keychange.lo: ../include/net-snmp/net-snmp-config.h
+./encode_keychange.lo: ../include/net-snmp/net-snmp-includes.h
+./encode_keychange.lo: ../include/net-snmp/definitions.h
+./encode_keychange.lo: ../include/net-snmp/types.h
+./encode_keychange.lo: ../include/net-snmp/library/oid.h
+./encode_keychange.lo: ../include/net-snmp/library/types.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_api.h
+./encode_keychange.lo: ../include/net-snmp/varbind_api.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_client.h
+./encode_keychange.lo: ../include/net-snmp/pdu_api.h
+./encode_keychange.lo: ../include/net-snmp/library/asn1.h
+./encode_keychange.lo: ../include/net-snmp/output_api.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_debug.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_logging.h
+./encode_keychange.lo: ../include/net-snmp/session_api.h
+./encode_keychange.lo: ../include/net-snmp/library/callback.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_transport.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_service.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./encode_keychange.lo: ../include/net-snmp/library/ucd_compat.h
+./encode_keychange.lo: ../include/net-snmp/library/mib.h
+./encode_keychange.lo: ../include/net-snmp/mib_api.h
+./encode_keychange.lo: ../include/net-snmp/library/parse.h
+./encode_keychange.lo: ../include/net-snmp/library/oid_stash.h
+./encode_keychange.lo: ../include/net-snmp/net-snmp-features.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_impl.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp-tc.h
+./encode_keychange.lo: ../include/net-snmp/library/getopt.h
+./encode_keychange.lo: ../include/net-snmp/utilities.h
+./encode_keychange.lo: ../include/net-snmp/library/system.h
+./encode_keychange.lo: ../include/net-snmp/library/tools.h
+./encode_keychange.lo: ../include/net-snmp/library/int64.h
+./encode_keychange.lo: ../include/net-snmp/library/mt_support.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_alarm.h
+./encode_keychange.lo: ../include/net-snmp/library/data_list.h
+./encode_keychange.lo: ../include/net-snmp/library/check_varbind.h
+./encode_keychange.lo: ../include/net-snmp/library/container.h
+./encode_keychange.lo: ../include/net-snmp/library/factory.h
+./encode_keychange.lo: ../include/net-snmp/library/container_binary_array.h
+./encode_keychange.lo: ../include/net-snmp/library/container_list_ssll.h
+./encode_keychange.lo: ../include/net-snmp/library/container_iterator.h
+./encode_keychange.lo: ../include/net-snmp/library/container.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_assert.h
+./encode_keychange.lo: ../include/net-snmp/version.h
+./encode_keychange.lo: ../include/net-snmp/config_api.h
+./encode_keychange.lo: ../include/net-snmp/library/read_config.h
+./encode_keychange.lo: ../include/net-snmp/library/default_store.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_parse_args.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_enum.h
+./encode_keychange.lo: ../include/net-snmp/library/vacm.h
+./encode_keychange.lo: ../include/net-snmp/snmpv3_api.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpv3.h
+./encode_keychange.lo: ../include/net-snmp/library/transform_oids.h
+./encode_keychange.lo: ../include/net-snmp/library/keytools.h
+./encode_keychange.lo: ../include/net-snmp/library/scapi.h
+./encode_keychange.lo: ../include/net-snmp/library/lcd_time.h
+./encode_keychange.lo: ../include/net-snmp/library/snmp_secmod.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./encode_keychange.lo: ../include/net-snmp/library/snmptsm.h
+./encode_keychange.lo: ../include/net-snmp/library/snmpusm.h
+./snmpbulkget.lo: ../include/net-snmp/net-snmp-config.h
+./snmpbulkget.lo: ../include/net-snmp/utilities.h
+./snmpbulkget.lo: ../include/net-snmp/types.h
+./snmpbulkget.lo: ../include/net-snmp/library/oid.h
+./snmpbulkget.lo: ../include/net-snmp/library/types.h
+./snmpbulkget.lo: ../include/net-snmp/definitions.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_api.h
+./snmpbulkget.lo: ../include/net-snmp/varbind_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_client.h
+./snmpbulkget.lo: ../include/net-snmp/pdu_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/asn1.h
+./snmpbulkget.lo: ../include/net-snmp/output_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpbulkget.lo: ../include/net-snmp/session_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/callback.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_service.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpbulkget.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpbulkget.lo: ../include/net-snmp/library/mib.h
+./snmpbulkget.lo: ../include/net-snmp/mib_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/parse.h
+./snmpbulkget.lo: ../include/net-snmp/library/oid_stash.h
+./snmpbulkget.lo: ../include/net-snmp/net-snmp-features.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpbulkget.lo: ../include/net-snmp/library/system.h
+./snmpbulkget.lo: ../include/net-snmp/library/tools.h
+./snmpbulkget.lo: ../include/net-snmp/library/int64.h
+./snmpbulkget.lo: ../include/net-snmp/library/mt_support.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpbulkget.lo: ../include/net-snmp/library/data_list.h
+./snmpbulkget.lo: ../include/net-snmp/library/check_varbind.h
+./snmpbulkget.lo: ../include/net-snmp/library/container.h
+./snmpbulkget.lo: ../include/net-snmp/library/factory.h
+./snmpbulkget.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpbulkget.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpbulkget.lo: ../include/net-snmp/library/container_iterator.h
+./snmpbulkget.lo: ../include/net-snmp/library/container.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpbulkget.lo: ../include/net-snmp/version.h
+./snmpbulkget.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpbulkget.lo: ../include/net-snmp/library/getopt.h
+./snmpbulkget.lo: ../include/net-snmp/config_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/read_config.h
+./snmpbulkget.lo: ../include/net-snmp/library/default_store.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpbulkget.lo: ../include/net-snmp/library/vacm.h
+./snmpbulkget.lo: ../include/net-snmp/snmpv3_api.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpv3.h
+./snmpbulkget.lo: ../include/net-snmp/library/transform_oids.h
+./snmpbulkget.lo: ../include/net-snmp/library/keytools.h
+./snmpbulkget.lo: ../include/net-snmp/library/scapi.h
+./snmpbulkget.lo: ../include/net-snmp/library/lcd_time.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmptsm.h
+./snmpbulkget.lo: ../include/net-snmp/library/snmpusm.h
+./snmpbulkwalk.lo: ../include/net-snmp/net-snmp-config.h
+./snmpbulkwalk.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpbulkwalk.lo: ../include/net-snmp/definitions.h
+./snmpbulkwalk.lo: ../include/net-snmp/types.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/oid.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/types.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/varbind_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_client.h
+./snmpbulkwalk.lo: ../include/net-snmp/pdu_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/asn1.h
+./snmpbulkwalk.lo: ../include/net-snmp/output_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpbulkwalk.lo: ../include/net-snmp/session_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/callback.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_service.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/mib.h
+./snmpbulkwalk.lo: ../include/net-snmp/mib_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/parse.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/oid_stash.h
+./snmpbulkwalk.lo: ../include/net-snmp/net-snmp-features.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/getopt.h
+./snmpbulkwalk.lo: ../include/net-snmp/utilities.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/system.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/tools.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/int64.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/mt_support.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/data_list.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/check_varbind.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/container.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/factory.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/container_iterator.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/container.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpbulkwalk.lo: ../include/net-snmp/version.h
+./snmpbulkwalk.lo: ../include/net-snmp/config_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/read_config.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/default_store.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/vacm.h
+./snmpbulkwalk.lo: ../include/net-snmp/snmpv3_api.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpv3.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/transform_oids.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/keytools.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/scapi.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/lcd_time.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmptsm.h
+./snmpbulkwalk.lo: ../include/net-snmp/library/snmpusm.h
+./snmpdelta.lo: ../include/net-snmp/net-snmp-config.h
+./snmpdelta.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpdelta.lo: ../include/net-snmp/definitions.h
+./snmpdelta.lo: ../include/net-snmp/types.h
+./snmpdelta.lo: ../include/net-snmp/library/oid.h
+./snmpdelta.lo: ../include/net-snmp/library/types.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_api.h
+./snmpdelta.lo: ../include/net-snmp/varbind_api.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_client.h
+./snmpdelta.lo: ../include/net-snmp/pdu_api.h
+./snmpdelta.lo: ../include/net-snmp/library/asn1.h
+./snmpdelta.lo: ../include/net-snmp/output_api.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpdelta.lo: ../include/net-snmp/session_api.h
+./snmpdelta.lo: ../include/net-snmp/library/callback.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_service.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpdelta.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpdelta.lo: ../include/net-snmp/library/mib.h
+./snmpdelta.lo: ../include/net-snmp/mib_api.h
+./snmpdelta.lo: ../include/net-snmp/library/parse.h
+./snmpdelta.lo: ../include/net-snmp/library/oid_stash.h
+./snmpdelta.lo: ../include/net-snmp/net-snmp-features.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpdelta.lo: ../include/net-snmp/library/getopt.h
+./snmpdelta.lo: ../include/net-snmp/utilities.h
+./snmpdelta.lo: ../include/net-snmp/library/system.h
+./snmpdelta.lo: ../include/net-snmp/library/tools.h
+./snmpdelta.lo: ../include/net-snmp/library/int64.h
+./snmpdelta.lo: ../include/net-snmp/library/mt_support.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpdelta.lo: ../include/net-snmp/library/data_list.h
+./snmpdelta.lo: ../include/net-snmp/library/check_varbind.h
+./snmpdelta.lo: ../include/net-snmp/library/container.h
+./snmpdelta.lo: ../include/net-snmp/library/factory.h
+./snmpdelta.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpdelta.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpdelta.lo: ../include/net-snmp/library/container_iterator.h
+./snmpdelta.lo: ../include/net-snmp/library/container.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpdelta.lo: ../include/net-snmp/version.h
+./snmpdelta.lo: ../include/net-snmp/config_api.h
+./snmpdelta.lo: ../include/net-snmp/library/read_config.h
+./snmpdelta.lo: ../include/net-snmp/library/default_store.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpdelta.lo: ../include/net-snmp/library/vacm.h
+./snmpdelta.lo: ../include/net-snmp/snmpv3_api.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpv3.h
+./snmpdelta.lo: ../include/net-snmp/library/transform_oids.h
+./snmpdelta.lo: ../include/net-snmp/library/keytools.h
+./snmpdelta.lo: ../include/net-snmp/library/scapi.h
+./snmpdelta.lo: ../include/net-snmp/library/lcd_time.h
+./snmpdelta.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpdelta.lo: ../include/net-snmp/library/snmptsm.h
+./snmpdelta.lo: ../include/net-snmp/library/snmpusm.h
+./snmpdf.lo: ../include/net-snmp/net-snmp-config.h
+./snmpdf.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpdf.lo: ../include/net-snmp/definitions.h
+./snmpdf.lo: ../include/net-snmp/types.h
+./snmpdf.lo: ../include/net-snmp/library/oid.h
+./snmpdf.lo: ../include/net-snmp/library/types.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_api.h
+./snmpdf.lo: ../include/net-snmp/varbind_api.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_client.h
+./snmpdf.lo: ../include/net-snmp/pdu_api.h ../include/net-snmp/library/asn1.h
+./snmpdf.lo: ../include/net-snmp/output_api.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpdf.lo: ../include/net-snmp/session_api.h
+./snmpdf.lo: ../include/net-snmp/library/callback.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_service.h
+./snmpdf.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpdf.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpdf.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpdf.lo: ../include/net-snmp/library/mib.h ../include/net-snmp/mib_api.h
+./snmpdf.lo: ../include/net-snmp/library/parse.h
+./snmpdf.lo: ../include/net-snmp/library/oid_stash.h
+./snmpdf.lo: ../include/net-snmp/net-snmp-features.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpdf.lo: ../include/net-snmp/library/snmp.h
+./snmpdf.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpdf.lo: ../include/net-snmp/library/getopt.h
+./snmpdf.lo: ../include/net-snmp/utilities.h
+./snmpdf.lo: ../include/net-snmp/library/system.h
+./snmpdf.lo: ../include/net-snmp/library/tools.h
+./snmpdf.lo: ../include/net-snmp/library/int64.h
+./snmpdf.lo: ../include/net-snmp/library/mt_support.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpdf.lo: ../include/net-snmp/library/data_list.h
+./snmpdf.lo: ../include/net-snmp/library/check_varbind.h
+./snmpdf.lo: ../include/net-snmp/library/container.h
+./snmpdf.lo: ../include/net-snmp/library/factory.h
+./snmpdf.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpdf.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpdf.lo: ../include/net-snmp/library/container_iterator.h
+./snmpdf.lo: ../include/net-snmp/library/container.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpdf.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmpdf.lo: ../include/net-snmp/library/read_config.h
+./snmpdf.lo: ../include/net-snmp/library/default_store.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpdf.lo: ../include/net-snmp/library/vacm.h
+./snmpdf.lo: ../include/net-snmp/snmpv3_api.h
+./snmpdf.lo: ../include/net-snmp/library/snmpv3.h
+./snmpdf.lo: ../include/net-snmp/library/transform_oids.h
+./snmpdf.lo: ../include/net-snmp/library/keytools.h
+./snmpdf.lo: ../include/net-snmp/library/scapi.h
+./snmpdf.lo: ../include/net-snmp/library/lcd_time.h
+./snmpdf.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpdf.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpdf.lo: ../include/net-snmp/library/snmptsm.h
+./snmpdf.lo: ../include/net-snmp/library/snmpusm.h
+./snmpget.lo: ../include/net-snmp/net-snmp-config.h
+./snmpget.lo: ../include/net-snmp/utilities.h ../include/net-snmp/types.h
+./snmpget.lo: ../include/net-snmp/library/oid.h
+./snmpget.lo: ../include/net-snmp/library/types.h
+./snmpget.lo: ../include/net-snmp/definitions.h
+./snmpget.lo: ../include/net-snmp/library/snmp_api.h
+./snmpget.lo: ../include/net-snmp/varbind_api.h
+./snmpget.lo: ../include/net-snmp/library/snmp_client.h
+./snmpget.lo: ../include/net-snmp/pdu_api.h
+./snmpget.lo: ../include/net-snmp/library/asn1.h
+./snmpget.lo: ../include/net-snmp/output_api.h
+./snmpget.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpget.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpget.lo: ../include/net-snmp/session_api.h
+./snmpget.lo: ../include/net-snmp/library/callback.h
+./snmpget.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpget.lo: ../include/net-snmp/library/snmp_service.h
+./snmpget.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpget.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpget.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpget.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpget.lo: ../include/net-snmp/library/mib.h ../include/net-snmp/mib_api.h
+./snmpget.lo: ../include/net-snmp/library/parse.h
+./snmpget.lo: ../include/net-snmp/library/oid_stash.h
+./snmpget.lo: ../include/net-snmp/net-snmp-features.h
+./snmpget.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpget.lo: ../include/net-snmp/library/snmp.h
+./snmpget.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpget.lo: ../include/net-snmp/library/system.h
+./snmpget.lo: ../include/net-snmp/library/tools.h
+./snmpget.lo: ../include/net-snmp/library/int64.h
+./snmpget.lo: ../include/net-snmp/library/mt_support.h
+./snmpget.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpget.lo: ../include/net-snmp/library/data_list.h
+./snmpget.lo: ../include/net-snmp/library/check_varbind.h
+./snmpget.lo: ../include/net-snmp/library/container.h
+./snmpget.lo: ../include/net-snmp/library/factory.h
+./snmpget.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpget.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpget.lo: ../include/net-snmp/library/container_iterator.h
+./snmpget.lo: ../include/net-snmp/library/container.h
+./snmpget.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpget.lo: ../include/net-snmp/version.h
+./snmpget.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpget.lo: ../include/net-snmp/library/getopt.h
+./snmpget.lo: ../include/net-snmp/config_api.h
+./snmpget.lo: ../include/net-snmp/library/read_config.h
+./snmpget.lo: ../include/net-snmp/library/default_store.h
+./snmpget.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpget.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpget.lo: ../include/net-snmp/library/vacm.h
+./snmpget.lo: ../include/net-snmp/snmpv3_api.h
+./snmpget.lo: ../include/net-snmp/library/snmpv3.h
+./snmpget.lo: ../include/net-snmp/library/transform_oids.h
+./snmpget.lo: ../include/net-snmp/library/keytools.h
+./snmpget.lo: ../include/net-snmp/library/scapi.h
+./snmpget.lo: ../include/net-snmp/library/lcd_time.h
+./snmpget.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpget.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpget.lo: ../include/net-snmp/library/snmptsm.h
+./snmpget.lo: ../include/net-snmp/library/snmpusm.h
+./snmpgetnext.lo: ../include/net-snmp/net-snmp-config.h
+./snmpgetnext.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpgetnext.lo: ../include/net-snmp/definitions.h
+./snmpgetnext.lo: ../include/net-snmp/types.h
+./snmpgetnext.lo: ../include/net-snmp/library/oid.h
+./snmpgetnext.lo: ../include/net-snmp/library/types.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_api.h
+./snmpgetnext.lo: ../include/net-snmp/varbind_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_client.h
+./snmpgetnext.lo: ../include/net-snmp/pdu_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/asn1.h
+./snmpgetnext.lo: ../include/net-snmp/output_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpgetnext.lo: ../include/net-snmp/session_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/callback.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_service.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpgetnext.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpgetnext.lo: ../include/net-snmp/library/mib.h
+./snmpgetnext.lo: ../include/net-snmp/mib_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/parse.h
+./snmpgetnext.lo: ../include/net-snmp/library/oid_stash.h
+./snmpgetnext.lo: ../include/net-snmp/net-snmp-features.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpgetnext.lo: ../include/net-snmp/library/getopt.h
+./snmpgetnext.lo: ../include/net-snmp/utilities.h
+./snmpgetnext.lo: ../include/net-snmp/library/system.h
+./snmpgetnext.lo: ../include/net-snmp/library/tools.h
+./snmpgetnext.lo: ../include/net-snmp/library/int64.h
+./snmpgetnext.lo: ../include/net-snmp/library/mt_support.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpgetnext.lo: ../include/net-snmp/library/data_list.h
+./snmpgetnext.lo: ../include/net-snmp/library/check_varbind.h
+./snmpgetnext.lo: ../include/net-snmp/library/container.h
+./snmpgetnext.lo: ../include/net-snmp/library/factory.h
+./snmpgetnext.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpgetnext.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpgetnext.lo: ../include/net-snmp/library/container_iterator.h
+./snmpgetnext.lo: ../include/net-snmp/library/container.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpgetnext.lo: ../include/net-snmp/version.h
+./snmpgetnext.lo: ../include/net-snmp/config_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/read_config.h
+./snmpgetnext.lo: ../include/net-snmp/library/default_store.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpgetnext.lo: ../include/net-snmp/library/vacm.h
+./snmpgetnext.lo: ../include/net-snmp/snmpv3_api.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpv3.h
+./snmpgetnext.lo: ../include/net-snmp/library/transform_oids.h
+./snmpgetnext.lo: ../include/net-snmp/library/keytools.h
+./snmpgetnext.lo: ../include/net-snmp/library/scapi.h
+./snmpgetnext.lo: ../include/net-snmp/library/lcd_time.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmptsm.h
+./snmpgetnext.lo: ../include/net-snmp/library/snmpusm.h
+./snmpset.lo: ../include/net-snmp/net-snmp-config.h
+./snmpset.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpset.lo: ../include/net-snmp/definitions.h
+./snmpset.lo: ../include/net-snmp/types.h
+./snmpset.lo: ../include/net-snmp/library/oid.h
+./snmpset.lo: ../include/net-snmp/library/types.h
+./snmpset.lo: ../include/net-snmp/library/snmp_api.h
+./snmpset.lo: ../include/net-snmp/varbind_api.h
+./snmpset.lo: ../include/net-snmp/library/snmp_client.h
+./snmpset.lo: ../include/net-snmp/pdu_api.h
+./snmpset.lo: ../include/net-snmp/library/asn1.h
+./snmpset.lo: ../include/net-snmp/output_api.h
+./snmpset.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpset.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpset.lo: ../include/net-snmp/session_api.h
+./snmpset.lo: ../include/net-snmp/library/callback.h
+./snmpset.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpset.lo: ../include/net-snmp/library/snmp_service.h
+./snmpset.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpset.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpset.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpset.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpset.lo: ../include/net-snmp/library/mib.h ../include/net-snmp/mib_api.h
+./snmpset.lo: ../include/net-snmp/library/parse.h
+./snmpset.lo: ../include/net-snmp/library/oid_stash.h
+./snmpset.lo: ../include/net-snmp/net-snmp-features.h
+./snmpset.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpset.lo: ../include/net-snmp/library/snmp.h
+./snmpset.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpset.lo: ../include/net-snmp/library/getopt.h
+./snmpset.lo: ../include/net-snmp/utilities.h
+./snmpset.lo: ../include/net-snmp/library/system.h
+./snmpset.lo: ../include/net-snmp/library/tools.h
+./snmpset.lo: ../include/net-snmp/library/int64.h
+./snmpset.lo: ../include/net-snmp/library/mt_support.h
+./snmpset.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpset.lo: ../include/net-snmp/library/data_list.h
+./snmpset.lo: ../include/net-snmp/library/check_varbind.h
+./snmpset.lo: ../include/net-snmp/library/container.h
+./snmpset.lo: ../include/net-snmp/library/factory.h
+./snmpset.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpset.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpset.lo: ../include/net-snmp/library/container_iterator.h
+./snmpset.lo: ../include/net-snmp/library/container.h
+./snmpset.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpset.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmpset.lo: ../include/net-snmp/library/read_config.h
+./snmpset.lo: ../include/net-snmp/library/default_store.h
+./snmpset.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpset.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpset.lo: ../include/net-snmp/library/vacm.h
+./snmpset.lo: ../include/net-snmp/snmpv3_api.h
+./snmpset.lo: ../include/net-snmp/library/snmpv3.h
+./snmpset.lo: ../include/net-snmp/library/transform_oids.h
+./snmpset.lo: ../include/net-snmp/library/keytools.h
+./snmpset.lo: ../include/net-snmp/library/scapi.h
+./snmpset.lo: ../include/net-snmp/library/lcd_time.h
+./snmpset.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpset.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpset.lo: ../include/net-snmp/library/snmptsm.h
+./snmpset.lo: ../include/net-snmp/library/snmpusm.h
+./snmpstatus.lo: ../include/net-snmp/net-snmp-config.h
+./snmpstatus.lo: ../include/net-snmp/utilities.h ../include/net-snmp/types.h
+./snmpstatus.lo: ../include/net-snmp/library/oid.h
+./snmpstatus.lo: ../include/net-snmp/library/types.h
+./snmpstatus.lo: ../include/net-snmp/definitions.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_api.h
+./snmpstatus.lo: ../include/net-snmp/varbind_api.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_client.h
+./snmpstatus.lo: ../include/net-snmp/pdu_api.h
+./snmpstatus.lo: ../include/net-snmp/library/asn1.h
+./snmpstatus.lo: ../include/net-snmp/output_api.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpstatus.lo: ../include/net-snmp/session_api.h
+./snmpstatus.lo: ../include/net-snmp/library/callback.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_service.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpstatus.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpstatus.lo: ../include/net-snmp/library/mib.h
+./snmpstatus.lo: ../include/net-snmp/mib_api.h
+./snmpstatus.lo: ../include/net-snmp/library/parse.h
+./snmpstatus.lo: ../include/net-snmp/library/oid_stash.h
+./snmpstatus.lo: ../include/net-snmp/net-snmp-features.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpstatus.lo: ../include/net-snmp/library/system.h
+./snmpstatus.lo: ../include/net-snmp/library/tools.h
+./snmpstatus.lo: ../include/net-snmp/library/int64.h
+./snmpstatus.lo: ../include/net-snmp/library/mt_support.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpstatus.lo: ../include/net-snmp/library/data_list.h
+./snmpstatus.lo: ../include/net-snmp/library/check_varbind.h
+./snmpstatus.lo: ../include/net-snmp/library/container.h
+./snmpstatus.lo: ../include/net-snmp/library/factory.h
+./snmpstatus.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpstatus.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpstatus.lo: ../include/net-snmp/library/container_iterator.h
+./snmpstatus.lo: ../include/net-snmp/library/container.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpstatus.lo: ../include/net-snmp/version.h
+./snmpstatus.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpstatus.lo: ../include/net-snmp/library/getopt.h
+./snmpstatus.lo: ../include/net-snmp/config_api.h
+./snmpstatus.lo: ../include/net-snmp/library/read_config.h
+./snmpstatus.lo: ../include/net-snmp/library/default_store.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpstatus.lo: ../include/net-snmp/library/vacm.h
+./snmpstatus.lo: ../include/net-snmp/snmpv3_api.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpv3.h
+./snmpstatus.lo: ../include/net-snmp/library/transform_oids.h
+./snmpstatus.lo: ../include/net-snmp/library/keytools.h
+./snmpstatus.lo: ../include/net-snmp/library/scapi.h
+./snmpstatus.lo: ../include/net-snmp/library/lcd_time.h
+./snmpstatus.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpstatus.lo: ../include/net-snmp/library/snmptsm.h
+./snmpstatus.lo: ../include/net-snmp/library/snmpusm.h
+./snmptable.lo: ../include/net-snmp/net-snmp-config.h
+./snmptable.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptable.lo: ../include/net-snmp/definitions.h
+./snmptable.lo: ../include/net-snmp/types.h
+./snmptable.lo: ../include/net-snmp/library/oid.h
+./snmptable.lo: ../include/net-snmp/library/types.h
+./snmptable.lo: ../include/net-snmp/library/snmp_api.h
+./snmptable.lo: ../include/net-snmp/varbind_api.h
+./snmptable.lo: ../include/net-snmp/library/snmp_client.h
+./snmptable.lo: ../include/net-snmp/pdu_api.h
+./snmptable.lo: ../include/net-snmp/library/asn1.h
+./snmptable.lo: ../include/net-snmp/output_api.h
+./snmptable.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptable.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptable.lo: ../include/net-snmp/session_api.h
+./snmptable.lo: ../include/net-snmp/library/callback.h
+./snmptable.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptable.lo: ../include/net-snmp/library/snmp_service.h
+./snmptable.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptable.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptable.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptable.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptable.lo: ../include/net-snmp/library/mib.h
+./snmptable.lo: ../include/net-snmp/mib_api.h
+./snmptable.lo: ../include/net-snmp/library/parse.h
+./snmptable.lo: ../include/net-snmp/library/oid_stash.h
+./snmptable.lo: ../include/net-snmp/net-snmp-features.h
+./snmptable.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptable.lo: ../include/net-snmp/library/snmp.h
+./snmptable.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptable.lo: ../include/net-snmp/library/getopt.h
+./snmptable.lo: ../include/net-snmp/utilities.h
+./snmptable.lo: ../include/net-snmp/library/system.h
+./snmptable.lo: ../include/net-snmp/library/tools.h
+./snmptable.lo: ../include/net-snmp/library/int64.h
+./snmptable.lo: ../include/net-snmp/library/mt_support.h
+./snmptable.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptable.lo: ../include/net-snmp/library/data_list.h
+./snmptable.lo: ../include/net-snmp/library/check_varbind.h
+./snmptable.lo: ../include/net-snmp/library/container.h
+./snmptable.lo: ../include/net-snmp/library/factory.h
+./snmptable.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptable.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptable.lo: ../include/net-snmp/library/container_iterator.h
+./snmptable.lo: ../include/net-snmp/library/container.h
+./snmptable.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptable.lo: ../include/net-snmp/version.h
+./snmptable.lo: ../include/net-snmp/config_api.h
+./snmptable.lo: ../include/net-snmp/library/read_config.h
+./snmptable.lo: ../include/net-snmp/library/default_store.h
+./snmptable.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptable.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptable.lo: ../include/net-snmp/library/vacm.h
+./snmptable.lo: ../include/net-snmp/snmpv3_api.h
+./snmptable.lo: ../include/net-snmp/library/snmpv3.h
+./snmptable.lo: ../include/net-snmp/library/transform_oids.h
+./snmptable.lo: ../include/net-snmp/library/keytools.h
+./snmptable.lo: ../include/net-snmp/library/scapi.h
+./snmptable.lo: ../include/net-snmp/library/lcd_time.h
+./snmptable.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptable.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptable.lo: ../include/net-snmp/library/snmptsm.h
+./snmptable.lo: ../include/net-snmp/library/snmpusm.h
+./snmptest.lo: ../include/net-snmp/net-snmp-config.h
+./snmptest.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptest.lo: ../include/net-snmp/definitions.h
+./snmptest.lo: ../include/net-snmp/types.h
+./snmptest.lo: ../include/net-snmp/library/oid.h
+./snmptest.lo: ../include/net-snmp/library/types.h
+./snmptest.lo: ../include/net-snmp/library/snmp_api.h
+./snmptest.lo: ../include/net-snmp/varbind_api.h
+./snmptest.lo: ../include/net-snmp/library/snmp_client.h
+./snmptest.lo: ../include/net-snmp/pdu_api.h
+./snmptest.lo: ../include/net-snmp/library/asn1.h
+./snmptest.lo: ../include/net-snmp/output_api.h
+./snmptest.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptest.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptest.lo: ../include/net-snmp/session_api.h
+./snmptest.lo: ../include/net-snmp/library/callback.h
+./snmptest.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptest.lo: ../include/net-snmp/library/snmp_service.h
+./snmptest.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptest.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptest.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptest.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptest.lo: ../include/net-snmp/library/mib.h
+./snmptest.lo: ../include/net-snmp/mib_api.h
+./snmptest.lo: ../include/net-snmp/library/parse.h
+./snmptest.lo: ../include/net-snmp/library/oid_stash.h
+./snmptest.lo: ../include/net-snmp/net-snmp-features.h
+./snmptest.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptest.lo: ../include/net-snmp/library/snmp.h
+./snmptest.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptest.lo: ../include/net-snmp/library/getopt.h
+./snmptest.lo: ../include/net-snmp/utilities.h
+./snmptest.lo: ../include/net-snmp/library/system.h
+./snmptest.lo: ../include/net-snmp/library/tools.h
+./snmptest.lo: ../include/net-snmp/library/int64.h
+./snmptest.lo: ../include/net-snmp/library/mt_support.h
+./snmptest.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptest.lo: ../include/net-snmp/library/data_list.h
+./snmptest.lo: ../include/net-snmp/library/check_varbind.h
+./snmptest.lo: ../include/net-snmp/library/container.h
+./snmptest.lo: ../include/net-snmp/library/factory.h
+./snmptest.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptest.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptest.lo: ../include/net-snmp/library/container_iterator.h
+./snmptest.lo: ../include/net-snmp/library/container.h
+./snmptest.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptest.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmptest.lo: ../include/net-snmp/library/read_config.h
+./snmptest.lo: ../include/net-snmp/library/default_store.h
+./snmptest.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptest.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptest.lo: ../include/net-snmp/library/vacm.h
+./snmptest.lo: ../include/net-snmp/snmpv3_api.h
+./snmptest.lo: ../include/net-snmp/library/snmpv3.h
+./snmptest.lo: ../include/net-snmp/library/transform_oids.h
+./snmptest.lo: ../include/net-snmp/library/keytools.h
+./snmptest.lo: ../include/net-snmp/library/scapi.h
+./snmptest.lo: ../include/net-snmp/library/lcd_time.h
+./snmptest.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptest.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptest.lo: ../include/net-snmp/library/snmptsm.h
+./snmptest.lo: ../include/net-snmp/library/snmpusm.h
+./snmptls.lo: ../include/net-snmp/net-snmp-config.h
+./snmptls.lo: ../include/net-snmp/net-snmp-features.h
+./snmptls.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptls.lo: ../include/net-snmp/definitions.h ../include/net-snmp/types.h
+./snmptls.lo: ../include/net-snmp/library/oid.h
+./snmptls.lo: ../include/net-snmp/library/types.h
+./snmptls.lo: ../include/net-snmp/library/snmp_api.h
+./snmptls.lo: ../include/net-snmp/varbind_api.h
+./snmptls.lo: ../include/net-snmp/library/snmp_client.h
+./snmptls.lo: ../include/net-snmp/pdu_api.h
+./snmptls.lo: ../include/net-snmp/library/asn1.h
+./snmptls.lo: ../include/net-snmp/output_api.h
+./snmptls.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptls.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptls.lo: ../include/net-snmp/session_api.h
+./snmptls.lo: ../include/net-snmp/library/callback.h
+./snmptls.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptls.lo: ../include/net-snmp/library/snmp_service.h
+./snmptls.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptls.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptls.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptls.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptls.lo: ../include/net-snmp/library/mib.h ../include/net-snmp/mib_api.h
+./snmptls.lo: ../include/net-snmp/library/parse.h
+./snmptls.lo: ../include/net-snmp/library/oid_stash.h
+./snmptls.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptls.lo: ../include/net-snmp/library/snmp.h
+./snmptls.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptls.lo: ../include/net-snmp/library/getopt.h
+./snmptls.lo: ../include/net-snmp/utilities.h
+./snmptls.lo: ../include/net-snmp/library/system.h
+./snmptls.lo: ../include/net-snmp/library/tools.h
+./snmptls.lo: ../include/net-snmp/library/int64.h
+./snmptls.lo: ../include/net-snmp/library/mt_support.h
+./snmptls.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptls.lo: ../include/net-snmp/library/data_list.h
+./snmptls.lo: ../include/net-snmp/library/check_varbind.h
+./snmptls.lo: ../include/net-snmp/library/container.h
+./snmptls.lo: ../include/net-snmp/library/factory.h
+./snmptls.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptls.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptls.lo: ../include/net-snmp/library/container_iterator.h
+./snmptls.lo: ../include/net-snmp/library/container.h
+./snmptls.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptls.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmptls.lo: ../include/net-snmp/library/read_config.h
+./snmptls.lo: ../include/net-snmp/library/default_store.h
+./snmptls.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptls.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptls.lo: ../include/net-snmp/library/vacm.h
+./snmptls.lo: ../include/net-snmp/snmpv3_api.h
+./snmptls.lo: ../include/net-snmp/library/snmpv3.h
+./snmptls.lo: ../include/net-snmp/library/transform_oids.h
+./snmptls.lo: ../include/net-snmp/library/keytools.h
+./snmptls.lo: ../include/net-snmp/library/scapi.h
+./snmptls.lo: ../include/net-snmp/library/lcd_time.h
+./snmptls.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptls.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptls.lo: ../include/net-snmp/library/snmptsm.h
+./snmptls.lo: ../include/net-snmp/library/snmpusm.h
+./snmptls.lo: ../include/net-snmp/agent/net-snmp-agent-includes.h
+./snmptls.lo: ../include/net-snmp/agent/mib_module_config.h
+./snmptls.lo: ../include/net-snmp/agent/agent_module_config.h
+./snmptls.lo: ../include/net-snmp/agent/snmp_agent.h
+./snmptls.lo: ../include/net-snmp/agent/snmp_vars.h
+./snmptls.lo: ../include/net-snmp/agent/agent_handler.h
+./snmptls.lo: ../include/net-snmp/agent/var_struct.h
+./snmptls.lo: ../include/net-snmp/agent/agent_registry.h
+./snmptls.lo: ../include/net-snmp/library/fd_event_manager.h
+./snmptls.lo: ../include/net-snmp/agent/ds_agent.h
+./snmptls.lo: ../include/net-snmp/agent/agent_read_config.h
+./snmptls.lo: ../include/net-snmp/agent/agent_trap.h
+./snmptls.lo: ../include/net-snmp/agent/all_helpers.h
+./snmptls.lo: ../include/net-snmp/agent/instance.h
+./snmptls.lo: ../include/net-snmp/agent/baby_steps.h
+./snmptls.lo: ../include/net-snmp/agent/scalar.h
+./snmptls.lo: ../include/net-snmp/agent/scalar_group.h
+./snmptls.lo: ../include/net-snmp/agent/watcher.h
+./snmptls.lo: ../include/net-snmp/agent/multiplexer.h
+./snmptls.lo: ../include/net-snmp/agent/null.h
+./snmptls.lo: ../include/net-snmp/agent/debug_handler.h
+./snmptls.lo: ../include/net-snmp/agent/cache_handler.h
+./snmptls.lo: ../include/net-snmp/agent/old_api.h
+./snmptls.lo: ../include/net-snmp/agent/read_only.h
+./snmptls.lo: ../include/net-snmp/agent/row_merge.h
+./snmptls.lo: ../include/net-snmp/agent/serialize.h
+./snmptls.lo: ../include/net-snmp/agent/bulk_to_next.h
+./snmptls.lo: ../include/net-snmp/agent/mode_end_call.h
+./snmptls.lo: ../include/net-snmp/agent/table.h
+./snmptls.lo: ../include/net-snmp/agent/table_data.h
+./snmptls.lo: ../include/net-snmp/agent/table_dataset.h
+./snmptls.lo: ../include/net-snmp/agent/table_tdata.h
+./snmptls.lo: ../include/net-snmp/agent/table_iterator.h
+./snmptls.lo: ../include/net-snmp/agent/table_container.h
+./snmptls.lo: ../include/net-snmp/agent/table_array.h
+./snmptls.lo: ../include/net-snmp/agent/mfd.h
+./snmptls.lo: ../include/net-snmp/agent/snmp_get_statistic.h
+./snmptls.lo: ../include/net-snmp/library/cert_util.h
+./snmptls.lo: ../agent/mibgroup/tlstm-mib.h
+./snmptls.lo: ../agent/mibgroup/tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.h
+./snmptls.lo: ../agent/mibgroup/tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.h
+./snmptls.lo: ../agent/mibgroup/tlstm-mib/snmpTlstmCertToTSNTable/snmpTlstmCertToTSNTable.h
+./snmptranslate.lo: ../include/net-snmp/net-snmp-config.h
+./snmptranslate.lo: ../include/net-snmp/utilities.h
+./snmptranslate.lo: ../include/net-snmp/types.h
+./snmptranslate.lo: ../include/net-snmp/library/oid.h
+./snmptranslate.lo: ../include/net-snmp/library/types.h
+./snmptranslate.lo: ../include/net-snmp/definitions.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_api.h
+./snmptranslate.lo: ../include/net-snmp/varbind_api.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_client.h
+./snmptranslate.lo: ../include/net-snmp/pdu_api.h
+./snmptranslate.lo: ../include/net-snmp/library/asn1.h
+./snmptranslate.lo: ../include/net-snmp/output_api.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptranslate.lo: ../include/net-snmp/session_api.h
+./snmptranslate.lo: ../include/net-snmp/library/callback.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_service.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptranslate.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptranslate.lo: ../include/net-snmp/library/mib.h
+./snmptranslate.lo: ../include/net-snmp/mib_api.h
+./snmptranslate.lo: ../include/net-snmp/library/parse.h
+./snmptranslate.lo: ../include/net-snmp/library/oid_stash.h
+./snmptranslate.lo: ../include/net-snmp/net-snmp-features.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptranslate.lo: ../include/net-snmp/library/system.h
+./snmptranslate.lo: ../include/net-snmp/library/tools.h
+./snmptranslate.lo: ../include/net-snmp/library/int64.h
+./snmptranslate.lo: ../include/net-snmp/library/mt_support.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptranslate.lo: ../include/net-snmp/library/data_list.h
+./snmptranslate.lo: ../include/net-snmp/library/check_varbind.h
+./snmptranslate.lo: ../include/net-snmp/library/container.h
+./snmptranslate.lo: ../include/net-snmp/library/factory.h
+./snmptranslate.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptranslate.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptranslate.lo: ../include/net-snmp/library/container_iterator.h
+./snmptranslate.lo: ../include/net-snmp/library/container.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptranslate.lo: ../include/net-snmp/version.h
+./snmptranslate.lo: ../include/net-snmp/config_api.h
+./snmptranslate.lo: ../include/net-snmp/library/read_config.h
+./snmptranslate.lo: ../include/net-snmp/library/default_store.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptranslate.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptranslate.lo: ../include/net-snmp/library/vacm.h
+./snmptrap.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrap.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptrap.lo: ../include/net-snmp/definitions.h
+./snmptrap.lo: ../include/net-snmp/types.h
+./snmptrap.lo: ../include/net-snmp/library/oid.h
+./snmptrap.lo: ../include/net-snmp/library/types.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_api.h
+./snmptrap.lo: ../include/net-snmp/varbind_api.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_client.h
+./snmptrap.lo: ../include/net-snmp/pdu_api.h
+./snmptrap.lo: ../include/net-snmp/library/asn1.h
+./snmptrap.lo: ../include/net-snmp/output_api.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptrap.lo: ../include/net-snmp/session_api.h
+./snmptrap.lo: ../include/net-snmp/library/callback.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_service.h
+./snmptrap.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptrap.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptrap.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptrap.lo: ../include/net-snmp/library/mib.h
+./snmptrap.lo: ../include/net-snmp/mib_api.h
+./snmptrap.lo: ../include/net-snmp/library/parse.h
+./snmptrap.lo: ../include/net-snmp/library/oid_stash.h
+./snmptrap.lo: ../include/net-snmp/net-snmp-features.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptrap.lo: ../include/net-snmp/library/snmp.h
+./snmptrap.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptrap.lo: ../include/net-snmp/library/getopt.h
+./snmptrap.lo: ../include/net-snmp/utilities.h
+./snmptrap.lo: ../include/net-snmp/library/system.h
+./snmptrap.lo: ../include/net-snmp/library/tools.h
+./snmptrap.lo: ../include/net-snmp/library/int64.h
+./snmptrap.lo: ../include/net-snmp/library/mt_support.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptrap.lo: ../include/net-snmp/library/data_list.h
+./snmptrap.lo: ../include/net-snmp/library/check_varbind.h
+./snmptrap.lo: ../include/net-snmp/library/container.h
+./snmptrap.lo: ../include/net-snmp/library/factory.h
+./snmptrap.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptrap.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptrap.lo: ../include/net-snmp/library/container_iterator.h
+./snmptrap.lo: ../include/net-snmp/library/container.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptrap.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmptrap.lo: ../include/net-snmp/library/read_config.h
+./snmptrap.lo: ../include/net-snmp/library/default_store.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptrap.lo: ../include/net-snmp/library/vacm.h
+./snmptrap.lo: ../include/net-snmp/snmpv3_api.h
+./snmptrap.lo: ../include/net-snmp/library/snmpv3.h
+./snmptrap.lo: ../include/net-snmp/library/transform_oids.h
+./snmptrap.lo: ../include/net-snmp/library/keytools.h
+./snmptrap.lo: ../include/net-snmp/library/scapi.h
+./snmptrap.lo: ../include/net-snmp/library/lcd_time.h
+./snmptrap.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptrap.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptrap.lo: ../include/net-snmp/library/snmptsm.h
+./snmptrap.lo: ../include/net-snmp/library/snmpusm.h
+./snmptrapd_auth.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrapd_auth.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptrapd_auth.lo: ../include/net-snmp/definitions.h
+./snmptrapd_auth.lo: ../include/net-snmp/types.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/oid.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/types.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/varbind_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_client.h
+./snmptrapd_auth.lo: ../include/net-snmp/pdu_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/asn1.h
+./snmptrapd_auth.lo: ../include/net-snmp/output_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptrapd_auth.lo: ../include/net-snmp/session_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/callback.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_service.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/mib.h
+./snmptrapd_auth.lo: ../include/net-snmp/mib_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/parse.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/oid_stash.h
+./snmptrapd_auth.lo: ../include/net-snmp/net-snmp-features.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/getopt.h
+./snmptrapd_auth.lo: ../include/net-snmp/utilities.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/system.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/tools.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/int64.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/mt_support.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/data_list.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/check_varbind.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/container.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/factory.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/container_iterator.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/container.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptrapd_auth.lo: ../include/net-snmp/version.h
+./snmptrapd_auth.lo: ../include/net-snmp/config_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/read_config.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/default_store.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/vacm.h
+./snmptrapd_auth.lo: ../include/net-snmp/snmpv3_api.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpv3.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/transform_oids.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/keytools.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/scapi.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/lcd_time.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmptsm.h
+./snmptrapd_auth.lo: ../include/net-snmp/library/snmpusm.h
+./snmptrapd_auth.lo: snmptrapd_handlers.h snmptrapd_auth.h snmptrapd_ds.h
+./snmptrapd_auth.lo: ../include/net-snmp/agent/agent_module_config.h
+./snmptrapd_auth.lo: ../include/net-snmp/agent/mib_module_config.h
+./snmptrapd_auth.lo: ../agent/mibgroup/mibII/vacm_conf.h
+./snmptrapd_auth.lo: ../include/net-snmp/agent/agent_trap.h
+./snmptrapd.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrapd.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptrapd.lo: ../include/net-snmp/definitions.h
+./snmptrapd.lo: ../include/net-snmp/types.h
+./snmptrapd.lo: ../include/net-snmp/library/oid.h
+./snmptrapd.lo: ../include/net-snmp/library/types.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_api.h
+./snmptrapd.lo: ../include/net-snmp/varbind_api.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_client.h
+./snmptrapd.lo: ../include/net-snmp/pdu_api.h
+./snmptrapd.lo: ../include/net-snmp/library/asn1.h
+./snmptrapd.lo: ../include/net-snmp/output_api.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptrapd.lo: ../include/net-snmp/session_api.h
+./snmptrapd.lo: ../include/net-snmp/library/callback.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_service.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptrapd.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptrapd.lo: ../include/net-snmp/library/mib.h
+./snmptrapd.lo: ../include/net-snmp/mib_api.h
+./snmptrapd.lo: ../include/net-snmp/library/parse.h
+./snmptrapd.lo: ../include/net-snmp/library/oid_stash.h
+./snmptrapd.lo: ../include/net-snmp/net-snmp-features.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptrapd.lo: ../include/net-snmp/library/getopt.h
+./snmptrapd.lo: ../include/net-snmp/utilities.h
+./snmptrapd.lo: ../include/net-snmp/library/system.h
+./snmptrapd.lo: ../include/net-snmp/library/tools.h
+./snmptrapd.lo: ../include/net-snmp/library/int64.h
+./snmptrapd.lo: ../include/net-snmp/library/mt_support.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptrapd.lo: ../include/net-snmp/library/data_list.h
+./snmptrapd.lo: ../include/net-snmp/library/check_varbind.h
+./snmptrapd.lo: ../include/net-snmp/library/container.h
+./snmptrapd.lo: ../include/net-snmp/library/factory.h
+./snmptrapd.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptrapd.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptrapd.lo: ../include/net-snmp/library/container_iterator.h
+./snmptrapd.lo: ../include/net-snmp/library/container.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptrapd.lo: ../include/net-snmp/version.h
+./snmptrapd.lo: ../include/net-snmp/config_api.h
+./snmptrapd.lo: ../include/net-snmp/library/read_config.h
+./snmptrapd.lo: ../include/net-snmp/library/default_store.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptrapd.lo: ../include/net-snmp/library/vacm.h
+./snmptrapd.lo: ../include/net-snmp/snmpv3_api.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpv3.h
+./snmptrapd.lo: ../include/net-snmp/library/transform_oids.h
+./snmptrapd.lo: ../include/net-snmp/library/keytools.h
+./snmptrapd.lo: ../include/net-snmp/library/scapi.h
+./snmptrapd.lo: ../include/net-snmp/library/lcd_time.h
+./snmptrapd.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptrapd.lo: ../include/net-snmp/library/snmptsm.h
+./snmptrapd.lo: ../include/net-snmp/library/snmpusm.h
+./snmptrapd.lo: ../include/net-snmp/agent/net-snmp-agent-includes.h
+./snmptrapd.lo: ../include/net-snmp/agent/mib_module_config.h
+./snmptrapd.lo: ../include/net-snmp/agent/agent_module_config.h
+./snmptrapd.lo: ../include/net-snmp/agent/snmp_agent.h
+./snmptrapd.lo: ../include/net-snmp/agent/snmp_vars.h
+./snmptrapd.lo: ../include/net-snmp/agent/agent_handler.h
+./snmptrapd.lo: ../include/net-snmp/agent/var_struct.h
+./snmptrapd.lo: ../include/net-snmp/agent/agent_registry.h
+./snmptrapd.lo: ../include/net-snmp/library/fd_event_manager.h
+./snmptrapd.lo: ../include/net-snmp/agent/ds_agent.h
+./snmptrapd.lo: ../include/net-snmp/agent/agent_read_config.h
+./snmptrapd.lo: ../include/net-snmp/agent/agent_trap.h
+./snmptrapd.lo: ../include/net-snmp/agent/all_helpers.h
+./snmptrapd.lo: ../include/net-snmp/agent/instance.h
+./snmptrapd.lo: ../include/net-snmp/agent/baby_steps.h
+./snmptrapd.lo: ../include/net-snmp/agent/scalar.h
+./snmptrapd.lo: ../include/net-snmp/agent/scalar_group.h
+./snmptrapd.lo: ../include/net-snmp/agent/watcher.h
+./snmptrapd.lo: ../include/net-snmp/agent/multiplexer.h
+./snmptrapd.lo: ../include/net-snmp/agent/null.h
+./snmptrapd.lo: ../include/net-snmp/agent/debug_handler.h
+./snmptrapd.lo: ../include/net-snmp/agent/cache_handler.h
+./snmptrapd.lo: ../include/net-snmp/agent/old_api.h
+./snmptrapd.lo: ../include/net-snmp/agent/read_only.h
+./snmptrapd.lo: ../include/net-snmp/agent/row_merge.h
+./snmptrapd.lo: ../include/net-snmp/agent/serialize.h
+./snmptrapd.lo: ../include/net-snmp/agent/bulk_to_next.h
+./snmptrapd.lo: ../include/net-snmp/agent/mode_end_call.h
+./snmptrapd.lo: ../include/net-snmp/agent/table.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_data.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_dataset.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_tdata.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_iterator.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_container.h
+./snmptrapd.lo: ../include/net-snmp/agent/table_array.h
+./snmptrapd.lo: ../include/net-snmp/agent/mfd.h
+./snmptrapd.lo: ../include/net-snmp/agent/snmp_get_statistic.h
+./snmptrapd.lo: snmptrapd_handlers.h snmptrapd_log.h snmptrapd_ds.h
+./snmptrapd.lo: snmptrapd_auth.h
+./snmptrapd.lo: ../agent/mibgroup/notification-log-mib/notification_log.h
+./snmptrapd.lo: ../agent/mibgroup/tlstm-mib/snmpTlstmCertToTSNTable/snmpTlstmCertToTSNTable.h
+./snmptrapd.lo: ../agent/mibgroup/mibII/vacm_conf.h
+./snmptrapd_handlers.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrapd_handlers.lo: ../include/net-snmp/net-snmp-features.h
+./snmptrapd_handlers.lo: ../include/net-snmp/config_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/types.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/oid.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/types.h
+./snmptrapd_handlers.lo: ../include/net-snmp/definitions.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/varbind_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_client.h
+./snmptrapd_handlers.lo: ../include/net-snmp/pdu_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/asn1.h
+./snmptrapd_handlers.lo: ../include/net-snmp/output_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptrapd_handlers.lo: ../include/net-snmp/session_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/callback.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_service.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/mib.h
+./snmptrapd_handlers.lo: ../include/net-snmp/mib_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/parse.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/oid_stash.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/read_config.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/default_store.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/vacm.h
+./snmptrapd_handlers.lo: ../include/net-snmp/utilities.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/system.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/tools.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/int64.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/mt_support.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/data_list.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/check_varbind.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/container.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/factory.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/container_iterator.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/container.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptrapd_handlers.lo: ../include/net-snmp/version.h
+./snmptrapd_handlers.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/getopt.h
+./snmptrapd_handlers.lo: ../include/net-snmp/snmpv3_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpv3.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/transform_oids.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/keytools.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/scapi.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/lcd_time.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmptsm.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/snmpusm.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/net-snmp-agent-includes.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/mib_module_config.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/agent_module_config.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/snmp_agent.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/snmp_vars.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/agent_handler.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/var_struct.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/agent_registry.h
+./snmptrapd_handlers.lo: ../include/net-snmp/library/fd_event_manager.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/ds_agent.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/agent_read_config.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/agent_trap.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/all_helpers.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/instance.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/baby_steps.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/scalar.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/scalar_group.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/watcher.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/multiplexer.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/null.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/debug_handler.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/cache_handler.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/old_api.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/read_only.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/row_merge.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/serialize.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/bulk_to_next.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/mode_end_call.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_data.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_dataset.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_tdata.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_iterator.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_container.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/table_array.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/mfd.h
+./snmptrapd_handlers.lo: ../include/net-snmp/agent/snmp_get_statistic.h
+./snmptrapd_handlers.lo: ../agent/mibgroup/utilities/execute.h
+./snmptrapd_handlers.lo: snmptrapd_handlers.h snmptrapd_auth.h
+./snmptrapd_handlers.lo: snmptrapd_log.h snmptrapd_ds.h
+./snmptrapd_handlers.lo: ../agent/mibgroup/notification-log-mib/notification_log.h
+./snmptrapd_log.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrapd_log.lo: ../include/net-snmp/net-snmp-includes.h
+./snmptrapd_log.lo: ../include/net-snmp/definitions.h
+./snmptrapd_log.lo: ../include/net-snmp/types.h
+./snmptrapd_log.lo: ../include/net-snmp/library/oid.h
+./snmptrapd_log.lo: ../include/net-snmp/library/types.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_api.h
+./snmptrapd_log.lo: ../include/net-snmp/varbind_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_client.h
+./snmptrapd_log.lo: ../include/net-snmp/pdu_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/asn1.h
+./snmptrapd_log.lo: ../include/net-snmp/output_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_debug.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_logging.h
+./snmptrapd_log.lo: ../include/net-snmp/session_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/callback.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_transport.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_service.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmptrapd_log.lo: ../include/net-snmp/library/ucd_compat.h
+./snmptrapd_log.lo: ../include/net-snmp/library/mib.h
+./snmptrapd_log.lo: ../include/net-snmp/mib_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/parse.h
+./snmptrapd_log.lo: ../include/net-snmp/library/oid_stash.h
+./snmptrapd_log.lo: ../include/net-snmp/net-snmp-features.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_impl.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp-tc.h
+./snmptrapd_log.lo: ../include/net-snmp/library/getopt.h
+./snmptrapd_log.lo: ../include/net-snmp/utilities.h
+./snmptrapd_log.lo: ../include/net-snmp/library/system.h
+./snmptrapd_log.lo: ../include/net-snmp/library/tools.h
+./snmptrapd_log.lo: ../include/net-snmp/library/int64.h
+./snmptrapd_log.lo: ../include/net-snmp/library/mt_support.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmptrapd_log.lo: ../include/net-snmp/library/data_list.h
+./snmptrapd_log.lo: ../include/net-snmp/library/check_varbind.h
+./snmptrapd_log.lo: ../include/net-snmp/library/container.h
+./snmptrapd_log.lo: ../include/net-snmp/library/factory.h
+./snmptrapd_log.lo: ../include/net-snmp/library/container_binary_array.h
+./snmptrapd_log.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmptrapd_log.lo: ../include/net-snmp/library/container_iterator.h
+./snmptrapd_log.lo: ../include/net-snmp/library/container.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_assert.h
+./snmptrapd_log.lo: ../include/net-snmp/version.h
+./snmptrapd_log.lo: ../include/net-snmp/config_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/read_config.h
+./snmptrapd_log.lo: ../include/net-snmp/library/default_store.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_enum.h
+./snmptrapd_log.lo: ../include/net-snmp/library/vacm.h
+./snmptrapd_log.lo: ../include/net-snmp/snmpv3_api.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpv3.h
+./snmptrapd_log.lo: ../include/net-snmp/library/transform_oids.h
+./snmptrapd_log.lo: ../include/net-snmp/library/keytools.h
+./snmptrapd_log.lo: ../include/net-snmp/library/scapi.h
+./snmptrapd_log.lo: ../include/net-snmp/library/lcd_time.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmptsm.h
+./snmptrapd_log.lo: ../include/net-snmp/library/snmpusm.h snmptrapd_log.h
+./snmptrapd_log.lo: snmptrapd_ds.h
+./snmptrapd_sql.lo: ../include/net-snmp/net-snmp-config.h
+./snmptrapd_sql.lo: ../include/net-snmp/net-snmp-features.h
+./snmpusm.lo: ../include/net-snmp/net-snmp-config.h
+./snmpusm.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpusm.lo: ../include/net-snmp/definitions.h
+./snmpusm.lo: ../include/net-snmp/types.h
+./snmpusm.lo: ../include/net-snmp/library/oid.h
+./snmpusm.lo: ../include/net-snmp/library/types.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_api.h
+./snmpusm.lo: ../include/net-snmp/varbind_api.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_client.h
+./snmpusm.lo: ../include/net-snmp/pdu_api.h
+./snmpusm.lo: ../include/net-snmp/library/asn1.h
+./snmpusm.lo: ../include/net-snmp/output_api.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpusm.lo: ../include/net-snmp/session_api.h
+./snmpusm.lo: ../include/net-snmp/library/callback.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_service.h
+./snmpusm.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpusm.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpusm.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpusm.lo: ../include/net-snmp/library/mib.h ../include/net-snmp/mib_api.h
+./snmpusm.lo: ../include/net-snmp/library/parse.h
+./snmpusm.lo: ../include/net-snmp/library/oid_stash.h
+./snmpusm.lo: ../include/net-snmp/net-snmp-features.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpusm.lo: ../include/net-snmp/library/snmp.h
+./snmpusm.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpusm.lo: ../include/net-snmp/library/getopt.h
+./snmpusm.lo: ../include/net-snmp/utilities.h
+./snmpusm.lo: ../include/net-snmp/library/system.h
+./snmpusm.lo: ../include/net-snmp/library/tools.h
+./snmpusm.lo: ../include/net-snmp/library/int64.h
+./snmpusm.lo: ../include/net-snmp/library/mt_support.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpusm.lo: ../include/net-snmp/library/data_list.h
+./snmpusm.lo: ../include/net-snmp/library/check_varbind.h
+./snmpusm.lo: ../include/net-snmp/library/container.h
+./snmpusm.lo: ../include/net-snmp/library/factory.h
+./snmpusm.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpusm.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpusm.lo: ../include/net-snmp/library/container_iterator.h
+./snmpusm.lo: ../include/net-snmp/library/container.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpusm.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmpusm.lo: ../include/net-snmp/library/read_config.h
+./snmpusm.lo: ../include/net-snmp/library/default_store.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpusm.lo: ../include/net-snmp/library/vacm.h
+./snmpusm.lo: ../include/net-snmp/snmpv3_api.h
+./snmpusm.lo: ../include/net-snmp/library/snmpv3.h
+./snmpusm.lo: ../include/net-snmp/library/transform_oids.h
+./snmpusm.lo: ../include/net-snmp/library/keytools.h
+./snmpusm.lo: ../include/net-snmp/library/scapi.h
+./snmpusm.lo: ../include/net-snmp/library/lcd_time.h
+./snmpusm.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpusm.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpusm.lo: ../include/net-snmp/library/snmptsm.h
+./snmpusm.lo: ../include/net-snmp/library/snmpusm.h
+./snmpvacm.lo: ../include/net-snmp/net-snmp-config.h
+./snmpvacm.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpvacm.lo: ../include/net-snmp/definitions.h
+./snmpvacm.lo: ../include/net-snmp/types.h
+./snmpvacm.lo: ../include/net-snmp/library/oid.h
+./snmpvacm.lo: ../include/net-snmp/library/types.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_api.h
+./snmpvacm.lo: ../include/net-snmp/varbind_api.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_client.h
+./snmpvacm.lo: ../include/net-snmp/pdu_api.h
+./snmpvacm.lo: ../include/net-snmp/library/asn1.h
+./snmpvacm.lo: ../include/net-snmp/output_api.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpvacm.lo: ../include/net-snmp/session_api.h
+./snmpvacm.lo: ../include/net-snmp/library/callback.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_service.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpvacm.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpvacm.lo: ../include/net-snmp/library/mib.h
+./snmpvacm.lo: ../include/net-snmp/mib_api.h
+./snmpvacm.lo: ../include/net-snmp/library/parse.h
+./snmpvacm.lo: ../include/net-snmp/library/oid_stash.h
+./snmpvacm.lo: ../include/net-snmp/net-snmp-features.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpvacm.lo: ../include/net-snmp/library/getopt.h
+./snmpvacm.lo: ../include/net-snmp/utilities.h
+./snmpvacm.lo: ../include/net-snmp/library/system.h
+./snmpvacm.lo: ../include/net-snmp/library/tools.h
+./snmpvacm.lo: ../include/net-snmp/library/int64.h
+./snmpvacm.lo: ../include/net-snmp/library/mt_support.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpvacm.lo: ../include/net-snmp/library/data_list.h
+./snmpvacm.lo: ../include/net-snmp/library/check_varbind.h
+./snmpvacm.lo: ../include/net-snmp/library/container.h
+./snmpvacm.lo: ../include/net-snmp/library/factory.h
+./snmpvacm.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpvacm.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpvacm.lo: ../include/net-snmp/library/container_iterator.h
+./snmpvacm.lo: ../include/net-snmp/library/container.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpvacm.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmpvacm.lo: ../include/net-snmp/library/read_config.h
+./snmpvacm.lo: ../include/net-snmp/library/default_store.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpvacm.lo: ../include/net-snmp/library/vacm.h
+./snmpvacm.lo: ../include/net-snmp/snmpv3_api.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpv3.h
+./snmpvacm.lo: ../include/net-snmp/library/transform_oids.h
+./snmpvacm.lo: ../include/net-snmp/library/keytools.h
+./snmpvacm.lo: ../include/net-snmp/library/scapi.h
+./snmpvacm.lo: ../include/net-snmp/library/lcd_time.h
+./snmpvacm.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpvacm.lo: ../include/net-snmp/library/snmptsm.h
+./snmpvacm.lo: ../include/net-snmp/library/snmpusm.h
+./snmpwalk.lo: ../include/net-snmp/net-snmp-config.h
+./snmpwalk.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpwalk.lo: ../include/net-snmp/definitions.h
+./snmpwalk.lo: ../include/net-snmp/types.h
+./snmpwalk.lo: ../include/net-snmp/library/oid.h
+./snmpwalk.lo: ../include/net-snmp/library/types.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_api.h
+./snmpwalk.lo: ../include/net-snmp/varbind_api.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_client.h
+./snmpwalk.lo: ../include/net-snmp/pdu_api.h
+./snmpwalk.lo: ../include/net-snmp/library/asn1.h
+./snmpwalk.lo: ../include/net-snmp/output_api.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpwalk.lo: ../include/net-snmp/session_api.h
+./snmpwalk.lo: ../include/net-snmp/library/callback.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_service.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpwalk.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpwalk.lo: ../include/net-snmp/library/mib.h
+./snmpwalk.lo: ../include/net-snmp/mib_api.h
+./snmpwalk.lo: ../include/net-snmp/library/parse.h
+./snmpwalk.lo: ../include/net-snmp/library/oid_stash.h
+./snmpwalk.lo: ../include/net-snmp/net-snmp-features.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpwalk.lo: ../include/net-snmp/library/getopt.h
+./snmpwalk.lo: ../include/net-snmp/utilities.h
+./snmpwalk.lo: ../include/net-snmp/library/system.h
+./snmpwalk.lo: ../include/net-snmp/library/tools.h
+./snmpwalk.lo: ../include/net-snmp/library/int64.h
+./snmpwalk.lo: ../include/net-snmp/library/mt_support.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpwalk.lo: ../include/net-snmp/library/data_list.h
+./snmpwalk.lo: ../include/net-snmp/library/check_varbind.h
+./snmpwalk.lo: ../include/net-snmp/library/container.h
+./snmpwalk.lo: ../include/net-snmp/library/factory.h
+./snmpwalk.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpwalk.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpwalk.lo: ../include/net-snmp/library/container_iterator.h
+./snmpwalk.lo: ../include/net-snmp/library/container.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpwalk.lo: ../include/net-snmp/version.h ../include/net-snmp/config_api.h
+./snmpwalk.lo: ../include/net-snmp/library/read_config.h
+./snmpwalk.lo: ../include/net-snmp/library/default_store.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpwalk.lo: ../include/net-snmp/library/vacm.h
+./snmpwalk.lo: ../include/net-snmp/snmpv3_api.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpv3.h
+./snmpwalk.lo: ../include/net-snmp/library/transform_oids.h
+./snmpwalk.lo: ../include/net-snmp/library/keytools.h
+./snmpwalk.lo: ../include/net-snmp/library/scapi.h
+./snmpwalk.lo: ../include/net-snmp/library/lcd_time.h
+./snmpwalk.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpwalk.lo: ../include/net-snmp/library/snmptsm.h
+./snmpwalk.lo: ../include/net-snmp/library/snmpusm.h
+./sshtosnmp.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/if.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/if.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/if.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/if.lo: ../include/net-snmp/types.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/if.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/if.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/if.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/if.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/if.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/if.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/if.lo: ../include/net-snmp/version.h
+./snmpnetstat/if.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/if.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/if.lo: ../include/net-snmp/library/snmpusm.h
+./snmpnetstat/if.lo: ./snmpnetstat/main.h
+./snmpnetstat/if.lo: ./snmpnetstat/netstat.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/types.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/version.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/inet6.lo: ../include/net-snmp/library/snmpusm.h
+./snmpnetstat/inet6.lo: ./snmpnetstat/main.h ./snmpnetstat/netstat.h
+./snmpnetstat/inet.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/inet.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/inet.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/inet.lo: ../include/net-snmp/types.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/inet.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/inet.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/inet.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/inet.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/inet.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/inet.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/inet.lo: ../include/net-snmp/version.h
+./snmpnetstat/inet.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/inet.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/inet.lo: ../include/net-snmp/library/snmpusm.h
+./snmpnetstat/inet.lo: ./snmpnetstat/main.h ./snmpnetstat/netstat.h
+./snmpnetstat/main.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/main.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/main.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/main.lo: ../include/net-snmp/types.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/main.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/main.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/main.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/main.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/main.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/main.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/main.lo: ../include/net-snmp/version.h
+./snmpnetstat/main.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/main.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/main.lo: ../include/net-snmp/library/snmpusm.h
+./snmpnetstat/main.lo: ./snmpnetstat/main.h ./snmpnetstat/netstat.h
+./snmpnetstat/route.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/route.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/route.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/route.lo: ../include/net-snmp/types.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/route.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/route.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/route.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/route.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/route.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/route.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/route.lo: ../include/net-snmp/version.h
+./snmpnetstat/route.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/route.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/route.lo: ../include/net-snmp/library/snmpusm.h
+./snmpnetstat/route.lo: ./snmpnetstat/main.h ./snmpnetstat/netstat.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/net-snmp-config.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/net-snmp-includes.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/definitions.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/types.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/oid.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/types.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/varbind_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_client.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/pdu_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/asn1.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/output_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_debug.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_logging.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/session_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/callback.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_transport.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_service.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpCallbackDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpUnixDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpUDPDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpIPv4BaseDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpUDPBaseDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpTCPDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpUDPIPv6Domain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpIPv6BaseDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpIPXDomain.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/ucd_compat.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/mib.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/mib_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/parse.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/oid_stash.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/net-snmp-features.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_impl.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp-tc.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/getopt.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/utilities.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/system.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/tools.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/int64.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/mt_support.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_alarm.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/data_list.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/check_varbind.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/factory.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/container_binary_array.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/container_list_ssll.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/container_iterator.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/container.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_assert.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/version.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/config_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/read_config.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/default_store.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_parse_args.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_enum.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/vacm.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/snmpv3_api.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpv3.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/transform_oids.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/keytools.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/scapi.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/lcd_time.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmp_secmod.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpv3-security-includes.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmptsm.h
+./snmpnetstat/winstub.lo: ../include/net-snmp/library/snmpusm.h
diff --git a/apps/Makefile.in b/apps/Makefile.in
new file mode 100644
index 0000000..77404dd
--- /dev/null
+++ b/apps/Makefile.in
@@ -0,0 +1,230 @@
+#
+# Makefile for snmpget, snmpwalk, snmpbulkwalk, snmptest, snmptranslate,
+# snmptrapd, snmptable, snmpset, snmpgetnext, and other utilities.
+#
+
+top_builddir=..
+mysubdir=apps
+
+# use GNU vpath, if available, to only set a path for source and headers
+# VPATH will pick up objects too, which is bad if you are sharing a
+# source dir...
+@GNU_vpath@ %.h $(srcdir)
+@GNU_vpath@ %.c $(srcdir)
+# fallback to regular VPATH for non-gnu...
+@NON_GNU_VPATH@ $(srcdir)
+
+#
+# Things to install
+#
+
+@NETSNMP_BUILD_SSH_PROG_TRUE@SSHINSTALLBINPROG = sshtosnmp$(EXEEXT)
+@NETSNMP_BUILD_SSH_PROG_FALSE@SSHINSTALLBINPROG =
+@NETSNMP_BUILD_SSH_PROG_TRUE@SSHFEATUREPROG = sshtosnmp.ft
+@NETSNMP_BUILD_SSH_PROG_FALSE@SSHFEATUREPROG =
+@NETSNMP_BUILD_TLS_PROG_TRUE@TLSINSTALLBINPROG = snmptls$(EXEEXT)
+@NETSNMP_BUILD_TLS_PROG_FALSE@TLSINSTALLBINPROG =
+@NETSNMP_BUILD_TLS_PROG_TRUE@TLSFEATUREPROG = snmptls.ft
+@NETSNMP_BUILD_TLS_PROG_FALSE@TLSFEATUREPROG =
+@NETSNMP_BUILD_USM_PROG_TRUE@USMINSTALLBINPROG = snmpusm$(EXEEXT)
+@NETSNMP_BUILD_USM_PROG_FALSE@USMINSTALLBINPROG =
+@NETSNMP_BUILD_USM_PROG_TRUE@USMFEATUREPROG = snmpusm.ft
+@NETSNMP_BUILD_USM_PROG_FALSE@USMFEATUREPROG =
+@NETSNMP_BUILD_USM_PROG_TRUE@EKCSTALLBINPROG = encode_keychange$(EXEEXT)
+@NETSNMP_BUILD_USM_PROG_FALSE@EKCSTALLBINPROG =
+@NETSNMP_BUILD_USM_PROG_TRUE@EKCFEATUREPROG = encode_keychange.ft
+@NETSNMP_BUILD_USM_PROG_FALSE@EKCFEATUREPROG =
+@NETSNMP_BUILD_SET_PROG_TRUE@SNMPSETINSTALLBINPROG = snmpset$(EXEEXT)
+@NETSNMP_BUILD_SET_PROG_FALSE@SNMPSETINSTALLBINPROG =
+@NETSNMP_BUILD_SET_PROG_TRUE@SNMPSETFEATUREPROG = snmpset.ft
+@NETSNMP_BUILD_SET_PROG_FALSE@SNMPSETFEATUREPROG =
+@NETSNMP_BUILD_SET_PROG_TRUE@SNMPVACMINSTALLBINPROG = snmpvacm$(EXEEXT)
+@NETSNMP_BUILD_SET_PROG_FALSE@SNMPVACMINSTALLBINPROG =
+@NETSNMP_BUILD_SET_PROG_TRUE@SNMPVACMFEATUREPROG = snmpvacm.ft
+@NETSNMP_BUILD_SET_PROG_FALSE@SNMPVACMFEATUREPROG =
+
+@NETSNMP_HAVE_AGENTX_LIBS_TRUE@AGENTXTRAP = agentxtrap$(EXEEXT)
+@NETSNMP_HAVE_AGENTX_LIBS_FALSE@AGENTXTRAP =
+
+INSTALLBINPROGS = snmpget$(EXEEXT) \
+ snmpgetnext$(EXEEXT) \
+ $(SNMPSETINSTALLBINPROG) \
+ snmpwalk$(EXEEXT) \
+ snmpbulkwalk$(EXEEXT) \
+ snmptable$(EXEEXT) \
+ snmptrap$(EXEEXT) \
+ snmpbulkget$(EXEEXT) \
+ snmptranslate$(EXEEXT) \
+ snmpstatus$(EXEEXT) \
+ snmpdelta$(EXEEXT) \
+ snmptest$(EXEEXT) \
+ snmpdf$(EXEEXT) \
+ $(AGENTXTRAP) \
+ $(SNMPVACMINSTALLBINPROG) \
+ $(SSHINSTALLBINPROG) $(TLSINSTALLBINPROG) \
+ $(USMINSTALLBINPROG) $(EKCSTALLBINPROG)
+
+INSTALLSBINPROGS = snmptrapd$(EXEEXT)
+
+INSTALLLIBS = libnetsnmptrapd.$(LIB_EXTENSION)$(LIB_VERSION)
+
+SUBDIRS = snmpnetstat
+
+FEATUREFILE=../include/net-snmp/features-apps.h
+
+#
+# build variables.
+#
+
+# USELIBS/USEAGENTLIBS are for dependencies
+USELIBS = ../snmplib/libnetsnmp.$(LIB_EXTENSION)$(LIB_VERSION)
+AGENTLIB = ../agent/libnetsnmpagent.$(LIB_EXTENSION)$(LIB_VERSION)
+MIBLIB = ../agent/libnetsnmpmibs.$(LIB_EXTENSION)$(LIB_VERSION)
+USEAGENTLIBS = $(MIBLIB) $(AGENTLIB) $(USELIBS)
+MYSQL_LIBS = @MYSQL_LIBS@
+MYSQL_INCLUDES = @MYSQL_INCLUDES@
+
+VAL_LIBS = @VAL_LIBS@
+LIBS = $(USELIBS) $(VAL_LIBS) @LIBS@
+PERLLDOPTS_FOR_APPS = @PERLLDOPTS_FOR_APPS@
+PERLLDOPTS_FOR_LIBS = @PERLLDOPTS_FOR_LIBS@
+
+#
+# hack for compiling trapd when agent is disabled
+TRAPDWITHAGENT = $(USETRAPLIBS) $(MYSQL_LIBS) $(VAL_LIBS) @AGENTLIBS@
+TRAPDWITHOUTAGENT = $(LIBS) $(MYSQL_LIBS) $(VAL_LIBS)
+
+# these will be set by configure to one of the above 2 lines
+TRAPLIBS = @TRAPLIBS@ $(PERLLDOPTS_FOR_APPS)
+USETRAPLIBS = @USETRAPLIBS@
+
+CPPFLAGS = $(TOP_INCLUDES) -I. $(AGENT_INCLUDES) $(HELPER_INCLUDES) \
+ $(MIBGROUP_INCLUDES) \
+ $(SNMPLIB_INCLUDES) $(MYSQL_INCLUDES) @CPPFLAGS@
+
+OSUFFIX = lo
+TRAPD_OBJECTS = snmptrapd.$(OSUFFIX) @other_trapd_objects@
+LIBTRAPD_OBJS = snmptrapd_handlers.o snmptrapd_log.o \
+ snmptrapd_auth.o snmptrapd_sql.o
+LLIBTRAPD_OBJS = snmptrapd_handlers.lo snmptrapd_log.lo \
+ snmptrapd_auth.lo snmptrapd_sql.lo
+LIBTRAPD_FTS = snmptrapd_handlers.ft snmptrapd_log.ft \
+ snmptrapd_auth.ft snmptrapd_sql.ft
+OBJS = *.o
+LOBJS = *.lo
+FTOBJS=$(LIBTRAPD_FTS) \
+ snmpwalk.ft \
+ snmpbulkwalk.ft \
+ snmpbulkget.ft \
+ snmptranslate.ft \
+ snmpstatus.ft \
+ snmpget.ft \
+ snmpdelta.ft \
+ snmptable.ft \
+ snmptest.ft \
+ snmptrapd.ft \
+ snmptrap.ft \
+ $(SNMPSETFEATUREPROG) \
+ $(SNMPVACMFEATUREPROG) \
+ $(USMFEATUREPROG) \
+ $(TLSFEATUREPROG) \
+ agentxtrap.ft \
+ snmpgetnext.ft \
+ $(EKCFEATUREPROG) \
+ snmpdf.ft \
+ $(SSHFEATUREPROG)
+
+all: standardall
+
+OTHERINSTALL=snmpinforminstall snmptrapdperlinstall
+OTHERUNINSTALL=snmpinformuninstall snmptrapdperluninstall
+
+#
+# build rules
+#
+snmpwalk$(EXEEXT): snmpwalk.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpbulkwalk$(EXEEXT): snmpbulkwalk.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpbulkwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpbulkget$(EXEEXT): snmpbulkget.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpbulkget.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmptranslate$(EXEEXT): snmptranslate.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmptranslate.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpstatus$(EXEEXT): snmpstatus.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpstatus.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpget$(EXEEXT): snmpget.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpget.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpdelta$(EXEEXT): snmpdelta.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpdelta.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmptable$(EXEEXT): snmptable.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmptable.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmptest$(EXEEXT): snmptest.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmptest.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmptrapd$(EXEEXT): $(TRAPD_OBJECTS) $(USETRAPLIBS) $(INSTALLLIBS)
+ $(LINK) ${CFLAGS} -o $@ $(TRAPD_OBJECTS) $(INSTALLLIBS) ${LDFLAGS} ${TRAPLIBS}
+
+snmptrap$(EXEEXT): snmptrap.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmptrap.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpinform$(EXEEXT): snmptrap$(EXEEXT)
+ rm -f snmpinform
+ $(LN_S) snmptrap$(EXEEXT) snmpinform$(EXEEXT)
+
+snmpset$(EXEEXT): snmpset.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpset.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpusm$(EXEEXT): snmpusm.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpusm.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpvacm$(EXEEXT): snmpvacm.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpvacm.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmptls$(EXEEXT): snmptls.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmptls.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+agentxtrap$(EXEEXT): agentxtrap.$(OSUFFIX) $(USEAGENTLIBS)
+ $(LINK) ${CFLAGS} -o $@ agentxtrap.$(OSUFFIX) ${LDFLAGS} $(USEAGENTLIBS) $(PERLLDOPTS_FOR_APPS) ${LIBS}
+
+snmpgetnext$(EXEEXT): snmpgetnext.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpgetnext.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+encode_keychange$(EXEEXT): encode_keychange.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ encode_keychange.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+snmpdf$(EXEEXT): snmpdf.$(OSUFFIX) $(USELIBS)
+ $(LINK) ${CFLAGS} -o $@ snmpdf.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+libnetsnmptrapd.$(LIB_EXTENSION)$(LIB_VERSION): $(LLIBTRAPD_OBJS)
+ $(LIB_LD_CMD) $@ ${LLIBTRAPD_OBJS} $(MIBLIB) $(USELIBS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS)
+ $(RANLIB) $@
+
+snmpinforminstall:
+ rm -f $(INSTALL_PREFIX)$(bindir)/snmpinform$(EXEEXT)
+ $(LN_S) snmptrap$(EXEEXT) $(INSTALL_PREFIX)$(bindir)/snmpinform$(EXEEXT)
+
+snmpinformuninstall:
+ rm -f $(INSTALL_PREFIX)$(bindir)/snmpinform$(EXEEXT)
+
+snmptrapdperlinstall: installdirs
+ @$(INSTALL_DATA) $(srcdir)/snmp_perl_trapd.pl $(INSTALL_PREFIX)$(snmplibdir)/snmp_perl_trapd.pl
+ @echo "install: installed snmp_perl_trapd.pl in $(INSTALL_PREFIX)$(snmplibdir)"
+
+snmptrapdperluninstall: installdirs
+ @rm -f $(INSTALL_PREFIX)$(snmplibdir)/snmp_perl_trapd.pl
+ @echo "removed snmp_perl_trapd.pl from $(INSTALL_PREFIX)$(snmplibdir)"
+
+sshtosnmp$(EXEEXT): sshtosnmp.$(OSUFFIX)
+ $(LINK) ${CFLAGS} -o $@ sshtosnmp.$(OSUFFIX)
+
+
+installdirs:
+ @$(SHELL) $(srcdir)/../mkinstalldirs $(INSTALL_PREFIX)$(snmplibdir)
diff --git a/apps/agentxtrap.c b/apps/agentxtrap.c
new file mode 100644
index 0000000..f366f61
--- /dev/null
+++ b/apps/agentxtrap.c
@@ -0,0 +1,607 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> /* optind, optarg and optopt */
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/ds_agent.h>
+
+#include "../agent/mibgroup/agentx/agentx_config.h"
+#include "../agent/mibgroup/agentx/client.h"
+#include "../agent/mibgroup/agentx/protocol.h"
+
+netsnmp_feature_require(snmp_split_pdu)
+netsnmp_feature_require(snmp_reset_var_types)
+
+
+#ifdef __GNUC__
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
+extern const oid sysuptime_oid[];
+extern const size_t sysuptime_oid_len;
+extern const oid snmptrap_oid[];
+extern const size_t snmptrap_oid_len;
+
+static void
+usage(const char* progname)
+{
+ fprintf(stderr,
+ "USAGE: %s [OPTIONS] TRAP-PARAMETERS\n"
+ "\n"
+ " Version: %s\n"
+ " Web: http://www.net-snmp.org/\n"
+ " Email: net-snmp-coders@lists.sourceforge.net\n"
+ "\n"
+ "OPTIONS:\n", progname, netsnmp_get_version());
+
+ fprintf(stderr,
+ " -h\t\t\tdisplay this help message\n"
+ " -V\t\t\tdisplay package version number\n"
+ " -m MIB[:...]\t\tload given list of MIBs (ALL loads "
+ "everything)\n"
+ " -M DIR[:...]\t\tlook in given list of directories for MIBs\n"
+ " -D[TOKEN[,...]]\tturn on debugging output for the specified "
+ "TOKENs\n"
+ "\t\t\t (ALL gives extremely verbose debugging output)\n"
+ " -d\t\t\tdump all traffic\n");
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ fprintf(stderr,
+ " -P MIBOPTS\t\tToggle various defaults controlling mib "
+ "parsing:\n");
+ snmp_mib_toggle_options_usage("\t\t\t ", stderr);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ fprintf(stderr,
+ " -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
+ snmp_log_options_usage("\t\t\t ", stderr);
+
+ fprintf(stderr,
+ " -c context\n"
+ " -U uptime\n"
+ " -x ADDRESS\t\tuse ADDRESS as AgentX address\n"
+ "\n"
+ "TRAP-PARAMETERS:\n"
+ " trapoid [OID TYPE VALUE] ...\n");
+}
+
+struct tState_s;
+typedef const struct tState_s* tState;
+struct tState_s {
+ void (*entry)(tState self); /**<< State entry action */
+ void (*exit)(tState self); /**<< State exit action */
+ /** Handler for AgentX-Response-PDU's */
+ void (*response)(tState self, netsnmp_pdu *res);
+ /** State to change to if an AgentX timeout occurs or the timer runs out */
+ tState timeout;
+ void (*disconnect)(tState self); /**<< Handler for disconnect indications */
+ /** Handler for Close-PDU indications */
+ void (*close)(tState self, netsnmp_pdu *res);
+ const char* name; /**<< Name of the current state */
+ int is_open; /**<< If the connection is open in this state */
+};
+
+static tState state; /**<< Current state of the state machine */
+static tState next_state; /**<< Next state of the state machine */
+
+static const char *context = NULL; /**<< Context that delivers the trap */
+static size_t contextLen; /**<< Length of eventual context */
+static int result = 1; /**<< Program return value */
+static netsnmp_pdu *pdu = NULL; /**<< The trap pdu that is to be sent */
+/** The reference number of the next packet */
+static long packetid = 0;
+/** The session id of the session to the master */
+static long session;
+static void *sessp = NULL; /**<< The current communication session */
+
+#define STATE_CALL(method) \
+ if(!state->method) { \
+ snmp_log(LOG_ERR, "No " #method " method in %s, terminating\n", \
+ state->name); \
+ abort(); \
+ } else \
+ state->method
+
+static void
+change_state(tState new_state)
+{
+ if (next_state && next_state != new_state)
+ DEBUGMSGTL(("process", "Ignore transition to %s\n", next_state->name));
+ next_state = new_state;
+}
+
+static int
+handle_agentx_response(int operation, netsnmp_session *sp, UNUSED int reqid,
+ netsnmp_pdu *act, UNUSED void *magic)
+{
+ switch(operation) {
+ case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:
+ if(act->command == AGENTX_MSG_CLEANUPSET) {
+ /* Do nothing - no response and no action as nothing get
+ * allocated in any handler here
+ */
+ } else if(act->command != AGENTX_MSG_RESPONSE) {
+ /* Copy the head to a response */
+ netsnmp_pdu* res = snmp_split_pdu(act, 0, 0);
+ res->command = AGENTX_MSG_RESPONSE;
+ if (act->sessid != session || !state->is_open)
+ res->errstat = AGENTX_ERR_NOT_OPEN;
+ if(res->errstat == AGENTX_ERR_NOERROR)
+ switch(act->command) {
+ case AGENTX_MSG_GET:
+ res->variables = snmp_clone_varbind(act->variables);
+ snmp_reset_var_types(res->variables, SNMP_NOSUCHOBJECT);
+ break;
+ case AGENTX_MSG_GETNEXT:
+ case AGENTX_MSG_GETBULK:
+ res->variables = snmp_clone_varbind(act->variables);
+ snmp_reset_var_types(res->variables, SNMP_ENDOFMIBVIEW);
+ break;
+ case AGENTX_MSG_TESTSET:
+ res->errstat = SNMP_ERR_NOTWRITABLE;
+ res->errindex = 1;
+ break;
+ case AGENTX_MSG_COMMITSET:
+ res->errstat = SNMP_ERR_COMMITFAILED;
+ res->errindex = 1;
+ break;
+ case AGENTX_MSG_UNDOSET:
+ /* Success - could undo not setting any value :-) */
+ break;
+ case AGENTX_MSG_CLOSE:
+ /* Always let the master succeed! */
+ break;
+ default:
+ /* Unknown command */
+ res->errstat = AGENTX_ERR_PARSE_FAILED;
+ break;
+ }
+ if(snmp_send(sp, res) == 0)
+ snmp_free_pdu(res);
+ switch(act->command) {
+ case AGENTX_MSG_CLOSE:
+ /* Take action once the answer is sent! */
+ STATE_CALL(close)(state, act);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ } else
+ /* RESPONSE act->time, act->errstat, act->errindex, varlist */
+ STATE_CALL(response)(state, act);
+ break;
+ case NETSNMP_CALLBACK_OP_TIMED_OUT:
+ change_state(state->timeout);
+ break;
+ case NETSNMP_CALLBACK_OP_DISCONNECT:
+ STATE_CALL(disconnect)(state);
+ break;
+ }
+ return 0;
+}
+
+extern const struct tState_s Connecting;
+extern const struct tState_s Opening;
+extern const struct tState_s Notifying;
+extern const struct tState_s Closing;
+extern const struct tState_s Disconnecting;
+extern const struct tState_s Exit;
+
+static void
+StateDisconnect(UNUSED tState self)
+{
+ snmp_log(LOG_ERR, "Unexpected disconnect in state %s\n", self->name);
+ change_state(&Disconnecting);
+}
+
+static void
+StateClose(UNUSED tState self, netsnmp_pdu *act)
+{
+ snmp_log(LOG_ERR, "Unexpected close with reason code %ld in state %s\n",
+ act->errstat, self->name);
+ change_state(&Disconnecting);
+}
+
+static void
+ConnectingEntry(UNUSED tState self)
+{
+ netsnmp_session init;
+ netsnmp_transport* t;
+ void* sess;
+
+ if(sessp) {
+ snmp_sess_close(sessp);
+ sessp = NULL;
+ }
+
+ snmp_sess_init(&init);
+ init.version = AGENTX_VERSION_1;
+ init.retries = 0; /* Retries are handled by the state machine */
+ init.timeout = SNMP_DEFAULT_TIMEOUT;
+ init.flags |= SNMP_FLAGS_STREAM_SOCKET;
+ init.callback = handle_agentx_response;
+ init.authenticator = NULL;
+
+ if(!(t = netsnmp_transport_open_client(
+ "agentx", netsnmp_ds_get_string(
+ NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)))) {
+ snmp_perror("Failed to connect to AgentX server");
+ change_state(&Exit);
+ } else if(!(sess = snmp_sess_add_ex(
+ &init, t, NULL, agentx_parse, NULL, NULL,
+ agentx_realloc_build, agentx_check_packet, NULL))) {
+ snmp_perror("Failed to create session");
+ change_state(&Exit);
+ } else {
+ sessp = sess;
+ change_state(&Opening);
+ }
+}
+
+const struct tState_s Connecting = {
+ ConnectingEntry,
+ NULL,
+ NULL,
+ NULL,
+ StateDisconnect,
+ NULL,
+ "Connnecting",
+ 0
+};
+
+static netsnmp_pdu*
+pdu_create_opt_context(int command, const char* context, size_t len)
+{
+ netsnmp_pdu* res = snmp_pdu_create(command);
+ if (res)
+ if (context) {
+ if (snmp_clone_mem((void**)&res->contextName, context, len)) {
+ snmp_free_pdu(res);
+ res = NULL;
+ } else
+ res->contextNameLen = len;
+ }
+ return res;
+}
+
+static void
+OpeningEntry(UNUSED tState self)
+{
+ netsnmp_pdu* act =
+ pdu_create_opt_context(AGENTX_MSG_OPEN, context, contextLen);
+ if(act) {
+ act->sessid = 0;
+ act->transid = 0;
+ act->reqid = ++packetid;
+ act->time = 0;
+ snmp_pdu_add_variable(act, NULL, 0, ASN_OCTET_STR, NULL, 0);
+ if(snmp_sess_send(sessp, act) == 0)
+ snmp_free_pdu(act);
+ }
+}
+
+static void
+OpeningRes(UNUSED tState self, netsnmp_pdu *act)
+{
+ if(act->errstat == AGENTX_ERR_NOERROR) {
+ session = act->sessid;
+ change_state(&Notifying);
+ } else {
+ snmp_perror("Failed to open session");
+ change_state(&Exit);
+ }
+}
+
+const struct tState_s Opening = {
+ OpeningEntry,
+ NULL,
+ OpeningRes,
+ &Disconnecting,
+ StateDisconnect,
+ StateClose,
+ "Opening",
+ 0
+};
+
+static void
+NotifyingEntry(UNUSED tState self)
+{
+ netsnmp_pdu* act = snmp_clone_pdu(pdu);
+ if(act) {
+ act->sessid = session;
+ act->transid = 0;
+ act->reqid = ++packetid;
+ if(snmp_sess_send(sessp, act) == 0)
+ snmp_free_pdu(act);
+ }
+}
+
+static void
+NotifyingRes(UNUSED tState self, netsnmp_pdu *act)
+{
+ if(act->errstat == AGENTX_ERR_NOERROR)
+ result = 0;
+ else
+ snmp_perror("Failed to send notification");
+ /** \todo: Retry handling --- ClosingReconnect??? */
+ change_state(&Closing);
+}
+
+const struct tState_s Notifying = {
+ NotifyingEntry,
+ NULL,
+ NotifyingRes,
+ NULL, /** \todo: Retry handling? */
+ StateDisconnect, /** \todo: Retry handling? */
+ StateClose,
+ "Notifying",
+ 1
+};
+
+static void
+ClosingEntry(UNUSED tState self)
+{
+ /* CLOSE pdu->errstat */
+ netsnmp_pdu* act =
+ pdu_create_opt_context(AGENTX_MSG_CLOSE, context, contextLen);
+ if(act) {
+ act->sessid = session;
+ act->transid = 0;
+ act->reqid = ++packetid;
+ act->errstat = AGENTX_CLOSE_SHUTDOWN;
+ if(snmp_sess_send(sessp, act) == 0)
+ snmp_free_pdu(act);
+ }
+}
+
+static void
+ClosingRes(UNUSED tState self, netsnmp_pdu *act)
+{
+ if(act->errstat != AGENTX_ERR_NOERROR) {
+ snmp_log(LOG_ERR, "AgentX error status of %ld\n", act->errstat);
+ }
+ change_state(&Disconnecting);
+}
+
+static void
+ClosingDisconnect(UNUSED tState self)
+{
+ change_state(&Disconnecting);
+}
+
+static void
+ClosingClose(UNUSED tState self, UNUSED netsnmp_pdu *act)
+{
+ change_state(&Disconnecting);
+}
+
+const struct tState_s Closing = {
+ ClosingEntry,
+ NULL,
+ ClosingRes,
+ &Disconnecting,
+ ClosingDisconnect,
+ ClosingClose,
+ "Closing",
+ 1
+};
+
+static void
+DisconnectingEntry(UNUSED tState self)
+{
+ snmp_sess_close(sessp);
+ sessp = NULL;
+ change_state(&Exit);
+}
+
+const struct tState_s Disconnecting = {
+ DisconnectingEntry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Disconnecting",
+ 0
+};
+
+const struct tState_s Exit = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "Exit",
+ 0
+};
+
+int
+main(int argc, char *argv[])
+{
+ int arg;
+ char *prognam;
+ char *cp = NULL;
+
+ const char* sysUpTime = NULL;
+
+ prognam = strrchr(argv[0], '/');
+ if (prognam)
+ ++prognam;
+ else
+ prognam = argv[0];
+
+ putenv(strdup("POSIXLY_CORRECT=1"));
+
+ while ((arg = getopt(argc, argv, ":Vhm:M:D:dP:L:U:c:x:")) != -1) {
+ switch (arg) {
+ case 'h':
+ usage(prognam);
+ exit(0);
+ case 'm':
+ setenv("MIBS", optarg, 1);
+ break;
+ case 'M':
+ setenv("MIBDIRS", optarg, 1);
+ break;
+ case 'c':
+ context = optarg;
+ contextLen = strlen(context);
+ break;
+ case 'D':
+ debug_register_tokens(optarg);
+ snmp_set_do_debugging(1);
+ break;
+ case 'd':
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET, 1);
+ break;
+ case 'U':
+ sysUpTime = optarg;
+ break;
+ case 'V':
+ fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
+ exit(0);
+ break;
+#ifndef DISABLE_MIB_LOADING
+ case 'P':
+ cp = snmp_mib_toggle_options(optarg);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
+ usage(prognam);
+ exit(1);
+ }
+ break;
+#endif /* DISABLE_MIB_LOADING */
+ case 'L':
+ if (snmp_log_options(optarg, argc, argv) < 0) {
+ exit(1);
+ }
+ break;
+ case 'x':
+ if (optarg != NULL) {
+ netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_X_SOCKET, optarg);
+ } else
+ usage(argv[0]);
+ break;
+
+ case ':':
+ fprintf(stderr, "Option -%c requires an operand\n", optopt);
+ usage(prognam);
+ exit(1);
+ break;
+ case '?':
+ fprintf(stderr, "Unrecognized option: -%c\n", optopt);
+ usage(prognam);
+ exit(1);
+ break;
+ }
+ }
+
+ arg = optind;
+
+ /* initialize tcpip, if necessary */
+ SOCK_STARTUP;
+
+ init_snmp("snmpapp");
+ agentx_config_init();
+
+ /* NOTIFY varlist */
+ pdu = pdu_create_opt_context(AGENTX_MSG_NOTIFY, context, contextLen);
+
+ if (sysUpTime)
+ snmp_add_var(pdu, sysuptime_oid, sysuptime_oid_len, 't', sysUpTime);
+
+ if (arg == argc) {
+ fprintf(stderr, "Missing trap-oid parameter\n");
+ usage(prognam);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ if (snmp_add_var(pdu, snmptrap_oid, snmptrap_oid_len, 'o', argv[arg])) {
+ snmp_perror(argv[arg]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ ++arg;
+
+ while (arg < argc) {
+ oid name[MAX_OID_LEN];
+ size_t name_length = MAX_OID_LEN;
+ arg += 3;
+ if (arg > argc) {
+ fprintf(stderr, "%s: Missing type/value for variable\n",
+ argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) {
+ snmp_perror(argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (snmp_add_var(pdu, name, name_length, argv[arg - 2][0],
+ argv[arg - 1]) != 0) {
+ snmp_perror(argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ }
+
+ packetid = 0;
+
+ state = &Connecting;
+ next_state = NULL;
+ if(state->entry) state->entry(state);
+
+ /* main loop here... */
+ for(;;) {
+ int block = 1;
+ int numfds = 0;
+ int count;
+ fd_set fdset;
+ struct timeval timeout;
+
+ while(next_state) {
+ if(state->exit) state->exit(state);
+ DEBUGMSGTL(("process", "State transition: %s -> %s\n",
+ state->name, next_state->name));
+ state = next_state;
+ next_state = NULL;
+ if(state->entry) state->entry(state);
+ }
+
+ if(state == &Exit)
+ break;
+
+ FD_ZERO(&fdset);
+ snmp_sess_select_info(sessp, &numfds, &fdset, &timeout, &block);
+ count = select(numfds, &fdset, NULL, NULL, !block ? &timeout : NULL);
+ if (count > 0)
+ snmp_sess_read(sessp, &fdset);
+ else if (count == 0)
+ snmp_sess_timeout(sessp);
+ else if (errno != EINTR) {
+ snmp_log(LOG_ERR, "select error [%s]\n", strerror(errno));
+ change_state(&Exit);
+ }
+ }
+
+ /* at shutdown time */
+ snmp_free_pdu(pdu);
+ pdu = NULL;
+
+ snmp_shutdown("snmpapp");
+
+ SOCK_CLEANUP;
+ exit(result);
+}
diff --git a/apps/encode_keychange.c b/apps/encode_keychange.c
new file mode 100644
index 0000000..5bf8e4c
--- /dev/null
+++ b/apps/encode_keychange.c
@@ -0,0 +1,803 @@
+/*
+ * encode_keychange.c
+ *
+ * Collect information to build a KeyChange encoding, per the textual
+ * convention given in RFC 2274, Section 5. Compute the value and
+ * dump to stdout as a string of hex nibbles.
+ *
+ *
+ * Passphrase material may come from many sources. The following are
+ * checked in order (see get_user_passphrases()):
+ * - Prompt always if -f is given.
+ * - Commandline arguments.
+ * - PASSPHRASE_FILE.
+ * - Prompts on stdout. Use -P to turn off prompt tags.
+ *
+ *
+ * FIX Better name?
+ * FIX Change encode_keychange() to take random bits?
+ * FIX QUITFUN not quite appropriate here...
+ * FIX This is slow...
+ */
+
+#include <net-snmp/net-snmp-config.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#include <stdlib.h>
+
+/*
+ * Globals, &c...
+ */
+char *local_progname;
+char *local_passphrase_filename;
+
+#define NL "\n"
+
+#define USAGE "Usage: %s [-fhPvV] -t (md5|sha1) [-O \"<old_passphrase>\"][-N \"<new_passphrase>\"][-E [0x]<engineID>]"
+
+#define OPTIONLIST "E:fhN:O:Pt:vVD"
+
+#define PASSPHRASE_DIR ".snmp"
+ /*
+ * Rooted at $HOME.
+ */
+#define PASSPHRASE_FILE "passphrase.ek"
+ /*
+ * Format: two lines containing old and new passphrases, nothing more.
+ *
+ * XXX Add creature comforts like: comments and
+ * tokens identifying passphrases, separate directory check,
+ * check in current directory (?), traverse a path of
+ * directories (?)...
+ * FIX Better name?
+ */
+
+
+int forcepassphrase = 0, /* Always prompt for passphrases. */
+ promptindicator = 1, /* Output an indicator that input
+ * is requested. */
+ visible = 0, /* Echo passphrases to terminal. */
+ verbose = 0; /* Output progress to stderr. */
+size_t engineid_len = 0;
+
+u_char *engineid = NULL; /* Both input & final binary form. */
+char *newpass = NULL, *oldpass = NULL;
+
+char *transform_type_input = NULL;
+
+const oid *transform_type = NULL; /* Type of HMAC hash to use. */
+
+
+
+/*
+ * Prototypes.
+ */
+void usage_to_file(FILE * ofp);
+void usage_synopsis(FILE * ofp);
+int get_user_passphrases(void);
+int snmp_ttyecho(const int fd, const int echo);
+char *snmp_getpassphrase(const char *prompt, int fvisible);
+
+#ifdef WIN32
+#define HAVE_GETPASS 1
+char *getpass(const char *prompt);
+int isatty(int);
+int _cputs(const char *);
+int _getch(void);
+#endif
+
+/*******************************************************************-o-******
+ */
+int
+main(int argc, char **argv)
+{
+ int rval = 1;
+ size_t oldKu_len = SNMP_MAXBUF_SMALL,
+ newKu_len = SNMP_MAXBUF_SMALL,
+ oldkul_len = SNMP_MAXBUF_SMALL,
+ newkul_len = SNMP_MAXBUF_SMALL, keychange_len = SNMP_MAXBUF_SMALL;
+
+ char *s = NULL;
+ u_char oldKu[SNMP_MAXBUF_SMALL],
+ newKu[SNMP_MAXBUF_SMALL],
+ oldkul[SNMP_MAXBUF_SMALL],
+ newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL];
+
+ int i;
+ int arg = 1;
+
+ local_progname = argv[0];
+ local_passphrase_filename = (char *) malloc(sizeof(PASSPHRASE_DIR) +
+ sizeof(PASSPHRASE_FILE) +
+ 4);
+ if (!local_passphrase_filename) {
+ fprintf(stderr, "%s: out of memory!", local_progname);
+ exit(-1);
+ }
+ sprintf(local_passphrase_filename, "%s/%s", PASSPHRASE_DIR,
+ PASSPHRASE_FILE);
+
+
+
+ /*
+ * Parse.
+ */
+ for (; (arg < argc) && (argv[arg][0] == '-'); arg++) {
+ switch (argv[arg][1]) {
+ case 'D':
+ snmp_set_do_debugging(1);
+ break;
+ case 'E':
+ engineid = (u_char *) argv[++arg];
+ break;
+ case 'f':
+ forcepassphrase = 1;
+ break;
+ case 'N':
+ newpass = argv[++arg];
+ break;
+ case 'O':
+ oldpass = argv[++arg];
+ break;
+ case 'P':
+ promptindicator = 0;
+ break;
+ case 't':
+ transform_type_input = argv[++arg];
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'V':
+ visible = 1;
+ break;
+ case 'h':
+ rval = 0;
+ /* fallthrough */
+ default:
+ usage_to_file(stdout);
+ exit(rval);
+ }
+ }
+
+ if (!transform_type_input) {
+ fprintf(stderr, "The -t option is mandatory.\n");
+ usage_synopsis(stdout);
+ exit(1000);
+ }
+
+
+
+ /*
+ * Convert and error check transform_type.
+ */
+#ifndef NETSNMP_DISABLE_MD5
+ if (!strcmp(transform_type_input, "md5")) {
+ transform_type = usmHMACMD5AuthProtocol;
+
+ } else
+#endif
+ if (!strcmp(transform_type_input, "sha1")) {
+ transform_type = usmHMACSHA1AuthProtocol;
+
+ } else {
+ fprintf(stderr,
+ "Unrecognized hash transform: \"%s\".\n",
+ transform_type_input);
+ usage_synopsis(stderr);
+ QUITFUN(SNMPERR_GENERR, main_quit);
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Hash:\t\t%s\n",
+#ifndef NETSNMP_DISABLE_MD5
+ (transform_type == usmHMACMD5AuthProtocol)
+ ? "usmHMACMD5AuthProtocol" :
+#endif
+ "usmHMACSHA1AuthProtocol"
+ );
+ }
+
+
+
+ /*
+ * Build engineID. Accept hex engineID as the bits
+ * "in-and-of-themselves", otherwise create an engineID with the
+ * given string as text.
+ *
+ * If no engineID is given, lookup the first IP address for the
+ * localhost and use that (see setup_engineID()).
+ */
+ if (engineid && (tolower(*(engineid + 1)) == 'x')) {
+ engineid_len = hex_to_binary2(engineid + 2,
+ strlen((char *) engineid) - 2,
+ (char **) &engineid);
+ DEBUGMSGTL(("encode_keychange", "engineIDLen: %lu\n",
+ (unsigned long)engineid_len));
+ } else {
+ engineid_len = setup_engineID(&engineid, (char *) engineid);
+
+ }
+
+#ifdef NETSNMP_ENABLE_TESTING_CODE
+ if (verbose) {
+ fprintf(stderr, "EngineID:\t%s\n",
+ /*
+ * XXX =
+ */ dump_snmpEngineID(engineid, &engineid_len));
+ }
+#endif
+
+
+ /*
+ * Get passphrases from user.
+ */
+ rval = get_user_passphrases();
+ QUITFUN(rval, main_quit);
+
+ if (strlen(oldpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr, "Old passphrase must be greater than %d "
+ "characters in length.\n", USM_LENGTH_P_MIN);
+ QUITFUN(SNMPERR_GENERR, main_quit);
+
+ } else if (strlen(newpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr, "New passphrase must be greater than %d "
+ "characters in length.\n", USM_LENGTH_P_MIN);
+ QUITFUN(SNMPERR_GENERR, main_quit);
+ }
+
+ if (verbose) {
+ fprintf(stderr,
+ "Old passphrase:\t%s\nNew passphrase:\t%s\n",
+ oldpass, newpass);
+ }
+
+
+
+ /*
+ * Compute Ku and Kul's from old and new passphrases, then
+ * compute the keychange string & print it out.
+ */
+ rval = sc_init();
+ QUITFUN(rval, main_quit);
+
+
+ rval = generate_Ku(transform_type, USM_LENGTH_OID_TRANSFORM,
+ (u_char *) oldpass, strlen(oldpass),
+ oldKu, &oldKu_len);
+ QUITFUN(rval, main_quit);
+
+
+ rval = generate_Ku(transform_type, USM_LENGTH_OID_TRANSFORM,
+ (u_char *) newpass, strlen(newpass),
+ newKu, &newKu_len);
+ QUITFUN(rval, main_quit);
+
+
+ DEBUGMSGTL(("encode_keychange", "EID (%lu): ", (unsigned long)engineid_len));
+ for (i = 0; i < (int) engineid_len; i++)
+ DEBUGMSGTL(("encode_keychange", "%02x", (int) (engineid[i])));
+ DEBUGMSGTL(("encode_keychange", "\n"));
+
+ DEBUGMSGTL(("encode_keychange", "old Ku (%lu) (from %s): ", (unsigned long)oldKu_len,
+ oldpass));
+ for (i = 0; i < (int) oldKu_len; i++)
+ DEBUGMSGTL(("encode_keychange", "%02x", (int) (oldKu[i])));
+ DEBUGMSGTL(("encode_keychange", "\n"));
+
+ rval = generate_kul(transform_type, USM_LENGTH_OID_TRANSFORM,
+ engineid, engineid_len,
+ oldKu, oldKu_len, oldkul, &oldkul_len);
+ QUITFUN(rval, main_quit);
+
+
+ DEBUGMSGTL(("encode_keychange", "generating old Kul (%lu) (from Ku): ",
+ (unsigned long)oldkul_len));
+ for (i = 0; i < (int) oldkul_len; i++)
+ DEBUGMSGTL(("encode_keychange", "%02x", (int) (oldkul[i])));
+ DEBUGMSGTL(("encode_keychange", "\n"));
+
+ rval = generate_kul(transform_type, USM_LENGTH_OID_TRANSFORM,
+ engineid, engineid_len,
+ newKu, newKu_len, newkul, &newkul_len);
+ QUITFUN(rval, main_quit);
+
+ DEBUGMSGTL(("encode_keychange", "generating new Kul (%lu) (from Ku): ",
+ (unsigned long)oldkul_len));
+ for (i = 0; i < (int) newkul_len; i++)
+ DEBUGMSGTL(("encode_keychange", "%02x", newkul[i]));
+ DEBUGMSGTL(("encode_keychange", "\n"));
+
+ rval = encode_keychange(transform_type, USM_LENGTH_OID_TRANSFORM,
+ oldkul, oldkul_len,
+ newkul, newkul_len, keychange, &keychange_len);
+ QUITFUN(rval, main_quit);
+
+
+
+ binary_to_hex(keychange, keychange_len, &s);
+ printf("%s%s\n", (verbose) ? "KeyChange string:\t" : "", /* XXX stdout */
+ s);
+
+
+ /*
+ * Cleanup.
+ */
+ main_quit:
+ snmp_call_callbacks(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
+ NULL);
+
+
+ SNMP_ZERO(oldpass, strlen(oldpass));
+ SNMP_ZERO(newpass, strlen(newpass));
+
+ memset(oldKu, 0, oldKu_len);
+ memset(newKu, 0, newKu_len);
+
+ memset(oldkul, 0, oldkul_len);
+ memset(newkul, 0, newkul_len);
+
+ SNMP_ZERO(s, strlen(s));
+
+ return rval;
+
+} /* end main() */
+
+
+
+
+/*******************************************************************-o-******
+ */
+void
+usage_synopsis(FILE * ofp)
+{
+ fprintf(ofp, USAGE "\n\
+\n\
+ -E [0x]<engineID> EngineID used for kul generation.\n\
+ -f Force passphrases to be read from stdin.\n\
+ -h Help.\n\
+ -N \"<new_passphrase>\" Passphrase used to generate new Ku.\n\
+ -O \"<old_passphrase>\" Passphrase used to generate old Ku.\n\
+ -P Turn off prompt indicators.\n\
+ -t md5 | sha1 HMAC hash transform type.\n\
+ -v Verbose.\n\
+ -V Visible. Echo passphrases to terminal.\n\
+ " NL, local_progname);
+
+} /* end usage_synopsis() */
+
+void
+usage_to_file(FILE * ofp)
+{
+ char *s;
+
+ usage_synopsis(ofp);
+
+ fprintf(ofp, "\n%s\
+ a) Commandline options,\n\
+ b) The file \"%s/%s\",\n\
+ c) stdin -or- User input from the terminal.\n\n%s\
+ " NL,
+ "Only -t is mandatory. The transform is used to convert P=>Ku, convert\n\
+ Ku=>Kul, and to hash the old Kul with the random bits.\n\
+\n\
+ Passphrase will be taken from the first successful source as follows:\n",
+ (s = getenv("HOME")) ? s : "$HOME", local_passphrase_filename,
+ "-f will require reading from the stdin/terminal, ignoring a) and b).\n\
+ -P will prevent prompts for passphrases to stdout from being printed.\n\
+\n\
+ <engineID> is interpreted as a hex string when preceeded by \"0x\",\n\
+ otherwise it is created to contain \"text\". If nothing is given,\n\
+ <engineID> is constructed from the first IP address for the local host.\n");
+
+
+ /*
+ * FIX -- make this possible?
+ * -r [0x]<random_bits> Random bits used in KeyChange XOR.
+ *
+ * <engineID> and <random_bits> are interpreted as hex strings when
+ * preceeded by \"0x\", otherwise <engineID> is created to contain \"text\"
+ * and <random_bits> are the same as the ascii input.
+ *
+ * <random_bits> will be generated by SCAPI if not given. If value is
+ * too long, it will be truncated; if too short, the remainder will be
+ * filled in with zeros.
+ */
+
+} /* end usage() */
+
+
+/*
+ * this defined for HPUX aCC because the aCC doesn't drop the
+ */
+/*
+ * snmp_parse_args.c functionality if compile with -g, PKY
+ */
+
+void
+usage(void)
+{
+ usage_to_file(stdout);
+}
+
+
+
+
+
+/*******************************************************************-o-******
+ * get_user_passphrases
+ *
+ * Returns:
+ * SNMPERR_SUCCESS Success.
+ * SNMPERR_GENERR Otherwise.
+ *
+ *
+ * Acquire new and old passphrases from the user:
+ *
+ * + Always prompt if 'forcepassphrase' is set.
+ * + Use given arguments if they are defined.
+ * + Otherwise read file format from PASSPHRASE_FILE.
+ * Sanity check existence and permissions of the path.
+ * ASSUME for now that PASSPHRASE_FILE is rooted only at $HOME.
+ * + Otherwise prompt user for passphrase(s).
+ * Echo input if 'visible' is set.
+ * Turning off 'promptindicator' makes piping in input cleaner.
+ *
+ * NOTE Only using forcepassphrase mandates taking both passphrases
+ * from the same source. Otherwise processing continues until both
+ * passphrases are defined.
+ */
+int
+get_user_passphrases(void)
+{
+ int rval = SNMPERR_SUCCESS;
+ size_t len;
+
+ char *obuf = NULL, *nbuf = NULL;
+
+ char path[SNMP_MAXBUF], buf[SNMP_MAXBUF], *s = NULL;
+
+ struct stat statbuf;
+ FILE *fp = NULL;
+
+
+
+ /*
+ * Allow prompts to the user to override all other sources.
+ * Nothing to do otherwise if oldpass and newpass are already defined.
+ */
+ if (forcepassphrase)
+ goto get_user_passphrases_prompt;
+ if (oldpass && newpass)
+ goto get_user_passphrases_quit;
+
+
+
+ /*
+ * Read passphrases out of PASSPHRASE_FILE. Sanity check the
+ * path for existence and access first. Refuse to read
+ * if the permissions are wrong.
+ */
+ s = getenv("HOME");
+ snprintf(path, sizeof(path), "%s/%s", s, PASSPHRASE_DIR);
+ path[ sizeof(path)-1 ] = 0;
+
+ /*
+ * Test directory.
+ */
+ if (stat(path, &statbuf) < 0) {
+ fprintf(stderr, "Cannot access directory \"%s\".\n", path);
+ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+#ifndef WIN32
+ } else if (statbuf.st_mode & (S_IRWXG | S_IRWXO)) {
+ fprintf(stderr,
+ "Directory \"%s\" is accessible by group or world.\n",
+ path);
+ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+#endif /* !WIN32 */
+ }
+
+ /*
+ * Test file.
+ */
+ snprintf(path, sizeof(path), "%s/%s", s, local_passphrase_filename);
+ path[ sizeof(path)-1 ] = 0;
+ if (stat(path, &statbuf) < 0) {
+ fprintf(stderr, "Cannot access file \"%s\".\n", path);
+ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+#ifndef WIN32
+ } else if (statbuf.st_mode & (S_IRWXG | S_IRWXO)) {
+ fprintf(stderr,
+ "File \"%s\" is accessible by group or world.\n", path);
+ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+#endif /* !WIN32 */
+ }
+
+ /*
+ * Open the file.
+ */
+ if ((fp = fopen(path, "r")) == NULL) {
+ fprintf(stderr, "Cannot open \"%s\".", path);
+ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ }
+
+ /*
+ * Read 1st line.
+ */
+ if (!fgets(buf, sizeof(buf), fp)) {
+ if (verbose) {
+ fprintf(stderr, "Passphrase file \"%s\" is empty...\n", path);
+ }
+ goto get_user_passphrases_prompt;
+
+ } else if (!oldpass) {
+ len = strlen(buf);
+ if (buf[len - 1] == '\n')
+ buf[--len] = '\0';
+ oldpass = (char *) calloc(1, len + 1);
+ if (oldpass)
+ memcpy(oldpass, buf, len + 1);
+ }
+ /*
+ * Read 2nd line.
+ */
+ if (!fgets(buf, sizeof(buf), fp)) {
+ if (verbose) {
+ fprintf(stderr, "Only one line in file \"%s\"...\n", path);
+ }
+
+ } else if (!newpass) {
+ len = strlen(buf);
+ if (buf[len - 1] == '\n')
+ buf[--len] = '\0';
+ newpass = (char *) calloc(1, len + 1);
+ if (newpass)
+ memcpy(newpass, buf, len + 1);
+ }
+
+ if (oldpass && newpass)
+ goto get_user_passphrases_quit;
+
+
+
+ /*
+ * Prompt the user for passphrase entry. Visible prompts
+ * may be omitted, and invisible entry may turned off.
+ */
+ get_user_passphrases_prompt:
+ if (forcepassphrase) {
+ oldpass = newpass = NULL;
+ }
+
+ if (!oldpass) {
+ oldpass = obuf
+ = snmp_getpassphrase((promptindicator) ? "Old passphrase: " :
+ "", visible);
+ }
+ if (!newpass) {
+ newpass = nbuf
+ = snmp_getpassphrase((promptindicator) ? "New passphrase: " :
+ "", visible);
+ }
+
+
+
+ /*
+ * Check that both passphrases were defined.
+ */
+ if (oldpass && newpass) {
+ goto get_user_passphrases_quit;
+ } else {
+ rval = SNMPERR_GENERR;
+ }
+
+
+ get_user_passphrases_quit:
+ memset(buf, 0, SNMP_MAXBUF);
+
+ if (obuf != oldpass) {
+ SNMP_ZERO(obuf, strlen(obuf));
+ SNMP_FREE(obuf);
+ }
+ if (nbuf != newpass) {
+ SNMP_ZERO(nbuf, strlen(nbuf));
+ SNMP_FREE(nbuf);
+ }
+
+ if (fp)
+ fclose (fp);
+
+ return rval;
+
+} /* end get_user_passphrases() */
+
+/*******************************************************************-o-******
+ * snmp_ttyecho
+ *
+ * Parameters:
+ * fd Descriptor of terminal on which to toggle echoing.
+ * echo TRUE if echoing should be on; FALSE otherwise.
+ *
+ * Returns:
+ * Previous value of echo setting.
+ *
+ *
+ * FIX Put HAVE_TCGETATTR in autoconf?
+ */
+#ifndef HAVE_GETPASS
+#ifdef HAVE_TCGETATTR
+#include <termios.h>
+int
+snmp_ttyecho(const int fd, const int echo)
+{
+ struct termios tio;
+ int was_echo;
+
+
+ if (!isatty(fd))
+ return (-1);
+ tcgetattr(fd, &tio);
+ was_echo = (tio.c_lflag & ECHO) != 0;
+ if (echo)
+ tio.c_lflag |= (ECHO | ECHONL);
+ else
+ tio.c_lflag &= ~(ECHO | ECHONL);
+ tcsetattr(fd, TCSANOW, &tio);
+
+ return (was_echo);
+
+} /* end snmp_ttyecho() */
+
+#else
+#include <sgtty.h>
+int
+snmp_ttyecho(const int fd, const int echo)
+{
+ struct sgttyb ttyparams;
+ int was_echo;
+
+
+ if (!isatty(fd))
+ was_echo = -1;
+ else {
+ ioctl(fd, TIOCGETP, &ttyparams);
+ was_echo = (ttyparams.sg_flags & ECHO) != 0;
+ if (echo)
+ ttyparams.sg_flags = ttyparams.sg_flags | ECHO;
+ else
+ ttyparams.sg_flags = ttyparams.sg_flags & ~ECHO;
+ ioctl(fd, TIOCSETP, &ttyparams);
+ }
+
+ return (was_echo);
+
+} /* end snmp_ttyecho() */
+#endif /* HAVE_TCGETATTR */
+#endif /* HAVE_GETPASS */
+
+
+
+
+/*******************************************************************-o-******
+ * snmp_getpassphrase
+ *
+ * Parameters:
+ * *prompt (May be NULL.)
+ * bvisible TRUE means echo back user input.
+ *
+ * Returns:
+ * Pointer to newly allocated, null terminated string containing
+ * passphrase -OR-
+ * NULL on error.
+ *
+ *
+ * Prompt stdin for a string (or passphrase). Return a copy of the
+ * input in a null terminated string.
+ *
+ * FIX Put HAVE_GETPASS in autoconf.
+ */
+char *
+snmp_getpassphrase(const char *prompt, int bvisible)
+{
+ int ti = 0;
+ size_t len;
+
+ char *bufp = NULL;
+ static char buffer[SNMP_MAXBUF];
+
+ FILE *ofp = stdout;
+
+
+ /*
+ * Query stdin for a passphrase.
+ */
+#ifdef HAVE_GETPASS
+ if (isatty(0)) {
+ return getpass((prompt) ? prompt : "");
+ }
+#endif
+
+ fputs((prompt) ? prompt : "", ofp);
+
+ if (!bvisible) {
+ ti = snmp_ttyecho(0, 0);
+ }
+
+ bufp = fgets(buffer, sizeof(buffer), stdin);
+
+ if (!bvisible) {
+ ti = snmp_ttyecho(0, ti);
+ fputs("\n", ofp);
+ }
+ if (!bufp) {
+ fprintf(stderr, "Aborted...\n");
+ exit(1);
+ }
+
+
+ /*
+ * Copy the input and zero out the read-in buffer.
+ */
+ len = strlen(buffer);
+ if (buffer[len - 1] == '\n')
+ buffer[--len] = '\0';
+
+ bufp = (char *) calloc(1, len + 1);
+ if (bufp)
+ memcpy(bufp, buffer, len + 1);
+
+ memset(buffer, 0, SNMP_MAXBUF);
+
+
+ return bufp;
+
+} /* end snmp_getpassphrase() */
+
+#ifdef WIN32
+
+int
+snmp_ttyecho(const int fd, const int echo)
+{
+ return 0;
+}
+
+/*
+ * stops at the first newline, carrier return, or backspace.
+ * WARNING! _getch does NOT read <Ctrl-C>
+ */
+char *
+getpass(const char *prompt)
+{
+ static char pbuf[128];
+ int ch, lim;
+
+ _cputs(prompt);
+ for (ch = 0, lim = 0; ch != '\n' && lim < sizeof(pbuf)-1;) {
+ ch = _getch(); /* look ma, no echo ! */
+ if (ch == '\r' || ch == '\n' || ch == '\b')
+ break;
+ pbuf[lim++] = ch;
+ }
+ pbuf[lim] = '\0';
+ puts("\n");
+
+ return pbuf;
+}
+#endif /* WIN32 */
diff --git a/apps/snmp_perl_trapd.pl b/apps/snmp_perl_trapd.pl
new file mode 100644
index 0000000..edae3ae
--- /dev/null
+++ b/apps/snmp_perl_trapd.pl
@@ -0,0 +1,15 @@
+##
+## SNMPTRAPD perl initialization file.
+##
+
+# DO NOT EDIT THIS FILE
+#
+# This file is intended for initialization of the perl subsystem used by
+# snmptrapd. Though it could be modified by a local administrator to do
+# things, it should not be as it will be overwritten by future
+# Net-SNMP installations. Run "perldoc NetSNMP::TrapReceiver" for
+# documentation on how to use perl within snmptrapd.
+
+use NetSNMP::TrapReceiver;
+
+
diff --git a/apps/snmpbulkget.c b/apps/snmpbulkget.c
new file mode 100644
index 0000000..2e9ee34
--- /dev/null
+++ b/apps/snmpbulkget.c
@@ -0,0 +1,250 @@
+/*
+ * snmpbulkget.c - send SNMPv2 Bulk requests to a network entity.
+ *
+ */
+/*********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+**********************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <net-snmp/utilities.h>
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+oid objid_mib[] = { 1, 3, 6, 1, 2, 1 };
+int max_repetitions = 10;
+int non_repeaters = 0;
+struct nameStruct {
+ oid name[MAX_OID_LEN];
+ size_t name_len;
+} *name, *namep;
+int names;
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpbulkget ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " OID [OID]...\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr, "\t\t\t n<NUM>: set non-repeaters to <NUM>\n");
+ fprintf(stderr, "\t\t\t r<NUM>: set max-repeaters to <NUM>\n");
+}
+
+static
+ void
+optProc(int argc, char *const *argv, int opt)
+{
+ char *endptr = NULL;
+
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'n':
+ case 'r':
+ if (*(optarg - 1) == 'r') {
+ max_repetitions = strtol(optarg, &endptr, 0);
+ } else {
+ non_repeaters = strtol(optarg, &endptr, 0);
+ }
+
+ if (endptr == optarg) {
+ /*
+ * No number given -- error.
+ */
+ usage();
+ exit(1);
+ } else {
+ optarg = endptr;
+ if (isspace((unsigned char)(*optarg))) {
+ return;
+ }
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu;
+ netsnmp_pdu *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ int count;
+ int status;
+ int exitval = 0;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ names = argc - arg;
+ if (names < non_repeaters) {
+ fprintf(stderr, "snmpbulkget: need more objects than <nonrep>\n");
+ exit(1);
+ }
+
+ namep = name = (struct nameStruct *) calloc(names, sizeof(*name));
+ while (arg < argc) {
+ namep->name_len = MAX_OID_LEN;
+ if (snmp_parse_oid(argv[arg], namep->name, &namep->name_len) ==
+ NULL) {
+ snmp_perror(argv[arg]);
+ exit(1);
+ }
+ arg++;
+ namep++;
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpbulkget", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * create PDU for GETBULK request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
+ pdu->non_repeaters = non_repeaters;
+ pdu->max_repetitions = max_repetitions; /* fill the packet */
+ for (arg = 0; arg < names; arg++)
+ snmp_add_null_var(pdu, name[arg].name, name[arg].name_len);
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ /*
+ * check resulting variables
+ */
+ for (vars = response->variables; vars;
+ vars = vars->next_variable)
+ print_variable(vars->name, vars->name_length, vars);
+ } else {
+ /*
+ * error in response, print it
+ */
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ printf("End of MIB.\n");
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && (count != response->errindex);
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpbulkget", ss);
+ exitval = 1;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpbulkwalk.c b/apps/snmpbulkwalk.c
new file mode 100644
index 0000000..379d2ae
--- /dev/null
+++ b/apps/snmpbulkwalk.c
@@ -0,0 +1,386 @@
+/*
+ * snmpbulkwalk.c - send SNMPv2 Bulk requests to a network entity, walking a
+ * subtree.
+ *
+ */
+/*********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+**********************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#define NETSNMP_DS_WALK_INCLUDE_REQUESTED 1
+#define NETSNMP_DS_WALK_PRINT_STATISTICS 2
+#define NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC 3
+
+oid objid_mib[] = { 1, 3, 6, 1, 2, 1 };
+int numprinted = 0;
+int reps = 10, non_reps = 0;
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpbulkwalk ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " [OID]\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr,
+ "\t\t\t c: do not check returned OIDs are increasing\n");
+ fprintf(stderr,
+ "\t\t\t i: include given OIDs in the search range\n");
+ fprintf(stderr, "\t\t\t n<NUM>: set non-repeaters to <NUM>\n");
+ fprintf(stderr,
+ "\t\t\t p: print the number of variables found\n");
+ fprintf(stderr, "\t\t\t r<NUM>: set max-repeaters to <NUM>\n");
+}
+
+static void
+snmp_get_and_print(netsnmp_session * ss, oid * theoid, size_t theoid_len)
+{
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int status;
+
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+ snmp_add_null_var(pdu, theoid, theoid_len);
+
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars; vars = vars->next_variable) {
+ numprinted++;
+ print_variable(vars->name, vars->name_length, vars);
+ }
+ }
+ if (response) {
+ snmp_free_pdu(response);
+ }
+}
+
+static
+ void
+optProc(int argc, char *const *argv, int opt)
+{
+ char *endptr = NULL;
+
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'c':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+ break;
+
+ case 'i':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_INCLUDE_REQUESTED);
+ break;
+
+ case 'n':
+ case 'r':
+ if (*(optarg - 1) == 'r') {
+ reps = strtol(optarg, &endptr, 0);
+ } else {
+ non_reps = strtol(optarg, &endptr, 0);
+ }
+
+ if (endptr == optarg) {
+ /*
+ * No number given -- error.
+ */
+ usage();
+ exit(1);
+ } else {
+ optarg = endptr;
+ if (isspace((unsigned char)(*optarg))) {
+ return;
+ }
+ }
+ break;
+
+ case 'p':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS);
+ break;
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ oid root[MAX_OID_LEN];
+ size_t rootlen;
+ int count;
+ int running;
+ int status = STAT_ERROR;
+ int check;
+ int exitval = 0;
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "includeRequested",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_INCLUDE_REQUESTED);
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "printStatistics",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS);
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "dontCheckOrdering",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ /*
+ * get the initial object and subtree
+ */
+ if (arg < argc) {
+ /*
+ * specified on the command line
+ */
+ rootlen = MAX_OID_LEN;
+ if (snmp_parse_oid(argv[arg], root, &rootlen) == NULL) {
+ snmp_perror(argv[arg]);
+ exit(1);
+ }
+ } else {
+ /*
+ * use default value
+ */
+ memmove(root, objid_mib, sizeof(objid_mib));
+ rootlen = sizeof(objid_mib) / sizeof(oid);
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpbulkwalk", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * setup initial object name
+ */
+ memmove(name, root, rootlen * sizeof(oid));
+ name_length = rootlen;
+
+ running = 1;
+
+ check = !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_INCLUDE_REQUESTED)) {
+ snmp_get_and_print(ss, root, rootlen);
+ }
+
+ while (running) {
+ /*
+ * create PDU for GETBULK request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
+ pdu->non_repeaters = non_reps;
+ pdu->max_repetitions = reps; /* fill the packet */
+ snmp_add_null_var(pdu, name, name_length);
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ /*
+ * check resulting variables
+ */
+ for (vars = response->variables; vars;
+ vars = vars->next_variable) {
+ if ((vars->name_length < rootlen)
+ || (memcmp(root, vars->name, rootlen * sizeof(oid))
+ != 0)) {
+ /*
+ * not part of this subtree
+ */
+ running = 0;
+ continue;
+ }
+ numprinted++;
+ print_variable(vars->name, vars->name_length, vars);
+ if ((vars->type != SNMP_ENDOFMIBVIEW) &&
+ (vars->type != SNMP_NOSUCHOBJECT) &&
+ (vars->type != SNMP_NOSUCHINSTANCE)) {
+ /*
+ * not an exception value
+ */
+ if (check
+ && snmp_oid_compare(name, name_length,
+ vars->name,
+ vars->name_length) >= 0) {
+ fprintf(stderr, "Error: OID not increasing: ");
+ fprint_objid(stderr, name, name_length);
+ fprintf(stderr, " >= ");
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ running = 0;
+ exitval = 1;
+ }
+ /*
+ * Check if last variable, and if so, save for next request.
+ */
+ if (vars->next_variable == NULL) {
+ memmove(name, vars->name,
+ vars->name_length * sizeof(oid));
+ name_length = vars->name_length;
+ }
+ } else {
+ /*
+ * an exception value, so stop
+ */
+ running = 0;
+ }
+ }
+ } else {
+ /*
+ * error in response, print it
+ */
+ running = 0;
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ printf("End of MIB\n");
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ running = 0;
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpbulkwalk", ss);
+ running = 0;
+ exitval = 1;
+ }
+ if (response)
+ snmp_free_pdu(response);
+ }
+
+ if (numprinted == 0 && status == STAT_SUCCESS) {
+ /*
+ * no printed successful results, which may mean we were
+ * pointed at an only existing instance. Attempt a GET, just
+ * for get measure.
+ */
+ snmp_get_and_print(ss, root, rootlen);
+ }
+ snmp_close(ss);
+
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS)) {
+ printf("Variables found: %d\n", numprinted);
+ }
+
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpdelta.c b/apps/snmpdelta.c
new file mode 100644
index 0000000..08e2ebc
--- /dev/null
+++ b/apps/snmpdelta.c
@@ -0,0 +1,748 @@
+/*
+ * snmpdelta.c - Monitor deltas of integer valued SNMP variables
+ *
+ */
+/**********************************************************************
+ *
+ * Copyright 1996 by Carnegie Mellon University
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of CMU not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ **********************************************************************/
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#define MAX_ARGS 256
+#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
+
+const char *SumFile = "Sum";
+
+/*
+ * Information about the handled variables
+ */
+struct varInfo {
+ char *name;
+ oid *info_oid;
+ int type;
+ size_t oidlen;
+ char descriptor[64];
+ u_int value;
+ struct counter64 c64value;
+ float max;
+ time_t time;
+ int peak_count;
+ float peak;
+ float peak_average;
+ int spoiled;
+};
+
+struct varInfo varinfo[MAX_ARGS];
+int current_name = 0;
+int period = 1;
+int deltat = 0, timestamp = 0, fileout = 0, dosum =
+ 0, printmax = 0;
+int keepSeconds = 0, peaks = 0;
+int tableForm = 0;
+int varbindsPerPacket = 60;
+
+void processFileArgs(char *fileName);
+
+void
+usage(void)
+{
+ fprintf(stderr,
+ "Usage: snmpdelta [-Cf] [-CF commandFile] [-Cl] [-CL SumFileName]\n\t[-Cs] [-Ck] [-Ct] [-CS] [-Cv vars/pkt] [-Cp period]\n\t[-CP peaks] ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " oid [oid ...]\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr, "snmpdelta specific options\n");
+ fprintf(stderr, " -Cf\t\tDon't fix errors and retry the request.\n");
+ fprintf(stderr, " -Cl\t\twrite configuration to file\n");
+ fprintf(stderr, " -CF config\tload configuration from file\n");
+ fprintf(stderr, " -Cp period\tspecifies the poll period\n");
+ fprintf(stderr, " -CP peaks\treporting period in poll periods\n");
+ fprintf(stderr, " -Cv vars/pkt\tnumber of variables per packet\n");
+ fprintf(stderr, " -Ck\t\tkeep seconds in output time\n");
+ fprintf(stderr, " -Cm\t\tshow max values\n");
+ fprintf(stderr, " -CS\t\tlog to a sum file\n");
+ fprintf(stderr, " -Cs\t\tshow timestamps\n");
+ fprintf(stderr, " -Ct\t\tget timing from agent\n");
+ fprintf(stderr, " -CT\t\tprint output in tabular form\n");
+ fprintf(stderr, " -CL sumfile\tspecifies the sum file name\n");
+}
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch ((opt = *optarg++)) {
+ case 'f':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS);
+ break;
+ case 'p':
+ period = atoi(argv[optind++]);
+ break;
+ case 'P':
+ peaks = atoi(argv[optind++]);
+ break;
+ case 'v':
+ varbindsPerPacket = atoi(argv[optind++]);
+ break;
+ case 't':
+ deltat = 1;
+ break;
+ case 's':
+ timestamp = 1;
+ break;
+ case 'S':
+ dosum = 1;
+ break;
+ case 'm':
+ printmax = 1;
+ break;
+ case 'F':
+ processFileArgs(argv[optind++]);
+ break;
+ case 'l':
+ fileout = 1;
+ break;
+ case 'L':
+ SumFile = argv[optind++];
+ break;
+ case 'k':
+ keepSeconds = 1;
+ break;
+ case 'T':
+ tableForm = 1;
+ break;
+ default:
+ fprintf(stderr, "Bad -C options: %c\n", opt);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+int
+wait_for_peak_start(int period, int peak)
+{
+ struct timeval m_time, *tv = &m_time;
+ struct tm tm;
+ time_t SecondsAtNextHour;
+ int target = 0;
+ int seconds;
+
+ seconds = period * peak;
+
+ /*
+ * Find the current time
+ */
+ gettimeofday(tv, (struct timezone *) 0);
+
+ /*
+ * Create a tm struct from it
+ */
+ memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
+
+ /*
+ * Calculate the next hour
+ */
+ tm.tm_sec = 0;
+ tm.tm_min = 0;
+ tm.tm_hour++;
+ SecondsAtNextHour = mktime(&tm);
+
+ /*
+ * Now figure out the amount of time to sleep
+ */
+ target = (int)(SecondsAtNextHour - tv->tv_sec) % seconds;
+
+ return target;
+}
+
+void
+print_log(char *file, char *message)
+{
+ FILE *fp;
+
+ fp = fopen(file, "a");
+ if (fp == NULL) {
+ fprintf(stderr, "Couldn't open %s\n", file);
+ return;
+ }
+ fprintf(fp, "%s\n", message);
+ fclose(fp);
+}
+
+void
+sprint_descriptor(char *buffer, struct varInfo *vip)
+{
+ char *buf = NULL, *cp = NULL;
+ size_t buf_len = 0, out_len = 0;
+
+ if (!sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
+ vip->info_oid, vip->oidlen)) {
+ if (buf != NULL) {
+ free(buf);
+ }
+ return;
+ }
+
+ for (cp = buf; *cp; cp++);
+ while (cp >= buf) {
+ if (isalpha((unsigned char)(*cp)))
+ break;
+ cp--;
+ }
+ while (cp >= buf) {
+ if (*cp == '.')
+ break;
+ cp--;
+ }
+ cp++;
+ if (cp < buf)
+ cp = buf;
+ strcpy(buffer, cp);
+
+ if (buf != NULL) {
+ free(buf);
+ }
+}
+
+void
+processFileArgs(char *fileName)
+{
+ FILE *fp;
+ char buf[260] = { 0 }, *cp;
+ int blank, linenumber = 0;
+
+ fp = fopen(fileName, "r");
+ if (fp == NULL)
+ return;
+ while (fgets(buf, sizeof(buf), fp)) {
+ linenumber++;
+ if (strlen(buf) > (sizeof(buf) - 2)) {
+ fprintf(stderr, "Line too long on line %d of %s\n",
+ linenumber, fileName);
+ exit(1);
+ }
+ if (buf[0] == '#')
+ continue;
+ blank = TRUE;
+ for (cp = buf; *cp; cp++)
+ if (!isspace((unsigned char)(*cp))) {
+ blank = FALSE;
+ break;
+ }
+ if (blank)
+ continue;
+ buf[strlen(buf) - 1] = 0;
+ if (current_name >= MAX_ARGS) {
+ fprintf(stderr, "Too many variables read at line %d of %s (max %d)\n",
+ linenumber, fileName, MAX_ARGS);
+ exit(1);
+ }
+ varinfo[current_name++].name = strdup(buf);
+ }
+ fclose(fp);
+ return;
+}
+
+void
+wait_for_period(int period)
+{
+#ifdef WIN32
+ Sleep(period * 1000);
+#else /* WIN32 */
+ struct timeval m_time, *tv = &m_time;
+ struct tm tm;
+ int count;
+ static int target = 0;
+ time_t nexthour;
+
+ gettimeofday(tv, (struct timezone *) 0);
+
+ if (target) {
+ target += period;
+ } else {
+ memcpy(&tm, localtime((time_t *) & tv->tv_sec), sizeof(tm));
+ tm.tm_sec = 0;
+ tm.tm_min = 0;
+ tm.tm_hour++;
+ nexthour = mktime(&tm);
+
+ target = (nexthour - tv->tv_sec) % period;
+ if (target == 0)
+ target = period;
+ target += tv->tv_sec;
+ }
+
+ tv->tv_sec = target - tv->tv_sec;
+ if (tv->tv_usec != 0) {
+ tv->tv_sec--;
+ tv->tv_usec = 1000000 - tv->tv_usec;
+ }
+ if (tv->tv_sec < 0) {
+ /*
+ * ran out of time, schedule immediately
+ */
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ }
+ count = 1;
+ while (count != 0) {
+ count = select(0, NULL, NULL, NULL, tv);
+ switch (count) {
+ case 0:
+ break;
+ case -1:
+ /*
+ * FALLTHRU
+ */
+ default:
+ snmp_log_perror("select");
+ break;
+ }
+ }
+#endif /* WIN32 */
+}
+
+oid sysUpTimeOid[9] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
+size_t sysUpTimeLen = 9;
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ char *gateway;
+
+ int count;
+ struct varInfo *vip;
+ u_int value = 0;
+ struct counter64 c64value;
+ float printvalue;
+ time_t last_time = 0;
+ time_t this_time;
+ time_t delta_time;
+ int sum; /* what the heck is this for, its never used? */
+ char filename[128] = { 0 };
+ struct timeval tv;
+ struct tm tm;
+ char timestring[64] = { 0 }, valueStr[64] = {
+ 0}, maxStr[64] = {
+ 0};
+ char outstr[256] = { 0 }, peakStr[64] = {
+ 0};
+ int status;
+ int begin, end, last_end;
+ int print = 1;
+ int exit_code = 0;
+
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ gateway = session.peername;
+
+ for (; optind < argc; optind++) {
+ if (current_name >= MAX_ARGS) {
+ fprintf(stderr, "%s: Too many variables specified (max %d)\n",
+ argv[optind], MAX_ARGS);
+ exit(1);
+ }
+ varinfo[current_name++].name = argv[optind];
+ }
+
+ if (current_name == 0) {
+ usage();
+ exit(1);
+ }
+
+ if (dosum) {
+ if (current_name >= MAX_ARGS) {
+ fprintf(stderr, "Too many variables specified (max %d)\n",
+ MAX_ARGS);
+ exit(1);
+ }
+ varinfo[current_name++].name = NULL;
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpdelta", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ if (tableForm && timestamp) {
+ printf("%s", gateway);
+ }
+ for (count = 0; count < current_name; count++) {
+ vip = varinfo + count;
+ if (vip->name) {
+ vip->oidlen = MAX_OID_LEN;
+ vip->info_oid = (oid *) malloc(sizeof(oid) * vip->oidlen);
+ if (snmp_parse_oid(vip->name, vip->info_oid, &vip->oidlen) ==
+ NULL) {
+ snmp_perror(vip->name);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ sprint_descriptor(vip->descriptor, vip);
+ if (tableForm)
+ printf("\t%s", vip->descriptor);
+ } else {
+ vip->oidlen = 0;
+ strlcpy(vip->descriptor, SumFile, sizeof(vip->descriptor));
+ }
+ vip->value = 0;
+ zeroU64(&vip->c64value);
+ vip->time = 0;
+ vip->max = 0;
+ if (peaks) {
+ vip->peak_count = -1;
+ vip->peak = 0;
+ vip->peak_average = 0;
+ }
+ }
+
+ wait_for_period(period);
+
+ end = current_name;
+ sum = 0;
+ while (1) {
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+
+ if (deltat)
+ snmp_add_null_var(pdu, sysUpTimeOid, sysUpTimeLen);
+
+ if (end == current_name)
+ count = 0;
+ else
+ count = end;
+ begin = count;
+ for (; count < current_name
+ && count < begin + varbindsPerPacket - deltat; count++) {
+ if (varinfo[count].oidlen)
+ snmp_add_null_var(pdu, varinfo[count].info_oid,
+ varinfo[count].oidlen);
+ }
+ last_end = end;
+ end = count;
+
+ retry:
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ if (timestamp) {
+ gettimeofday(&tv, (struct timezone *) 0);
+ memcpy(&tm, localtime((time_t *) & tv.tv_sec),
+ sizeof(tm));
+ if (((period % 60)
+ && (!peaks || ((period * peaks) % 60)))
+ || keepSeconds)
+ sprintf(timestring, " [%02d:%02d:%02d %d/%d]",
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ tm.tm_mon + 1, tm.tm_mday);
+ else
+ sprintf(timestring, " [%02d:%02d %d/%d]",
+ tm.tm_hour, tm.tm_min,
+ tm.tm_mon + 1, tm.tm_mday);
+ }
+
+ vars = response->variables;
+ if (deltat) {
+ if (!vars || !vars->val.integer) {
+ fprintf(stderr, "Missing variable in reply\n");
+ continue;
+ } else {
+ this_time = *(vars->val.integer);
+ }
+ vars = vars->next_variable;
+ } else {
+ this_time = 1;
+ }
+
+ for (count = begin; count < end; count++) {
+ vip = varinfo + count;
+
+ if (vip->oidlen) {
+ if (!vars || !vars->val.integer) {
+ fprintf(stderr, "Missing variable in reply\n");
+ break;
+ }
+ vip->type = vars->type;
+ if (vars->type == ASN_COUNTER64) {
+ u64Subtract(vars->val.counter64,
+ &vip->c64value, &c64value);
+ memcpy(&vip->c64value, vars->val.counter64,
+ sizeof(struct counter64));
+ } else {
+ value = *(vars->val.integer) - vip->value;
+ vip->value = *(vars->val.integer);
+ }
+ vars = vars->next_variable;
+ } else {
+ value = sum;
+ sum = 0;
+ }
+ delta_time = this_time - vip->time;
+ if (delta_time <= 0)
+ delta_time = 100;
+ last_time = vip->time;
+ vip->time = this_time;
+ if (last_time == 0)
+ continue;
+
+ if (vip->oidlen && vip->type != ASN_COUNTER64) {
+ sum += value;
+ }
+
+ if (tableForm) {
+ if (count == begin) {
+ sprintf(outstr, "%s", timestring + 1);
+ } else {
+ outstr[0] = '\0';
+ }
+ } else {
+ sprintf(outstr, "%s %s", timestring,
+ vip->descriptor);
+ }
+
+ if (deltat || tableForm) {
+ if (vip->type == ASN_COUNTER64) {
+ fprintf(stderr,
+ "time delta and table form not supported for counter64s\n");
+ exit(1);
+ } else {
+ printvalue =
+ ((float) value * 100) / delta_time;
+ if (tableForm)
+ sprintf(valueStr, "\t%.2f", printvalue);
+ else
+ sprintf(valueStr, " /sec: %.2f",
+ printvalue);
+ }
+ } else {
+ printvalue = (float) value;
+ sprintf(valueStr, " /%d sec: ", period);
+ if (vip->type == ASN_COUNTER64)
+ printU64(valueStr + strlen(valueStr),
+ &c64value);
+ else
+ sprintf(valueStr + strlen(valueStr), "%u",
+ value);
+ }
+
+ if (!peaks) {
+ strcat(outstr, valueStr);
+ } else {
+ print = 0;
+ if (vip->peak_count == -1) {
+ if (wait_for_peak_start(period, peaks) == 0)
+ vip->peak_count = 0;
+ } else {
+ vip->peak_average += printvalue;
+ if (vip->peak < printvalue)
+ vip->peak = printvalue;
+ if (++vip->peak_count == peaks) {
+ if (deltat)
+ sprintf(peakStr,
+ " /sec: %.2f (%d sec Peak: %.2f)",
+ vip->peak_average /
+ vip->peak_count, period,
+ vip->peak);
+ else
+ sprintf(peakStr,
+ " /%d sec: %.0f (%d sec Peak: %.0f)",
+ period,
+ vip->peak_average /
+ vip->peak_count, period,
+ vip->peak);
+ vip->peak_average = 0;
+ vip->peak = 0;
+ vip->peak_count = 0;
+ print = 1;
+ strcat(outstr, peakStr);
+ }
+ }
+ }
+
+ if (printmax) {
+ if (printvalue > vip->max) {
+ vip->max = printvalue;
+ }
+ if (deltat)
+ sprintf(maxStr, " (Max: %.2f)", vip->max);
+ else
+ sprintf(maxStr, " (Max: %.0f)", vip->max);
+ strcat(outstr, maxStr);
+ }
+
+ if (print) {
+ if (fileout) {
+ sprintf(filename, "%s-%s", gateway,
+ vip->descriptor);
+ print_log(filename, outstr + 1);
+ } else {
+ if (tableForm)
+ printf("%s", outstr);
+ else
+ printf("%s\n", outstr + 1);
+ fflush(stdout);
+ }
+ }
+ }
+ if (end == last_end && tableForm)
+ printf("\n");
+ } else {
+ if (response->errstat == SNMP_ERR_TOOBIG) {
+ if (response->errindex <= varbindsPerPacket
+ && response->errindex > 0) {
+ varbindsPerPacket = response->errindex - 1;
+ } else {
+ if (varbindsPerPacket > 30)
+ varbindsPerPacket -= 5;
+ else
+ varbindsPerPacket--;
+ }
+ if (varbindsPerPacket <= 0) {
+ exit_code = 5;
+ break;
+ }
+ end = last_end;
+ continue;
+ } else if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++);
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ /*
+ * Don't exit when OIDs from file are not found on agent
+ * exit_code = 1;
+ * break;
+ */
+ } else {
+ fprintf(stderr, "Error in packet: %s\n",
+ snmp_errstring(response->errstat));
+ exit_code = 1;
+ break;
+ }
+
+ /*
+ * retry if the errored variable was successfully removed
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS)) {
+ pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
+ snmp_free_pdu(response);
+ response = NULL;
+ if (pdu != NULL)
+ goto retry;
+ }
+ }
+
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n", gateway);
+ response = NULL;
+ exit_code = 1;
+ break;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpdelta", ss);
+ response = NULL;
+ exit_code = 1;
+ break;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+ if (end == current_name) {
+ wait_for_period(period);
+ }
+ }
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return (exit_code);
+}
diff --git a/apps/snmpdf.c b/apps/snmpdf.c
new file mode 100644
index 0000000..6a5ef19
--- /dev/null
+++ b/apps/snmpdf.c
@@ -0,0 +1,389 @@
+/*
+ * snmpdf.c - display disk space usage on a network entity via SNMP.
+ *
+ */
+
+/* Portions of this file are subject to the following copyright(s). See
+ * the Net-SNMP's COPYING file for more details and other copyrights
+ * that may apply:
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * Portions of this file are copyrighted by:
+ * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms specified in the COPYING file
+ * distributed with the Net-SNMP package.
+ */
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+void
+usage(void)
+{
+ fprintf(stderr, "Usage: snmpdf [-Cu] ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, "\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr, "\nsnmpdf options:\n");
+ fprintf(stderr,
+ "\t-Cu\tUse UCD-SNMP dskTable to do the calculations.\n");
+ fprintf(stderr,
+ "\t\t[Normally the HOST-RESOURCES-MIB is consulted first.]\n");
+}
+
+int ucd_mib = 0;
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'u':
+ ucd_mib = 1;
+ break;
+ default:
+ fprintf(stderr,
+ "Unknown flag passed to -C: %c\n", optarg[-1]);
+ exit(1);
+ }
+ }
+ }
+}
+
+struct hrStorageTable {
+ u_long hrStorageIndex;
+ oid *hrStorageType;
+ char *hrStorageDescr;
+ u_long hrStorageAllocationUnits;
+ u_long hrStorageSize;
+ u_long hrStorageUsed;
+};
+
+int
+add(netsnmp_pdu *pdu, const char *mibnodename,
+ oid * index, size_t indexlen)
+{
+ oid base[MAX_OID_LEN];
+ size_t base_length = MAX_OID_LEN;
+
+ memset(base, 0, MAX_OID_LEN * sizeof(oid));
+
+ if (!snmp_parse_oid(mibnodename, base, &base_length)) {
+ snmp_perror(mibnodename);
+ fprintf(stderr, "couldn't find mib node %s, giving up\n",
+ mibnodename);
+ exit(1);
+ }
+
+ if (index && indexlen) {
+ memcpy(&(base[base_length]), index, indexlen * sizeof(oid));
+ base_length += indexlen;
+ }
+ DEBUGMSGTL(("add", "created: "));
+ DEBUGMSGOID(("add", base, base_length));
+ DEBUGMSG(("add", "\n"));
+ snmp_add_null_var(pdu, base, base_length);
+
+ return base_length;
+}
+
+netsnmp_variable_list *
+collect(netsnmp_session * ss, netsnmp_pdu *pdu,
+ oid * base, size_t base_length)
+{
+ netsnmp_pdu *response;
+ int running = 1;
+ netsnmp_variable_list *saved = NULL, **vlpp = &saved;
+ int status;
+
+ while (running) {
+ /*
+ * gotta catch em all, gotta catch em all!
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status != STAT_SUCCESS || !response) {
+ snmp_sess_perror("snmpdf", ss);
+ exit(1);
+ }
+ if (response->errstat != SNMP_ERR_NOERROR) {
+ fprintf(stderr, "snmpdf: Error in packet: %s\n",
+ snmp_errstring(response->errstat));
+ exit(1);
+ }
+ if (response && snmp_oid_compare(response->variables->name,
+ SNMP_MIN(base_length,
+ response->variables->
+ name_length), base,
+ base_length) != 0)
+ running = 0;
+ else {
+ /*
+ * get response
+ */
+ *vlpp = response->variables;
+ (*vlpp)->next_variable = NULL; /* shouldn't be any, but just in case */
+
+ /*
+ * create the next request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ snmp_add_null_var(pdu, (*vlpp)->name, (*vlpp)->name_length);
+
+ /*
+ * finish loop setup
+ */
+ vlpp = &((*vlpp)->next_variable);
+ response->variables = NULL; /* ahh, forget about it */
+ }
+ snmp_free_pdu(response);
+ }
+ return saved;
+}
+
+/* Computes value*units/divisor in an overflow-proof way.
+ */
+unsigned long
+convert_units(unsigned long value, size_t units, size_t divisor)
+{
+ return (unsigned long)((double)value * units / (double)divisor);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu;
+ netsnmp_pdu *response;
+ int arg;
+ oid base[MAX_OID_LEN];
+ size_t base_length;
+ int status;
+ netsnmp_variable_list *saved = NULL, *vlp = saved, *vlp2;
+ int count = 0;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ if (arg != argc) {
+ fprintf(stderr, "snmpdf: extra argument: %s\n", argv[arg]);
+ exit(1);
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * Open an SNMP session.
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpdf", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ printf("%-18s %15s %15s %15s %5s\n", "Description", "size (kB)",
+ "Used", "Available", "Used%");
+ if (ucd_mib == 0) {
+ /*
+ * * Begin by finding all the storage pieces that are of
+ * * type hrStorageFixedDisk, which is a standard disk.
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ base_length =
+ add(pdu, "HOST-RESOURCES-MIB:hrStorageIndex", NULL, 0);
+ memcpy(base, pdu->variables->name, base_length * sizeof(oid));
+
+ vlp = collect(ss, pdu, base, base_length);
+
+ while (vlp) {
+ size_t units;
+ unsigned long hssize, hsused;
+ char descr[SPRINT_MAX_LEN];
+ int len;
+
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+
+ add(pdu, "HOST-RESOURCES-MIB:hrStorageDescr",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+ add(pdu, "HOST-RESOURCES-MIB:hrStorageAllocationUnits",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+ add(pdu, "HOST-RESOURCES-MIB:hrStorageSize",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+ add(pdu, "HOST-RESOURCES-MIB:hrStorageUsed",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status != STAT_SUCCESS || !response) {
+ snmp_sess_perror("snmpdf", ss);
+ exit(1);
+ }
+
+ vlp2 = response->variables;
+ len = vlp2->val_len;
+ if (len >= SPRINT_MAX_LEN) len = SPRINT_MAX_LEN-1;
+ memcpy(descr, vlp2->val.string, len);
+ descr[len] = '\0';
+
+ vlp2 = vlp2->next_variable;
+ units = vlp2->val.integer ? *(vlp2->val.integer) : 0;
+
+ vlp2 = vlp2->next_variable;
+ hssize = vlp2->val.integer ? *(vlp2->val.integer) : 0;
+
+ vlp2 = vlp2->next_variable;
+ hsused = vlp2->val.integer ? *(vlp2->val.integer) : 0;
+
+ printf("%-18s %15lu %15lu %15lu %4lu%%\n", descr,
+ units ? convert_units(hssize, units, 1024) : hssize,
+ units ? convert_units(hsused, units, 1024) : hsused,
+ units ? convert_units(hssize-hsused, units, 1024) : hssize -
+ hsused, hssize ? convert_units(hsused, 100, hssize) :
+ hsused);
+
+ vlp = vlp->next_variable;
+ snmp_free_pdu(response);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ size_t units = 0;
+ /*
+ * the host resources mib must not be supported. Lets try the
+ * UCD-SNMP-MIB and its dskTable
+ */
+
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ base_length = add(pdu, "UCD-SNMP-MIB:dskIndex", NULL, 0);
+ memcpy(base, pdu->variables->name, base_length * sizeof(oid));
+
+ vlp = collect(ss, pdu, base, base_length);
+
+ while (vlp) {
+ unsigned long hssize, hsused;
+ char descr[SPRINT_MAX_LEN];
+
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+
+ add(pdu, "UCD-SNMP-MIB:dskPath",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+ add(pdu, "UCD-SNMP-MIB:dskTotal",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+ add(pdu, "UCD-SNMP-MIB:dskUsed",
+ &(vlp->name[base_length]), vlp->name_length - base_length);
+
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status != STAT_SUCCESS || !response) {
+ snmp_sess_perror("snmpdf", ss);
+ exit(1);
+ }
+
+ vlp2 = response->variables;
+ memcpy(descr, vlp2->val.string, vlp2->val_len);
+ descr[vlp2->val_len] = '\0';
+
+ vlp2 = vlp2->next_variable;
+ hssize = *(vlp2->val.integer);
+
+ vlp2 = vlp2->next_variable;
+ hsused = *(vlp2->val.integer);
+
+ printf("%-18s %15lu %15lu %15lu %4lu%%\n", descr,
+ units ? convert_units(hssize, units, 1024) : hssize,
+ units ? convert_units(hsused, units, 1024) : hsused,
+ units ? convert_units(hssize-hsused, units, 1024) : hssize -
+ hsused, hssize ? convert_units(hsused, 100, hssize) :
+ hsused);
+
+ vlp = vlp->next_variable;
+ snmp_free_pdu(response);
+ count++;
+ }
+ }
+
+ if (count == 0) {
+ fprintf(stderr, "Failed to locate any partitions.\n");
+ exit(1);
+ }
+
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return 0;
+
+} /* end main() */
diff --git a/apps/snmpget.c b/apps/snmpget.c
new file mode 100644
index 0000000..701f536
--- /dev/null
+++ b/apps/snmpget.c
@@ -0,0 +1,255 @@
+/*
+ * snmpget.c - send snmp GET requests to a network entity.
+ *
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/utilities.h>
+
+#include <net-snmp/net-snmp-includes.h>
+
+#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'f':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS);
+ break;
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpget ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " OID [OID]...\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr,
+ "\t\t\t f: do not fix errors and retry the request\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu;
+ netsnmp_pdu *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ int count;
+ int current_name = 0;
+ char *names[SNMP_MAX_CMDLINE_OIDS];
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ int status;
+ int failures = 0;
+ int exitval = 0;
+
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ if (arg >= argc) {
+ fprintf(stderr, "Missing object name\n");
+ usage();
+ exit(1);
+ }
+ if ((argc - arg) > SNMP_MAX_CMDLINE_OIDS) {
+ fprintf(stderr, "Too many object identifiers specified. ");
+ fprintf(stderr, "Only %d allowed in one request.\n", SNMP_MAX_CMDLINE_OIDS);
+ usage();
+ exit(1);
+ }
+
+ /*
+ * get the object names
+ */
+ for (; arg < argc; arg++)
+ names[current_name++] = argv[arg];
+
+ SOCK_STARTUP;
+
+
+ /*
+ * Open an SNMP session.
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpget", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+
+ /*
+ * Create PDU for GET request and add object names to request.
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+ for (count = 0; count < current_name; count++) {
+ name_length = MAX_OID_LEN;
+ if (!snmp_parse_oid(names[count], name, &name_length)) {
+ snmp_perror(names[count]);
+ failures++;
+ } else
+ snmp_add_null_var(pdu, name, name_length);
+ }
+ if (failures) {
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+
+ /*
+ * Perform the request.
+ *
+ * If the Get Request fails, note the OID that caused the error,
+ * "fix" the PDU (removing the error-prone OID) and retry.
+ */
+ retry:
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars;
+ vars = vars->next_variable)
+ print_variable(vars->name, vars->name_length, vars);
+
+ } else {
+ fprintf(stderr, "Error in packet\nReason: %s\n",
+ snmp_errstring(response->errstat));
+
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars) {
+ fprint_objid(stderr, vars->name, vars->name_length);
+ }
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+
+ /*
+ * retry if the errored variable was successfully removed
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS)) {
+ pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
+ snmp_free_pdu(response);
+ response = NULL;
+ if (pdu != NULL) {
+ goto retry;
+ }
+ }
+ } /* endif -- SNMP_ERR_NOERROR */
+
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s.\n",
+ session.peername);
+ exitval = 1;
+
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpget", ss);
+ exitval = 1;
+
+ } /* endif -- STAT_SUCCESS */
+
+
+ if (response)
+ snmp_free_pdu(response);
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+
+} /* end main() */
diff --git a/apps/snmpgetnext.c b/apps/snmpgetnext.c
new file mode 100644
index 0000000..7de13f3
--- /dev/null
+++ b/apps/snmpgetnext.c
@@ -0,0 +1,236 @@
+/*
+ * snmpgetnext.c - send snmp GETNEXT requests to a network entity.
+ *
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'f':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS);
+ break;
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpgetnext ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " OID [OID]...\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr,
+ "\t\t\t f: do not fix errors and retry the request\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ int count;
+ int current_name = 0;
+ char *names[SNMP_MAX_CMDLINE_OIDS];
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ int status;
+ int failures = 0;
+ int exitval = 0;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ if (arg >= argc) {
+ fprintf(stderr, "Missing object name\n");
+ usage();
+ exit(1);
+ }
+ if ((argc - arg) > SNMP_MAX_CMDLINE_OIDS) {
+ fprintf(stderr, "Too many object identifiers specified. ");
+ fprintf(stderr, "Only %d allowed in one request.\n", SNMP_MAX_CMDLINE_OIDS);
+ usage();
+ exit(1);
+ }
+
+ /*
+ * get the object names
+ */
+ for (; arg < argc; arg++)
+ names[current_name++] = argv[arg];
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpgetnext", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * create PDU for GET request and add object names to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+
+ for (count = 0; count < current_name; count++) {
+ name_length = MAX_OID_LEN;
+ if (snmp_parse_oid(names[count], name, &name_length) == NULL) {
+ snmp_perror(names[count]);
+ failures++;
+ } else
+ snmp_add_null_var(pdu, name, name_length);
+ }
+ if (failures) {
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * do the request
+ */
+ retry:
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars;
+ vars = vars->next_variable)
+ print_variable(vars->name, vars->name_length, vars);
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++);
+ if (vars)
+ fprint_objid(stderr, vars->name, vars->name_length);
+ fprintf(stderr, "\n");
+ exitval = 2;
+ }
+
+ /*
+ * retry if the errored variable was successfully removed
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS)) {
+ pdu = snmp_fix_pdu(response, SNMP_MSG_GETNEXT);
+ snmp_free_pdu(response);
+ response = NULL;
+ if (pdu != NULL)
+ goto retry;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s.\n",
+ session.peername);
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpgetnext", ss);
+ exitval = 1;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpnetstat/Makefile.depend b/apps/snmpnetstat/Makefile.depend
new file mode 100644
index 0000000..6bfc11a
--- /dev/null
+++ b/apps/snmpnetstat/Makefile.depend
@@ -0,0 +1,425 @@
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+./if.lo: ../../include/net-snmp/net-snmp-config.h
+./if.lo: ../../include/net-snmp/system/linux.h
+./if.lo: ../../include/net-snmp/system/sysv.h
+./if.lo: ../../include/net-snmp/system/generic.h
+./if.lo: ../../include/net-snmp/net-snmp-includes.h
+./if.lo: ../../include/net-snmp/definitions.h ../../include/net-snmp/types.h
+./if.lo: ../../include/net-snmp/library/oid.h
+./if.lo: ../../include/net-snmp/library/types.h
+./if.lo: ../../include/net-snmp/library/snmp_api.h
+./if.lo: ../../include/net-snmp/varbind_api.h
+./if.lo: ../../include/net-snmp/library/snmp_client.h
+./if.lo: ../../include/net-snmp/pdu_api.h
+./if.lo: ../../include/net-snmp/library/asn1.h
+./if.lo: ../../include/net-snmp/output_api.h
+./if.lo: ../../include/net-snmp/library/snmp_debug.h
+./if.lo: ../../include/net-snmp/library/snmp_logging.h
+./if.lo: ../../include/net-snmp/session_api.h
+./if.lo: ../../include/net-snmp/library/callback.h
+./if.lo: ../../include/net-snmp/library/snmp_transport.h
+./if.lo: ../../include/net-snmp/library/snmp_service.h
+./if.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./if.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./if.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./if.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./if.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./if.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./if.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./if.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./if.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./if.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./if.lo: ../../include/net-snmp/library/ucd_compat.h
+./if.lo: ../../include/net-snmp/library/mib.h
+./if.lo: ../../include/net-snmp/mib_api.h
+./if.lo: ../../include/net-snmp/library/parse.h
+./if.lo: ../../include/net-snmp/library/oid_stash.h
+./if.lo: ../../include/net-snmp/net-snmp-features.h
+./if.lo: ../../include/net-snmp/library/snmp_impl.h
+./if.lo: ../../include/net-snmp/library/snmp.h
+./if.lo: ../../include/net-snmp/library/snmp-tc.h
+./if.lo: ../../include/net-snmp/library/getopt.h
+./if.lo: ../../include/net-snmp/utilities.h
+./if.lo: ../../include/net-snmp/library/system.h
+./if.lo: ../../include/net-snmp/library/tools.h
+./if.lo: ../../include/net-snmp/library/int64.h
+./if.lo: ../../include/net-snmp/library/mt_support.h
+./if.lo: ../../include/net-snmp/library/snmp_alarm.h
+./if.lo: ../../include/net-snmp/library/data_list.h
+./if.lo: ../../include/net-snmp/library/check_varbind.h
+./if.lo: ../../include/net-snmp/library/container.h
+./if.lo: ../../include/net-snmp/library/factory.h
+./if.lo: ../../include/net-snmp/library/container_binary_array.h
+./if.lo: ../../include/net-snmp/library/container_list_ssll.h
+./if.lo: ../../include/net-snmp/library/container_iterator.h
+./if.lo: ../../include/net-snmp/library/container.h
+./if.lo: ../../include/net-snmp/library/snmp_assert.h
+./if.lo: ../../include/net-snmp/version.h ../../include/net-snmp/config_api.h
+./if.lo: ../../include/net-snmp/library/read_config.h
+./if.lo: ../../include/net-snmp/library/default_store.h
+./if.lo: ../../include/net-snmp/net-snmp-config.h
+./if.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./if.lo: ../../include/net-snmp/library/snmp_enum.h
+./if.lo: ../../include/net-snmp/library/vacm.h
+./if.lo: ../../include/net-snmp/snmpv3_api.h
+./if.lo: ../../include/net-snmp/library/snmpv3.h
+./if.lo: ../../include/net-snmp/library/transform_oids.h
+./if.lo: ../../include/net-snmp/library/keytools.h
+./if.lo: ../../include/net-snmp/library/scapi.h
+./if.lo: ../../include/net-snmp/library/lcd_time.h
+./if.lo: ../../include/net-snmp/library/snmp_secmod.h
+./if.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./if.lo: ../../include/net-snmp/library/snmptsm.h
+./if.lo: ../../include/net-snmp/library/snmpusm.h
+./if.lo: main.h netstat.h
+./inet6.lo: ../../include/net-snmp/net-snmp-config.h
+./inet6.lo: ../../include/net-snmp/net-snmp-includes.h
+./inet6.lo: ../../include/net-snmp/definitions.h
+./inet6.lo: ../../include/net-snmp/types.h
+./inet6.lo: ../../include/net-snmp/library/oid.h
+./inet6.lo: ../../include/net-snmp/library/types.h
+./inet6.lo: ../../include/net-snmp/library/snmp_api.h
+./inet6.lo: ../../include/net-snmp/varbind_api.h
+./inet6.lo: ../../include/net-snmp/library/snmp_client.h
+./inet6.lo: ../../include/net-snmp/pdu_api.h
+./inet6.lo: ../../include/net-snmp/library/asn1.h
+./inet6.lo: ../../include/net-snmp/output_api.h
+./inet6.lo: ../../include/net-snmp/library/snmp_debug.h
+./inet6.lo: ../../include/net-snmp/library/snmp_logging.h
+./inet6.lo: ../../include/net-snmp/session_api.h
+./inet6.lo: ../../include/net-snmp/library/callback.h
+./inet6.lo: ../../include/net-snmp/library/snmp_transport.h
+./inet6.lo: ../../include/net-snmp/library/snmp_service.h
+./inet6.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./inet6.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./inet6.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./inet6.lo: ../../include/net-snmp/library/ucd_compat.h
+./inet6.lo: ../../include/net-snmp/library/mib.h
+./inet6.lo: ../../include/net-snmp/mib_api.h
+./inet6.lo: ../../include/net-snmp/library/parse.h
+./inet6.lo: ../../include/net-snmp/library/oid_stash.h
+./inet6.lo: ../../include/net-snmp/net-snmp-features.h
+./inet6.lo: ../../include/net-snmp/library/snmp_impl.h
+./inet6.lo: ../../include/net-snmp/library/snmp.h
+./inet6.lo: ../../include/net-snmp/library/snmp-tc.h
+./inet6.lo: ../../include/net-snmp/library/getopt.h
+./inet6.lo: ../../include/net-snmp/utilities.h
+./inet6.lo: ../../include/net-snmp/library/system.h
+./inet6.lo: ../../include/net-snmp/library/tools.h
+./inet6.lo: ../../include/net-snmp/library/int64.h
+./inet6.lo: ../../include/net-snmp/library/mt_support.h
+./inet6.lo: ../../include/net-snmp/library/snmp_alarm.h
+./inet6.lo: ../../include/net-snmp/library/data_list.h
+./inet6.lo: ../../include/net-snmp/library/check_varbind.h
+./inet6.lo: ../../include/net-snmp/library/container.h
+./inet6.lo: ../../include/net-snmp/library/factory.h
+./inet6.lo: ../../include/net-snmp/library/container_binary_array.h
+./inet6.lo: ../../include/net-snmp/library/container_list_ssll.h
+./inet6.lo: ../../include/net-snmp/library/container_iterator.h
+./inet6.lo: ../../include/net-snmp/library/container.h
+./inet6.lo: ../../include/net-snmp/library/snmp_assert.h
+./inet6.lo: ../../include/net-snmp/version.h
+./inet6.lo: ../../include/net-snmp/config_api.h
+./inet6.lo: ../../include/net-snmp/library/read_config.h
+./inet6.lo: ../../include/net-snmp/library/default_store.h
+./inet6.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./inet6.lo: ../../include/net-snmp/library/snmp_enum.h
+./inet6.lo: ../../include/net-snmp/library/vacm.h
+./inet6.lo: ../../include/net-snmp/snmpv3_api.h
+./inet6.lo: ../../include/net-snmp/library/snmpv3.h
+./inet6.lo: ../../include/net-snmp/library/transform_oids.h
+./inet6.lo: ../../include/net-snmp/library/keytools.h
+./inet6.lo: ../../include/net-snmp/library/scapi.h
+./inet6.lo: ../../include/net-snmp/library/lcd_time.h
+./inet6.lo: ../../include/net-snmp/library/snmp_secmod.h
+./inet6.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./inet6.lo: ../../include/net-snmp/library/snmptsm.h
+./inet6.lo: ../../include/net-snmp/library/snmpusm.h main.h netstat.h
+./inet.lo: ../../include/net-snmp/net-snmp-config.h
+./inet.lo: ../../include/net-snmp/net-snmp-includes.h
+./inet.lo: ../../include/net-snmp/definitions.h
+./inet.lo: ../../include/net-snmp/types.h
+./inet.lo: ../../include/net-snmp/library/oid.h
+./inet.lo: ../../include/net-snmp/library/types.h
+./inet.lo: ../../include/net-snmp/library/snmp_api.h
+./inet.lo: ../../include/net-snmp/varbind_api.h
+./inet.lo: ../../include/net-snmp/library/snmp_client.h
+./inet.lo: ../../include/net-snmp/pdu_api.h
+./inet.lo: ../../include/net-snmp/library/asn1.h
+./inet.lo: ../../include/net-snmp/output_api.h
+./inet.lo: ../../include/net-snmp/library/snmp_debug.h
+./inet.lo: ../../include/net-snmp/library/snmp_logging.h
+./inet.lo: ../../include/net-snmp/session_api.h
+./inet.lo: ../../include/net-snmp/library/callback.h
+./inet.lo: ../../include/net-snmp/library/snmp_transport.h
+./inet.lo: ../../include/net-snmp/library/snmp_service.h
+./inet.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./inet.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./inet.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./inet.lo: ../../include/net-snmp/library/ucd_compat.h
+./inet.lo: ../../include/net-snmp/library/mib.h
+./inet.lo: ../../include/net-snmp/mib_api.h
+./inet.lo: ../../include/net-snmp/library/parse.h
+./inet.lo: ../../include/net-snmp/library/oid_stash.h
+./inet.lo: ../../include/net-snmp/net-snmp-features.h
+./inet.lo: ../../include/net-snmp/library/snmp_impl.h
+./inet.lo: ../../include/net-snmp/library/snmp.h
+./inet.lo: ../../include/net-snmp/library/snmp-tc.h
+./inet.lo: ../../include/net-snmp/library/getopt.h
+./inet.lo: ../../include/net-snmp/utilities.h
+./inet.lo: ../../include/net-snmp/library/system.h
+./inet.lo: ../../include/net-snmp/library/tools.h
+./inet.lo: ../../include/net-snmp/library/int64.h
+./inet.lo: ../../include/net-snmp/library/mt_support.h
+./inet.lo: ../../include/net-snmp/library/snmp_alarm.h
+./inet.lo: ../../include/net-snmp/library/data_list.h
+./inet.lo: ../../include/net-snmp/library/check_varbind.h
+./inet.lo: ../../include/net-snmp/library/container.h
+./inet.lo: ../../include/net-snmp/library/factory.h
+./inet.lo: ../../include/net-snmp/library/container_binary_array.h
+./inet.lo: ../../include/net-snmp/library/container_list_ssll.h
+./inet.lo: ../../include/net-snmp/library/container_iterator.h
+./inet.lo: ../../include/net-snmp/library/container.h
+./inet.lo: ../../include/net-snmp/library/snmp_assert.h
+./inet.lo: ../../include/net-snmp/version.h
+./inet.lo: ../../include/net-snmp/config_api.h
+./inet.lo: ../../include/net-snmp/library/read_config.h
+./inet.lo: ../../include/net-snmp/library/default_store.h
+./inet.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./inet.lo: ../../include/net-snmp/library/snmp_enum.h
+./inet.lo: ../../include/net-snmp/library/vacm.h
+./inet.lo: ../../include/net-snmp/snmpv3_api.h
+./inet.lo: ../../include/net-snmp/library/snmpv3.h
+./inet.lo: ../../include/net-snmp/library/transform_oids.h
+./inet.lo: ../../include/net-snmp/library/keytools.h
+./inet.lo: ../../include/net-snmp/library/scapi.h
+./inet.lo: ../../include/net-snmp/library/lcd_time.h
+./inet.lo: ../../include/net-snmp/library/snmp_secmod.h
+./inet.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./inet.lo: ../../include/net-snmp/library/snmptsm.h
+./inet.lo: ../../include/net-snmp/library/snmpusm.h main.h netstat.h
+./main.lo: ../../include/net-snmp/net-snmp-config.h
+./main.lo: ../../include/net-snmp/net-snmp-includes.h
+./main.lo: ../../include/net-snmp/definitions.h
+./main.lo: ../../include/net-snmp/types.h
+./main.lo: ../../include/net-snmp/library/oid.h
+./main.lo: ../../include/net-snmp/library/types.h
+./main.lo: ../../include/net-snmp/library/snmp_api.h
+./main.lo: ../../include/net-snmp/varbind_api.h
+./main.lo: ../../include/net-snmp/library/snmp_client.h
+./main.lo: ../../include/net-snmp/pdu_api.h
+./main.lo: ../../include/net-snmp/library/asn1.h
+./main.lo: ../../include/net-snmp/output_api.h
+./main.lo: ../../include/net-snmp/library/snmp_debug.h
+./main.lo: ../../include/net-snmp/library/snmp_logging.h
+./main.lo: ../../include/net-snmp/session_api.h
+./main.lo: ../../include/net-snmp/library/callback.h
+./main.lo: ../../include/net-snmp/library/snmp_transport.h
+./main.lo: ../../include/net-snmp/library/snmp_service.h
+./main.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./main.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./main.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./main.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./main.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./main.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./main.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./main.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./main.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./main.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./main.lo: ../../include/net-snmp/library/ucd_compat.h
+./main.lo: ../../include/net-snmp/library/mib.h
+./main.lo: ../../include/net-snmp/mib_api.h
+./main.lo: ../../include/net-snmp/library/parse.h
+./main.lo: ../../include/net-snmp/library/oid_stash.h
+./main.lo: ../../include/net-snmp/net-snmp-features.h
+./main.lo: ../../include/net-snmp/library/snmp_impl.h
+./main.lo: ../../include/net-snmp/library/snmp.h
+./main.lo: ../../include/net-snmp/library/snmp-tc.h
+./main.lo: ../../include/net-snmp/library/getopt.h
+./main.lo: ../../include/net-snmp/utilities.h
+./main.lo: ../../include/net-snmp/library/system.h
+./main.lo: ../../include/net-snmp/library/tools.h
+./main.lo: ../../include/net-snmp/library/int64.h
+./main.lo: ../../include/net-snmp/library/mt_support.h
+./main.lo: ../../include/net-snmp/library/snmp_alarm.h
+./main.lo: ../../include/net-snmp/library/data_list.h
+./main.lo: ../../include/net-snmp/library/check_varbind.h
+./main.lo: ../../include/net-snmp/library/container.h
+./main.lo: ../../include/net-snmp/library/factory.h
+./main.lo: ../../include/net-snmp/library/container_binary_array.h
+./main.lo: ../../include/net-snmp/library/container_list_ssll.h
+./main.lo: ../../include/net-snmp/library/container_iterator.h
+./main.lo: ../../include/net-snmp/library/container.h
+./main.lo: ../../include/net-snmp/library/snmp_assert.h
+./main.lo: ../../include/net-snmp/version.h
+./main.lo: ../../include/net-snmp/config_api.h
+./main.lo: ../../include/net-snmp/library/read_config.h
+./main.lo: ../../include/net-snmp/library/default_store.h
+./main.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./main.lo: ../../include/net-snmp/library/snmp_enum.h
+./main.lo: ../../include/net-snmp/library/vacm.h
+./main.lo: ../../include/net-snmp/snmpv3_api.h
+./main.lo: ../../include/net-snmp/library/snmpv3.h
+./main.lo: ../../include/net-snmp/library/transform_oids.h
+./main.lo: ../../include/net-snmp/library/keytools.h
+./main.lo: ../../include/net-snmp/library/scapi.h
+./main.lo: ../../include/net-snmp/library/lcd_time.h
+./main.lo: ../../include/net-snmp/library/snmp_secmod.h
+./main.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./main.lo: ../../include/net-snmp/library/snmptsm.h
+./main.lo: ../../include/net-snmp/library/snmpusm.h main.h netstat.h
+./route.lo: ../../include/net-snmp/net-snmp-config.h
+./route.lo: ../../include/net-snmp/net-snmp-includes.h
+./route.lo: ../../include/net-snmp/definitions.h
+./route.lo: ../../include/net-snmp/types.h
+./route.lo: ../../include/net-snmp/library/oid.h
+./route.lo: ../../include/net-snmp/library/types.h
+./route.lo: ../../include/net-snmp/library/snmp_api.h
+./route.lo: ../../include/net-snmp/varbind_api.h
+./route.lo: ../../include/net-snmp/library/snmp_client.h
+./route.lo: ../../include/net-snmp/pdu_api.h
+./route.lo: ../../include/net-snmp/library/asn1.h
+./route.lo: ../../include/net-snmp/output_api.h
+./route.lo: ../../include/net-snmp/library/snmp_debug.h
+./route.lo: ../../include/net-snmp/library/snmp_logging.h
+./route.lo: ../../include/net-snmp/session_api.h
+./route.lo: ../../include/net-snmp/library/callback.h
+./route.lo: ../../include/net-snmp/library/snmp_transport.h
+./route.lo: ../../include/net-snmp/library/snmp_service.h
+./route.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./route.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./route.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./route.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./route.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./route.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./route.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./route.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./route.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./route.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./route.lo: ../../include/net-snmp/library/ucd_compat.h
+./route.lo: ../../include/net-snmp/library/mib.h
+./route.lo: ../../include/net-snmp/mib_api.h
+./route.lo: ../../include/net-snmp/library/parse.h
+./route.lo: ../../include/net-snmp/library/oid_stash.h
+./route.lo: ../../include/net-snmp/net-snmp-features.h
+./route.lo: ../../include/net-snmp/library/snmp_impl.h
+./route.lo: ../../include/net-snmp/library/snmp.h
+./route.lo: ../../include/net-snmp/library/snmp-tc.h
+./route.lo: ../../include/net-snmp/library/getopt.h
+./route.lo: ../../include/net-snmp/utilities.h
+./route.lo: ../../include/net-snmp/library/system.h
+./route.lo: ../../include/net-snmp/library/tools.h
+./route.lo: ../../include/net-snmp/library/int64.h
+./route.lo: ../../include/net-snmp/library/mt_support.h
+./route.lo: ../../include/net-snmp/library/snmp_alarm.h
+./route.lo: ../../include/net-snmp/library/data_list.h
+./route.lo: ../../include/net-snmp/library/check_varbind.h
+./route.lo: ../../include/net-snmp/library/container.h
+./route.lo: ../../include/net-snmp/library/factory.h
+./route.lo: ../../include/net-snmp/library/container_binary_array.h
+./route.lo: ../../include/net-snmp/library/container_list_ssll.h
+./route.lo: ../../include/net-snmp/library/container_iterator.h
+./route.lo: ../../include/net-snmp/library/container.h
+./route.lo: ../../include/net-snmp/library/snmp_assert.h
+./route.lo: ../../include/net-snmp/version.h
+./route.lo: ../../include/net-snmp/config_api.h
+./route.lo: ../../include/net-snmp/library/read_config.h
+./route.lo: ../../include/net-snmp/library/default_store.h
+./route.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./route.lo: ../../include/net-snmp/library/snmp_enum.h
+./route.lo: ../../include/net-snmp/library/vacm.h
+./route.lo: ../../include/net-snmp/snmpv3_api.h
+./route.lo: ../../include/net-snmp/library/snmpv3.h
+./route.lo: ../../include/net-snmp/library/transform_oids.h
+./route.lo: ../../include/net-snmp/library/keytools.h
+./route.lo: ../../include/net-snmp/library/scapi.h
+./route.lo: ../../include/net-snmp/library/lcd_time.h
+./route.lo: ../../include/net-snmp/library/snmp_secmod.h
+./route.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./route.lo: ../../include/net-snmp/library/snmptsm.h
+./route.lo: ../../include/net-snmp/library/snmpusm.h main.h netstat.h
+./winstub.lo: ../../include/net-snmp/net-snmp-config.h
+./winstub.lo: ../../include/net-snmp/net-snmp-includes.h
+./winstub.lo: ../../include/net-snmp/definitions.h
+./winstub.lo: ../../include/net-snmp/types.h
+./winstub.lo: ../../include/net-snmp/library/oid.h
+./winstub.lo: ../../include/net-snmp/library/types.h
+./winstub.lo: ../../include/net-snmp/library/snmp_api.h
+./winstub.lo: ../../include/net-snmp/varbind_api.h
+./winstub.lo: ../../include/net-snmp/library/snmp_client.h
+./winstub.lo: ../../include/net-snmp/pdu_api.h
+./winstub.lo: ../../include/net-snmp/library/asn1.h
+./winstub.lo: ../../include/net-snmp/output_api.h
+./winstub.lo: ../../include/net-snmp/library/snmp_debug.h
+./winstub.lo: ../../include/net-snmp/library/snmp_logging.h
+./winstub.lo: ../../include/net-snmp/session_api.h
+./winstub.lo: ../../include/net-snmp/library/callback.h
+./winstub.lo: ../../include/net-snmp/library/snmp_transport.h
+./winstub.lo: ../../include/net-snmp/library/snmp_service.h
+./winstub.lo: ../../include/net-snmp/library/snmpCallbackDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpUnixDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpUDPDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpUDPIPv4BaseDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpIPv4BaseDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpUDPBaseDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpTCPDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpUDPIPv6Domain.h
+./winstub.lo: ../../include/net-snmp/library/snmpIPv6BaseDomain.h
+./winstub.lo: ../../include/net-snmp/library/snmpIPXDomain.h
+./winstub.lo: ../../include/net-snmp/library/ucd_compat.h
+./winstub.lo: ../../include/net-snmp/library/mib.h
+./winstub.lo: ../../include/net-snmp/mib_api.h
+./winstub.lo: ../../include/net-snmp/library/parse.h
+./winstub.lo: ../../include/net-snmp/library/oid_stash.h
+./winstub.lo: ../../include/net-snmp/net-snmp-features.h
+./winstub.lo: ../../include/net-snmp/library/snmp_impl.h
+./winstub.lo: ../../include/net-snmp/library/snmp.h
+./winstub.lo: ../../include/net-snmp/library/snmp-tc.h
+./winstub.lo: ../../include/net-snmp/library/getopt.h
+./winstub.lo: ../../include/net-snmp/utilities.h
+./winstub.lo: ../../include/net-snmp/library/system.h
+./winstub.lo: ../../include/net-snmp/library/tools.h
+./winstub.lo: ../../include/net-snmp/library/int64.h
+./winstub.lo: ../../include/net-snmp/library/mt_support.h
+./winstub.lo: ../../include/net-snmp/library/snmp_alarm.h
+./winstub.lo: ../../include/net-snmp/library/data_list.h
+./winstub.lo: ../../include/net-snmp/library/check_varbind.h
+./winstub.lo: ../../include/net-snmp/library/container.h
+./winstub.lo: ../../include/net-snmp/library/factory.h
+./winstub.lo: ../../include/net-snmp/library/container_binary_array.h
+./winstub.lo: ../../include/net-snmp/library/container_list_ssll.h
+./winstub.lo: ../../include/net-snmp/library/container_iterator.h
+./winstub.lo: ../../include/net-snmp/library/container.h
+./winstub.lo: ../../include/net-snmp/library/snmp_assert.h
+./winstub.lo: ../../include/net-snmp/version.h
+./winstub.lo: ../../include/net-snmp/config_api.h
+./winstub.lo: ../../include/net-snmp/library/read_config.h
+./winstub.lo: ../../include/net-snmp/library/default_store.h
+./winstub.lo: ../../include/net-snmp/library/snmp_parse_args.h
+./winstub.lo: ../../include/net-snmp/library/snmp_enum.h
+./winstub.lo: ../../include/net-snmp/library/vacm.h
+./winstub.lo: ../../include/net-snmp/snmpv3_api.h
+./winstub.lo: ../../include/net-snmp/library/snmpv3.h
+./winstub.lo: ../../include/net-snmp/library/transform_oids.h
+./winstub.lo: ../../include/net-snmp/library/keytools.h
+./winstub.lo: ../../include/net-snmp/library/scapi.h
+./winstub.lo: ../../include/net-snmp/library/lcd_time.h
+./winstub.lo: ../../include/net-snmp/library/snmp_secmod.h
+./winstub.lo: ../../include/net-snmp/library/snmpv3-security-includes.h
+./winstub.lo: ../../include/net-snmp/library/snmptsm.h
+./winstub.lo: ../../include/net-snmp/library/snmpusm.h
diff --git a/apps/snmpnetstat/Makefile.in b/apps/snmpnetstat/Makefile.in
new file mode 100644
index 0000000..ac6e775
--- /dev/null
+++ b/apps/snmpnetstat/Makefile.in
@@ -0,0 +1,38 @@
+#
+# snmpnetstat Makefile
+#
+
+top_builddir=../..
+mysubdir=apps/snmpnetstat
+
+INSTALLBINPROGS=snmpnetstat$(EXEEXT)
+
+# use GNU vpath, if available, to only set a path for source and headers
+# VPATH will pick up objects too, which is bad if you are sharing a
+# source dir...
+@GNU_vpath@ %.h $(srcdir)
+@GNU_vpath@ %.c $(srcdir)
+# fallback to regular VPATH for non-gnu...
+@NON_GNU_VPATH@ $(srcdir)
+
+#
+# build info
+#
+SRCS= inet.c inet6.c if.c main.c route.c winstub.c ffs.c
+OBJS= inet.o inet6.o if.o main.o route.o winstub.o ffs.o
+LOBJS= inet.lo inet6.lo if.lo main.lo route.lo winstub.lo ffs.lo
+FTOBJS= inet.ft inet6.ft if.ft main.ft route.ft winstub.ft ffs.ft
+TARG= snmpnetstat$(EXEEXT)
+
+FEATUREFILE=../../include/net-snmp/features-snmpnetstat.h
+
+CPPFLAGS= $(TOP_INCLUDES) @CPPFLAGS@
+
+VAL_LIBS = @VAL_LIBS@
+USELIBS= ../../snmplib/libnetsnmp.$(LIB_EXTENSION)$(LIB_VERSION)
+LIBS= ../../snmplib/libnetsnmp.$(LIB_EXTENSION)$(LIB_VERSION) $(VAL_LIBS) @LIBS@
+
+all: standardall
+
+snmpnetstat$(EXEEXT): ${LOBJS} ${USELIBS}
+ ${LINK} ${CFLAGS} -o $@ ${LOBJS} ${LOCAL_LIBS} ${LDFLAGS} ${LIBS}
diff --git a/apps/snmpnetstat/ffs.c b/apps/snmpnetstat/ffs.c
new file mode 100644
index 0000000..5997339
--- /dev/null
+++ b/apps/snmpnetstat/ffs.c
@@ -0,0 +1,38 @@
+/* $OpenBSD: ffs.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
+
+/*
+ * Public domain.
+ * Written by Dale Rahn.
+ */
+
+/*
+ * ffs -- vax ffs instruction
+ */
+int
+_ffs(int mask)
+{
+ int bit;
+ unsigned int r = mask;
+ static const signed char t[16] = {
+ -28, 1, 2, 1,
+ 3, 1, 2, 1,
+ 4, 1, 2, 1,
+ 3, 1, 2, 1
+ };
+
+ bit = 0;
+ if (!(r & 0xffff)) {
+ bit += 16;
+ r >>= 16;
+ }
+ if (!(r & 0xff)) {
+ bit += 8;
+ r >>= 8;
+ }
+ if (!(r & 0xf)) {
+ bit += 4;
+ r >>= 4;
+ }
+
+ return (bit + t[ r & 0xf ]);
+}
diff --git a/apps/snmpnetstat/if.c b/apps/snmpnetstat/if.c
new file mode 100644
index 0000000..f7e7554
--- /dev/null
+++ b/apps/snmpnetstat/if.c
@@ -0,0 +1,870 @@
+/* $OpenBSD: if.c,v 1.42 2005/03/13 16:05:50 mpf Exp $ */
+/* $NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef INHERITED_CODE
+#ifndef lint
+#if 0
+static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";
+#else
+static char *rcsid = "$OpenBSD: if.c,v 1.42 2005/03/13 16:05:50 mpf Exp $";
+#endif
+#endif /* not lint */
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 1
+#endif
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+#include <signal.h>
+
+#include "main.h"
+#include "netstat.h"
+
+#define YES 1
+#define NO 0
+
+static void sidewaysintpr(u_int);
+static void timerSet(int interval_seconds);
+static void timerPause(void);
+
+ struct _if_info {
+ char name[128];
+ char ip[128], route[128];
+ int mtu;
+ int drops;
+ unsigned int ifindex;
+ /*
+ * Save "expandable" fields as string values
+ * rather than integer statistics
+ */
+ char s_ipkts[20], s_ierrs[20];
+ char s_opkts[20], s_oerrs[20];
+ char s_ibytes[20], s_obytes[20];
+ char s_outq[20];
+ unsigned long ipkts, opkts; /* Need to combine 2 MIB values */
+ int operstatus;
+/*
+ u_long netmask;
+ struct in_addr ifip, ifroute;
+ */
+ struct _if_info *next;
+ };
+
+
+/*
+ * Retrieve the interface addressing information
+ * XXX - This could also be extended to handle non-IP interfaces
+ */
+void
+_set_address( struct _if_info *cur_if )
+{
+ oid ipaddr_oid[] = { 1,3,6,1,2,1,4,20,1,0 };
+ size_t ipaddr_len = OID_LENGTH( ipaddr_oid );
+ static netsnmp_variable_list *addr_if_var =NULL;
+ static netsnmp_variable_list *addr_mask_var=NULL;
+ netsnmp_variable_list *vp, *vp2;
+ union {
+ in_addr_t addr;
+ char data[4];
+ } tmpAddr;
+ char *cp;
+ in_addr_t ifAddr, mask;
+
+ /*
+ * Note that this information only needs to be retrieved
+ * once, and can be re-used for subsequent calls.
+ */
+ if ( addr_if_var == NULL ) {
+ ipaddr_oid[ 9 ] = 2; /* ipAdEntIfIndex */
+ snmp_varlist_add_variable( &addr_if_var, ipaddr_oid, ipaddr_len,
+ ASN_NULL, NULL, 0);
+ netsnmp_query_walk( addr_if_var, ss );
+
+ ipaddr_oid[ 9 ] = 3; /* ipAdEntNetMask */
+ snmp_varlist_add_variable( &addr_mask_var, ipaddr_oid, ipaddr_len,
+ ASN_NULL, NULL, 0);
+ netsnmp_query_walk( addr_mask_var, ss );
+ }
+
+ /*
+ * Find the address row relevant to this interface
+ */
+ for (vp=addr_if_var, vp2=addr_mask_var; vp;
+ vp=vp->next_variable, vp2=vp2->next_variable) {
+ if ( vp->val.integer && *vp->val.integer == (int)cur_if->ifindex )
+ break;
+ }
+ if (vp2) {
+ /*
+ * Always want a numeric interface IP address
+ */
+ snprintf( cur_if->ip, 128, "%" NETSNMP_PRIo "u.%" NETSNMP_PRIo "u."
+ "%" NETSNMP_PRIo "u.%" NETSNMP_PRIo "u",
+ vp2->name[10],
+ vp2->name[11],
+ vp2->name[12],
+ vp2->name[13]);
+
+ /*
+ * But re-use the routing table utilities/code for
+ * displaying the local network information
+ */
+ cp = tmpAddr.data;
+ cp[0] = vp2->name[ 10 ] & 0xff;
+ cp[1] = vp2->name[ 11 ] & 0xff;
+ cp[2] = vp2->name[ 12 ] & 0xff;
+ cp[3] = vp2->name[ 13 ] & 0xff;
+ ifAddr = tmpAddr.addr;
+ cp = tmpAddr.data;
+ cp[0] = vp2->val.string[ 0 ] & 0xff;
+ cp[1] = vp2->val.string[ 1 ] & 0xff;
+ cp[2] = vp2->val.string[ 2 ] & 0xff;
+ cp[3] = vp2->val.string[ 3 ] & 0xff;
+ mask = tmpAddr.addr;
+ snprintf( cur_if->route, 128, "%s", netname(ifAddr, mask));
+ }
+}
+
+
+/*
+ * Print a description of the network interfaces.
+ */
+void
+intpr(int interval)
+{
+ oid ifcol_oid[] = { 1,3,6,1,2,1,2,2,1,0 };
+ size_t ifcol_len = OID_LENGTH( ifcol_oid );
+
+ struct _if_info *if_head, *if_tail, *cur_if;
+ netsnmp_variable_list *var, *vp;
+ /*
+ * Track maximum field widths, expanding as necessary
+ * This is one reason why results can't be
+ * displayed immediately they are retrieved.
+ */
+ int max_name = 4, max_ip = 7, max_route = 7, max_outq = 5;
+ int max_ipkts = 5, max_ierrs = 5, max_opkts = 5, max_oerrs = 5;
+ int max_ibytes = 6, max_obytes = 6;
+ int i;
+
+
+ if (interval) {
+ sidewaysintpr((unsigned)interval);
+ return;
+ }
+
+ /*
+ * The traditional "netstat -i" output combines information
+ * from two SNMP tables:
+ * ipAddrTable (for the IP address/network)
+ * ifTable (for the interface statistics)
+ *
+ * The previous approach was to retrieve (and save) the
+ * address information first. Then walk the main ifTable,
+ * add the relevant stored addresses, and saving the
+ * full information for each interface, before displaying
+ * the results as a separate pass.
+ *
+ * This code reverses this general structure, by first retrieving
+ * (and storing) the interface statistics for the whole table,
+ * then inserting the address information obtained from the
+ * ipAddrTable, and finally displaying the results.
+ * Such an arrangement should make it easier to extend this
+ * to handle non-IP interfaces (hence not in ipAddrTable)
+ */
+ if_head = NULL;
+ if_tail = NULL;
+ var = NULL;
+
+#define ADD_IFVAR( x ) ifcol_oid[ ifcol_len-1 ] = x; \
+ snmp_varlist_add_variable( &var, ifcol_oid, ifcol_len, ASN_NULL, NULL, 0)
+ ADD_IFVAR( 2 ); /* ifName */
+ ADD_IFVAR( 4 ); /* ifMtu */
+ ADD_IFVAR( 8 ); /* ifOperStatus */
+ /*
+ * The Net/Open-BSD behaviour is to display *either* byte
+ * counts *or* packet/error counts (but not both). FreeBSD
+ * integrates the byte counts into the traditional display.
+ *
+ * The previous 'snmpnetstat' implementation followed the
+ * separatist model. This re-write offers an opportunity
+ * to adopt the (more useful, IMO) Free-BSD approach.
+ *
+ * Or we could perhaps support both styles? :-)
+ */
+ if (bflag || oflag) {
+ ADD_IFVAR( 10 ); /* ifInOctets */
+ ADD_IFVAR( 16 ); /* ifOutOctets */
+ }
+ if (!oflag) {
+ ADD_IFVAR( 11 ); /* ifInUcastPkts */
+ ADD_IFVAR( 12 ); /* ifInNUcastPkts */
+ ADD_IFVAR( 14 ); /* ifInErrors */
+ ADD_IFVAR( 17 ); /* ifOutUcastPkts */
+ ADD_IFVAR( 18 ); /* ifOutNUcastPkts */
+ ADD_IFVAR( 20 ); /* ifOutErrors */
+ ADD_IFVAR( 21 ); /* ifOutQLen */
+ }
+#if 0
+ if (tflag) {
+ ADD_IFVAR( XX ); /* ??? */
+ }
+#endif
+ if (dflag) {
+ ADD_IFVAR( 19 ); /* ifOutDiscards */
+ }
+#undef ADD_IFVAR
+
+ /*
+ * Now walk the ifTable, creating a list of interfaces
+ */
+ while ( 1 ) {
+ if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
+ break;
+ ifcol_oid[ ifcol_len-1 ] = 2; /* ifDescr */
+ if ( snmp_oid_compare( ifcol_oid, ifcol_len,
+ var->name, ifcol_len) != 0 )
+ break; /* End of Table */
+ cur_if = SNMP_MALLOC_TYPEDEF( struct _if_info );
+ if (!cur_if)
+ break;
+ cur_if->ifindex = var->name[ var->name_length-1 ];
+ for ( vp=var; vp; vp=vp->next_variable ) {
+ if ( ! vp->val.integer )
+ continue;
+ if ( var->name[ var->name_length-1 ] != cur_if->ifindex ) {
+ /*
+ * Inconsistent index information
+ * XXX - Try to recover ?
+ */
+ SNMP_FREE( cur_if );
+ break; /* not for now, no */
+ }
+ switch ( vp->name[ var->name_length-2 ] ) {
+ case 2: /* ifDescr */
+ if (vp->val_len >= sizeof(cur_if->name))
+ vp->val_len = sizeof(cur_if->name)-1;
+ memmove( cur_if->name, vp->val.string, vp->val_len );
+ cur_if->name[vp->val_len] = 0;
+ if ((i = strlen(cur_if->name) + 1) > max_name)
+ max_name = i;
+ break;
+ case 4: /* ifMtu */
+ cur_if->mtu = *vp->val.integer;
+ break;
+ case 8: /* ifOperStatus */
+ cur_if->operstatus = *vp->val.integer;
+ /* XXX - any special processing ?? */
+ break;
+ case 10: /* ifInOctets */
+ sprintf(cur_if->s_ibytes, "%lu", *vp->val.integer);
+ i = strlen(cur_if->s_ibytes);
+ if (i > max_ibytes)
+ max_ibytes = i;
+ break;
+ case 11: /* ifInUcastPkts */
+ cur_if->ipkts += *vp->val.integer;
+ sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
+ i = strlen(cur_if->s_ipkts);
+ if (i > max_ipkts)
+ max_ipkts = i;
+ break;
+ case 12: /* ifInNUcastPkts */
+ cur_if->ipkts += *vp->val.integer;
+ sprintf(cur_if->s_ipkts, "%lu", cur_if->ipkts);
+ i = strlen(cur_if->s_ipkts);
+ if (i > max_ipkts)
+ max_ipkts = i;
+ break;
+ case 14: /* ifInErrors */
+ sprintf(cur_if->s_ierrs, "%lu", *vp->val.integer);
+ i = strlen(cur_if->s_ierrs);
+ if (i > max_ierrs)
+ max_ierrs = i;
+ break;
+ case 16: /* ifOutOctets */
+ sprintf(cur_if->s_obytes, "%lu", *vp->val.integer);
+ i = strlen(cur_if->s_obytes);
+ if (i > max_obytes)
+ max_obytes = i;
+ break;
+ case 17: /* ifOutUcastPkts */
+ cur_if->opkts += *vp->val.integer;
+ sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
+ i = strlen(cur_if->s_opkts);
+ if (i > max_opkts)
+ max_opkts = i;
+ break;
+ case 18: /* ifOutNUcastPkts */
+ cur_if->opkts += *vp->val.integer;
+ sprintf(cur_if->s_opkts, "%lu", cur_if->opkts);
+ i = strlen(cur_if->s_opkts);
+ if (i > max_opkts)
+ max_opkts = i;
+ break;
+ case 19: /* ifOutDiscards */
+ cur_if->drops = *vp->val.integer;
+ break;
+ case 20: /* ifOutErrors */
+ sprintf(cur_if->s_oerrs, "%lu", *vp->val.integer);
+ i = strlen(cur_if->s_oerrs);
+ if (i > max_oerrs)
+ max_oerrs = i;
+ break;
+ case 21: /* ifOutQLen */
+ sprintf(cur_if->s_outq, "%lu", *vp->val.integer);
+ i = strlen(cur_if->s_outq);
+ if (i > max_outq)
+ max_outq = i;
+ break;
+ }
+ }
+
+ /*
+ * XXX - Perhaps query ifXTable for additional info ??
+ * (ifName/ifAlias, or HC counters)
+ */
+
+ /*
+ * If we're to monitor a particular interface, then
+ * ignore all others. It would be more efficient
+ * to check this earlier (as part of processing
+ * the varbind list). But performing this test here
+ * means we can recognise ifXTable names as well)
+ */
+ if ( intrface && strcmp( cur_if->name, intrface ) != 0) {
+ SNMP_FREE( cur_if );
+ }
+
+ /*
+ * Insert the IP address and network settings, and
+ * add the new _if_stat structure to the list.
+ */
+ if ( cur_if ) {
+ _set_address( cur_if );
+ i = strlen(cur_if->ip);
+ if (i > max_ip)
+ max_ip = i;
+ i = strlen(cur_if->route);
+ if (i > max_route)
+ max_route = i;
+
+ if ( if_tail ) {
+ if_tail->next = cur_if;
+ if_tail = cur_if;
+ } else {
+ if_head = cur_if;
+ if_tail = cur_if;
+ }
+ }
+ } /* while (1) */
+
+ /*
+ * Now display the specified results (in Free-BSD format)
+ * setting the field widths appropriately....
+ */
+ printf("%*.*s %5.5s %*.*s %*.*s",
+ -max_name, max_name, "Name", "Mtu",
+ -max_route, max_route, "Network",
+ -max_ip, max_ip, "Address");
+ if (oflag) {
+ printf(" %*s %*s", max_ibytes, "Ibytes",
+ max_obytes, "Obytes");
+ } else {
+ printf(" %*s %*s", max_ipkts, "Ipkts",
+ max_ierrs, "Ierrs");
+ if (bflag)
+ printf(" %*s", max_ibytes, "Ibytes");
+
+ printf(" %*s %*s", max_opkts, "Opkts",
+ max_oerrs, "Oerrs");
+ if (bflag)
+ printf(" %*s", max_obytes, "Obytes");
+
+ printf(" %*s", max_outq, "Queue");
+ }
+ /* if (tflag)
+ printf(" %s", "Time");
+ */
+ if (dflag)
+ printf(" %s", "Drop");
+ putchar('\n');
+
+ for (cur_if = if_head; cur_if; cur_if=cur_if->next) {
+ if (cur_if->name[0] == 0)
+ continue;
+ printf( "%*.*s %5d", -max_name, max_name, cur_if->name, cur_if->mtu);
+ printf(" %*.*s", -max_route, max_route, cur_if->route);
+ printf(" %*.*s", -max_ip, max_ip, cur_if->ip);
+
+ if (oflag) {
+ printf(" %*s %*s", max_ibytes, cur_if->s_ibytes,
+ max_obytes, cur_if->s_obytes);
+ } else {
+ printf(" %*s %*s", max_ipkts, cur_if->s_ipkts,
+ max_ierrs, cur_if->s_ierrs);
+ if (bflag)
+ printf(" %*s", max_ibytes, cur_if->s_ibytes);
+
+ printf(" %*s %*s", max_opkts, cur_if->s_opkts,
+ max_oerrs, cur_if->s_oerrs);
+ if (bflag)
+ printf(" %*s", max_obytes, cur_if->s_obytes);
+ printf(" %*s", max_outq, cur_if->s_outq);
+ }
+ /* if (tflag)
+ printf(" %4d", cur_if->???);
+ */
+ if (dflag)
+ printf(" %4d", cur_if->drops);
+ putchar('\n');
+ }
+
+ /*
+ * ... and tidy up.
+ */
+ for (cur_if = if_head; cur_if; cur_if=if_head) {
+ if_head=cur_if->next;
+ cur_if->next = NULL;
+ SNMP_FREE( cur_if );
+ }
+}
+
+
+#define MAXIF 100
+struct iftot {
+ char ift_name[128]; /* interface name */
+ int ifIndex;
+ u_long ift_ip; /* input packets */
+ u_long ift_ib; /* input bytes */
+ u_long ift_ie; /* input errors */
+ u_long ift_op; /* output packets */
+ u_long ift_ob; /* output bytes */
+ u_long ift_oe; /* output errors */
+ u_long ift_co; /* collisions */
+ u_long ift_dr; /* drops */
+};
+
+int signalled; /* set if alarm goes off "early" */
+
+/*
+ * Print a running summary of interface statistics.
+ * Repeat display every interval seconds, showing statistics
+ * collected over that interval. Assumes that interval is non-zero.
+ * First line printed at top of screen is always cumulative.
+ */
+static void
+sidewaysintpr(unsigned int interval)
+{
+ /*
+ * As with the "one-shot" interface display, there are
+ * two different possible output formats. The Net/
+ * Open-BSD style displays both information about a
+ * single interface *and* the overall totals.
+ * The equivalent Free-BSD approach is to report on one
+ * or the other (rather than both). This is probably
+ * more useful (IMO), and significantly more efficient.
+ * So that's the style implemented here.
+ *
+ * Note that the 'ifcol' OID buffer can represent a full
+ * instance (including ifIndex), rather than just a
+ * column object OID, as with the one-shot code.
+ */
+ oid ifcol_oid[] = { 1,3,6,1,2,1,2,2,1,0,0 };
+ size_t ifcol_len = OID_LENGTH( ifcol_oid );
+ netsnmp_variable_list *var, *vp;
+ struct iftot *ip = NULL, *cur_if = NULL; /* single I/F display */
+ struct iftot *sum = NULL, *total = NULL; /* overall summary */
+ int line;
+ int first;
+ size_t i;
+
+ var = NULL;
+ if ( intrface ) {
+ /*
+ * Locate the ifIndex of the interface to monitor,
+ * by walking the ifDescr column of the ifTable
+ */
+ ifcol_oid[ ifcol_len-2 ] = 2; /* ifDescr */
+ snmp_varlist_add_variable( &var, ifcol_oid, ifcol_len-1,
+ ASN_NULL, NULL, 0);
+ i = strlen(intrface);
+ netsnmp_query_walk( var, ss );
+ for (vp=var; vp; vp=vp->next_variable) {
+ if (strncmp(intrface, (char *)vp->val.string, i) == 0 &&
+ i == vp->val_len)
+ break; /* found requested interface */
+ }
+ /*
+ * XXX - Might be worth searching ifName/ifAlias as well
+ */
+ if (!vp) {
+ fprintf(stderr, "%s: unknown interface\n", intrface );
+ exit(1);
+ }
+
+ /*
+ * Prepare the current and previous 'iftot' structures,
+ * and set the ifIndex value in the OID buffer.
+ */
+ ip = SNMP_MALLOC_TYPEDEF( struct iftot );
+ cur_if = SNMP_MALLOC_TYPEDEF( struct iftot );
+ if (!ip || !cur_if) {
+ fprintf(stderr, "internal error\n");
+ exit(1);
+ }
+ ifcol_oid[ ifcol_len-1 ] = vp->name[ ifcol_len-1 ];
+ snmp_free_var( var );
+ var = NULL;
+ } else {
+ /*
+ * Prepare the current and previous 'iftot' structures.
+ * (using different pointers, for consistency with *BSD code)
+ */
+ sum = SNMP_MALLOC_TYPEDEF( struct iftot );
+ total = SNMP_MALLOC_TYPEDEF( struct iftot );
+ if (!sum || !total) {
+ fprintf(stderr, "internal error\n");
+ exit(1);
+ }
+ }
+
+ timerSet( interval );
+ first = 1;
+banner:
+ printf( "%17s %14s %16s", "input",
+ intrface ? intrface : "(Total)", "output");
+ putchar('\n');
+ printf( "%10s %5s %10s %10s %5s %10s %5s",
+ "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
+ if (dflag)
+ printf(" %5.5s", "drops");
+ putchar('\n');
+ fflush(stdout);
+ line = 0;
+loop:
+ if ( intrface ) {
+#define ADD_IFVAR( x ) ifcol_oid[ ifcol_len-2 ] = x; \
+ snmp_varlist_add_variable( &var, ifcol_oid, ifcol_len, ASN_NULL, NULL, 0)
+ /* if (bflag) { */
+ ADD_IFVAR( 10 ); /* ifInOctets */
+ ADD_IFVAR( 16 ); /* ifOutOctets */
+ /* } */
+ ADD_IFVAR( 11 ); /* ifInUcastPkts */
+ ADD_IFVAR( 12 ); /* ifInNUcastPkts */
+ ADD_IFVAR( 14 ); /* ifInErrors */
+ ADD_IFVAR( 17 ); /* ifOutUcastPkts */
+ ADD_IFVAR( 18 ); /* ifOutNUcastPkts */
+ ADD_IFVAR( 20 ); /* ifOutErrors */
+ ADD_IFVAR( 21 ); /* ifOutQLen */
+ if (dflag) {
+ ADD_IFVAR( 19 ); /* ifOutDiscards */
+ }
+#undef ADD_IFVAR
+
+ netsnmp_query_get( var, ss ); /* Or parallel walk ?? */
+ cur_if->ift_ip = 0;
+ cur_if->ift_ib = 0;
+ cur_if->ift_ie = 0;
+ cur_if->ift_op = 0;
+ cur_if->ift_ob = 0;
+ cur_if->ift_oe = 0;
+ cur_if->ift_co = 0;
+ cur_if->ift_dr = 0;
+ cur_if->ifIndex = var->name[ ifcol_len-1 ];
+ for (vp=var; vp; vp=vp->next_variable) {
+ if ( ! vp->val.integer )
+ continue;
+ switch (vp->name[ifcol_len-2]) {
+ case 10: /* ifInOctets */
+ cur_if->ift_ib = *vp->val.integer;
+ break;
+ case 11: /* ifInUcastPkts */
+ cur_if->ift_ip += *vp->val.integer;
+ break;
+ case 12: /* ifInNUcastPkts */
+ cur_if->ift_ip += *vp->val.integer;
+ break;
+ case 14: /* ifInErrors */
+ cur_if->ift_ie = *vp->val.integer;
+ break;
+ case 16: /* ifOutOctets */
+ cur_if->ift_ob = *vp->val.integer;
+ break;
+ case 17: /* ifOutUcastPkts */
+ cur_if->ift_op += *vp->val.integer;
+ break;
+ case 18: /* ifOutNUcastPkts */
+ cur_if->ift_op += *vp->val.integer;
+ break;
+ case 19: /* ifOutDiscards */
+ cur_if->ift_dr = *vp->val.integer;
+ break;
+ case 20: /* ifOutErrors */
+ cur_if->ift_oe = *vp->val.integer;
+ break;
+ case 21: /* ifOutQLen */
+ cur_if->ift_co = *vp->val.integer;
+ break;
+ }
+ }
+ snmp_free_varbind( var );
+ var = NULL;
+
+ if (!first) {
+ printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
+ cur_if->ift_ip - ip->ift_ip,
+ cur_if->ift_ie - ip->ift_ie,
+ cur_if->ift_ib - ip->ift_ib,
+ cur_if->ift_op - ip->ift_op,
+ cur_if->ift_oe - ip->ift_oe,
+ cur_if->ift_ob - ip->ift_ob,
+ cur_if->ift_co - ip->ift_co);
+ if (dflag)
+ printf(" %5lu", cur_if->ift_dr - ip->ift_dr);
+ putchar('\n');
+ fflush(stdout);
+ }
+ ip->ift_ip = cur_if->ift_ip;
+ ip->ift_ie = cur_if->ift_ie;
+ ip->ift_ib = cur_if->ift_ib;
+ ip->ift_op = cur_if->ift_op;
+ ip->ift_oe = cur_if->ift_oe;
+ ip->ift_ob = cur_if->ift_ob;
+ ip->ift_co = cur_if->ift_co;
+ ip->ift_dr = cur_if->ift_dr;
+ } /* (single) interface */
+ else {
+ sum->ift_ip = 0;
+ sum->ift_ib = 0;
+ sum->ift_ie = 0;
+ sum->ift_op = 0;
+ sum->ift_ob = 0;
+ sum->ift_oe = 0;
+ sum->ift_co = 0;
+ sum->ift_dr = 0;
+#define ADD_IFVAR( x ) ifcol_oid[ ifcol_len-2 ] = x; \
+ snmp_varlist_add_variable( &var, ifcol_oid, ifcol_len-1, ASN_NULL, NULL, 0)
+ ADD_IFVAR( 11 ); /* ifInUcastPkts */
+ ADD_IFVAR( 12 ); /* ifInNUcastPkts */
+ ADD_IFVAR( 14 ); /* ifInErrors */
+ ADD_IFVAR( 17 ); /* ifOutUcastPkts */
+ ADD_IFVAR( 18 ); /* ifOutNUcastPkts */
+ ADD_IFVAR( 20 ); /* ifOutErrors */
+ ADD_IFVAR( 21 ); /* ifOutQLen */
+ /* if (bflag) { */
+ ADD_IFVAR( 10 ); /* ifInOctets */
+ ADD_IFVAR( 16 ); /* ifOutOctets */
+ /* } */
+ if (dflag) {
+ ADD_IFVAR( 19 ); /* ifOutDiscards */
+ }
+#undef ADD_IFVAR
+
+ ifcol_oid[ ifcol_len-2 ] = 11; /* ifInUcastPkts */
+ while ( 1 ) {
+ if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
+ break;
+ if ( snmp_oid_compare( ifcol_oid, ifcol_len-2,
+ var->name, ifcol_len-2) != 0 )
+ break; /* End of Table */
+
+ for ( vp=var; vp; vp=vp->next_variable ) {
+ if ( ! vp->val.integer )
+ continue;
+ switch ( vp->name[ ifcol_len-2 ] ) {
+ case 10: /* ifInOctets */
+ sum->ift_ib += *vp->val.integer;
+ break;
+ case 11: /* ifInUcastPkts */
+ sum->ift_ip += *vp->val.integer;
+ break;
+ case 12: /* ifInNUcastPkts */
+ sum->ift_ip += *vp->val.integer;
+ break;
+ case 14: /* ifInErrors */
+ sum->ift_ie += *vp->val.integer;
+ break;
+ case 16: /* ifOutOctets */
+ sum->ift_ob += *vp->val.integer;
+ break;
+ case 17: /* ifOutUcastPkts */
+ sum->ift_op += *vp->val.integer;
+ break;
+ case 18: /* ifOutNUcastPkts */
+ sum->ift_op += *vp->val.integer;
+ break;
+ case 19: /* ifOutDiscards */
+ sum->ift_dr += *vp->val.integer;
+ break;
+ case 20: /* ifOutErrors */
+ sum->ift_oe += *vp->val.integer;
+ break;
+ case 21: /* ifOutQLen */
+ sum->ift_co += *vp->val.integer;
+ break;
+ }
+ }
+ /*
+ * Now loop to retrieve the next entry from the table.
+ */
+ } /* while (1) */
+
+ snmp_free_varbind( var );
+ var = NULL;
+
+ if (!first) {
+ printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu",
+ sum->ift_ip - total->ift_ip,
+ sum->ift_ie - total->ift_ie,
+ sum->ift_ib - total->ift_ib,
+ sum->ift_op - total->ift_op,
+ sum->ift_oe - total->ift_oe,
+ sum->ift_ob - total->ift_ob,
+ sum->ift_co - total->ift_co);
+ if (dflag)
+ printf(" %5lu", sum->ift_dr - total->ift_dr);
+ putchar('\n');
+ fflush(stdout);
+ }
+ total->ift_ip = sum->ift_ip;
+ total->ift_ie = sum->ift_ie;
+ total->ift_ib = sum->ift_ib;
+ total->ift_op = sum->ift_op;
+ total->ift_oe = sum->ift_oe;
+ total->ift_ob = sum->ift_ob;
+ total->ift_co = sum->ift_co;
+ total->ift_dr = sum->ift_dr;
+ } /* overall summary */
+
+ timerPause();
+ timerSet(interval);
+ line++;
+ first = 0;
+ if (line == 21)
+ goto banner;
+ else
+ goto loop;
+ /*NOTREACHED*/
+}
+
+
+/*
+ * timerSet sets or resets the timer to fire in "interval" seconds.
+ * timerPause waits only if the timer has not fired.
+ * timing precision is not considered important.
+ */
+
+#if (defined(WIN32) || defined(cygwin))
+static int sav_int;
+static time_t timezup;
+static void
+timerSet(int interval_seconds)
+{
+ sav_int = interval_seconds;
+ timezup = time(0) + interval_seconds;
+}
+
+/*
+ * you can do better than this !
+ */
+static void
+timerPause(void)
+{
+ time_t now;
+ while (time(&now) < timezup)
+#ifdef WIN32
+ Sleep(400);
+#else
+ {
+ struct timeval tx;
+ tx.tv_sec = 0;
+ tx.tv_usec = 400 * 1000; /* 400 milliseconds */
+ select(0, 0, 0, 0, &tx);
+ }
+#endif
+}
+
+#else
+
+/*
+ * Called if an interval expires before sidewaysintpr has completed a loop.
+ * Sets a flag to not wait for the alarm.
+ */
+RETSIGTYPE
+catchalarm(int sig)
+{
+ signalled = YES;
+}
+
+static void
+timerSet(int interval_seconds)
+{
+#ifdef HAVE_SIGSET
+ (void) sigset(SIGALRM, catchalarm);
+#else
+ (void) signal(SIGALRM, catchalarm);
+#endif
+ signalled = NO;
+ (void) alarm(interval_seconds);
+}
+
+static void
+timerPause(void)
+{
+#ifdef HAVE_SIGHOLD
+ sighold(SIGALRM);
+ if (!signalled) {
+ sigpause(SIGALRM);
+ }
+#else
+ int oldmask;
+ oldmask = sigblock(sigmask(SIGALRM));
+ if (!signalled) {
+ sigpause(0);
+ }
+ sigsetmask(oldmask);
+#endif
+}
+
+#endif /* !WIN32 && !cygwin */
diff --git a/apps/snmpnetstat/inet.c b/apps/snmpnetstat/inet.c
new file mode 100644
index 0000000..0ae810d
--- /dev/null
+++ b/apps/snmpnetstat/inet.c
@@ -0,0 +1,649 @@
+/* $OpenBSD: inet.c,v 1.92 2005/02/10 14:25:08 itojun Exp $ */
+/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef INHERITED_CODE
+#ifndef lint
+#if 0
+static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";
+#else
+static const char *rcsid = "$OpenBSD: inet.c,v 1.92 2005/02/10 14:25:08 itojun Exp $";
+#endif
+#endif /* not lint */
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK_H
+#include "winstub.h"
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#include "main.h"
+#include "netstat.h"
+
+struct stat_table {
+ unsigned int entry; /* entry number in table */
+ /*
+ * format string to printf(description, value)
+ * warning: the %d must be before the %s
+ */
+ char description[80];
+};
+
+char *inetname(struct in_addr *);
+void inetprint(struct in_addr *, int, const char *, int);
+
+ /*
+ * Print a summary of connections related to
+ * an Internet protocol (kread-based) - Omitted
+ */
+
+/*
+ * Print a summary of TCP connections
+ * Listening processes are suppressed unless the
+ * -a (all) flag is specified.
+ */
+const char *tcpstates[] = {
+ "",
+ "CLOSED",
+ "LISTEN",
+ "SYNSENT",
+ "SYNRECEIVED",
+ "ESTABLISHED",
+ "FINWAIT1",
+ "FINWAIT2",
+ "CLOSEWAIT",
+ "LASTACK",
+ "CLOSING",
+ "TIMEWAIT"
+};
+#define TCP_NSTATES 11
+
+static void
+tcpprotoprint_line(const char *name, netsnmp_variable_list *vp, int *first)
+{
+ int state, width;
+ char *cp;
+ union {
+ struct in_addr addr;
+ char data[4];
+ } tmpAddr;
+ oid localPort, remotePort;
+ struct in_addr localAddr, remoteAddr;
+
+ state = *vp->val.integer;
+ if (!aflag && state == MIB_TCPCONNSTATE_LISTEN) {
+ return;
+ }
+
+ if (*first) {
+ printf("Active Internet (%s) Connections", name);
+ if (aflag)
+ printf(" (including servers)");
+ putchar('\n');
+ width = Aflag ? 18 : 22;
+ printf("%-5.5s %*.*s %*.*s %s\n",
+ "Proto", -width, width, "Local Address",
+ -width, width, "Remote Address", "(state)");
+ *first = 0;
+ }
+
+ /* Extract the local/remote information from the index values */
+ cp = tmpAddr.data;
+ cp[0] = vp->name[ 10 ] & 0xff;
+ cp[1] = vp->name[ 11 ] & 0xff;
+ cp[2] = vp->name[ 12 ] & 0xff;
+ cp[3] = vp->name[ 13 ] & 0xff;
+ localAddr.s_addr = tmpAddr.addr.s_addr;
+ localPort = ntohs(vp->name[ 14 ]);
+ cp = tmpAddr.data;
+ cp[0] = vp->name[ 15 ] & 0xff;
+ cp[1] = vp->name[ 16 ] & 0xff;
+ cp[2] = vp->name[ 17 ] & 0xff;
+ cp[3] = vp->name[ 18 ] & 0xff;
+ remoteAddr.s_addr = tmpAddr.addr.s_addr;
+ remotePort = ntohs(vp->name[ 19 ]);
+
+ printf("%-5.5s", name);
+ inetprint(&localAddr, localPort, name, 1);
+ inetprint(&remoteAddr, remotePort, name, 0);
+ if (state < 1 || state > TCP_NSTATES) {
+ printf("%d\n", state );
+ } else {
+ printf("%s\n", tcpstates[state]);
+ }
+}
+
+static void
+tcpprotopr_get(const char *name, oid *root, size_t root_len)
+{
+ netsnmp_variable_list *var, *vp;
+ int first = 1;
+
+ /*
+ * Walking the tcpConnState column will provide all
+ * the necessary information.
+ */
+ var = NULL;
+ snmp_varlist_add_variable( &var, root, root_len,
+ ASN_NULL, NULL, 0);
+ if (!var)
+ return;
+ if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR)
+ return;
+
+ for (vp = var; vp ; vp=vp->next_variable) {
+ tcpprotoprint_line(name, vp, &first);
+ }
+ snmp_free_varbind( var );
+}
+
+/*
+ * Print a summary of UDP "connections"
+ * XXX - what about "listening" services ??
+ */
+void
+udpprotopr(const char *name)
+{
+ netsnmp_variable_list *var, *vp;
+ oid udpLocalAddress_oid[] = { 1,3,6,1,2,1,7,5,1,1 };
+ size_t udpLocalAddress_len = OID_LENGTH( udpLocalAddress_oid );
+ union {
+ struct in_addr addr;
+ char data[4];
+ } tmpAddr;
+ struct in_addr localAddr;
+ oid localPort;
+ char *cp;
+
+ /*
+ * Walking a single column of the udpTable will provide
+ * all the necessary information from the index values.
+ */
+ var = NULL;
+ snmp_varlist_add_variable( &var, udpLocalAddress_oid, udpLocalAddress_len,
+ ASN_NULL, NULL, 0);
+ if (!var)
+ return;
+ if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR)
+ return;
+
+ printf("Active Internet (%s) Connections\n", name);
+ printf("%-5.5s %-28.28s\n", "Proto", "Local Address");
+ for (vp = var; vp ; vp=vp->next_variable) {
+ printf("%-5.5s", name);
+ /*
+ * Extract the local port from the index values, but take
+ * the IP address from the varbind value, (which is why
+ * we walked udpLocalAddress rather than udpLocalPort)
+ */
+ cp = tmpAddr.data;
+ cp[0] = vp->name[ 10 ] & 0xff;
+ cp[1] = vp->name[ 11 ] & 0xff;
+ cp[2] = vp->name[ 12 ] & 0xff;
+ cp[3] = vp->name[ 13 ] & 0xff;
+ localAddr.s_addr = tmpAddr.addr.s_addr;
+ localPort = ntohs( (u_short)(vp->name[ 14 ]));
+ inetprint(&localAddr, localPort, name, 1);
+ putchar('\n');
+ }
+ snmp_free_varbind( var );
+}
+
+void
+tcpprotopr_bulkget(const char *name, oid *root, size_t root_len)
+{
+ netsnmp_variable_list *vp;
+ netsnmp_pdu *pdu, *response;
+ oid tcpConnState_oid[MAX_OID_LEN];
+ size_t tcpConnState_len;
+ int first = 1;
+ int running = 1;
+ int status;
+
+ /*
+ * setup initial object name
+ */
+ memmove(tcpConnState_oid, root, sizeof(oid) * root_len);
+ tcpConnState_len = root_len;
+
+ /*
+ * Walking the tcpConnState column will provide all
+ * the necessary information.
+ */
+ while (running) {
+ /*
+ * create PDU for GETBULK request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
+ pdu->non_repeaters = 0;
+ pdu->max_repetitions = max_getbulk; /* fill the packet */
+ snmp_add_null_var(pdu, tcpConnState_oid, tcpConnState_len);
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ for (vp = response->variables; vp ; vp=vp->next_variable) {
+ if ((vp->name_length < root_len) ||
+ (memcmp(root, vp->name, sizeof(oid) * root_len) != 0)) {
+ /*
+ * not part of this subtree
+ */
+ running = 0;
+ continue;
+ }
+
+ tcpprotoprint_line(name, vp, &first);
+
+ if ((vp->type != SNMP_ENDOFMIBVIEW) &&
+ (vp->type != SNMP_NOSUCHOBJECT) &&
+ (vp->type != SNMP_NOSUCHINSTANCE)) {
+ /*
+ * Check if last variable, and if so, save for next request.
+ */
+ if (vp->next_variable == NULL) {
+ memmove(tcpConnState_oid, vp->name,
+ vp->name_length * sizeof(oid));
+ tcpConnState_len = vp->name_length;
+ }
+ } else {
+ /*
+ * an exception value, so stop
+ */
+ running = 0;
+ }
+ }
+ } else {
+ /*
+ * error in response, print it
+ */
+ running = 0;
+ }
+ } else if (status == STAT_TIMEOUT) {
+ running = 0;
+ } else { /* status == STAT_ERROR */
+ running = 0;
+ }
+
+ if (response) {
+ snmp_free_pdu(response);
+ }
+ }
+}
+
+void
+tcpprotopr(const char *name)
+{
+ oid tcpConnState_oid[] = { 1,3,6,1,2,1,6,13,1,1 };
+ size_t tcpConnState_len = OID_LENGTH( tcpConnState_oid );
+ int use_getbulk = 1;
+
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (ss->version == SNMP_VERSION_1) {
+ use_getbulk = 0;
+ }
+#endif
+
+ if (use_getbulk) {
+ tcpprotopr_bulkget(name, tcpConnState_oid, tcpConnState_len);
+ } else {
+ tcpprotopr_get(name, tcpConnState_oid, tcpConnState_len);
+ }
+}
+
+
+ /*********************
+ *
+ * Internet-protocol statistics
+ *
+ *********************/
+
+void
+_dump_stats( const char *name, oid *oid_buf, size_t buf_len,
+ struct stat_table *stable )
+{
+ netsnmp_variable_list *var, *vp;
+ struct stat_table *sp;
+ oid stat;
+
+ var = NULL;
+ for (sp=stable; sp->entry; sp++) {
+ oid_buf[buf_len-2] = sp->entry;
+ snmp_varlist_add_variable( &var, oid_buf, buf_len,
+ ASN_NULL, NULL, 0);
+ }
+
+ if (netsnmp_query_get( var, ss ) != SNMP_ERR_NOERROR) {
+ /* Need to fix and re-try SNMPv1 errors */
+ snmp_free_var( var );
+ return;
+ }
+
+ printf("%s:\n", name);
+ sp=stable;
+ for (vp=var; vp; vp=vp->next_variable, sp++) {
+ /*
+ * Match the returned results against
+ * the original stats table.
+ */
+ stat = vp->name[buf_len-2];
+ while (sp->entry < stat) {
+ sp++;
+ if (sp->entry == 0)
+ break;
+ }
+ if (sp->entry > stat)
+ continue;
+
+ /* Skip exceptions or missing values */
+ if ( !vp->val.integer )
+ continue;
+ /*
+ * If '-Cs' was specified twice,
+ * then only display non-zero stats.
+ */
+ if ( *vp->val.integer > 0 || sflag == 1 ) {
+ putchar('\t');
+ printf(sp->description, *vp->val.integer,
+ plural(*vp->val.integer));
+ putchar('\n');
+ }
+ }
+ snmp_free_varbind( var );
+}
+
+
+/*
+ * Dump IP statistics.
+ */
+void
+ip_stats(const char *name)
+{
+ oid ipstats_oid[] = { 1, 3, 6, 1, 2, 1, 4, 0, 0 };
+ size_t ipstats_len = OID_LENGTH( ipstats_oid );
+ struct stat_table ipstats_tbl[] = {
+ {3, "%d total datagram%s received"},
+ {4, "%d datagram%s with header errors"},
+ {5, "%d datagram%s with an invalid destination address"},
+ {6, "%d datagram%s forwarded"},
+ {7, "%d datagram%s with unknown protocol"},
+ {8, "%d datagram%s discarded"},
+ {9, "%d datagram%s delivered"},
+ {10, "%d output datagram request%s"},
+ {11, "%d output datagram%s discarded"},
+ {12, "%d datagram%s with no route"},
+ {14, "%d fragment%s received"},
+ {15, "%d datagram%s reassembled"},
+ {16, "%d reassembly failure%s"},
+ {17, "%d datagram%s fragmented"},
+ {18, "%d fragmentation failure%s"},
+ {19, "%d fragment%s created"},
+ {23, "%d route%s discarded"},
+ {0, ""}
+ };
+
+ _dump_stats( name, ipstats_oid, ipstats_len, ipstats_tbl );
+}
+
+
+/*
+ * Dump ICMP statistics.
+ */
+void
+icmp_stats(const char *name)
+{
+ oid icmpstats_oid[] = { 1, 3, 6, 1, 2, 1, 5, 0, 0 };
+ size_t icmpstats_len = OID_LENGTH( icmpstats_oid );
+ struct stat_table icmpstats_tbl[] = {
+ {1, "%d total message%s received"},
+ {2, "%d message%s dropped due to errors"},
+ {14, "%d ouput message request%s"},
+ {15, "%d output message%s discarded"},
+ {0, ""}
+ };
+ struct stat_table icmp_inhistogram[] = {
+ {3, "Destination unreachable: %d"},
+ {4, "Time Exceeded: %d"},
+ {5, "Parameter Problem: %d"},
+ {6, "Source Quench: %d"},
+ {7, "Redirect: %d"},
+ {8, "Echo Request: %d"},
+ {9, "Echo Reply: %d"},
+ {10, "Timestamp Request: %d"},
+ {11, "Timestamp Reply: %d"},
+ {12, "Address Mask Request: %d"},
+ {13, "Address Mask Reply: %d"},
+ {0, ""}
+ };
+ struct stat_table icmp_outhistogram[] = {
+ {16, "Destination unreachable: %d"},
+ {17, "Time Exceeded: %d"},
+ {18, "Parameter Problem: %d"},
+ {19, "Source Quench: %d"},
+ {20, "Redirect: %d"},
+ {21, "Echo Request: %d"},
+ {22, "Echo Reply: %d"},
+ {23, "Timestamp Request: %d"},
+ {24, "Timestamp Reply: %d"},
+ {25, "Address Mask Request: %d"},
+ {26, "Address Mask Reply: %d"},
+ {0, ""}
+ };
+
+ _dump_stats( name, icmpstats_oid, icmpstats_len, icmpstats_tbl );
+ _dump_stats( " Input Histogram",
+ icmpstats_oid, icmpstats_len, icmp_inhistogram );
+ _dump_stats( " Output Histogram",
+ icmpstats_oid, icmpstats_len, icmp_outhistogram );
+}
+
+
+/*
+ * Dump TCP statistics.
+ */
+void
+tcp_stats(const char *name)
+{
+ oid tcpstats_oid[] = { 1, 3, 6, 1, 2, 1, 6, 0, 0 };
+ size_t tcpstats_len = OID_LENGTH( tcpstats_oid );
+ struct stat_table tcpstats_tbl[] = {
+ {5, "%d active open%s"},
+ {6, "%d passive open%s"},
+ {7, "%d failed attempt%s"},
+ {8, "%d reset%s of established connections"},
+ {9, "%d current established connection%s"},
+ {10, "%d segment%s received"},
+ {11, "%d segment%s sent"},
+ {12, "%d segment%s retransmitted"},
+ {14, "%d invalid segment%s received"},
+ {15, "%d reset%s sent"},
+ {0, ""}
+ };
+ _dump_stats( name, tcpstats_oid, tcpstats_len, tcpstats_tbl );
+}
+
+
+/*
+ * Dump UDP statistics.
+ */
+void
+udp_stats(const char *name)
+{
+ oid udpstats_oid[] = { 1, 3, 6, 1, 2, 1, 7, 0, 0 };
+ size_t udpstats_len = OID_LENGTH( udpstats_oid );
+ struct stat_table udpstats_tbl[] = {
+ {1, "%d total datagram%s received"},
+ {2, "%d datagram%s to invalid port"},
+ {3, "%d datagram%s dropped due to errors"},
+ {4, "%d output datagram request%s"},
+ {0, ""}
+ };
+ _dump_stats( name, udpstats_oid, udpstats_len, udpstats_tbl );
+}
+
+
+/*
+ * Omitted:
+ * Dump IGMP statistics
+ * Dump PIM statistics
+ * Dump AH statistics
+ * Dump etherip statistics
+ * Dump ESP statistics
+ * Dump IP-in-IP statistics
+ * Dump CARP statistics
+ * Dump pfsync statistics
+ * Dump IPCOMP statistics
+ */
+
+ /*
+ * Utility routines
+ */
+
+/*
+ * Translation of RPC service names - Omitted
+ */
+
+/*
+ * Pretty print an Internet address (net address + port).
+ * If the nflag was specified, use numbers instead of names.
+ */
+void
+inetprint(struct in_addr *in, int port, const char *proto, int local)
+{
+ struct servent *sp = NULL;
+ char line[80], *cp;
+ int width;
+
+ snprintf(line, sizeof line, "%.*s.", (Aflag && !nflag) ? 12 : 16,
+ inetname(in));
+ cp = strchr(line, '\0');
+ if (!nflag && port)
+ sp = getservbyport((int)port, proto);
+ if (sp || port == 0)
+ snprintf(cp, line + sizeof line - cp, "%.8s",
+ sp ? sp->s_name : "*");
+ /*
+ * Translation of RPC service names - Omitted
+ */
+ else
+ snprintf(cp, line + sizeof line - cp, "%d", ntohs(port));
+ width = Aflag ? 18 : 22;
+ printf(" %-*.*s", width, width, line);
+}
+
+/*
+ * Construct an Internet address representation.
+ * If the nflag has been supplied, give
+ * numeric value, otherwise try for symbolic name.
+ */
+char *
+inetname(struct in_addr *inp)
+{
+ char *cp;
+ static char line[50];
+ struct hostent *hp;
+ struct netent *np;
+ static char domain[MAXHOSTNAMELEN];
+ static int first = 1;
+#if defined (WIN32) || defined (cygwin)
+ char host_temp[] = "localhost";
+#endif
+
+ if (first && !nflag) {
+ first = 0;
+ if (gethostname(domain, sizeof(domain)) == 0 &&
+ (cp = strchr(domain, '.')))
+ (void) strlcpy(domain, cp + 1, sizeof domain);
+ else
+ domain[0] = '\0';
+ }
+ cp = NULL;
+ if (!nflag && inp->s_addr != INADDR_ANY) {
+ int net = inet_netof(*inp);
+ int lna = inet_lnaof(*inp);
+
+ if (lna == INADDR_ANY) {
+ np = getnetbyaddr(net, AF_INET);
+ if (np)
+ cp = np->n_name;
+ }
+ if (cp == NULL) {
+ hp = netsnmp_gethostbyaddr((char *)inp, sizeof (*inp),
+ AF_INET);
+ if (hp) {
+ if ((cp = strchr(hp->h_name, '.')) &&
+ !strcmp(cp + 1, domain))
+ *cp = '\0';
+#if defined (WIN32) || defined (cygwin)
+ /* Windows insists on returning the computer name for 127.0.0.1
+ * even if the hosts file lists something else such as 'localhost'.
+ * If we are trying to look up 127.0.0.1, just return 'localhost' */
+ if (!strcmp(inet_ntoa(*inp),"127.0.0.1"))
+ cp = host_temp;
+ else
+#endif
+ cp = hp->h_name;
+ }
+ }
+ }
+ if (inp->s_addr == INADDR_ANY)
+ snprintf(line, sizeof line, "*");
+ else if (cp)
+ snprintf(line, sizeof line, "%s", cp);
+ else {
+ inp->s_addr = ntohl(inp->s_addr);
+#define C(x) (unsigned)((x) & 0xff)
+ snprintf(line, sizeof line, "%u.%u.%u.%u",
+ C(inp->s_addr >> 24), C(inp->s_addr >> 16),
+ C(inp->s_addr >> 8), C(inp->s_addr));
+ }
+ return (line);
+}
diff --git a/apps/snmpnetstat/inet6.c b/apps/snmpnetstat/inet6.c
new file mode 100644
index 0000000..d4ad391
--- /dev/null
+++ b/apps/snmpnetstat/inet6.c
@@ -0,0 +1,516 @@
+/* $OpenBSD: inet6.c,v 1.31 2004/11/17 01:47:20 itojun Exp $ */
+/* BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp */
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef INHERITED_CODE
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)inet.c 8.4 (Berkeley) 4/20/94";
+#else
+/*__RCSID("$OpenBSD: inet6.c,v 1.31 2004/11/17 01:47:20 itojun Exp $");*/
+/*__RCSID("KAME Id: inet6.c,v 1.10 2000/02/09 10:49:31 itojun Exp");*/
+#endif
+#endif /* not lint */
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_WINSOCK_H
+#include "winstub.h"
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#include "main.h"
+#include "netstat.h"
+
+struct stat_table {
+ unsigned int entry; /* entry number in table */
+ /*
+ * format string to printf(description, value)
+ * warning: the %d must be before the %s
+ */
+ char description[80];
+};
+
+char *inet6name(const unsigned char *);
+void inet6print(unsigned char *, int, const char *, int);
+
+/*
+ * Print a summary of TCPv6 connections
+ * Listening processes are suppressed unless the
+ * -a (all) flag is specified.
+ */
+const char *tcp6states[] = {
+ "",
+ "CLOSED",
+ "LISTEN",
+ "SYNSENT",
+ "SYNRECEIVED",
+ "ESTABLISHED",
+ "FINWAIT1",
+ "FINWAIT2",
+ "CLOSEWAIT",
+ "LASTACK",
+ "CLOSING",
+ "TIMEWAIT"
+};
+#define TCP_NSTATES 11
+
+void
+tcp6protopr(const char *name)
+{
+ netsnmp_variable_list *var, *vp;
+ oid ipv6TcpConnState_oid[] = { 1,3,6,1,2,1,6,16,1,6 };
+ size_t ipv6TcpConnState_len = OID_LENGTH( ipv6TcpConnState_oid );
+ int state, i;
+ unsigned char localAddr[16], remoteAddr[16];
+ int localPort, remotePort, ifIndex;
+ int first = 1;
+
+ /*
+ * Walking the v6 tcpConnState column will provide all
+ * the necessary information.
+ */
+ var = NULL;
+ snmp_varlist_add_variable( &var, ipv6TcpConnState_oid,
+ ipv6TcpConnState_len,
+ ASN_NULL, NULL, 0);
+ if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR)
+ return;
+ if (var->type == ASN_NULL) /* No entries */
+ return;
+
+ for (vp = var; vp ; vp=vp->next_variable) {
+ state = *vp->val.integer;
+ if (!aflag && state == MIB_TCPCONNSTATE_LISTEN)
+ continue;
+
+ if (first) {
+ printf("Active Internet Connections");
+ if (aflag)
+ printf(" (including servers)");
+ putchar('\n');
+ printf("%-5.5s %-28.28s %-28.28s %4s %s\n",
+ "Proto", "Local Address", "Remote Address", "I/F", "(state)");
+ first = 0;
+ }
+
+ /* Extract the local/remote information from the index values */
+ for (i=0; i<16; i++)
+ localAddr[i] = vp->name[ 10+i ];
+ localPort = vp->name[ 26 ];
+ for (i=0; i<16; i++)
+ remoteAddr[i] = vp->name[ 27+i ];
+ remotePort = vp->name[ 43 ];
+ ifIndex = vp->name[ 44 ];
+
+ printf("%-5.5s", name);
+ inet6print(localAddr, localPort, name, 1);
+ inet6print(remoteAddr, remotePort, name, 0);
+ if ( state < 1 || state > TCP_NSTATES )
+ printf(" %4d %d\n", ifIndex, state );
+ else
+ printf(" %4d %s\n", ifIndex, tcp6states[ state ]);
+ }
+ snmp_free_varbind( var );
+}
+
+/*
+ * Print a summary of UDPv6 "connections"
+ * XXX - what about "listening" services ??
+ */
+void
+udp6protopr(const char *name)
+{
+ netsnmp_variable_list *var, *vp;
+ oid ipv6UdpLocalAddress_oid[] = { 1,3,6,1,2,1,7,6,1,1 };
+ size_t ipv6UdpLocalAddress_len = OID_LENGTH( ipv6UdpLocalAddress_oid );
+ int localPort, ifIndex;
+
+ /*
+ * Walking a single column of the udpTable will provide
+ * all the necessary information from the index values.
+ */
+ var = NULL;
+ snmp_varlist_add_variable( &var, ipv6UdpLocalAddress_oid,
+ ipv6UdpLocalAddress_len,
+ ASN_NULL, NULL, 0);
+ if (netsnmp_query_walk( var, ss ) != SNMP_ERR_NOERROR)
+ return;
+ if (var->type == ASN_NULL) /* No entries */
+ return;
+
+ printf("Active Internet Connections\n");
+ printf("%-5.5s %-28.28s %4s\n", "Proto", "Local Address", "I/F");
+ for (vp = var; vp ; vp=vp->next_variable) {
+ printf("%-5.5s", name);
+ /*
+ * Extract the local port from the index values, but take
+ * the IP address from the varbind value, (which is why
+ * we walked udpLocalAddress rather than udpLocalPort)
+ */
+ localPort = vp->name[ vp->name_length-2 ];
+ ifIndex = vp->name[ vp->name_length-1 ];
+ inet6print(vp->val.string, localPort, name, 1);
+ printf(" %4d\n", ifIndex );
+ }
+ snmp_free_varbind( var );
+}
+
+
+ /*********************
+ *
+ * IPv6 statistics
+ *
+ *********************/
+
+/*
+ * Unlike the equivalent IPv4 statistics display routine,
+ * the IPv6 version must walk the columns of a table
+ * and total the statistics for each column (rather
+ * than simply retrieving individual scalar values)
+ */
+void
+_dump_v6stats( const char *name, oid *oid_buf, size_t buf_len,
+ struct stat_table *stable )
+{
+ netsnmp_variable_list *var, *vp;
+ struct stat_table *sp;
+ long *stats;
+ oid stat;
+ unsigned int max_stat = 0;
+ int active = 0;
+
+ var = NULL;
+ for (sp=stable; sp->entry; sp++) {
+ oid_buf[buf_len-1] = sp->entry;
+ if (sp->entry > max_stat)
+ max_stat = sp->entry;
+ snmp_varlist_add_variable( &var, oid_buf, buf_len,
+ ASN_NULL, NULL, 0);
+ }
+ oid_buf[buf_len-1] = stable[0].entry;
+ stats = (long *)calloc(max_stat+1, sizeof(long));
+
+ /*
+ * Walk the specified column(s), and total the individual statistics
+ */
+ while (1) {
+ if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
+ break;
+ if ( snmp_oid_compare( oid_buf, buf_len,
+ var->name, buf_len) != 0 )
+ break; /* End of Table */
+
+ for ( vp=var; vp; vp=vp->next_variable ) {
+ stat = vp->name[ buf_len-1 ];
+ stats[stat] += *vp->val.integer;
+ }
+ active=1;
+ }
+ if (!active) {
+ free( stats );
+ snmp_free_varbind( var );
+ return; /* No statistics to display */
+ }
+
+ /*
+ * Display the results
+ */
+ printf("%s:\n", name);
+ for (sp=stable; sp->entry; sp++) {
+ /*
+ * If '-Cs' was specified twice,
+ * then only display non-zero stats.
+ */
+ if ( stats[sp->entry] > 0 || sflag == 1 ) {
+ putchar('\t');
+ printf(sp->description, stats[sp->entry],
+ plural(stats[sp->entry]));
+ putchar('\n');
+ }
+ }
+ free( stats );
+ snmp_free_varbind( var );
+}
+
+
+/*
+ * Dump IP6 statistics.
+ */
+void
+ip6_stats(const char *name)
+{
+ oid ip6stats_oid[] = { 1, 3, 6, 1, 2, 1, 55, 1, 6, 1, 0 };
+ size_t ip6stats_len = OID_LENGTH( ip6stats_oid );
+ struct stat_table ip6stats_tbl[] = {
+ {1, "%d total datagram%s received"},
+ {2, "%d datagram%s with header errors"},
+ {3, "%d oversized datagram%s"},
+ {4, "%d datagram%s with no route"},
+ {5, "%d datagram%s with an invalid destination address"},
+ {6, "%d datagram%s with unknown protocol"},
+ {7, "%d short datagram%s discarded"},
+ {8, "%d datagram%s discarded"},
+ {9, "%d datagram%s delivered"},
+ {10, "%d datagram%s forwarded"},
+ {11, "%d output datagram request%s"},
+ {12, "%d output datagram%s discarded"},
+ {13, "%d datagram%s fragmented"},
+ {14, "%d fragmentation failure%s"},
+ {15, "%d fragment%s created"},
+ {16, "%d fragment%s received"},
+ {17, "%d datagram%s reassembled"},
+ {18, "%d reassembly failure%s"},
+ {19, "%d multicast datagram%s received"},
+ {20, "%d multicast datagram%s transmitted"},
+ {0, ""}
+ };
+
+ _dump_v6stats( name, ip6stats_oid, ip6stats_len, ip6stats_tbl );
+}
+
+/*
+ * Dump IPv6 per-interface statistics - Omitted
+ */
+
+
+/*
+ * Dump ICMP6 statistics.
+ */
+void
+icmp6_stats(const char *name)
+{
+ oid icmp6stats_oid[] = { 1, 3, 6, 1, 2, 1, 56, 1, 1, 1, 0 };
+ size_t icmp6stats_len = OID_LENGTH( icmp6stats_oid );
+ struct stat_table icmp6stats_tbl[] = {
+ {1, "%d total message%s received"},
+ {2, "%d message%s dropped due to errors"},
+ {18, "%d ouput message request%s"},
+ {19, "%d output message%s discarded"},
+ {0, ""}
+ };
+ struct stat_table icmp6_inhistogram[] = {
+ {3, "Destination unreachable: %d"},
+ {4, "Admin Prohibit: %d"},
+ {5, "Time Exceeded: %d"},
+ {6, "Parameter Problem: %d"},
+ {7, "Too Big: %d"},
+ {8, "Echo Request: %d"},
+ {9, "Echo Reply: %d"},
+ {10, "Router Solicit: %d"},
+ {11, "Router Advert: %d"},
+ {12, "Neighbor Solicit: %d"},
+ {13, "Neighbor Advert: %d"},
+ {14, "Redirect: %d"},
+ {15, "Group Member Request: %d"},
+ {16, "Group Member Reply:%d"},
+ {17, "Group Member Reduce:%d"},
+ {0, ""}
+ };
+ struct stat_table icmp6_outhistogram[] = {
+ {20, "Destination unreachable: %d"},
+ {21, "Admin Prohibit: %d"},
+ {22, "Time Exceeded: %d"},
+ {23, "Parameter Problem: %d"},
+ {24, "Too Big: %d"},
+ {25, "Echo Request: %d"},
+ {26, "Echo Reply: %d"},
+ {27, "Router Solicit: %d"},
+ {28, "Router Advert: %d"},
+ {29, "Neighbor Solicit: %d"},
+ {30, "Neighbor Advert: %d"},
+ {31, "Redirect: %d"},
+ {32, "Group Member Request: %d"},
+ {33, "Group Member Reply:%d"},
+ {34, "Group Member Reduce:%d"},
+ {0, ""}
+ };
+
+ _dump_v6stats( name, icmp6stats_oid, icmp6stats_len, icmp6stats_tbl );
+ _dump_v6stats( " Input Histogram",
+ icmp6stats_oid, icmp6stats_len, icmp6_inhistogram );
+ _dump_v6stats( " Output Histogram",
+ icmp6stats_oid, icmp6stats_len, icmp6_outhistogram );
+}
+
+/*
+ * Dump ICMPv6 per-interface statistics - Omitted
+ */
+
+
+/*
+ * Ommitted:
+ * Dump PIM statistics
+ * Dump raw ip6 statistics
+ */
+
+
+
+/*
+ * Pretty print an Internet address (net address + port).
+ * If the nflag was specified, use numbers instead of names.
+ */
+
+void
+inet6print(unsigned char *in6, int port, const char *proto, int local)
+{
+
+#define GETSERVBYPORT6(port, proto, ret) do { \
+ if (strcmp((proto), "tcp6") == 0) \
+ (ret) = getservbyport((int)(port), "tcp"); \
+ else if (strcmp((proto), "udp6") == 0) \
+ (ret) = getservbyport((int)(port), "udp"); \
+ else \
+ (ret) = getservbyport((int)(port), (proto)); \
+ } while (0)
+
+ struct servent *sp = NULL;
+ char line[80], *cp;
+ unsigned width;
+ int len = sizeof line;
+
+ width = Aflag ? 12 : 16;
+ if (vflag && width < strlen(inet6name(in6)))
+ width = strlen(inet6name(in6));
+ snprintf(line, len, "%.*s.", width, inet6name(in6));
+ len -= strlen(line);
+ if (len <= 0)
+ goto bail;
+
+ cp = strchr(line, '\0');
+ if (!nflag && port && local)
+ GETSERVBYPORT6(port, proto, sp);
+ if (sp || port == 0)
+ snprintf(cp, len, "%.8s", sp ? sp->s_name : "*");
+ else
+ snprintf(cp, len, "%d", ntohs((u_short)port));
+ width = Aflag ? 18 : 22;
+ if (vflag && width < strlen(line))
+ width = strlen(line);
+bail:
+ printf(" %-*.*s", width, width, line);
+}
+
+/*
+ * Construct an Internet address representation.
+ * If the nflag has been supplied, give
+ * numeric value, otherwise try for symbolic name.
+ */
+
+char *
+inet6name(const unsigned char *in6)
+{
+ char *cp;
+ static char line[NI_MAXHOST];
+ static char domain[MAXHOSTNAMELEN];
+ static int first = 1;
+#ifdef NETSNMP_ENABLE_IPV6
+ struct hostent *hp;
+ char hbuf[NI_MAXHOST];
+ const int niflag = NI_NUMERICHOST;
+ struct sockaddr_in6 sin6;
+ const struct in6_addr *in6p = (const struct in6_addr *)in6;
+#endif
+
+ if (first && !nflag) {
+ first = 0;
+ if (gethostname(domain, sizeof(domain)) == 0 &&
+ (cp = strchr(domain, '.')))
+ (void) strlcpy(domain, cp + 1, sizeof domain);
+ else
+ domain[0] = '\0';
+ }
+#ifdef NETSNMP_ENABLE_IPV6
+ cp = NULL;
+ if (!nflag && !IN6_IS_ADDR_UNSPECIFIED(in6p)) {
+ hp = netsnmp_gethostbyaddr((const char *)in6p, sizeof(*in6p),
+ AF_INET6);
+ if (hp) {
+ if ((cp = strchr(hp->h_name, '.')) &&
+ !strcmp(cp + 1, domain))
+ *cp = 0;
+ cp = hp->h_name;
+ }
+ }
+ if (IN6_IS_ADDR_UNSPECIFIED(in6p))
+ strlcpy(line, "*", sizeof(line));
+ else if (cp)
+ strlcpy(line, cp, sizeof(line));
+ else {
+ memset(&sin6, 0, sizeof(sin6));
+/* sin6.sin6_len = sizeof(sin6); */
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_addr = *in6p;
+#ifdef __KAME__
+ if (IN6_IS_ADDR_LINKLOCAL(in6p) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(in6p)) {
+ sin6.sin6_scope_id =
+ ntohs(*(const uint16_t *)&in6p->s6_addr[2]);
+ sin6.sin6_addr.s6_addr[2] = 0;
+ sin6.sin6_addr.s6_addr[3] = 0;
+ }
+#endif
+ if (getnameinfo((struct sockaddr *)&sin6, sizeof(sin6),
+ hbuf, sizeof(hbuf), NULL, 0, niflag) != 0)
+ strlcpy(hbuf, "?", sizeof hbuf);
+ strlcpy(line, hbuf, sizeof(line));
+ }
+#else
+ strlcpy(line, "[[XXX - inet6 address]]", sizeof(line));
+#endif
+ return (line);
+}
+
+#ifdef TCP6
+/*
+ * Dump the contents of a TCP6 PCB - Omitted
+ */
+#endif
diff --git a/apps/snmpnetstat/main.c b/apps/snmpnetstat/main.c
new file mode 100644
index 0000000..2e09d5e
--- /dev/null
+++ b/apps/snmpnetstat/main.c
@@ -0,0 +1,539 @@
+/* $OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $ */
+/* $NetBSD: main.c,v 1.9 1996/05/07 02:55:02 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983, 1988, 1993\n\
+ Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifdef INHERITED_CODE
+#ifndef lint
+#if 0
+static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";
+#else
+static char *rcsid = "$OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $";
+#endif
+#endif /* not lint */
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/utilities.h>
+
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "main.h"
+#include "netstat.h"
+
+#if HAVE_WINSOCK_H
+#include "winstub.h"
+#endif
+
+int Aflag; /* show addresses of protocol control block */
+int aflag; /* show all sockets (including servers) */
+int bflag; /* show bytes instead of packets */
+int dflag; /* show i/f dropped packets */
+int gflag; /* show group (multicast) routing or stats */
+int iflag; /* show interfaces */
+int lflag; /* show routing table with use and ref */
+int mflag; /* show memory stats */
+int nflag; /* show addresses numerically */
+int oflag; /* Open/Net-BSD style octet output */
+int pflag; /* show given protocol */
+int qflag; /* only display non-zero values for output */
+int rflag; /* show routing tables (or routing stats) */
+int Sflag; /* show source address in routing table */
+int sflag; /* show protocol statistics */
+int tflag; /* show i/f watchdog timers */
+int vflag; /* be verbose */
+
+
+int interval; /* repeat interval for i/f stats */
+char *intrface; /* desired i/f for stats, or NULL for all i/fs */
+int af; /* address family */
+int max_getbulk = 32; /* specifies the max-repeaters value to use with GETBULK requests */
+
+char *progname = NULL;
+
+ /*
+ * struct nlist nl[] - Omitted
+ */
+
+typedef void (stringfun)(const char*);
+
+struct protox {
+ /* pr_index/pr_sindex - Omitted */
+ int pr_wanted; /* 1 if wanted, 0 otherwise */
+ stringfun *pr_cblocks; /* control blocks printing routine */
+ stringfun *pr_stats; /* statistics printing routine */
+ const char *pr_name; /* well-known name */
+} protox[] = {
+ { 1, tcpprotopr, tcp_stats, "tcp" },
+ { 1, udpprotopr, udp_stats, "udp" },
+
+ { 1, (stringfun*)0, ip_stats, "ip" }, /* protopr Omitted */
+ { 1, (stringfun*)0, icmp_stats, "icmp" },
+ /* igmp/ah/esp/ipencap/etherip/ipcomp/carp/pfsync/pim - Omitted */
+ { 0, (stringfun*)0, (stringfun*)0, NULL }
+};
+
+struct protox ip6protox[] = {
+ { 1, tcp6protopr, (stringfun*)0, "tcp6" },
+ { 1, udp6protopr, (stringfun*)0, "udp6" },
+
+ { 1, (stringfun*)0, ip6_stats, "ip6" },/* ip6protopr Omitted */
+ { 1, (stringfun*)0, icmp6_stats, "icmp6" },
+ /* pim6/rip6 - Omitted */
+ { 0, (stringfun*)0, (stringfun*)0, NULL }
+};
+
+ /* {ipx,ns,atalk}protox Omitted */
+
+struct protox *protoprotox[] = {
+ protox, ip6protox, NULL
+};
+
+static void printproto(struct protox *, const char *);
+static void usage(void);
+static struct protox *name2protox(const char *);
+static struct protox *knownname(const char *);
+
+netsnmp_session *ss;
+struct protox *tp = NULL; /* for printing cblocks & stats */
+
+static void
+optProc( int argc, char *const *argv, int opt )
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ /* case 'A': *BSD: display PCB addresses
+ Linux: protocol family
+ Aflag = 1;
+ break;
+ */
+ case 'a':
+ aflag = 1;
+ break;
+ case 'b':
+ bflag = 1;
+ break;
+ case 'd':
+ dflag = 1;
+ break;
+ case 'f':
+ if (!*optarg)
+ optarg = argv[optind++];
+ if (strcmp(optarg, "inet") == 0)
+ af = AF_INET;
+ else if (strcmp(optarg, "inet6") == 0)
+ af = AF_INET6;
+ /*
+ else if (strcmp(optarg, "local") == 0)
+ af = AF_LOCAL;
+ else if (strcmp(optarg, "unix") == 0)
+ af = AF_UNIX;
+ else if (strcmp(optarg, "ipx") == 0)
+ af = AF_IPX;
+ else if (strcmp(optarg, "ns") == 0)
+ af = AF_NS;
+ else if (strcmp(optarg, "encap") == 0)
+ af = PF_KEY;
+ else if (strcmp(optarg, "atalk") == 0)
+ af = AF_APPLETALK;
+ */
+ else {
+ (void)fprintf(stderr,
+ "%s: %s: unknown address family\n",
+ progname, optarg);
+ exit(1);
+ }
+ return;
+ case 'g':
+ gflag = 1;
+ break;
+ case 'I':
+ iflag = 1;
+ if (!*optarg)
+ optarg = argv[optind++];
+ intrface = optarg;
+ return;
+ case 'i':
+ iflag = 1;
+ break;
+ /* case 'L': FreeBSD: Display listen queue lengths
+ NetBSD: Suppress link-level routes */
+ /* case 'l': OpenBSD: Wider IPv6 display
+ Linux: Listening sockets only
+ lflag = 1;
+ break;
+ case 'M': *BSD: Memory image
+ Linux: Masqueraded connections
+ memf = optarg;
+ break;
+ */
+ case 'm':
+ mflag = 1;
+ break;
+ /* case 'N': *BSD: Kernel image
+ nlistf = optarg;
+ break;
+ */
+ case 'n':
+ nflag = 1;
+ break;
+ case 'o':
+ oflag = 1;
+ break;
+ /* case 'P': NetBSD:
+ OpenBSD: dump PCB block */
+ case 'p':
+ if (!*optarg)
+ optarg = argv[optind++];
+ if ((tp = name2protox(optarg)) == NULL) {
+ (void)fprintf(stderr,
+ "%s: %s: unknown protocol\n",
+ progname, optarg);
+ exit(1);
+ }
+ pflag = 1;
+ return;
+ /* case 'q': NetBSD: IRQ information
+ OpenBSD: Suppress inactive I/Fs
+ qflag = 1;
+ break;
+ */
+ case 'r':
+ rflag = 1;
+ break;
+ case 'R':
+ if (optind < argc) {
+ if (argv[optind]) {
+ max_getbulk = atoi(argv[optind]);
+ if (max_getbulk == 0) {
+ usage();
+ fprintf(stderr, "Bad -CR option: %s\n",
+ argv[optind]);
+ exit(1);
+ }
+ }
+ } else {
+ usage();
+ fprintf(stderr, "Bad -CR option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ case 'S': /* FreeBSD:
+ NetBSD: Semi-numeric display
+ OpenBSD: Show route source selector */
+ Sflag = 1;
+ break;
+ case 's':
+ ++sflag;
+ break;
+ /* case 't': FreeBSD:
+ OpenBSD: Display watchdog timers
+ tflag = 1;
+ break;
+ case 'u': OpenBSD: unix sockets only
+ af = AF_UNIX;
+ break;
+ */
+ case 'v':
+ vflag = 1;
+ break;
+ case 'w':
+ if (!*optarg)
+ optarg = argv[optind++];
+ interval = atoi(optarg);
+ iflag = 1;
+ return;
+ case '?':
+ default:
+ usage();
+ }
+ }
+ break; /* End of '-Cx' switch */
+
+ /*
+ * Backward compatability for the main display modes
+ * (where this doesn't clash with standard SNMP flags)
+ */
+ case 'i':
+ iflag = 1;
+ break;
+ case 'R':
+ rflag = 1; /* -r sets the retry count */
+ break;
+ case 's':
+ ++sflag;
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session;
+ struct protoent *p;
+ char *cp;
+
+ af = AF_UNSPEC;
+ cp = strrchr( argv[0], '/' );
+ if (cp)
+ progname = cp+1;
+ else
+ progname = argv[0];
+
+ switch (snmp_parse_args( argc, argv, &session, "C:iRs", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ /*
+ * Check argc vs optind ??
+ */
+ argv += optind;
+ argc -= optind;
+
+ /*
+ * Open an SNMP session.
+ */
+ SOCK_STARTUP;
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpnetstat", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * Omitted:
+ * Privilege handling
+ * "Backward Compatibility"
+ * Kernel namelis handling
+ */
+
+ if (mflag) {
+ /*
+ mbpr(nl[N_MBSTAT].n_value, nl[N_MBPOOL].n_value,
+ nl[N_MCLPOOL].n_value);
+ */
+ exit(0);
+ }
+ if (pflag) {
+ printproto(tp, tp->pr_name);
+ exit(0);
+ }
+ /*
+ * Keep file descriptors open to avoid overhead
+ * of open/close on each call to get* routines.
+ */
+ sethostent(1);
+ setnetent(1);
+ if (iflag) {
+ intpr(interval);
+ exit(0);
+ }
+ if (rflag) {
+ /*
+ if (sflag)
+ rt_stats();
+ else
+ */
+ routepr();
+ exit(0);
+ }
+ /*
+ if (gflag) {
+ if (sflag) {
+ if (af == AF_INET || af == AF_UNSPEC)
+ mrt_stats(nl[N_MRTPROTO].n_value,
+ nl[N_MRTSTAT].n_value);
+#ifdef NETSNMP_ENABLE_IPV6
+ if (af == AF_INET6 || af == AF_UNSPEC)
+ mrt6_stats(nl[N_MRT6PROTO].n_value,
+ nl[N_MRT6STAT].n_value);
+#endif
+ }
+ else {
+ if (af == AF_INET || af == AF_UNSPEC)
+ mroutepr(nl[N_MRTPROTO].n_value,
+ nl[N_MFCHASHTBL].n_value,
+ nl[N_MFCHASH].n_value,
+ nl[N_VIFTABLE].n_value);
+#ifdef NETSNMP_ENABLE_IPV6
+ if (af == AF_INET6 || af == AF_UNSPEC)
+ mroute6pr(nl[N_MRT6PROTO].n_value,
+ nl[N_MF6CTABLE].n_value,
+ nl[N_MIF6TABLE].n_value);
+#endif
+ }
+ exit(0);
+ }
+ */
+ if (af == AF_INET || af == AF_UNSPEC) {
+ setprotoent(1);
+ setservent(1);
+ /* ugh, this is O(MN) ... why do we do this? */
+ while ((p = getprotoent())) {
+ for (tp = protox; tp->pr_name; tp++)
+ if (strcmp(tp->pr_name, p->p_name) == 0)
+ break;
+ if (tp->pr_name == NULL || tp->pr_wanted == 0)
+ continue;
+ printproto(tp, p->p_name);
+ }
+ endprotoent();
+ }
+ if (af == AF_INET6 || af == AF_UNSPEC)
+ for (tp = ip6protox; tp->pr_name; tp++)
+ printproto(tp, tp->pr_name);
+ /*
+ if (af == AF_IPX || af == AF_UNSPEC)
+ for (tp = ipxprotox; tp->pr_name; tp++)
+ printproto(tp, tp->pr_name);
+ if (af == AF_NS || af == AF_UNSPEC)
+ for (tp = nsprotox; tp->pr_name; tp++)
+ printproto(tp, tp->pr_name);
+ if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
+ unixpr(nl[N_UNIXSW].n_value);
+ if (af == AF_APPLETALK || af == AF_UNSPEC)
+ for (tp = atalkprotox; tp->pr_name; tp++)
+ printproto(tp, tp->pr_name);
+ */
+ exit(0);
+}
+
+/*
+ * Print out protocol statistics or control blocks (per sflag).
+ * Namelist checks - Omitted
+ */
+static void
+printproto(struct protox *tp, const char *name)
+{
+ void (*pr)(const char *);
+
+ if (sflag) {
+ pr = tp->pr_stats;
+ } else {
+ pr = tp->pr_cblocks;
+ }
+ if (pr != NULL)
+ (*pr)(name);
+}
+
+/*
+ * Read kernel memory - Omitted
+ */
+
+const char *
+plural(int n)
+{
+ return (n != 1 ? "s" : "");
+}
+
+/*
+ * Find the protox for the given "well-known" name.
+ */
+static struct protox *
+knownname(const char *name)
+{
+ struct protox **tpp, *tp;
+
+ for (tpp = protoprotox; *tpp; tpp++)
+ for (tp = *tpp; tp->pr_name; tp++)
+ if (strcmp(tp->pr_name, name) == 0)
+ return (tp);
+ return (NULL);
+}
+
+/*
+ * Find the protox corresponding to name.
+ */
+static struct protox *
+name2protox(const char *name)
+{
+ struct protox *tp;
+ char **alias; /* alias from p->aliases */
+ struct protoent *p;
+
+ /*
+ * Try to find the name in the list of "well-known" names. If that
+ * fails, check if name is an alias for an Internet protocol.
+ */
+ if ((tp = knownname(name)))
+ return (tp);
+
+ setprotoent(1); /* make protocol lookup cheaper */
+ while ((p = getprotoent())) {
+ /* netsnmp_assert: name not same as p->name */
+ for (alias = p->p_aliases; *alias; alias++)
+ if (strcmp(name, *alias) == 0) {
+ endprotoent();
+ return (knownname(p->p_name));
+ }
+ }
+ endprotoent();
+ return (NULL);
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+"usage: %s [snmp_opts] [-Can] [-Cf address_family]\n", progname);
+ (void)fprintf(stderr,
+" %s [snmp_opts] [-CbdgimnrSs] [-Cf address_family]\n", progname);
+ (void)fprintf(stderr,
+" %s [snmp_opts] [-Cbdn] [-CI interface] [-Cw wait]\n", progname);
+ (void)fprintf(stderr,
+" %s [snmp_opts] [-Cs] [-Cp protocol]\n", progname);
+ (void)fprintf(stderr,
+" %s [snmp_opts] [-Ca] [-Cf address_family] [-Ci | -CI interface]\n", progname);
+ exit(1);
+}
diff --git a/apps/snmpnetstat/main.h b/apps/snmpnetstat/main.h
new file mode 100644
index 0000000..1272321
--- /dev/null
+++ b/apps/snmpnetstat/main.h
@@ -0,0 +1,23 @@
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+extern netsnmp_session *ss;
+NETSNMP_IMPORT
+int netsnmp_query_get( netsnmp_variable_list *list,
+ netsnmp_session *session);
+NETSNMP_IMPORT
+int netsnmp_query_getnext(netsnmp_variable_list *list,
+ netsnmp_session *session);
+NETSNMP_IMPORT
+int netsnmp_query_walk( netsnmp_variable_list *list,
+ netsnmp_session *session);
+
+#ifndef AF_INET6
+#define AF_INET6 10
+#endif
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
diff --git a/apps/snmpnetstat/netstat.h b/apps/snmpnetstat/netstat.h
new file mode 100644
index 0000000..2841bf2
--- /dev/null
+++ b/apps/snmpnetstat/netstat.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: netstat.h,v 1.31 2005/02/10 14:25:08 itojun Exp $ */
+/* $NetBSD: netstat.h,v 1.6 1996/05/07 02:55:05 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ * Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)netstat.h 8.2 (Berkeley) 1/4/94
+ */
+
+#ifdef HAVE_SYS_CDEFS_H
+#include <sys/cdefs.h>
+#endif
+
+/* What is the max length of a pointer printed with %p (including 0x)? */
+#define PLEN (LONG_BIT / 4 + 2)
+
+extern int Aflag; /* show addresses of protocol control block */
+extern int aflag; /* show all sockets (including servers) */
+extern int bflag; /* show bytes instead of packets */
+extern int dflag; /* show i/f dropped packets */
+extern int gflag; /* show group (multicast) routing or stats */
+extern int iflag; /* show interfaces */
+extern int lflag; /* show routing table with use and ref */
+extern int mflag; /* show memory stats */
+extern int nflag; /* show addresses numerically */
+extern int oflag; /* Open/Net-BSD style octet output */
+extern int pflag; /* show given protocol */
+extern int qflag; /* only display non-zero values for output */
+extern int rflag; /* show routing tables (or routing stats) */
+extern int Sflag; /* show source address in routing table */
+extern int sflag; /* show protocol statistics */
+extern int tflag; /* show i/f watchdog timers */
+extern int vflag; /* be verbose */
+
+extern int interval; /* repeat interval for i/f stats */
+
+extern char *intrface; /* desired i/f for stats, or NULL for all i/fs */
+
+extern int af; /* address family */
+extern int max_getbulk; /* specifies the max-repeaters value to use with GETBULK requests */
+
+extern char *__progname; /* program name, from crt0.o */
+
+const char *plural(int);
+
+void tcpprotopr(const char *);
+void udpprotopr(const char *);
+void tcp_stats( const char *);
+void udp_stats( const char *);
+void ip_stats( const char *);
+void icmp_stats(const char *);
+
+void tcp6protopr(const char *);
+void udp6protopr(const char *);
+void ip6_stats( const char *);
+void icmp6_stats(const char *);
+
+void pr_rthdr(int);
+void pr_encaphdr(void);
+void pr_family(int);
+void rt_stats(void);
+
+char *routename(in_addr_t);
+char *netname(in_addr_t, in_addr_t);
+char *ns_print(struct sockaddr *);
+void routepr(void);
+
+void intpr(int);
+
diff --git a/apps/snmpnetstat/route.c b/apps/snmpnetstat/route.c
new file mode 100644
index 0000000..e5526dc
--- /dev/null
+++ b/apps/snmpnetstat/route.c
@@ -0,0 +1,487 @@
+/* $OpenBSD: route.c,v 1.66 2004/11/17 01:47:20 itojun Exp $ */
+/* $NetBSD: route.c,v 1.15 1996/05/07 02:55:06 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef INHERITED_CODE
+#ifndef lint
+#if 0
+static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";
+#else
+static char *rcsid = "$OpenBSD: route.c,v 1.66 2004/11/17 01:47:20 itojun Exp $";
+#endif
+#endif /* not lint */
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifndef INET
+#define INET
+#endif
+
+#include "main.h"
+#include "netstat.h"
+#if HAVE_WINSOCK_H
+#include "winstub.h"
+#endif
+
+#define SET_MASK 0x01
+#define SET_GWAY 0x02
+#define SET_IFNO 0x04
+#define SET_TYPE 0x08
+#define SET_PRTO 0x10
+#define SET_ALL 0x1f
+
+struct route_entry {
+ oid instance[4];
+ in_addr_t destination;
+ in_addr_t mask;
+ in_addr_t gateway;
+ int ifNumber;
+ int type;
+ int proto;
+ int set_bits;
+ char ifname[64];
+};
+
+void p_rtnode( struct route_entry *rp );
+extern int _ffs(int mask);
+
+/*
+ * Print routing tables.
+ */
+void
+routepr(void)
+{
+ struct route_entry route, *rp = &route;
+ oid rtcol_oid[] = { 1,3,6,1,2,1,4,21,1,0 };
+ size_t rtcol_len = OID_LENGTH( rtcol_oid );
+ union {
+ in_addr_t addr;
+ char data[4];
+ } tmpAddr;
+ netsnmp_variable_list *var=NULL, *vp;
+ char *cp;
+
+ printf("Routing tables\n");
+ pr_rthdr(AF_INET);
+
+#define ADD_RTVAR( x ) rtcol_oid[ rtcol_len-1 ] = x; \
+ snmp_varlist_add_variable( &var, rtcol_oid, rtcol_len, ASN_NULL, NULL, 0)
+ ADD_RTVAR( 2 ); /* ipRouteIfIndex */
+ ADD_RTVAR( 7 ); /* ipRouteNextHop */
+ ADD_RTVAR( 8 ); /* ipRouteType */
+ ADD_RTVAR( 9 ); /* ipRouteProto */
+ ADD_RTVAR( 11 ); /* ipRouteMask */
+#undef ADD_RTVAR
+
+ /*
+ * Now walk the ipRouteTable, reporting the various route entries
+ */
+ while ( 1 ) {
+ if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
+ break;
+ rtcol_oid[ rtcol_len-1 ] = 2; /* ifRouteIfIndex */
+ if ( snmp_oid_compare( rtcol_oid, rtcol_len,
+ var->name, rtcol_len) != 0 )
+ break; /* End of Table */
+ memset( &route, 0, sizeof( struct route_entry ));
+ /* Extract ipRouteDest index value */
+ cp = tmpAddr.data;
+ cp[0] = var->name[ 10 ] & 0xff;
+ cp[1] = var->name[ 11 ] & 0xff;
+ cp[2] = var->name[ 12 ] & 0xff;
+ cp[3] = var->name[ 13 ] & 0xff;
+ rp->destination = tmpAddr.addr;
+
+ for ( vp=var; vp; vp=vp->next_variable ) {
+ switch ( vp->name[ 9 ] ) {
+ case 2: /* ifRouteIfIndex */
+ rp->ifNumber = *vp->val.integer;
+ rp->set_bits |= SET_IFNO;
+ break;
+ case 7: /* ipRouteNextHop */
+ memmove(&rp->gateway, vp->val.string, 4);
+ rp->set_bits |= SET_GWAY;
+ break;
+ case 8: /* ipRouteType */
+ rp->type = *vp->val.integer;
+ rp->set_bits |= SET_TYPE;
+ break;
+ case 9: /* ipRouteProto */
+ rp->proto = *vp->val.integer;
+ rp->set_bits |= SET_PRTO;
+ break;
+ case 11: /* ipRouteMask */
+ memmove(&rp->mask, vp->val.string, 4);
+ rp->set_bits |= SET_MASK;
+ break;
+ }
+ }
+ if (rp->set_bits != SET_ALL) {
+ continue; /* Incomplete query */
+ }
+
+ p_rtnode( rp );
+ }
+}
+
+
+
+struct iflist {
+ int index;
+ char name[64];
+ struct iflist *next;
+} *Iflist = NULL;
+
+void
+get_ifname(char *name, int ifIndex)
+{
+ oid ifdescr_oid[] = { 1,3,6,1,2,1,2,2,1,2,0 };
+ size_t ifdescr_len = OID_LENGTH( ifdescr_oid );
+ netsnmp_variable_list *var = NULL;
+ struct iflist *ip;
+
+ for (ip = Iflist; ip; ip = ip->next) {
+ if (ip->index == ifIndex)
+ break;
+ }
+ if (ip) {
+ strcpy(name, ip->name);
+ return;
+ }
+ ip = (struct iflist *) malloc(sizeof(struct iflist));
+ if (ip == NULL)
+ return;
+ ip->next = Iflist;
+ Iflist = ip;
+ ip->index = ifIndex;
+
+ ifdescr_oid[ ifdescr_len-1 ] = ifIndex;
+ snmp_varlist_add_variable( &var, ifdescr_oid, ifdescr_len,
+ ASN_NULL, NULL, 0);
+ if (netsnmp_query_get( var, ss ) == SNMP_ERR_NOERROR) {
+ if (var->val_len >= sizeof(ip->name))
+ var->val_len = sizeof(ip->name) - 1;
+ memmove(ip->name, var->val.string, var->val_len);
+ ip->name[var->val_len] = '\0';
+ } else {
+ sprintf(ip->name, "if%d", ifIndex);
+ }
+ strcpy(name, ip->name);
+}
+
+/* column widths; each followed by one space */
+#ifndef NETSNMP_ENABLE_IPV6
+#define WID_DST(af) 26 /* width of destination column */
+#define WID_GW(af) 18 /* width of gateway column */
+#else
+/* width of destination/gateway column */
+#if 1
+/* strlen("fe80::aaaa:bbbb:cccc:dddd@gif0") == 30, strlen("/128") == 4 */
+#define WID_DST(af) ((af) == AF_INET6 ? (nflag ? 34 : 26) : 26)
+#define WID_GW(af) ((af) == AF_INET6 ? (nflag ? 30 : 18) : 18)
+#else
+/* strlen("fe80::aaaa:bbbb:cccc:dddd") == 25, strlen("/128") == 4 */
+#define WID_DST(af) ((af) == AF_INET6 ? (nflag ? 29 : 18) : 18)
+#define WID_GW(af) ((af) == AF_INET6 ? (nflag ? 25 : 18) : 18)
+#endif
+#endif /* NETSNMP_ENABLE_IPV6 */
+
+/*
+ * Print header for routing table columns.
+ */
+void
+pr_rthdr(int af)
+{
+ /*
+ if (Aflag)
+ printf("%-*.*s ", PLEN, PLEN, "Address");
+ if (Sflag)
+ printf("%-*.*s ",
+ WID_DST(af), WID_DST(af), "Source");
+ */
+ printf("%-*.*s ",
+ WID_DST(af), WID_DST(af), "Destination");
+ printf("%-*.*s %-6.6s %s\n",
+ WID_GW(af), WID_GW(af), "Gateway",
+ "Flags", "Interface");
+}
+
+/*
+ * Print header for PF_KEY entries.
+void
+pr_encaphdr(void)
+{
+ if (Aflag)
+ printf("%-*s ", PLEN, "Address");
+ printf("%-18s %-5s %-18s %-5s %-5s %-22s\n",
+ "Source", "Port", "Destination",
+ "Port", "Proto", "SA(Address/Proto/Type/Direction)");
+}
+ */
+
+char *
+routename(in_addr_t in)
+{
+ char *cp;
+ static char line[MAXHOSTNAMELEN];
+ struct hostent *hp;
+ static char domain[MAXHOSTNAMELEN];
+ static int first = 1;
+
+ if (first) {
+ first = 0;
+ if (gethostname(domain, sizeof domain) == 0 &&
+ (cp = strchr(domain, '.')))
+ (void) strlcpy(domain, cp + 1, sizeof domain);
+ else
+ domain[0] = '\0';
+ }
+ cp = NULL;
+ if (!nflag) {
+ hp = netsnmp_gethostbyaddr((char *)&in, sizeof (struct in_addr),
+ AF_INET);
+ if (hp) {
+ if ((cp = strchr(hp->h_name, '.')) &&
+ !strcmp(cp + 1, domain))
+ *cp = '\0';
+ cp = hp->h_name;
+ }
+ }
+ if (cp) {
+ strlcpy(line, cp, sizeof(line));
+ } else {
+#define C(x) (unsigned)((x) & 0xff)
+ in = ntohl(in);
+ snprintf(line, sizeof line, "%u.%u.%u.%u",
+ C(in >> 24), C(in >> 16), C(in >> 8), C(in));
+ }
+ return (line);
+}
+
+/*
+ * Return the name of the network whose address is given.
+ * The address is assumed to be that of a net or subnet, not a host.
+ */
+char *
+netname(in_addr_t in, in_addr_t mask)
+{
+ char *cp = NULL;
+ static char line[MAXHOSTNAMELEN];
+ struct netent *np = NULL;
+ int mbits;
+
+ in = ntohl(in);
+ mask = ntohl(mask);
+ if (!nflag && in != INADDR_ANY) {
+ if ((np = getnetbyaddr(in, AF_INET)) != NULL)
+ cp = np->n_name;
+ }
+ mbits = mask ? 33 - _ffs(mask) : 0;
+ if (cp) {
+ strlcpy(line, cp, sizeof(line));
+ } else if (mbits < 9)
+ snprintf(line, sizeof line, "%u/%d", C(in >> 24), mbits);
+ else if (mbits < 17)
+ snprintf(line, sizeof line, "%u.%u/%d",
+ C(in >> 24) , C(in >> 16), mbits);
+ else if (mbits < 25)
+ snprintf(line, sizeof line, "%u.%u.%u/%d",
+ C(in >> 24), C(in >> 16), C(in >> 8), mbits);
+ else
+ snprintf(line, sizeof line, "%u.%u.%u.%u/%d", C(in >> 24),
+ C(in >> 16), C(in >> 8), C(in), mbits);
+ return (line);
+}
+
+#undef NETSNMP_ENABLE_IPV6
+#ifdef NETSNMP_ENABLE_IPV6
+char *
+netname6(struct sockaddr_in6 *sa6, struct in6_addr *mask)
+{
+ static char line[MAXHOSTNAMELEN + 1];
+ struct sockaddr_in6 sin6;
+ u_char *p;
+ u_char *lim;
+ int masklen, final = 0, illegal = 0;
+ int i;
+ char hbuf[NI_MAXHOST];
+ int flag = 0;
+ int error;
+
+ sin6 = *sa6;
+
+ masklen = 0;
+ lim = (u_char *)(mask + 1);
+ i = 0;
+ if (mask) {
+ for (p = (u_char *)mask; p < lim; p++) {
+ if (final && *p) {
+ illegal++;
+ sin6.sin6_addr.s6_addr[i++] = 0x00;
+ continue;
+ }
+
+ switch (*p & 0xff) {
+ case 0xff:
+ masklen += 8;
+ break;
+ case 0xfe:
+ masklen += 7;
+ final++;
+ break;
+ case 0xfc:
+ masklen += 6;
+ final++;
+ break;
+ case 0xf8:
+ masklen += 5;
+ final++;
+ break;
+ case 0xf0:
+ masklen += 4;
+ final++;
+ break;
+ case 0xe0:
+ masklen += 3;
+ final++;
+ break;
+ case 0xc0:
+ masklen += 2;
+ final++;
+ break;
+ case 0x80:
+ masklen += 1;
+ final++;
+ break;
+ case 0x00:
+ final++;
+ break;
+ default:
+ final++;
+ illegal++;
+ break;
+ }
+
+ if (!illegal)
+ sin6.sin6_addr.s6_addr[i++] &= *p;
+ else
+ sin6.sin6_addr.s6_addr[i++] = 0x00;
+ }
+ } else
+ masklen = 128;
+
+ if (masklen == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr))
+ return("default");
+
+ if (illegal)
+ fprintf(stderr, "illegal prefixlen\n");
+
+ if (nflag)
+ flag |= NI_NUMERICHOST;
+ error = getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
+ hbuf, sizeof(hbuf), NULL, 0, flag);
+ if (error)
+ snprintf(hbuf, sizeof(hbuf), "invalid");
+
+ snprintf(line, sizeof(line), "%s/%d", hbuf, masklen);
+ return line;
+}
+
+char *
+routename6(struct sockaddr_in6 *sa6)
+{
+ static char line[NI_MAXHOST];
+ const int niflag = NI_NUMERICHOST;
+
+ if (getnameinfo((struct sockaddr *)sa6, sa6->sin6_len,
+ line, sizeof(line), NULL, 0, niflag) != 0)
+ strlcpy(line, "", sizeof line);
+ return line;
+}
+#endif /*NETSNMP_ENABLE_IPV6*/
+
+char *
+s_rtflags( struct route_entry *rp )
+{
+ static char flag_buf[10];
+ char *cp = flag_buf;
+
+ memset( flag_buf, 0, sizeof(flag_buf));
+ *cp++ = '<';
+ *cp++ = 'U'; /* route is in use */
+ if (rp->mask == 0xffffffff)
+ *cp++ = 'H'; /* host */
+ if (rp->proto == 4)
+ *cp++ = 'D'; /* ICMP redirect */
+ if (rp->type == 4)
+ *cp++ = 'G'; /* remote destination/net */
+ *cp++ = '>';
+ return flag_buf;
+}
+
+void
+p_rtnode( struct route_entry *rp )
+{
+ get_ifname(rp->ifname, rp->ifNumber);
+ printf("%-*.*s ",
+ WID_DST(AF_INET), WID_DST(AF_INET),
+ (rp->destination == INADDR_ANY) ? "default" :
+ (rp->set_bits & SET_MASK) ?
+ (rp->mask == 0xffffffff ?
+ routename(rp->destination) :
+ netname(rp->destination, rp->mask)) :
+ netname(rp->destination, 0L));
+ printf("%-*.*s %-6.6s %s\n",
+ WID_GW(af), WID_GW(af),
+ rp->gateway ? routename(rp->gateway) : "*",
+ s_rtflags(rp), rp->ifname);
+}
diff --git a/apps/snmpnetstat/winstub.c b/apps/snmpnetstat/winstub.c
new file mode 100644
index 0000000..5e2dd64
--- /dev/null
+++ b/apps/snmpnetstat/winstub.c
@@ -0,0 +1,285 @@
+/*
+ * cheap and dirty network database lookup functions
+ */
+/*
+ * uses local files only
+ */
+/*
+ * currently searches the protocols only
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+
+#if (defined(WIN32) || defined(cygwin) || defined(aix4))
+
+#ifdef aix4
+#define _NO_PROTO /* Hack, you say ? */
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+static int h_stay_open, s_stay_open, p_stay_open, n_stay_open;
+static FILE *h_fp, *s_fp, *p_fp, *n_fp;
+static char *p_fn;
+#ifdef notused
+static char *h_fn, *s_fn, *n_fn;
+#endif
+
+#ifdef aix4
+#define ROOT_BASE "/etc/"
+#define PROT_FN "protocols"
+#else
+#define ROOT_BASE "\\SYSTEM32\\DRIVERS\\ETC\\"
+#define PROT_FN "protocol"
+#endif
+#define HOST_FN "hosts"
+#define SERV_FN "services"
+#define NETW_FN "networks"
+
+static int pre_env_done = 0;
+static void
+pre_env(void)
+{
+ const char *cproot;
+ const char *cp = "";
+
+ if (pre_env_done)
+ return;
+ pre_env_done = 1;
+
+#ifndef aix4
+ cp = getenv("SYSTEMROOT");
+ if (cp) {
+ ;
+ /*
+ * printf ("Root is '%s'\n", cp);
+ */
+ } else
+ cp = "C:\\WINNT";
+#endif
+
+ cproot = ROOT_BASE;
+ p_fn =
+ (char *) malloc(3 + strlen(cp) + strlen(cproot) + strlen(PROT_FN));
+ if (p_fn)
+ sprintf(p_fn, "%s%s%s", cp, cproot, PROT_FN);
+#ifdef notused
+ h_fn =
+ (char *) malloc(3 + strlen(cp) + strlen(cproot) + strlen(HOST_FN));
+ if (h_fn)
+ sprintf(h_fn, "%s%s%s", cp, cproot, HOST_FN);
+ s_fn =
+ (char *) malloc(3 + strlen(cp) + strlen(cproot) + strlen(SERV_FN));
+ if (s_fn)
+ sprintf(s_fn, "%s%s%s", cp, cproot, SERV_FN);
+ n_fn =
+ (char *) malloc(3 + strlen(cp) + strlen(cproot) + strlen(NETW_FN));
+ if (n_fn)
+ sprintf(n_fn, "%s%s%s", cp, cproot, NETW_FN);
+#endif
+}
+
+/*
+ * sets can open. ends must close.
+ */
+void
+endhostent(void)
+{
+ if (h_fp)
+ fclose(h_fp);
+ h_fp = 0;
+}
+
+void
+endservent(void)
+{
+ if (s_fp)
+ fclose(s_fp);
+ s_fp = 0;
+}
+
+void
+endprotoent(void)
+{
+ if (p_fp)
+ fclose(p_fp);
+ p_fp = 0;
+}
+
+void
+endnetent(void)
+{
+ if (n_fp)
+ fclose(n_fp);
+ n_fp = 0;
+}
+
+void
+sethostent(int stay_open)
+{
+ pre_env();
+ endhostent();
+ h_stay_open = stay_open;
+}
+
+void
+setservent(int stay_open)
+{
+ pre_env();
+ endservent();
+ s_stay_open = stay_open;
+}
+
+void
+setprotoent(int stay_open)
+{
+ pre_env();
+ endprotoent();
+ p_stay_open = stay_open;
+}
+
+void
+setnetent(int stay_open)
+{
+ pre_env();
+ endnetent();
+ n_stay_open = stay_open;
+}
+
+#define STRTOK_DELIMS " \t\n"
+
+/*
+ * get next entry from data base file, or from NIS if possible.
+ */
+/*
+ * returns 0 if there are no more entries to read.
+ */
+struct hostent *
+gethostent(void)
+{
+ return 0;
+}
+struct servent *
+getservent(void)
+{
+ return 0;
+}
+
+struct protoent *
+getprotoent(void)
+{
+ char *cp, **alp, lbuf[256];
+ static struct protoent spx;
+ static char *ali[10];
+ struct protoent *px = &spx;
+ int linecnt = 0;
+ char *st;
+
+ for (alp = ali; *alp; free(*alp), *alp = 0, alp++);
+ if (px->p_name)
+ free(px->p_name);
+ px->p_aliases = ali;
+
+ if (!p_fn)
+ return 0;
+ if (!p_fp)
+ p_fp = fopen(p_fn, "r");
+
+ if (!p_fp)
+ return 0;
+ while (fgets(lbuf, sizeof(lbuf), p_fp)) {
+ linecnt++;
+ cp = lbuf;
+ if (*cp == '#')
+ continue;
+
+ cp = strtok_r(lbuf, STRTOK_DELIMS, &st);
+ if (!cp)
+ continue;
+ if (cp)
+ px->p_name = strdup(cp);
+
+ cp = strtok_r(NULL, STRTOK_DELIMS, &st);
+ if (!cp) {
+ free(px->p_name);
+ continue;
+ }
+ px->p_proto = (short) atoi(cp);
+
+ for (alp = px->p_aliases; cp; alp++) {
+ cp = strtok_r(NULL, STRTOK_DELIMS, &st);
+ if (!cp)
+ break;
+ if (*cp == '#')
+ break;
+ *alp = strdup(cp);
+ }
+
+ return (px);
+ }
+
+ return 0;
+}
+struct netent *
+getnetent(void)
+{
+ return 0;
+}
+
+struct netent *
+getnetbyaddr(long net, int type)
+{
+ return 0;
+}
+
+/*
+ * Return the network number from an internet address
+ */
+u_long
+inet_netof(struct in_addr in)
+{
+ register u_long i = ntohl(in.s_addr);
+ u_long ii = (i >> 24) & 0xff;
+ if (0 == (ii & 0x80))
+ return ((0xff000000 & i) >> 24);
+ if (0x80 == (ii & 0xc0))
+ return ((0xffff0000 & i) >> 16);
+ /*
+ * if (0xc0 == (ii & 0xe0))
+ */
+ return ((0xffffff00 & i) >> 8);
+}
+
+/*
+ * Return the host number from an internet address
+ */
+u_long
+inet_lnaof(struct in_addr in)
+{
+ register u_long i = ntohl(in.s_addr);
+ u_long ii = (i >> 24) & 0xff;
+ if (0 == (ii & 0x80))
+ return (0x00ffffff & i);
+ if (0x80 == (ii & 0xc0))
+ return (0x0000ffff & i);
+ /*
+ * if (0xc0 == (ii & 0xe0))
+ */
+ return (0x000000ff & i);
+}
+
+#endif /* WIN32 or cygwin */
diff --git a/apps/snmpnetstat/winstub.h b/apps/snmpnetstat/winstub.h
new file mode 100644
index 0000000..8fc51dd
--- /dev/null
+++ b/apps/snmpnetstat/winstub.h
@@ -0,0 +1,50 @@
+
+#ifndef _WINSTUB_H_
+#define _WINSTUB_H_
+
+#include <net-snmp/types.h>
+
+#if (defined(WIN32) || defined(cygwin))
+
+/*
+ * database access functions for host, services, protocols, networks
+ */
+
+/*
+ * sets can open. ends must close.
+ */
+void sethostent(int stay_open);
+void setservent(int stay_open);
+void setprotoent(int stay_open);
+void setnetent(int stay_open);
+void endhostent(void);
+void endservent(void);
+void endprotoent(void);
+void endnetent(void);
+
+/*
+ * get next entry from data base file, or from NIS if possible.
+ */
+/*
+ * returns 0 if there are no more entries to read.
+ */
+struct hostent *gethostent(void);
+struct servent *getservent(void);
+struct protoent *getprotoent(void);
+struct netent *getnetent(void);
+
+struct netent *getnetbyaddr(long net, int type);
+
+/*
+ * Return the network number from an internet address
+ */
+u_long inet_netof(struct in_addr in);
+
+/*
+ * Return the host number from an internet address
+ */
+u_long inet_lnaof(struct in_addr in);
+
+#endif /* WIN32 or cygwin */
+
+#endif /*_WINSTUB_H_ */
diff --git a/apps/snmpset.c b/apps/snmpset.c
new file mode 100644
index 0000000..1b29a6c
--- /dev/null
+++ b/apps/snmpset.c
@@ -0,0 +1,284 @@
+/*
+ * snmpset.c - send snmp SET requests to a network entity.
+ *
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpset ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " OID TYPE VALUE [OID TYPE VALUE]...\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr, "\t\t\t q: don't print results on success\n");
+ fprintf(stderr, "\n TYPE: one of i, u, t, a, o, s, x, d, b\n");
+ fprintf(stderr,
+ "\ti: INTEGER, u: unsigned INTEGER, t: TIMETICKS, a: IPADDRESS\n");
+ fprintf(stderr,
+ "\to: OBJID, s: STRING, x: HEX STRING, d: DECIMAL STRING, b: BITS\n");
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ fprintf(stderr,
+ "\tU: unsigned int64, I: signed int64, F: float, D: double\n");
+#endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
+
+}
+
+static int quiet = 0;
+
+static
+ void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'q':
+ quiet = 1;
+ break;
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response = NULL;
+ netsnmp_variable_list *vars;
+ int arg;
+ int count;
+ int current_name = 0;
+ int current_type = 0;
+ int current_value = 0;
+ char *names[SNMP_MAX_CMDLINE_OIDS];
+ char types[SNMP_MAX_CMDLINE_OIDS];
+ char *values[SNMP_MAX_CMDLINE_OIDS];
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ int status;
+ int failures = 0;
+ int exitval = 0;
+
+ putenv(strdup("POSIXLY_CORRECT=1"));
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ if (arg >= argc) {
+ fprintf(stderr, "Missing object name\n");
+ usage();
+ exit(1);
+ }
+ if ((argc - arg) > 3*SNMP_MAX_CMDLINE_OIDS) {
+ fprintf(stderr, "Too many assignments specified. ");
+ fprintf(stderr, "Only %d allowed in one request.\n", SNMP_MAX_CMDLINE_OIDS);
+ usage();
+ exit(1);
+ }
+
+ /*
+ * get object names, types, and values
+ */
+ for (; arg < argc; arg++) {
+ DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %s %s %s\n",
+ arg,argv[arg], arg+1 < argc ? argv[arg+1] : NULL,
+ arg+2 < argc ? argv[arg+2] : NULL));
+ names[current_name++] = argv[arg++];
+ if (arg < argc) {
+ switch (*argv[arg]) {
+ case '=':
+ case 'i':
+ case 'u':
+ case '3':
+ case 't':
+ case 'a':
+ case 'o':
+ case 's':
+ case 'x':
+ case 'd':
+ case 'b':
+#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case 'I':
+ case 'U':
+ case 'F':
+ case 'D':
+#endif /* NETSNMP_WITH_OPAQUE_SPECIAL_TYPES */
+ types[current_type++] = *argv[arg++];
+ break;
+ default:
+ fprintf(stderr, "%s: Bad object type: %c\n", argv[arg - 1],
+ *argv[arg]);
+ exit(1);
+ }
+ } else {
+ fprintf(stderr, "%s: Needs type and value\n", argv[arg - 1]);
+ exit(1);
+ }
+ if (arg < argc)
+ values[current_value++] = argv[arg];
+ else {
+ fprintf(stderr, "%s: Needs value\n", argv[arg - 2]);
+ exit(1);
+ }
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpset", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * create PDU for SET request and add object names and values to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_SET);
+ for (count = 0; count < current_name; count++) {
+ name_length = MAX_OID_LEN;
+ if (snmp_parse_oid(names[count], name, &name_length) == NULL) {
+ snmp_perror(names[count]);
+ failures++;
+ } else
+ if (snmp_add_var
+ (pdu, name, name_length, types[count], values[count])) {
+ snmp_perror(names[count]);
+ failures++;
+ }
+ }
+
+ if (failures) {
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ if (!quiet) {
+ for (vars = response->variables; vars;
+ vars = vars->next_variable)
+ print_variable(vars->name, vars->name_length, vars);
+ }
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && (count != response->errindex);
+ vars = vars->next_variable, count++);
+ if (vars)
+ fprint_objid(stderr, vars->name, vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpset", ss);
+ exitval = 1;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpstatus.c b/apps/snmpstatus.c
new file mode 100644
index 0000000..166ff3d
--- /dev/null
+++ b/apps/snmpstatus.c
@@ -0,0 +1,382 @@
+/*
+ * snmpstatus.c - retrieves a fixed set of management information from
+ * a network entity.
+ *
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/utilities.h>
+
+#include <net-snmp/net-snmp-includes.h>
+
+oid objid_sysDescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
+size_t length_sysDescr = sizeof(objid_sysDescr) / sizeof(oid);
+oid objid_sysUpTime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
+size_t length_sysUpTime = sizeof(objid_sysUpTime) / sizeof(oid);
+oid objid_ifOperStatus[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 8 };
+size_t length_ifOperStatus =
+ sizeof(objid_ifOperStatus) / sizeof(oid);
+oid objid_ifInUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 11 };
+size_t length_ifInUCastPkts =
+ sizeof(objid_ifInUCastPkts) / sizeof(oid);
+oid objid_ifInNUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 12 };
+size_t length_ifInNUCastPkts =
+ sizeof(objid_ifInNUCastPkts) / sizeof(oid);
+oid objid_ifOutUCastPkts[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 17 };
+size_t length_ifOutUCastPkts =
+ sizeof(objid_ifOutUCastPkts) / sizeof(oid);
+oid objid_ifOutNUCastPkts[] =
+ { 1, 3, 6, 1, 2, 1, 2, 2, 1, 18 };
+size_t length_ifOutNUCastPkts =
+ sizeof(objid_ifOutNUCastPkts) / sizeof(oid);
+oid objid_ipInReceives[] = { 1, 3, 6, 1, 2, 1, 4, 3, 0 };
+size_t length_ipInReceives =
+ sizeof(objid_ipInReceives) / sizeof(oid);
+oid objid_ipOutRequests[] = { 1, 3, 6, 1, 2, 1, 4, 10, 0 };
+size_t length_ipOutRequests =
+ sizeof(objid_ipOutRequests) / sizeof(oid);
+
+#define NETSNMP_DS_APP_DONT_FIX_PDUS 0
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'f':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS);
+ break;
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpstatus ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, "\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr,
+ "\t\t\t f: do not fix errors and retry the request\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ netsnmp_transport *transport = NULL;
+ char *sysdescr = NULL;
+ u_long uptime = 0;
+ int status;
+ int ipin = 0, ipout = 0, ipackets = 0, opackets = 0;
+ int good_var;
+ int down_interfaces = 0;
+ char buf[40];
+ int interfaces;
+ int count;
+ int exitval = 0;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (snmp_parse_args(argc, argv, &session, "C:", &optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpstatus", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * create PDU for GET request and add object names to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+ snmp_add_null_var(pdu, objid_sysDescr, length_sysDescr);
+ snmp_add_null_var(pdu, objid_sysUpTime, length_sysUpTime);
+ snmp_add_null_var(pdu, objid_ipInReceives, length_ipInReceives);
+ snmp_add_null_var(pdu, objid_ipOutRequests, length_ipOutRequests);
+
+ /*
+ * do the request
+ */
+ retry:
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars;
+ vars = vars->next_variable) {
+ if (vars->name_length == length_sysDescr
+ && !memcmp(objid_sysDescr, vars->name,
+ sizeof(objid_sysDescr))) {
+ sysdescr = (char *) malloc(vars->val_len + 1);
+ memcpy(sysdescr, vars->val.string, vars->val_len);
+ sysdescr[vars->val_len] = '\0';
+ }
+ if (vars->name_length == length_sysUpTime &&
+ !memcmp(objid_sysUpTime, vars->name,
+ sizeof(objid_sysUpTime)) &&
+ vars->val.integer) {
+ uptime = *vars->val.integer;
+ }
+ if (vars->name_length == length_ipInReceives &&
+ !memcmp(objid_ipInReceives, vars->name,
+ sizeof(objid_ipInReceives)) &&
+ vars->val.integer) {
+ ipin = *vars->val.integer;
+ }
+ if (vars->name_length == length_ipOutRequests &&
+ !memcmp(objid_ipOutRequests, vars->name,
+ sizeof(objid_ipOutRequests)) &&
+ vars->val.integer) {
+ ipout = *vars->val.integer;
+ }
+ }
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++);
+ if (vars)
+ fprint_objid(stderr, vars->name, vars->name_length);
+ fprintf(stderr, "\n");
+ }
+
+ /*
+ * retry if the errored variable was successfully removed
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_DONT_FIX_PDUS)) {
+ pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
+ snmp_free_pdu(response);
+ response = NULL;
+ if (pdu != NULL)
+ goto retry;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ SOCK_CLEANUP;
+ exit(1);
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpstatus", ss);
+ SOCK_CLEANUP;
+ exit(2);
+ }
+
+ transport = snmp_sess_transport(snmp_sess_pointer(ss));
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ char *addr_string = transport->f_fmtaddr(transport,
+ response->transport_data,
+ response->
+ transport_data_length);
+ if (addr_string != NULL) {
+ printf("[%s]=>[%s] Up: %s\n", addr_string, sysdescr,
+ uptime_string(uptime, buf));
+ free(addr_string);
+ }
+ } else {
+ printf("[<UNKNOWN>]=>[%s] Up: %s\n", sysdescr,
+ uptime_string(uptime, buf));
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+
+ /*
+ * create PDU for GET request and add object names to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ snmp_add_null_var(pdu, objid_ifOperStatus, length_ifOperStatus);
+ snmp_add_null_var(pdu, objid_ifInUCastPkts, length_ifInUCastPkts);
+ snmp_add_null_var(pdu, objid_ifInNUCastPkts, length_ifInNUCastPkts);
+ snmp_add_null_var(pdu, objid_ifOutUCastPkts, length_ifOutUCastPkts);
+ snmp_add_null_var(pdu, objid_ifOutNUCastPkts, length_ifOutNUCastPkts);
+
+ /*
+ * ?? note: this code is not quite complete
+ */
+ good_var = 5;
+ interfaces = 0;
+ while (good_var == 5) {
+ good_var = 0;
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ for (vars = response->variables; vars;
+ vars = vars->next_variable) {
+ if (vars->name_length >= length_ifOperStatus
+ && !memcmp(objid_ifOperStatus, vars->name,
+ sizeof(objid_ifOperStatus))) {
+ if (*vars->val.integer != MIB_IFSTATUS_UP)
+ down_interfaces++;
+ snmp_add_null_var(pdu, vars->name,
+ vars->name_length);
+ good_var++;
+ } else if (vars->name_length >= length_ifInUCastPkts &&
+ !memcmp(objid_ifInUCastPkts, vars->name,
+ sizeof(objid_ifInUCastPkts))) {
+ ipackets += *vars->val.integer;
+ snmp_add_null_var(pdu, vars->name,
+ vars->name_length);
+ good_var++;
+ } else if (vars->name_length >= length_ifInNUCastPkts
+ && !memcmp(objid_ifInNUCastPkts, vars->name,
+ sizeof(objid_ifInNUCastPkts))) {
+ ipackets += *vars->val.integer;
+ snmp_add_null_var(pdu, vars->name,
+ vars->name_length);
+ good_var++;
+ } else if (vars->name_length >= length_ifOutUCastPkts
+ && !memcmp(objid_ifOutUCastPkts, vars->name,
+ sizeof(objid_ifOutUCastPkts))) {
+ opackets += *vars->val.integer;
+ snmp_add_null_var(pdu, vars->name,
+ vars->name_length);
+ good_var++;
+ } else if (vars->name_length >= length_ifOutNUCastPkts
+ && !memcmp(objid_ifOutNUCastPkts,
+ vars->name,
+ sizeof(objid_ifOutNUCastPkts))) {
+ opackets += *vars->val.integer;
+ snmp_add_null_var(pdu, vars->name,
+ vars->name_length);
+ good_var++;
+ }
+ }
+ if (good_var == 5)
+ interfaces++;
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++);
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpstatus", ss);
+ exitval = 1;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+ }
+ printf("Interfaces: %d, Recv/Trans packets: %d/%d | IP: %d/%d\n",
+ interfaces, ipackets, opackets, ipin, ipout);
+ if (down_interfaces > 0) {
+ printf("%d interface%s down!\n",
+ down_interfaces, down_interfaces > 1 ? "s are" : " is");
+ }
+
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmptable.c b/apps/snmptable.c
new file mode 100644
index 0000000..c9c7d26
--- /dev/null
+++ b/apps/snmptable.c
@@ -0,0 +1,1010 @@
+/*
+ * snmptable.c - walk a table and print it nicely
+ *
+ * Update: 1999-10-26 <rs-snmp@revelstone.com>
+ * Added ability to use MIB to query tables with non-sequential column OIDs
+ * Added code to handle sparse tables
+ *
+ * Update: 1998-07-17 <jhy@gsu.edu>
+ * Added text <special options> to usage().
+ */
+/**********************************************************************
+ Copyright 1997 Niels Baggesen
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies.
+
+I DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+I BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <stdio.h>
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+struct column {
+ int width;
+ oid subid;
+ char *label;
+ char *fmt;
+} *column = NULL;
+
+static char **data = NULL;
+static char **indices = NULL;
+static int index_width = sizeof("index ") - 1;
+static int fields;
+static int entries;
+static int allocated;
+static int end_of_table = 1;
+static int headers_only = 0;
+static int no_headers = 0;
+static int max_width = 0;
+static int column_width = 0;
+static int brief = 0;
+static int show_index = 0;
+static const char *left_justify_flag = "";
+static char *field_separator = NULL;
+static char *table_name;
+static oid name[MAX_OID_LEN];
+static size_t name_length;
+static oid root[MAX_OID_LEN];
+static size_t rootlen;
+static int localdebug;
+static int exitval = 0;
+static int use_getbulk = 1;
+static int max_getbulk = 10;
+static int extra_columns = 0;
+
+void usage(void);
+void get_field_names(void);
+void get_table_entries(netsnmp_session * ss);
+void getbulk_table_entries(netsnmp_session * ss);
+void print_table(void);
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ /*
+ * Handle new '-C' command-specific meta-options
+ */
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'w':
+ if (optind < argc) {
+ if (argv[optind]) {
+ max_width = atoi(argv[optind]);
+ if (max_width == 0) {
+ usage();
+ fprintf(stderr, "Bad -Cw option: %s\n",
+ argv[optind]);
+ exit(1);
+ }
+ }
+ } else {
+ usage();
+ fprintf(stderr, "Bad -Cw option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ case 'c':
+ if (optind < argc) {
+ if (argv[optind]) {
+ column_width = atoi(argv[optind]);
+ if (column_width <= 2) {
+ usage();
+ fprintf(stderr, "Bad -Cc option: %s\n",
+ argv[optind]);
+ exit(1);
+ }
+ /* Reduce by one for space at end of column */
+ column_width -= 1;
+ }
+ } else {
+ usage();
+ fprintf(stderr, "Bad -Cc option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ case 'l':
+ left_justify_flag = "-";
+ break;
+ case 'f':
+ if (optind < argc) {
+ field_separator = argv[optind];
+ } else {
+ usage();
+ fprintf(stderr, "Bad -Cf option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ case 'h':
+ headers_only = 1;
+ break;
+ case 'H':
+ no_headers = 1;
+ break;
+ case 'B':
+ use_getbulk = 0;
+ break;
+ case 'b':
+ brief = 1;
+ break;
+ case 'i':
+ show_index = 1;
+ break;
+ case 'r':
+ if (optind < argc) {
+ if (argv[optind]) {
+ max_getbulk = atoi(argv[optind]);
+ if (max_getbulk == 0) {
+ usage();
+ fprintf(stderr, "Bad -Cr option: %s\n",
+ argv[optind]);
+ exit(1);
+ }
+ }
+ } else {
+ usage();
+ fprintf(stderr, "Bad -Cr option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ default:
+ fprintf(stderr, "Bad option after -C: %c\n", optarg[-1]);
+ usage();
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmptable ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " TABLE-OID\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr, "\t\t\t b: brief field names\n");
+ fprintf(stderr, "\t\t\t B: do not use GETBULK requests\n");
+ fprintf(stderr, "\t\t\t c<NUM>: print table in columns of <NUM> chars width\n");
+ fprintf(stderr, "\t\t\t f<STR>: print table delimitied with <STR>\n");
+ fprintf(stderr, "\t\t\t h: print only the column headers\n");
+ fprintf(stderr, "\t\t\t H: print no column headers\n");
+ fprintf(stderr, "\t\t\t i: print index values\n");
+ fprintf(stderr, "\t\t\t l: left justify output\n");
+ fprintf(stderr, "\t\t\t r<NUM>: for GETBULK: set max-repeaters to <NUM>\n");
+ fprintf(stderr, "\t\t\t for GETNEXT: retrieve <NUM> entries at a time\n");
+ fprintf(stderr, "\t\t\t w<NUM>: print table in parts of <NUM> chars width\n");
+}
+
+void
+reverse_fields(void)
+{
+ struct column tmp;
+ int i;
+
+ for (i = 0; i < fields / 2; i++) {
+ memcpy(&tmp, &(column[i]), sizeof(struct column));
+ memcpy(&(column[i]), &(column[fields - 1 - i]),
+ sizeof(struct column));
+ memcpy(&(column[fields - 1 - i]), &tmp, sizeof(struct column));
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ int total_entries = 0;
+
+ netsnmp_set_line_buffering(stdout);
+
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT, 1);
+
+ /*
+ * get the common command line arguments
+ */
+ switch (snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ /*
+ * get the initial object and subtree
+ */
+ /*
+ * specified on the command line
+ */
+ if (optind + 1 != argc) {
+ fprintf(stderr, "Must have exactly one table name\n");
+ usage();
+ exit(1);
+ }
+
+ rootlen = MAX_OID_LEN;
+ if (!snmp_parse_oid(argv[optind], root, &rootlen)) {
+ snmp_perror(argv[optind]);
+ exit(1);
+ }
+ localdebug = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET);
+
+ get_field_names();
+ reverse_fields();
+
+ /*
+ * open an SNMP session
+ */
+ SOCK_STARTUP;
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmptable", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (ss->version == SNMP_VERSION_1)
+ use_getbulk = 0;
+#endif
+
+ do {
+ entries = 0;
+ allocated = 0;
+ if (!headers_only) {
+ if (use_getbulk)
+ getbulk_table_entries(ss);
+ else
+ get_table_entries(ss);
+ }
+
+ if (exitval) {
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+ }
+
+ if (entries || headers_only)
+ print_table();
+
+ if (data) {
+ free (data);
+ data = NULL;
+ }
+
+ if (indices) {
+ free (indices);
+ indices = NULL;
+ }
+
+ total_entries += entries;
+
+ } while (!end_of_table);
+
+ snmp_close(ss);
+ SOCK_CLEANUP;
+
+ if (total_entries == 0)
+ printf("%s: No entries\n", table_name);
+ if (extra_columns)
+ printf("%s: WARNING: More columns on agent than in MIB\n", table_name);
+
+ return 0;
+}
+
+void
+print_table(void)
+{
+ int entry, field, first_field, last_field = 0, width, part = 0;
+ char **dp;
+ char string_buf[SPRINT_MAX_LEN];
+ char *index_fmt = NULL;
+ static int first_pass = 1;
+
+ if (!no_headers && !headers_only && first_pass)
+ printf("SNMP table: %s\n\n", table_name);
+
+ for (field = 0; field < fields; field++) {
+ if (column_width != 0)
+ sprintf(string_buf, "%%%s%d.%ds", left_justify_flag,
+ column_width + 1, column_width );
+ else if (field_separator == NULL)
+ sprintf(string_buf, "%%%s%ds", left_justify_flag,
+ column[field].width + 1);
+ else if (field == 0 && !show_index)
+ sprintf(string_buf, "%%s");
+ else
+ sprintf(string_buf, "%s%%s", field_separator);
+ column[field].fmt = strdup(string_buf);
+ }
+ if (show_index) {
+ if (column_width)
+ sprintf(string_buf, "\nindex: %%s\n");
+ else if (field_separator == NULL)
+ sprintf(string_buf, "%%%s%ds", left_justify_flag, index_width);
+ else
+ sprintf(string_buf, "%%s");
+ index_fmt = strdup(string_buf);
+ }
+
+ while (last_field != fields) {
+ part++;
+ if (part != 1 && !no_headers)
+ printf("\nSNMP table %s, part %d\n\n", table_name, part);
+ first_field = last_field;
+ dp = data;
+ if (show_index && !no_headers && !column_width && first_pass) {
+ width = index_width;
+ printf(index_fmt, "index");
+ } else
+ width = 0;
+ for (field = first_field; field < fields; field++) {
+ if (max_width)
+ {
+ if (column_width) {
+ if (!no_headers && first_pass) {
+ width += column_width + 1;
+ if (field != first_field && width > max_width) {
+ printf("\n");
+ width = column_width + 1;
+ }
+ }
+ }
+ else {
+ width += column[field].width + 1;
+ if (field != first_field && width > max_width)
+ break;
+ }
+ }
+ if (!no_headers && first_pass)
+ printf(column[field].fmt, column[field].label);
+ }
+ last_field = field;
+ if (!no_headers && first_pass)
+ printf("\n");
+ for (entry = 0; entry < entries; entry++) {
+ width = 0;
+ if (show_index)
+ {
+ if (!column_width)
+ width = index_width;
+ printf(index_fmt, indices[entry]);
+ }
+ for (field = first_field; field < last_field; field++) {
+ if (column_width && max_width) {
+ width += column_width + 1;
+ if (field != first_field && width > max_width) {
+ printf("\n");
+ width = column_width + 1;
+ }
+ }
+ printf(column[field].fmt, dp[field] ? dp[field] : "?");
+ }
+ dp += fields;
+ printf("\n");
+ }
+ }
+
+ first_pass = 0;
+}
+
+void
+get_field_names(void)
+{
+ char *buf = NULL, *name_p = NULL;
+ size_t buf_len = 0, out_len = 0;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ struct tree *tbl = NULL;
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ int going = 1;
+
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ tbl = get_tree(root, rootlen, get_tree_head());
+ if (tbl) {
+ tbl = tbl->child_list;
+ if (tbl) {
+ root[rootlen++] = tbl->subid;
+ tbl = tbl->child_list;
+ } else {
+ root[rootlen++] = 1;
+ going = 0;
+ }
+ }
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+
+ if (sprint_realloc_objid
+ ((u_char **)&buf, &buf_len, &out_len, 1, root, rootlen - 1)) {
+ table_name = buf;
+ buf = NULL;
+ buf_len = out_len = 0;
+ } else {
+ table_name = strdup("[TRUNCATED]");
+ out_len = 0;
+ }
+
+ fields = 0;
+ while (going) {
+ fields++;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ if (tbl) {
+ if (tbl->access == MIB_ACCESS_NOACCESS) {
+ fields--;
+ tbl = tbl->next_peer;
+ if (!tbl) {
+ going = 0;
+ }
+ continue;
+ }
+ root[rootlen] = tbl->subid;
+ tbl = tbl->next_peer;
+ if (!tbl)
+ going = 0;
+ } else {
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ root[rootlen] = fields;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ }
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ out_len = 0;
+ if (sprint_realloc_objid
+ ((u_char **)&buf, &buf_len, &out_len, 1, root, rootlen + 1)) {
+ name_p = strrchr(buf, '.');
+ if (name_p == NULL) {
+ name_p = strrchr(buf, ':');
+ }
+ if (name_p == NULL) {
+ name_p = buf;
+ } else {
+ name_p++;
+ }
+ } else {
+ break;
+ }
+ if (localdebug) {
+ printf("%s %c\n", buf, name_p[0]);
+ }
+ if ('0' <= name_p[0] && name_p[0] <= '9') {
+ fields--;
+ break;
+ }
+ if (fields == 1) {
+ column = (struct column *) malloc(sizeof(*column));
+ } else {
+ column =
+ (struct column *) realloc(column,
+ fields * sizeof(*column));
+ }
+ column[fields - 1].label = strdup(name_p);
+ column[fields - 1].width = strlen(name_p);
+ column[fields - 1].subid = root[rootlen];
+ }
+ if (fields == 0) {
+ fprintf(stderr, "Was that a table? %s\n", table_name);
+ exit(1);
+ }
+ if (name_p) {
+ *name_p = 0;
+ memmove(name, root, rootlen * sizeof(oid));
+ name_length = rootlen + 1;
+ name_p = strrchr(buf, '.');
+ if (name_p == NULL) {
+ name_p = strrchr(buf, ':');
+ }
+ if (name_p != NULL) {
+ *name_p = 0;
+ }
+ }
+ if (brief && fields > 1) {
+ char *f1, *f2;
+ int common = strlen(column[0].label);
+ int field, len;
+ for (field = 1; field < fields; field++) {
+ f1 = column[field - 1].label;
+ f2 = column[field].label;
+ while (*f1 && *f1++ == *f2++);
+ len = f2 - column[field].label - 1;
+ if (len < common)
+ common = len;
+ }
+ if (common) {
+ for (field = 0; field < fields; field++) {
+ column[field].label += common;
+ column[field].width -= common;
+ }
+ }
+ }
+ if (buf != NULL) {
+ free(buf);
+ }
+}
+
+void
+get_table_entries(netsnmp_session * ss)
+{
+ int running = 1;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int count;
+ int status;
+ int i;
+ int col;
+ char *buf = NULL;
+ size_t out_len = 0, buf_len = 0;
+ char *cp;
+ char *name_p = NULL;
+ char **dp;
+ int have_current_index;
+
+ /*
+ * TODO:
+ * 1) Deal with multiple index fields
+ * 2) Deal with variable length index fields
+ * 3) optimize to remove a sparse column from get-requests
+ */
+
+ while (running &&
+ ((max_width && !column_width) || (entries < max_getbulk))) {
+ /*
+ * create PDU for GETNEXT request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ for (i = 1; i <= fields; i++) {
+ name[rootlen] = column[i - 1].subid;
+ snmp_add_null_var(pdu, name, name_length);
+ }
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ /*
+ * check resulting variables
+ */
+ vars = response->variables;
+ entries++;
+ if (entries >= allocated) {
+ if (allocated == 0) {
+ allocated = 10;
+ data =
+ (char **) malloc(allocated * fields *
+ sizeof(char *));
+ memset(data, 0,
+ allocated * fields * sizeof(char *));
+ if (show_index)
+ indices =
+ (char **) malloc(allocated *
+ sizeof(char *));
+ } else {
+ allocated += 10;
+ data =
+ (char **) realloc(data,
+ allocated * fields *
+ sizeof(char *));
+ memset(data + entries * fields, 0,
+ (allocated -
+ entries) * fields * sizeof(char *));
+ if (show_index)
+ indices =
+ (char **) realloc(indices,
+ allocated *
+ sizeof(char *));
+ }
+ }
+ dp = data + (entries - 1) * fields;
+ col = -1;
+ end_of_table = 1; /* assume end of table */
+ have_current_index = 0;
+ name_length = rootlen + 1;
+ for (vars = response->variables; vars;
+ vars = vars->next_variable) {
+ col++;
+ name[rootlen] = column[col].subid;
+ if ((vars->name_length < name_length) ||
+ (vars->name[rootlen] != column[col].subid) ||
+ memcmp(name, vars->name,
+ name_length * sizeof(oid)) != 0
+ || vars->type == SNMP_ENDOFMIBVIEW) {
+ /*
+ * not part of this subtree
+ */
+ if (localdebug) {
+ fprint_variable(stderr, vars->name,
+ vars->name_length, vars);
+ fprintf(stderr, " => ignored\n");
+ }
+ continue;
+ }
+
+ /*
+ * save index off
+ */
+ if (!have_current_index) {
+ end_of_table = 0;
+ have_current_index = 1;
+ name_length = vars->name_length;
+ memcpy(name, vars->name,
+ name_length * sizeof(oid));
+ out_len = 0;
+ if (!sprint_realloc_objid
+ ((u_char **)&buf, &buf_len, &out_len, 1, vars->name,
+ vars->name_length)) {
+ break;
+ }
+ i = vars->name_length - rootlen + 1;
+ if (localdebug || show_index) {
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_EXTENDED_INDEX)) {
+ name_p = strchr(buf, '[');
+ } else {
+ switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
+ case NETSNMP_OID_OUTPUT_MODULE:
+ case 0:
+ name_p = strchr(buf, ':');
+ break;
+ case NETSNMP_OID_OUTPUT_SUFFIX:
+ name_p = buf;
+ break;
+ case NETSNMP_OID_OUTPUT_FULL:
+ case NETSNMP_OID_OUTPUT_NUMERIC:
+ case NETSNMP_OID_OUTPUT_UCD:
+ name_p = buf + strlen(table_name)+1;
+ name_p = strchr(name_p, '.')+1;
+ break;
+ default:
+ fprintf(stderr, "Unrecognized -O option: %d\n",
+ netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
+ exit(1);
+ }
+ name_p = strchr(name_p, '.') + 1;
+ }
+ }
+ if (localdebug) {
+ printf("Name: %s Index: %s\n", buf, name_p);
+ }
+ if (show_index) {
+ indices[entries - 1] = strdup(name_p);
+ i = strlen(name_p);
+ if (i > index_width)
+ index_width = i;
+ }
+ }
+
+ if (localdebug && buf) {
+ printf("%s => taken\n", buf);
+ }
+ out_len = 0;
+ sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
+ vars->name, vars->name_length,
+ vars);
+ for (cp = buf; *cp; cp++) {
+ if (*cp == '\n') {
+ *cp = ' ';
+ }
+ }
+ dp[col] = buf;
+ i = out_len;
+ buf = NULL;
+ buf_len = 0;
+ if (i > column[col].width) {
+ column[col].width = i;
+ }
+ }
+
+ if (end_of_table) {
+ --entries;
+ /*
+ * not part of this subtree
+ */
+ if (localdebug) {
+ printf("End of table: %s\n",
+ buf ? (char *) buf : "[NIL]");
+ }
+ running = 0;
+ continue;
+ }
+ } else {
+ /*
+ * error in response, print it
+ */
+ running = 0;
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ printf("End of MIB\n");
+ end_of_table = 1;
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars) {
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ }
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ ss->peername);
+ running = 0;
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmptable", ss);
+ running = 0;
+ exitval = 1;
+ }
+ if (response)
+ snmp_free_pdu(response);
+ }
+}
+
+void
+getbulk_table_entries(netsnmp_session * ss)
+{
+ int running = 1;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars, *last_var;
+ int count;
+ int status;
+ int i;
+ int row, col;
+ char *buf = NULL;
+ size_t buf_len = 0, out_len = 0;
+ char *cp;
+ char *name_p = NULL;
+ char **dp;
+
+ while (running) {
+ /*
+ * create PDU for GETBULK request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
+ pdu->non_repeaters = 0;
+ pdu->max_repetitions = max_getbulk;
+ snmp_add_null_var(pdu, name, name_length);
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ /*
+ * check resulting variables
+ */
+ vars = response->variables;
+ last_var = NULL;
+ while (vars) {
+ out_len = 0;
+ sprint_realloc_objid((u_char **)&buf, &buf_len, &out_len, 1,
+ vars->name, vars->name_length);
+ if (vars->type == SNMP_ENDOFMIBVIEW ||
+ memcmp(vars->name, name,
+ rootlen * sizeof(oid)) != 0) {
+ if (localdebug) {
+ printf("%s => end of table\n",
+ buf ? (char *) buf : "[NIL]");
+ }
+ running = 0;
+ break;
+ }
+ if (localdebug) {
+ printf("%s => taken\n",
+ buf ? (char *) buf : "[NIL]");
+ }
+ for (col = 0; col < fields; col++)
+ if (column[col].subid == vars->name[rootlen])
+ break;
+ if (col == fields) {
+ extra_columns = 1;
+ last_var = vars;
+ vars = vars->next_variable;
+ continue;
+ }
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_EXTENDED_INDEX)) {
+ name_p = strchr(buf, '[');
+ } else {
+ switch (netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OID_OUTPUT_FORMAT)) {
+ case NETSNMP_OID_OUTPUT_MODULE:
+ case 0:
+ name_p = strchr(buf, ':')+1;
+ break;
+ case NETSNMP_OID_OUTPUT_SUFFIX:
+ name_p = buf;
+ break;
+ case NETSNMP_OID_OUTPUT_FULL:
+ case NETSNMP_OID_OUTPUT_NUMERIC:
+ case NETSNMP_OID_OUTPUT_UCD:
+ name_p = buf + strlen(table_name)+1;
+ name_p = strchr(name_p, '.')+1;
+ break;
+ default:
+ fprintf(stderr, "Unrecognized -O option: %d\n",
+ netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OID_OUTPUT_FORMAT));
+ exit(1);
+ }
+ name_p = strchr(name_p, '.');
+ if ( name_p == NULL ) {
+ /* The 'strchr' call above failed, i.e. the results
+ * don't seem to include instance subidentifiers! */
+ running = 0;
+ break;
+ }
+ name_p++; /* Move on to the instance identifier */
+ }
+ for (row = 0; row < entries; row++)
+ if (strcmp(name_p, indices[row]) == 0)
+ break;
+ if (row == entries) {
+ entries++;
+ if (entries >= allocated) {
+ if (allocated == 0) {
+ allocated = 10;
+ data =
+ (char **) malloc(allocated * fields *
+ sizeof(char *));
+ memset(data, 0,
+ allocated * fields *
+ sizeof(char *));
+ indices =
+ (char **) malloc(allocated *
+ sizeof(char *));
+ } else {
+ allocated += 10;
+ data =
+ (char **) realloc(data,
+ allocated * fields *
+ sizeof(char *));
+ memset(data + entries * fields, 0,
+ (allocated -
+ entries) * fields *
+ sizeof(char *));
+ indices =
+ (char **) realloc(indices,
+ allocated *
+ sizeof(char *));
+ }
+ }
+ indices[row] = strdup(name_p);
+ i = strlen(name_p);
+ if (i > index_width)
+ index_width = i;
+ }
+ dp = data + row * fields;
+ out_len = 0;
+ sprint_realloc_value((u_char **)&buf, &buf_len, &out_len, 1,
+ vars->name, vars->name_length,
+ vars);
+ for (cp = buf; *cp; cp++)
+ if (*cp == '\n')
+ *cp = ' ';
+ dp[col] = buf;
+ i = out_len;
+ buf = NULL;
+ buf_len = 0;
+ if (i > column[col].width)
+ column[col].width = i;
+ last_var = vars;
+ vars = vars->next_variable;
+ }
+ if (last_var) {
+ name_length = last_var->name_length;
+ memcpy(name, last_var->name,
+ name_length * sizeof(oid));
+ }
+ } else {
+ /*
+ * error in response, print it
+ */
+ running = 0;
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ printf("End of MIB\n");
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ fprintf(stderr,
+ "The request for this object identifier failed: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars) {
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ }
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ ss->peername);
+ running = 0;
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmptable", ss);
+ running = 0;
+ exitval = 1;
+ }
+ if (response)
+ snmp_free_pdu(response);
+ }
+}
diff --git a/apps/snmptest.c b/apps/snmptest.c
new file mode 100644
index 0000000..24de47b
--- /dev/null
+++ b/apps/snmptest.c
@@ -0,0 +1,535 @@
+/*
+ * snmptest.c - send snmp requests to a network entity.
+ *
+ * Usage: snmptest -v 1 [-q] hostname community [objectID]
+ *
+ */
+/***********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+int command = SNMP_MSG_GET;
+
+int input_variable(netsnmp_variable_list *);
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmptest ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, "\n\n");
+ snmp_parse_args_descriptions(stderr);
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu = NULL, *response, *copy = NULL;
+ netsnmp_variable_list *vars, *vp;
+ netsnmp_transport *transport = NULL;
+ int ret;
+ int status, count;
+ char input[128];
+ int varcount, nonRepeaters = -1, maxRepetitions;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (snmp_parse_args(argc, argv, &session, NULL, NULL)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmptest", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ varcount = 0;
+ for(;;) {
+ vars = NULL;
+ for (ret = 1; ret != 0;) {
+ vp = (netsnmp_variable_list *)
+ malloc(sizeof(netsnmp_variable_list));
+ memset(vp, 0, sizeof(netsnmp_variable_list));
+
+ while ((ret = input_variable(vp)) == -1);
+ if (ret == 1) {
+ varcount++;
+ /*
+ * add it to the list
+ */
+ if (vars == NULL) {
+ /*
+ * if first variable
+ */
+ pdu = snmp_pdu_create(command);
+ pdu->variables = vp;
+ } else {
+ vars->next_variable = vp;
+ }
+ vars = vp;
+ } else {
+ /*
+ * free the last (unused) variable
+ */
+ if (vp->name)
+ free((char *) vp->name);
+ if (vp->val.string)
+ free((char *) vp->val.string);
+ free((char *) vp);
+
+ if (command == SNMP_MSG_GETBULK) {
+ if (nonRepeaters == -1) {
+ nonRepeaters = varcount;
+ ret = -1; /* so we collect more variables */
+ printf("Now input the repeating variables\n");
+ } else {
+ printf("What repeat count? ");
+ fflush(stdout);
+ if (!fgets(input, sizeof(input), stdin)) {
+ printf("Quitting, Goodbye\n");
+ SOCK_CLEANUP;
+ exit(0);
+ }
+ maxRepetitions = atoi(input);
+ pdu->non_repeaters = nonRepeaters;
+ pdu->max_repetitions = maxRepetitions;
+ }
+ }
+ }
+ if (varcount == 0 && ret == 0) {
+ if (!copy) {
+ printf("No PDU to send.\n");
+ ret = -1;
+ } else {
+ pdu = snmp_clone_pdu(copy);
+ printf("Resending last PDU.\n");
+ }
+ }
+ }
+ copy = snmp_clone_pdu(pdu);
+ if (command == SNMP_MSG_TRAP2) {
+ /*
+ * No response needed
+ */
+ if (!snmp_send(ss, pdu)) {
+ snmp_free_pdu(pdu);
+ snmp_sess_perror("snmptest", ss);
+ }
+ } else {
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (command == SNMP_MSG_INFORM &&
+ response->errstat == SNMP_ERR_NOERROR) {
+ printf("Inform Acknowledged\n");
+ } else {
+ switch (response->command) {
+ case SNMP_MSG_GET:
+ printf("Received Get Request ");
+ break;
+ case SNMP_MSG_GETNEXT:
+ printf("Received Getnext Request ");
+ break;
+ case SNMP_MSG_RESPONSE:
+ printf("Received Get Response ");
+ break;
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case SNMP_MSG_SET:
+ printf("Received Set Request ");
+ break;
+#endif /* NETSNMP_NO_WRITE_SUPPORT */
+ case SNMP_MSG_TRAP:
+ printf("Received Trap Request ");
+ break;
+ case SNMP_MSG_GETBULK:
+ printf("Received Bulk Request ");
+ break;
+ case SNMP_MSG_INFORM:
+ printf("Received Inform Request ");
+ break;
+ case SNMP_MSG_TRAP2:
+ printf("Received SNMPv2 Trap Request ");
+ break;
+ }
+ transport = snmp_sess_transport(snmp_sess_pointer(ss));
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ char *addr_string = transport->f_fmtaddr(transport,
+ response->
+ transport_data,
+ response->
+ transport_data_length);
+ if (addr_string != NULL) {
+ printf("from %s\n", addr_string);
+ free(addr_string);
+ }
+ } else {
+ printf("from <UNKNOWN>\n");
+ }
+ printf
+ ("requestid 0x%lX errstat 0x%lX errindex 0x%lX\n",
+ response->reqid, response->errstat,
+ response->errindex);
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars;
+ vars = vars->next_variable)
+ print_variable(vars->name, vars->name_length,
+ vars);
+ } else {
+ printf("Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++);
+ if (vars) {
+ printf("Failed object: ");
+ print_objid(vars->name, vars->name_length);
+ }
+ printf("\n");
+ }
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ printf("Timeout: No Response from %s\n", session.peername);
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmptest", ss);
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+ }
+ varcount = 0;
+ nonRepeaters = -1;
+ }
+ /* NOTREACHED */
+}
+
+int
+input_variable(netsnmp_variable_list * vp)
+{
+ char buf[256];
+ size_t val_len;
+ u_char ch;
+
+ printf("Variable: ");
+ fflush(stdout);
+ if (!fgets(buf, sizeof(buf), stdin)) {
+ printf("Quitting, Goobye\n");
+ SOCK_CLEANUP;
+ exit(0);
+ }
+ val_len = strlen(buf);
+
+ if (val_len == 0 || *buf == '\n') {
+ vp->name_length = 0;
+ return 0;
+ }
+ if (buf[val_len - 1] == '\n')
+ buf[--val_len] = 0;
+ if (*buf == '$') {
+ switch (toupper((unsigned char)(buf[1]))) {
+ case 'G':
+ command = SNMP_MSG_GET;
+ printf("Request type is Get Request\n");
+ break;
+ case 'N':
+ command = SNMP_MSG_GETNEXT;
+ printf("Request type is Getnext Request\n");
+ break;
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case 'S':
+ command = SNMP_MSG_SET;
+ printf("Request type is Set Request\n");
+ break;
+#endif /* NETSNMP_NO_WRITE_SUPPORT */
+ case 'B':
+ command = SNMP_MSG_GETBULK;
+ printf("Request type is Bulk Request\n");
+ printf
+ ("Enter a blank line to terminate the list of non-repeaters\n");
+ printf("and to begin the repeating variables\n");
+ break;
+ case 'I':
+ command = SNMP_MSG_INFORM;
+ printf("Request type is Inform Request\n");
+ printf("(Are you sending to the right port?)\n");
+ break;
+ case 'T':
+ command = SNMP_MSG_TRAP2;
+ printf("Request type is SNMPv2 Trap Request\n");
+ printf("(Are you sending to the right port?)\n");
+ break;
+ case 'D':
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET)) {
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET, 0);
+ printf("Turned packet dump off\n");
+ } else {
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET, 1);
+ printf("Turned packet dump on\n");
+ }
+ break;
+ case 'Q':
+ switch ((toupper((unsigned char)(buf[2])))) {
+ case '\n':
+ case 0:
+ printf("Quitting, Goodbye\n");
+ SOCK_CLEANUP;
+ exit(0);
+ break;
+ case 'P':
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT)) {
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT, 0);
+ printf("Turned quick printing off\n");
+ } else {
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT, 1);
+ printf("Turned quick printing on\n");
+ }
+ break;
+ }
+ break;
+ default:
+ printf("Bad command\n");
+ }
+ return -1;
+ }
+ {
+ oid name[MAX_OID_LEN];
+ vp->name_length = MAX_OID_LEN;
+ if (!snmp_parse_oid(buf, name, &vp->name_length)) {
+ snmp_perror(buf);
+ return -1;
+ }
+ vp->name = snmp_duplicate_objid(name, vp->name_length);
+ }
+
+ if (command == SNMP_MSG_INFORM
+ || command == SNMP_MSG_TRAP2
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ || command == SNMP_MSG_SET
+#endif /* NETSNMP_NO_WRITE_SUPPORT */
+ ) {
+ printf("Type [i|u|s|x|d|n|o|t|a]: ");
+ fflush(stdout);
+ if (!fgets(buf, sizeof(buf), stdin)) {
+ printf("Quitting, Goodbye\n");
+ SOCK_CLEANUP;
+ exit(0);
+ }
+ ch = *buf;
+ switch (ch) {
+ case 'i':
+ vp->type = ASN_INTEGER;
+ break;
+ case 'u':
+ vp->type = ASN_UNSIGNED;
+ break;
+ case 's':
+ vp->type = ASN_OCTET_STR;
+ break;
+ case 'x':
+ vp->type = ASN_OCTET_STR;
+ break;
+ case 'd':
+ vp->type = ASN_OCTET_STR;
+ break;
+ case 'n':
+ vp->type = ASN_NULL;
+ break;
+ case 'o':
+ vp->type = ASN_OBJECT_ID;
+ break;
+ case 't':
+ vp->type = ASN_TIMETICKS;
+ break;
+ case 'a':
+ vp->type = ASN_IPADDRESS;
+ break;
+ default:
+ printf
+ ("bad type \"%c\", use \"i\", \"u\", \"s\", \"x\", \"d\", \"n\", \"o\", \"t\", or \"a\".\n",
+ *buf);
+ return -1;
+ }
+ getValue:
+ printf("Value: ");
+ fflush(stdout);
+ if (!fgets(buf, sizeof(buf), stdin)) {
+ printf("Quitting, Goodbye\n");
+ SOCK_CLEANUP;
+ exit(0);
+ }
+ switch (vp->type) {
+ case ASN_INTEGER:
+ vp->val.integer = (long *) malloc(sizeof(long));
+ *(vp->val.integer) = atoi(buf);
+ vp->val_len = sizeof(long);
+ break;
+ case ASN_UNSIGNED:
+ vp->val.integer = (long *) malloc(sizeof(long));
+ *(vp->val.integer) = strtoul(buf, NULL, 0);
+ vp->val_len = sizeof(long);
+ break;
+ case ASN_OCTET_STR:
+ if (ch == 'd') {
+ size_t buf_len = 256;
+ val_len = 0;
+ if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
+ printf("malloc failure\n");
+ goto getValue;
+ }
+ if (!snmp_decimal_to_binary(&(vp->val.string), &buf_len,
+ &val_len, 1, buf)) {
+ printf("Bad value or no sub-identifier > 255\n");
+ free(vp->val.string);
+ goto getValue;
+ }
+ vp->val_len = val_len;
+ } else if (ch == 's') {
+ /*
+ * -1 to omit trailing newline
+ */
+ vp->val.string = (u_char *) malloc(strlen(buf) - 1);
+ if (vp->val.string == NULL) {
+ printf("malloc failure\n");
+ goto getValue;
+ }
+ memcpy(vp->val.string, buf, strlen(buf) - 1);
+ vp->val.string[sizeof(vp->val.string)-1] = 0;
+ vp->val_len = strlen(buf) - 1;
+ } else if (ch == 'x') {
+ size_t buf_len = 256;
+ val_len = 0;
+ if ((vp->val.string = (u_char *) malloc(buf_len)) == NULL) {
+ printf("malloc failure\n");
+ goto getValue;
+ }
+ if (!snmp_hex_to_binary(&(vp->val.string), &buf_len,
+ &val_len, 1, buf)) {
+ printf("Bad value (need pairs of hex digits)\n");
+ free(vp->val.string);
+ goto getValue;
+ }
+ vp->val_len = val_len;
+ }
+ break;
+ case ASN_NULL:
+ vp->val_len = 0;
+ vp->val.string = NULL;
+ break;
+ case ASN_OBJECT_ID:
+ if ('\n' == buf[strlen(buf) - 1])
+ buf[strlen(buf) - 1] = '\0';
+ else {
+ oid value[MAX_OID_LEN];
+ vp->val_len = MAX_OID_LEN;
+ if (0 == read_objid(buf, value, &vp->val_len)) {
+ printf("Unrecognised OID value\n");
+ goto getValue;
+ }
+ vp->val.objid = snmp_duplicate_objid(value, vp->val_len);
+ vp->val_len *= sizeof(oid);
+ }
+ break;
+ case ASN_TIMETICKS:
+ vp->val.integer = (long *) malloc(sizeof(long));
+ *(vp->val.integer) = atoi(buf);
+ vp->val_len = sizeof(long);
+ break;
+ case ASN_IPADDRESS:
+ vp->val.integer = (long *) malloc(sizeof(long));
+ *(vp->val.integer) = inet_addr(buf);
+ vp->val_len = sizeof(long);
+ break;
+ default:
+ printf("Internal error\n");
+ break;
+ }
+ } else { /* some form of get message */
+ vp->type = ASN_NULL;
+ vp->val_len = 0;
+ }
+ return 1;
+}
diff --git a/apps/snmptls.c b/apps/snmptls.c
new file mode 100644
index 0000000..93b648b
--- /dev/null
+++ b/apps/snmptls.c
@@ -0,0 +1,559 @@
+/*
+ * Note: this file originally auto-generated by mib2c using
+ * $
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+#undef NETSNMP_USE_ASSERT
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+netsnmp_feature_require(tls_fingerprint_build)
+
+#include <ctype.h>
+
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <net-snmp/library/cert_util.h>
+
+#include "tlstm-mib.h"
+#include "tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.h"
+#include "tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.h"
+#include "tlstm-mib/snmpTlstmCertToTSNTable/snmpTlstmCertToTSNTable.h"
+
+
+
+/*
+#define COL_SNMPTLSTMCERTTOTSN_ID 1
+#define COL_SNMPTLSTMCERTTOTSN_FINGERPRINT 2
+#define COL_SNMPTLSTMCERTTOTSN_MAPTYPE 3
+#define COL_SNMPTLSTMCERTTOTSN_DATA 4
+#define COL_SNMPTLSTMCERTTOTSN_STORAGETYPE 5
+#define COL_SNMPTLSTMCERTTOTSN_ROWSTATUS 6
+*/
+const oid certNum[] = { SNMP_TLS_TM_CERT_COUNT };
+const oid certChg[] = { SNMP_TLS_TM_CERT_CHANGED };
+const oid certTbl[] = { SNMP_TLS_TM_CERT_TABLE };
+
+/*
+#define COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT 1
+#define COLUMN_SNMPTLSTMPARAMSSTORAGETYPE 2
+#define COLUMN_SNMPTLSTMPARAMSROWSTATUS 3
+*/
+
+const oid paramsNum[] = { SNMP_TLS_TM_PARAMS_COUNT };
+const oid paramsChg[] = { SNMP_TLS_TM_PARAMS_CHANGED };
+const oid paramsTbl[] = { SNMP_TLS_TM_PARAMS_TABLE };
+
+const oid addrNum[] = { SNMP_TLS_TM_ADDR_COUNT };
+const oid addrChg[] = { SNMP_TLS_TM_ADDR_CHANGED };
+const oid addrTbl[] = { SNMP_TLS_TM_ADDR_TABLE };
+
+
+const oid tlstmCertSpecified[] = { SNMP_TLS_TM_BASE, 1, 1, 1 };
+const oid tlstmCertSANRFC822Name[] = { SNMP_TLS_TM_BASE, 1, 1, 2 };
+const oid tlstmCertSANDNSName[] = { SNMP_TLS_TM_BASE, 1, 1, 3 };
+const oid tlstmCertSANIpAddress[] = { SNMP_TLS_TM_BASE, 1, 1, 4 };
+const oid tlstmCertSANAny[] = { SNMP_TLS_TM_BASE, 1, 1, 5 };
+const oid tlstmCertCommonName[] = { SNMP_TLS_TM_BASE, 1, 1, 6 };
+
+const oid *certMapTypes[TSNM_tlstmCert_MAX + 1] = {
+ 0, tlstmCertSpecified, tlstmCertSANRFC822Name, tlstmCertSANDNSName,
+ tlstmCertSANIpAddress, tlstmCertSANAny, tlstmCertCommonName };
+
+/** **************************************************************************
+ *
+ * cert rows
+ *
+ */
+netsnmp_variable_list *
+cert_row_create(uint32_t priority, int hash_type, const char *fp,
+ const oid *map_type, int map_type_len, const u_char *data,
+ int data_len, uint32_t st, int *row_status_index)
+{
+ oid name[] = { SNMP_TLS_TM_CERT_TABLE, 1, -1, -1 };
+ int name_len = OID_LENGTH(name), col_pos = name_len - 2;
+ int rs_index = 4;
+ u_char bin_fp[SNMP_MAXBUF_SMALL], *bin_fp_ptr = bin_fp;
+ u_int rs;
+ size_t bin_fp_len;
+ netsnmp_variable_list *vl = NULL, *vb;
+
+ netsnmp_require_ptr_LRV( fp, NULL );
+
+ DEBUGMSGT(("cert:create", "creating varbinds for pri %d, fp %s\n", priority,
+ fp));
+
+ bin_fp_len = sizeof(bin_fp);
+ netsnmp_tls_fingerprint_build(hash_type, fp, &bin_fp_ptr, &bin_fp_len, 0);
+
+ name[name_len-1] = priority;
+ name[col_pos] = COL_SNMPTLSTMCERTTOTSN_FINGERPRINT;
+ vl = snmp_varlist_add_variable(&vl, name, name_len, ASN_OCTET_STR,
+ &bin_fp, bin_fp_len);
+ netsnmp_require_ptr_LRV(vl, NULL);
+
+ if (map_type_len && map_type) {
+ name[col_pos] = COL_SNMPTLSTMCERTTOTSN_MAPTYPE;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_OBJECT_ID,
+ map_type, map_type_len * sizeof(oid));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+ }
+ else
+ --rs_index;
+
+ if (data) {
+ name[col_pos] = COL_SNMPTLSTMCERTTOTSN_DATA;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_OCTET_STR,
+ data, data_len);
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+ }
+ else
+ --rs_index;
+
+ if (st) {
+ name[col_pos] = COL_SNMPTLSTMCERTTOTSN_STORAGETYPE;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &st, sizeof(st));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+ }
+ else
+ --rs_index;
+
+ name[col_pos] = COL_SNMPTLSTMCERTTOTSN_ROWSTATUS;
+ rs = RS_CREATEANDGO;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &rs, sizeof(rs));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+
+ if (row_status_index)
+ *row_status_index = rs_index;
+
+ return vl;
+}
+
+/** **************************************************************************
+ *
+ * param rows
+ *
+ */
+netsnmp_variable_list *
+params_row_create(const char *param_name, int hash_type, const char *fp,
+ uint32_t st, int *row_status_index)
+{
+ oid name[MAX_OID_LEN];
+ int name_len, col_pos, rs_index = 2;
+ u_char bin_fp[SNMP_MAXBUF_SMALL], *bin_fp_ptr = bin_fp;
+ u_int rs;
+ size_t bin_fp_len;
+ netsnmp_variable_list *vl = NULL, *vb;
+
+ netsnmp_require_ptr_LRV( param_name, NULL );
+ netsnmp_require_ptr_LRV( fp, NULL );
+
+ DEBUGMSGT(("params:create", "creating varbinds for %s params, fp %s\n",
+ param_name, fp));
+
+ /*
+ * build base name
+ */
+ name_len = OID_LENGTH(paramsTbl);
+ memcpy(name, paramsTbl, sizeof(paramsTbl));
+ name[name_len++] = 1; /* entry */
+ col_pos = name_len++; /* column */
+ while (*param_name)
+ name[name_len++] = *param_name++;
+
+ bin_fp_len = sizeof(bin_fp);
+ netsnmp_tls_fingerprint_build(hash_type, fp, &bin_fp_ptr, &bin_fp_len, 0);
+
+ name[col_pos] = COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT;
+ vl = snmp_varlist_add_variable(&vl, name, name_len, ASN_OCTET_STR,
+ &bin_fp, bin_fp_len);
+ netsnmp_require_ptr_LRV(vl, NULL);
+
+ if (st) {
+ name[col_pos] = COLUMN_SNMPTLSTMPARAMSSTORAGETYPE;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &st, sizeof(st));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+ }
+ else
+ --rs_index;
+
+ name[col_pos] = COLUMN_SNMPTLSTMPARAMSROWSTATUS;
+ rs = RS_CREATEANDGO;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &rs, sizeof(rs));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+
+ if (row_status_index)
+ *row_status_index = rs_index;
+
+ return vl;
+}
+
+/** **************************************************************************
+ *
+ * addr rows
+ *
+ */
+netsnmp_variable_list *
+addr_row_create(const char *target_name, int hash_type, const char *fp,
+ const char *identity, uint32_t st, int *row_status_index)
+{
+ oid name[MAX_OID_LEN];
+ int name_len, col_pos, rs_index = 3;
+ u_char bin_fp[SNMP_MAXBUF_SMALL], *bin_fp_ptr = bin_fp;
+ u_int rs;
+ size_t bin_fp_len;
+ netsnmp_variable_list *vl = NULL, *vb;
+
+ netsnmp_require_ptr_LRV( target_name, NULL );
+
+ DEBUGMSGT(("addr:create", "creating varbinds for %s addr, fp %s, id %s\n",
+ target_name, fp, identity));
+
+ /*
+ * build base name
+ */
+ name_len = OID_LENGTH(addrTbl);
+ memcpy(name, addrTbl, sizeof(addrTbl));
+ name[name_len++] = 1; /* entry */
+ col_pos = name_len++; /* column */
+ while (*target_name)
+ name[name_len++] = *target_name++;
+
+ if (fp) {
+ bin_fp_len = sizeof(bin_fp);
+ netsnmp_tls_fingerprint_build(hash_type, fp, &bin_fp_ptr,
+ &bin_fp_len, 0);
+
+ name[col_pos] = COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT;
+ vl = snmp_varlist_add_variable(&vl, name, name_len, ASN_OCTET_STR,
+ &bin_fp, bin_fp_len);
+ netsnmp_require_ptr_LRV(vl, NULL);
+ }
+ else
+ --rs_index;
+
+ if (identity) {
+ name[col_pos] = COLUMN_SNMPTLSTMADDRSERVERIDENTITY;
+ vl = snmp_varlist_add_variable(&vl, name, name_len, ASN_OCTET_STR,
+ identity, strlen(identity));
+ netsnmp_require_ptr_LRV(vl, NULL);
+ }
+ else
+ --rs_index;
+
+ if (st) {
+ name[col_pos] = COLUMN_SNMPTLSTMADDRSTORAGETYPE;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &st, sizeof(st));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+ }
+ else
+ --rs_index;
+
+ name[col_pos] = COLUMN_SNMPTLSTMADDRROWSTATUS;
+ rs = RS_CREATEANDGO;
+ vb = snmp_varlist_add_variable(&vl, name, name_len, ASN_INTEGER,
+ &rs, sizeof(rs));
+ if (NULL == vb) {
+ snmp_free_varbind(vl);
+ return NULL;
+ }
+
+ if (row_status_index)
+ *row_status_index = rs_index;
+
+ return vl;
+}
+
+/** **************************************************************************
+ *
+ * application code
+ *
+ */
+static char *_data = NULL, *_map_type_str = NULL, *_id_str = NULL;
+static char *_storage_type_str = NULL, *_fp_str = NULL;
+static int _storage_type = ST_NONE, _hash_type = NS_HASH_NONE;
+static size_t _data_len;
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ if ('C' != opt)
+ return;
+
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'm':
+ if (optind < argc)
+ _map_type_str = argv[optind++];
+ else {
+ fprintf(stderr, "Bad -Cm option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ case 'd':
+ if (optind < argc) {
+ _data = argv[optind++];
+ _data_len = strlen(_data);
+ }
+ else {
+ fprintf(stderr, "Bad -Cd option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ case 's':
+ if (optind < argc) {
+ if (isdigit(0xFF & argv[optind][0]))
+ _storage_type = atoi(argv[optind++]);
+ else
+ _storage_type_str = argv[optind++];
+ }
+ else {
+ fprintf(stderr, "Bad -Cs option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ case 'h':
+ if (optind < argc) {
+ if (isdigit(0xFF & argv[optind][0]))
+ _hash_type = atoi(argv[optind++]);
+ }
+ else {
+ fprintf(stderr, "Bad -Ch option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ case 'f':
+ if (optind < argc)
+ _fp_str = argv[optind++];
+ else {
+ fprintf(stderr, "Bad -Cf option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ case 'i':
+ if (optind < argc)
+ _id_str = argv[optind++];
+ else {
+ fprintf(stderr, "Bad -Ci option: no argument given\n");
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+}
+
+void
+_parse_storage_type(const char *arg)
+{
+ netsnmp_pdu dummy;
+ oid name[] = { SNMP_TLS_TM_CERT_TABLE, 1,
+ COL_SNMPTLSTMCERTTOTSN_STORAGETYPE };
+ int name_len = OID_LENGTH(name);
+
+ if (NULL == arg)
+ return;
+
+ memset(&dummy, 0x00, sizeof(dummy));
+ snmp_add_var(&dummy, name, name_len, 'i', arg);
+ if (dummy.variables) {
+ _storage_type = *dummy.variables->val.integer;
+ snmp_free_varbind(dummy.variables);
+ }
+ else {
+ fprintf(stderr, "unknown storage type %s for -Cs\n", arg);
+ exit(1);
+ }
+
+ return;
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmptls [-Cm mapTypeOID] [-Cd data] [-Cs storageType] ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, "<command> [command options]\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr, " [options] certToSecName add <priority> <hashType> <fingerprint>\n");
+ fprintf(stderr, "\t-Cm\t\tMaptype; [snmpTlstmCertCommonName|snmpTlstmCertSANRFC822Name|snmpTlstmCertSANIpAddress|snmpTlstmCertSANDNSName|snmpTlstmCertSpecified]\n");
+ fprintf(stderr, "\t\t\t(default is snmpTlstmCertSpecified)\n");
+ fprintf(stderr, "\t-Cd\t\tData; data for snmpTlstmCertSpecified.\n");
+ fprintf(stderr, "\t-Cs\t\tstorageType; default is nonVolatile.\n");
+
+ fprintf(stderr, " [options] targetParamsFingerprint add <params-name> <hashType> <fingerprint>\n");
+ fprintf(stderr, "\t-Cs\t\tstorageType; default is nonVolatile.\n");
+
+ fprintf(stderr, " [options] targetAddr add <target-name> <hashType> [<hash_type> <remote-fingerprint>] [server-identity]\n");
+ fprintf(stderr, "\t-Cs\t\tstorageType; default is nonVolatile.\n");
+
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ netsnmp_session session, *ss;
+ netsnmp_variable_list *var_list = NULL;
+ int arg, rs_idx;
+ u_int hash_type;
+ char *fingerprint, *tmp;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ default:
+ break;
+ }
+
+ /*
+ * Open an SNMP session.
+ */
+ SOCK_STARTUP;
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmptls", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ if (strcmp(argv[arg], "certToSecName") == 0) {
+
+ oid map_type[MAX_OID_LEN];
+ u_int pri;
+ size_t map_type_len;
+
+ if (strcmp(argv[++arg], "add") != 0) {
+ fprintf(stderr, "only add is supported at this time\n");
+ exit(1);
+ }
+
+ pri = atoi(argv[++arg]);
+ tmp = argv[++arg];
+ hash_type = atoi(tmp);
+ fingerprint = argv[++arg];
+
+ DEBUGMSGT(("snmptls",
+ "create pri %d, hash type %d, fp %s",
+ pri, hash_type, fingerprint));
+ if (_map_type_str) {
+ map_type_len = MAX_OID_LEN;
+ if (snmp_parse_oid(_map_type_str, map_type, &map_type_len)
+ == NULL) {
+ snmp_perror(_map_type_str);
+ exit(1);
+ }
+ DEBUGMSG(("snmptls", ", map type "));
+ DEBUGMSGOID(("snmptls", map_type, map_type_len));
+ }
+ if (_data)
+ DEBUGMSG(("snmptls", ", data %s", _data));
+
+ _parse_storage_type(_storage_type_str);
+
+ DEBUGMSG(("snmptls", "\n"));
+ var_list = cert_row_create(pri, hash_type, fingerprint, map_type,
+ map_type_len, (u_char*)_data, _data_len,
+ _storage_type, &rs_idx);
+ }
+ else if (strcmp(argv[arg], "targetParamsFingerprint") == 0) {
+
+ char * params_name;
+
+ if (strcmp(argv[++arg], "add") != 0) {
+ fprintf(stderr, "only add is supported at this time\n");
+ exit(1);
+ }
+
+ params_name = argv[++arg];
+ hash_type = atoi(argv[++arg]);
+ fingerprint = argv[++arg];
+
+ _parse_storage_type(_storage_type_str);
+
+ DEBUGMSGT(("snmptls",
+ "create %s param fp, hash type %d, fp %s\n",
+ params_name, hash_type, fingerprint));
+
+ var_list = params_row_create(params_name, hash_type, fingerprint,
+ _storage_type, &rs_idx);
+ }
+
+ else if (strcmp(argv[arg], "targetAddr") == 0) {
+
+ char * addr_name;
+
+ if (strcmp(argv[++arg], "add") != 0) {
+ fprintf(stderr, "only add is supported at this time\n");
+ exit(1);
+ }
+
+ addr_name = argv[++arg];
+
+ _parse_storage_type(_storage_type_str);
+
+ DEBUGMSGT(("snmptls",
+ "create %s addr fp, hash type %d, fp %s, id %s\n",
+ addr_name, _hash_type, _fp_str, _id_str));
+
+ var_list = addr_row_create(addr_name, _hash_type, _fp_str, _id_str,
+ _storage_type, &rs_idx);
+ }
+
+ if (! var_list) {
+ fprintf(stderr, "no command specified\n");
+ usage();
+ }
+
+ netsnmp_row_create(ss, var_list, rs_idx);
+
+ SOCK_CLEANUP;
+ return 0;
+}
diff --git a/apps/snmptranslate.c b/apps/snmptranslate.c
new file mode 100644
index 0000000..c3d47ae
--- /dev/null
+++ b/apps/snmptranslate.c
@@ -0,0 +1,367 @@
+/*
+ * snmptranslate.c - report or translate info about oid from mibs
+ *
+ * Update: 1998-07-17 <jhy@gsu.edu>
+ * Added support for dumping alternate oid reports (-t and -T options).
+ * Added more detailed (useful?) usage info.
+ */
+/************************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+
+
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <net-snmp/utilities.h>
+#include <net-snmp/config_api.h>
+#include <net-snmp/output_api.h>
+#include <net-snmp/mib_api.h>
+
+int show_all_matched_objects(FILE *, const char *, oid *,
+ size_t *, int, int);
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmptranslate [OPTIONS] OID [OID]...\n\n");
+ fprintf(stderr, " Version: %s\n", netsnmp_get_version());
+ fprintf(stderr, " Web: http://www.net-snmp.org/\n");
+ fprintf(stderr,
+ " Email: net-snmp-coders@lists.sourceforge.net\n\nOPTIONS:\n");
+
+ fprintf(stderr, " -h\t\t\tdisplay this help message\n");
+ fprintf(stderr, " -V\t\t\tdisplay package version number\n");
+ fprintf(stderr,
+ " -m MIB[:...]\t\tload given list of MIBs (ALL loads everything)\n");
+ fprintf(stderr,
+ " -M DIR[:...]\t\tlook in given list of directories for MIBs\n");
+ fprintf(stderr,
+ " -D[TOKEN[,...]]\tturn on debugging output for the specified TOKENs\n\t\t\t (ALL gives extremely verbose debugging output)\n");
+ fprintf(stderr, " -w WIDTH\t\tset width of tree and detail output\n");
+ fprintf(stderr,
+ " -T TRANSOPTS\t\tSet various options controlling report produced:\n");
+ fprintf(stderr,
+ "\t\t\t B: print all matching objects for a regex search\n");
+ fprintf(stderr, "\t\t\t d: print full details of the given OID\n");
+ fprintf(stderr, "\t\t\t p: print tree format symbol table\n");
+ fprintf(stderr, "\t\t\t a: print ASCII format symbol table\n");
+ fprintf(stderr, "\t\t\t l: enable labeled OID report\n");
+ fprintf(stderr, "\t\t\t o: enable OID report\n");
+ fprintf(stderr, "\t\t\t s: enable dotted symbolic report\n");
+ fprintf(stderr, "\t\t\t z: enable MIB child OID report\n");
+ fprintf(stderr,
+ "\t\t\t t: enable alternate format symbolic suffix report\n");
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ fprintf(stderr,
+ " -P MIBOPTS\t\tToggle various defaults controlling mib parsing:\n");
+ snmp_mib_toggle_options_usage("\t\t\t ", stderr);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ fprintf(stderr,
+ " -O OUTOPTS\t\tToggle various defaults controlling output display:\n");
+ snmp_out_toggle_options_usage("\t\t\t ", stderr);
+ fprintf(stderr,
+ " -I INOPTS\t\tToggle various defaults controlling input parsing:\n");
+ snmp_in_toggle_options_usage("\t\t\t ", stderr);
+ fprintf(stderr,
+ " -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
+ snmp_log_options_usage("\t\t\t ", stderr);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int arg;
+ char *current_name = NULL, *cp = NULL;
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ int description = 0;
+ int print = 0;
+ int find_all = 0;
+ int width = 1000000;
+
+ /*
+ * usage: snmptranslate name
+ */
+ while ((arg = getopt(argc, argv, "Vhm:M:w:D:P:T:O:I:L:")) != EOF) {
+ switch (arg) {
+ case 'h':
+ usage();
+ exit(1);
+
+ case 'm':
+ setenv("MIBS", optarg, 1);
+ break;
+ case 'M':
+ setenv("MIBDIRS", optarg, 1);
+ break;
+ case 'D':
+ debug_register_tokens(optarg);
+ snmp_set_do_debugging(1);
+ break;
+ case 'V':
+ fprintf(stderr, "NET-SNMP version: %s\n",
+ netsnmp_get_version());
+ exit(0);
+ break;
+ case 'w':
+ width = atoi(optarg);
+ if (width <= 0) {
+ fprintf(stderr, "Invalid width specification: %s\n", optarg);
+ exit (1);
+ }
+ break;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ case 'P':
+ cp = snmp_mib_toggle_options(optarg);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown parser option to -P: %c.\n", *cp);
+ usage();
+ exit(1);
+ }
+ break;
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ case 'O':
+ cp = snmp_out_toggle_options(optarg);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown OID option to -O: %c.\n", *cp);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'I':
+ cp = snmp_in_toggle_options(optarg);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown OID option to -I: %c.\n", *cp);
+ usage();
+ exit(1);
+ }
+ break;
+ case 'T':
+ for (cp = optarg; *cp; cp++) {
+ switch (*cp) {
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ case 'l':
+ print = 3;
+ print_oid_report_enable_labeledoid();
+ break;
+ case 'o':
+ print = 3;
+ print_oid_report_enable_oid();
+ break;
+ case 's':
+ print = 3;
+ print_oid_report_enable_symbolic();
+ break;
+ case 't':
+ print = 3;
+ print_oid_report_enable_suffix();
+ break;
+ case 'z':
+ print = 3;
+ print_oid_report_enable_mibchildoid();
+ break;
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ case 'd':
+ description = 1;
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_SAVE_MIB_DESCRS, 1);
+ break;
+ case 'B':
+ find_all = 1;
+ break;
+ case 'p':
+ print = 1;
+ break;
+ case 'a':
+ print = 2;
+ break;
+ default:
+ fprintf(stderr, "Invalid -T<lostpad> character: %c\n",
+ *cp);
+ usage();
+ exit(1);
+ break;
+ }
+ }
+ break;
+ case 'L':
+ if (snmp_log_options(optarg, argc, argv) < 0) {
+ return (-1);
+ }
+ break;
+ default:
+ fprintf(stderr, "invalid option: -%c\n", arg);
+ usage();
+ exit(1);
+ break;
+ }
+ }
+
+ init_snmp("snmpapp");
+ if (optind < argc)
+ current_name = argv[optind];
+
+ if (current_name == NULL) {
+ switch (print) {
+ default:
+ usage();
+ exit(1);
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ case 1:
+ print_mib_tree(stdout, get_tree_head(), width);
+ break;
+ case 2:
+ print_ascii_dump(stdout);
+ break;
+ case 3:
+ print_oid_report(stdout);
+ break;
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ }
+ exit(0);
+ }
+
+ do {
+ name_length = MAX_OID_LEN;
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_RANDOM_ACCESS)) {
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ if (!get_node(current_name, name, &name_length)) {
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ fprintf(stderr, "Unknown object identifier: %s\n",
+ current_name);
+ exit(2);
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ }
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ } else if (find_all) {
+ if (0 == show_all_matched_objects(stdout, current_name,
+ name, &name_length,
+ description, width)) {
+ fprintf(stderr,
+ "Unable to find a matching object identifier for \"%s\"\n",
+ current_name);
+ exit(1);
+ }
+ exit(0);
+ } else if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_REGEX_ACCESS)) {
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ if (0 == get_wild_node(current_name, name, &name_length)) {
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ fprintf(stderr,
+ "Unable to find a matching object identifier for \"%s\"\n",
+ current_name);
+ exit(1);
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ }
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ } else {
+ if (!read_objid(current_name, name, &name_length)) {
+ snmp_perror(current_name);
+ exit(2);
+ }
+ }
+
+
+ if (print == 1) {
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ struct tree *tp;
+ tp = get_tree(name, name_length, get_tree_head());
+ if (tp == NULL) {
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ snmp_log(LOG_ERR,
+ "Unable to find a matching object identifier for \"%s\"\n",
+ current_name);
+ exit(1);
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ }
+ print_mib_tree(stdout, tp, width);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ } else {
+ print_objid(name, name_length);
+ if (description) {
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ print_description(name, name_length, width);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ }
+ }
+ current_name = argv[++optind];
+ if (current_name != NULL)
+ printf("\n");
+ } while (optind < argc);
+
+ return (0);
+}
+
+/*
+ * Show all object identifiers that match the pattern.
+ */
+
+int
+show_all_matched_objects(FILE * fp, const char *patmatch, oid * name, size_t * name_length, int f_desc, /* non-zero if descriptions should be shown */
+ int width)
+{
+ int result = 0, count = 0;
+ size_t savlen = *name_length;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ clear_tree_flags(get_tree_head());
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+
+ while (1) {
+ *name_length = savlen;
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ result = get_wild_node(patmatch, name, name_length);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ if (!result)
+ break;
+ count++;
+
+ fprint_objid(fp, name, *name_length);
+#ifndef NETSNMP_DISABLE_MIB_LOADING
+ if (f_desc)
+ fprint_description(fp, name, *name_length, width);
+#endif /* NETSNMP_DISABLE_MIB_LOADING */
+ }
+
+ return (count);
+}
diff --git a/apps/snmptrap.c b/apps/snmptrap.c
new file mode 100644
index 0000000..7c086db
--- /dev/null
+++ b/apps/snmptrap.c
@@ -0,0 +1,392 @@
+/*
+ * snmptrap.c - send snmp traps to a network entity.
+ *
+ */
+/******************************************************************
+ Copyright 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <stdio.h>
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+oid objid_enterprise[] = { 1, 3, 6, 1, 4, 1, 3, 1, 1 };
+oid objid_sysdescr[] = { 1, 3, 6, 1, 2, 1, 1, 1, 0 };
+oid objid_sysuptime[] = { 1, 3, 6, 1, 2, 1, 1, 3, 0 };
+oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
+int inform = 0;
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: %s ", inform ? "snmpinform" : "snmptrap");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " TRAP-PARAMETERS\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviour:\n");
+ fprintf(stderr, "\t\t\t i: send an INFORM instead of a TRAP\n");
+ fprintf(stderr,
+ "\n -v 1 TRAP-PARAMETERS:\n\t enterprise-oid agent trap-type specific-type uptime [OID TYPE VALUE]...\n");
+ fprintf(stderr, " or\n");
+ fprintf(stderr,
+ " -v 2 TRAP-PARAMETERS:\n\t uptime trapoid [OID TYPE VALUE] ...\n");
+}
+
+int
+snmp_input(int operation,
+ netsnmp_session * session,
+ int reqid, netsnmp_pdu *pdu, void *magic)
+{
+ return 1;
+}
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'i':
+ inform = 1;
+ break;
+ default:
+ fprintf(stderr,
+ "Unknown flag passed to -C: %c\n", optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ int arg;
+ int status;
+ char *trap = NULL;
+ char *prognam;
+ int exitval = 0;
+#ifndef NETSNMP_DISABLE_SNMPV1
+ char *specific = NULL, *description = NULL, *agent = NULL;
+ in_addr_t *pdu_in_addr_t;
+#endif
+
+ prognam = strrchr(argv[0], '/');
+ if (prognam)
+ prognam++;
+ else
+ prognam = argv[0];
+
+ putenv(strdup("POSIXLY_CORRECT=1"));
+
+ if (strcmp(prognam, "snmpinform") == 0)
+ inform = 1;
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ SOCK_STARTUP;
+
+ session.callback = snmp_input;
+ session.callback_magic = NULL;
+
+ /*
+ * setup the local engineID which may be for either or both of the
+ * contextEngineID and/or the securityEngineID.
+ */
+ setup_engineID(NULL, NULL);
+
+ /* if we don't have a contextEngineID set via command line
+ arguments, use our internal engineID as the context. */
+ if (session.contextEngineIDLen == 0 ||
+ session.contextEngineID == NULL) {
+ session.contextEngineID =
+ snmpv3_generate_engineID(&session.contextEngineIDLen);
+ }
+
+ if (session.version == SNMP_VERSION_3 && !inform) {
+ /*
+ * for traps, we use ourselves as the authoritative engine
+ * which is really stupid since command line apps don't have a
+ * notion of a persistent engine. Hence, our boots and time
+ * values are probably always really wacked with respect to what
+ * a manager would like to see.
+ *
+ * The following should be enough to:
+ *
+ * 1) prevent the library from doing discovery for engineid & time.
+ * 2) use our engineid instead of the remote engineid for
+ * authoritative & privacy related operations.
+ * 3) The remote engine must be configured with users for our engineID.
+ *
+ * -- Wes
+ */
+
+ /*
+ * pick our own engineID
+ */
+ if (session.securityEngineIDLen == 0 ||
+ session.securityEngineID == NULL) {
+ session.securityEngineID =
+ snmpv3_generate_engineID(&session.securityEngineIDLen);
+ }
+
+ /*
+ * set boots and time, which will cause problems if this
+ * machine ever reboots and a remote trap receiver has cached our
+ * boots and time... I'll cause a not-in-time-window report to
+ * be sent back to this machine.
+ */
+ if (session.engineBoots == 0)
+ session.engineBoots = 1;
+ if (session.engineTime == 0) /* not really correct, */
+ session.engineTime = get_uptime(); /* but it'll work. Sort of. */
+ }
+
+ ss = snmp_add(&session,
+ netsnmp_transport_open_client("snmptrap", session.peername),
+ NULL, NULL);
+ if (ss == NULL) {
+ /*
+ * diagnose netsnmp_transport_open_client and snmp_add errors with
+ * the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmptrap", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (session.version == SNMP_VERSION_1) {
+ if (inform) {
+ fprintf(stderr, "Cannot send INFORM as SNMPv1 PDU\n");
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ pdu = snmp_pdu_create(SNMP_MSG_TRAP);
+ if ( !pdu ) {
+ fprintf(stderr, "Failed to create trap PDU\n");
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ pdu_in_addr_t = (in_addr_t *) pdu->agent_addr;
+ if (arg == argc) {
+ fprintf(stderr, "No enterprise oid\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (argv[arg][0] == 0) {
+ pdu->enterprise = (oid *) malloc(sizeof(objid_enterprise));
+ memcpy(pdu->enterprise, objid_enterprise,
+ sizeof(objid_enterprise));
+ pdu->enterprise_length =
+ sizeof(objid_enterprise) / sizeof(oid);
+ } else {
+ name_length = MAX_OID_LEN;
+ if (!snmp_parse_oid(argv[arg], name, &name_length)) {
+ snmp_perror(argv[arg]);
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ pdu->enterprise = (oid *) malloc(name_length * sizeof(oid));
+ memcpy(pdu->enterprise, name, name_length * sizeof(oid));
+ pdu->enterprise_length = name_length;
+ }
+ if (++arg >= argc) {
+ fprintf(stderr, "Missing agent parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ agent = argv[arg];
+ if (agent != NULL && strlen(agent) != 0) {
+ int ret = netsnmp_gethostbyname_v4(agent, pdu_in_addr_t);
+ if (ret < 0) {
+ fprintf(stderr, "unknown host: %s\n", agent);
+ exit(1);
+ }
+ } else {
+ *pdu_in_addr_t = get_myaddr();
+ }
+ if (++arg == argc) {
+ fprintf(stderr, "Missing generic-trap parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ trap = argv[arg];
+ pdu->trap_type = atoi(trap);
+ if (++arg == argc) {
+ fprintf(stderr, "Missing specific-trap parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ specific = argv[arg];
+ pdu->specific_type = atoi(specific);
+ if (++arg == argc) {
+ fprintf(stderr, "Missing uptime parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ description = argv[arg];
+ if (description == NULL || *description == 0)
+ pdu->time = get_uptime();
+ else
+ pdu->time = atol(description);
+ } else
+#endif
+ {
+ long sysuptime;
+ char csysuptime[20];
+
+ pdu = snmp_pdu_create(inform ? SNMP_MSG_INFORM : SNMP_MSG_TRAP2);
+ if ( !pdu ) {
+ fprintf(stderr, "Failed to create notification PDU\n");
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (arg == argc) {
+ fprintf(stderr, "Missing up-time parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ trap = argv[arg];
+ if (*trap == 0) {
+ sysuptime = get_uptime();
+ sprintf(csysuptime, "%ld", sysuptime);
+ trap = csysuptime;
+ }
+ snmp_add_var(pdu, objid_sysuptime,
+ sizeof(objid_sysuptime) / sizeof(oid), 't', trap);
+ if (++arg == argc) {
+ fprintf(stderr, "Missing trap-oid parameter\n");
+ usage();
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (snmp_add_var
+ (pdu, objid_snmptrap, sizeof(objid_snmptrap) / sizeof(oid),
+ 'o', argv[arg]) != 0) {
+ snmp_perror(argv[arg]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ }
+ arg++;
+
+ while (arg < argc) {
+ arg += 3;
+ if (arg > argc) {
+ fprintf(stderr, "%s: Missing type/value for variable\n",
+ argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ name_length = MAX_OID_LEN;
+ if (!snmp_parse_oid(argv[arg - 3], name, &name_length)) {
+ snmp_perror(argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ if (snmp_add_var
+ (pdu, name, name_length, argv[arg - 2][0],
+ argv[arg - 1]) != 0) {
+ snmp_perror(argv[arg - 3]);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+ }
+
+ if (inform)
+ status = snmp_synch_response(ss, pdu, &response);
+ else
+ status = snmp_send(ss, pdu) == 0;
+ if (status) {
+ snmp_sess_perror(inform ? "snmpinform" : "snmptrap", ss);
+ if (!inform)
+ snmp_free_pdu(pdu);
+ exitval = 1;
+ } else if (inform)
+ snmp_free_pdu(response);
+
+ snmp_close(ss);
+ snmp_shutdown("snmpapp");
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmptrapd.c b/apps/snmptrapd.c
new file mode 100644
index 0000000..1a52080
--- /dev/null
+++ b/apps/snmptrapd.c
@@ -0,0 +1,1464 @@
+/*
+ * snmptrapd.c - receive and log snmp traps
+ *
+ */
+/*****************************************************************
+ Copyright 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#if !defined(mingw32) && defined(HAVE_SYS_TIME_H)
+# include <sys/time.h>
+# if TIME_WITH_SYS_TIME
+# include <time.h>
+# endif
+#else
+# include <time.h>
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#if HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#if HAVE_PROCESS_H /* Win32-getpid */
+#include <process.h>
+#endif
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif
+#if HAVE_GRP_H
+#include <grp.h>
+#endif
+#include <signal.h>
+#include <errno.h>
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/library/fd_event_manager.h>
+#include "snmptrapd_handlers.h"
+#include "snmptrapd_log.h"
+#include "snmptrapd_auth.h"
+#include "notification-log-mib/notification_log.h"
+#include "tlstm-mib/snmpTlstmCertToTSNTable/snmpTlstmCertToTSNTable.h"
+#include "mibII/vacm_conf.h"
+#ifdef NETSNMP_EMBEDDED_PERL
+#include "snmp_perl.h"
+#endif
+
+/*
+ * Include winservice.h to support Windows Service
+ */
+#ifdef WIN32
+#include <windows.h>
+#include <tchar.h>
+#include <net-snmp/library/winservice.h>
+
+#define WIN32SERVICE
+
+#endif
+
+#if NETSNMP_USE_LIBWRAP
+#include <tcpd.h>
+#endif
+
+#include <net-snmp/net-snmp-features.h>
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+#ifndef FD_SET
+
+typedef long fd_mask;
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
+#endif
+
+char *logfile = NULL;
+extern int SyslogTrap;
+extern int dropauth;
+static int reconfig = 0;
+char ddefault_port[] = "udp:162"; /* Default default port */
+char *default_port = ddefault_port;
+#if HAVE_GETPID
+ FILE *PID;
+ char *pid_file = NULL;
+#endif
+extern void parse_format(const char *token, char *line);
+char *trap1_fmt_str_remember = NULL;
+int dofork = 1;
+
+extern int netsnmp_running;
+
+#ifdef NETSNMP_USE_MYSQL
+extern int netsnmp_mysql_init(void);
+extern void snmptrapd_register_sql_configs( void );
+#endif
+
+/*
+ * These definitions handle 4.2 systems without additional syslog facilities.
+ */
+#ifndef LOG_CONS
+#define LOG_CONS 0 /* Don't bother if not defined... */
+#endif
+#ifndef LOG_PID
+#define LOG_PID 0 /* Don't bother if not defined... */
+#endif
+#ifndef LOG_LOCAL0
+#define LOG_LOCAL0 0
+#endif
+#ifndef LOG_LOCAL1
+#define LOG_LOCAL1 0
+#endif
+#ifndef LOG_LOCAL2
+#define LOG_LOCAL2 0
+#endif
+#ifndef LOG_LOCAL3
+#define LOG_LOCAL3 0
+#endif
+#ifndef LOG_LOCAL4
+#define LOG_LOCAL4 0
+#endif
+#ifndef LOG_LOCAL5
+#define LOG_LOCAL5 0
+#endif
+#ifndef LOG_LOCAL6
+#define LOG_LOCAL6 0
+#endif
+#ifndef LOG_LOCAL7
+#define LOG_LOCAL7 0
+#endif
+#ifndef LOG_DAEMON
+#define LOG_DAEMON 0
+#endif
+
+/*
+ * Include an extra Facility variable to allow command line adjustment of
+ * syslog destination
+ */
+int Facility = LOG_DAEMON;
+
+#ifdef WIN32SERVICE
+/*
+ * SNMP Trap Receiver Status
+ */
+#define SNMPTRAPD_RUNNING 1
+#define SNMPTRAPD_STOPPED 0
+int trapd_status = SNMPTRAPD_STOPPED;
+/* app_name_long used for SCM, registry etc */
+LPCTSTR app_name_long = _T("Net-SNMP Trap Handler"); /* Application Name */
+#endif
+
+const char *app_name = "snmptrapd";
+
+void trapd_update_config(void);
+
+#ifdef WIN32SERVICE
+void StopSnmpTrapd(void);
+int SnmpTrapdMain(int argc, TCHAR * argv[]);
+int __cdecl _tmain(int argc, TCHAR * argv[]);
+#else
+int main(int, char **);
+#endif
+
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+extern void subagent_init(void);
+#endif
+
+
+void
+usage(void)
+{
+#ifdef WIN32SERVICE
+ fprintf(stderr, "\nUsage: snmptrapd [-register] [-quiet] [OPTIONS] [LISTENING ADDRESSES]");
+ fprintf(stderr, "\n snmptrapd [-unregister] [-quiet]");
+#else
+ fprintf(stderr, "Usage: snmptrapd [OPTIONS] [LISTENING ADDRESSES]\n");
+#endif
+ fprintf(stderr, "\n\tNET-SNMP Version: %s\n", netsnmp_get_version());
+ fprintf(stderr, "\tWeb: http://www.net-snmp.org/\n");
+ fprintf(stderr, "\tEmail: net-snmp-coders@lists.sourceforge.net\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, " -a\t\t\tignore authentication failure traps\n");
+ fprintf(stderr, " -A\t\t\tappend to log file rather than truncating it\n");
+ fprintf(stderr, " -c FILE\t\tread FILE as a configuration file\n");
+ fprintf(stderr,
+ " -C\t\t\tdo not read the default configuration files\n");
+ fprintf(stderr, " -d\t\t\tdump sent and received SNMP packets\n");
+ fprintf(stderr, " -D[TOKEN[,...]]\t\tturn on debugging output for the specified TOKENs\n\t\t\t (ALL gives extremely verbose debugging output)\n");
+ fprintf(stderr, " -f\t\t\tdo not fork from the shell\n");
+ fprintf(stderr,
+ " -F FORMAT\t\tuse specified format for logging to standard error\n");
+#if HAVE_UNISTD_H
+ fprintf(stderr, " -g GID\t\tchange to this numeric gid after opening\n"
+ "\t\t\t transport endpoints\n");
+#endif
+ fprintf(stderr, " -h, --help\t\tdisplay this usage message\n");
+ fprintf(stderr,
+ " -H\t\t\tdisplay configuration file directives understood\n");
+ fprintf(stderr,
+ " -m MIBLIST\t\tuse MIBLIST instead of the default MIB list\n");
+ fprintf(stderr,
+ " -M DIRLIST\t\tuse DIRLIST as the list of locations\n\t\t\t to look for MIBs\n");
+ fprintf(stderr,
+ " -n\t\t\tuse numeric addresses instead of attempting\n\t\t\t hostname lookups (no DNS)\n");
+#if HAVE_GETPID
+ fprintf(stderr, " -p FILE\t\tstore process id in FILE\n");
+#endif
+#ifdef WIN32SERVICE
+ fprintf(stderr, " -register\t\tregister as a Windows service\n");
+ fprintf(stderr, " \t\t\t (followed by -quiet to prevent message popups)\n");
+ fprintf(stderr, " \t\t\t (followed by the startup parameter list)\n");
+ fprintf(stderr, " \t\t\t Note that some parameters are not relevant when running as a service\n");
+#endif
+ fprintf(stderr, " -t\t\t\tPrevent traps from being logged to syslog\n");
+#if HAVE_UNISTD_H
+ fprintf(stderr, " -u UID\t\tchange to this uid (numeric or textual) after\n"
+ "\t\t\t opening transport endpoints\n");
+#endif
+#ifdef WIN32SERVICE
+ fprintf(stderr, " -unregister\t\tunregister as a Windows service\n");
+ fprintf(stderr, " \t\t\t (followed -quiet to prevent message popups)\n");
+#endif
+ fprintf(stderr, " -v, --version\t\tdisplay version information\n");
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+ fprintf(stderr, " -x ADDRESS\t\tuse ADDRESS as AgentX address\n");
+#endif
+ fprintf(stderr,
+ " -O <OUTOPTS>\t\ttoggle options controlling output display\n");
+ snmp_out_toggle_options_usage("\t\t\t", stderr);
+ fprintf(stderr,
+ " -L <LOGOPTS>\t\ttoggle options controlling where to log to\n");
+ snmp_log_options_usage("\t\t\t", stderr);
+}
+
+static void
+version(void)
+{
+ printf("\nNET-SNMP Version: %s\n", netsnmp_get_version());
+ printf("Web: http://www.net-snmp.org/\n");
+ printf("Email: net-snmp-coders@lists.sourceforge.net\n\n");
+ exit(0);
+}
+
+RETSIGTYPE
+term_handler(int sig)
+{
+#ifdef WIN32SERVICE
+ extern netsnmp_session *main_session;
+#endif
+ netsnmp_running = 0;
+
+#ifdef WIN32SERVICE
+ /*
+ * In case of windows, select() in receive() function will not return
+ * on signal. Thats why following function is called, which closes the
+ * socket descriptors and causes the select() to return
+ */
+ snmp_close(main_session);
+#endif
+}
+
+#ifdef SIGHUP
+RETSIGTYPE
+hup_handler(int sig)
+{
+ reconfig = 1;
+ signal(SIGHUP, hup_handler);
+}
+#endif
+
+static int
+pre_parse(netsnmp_session * session, netsnmp_transport *transport,
+ void *transport_data, int transport_data_length)
+{
+#if NETSNMP_USE_LIBWRAP
+ char *addr_string = NULL;
+
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ /*
+ * Okay I do know how to format this address for logging.
+ */
+ addr_string = transport->f_fmtaddr(transport, transport_data,
+ transport_data_length);
+ /*
+ * Don't forget to free() it.
+ */
+ }
+
+ if (addr_string != NULL) {
+ /* Catch udp,udp6,tcp,tcp6 transports using "[" */
+ char *tcpudpaddr = strstr(addr_string, "[");
+ if ( tcpudpaddr != 0 ) {
+ char sbuf[64];
+ char *xp;
+
+ strlcpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
+ xp = strstr(sbuf, "]");
+ if (xp)
+ *xp = '\0';
+
+ if (hosts_ctl("snmptrapd", STRING_UNKNOWN,
+ sbuf, STRING_UNKNOWN) == 0) {
+ DEBUGMSGTL(("snmptrapd:libwrap", "%s rejected", addr_string));
+ SNMP_FREE(addr_string);
+ return 0;
+ }
+ }
+ SNMP_FREE(addr_string);
+ } else {
+ if (hosts_ctl("snmptrapd", STRING_UNKNOWN,
+ STRING_UNKNOWN, STRING_UNKNOWN) == 0) {
+ DEBUGMSGTL(("snmptrapd:libwrap", "[unknown] rejected"));
+ return 0;
+ }
+ }
+#endif/* NETSNMP_USE_LIBWRAP */
+ return 1;
+}
+
+static netsnmp_session *
+snmptrapd_add_session(netsnmp_transport *t)
+{
+ netsnmp_session sess, *session = &sess, *rc = NULL;
+
+ snmp_sess_init(session);
+ session->peername = SNMP_DEFAULT_PEERNAME; /* Original code had NULL here */
+ session->version = SNMP_DEFAULT_VERSION;
+ session->community_len = SNMP_DEFAULT_COMMUNITY_LEN;
+ session->retries = SNMP_DEFAULT_RETRIES;
+ session->timeout = SNMP_DEFAULT_TIMEOUT;
+ session->callback = snmp_input;
+ session->callback_magic = (void *) t;
+ session->authenticator = NULL;
+ sess.isAuthoritative = SNMP_SESS_UNKNOWNAUTH;
+
+ rc = snmp_add(session, t, pre_parse, NULL);
+ if (rc == NULL) {
+ snmp_sess_perror("snmptrapd", session);
+ }
+ return rc;
+}
+
+static void
+snmptrapd_close_sessions(netsnmp_session * sess_list)
+{
+ netsnmp_session *s = NULL, *next = NULL;
+
+ for (s = sess_list; s != NULL; s = next) {
+ next = s->next;
+ snmp_close(s);
+ }
+}
+
+void
+parse_trapd_address(const char *token, char *cptr)
+{
+ char buf[BUFSIZ];
+ char *p;
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+
+ if (default_port == ddefault_port) {
+ default_port = strdup(buf);
+ } else {
+ p = malloc(strlen(buf) + 1 + strlen(default_port) + 1);
+ if (p) {
+ strcat(p, buf);
+ strcat(p, ",");
+ strcat(p, default_port );
+ }
+ free(default_port);
+ default_port = p;
+ }
+}
+
+void
+free_trapd_address(void)
+{
+ if (default_port != ddefault_port) {
+ free(default_port);
+ }
+}
+
+void
+parse_config_doNotLogTraps(const char *token, char *cptr)
+{
+ if (atoi(cptr) > 0)
+ SyslogTrap++;
+}
+
+void
+free_config_pidFile(void)
+{
+ if (pid_file)
+ free(pid_file);
+ pid_file = NULL;
+}
+
+void
+parse_config_pidFile(const char *token, char *cptr)
+{
+ free_config_pidFile();
+ pid_file = strdup (cptr);
+}
+
+#ifdef HAVE_UNISTD_H
+void
+parse_config_agentuser(const char *token, char *cptr)
+{
+ if (cptr[0] == '#') {
+ char *ecp;
+ int uid;
+
+ uid = strtoul(cptr + 1, &ecp, 10);
+ if (*ecp != 0) {
+ config_perror("Bad number");
+ } else {
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+ }
+#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+ } else {
+ struct passwd *info;
+
+ info = getpwnam(cptr);
+ if (info)
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, info->pw_uid);
+ else
+ config_perror("User not found in passwd database");
+ endpwent();
+#endif
+ }
+}
+
+void
+parse_config_agentgroup(const char *token, char *cptr)
+{
+ if (cptr[0] == '#') {
+ char *ecp;
+ int gid = strtoul(cptr + 1, &ecp, 10);
+
+ if (*ecp != 0) {
+ config_perror("Bad number");
+ } else {
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, gid);
+ }
+#if defined(HAVE_GETGRNAM) && defined(HAVE_GRP_H)
+ } else {
+ struct group *info;
+
+ info = getgrnam(cptr);
+ if (info)
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, info->gr_gid);
+ else
+ config_perror("Group not found in group database");
+ endgrent();
+#endif
+ }
+}
+#endif
+
+void
+parse_config_doNotFork(const char *token, char *cptr)
+{
+ if (netsnmp_ds_parse_boolean(cptr) == 1)
+ dofork = 0;
+}
+
+void
+parse_config_ignoreAuthFailure(const char *token, char *cptr)
+{
+ if (netsnmp_ds_parse_boolean(cptr) == 1)
+ dropauth = 1;
+}
+
+void
+parse_config_outputOption(const char *token, char *cptr)
+{
+ char *cp;
+
+ cp = snmp_out_toggle_options(cptr);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown output option passed to -O: %c\n",
+ *cp);
+ }
+}
+
+static void
+snmptrapd_main_loop(void)
+{
+ int count, numfds, block;
+ fd_set readfds,writefds,exceptfds;
+ struct timeval timeout, *tvp;
+
+ while (netsnmp_running) {
+ if (reconfig) {
+ /*
+ * If we are logging to a file, receipt of SIGHUP also
+ * indicates that the log file should be closed and
+ * re-opened. This is useful for users that want to
+ * rotate logs in a more predictable manner.
+ */
+ netsnmp_logging_restart();
+ snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
+ netsnmp_get_version());
+ trapd_update_config();
+ if (trap1_fmt_str_remember) {
+ parse_format( NULL, trap1_fmt_str_remember );
+ }
+ reconfig = 0;
+ }
+ numfds = 0;
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+ block = 0;
+ tvp = &timeout;
+ timerclear(tvp);
+ tvp->tv_sec = 5;
+ snmp_select_info(&numfds, &readfds, tvp, &block);
+ if (block == 1)
+ tvp = NULL; /* block without timeout */
+#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
+ netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
+#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
+ count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
+ if (count > 0) {
+#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
+ netsnmp_dispatch_external_events(&count, &readfds, &writefds,
+ &exceptfds);
+#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
+ /* If there are any more events after external events, then
+ * try SNMP events. */
+ if (count > 0) {
+ snmp_read(&readfds);
+ }
+ } else {
+ switch (count) {
+ case 0:
+ snmp_timeout();
+ break;
+ case -1:
+ if (errno == EINTR)
+ continue;
+ snmp_log_perror("select");
+ netsnmp_running = 0;
+ break;
+ default:
+ fprintf(stderr, "select returned %d\n", count);
+ netsnmp_running = 0;
+ }
+ }
+ run_alarms();
+ }
+}
+
+/*******************************************************************-o-******
+ * main - Non Windows
+ * SnmpTrapdMain - Windows to support windows service
+ *
+ * Parameters:
+ * argc
+ * *argv[]
+ *
+ * Returns:
+ * 0 Always succeeds. (?)
+ *
+ *
+ * Setup and start the trap receiver daemon.
+ *
+ * Also successfully EXITs with zero for some options.
+ */
+int
+#ifdef WIN32SERVICE
+SnmpTrapdMain(int argc, TCHAR * argv[])
+#else
+main(int argc, char *argv[])
+#endif
+{
+ char options[128] = "aAc:CdD::efF:g:hHI:L:m:M:no:O:PqsS:tu:vx:-:";
+ netsnmp_session *sess_list = NULL, *ss = NULL;
+ netsnmp_transport *transport = NULL;
+ int arg, i = 0;
+ int uid = 0, gid = 0;
+ char *cp, *listen_ports = NULL;
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+ int agentx_subagent = 1;
+#endif
+ netsnmp_trapd_handler *traph;
+
+
+#ifndef WIN32
+ /*
+ * close all non-standard file descriptors we may have
+ * inherited from the shell.
+ */
+ for (i = getdtablesize() - 1; i > 2; --i) {
+ (void) close(i);
+ }
+#endif /* #WIN32 */
+
+#ifdef SIGTERM
+ signal(SIGTERM, term_handler);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, SIG_IGN); /* do not terminate on early SIGHUP */
+#endif
+
+#ifdef SIGINT
+ signal(SIGINT, term_handler);
+#endif
+#ifdef SIGPIPE
+ signal(SIGPIPE, SIG_IGN); /* 'Inline' failure of wayward readers */
+#endif
+
+ /*
+ * register our configuration handlers now so -H properly displays them
+ */
+ snmptrapd_register_configs( );
+#ifdef NETSNMP_USE_MYSQL
+ snmptrapd_register_sql_configs( );
+#endif
+#ifdef NETSNMP_SECMOD_USM
+ init_usm_conf( "snmptrapd" );
+#endif /* NETSNMP_SECMOD_USM */
+ register_config_handler("snmptrapd", "snmpTrapdAddr",
+ parse_trapd_address, free_trapd_address, "string");
+
+ register_config_handler("snmptrapd", "doNotLogTraps",
+ parse_config_doNotLogTraps, NULL, "(1|yes|true|0|no|false)");
+#if HAVE_GETPID
+ register_config_handler("snmptrapd", "pidFile",
+ parse_config_pidFile, NULL, "string");
+#endif
+#ifdef HAVE_UNISTD_H
+ register_config_handler("snmptrapd", "agentuser",
+ parse_config_agentuser, NULL, "userid");
+ register_config_handler("snmptrapd", "agentgroup",
+ parse_config_agentgroup, NULL, "groupid");
+#endif
+
+ register_config_handler("snmptrapd", "doNotFork",
+ parse_config_doNotFork, NULL, "(1|yes|true|0|no|false)");
+
+ register_config_handler("snmptrapd", "ignoreAuthFailure",
+ parse_config_ignoreAuthFailure, NULL, "(1|yes|true|0|no|false)");
+
+ register_config_handler("snmptrapd", "outputOption",
+ parse_config_outputOption, NULL, "string");
+
+ /*
+ * Add some options if they are available.
+ */
+#if HAVE_GETPID
+ strcat(options, "p:");
+#endif
+
+#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
+#ifdef WIN32
+ snmp_log_syslogname(app_name_long);
+#else
+ snmp_log_syslogname(app_name);
+#endif
+#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
+
+ /*
+ * Now process options normally.
+ */
+
+ while ((arg = getopt(argc, argv, options)) != EOF) {
+ switch (arg) {
+ case '-':
+ if (strcasecmp(optarg, "help") == 0) {
+ usage();
+ exit(0);
+ }
+ if (strcasecmp(optarg, "version") == 0) {
+ version();
+ exit(0);
+ }
+
+ handle_long_opt(optarg);
+ break;
+
+ case 'a':
+ dropauth = 1;
+ break;
+
+ case 'A':
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_APPEND_LOGFILES, 1);
+ break;
+
+ case 'c':
+ if (optarg != NULL) {
+ netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OPTIONALCONFIG, optarg);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+
+ case 'C':
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DONT_READ_CONFIGS, 1);
+ break;
+
+ case 'd':
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_DUMP_PACKET, 1);
+ break;
+
+ case 'D':
+ debug_register_tokens(optarg);
+ snmp_set_do_debugging(1);
+ break;
+
+ case 'f':
+ dofork = 0;
+ break;
+
+ case 'F':
+ if (optarg != NULL) {
+ if (( strncmp( optarg, "print", 5 ) == 0 ) ||
+ ( strncmp( optarg, "syslog", 6 ) == 0 ) ||
+ ( strncmp( optarg, "execute", 7 ) == 0 )) {
+ /* New style: "type=format" */
+ trap1_fmt_str_remember = strdup(optarg);
+ cp = strchr( trap1_fmt_str_remember, '=' );
+ if (cp)
+ *cp = ' ';
+ } else {
+ /* Old style: implicitly "print=format" */
+ trap1_fmt_str_remember = malloc(strlen(optarg) + 7);
+ sprintf( trap1_fmt_str_remember, "print %s", optarg );
+ }
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+
+#if HAVE_UNISTD_H
+ case 'g':
+ if (optarg != NULL) {
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, gid = atoi(optarg));
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+#endif
+
+ case 'h':
+ usage();
+ exit(0);
+
+ case 'H':
+ init_agent("snmptrapd");
+#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
+ init_notification_log();
+#endif
+#ifdef NETSNMP_EMBEDDED_PERL
+ init_perl();
+#endif
+ init_snmp("snmptrapd");
+ fprintf(stderr, "Configuration directives understood:\n");
+ read_config_print_usage(" ");
+ exit(0);
+
+ case 'I':
+ if (optarg != NULL) {
+ add_to_init_list(optarg);
+ } else {
+ usage();
+ }
+ break;
+
+ case 'S':
+ fprintf(stderr,
+ "Warning: -S option has been withdrawn; use -Ls <facility> instead\n");
+ exit(1);
+ break;
+
+ case 'm':
+ if (optarg != NULL) {
+ setenv("MIBS", optarg, 1);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+
+ case 'M':
+ if (optarg != NULL) {
+ setenv("MIBDIRS", optarg, 1);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+
+ case 'n':
+ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NUMERIC_IP, 1);
+ break;
+
+ case 'o':
+ fprintf(stderr,
+ "Warning: -o option has been withdrawn; use -Lf <file> instead\n");
+ exit(1);
+ break;
+
+ case 'O':
+ cp = snmp_out_toggle_options(optarg);
+ if (cp != NULL) {
+ fprintf(stderr, "Unknown output option passed to -O: %c\n",
+ *cp);
+ usage();
+ exit(1);
+ }
+ break;
+
+ case 'L':
+ if (snmp_log_options( optarg, argc, argv ) < 0 ) {
+ usage();
+ exit(1);
+ }
+ break;
+
+#if HAVE_GETPID
+ case 'p':
+ if (optarg != NULL) {
+ parse_config_pidFile(NULL, optarg);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+#endif
+
+ case 'P':
+ fprintf(stderr,
+ "Warning: -P option has been withdrawn; use -f -Le instead\n");
+ exit(1);
+ break;
+
+ case 's':
+ fprintf(stderr,
+ "Warning: -s option has been withdrawn; use -Lsd instead\n");
+ exit(1);
+ break;
+
+ case 't':
+ SyslogTrap++;
+ break;
+
+#if HAVE_UNISTD_H
+ case 'u':
+ if (optarg != NULL) {
+ char *ecp;
+
+ uid = strtoul(optarg, &ecp, 10);
+#if HAVE_GETPWNAM && HAVE_PWD_H
+ if (*ecp) {
+ struct passwd *info;
+
+ info = getpwnam(optarg);
+ uid = info ? info->pw_uid : -1;
+ endpwent();
+ }
+#endif
+ if (uid < 0) {
+ fprintf(stderr, "Bad user id: %s\n", optarg);
+ exit(1);
+ }
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+#endif
+
+ case 'v':
+ version();
+ exit(0);
+ break;
+
+ case 'x':
+ if (optarg != NULL) {
+ netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_X_SOCKET, optarg);
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "invalid option: -%c\n", arg);
+ usage();
+ exit(1);
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ /*
+ * There are optional transport addresses on the command line.
+ */
+ for (i = optind; i < argc; i++) {
+ char *astring;
+ if (listen_ports != NULL) {
+ astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
+ if (astring == NULL) {
+ fprintf(stderr, "malloc failure processing argv[%d]\n", i);
+ exit(1);
+ }
+ sprintf(astring, "%s,%s", listen_ports, argv[i]);
+ free(listen_ports);
+ listen_ports = astring;
+ } else {
+ listen_ports = strdup(argv[i]);
+ if (listen_ports == NULL) {
+ fprintf(stderr, "malloc failure processing argv[%d]\n", i);
+ exit(1);
+ }
+ }
+ }
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * I'm being lazy here, and not checking the
+ * return value from these registration calls.
+ * Don't try this at home, children!
+ */
+ if (0 == snmp_get_do_logging()) {
+#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
+ syslog_handler);
+ traph->authtypes = TRAP_AUTH_LOG;
+ snmp_enable_syslog();
+#else /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
+#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
+ print_handler);
+ traph->authtypes = TRAP_AUTH_LOG;
+ snmp_enable_stderr();
+#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */
+#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
+ } else {
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
+ print_handler);
+ traph->authtypes = TRAP_AUTH_LOG;
+ }
+
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+ /*
+ * we're an agentx subagent?
+ */
+ if (agentx_subagent) {
+ /*
+ * make us a agentx client.
+ */
+ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_ROLE, 1);
+ }
+#endif
+
+ /*
+ * don't fail if we can't do agentx (ie, socket not there, or not root)
+ */
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_ROOT_ACCESS);
+ /*
+ * ignore any warning messages.
+ */
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS);
+
+ /*
+ * initialize the agent library
+ */
+ init_agent("snmptrapd");
+
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+#ifdef NETSNMP_FEATURE_CHECKING
+ netsnmp_feature_require(register_snmpEngine_scalars_context)
+#endif /* NETSNMP_FEATURE_CHECKING */
+ /*
+ * initialize local modules
+ */
+ if (agentx_subagent) {
+#ifdef USING_SNMPV3_SNMPENGINE_MODULE
+ extern void register_snmpEngine_scalars_context(const char *);
+#endif
+ subagent_init();
+#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
+ /* register the notification log table */
+ if (should_init("notificationLogMib")) {
+ netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_NOTIF_LOG_CTX,
+ "snmptrapd");
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_POST_HANDLER,
+ notification_handler);
+ traph->authtypes = TRAP_AUTH_LOG;
+ init_notification_log();
+ }
+#endif
+#ifdef USING_SNMPV3_SNMPENGINE_MODULE
+ /*
+ * register scalars from SNMP-FRAMEWORK-MIB::snmpEngineID group;
+ * allows engineID probes via the master agent under the
+ * snmptrapd context
+ */
+ register_snmpEngine_scalars_context("snmptrapd");
+#endif
+ }
+#endif /* USING_AGENTX_SUBAGENT_MODULE && !NETSNMP_SNMPTRAPD_DISABLE_AGENTX */
+
+ /* register our authorization handler */
+ init_netsnmp_trapd_auth();
+
+#if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+ if (agentx_subagent) {
+#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
+ extern void init_register_nsVacm_context(const char *);
+#endif
+#ifdef USING_SNMPV3_USMUSER_MODULE
+#ifdef NETSNMP_FEATURE_CHECKING
+ netsnmp_feature_require(init_register_usmUser_context)
+#endif /* NETSNMP_FEATURE_CHECKING */
+ extern void init_register_usmUser_context(const char *);
+ /* register ourselves as having a USM user database */
+ init_register_usmUser_context("snmptrapd");
+#endif
+#ifdef USING_AGENT_NSVACMACCESSTABLE_MODULE
+ /* register net-snmp vacm extensions */
+ init_register_nsVacm_context("snmptrapd");
+#endif
+#ifdef USING_TLSTM_MIB_SNMPTLSTMCERTTOTSNTABLE_MODULE
+ init_snmpTlstmCertToTSNTable_context("snmptrapd");
+#endif
+ }
+#endif
+
+#ifdef NETSNMP_EMBEDDED_PERL
+ init_perl();
+ {
+ /* set the default path to load */
+ char init_file[SNMP_MAXBUF];
+ snprintf(init_file, sizeof(init_file) - 1,
+ "%s/%s", SNMPSHAREPATH, "snmp_perl_trapd.pl");
+ netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_PERL_INIT_FILE,
+ init_file);
+ }
+#endif
+
+ /*
+ * Initialize the world.
+ */
+ init_snmp("snmptrapd");
+
+#ifdef SIGHUP
+ signal(SIGHUP, hup_handler);
+#endif
+
+ if (trap1_fmt_str_remember) {
+ parse_format( NULL, trap1_fmt_str_remember );
+ }
+
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_QUIT_IMMEDIATELY)) {
+ /*
+ * just starting up to process specific configuration and then
+ * shutting down immediately.
+ */
+ netsnmp_running = 0;
+ }
+
+ /*
+ * if no logging options on command line or in conf files, use syslog
+ */
+ if (0 == snmp_get_do_logging()) {
+#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
+#ifdef WIN32
+ snmp_enable_syslog_ident(app_name_long, Facility);
+#else
+ snmp_enable_syslog_ident(app_name, Facility);
+#endif
+#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */
+ }
+
+ if (listen_ports)
+ cp = listen_ports;
+ else
+ cp = default_port;
+
+ while (cp != NULL) {
+ char *sep = strchr(cp, ',');
+
+ if (sep != NULL) {
+ *sep = 0;
+ }
+
+ transport = netsnmp_transport_open_server("snmptrap", cp);
+ if (transport == NULL) {
+ snmp_log(LOG_ERR, "couldn't open %s -- errno %d (\"%s\")\n",
+ cp, errno, strerror(errno));
+ snmptrapd_close_sessions(sess_list);
+ SOCK_CLEANUP;
+ exit(1);
+ } else {
+ ss = snmptrapd_add_session(transport);
+ if (ss == NULL) {
+ /*
+ * Shouldn't happen? We have already opened the transport
+ * successfully so what could have gone wrong?
+ */
+ snmptrapd_close_sessions(sess_list);
+ netsnmp_transport_free(transport);
+ snmp_log(LOG_ERR, "couldn't open snmp - %s", strerror(errno));
+ SOCK_CLEANUP;
+ exit(1);
+ } else {
+ ss->next = sess_list;
+ sess_list = ss;
+ }
+ }
+
+ /*
+ * Process next listen address, if there is one.
+ */
+
+ if (sep != NULL) {
+ *sep = ',';
+ cp = sep + 1;
+ } else {
+ cp = NULL;
+ }
+ }
+ SNMP_FREE(listen_ports); /* done with them */
+
+#ifdef NETSNMP_USE_MYSQL
+ if( netsnmp_mysql_init() ) {
+ fprintf(stderr, "MySQL initialization failed\n");
+ exit(1);
+ }
+#endif
+
+#ifndef WIN32
+ /*
+ * fork the process to the background if we are not printing to stderr
+ */
+ if (dofork && netsnmp_running) {
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ fprintf(stderr, "bad fork - %s\n", strerror(errno));
+ _exit(1);
+
+ case 0:
+ /*
+ * become process group leader
+ */
+ if (setsid() == -1) {
+ fprintf(stderr, "bad setsid - %s\n", strerror(errno));
+ _exit(1);
+ }
+
+ /*
+ * if we are forked, we don't want to print out to stdout or stderr
+ */
+ fd = open("/dev/null", O_RDWR);
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ close(fd);
+ break;
+
+ default:
+ _exit(0);
+ }
+ }
+#endif /* WIN32 */
+#if HAVE_GETPID
+ if (pid_file != NULL) {
+ if ((PID = fopen(pid_file, "w")) == NULL) {
+ snmp_log_perror("fopen");
+ exit(1);
+ }
+ fprintf(PID, "%d\n", (int) getpid());
+ fclose(PID);
+ free_config_pidFile();
+ }
+#endif
+
+ snmp_log(LOG_INFO, "NET-SNMP version %s\n", netsnmp_get_version());
+
+ /*
+ * ignore early sighup during startup
+ */
+ reconfig = 0;
+
+#if HAVE_UNISTD_H
+#ifdef HAVE_SETGID
+ if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID)) != 0) {
+ DEBUGMSGTL(("snmptrapd/main", "Changing gid to %d.\n", gid));
+ if (setgid(gid) == -1
+#ifdef HAVE_SETGROUPS
+ || setgroups(1, (gid_t *)&gid) == -1
+#endif
+ ) {
+ snmp_log_perror("setgid failed");
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
+ exit(1);
+ }
+ }
+ }
+#endif
+#ifdef HAVE_SETUID
+ if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID)) != 0) {
+ DEBUGMSGTL(("snmptrapd/main", "Changing uid to %d.\n", uid));
+ if (setuid(uid) == -1) {
+ snmp_log_perror("setuid failed");
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
+ exit(1);
+ }
+ }
+ }
+#endif
+#endif
+
+#ifdef WIN32SERVICE
+ trapd_status = SNMPTRAPD_RUNNING;
+#endif
+
+ snmptrapd_main_loop();
+
+ if (snmp_get_do_logging()) {
+ struct tm *tm;
+ time_t timer;
+ time(&timer);
+ tm = localtime(&timer);
+ snmp_log(LOG_INFO,
+ "%.4d-%.2d-%.2d %.2d:%.2d:%.2d NET-SNMP version %s Stopped.\n",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
+ tm->tm_min, tm->tm_sec, netsnmp_get_version());
+ }
+ snmp_log(LOG_INFO, "Stopping snmptrapd\n");
+
+#ifdef NETSNMP_EMBEDDED_PERL
+ shutdown_perl();
+#endif
+ snmptrapd_close_sessions(sess_list);
+ snmp_shutdown("snmptrapd");
+#ifdef WIN32SERVICE
+ trapd_status = SNMPTRAPD_STOPPED;
+#endif
+ snmp_disable_log();
+ SOCK_CLEANUP;
+ return 0;
+}
+
+/*
+ * Read the configuration files. Implemented as a signal handler so that
+ * receipt of SIGHUP will cause configuration to be re-read when the
+ * trap daemon is running detatched from the console.
+ *
+ */
+void
+trapd_update_config(void)
+{
+ free_config();
+#ifdef USING_MIBII_VACM_CONF_MODULE
+ vacm_standard_views(0,0,NULL,NULL);
+#endif
+ read_configs();
+}
+
+
+#if !defined(HAVE_GETDTABLESIZE) && !defined(WIN32)
+#include <sys/resource.h>
+int
+getdtablesize(void)
+{
+ struct rlimit rl;
+ getrlimit(RLIMIT_NOFILE, &rl);
+ return (rl.rlim_cur);
+}
+#endif
+
+/*
+ * Windows Service Related functions
+ */
+#ifdef WIN32SERVICE
+/************************************************************
+* main function for Windows
+* Parse command line arguments for startup options,
+* to start as service or console mode application in windows.
+* Invokes appropriate startup functions depending on the
+* parameters passed
+*************************************************************/
+int
+ __cdecl
+_tmain(int argc, TCHAR * argv[])
+{
+ /*
+ * Define Service Name and Description, which appears in windows SCM
+ */
+ LPCTSTR lpszServiceName = app_name_long; /* Service Registry Name */
+ LPCTSTR lpszServiceDisplayName = _T("Net-SNMP Trap Handler"); /* Display Name */
+ LPCTSTR lpszServiceDescription =
+#ifdef IFDESCR
+ _T("SNMPv2c / SNMPv3 trap/inform receiver from Net-SNMP. Supports MIB objects for IP,ICMP,TCP,UDP, and network interface sub-layers.");
+#else
+ _T("SNMPv2c / SNMPv3 trap/inform receiver from Net-SNMP");
+#endif
+ InputParams InputOptions;
+
+ int nRunType = RUN_AS_CONSOLE;
+ int quiet = 0;
+
+ nRunType = ParseCmdLineForServiceOption(argc, argv, &quiet);
+
+ switch (nRunType) {
+ case REGISTER_SERVICE:
+ /*
+ * Register As service
+ */
+ InputOptions.Argc = argc;
+ InputOptions.Argv = argv;
+ exit (RegisterService(lpszServiceName,
+ lpszServiceDisplayName,
+ lpszServiceDescription, &InputOptions, quiet));
+ break;
+ case UN_REGISTER_SERVICE:
+ /*
+ * Unregister service
+ */
+ exit (UnregisterService(lpszServiceName, quiet));
+ exit(0);
+ break;
+ case RUN_AS_SERVICE:
+ /*
+ * Run as service
+ */
+ /*
+ * Register Stop Function
+ */
+ RegisterStopFunction(StopSnmpTrapd);
+ return RunAsService(SnmpTrapdMain);
+ break;
+ default:
+ /*
+ * Run in console mode
+ */
+ return SnmpTrapdMain(argc, argv);
+ break;
+ }
+}
+
+/*
+ * To stop Snmp Trap Receiver daemon
+ * This portion is still not working
+ */
+void
+StopSnmpTrapd(void)
+{
+ /*
+ * Shut Down Service
+ */
+ term_handler(1);
+
+ /*
+ * Wait till trap receiver is completely stopped
+ */
+
+ while (trapd_status != SNMPTRAPD_STOPPED) {
+ Sleep(100);
+ }
+}
+
+#endif /*WIN32SERVICE*/
diff --git a/apps/snmptrapd_auth.c b/apps/snmptrapd_auth.c
new file mode 100644
index 0000000..be21e5e
--- /dev/null
+++ b/apps/snmptrapd_auth.c
@@ -0,0 +1,182 @@
+/*
+ * snmptrapd_auth.c - authorize notifications for further processing
+ *
+ */
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include "snmptrapd_handlers.h"
+#include "snmptrapd_auth.h"
+#include "snmptrapd_ds.h"
+
+#include <net-snmp/agent/agent_module_config.h>
+#include <net-snmp/agent/mib_module_config.h>
+
+#ifdef USING_MIBII_VACM_CONF_MODULE
+#include "mibII/vacm_conf.h"
+#endif
+
+#include <net-snmp/agent/agent_trap.h>
+
+/**
+ * initializes the snmptrapd authorization code registering needed
+ * handlers and config parsers.
+ */
+void
+init_netsnmp_trapd_auth(void)
+{
+ /* register our function as a authorization handler */
+ netsnmp_trapd_handler *traph;
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_AUTH_HANDLER,
+ netsnmp_trapd_auth);
+ traph->authtypes = TRAP_AUTH_NONE;
+
+#ifdef USING_MIBII_VACM_CONF_MODULE
+ /* register our configuration tokens for VACM configs */
+ init_vacm_config_tokens();
+#endif
+
+ /* register a config token for turning off the authorization entirely */
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmptrapd", "disableAuthorization",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NO_AUTHORIZATION);
+}
+
+/* XXX: store somewhere in the PDU instead */
+static int lastlookup;
+
+/**
+ * Authorizes incoming notifications for further processing
+ */
+int
+netsnmp_trapd_auth(netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ int ret = 0;
+ oid snmptrapoid[] = { 1,3,6,1,6,3,1,1,4,1,0 };
+ size_t snmptrapoid_len = OID_LENGTH(snmptrapoid);
+ int i;
+ netsnmp_pdu *newpdu = pdu;
+ netsnmp_variable_list *var;
+
+ /* check to see if authorization was not disabled */
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NO_AUTHORIZATION)) {
+ DEBUGMSGTL(("snmptrapd:auth",
+ "authorization turned off: not checking\n"));
+ return NETSNMPTRAPD_HANDLER_OK;
+ }
+
+ /* bail early if called illegally */
+ if (!pdu || !transport || !handler)
+ return NETSNMPTRAPD_HANDLER_FINISH;
+
+ /* convert to v2 so we can check it in a consistent manner */
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (pdu->version == SNMP_VERSION_1) {
+ newpdu = convert_v1pdu_to_v2(pdu);
+ if (!newpdu) {
+ snmp_log(LOG_ERR, "Failed to duplicate incoming PDU. Refusing to authorize.\n");
+ return NETSNMPTRAPD_HANDLER_FINISH;
+ }
+ }
+#endif
+
+ if (!vacm_is_configured()) {
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (newpdu != pdu)
+ snmp_free_pdu(newpdu);
+#endif
+ snmp_log(LOG_WARNING, "No access configuration - dropping trap.\n");
+ return NETSNMPTRAPD_HANDLER_FINISH;
+ }
+
+ /* loop through each variable and find the snmpTrapOID.0 var
+ indicating what the trap is we're staring at. */
+ for (var = newpdu->variables; var != NULL; var = var->next_variable) {
+ if (netsnmp_oid_equals(var->name, var->name_length,
+ snmptrapoid, snmptrapoid_len) == 0)
+ break;
+ }
+
+ /* make sure we can continue: we found the snmpTrapOID.0 and its an oid */
+ if (!var || var->type != ASN_OBJECT_ID) {
+ snmp_log(LOG_ERR, "Can't determine trap identifier; refusing to authorize it\n");
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (newpdu != pdu)
+ snmp_free_pdu(newpdu);
+#endif
+ return NETSNMPTRAPD_HANDLER_FINISH;
+ }
+
+#ifdef USING_MIBII_VACM_CONF_MODULE
+ /* check the pdu against each typo of VACM access we may want to
+ check up on later. We cache the results for future lookup on
+ each call to netsnmp_trapd_check_auth */
+ for(i = 0; i < VACM_MAX_VIEWS; i++) {
+ /* pass the PDU to the VACM routine for handling authorization */
+ DEBUGMSGTL(("snmptrapd:auth", "Calling VACM for checking phase %d:%s\n",
+ i, se_find_label_in_slist(VACM_VIEW_ENUM_NAME, i)));
+ if (vacm_check_view_contents(newpdu, var->val.objid,
+ var->val_len/sizeof(oid), 0, i,
+ VACM_CHECK_VIEW_CONTENTS_DNE_CONTEXT_OK)
+ == VACM_SUCCESS) {
+ DEBUGMSGTL(("snmptrapd:auth", " result: authorized\n"));
+ ret |= 1 << i;
+ } else {
+ DEBUGMSGTL(("snmptrapd:auth", " result: not authorized\n"));
+ }
+ }
+ DEBUGMSGTL(("snmptrapd:auth", "Final bitmask auth: %x\n", ret));
+#endif
+
+ if (ret) {
+ /* we have policy to at least do "something". Remember and continue. */
+ lastlookup = ret;
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (newpdu != pdu)
+ snmp_free_pdu(newpdu);
+#endif
+ return NETSNMPTRAPD_HANDLER_OK;
+ }
+
+ /* No policy was met, so we drop the PDU from further processing */
+ DEBUGMSGTL(("snmptrapd:auth", "Dropping unauthorized message\n"));
+#ifndef NETSNMP_DISABLE_SNMPV1
+ if (newpdu != pdu)
+ snmp_free_pdu(newpdu);
+#endif
+ return NETSNMPTRAPD_HANDLER_FINISH;
+}
+
+/**
+ * Checks to see if the pdu is authorized for a set of given action types.
+ * @returns 1 if authorized, 0 if not.
+ */
+int
+netsnmp_trapd_check_auth(int authtypes)
+{
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NO_AUTHORIZATION)) {
+ DEBUGMSGTL(("snmptrapd:auth", "authorization turned off\n"));
+ return 1;
+ }
+
+ DEBUGMSGTL(("snmptrapd:auth",
+ "Comparing auth types: result=%d, request=%d, result=%d\n",
+ lastlookup, authtypes,
+ ((authtypes & lastlookup) == authtypes)));
+ return ((authtypes & lastlookup) == authtypes);
+}
+
diff --git a/apps/snmptrapd_auth.h b/apps/snmptrapd_auth.h
new file mode 100644
index 0000000..07427b2
--- /dev/null
+++ b/apps/snmptrapd_auth.h
@@ -0,0 +1,16 @@
+#ifndef SNMPTRAPD_AUTH_H
+#define SNMPTRAPD_AUTH_H
+
+void init_netsnmp_trapd_auth(void);
+int netsnmp_trapd_auth(netsnmp_pdu *pdu, netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler);
+int netsnmp_trapd_check_auth(int authtypes);
+
+#define TRAP_AUTH_LOG (1 << VACM_VIEW_LOG) /* displaying and logging */
+#define TRAP_AUTH_EXE (1 << VACM_VIEW_EXECUTE) /* executing code or binaries */
+#define TRAP_AUTH_NET (1 << VACM_VIEW_NET) /* forwarding and net access */
+
+#define TRAP_AUTH_ALL (TRAP_AUTH_LOG | TRAP_AUTH_EXE | TRAP_AUTH_NET)
+#define TRAP_AUTH_NONE 0
+
+#endif /* SNMPTRAPD_AUTH_H */
diff --git a/apps/snmptrapd_ds.h b/apps/snmptrapd_ds.h
new file mode 100644
index 0000000..03eba14
--- /dev/null
+++ b/apps/snmptrapd_ds.h
@@ -0,0 +1,19 @@
+#ifndef SNMPTRAPD_DS_H
+#define SNMPTRAPD_DS_H
+
+/* booleans
+ *
+ * WARNING: These must not conflict with the agent's DS booleans
+ * If you define additional entries here, check in <agent/ds_agent.h> first
+ * (and consider repeating the definitions there) */
+
+#define NETSNMP_DS_APP_NUMERIC_IP 16
+#define NETSNMP_DS_APP_NO_AUTHORIZATION 17
+
+/*
+ * NB: The NETSNMP_DS_APP_NO_AUTHORIZATION definition is repeated
+ * in the code file agent/mibgroup/mibII/vacm_conf.c
+ * If this definition is changed, it should be updated there too.
+ */
+
+#endif /* SNMPTRAPD_DS_H */
diff --git a/apps/snmptrapd_handlers.c b/apps/snmptrapd_handlers.c
new file mode 100644
index 0000000..5a8e3c8
--- /dev/null
+++ b/apps/snmptrapd_handlers.c
@@ -0,0 +1,1109 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include <net-snmp/config_api.h>
+#include <net-snmp/output_api.h>
+#include <net-snmp/mib_api.h>
+#include <net-snmp/utilities.h>
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "utilities/execute.h"
+#include "snmptrapd_handlers.h"
+#include "snmptrapd_auth.h"
+#include "snmptrapd_log.h"
+#include "notification-log-mib/notification_log.h"
+
+netsnmp_feature_child_of(add_default_traphandler, snmptrapd)
+
+char *syslog_format1 = NULL;
+char *syslog_format2 = NULL;
+char *print_format1 = NULL;
+char *print_format2 = NULL;
+char *exec_format1 = NULL;
+char *exec_format2 = NULL;
+
+int SyslogTrap = 0;
+int dropauth = 0;
+
+const char *trap1_std_str = "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b] (via %A [%a]): %N\n\t%W Trap (%q) Uptime: %#T\n%v\n";
+const char *trap2_std_str = "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b]:\n%v\n";
+
+void snmptrapd_free_traphandle(void);
+
+const char *
+trap_description(int trap)
+{
+ switch (trap) {
+ case SNMP_TRAP_COLDSTART:
+ return "Cold Start";
+ case SNMP_TRAP_WARMSTART:
+ return "Warm Start";
+ case SNMP_TRAP_LINKDOWN:
+ return "Link Down";
+ case SNMP_TRAP_LINKUP:
+ return "Link Up";
+ case SNMP_TRAP_AUTHFAIL:
+ return "Authentication Failure";
+ case SNMP_TRAP_EGPNEIGHBORLOSS:
+ return "EGP Neighbor Loss";
+ case SNMP_TRAP_ENTERPRISESPECIFIC:
+ return "Enterprise Specific";
+ default:
+ return "Unknown Type";
+ }
+}
+
+
+
+void
+snmptrapd_parse_traphandle(const char *token, char *line)
+{
+ char buf[STRINGMAX];
+ oid obuf[MAX_OID_LEN];
+ size_t olen = MAX_OID_LEN;
+ char *cptr, *cp;
+ netsnmp_trapd_handler *traph;
+ int flags = 0;
+ char *format = NULL;
+
+ memset( buf, 0, sizeof(buf));
+ memset(obuf, 0, sizeof(obuf));
+ cptr = copy_nword(line, buf, sizeof(buf));
+
+ if ( buf[0] == '-' && buf[1] == 'F' ) {
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+ format = strdup( buf );
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+ }
+ if ( !cptr ) {
+ netsnmp_config_error("Missing traphandle command (%s)", buf);
+ return;
+ }
+
+ DEBUGMSGTL(("read_config:traphandle", "registering handler for: "));
+ if (!strcmp(buf, "default")) {
+ DEBUGMSG(("read_config:traphandle", "default"));
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
+ command_handler );
+ } else {
+ cp = buf+strlen(buf)-1;
+ if ( *cp == '*' ) {
+ flags |= NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE;
+ *(cp--) = '\0';
+ if ( *cp == '.' ) {
+ /*
+ * Distinguish between 'oid.*' & 'oid*'
+ */
+ flags |= NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE;
+ *(cp--) = '\0';
+ }
+ }
+ if (!read_objid(buf, obuf, &olen)) {
+ netsnmp_config_error("Bad trap OID in traphandle directive: %s",
+ buf);
+ return;
+ }
+ DEBUGMSGOID(("read_config:traphandle", obuf, olen));
+ traph = netsnmp_add_traphandler( command_handler, obuf, olen );
+ }
+
+ DEBUGMSG(("read_config:traphandle", "\n"));
+
+ if (traph) {
+ traph->flags = flags;
+ traph->authtypes = TRAP_AUTH_EXE;
+ traph->token = strdup(cptr);
+ if (format)
+ traph->format = format;
+ }
+}
+
+
+static void
+parse_forward(const char *token, char *line)
+{
+ char buf[STRINGMAX];
+ oid obuf[MAX_OID_LEN];
+ size_t olen = MAX_OID_LEN;
+ char *cptr, *cp;
+ netsnmp_trapd_handler *traph;
+ int flags = 0;
+ char *format = NULL;
+
+ memset( buf, 0, sizeof(buf));
+ memset(obuf, 0, sizeof(obuf));
+ cptr = copy_nword(line, buf, sizeof(buf));
+
+ if ( buf[0] == '-' && buf[1] == 'F' ) {
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+ format = strdup( buf );
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+ }
+ DEBUGMSGTL(("read_config:forward", "registering forward for: "));
+ if (!strcmp(buf, "default")) {
+ DEBUGMSG(("read_config:forward", "default"));
+ if ( !strcmp( cptr, "agentx" ))
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
+ axforward_handler );
+ else
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
+ forward_handler );
+ } else {
+ cp = buf+strlen(buf)-1;
+ if ( *cp == '*' ) {
+ flags |= NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE;
+ *(cp--) = '\0';
+ if ( *cp == '.' ) {
+ /*
+ * Distinguish between 'oid.*' & 'oid*'
+ */
+ flags |= NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE;
+ *(cp--) = '\0';
+ }
+ }
+
+ if (!read_objid(buf, obuf, &olen)) {
+ netsnmp_config_error("Bad trap OID in forward directive: %s", buf);
+ return;
+ }
+ DEBUGMSGOID(("read_config:forward", obuf, olen));
+ if ( !strcmp( cptr, "agentx" ))
+ traph = netsnmp_add_traphandler( axforward_handler, obuf, olen );
+ else
+ traph = netsnmp_add_traphandler( forward_handler, obuf, olen );
+ }
+
+ DEBUGMSG(("read_config:forward", "\n"));
+
+ if (traph) {
+ traph->flags = flags;
+ traph->authtypes = TRAP_AUTH_NET;
+ traph->token = strdup(cptr);
+ if (format)
+ traph->format = format;
+ }
+}
+
+
+void
+parse_format(const char *token, char *line)
+{
+ char *cp, *sep;
+
+ /*
+ * Extract the first token from the value
+ * which tells us which style of format this is
+ */
+ cp = line;
+ while (*cp && !isspace((unsigned char)(*cp)))
+ cp++;
+ if (!(*cp)) {
+ /*
+ * If we haven't got anything left,
+ * then this entry is malformed.
+ * So report this, and give up
+ */
+ return;
+ }
+
+ sep = cp;
+ *(cp++) = '\0';
+ while (*cp && isspace((unsigned char)(*cp)))
+ cp++;
+
+ /*
+ * OK - now "line" contains the format type,
+ * and cp points to the actual format string.
+ * So update the appropriate pointer(s).
+ */
+ if (!strcmp( line, "print1")) {
+ SNMP_FREE( print_format1 );
+ print_format1 = strdup(cp);
+ } else if (!strcmp( line, "print2")) {
+ SNMP_FREE( print_format2 );
+ print_format2 = strdup(cp);
+ } else if (!strcmp( line, "print")) {
+ SNMP_FREE( print_format1 );
+ SNMP_FREE( print_format2 );
+ print_format1 = strdup(cp);
+ print_format2 = strdup(cp);
+ } else if (!strcmp( line, "syslog1")) {
+ SNMP_FREE( syslog_format1 );
+ syslog_format1 = strdup(cp);
+ } else if (!strcmp( line, "syslog2")) {
+ SNMP_FREE( syslog_format2 );
+ syslog_format2 = strdup(cp);
+ } else if (!strcmp( line, "syslog")) {
+ SNMP_FREE( syslog_format1 );
+ SNMP_FREE( syslog_format2 );
+ syslog_format1 = strdup(cp);
+ syslog_format2 = strdup(cp);
+ } else if (!strcmp( line, "execute1")) {
+ SNMP_FREE( exec_format1 );
+ exec_format1 = strdup(cp);
+ } else if (!strcmp( line, "execute2")) {
+ SNMP_FREE( exec_format2 );
+ exec_format2 = strdup(cp);
+ } else if (!strcmp( line, "execute")) {
+ SNMP_FREE( exec_format1 );
+ SNMP_FREE( exec_format2 );
+ exec_format1 = strdup(cp);
+ exec_format2 = strdup(cp);
+ }
+
+ *sep = ' ';
+}
+
+
+static void
+parse_trap1_fmt(const char *token, char *line)
+{
+ print_format1 = strdup(line);
+}
+
+
+void
+free_trap1_fmt(void)
+{
+ if (print_format1 && print_format1 != trap1_std_str)
+ free((char *) print_format1);
+ print_format1 = NULL;
+}
+
+
+static void
+parse_trap2_fmt(const char *token, char *line)
+{
+ print_format2 = strdup(line);
+}
+
+
+void
+free_trap2_fmt(void)
+{
+ if (print_format2 && print_format2 != trap2_std_str)
+ free((char *) print_format2);
+ print_format2 = NULL;
+}
+
+
+void
+snmptrapd_register_configs( void )
+{
+ register_config_handler("snmptrapd", "traphandle",
+ snmptrapd_parse_traphandle,
+ snmptrapd_free_traphandle,
+ "oid|\"default\" program [args ...] ");
+ register_config_handler("snmptrapd", "format1",
+ parse_trap1_fmt, free_trap1_fmt, "format");
+ register_config_handler("snmptrapd", "format2",
+ parse_trap2_fmt, free_trap2_fmt, "format");
+ register_config_handler("snmptrapd", "format",
+ parse_format, NULL,
+ "[print{,1,2}|syslog{,1,2}|execute{,1,2}] format");
+ register_config_handler("snmptrapd", "forward",
+ parse_forward, NULL, "OID|\"default\" destination");
+}
+
+
+
+/*-----------------------------
+ *
+ * Routines to implement a "registry" of trap handlers
+ *
+ *-----------------------------*/
+
+netsnmp_trapd_handler *netsnmp_auth_global_traphandlers = NULL;
+netsnmp_trapd_handler *netsnmp_pre_global_traphandlers = NULL;
+netsnmp_trapd_handler *netsnmp_post_global_traphandlers = NULL;
+netsnmp_trapd_handler *netsnmp_default_traphandlers = NULL;
+netsnmp_trapd_handler *netsnmp_specific_traphandlers = NULL;
+
+typedef struct netsnmp_handler_map_t {
+ netsnmp_trapd_handler **handler;
+ const char *descr;
+} netsnmp_handler_map;
+
+static netsnmp_handler_map handlers[] = {
+ { &netsnmp_auth_global_traphandlers, "auth trap" },
+ { &netsnmp_pre_global_traphandlers, "pre-global trap" },
+ { NULL, "trap specific" },
+ { &netsnmp_post_global_traphandlers, "global" },
+ { NULL, NULL }
+};
+
+/*
+ * Register a new "global" traphandler,
+ * to be applied to *all* incoming traps
+ */
+netsnmp_trapd_handler *
+netsnmp_add_global_traphandler(int list, Netsnmp_Trap_Handler *handler)
+{
+ netsnmp_trapd_handler *traph;
+
+ if ( !handler )
+ return NULL;
+
+ traph = SNMP_MALLOC_TYPEDEF(netsnmp_trapd_handler);
+ if ( !traph )
+ return NULL;
+
+ /*
+ * Add this new handler to the front of the appropriate list
+ * (or should it go on the end?)
+ */
+ traph->handler = handler;
+ traph->authtypes = TRAP_AUTH_ALL; /* callers will likely change this */
+ switch (list) {
+ case NETSNMPTRAPD_AUTH_HANDLER:
+ traph->nexth = netsnmp_auth_global_traphandlers;
+ netsnmp_auth_global_traphandlers = traph;
+ break;
+ case NETSNMPTRAPD_PRE_HANDLER:
+ traph->nexth = netsnmp_pre_global_traphandlers;
+ netsnmp_pre_global_traphandlers = traph;
+ break;
+ case NETSNMPTRAPD_POST_HANDLER:
+ traph->nexth = netsnmp_post_global_traphandlers;
+ netsnmp_post_global_traphandlers = traph;
+ break;
+ case NETSNMPTRAPD_DEFAULT_HANDLER:
+ traph->nexth = netsnmp_default_traphandlers;
+ netsnmp_default_traphandlers = traph;
+ break;
+ default:
+ free( traph );
+ return NULL;
+ }
+ return traph;
+}
+
+#ifndef NETSNMP_FEATURE_REMOVE_ADD_DEFAULT_TRAPHANDLER
+/*
+ * Register a new "default" traphandler, to be applied to all
+ * traps with no specific trap handlers of their own.
+ */
+netsnmp_trapd_handler *
+netsnmp_add_default_traphandler(Netsnmp_Trap_Handler *handler) {
+ return netsnmp_add_global_traphandler(NETSNMPTRAPD_DEFAULT_HANDLER,
+ handler);
+}
+#endif /* NETSNMP_FEATURE_REMOVE_ADD_DEFAULT_TRAPHANDLER */
+
+
+/*
+ * Register a new trap-specific traphandler
+ */
+netsnmp_trapd_handler *
+netsnmp_add_traphandler(Netsnmp_Trap_Handler* handler,
+ oid *trapOid, int trapOidLen ) {
+ netsnmp_trapd_handler *traph, *traph2;
+
+ if ( !handler )
+ return NULL;
+
+ traph = SNMP_MALLOC_TYPEDEF(netsnmp_trapd_handler);
+ if ( !traph )
+ return NULL;
+
+ /*
+ * Populate this new handler with the trap information
+ * (NB: the OID fields were not used in the default/global lists)
+ */
+ traph->authtypes = TRAP_AUTH_ALL; /* callers will likely change this */
+ traph->handler = handler;
+ traph->trapoid_len = trapOidLen;
+ traph->trapoid = snmp_duplicate_objid(trapOid, trapOidLen);
+
+ /*
+ * Now try to find the appropriate place in the trap-specific
+ * list for this particular trap OID. If there's a matching OID
+ * already, then find it. Otherwise find the one that follows.
+ * If we run out of entried, the new one should be tacked onto the end.
+ */
+ for (traph2 = netsnmp_specific_traphandlers;
+ traph2; traph2 = traph2->nextt) {
+ /* XXX - check this! */
+ if (snmp_oid_compare(traph2->trapoid, traph2->trapoid_len,
+ trapOid, trapOidLen) <= 0)
+ break;
+ }
+ if (traph2) {
+ /*
+ * OK - We've either got an exact match, or we've found the
+ * entry *after* where the new one should go.
+ */
+ if (!snmp_oid_compare(traph->trapoid, traph->trapoid_len,
+ traph2->trapoid, traph2->trapoid_len)) {
+ /*
+ * Exact match, so find the end of the *handler* list
+ * and tack on this new entry...
+ */
+ while (traph2->nexth)
+ traph2 = traph2->nexth;
+ traph2->nexth = traph;
+ traph->nextt = traph2->nextt; /* Might as well... */
+ traph->prevt = traph2->prevt;
+ } else {
+ /*
+ * .. or the following entry, so insert the new one before it.
+ */
+ traph->prevt = traph2->prevt;
+ if (traph2->prevt)
+ traph2->prevt->nextt = traph;
+ else
+ netsnmp_specific_traphandlers = traph;
+ traph2->prevt = traph;
+ traph->nextt = traph2;
+ }
+ } else {
+ /*
+ * If we've run out of entries without finding a suitable spot,
+ * the new one should be tacked onto the end.....
+ */
+ if (netsnmp_specific_traphandlers) {
+ traph2 = netsnmp_specific_traphandlers;
+ while (traph2->nextt)
+ traph2 = traph2->nextt;
+ traph2->nextt = traph;
+ traph->prevt = traph2;
+ } else {
+ /*
+ * .... unless this is the very first entry, of course!
+ */
+ netsnmp_specific_traphandlers = traph;
+ }
+ }
+
+ return traph;
+}
+
+void
+snmptrapd_free_traphandle(void)
+{
+ netsnmp_trapd_handler *traph = NULL, *nextt = NULL, *nexth = NULL;
+
+ DEBUGMSGTL(("snmptrapd", "Freeing trap handler lists\n"));
+
+ /*
+ * Free default trap handlers
+ */
+ traph = netsnmp_default_traphandlers;
+ /* loop over handlers */
+ while (traph) {
+ DEBUGMSG(("snmptrapd", "Freeing default trap handler\n"));
+ nexth = traph->nexth;
+ SNMP_FREE(traph->token);
+ SNMP_FREE(traph);
+ traph = nexth;
+ }
+ netsnmp_default_traphandlers = NULL;
+
+ /*
+ * Free specific trap handlers
+ */
+ traph = netsnmp_specific_traphandlers;
+ /* loop over traps */
+ while (traph) {
+ nextt = traph->nextt;
+ /* loop over handlers for this trap */
+ while (traph) {
+ DEBUGMSG(("snmptrapd", "Freeing specific trap handler\n"));
+ nexth = traph->nexth;
+ SNMP_FREE(traph->token);
+ SNMP_FREE(traph->trapoid);
+ SNMP_FREE(traph);
+ traph = nexth;
+ }
+ traph = nextt;
+ }
+ netsnmp_specific_traphandlers = NULL;
+}
+
+/*
+ * Locate the list of handlers for this particular Trap OID
+ * Returns NULL if there are no relevant traps
+ */
+netsnmp_trapd_handler *
+netsnmp_get_traphandler( oid *trapOid, int trapOidLen ) {
+ netsnmp_trapd_handler *traph;
+
+ if (!trapOid || !trapOidLen) {
+ DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler no OID!\n"));
+ return NULL;
+ }
+ DEBUGMSGTL(( "snmptrapd:lookup", "Looking up Trap OID: "));
+ DEBUGMSGOID(("snmptrapd:lookup", trapOid, trapOidLen));
+ DEBUGMSG(( "snmptrapd:lookup", "\n"));
+
+ /*
+ * Look for a matching OID, and return that list...
+ */
+ for (traph = netsnmp_specific_traphandlers;
+ traph; traph=traph->nextt ) {
+
+ /*
+ * If the trap handler wasn't wildcarded, then the trapOID
+ * should match the registered OID exactly.
+ */
+ if (!(traph->flags & NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE)) {
+ if (snmp_oid_compare(traph->trapoid, traph->trapoid_len,
+ trapOid, trapOidLen) == 0) {
+ DEBUGMSGTL(( "snmptrapd:lookup",
+ "get_traphandler exact match (%p)\n", traph));
+ return traph;
+ }
+ } else {
+ /*
+ * If the trap handler *was* wildcarded, then the trapOID
+ * should have the registered OID as a prefix...
+ */
+ if (snmp_oidsubtree_compare(traph->trapoid,
+ traph->trapoid_len,
+ trapOid, trapOidLen) == 0) {
+ if (traph->flags & NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE) {
+ /*
+ * ... and (optionally) *strictly* as a prefix
+ * i.e. not including an exact match.
+ */
+ if (snmp_oid_compare(traph->trapoid, traph->trapoid_len,
+ trapOid, trapOidLen) != 0) {
+ DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler strict subtree match (%p)\n", traph));
+ return traph;
+ }
+ } else {
+ DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler subtree match (%p)\n", traph));
+ return traph;
+ }
+ }
+ }
+ }
+
+ /*
+ * .... or failing that, return the "default" list (which may be NULL)
+ */
+ DEBUGMSGTL(( "snmptrapd:lookup", "get_traphandler default (%p)\n",
+ netsnmp_default_traphandlers));
+ return netsnmp_default_traphandlers;
+}
+
+/*-----------------------------
+ *
+ * Standard traphandlers for the common requirements
+ *
+ *-----------------------------*/
+
+#define SYSLOG_V1_STANDARD_FORMAT "%a: %W Trap (%q) Uptime: %#T%#v\n"
+#define SYSLOG_V1_ENTERPRISE_FORMAT "%a: %W Trap (%q) Uptime: %#T%#v\n" /* XXX - (%q) become (.N) ??? */
+#define SYSLOG_V23_NOTIFICATION_FORMAT "%B [%b]: Trap %#v\n" /* XXX - introduces a leading " ," */
+
+/*
+ * Trap handler for logging via syslog
+ */
+int syslog_handler( netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ u_char *rbuf = NULL;
+ size_t r_len = 64, o_len = 0;
+ int trunc = 0;
+
+ DEBUGMSGTL(( "snmptrapd", "syslog_handler\n"));
+
+ if (SyslogTrap)
+ return NETSNMPTRAPD_HANDLER_OK;
+
+ if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
+ snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
+ return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
+ }
+
+ /*
+ * If there's a format string registered for this trap, then use it.
+ */
+ if (handler && handler->format) {
+ DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
+ if (*handler->format) {
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ handler->format, pdu, transport);
+ } else {
+ free(rbuf);
+ return NETSNMPTRAPD_HANDLER_OK; /* A 0-length format string means don't log */
+ }
+
+ /*
+ * Otherwise (i.e. a NULL handler format string),
+ * use a standard output format setting
+ * either configurable, or hardwired
+ *
+ * XXX - v1 traps use a different hardwired formats for
+ * standard and enterprise specific traps
+ * Do we actually need this?
+ */
+ } else {
+ if ( pdu->command == SNMP_MSG_TRAP ) {
+ if (syslog_format1) {
+ DEBUGMSGTL(( "snmptrapd", "syslog_format v1 = '%s'\n", syslog_format1));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ syslog_format1, pdu, transport);
+
+ } else if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
+ DEBUGMSGTL(( "snmptrapd", "v1 enterprise format\n"));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ SYSLOG_V1_ENTERPRISE_FORMAT,
+ pdu, transport);
+ } else {
+ DEBUGMSGTL(( "snmptrapd", "v1 standard trap format\n"));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ SYSLOG_V1_STANDARD_FORMAT,
+ pdu, transport);
+ }
+ } else { /* SNMPv2/3 notifications */
+ if (syslog_format2) {
+ DEBUGMSGTL(( "snmptrapd", "syslog_format v1 = '%s'\n", syslog_format2));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ syslog_format2, pdu, transport);
+ } else {
+ DEBUGMSGTL(( "snmptrapd", "v2/3 format\n"));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ SYSLOG_V23_NOTIFICATION_FORMAT,
+ pdu, transport);
+ }
+ }
+ }
+ snmp_log(LOG_WARNING, "%s%s", rbuf, (trunc?" [TRUNCATED]\n":""));
+ free(rbuf);
+ return NETSNMPTRAPD_HANDLER_OK;
+}
+
+
+#define PRINT_V23_NOTIFICATION_FORMAT "%.4y-%.2m-%.2l %.2h:%.2j:%.2k %B [%b]:\n%v\n"
+
+/*
+ * Trap handler for logging to a file
+ */
+int print_handler( netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ u_char *rbuf = NULL;
+ size_t r_len = 64, o_len = 0;
+ int trunc = 0;
+
+ DEBUGMSGTL(( "snmptrapd", "print_handler\n"));
+
+ /*
+ * Don't bother logging authentication failures
+ * XXX - can we handle this via suitable handler entries instead?
+ */
+ if (pdu->trap_type == SNMP_TRAP_AUTHFAIL && dropauth)
+ return NETSNMPTRAPD_HANDLER_OK;
+
+ if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
+ snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
+ return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
+ }
+
+ /*
+ * If there's a format string registered for this trap, then use it.
+ */
+ if (handler && handler->format) {
+ DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
+ if (*handler->format) {
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ handler->format, pdu, transport);
+ } else {
+ free(rbuf);
+ return NETSNMPTRAPD_HANDLER_OK; /* A 0-length format string means don't log */
+ }
+
+ /*
+ * Otherwise (i.e. a NULL handler format string),
+ * use a standard output format setting
+ * either configurable, or hardwired
+ *
+ * XXX - v1 traps use a different routine for hardwired output
+ * Do we actually need this separate v1 routine?
+ * Or would a suitable format string be sufficient?
+ */
+ } else {
+ if ( pdu->command == SNMP_MSG_TRAP ) {
+ if (print_format1) {
+ DEBUGMSGTL(( "snmptrapd", "print_format v1 = '%s'\n", print_format1));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ print_format1, pdu, transport);
+ } else {
+ DEBUGMSGTL(( "snmptrapd", "v1 format\n"));
+ trunc = !realloc_format_plain_trap(&rbuf, &r_len, &o_len, 1,
+ pdu, transport);
+ }
+ } else {
+ if (print_format2) {
+ DEBUGMSGTL(( "snmptrapd", "print_format v2 = '%s'\n", print_format2));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ print_format2, pdu, transport);
+ } else {
+ DEBUGMSGTL(( "snmptrapd", "v2/3 format\n"));
+ trunc = !realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ PRINT_V23_NOTIFICATION_FORMAT,
+ pdu, transport);
+ }
+ }
+ }
+ snmp_log(LOG_INFO, "%s%s", rbuf, (trunc?" [TRUNCATED]\n":""));
+ free(rbuf);
+ return NETSNMPTRAPD_HANDLER_OK;
+}
+
+
+#define EXECUTE_FORMAT "%B\n%b\n%V\n%v\n"
+
+/*
+ * Trap handler for invoking a suitable script
+ */
+int command_handler( netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+#ifndef USING_UTILITIES_EXECUTE_MODULE
+ NETSNMP_LOGONCE((LOG_WARNING,
+ "support for run_shell_command not available\n"));
+ return NETSNMPTRAPD_HANDLER_FAIL;
+#else
+ u_char *rbuf = NULL;
+ size_t r_len = 64, o_len = 0;
+ int oldquick;
+
+ DEBUGMSGTL(( "snmptrapd", "command_handler\n"));
+ DEBUGMSGTL(( "snmptrapd", "token = '%s'\n", handler->token));
+ if (handler && handler->token && *handler->token) {
+ netsnmp_pdu *v2_pdu = NULL;
+ if (pdu->command == SNMP_MSG_TRAP)
+ v2_pdu = convert_v1pdu_to_v2(pdu);
+ else
+ v2_pdu = pdu;
+ oldquick = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT);
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT, 1);
+
+ /*
+ * Format the trap and pass this string to the external command
+ */
+ if ((rbuf = (u_char *) calloc(r_len, 1)) == NULL) {
+ snmp_log(LOG_ERR, "couldn't display trap -- malloc failed\n");
+ return NETSNMPTRAPD_HANDLER_FAIL; /* Failed but keep going */
+ }
+
+ /*
+ * If there's a format string registered for this trap, then use it.
+ * Otherwise use the standard execution format setting.
+ */
+ if (handler && handler->format && *handler->format) {
+ DEBUGMSGTL(( "snmptrapd", "format = '%s'\n", handler->format));
+ realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ handler->format,
+ v2_pdu, transport);
+ } else {
+ if ( pdu->command == SNMP_MSG_TRAP && exec_format1 ) {
+ DEBUGMSGTL(( "snmptrapd", "exec v1 = '%s'\n", exec_format1));
+ realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ exec_format1, pdu, transport);
+ } else if ( pdu->command != SNMP_MSG_TRAP && exec_format2 ) {
+ DEBUGMSGTL(( "snmptrapd", "exec v2/3 = '%s'\n", exec_format2));
+ realloc_format_trap(&rbuf, &r_len, &o_len, 1,
+ exec_format2, pdu, transport);
+ } else {
+ DEBUGMSGTL(( "snmptrapd", "execute format\n"));
+ realloc_format_trap(&rbuf, &r_len, &o_len, 1, EXECUTE_FORMAT,
+ v2_pdu, transport);
+ }
+ }
+
+ /*
+ * and pass this formatted string to the command specified
+ */
+ run_shell_command(handler->token, (char*)rbuf, NULL, NULL); /* Not interested in output */
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_QUICK_PRINT, oldquick);
+ if (pdu->command == SNMP_MSG_TRAP)
+ snmp_free_pdu(v2_pdu);
+ free(rbuf);
+ }
+ return NETSNMPTRAPD_HANDLER_OK;
+#endif /* !def USING_UTILITIES_EXECUTE_MODULE */
+}
+
+
+
+
+/*
+ * Trap handler for forwarding to the AgentX master agent
+ */
+int axforward_handler( netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ send_v2trap( pdu->variables );
+ return NETSNMPTRAPD_HANDLER_OK;
+}
+
+/*
+ * Trap handler for forwarding to another destination
+ */
+int forward_handler( netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu2;
+ char buf[BUFSIZ], *cp;
+
+ DEBUGMSGTL(( "snmptrapd", "forward_handler (%s)\n", handler->token));
+
+ snmp_sess_init( &session );
+ if (strchr( handler->token, ':') == NULL) {
+ snprintf( buf, BUFSIZ, "%s:%d", handler->token, SNMP_TRAP_PORT);
+ cp = buf;
+ } else {
+ cp = handler->token;
+ }
+ session.peername = cp;
+ session.version = pdu->version;
+ ss = snmp_open( &session );
+ if (!ss)
+ return NETSNMPTRAPD_HANDLER_FAIL;
+
+ /* XXX: wjh we should be caching sessions here and not always
+ reopening a session. It's very ineffecient, especially with v3
+ INFORMS which may require engineID probing */
+
+ pdu2 = snmp_clone_pdu(pdu);
+ if (pdu2->transport_data) {
+ free(pdu2->transport_data);
+ pdu2->transport_data = NULL;
+ pdu2->transport_data_length = 0;
+ }
+ if (!snmp_send( ss, pdu2 )) {
+ snmp_sess_perror("Forward failed", ss);
+ snmp_free_pdu(pdu2);
+ }
+ snmp_close( ss );
+ return NETSNMPTRAPD_HANDLER_OK;
+}
+
+#if defined(USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE) && defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+/*
+ * "Notification" handler for implementing NOTIFICATION-MIB
+ * (presumably)
+ */
+int notification_handler(netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ DEBUGMSGTL(( "snmptrapd", "notification_handler\n"));
+ log_notification(pdu, transport);
+ return NETSNMPTRAPD_HANDLER_OK;
+}
+#endif
+
+/*-----------------------------
+ *
+ * Main driving code, to process an incoming trap
+ *
+ *-----------------------------*/
+
+
+
+int
+snmp_input(int op, netsnmp_session *session,
+ int reqid, netsnmp_pdu *pdu, void *magic)
+{
+ oid stdTrapOidRoot[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5 };
+ oid snmpTrapOid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
+ oid trapOid[MAX_OID_LEN+2] = {0};
+ int trapOidLen;
+ netsnmp_variable_list *vars;
+ netsnmp_trapd_handler *traph;
+ netsnmp_transport *transport = (netsnmp_transport *) magic;
+ int ret, idx;
+
+ switch (op) {
+ case NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE:
+ /*
+ * Drops packets with reception problems
+ */
+ if (session->s_snmp_errno) {
+ /* drop problem packets */
+ return 1;
+ }
+
+ /*
+ * Determine the OID that identifies the trap being handled
+ */
+ DEBUGMSGTL(("snmptrapd", "input: %x\n", pdu->command));
+ switch (pdu->command) {
+ case SNMP_MSG_TRAP:
+ /*
+ * Convert v1 traps into a v2-style trap OID
+ * (following RFC 2576)
+ */
+ if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
+ trapOidLen = pdu->enterprise_length;
+ memcpy(trapOid, pdu->enterprise, sizeof(oid) * trapOidLen);
+ if (trapOid[trapOidLen - 1] != 0) {
+ trapOid[trapOidLen++] = 0;
+ }
+ trapOid[trapOidLen++] = pdu->specific_type;
+ } else {
+ memcpy(trapOid, stdTrapOidRoot, sizeof(stdTrapOidRoot));
+ trapOidLen = OID_LENGTH(stdTrapOidRoot); /* 9 */
+ trapOid[trapOidLen++] = pdu->trap_type+1;
+ }
+ break;
+
+ case SNMP_MSG_TRAP2:
+ case SNMP_MSG_INFORM:
+ /*
+ * v2c/v3 notifications *should* have snmpTrapOID as the
+ * second varbind, so we can go straight there.
+ * But check, just to make sure
+ */
+ vars = pdu->variables;
+ if (vars)
+ vars = vars->next_variable;
+ if (!vars || snmp_oid_compare(vars->name, vars->name_length,
+ snmpTrapOid, OID_LENGTH(snmpTrapOid))) {
+ /*
+ * Didn't find it!
+ * Let's look through the full list....
+ */
+ for ( vars = pdu->variables; vars; vars=vars->next_variable) {
+ if (!snmp_oid_compare(vars->name, vars->name_length,
+ snmpTrapOid, OID_LENGTH(snmpTrapOid)))
+ break;
+ }
+ if (!vars) {
+ /*
+ * Still can't find it! Give up.
+ */
+ snmp_log(LOG_ERR, "Cannot find TrapOID in TRAP2 PDU\n");
+ return 1; /* ??? */
+ }
+ }
+ memcpy(trapOid, vars->val.objid, vars->val_len);
+ trapOidLen = vars->val_len /sizeof(oid);
+ break;
+
+ default:
+ /* SHOULDN'T HAPPEN! */
+ return 1; /* ??? */
+ }
+ DEBUGMSGTL(( "snmptrapd", "Trap OID: "));
+ DEBUGMSGOID(("snmptrapd", trapOid, trapOidLen));
+ DEBUGMSG(( "snmptrapd", "\n"));
+
+
+ /*
+ * OK - We've found the Trap OID used to identify this trap.
+ * Call each of the various lists of handlers:
+ * a) authentication-related handlers,
+ * b) other handlers to be applied to all traps
+ * (*before* trap-specific handlers)
+ * c) the handler(s) specific to this trap
+t * d) any other global handlers
+ *
+ * In each case, a particular trap handler can abort further
+ * processing - either just for that particular list,
+ * or for the trap completely.
+ *
+ * This is particularly designed for authentication-related
+ * handlers, but can also be used elsewhere.
+ *
+ * OK - Enough waffling, let's get to work.....
+ */
+
+ for( idx = 0; handlers[idx].descr; ++idx ) {
+ DEBUGMSGTL(("snmptrapd", "Running %s handlers\n",
+ handlers[idx].descr));
+ if (NULL == handlers[idx].handler) /* specific */
+ traph = netsnmp_get_traphandler(trapOid, trapOidLen);
+ else
+ traph = *handlers[idx].handler;
+
+ for( ; traph; traph = traph->nexth) {
+ if (!netsnmp_trapd_check_auth(traph->authtypes))
+ continue; /* we continue on and skip this one */
+
+ ret = (*(traph->handler))(pdu, transport, traph);
+ if(NETSNMPTRAPD_HANDLER_FINISH == ret)
+ return 1;
+ if (ret == NETSNMPTRAPD_HANDLER_BREAK)
+ break; /* move on to next type */
+ } /* traph */
+ } /* handlers */
+
+
+ if (pdu->command == SNMP_MSG_INFORM) {
+ netsnmp_pdu *reply = snmp_clone_pdu(pdu);
+ if (!reply) {
+ snmp_log(LOG_ERR, "couldn't clone PDU for INFORM response\n");
+ } else {
+ reply->command = SNMP_MSG_RESPONSE;
+ reply->errstat = 0;
+ reply->errindex = 0;
+ if (!snmp_send(session, reply)) {
+ snmp_sess_perror("snmptrapd: Couldn't respond to inform pdu",
+ session);
+ snmp_free_pdu(reply);
+ }
+ }
+ }
+
+ break;
+
+ case NETSNMP_CALLBACK_OP_TIMED_OUT:
+ snmp_log(LOG_ERR, "Timeout: This shouldn't happen!\n");
+ break;
+
+ case NETSNMP_CALLBACK_OP_SEND_FAILED:
+ snmp_log(LOG_ERR, "Send Failed: This shouldn't happen either!\n");
+ break;
+
+ case NETSNMP_CALLBACK_OP_CONNECT:
+ case NETSNMP_CALLBACK_OP_DISCONNECT:
+ /* Ignore silently */
+ break;
+
+ default:
+ snmp_log(LOG_ERR, "Unknown operation (%d): This shouldn't happen!\n", op);
+ break;
+ }
+ return 0;
+}
+
diff --git a/apps/snmptrapd_handlers.h b/apps/snmptrapd_handlers.h
new file mode 100644
index 0000000..097c02d
--- /dev/null
+++ b/apps/snmptrapd_handlers.h
@@ -0,0 +1,68 @@
+#ifndef SNMPTRAPD_HANDLERS_H
+#define SNMPTRAPD_HANDLERS_H
+
+typedef struct netsnmp_trapd_handler_s netsnmp_trapd_handler;
+
+typedef int (Netsnmp_Trap_Handler)(netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler);
+
+
+#define NETSNMP_TRAPHANDLER_FLAG_MATCH_TREE 0x1
+#define NETSNMP_TRAPHANDLER_FLAG_STRICT_SUBTREE 0x2
+
+struct netsnmp_trapd_handler_s {
+ oid *trapoid;
+ int trapoid_len;
+ char *token; /* Or an array of tokens? */
+ char *format; /* Formatting string */
+ int version; /* ??? */
+ int authtypes;
+ int flags;
+ Netsnmp_Trap_Handler *handler;
+ void *handler_data;
+
+ netsnmp_trapd_handler *nexth; /* Next handler for this trap */
+ /* Doubly-linked list of traps with registered handlers */
+ netsnmp_trapd_handler *prevt;
+ netsnmp_trapd_handler *nextt;
+};
+
+Netsnmp_Trap_Handler syslog_handler;
+Netsnmp_Trap_Handler print_handler;
+Netsnmp_Trap_Handler command_handler;
+Netsnmp_Trap_Handler event_handler;
+Netsnmp_Trap_Handler forward_handler;
+Netsnmp_Trap_Handler axforward_handler;
+Netsnmp_Trap_Handler notification_handler;
+Netsnmp_Trap_Handler mysql_handler;
+
+void free_trap1_fmt(void);
+void free_trap2_fmt(void);
+extern char *print_format1;
+extern char *print_format2;
+
+#define NETSNMPTRAPD_AUTH_HANDLER 1
+#define NETSNMPTRAPD_PRE_HANDLER 2
+#define NETSNMPTRAPD_POST_HANDLER 3
+#define NETSNMPTRAPD_DEFAULT_HANDLER 4
+
+#define NETSNMPTRAPD_HANDLER_OK 1 /* Succeed, & keep going */
+#define NETSNMPTRAPD_HANDLER_FAIL 2 /* Failed but keep going */
+#define NETSNMPTRAPD_HANDLER_BREAK 3 /* Move to the next list */
+#define NETSNMPTRAPD_HANDLER_FINISH 4 /* No further processing */
+
+void snmptrapd_register_configs( void );
+netsnmp_trapd_handler *netsnmp_add_global_traphandler(int list, Netsnmp_Trap_Handler* handler);
+netsnmp_trapd_handler *netsnmp_add_default_traphandler(Netsnmp_Trap_Handler* handler);
+netsnmp_trapd_handler *netsnmp_add_traphandler(Netsnmp_Trap_Handler* handler,
+ oid *trapOid, int trapOidLen);
+netsnmp_trapd_handler *netsnmp_get_traphandler(oid *trapOid, int trapOidLen);
+
+const char *trap_description(int trap);
+void do_external(char *cmd, struct hostent *host,
+ netsnmp_pdu *pdu, netsnmp_transport *transport);
+int snmp_input(int op, netsnmp_session *session,
+ int reqid, netsnmp_pdu *pdu, void *magic);
+
+#endif /* SNMPTRAPD_HANDLERS_H */
diff --git a/apps/snmptrapd_log.c b/apps/snmptrapd_log.c
new file mode 100644
index 0000000..774f797
--- /dev/null
+++ b/apps/snmptrapd_log.c
@@ -0,0 +1,1802 @@
+/*
+ * snmptrapd_log.c - format SNMP trap information for logging
+ *
+ */
+/*****************************************************************
+ Copyright 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if !defined(mingw32) && defined(HAVE_SYS_TIME_H)
+# include <sys/time.h>
+# if TIME_WITH_SYS_TIME
+# include <time.h>
+# endif
+#else
+# include <time.h>
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#if HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include "snmptrapd_log.h"
+
+
+#ifndef BSD4_3
+#define BSD4_2
+#endif
+
+/*
+ * These flags mark undefined values in the options structure
+ */
+#define UNDEF_CMD '*'
+#define UNDEF_PRECISION -1
+
+/*
+ * This structure holds the options for a single format command
+ */
+typedef struct {
+ char cmd; /* the format command itself */
+ size_t width; /* the field's minimum width */
+ int precision; /* the field's precision */
+ int left_justify; /* if true, left justify this field */
+ int alt_format; /* if true, display in alternate format */
+ int leading_zeroes; /* if true, display with leading zeroes */
+} options_type;
+
+char separator[32];
+
+/*
+ * These symbols define the characters that the parser recognizes.
+ * The rather odd choice of symbols comes from an attempt to avoid
+ * colliding with the ones that printf uses, so that someone could add
+ * printf functionality to this code and turn it into a library
+ * routine in the future.
+ */
+typedef enum {
+ CHR_FMT_DELIM = '%', /* starts a format command */
+ CHR_LEFT_JUST = '-', /* left justify */
+ CHR_LEAD_ZERO = '0', /* use leading zeroes */
+ CHR_ALT_FORM = '#', /* use alternate format */
+ CHR_FIELD_SEP = '.', /* separates width and precision fields */
+
+ /* Date / Time Information */
+ CHR_CUR_TIME = 't', /* current time, Unix format */
+ CHR_CUR_YEAR = 'y', /* current year */
+ CHR_CUR_MONTH = 'm', /* current month */
+ CHR_CUR_MDAY = 'l', /* current day of month */
+ CHR_CUR_HOUR = 'h', /* current hour */
+ CHR_CUR_MIN = 'j', /* current minute */
+ CHR_CUR_SEC = 'k', /* current second */
+ CHR_UP_TIME = 'T', /* uptime, Unix format */
+ CHR_UP_YEAR = 'Y', /* uptime year */
+ CHR_UP_MONTH = 'M', /* uptime month */
+ CHR_UP_MDAY = 'L', /* uptime day of month */
+ CHR_UP_HOUR = 'H', /* uptime hour */
+ CHR_UP_MIN = 'J', /* uptime minute */
+ CHR_UP_SEC = 'K', /* uptime second */
+
+ /* transport information */
+ CHR_AGENT_IP = 'a', /* agent's IP address */
+ CHR_AGENT_NAME = 'A', /* agent's host name if available */
+
+ /* authentication information */
+ CHR_SNMP_VERSION = 's', /* SNMP Version Number */
+ CHR_SNMP_SECMOD = 'S', /* SNMPv3 Security Model Version Number */
+ CHR_SNMP_USER = 'u', /* SNMPv3 secName or v1/v2c community */
+ CHR_TRAP_CONTEXTID = 'E', /* SNMPv3 context engineID if available */
+
+ /* PDU information */
+ CHR_PDU_IP = 'b', /* PDU's IP address */
+ CHR_PDU_NAME = 'B', /* PDU's host name if available */
+ CHR_PDU_ENT = 'N', /* PDU's enterprise string */
+ CHR_PDU_WRAP = 'P', /* PDU's wrapper info (community, security) */
+ CHR_TRAP_NUM = 'w', /* trap number */
+ CHR_TRAP_DESC = 'W', /* trap's description (textual) */
+ CHR_TRAP_STYPE = 'q', /* trap's subtype */
+ CHR_TRAP_VARSEP = 'V', /* character (or string) to separate variables */
+ CHR_TRAP_VARS = 'v' /* tab-separated list of trap's variables */
+
+} parse_chr_type;
+
+/*
+ * These symbols define the states for the parser's state machine
+ */
+typedef enum {
+ PARSE_NORMAL, /* looking for next character */
+ PARSE_BACKSLASH, /* saw a backslash */
+ PARSE_IN_FORMAT, /* saw a % sign, in a format command */
+ PARSE_GET_WIDTH, /* getting field width */
+ PARSE_GET_PRECISION, /* getting field precision */
+ PARSE_GET_SEPARATOR /* getting field separator */
+} parse_state_type;
+
+/*
+ * macros
+ */
+
+#define is_cur_time_cmd(chr) ((((chr) == CHR_CUR_TIME) \
+ || ((chr) == CHR_CUR_YEAR) \
+ || ((chr) == CHR_CUR_MONTH) \
+ || ((chr) == CHR_CUR_MDAY) \
+ || ((chr) == CHR_CUR_HOUR) \
+ || ((chr) == CHR_CUR_MIN) \
+ || ((chr) == CHR_CUR_SEC)) ? TRUE : FALSE)
+ /*
+ * Function:
+ * Returns true if the character is a format command that outputs
+ * some field that deals with the current time.
+ *
+ * Input Parameters:
+ * chr - character to check
+ */
+
+#define is_up_time_cmd(chr) ((((chr) == CHR_UP_TIME) \
+ || ((chr) == CHR_UP_YEAR) \
+ || ((chr) == CHR_UP_MONTH) \
+ || ((chr) == CHR_UP_MDAY) \
+ || ((chr) == CHR_UP_HOUR) \
+ || ((chr) == CHR_UP_MIN) \
+ || ((chr) == CHR_UP_SEC)) ? TRUE : FALSE)
+ /*
+ * Function:
+ * Returns true if the character is a format command that outputs
+ * some field that deals with up-time.
+ *
+ * Input Parameters:
+ * chr - character to check
+ */
+
+#define is_agent_cmd(chr) ((((chr) == CHR_AGENT_IP) \
+ || ((chr) == CHR_AGENT_NAME)) ? TRUE : FALSE)
+ /*
+ * Function:
+ * Returns true if the character outputs information about the
+ * agent.
+ *
+ * Input Parameters:
+ * chr - the character to check
+ */
+
+#define is_pdu_ip_cmd(chr) ((((chr) == CHR_PDU_IP) \
+ || ((chr) == CHR_PDU_NAME)) ? TRUE : FALSE)
+
+ /*
+ * Function:
+ * Returns true if the character outputs information about the SNMP
+ * authentication information
+ * Input Parameters:
+ * chr - the character to check
+ */
+
+#define is_auth_cmd(chr) ((((chr) == CHR_SNMP_VERSION \
+ || (chr) == CHR_SNMP_SECMOD \
+ || (chr) == CHR_SNMP_USER)) ? TRUE : FALSE)
+
+ /*
+ * Function:
+ * Returns true if the character outputs information about the PDU's
+ * host name or IP address.
+ *
+ * Input Parameters:
+ * chr - the character to check
+ */
+
+#define is_trap_cmd(chr) ((((chr) == CHR_TRAP_NUM) \
+ || ((chr) == CHR_TRAP_DESC) \
+ || ((chr) == CHR_TRAP_STYPE) \
+ || ((chr) == CHR_TRAP_VARS)) ? TRUE : FALSE)
+
+ /*
+ * Function:
+ * Returns true if the character outputs information about the trap.
+ *
+ * Input Parameters:
+ * chr - the character to check
+ */
+
+#define is_fmt_cmd(chr) ((is_cur_time_cmd (chr) \
+ || is_up_time_cmd (chr) \
+ || is_auth_cmd (chr) \
+ || is_agent_cmd (chr) \
+ || is_pdu_ip_cmd (chr) \
+ || ((chr) == CHR_PDU_ENT) \
+ || ((chr) == CHR_TRAP_CONTEXTID) \
+ || ((chr) == CHR_PDU_WRAP) \
+ || is_trap_cmd (chr)) ? TRUE : FALSE)
+ /*
+ * Function:
+ * Returns true if the character is a format command.
+ *
+ * Input Parameters:
+ * chr - character to check
+ */
+
+#define is_numeric_cmd(chr) ((is_cur_time_cmd(chr) \
+ || is_up_time_cmd(chr) \
+ || (chr) == CHR_TRAP_NUM) ? TRUE : FALSE)
+ /*
+ * Function:
+ * Returns true if this is a numeric format command.
+ *
+ * Input Parameters:
+ * chr - character to check
+ */
+
+#define reference(var) ((var) == (var))
+
+ /*
+ * Function:
+ * Some compiler options will tell the compiler to be picky and
+ * warn you if you pass a parameter to a function but don't use it.
+ * This macro lets you reference a parameter so that the compiler won't
+ * generate the warning. It has no other effect.
+ *
+ * Input Parameters:
+ * var - the parameter to reference
+ */
+
+/*
+ * prototypes
+ */
+extern const char *trap_description(int trap);
+
+static void
+init_options(options_type * options)
+
+ /*
+ * Function:
+ * Initialize a structure that contains the option settings for
+ * a format command.
+ *
+ * Input Parameters:
+ * options - points to the structure to initialize
+ */
+{
+ /*
+ * initialize the structure's fields
+ */
+ options->cmd = '*';
+ options->width = 0;
+ options->precision = UNDEF_PRECISION;
+ options->left_justify = FALSE;
+ options->alt_format = FALSE;
+ options->leading_zeroes = FALSE;
+ return;
+}
+
+
+static int
+realloc_output_temp_bfr(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ u_char ** temp_buf, options_type * options)
+
+ /*
+ * Function:
+ * Append the contents of the temporary buffer to the specified
+ * buffer using the correct justification, leading zeroes, width,
+ * precision, and other characteristics specified in the options
+ * structure.
+ *
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * temp_buf - pointer to string to append onto output buffer. THIS
+ * STRING IS free()d BY THIS FUNCTION.
+ * options - what options to use when appending string
+ */
+{
+ size_t temp_len; /* length of temporary buffer */
+ size_t temp_to_write; /* # of chars to write from temp bfr */
+ size_t char_to_write; /* # of other chars to write */
+ size_t zeroes_to_write; /* fill to precision with zeroes for numbers */
+
+ if (temp_buf == NULL || *temp_buf == NULL) {
+ return 1;
+ }
+
+ /*
+ * Figure out how many characters are in the temporary buffer now,
+ * and how many of them we'll write.
+ */
+ temp_len = strlen((char *) *temp_buf);
+ temp_to_write = temp_len;
+
+ if (options->precision != UNDEF_PRECISION &&
+ temp_to_write > (size_t)options->precision) {
+ temp_to_write = options->precision;
+ }
+
+ /*
+ * Handle leading characters.
+ */
+ if ((!options->left_justify) && (temp_to_write < options->width)) {
+ zeroes_to_write = options->precision - temp_to_write;
+ if (!is_numeric_cmd(options->cmd)) {
+ zeroes_to_write = 0;
+ }
+
+ for (char_to_write = options->width - temp_to_write;
+ char_to_write > 0; char_to_write--) {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ *(*buf + *out_len) = '\0';
+ free(*temp_buf);
+ return 0;
+ }
+ }
+ if (options->leading_zeroes || zeroes_to_write-- > 0) {
+ *(*buf + *out_len) = '0';
+ } else {
+ *(*buf + *out_len) = ' ';
+ }
+ (*out_len)++;
+ }
+ }
+
+ /*
+ * Truncate the temporary buffer and append its contents.
+ */
+ *(*temp_buf + temp_to_write) = '\0';
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, *temp_buf)) {
+ free(*temp_buf);
+ return 0;
+ }
+
+ /*
+ * Handle trailing characters.
+ */
+ if ((options->left_justify) && (temp_to_write < options->width)) {
+ for (char_to_write = options->width - temp_to_write;
+ char_to_write > 0; char_to_write--) {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ *(*buf + *out_len) = '\0';
+ free(*temp_buf);
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = '0';
+ (*out_len)++;
+ }
+ }
+
+ /*
+ * Slap on a trailing \0 for good measure.
+ */
+
+ *(*buf + *out_len) = '\0';
+ free(*temp_buf);
+ *temp_buf = NULL;
+ return 1;
+}
+
+
+static int
+realloc_handle_time_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu)
+
+ /*
+ * Function:
+ * Handle a format command that deals with the current or up-time.
+ * Append the correct time information to the buffer subject to the
+ * buffer's length limit.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ */
+{
+ time_t time_val; /* the time value to output */
+ unsigned long time_ul; /* u_long time/timeticks */
+ struct tm *parsed_time; /* parsed version of current time */
+ char *safe_bfr = NULL;
+ char fmt_cmd = options->cmd; /* the format command to use */
+
+ if ((safe_bfr = (char *) calloc(30, 1)) == NULL) {
+ return 0;
+ }
+
+ /*
+ * Get the time field to output.
+ */
+ if (is_up_time_cmd(fmt_cmd)) {
+ time_ul = pdu->time;
+ } else {
+ /*
+ * Note: a time_t is a signed long.
+ */
+ time(&time_val);
+ time_ul = (unsigned long) time_val;
+ }
+
+ /*
+ * Handle output in Unix time format.
+ */
+ if (fmt_cmd == CHR_CUR_TIME) {
+ sprintf(safe_bfr, "%lu", time_ul);
+ } else if (fmt_cmd == CHR_UP_TIME && !options->alt_format) {
+ sprintf(safe_bfr, "%lu", time_ul);
+ } else if (fmt_cmd == CHR_UP_TIME) {
+ unsigned int centisecs, seconds, minutes, hours, days;
+
+ centisecs = time_ul % 100;
+ time_ul /= 100;
+ days = time_ul / (60 * 60 * 24);
+ time_ul %= (60 * 60 * 24);
+
+ hours = time_ul / (60 * 60);
+ time_ul %= (60 * 60);
+
+ minutes = time_ul / 60;
+ seconds = time_ul % 60;
+
+ switch (days) {
+ case 0:
+ sprintf(safe_bfr, "%u:%02u:%02u.%02u",
+ hours, minutes, seconds, centisecs);
+ break;
+ case 1:
+ sprintf(safe_bfr, "1 day, %u:%02u:%02u.%02u",
+ hours, minutes, seconds, centisecs);
+ break;
+ default:
+ sprintf(safe_bfr, "%u days, %u:%02u:%02u.%02u",
+ days, hours, minutes, seconds, centisecs);
+ }
+ } else {
+ /*
+ * Handle other time fields.
+ */
+
+ if (options->alt_format) {
+ parsed_time = gmtime(&time_val);
+ } else {
+ parsed_time = localtime(&time_val);
+ }
+
+ switch (fmt_cmd) {
+
+ /*
+ * Output year. The year field is unusual: if there's a restriction
+ * on precision, we want to truncate from the left of the number,
+ * not the right, so someone printing the year 1972 with 2 digit
+ * precision gets "72" not "19".
+ */
+ case CHR_CUR_YEAR:
+ case CHR_UP_YEAR:
+ sprintf(safe_bfr, "%d", parsed_time->tm_year + 1900);
+ break;
+
+ /*
+ * output month
+ */
+ case CHR_CUR_MONTH:
+ case CHR_UP_MONTH:
+ sprintf(safe_bfr, "%d", parsed_time->tm_mon + 1);
+ break;
+
+ /*
+ * output day of month
+ */
+ case CHR_CUR_MDAY:
+ case CHR_UP_MDAY:
+ sprintf(safe_bfr, "%d", parsed_time->tm_mday);
+ break;
+
+ /*
+ * output hour
+ */
+ case CHR_CUR_HOUR:
+ case CHR_UP_HOUR:
+ sprintf(safe_bfr, "%d", parsed_time->tm_hour);
+ break;
+
+ /*
+ * output minute
+ */
+ case CHR_CUR_MIN:
+ case CHR_UP_MIN:
+ sprintf(safe_bfr, "%d", parsed_time->tm_min);
+ break;
+
+ /*
+ * output second
+ */
+ case CHR_CUR_SEC:
+ case CHR_UP_SEC:
+ sprintf(safe_bfr, "%d", parsed_time->tm_sec);
+ break;
+
+ /*
+ * unknown format command - just output the character
+ */
+ default:
+ sprintf(safe_bfr, "%c", fmt_cmd);
+ }
+ }
+
+ /*
+ * Output with correct justification, leading zeroes, etc.
+ */
+ return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
+ (u_char **) & safe_bfr, options);
+}
+
+
+static int
+realloc_handle_ip_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu,
+ netsnmp_transport *transport)
+
+ /*
+ * Function:
+ * Handle a format command that deals with an IP address
+ * or host name. Append the information to the buffer subject to
+ * the buffer's length limit.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ * transport - the transport descriptor
+ */
+{
+ struct in_addr *agent_inaddr = (struct in_addr *) pdu->agent_addr;
+ struct hostent *host = NULL; /* corresponding host name */
+ char fmt_cmd = options->cmd; /* what we're formatting */
+ u_char *temp_buf = NULL;
+ size_t temp_buf_len = 64, temp_out_len = 0;
+ char *tstr;
+ unsigned int oflags;
+
+ if ((temp_buf = (u_char*)calloc(temp_buf_len, 1)) == NULL) {
+ return 0;
+ }
+
+ /*
+ * Decide exactly what to output.
+ */
+ switch (fmt_cmd) {
+ case CHR_AGENT_IP:
+ /*
+ * Write a numerical address.
+ */
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
+ (u_char *)inet_ntoa(*agent_inaddr))) {
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ break;
+
+ case CHR_AGENT_NAME:
+ /*
+ * Try to resolve the agent_addr field as a hostname; fall back
+ * to numerical address.
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NUMERIC_IP)) {
+ host = netsnmp_gethostbyaddr((char *) pdu->agent_addr, 4, AF_INET);
+ }
+ if (host != NULL) {
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
+ (const u_char *)host->h_name)) {
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ } else {
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
+ (u_char *)inet_ntoa(*agent_inaddr))) {
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ }
+ break;
+
+ case CHR_PDU_IP:
+ /*
+ * Write the numerical transport information.
+ */
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ oflags = transport->flags;
+ transport->flags &= ~NETSNMP_TRANSPORT_FLAG_HOSTNAME;
+ tstr = transport->f_fmtaddr(transport, pdu->transport_data,
+ pdu->transport_data_length);
+ transport->flags = oflags;
+
+ if (!tstr) goto noip;
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len,
+ 1, (u_char *)tstr)) {
+ SNMP_FREE(temp_buf);
+ SNMP_FREE(tstr);
+ return 0;
+ }
+ SNMP_FREE(tstr);
+ } else {
+noip:
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
+ (const u_char*)"<UNKNOWN>")) {
+ SNMP_FREE(temp_buf);
+ return 0;
+ }
+ }
+ break;
+
+ case CHR_PDU_NAME:
+ /*
+ * Try to convert the numerical transport information
+ * into a hostname. Or rather, have the transport-specific
+ * address formatting routine do this.
+ * Otherwise falls back to the numeric address format.
+ */
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ oflags = transport->flags;
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NUMERIC_IP))
+ transport->flags |= NETSNMP_TRANSPORT_FLAG_HOSTNAME;
+ tstr = transport->f_fmtaddr(transport, pdu->transport_data,
+ pdu->transport_data_length);
+ transport->flags = oflags;
+
+ if (!tstr) goto nohost;
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len,
+ 1, (u_char *)tstr)) {
+ SNMP_FREE(temp_buf);
+ SNMP_FREE(tstr);
+ return 0;
+ }
+ SNMP_FREE(tstr);
+ } else {
+nohost:
+ if (!snmp_strcat(&temp_buf, &temp_buf_len, &temp_out_len, 1,
+ (const u_char*)"<UNKNOWN>")) {
+ SNMP_FREE(temp_buf);
+ return 0;
+ }
+ }
+ break;
+
+ /*
+ * Don't know how to handle this command - write the character itself.
+ */
+ default:
+ temp_buf[0] = fmt_cmd;
+ }
+
+ /*
+ * Output with correct justification, leading zeroes, etc.
+ */
+ return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
+ &temp_buf, options);
+}
+
+
+static int
+realloc_handle_ent_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu)
+
+ /*
+ * Function:
+ * Handle a format command that deals with OID strings.
+ * Append the information to the buffer subject to the
+ * buffer's length limit.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ */
+{
+ char fmt_cmd = options->cmd; /* what we're formatting */
+ u_char *temp_buf = NULL;
+ size_t temp_buf_len = 64, temp_out_len = 0;
+
+ if ((temp_buf = (u_char *) calloc(temp_buf_len, 1)) == NULL) {
+ return 0;
+ }
+
+ /*
+ * Decide exactly what to output.
+ */
+ switch (fmt_cmd) {
+ case CHR_PDU_ENT:
+ /*
+ * Write the enterprise oid.
+ */
+ if (!sprint_realloc_objid
+ (&temp_buf, &temp_buf_len, &temp_out_len, 1, pdu->enterprise,
+ pdu->enterprise_length)) {
+ free(temp_buf);
+ return 0;
+ }
+ break;
+
+ case CHR_TRAP_CONTEXTID:
+ /*
+ * Write the context oid.
+ */
+ if (!sprint_realloc_hexstring
+ (&temp_buf, &temp_buf_len, &temp_out_len, 1, pdu->contextEngineID,
+ pdu->contextEngineIDLen)) {
+ free(temp_buf);
+ return 0;
+ }
+ break;
+
+ /*
+ * Don't know how to handle this command - write the character itself.
+ */
+ default:
+ temp_buf[0] = fmt_cmd;
+ }
+
+ /*
+ * Output with correct justification, leading zeroes, etc.
+ */
+ return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
+ &temp_buf, options);
+}
+
+
+static int
+realloc_handle_trap_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu)
+
+ /*
+ * Function:
+ * Handle a format command that deals with the trap itself.
+ * Append the information to the buffer subject to the buffer's
+ * length limit.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ */
+{
+ netsnmp_variable_list *vars; /* variables assoc with trap */
+ char fmt_cmd = options->cmd; /* what we're outputting */
+ u_char *temp_buf = NULL;
+ size_t tbuf_len = 64, tout_len = 0;
+ const char *sep = separator;
+ const char *default_sep = "\t";
+ const char *default_alt_sep = ", ";
+
+ if ((temp_buf = (u_char *) calloc(tbuf_len, 1)) == NULL) {
+ return 0;
+ }
+
+ /*
+ * Decide exactly what to output.
+ */
+ switch (fmt_cmd) {
+ case CHR_TRAP_NUM:
+ /*
+ * Write the trap's number.
+ */
+ tout_len = sprintf((char*)temp_buf, "%ld", pdu->trap_type);
+ break;
+
+ case CHR_TRAP_DESC:
+ /*
+ * Write the trap's description.
+ */
+ tout_len =
+ sprintf((char*)temp_buf, "%s", trap_description(pdu->trap_type));
+ break;
+
+ case CHR_TRAP_STYPE:
+ /*
+ * Write the trap's subtype.
+ */
+ if (pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC) {
+ tout_len = sprintf((char*)temp_buf, "%ld", pdu->specific_type);
+ } else {
+ /*
+ * Get object ID for the trap.
+ */
+ size_t obuf_len = 64, oout_len = 0, trap_oid_len = 0;
+ oid trap_oid[MAX_OID_LEN + 2] = { 0 };
+ u_char *obuf = NULL;
+ char *ptr = NULL;
+
+ if ((obuf = (u_char *) calloc(obuf_len, 1)) == NULL) {
+ free(temp_buf);
+ return 0;
+ }
+
+ trap_oid_len = pdu->enterprise_length;
+ memcpy(trap_oid, pdu->enterprise, trap_oid_len * sizeof(oid));
+ if (trap_oid[trap_oid_len - 1] != 0) {
+ trap_oid[trap_oid_len] = 0;
+ trap_oid_len++;
+ }
+ trap_oid[trap_oid_len] = pdu->specific_type;
+ trap_oid_len++;
+
+ /*
+ * Find the element after the last dot.
+ */
+ if (!sprint_realloc_objid(&obuf, &obuf_len, &oout_len, 1,
+ trap_oid, trap_oid_len)) {
+ if (obuf != NULL) {
+ free(obuf);
+ }
+ free(temp_buf);
+ return 0;
+ }
+
+ ptr = strrchr((char *) obuf, '.');
+ if (ptr != NULL) {
+ if (!snmp_strcat
+ (&temp_buf, &tbuf_len, &tout_len, 1, (u_char *) ptr)) {
+ free(obuf);
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ free(obuf);
+ } else {
+ free(temp_buf);
+ temp_buf = obuf;
+ tbuf_len = obuf_len;
+ tout_len = oout_len;
+ }
+ }
+ break;
+
+ case CHR_TRAP_VARS:
+ /*
+ * Write the trap's variables.
+ */
+ if (!sep || !*sep)
+ sep = (options->alt_format ? default_alt_sep : default_sep);
+ for (vars = pdu->variables; vars != NULL;
+ vars = vars->next_variable) {
+ /*
+ * Print a separator between variables,
+ * (plus beforehand if the alt format is used)
+ */
+ if (options->alt_format ||
+ vars != pdu->variables ) {
+ if (!snmp_strcat(&temp_buf, &tbuf_len, &tout_len, 1, (const u_char *)sep)) {
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ }
+ if (!sprint_realloc_variable
+ (&temp_buf, &tbuf_len, &tout_len, 1, vars->name,
+ vars->name_length, vars)) {
+ if (temp_buf != NULL) {
+ free(temp_buf);
+ }
+ return 0;
+ }
+ }
+ break;
+
+ default:
+ /*
+ * Don't know how to handle this command - write the character itself.
+ */
+ temp_buf[0] = fmt_cmd;
+ }
+
+ /*
+ * Output with correct justification, leading zeroes, etc.
+ */
+ return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
+ &temp_buf, options);
+}
+
+static int
+realloc_handle_auth_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu)
+ /*
+ * Function:
+ * Handle a format command that deals with authentication
+ * information.
+ * Append the information to the buffer subject to the buffer's
+ * length limit.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ */
+{
+ char fmt_cmd = options->cmd; /* what we're outputting */
+ u_char *temp_buf = NULL;
+ size_t tbuf_len = 64;
+ unsigned int i;
+
+ if ((temp_buf = (u_char*)calloc(tbuf_len, 1)) == NULL) {
+ return 0;
+ }
+
+ switch (fmt_cmd) {
+
+ case CHR_SNMP_VERSION:
+ snprintf((char*)temp_buf, tbuf_len, "%ld", pdu->version);
+ break;
+
+ case CHR_SNMP_SECMOD:
+ snprintf((char*)temp_buf, tbuf_len, "%d", pdu->securityModel);
+ break;
+
+ case CHR_SNMP_USER:
+ switch ( pdu->version ) {
+#ifndef NETSNMP_DISABLE_SNMPV1
+ case SNMP_VERSION_1:
+#endif
+#ifndef NETSNMP_DISABLE_SNMPV2C
+ case SNMP_VERSION_2c:
+#endif
+#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
+ while ((*out_len + pdu->community_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ if (temp_buf)
+ free(temp_buf);
+ return 0;
+ }
+ }
+
+ for (i = 0; i < pdu->community_len; i++) {
+ if (isprint(pdu->community[i])) {
+ *(*buf + *out_len) = pdu->community[i];
+ } else {
+ *(*buf + *out_len) = '.';
+ }
+ (*out_len)++;
+ }
+ *(*buf + *out_len) = '\0';
+ break;
+#endif
+ default:
+ snprintf((char*)temp_buf, tbuf_len, "%s", pdu->securityName);
+ }
+ break;
+
+ default:
+ /*
+ * Don't know how to handle this command - write the character itself.
+ */
+ temp_buf[0] = fmt_cmd;
+ }
+
+ /*
+ * Output with correct justification, leading zeroes, etc.
+ */
+ return realloc_output_temp_bfr(buf, buf_len, out_len, allow_realloc,
+ &temp_buf, options);
+}
+
+static int
+realloc_handle_wrap_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc, netsnmp_pdu *pdu)
+{
+ size_t i = 0;
+
+ switch (pdu->command) {
+ case SNMP_MSG_TRAP:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "TRAP")) {
+ return 0;
+ }
+ break;
+ case SNMP_MSG_TRAP2:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "TRAP2")) {
+ return 0;
+ }
+ break;
+ case SNMP_MSG_INFORM:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "INFORM")) {
+ return 0;
+ }
+ break;
+ }
+
+ switch (pdu->version) {
+#ifndef NETSNMP_DISABLE_SNMPV1
+ case SNMP_VERSION_1:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", SNMP v1")) {
+ return 0;
+ }
+ break;
+#endif
+#ifndef NETSNMP_DISABLE_SNMPV2C
+ case SNMP_VERSION_2c:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", SNMP v2c")) {
+ return 0;
+ }
+ break;
+#endif
+ case SNMP_VERSION_3:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", SNMP v3")) {
+ return 0;
+ }
+ break;
+ }
+
+ switch (pdu->version) {
+#ifndef NETSNMP_DISABLE_SNMPV1
+ case SNMP_VERSION_1:
+#endif
+#ifndef NETSNMP_DISABLE_SNMPV2C
+ case SNMP_VERSION_2c:
+#endif
+#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", community ")) {
+ return 0;
+ }
+
+ while ((*out_len + pdu->community_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+
+ for (i = 0; i < pdu->community_len; i++) {
+ if (isprint(pdu->community[i])) {
+ *(*buf + *out_len) = pdu->community[i];
+ } else {
+ *(*buf + *out_len) = '.';
+ }
+ (*out_len)++;
+ }
+ *(*buf + *out_len) = '\0';
+ break;
+#endif
+ case SNMP_VERSION_3:
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", user ")) {
+ return 0;
+ }
+
+ while ((*out_len + pdu->securityNameLen + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+
+ for (i = 0; i < pdu->securityNameLen; i++) {
+ if (isprint((unsigned char)(pdu->securityName[i]))) {
+ *(*buf + *out_len) = pdu->securityName[i];
+ } else {
+ *(*buf + *out_len) = '.';
+ }
+ (*out_len)++;
+ }
+ *(*buf + *out_len) = '\0';
+
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ", context ")) {
+ return 0;
+ }
+
+ while ((*out_len + pdu->contextNameLen + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+
+ for (i = 0; i < pdu->contextNameLen; i++) {
+ if (isprint((unsigned char)(pdu->contextName[i]))) {
+ *(*buf + *out_len) = pdu->contextName[i];
+ } else {
+ *(*buf + *out_len) = '.';
+ }
+ (*out_len)++;
+ }
+ *(*buf + *out_len) = '\0';
+ }
+ return 1;
+}
+
+
+static int
+realloc_dispatch_format_cmd(u_char ** buf, size_t * buf_len,
+ size_t * out_len, int allow_realloc,
+ options_type * options, netsnmp_pdu *pdu,
+ netsnmp_transport *transport)
+
+ /*
+ * Function:
+ * Dispatch a format command to the appropriate command handler.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * options - options governing how to write the field
+ * pdu - information about this trap
+ * transport - the transport descriptor
+ */
+{
+ char fmt_cmd = options->cmd; /* for speed */
+
+ /*
+ * choose the appropriate command handler
+ */
+
+ if (is_cur_time_cmd(fmt_cmd) || is_up_time_cmd(fmt_cmd)) {
+ return realloc_handle_time_fmt(buf, buf_len, out_len,
+ allow_realloc, options, pdu);
+ } else if (is_agent_cmd(fmt_cmd) || is_pdu_ip_cmd(fmt_cmd)) {
+ return realloc_handle_ip_fmt(buf, buf_len, out_len, allow_realloc,
+ options, pdu, transport);
+ } else if (is_trap_cmd(fmt_cmd)) {
+ return realloc_handle_trap_fmt(buf, buf_len, out_len,
+ allow_realloc, options, pdu);
+ } else if (is_auth_cmd(fmt_cmd)) {
+ return realloc_handle_auth_fmt(buf, buf_len, out_len,
+ allow_realloc, options, pdu);
+ } else if (fmt_cmd == CHR_PDU_ENT || fmt_cmd == CHR_TRAP_CONTEXTID) {
+ return realloc_handle_ent_fmt(buf, buf_len, out_len, allow_realloc,
+ options, pdu);
+ } else if (fmt_cmd == CHR_PDU_WRAP) {
+ return realloc_handle_wrap_fmt(buf, buf_len, out_len,
+ allow_realloc, pdu);
+ } else {
+ /*
+ * unknown format command - just output the character
+ */
+ char fmt_cmd_string[2] = { 0, 0 };
+ fmt_cmd_string[0] = fmt_cmd;
+
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) fmt_cmd_string);
+ }
+}
+
+
+static int
+realloc_handle_backslash(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc, char fmt_cmd)
+
+ /*
+ * Function:
+ * Handle a character following a backslash. Append the resulting
+ * character to the buffer subject to the buffer's length limit.
+ * This routine currently isn't sophisticated enough to handle
+ * \nnn or \xhh formats.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * fmt_cmd - the character after the backslash
+ */
+{
+ char temp_bfr[3]; /* for bulding temporary strings */
+
+ /*
+ * select the proper output character(s)
+ */
+ switch (fmt_cmd) {
+ case 'a':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\a");
+ case 'b':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\b");
+ case 'f':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\f");
+ case 'n':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\n");
+ case 'r':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\r");
+ case 't':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\t");
+ case 'v':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\v");
+ case '\\':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\\");
+ case '?':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "?");
+ case '%':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "%");
+ case '\'':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\'");
+ case '"':
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\"");
+ default:
+ sprintf(temp_bfr, "\\%c", fmt_cmd);
+ return snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) temp_bfr);
+ }
+}
+
+
+int
+realloc_format_plain_trap(u_char ** buf, size_t * buf_len,
+ size_t * out_len, int allow_realloc,
+ netsnmp_pdu *pdu, netsnmp_transport *transport)
+
+ /*
+ * Function:
+ * Format the trap information in the default way and put the results
+ * into the buffer, truncating at the buffer's length limit. This
+ * routine returns 1 if the output was completed successfully or
+ * 0 if it is truncated due to a memory allocation failure.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * pdu - the pdu information
+ * transport - the transport descriptor
+ */
+{
+ time_t now; /* the current time */
+ struct tm *now_parsed; /* time in struct format */
+ char safe_bfr[200]; /* holds other strings */
+ struct in_addr *agent_inaddr = (struct in_addr *) pdu->agent_addr;
+ struct hostent *host = NULL; /* host name */
+ netsnmp_variable_list *vars; /* variables assoc with trap */
+
+ if (buf == NULL) {
+ return 0;
+ }
+
+ /*
+ * Print the current time. Since we don't know how long the buffer is,
+ * and snprintf isn't yet standard, build the timestamp in a separate
+ * buffer of guaranteed length and then copy it to the output buffer.
+ */
+ time(&now);
+ now_parsed = localtime(&now);
+ sprintf(safe_bfr, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d ",
+ now_parsed->tm_year + 1900, now_parsed->tm_mon + 1,
+ now_parsed->tm_mday, now_parsed->tm_hour,
+ now_parsed->tm_min, now_parsed->tm_sec);
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) safe_bfr)) {
+ return 0;
+ }
+
+ /*
+ * Get info about the sender.
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_APP_NUMERIC_IP)) {
+ host = netsnmp_gethostbyaddr((char *) pdu->agent_addr, 4, AF_INET);
+ }
+ if (host != (struct hostent *) NULL) {
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) host->h_name)) {
+ return 0;
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) " [")) {
+ return 0;
+ }
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) inet_ntoa(*agent_inaddr))) {
+ return 0;
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "] ")) {
+ return 0;
+ }
+ } else {
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) inet_ntoa(*agent_inaddr))) {
+ return 0;
+ }
+ }
+
+ /*
+ * Append PDU transport info.
+ */
+ if (transport != NULL && transport->f_fmtaddr != NULL) {
+ char *tstr =
+ transport->f_fmtaddr(transport, pdu->transport_data,
+ pdu->transport_data_length);
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "(via ")) {
+ if (tstr != NULL) {
+ free(tstr);
+ }
+ return 0;
+ }
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc, (u_char *)tstr)) {
+ if (tstr != NULL) {
+ free(tstr);
+ }
+ return 0;
+ }
+ if (tstr != NULL) {
+ free(tstr);
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ") ")) {
+ return 0;
+ }
+ }
+
+ /*
+ * Add security wrapper information.
+ */
+ if (!realloc_handle_wrap_fmt
+ (buf, buf_len, out_len, allow_realloc, pdu)) {
+ return 0;
+ }
+
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n\t")) {
+ return 0;
+ }
+
+ /*
+ * Add enterprise information.
+ */
+ if (!sprint_realloc_objid(buf, buf_len, out_len, allow_realloc,
+ pdu->enterprise, pdu->enterprise_length)) {
+ return 0;
+ }
+
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc, (const u_char *) " ")) {
+ return 0;
+ }
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *)trap_description(pdu->trap_type))) {
+ return 0;
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) " Trap (")) {
+ return 0;
+ }
+
+ /*
+ * Handle enterprise specific traps.
+ */
+ if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
+ size_t obuf_len = 64, oout_len = 0, trap_oid_len = 0;
+ oid trap_oid[MAX_OID_LEN + 2] = { 0 };
+ char *ent_spec_code = NULL;
+ u_char *obuf = NULL;
+
+ if ((obuf = (u_char *) calloc(obuf_len, 1)) == NULL) {
+ return 0;
+ }
+
+ /*
+ * Get object ID for the trap.
+ */
+ trap_oid_len = pdu->enterprise_length;
+ memcpy(trap_oid, pdu->enterprise, trap_oid_len * sizeof(oid));
+ if (trap_oid[trap_oid_len - 1] != 0) {
+ trap_oid[trap_oid_len] = 0;
+ trap_oid_len++;
+ }
+ trap_oid[trap_oid_len] = pdu->specific_type;
+ trap_oid_len++;
+
+ /*
+ * Find the element after the last dot.
+ */
+ if (!sprint_realloc_objid(&obuf, &obuf_len, &oout_len, 1,
+ trap_oid, trap_oid_len)) {
+ if (obuf != NULL) {
+ free(obuf);
+ }
+ return 0;
+ }
+ ent_spec_code = strrchr((char *) obuf, '.');
+ if (ent_spec_code != NULL) {
+ ent_spec_code++;
+ } else {
+ ent_spec_code = (char *) obuf;
+ }
+
+ /*
+ * Print trap info.
+ */
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ent_spec_code)) {
+ free(obuf);
+ return 0;
+ }
+ free(obuf);
+ } else {
+ /*
+ * Handle traps that aren't enterprise specific.
+ */
+ sprintf(safe_bfr, "%ld", pdu->specific_type);
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) safe_bfr)) {
+ return 0;
+ }
+ }
+
+ /*
+ * Finish the line.
+ */
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) ") Uptime: ")) {
+ return 0;
+ }
+ if (!snmp_strcat(buf, buf_len, out_len, allow_realloc,
+ (const u_char *) uptime_string(pdu->time,
+ safe_bfr))) {
+ return 0;
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n")) {
+ return 0;
+ }
+
+ /*
+ * Finally, output the PDU variables.
+ */
+ for (vars = pdu->variables; vars != NULL; vars = vars->next_variable) {
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc,
+ (const u_char *) "\t")) {
+ return 0;
+ }
+ if (!sprint_realloc_variable(buf, buf_len, out_len, allow_realloc,
+ vars->name, vars->name_length,
+ vars)) {
+ return 0;
+ }
+ }
+ if (!snmp_strcat
+ (buf, buf_len, out_len, allow_realloc, (const u_char *) "\n")) {
+ return 0;
+ }
+
+ /*
+ * String is already null-terminated. That's all folks!
+ */
+ return 1;
+}
+
+
+int
+realloc_format_trap(u_char ** buf, size_t * buf_len, size_t * out_len,
+ int allow_realloc, const char *format_str,
+ netsnmp_pdu *pdu, netsnmp_transport *transport)
+
+ /*
+ * Function:
+ * Format the trap information for display in a log. Place the results
+ * in the specified buffer (truncating to the length of the buffer).
+ * Returns the number of characters it put in the buffer.
+ *
+ * Input Parameters:
+ * buf, buf_len, out_len, allow_realloc - standard relocatable
+ * buffer parameters
+ * format_str - specifies how to format the trap info
+ * pdu - the pdu information
+ * transport - the transport descriptor
+ */
+{
+ unsigned long fmt_idx = 0; /* index into the format string */
+ options_type options; /* formatting options */
+ parse_state_type state = PARSE_NORMAL; /* state of the parser */
+ char next_chr; /* for speed */
+ int reset_options = TRUE; /* reset opts on next NORMAL state */
+
+ if (buf == NULL) {
+ return 0;
+ }
+
+ memset(separator, 0, sizeof(separator));
+ /*
+ * Go until we reach the end of the format string:
+ */
+ for (fmt_idx = 0; format_str[fmt_idx] != '\0'; fmt_idx++) {
+ next_chr = format_str[fmt_idx];
+ switch (state) {
+ case PARSE_NORMAL:
+ /*
+ * Looking for next character.
+ */
+ if (reset_options) {
+ init_options(&options);
+ reset_options = FALSE;
+ }
+ if (next_chr == '\\') {
+ state = PARSE_BACKSLASH;
+ } else if (next_chr == CHR_FMT_DELIM) {
+ state = PARSE_IN_FORMAT;
+ } else {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = next_chr;
+ (*out_len)++;
+ }
+ break;
+
+ case PARSE_GET_SEPARATOR:
+ /*
+ * Parse the separator character
+ * XXX - Possibly need to handle quoted strings ??
+ */
+ { char *sep = separator;
+ size_t i, j;
+ i = sizeof(separator);
+ j = 0;
+ memset(separator, 0, i);
+ while (j < i && next_chr && next_chr != CHR_FMT_DELIM) {
+ if (next_chr == '\\') {
+ /*
+ * Handle backslash interpretation
+ * Print to "separator" string rather than the output buffer
+ * (a bit of a hack, but it should work!)
+ */
+ next_chr = format_str[++fmt_idx];
+ if (!realloc_handle_backslash
+ ((u_char **)&sep, &i, &j, 0, next_chr)) {
+ return 0;
+ }
+ } else {
+ separator[j++] = next_chr;
+ }
+ next_chr = format_str[++fmt_idx];
+ }
+ }
+ state = PARSE_IN_FORMAT;
+ break;
+
+ case PARSE_BACKSLASH:
+ /*
+ * Found a backslash.
+ */
+ if (!realloc_handle_backslash
+ (buf, buf_len, out_len, allow_realloc, next_chr)) {
+ return 0;
+ }
+ state = PARSE_NORMAL;
+ break;
+
+ case PARSE_IN_FORMAT:
+ /*
+ * In a format command.
+ */
+ reset_options = TRUE;
+ if (next_chr == CHR_LEFT_JUST) {
+ options.left_justify = TRUE;
+ } else if (next_chr == CHR_LEAD_ZERO) {
+ options.leading_zeroes = TRUE;
+ } else if (next_chr == CHR_ALT_FORM) {
+ options.alt_format = TRUE;
+ } else if (next_chr == CHR_FIELD_SEP) {
+ state = PARSE_GET_PRECISION;
+ } else if (next_chr == CHR_TRAP_VARSEP) {
+ state = PARSE_GET_SEPARATOR;
+ } else if ((next_chr >= '1') && (next_chr <= '9')) {
+ options.width =
+ ((unsigned long) next_chr) - ((unsigned long) '0');
+ state = PARSE_GET_WIDTH;
+ } else if (is_fmt_cmd(next_chr)) {
+ options.cmd = next_chr;
+ if (!realloc_dispatch_format_cmd
+ (buf, buf_len, out_len, allow_realloc, &options, pdu,
+ transport)) {
+ return 0;
+ }
+ state = PARSE_NORMAL;
+ } else {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = next_chr;
+ (*out_len)++;
+ state = PARSE_NORMAL;
+ }
+ break;
+
+ case PARSE_GET_WIDTH:
+ /*
+ * Parsing a width field.
+ */
+ reset_options = TRUE;
+ if (isdigit((unsigned char)(next_chr))) {
+ options.width *= 10;
+ options.width +=
+ (unsigned long) next_chr - (unsigned long) '0';
+ } else if (next_chr == CHR_FIELD_SEP) {
+ state = PARSE_GET_PRECISION;
+ } else if (is_fmt_cmd(next_chr)) {
+ options.cmd = next_chr;
+ if (!realloc_dispatch_format_cmd
+ (buf, buf_len, out_len, allow_realloc, &options, pdu,
+ transport)) {
+ return 0;
+ }
+ state = PARSE_NORMAL;
+ } else {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = next_chr;
+ (*out_len)++;
+ state = PARSE_NORMAL;
+ }
+ break;
+
+ case PARSE_GET_PRECISION:
+ /*
+ * Parsing a precision field.
+ */
+ reset_options = TRUE;
+ if (isdigit((unsigned char)(next_chr))) {
+ if (options.precision == UNDEF_PRECISION) {
+ options.precision =
+ (unsigned long) next_chr - (unsigned long) '0';
+ } else {
+ options.precision *= 10;
+ options.precision +=
+ (unsigned long) next_chr - (unsigned long) '0';
+ }
+ } else if (is_fmt_cmd(next_chr)) {
+ options.cmd = next_chr;
+ if ((options.precision != UNDEF_PRECISION) &&
+ (options.width < (size_t)options.precision)) {
+ options.width = (size_t)options.precision;
+ }
+ if (!realloc_dispatch_format_cmd
+ (buf, buf_len, out_len, allow_realloc, &options, pdu,
+ transport)) {
+ return 0;
+ }
+ state = PARSE_NORMAL;
+ } else {
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = next_chr;
+ (*out_len)++;
+ state = PARSE_NORMAL;
+ }
+ break;
+
+ default:
+ /*
+ * Unknown state.
+ */
+ reset_options = TRUE;
+ if ((*out_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+ return 0;
+ }
+ }
+ *(*buf + *out_len) = next_chr;
+ (*out_len)++;
+ state = PARSE_NORMAL;
+ }
+ }
+
+ *(*buf + *out_len) = '\0';
+ return 1;
+}
diff --git a/apps/snmptrapd_log.h b/apps/snmptrapd_log.h
new file mode 100644
index 0000000..e8d797a
--- /dev/null
+++ b/apps/snmptrapd_log.h
@@ -0,0 +1,18 @@
+#ifndef _SNMPTRAPD_LOG_H
+#define _SNMPTRAPD_LOG_H
+
+#include "snmptrapd_ds.h"
+
+int realloc_format_trap(u_char ** buf, size_t * buf_len,
+ size_t * out_len, int allow_realloc,
+ const char *format_str,
+ netsnmp_pdu *pdu,
+ struct netsnmp_transport_s *transport);
+
+int realloc_format_plain_trap(u_char ** buf, size_t * buf_len,
+ size_t * out_len,
+ int allow_realloc,
+ netsnmp_pdu *pdu,
+ struct netsnmp_transport_s
+ *transport);
+#endif /* _SNMPTRAPD_LOG_H */
diff --git a/apps/snmptrapd_sql.c b/apps/snmptrapd_sql.c
new file mode 100644
index 0000000..ccba258
--- /dev/null
+++ b/apps/snmptrapd_sql.c
@@ -0,0 +1,1118 @@
+/*
+ * File : snmptrapd_sql
+ * Author : Robert Story
+ *
+ * Copyright © 2009 Science Logic, Inc. All rights reserved.
+ * Use is subject to license terms specified in the COPYING file
+ * distributed with the Net-SNMP package.
+ *
+ * This file implements a handler for snmptrapd which will cache incoming
+ * traps and then write them to a MySQL database.
+ *
+ */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-features.h>
+
+#ifdef NETSNMP_USE_MYSQL
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "snmptrapd_handlers.h"
+#include "snmptrapd_auth.h"
+#include "snmptrapd_log.h"
+
+/*
+ * SQL includes
+ */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#include <mysql/my_global.h>
+#include <mysql/my_sys.h>
+#include <mysql/mysql.h>
+#include <mysql/errmsg.h>
+
+netsnmp_feature_require(container_fifo)
+
+/*
+ * define a structure to hold all the file globals
+ */
+typedef struct netsnmp_sql_globals_t {
+ char *host_name; /* server host (def=localhost) */
+ char *user_name; /* username (def=login name) */
+ char *password; /* password (def=none) */
+ u_int port_num; /* port number (built-in value) */
+ char *socket_name; /* socket name (built-in value) */
+ const char *db_name; /* database name (def=none) */
+ u_int flags; /* connection flags (none) */
+ MYSQL *conn; /* connection */
+ u_char connected; /* connected flag */
+ const char *groups[3];
+ MYSQL_STMT *trap_stmt, *vb_stmt; /* prepared statements */
+ u_int alarm_id; /* id of periodic save alarm */
+ netsnmp_container *queue; /* container; traps pending database write */
+ u_int queue_max; /* auto save queue when it gets this big */
+ int queue_interval; /* auto save every N seconds */
+} netsnmp_sql_globals;
+
+static netsnmp_sql_globals _sql = {
+ NULL, /* host */
+ NULL, /* username */
+ NULL, /* password */
+ 0, /* port */
+ NULL, /* socket */
+ "net_snmp", /* database */
+ 0, /* conn flags */
+ NULL, /* connection */
+ 0, /* connected */
+ { "client", "snmptrapd", NULL }, /* groups to read from .my.cnf */
+ NULL, /* trap_stmt */
+ NULL, /* vb_stmt */
+ 0, /* alarm_id */
+ NULL, /* queue */
+ 1, /* queue_max */
+ -1 /* queue_interval */
+};
+
+/*
+ * log traps as text, or binary blobs?
+ */
+#define NETSNMP_MYSQL_TRAP_VALUE_TEXT 1
+
+/*
+ * We will be using prepared statements for performance reasons. This
+ * requires a sql bind structure for each cell to be inserted in the
+ * database. We will be using 2 global static structures to bind to,
+ * and a netsnmp container to store the necessary data until it is
+ * written to the database. Fixed size buffers are also used to
+ * simplify memory management.
+ */
+/** enums for the trap fields to be bound */
+enum{
+ TBIND_DATE = 0, /* time received */
+ TBIND_HOST, /* src ip */
+ TBIND_USER, /* auth/user information */
+ TBIND_TYPE, /* pdu type */
+ TBIND_VER, /* snmp version */
+ TBIND_REQID, /* request id */
+ TBIND_OID, /* trap OID */
+ TBIND_TRANSPORT, /* transport */
+ TBIND_SECURITY_MODEL, /* security model */
+ TBIND_v3_MSGID, /* v3 msg id */
+ TBIND_v3_SECURITY_LEVEL, /* security level */
+ TBIND_v3_CONTEXT_NAME, /* context */
+ TBIND_v3_CONTEXT_ENGINE, /* context engine id */
+ TBIND_v3_SECURITY_NAME, /* security name */
+ TBIND_v3_SECURITY_ENGINE, /* security engine id */
+ TBIND_MAX
+};
+
+/** enums for the varbind fields to be bound */
+enum {
+ VBIND_ID = 0, /* trap_id */
+ VBIND_OID, /* varbind oid */
+ VBIND_TYPE, /* varbind type */
+ VBIND_VAL, /* varbind value */
+ VBIND_MAX
+};
+
+/** buffer struct for varbind data */
+typedef struct sql_vb_buf_t {
+
+ char *oid;
+ u_long oid_len;
+
+ u_char *val;
+ u_long val_len;
+
+ uint16_t type;
+
+} sql_vb_buf;
+
+/** buffer struct for trap data */
+typedef struct sql_buf_t {
+ char *host;
+ u_long host_len;
+
+ char *oid;
+ u_long oid_len;
+
+ char *user;
+ u_long user_len;
+
+ MYSQL_TIME time;
+ uint16_t version, type;
+ uint32_t reqid;
+
+ char *transport;
+ u_long transport_len;
+
+ uint16_t security_level, security_model;
+ uint32_t msgid;
+
+ char *context;
+ u_long context_len;
+
+ char *context_engine;
+ u_long context_engine_len;
+
+ char *security_name;
+ u_long security_name_len;
+
+ char *security_engine;
+ u_long security_engine_len;
+
+ netsnmp_container *varbinds;
+
+ char logged;
+} sql_buf;
+
+/*
+ * static bind structures, plus 2 static buffers to bind to.
+ */
+static MYSQL_BIND _tbind[TBIND_MAX], _vbind[VBIND_MAX];
+static my_bool _no_v3;
+
+static void _sql_process_queue(u_int dontcare, void *meeither);
+
+/*
+ * parse the sqlMaxQueue configuration token
+ */
+static void
+_parse_queue_fmt(const char *token, char *cptr)
+{
+ _sql.queue_max = atoi(cptr);
+ DEBUGMSGTL(("sql:queue","queue max now %d\n", _sql.queue_max));
+}
+
+/*
+ * parse the sqlSaveInterval configuration token
+ */
+static void
+_parse_interval_fmt(const char *token, char *cptr)
+{
+ _sql.queue_interval = atoi(cptr);
+ DEBUGMSGTL(("sql:queue","queue interval now %d seconds\n",
+ _sql.queue_interval));
+}
+
+/*
+ * register sql related configuration tokens
+ */
+void
+snmptrapd_register_sql_configs( void )
+{
+ register_config_handler("snmptrapd", "sqlMaxQueue",
+ _parse_queue_fmt, NULL, "integer");
+ register_config_handler("snmptrapd", "sqlSaveInterval",
+ _parse_interval_fmt, NULL, "seconds");
+}
+
+static void
+netsnmp_sql_disconnected(void)
+{
+ DEBUGMSGTL(("sql:connection","disconnected\n"));
+
+ _sql.connected = 0;
+
+ /** release prepared statements */
+ if (_sql.trap_stmt) {
+ mysql_stmt_close(_sql.trap_stmt);
+ _sql.trap_stmt = NULL;
+ }
+ if (_sql.vb_stmt) {
+ mysql_stmt_close(_sql.vb_stmt);
+ _sql.vb_stmt = NULL;
+ }
+}
+
+/*
+ * convenience function to log mysql errors
+ */
+static void
+netsnmp_sql_error(const char *message)
+{
+ u_int err = mysql_errno(_sql.conn);
+ snmp_log(LOG_ERR, "%s\n", message);
+ if (_sql.conn != NULL) {
+#if MYSQL_VERSION_ID >= 40101
+ snmp_log(LOG_ERR, "Error %u (%s): %s\n",
+ err, mysql_sqlstate(_sql.conn), mysql_error(_sql.conn));
+#else
+ snmp(LOG_ERR, "Error %u: %s\n",
+ mysql_errno(_sql.conn), mysql_error(_sql.conn));
+#endif
+ }
+ if (CR_SERVER_GONE_ERROR == err)
+ netsnmp_sql_disconnected();
+}
+
+/*
+ * convenience function to log mysql statement errors
+ */
+static void
+netsnmp_sql_stmt_error (MYSQL_STMT *stmt, const char *message)
+{
+ u_int err = mysql_errno(_sql.conn);
+
+ snmp_log(LOG_ERR, "%s\n", message);
+ if (stmt) {
+ snmp_log(LOG_ERR, "SQL Error %u (%s): %s\n",
+ mysql_stmt_errno(stmt), mysql_stmt_sqlstate(stmt),
+ mysql_stmt_error(stmt));
+ }
+
+ if (CR_SERVER_GONE_ERROR == err)
+ netsnmp_sql_disconnected();
+}
+
+/*
+ * sql cleanup function, called at exit
+ */
+static void
+netsnmp_mysql_cleanup(void)
+{
+ DEBUGMSGTL(("sql:cleanup"," called\n"));
+
+ /** unregister alarm */
+ if (_sql.alarm_id)
+ snmp_alarm_unregister(_sql.alarm_id);
+
+ /** save any queued traps */
+ if (CONTAINER_SIZE(_sql.queue))
+ _sql_process_queue(0,NULL);
+
+ CONTAINER_FREE(_sql.queue);
+ _sql.queue = NULL;
+
+ if (_sql.trap_stmt) {
+ mysql_stmt_close(_sql.trap_stmt);
+ _sql.trap_stmt = NULL;
+ }
+ if (_sql.vb_stmt) {
+ mysql_stmt_close(_sql.vb_stmt);
+ _sql.vb_stmt = NULL;
+ }
+
+ /** disconnect from server */
+ netsnmp_sql_disconnected();
+
+ if (_sql.conn) {
+ mysql_close(_sql.conn);
+ _sql.conn = NULL;
+ }
+
+ mysql_library_end();
+}
+
+/*
+ * setup (initialize, prepare and bind) a prepared statement
+ */
+static int
+netsnmp_mysql_bind(const char *text, size_t text_size, MYSQL_STMT **stmt,
+ MYSQL_BIND *bind)
+{
+ if ((NULL == text) || (NULL == stmt) || (NULL == bind)) {
+ snmp_log(LOG_ERR,"invalid paramaters to netsnmp_mysql_bind()\n");
+ return -1;
+ }
+
+ *stmt = mysql_stmt_init(_sql.conn);
+ if (NULL == *stmt) {
+ netsnmp_sql_error("could not initialize trap statement handler");
+ return -1;
+ }
+
+ if (mysql_stmt_prepare(*stmt, text, text_size) != 0) {
+ netsnmp_sql_stmt_error(*stmt, "Could not prepare INSERT");
+ mysql_stmt_close(*stmt);
+ *stmt = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * connect to the database and do initial setup
+ */
+static int
+netsnmp_mysql_connect(void)
+{
+ char trap_stmt[] = "INSERT INTO notifications "
+ "(date_time, host, auth, type, version, request_id, snmpTrapOID, transport, security_model, v3msgid, v3security_level, v3context_name, v3context_engine, v3security_name, v3security_engine) "
+ "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+ char vb_stmt[] = "INSERT INTO varbinds "
+ "(trap_id, oid, type, value) VALUES (?,?,?,?)";
+
+ /** initialize connection handler */
+ if (_sql.connected)
+ return 0;
+
+ DEBUGMSGTL(("sql:connection","connecting\n"));
+
+ /** connect to server */
+ if (mysql_real_connect (_sql.conn, _sql.host_name, _sql.user_name,
+ _sql.password, _sql.db_name, _sql.port_num,
+ _sql.socket_name, _sql.flags) == NULL) {
+ netsnmp_sql_error("mysql_real_connect() failed");
+ goto err;
+ }
+ _sql.connected = 1;
+
+ /** disable autocommit */
+ if(0 != mysql_autocommit(_sql.conn, 0)) {
+ netsnmp_sql_error("mysql_autocommit(0) failed");
+ goto err;
+ }
+
+ netsnmp_assert((_sql.trap_stmt == NULL) && (_sql.vb_stmt == NULL));
+
+ /** prepared statement for inserts */
+ if (0 != netsnmp_mysql_bind(trap_stmt,sizeof(trap_stmt), &_sql.trap_stmt,
+ _tbind))
+ goto err;
+
+ if (0 != netsnmp_mysql_bind(vb_stmt,sizeof(vb_stmt),&_sql.vb_stmt,
+ _vbind)) {
+ mysql_stmt_close(_sql.trap_stmt);
+ _sql.trap_stmt = NULL;
+ goto err;
+ }
+
+ return 0;
+
+ err:
+ if (_sql.connected)
+ _sql.connected = 0;
+
+ return -1;
+}
+
+/** one-time initialization for mysql */
+int
+netsnmp_mysql_init(void)
+{
+ int not_argc = 0, i;
+ char *not_args[] = { NULL };
+ char **not_argv = not_args;
+ netsnmp_trapd_handler *traph;
+
+ DEBUGMSGTL(("sql:init","called\n"));
+
+ /** negative or 0 interval disables sql logging */
+ if (_sql.queue_interval <= 0) {
+ DEBUGMSGTL(("sql:init",
+ "mysql not enabled (sqlSaveInterval is <= 0)\n"));
+ return 0;
+ }
+
+ /** create queue for storing traps til they are written to the db */
+ _sql.queue = netsnmp_container_find("fifo");
+ if (NULL == _sql.queue) {
+ snmp_log(LOG_ERR, "Could not allocate sql buf container\n");
+ return -1;
+ }
+
+#ifdef HAVE_BROKEN_LIBMYSQLCLIENT
+ my_init();
+#else
+ MY_INIT("snmptrapd");
+#endif
+
+ /** load .my.cnf values */
+ load_defaults ("my", _sql.groups, &not_argc, &not_argv);
+ for(i=0; i < not_argc; ++i) {
+ if (NULL == not_argv[i])
+ continue;
+ if (strncmp(not_argv[i],"--password=",11) == 0)
+ _sql.password = &not_argv[i][11];
+ else if (strncmp(not_argv[i],"--host=",7) == 0)
+ _sql.host_name = &not_argv[i][7];
+ else if (strncmp(not_argv[i],"--user=",7) == 0)
+ _sql.user_name = &not_argv[i][7];
+ else if (strncmp(not_argv[i],"--port=",7) == 0)
+ _sql.port_num = atoi(&not_argv[i][7]);
+ else if (strncmp(not_argv[i],"--socket=",9) == 0)
+ _sql.socket_name = &not_argv[i][9];
+ else
+ snmp_log(LOG_WARNING, "unknown argument[%d] %s\n", i, not_argv[i]);
+ }
+
+ /** init bind structures */
+ memset(_tbind, 0x0, sizeof(_tbind));
+ memset(_vbind, 0x0, sizeof(_vbind));
+
+ /** trap static bindings */
+ _tbind[TBIND_HOST].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_HOST].length = &_tbind[TBIND_HOST].buffer_length;
+
+ _tbind[TBIND_OID].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_OID].length = &_tbind[TBIND_OID].buffer_length;
+
+ _tbind[TBIND_REQID].buffer_type = MYSQL_TYPE_LONG;
+ _tbind[TBIND_REQID].is_unsigned = 1;
+
+ _tbind[TBIND_VER].buffer_type = MYSQL_TYPE_SHORT;
+ _tbind[TBIND_VER].is_unsigned = 1;
+
+ _tbind[TBIND_TYPE].buffer_type = MYSQL_TYPE_SHORT;
+ _tbind[TBIND_TYPE].is_unsigned = 1;
+
+ _tbind[TBIND_DATE].buffer_type = MYSQL_TYPE_DATETIME;
+
+ _tbind[TBIND_USER].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_USER].length = &_tbind[TBIND_USER].buffer_length;
+
+ _tbind[TBIND_TRANSPORT].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_TRANSPORT].length = &_tbind[TBIND_TRANSPORT].buffer_length;
+
+ _tbind[TBIND_SECURITY_MODEL].buffer_type = MYSQL_TYPE_SHORT;
+ _tbind[TBIND_SECURITY_MODEL].is_unsigned = 1;
+
+ _tbind[TBIND_v3_MSGID].buffer_type = MYSQL_TYPE_LONG;
+ _tbind[TBIND_v3_MSGID].is_unsigned = 1;
+ _tbind[TBIND_v3_SECURITY_LEVEL].buffer_type = MYSQL_TYPE_SHORT;
+ _tbind[TBIND_v3_SECURITY_LEVEL].is_unsigned = 1;
+ _tbind[TBIND_v3_CONTEXT_NAME].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_v3_CONTEXT_ENGINE].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_v3_SECURITY_NAME].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_v3_SECURITY_NAME].length =
+ &_tbind[TBIND_v3_SECURITY_NAME].buffer_length;
+ _tbind[TBIND_v3_CONTEXT_NAME].length =
+ &_tbind[TBIND_v3_CONTEXT_NAME].buffer_length;
+ _tbind[TBIND_v3_SECURITY_ENGINE].buffer_type = MYSQL_TYPE_STRING;
+ _tbind[TBIND_v3_SECURITY_ENGINE].length =
+ &_tbind[TBIND_v3_SECURITY_ENGINE].buffer_length;
+ _tbind[TBIND_v3_CONTEXT_ENGINE].length =
+ &_tbind[TBIND_v3_CONTEXT_ENGINE].buffer_length;
+
+ _tbind[TBIND_v3_MSGID].is_null =
+ _tbind[TBIND_v3_SECURITY_LEVEL].is_null =
+ _tbind[TBIND_v3_CONTEXT_NAME].is_null =
+ _tbind[TBIND_v3_CONTEXT_ENGINE].is_null =
+ _tbind[TBIND_v3_SECURITY_NAME].is_null =
+ _tbind[TBIND_v3_SECURITY_ENGINE].is_null = &_no_v3;
+
+ /** variable static bindings */
+ _vbind[VBIND_ID].buffer_type = MYSQL_TYPE_LONG;
+ _vbind[VBIND_ID].is_unsigned = 1;
+
+ _vbind[VBIND_OID].buffer_type = MYSQL_TYPE_STRING;
+ _vbind[VBIND_OID].length = &_vbind[VBIND_OID].buffer_length;
+
+ _vbind[VBIND_TYPE].buffer_type = MYSQL_TYPE_SHORT;
+ _vbind[VBIND_TYPE].is_unsigned = 1;
+
+#ifdef NETSNMP_MYSQL_TRAP_VALUE_TEXT
+ _vbind[VBIND_VAL].buffer_type = MYSQL_TYPE_STRING;
+#else
+ _vbind[VBIND_VAL].buffer_type = MYSQL_TYPE_BLOB;
+#endif
+ _vbind[VBIND_VAL].length = &_vbind[VBIND_VAL].buffer_length;
+
+ _sql.conn = mysql_init (NULL);
+ if (_sql.conn == NULL) {
+ netsnmp_sql_error("mysql_init() failed (out of memory?)");
+ return -1;
+ }
+
+ /** try to connect; we'll try again later if we fail */
+ (void) netsnmp_mysql_connect();
+
+ /** register periodic queue save */
+ _sql.alarm_id = snmp_alarm_register(_sql.queue_interval, /* seconds */
+ 1, /* repeat */
+ _sql_process_queue, /* function */
+ NULL); /* client args */
+
+ /** add handler */
+ traph = netsnmp_add_global_traphandler(NETSNMPTRAPD_PRE_HANDLER,
+ mysql_handler);
+ if (NULL == traph) {
+ snmp_log(LOG_ERR, "Could not allocate sql trap handler\n");
+ return -1;
+ }
+ traph->authtypes = TRAP_AUTH_LOG;
+
+ atexit(netsnmp_mysql_cleanup);
+ return 0;
+}
+
+/*
+ * log CSV version of trap.
+ * dontcare param is there so this function can be passed directly
+ * to CONTAINER_FOR_EACH.
+ */
+static void
+_sql_log(sql_buf *sqlb, void* dontcare)
+{
+ netsnmp_iterator *it;
+ sql_vb_buf *sqlvb;
+
+ if ((NULL == sqlb) || sqlb->logged)
+ return;
+
+ /*
+ * log trap info
+ * nothing done to protect against data insertion attacks with
+ * respect to bad data (commas, newlines, etc)
+ */
+ snmp_log(LOG_ERR,
+ "trap:%d-%d-%d %d:%d:%d,%s,%d,%d,%d,%s,%s,%d,%d,%d,%s,%s,%s,%s\n",
+ sqlb->time.year,sqlb->time.month,sqlb->time.day,
+ sqlb->time.hour,sqlb->time.minute,sqlb->time.second,
+ sqlb->user,
+ sqlb->type, sqlb->version, sqlb->reqid, sqlb->oid,
+ sqlb->transport, sqlb->security_model, sqlb->msgid,
+ sqlb->security_level, sqlb->context,
+ sqlb->context_engine, sqlb->security_name,
+ sqlb->security_engine);
+
+ sqlb->logged = 1; /* prevent multiple logging */
+
+ it = CONTAINER_ITERATOR(sqlb->varbinds);
+ if (NULL == it) {
+ snmp_log(LOG_ERR,
+ "error creating iterator; incomplete trap logged\n");
+ return;
+ }
+
+ /** log varbind info */
+ for( sqlvb = ITERATOR_FIRST(it); sqlvb; sqlvb = ITERATOR_NEXT(it)) {
+#ifdef NETSNMP_MYSQL_TRAP_VALUE_TEXT
+ snmp_log(LOG_ERR,"varbind:%s,%s\n", sqlvb->oid, sqlvb->val);
+#else
+ char *hex;
+ int len = binary_to_hex(sqlvb->val, sqlvb->val_len, &hex);
+ if (hex) {
+ snmp_log(LOG_ERR,"varbind:%d,%s,%s\n", sqlvb->oid, hex);
+ free(hex);
+ }
+ else {
+ snmp_log(LOG_ERR,"malloc failed for varbind hex value\n");
+ snmp_log(LOG_ERR,"varbind:%s,\n", sqlvb->oid);
+ }
+#endif
+ }
+ ITERATOR_RELEASE(it);
+
+}
+
+/*
+ * free a buffer
+ * dontcare param is there so this function can be passed directly
+ * to CONTAINER_FOR_EACH.
+ */
+static void
+_sql_vb_buf_free(sql_vb_buf *sqlvb, void* dontcare)
+{
+ if (NULL == sqlvb)
+ return;
+
+ SNMP_FREE(sqlvb->oid);
+ SNMP_FREE(sqlvb->val);
+
+ free(sqlvb);
+}
+
+/*
+ * free a buffer
+ * dontcare param is there so this function can be passed directly
+ * to CONTAINER_FOR_EACH.
+ */
+static void
+_sql_buf_free(sql_buf *sqlb, void* dontcare)
+{
+ if (NULL == sqlb)
+ return;
+
+ /** do varbinds first */
+ if (sqlb->varbinds) {
+ CONTAINER_CLEAR(sqlb->varbinds,
+ (netsnmp_container_obj_func*)_sql_vb_buf_free, NULL);
+ CONTAINER_FREE(sqlb->varbinds);
+ }
+
+ SNMP_FREE(sqlb->host);
+ SNMP_FREE(sqlb->oid);
+ SNMP_FREE(sqlb->user);
+
+ SNMP_FREE(sqlb->context);
+ SNMP_FREE(sqlb->security_name);
+ SNMP_FREE(sqlb->context_engine);
+ SNMP_FREE(sqlb->security_engine);
+ SNMP_FREE(sqlb->transport);
+
+ free(sqlb);
+}
+
+/*
+ * allocate buffer to store trap and varbinds
+ */
+static sql_buf *
+_sql_buf_get(void)
+{
+ sql_buf *sqlb;
+
+ /** buffer for trap info */
+ sqlb = SNMP_MALLOC_TYPEDEF(sql_buf);
+ if (NULL == sqlb)
+ return NULL;
+
+ /** fifo for varbinds */
+ sqlb->varbinds = netsnmp_container_find("fifo");
+ if (NULL == sqlb->varbinds) {
+ free(sqlb);
+ return NULL;
+ }
+
+ return sqlb;
+}
+
+/*
+ * save info from incoming trap
+ *
+ * return 0 on success, anything else is an error
+ */
+static int
+_sql_save_trap_info(sql_buf *sqlb, netsnmp_pdu *pdu,
+ netsnmp_transport *transport)
+{
+ static oid trapoids[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5, 0 };
+ oid *trap_oid, tmp_oid[MAX_OID_LEN];
+ time_t now;
+ struct tm *cur_time;
+ size_t tmp_size;
+ size_t buf_host_len_t, buf_oid_len_t, buf_user_len_t;
+ int oid_overflow, trap_oid_len;
+ netsnmp_variable_list *vars;
+
+ if ((NULL == sqlb) || (NULL == pdu) || (NULL == transport))
+ return -1;
+
+ DEBUGMSGTL(("sql:queue", "queueing incoming trap\n"));
+
+ /** time */
+ (void) time(&now);
+ cur_time = localtime(&now);
+ sqlb->time.year = cur_time->tm_year + 1900;
+ sqlb->time.month = cur_time->tm_mon + 1;
+ sqlb->time.day = cur_time->tm_mday;
+ sqlb->time.hour = cur_time->tm_hour;
+ sqlb->time.minute = cur_time->tm_min;
+ sqlb->time.second = cur_time->tm_sec;
+ sqlb->time.second_part = 0;
+ sqlb->time.neg = 0;
+
+ /** host name */
+ buf_host_len_t = 0;
+ tmp_size = sizeof(sqlb->host);
+ realloc_format_trap((u_char**)&sqlb->host, &tmp_size,
+ &buf_host_len_t, 1, "%B", pdu, transport);
+ sqlb->host_len = buf_host_len_t;
+
+ /* snmpTrapOID */
+ if (pdu->command == SNMP_MSG_TRAP) {
+ /*
+ * convert a v1 trap to a v2 varbind
+ */
+ if (pdu->trap_type == SNMP_TRAP_ENTERPRISESPECIFIC) {
+ trap_oid_len = pdu->enterprise_length;
+ memcpy(tmp_oid, pdu->enterprise, sizeof(oid) * trap_oid_len);
+ if (tmp_oid[trap_oid_len - 1] != 0)
+ tmp_oid[trap_oid_len++] = 0;
+ tmp_oid[trap_oid_len++] = pdu->specific_type;
+ trap_oid = tmp_oid;
+ } else {
+ trapoids[9] = pdu->trap_type + 1;
+ trap_oid = trapoids;
+ trap_oid_len = OID_LENGTH(trapoids);
+ }
+ }
+ else {
+ vars = pdu->variables;
+ if (vars && vars->next_variable) {
+ trap_oid_len = vars->next_variable->val_len / sizeof(oid);
+ trap_oid = vars->next_variable->val.objid;
+ }
+ else {
+ static oid null_oid[] = { 0, 0 };
+ trap_oid_len = OID_LENGTH(null_oid);
+ trap_oid = null_oid;
+ }
+ }
+ tmp_size = 0;
+ buf_oid_len_t = oid_overflow = 0;
+ netsnmp_sprint_realloc_objid_tree((u_char**)&sqlb->oid,&tmp_size,
+ &buf_oid_len_t, 1, &oid_overflow,
+ trap_oid, trap_oid_len);
+ sqlb->oid_len = buf_oid_len_t;
+ if (oid_overflow)
+ snmp_log(LOG_WARNING,"OID truncated in sql buffer\n");
+
+ /** request id */
+ sqlb->reqid = pdu->reqid;
+
+ /** version (convert to 1 based, for sql enum) */
+ sqlb->version = pdu->version + 1;
+
+ /** command type (convert to 1 based, for sql enum) */
+ sqlb->type = pdu->command - 159;
+
+ /** community string/user name */
+ tmp_size = 0;
+ buf_user_len_t = 0;
+ realloc_format_trap((u_char**)&sqlb->user, &tmp_size,
+ &buf_user_len_t, 1, "%u", pdu, transport);
+ sqlb->user_len = buf_user_len_t;
+
+ /** transport */
+ sqlb->transport = transport->f_fmtaddr(transport, pdu->transport_data,
+ pdu->transport_data_length);
+
+ /** security model */
+ sqlb->security_model = pdu->securityModel;
+
+ if ((SNMP_MP_MODEL_SNMPv3+1) == sqlb->version) {
+
+ sqlb->msgid = pdu->msgid;
+ sqlb->security_level = pdu->securityLevel;
+
+ if (pdu->contextName) {
+ sqlb->context = netsnmp_strdup_and_null((u_char*)pdu->contextName,
+ pdu->contextNameLen);
+ sqlb->context_len = pdu->contextNameLen;
+ }
+ if (pdu->contextEngineID) {
+ sqlb->context_engine_len =
+ binary_to_hex(pdu->contextEngineID, pdu->contextEngineIDLen,
+ &sqlb->context_engine);
+ }
+
+ if (pdu->securityName) {
+ sqlb->security_name =
+ netsnmp_strdup_and_null((u_char*)pdu->securityName,
+ pdu->securityNameLen);
+ sqlb->security_name_len = pdu->securityNameLen;
+ }
+ if (pdu->securityEngineID) {
+ sqlb->security_engine_len =
+ binary_to_hex(pdu->securityEngineID, pdu->securityEngineIDLen,
+ &sqlb->security_engine);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * save varbind info from incoming trap
+ *
+ * return 0 on success, anything else is an error
+ */
+static int
+_sql_save_varbind_info(sql_buf *sqlb, netsnmp_pdu *pdu)
+{
+ netsnmp_variable_list *var;
+ sql_vb_buf *sqlvb;
+ size_t tmp_size, buf_oid_len_t;
+ int oid_overflow, rc;
+#ifdef NETSNMP_MYSQL_TRAP_VALUE_TEXT
+ size_t buf_val_len_t;
+#endif
+
+ if ((NULL == sqlb) || (NULL == pdu))
+ return -1;
+
+ var = pdu->variables;
+ while(var) {
+ sqlvb = SNMP_MALLOC_TYPEDEF(sql_vb_buf);
+ if (NULL == sqlvb)
+ break;
+
+ /** OID */
+ tmp_size = 0;
+ buf_oid_len_t = oid_overflow = 0;
+ netsnmp_sprint_realloc_objid_tree((u_char**)&sqlvb->oid, &tmp_size,
+ &buf_oid_len_t,
+ 1, &oid_overflow, var->name,
+ var->name_length);
+ sqlvb->oid_len = buf_oid_len_t;
+ if (oid_overflow)
+ snmp_log(LOG_WARNING,"OID truncated in sql insert\n");
+
+ /** type */
+ if (var->type > ASN_OBJECT_ID)
+ /** convert application types to sql enum */
+ sqlvb->type = ASN_OBJECT_ID + 1 + (var->type & ~ASN_APPLICATION);
+ else
+ sqlvb->type = var->type;
+
+ /** value */
+#ifdef NETSNMP_MYSQL_TRAP_VALUE_TEXT
+ tmp_size = 0;
+ buf_val_len_t = 0;
+ sprint_realloc_by_type((u_char**)&sqlvb->val, &tmp_size,
+ &buf_val_len_t, 1, var, 0, 0, 0);
+ sqlvb->val_len = buf_val_len_t;
+#else
+ memdup(&sqlvb->val, var->val.string, var->val_len);
+ sqlvb->val_len = var->val_len;
+#endif
+
+ var = var->next_variable;
+
+ /** insert into container */
+ rc = CONTAINER_INSERT(sqlb->varbinds,sqlvb);
+ if(rc)
+ snmp_log(LOG_ERR, "couldn't insert varbind into trap container\n");
+ }
+
+ return 0;
+}
+
+/*
+ * sql trap handler
+ */
+int
+mysql_handler(netsnmp_pdu *pdu,
+ netsnmp_transport *transport,
+ netsnmp_trapd_handler *handler)
+{
+ sql_buf *sqlb;
+ int old_format, rc;
+
+ DEBUGMSGTL(("sql:handler", "called\n"));
+
+ /** allocate a buffer to save data */
+ sqlb = _sql_buf_get();
+ if (NULL == sqlb) {
+ snmp_log(LOG_ERR, "Could not allocate trap sql buffer\n");
+ return syslog_handler( pdu, transport, handler );
+ }
+
+ /** save OID output format and change to numeric */
+ old_format = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_OID_OUTPUT_FORMAT);
+ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
+ NETSNMP_OID_OUTPUT_NUMERIC);
+
+
+ rc = _sql_save_trap_info(sqlb, pdu, transport);
+ rc = _sql_save_varbind_info(sqlb, pdu);
+
+ /** restore previous OID output format */
+ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT,
+ old_format);
+
+ /** insert into queue */
+ rc = CONTAINER_INSERT(_sql.queue, sqlb);
+ if(rc) {
+ snmp_log(LOG_ERR, "Could not log queue sql trap buffer\n");
+ _sql_log(sqlb, NULL);
+ _sql_buf_free(sqlb, 0);
+ return -1;
+ }
+
+ /** save queue if size is > max */
+ if (CONTAINER_SIZE(_sql.queue) >= _sql.queue_max)
+ _sql_process_queue(0,NULL);
+
+ return 0;
+}
+
+/*
+ * save a buffered trap to sql database
+ */
+static void
+_sql_save(sql_buf *sqlb, void *dontcare)
+{
+ netsnmp_iterator *it;
+ sql_vb_buf *sqlvb;
+ u_long trap_id;
+
+ /*
+ * don't even try if we don't have a database connection
+ */
+ if (0 == _sql.connected) {
+ _sql_log(sqlb, NULL);
+ return;
+ }
+
+ /*
+ * the prepared statements are bound to the static buffer objects,
+ * so copy the queued data to the static version.
+ */
+ _tbind[TBIND_HOST].buffer = sqlb->host;
+ _tbind[TBIND_HOST].buffer_length = sqlb->host_len;
+
+ _tbind[TBIND_OID].buffer = sqlb->oid;
+ _tbind[TBIND_OID].buffer_length = sqlb->oid_len;
+
+ _tbind[TBIND_REQID].buffer = (void *)&sqlb->reqid;
+ _tbind[TBIND_VER].buffer = (void *)&sqlb->version;
+ _tbind[TBIND_TYPE].buffer = (void *)&sqlb->type;
+ _tbind[TBIND_SECURITY_MODEL].buffer = (void *)&sqlb->security_model;
+
+ _tbind[TBIND_DATE].buffer = (void *)&sqlb->time;
+
+ _tbind[TBIND_USER].buffer = sqlb->user;
+ _tbind[TBIND_USER].buffer_length = sqlb->user_len;
+
+ _tbind[TBIND_TRANSPORT].buffer = sqlb->transport;
+ if (sqlb->transport)
+ _tbind[TBIND_TRANSPORT].buffer_length = strlen(sqlb->transport);
+ else
+ _tbind[TBIND_TRANSPORT].buffer_length = 0;
+
+
+ if ((SNMP_MP_MODEL_SNMPv3+1) == sqlb->version) {
+ _no_v3 = 0;
+
+ _tbind[TBIND_v3_MSGID].buffer = &sqlb->msgid;
+
+ _tbind[TBIND_v3_SECURITY_LEVEL].buffer = &sqlb->security_level;
+
+ _tbind[TBIND_v3_CONTEXT_NAME].buffer = sqlb->context;
+ _tbind[TBIND_v3_CONTEXT_NAME].buffer_length = sqlb->context_len;
+
+ _tbind[TBIND_v3_CONTEXT_ENGINE].buffer = sqlb->context_engine;
+ _tbind[TBIND_v3_CONTEXT_ENGINE].buffer_length =
+ sqlb->context_engine_len;
+
+ _tbind[TBIND_v3_SECURITY_NAME].buffer = sqlb->security_name;
+ _tbind[TBIND_v3_SECURITY_NAME].buffer_length = sqlb->security_name_len;
+
+ _tbind[TBIND_v3_SECURITY_ENGINE].buffer = sqlb->security_engine;
+ _tbind[TBIND_v3_SECURITY_ENGINE].buffer_length =
+ sqlb->security_engine_len;
+ }
+ else {
+ _no_v3 = 1;
+ }
+
+ if (mysql_stmt_bind_param(_sql.trap_stmt, _tbind) != 0) {
+ netsnmp_sql_stmt_error(_sql.trap_stmt,
+ "Could not bind parameters for INSERT");
+ _sql_log(sqlb, NULL);
+ return;
+ }
+
+ /** execute the prepared statement */
+ if (mysql_stmt_execute(_sql.trap_stmt) != 0) {
+ netsnmp_sql_stmt_error(_sql.trap_stmt,
+ "Could not execute insert statement for trap");
+ _sql_log(sqlb, NULL);
+ return;
+ }
+ trap_id = mysql_insert_id(_sql.conn);
+
+ /*
+ * iterate over the varbinds, copy data and insert
+ */
+ it = CONTAINER_ITERATOR(sqlb->varbinds);
+ if (NULL == it) {
+ snmp_log(LOG_ERR,"Could not allocate iterator\n");
+ _sql_log(sqlb, NULL);
+ return;
+ }
+
+ for( sqlvb = ITERATOR_FIRST(it); sqlvb; sqlvb = ITERATOR_NEXT(it)) {
+
+ _vbind[VBIND_ID].buffer = (void *)&trap_id;
+ _vbind[VBIND_TYPE].buffer = (void *)&sqlvb->type;
+
+ _vbind[VBIND_OID].buffer = sqlvb->oid;
+ _vbind[VBIND_OID].buffer_length = sqlvb->oid_len;
+
+ _vbind[VBIND_VAL].buffer = sqlvb->val;
+ _vbind[VBIND_VAL].buffer_length = sqlvb->val_len;
+
+ if (mysql_stmt_bind_param(_sql.vb_stmt, _vbind) != 0) {
+ netsnmp_sql_stmt_error(_sql.vb_stmt,
+ "Could not bind parameters for INSERT");
+ _sql_log(sqlb, NULL);
+ break;
+ }
+
+ if (mysql_stmt_execute(_sql.vb_stmt) != 0) {
+ netsnmp_sql_stmt_error(_sql.vb_stmt,
+ "Could not execute insert statement for varbind");
+ _sql_log(sqlb, NULL);
+ break;
+ }
+ }
+ ITERATOR_RELEASE(it);
+}
+
+/*
+ * process (save) queued items to sql database.
+ *
+ * dontcare & meeither are dummy params so this function can be used
+ * as a netsnmp_alarm callback function.
+ */
+static void
+_sql_process_queue(u_int dontcare, void *meeither)
+{
+ int rc;
+
+ /** bail if the queue is empty */
+ if( 0 == CONTAINER_SIZE(_sql.queue))
+ return;
+
+ DEBUGMSGT(("sql:process", "processing %d queued traps\n",
+ (int)CONTAINER_SIZE(_sql.queue)));
+
+ /*
+ * if we don't have a database connection, try to reconnect. We
+ * don't care if we fail - traps will be logged in that case.
+ */
+ if (0 == _sql.connected) {
+ DEBUGMSGT(("sql:process", "no sql connection; reconnecting\n"));
+ (void) netsnmp_mysql_connect();
+ }
+
+ CONTAINER_FOR_EACH(_sql.queue, (netsnmp_container_obj_func*)_sql_save,
+ NULL);
+
+ if (_sql.connected) {
+ rc = mysql_commit(_sql.conn);
+ if (rc) { /* nuts... now what? */
+ netsnmp_sql_error("commit failed");
+ CONTAINER_FOR_EACH(_sql.queue,
+ (netsnmp_container_obj_func*)_sql_log,
+ NULL);
+ }
+ }
+
+ CONTAINER_CLEAR(_sql.queue, (netsnmp_container_obj_func*)_sql_buf_free,
+ NULL);
+}
+
+#else
+int unused; /* Suppress "empty translation unit" warning */
+#endif /* NETSNMP_USE_MYSQL */
diff --git a/apps/snmpusm.c b/apps/snmpusm.c
new file mode 100644
index 0000000..42919bd
--- /dev/null
+++ b/apps/snmpusm.c
@@ -0,0 +1,1023 @@
+/*
+ * snmpusm.c - send snmp SET requests to a network entity to change the
+ * usm user database
+ *
+ * XXX get engineID dynamically.
+ * XXX read passwords from prompts
+ * XXX customize responses with user names, etc.
+ */
+/* Portions of this file are subject to the following copyright(s). See
+ * the Net-SNMP's COPYING file for more details and other copyrights
+ * that may apply:
+ */
+/*
+ * Portions of this file are copyrighted by:
+ * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms specified in the COPYING file
+ * distributed with the Net-SNMP package.
+ */
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
+#include <openssl/dh.h>
+#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
+
+#include <net-snmp/net-snmp-includes.h>
+
+int main(int, char **);
+
+#define CMD_PASSWD_NAME "passwd"
+#define CMD_PASSWD 1
+#define CMD_CREATE_NAME "create"
+#define CMD_CREATE 2
+#define CMD_DELETE_NAME "delete"
+#define CMD_DELETE 3
+#define CMD_CLONEFROM_NAME "cloneFrom"
+#define CMD_CLONEFROM 4
+#define CMD_ACTIVATE_NAME "activate"
+#define CMD_ACTIVATE 5
+#define CMD_DEACTIVATE_NAME "deactivate"
+#define CMD_DEACTIVATE 6
+#define CMD_CHANGEKEY_NAME "changekey"
+#define CMD_CHANGEKEY 7
+
+#define CMD_NUM 7
+
+static const char *successNotes[CMD_NUM] = {
+ "SNMPv3 Key(s) successfully changed.",
+ "User successfully created.",
+ "User successfully deleted.",
+ "User successfully cloned.",
+ "User successfully activated.",
+ "User successfully deactivated.",
+ "SNMPv3 Key(s) successfully changed."
+};
+
+#define USM_OID_LEN 12
+#define DH_USM_OID_LEN 11
+
+static oid
+
+authKeyOid[MAX_OID_LEN] = { 1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 6 },
+ownAuthKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 7},
+privKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 9},
+ownPrivKeyOid[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 10},
+usmUserCloneFrom[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 4},
+usmUserSecurityName[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 3},
+usmUserPublic[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 11},
+usmUserStatus[MAX_OID_LEN] = {1, 3, 6, 1, 6, 3, 15, 1, 2, 2, 1, 13},
+/* diffie helman change key objects */
+usmDHUserAuthKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 1 },
+usmDHUserPrivKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 3 },
+#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
+usmDHUserOwnAuthKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 2 },
+usmDHUserOwnPrivKeyChange[MAX_OID_LEN] = {1, 3, 6, 1, 3, 101, 1, 1, 2, 1, 4 },
+#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
+usmDHParameters[] = { 1,3,6,1,3,101,1,1,1,0 }
+;
+size_t usmDHParameters_len = OID_LENGTH(usmDHParameters);
+
+static
+oid *authKeyChange = authKeyOid, *privKeyChange = privKeyOid;
+oid *dhauthKeyChange = usmDHUserAuthKeyChange,
+ *dhprivKeyChange = usmDHUserPrivKeyChange;
+int doauthkey = 0, doprivkey = 0, uselocalizedkey = 0;
+size_t usmUserEngineIDLen = 0;
+u_char *usmUserEngineID = NULL;
+char *usmUserPublic_val = NULL;
+int docreateandwait = 0;
+
+
+void
+usage(void)
+{
+ fprintf(stderr, "Usage: snmpusm ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " COMMAND\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr, "\nsnmpusm commands:\n");
+ fprintf(stderr, " [options] create USER [CLONEFROM-USER]\n");
+ fprintf(stderr, " [options] delete USER\n");
+ fprintf(stderr, " [options] activate USER\n");
+ fprintf(stderr, " [options] deactivate USER\n");
+ fprintf(stderr, " [options] [-Cw] cloneFrom USER CLONEFROM-USER\n");
+ fprintf(stderr, " [options] [-Ca] [-Cx] changekey [USER]\n");
+ fprintf(stderr,
+ " [options] [-Ca] [-Cx] passwd OLD-PASSPHRASE NEW-PASSPHRASE [USER]\n");
+ fprintf(stderr,
+ " [options] (-Ca|-Cx) -Ck passwd OLD-KEY-OR-PASS NEW-KEY-OR-PASS [USER]\n");
+ fprintf(stderr, "\nsnmpusm options:\n");
+ fprintf(stderr, "\t-CE ENGINE-ID\tSet usmUserEngineID (e.g. 800000020109840301).\n");
+ fprintf(stderr, "\t-Cp STRING\tSet usmUserPublic value to STRING.\n");
+ fprintf(stderr, "\t-Cw\t\tCreate the user with createAndWait.\n");
+ fprintf(stderr, "\t\t\t(it won't be active until you active it)\n");
+ fprintf(stderr, "\t-Cx\t\tChange the privacy key.\n");
+ fprintf(stderr, "\t-Ca\t\tChange the authentication key.\n");
+ fprintf(stderr, "\t-Ck\t\tAllows to use localized key (must start with 0x)\n");
+ fprintf(stderr, "\t\t\tinstead of passphrase.\n");
+}
+
+/*
+ * setup_oid appends to the oid the index for the engineid/user
+ */
+void
+setup_oid(oid * it, size_t * len, u_char * id, size_t idlen,
+ const char *user)
+{
+ int i, itIndex = *len;
+
+ *len = itIndex + 1 + idlen + 1 + strlen(user);
+
+ it[itIndex++] = idlen;
+ for (i = 0; i < (int) idlen; i++) {
+ it[itIndex++] = id[i];
+ }
+
+ it[itIndex++] = strlen(user);
+ for (i = 0; i < (int) strlen(user); i++) {
+ it[itIndex++] = user[i];
+ }
+
+#ifdef NETSNMP_ENABLE_TESTING_CODE
+ fprintf(stdout, "setup_oid: ");
+ fprint_objid(stdout, it, *len);
+ fprintf(stdout, "\n");
+#endif
+}
+
+#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
+int
+get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar,
+ size_t outkey_len,
+ netsnmp_pdu *pdu, const char *keyname,
+ oid *keyoid, size_t keyoid_len) {
+ u_char *dhkeychange;
+ DH *dh;
+ BIGNUM *other_pub;
+ u_char *key;
+ size_t key_len;
+
+ dhkeychange = (u_char *) malloc(2 * vars->val_len * sizeof(char));
+ if (!dhkeychange)
+ return SNMPERR_GENERR;
+
+ memcpy(dhkeychange, vars->val.string, vars->val_len);
+
+ {
+ const unsigned char *cp = dhvar->val.string;
+ dh = d2i_DHparams(NULL, &cp, dhvar->val_len);
+ }
+
+ if (!dh || !dh->g || !dh->p) {
+ SNMP_FREE(dhkeychange);
+ return SNMPERR_GENERR;
+ }
+
+ DH_generate_key(dh);
+ if (!dh->pub_key) {
+ SNMP_FREE(dhkeychange);
+ return SNMPERR_GENERR;
+ }
+
+ if (vars->val_len != (unsigned int)BN_num_bytes(dh->pub_key)) {
+ SNMP_FREE(dhkeychange);
+ fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n",
+ (unsigned long)vars->val_len, BN_num_bytes(dh->pub_key));
+ return SNMPERR_GENERR;
+ }
+
+ BN_bn2bin(dh->pub_key, dhkeychange + vars->val_len);
+
+ key_len = DH_size(dh);
+ if (!key_len) {
+ SNMP_FREE(dhkeychange);
+ return SNMPERR_GENERR;
+ }
+ key = (u_char *) malloc(key_len * sizeof(u_char));
+
+ if (!key) {
+ SNMP_FREE(dhkeychange);
+ return SNMPERR_GENERR;
+ }
+
+ other_pub = BN_bin2bn(vars->val.string, vars->val_len, NULL);
+ if (!other_pub) {
+ SNMP_FREE(dhkeychange);
+ SNMP_FREE(key);
+ return SNMPERR_GENERR;
+ }
+
+ if (DH_compute_key(key, other_pub, dh)) {
+ u_char *kp;
+
+ printf("new %s key: 0x", keyname);
+ for(kp = key + key_len - outkey_len;
+ kp - key < (int)key_len; kp++) {
+ printf("%02x", (unsigned char) *kp);
+ }
+ printf("\n");
+ }
+
+ snmp_pdu_add_variable(pdu, keyoid, keyoid_len,
+ ASN_OCTET_STR, dhkeychange,
+ 2 * vars->val_len);
+
+ SNMP_FREE(dhkeychange);
+ SNMP_FREE(other_pub);
+ SNMP_FREE(key);
+
+ return SNMPERR_SUCCESS;
+}
+#endif /* HAVE_OPENSSL_DH_H */
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'a':
+ doauthkey = 1;
+ break;
+
+ case 'x':
+ doprivkey = 1;
+ break;
+
+ case 'k':
+ uselocalizedkey = 1;
+ break;
+
+ case 'p':
+ if (optind < argc) {
+ usmUserPublic_val = argv[optind];
+ } else {
+ fprintf(stderr, "Bad -Cp option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+
+ case 'w':
+ docreateandwait = 1;
+ break;
+
+ case 'E': {
+ size_t ebuf_len = MAX_ENGINEID_LENGTH;
+ u_char *ebuf;
+ if (optind < argc) {
+ if (argv[optind]) {
+ ebuf = (u_char *)malloc(ebuf_len);
+ if (ebuf == NULL) {
+ fprintf(stderr,
+ "malloc failure processing -CE option.\n");
+ exit(1);
+ }
+ if (!snmp_hex_to_binary(&ebuf, &ebuf_len,
+ &usmUserEngineIDLen, 1, argv[optind])) {
+ fprintf(stderr,
+ "Bad usmUserEngineID value after -CE option.\n");
+ free(ebuf);
+ exit(1);
+ }
+ usmUserEngineID = ebuf;
+ DEBUGMSGTL(("snmpusm", "usmUserEngineID set to: "));
+ DEBUGMSGHEX(("snmpusm", usmUserEngineID, usmUserEngineIDLen));
+ DEBUGMSG(("snmpusm", "\n"));
+
+ }
+ } else {
+ fprintf(stderr, "Bad -CE option: no argument given\n");
+ exit(1);
+ }
+ optind++;
+ break;
+ }
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu = NULL, *response = NULL;
+
+ int arg;
+ size_t name_length = USM_OID_LEN;
+ size_t name_length2 = USM_OID_LEN;
+ int status;
+ int exitval = 0;
+ int rval;
+ int command = 0;
+ long longvar;
+
+ size_t oldKu_len = SNMP_MAXBUF_SMALL,
+ newKu_len = SNMP_MAXBUF_SMALL,
+ oldkul_len = SNMP_MAXBUF_SMALL,
+ oldkulpriv_len = SNMP_MAXBUF_SMALL,
+ newkulpriv_len = SNMP_MAXBUF_SMALL,
+ newkul_len = SNMP_MAXBUF_SMALL,
+ keychange_len = SNMP_MAXBUF_SMALL,
+ keychangepriv_len = SNMP_MAXBUF_SMALL;
+
+ char *newpass = NULL, *oldpass = NULL;
+ u_char oldKu[SNMP_MAXBUF_SMALL],
+ newKu[SNMP_MAXBUF_SMALL],
+ oldkul[SNMP_MAXBUF_SMALL],
+ oldkulpriv[SNMP_MAXBUF_SMALL],
+ newkulpriv[SNMP_MAXBUF_SMALL],
+ newkul[SNMP_MAXBUF_SMALL], keychange[SNMP_MAXBUF_SMALL],
+ keychangepriv[SNMP_MAXBUF_SMALL];
+
+ authKeyChange = authKeyOid;
+ privKeyChange = privKeyOid;
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ if (arg >= argc) {
+ fprintf(stderr, "Please specify an operation to perform.\n");
+ usage();
+ exit(1);
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ /*
+ * Note: this needs to obtain the engineID used below
+ */
+ session.flags &= ~SNMP_FLAGS_DONT_PROBE;
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpusm", &session);
+ exit(1);
+ }
+
+ /*
+ * set usmUserEngineID from ss->contextEngineID
+ * if not already set (via -CE)
+ */
+ if (usmUserEngineID == NULL) {
+ usmUserEngineID = ss->contextEngineID;
+ usmUserEngineIDLen = ss->contextEngineIDLen;
+ }
+
+ /*
+ * create PDU for SET request and add object names and values to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_SET);
+ if (!pdu) {
+ fprintf(stderr, "Failed to create request\n");
+ exit(1);
+ }
+
+
+ if (strcmp(argv[arg], CMD_PASSWD_NAME) == 0) {
+
+ /*
+ * passwd: change a users password.
+ *
+ * XXX: Uses the auth type of the calling user, a MD5 user can't
+ * change a SHA user's key.
+ */
+ char *passwd_user;
+
+ command = CMD_PASSWD;
+ oldpass = argv[++arg];
+ newpass = argv[++arg];
+ passwd_user = argv[++arg];
+
+ if (doprivkey == 0 && doauthkey == 0)
+ doprivkey = doauthkey = 1;
+
+ if (newpass == NULL || strlen(newpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr,
+ "New passphrase must be greater than %d characters in length.\n",
+ USM_LENGTH_P_MIN);
+ exit(1);
+ }
+
+ if (oldpass == NULL || strlen(oldpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr,
+ "Old passphrase must be greater than %d characters in length.\n",
+ USM_LENGTH_P_MIN);
+ exit(1);
+ }
+
+ /*
+ * Change the user supplied on command line.
+ */
+ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
+ session.securityName = passwd_user;
+ } else {
+ /*
+ * Use own key object if no user was supplied.
+ */
+ authKeyChange = ownAuthKeyOid;
+ privKeyChange = ownPrivKeyOid;
+ }
+
+ /*
+ * do we have a securityName? If not, copy the default
+ */
+ if (session.securityName == NULL) {
+ session.securityName =
+ strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_SECNAME));
+ }
+
+ /*
+ * the old Ku is in the session, but we need the new one
+ */
+ if (session.securityAuthProto == NULL) {
+ /*
+ * get .conf set default
+ */
+ const oid *def =
+ get_default_authtype(&session.securityAuthProtoLen);
+ session.securityAuthProto =
+ snmp_duplicate_objid(def, session.securityAuthProtoLen);
+ }
+ if (session.securityAuthProto == NULL) {
+ /*
+ * assume MD5
+ */
+#ifndef NETSNMP_DISABLE_MD5
+ session.securityAuthProtoLen =
+ sizeof(usmHMACMD5AuthProtocol) / sizeof(oid);
+ session.securityAuthProto =
+ snmp_duplicate_objid(usmHMACMD5AuthProtocol,
+ session.securityAuthProtoLen);
+#else
+ session.securityAuthProtoLen =
+ sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid);
+ session.securityAuthProto =
+ snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
+ session.securityAuthProtoLen);
+#endif
+
+ }
+
+ if (uselocalizedkey && (strncmp(oldpass, "0x", 2) == 0)) {
+ /*
+ * use the localized key from the command line
+ */
+ u_char *buf;
+ size_t buf_len = SNMP_MAXBUF_SMALL;
+ buf = (u_char *) malloc (buf_len * sizeof(u_char));
+
+ oldkul_len = 0; /* initialize the offset */
+ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &oldkul_len, 0, oldpass)) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the old Kul from localized key failed\n");
+ exit(1);
+ }
+
+ memcpy(oldkul, buf, oldkul_len);
+ SNMP_FREE(buf);
+ }
+ else {
+ /*
+ * the old Ku is in the session, but we need the new one
+ */
+ rval = generate_Ku(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ (u_char *) oldpass, strlen(oldpass),
+ oldKu, &oldKu_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the old Ku failed\n");
+ exit(1);
+ }
+
+ /*
+ * generate the two Kul's
+ */
+ rval = generate_kul(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ usmUserEngineID, usmUserEngineIDLen,
+ oldKu, oldKu_len, oldkul, &oldkul_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the old Kul failed\n");
+ exit(1);
+ }
+ }
+ if (uselocalizedkey && (strncmp(newpass, "0x", 2) == 0)) {
+ /*
+ * use the localized key from the command line
+ */
+ u_char *buf;
+ size_t buf_len = SNMP_MAXBUF_SMALL;
+ buf = (u_char *) malloc (buf_len * sizeof(u_char));
+
+ newkul_len = 0; /* initialize the offset */
+ if (!snmp_hex_to_binary((u_char **) (&buf), &buf_len, &newkul_len, 0, newpass)) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the new Kul from localized key failed\n");
+ exit(1);
+ }
+
+ memcpy(newkul, buf, newkul_len);
+ SNMP_FREE(buf);
+ } else {
+ rval = generate_Ku(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ (u_char *) newpass, strlen(newpass),
+ newKu, &newKu_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the new Ku failed\n");
+ exit(1);
+ }
+
+ rval = generate_kul(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ usmUserEngineID, usmUserEngineIDLen,
+ newKu, newKu_len, newkul, &newkul_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "generating the new Kul failed\n");
+ exit(1);
+ }
+ }
+
+ /*
+ * for encryption, we may need to truncate the key to the proper length
+ * so we need two copies. For simplicity, we always just copy even if
+ * they're the same lengths.
+ */
+ if (doprivkey) {
+ if (!session.securityPrivProto) {
+ snmp_log(LOG_ERR, "no encryption type specified, which I need in order to know to change the key\n");
+ exit(1);
+ }
+
+#ifndef NETSNMP_DISABLE_DES
+ if (ISTRANSFORM(session.securityPrivProto, DESPriv)) {
+ /* DES uses a 128 bit key, 64 bits of which is a salt */
+ oldkulpriv_len = newkulpriv_len = 16;
+ }
+#endif
+#ifdef HAVE_AES
+ if (ISTRANSFORM(session.securityPrivProto, AESPriv)) {
+ oldkulpriv_len = newkulpriv_len = 16;
+ }
+#endif
+ memcpy(oldkulpriv, oldkul, oldkulpriv_len);
+ memcpy(newkulpriv, newkul, newkulpriv_len);
+ }
+
+
+ /*
+ * create the keychange string
+ */
+ if (doauthkey) {
+ rval = encode_keychange(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ oldkul, oldkul_len,
+ newkul, newkul_len,
+ keychange, &keychange_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "encoding the keychange failed\n");
+ usage();
+ exit(1);
+ }
+ }
+
+ /* which is slightly different for encryption if lengths are
+ different */
+ if (doprivkey) {
+ rval = encode_keychange(session.securityAuthProto,
+ session.securityAuthProtoLen,
+ oldkulpriv, oldkulpriv_len,
+ newkulpriv, newkulpriv_len,
+ keychangepriv, &keychangepriv_len);
+
+ if (rval != SNMPERR_SUCCESS) {
+ snmp_perror(argv[0]);
+ fprintf(stderr, "encoding the keychange failed\n");
+ usage();
+ exit(1);
+ }
+ }
+
+ /*
+ * add the keychange string to the outgoing packet
+ */
+ if (doauthkey) {
+ setup_oid(authKeyChange, &name_length,
+ usmUserEngineID, usmUserEngineIDLen,
+ session.securityName);
+ snmp_pdu_add_variable(pdu, authKeyChange, name_length,
+ ASN_OCTET_STR, keychange, keychange_len);
+ }
+ if (doprivkey) {
+ setup_oid(privKeyChange, &name_length2,
+ usmUserEngineID, usmUserEngineIDLen,
+ session.securityName);
+ snmp_pdu_add_variable(pdu, privKeyChange, name_length2,
+ ASN_OCTET_STR,
+ keychangepriv, keychangepriv_len);
+ }
+
+ } else if (strcmp(argv[arg], CMD_CREATE_NAME) == 0) {
+ /*
+ * create: create a user
+ *
+ * create USER [CLONEFROM]
+ */
+ if (++arg >= argc) {
+ fprintf(stderr, "You must specify the user name to create\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_CREATE;
+
+ if (++arg < argc) {
+ /*
+ * clone the new user from an existing user
+ * (and make them active immediately)
+ */
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
+ if (docreateandwait) {
+ longvar = RS_CREATEANDWAIT;
+ } else {
+ longvar = RS_CREATEANDGO;
+ }
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+
+ name_length = USM_OID_LEN;
+ setup_oid(usmUserCloneFrom, &name_length,
+ usmUserEngineID, usmUserEngineIDLen,
+ argv[arg - 1]);
+ setup_oid(usmUserSecurityName, &name_length2,
+ usmUserEngineID, usmUserEngineIDLen,
+ argv[arg]);
+ snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
+ ASN_OBJECT_ID,
+ (u_char *) usmUserSecurityName,
+ sizeof(oid) * name_length2);
+ } else {
+ /*
+ * create a new (unauthenticated) user from scratch
+ * The Net-SNMP agent won't allow such a user to be made active.
+ */
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg-1]);
+ longvar = RS_CREATEANDWAIT;
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ }
+
+ } else if (strcmp(argv[arg], CMD_CLONEFROM_NAME) == 0) {
+ /*
+ * create: clone a user from another
+ *
+ * cloneFrom USER FROM
+ */
+ if (++arg >= argc) {
+ fprintf(stderr,
+ "You must specify the user name to operate on\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_CLONEFROM;
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+ longvar = RS_ACTIVE;
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ name_length = USM_OID_LEN;
+ setup_oid(usmUserCloneFrom, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+
+ if (++arg >= argc) {
+ fprintf(stderr,
+ "You must specify the user name to clone from\n");
+ usage();
+ exit(1);
+ }
+
+ setup_oid(usmUserSecurityName, &name_length2,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+ snmp_pdu_add_variable(pdu, usmUserCloneFrom, name_length,
+ ASN_OBJECT_ID,
+ (u_char *) usmUserSecurityName,
+ sizeof(oid) * name_length2);
+
+ } else if (strcmp(argv[arg], CMD_DELETE_NAME) == 0) {
+ /*
+ * delete: delete a user
+ *
+ * delete USER
+ */
+ if (++arg >= argc) {
+ fprintf(stderr, "You must specify the user name to delete\n");
+ exit(1);
+ }
+
+ command = CMD_DELETE;
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+ longvar = RS_DESTROY;
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_ACTIVATE_NAME) == 0) {
+ /*
+ * activate: activate a user
+ *
+ * activate USER
+ */
+ if (++arg >= argc) {
+ fprintf(stderr, "You must specify the user name to activate\n");
+ exit(1);
+ }
+
+ command = CMD_ACTIVATE;
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+ longvar = RS_ACTIVE;
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_DEACTIVATE_NAME) == 0) {
+ /*
+ * deactivate: deactivate a user
+ *
+ * deactivate USER
+ */
+ if (++arg >= argc) {
+ fprintf(stderr, "You must specify the user name to deactivate\n");
+ exit(1);
+ }
+
+ command = CMD_DEACTIVATE;
+ setup_oid(usmUserStatus, &name_length,
+ usmUserEngineID, usmUserEngineIDLen, argv[arg]);
+ longvar = RS_NOTINSERVICE;
+ snmp_pdu_add_variable(pdu, usmUserStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
+ } else if (strcmp(argv[arg], CMD_CHANGEKEY_NAME) == 0) {
+ /*
+ * change the key of a user if DH is available
+ */
+
+ char *passwd_user;
+ netsnmp_pdu *dhpdu, *dhresponse = NULL;
+ netsnmp_variable_list *vars, *dhvar;
+
+ command = CMD_CHANGEKEY;
+ name_length = DH_USM_OID_LEN;
+ name_length2 = DH_USM_OID_LEN;
+
+ passwd_user = argv[++arg];
+
+ if (doprivkey == 0 && doauthkey == 0)
+ doprivkey = doauthkey = 1;
+
+ /*
+ * Change the user supplied on command line.
+ */
+ if ((passwd_user != NULL) && (strlen(passwd_user) > 0)) {
+ session.securityName = passwd_user;
+ } else {
+ /*
+ * Use own key object if no user was supplied.
+ */
+ dhauthKeyChange = usmDHUserOwnAuthKeyChange;
+ dhprivKeyChange = usmDHUserOwnPrivKeyChange;
+ }
+
+ /*
+ * do we have a securityName? If not, copy the default
+ */
+ if (session.securityName == NULL) {
+ session.securityName =
+ strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_SECNAME));
+ }
+
+ /* fetch the needed diffie helman parameters */
+ dhpdu = snmp_pdu_create(SNMP_MSG_GET);
+ if (!dhpdu) {
+ fprintf(stderr, "Failed to create DH request\n");
+ exit(1);
+ }
+
+ /* get the current DH parameters */
+ snmp_add_null_var(dhpdu, usmDHParameters, usmDHParameters_len);
+
+ /* maybe the auth key public value */
+ if (doauthkey) {
+ setup_oid(dhauthKeyChange, &name_length,
+ usmUserEngineID, usmUserEngineIDLen,
+ session.securityName);
+ snmp_add_null_var(dhpdu, dhauthKeyChange, name_length);
+ }
+
+ /* maybe the priv key public value */
+ if (doprivkey) {
+ setup_oid(dhprivKeyChange, &name_length2,
+ usmUserEngineID, usmUserEngineIDLen,
+ session.securityName);
+ snmp_add_null_var(dhpdu, dhprivKeyChange, name_length2);
+ }
+
+ /* fetch the values */
+ status = snmp_synch_response(ss, dhpdu, &dhresponse);
+
+ if (status != SNMPERR_SUCCESS || dhresponse == NULL ||
+ dhresponse->errstat != SNMP_ERR_NOERROR ||
+ dhresponse->variables->type != ASN_OCTET_STR) {
+ snmp_sess_perror("snmpusm", ss);
+ if (dhresponse && dhresponse->variables &&
+ dhresponse->variables->type != ASN_OCTET_STR) {
+ fprintf(stderr,
+ "Can't get diffie-helman exchange from the agent\n");
+ fprintf(stderr,
+ " (maybe it doesn't support the SNMP-USM-DH-OBJECTS-MIB MIB)\n");
+ }
+ exitval = 1;
+ goto begone;
+ }
+
+ dhvar = dhresponse->variables;
+ vars = dhvar->next_variable;
+ /* complete the DH equation & print resulting keys */
+ if (doauthkey) {
+ if (get_USM_DH_key(vars, dhvar,
+ sc_get_properlength(ss->securityAuthProto,
+ ss->securityAuthProtoLen),
+ pdu, "auth",
+ dhauthKeyChange, name_length) != SNMPERR_SUCCESS)
+ goto begone;
+ vars = vars->next_variable;
+ }
+ if (doprivkey) {
+ size_t dhprivKeyLen = 0;
+#ifndef NETSNMP_DISABLE_DES
+ if (ISTRANSFORM(ss->securityPrivProto, DESPriv)) {
+ /* DES uses a 128 bit key, 64 bits of which is a salt */
+ dhprivKeyLen = 16;
+ }
+#endif
+#ifdef HAVE_AES
+ if (ISTRANSFORM(ss->securityPrivProto, AESPriv)) {
+ dhprivKeyLen = 16;
+ }
+#endif
+ if (get_USM_DH_key(vars, dhvar,
+ dhprivKeyLen,
+ pdu, "priv",
+ dhprivKeyChange, name_length2)
+ != SNMPERR_SUCCESS)
+ goto begone;
+ vars = vars->next_variable;
+ }
+ /* snmp_free_pdu(dhresponse); */ /* parts still in use somewhere */
+#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
+ } else {
+ fprintf(stderr, "Unknown command\n");
+ usage();
+ exit(1);
+ }
+
+ /*
+ * add usmUserPublic if specified (via -Cp)
+ */
+ if (usmUserPublic_val) {
+ name_length = USM_OID_LEN;
+ setup_oid(usmUserPublic, &name_length,
+ usmUserEngineID, usmUserEngineIDLen,
+ session.securityName);
+ snmp_pdu_add_variable(pdu, usmUserPublic, name_length,
+ ASN_OCTET_STR, usmUserPublic_val,
+ strlen(usmUserPublic_val));
+ }
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ fprintf(stdout, "%s\n", successNotes[command - 1]);
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ int count;
+ netsnmp_variable_list *vars;
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpset", ss);
+ exitval = 1;
+ }
+
+#if defined(HAVE_OPENSSL_DH_H) && defined(HAVE_LIBCRYPTO)
+ begone:
+#endif /* HAVE_OPENSSL_DH_H && HAVE_LIBCRYPTO */
+ if (response)
+ snmp_free_pdu(response);
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpvacm.c b/apps/snmpvacm.c
new file mode 100644
index 0000000..f88ede6
--- /dev/null
+++ b/apps/snmpvacm.c
@@ -0,0 +1,711 @@
+/*
+ * snmpvacm.c - send snmp SET requests to a network entity to change the
+ * vacm database
+ *
+ */
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+int main(int, char **);
+
+#define CMD_CREATESEC2GROUP_NAME "createSec2Group"
+#define CMD_CREATESEC2GROUP 1
+#define CMD_DELETESEC2GROUP_NAME "deleteSec2Group"
+#define CMD_DELETESEC2GROUP 2
+#define CMD_CREATEACCESS_NAME "createAccess"
+#define CMD_CREATEACCESS 3
+#define CMD_DELETEACCESS_NAME "deleteAccess"
+#define CMD_DELETEACCESS 4
+#define CMD_CREATEVIEW_NAME "createView"
+#define CMD_CREATEVIEW 5
+#define CMD_DELETEVIEW_NAME "deleteView"
+#define CMD_DELETEVIEW 6
+#define CMD_CREATEAUTH_NAME "createAuth"
+#define CMD_CREATEAUTH 7
+#define CMD_DELETEAUTH_NAME "deleteAuth"
+#define CMD_DELETEAUTH 8
+
+#define CMD_NUM 8
+
+static const char *successNotes[CMD_NUM] = {
+ "Sec2group successfully created.",
+ "Sec2group successfully deleted.",
+ "Access successfully created.",
+ "Access successfully deleted.",
+ "View successfully created.",
+ "View successfully deleted.",
+ "AuthAccess successfully created.",
+ "AuthAccess successfully deleted."
+};
+
+#define SEC2GROUP_OID_LEN 11
+#define ACCESS_OID_LEN 11
+#define VIEW_OID_LEN 12
+#define AUTH_OID_LEN 12
+
+static oid vacmGroupName[MAX_OID_LEN] =
+ { 1, 3, 6, 1, 6, 3, 16, 1, 2, 1, 3 },
+ vacmSec2GroupStatus[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 2, 1, 5}, vacmAccessContextMatch[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 4}, vacmAccessReadViewName[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 5}, vacmAccessWriteViewName[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 6}, vacmAccessNotifyViewName[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 7}, vacmAccessStatus[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 9}, vacmViewTreeFamilyMask[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 3}, vacmViewTreeFamilyType[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 4},
+ vacmViewTreeFamilyStatus[MAX_OID_LEN] = {
+1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 6}
+
+;
+
+#define NSVACMACCESSTABLE 1, 3, 6, 1, 4, 1, 8072, 1, 9, 1
+static oid nsVacmContextPfx[MAX_OID_LEN] = { NSVACMACCESSTABLE, 1, 2 };
+static oid nsVacmViewName[MAX_OID_LEN] = { NSVACMACCESSTABLE, 1, 3 };
+static oid nsVacmRowStatus[MAX_OID_LEN] = { NSVACMACCESSTABLE, 1, 5 };
+
+int viewTreeFamilyType = 1;
+
+void
+usage(void)
+{
+ fprintf(stderr, "Usage: snmpvacm ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " COMMAND\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr, "\nsnmpvacm commands:\n");
+ fprintf(stderr, " createAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME\n");
+ fprintf(stderr, " deleteAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL\n");
+ fprintf(stderr, " createSec2Group MODEL SECURITYNAME GROUPNAME\n");
+ fprintf(stderr, " deleteSec2Group MODEL SECURITYNAME\n");
+ fprintf(stderr, " [-Ce] createView NAME SUBTREE [MASK]\n");
+ fprintf(stderr, " deleteView NAME SUBTREE\n");
+ fprintf(stderr, " createAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE CONTEXTMATCH VIEWNAME\n");
+ fprintf(stderr, " deleteAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE\n");
+}
+
+
+void
+auth_oid(oid * it, size_t * len, const char *groupName,
+ const char *prefix, int model, int level, const char *authtype)
+{
+ int i;
+ int itIndex = AUTH_OID_LEN;
+
+ it[itIndex++] = strlen(groupName);
+ for (i = 0; i < (int) strlen(groupName); i++)
+ it[itIndex++] = groupName[i];
+
+ if (prefix) {
+ *len += strlen(prefix);
+ it[itIndex++] = strlen(prefix);
+ for (i = 0; i < (int) strlen(prefix); i++)
+ it[itIndex++] = prefix[i];
+ } else
+ it[itIndex++] = 0;
+
+ it[itIndex++] = model;
+ it[itIndex++] = level;
+
+ it[itIndex++] = strlen(authtype);
+ for (i = 0; i < (int) strlen(authtype); i++)
+ it[itIndex++] = authtype[i];
+
+ *len = itIndex;
+}
+
+void
+access_oid(oid * it, size_t * len, const char *groupName,
+ const char *prefix, int model, int level)
+{
+ int i;
+
+ int itIndex = ACCESS_OID_LEN;
+
+ *len = itIndex + 4 + +strlen(groupName);
+
+ it[itIndex++] = strlen(groupName);
+ for (i = 0; i < (int) strlen(groupName); i++)
+ it[itIndex++] = groupName[i];
+
+ if (prefix) {
+ *len += strlen(prefix);
+ it[itIndex++] = strlen(prefix);
+ for (i = 0; i < (int) strlen(prefix); i++)
+ it[itIndex++] = prefix[i];
+ } else
+ it[itIndex++] = 0;
+
+ it[itIndex++] = model;
+ it[itIndex++] = level;
+}
+
+
+void
+sec2group_oid(oid * it, size_t * len, int model, const char *name)
+{
+ int i;
+
+ int itIndex = SEC2GROUP_OID_LEN;
+
+ *len = itIndex + 2 + strlen(name);
+
+ it[itIndex++] = model;
+
+ it[itIndex++] = strlen(name);
+ for (i = 0; i < (int) strlen(name); i++)
+ it[itIndex++] = name[i];
+}
+
+void
+view_oid(oid * it, size_t * len, const char *viewName, char *viewSubtree)
+{
+ int i;
+ oid c_oid[SPRINT_MAX_LEN];
+ size_t c_oid_length = SPRINT_MAX_LEN;
+
+ int itIndex = VIEW_OID_LEN;
+
+ if (!snmp_parse_oid(viewSubtree, c_oid, &c_oid_length)) {
+ printf("Error parsing subtree (%s)\n", viewSubtree);
+ exit(1);
+ }
+
+ *len = itIndex + 2 + strlen(viewName) + c_oid_length;
+
+ it[itIndex++] = strlen(viewName);
+ for (i = 0; i < (int) strlen(viewName); i++)
+ it[itIndex++] = viewName[i];
+
+
+ it[itIndex++] = c_oid_length;
+ for (i = 0; i < (int) c_oid_length; i++)
+ it[itIndex++] = c_oid[i];
+
+ /*
+ * sprint_objid(c_oid, it, *len);
+ */
+}
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'e':
+ viewTreeFamilyType = 2;
+ break;
+
+ default:
+ fprintf(stderr,
+ "Unknown flag passed to -C: %c\n", optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu = NULL, *response = NULL;
+#ifdef notused
+ netsnmp_variable_list *vars;
+#endif
+
+ int arg;
+#ifdef notused
+ int count;
+ int current_name = 0;
+ int current_type = 0;
+ int current_value = 0;
+ char *names[128];
+ char types[128];
+ char *values[128];
+ oid name[MAX_OID_LEN];
+#endif
+ size_t name_length;
+ int status;
+ int exitval = 0;
+ int command = 0;
+ long longvar;
+ int secModel, secLevel, contextMatch;
+ unsigned int val, i = 0;
+ char *mask, *groupName, *prefix, *authtype;
+ u_char viewMask[VACMSTRINGLEN];
+ char *st;
+
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ /*
+ * Note: this wil obtain the engineID needed below
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpvacm", &session);
+ exit(1);
+ }
+
+ /*
+ * create PDU for SET request and add object names and values to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_SET);
+
+ if (arg >= argc) {
+ fprintf(stderr, "Please specify a operation to perform.\n");
+ usage();
+ exit(1);
+ }
+
+ if (strcmp(argv[arg], CMD_DELETEVIEW_NAME) == 0)
+ /*
+ * deleteView: delete a view
+ *
+ * deleteView NAME SUBTREE
+ *
+ */
+ {
+ if (++arg + 2 != argc) {
+ fprintf(stderr, "You must specify the view to delete\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_DELETEVIEW;
+ name_length = VIEW_OID_LEN;
+ view_oid(vacmViewTreeFamilyStatus, &name_length, argv[arg],
+ argv[arg + 1]);
+ longvar = RS_DESTROY;
+ snmp_pdu_add_variable(pdu, vacmViewTreeFamilyStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_CREATEVIEW_NAME) == 0)
+ /*
+ * createView: create a view
+ *
+ * createView NAME SUBTREE MASK
+ *
+ */
+ {
+ if (++arg + 2 > argc) {
+ fprintf(stderr, "You must specify name, subtree and mask\n");
+ usage();
+ exit(1);
+ }
+ command = CMD_CREATEVIEW;
+ name_length = VIEW_OID_LEN;
+ view_oid(vacmViewTreeFamilyStatus, &name_length, argv[arg],
+ argv[arg + 1]);
+ longvar = RS_CREATEANDGO;
+ snmp_pdu_add_variable(pdu, vacmViewTreeFamilyStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ /*
+ * Mask
+ */
+ if (arg + 3 == argc) {
+ mask = argv[arg + 2];
+ for (mask = strtok_r(mask, ".:", &st); mask; mask = strtok_r(NULL, ".:", &st)) {
+ if (i >= sizeof(viewMask)) {
+ printf("MASK too long\n");
+ exit(1);
+ }
+ if (sscanf(mask, "%x", &val) == 0) {
+ printf("invalid MASK\n");
+ exit(1);
+ }
+ viewMask[i] = val;
+ i++;
+ }
+ } else {
+ for (i=0 ; i < (name_length+7)/8; i++)
+ viewMask[i] = (u_char)0xff;
+ }
+ view_oid(vacmViewTreeFamilyMask, &name_length, argv[arg],
+ argv[arg + 1]);
+ snmp_pdu_add_variable(pdu, vacmViewTreeFamilyMask, name_length,
+ ASN_OCTET_STR, viewMask, i);
+
+ view_oid(vacmViewTreeFamilyType, &name_length, argv[arg],
+ argv[arg + 1]);
+ snmp_pdu_add_variable(pdu, vacmViewTreeFamilyType, name_length,
+ ASN_INTEGER, (u_char *) & viewTreeFamilyType,
+ sizeof(viewTreeFamilyType));
+
+ } else if (strcmp(argv[arg], CMD_DELETESEC2GROUP_NAME) == 0)
+ /*
+ * deleteSec2Group: delete security2group
+ *
+ * deleteSec2Group MODEL SECURITYNAME
+ *
+ */
+ {
+ if (++arg + 2 != argc) {
+ fprintf(stderr, "You must specify the sec2group to delete\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_DELETESEC2GROUP;
+ name_length = SEC2GROUP_OID_LEN;
+ if (sscanf(argv[arg], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ sec2group_oid(vacmSec2GroupStatus, &name_length, secModel,
+ argv[arg + 1]);
+ longvar = RS_DESTROY;
+ snmp_pdu_add_variable(pdu, vacmSec2GroupStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_CREATESEC2GROUP_NAME) == 0)
+ /*
+ * createSec2Group: create a security2group
+ *
+ * createSec2Group MODEL SECURITYNAME GROUPNAME
+ *
+ */
+ {
+ if (++arg + 3 != argc) {
+ fprintf(stderr,
+ "You must specify model, security name and group name\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_CREATESEC2GROUP;
+ name_length = SEC2GROUP_OID_LEN;
+ if (sscanf(argv[arg], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ sec2group_oid(vacmSec2GroupStatus, &name_length, secModel,
+ argv[arg + 1]);
+ longvar = RS_CREATEANDGO;
+ snmp_pdu_add_variable(pdu, vacmSec2GroupStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ sec2group_oid(vacmGroupName, &name_length, secModel,
+ argv[arg + 1]);
+ snmp_pdu_add_variable(pdu, vacmGroupName, name_length,
+ ASN_OCTET_STR, (u_char *) argv[arg + 2],
+ strlen(argv[arg + 2]));
+ } else if (strcmp(argv[arg], CMD_DELETEACCESS_NAME) == 0)
+ /*
+ * deleteAccess: delete access entry
+ *
+ * deleteAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL
+ *
+ */
+ {
+ if (++arg + 3 > argc) {
+ fprintf(stderr,
+ "You must specify the access entry to delete\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_DELETEACCESS;
+ name_length = ACCESS_OID_LEN;
+ groupName = argv[arg];
+ if (arg + 4 == argc)
+ prefix = argv[++arg];
+ else
+ prefix = NULL;
+
+ if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
+ printf("invalid security level\n");
+ usage();
+ exit(1);
+ }
+ access_oid(vacmAccessStatus, &name_length, groupName, prefix,
+ secModel, secLevel);
+ longvar = RS_DESTROY;
+ snmp_pdu_add_variable(pdu, vacmAccessStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_CREATEACCESS_NAME) == 0)
+ /*
+ * createAccess: create access entry
+ *
+ * createAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME
+ *
+ */
+ {
+ if (++arg + 7 > argc) {
+ fprintf(stderr,
+ "You must specify the access entry to create\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_CREATEACCESS;
+ name_length = ACCESS_OID_LEN;
+ groupName = argv[arg];
+ if (arg + 8 == argc)
+ prefix = argv[++arg];
+ else
+ prefix = NULL;
+
+ if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
+ printf("invalid security level\n");
+ usage();
+ exit(1);
+ }
+ access_oid(vacmAccessStatus, &name_length, groupName, prefix,
+ secModel, secLevel);
+ longvar = RS_CREATEANDGO;
+ snmp_pdu_add_variable(pdu, vacmAccessStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+
+ access_oid(vacmAccessContextMatch, &name_length, groupName, prefix,
+ secModel, secLevel);
+ if (sscanf(argv[arg + 3], "%d", &contextMatch) == 0) {
+ printf("invalid contextMatch\n");
+ usage();
+ exit(1);
+ }
+ snmp_pdu_add_variable(pdu, vacmAccessContextMatch, name_length,
+ ASN_INTEGER, (u_char *) & contextMatch,
+ sizeof(contextMatch));
+
+ access_oid(vacmAccessReadViewName, &name_length, groupName, prefix,
+ secModel, secLevel);
+ snmp_pdu_add_variable(pdu, vacmAccessReadViewName, name_length,
+ ASN_OCTET_STR, (u_char *) argv[arg + 4],
+ strlen(argv[arg + 4]));
+
+ access_oid(vacmAccessWriteViewName, &name_length, groupName,
+ prefix, secModel, secLevel);
+ snmp_pdu_add_variable(pdu, vacmAccessWriteViewName, name_length,
+ ASN_OCTET_STR, (u_char *) argv[arg + 5],
+ strlen(argv[arg + 5]));
+
+ access_oid(vacmAccessNotifyViewName, &name_length, groupName,
+ prefix, secModel, secLevel);
+ snmp_pdu_add_variable(pdu, vacmAccessNotifyViewName, name_length,
+ ASN_OCTET_STR, (u_char *) argv[arg + 6],
+ strlen(argv[arg + 6]));
+ } else if (strcmp(argv[arg], CMD_DELETEAUTH_NAME) == 0)
+ /*
+ * deleteAuth: delete authAccess entry
+ *
+ * deleteAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE
+ *
+ */
+ {
+ if (++arg + 4 > argc) {
+ fprintf(stderr,
+ "You must specify the authAccess entry to delete\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_DELETEAUTH;
+ name_length = AUTH_OID_LEN;
+ groupName = argv[arg];
+ if (arg + 5 == argc)
+ prefix = argv[++arg];
+ else
+ prefix = NULL;
+
+ if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
+ printf("invalid security level\n");
+ usage();
+ exit(1);
+ }
+ authtype = argv[arg+3];
+ auth_oid(nsVacmRowStatus, &name_length, groupName, prefix,
+ secModel, secLevel, authtype);
+ longvar = RS_DESTROY;
+ snmp_pdu_add_variable(pdu, nsVacmRowStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+ } else if (strcmp(argv[arg], CMD_CREATEAUTH_NAME) == 0)
+ /*
+ * createAuth: create authAccess entry
+ *
+ * createAuth GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL AUTHTYPE CONTEXTMATCH VIEWNAME
+ *
+ */
+ {
+ if (++arg + 6 > argc) {
+ fprintf(stderr,
+ "You must specify the authAccess entry to create\n");
+ usage();
+ exit(1);
+ }
+
+ command = CMD_CREATEAUTH;
+ name_length = AUTH_OID_LEN;
+ groupName = argv[arg];
+ if (arg + 7 == argc)
+ prefix = argv[++arg];
+ else
+ prefix = NULL;
+
+ if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
+ printf("invalid security model\n");
+ usage();
+ exit(1);
+ }
+ if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
+ printf("invalid security level\n");
+ usage();
+ exit(1);
+ }
+ authtype = argv[arg+3];
+ auth_oid(nsVacmRowStatus, &name_length, groupName, prefix,
+ secModel, secLevel, authtype);
+ longvar = RS_CREATEANDGO;
+ snmp_pdu_add_variable(pdu, nsVacmRowStatus, name_length,
+ ASN_INTEGER, (u_char *) & longvar,
+ sizeof(longvar));
+
+ auth_oid(nsVacmContextPfx, &name_length, groupName, prefix,
+ secModel, secLevel, authtype);
+ if (sscanf(argv[arg + 4], "%d", &contextMatch) == 0) {
+ printf("invalid contextMatch\n");
+ usage();
+ exit(1);
+ }
+ snmp_pdu_add_variable(pdu, nsVacmContextPfx, name_length,
+ ASN_INTEGER, (u_char *) & contextMatch,
+ sizeof(contextMatch));
+
+ auth_oid(nsVacmViewName, &name_length, groupName, prefix,
+ secModel, secLevel, authtype);
+ snmp_pdu_add_variable(pdu, nsVacmViewName, name_length,
+ ASN_OCTET_STR, (u_char *) argv[arg + 5],
+ strlen(argv[arg + 5]));
+ } else {
+ printf("Unknown command\n");
+ usage();
+ exit(1);
+ }
+
+ /*
+ * do the request
+ */
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (response) {
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ fprintf(stderr, "%s\n", successNotes[command - 1]);
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0){
+ int count;
+ struct variable_list *vars = response->variables;
+ fprintf(stderr, "Failed object: ");
+ for(count = 1; vars && (count != response->errindex);
+ vars = vars->next_variable, count++)
+ ;
+ if (vars)
+ fprint_objid(stderr, vars->name, vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ exitval = 1;
+ } else {
+ snmp_sess_perror("snmpset", ss);
+ exitval = 1;
+ }
+
+ if (response)
+ snmp_free_pdu(response);
+
+ snmp_close(ss);
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/snmpwalk.c b/apps/snmpwalk.c
new file mode 100644
index 0000000..659d7de
--- /dev/null
+++ b/apps/snmpwalk.c
@@ -0,0 +1,432 @@
+/*
+ * snmpwalk.c - send snmp GETNEXT requests to a network entity, walking a
+ * subtree.
+ *
+ */
+/**********************************************************************
+ Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+#include <net-snmp/net-snmp-config.h>
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <sys/types.h>
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <stdio.h>
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+
+#define NETSNMP_DS_WALK_INCLUDE_REQUESTED 1
+#define NETSNMP_DS_WALK_PRINT_STATISTICS 2
+#define NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC 3
+#define NETSNMP_DS_WALK_TIME_RESULTS 4
+#define NETSNMP_DS_WALK_DONT_GET_REQUESTED 5
+#define NETSNMP_DS_WALK_TIME_RESULTS_SINGLE 6
+
+oid objid_mib[] = { 1, 3, 6, 1, 2, 1 };
+int numprinted = 0;
+
+char *end_name = NULL;
+
+void
+usage(void)
+{
+ fprintf(stderr, "USAGE: snmpwalk ");
+ snmp_parse_args_usage(stderr);
+ fprintf(stderr, " [OID]\n\n");
+ snmp_parse_args_descriptions(stderr);
+ fprintf(stderr,
+ " -C APPOPTS\t\tSet various application specific behaviours:\n");
+ fprintf(stderr, "\t\t\t p: print the number of variables found\n");
+ fprintf(stderr, "\t\t\t i: include given OID in the search range\n");
+ fprintf(stderr, "\t\t\t I: don't include the given OID, even if no results are returned\n");
+ fprintf(stderr,
+ "\t\t\t c: do not check returned OIDs are increasing\n");
+ fprintf(stderr,
+ "\t\t\t t: Display wall-clock time to complete the walk\n");
+ fprintf(stderr,
+ "\t\t\t T: Display wall-clock time to complete each request\n");
+ fprintf(stderr, "\t\t\t E {OID}: End the walk at the specified OID\n");
+}
+
+void
+snmp_get_and_print(netsnmp_session * ss, oid * theoid, size_t theoid_len)
+{
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int status;
+
+ pdu = snmp_pdu_create(SNMP_MSG_GET);
+ snmp_add_null_var(pdu, theoid, theoid_len);
+
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
+ for (vars = response->variables; vars; vars = vars->next_variable) {
+ numprinted++;
+ print_variable(vars->name, vars->name_length, vars);
+ }
+ }
+ if (response) {
+ snmp_free_pdu(response);
+ }
+}
+
+static void
+optProc(int argc, char *const *argv, int opt)
+{
+ switch (opt) {
+ case 'C':
+ while (*optarg) {
+ switch (*optarg++) {
+ case 'i':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_INCLUDE_REQUESTED);
+ break;
+
+ case 'I':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_GET_REQUESTED);
+ break;
+
+ case 'p':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS);
+ break;
+
+ case 'c':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+ break;
+
+ case 't':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS);
+ break;
+
+ case 'E':
+ end_name = argv[optind++];
+ break;
+
+ case 'T':
+ netsnmp_ds_toggle_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS_SINGLE);
+ break;
+
+ default:
+ fprintf(stderr, "Unknown flag passed to -C: %c\n",
+ optarg[-1]);
+ exit(1);
+ }
+ }
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ netsnmp_session session, *ss;
+ netsnmp_pdu *pdu, *response;
+ netsnmp_variable_list *vars;
+ int arg;
+ oid name[MAX_OID_LEN];
+ size_t name_length;
+ oid root[MAX_OID_LEN];
+ size_t rootlen;
+ oid end_oid[MAX_OID_LEN];
+ size_t end_len = 0;
+ int count;
+ int running;
+ int status = STAT_ERROR;
+ int check;
+ int exitval = 0;
+ struct timeval tv1, tv2, tv_a, tv_b;
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "includeRequested",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_INCLUDE_REQUESTED);
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "excludeRequested",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_GET_REQUESTED);
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "printStatistics",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS);
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "dontCheckOrdering",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "timeResults",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS);
+
+ netsnmp_ds_register_config(ASN_BOOLEAN, "snmpwalk", "timeResultsSingle",
+ NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS_SINGLE);
+
+ /*
+ * get the common command line arguments
+ */
+ switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
+ case NETSNMP_PARSE_ARGS_ERROR:
+ exit(1);
+ case NETSNMP_PARSE_ARGS_SUCCESS_EXIT:
+ exit(0);
+ case NETSNMP_PARSE_ARGS_ERROR_USAGE:
+ usage();
+ exit(1);
+ default:
+ break;
+ }
+
+ /*
+ * get the initial object and subtree
+ */
+ if (arg < argc) {
+ /*
+ * specified on the command line
+ */
+ rootlen = MAX_OID_LEN;
+ if (snmp_parse_oid(argv[arg], root, &rootlen) == NULL) {
+ snmp_perror(argv[arg]);
+ exit(1);
+ }
+ } else {
+ /*
+ * use default value
+ */
+ memmove(root, objid_mib, sizeof(objid_mib));
+ rootlen = sizeof(objid_mib) / sizeof(oid);
+ }
+
+ /*
+ * If we've been given an explicit end point,
+ * then convert this to an OID, otherwise
+ * move to the next sibling of the start.
+ */
+ if ( end_name ) {
+ end_len = MAX_OID_LEN;
+ if (snmp_parse_oid(end_name, end_oid, &end_len) == NULL) {
+ snmp_perror(end_name);
+ exit(1);
+ }
+ } else {
+ memmove(end_oid, root, rootlen*sizeof(oid));
+ end_len = rootlen;
+ end_oid[end_len-1]++;
+ }
+
+ SOCK_STARTUP;
+
+ /*
+ * open an SNMP session
+ */
+ ss = snmp_open(&session);
+ if (ss == NULL) {
+ /*
+ * diagnose snmp_open errors with the input netsnmp_session pointer
+ */
+ snmp_sess_perror("snmpwalk", &session);
+ SOCK_CLEANUP;
+ exit(1);
+ }
+
+ /*
+ * get first object to start walk
+ */
+ memmove(name, root, rootlen * sizeof(oid));
+ name_length = rootlen;
+
+ running = 1;
+
+ check =
+ !netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_DONT_CHECK_LEXICOGRAPHIC);
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_INCLUDE_REQUESTED)) {
+ snmp_get_and_print(ss, root, rootlen);
+ }
+
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS))
+ netsnmp_get_monotonic_clock(&tv1);
+ while (running) {
+ /*
+ * create PDU for GETNEXT request and add object name to request
+ */
+ pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ snmp_add_null_var(pdu, name, name_length);
+
+ /*
+ * do the request
+ */
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_TIME_RESULTS_SINGLE))
+ netsnmp_get_monotonic_clock(&tv_a);
+ status = snmp_synch_response(ss, pdu, &response);
+ if (status == STAT_SUCCESS) {
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_TIME_RESULTS_SINGLE))
+ netsnmp_get_monotonic_clock(&tv_b);
+ if (response->errstat == SNMP_ERR_NOERROR) {
+ /*
+ * check resulting variables
+ */
+ for (vars = response->variables; vars;
+ vars = vars->next_variable) {
+ if (snmp_oid_compare(end_oid, end_len,
+ vars->name, vars->name_length) <= 0) {
+ /*
+ * not part of this subtree
+ */
+ running = 0;
+ continue;
+ }
+ numprinted++;
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_TIME_RESULTS_SINGLE))
+ fprintf(stdout, "%f s: ",
+ (double) (tv_b.tv_usec - tv_a.tv_usec)/1000000 +
+ (double) (tv_b.tv_sec - tv_a.tv_sec));
+ print_variable(vars->name, vars->name_length, vars);
+ if ((vars->type != SNMP_ENDOFMIBVIEW) &&
+ (vars->type != SNMP_NOSUCHOBJECT) &&
+ (vars->type != SNMP_NOSUCHINSTANCE)) {
+ /*
+ * not an exception value
+ */
+ if (check
+ && snmp_oid_compare(name, name_length,
+ vars->name,
+ vars->name_length) >= 0) {
+ fprintf(stderr, "Error: OID not increasing: ");
+ fprint_objid(stderr, name, name_length);
+ fprintf(stderr, " >= ");
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ running = 0;
+ exitval = 1;
+ }
+ memmove((char *) name, (char *) vars->name,
+ vars->name_length * sizeof(oid));
+ name_length = vars->name_length;
+ } else
+ /*
+ * an exception value, so stop
+ */
+ running = 0;
+ }
+ } else {
+ /*
+ * error in response, print it
+ */
+ running = 0;
+ if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+ printf("End of MIB\n");
+ } else {
+ fprintf(stderr, "Error in packet.\nReason: %s\n",
+ snmp_errstring(response->errstat));
+ if (response->errindex != 0) {
+ fprintf(stderr, "Failed object: ");
+ for (count = 1, vars = response->variables;
+ vars && count != response->errindex;
+ vars = vars->next_variable, count++)
+ /*EMPTY*/;
+ if (vars)
+ fprint_objid(stderr, vars->name,
+ vars->name_length);
+ fprintf(stderr, "\n");
+ }
+ exitval = 2;
+ }
+ }
+ } else if (status == STAT_TIMEOUT) {
+ fprintf(stderr, "Timeout: No Response from %s\n",
+ session.peername);
+ running = 0;
+ exitval = 1;
+ } else { /* status == STAT_ERROR */
+ snmp_sess_perror("snmpwalk", ss);
+ running = 0;
+ exitval = 1;
+ }
+ if (response)
+ snmp_free_pdu(response);
+ }
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS))
+ netsnmp_get_monotonic_clock(&tv2);
+
+ if (numprinted == 0 && status == STAT_SUCCESS) {
+ /*
+ * no printed successful results, which may mean we were
+ * pointed at an only existing instance. Attempt a GET, just
+ * for get measure.
+ */
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_WALK_DONT_GET_REQUESTED)) {
+ snmp_get_and_print(ss, root, rootlen);
+ }
+ }
+ snmp_close(ss);
+
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_PRINT_STATISTICS)) {
+ printf("Variables found: %d\n", numprinted);
+ }
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_WALK_TIME_RESULTS)) {
+ fprintf (stderr, "Total traversal time = %f seconds\n",
+ (double) (tv2.tv_usec - tv1.tv_usec)/1000000 +
+ (double) (tv2.tv_sec - tv1.tv_sec));
+ }
+
+ SOCK_CLEANUP;
+ return exitval;
+}
diff --git a/apps/sshtosnmp.c b/apps/sshtosnmp.c
new file mode 100644
index 0000000..d26067d
--- /dev/null
+++ b/apps/sshtosnmp.c
@@ -0,0 +1,233 @@
+/* Copyright 2009 SPARTA, Inc. All rights reserved
+ * Use is subject to license terms specified in the COPYING file
+ * distributed with the Net-SNMP package.
+ */
+
+/*
+ * This is merely a wrapper around stdin/out for sshd to call. It
+ * simply passes traffic to the running snmpd through a unix domain
+ * socket after first passing any needed SSH Domain information.
+ */
+
+#include <net-snmp/net-snmp-config.h>
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#include <sys/select.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+
+#ifndef MAXPATHLEN
+#warn no system max path length detected
+#define MAXPATHLEN 2048
+#endif
+
+#define DEFAULT_SOCK_PATH "/var/net-snmp/sshdomainsocket"
+
+#define NETSNMP_SSHTOSNMP_VERSION_NUMBER 1
+
+
+
+/*
+ * Extra debugging output for, um, debugging.
+ */
+
+#undef DEBUGGING
+
+#ifdef DEBUGGING
+#define DEBUG(x) deb(x)
+FILE *debf = NULL;
+void
+deb(const char *string) {
+ if (NULL == debf) {
+ debf = fopen("/tmp/sshtosnmp.log", "a");
+ }
+ if (NULL != debf) {
+ fprintf(debf, "%s\n", string);
+ fflush(debf);
+ }
+}
+#else /* !DEBUGGING */
+#define DEBUG(x)
+#endif /* DEBUGGING code */
+
+int
+main(int argc, char **argv) {
+
+ int sock;
+ struct sockaddr_un addr;
+ u_char buf[4096];
+ size_t buf_len = sizeof(buf);
+ int rc = 0, pktsize = 0;
+
+ fd_set read_set;
+
+ DEBUG("----------\nstarting up");
+
+ /* Open a connection to the UNIX domain socket or fail */
+
+ addr.sun_family = AF_UNIX;
+ if (argc > 1) {
+ strcpy(addr.sun_path, argv[1]);
+ } else {
+ strcpy(addr.sun_path, DEFAULT_SOCK_PATH);
+ }
+
+ sock = socket(PF_UNIX, SOCK_STREAM, 0);
+ DEBUG("created socket");
+ if (sock <= 0) {
+ exit(1);
+ }
+
+ /* set the SO_PASSCRED option so we can pass uid */
+ /* XXX: according to the unix(1) manual this shouldn't be needed
+ on the sending side? */
+ {
+ int one = 1;
+ setsockopt(sock, SOL_SOCKET, SO_PASSCRED, (void *) &one,
+ sizeof(one));
+ }
+
+ if (connect(sock, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr_un)) != 0) {
+ DEBUG("FAIL CONNECT");
+ exit(1);
+ }
+
+ DEBUG("opened socket");
+
+ /*
+ * we are running as the user that ssh authenticated us as, and this
+ * is the name/uid that the agent needs for processing as a SNMPv3
+ * security name. So this is the only thing needed to pass to the
+ * agent.
+ */
+
+ /* version 1 of our internal ssh to snmp wrapper is just a single
+ byte version number and indicates we're also passing unix
+ socket credentials containing our user id */
+
+ /* In case of future changes, we'll pass a version number first */
+
+ buf[0] = NETSNMP_SSHTOSNMP_VERSION_NUMBER;
+ buf_len = 1;
+
+ /* send the prelim message and the credentials together using sendmsg() */
+ {
+ struct msghdr m;
+ struct {
+ struct cmsghdr cm;
+ struct ucred ouruser;
+ } cmsg;
+ struct iovec iov = { buf, buf_len };
+
+ /* Make sure that even padding fields get initialized.*/
+ memset(&cmsg, 0, sizeof(cmsg));
+ memset(&m, 0, sizeof(m));
+
+ /* set up the basic message */
+ cmsg.cm.cmsg_len = sizeof(struct cmsghdr) + sizeof(struct ucred);
+ cmsg.cm.cmsg_level = SOL_SOCKET;
+ cmsg.cm.cmsg_type = SCM_CREDENTIALS;
+
+ cmsg.ouruser.uid = getuid();
+ cmsg.ouruser.gid = getgid();
+ cmsg.ouruser.pid = getpid();
+
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+ m.msg_control = &cmsg;
+ m.msg_controllen = sizeof(cmsg);
+ m.msg_flags = 0;
+
+ DEBUG("sending to sock");
+ rc = sendmsg(sock, &m, MSG_NOSIGNAL|MSG_DONTWAIT);
+ if (rc < 0) {
+ fprintf(stderr, "failed to send startup message\n");
+ DEBUG("failed to send startup message\n");
+ exit(1);
+ }
+ }
+
+ DEBUG("sent name");
+
+ /* now we just send and receive from both the socket and stdin/stdout */
+
+ while(1) {
+ /* read from stdin and the socket */
+ FD_SET(sock, &read_set);
+ FD_SET(STDIN_FILENO, &read_set);
+
+ /* blocking without a timeout be fine fine */
+ select(sock+1, &read_set, NULL, NULL, NULL);
+
+ if (FD_ISSET(STDIN_FILENO, &read_set)) {
+ /* read from stdin to get stuff from sshd to send to the agent */
+ DEBUG("data from stdin");
+ rc = read(STDIN_FILENO, buf, sizeof(buf));
+
+ if (rc <= 0) {
+ /* end-of-file */
+#ifndef HAVE_CLOSESOCKET
+ rc = close(sock);
+#else
+ rc = closesocket(sock);
+#endif
+ exit(0);
+ }
+ DEBUG("read from stdin");
+
+ /* send it up the pipe */
+ pktsize = rc;
+ rc = -1;
+ while (rc < 0) {
+ DEBUG("sending to socket");
+ rc = sendto(sock, buf, pktsize, 0, NULL, 0);
+ DEBUG("back from sendto");
+ if (rc < 0)
+ DEBUG("sentto failed");
+ if (rc < 0 && errno != EINTR) {
+ break;
+ }
+ }
+ if (rc > 0)
+ DEBUG("sent to socket");
+ else
+ DEBUG("failed to send to socket!!");
+ }
+
+ if (FD_ISSET(sock, &read_set)) {
+ /* read from the socket and send to to stdout which goes to sshd */
+ DEBUG("data on unix socket");
+
+ rc = -1;
+ while (rc < 0) {
+ rc = recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL);
+ if (rc < 0 && errno != EINTR) {
+ close(sock);
+ exit(0);
+ }
+ }
+ DEBUG("read from socket");
+
+ pktsize = rc;
+ rc = write(STDOUT_FILENO, buf, pktsize);
+ /* XXX: check that counts match */
+ if (rc > 0) {
+ DEBUG("wrote to stdout");
+ } else {
+ DEBUG("failed to write to stdout");
+ }
+ }
+ }
+}