PERFORCE change 165380 for review

Gabor Pali pgj at FreeBSD.org
Mon Jun 29 09:21:16 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=165380

Change 165380 by pgj at petymeg-current on 2009/06/29 09:20:38

	Modify libnetstat to use spcblist structures for monitoring inet
	connections.

Affected files ...

.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#36 edit

Differences ...

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#36 (text+ko) ====

@@ -54,6 +54,7 @@
 static void extract_unpcb_data(struct unpcb_data *, struct socket_type *);
 static void extract_inet_data(struct tcpcb *, struct inpcb *,
     struct xsocket *, struct socket_type *);
+static void extract_inpcb_data(struct inpcb_data *, struct socket_type *);
 
 static char ntop_buf[INET_ADDRSTRLEN];
 static char ntop_buf6[INET6_ADDRSTRLEN];
@@ -167,18 +168,17 @@
 net_inet_pcblist_sysctl(int family, int protocol,
     struct socket_type_list *list, int flags)
 {
-	char	*buf;
+	char	*buf, *p;
 	size_t	len;
 	char	mibvar[64];
 
-	struct	xinpgen	    *xig, *oxig;
-	struct	tcpcb	    *tp = NULL;
-	struct	inpcb	    *inp;
-	struct	xsocket	    *so;
+	u_int i;
 
-	struct	socket_type *stp;
+	struct	    inpcb_stream *isp;
+	struct	    inpcb_data *idp;
+	struct	    socket_type *stp;
 
-	sprintf(mibvar, "net.inet.%s.pcblist", ipproto(protocol));
+	sprintf(mibvar, "net.inet.%s.spcblist", ipproto(protocol));
 
 	len = 0;
 	if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
@@ -195,60 +195,65 @@
 		free(buf);
 		return (-2);
 	}
+	if (len < sizeof(*isp)) {
+		list->stl_error = NETSTAT_ERROR_VERSION;
+		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;
-		}
+	p = buf;
+	isp = (struct inpcb_stream *)p;
+	p += sizeof(*isp);
+
+	if (isp->is_version != INPCB_STREAM_VERSION) {
+		list->stl_error = NETSTAT_ERROR_VERSION;
+		free(buf);
+		return (-1);
+	}
+
+	for (i = 0; i < isp->is_count; i++) {
+		idp = (struct inpcb_data *)p;
+		p += sizeof(*idp);
 
-		/* Ignore sockets for protocols other than the desired one.
-		   XXX: is this needed? */
-		if (so->xso_protocol != protocol)
+		if (idp->id_protocol != protocol)
 			continue;
 
 		/* Keep active PCBs only. */
-		if (inp->inp_gencnt > oxig->xig_gen)
+		if (idp->id_gencnt > isp->is_gencnt)
 			continue;
 
 		/* Not a valid IPv4/IPv6 connection. */
-		if (((inp->inp_vflag & INP_IPV4) == 0)
+		if (((idp->id_vflag & INP_IPV4) == 0)
 #ifdef INET6
-		    && ((inp->inp_vflag & INP_IPV6) == 0)
+		    && ((idp->id_vflag & INP_IPV6) == 0)
 #endif
 		    )
 			continue;
 
 #ifdef INET6
-		if ((family == PF_INET && ((inp->inp_vflag & INP_IPV4) == 0)) ||
-		    (family == PF_INET6 && ((inp->inp_vflag & INP_IPV6) == 0)))
+		if ((family == PF_INET && ((idp->id_vflag & INP_IPV4) == 0)) ||
+		    (family == PF_INET6 && ((idp->id_vflag & INP_IPV6) == 0)))
 			continue;
 #endif
 
 		if ((flags & NETSTAT_SOCKET_ALL) == 0 &&
 		    (
-		     (protocol == IPPROTO_TCP && tp->t_state == TCPS_LISTEN)
-		     || ((inp->inp_vflag & INP_IPV4) != 0 &&
-		      inet_lnaof(inp->inp_laddr) == INADDR_ANY)
+		     (protocol == IPPROTO_TCP && idp->id_state == TCPS_LISTEN)
+		     || ((idp->id_vflag & INP_IPV4) != 0 &&
+		     inet_lnaof(*((struct in_addr *)&idp->id_laddr))
+			== INADDR_ANY)
 #ifdef INET6
-		     || ((inp->inp_vflag & INP_IPV6) != 0 &&
-		      IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
+		     || ((idp->id_vflag & INP_IPV6) != 0 &&
+		     IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)&idp->id_laddr))
 #endif
-		   ))
+		    ))
 			continue;
 
 		stp = _netstat_st_allocate(list, family, protocol,
 		    ipproto(protocol));
