From owner-p4-projects@FreeBSD.ORG Fri Jun 12 14:55:36 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 2726C1065670; Fri, 12 Jun 2009 14:55:36 +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 DAC8D106564A for ; Fri, 12 Jun 2009 14:55:35 +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 C85418FC1B for ; Fri, 12 Jun 2009 14:55:35 +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 n5CEtZap081786 for ; Fri, 12 Jun 2009 14:55:35 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5CEtZ7u081784 for perforce@freebsd.org; Fri, 12 Jun 2009 14:55:35 GMT (envelope-from pgj@FreeBSD.org) Date: Fri, 12 Jun 2009 14:55:35 GMT Message-Id: <200906121455.n5CEtZ7u081784@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 164178 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: Fri, 12 Jun 2009 14:55:37 -0000 http://perforce.freebsd.org/chv.cgi?CH=164178 Change 164178 by pgj@petymeg-current on 2009/06/12 14:55:17 libnetstat: netstat: Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#23 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#5 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#13 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#8 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#12 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#23 (text+ko) ==== @@ -370,16 +370,124 @@ #undef KREAD + +#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \ + if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \ + (flags)) != 0) { \ + list->stl_error = NETSTAT_ERROR_UNDEFINED; \ + return (-1); \ + } \ +} while (0) + +#define NPCB_SCT(proc, family, type, list, flags) do { \ + if (net_##proc##_pcblist_sysctl((family), (type), (list), \ + (flags)) != 0) { \ + list->stl_error = NETSTAT_ERROR_UNDEFINED; \ + return (-1); \ + } \ +} while (0) + int +netstat_local_sockets(int type, struct socket_type_list *list, kvm_t *kvm, + struct nlist *nl, int flags) +{ + int use_kvm = flags & NETSTAT_SOCKET_KVM; + + switch (type) { + case SOCK_STREAM: + case SOCK_DGRAM: + if (use_kvm) + NPCB_KVM(local, PF_LOCAL, type, list, kvm, nl, + flags); + else + /* Use sysctl (or something else). */ + NPCB_SCT(local, PF_LOCAL, type, list, flags); + break; + /* All PF_LOCAL */ + case 0: + if (use_kvm) { + NPCB_KVM(local, PF_LOCAL, SOCK_STREAM, list, kvm, + nl, flags); + NPCB_KVM(local, PF_LOCAL, SOCK_DGRAM, list, kvm, + nl, flags); + } else { + NPCB_SCT(local, PF_LOCAL, SOCK_STREAM, list, + flags); + NPCB_SCT(local, PF_LOCAL, SOCK_DGRAM, list, + flags); + } + break; + default: + list->stl_error = NETSTAT_ERROR_UNSUPPORTED; + return (-1); + } + return (0); +} + +int +netstat_inet_sockets(int domain, int protocol, struct socket_type_list *list, + kvm_t *kvm, struct nlist *nl, int flags) +{ + int use_kvm = flags & NETSTAT_SOCKET_KVM; + + switch (protocol) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_DIVERT: + case IPPROTO_RAW: + case IPPROTO_ICMP: + case IPPROTO_IGMP: + case IPPROTO_PIM: + case IPPROTO_ICMPV6: + if (use_kvm) + NPCB_KVM(inet, domain, protocol, list, kvm, nl, + flags); + else + NPCB_SCT(inet, domain, protocol, list, flags); + break; + /* All PF_INET */ + case 0: + /* Errors do not count here. */ + if (use_kvm) { + net_inet_pcblist_kvm(domain, IPPROTO_TCP, list, kvm, + nl, flags); + net_inet_pcblist_kvm(domain, IPPROTO_UDP, list, kvm, + nl, flags); + net_inet_pcblist_kvm(domain, IPPROTO_DIVERT, list, + kvm, nl, flags); + net_inet_pcblist_kvm(domain, IPPROTO_RAW, list, kvm, + nl, flags); + } else { + net_inet_pcblist_sysctl(domain, IPPROTO_TCP, list, + flags); + net_inet_pcblist_sysctl(domain, IPPROTO_UDP, list, + flags); + net_inet_pcblist_sysctl(domain, IPPROTO_DIVERT, list, + flags); + net_inet_pcblist_sysctl(domain, IPPROTO_RAW, list, + flags); + } + break; + default: + list->stl_error = NETSTAT_ERROR_UNSUPPORTED; + return (-1); + } + return (0); +} + +#undef NPCB_KVM +#undef NPCB_SCT + + +int netstat_socket(int domain, int type, int protocol, struct socket_type_list *list, int flags, void *kvm_handle) { kvm_t *kvm; - int use_kvm; + int result; struct nlist *nlp = NULL; - use_kvm = flags & NETSTAT_SOCKET_KVM; - if (use_kvm) { + if (flags & NETSTAT_SOCKET_KVM) { /* Use KVM to retrieve data. */ switch (domain) { case PF_LOCAL: @@ -398,104 +506,37 @@ return (-1); } } - -#define NPCB_KVM(proc, family, type, list, kvm, nl, flags) do { \ - if (net_##proc##_pcblist_kvm((family), (type), (list), (kvm), (nl), \ - (flags)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ - return (-1); \ - } \ -} while (0) - -#define NPCB_SCT(proc, family, type, list, flags) do { \ - if (net_##proc##_pcblist_sysctl((family), (type), (list), \ - (flags)) != 0) { \ - list->stl_error = NETSTAT_ERROR_UNDEFINED; \ - return (-1); \ - } \ -} while (0) - switch (domain) { + case PF_UNSPEC: + /* "Everything" */ + result = netstat_local_sockets(0, list, kvm, nl, flags); + if (result < 0) + return (result); +#if 1 + result = netstat_inet_sockets(PF_INET, 0, list, kvm, nl, + flags); + if (result < 0) + return (result); +#endif +#if 0 + result = netstat_inet_sockets(PF_INET6, 0, list, kvm, nl, + flags); + if (result < 0) + return (result); +#endif + break; case PF_LOCAL: - switch (type) { - case SOCK_STREAM: - case SOCK_DGRAM: - if (use_kvm) - NPCB_KVM(local, domain, type, list, kvm, nl, - flags); - else - /* Use sysctl (or something else). */ - NPCB_SCT(local, domain, type, list, flags); - break; - /* All PF_LOCAL */ - case 0: - if (use_kvm) { - NPCB_KVM(local, domain, SOCK_STREAM, list, kvm, - nl, flags); - NPCB_KVM(local, domain, SOCK_DGRAM, list, kvm, - nl, flags); - } else { - NPCB_SCT(local, domain, SOCK_STREAM, list, - flags); - NPCB_SCT(local, domain, SOCK_DGRAM, list, - flags); - } - break; - default: - list->stl_error = NETSTAT_ERROR_UNSUPPORTED; - return (-1); - } + return (netstat_local_sockets(type, list, kvm, nl, flags)); break; case PF_INET: case PF_INET6: - switch (protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_DIVERT: - case IPPROTO_RAW: - case IPPROTO_ICMP: - case IPPROTO_IGMP: - case IPPROTO_PIM: - case IPPROTO_ICMPV6: - if (use_kvm) - NPCB_KVM(inet, domain, protocol, list, kvm, nl, - flags); - else - NPCB_SCT(inet, domain, protocol, list, flags); - break; - /* All PF_INET */ - case 0: - if (use_kvm) { - NPCB_KVM(inet, domain, IPPROTO_TCP, list, kvm, - nl, flags); - NPCB_KVM(inet, domain, IPPROTO_UDP, list, kvm, - nl, flags); - NPCB_KVM(inet, domain, IPPROTO_DIVERT, list, - kvm, nl, flags); - NPCB_KVM(inet, domain, IPPROTO_RAW, list, kvm, - nl, flags); - } else { - NPCB_SCT(inet, domain, IPPROTO_TCP, list, - flags); - NPCB_SCT(inet, domain, IPPROTO_UDP, list, - flags); - NPCB_SCT(inet, domain, IPPROTO_DIVERT, list, - flags); - NPCB_SCT(inet, domain, IPPROTO_RAW, list, - flags); - } - break; - default: - list->stl_error = NETSTAT_ERROR_UNSUPPORTED; - return (-1); - } + return (netstat_inet_sockets(domain, protocol, list, kvm, nl, + flags)); break; default: list->stl_error = NETSTAT_ERROR_UNSUPPORTED; return (-1); } -#undef NPCB_KVM -#undef NPCB_SCT return (0); } @@ -568,22 +609,28 @@ stp->st_conn = (u_long)0; stp->st_refs = (u_long)0; stp->st_reflink = (u_long)0; - stp->st_flags = SOCKTYPE_TCP; + stp->st_flags = 0; /* XXX: Remove this. */ stp->XXX_inpcb = *inp; /* XXX: address is missing. */ stp->st_address[0] = '\0'; - 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 (tp != NULL) { + 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'; + /* 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) */ } -#endif /* defined(TF_NEEDSYN) && defined(TF_NEEDFIN) */ + stp->st_flags |= SOCKTYPE_TCP; + } else { + /* Has no TCP state. */ + stp->st_tcpstate[0] = '\0'; } #ifdef INET6 if ((inp->inp_vflag & INP_IPV6) != 0) ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#5 (text+ko) ==== @@ -35,6 +35,7 @@ */ #include +#include extern int Aflag; /* show addresses of protocol control block */ extern int aflag; /* show all sockets (including servers) */ @@ -69,6 +70,8 @@ int sotoxsocket(struct socket *, struct xsocket *); void inetpr(void *, int, int); +void inetppr(struct socket_type *); +void unixdomainpr(struct socket_type *); 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#13 (text+ko) ==== @@ -95,7 +95,6 @@ #ifdef INET6 static int udp_done, tcp_done; #endif /* INET6 */ -static void inetppr(struct socket_type *); /* * Print a summary of connections related to an Internet @@ -146,6 +145,8 @@ inetppr(stp); netstat_st_free(stp); } + netstat_sti_free(stip); + netstat_stl_free(stlp); #else netstat_stl_iterate(stlp, inetppr); #endif ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#8 (text+ko) ==== @@ -73,6 +73,9 @@ #include #include "extern.h" +#include + + static struct nlist nl[] = { #define N_IFNET 0 { .n_name = "_ifnet" }, @@ -294,6 +297,7 @@ #endif atalkprotox, NULL }; +static void connpr(struct socket_type *); static void printproto(struct protox *, const char *); static void usage(void); static struct protox *name2protox(const char *); @@ -336,6 +340,11 @@ struct protox *tp = NULL; /* for printing cblocks & stats */ int ch; + struct socket_type_list *stlp; + int error, st_flags; + struct socket_type_iterator *stip; + struct socket_type *stp; + af = AF_UNSPEC; while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:rSstuWw:xz")) != -1) @@ -552,11 +561,11 @@ printproto(tp, tp->pr_name); exit(0); } - if (af == AF_INET || af == AF_UNSPEC) + if (af == AF_INET) for (tp = protox; tp->pr_name; tp++) printproto(tp, tp->pr_name); #ifdef INET6 - if (af == AF_INET6 || af == AF_UNSPEC) + if (af == AF_INET6) for (tp = ip6protox; tp->pr_name; tp++) printproto(tp, tp->pr_name); #endif /*INET6*/ @@ -579,11 +588,64 @@ for (tp = netgraphprotox; tp->pr_name; tp++) printproto(tp, tp->pr_name); #endif /* NETGRAPH */ - if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) + if (af == AF_UNIX && !sflag) unixpr(kvmd); + if (af == AF_UNSPEC) { + stlp = netstat_stl_alloc(); + if (stlp == NULL) { + warn("netstat_stl_alloc"); + exit(-1); + } + st_flags = 0; + if (!live) + st_flags |= NETSTAT_SOCKET_KVM; + if (aflag) + st_flags |= NETSTAT_SOCKET_ALL; + /* + * There should be guaranteed that sockets are not mixed (i.e. + * they are coming ordered by family/protocol). + */ + if (netstat_socket(PF_UNSPEC, 0, 0, stlp, st_flags, + kvmd) < 0) { + error = netstat_stl_geterror(stlp); + if (error == NETSTAT_ERROR_KVM) + warnx("netstat_socket: %s", kvm_geterr(kvmd)); + else + warnx("netstat_socket: %s", + netstat_strerror(error)); + exit(-1); + } + if (netstat_sti_alloc(stlp, &stip) < 0) { + warnx("netstat_sti_alloc"); + exit(-1); + } + for (stp = netstat_sti_first(stip); stp != NULL; + stp = netstat_sti_next(stip)) { + connpr(stp); + netstat_st_free(stp); + } + netstat_sti_free(stip); + netstat_stl_free(stlp); + } exit(0); } +static void +connpr(struct socket_type *stp) +{ + switch (netstat_st_get_family(stp)) { + case PF_INET: + case PF_INET6: + inetppr(stp); + break; + case PF_LOCAL: + unixdomainpr(stp); + break; + default: + break; + } +} + /* * Print out protocol statistics or control blocks (per sflag). * If the interface was not specifically requested, and the symbol @@ -650,7 +712,8 @@ case IPPROTO_IGMP: case IPPROTO_PIM: case IPPROTO_ICMPV6: - inetpr(kvmd, af, tp->pr_protocol); + inetpr(kvmd, (af == PF_INET6) ? af : PF_INET, + tp->pr_protocol); break; default: if (pr != NULL) ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#12 (text+ko) ==== @@ -55,8 +55,6 @@ #define USE_ITERATOR_TYPE -static void unixdomainpr(struct socket_type *); - void unixpr(void *kvmd) { @@ -105,12 +103,14 @@ unixdomainpr(stp); netstat_st_free(stp); } + netstat_sti_free(stip); + netstat_stl_free(stlp); #else netstat_stl_iterate(stlp, unixdomainpr); #endif } -static void +void unixdomainpr(struct socket_type *stp) { static int first = 1;