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