PERFORCE change 165376 for review
Gabor Pali
pgj at FreeBSD.org
Mon Jun 29 09:18:12 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165376
Change 165376 by pgj at petymeg-current on 2009/06/29 09:17:15
Add "spcblist" sysctl(8) variable for TCP connnections.
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/sys/netinet/tcp_subr.c#3 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/sys/netinet/tcp_subr.c#3 (text+ko) ====
@@ -46,6 +46,7 @@
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#include <sys/sbuf.h>
#ifdef INET6
#include <sys/domain.h>
#endif
@@ -1154,6 +1155,137 @@
tcp_pcblist, "S,xtcpcb", "List of active TCP connections");
static int
+tcp_spcblist(SYSCTL_HANDLER_ARGS)
+{
+ struct inpcb_stream is;
+ struct inpcb_data id;
+ struct sbuf sbuf;
+ int error, i, buflen;
+ char *buffer;
+
+ struct inpcb *inp, **inp_list;
+ struct socket *sock;
+ struct tcpcb *pcb;
+
+ bzero(&is, sizeof(is));
+ is.is_version = INPCB_STREAM_VERSION;
+
+ INP_INFO_RLOCK(&V_tcbinfo);
+ is.is_gencnt = V_tcbinfo.ipi_gencnt;
+ is.is_count = V_tcbinfo.ipi_count;
+ INP_INFO_RUNLOCK(&V_tcbinfo);
+
+ inp_list = malloc(is.is_count * sizeof(*inp_list), M_TEMP, M_WAITOK);
+ if (inp_list == NULL)
+ return (ENOMEM);
+
+ INP_INFO_RLOCK(&V_tcbinfo);
+ for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
+ inp != NULL && i < is.is_count; inp = LIST_NEXT(inp, inp_list)) {
+ INP_RLOCK(inp);
+ if (inp->inp_gencnt <= is.is_gencnt) {
+ if (inp->inp_flags & INP_TIMEWAIT) {
+ if (intotw(inp) != NULL)
+ error = cr_cansee(req->td->td_ucred,
+ intotw(inp)->tw_cred);
+ else
+ error = EINVAL;
+ } else
+ error = cr_canseeinpcb(req->td->td_ucred, inp);
+ if (error == 0)
+ inp_list[i++] = inp;
+ }
+ INP_RUNLOCK(inp);
+ }
+ INP_INFO_RUNLOCK(&V_tcbinfo);
+ is.is_count = i;
+
+ error = 0;
+ buflen = sizeof(is) + is.is_count * sizeof(id) + 1;
+ buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
+ sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN);
+
+ if (sbuf_bcat(&sbuf, &is, sizeof(is)) < 0) {
+ error = ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < is.is_count; i++) {
+ inp = inp_list[i];
+ INP_RLOCK(inp);
+ if (inp->inp_gencnt <= is.is_gencnt) {
+ bzero(&id, sizeof(id));
+ id.id_gencnt = inp->inp_gencnt;
+ sock = inp->inp_socket;
+ if (sock != NULL) {
+ id.id_qlen = sock->so_qlen;
+ id.id_incqlen = sock->so_incqlen;
+ id.id_qlimit = sock->so_qlimit;
+ id.id_snd_cc = sock->so_snd.sb_cc;
+ id.id_snd_mcnt = sock->so_snd.sb_mcnt;
+ id.id_snd_ccnt = sock->so_snd.sb_ccnt;
+ id.id_snd_hiwat = sock->so_snd.sb_hiwat;
+ id.id_snd_lowat = sock->so_snd.sb_lowat;
+ id.id_snd_mbcnt = sock->so_snd.sb_mbcnt;
+ id.id_snd_mbmax = sock->so_snd.sb_mbmax;
+ id.id_rcv_cc = sock->so_rcv.sb_cc;
+ id.id_rcv_mcnt = sock->so_rcv.sb_mcnt;
+ id.id_rcv_ccnt = sock->so_rcv.sb_ccnt;
+ id.id_rcv_hiwat = sock->so_rcv.sb_hiwat;
+ id.id_rcv_lowat = sock->so_rcv.sb_lowat;
+ id.id_rcv_mbcnt = sock->so_rcv.sb_mbcnt;
+ id.id_rcv_mbmax = sock->so_rcv.sb_mbmax;
+ id.id_pcb = (u_long)sock->so_pcb;
+ id.id_protocol = sock->so_proto->pr_protocol;
+ } else {
+ id.id_protocol = IPPROTO_TCP;
+ }
+ pcb = (struct tcpcb *)inp->inp_ppcb;
+ if (pcb != NULL) {
+ if (inp->inp_flags & INP_TIMEWAIT)
+ id.id_state = TCPS_TIME_WAIT;
+ else
+ id.id_state = pcb->t_state;
+ }
+ id.id_flags = inp->inp_flags;
+ id.id_vflag = inp->inp_vflag;
+ id.id_lport = inp->inp_lport;
+ id.id_fport = inp->inp_fport;
+ if (inp->inp_vflag & INP_IPV4) {
+ bcopy(&inp->inp_laddr, &id.id_laddr,
+ sizeof(inp->inp_laddr));
+ bcopy(&inp->inp_faddr, &id.id_faddr,
+ sizeof(inp->inp_faddr));
+ }
+#ifdef INET6
+ else if (inp->inp_vflag & INP_IPV6) {
+ bcopy(&inp->in6p_laddr, &id.id_laddr,
+ sizeof(inp->in6p_laddr));
+ bcopy(&inp->in6p_faddr, &id.id_faddr,
+ sizeof(inp->in6p_faddr));
+ }
+#endif
+ if (sbuf_bcat(&sbuf, &id, sizeof(id)) < 0) {
+ INP_RUNLOCK(inp);
+ error = ENOMEM;
+ goto out;
+ }
+ }
+ INP_RUNLOCK(inp);
+ }
+ sbuf_finish(&sbuf);
+ error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
+out:
+ free(inp_list, M_TEMP);
+ free(buffer, M_TEMP);
+ return (error);
+}
+
+SYSCTL_PROC(_net_inet_tcp, OID_AUTO, spcblist, CTLFLAG_RD|CTLTYPE_STRUCT,
+ 0, 0, tcp_spcblist, "s,struct inpcb_data",
+ "List of active TCP connections (stream)");
+
+static int
tcp_getcred(SYSCTL_HANDLER_ARGS)
{
INIT_VNET_INET(curvnet);
More information about the p4-projects
mailing list