diff options
Diffstat (limited to 'apps/snmpnetstat')
-rw-r--r-- | apps/snmpnetstat/Makefile.depend | 425 | ||||
-rw-r--r-- | apps/snmpnetstat/Makefile.in | 38 | ||||
-rw-r--r-- | apps/snmpnetstat/ffs.c | 38 | ||||
-rw-r--r-- | apps/snmpnetstat/if.c | 870 | ||||
-rw-r--r-- | apps/snmpnetstat/inet.c | 649 | ||||
-rw-r--r-- | apps/snmpnetstat/inet6.c | 516 | ||||
-rw-r--r-- | apps/snmpnetstat/main.c | 539 | ||||
-rw-r--r-- | apps/snmpnetstat/main.h | 23 | ||||
-rw-r--r-- | apps/snmpnetstat/netstat.h | 94 | ||||
-rw-r--r-- | apps/snmpnetstat/route.c | 487 | ||||
-rw-r--r-- | apps/snmpnetstat/winstub.c | 285 | ||||
-rw-r--r-- | apps/snmpnetstat/winstub.h | 50 |
12 files changed, 4014 insertions, 0 deletions
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_ */ |