PERFORCE change 164178 for review
Gabor Pali
pgj at FreeBSD.org
Fri Jun 12 14:55:37 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=164178
Change 164178 by pgj at petymeg-current on 2009/06/12 14:55:17
libnetstat:
netstat:
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#23 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#5 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#13 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#8 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#12 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#23 (text+ko) ====
@@ -370,16 +370,124 @@
#undef KREAD
+
+#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \
+ if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \
+ (flags)) != 0) { \
+ list->stl_error = NETSTAT_ERROR_UNDEFINED; \
+ return (-1); \
+ } \
+} while (0)
+
+#define NPCB_SCT(proc, family, type, list, flags) do { \
+ if (net_##proc##_pcblist_sysctl((family), (type), (list), \
+ (flags)) != 0) { \
+ list->stl_error = NETSTAT_ERROR_UNDEFINED; \
+ return (-1); \
+ } \
+} while (0)
+
int
+netstat_local_sockets(int type, struct socket_type_list *list, kvm_t *kvm,
+ struct nlist *nl, int flags)
+{
+ int use_kvm = flags & NETSTAT_SOCKET_KVM;
+
+ switch (type) {
+ case SOCK_STREAM:
+ case SOCK_DGRAM:
+ if (use_kvm)
+ NPCB_KVM(local, PF_LOCAL, type, list, kvm, nl,
+ flags);
+ else
+ /* Use sysctl (or something else). */
+ NPCB_SCT(local, PF_LOCAL, type, list, flags);
+ break;
+ /* All PF_LOCAL */
+ case 0:
+ if (use_kvm) {
+ NPCB_KVM(local, PF_LOCAL, SOCK_STREAM, list, kvm,
+ nl, flags);
+ NPCB_KVM(local, PF_LOCAL, SOCK_DGRAM, list, kvm,
+ nl, flags);
+ } else {
+ NPCB_SCT(local, PF_LOCAL, SOCK_STREAM, list,
+ flags);
+ NPCB_SCT(local, PF_LOCAL, SOCK_DGRAM, list,
+ flags);
+ }
+ break;
+ default:
+ list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+ return (-1);
+ }
+ return (0);
+}
+
+int
+netstat_inet_sockets(int domain, int protocol, struct socket_type_list *list,
+ kvm_t *kvm, struct nlist *nl, int flags)
+{
+ int use_kvm = flags & NETSTAT_SOCKET_KVM;
+
+ switch (protocol) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ case IPPROTO_DIVERT:
+ case IPPROTO_RAW:
+ case IPPROTO_ICMP:
+ case IPPROTO_IGMP:
+ case IPPROTO_PIM:
+ case IPPROTO_ICMPV6:
+ if (use_kvm)
+ NPCB_KVM(inet, domain, protocol, list, kvm, nl,
+ flags);
+ else
+ NPCB_SCT(inet, domain, protocol, list, flags);
+ break;
+ /* All PF_INET */
+ case 0:
+ /* Errors do not count here. */
+ if (use_kvm) {
+ net_inet_pcblist_kvm(domain, IPPROTO_TCP, list, kvm,
+ nl, flags);
+ net_inet_pcblist_kvm(domain, IPPROTO_UDP, list, kvm,
+ nl, flags);
+ net_inet_pcblist_kvm(domain, IPPROTO_DIVERT, list,
+ kvm, nl, flags);
+ net_inet_pcblist_kvm(domain, IPPROTO_RAW, list, kvm,
+ nl, flags);
+ } else {
+ net_inet_pcblist_sysctl(domain, IPPROTO_TCP, list,
+ flags);
+ net_inet_pcblist_sysctl(domain, IPPROTO_UDP, list,
+ flags);
+ net_inet_pcblist_sysctl(domain, IPPROTO_DIVERT, list,
+ flags);
+ net_inet_pcblist_sysctl(domain, IPPROTO_RAW, list,
+ flags);
+ }
+ break;
+ default:
+ list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+ return (-1);
+ }
+ return (0);
+}
+
+#undef NPCB_KVM
+#undef NPCB_SCT
+
+
+int
netstat_socket(int domain, int type, int protocol,
struct socket_type_list *list, int flags, void *kvm_handle)
{
kvm_t *kvm;
- int use_kvm;
+ int result;
struct nlist *nlp = NULL;
- use_kvm = flags & NETSTAT_SOCKET_KVM;
- if (use_kvm) {
+ if (flags & NETSTAT_SOCKET_KVM) {
/* Use KVM to retrieve data. */
switch (domain) {
case PF_LOCAL:
@@ -398,104 +506,37 @@
return (-1);
}
}
-
-#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \
- if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \
- (flags)) != 0) { \
- list->stl_error = NETSTAT_ERROR_UNDEFINED; \
- return (-1); \
- } \
-} while (0)
-
-#define NPCB_SCT(proc, family, type, list, flags) do { \
- if (net_##proc##_pcblist_sysctl((family), (type), (list), \
- (flags)) != 0) { \
- list->stl_error = NETSTAT_ERROR_UNDEFINED; \
- return (-1); \
- } \
-} while (0)
-
switch (domain) {
+ case PF_UNSPEC:
+ /* "Everything" */
+ result = netstat_local_sockets(0, list, kvm, nl, flags);
+ if (result < 0)
+ return (result);
+#if 1
+ result = netstat_inet_sockets(PF_INET, 0, list, kvm, nl,
+ flags);
+ if (result < 0)
+ return (result);
+#endif
+#if 0
+ result = netstat_inet_sockets(PF_INET6, 0, list, kvm, nl,
+ flags);
+ if (result < 0)
+ return (result);
+#endif
+ break;
case PF_LOCAL:
- switch (type) {
- case SOCK_STREAM:
- case SOCK_DGRAM:
- if (use_kvm)
- NPCB_KVM(local, domain, type, list, kvm, nl,
- flags);
- else
- /* Use sysctl (or something else). */
- NPCB_SCT(local, domain, type, list, flags);
- break;
- /* All PF_LOCAL */
- case 0:
- if (use_kvm) {
- NPCB_KVM(local, domain, SOCK_STREAM, list, kvm,
- nl, flags);
- NPCB_KVM(local, domain, SOCK_DGRAM, list, kvm,
- nl, flags);
- } else {
- NPCB_SCT(local, domain, SOCK_STREAM, list,
- flags);
- NPCB_SCT(local, domain, SOCK_DGRAM, list,
- flags);
- }
- break;
- default:
- list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
- return (-1);
- }
+ return (netstat_local_sockets(type, list, kvm, nl, flags));
break;
case PF_INET:
case PF_INET6:
- switch (protocol) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- case IPPROTO_DIVERT:
- case IPPROTO_RAW:
- case IPPROTO_ICMP:
- case IPPROTO_IGMP:
- case IPPROTO_PIM:
- case IPPROTO_ICMPV6:
- if (use_kvm)
- NPCB_KVM(inet, domain, protocol, list, kvm, nl,
- flags);
- else
- NPCB_SCT(inet, domain, protocol, list, flags);
- break;
- /* All PF_INET */
- case 0:
- if (use_kvm) {
- NPCB_KVM(inet, domain, IPPROTO_TCP, list, kvm,
- nl, flags);
- NPCB_KVM(inet, domain, IPPROTO_UDP, list, kvm,
- nl, flags);
- NPCB_KVM(inet, domain, IPPROTO_DIVERT, list,
- kvm, nl, flags);
- NPCB_KVM(inet, domain, IPPROTO_RAW, list, kvm,
- nl, flags);
- } else {
- NPCB_SCT(inet, domain, IPPROTO_TCP, list,
- flags);
- NPCB_SCT(inet, domain, IPPROTO_UDP, list,
- flags);
- NPCB_SCT(inet, domain, IPPROTO_DIVERT, list,
- flags);
- NPCB_SCT(inet, domain, IPPROTO_RAW, list,
- flags);
- }
- break;
- default:
- list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
- return (-1);
- }
+ return (netstat_inet_sockets(domain, protocol, list, kvm, nl,
+ flags));
break;
default:
list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
return (-1);
}
-#undef NPCB_KVM
-#undef NPCB_SCT
return (0);
}
@@ -568,22 +609,28 @@
stp->st_conn = (u_long)0;
stp->st_refs = (u_long)0;
stp->st_reflink = (u_long)0;
- stp->st_flags = SOCKTYPE_TCP;
+ stp->st_flags = 0;
/* XXX: Remove this. */
stp->XXX_inpcb = *inp;
/* XXX: address is missing. */
stp->st_address[0] = '\0';
- if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
- sprintf(stp->st_tcpstate, "%d", tp->t_state);
- else {
- sprintf(stp->st_tcpstate, "%s", tcpstates[tp->t_state]);
+ if (tp != NULL) {
+ if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES)
+ sprintf(stp->st_tcpstate, "%d", tp->t_state);
+ else {
+ sprintf(stp->st_tcpstate, "%s", tcpstates[tp->t_state]);
#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
- /* T/TCP `hidden state' */
- if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) {
- stp->st_tcpstate[0] = '*';
- stp->st_tcpstate[1] = '\0';
+ /* T/TCP `hidden state' */
+ if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) {
+ stp->st_tcpstate[0] = '*';
+ stp->st_tcpstate[1] = '\0';
+ }
+#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
}
-#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+ stp->st_flags |= SOCKTYPE_TCP;
+ } else {
+ /* Has no TCP state. */
+ stp->st_tcpstate[0] = '\0';
}
#ifdef INET6
if ((inp->inp_vflag & INP_IPV6) != 0)
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#5 (text+ko) ====
@@ -35,6 +35,7 @@
*/
#include <sys/cdefs.h>
+#include <netstat.h>
extern int Aflag; /* show addresses of protocol control block */
extern int aflag; /* show all sockets (including servers) */
@@ -69,6 +70,8 @@
int sotoxsocket(struct socket *, struct xsocket *);
void inetpr(void *, int, int);
+void inetppr(struct socket_type *);
+void unixdomainpr(struct socket_type *);
void tcp_stats(u_long, const char *, int, int);
void udp_stats(u_long, const char *, int, int);
#ifdef SCTP
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#13 (text+ko) ====
@@ -95,7 +95,6 @@
#ifdef INET6
static int udp_done, tcp_done;
#endif /* INET6 */
-static void inetppr(struct socket_type *);
/*
* Print a summary of connections related to an Internet
@@ -146,6 +145,8 @@
inetppr(stp);
netstat_st_free(stp);
}
+ netstat_sti_free(stip);
+ netstat_stl_free(stlp);
#else
netstat_stl_iterate(stlp, inetppr);
#endif
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#8 (text+ko) ====
@@ -73,6 +73,9 @@
#include <unistd.h>
#include "extern.h"
+#include <netstat.h>
+
+
static struct nlist nl[] = {
#define N_IFNET 0
{ .n_name = "_ifnet" },
@@ -294,6 +297,7 @@
#endif
atalkprotox, NULL };
+static void connpr(struct socket_type *);
static void printproto(struct protox *, const char *);
static void usage(void);
static struct protox *name2protox(const char *);
@@ -336,6 +340,11 @@
struct protox *tp = NULL; /* for printing cblocks & stats */
int ch;
+ struct socket_type_list *stlp;
+ int error, st_flags;
+ struct socket_type_iterator *stip;
+ struct socket_type *stp;
+
af = AF_UNSPEC;
while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:xz")) != -1)
@@ -552,11 +561,11 @@
printproto(tp, tp->pr_name);
exit(0);
}
- if (af == AF_INET || af == AF_UNSPEC)
+ if (af == AF_INET)
for (tp = protox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#ifdef INET6
- if (af == AF_INET6 || af == AF_UNSPEC)
+ if (af == AF_INET6)
for (tp = ip6protox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#endif /*INET6*/
@@ -579,11 +588,64 @@
for (tp = netgraphprotox; tp->pr_name; tp++)
printproto(tp, tp->pr_name);
#endif /* NETGRAPH */
- if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
+ if (af == AF_UNIX && !sflag)
unixpr(kvmd);
+ if (af == AF_UNSPEC) {
+ stlp = netstat_stl_alloc();
+ if (stlp == NULL) {
+ warn("netstat_stl_alloc");
+ exit(-1);
+ }
+ st_flags = 0;
+ if (!live)
+ st_flags |= NETSTAT_SOCKET_KVM;
+ if (aflag)
+ st_flags |= NETSTAT_SOCKET_ALL;
+ /*
+ * There should be guaranteed that sockets are not mixed (i.e.
+ * they are coming ordered by family/protocol).
+ */
+ if (netstat_socket(PF_UNSPEC, 0, 0, stlp, st_flags,
+ kvmd) < 0) {
+ error = netstat_stl_geterror(stlp);
+ if (error == NETSTAT_ERROR_KVM)
+ warnx("netstat_socket: %s", kvm_geterr(kvmd));
+ else
+ warnx("netstat_socket: %s",
+ netstat_strerror(error));
+ exit(-1);
+ }
+ if (netstat_sti_alloc(stlp, &stip) < 0) {
+ warnx("netstat_sti_alloc");
+ exit(-1);
+ }
+ for (stp = netstat_sti_first(stip); stp != NULL;
+ stp = netstat_sti_next(stip)) {
+ connpr(stp);
+ netstat_st_free(stp);
+ }
+ netstat_sti_free(stip);
+ netstat_stl_free(stlp);
+ }
exit(0);
}
+static void
+connpr(struct socket_type *stp)
+{
+ switch (netstat_st_get_family(stp)) {
+ case PF_INET:
+ case PF_INET6:
+ inetppr(stp);
+ break;
+ case PF_LOCAL:
+ unixdomainpr(stp);
+ break;
+ default:
+ break;
+ }
+}
+
/*
* Print out protocol statistics or control blocks (per sflag).
* If the interface was not specifically requested, and the symbol
@@ -650,7 +712,8 @@
case IPPROTO_IGMP:
case IPPROTO_PIM:
case IPPROTO_ICMPV6:
- inetpr(kvmd, af, tp->pr_protocol);
+ inetpr(kvmd, (af == PF_INET6) ? af : PF_INET,
+ tp->pr_protocol);
break;
default:
if (pr != NULL)
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#12 (text+ko) ====
@@ -55,8 +55,6 @@
#define USE_ITERATOR_TYPE
-static void unixdomainpr(struct socket_type *);
-
void
unixpr(void *kvmd)
{
@@ -105,12 +103,14 @@
unixdomainpr(stp);
netstat_st_free(stp);
}
+ netstat_sti_free(stip);
+ netstat_stl_free(stlp);
#else
netstat_stl_iterate(stlp, unixdomainpr);
#endif
}
-static void
+void
unixdomainpr(struct socket_type *stp)
{
static int first = 1;
More information about the p4-projects
mailing list