summaryrefslogtreecommitdiff
path: root/apps/snmpnetstat
diff options
context:
space:
mode:
Diffstat (limited to 'apps/snmpnetstat')
-rw-r--r--apps/snmpnetstat/Makefile.depend425
-rw-r--r--apps/snmpnetstat/Makefile.in38
-rw-r--r--apps/snmpnetstat/ffs.c38
-rw-r--r--apps/snmpnetstat/if.c870
-rw-r--r--apps/snmpnetstat/inet.c649
-rw-r--r--apps/snmpnetstat/inet6.c516
-rw-r--r--apps/snmpnetstat/main.c539
-rw-r--r--apps/snmpnetstat/main.h23
-rw-r--r--apps/snmpnetstat/netstat.h94
-rw-r--r--apps/snmpnetstat/route.c487
-rw-r--r--apps/snmpnetstat/winstub.c285
-rw-r--r--apps/snmpnetstat/winstub.h50
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_ */