-		extract_inet_data(tp, inp, so, stp);
+		extract_inpcb_data(idp, stp);
 	}
-	
+
 	free(buf);
 	return (0);
 }
@@ -768,6 +773,84 @@
 #endif
 }
 
+void
+extract_inpcb_data(struct inpcb_data *idp, struct socket_type *stp)
+{
+	const char *vchar;
+
+	stp->st_qlen = idp->id_qlen;
+	stp->st_incqlen = idp->id_incqlen;
+	stp->st_qlimit = idp->id_qlimit;
+	stp->st_snd.sbt_cc = idp->id_snd_cc;
+	stp->st_snd.sbt_mcnt = idp->id_snd_mcnt;
+	stp->st_snd.sbt_ccnt = idp->id_snd_ccnt;
+	stp->st_snd.sbt_hiwat = idp->id_snd_hiwat;
+	stp->st_snd.sbt_lowat = idp->id_snd_lowat;
+	stp->st_snd.sbt_mbcnt = idp->id_snd_mbcnt;
+	stp->st_snd.sbt_mbmax = idp->id_snd_mbmax;
+	stp->st_rcv.sbt_cc = idp->id_rcv_cc;
+	stp->st_rcv.sbt_mcnt = idp->id_rcv_mcnt;
+	stp->st_rcv.sbt_ccnt = idp->id_rcv_ccnt;
+	stp->st_rcv.sbt_hiwat = idp->id_rcv_hiwat;
+	stp->st_rcv.sbt_lowat = idp->id_rcv_lowat;
+	stp->st_rcv.sbt_mbcnt = idp->id_rcv_mbcnt;
+	stp->st_rcv.sbt_mbmax = idp->id_rcv_mbmax;
+	stp->st_pcb = idp->id_pcb;
+	if (idp->id_protocol == IPPROTO_TCP) {
+		if (idp->id_state >= TCP_NSTATES)
+			sprintf(stp->st_tcpstate, "%d", idp->id_state);
+		else {
+			sprintf(stp->st_tcpstate, "%s",
+			    tcpstates[idp->id_state]);
+#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN)
+			/* T/TCP `hidden state` */
+			if (idp->id_flags & (TF_NEEDSYN | TF_NEEDFIN))
+				strcpy(stp->st_tcpstate, "*");
+#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */
+		}
+		stp->st_flags |= SOCKTYPE_TCP;
+	}	
+#ifdef INET6
+	if ((idp->id_vflag & INP_IPV6) != 0)
+		vchar = ((idp->id_vflag & INP_IPV4) != 0) ? "46" : "6";
+	else
+#endif
+	vchar = ((idp->id_vflag & INP_IPV4) != 0) ? "4 " : "  ";
+	sprintf(stp->st_extname, "%-3.3s%-2.2s", stp->st_name, vchar);
+	/* Local address. */
+	if (idp->id_vflag & INP_IPV4) {
+		stp->st_address[stp->st_addrcnt] =
+		    extract_inet_address(stp, NETSTAT_ADDRTYPE_INET_LOCAL,
+			(struct in_addr *)&idp->id_laddr, idp->id_lport,
+			idp->id_vflag & INP_ANONPORT);
+		stp->st_addrcnt += 1;
+	}
+#ifdef INET6
+	else if (idp->id_vflag & INP_IPV6) {
+		stp->st_address[stp->st_addrcnt] =
+		    extract_inet6_address(stp, NETSTAT_ADDRTYPE_INET6_LOCAL,
+			(struct in6_addr *)&idp->id_laddr, idp->id_lport);
+		stp->st_addrcnt += 1;
+	}
+#endif
+	/* Foreign address. */
+	if (idp->id_vflag & INP_IPV4) {
+		stp->st_address[stp->st_addrcnt] =
+		    extract_inet_address(stp, NETSTAT_ADDRTYPE_INET_FOREIGN,
+			(struct in_addr *)&idp->id_faddr, idp->id_fport,
+			idp->id_vflag & INP_ANONPORT);
+		stp->st_addrcnt += 1;
+	}
+#ifdef INET6
+	else if (idp->id_vflag & INP_IPV6) {
+		stp->st_address[stp->st_addrcnt] =
+		    extract_inet6_address(stp, NETSTAT_ADDRTYPE_INET6_FOREIGN,
+			(struct in6_addr *)&idp->id_faddr, idp->id_fport);
+		stp->st_addrcnt += 1;
+	}
+#endif
+}
+
 struct addr_type *
 extract_inet_address(struct socket_type *parent, int type, struct in_addr *in,
     u_short port, int anonport)


More information about the p4-projects mailing list