diff options
Diffstat (limited to 'apps')
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, ¬_argc, ¬_argv); + for(i=0; i < not_argc; ++i) { + if (NULL == not_argv[i]) + continue; + if (strncmp(not_argv[i],"--password=",11) == 0) + _sql.password = ¬_argv[i][11]; + else if (strncmp(not_argv[i],"--host=",7) == 0) + _sql.host_name = ¬_argv[i][7]; + else if (strncmp(not_argv[i],"--user=",7) == 0) + _sql.user_name = ¬_argv[i][7]; + else if (strncmp(not_argv[i],"--port=",7) == 0) + _sql.port_num = atoi(¬_argv[i][7]); + else if (strncmp(not_argv[i],"--socket=",9) == 0) + _sql.socket_name = ¬_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"); + } + } + } +} |