Date: Tue, 25 Oct 2011 14:17:41 -0400 From: Sean Mahood <smahood@uwaterloo.ca> To: freebsd-net@freebsd.org Subject: [PATCH] Have netstat test for sctp kernel support Message-ID: <20111025141741.26891k8ib38ekmkg@www.nexusmail.uwaterloo.ca>
next in thread | raw e-mail | index | archive | help
This message is in MIME format. --=_1gddn2ugd0sg Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; format="flowed" Content-Disposition: inline Content-Transfer-Encoding: 7bit Hello, I noticed that when doing a netstat -s (running on a kernel without SCTP support compiled in), I get the following message output to stderr: netstat: sysctl: net.inet.sctp.stats: No such file or directory Wondering why it would attempt to fetch SCTP stats when it was compiled out of the kernel, I noted that netstat could be compiled without SCTP support as well, but that there is no good way to link the two compilation conditions, or to have a generic binary that can run without error regardless of compiled kernel options. To that end, I added a method to check for environment compatibility in netstat. For SCTP specifically, I used the FEATURE macros and added SCTP as a FEATURE. Other protocols could also be configured to be checked at runtime if desired, though I haven't implemented any others at this time. -- Sean --=_1gddn2ugd0sg Content-Type: text/x-patch; charset=UTF-8; name="main.c.diff" Content-Disposition: attachment; filename="main.c.diff" Content-Transfer-Encoding: 7bit --- main.c@@/main/RELENG_8/RELENG_8_2/plt_ag_os/0 2011-10-21 11:35:33.000000000 -0400 +++ main.c 2011-10-24 14:30:13.000000000 -0400 @@ -198,106 +198,109 @@ struct protox { void (*pr_stats)(u_long, const char *, int, int); /* statistics printing routine */ void (*pr_istats)(char *); /* per/if statistics printing routine */ + int (*feature_test)(void); /* test routine to determine if kernel + suppport exists for protocol */ const char *pr_name; /* well-known name */ int pr_usesysctl; /* non-zero if we use sysctl, not kvm */ int pr_protocol; } protox[] = { { N_TCBINFO, N_TCPSTAT, 1, protopr, - tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, + tcp_stats, NULL, NULL, "tcp", 1, IPPROTO_TCP }, { N_UDBINFO, N_UDPSTAT, 1, protopr, - udp_stats, NULL, "udp", 1, IPPROTO_UDP }, + udp_stats, NULL, NULL, "udp", 1, IPPROTO_UDP }, #ifdef SCTP { -1, N_SCTPSTAT, 1, sctp_protopr, - sctp_stats, NULL, "sctp", 1, IPPROTO_SCTP }, + sctp_stats, NULL, sctp_feature_test, "sctp", 1, + IPPROTO_SCTP }, #endif { N_DIVCBINFO, -1, 1, protopr, - NULL, NULL, "divert", 1, IPPROTO_DIVERT }, + NULL, NULL, NULL, "divert", 1, IPPROTO_DIVERT }, { N_RIPCBINFO, N_IPSTAT, 1, protopr, - ip_stats, NULL, "ip", 1, IPPROTO_RAW }, + ip_stats, NULL, NULL, "ip", 1, IPPROTO_RAW }, { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, - icmp_stats, NULL, "icmp", 1, IPPROTO_ICMP }, + icmp_stats, NULL, NULL, "icmp", 1, IPPROTO_ICMP }, { N_RIPCBINFO, N_IGMPSTAT, 1, protopr, - igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP }, + igmp_stats, NULL, NULL, "igmp", 1, IPPROTO_IGMP }, #ifdef IPSEC { -1, N_IPSECSTAT, 1, NULL, /* keep as compat */ - ipsec_stats, NULL, "ipsec", 0, 0}, + ipsec_stats, NULL, NULL, "ipsec", 0, 0}, { -1, N_AHSTAT, 1, NULL, - ah_stats, NULL, "ah", 0, 0}, + ah_stats, NULL, NULL, "ah", 0, 0}, { -1, N_ESPSTAT, 1, NULL, - esp_stats, NULL, "esp", 0, 0}, + esp_stats, NULL, NULL, "esp", 0, 0}, { -1, N_IPCOMPSTAT, 1, NULL, - ipcomp_stats, NULL, "ipcomp", 0, 0}, + ipcomp_stats, NULL, NULL, "ipcomp", 0, 0}, #endif { N_RIPCBINFO, N_PIMSTAT, 1, protopr, - pim_stats, NULL, "pim", 1, IPPROTO_PIM }, + pim_stats, NULL, NULL, "pim", 1, IPPROTO_PIM }, { -1, N_CARPSTAT, 1, NULL, - carp_stats, NULL, "carp", 1, 0 }, + carp_stats, NULL, NULL, "carp", 1, 0 }, { -1, N_PFSYNCSTAT, 1, NULL, - pfsync_stats, NULL, "pfsync", 1, 0 }, + pfsync_stats, NULL, NULL, "pfsync", 1, 0 }, { -1, N_ARPSTAT, 1, NULL, - arp_stats, NULL, "arp", 1, 0 }, + arp_stats, NULL, NULL, "arp", 1, 0 }, { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } + NULL, NULL, NULL, NULL, 0, 0 } }; #ifdef INET6 struct protox ip6protox[] = { { N_TCBINFO, N_TCPSTAT, 1, protopr, - tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, + tcp_stats, NULL, NULL, "tcp", 1, IPPROTO_TCP }, { N_UDBINFO, N_UDPSTAT, 1, protopr, - udp_stats, NULL, "udp", 1, IPPROTO_UDP }, + udp_stats, NULL, NULL, "udp", 1, IPPROTO_UDP }, { N_RIPCBINFO, N_IP6STAT, 1, protopr, - ip6_stats, ip6_ifstats, "ip6", 1, IPPROTO_RAW }, + ip6_stats, ip6_ifstats, NULL, "ip6", 1, IPPROTO_RAW }, { N_RIPCBINFO, N_ICMP6STAT, 1, protopr, - icmp6_stats, icmp6_ifstats, "icmp6", 1, IPPROTO_ICMPV6 }, + icmp6_stats, icmp6_ifstats, NULL, "icmp6", 1, IPPROTO_ICMPV6 }, #ifdef IPSEC { -1, N_IPSEC6STAT, 1, NULL, - ipsec_stats, NULL, "ipsec6", 0, 0 }, + ipsec_stats, NULL, NULL, "ipsec6", 0, 0 }, #endif #ifdef notyet { -1, N_PIM6STAT, 1, NULL, - pim6_stats, NULL, "pim6", 1, 0 }, + pim6_stats, NULL, NULL, "pim6", 1, 0 }, #endif { -1, N_RIP6STAT, 1, NULL, - rip6_stats, NULL, "rip6", 1, 0 }, + rip6_stats, NULL, NULL, "rip6", 1, 0 }, { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } + NULL, NULL, NULL, NULL, 0, 0 } }; #endif /*INET6*/ #ifdef IPSEC struct protox pfkeyprotox[] = { { -1, N_PFKEYSTAT, 1, NULL, - pfkey_stats, NULL, "pfkey", 0, 0 }, + pfkey_stats, NULL, NULL, "pfkey", 0, 0 }, { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } + NULL, NULL, NULL, NULL, 0, 0 } }; #endif struct protox atalkprotox[] = { { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, - ddp_stats, NULL, "ddp", 0, 0 }, + ddp_stats, NULL, NULL, "ddp", 0, 0 }, { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } + NULL, NULL, NULL, NULL, 0, 0 } }; #ifdef NETGRAPH struct protox netgraphprotox[] = { { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, NULL, "ctrl", 0, 0 }, + NULL, NULL, NULL, "ctrl", 0, 0 }, { N_NGSOCKS, -1, 1, netgraphprotopr, - NULL, NULL, "data", 0, 0 }, + NULL, NULL, NULL, "data", 0, 0 }, { -1, -1, 0, NULL, - NULL, NULL, NULL, 0, 0 } + NULL, NULL, NULL, NULL, 0, 0 } }; #endif #ifdef IPX struct protox ipxprotox[] = { { N_IPX, N_IPXSTAT, 1, ipxprotopr, - ipx_stats, NULL, "ipx", 0, 0 }, + ipx_stats, NULL, NULL, "ipx", 0, 0 }, { N_IPX, N_SPXSTAT, 1, ipxprotopr, - spx_stats, NULL, "spx", 0, 0 }, + spx_stats, NULL, NULL, "spx", 0, 0 }, { -1, -1, 0, NULL, - NULL, NULL, 0, 0, 0 } + NULL, NULL, NULL, 0, 0, 0 } }; #endif @@ -624,6 +627,12 @@ printproto(tp, name) void (*pr)(u_long, const char *, int, int); u_long off; + if (tp->feature_test != NULL && !(*tp->feature_test)()) { + if (pflag) + fprintf(stderr, "%s: not supported in kernel\n", tp->pr_name); + return; + } + if (sflag) { if (iflag) { if (tp->pr_istats) --=_1gddn2ugd0sg Content-Type: text/x-patch; charset=UTF-8; name="netstat.h.diff" Content-Disposition: attachment; filename="netstat.h.diff" Content-Transfer-Encoding: 7bit --- netstat.h@@/main/RELENG_8/RELENG_8_2/plt_ag_os/0 2011-10-21 12:16:04.000000000 -0400 +++ netstat.h 2011-10-24 14:30:13.000000000 -0400 @@ -73,6 +73,7 @@ void protopr(u_long, const char *, int, void tcp_stats(u_long, const char *, int, int); void udp_stats(u_long, const char *, int, int); #ifdef SCTP +int sctp_feature_test(void); void sctp_protopr(u_long, const char *, int, int); void sctp_stats(u_long, const char *, int, int); #endif --=_1gddn2ugd0sg Content-Type: text/x-patch; charset=UTF-8; name="sctp.c.diff" Content-Disposition: attachment; filename="sctp.c.diff" Content-Transfer-Encoding: 7bit --- sctp.c@@/main/RELENG_8/RELENG_8_2/plt_ag_os/0 2011-10-20 18:00:53.000000000 -0400 +++ sctp.c 2011-10-24 14:30:14.000000000 -0400 @@ -102,6 +102,13 @@ struct xraddr_entry { LIST_ENTRY(xraddr_entry) xraddr_entries; }; +int +sctp_feature_test(void) +{ + + return (feature_present("sctp")); +} + static int sctp_skip_xinpcb_ifneed(char *buf, const size_t buflen, size_t *offset) { --=_1gddn2ugd0sg Content-Type: text/x-patch; charset=UTF-8; name="sctp_sysctl.c.diff" Content-Disposition: attachment; filename="sctp_sysctl.c.diff" Content-Transfer-Encoding: 7bit --- sctp_sysctl.c@@/main/RELENG_8/RELENG_8_2/plt_ag_os/0 2011-10-20 17:36:01.000000000 -0400 +++ sctp_sysctl.c 2011-10-24 14:30:11.000000000 -0400 @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$"); #include <netinet/sctp_output.h> #include <sys/smp.h> +FEATURE(sctp, "Stream Control Transmission Protocol"); + /* * sysctl tunable variables */ --=_1gddn2ugd0sg--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20111025141741.26891k8ib38ekmkg>