From owner-p4-projects@FreeBSD.ORG Mon Jun 29 09:21:15 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 23258106567A; Mon, 29 Jun 2009 09:21:15 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D5AA5106566C for ; Mon, 29 Jun 2009 09:21:14 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B8BEC8FC17 for ; Mon, 29 Jun 2009 09:21:14 +0000 (UTC) (envelope-from pgj@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5T9LEjb090500 for ; Mon, 29 Jun 2009 09:21:14 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5T9LEKv090498 for perforce@freebsd.org; Mon, 29 Jun 2009 09:21:14 GMT (envelope-from pgj@FreeBSD.org) Date: Mon, 29 Jun 2009 09:21:14 GMT Message-Id: <200906290921.n5T9LEKv090498@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to pgj@FreeBSD.org using -f From: Gabor Pali To: Perforce Change Reviews Cc: Subject: PERFORCE change 165380 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 29 Jun 2009 09:21:16 -0000 http://perforce.freebsd.org/chv.cgi?CH=165380 Change 165380 by pgj@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)