From owner-p4-projects@FreeBSD.ORG Tue Jun 9 21:01:19 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8CF0D1065672; Tue, 9 Jun 2009 21:01:19 +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 4BA81106566B for ; Tue, 9 Jun 2009 21:01:19 +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 368328FC1D for ; Tue, 9 Jun 2009 21:01:19 +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 n59L1J5l089755 for ; Tue, 9 Jun 2009 21:01:19 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n59L1JXU089753 for perforce@freebsd.org; Tue, 9 Jun 2009 21:01:19 GMT (envelope-from pgj@FreeBSD.org) Date: Tue, 9 Jun 2009 21:01:19 GMT Message-Id: <200906092101.n59L1JXU089753@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 163933 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: Tue, 09 Jun 2009 21:01:20 -0000 http://perforce.freebsd.org/chv.cgi?CH=163933 Change 163933 by pgj@petymeg-current on 2009/06/09 21:00:22 Start to use libnetstat for displaying tcp connections -- needs some work, still contains hacks Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#3 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/Makefile#5 (text+ko) ==== @@ -18,4 +18,8 @@ WITHOUT_MAN= yes +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+= -DINET6 +.endif + .include ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#9 (text+ko) ==== @@ -9,6 +9,11 @@ #include #include #include +#include +#include +#include +#define TCPSTATES +#include #include #include #include @@ -17,7 +22,7 @@ #include "netstat_internal.h" static struct nlist nl[] = { -/* UNP_###-related variables. */ +/* UNP_###-related */ #define X_UNP_COUNT 0 { .n_name = "_unp_count" }, #define X_UNP_GENCNT 1 @@ -27,19 +32,32 @@ #define X_UNP_SHEAD 3 { .n_name = "_unp_shead" }, { .n_name = NULL }, +/* INET-related */ +#define X_TCBINFO 5 + { .n_name = "_tcbinfo" }, +#define X_UDBINFO 6 + { .n_name = "_udbinfo" }, + { .n_name = NULL }, }; static void extract_xunpcb_data(struct xunpcb *, struct socket_type *); +static void extract_inet_data(struct tcpcb *, struct inpcb *, + struct xsocket *, struct socket_type *); +/* type names */ static const char *const socktype[] = { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" }; +static const char *const ipproto[] = + { "hopopts", "igmp", "tcp", "ggp", "ipv4", "ipip", "st", "egp", "pgip", + "rccmon", "nvpii", "pup", "argus", "emcon", "xnet", "chaos", "udp" }; + static int net_local_pcblist_sysctl(int type, struct socket_type_list *list) { char *buf; size_t len; - char mibvar[sizeof "net.local.seqpacket.pcblist"]; + char mibvar[64]; struct xunpgen *xug, *oxug; struct xunpcb *xunp; @@ -156,6 +174,75 @@ #undef KREAD } +static int +net_inet_pcblist_sysctl(int protocol, struct socket_type_list *list) +{ + char *buf; + size_t len; + char mibvar[64]; + + struct xinpgen *xig, *oxig; + struct tcpcb *tp = NULL; + struct inpcb *inp; + struct xsocket *so; + + struct socket_type *stp; + + sprintf(mibvar, "net.inet.%s.pcblist", ipproto[protocol]); + + len = 0; + if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) { + if (errno != ENOENT) + warn("sysctl: %s", mibvar); + return (-1); + } + if ((buf = malloc(len)) == 0) { + warnx("malloc %lu bytes", (u_long)len); + return (-2); + } + if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) { + warn("sysctl: %s", mibvar); + 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; + } + + /* Ignore sockets for protocols other than the desired one. + XXX: is this needed? */ + if (so->xso_protocol != protocol) + continue; + + if (inp->inp_gencnt <= oxig->xig_gen) { + stp = _netstat_st_allocate(list, PF_INET, protocol, + ipproto[protocol]); + extract_inet_data(tp, inp, so, stp); + } + } + + free(buf); + return (0); +} + +static int +net_inet_pcblist_kvm(int protocol, struct socket_type_list *list, + kvm_t *kvm, struct nlist *nlistp) +{ + /* XXX: to be filled in. */ + return (0); +} + int netstat_socket(int domain, int type, int protocol, struct socket_type_list *list, int flags, void *kvm_handle) @@ -173,18 +260,18 @@ } } -#define NLP_KVM(type, list, kvm, nl) do { \ - if (net_local_pcblist_kvm((type), (list), (kvm), (nl)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ - return (-1); \ - } \ +#define NPCB_KVM(family, type, list, kvm, nl) do { \ + if (net_##family##_pcblist_kvm((type), (list), (kvm), (nl)) != 0) { \ + list->stl_error = NETSTAT_ERROR_UNDEFINED; \ + return (-1); \ + } \ } while (0) -#define NLP_SCT(type, list) do { \ - if (net_local_pcblist_sysctl((type), (list)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ - return (-1); \ - } \ +#define NPCB_SCT(family, type, list) do { \ + if (net_##family##_pcblist_sysctl((type), (list)) != 0) { \ + list->stl_error = NETSTAT_ERROR_UNDEFINED; \ + return (-1); \ + } \ } while (0) switch (domain) { @@ -193,18 +280,43 @@ case SOCK_STREAM: case SOCK_DGRAM: if (use_kvm) - NLP_KVM(type, list, kvm, nl); + NPCB_KVM(local, type, list, kvm, nl); else /* Use sysctl (or something else). */ - NLP_SCT(type, list); + NPCB_SCT(local, type, list); + break; /* All PF_LOCAL */ case 0: if (use_kvm) { - NLP_KVM(SOCK_STREAM, list, kvm, nl); - NLP_KVM(SOCK_DGRAM, list, kvm, nl); + NPCB_KVM(local, SOCK_STREAM, list, kvm, nl); + NPCB_KVM(local, SOCK_DGRAM, list, kvm, nl); + } else { + NPCB_SCT(local, SOCK_STREAM, list); + NPCB_SCT(local, SOCK_DGRAM, list); + } + break; + default: + list->stl_error = NETSTAT_ERROR_UNSUPPORTED; + return (-1); + } + break; + case PF_INET: + switch (protocol) { + case IPPROTO_TCP: + case IPPROTO_UDP: + if (use_kvm) + NPCB_KVM(inet, protocol, list, kvm, nl); + else + NPCB_SCT(inet, protocol, list); + break; + /* All PF_INET */ + case 0: + if (use_kvm) { + NPCB_KVM(inet, IPPROTO_TCP, list, kvm, nl); + NPCB_KVM(inet, IPPROTO_UDP, list, kvm, nl); } else { - NLP_SCT(SOCK_STREAM, list); - NLP_SCT(SOCK_DGRAM, list); + NPCB_SCT(inet, IPPROTO_TCP, list); + NPCB_SCT(inet, IPPROTO_UDP, list); } break; default: @@ -216,8 +328,8 @@ list->stl_error = NETSTAT_ERROR_UNSUPPORTED; return (-1); } -#undef NLP_KVM -#undef NLP_SCT +#undef NPCB_KVM +#undef NPCB_SCT return (0); } @@ -230,12 +342,24 @@ stp->st_incqlen = xpcb->xu_socket.so_incqlen; stp->st_qlimit = xpcb->xu_socket.so_qlimit; stp->st_snd_cc = xpcb->xu_socket.so_snd.sb_cc; + stp->st_snd_mcnt = xpcb->xu_socket.so_snd.sb_mcnt; + stp->st_snd_ccnt = xpcb->xu_socket.so_snd.sb_ccnt; + stp->st_snd_hiwat = xpcb->xu_socket.so_snd.sb_hiwat; + stp->st_snd_lowat = xpcb->xu_socket.so_snd.sb_lowat; + stp->st_snd_mbcnt = xpcb->xu_socket.so_snd.sb_mbcnt; + stp->st_snd_mbmax = xpcb->xu_socket.so_snd.sb_mbmax; stp->st_rcv_cc = xpcb->xu_socket.so_rcv.sb_cc; - stp->st_pcb = (long)xpcb->xu_socket.so_pcb; - stp->st_vnode = (long)xpcb->xu_unp.unp_vnode; - stp->st_conn = (long)xpcb->xu_unp.unp_conn; - stp->st_refs = (long)LIST_FIRST(&xpcb->xu_unp.unp_refs); - stp->st_reflink = (long)LIST_NEXT(&xpcb->xu_unp, unp_reflink); + stp->st_rcv_mcnt = xpcb->xu_socket.so_rcv.sb_mcnt; + stp->st_rcv_ccnt = xpcb->xu_socket.so_rcv.sb_ccnt; + stp->st_rcv_hiwat = xpcb->xu_socket.so_rcv.sb_hiwat; + stp->st_rcv_lowat = xpcb->xu_socket.so_rcv.sb_lowat; + stp->st_rcv_mbcnt = xpcb->xu_socket.so_rcv.sb_mbcnt; + stp->st_rcv_mbmax = xpcb->xu_socket.so_rcv.sb_mbmax; + stp->st_pcb = (u_long)xpcb->xu_socket.so_pcb; + stp->st_vnode = (u_long)xpcb->xu_unp.unp_vnode; + stp->st_conn = (u_long)xpcb->xu_unp.unp_conn; + stp->st_refs = (u_long)LIST_FIRST(&xpcb->xu_unp.unp_refs); + stp->st_reflink = (u_long)LIST_NEXT(&xpcb->xu_unp, unp_reflink); stp->st_flags = SOCKTYPE_VNODE | SOCKTYPE_CONN | SOCKTYPE_REFS; if (xpcb->xu_unp.unp_addr) { sa = (struct sockaddr_un *)&xpcb->xu_addr; @@ -245,4 +369,56 @@ } else { stp->st_address[0] = '\0'; } + stp->st_listening = 0; + stp->st_tcpstate[0] = '\0'; +} + +void +extract_inet_data(struct tcpcb *tp, struct inpcb *inp, struct xsocket *so, + struct socket_type *stp) +{ + stp->st_qlen = so->so_qlen; + stp->st_incqlen = so->so_incqlen; + stp->st_qlimit = so->so_qlimit; + stp->st_snd_cc = so->so_snd.sb_cc; + stp->st_snd_mcnt = so->so_snd.sb_mcnt; + stp->st_snd_ccnt = so->so_snd.sb_ccnt; + stp->st_snd_hiwat = so->so_snd.sb_hiwat; + stp->st_snd_lowat = so->so_snd.sb_lowat; + stp->st_snd_mbcnt = so->so_snd.sb_mbcnt; + stp->st_snd_mbmax = so->so_snd.sb_mbmax; + stp->st_rcv_cc = so->so_rcv.sb_cc; + stp->st_rcv_mcnt = so->so_rcv.sb_mcnt; + stp->st_rcv_ccnt = so->so_rcv.sb_ccnt; + stp->st_rcv_hiwat = so->so_rcv.sb_hiwat; + stp->st_rcv_lowat = so->so_rcv.sb_lowat; + stp->st_rcv_mbcnt = so->so_rcv.sb_mbcnt; + stp->st_rcv_mbmax = so->so_rcv.sb_mbmax; + stp->st_pcb = (tp == NULL) ? (u_long)inp->inp_ppcb : + (u_long)so->so_pcb; + stp->st_vnode = (u_long)0; + stp->st_conn = (u_long)0; + stp->st_refs = (u_long)0; + stp->st_reflink = (u_long)0; + stp->st_flags = SOCKTYPE_TCP; + /* XXX: Remove this. */ + if (tp != NULL) + stp->XXX_tcpcb = *tp; + stp->XXX_inpcb = *inp; + stp->XXX_xsocket = *so; + /* XXX: address is missing. */ + stp->st_address[0] = '\0'; + stp->st_listening = (tp->t_state == TCPS_LISTEN); + if (tp->t_state < 0 || tp->t_state >= TCP_NSTATES) + sprintf(stp->st_tcpstate, "%d", tp->t_state); + else { + sprintf(stp->st_tcpstate, "%s", tcpstates[tp->t_state]); +#if defined(TF_NEEDSYN) && defined(TF_NEEDFIN) + /* T/TCP `hidden state' */ + if (tp->t_flags & (TF_NEEDSYN|TF_NEEDFIN)) { + stp->st_tcpstate[0] = '*'; + stp->st_tcpstate[1] = '\0'; + } +#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ + } } ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#12 (text+ko) ==== @@ -56,17 +56,36 @@ int netstat_st_get_family(const struct socket_type *stp); int netstat_st_get_protocol(const struct socket_type *stp); const char *netstat_st_get_name(const struct socket_type *stp); +/* XXX: move snd/rcv-related properties into a new abstract type? */ u_int netstat_st_get_snd_cc(const struct socket_type *stp); +u_int netstat_st_get_snd_hiwat(const struct socket_type *stp); +u_int netstat_st_get_snd_lowat(const struct socket_type *stp); +u_int netstat_st_get_snd_mbcnt(const struct socket_type *stp); +u_int netstat_st_get_snd_mcnt(const struct socket_type *stp); +u_int netstat_st_get_snd_ccnt(const struct socket_type *stp); +u_int netstat_st_get_snd_mbmax(const struct socket_type *stp); u_int netstat_st_get_rcv_cc(const struct socket_type *stp); +u_int netstat_st_get_rcv_hiwat(const struct socket_type *stp); +u_int netstat_st_get_rcv_lowat(const struct socket_type *stp); +u_int netstat_st_get_rcv_mbcnt(const struct socket_type *stp); +u_int netstat_st_get_rcv_mcnt(const struct socket_type *stp); +u_int netstat_st_get_rcv_ccnt(const struct socket_type *stp); +u_int netstat_st_get_rcv_mbmax(const struct socket_type *stp); u_short netstat_st_get_qlen(const struct socket_type *stp); u_short netstat_st_get_incqlen(const struct socket_type *stp); u_short netstat_st_get_qlimit(const struct socket_type *stp); -long netstat_st_get_pcb(const struct socket_type *stp); -long netstat_st_get_vnode(const struct socket_type *stp); -long netstat_st_get_conn(const struct socket_type *stp); -long netstat_st_get_refs(const struct socket_type *stp); -long netstat_st_get_reflink(const struct socket_type *stp); +u_long netstat_st_get_pcb(const struct socket_type *stp); +u_long netstat_st_get_vnode(const struct socket_type *stp); +u_long netstat_st_get_conn(const struct socket_type *stp); +u_long netstat_st_get_refs(const struct socket_type *stp); +u_long netstat_st_get_reflink(const struct socket_type *stp); const char *netstat_st_get_address(const struct socket_type *stp); +int netstat_st_get_listening(const struct socket_type *stp); +const char *netstat_st_get_tcpstate(const struct socket_type *stp); +/* XXX: Remove this hacks. */ +struct tcpcb XXX_netstat_st_get_tcpcb(const struct socket_type *stp); +struct inpcb XXX_netstat_st_get_inpcb(const struct socket_type *stp); +struct xsocket XXX_netstat_st_get_xsocket(const struct socket_type *stp); __END_DECLS #endif /* !_NETSTAT_H_ */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#9 (text+ko) ==== @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include /* XXX: not used yet */ /* Address type: @@ -34,17 +37,36 @@ #endif u_int st_snd_cc; /* actual chars in the send buffer */ + u_int st_snd_mcnt; + u_int st_snd_ccnt; + u_int st_snd_hiwat; + u_int st_snd_lowat; + u_int st_snd_mbcnt; + u_int st_snd_mbmax; u_int st_rcv_cc; /* actual chars in the receive buffer */ + u_int st_rcv_mcnt; + u_int st_rcv_ccnt; + u_int st_rcv_hiwat; + u_int st_rcv_lowat; + u_int st_rcv_mbcnt; + u_int st_rcv_mbmax; u_short st_qlen; /* number of unaccepted connections */ u_short st_incqlen; /* number of unaccepted incomplete connections */ u_short st_qlimit; /* max number queued connections */ - long st_pcb; /* protocol control block */ - long st_vnode; /* if associated with file */ - long st_conn; /* control block of connected socket */ - long st_refs; /* referencing socket linked list */ - long st_reflink; /* link in references list */ + u_long st_pcb; /* protocol control block */ + u_long st_vnode; /* if associated with file */ + u_long st_conn; /* control block of connected socket */ + u_long st_refs; /* referencing socket linked list */ + u_long st_reflink; /* link in references list */ char st_address[SOCKTYPE_MAXADDR]; + char st_tcpstate[16]; + int st_listening; + + /* XXX: Removables. */ + struct tcpcb XXX_tcpcb; + struct inpcb XXX_inpcb; + struct xsocket XXX_xsocket; /* list of types */ LIST_ENTRY(socket_type) st_list; @@ -54,6 +76,7 @@ #define SOCKTYPE_VNODE 0x01 /* Associated with a file. */ #define SOCKTYPE_CONN 0x02 /* Has a control block connected. */ #define SOCKTYPE_REFS 0x04 /* Has socket references. */ +#define SOCKTYPE_TCP 0x08 /* A TCP socket, has states. */ struct socket_type_list { LIST_HEAD(, socket_type) stl_list; ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#11 (text+ko) ==== @@ -259,11 +259,83 @@ } u_int +netstat_st_get_rcv_hiwat(const struct socket_type *stp) +{ + return (stp->st_rcv_hiwat); +} + +u_int +netstat_st_get_rcv_lowat(const struct socket_type *stp) +{ + return (stp->st_rcv_lowat); +} + +u_int +netstat_st_get_rcv_mbcnt(const struct socket_type *stp) +{ + return (stp->st_rcv_mbcnt); +} + +u_int +netstat_st_get_rcv_mcnt(const struct socket_type *stp) +{ + return (stp->st_rcv_mcnt); +} + +u_int +netstat_st_get_rcv_ccnt(const struct socket_type *stp) +{ + return (stp->st_rcv_ccnt); +} + +u_int +netstat_st_get_rcv_mbmax(const struct socket_type *stp) +{ + return (stp->st_rcv_mbmax); +} + +u_int netstat_st_get_snd_cc(const struct socket_type *stp) { return (stp->st_snd_cc); } +u_int +netstat_st_get_snd_hiwat(const struct socket_type *stp) +{ + return (stp->st_snd_hiwat); +} + +u_int +netstat_st_get_snd_lowat(const struct socket_type *stp) +{ + return (stp->st_snd_lowat); +} + +u_int +netstat_st_get_snd_mbcnt(const struct socket_type *stp) +{ + return (stp->st_snd_mbcnt); +} + +u_int +netstat_st_get_snd_mcnt(const struct socket_type *stp) +{ + return (stp->st_snd_mcnt); +} + +u_int +netstat_st_get_snd_ccnt(const struct socket_type *stp) +{ + return (stp->st_snd_ccnt); +} + +u_int +netstat_st_get_snd_mbmax(const struct socket_type *stp) +{ + return (stp->st_snd_mbmax); +} + u_short netstat_st_get_qlen(const struct socket_type *stp) { @@ -282,31 +354,31 @@ return (stp->st_qlimit); } -long +u_long netstat_st_get_pcb(const struct socket_type *stp) { return (stp->st_pcb); } -long +u_long netstat_st_get_vnode(const struct socket_type *stp) { return (stp->st_vnode); } -long +u_long netstat_st_get_conn(const struct socket_type *stp) { return (stp->st_conn); } -long +u_long netstat_st_get_refs(const struct socket_type *stp) { return (stp->st_refs); } -long +u_long netstat_st_get_reflink(const struct socket_type *stp) { return (stp->st_reflink); @@ -317,3 +389,34 @@ { return (stp->st_address); } + +int +netstat_st_get_listening(const struct socket_type *stp) +{ + return (stp->st_listening); +} + +const char * +netstat_st_get_tcpstate(const struct socket_type *stp) +{ + return (stp->st_tcpstate); +} + +/* XXX: Remove this hacks. */ +struct tcpcb +XXX_netstat_st_get_tcpcb(const struct socket_type *stp) +{ + return (stp->XXX_tcpcb); +} + +struct inpcb +XXX_netstat_st_get_inpcb(const struct socket_type *stp) +{ + return (stp->XXX_inpcb); +} + +struct xsocket +XXX_netstat_st_get_xsocket(const struct socket_type *stp) +{ + return (stp->XXX_xsocket); +} ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#2 (text+ko) ==== @@ -69,6 +69,7 @@ int sotoxsocket(struct socket *, struct xsocket *); void protopr(u_long, const char *, int, int); +void inetpr(void *, int); void tcp_stats(u_long, const char *, int, int); void udp_stats(u_long, const char *, int, int); #ifdef SCTP ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#3 (text+ko) ==== @@ -83,13 +83,19 @@ #include #include #include + +#include +#include #include "extern.h" +#define USE_ITERATOR_TYPE + char *inetname(struct in_addr *); void inetprint(struct in_addr *, int, const char *, int); #ifdef INET6 static int udp_done, tcp_done; #endif /* INET6 */ +static void inetppr(struct socket_type *); static int pcblist_sysctl(int proto, char **bufp, int istcp) @@ -554,6 +560,225 @@ free(buf); } +void +inetpr(void *kvmd, int proto) +{ + struct socket_type_list *stlp; + int error, st_flags; + kvm_t *kvm; +#ifdef USE_ITERATOR_TYPE + struct socket_type_iterator *stip; + struct socket_type *stp; +#endif + + kvm = (kvm_t *)kvmd; + stlp = netstat_stl_alloc(); + if (stlp == NULL) { + warn("netstat_stl_alloc"); + return; + } + + st_flags = 0; + if (live) + st_flags |= NETSTAT_SOCKET_KVM; + + if (netstat_socket(PF_INET, 0, proto, stlp, st_flags, kvm) < 0) { + error = netstat_stl_geterror(stlp); + if (error == NETSTAT_ERROR_KVM) + warnx("netstat_socket: %s", kvm_geterr(kvm)); + else + warnx("netstat_socket: %s", netstat_strerror(error)); + return; + } + +#ifdef USE_ITERATOR_TYPE + if (netstat_sti_alloc(stlp, &stip) < 0) { + warnx("netstat_sti_alloc"); + return; + } + for (stp = netstat_sti_first(stip); stp != NULL; + stp = netstat_sti_next(stip)) { + inetppr(stp); + netstat_st_free(stp); + } +#else + netstat_stl_iterate(stlp, inetppr); +#endif +} + +void +inetppr(struct socket_type *stp) +{ + static int first = 1; + char buf1[15]; + const char *vchar; + struct tcpcb tp; + struct inpcb inp; + struct xsocket so; + int istcp; + + istcp = 0; + inp = XXX_netstat_st_get_inpcb(stp); + so = XXX_netstat_st_get_xsocket(stp); + if (netstat_st_get_protocol(stp) == IPPROTO_TCP) { + tp = XXX_netstat_st_get_tcpcb(stp); + istcp = 1; + } +/* XXX: af1 */ +#if 0 + if ((af1 == AF_INET && (inp.inp_vflag & INP_IPV4) == 0) +#ifdef INET6 + || (af1 == AF_INET6 && (inp.inp_vflag & INP_IPV6) == 0) +#endif /* INET6 */ + || (af1 == AF_UNSPEC && ((inp.inp_vflag & INP_IPV4) == 0 +#ifdef INET6 + && (inp.inp_vflag & INP_IPV6) == 0 +#endif /* INET6 */ + )) + ) + continue; + if (!aflag && + ( + (istcp && netstat_st_get_listening(stp)) + || (af1 == AF_INET && + inet_lnaof(inp.inp_laddr) == INADDR_ANY) +#ifdef INET6 + || (af1 == AF_INET6 && + IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr)) +#endif /* INET6 */ + || (af1 == AF_UNSPEC && + (((inp.inp_vflag & INP_IPV4) != 0 && + inet_lnaof(inp.inp_laddr) == INADDR_ANY) +#ifdef INET6 + || ((inp.inp_vflag & INP_IPV6) != 0 && + IN6_IS_ADDR_UNSPECIFIED(&inp.in6p_laddr)) +#endif + )) + )) + return; +#endif + if (first) { + if (!Lflag) { + printf("Active Internet connections"); + if (aflag) + printf(" (including servers)"); + } else + printf( + "Current listen queue sizes (qlen/incqlen/maxqlen)"); + putchar('\n'); + if (Aflag) + printf("%-8.8s ", "Tcpcb"); + if (Lflag) + printf("%-5.5s %-14.14s %-22.22s\n", + "Proto", "Listen", "Local Address"); + else { + printf((Aflag && !Wflag) ? + "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" : + "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s", + "Proto", "Recv-Q", "Send-Q", + "Local Address", "Foreign Address"); + if (xflag) + printf( + "%-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s %-6.6s\n", + "R-MBUF", "S-MBUF", "R-CLUS", + "S-CLUS", "R-HIWA", "S-HIWA", + "R-LOWA", "S-LOWA", "R-BCNT", + "S-BCNT", "R-BMAX", "S-BMAX"); + else + printf("(state)\n"); + } + first = 0; + } + if (Lflag && so.so_qlimit == 0) + return; + if (Aflag) + printf("%8lx ", netstat_st_get_pcb(stp)); +#ifdef INET6 + if ((inp.inp_vflag & INP_IPV6) != 0) + vchar = ((inp.inp_vflag & INP_IPV4) != 0) ? + "46" : "6 "; + else +#endif + vchar = ((inp.inp_vflag & INP_IPV4) != 0) ? + "4 " : " "; + printf("%-3.3s%-2.2s", netstat_st_get_name(stp), vchar); + if (Lflag) { + snprintf(buf1, 15, "%d/%d/%d", netstat_st_get_qlen(stp), + netstat_st_get_incqlen(stp), netstat_st_get_qlimit(stp)); + printf("%-14.14s", buf1); + } else { + printf("%6u %6u", netstat_st_get_rcv_cc(stp), + netstat_st_get_snd_cc(stp)); + } + if (numeric_port) { + if (inp.inp_vflag & INP_IPV4) { + inetprint(&inp.inp_laddr, (int)inp.inp_lport, + netstat_st_get_name(stp), 1); + if (!Lflag) + inetprint(&inp.inp_faddr, + (int)inp.inp_fport, + netstat_st_get_name(stp), 1); + } +#ifdef INET6 + else if (inp.inp_vflag & INP_IPV6) { + inet6print(&inp.in6p_laddr, + (int)inp.inp_lport, netstat_st_get_name(stp), 1); + if (!Lflag) + inet6print(&inp.in6p_faddr, + (int)inp.inp_fport, + netstat_st_get_name(stp), 1); + } /* else nothing printed now */ +#endif /* INET6 */ + } else if (inp.inp_flags & INP_ANONPORT) { + if (inp.inp_vflag & INP_IPV4) { + inetprint(&inp.inp_laddr, (int)inp.inp_lport, + netstat_st_get_name(stp), 1); + if (!Lflag) + inetprint(&inp.inp_faddr, + (int)inp.inp_fport, + netstat_st_get_name(stp), 0); + } +#ifdef INET6 + else if (inp.inp_vflag & INP_IPV6) { + inet6print(&inp.in6p_laddr, + (int)inp.inp_lport, netstat_st_get_name(stp), 1); + if (!Lflag) + inet6print(&inp.in6p_faddr, + (int)inp.inp_fport, + netstat_st_get_name(stp), 0); + } /* else nothing printed now */ +#endif /* INET6 */ + else if (inp.inp_vflag & INP_IPV6) { + inet6print(&inp.in6p_laddr, + (int)inp.inp_lport, netstat_st_get_name(stp), 0); + if (!Lflag) + inet6print(&inp.in6p_faddr, + (int)inp.inp_fport, + netstat_st_get_name(stp), + inp.inp_lport != inp.inp_fport); + } /* else nothing printed now */ + } + if (xflag) { + if (Lflag) + printf("%21s", " "); + printf("%6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u %6u", + netstat_st_get_rcv_mcnt(stp), netstat_st_get_snd_mcnt(stp), + netstat_st_get_rcv_ccnt(stp), netstat_st_get_snd_ccnt(stp), + netstat_st_get_rcv_hiwat(stp), + netstat_st_get_snd_hiwat(stp), + netstat_st_get_rcv_lowat(stp), + netstat_st_get_snd_lowat(stp), + netstat_st_get_rcv_mbcnt(stp), + netstat_st_get_snd_mbcnt(stp), + netstat_st_get_rcv_mbmax(stp), + netstat_st_get_snd_mbmax(stp)); + } + if (istcp && !Lflag) { + printf("%s", netstat_st_get_tcpstate(stp)); + } + putchar('\n'); +} + /* * Dump TCP statistics structure. */ ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#5 (text+ko) ==== @@ -652,8 +652,13 @@ off = nl[tp->pr_index].n_value; } if (pr != NULL && (off || (live && tp->pr_usesysctl) || - af != AF_UNSPEC)) - (*pr)(off, name, af, tp->pr_protocol); + af != AF_UNSPEC)) { + /* XXX: temp. hack */ + if (tp->pr_index == N_TCBINFO) + inetpr(kvmd, IPPROTO_TCP); + else + (*pr)(off, name, af, tp->pr_protocol); + } } /*