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