PERFORCE change 163933 for review
Gabor Pali
pgj at FreeBSD.org
Tue Jun 9 21:01:20 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163933
Change 163933 by pgj at petymeg-current on 2009/06/09 21:00:22
Start to use libnetstat for displaying tcp connections -- needs
some work, still contains hacks
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#3 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 (text+ko) ====
@@ -18,4 +18,8 @@
WITHOUT_MAN= yes
+.if ${MK_INET6_SUPPORT} != "no"
+CFLAGS+= -DINET6
+.endif
+
.include <bsd.lib.mk>
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 (text+ko) ====
@@ -9,6 +9,11 @@
#include <err.h>
#include <errno.h>
#include <kvm.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
+#define TCPSTATES
+#include <netinet/tcp_fsm.h>
#include <nlist.h>
#include <stdio.h>
#include <stdlib.h>
@@ -17,7 +22,7 @@
#include "netstat_internal.h"
static struct nlist nl[] = {
-/* UNP_###-related variables. */
+/* UNP_###-related */
#define X_UNP_COUNT 0
{ .n_name = "_unp_count" },
#define X_UNP_GENCNT 1
@@ -27,19 +32,32 @@
#define X_UNP_SHEAD 3
{ .n_name = "_unp_shead" },
{ .n_name = NULL },
+/* INET-related */
+#define X_TCBINFO 5
+ { .n_name = "_tcbinfo" },
+#define X_UDBINFO 6
+ { .n_name = "_udbinfo" },
+ { .n_name = NULL },
};
static void extract_xunpcb_data(struct xunpcb *, struct socket_type *);
+static void extract_inet_data(struct tcpcb *, struct inpcb *,
+ struct xsocket *, struct socket_type *);
+/* type names */
static const char *const socktype[] =
{ "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
+static const char *const ipproto[] =
+ { "hopopts", "igmp", "tcp", "ggp", "ipv4", "ipip", "st", "egp", "pgip",
+ "rccmon", "nvpii", "pup", "argus", "emcon", "xnet", "chaos", "udp" };
+
static int
net_local_pcblist_sysctl(int type, struct socket_type_list *list)
{
char *buf;
size_t len;
- char mibvar[sizeof "net.local.seqpacket.pcblist"];
+ char mibvar[64];
struct xunpgen *xug, *oxug;
struct xunpcb *xunp;
@@ -156,6 +174,75 @@
#undef KREAD
}
+static int
+net_inet_pcblist_sysctl(int protocol, struct socket_type_list *list)
+{
+ char *buf;
+ size_t len;
+ char mibvar[64];
+
+ struct xinpgen *xig, *oxig;
+ struct tcpcb *tp = NULL;
+ struct inpcb *inp;
+ struct xsocket *so;
+
+ struct socket_type *stp;
+
+ sprintf(mibvar, "net.inet.%s.pcblist", ipproto[protocol]);
+
+ len = 0;
+ if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
+ if (errno != ENOENT)
+ warn("sysctl: %s", mibvar);
+ return (-1);
+ }
+ if ((buf = malloc(len)) == 0) {
+ warnx("malloc %lu bytes", (u_long)len);
+ return (-2);
+ }
+ if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
+ warn("sysctl: %s", mibvar);
+ free(buf);
+ return (-2);
+ }
+
+ oxig = xig = (struct xinpgen *)buf;
+ for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+ xig->xig_len > sizeof(struct xinpgen);
+ xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
+ if (protocol == IPPROTO_TCP) {
+ tp = &((struct xtcpcb *)xig)->xt_tp;
+ inp = &((struct xtcpcb *)xig)->xt_inp;
+ so = &((struct xtcpcb *)xig)->xt_socket;
+ } else {
+ inp = &((struct xinpcb *)xig)->xi_inp;
+ so = &((struct xinpcb *)xig)->xi_socket;
+ }
+
+ /* Ignore sockets for protocols other than the desired one.
+ XXX: is this needed? */
+ if (so->xso_protocol != protocol)
+ continue;
+
+ if (inp->inp_gencnt <= oxig->xig_gen) {
+ stp = _netstat_st_allocate(list, PF_INET, protocol,
+ ipproto[protocol]);
+ extract_inet_data(tp, inp, so, stp);
+ }
+ }
+
+ free(buf);
+ return (0);
+}
+
+static int
+net_inet_pcblist_kvm(int protocol, struct socket_type_list *list,
+ kvm_t *kvm, struct nlist *nlistp)
+{
+ /* XXX: to be filled in. */
+ return (0);
+}
+
int
netstat_socket(int domain, int type, int protocol,
struct socket_type_list *list, int flags, void *kvm_handle)
@@ -173,18 +260,18 @@
}
}
-#define NLP_KVM(type, list, kvm, nl) do { \
- if (net_local_pcblist_kvm((type), (list), (kvm), (nl)) != 0) { \
- list->stl_error = NETSTAT_ERROR_UNDEFINED; \
- return (-1); \
- } \
+#define NPCB_KVM(family, type, list, kvm, nl) do { \
+ if (net_##family##_pcblist_kvm((type), (list), (kvm), (nl)) != 0) { \
+ list->stl_error = NETSTAT_ERROR_UNDEFINED; \
+ return (-1); \
+ } \
} while (0)
-#define NLP_SCT(type, list) do { \
- if (net_local_pcblist_sysctl((type), (list)) != 0) { \
- list->stl_error = NETSTAT_ERROR_UNDEFINED; \
- return (-1); \
- } \
+#define NPCB_SCT(family, type, list) do { \
+ if (net_##family##_pcblist_sysctl((type), (list)) != 0) { \
+ list->stl_error = NETSTAT_ERROR_UNDEFINED; \
+ return (-1); \
+ } \
} while (0)
switch (domain) {
@@ -193,18 +280,43 @@
case SOCK_STREAM:
case SOCK_DGRAM:
if (use_kvm)
- NLP_KVM(type, list, kvm, nl);
+ NPCB_KVM(local, type, list, kvm, nl);
else
/* Use sysctl (or something else). */
- NLP_SCT(type, list);
+ NPCB_SCT(local, type, list);
+ break;
/* All PF_LOCAL */
case 0:
if (use_kvm) {
- NLP_KVM(SOCK_STREAM, list, kvm, nl);
- NLP_KVM(SOCK_DGRAM, list, kvm, nl);
+ NPCB_KVM(local, SOCK_STREAM, list, kvm, nl);
+ NPCB_KVM(local, SOCK_DGRAM, list, kvm, nl);
+ } else {
+ NPCB_SCT(local, SOCK_STREAM, list);
+ NPCB_SCT(local, SOCK_DGRAM, list);
+ }
+ break;
+ default:
+ list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
+ return (-1);
+ }
+ break;
+ case PF_INET:
+ switch (protocol) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ if (use_kvm)
+ NPCB_KVM(inet, protocol, list, kvm, nl);
+ else
+ NPCB_SCT(inet, protocol, list);
+ break;
+ /* All PF_INET */
+ case 0:
+ if (use_kvm) {
+ NPCB_KVM(inet, IPPROTO_TCP, list, kvm, nl);
+ NPCB_KVM(inet, IPPROTO_UDP, list, kvm, nl);
} else {
- NLP_SCT(SOCK_STREAM, list);
- NLP_SCT(SOCK_DGRAM, list);
+ NPCB_SCT(inet, IPPROTO_TCP, list);
+ NPCB_SCT(inet, IPPROTO_UDP, list);
}
break;
default:
@@ -216,8 +328,8 @@
list->stl_error = NETSTAT_ERROR_UNSUPPORTED;
return (-1);
}
-#undef NLP_KVM
-#undef NLP_SCT
+#undef NPCB_KVM
+#undef NPCB_SCT
return (0);
}
@@ -230,12 +342,24 @@
stp->st_incqlen = xpcb->xu_socket.so_incqlen;
stp->st_qlimit = xpcb->xu_socket.so_qlimit;
stp->st_snd_cc = xpcb->xu_socket.so_snd.sb_cc;
+ stp->st_snd_mcnt = xpcb->xu_socket.so_snd.sb_mcnt;
+ stp->st_snd_ccnt = xpcb->xu_socket.so_snd.sb_ccnt;
+ stp->st_snd_hiwat = xpcb->xu_socket.so_snd.sb_hiwat;
+ stp->st_snd_lowat = xpcb->xu_socket.so_snd.sb_lowat;
+ stp->st_snd_mbcnt = xpcb->xu_socket.so_snd.sb_mbcnt;
+ stp->st_snd_mbmax = xpcb->xu_socket.so_snd.sb_mbmax;
stp->st_rcv_cc = xpcb->xu_socket.so_rcv.sb_cc;
- stp->st_pcb = (long)xpcb->xu_socket.so_pcb;
- stp->st_vnode = (long)xpcb->xu_unp.unp_vnode;
- stp->st_conn = (long)xpcb->xu_unp.unp_conn;
- stp->st_refs = (long)LIST_FIRST(&xpcb->xu_unp.unp_refs);
- stp->st_reflink = (long)LIST_NEXT(&xpcb->xu_unp, unp_reflink);
+ stp->st_rcv_mcnt = xpcb->xu_socket.so_rcv.sb_mcnt;
+ stp->st_rcv_ccnt = xpcb->xu_socket.so_rcv.sb_ccnt;
+ stp->st_rcv_hiwat = xpcb->xu_socket.so_rcv.sb_hiwat;
+ stp->st_rcv_lowat = xpcb->xu_socket.so_rcv.sb_lowat;
+ stp->st_rcv_mbcnt = xpcb->xu_socket.so_rcv.sb_mbcnt;
+ stp->st_rcv_mbmax = xpcb->xu_socket.so_rcv.sb_mbmax;
+ stp->st_pcb = (u_long)xpcb->xu_socket.so_pcb;
+ stp->st_vnode = (u_long)xpcb->xu_unp.unp_vnode;
+ stp->st_conn = (u_long)xpcb->xu_unp.unp_conn;
+ stp->st_refs = (u_long)LIST_FIRST(&xpcb->xu_unp.unp_refs);
+ stp->st_reflink = (u_long)LIST_NEXT(&xpcb->xu_unp, unp_reflink);
stp->st_flags = SOCKTYPE_VNODE | SOCKTYPE_CONN | SOCKTYPE_REFS;
if (xpcb->xu_unp.unp_addr) {
sa = (struct sockaddr_un *)&xpcb->xu_addr;
@@ -245,4 +369,56 @@
} else {
stp->st_address[0] = '\0';
}
+ stp->st_listening = 0;
+ stp->st_tcpstate[0] = '\0';
+}
+
+void
+extract_inet_data(struct tcpcb *tp, struct inpcb *inp, struct xsocket *so,
+ struct socket_type *stp)
+{
+ stp->st_qlen = so->so_qlen;
+ stp->st_incqlen = so->so_incqlen;
+ stp->st_qlimit = so->so_qlimit;
+ stp->st_snd_cc = so->so_snd.sb_cc;
+ stp->st_snd_mcnt = so->so_snd.sb_mcnt;
+ stp->st_snd_ccnt = so->so_snd.sb_ccnt;
+ stp->st_snd_hiwat = so->so_snd.sb_hiwat;
+ stp->st_snd_lowat = so->so_snd.sb_lowat;
+ stp->st_snd_mbcnt = so->so_snd.sb_mbcnt;
+ stp->st_snd_mbmax = so->so_snd.sb_mbmax;
+ stp->st_rcv_cc = so->so_rcv.sb_cc;
+ stp->st_rcv_mcnt = so->so_rcv.sb_mcnt;
+ stp->st_rcv_ccnt = so->so_rcv.sb_ccnt;
+ stp->st_rcv_hiwat = so->so_rcv.sb_hiwat;
+ stp->st_rcv_lowat = so->so_rcv.sb_lowat;
+ stp->st_rcv_mbcnt = so->so_rcv.sb_mbcnt;
+ stp->st_rcv_mbmax = so->so_rcv.sb_mbmax;
+ stp->st_pcb = (tp == NULL) ? (u_long)inp->inp_ppcb :
+ (u_long)so->so_pcb;
+ stp->st_vnode = (u_long)0;
+ stp->st_conn = (u_long)0;
+ stp->st_refs = (u_long)0;
+ stp->st_reflink = (u_long)0;
+ stp->st_flags = SOCKTYPE_TCP;
+ /* XXX: Remove this. */
+ if (tp != NULL)
+ stp->XXX_tcpcb = *tp;
+ stp->XXX_inpcb = *inp;
+ stp->XXX_xsocket = *so;
+ /* XXX: address is missing. */
+ stp->st_address[0] = '\0';
+ stp->st_listening = (tp->t_state == TCPS_LISTEN);
+ 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';
+ }
+#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+ }
}
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 (text+ko) ====
@@ -56,17 +56,36 @@
int netstat_st_get_family(const struct socket_type *stp);
int netstat_st_get_protocol(const struct socket_type *stp);
const char *netstat_st_get_name(const struct socket_type *stp);
+/* XXX: move snd/rcv-related properties into a new abstract type? */
u_int netstat_st_get_snd_cc(const struct socket_type *stp);
+u_int netstat_st_get_snd_hiwat(const struct socket_type *stp);
+u_int netstat_st_get_snd_lowat(const struct socket_type *stp);
+u_int netstat_st_get_snd_mbcnt(const struct socket_type *stp);
+u_int netstat_st_get_snd_mcnt(const struct socket_type *stp);
+u_int netstat_st_get_snd_ccnt(const struct socket_type *stp);
+u_int netstat_st_get_snd_mbmax(const struct socket_type *stp);
u_int netstat_st_get_rcv_cc(const struct socket_type *stp);
+u_int netstat_st_get_rcv_hiwat(const struct socket_type *stp);
+u_int netstat_st_get_rcv_lowat(const struct socket_type *stp);
+u_int netstat_st_get_rcv_mbcnt(const struct socket_type *stp);
+u_int netstat_st_get_rcv_mcnt(const struct socket_type *stp);
+u_int netstat_st_get_rcv_ccnt(const struct socket_type *stp);
+u_int netstat_st_get_rcv_mbmax(const struct socket_type *stp);
u_short netstat_st_get_qlen(const struct socket_type *stp);
u_short netstat_st_get_incqlen(const struct socket_type *stp);
u_short netstat_st_get_qlimit(const struct socket_type *stp);
-long netstat_st_get_pcb(const struct socket_type *stp);
-long netstat_st_get_vnode(const struct socket_type *stp);
-long netstat_st_get_conn(const struct socket_type *stp);
-long netstat_st_get_refs(const struct socket_type *stp);
-long netstat_st_get_reflink(const struct socket_type *stp);
+u_long netstat_st_get_pcb(const struct socket_type *stp);
+u_long netstat_st_get_vnode(const struct socket_type *stp);
+u_long netstat_st_get_conn(const struct socket_type *stp);
+u_long netstat_st_get_refs(const struct socket_type *stp);
+u_long netstat_st_get_reflink(const struct socket_type *stp);
const char *netstat_st_get_address(const struct socket_type *stp);
+int netstat_st_get_listening(const struct socket_type *stp);
+const char *netstat_st_get_tcpstate(const struct socket_type *stp);
+/* XXX: Remove this hacks. */
+struct tcpcb XXX_netstat_st_get_tcpcb(const struct socket_type *stp);
+struct inpcb XXX_netstat_st_get_inpcb(const struct socket_type *stp);
+struct xsocket XXX_netstat_st_get_xsocket(const struct socket_type *stp);
__END_DECLS
#endif /* !_NETSTAT_H_ */
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 (text+ko) ====
@@ -9,6 +9,9 @@
#include <sys/un.h>
#include <sys/unpcb.h>
#include <kvm.h>
+#include <netinet/in.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
/* XXX: not used yet */
/* Address type:
@@ -34,17 +37,36 @@
#endif
u_int st_snd_cc; /* actual chars in the send buffer */
+ u_int st_snd_mcnt;
+ u_int st_snd_ccnt;
+ u_int st_snd_hiwat;
+ u_int st_snd_lowat;
+ u_int st_snd_mbcnt;
+ u_int st_snd_mbmax;
u_int st_rcv_cc; /* actual chars in the receive buffer */
+ u_int st_rcv_mcnt;
+ u_int st_rcv_ccnt;
+ u_int st_rcv_hiwat;
+ u_int st_rcv_lowat;
+ u_int st_rcv_mbcnt;
+ u_int st_rcv_mbmax;
u_short st_qlen; /* number of unaccepted connections */
u_short st_incqlen; /* number of unaccepted incomplete
connections */
u_short st_qlimit; /* max number queued connections */
- long st_pcb; /* protocol control block */
- long st_vnode; /* if associated with file */
- long st_conn; /* control block of connected socket */
- long st_refs; /* referencing socket linked list */
- long st_reflink; /* link in references list */
+ u_long st_pcb; /* protocol control block */
+ u_long st_vnode; /* if associated with file */
+ u_long st_conn; /* control block of connected socket */
+ u_long st_refs; /* referencing socket linked list */
+ u_long st_reflink; /* link in references list */
char st_address[SOCKTYPE_MAXADDR];
+ char st_tcpstate[16];
+ int st_listening;
+
+ /* XXX: Removables. */
+ struct tcpcb XXX_tcpcb;
+ struct inpcb XXX_inpcb;
+ struct xsocket XXX_xsocket;
/* list of types */
LIST_ENTRY(socket_type) st_list;
@@ -54,6 +76,7 @@
#define SOCKTYPE_VNODE 0x01 /* Associated with a file. */
#define SOCKTYPE_CONN 0x02 /* Has a control block connected. */
#define SOCKTYPE_REFS 0x04 /* Has socket references. */
+#define SOCKTYPE_TCP 0x08 /* A TCP socket, has states. */
struct socket_type_list {
LIST_HEAD(, socket_type) stl_list;
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 (text+ko) ====
@@ -259,11 +259,83 @@
}
u_int
+netstat_st_get_rcv_hiwat(const struct socket_type *stp)
+{
+ return (stp->st_rcv_hiwat);
+}
+
+u_int
+netstat_st_get_rcv_lowat(const struct socket_type *stp)
+{
+ return (stp->st_rcv_lowat);
+}
+
+u_int
+netstat_st_get_rcv_mbcnt(const struct socket_type *stp)
+{
+ return (stp->st_rcv_mbcnt);
+}
+
+u_int
+netstat_st_get_rcv_mcnt(const struct socket_type *stp)
+{
+ return (stp->st_rcv_mcnt);
+}
+
+u_int
+netstat_st_get_rcv_ccnt(const struct socket_type *stp)
+{
+ return (stp->st_rcv_ccnt);
+}
+
+u_int
+netstat_st_get_rcv_mbmax(const struct socket_type *stp)
+{
+ return (stp->st_rcv_mbmax);
+}
+
+u_int
netstat_st_get_snd_cc(const struct socket_type *stp)
{
return (stp->st_snd_cc);
}
+u_int
+netstat_st_get_snd_hiwat(const struct socket_type *stp)
+{
+ return (stp->st_snd_hiwat);
+}
+
+u_int
+netstat_st_get_snd_lowat(const struct socket_type *stp)
+{
+ return (stp->st_snd_lowat);
+}
+
+u_int
+netstat_st_get_snd_mbcnt(const struct socket_type *stp)
+{
+ return (stp->st_snd_mbcnt);
+}
+
+u_int
+netstat_st_get_snd_mcnt(const struct socket_type *stp)
+{
+ return (stp->st_snd_mcnt);
+}
+
+u_int
+netstat_st_get_snd_ccnt(const struct socket_type *stp)
+{
+ return (stp->st_snd_ccnt);
+}
+
+u_int
+netstat_st_get_snd_mbmax(const struct socket_type *stp)
+{
+ return (stp->st_snd_mbmax);
+}
+
u_short
netstat_st_get_qlen(const struct socket_type *stp)
{
@@ -282,31 +354,31 @@
return (stp->st_qlimit);
}
-long
+u_long
netstat_st_get_pcb(const struct socket_type *stp)
{
return (stp->st_pcb);
}
-long
+u_long
netstat_st_get_vnode(const struct socket_type *stp)
{
return (stp->st_vnode);
}
-long
+u_long
netstat_st_get_conn(const struct socket_type *stp)
{
return (stp->st_conn);
}
-long
+u_long
netstat_st_get_refs(const struct socket_type *stp)
{
return (stp->st_refs);
}
-long
+u_long
netstat_st_get_reflink(const struct socket_type *stp)
{
return (stp->st_reflink);
@@ -317,3 +389,34 @@
{
return (stp->st_address);
}
+
+int
+netstat_st_get_listening(const struct socket_type *stp)
+{
+ return (stp->st_listening);
+}
+
+const char *
+netstat_st_get_tcpstate(const struct socket_type *stp)
+{
+ return (stp->st_tcpstate);
+}
+
+/* XXX: Remove this hacks. */
+struct tcpcb
+XXX_netstat_st_get_tcpcb(const struct socket_type *stp)
+{
+ return (stp->XXX_tcpcb);
+}
+
+struct inpcb
+XXX_netstat_st_get_inpcb(const struct socket_type *stp)
+{
+ return (stp->XXX_inpcb);
+}
+
+struct xsocket
+XXX_netstat_st_get_xsocket(const struct socket_type *stp)
+{
+ return (stp->XXX_xsocket);
+}
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 (text+ko) ====
@@ -69,6 +69,7 @@
int sotoxsocket(struct socket *, struct xsocket *);
void protopr(u_long, const char *, int, int);
+void inetpr(void *, int);
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#3 (text+ko) ====
@@ -83,13 +83,19 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
+#include <kvm.h>
+#include <netstat.h>
#include "extern.h"
+#define USE_ITERATOR_TYPE
+
char *inetname(struct in_addr *);
void inetprint(struct in_addr *, int, const char *, int);
#ifdef INET6
static int udp_done, tcp_done;
#endif /* INET6 */
+static void inetppr(struct socket_type *);
static int
pcblist_sysctl(int proto, char **bufp, int istcp)
@@ -554,6 +560,225 @@
free(buf);
}
+void
+inetpr(void *kvmd, int proto)
+{
+ struct socket_type_list *stlp;
+ int error, st_flags;
+ kvm_t *kvm;
+#ifdef USE_ITERATOR_TYPE
+ struct socket_type_iterator *stip;
+ struct socket_type *stp;
+#endif
+
+ kvm = (kvm_t *)kvmd;
+ stlp = netstat_stl_alloc();
+ if (stlp == NULL) {
+ warn("netstat_stl_alloc");
+ return;
+ }
+
+ st_flags = 0;
+ if (live)
+ st_flags |= NETSTAT_SOCKET_KVM;
+
+ if (netstat_socket(PF_INET, 0, proto, stlp, st_flags, kvm) < 0) {
+ error = netstat_stl_geterror(stlp);
+ if (error == NETSTAT_ERROR_KVM)
+ warnx("netstat_socket: %s", kvm_geterr(kvm));
+ else
+ warnx("netstat_socket: %s", netstat_strerror(error));
+ return;
+ }
+
+#ifdef USE_ITERATOR_TYPE
+ if (netstat_sti_alloc(stlp, &stip) < 0) {
+ warnx("netstat_sti_alloc");
+ return;
+ }
+ for (stp = netstat_sti_first(stip); stp != NULL;
+ stp = netstat_sti_next(stip)) {
+ inetppr(stp);
+ netstat_st_free(stp);
+ }
+#else
+ netstat_stl_iterate(stlp, inetppr);
+#endif
+}
+
+void
+inetppr(struct socket_type *stp)
+{
+ static int first = 1;
+ char buf1[15];
+ const char *vchar;
+ struct tcpcb tp;
+ struct inpcb inp;
+ struct xsocket so;
+ int istcp;
+
+ istcp = 0;
+ inp = XXX_netstat_st_get_inpcb(stp);
+ so = XXX_netstat_st_get_xsocket(stp);
+ if (netstat_st_get_protocol(stp) == IPPROTO_TCP) {
+ tp = XXX_netstat_st_get_tcpcb(stp);
+ istcp = 1;
+ }
+/* XXX: af1 */
+#if 0
+ if ((af1 == AF_INET && (inp.inp_vflag & INP_IPV4) == 0)
+#ifdef INET6
+ || (af1 == AF_INET6 && (inp.inp_vflag & INP_IPV6) == 0)
+#endif /* INET6 */
+ || (af1 == AF_UNSPEC && ((inp.inp_vflag & INP_IPV4) == 0
+#ifdef INET6
+ && (inp.inp_vflag & INP_IPV6) == 0
+#endif /* INET6 */
+ ))
+ )
+ continue;
+ if (!aflag &&
+ (
+ (istcp && netstat_st_get_listening(stp))
+ || (af1 == AF_INET &&
+ inet_lnaof(inp.inp_laddr) == INADDR_ANY)
+#ifdef INET6
+ || (af1 == AF_INET6 &&
+ IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr))
+#endif /* INET6 */
+ || (af1 == AF_UNSPEC &&
+ (((inp.inp_vflag & INP_IPV4) != 0 &&
+ inet_lnaof(inp.inp_laddr) == INADDR_ANY)
+#ifdef INET6
+ || ((inp.inp_vflag & INP_IPV6) != 0 &&
+ IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr))
+#endif
+ ))
+ ))
+ return;
+#endif
+ if (first) {
+ if (!Lflag) {
+ printf("Active Internet connections");
+ if (aflag)
+ printf(" (including servers)");
+ } else
+ printf(
+ "Current listen queue sizes (qlen/incqlen/maxqlen)");
+ putchar('\n');
+ if (Aflag)
+ printf("%-8.8s ", "Tcpcb");
+ if (Lflag)
+ printf("%-5.5s %-14.14s %-22.22s\n",
+ "Proto", "Listen", "Local Address");
+ else {
+ printf((Aflag && !Wflag) ?
+ "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" :
+ "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s",
+ "Proto", "Recv-Q", "Send-Q",
+ "Local Address", "Foreign Address");
+ if (xflag)
+ printf(
+ "%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s\n",
+ "R-MBUF", "S-MBUF", "R-CLUS",
+ "S-CLUS", "R-HIWA", "S-HIWA",
+ "R-LOWA", "S-LOWA", "R-BCNT",
+ "S-BCNT", "R-BMAX", "S-BMAX");
+ else
+ printf("(state)\n");
+ }
+ first = 0;
+ }
+ if (Lflag && so.so_qlimit == 0)
+ return;
+ if (Aflag)
+ printf("%8lx ", netstat_st_get_pcb(stp));
+#ifdef INET6
+ if ((inp.inp_vflag & INP_IPV6) != 0)
+ vchar = ((inp.inp_vflag & INP_IPV4) != 0) ?
+ "46" : "6 ";
+ else
+#endif
+ vchar = ((inp.inp_vflag & INP_IPV4) != 0) ?
+ "4 " : " ";
+ printf("%-3.3s%-2.2s", netstat_st_get_name(stp), vchar);
+ if (Lflag) {
+ snprintf(buf1, 15, "%d/%d/%d", netstat_st_get_qlen(stp),
+ netstat_st_get_incqlen(stp), netstat_st_get_qlimit(stp));
+ printf("%-14.14s", buf1);
+ } else {
+ printf("%6u %6u", netstat_st_get_rcv_cc(stp),
+ netstat_st_get_snd_cc(stp));
+ }
+ if (numeric_port) {
+ if (inp.inp_vflag & INP_IPV4) {
+ inetprint(&inp.inp_laddr, (int)inp.inp_lport,
+ netstat_st_get_name(stp), 1);
+ if (!Lflag)
+ inetprint(&inp.inp_faddr,
+ (int)inp.inp_fport,
+ netstat_st_get_name(stp), 1);
+ }
+#ifdef INET6
+ else if (inp.inp_vflag & INP_IPV6) {
+ inet6print(&inp.in6p_laddr,
+ (int)inp.inp_lport, netstat_st_get_name(stp), 1);
+ if (!Lflag)
+ inet6print(&inp.in6p_faddr,
+ (int)inp.inp_fport,
+ netstat_st_get_name(stp), 1);
+ } /* else nothing printed now */
+#endif /* INET6 */
+ } else if (inp.inp_flags & INP_ANONPORT) {
+ if (inp.inp_vflag & INP_IPV4) {
+ inetprint(&inp.inp_laddr, (int)inp.inp_lport,
+ netstat_st_get_name(stp), 1);
+ if (!Lflag)
+ inetprint(&inp.inp_faddr,
+ (int)inp.inp_fport,
+ netstat_st_get_name(stp), 0);
+ }
+#ifdef INET6
+ else if (inp.inp_vflag & INP_IPV6) {
+ inet6print(&inp.in6p_laddr,
+ (int)inp.inp_lport, netstat_st_get_name(stp), 1);
+ if (!Lflag)
+ inet6print(&inp.in6p_faddr,
+ (int)inp.inp_fport,
+ netstat_st_get_name(stp), 0);
+ } /* else nothing printed now */
+#endif /* INET6 */
+ else if (inp.inp_vflag & INP_IPV6) {
+ inet6print(&inp.in6p_laddr,
+ (int)inp.inp_lport, netstat_st_get_name(stp), 0);
+ if (!Lflag)
+ inet6print(&inp.in6p_faddr,
+ (int)inp.inp_fport,
+ netstat_st_get_name(stp),
+ inp.inp_lport != inp.inp_fport);
+ } /* else nothing printed now */
+ }
+ if (xflag) {
+ if (Lflag)
+ printf("%21s", " ");
+ printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u",
+ netstat_st_get_rcv_mcnt(stp), netstat_st_get_snd_mcnt(stp),
+ netstat_st_get_rcv_ccnt(stp), netstat_st_get_snd_ccnt(stp),
+ netstat_st_get_rcv_hiwat(stp),
+ netstat_st_get_snd_hiwat(stp),
+ netstat_st_get_rcv_lowat(stp),
+ netstat_st_get_snd_lowat(stp),
+ netstat_st_get_rcv_mbcnt(stp),
+ netstat_st_get_snd_mbcnt(stp),
+ netstat_st_get_rcv_mbmax(stp),
+ netstat_st_get_snd_mbmax(stp));
+ }
+ if (istcp && !Lflag) {
+ printf("%s", netstat_st_get_tcpstate(stp));
+ }
+ putchar('\n');
+}
+
/*
* Dump TCP statistics structure.
*/
==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 (text+ko) ====
@@ -652,8 +652,13 @@
off = nl[tp->pr_index].n_value;
}
if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
- af != AF_UNSPEC))
- (*pr)(off, name, af, tp->pr_protocol);
+ af != AF_UNSPEC)) {
+ /* XXX: temp. hack */
+ if (tp->pr_index == N_TCBINFO)
+ inetpr(kvmd, IPPROTO_TCP);
+ else
+ (*pr)(off, name, af, tp->pr_protocol);
+ }
}
/*
More information about the p4-projects
mailing list