From owner-p4-projects@FreeBSD.ORG Tue Jul 21 01:02:08 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 62922106567B; Tue, 21 Jul 2009 01:02:08 +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 217101065679 for ; Tue, 21 Jul 2009 01:02:08 +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 04FF98FC17 for ; Tue, 21 Jul 2009 01:02:08 +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 n6L127JU036584 for ; Tue, 21 Jul 2009 01:02:08 GMT (envelope-from pgj@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n6L127qe036582 for perforce@freebsd.org; Tue, 21 Jul 2009 01:02:07 GMT (envelope-from pgj@FreeBSD.org) Date: Tue, 21 Jul 2009 01:02:07 GMT Message-Id: <200907210102.n6L127qe036582@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 166340 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, 21 Jul 2009 01:02:09 -0000 http://perforce.freebsd.org/chv.cgi?CH=166340 Change 166340 by pgj@petymeg-current on 2009/07/21 01:01:29 Some netstat_interface() improvements: - Eliminate the need for extract_if_maddress() - Add support for PF_INET, PF_INET6 - Fix the problem of sockaddr types of different sizes - Fix & improve address resolution - Add further accessor functions Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#31 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#3 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#28 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#34 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#31 (text+ko) ==== @@ -245,9 +245,14 @@ u_int64_t netstat_ft_get_errors(const struct face_type *); int netstat_iat_get_family(const struct intfaddr_type *); -const char *netstat_iat_get_name(const struct intfaddr_type *); -const char *netstat_iat_get_subnet(const struct intfaddr_type *); +const char *netstat_iat_get_address(const struct intfaddr_type *, int numeric); +const char *netstat_iat_get_network(const struct intfaddr_type *, int numeric); enum intfaddr_layer netstat_iat_get_layer(const struct intfaddr_type *); +u_int64_t netstat_iat_get_ipackets(const struct intfaddr_type *); +u_int64_t netstat_iat_get_ibytes(const struct intfaddr_type *); +u_int64_t netstat_iat_get_opackets(const struct intfaddr_type *); +u_int64_t netstat_iat_get_obytes(const struct intfaddr_type *); +u_int32_t netstat_iat_get_refcount(const struct intfaddr_type *); /* Interface addresses: */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#3 (text+ko) ==== @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -56,9 +57,8 @@ static const char *const if_symbol[] = { "_ifnet" }; static void extract_if_data(struct ifnet *ifp, struct interface_type *itp); -static void extract_if_address(struct ifaddr *ifa, struct interface_type *itp); -static void extract_if_maddress(struct ifmultiaddr *ifma, - struct interface_type *itp); +static struct intfaddr_type *extract_if_address(int type, void *ifaddr, + void *saddr, struct interface_type *itp); #define KREAD(off, dst) do { \ if ((list->itl_error = (kread_data(kvm, (uintptr_t)(off), &(dst), \ @@ -78,7 +78,14 @@ struct ifnethead ifnethead; struct ifnet ifnet; - struct ifaddr ifaddr; + union { + struct ifaddr ifa; + struct in_ifaddr in; +#ifdef INET6 + struct in6_ifaddr in6; +#endif + struct ipx_ifaddr ipx; + } ifaddr; union { struct sockaddr sa; struct sockaddr_dl dl; @@ -126,15 +133,19 @@ /* Interface addresses. */ for (ifa_addr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); ifa_addr != 0; - ifa_addr = (u_long)TAILQ_NEXT(&ifaddr, ifa_link)) { + ifa_addr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link)) { KREAD(ifa_addr, ifaddr); - KREAD(ifaddr.ifa_addr, sa); - ifaddr.ifa_addr = &sa.sa; + KREAD(ifaddr.ifa.ifa_addr, sa); + ifaddr.ifa.ifa_addr = &sa.sa; /* List addresses with the given protocol. */ if (domain != PF_UNSPEC && - domain != ifaddr.ifa_addr->sa_family) + domain != ifaddr.ifa.ifa_addr->sa_family) continue; - extract_if_address(&ifaddr, itp); + if (itp->it_addrcnt >= IFTYPE_MAXADDRCNT) + continue; + itp->it_address[itp->it_addrcnt++] = + extract_if_address(NETSTAT_IF_IFADDR, + &ifaddr.ifa, ifaddr.ifa.ifa_addr, itp); } /* Multicast addresses. */ @@ -147,7 +158,11 @@ if (domain != PF_UNSPEC && domain != ifmultiaddr.ifma_addr->sa_family) continue; - extract_if_maddress(&ifmultiaddr, itp); + if (itp->it_maddrcnt >= IFTYPE_MAXADDRCNT) + continue; + itp->it_maddress[itp->it_maddrcnt++] = + extract_if_address(NETSTAT_IF_IFMULTIADDR, + &ifmultiaddr, ifmultiaddr.ifma_addr, itp); } } } else { @@ -184,11 +199,15 @@ itp->it_flags |= NETSTAT_IF_UP; } -void -extract_if_address(struct ifaddr *ifa, struct interface_type *itp) +struct intfaddr_type * +extract_if_address(int type, void *ifaddr, void *saddr, + struct interface_type *itp) { struct sockaddr *sa; struct sockaddr_in *sa_in; +#ifdef INET6 + struct sockaddr_in6 *sa_in6; +#endif struct sockaddr_dl *sa_dl; struct in_ifaddr *in; #ifdef INET6 @@ -196,34 +215,94 @@ #endif struct ipx_ifaddr *ipx; + struct ifmultiaddr *ifma; struct intfaddr_type *ifap; char *cp, *p; int n; - sa = (struct sockaddr *)ifa->ifa_addr; + sa = (struct sockaddr *)saddr; sa_in = (struct sockaddr_in *)sa; + sa_in6 = (struct sockaddr_in6 *)sa; sa_dl = (struct sockaddr_dl *)sa; - in = (struct in_ifaddr *)sa; - in6 = (struct in6_ifaddr *)sa; - ipx = (struct ipx_ifaddr *)sa; - /* Cannot store more addresses. */ - if (itp->it_addrcnt == IFTYPE_MAXADDRCNT) - return; + in = (struct in_ifaddr *)ifaddr; + in6 = (struct in6_ifaddr *)in; + ipx = (struct ipx_ifaddr *)in; + ifma = (struct ifmultiaddr *)ifaddr; - ifap = itp->it_address[itp->it_addrcnt] = - _netstat_iat_allocate(sa->sa_family, NETSTAT_IF_IFADDR); + ifap = _netstat_iat_allocate(sa->sa_family, type); if (ifap == NULL) - return; + return (NULL); switch (sa->sa_family) { case PF_UNSPEC: + ifap->iat_address = strdup("none"); + ifap->iat_network = strdup("none"); break; case PF_INET: + ifap->iat_sockaddr_len = sizeof(struct sockaddr_in); + ifap->iat_sockaddr = malloc(ifap->iat_sockaddr_len); + if (ifap->iat_sockaddr != NULL) + memcpy(ifap->iat_sockaddr, sa_in, + ifap->iat_sockaddr_len); + ifap->iat_ifaddr_len = sizeof(struct in_ifaddr); + if (ifap->iat_ifaddr != NULL) + memcpy(ifap->iat_ifaddr, in, ifap->iat_ifaddr_len); + strlcpy(ifap->iat_ni_network, + netname(htonl(in->ia_subnet), in->ia_subnetmask, 1), + sizeof(ifap->iat_ni_network)); + ifap->iat_network = strdup(netname(htonl(in->ia_subnet), + in->ia_subnetmask, 0)); + inet_ntop(PF_INET, &sa_in->sin_addr, ifap->iat_ni_address, + sizeof(ifap->iat_ni_address)); + ifap->iat_address = strdup(routename(sa_in->sin_addr.s_addr, 0)); + ifap->iat_layer = layer_Network; + switch (type) { + case NETSTAT_IF_IFADDR: + ifap->iat_refcount = in->ia_ifa.ifa_refcnt; + break; + case NETSTAT_IF_IFMULTIADDR: + ifap->iat_refcount = ifma->ifma_refcount; + break; + } + ifap->iat_opackets = in->ia_ifa.if_opackets; + ifap->iat_ipackets = in->ia_ifa.if_ipackets; + ifap->iat_obytes = in->ia_ifa.if_obytes; + ifap->iat_ibytes = in->ia_ifa.if_ibytes; break; #ifdef INET6 case PF_INET6: + ifap->iat_sockaddr_len = sizeof(struct sockaddr_in6); + ifap->iat_sockaddr = malloc(ifap->iat_sockaddr_len); + if (ifap->iat_sockaddr != NULL) + memcpy(ifap->iat_sockaddr, sa_in6, + ifap->iat_sockaddr_len); + ifap->iat_ifaddr_len = sizeof(struct in6_ifaddr); + if (ifap->iat_ifaddr != NULL) + memcpy(ifap->iat_ifaddr, in6, ifap->iat_ifaddr_len); + strlcpy(ifap->iat_ni_network, + netname6(&in6->ia_addr, &in6->ia_prefixmask.sin6_addr, 1), + sizeof(ifap->iat_ni_network)); + ifap->iat_network = + strdup(netname6(&in6->ia_addr, + &in6->ia_prefixmask.sin6_addr, 0)); + inet_ntop(PF_INET6, &sa_in6->sin6_addr, ifap->iat_ni_address, + sizeof(ifap->iat_ni_address)); + ifap->iat_address = strdup(routename6(sa_in6, 0)); + ifap->iat_layer = layer_Network; + switch (type) { + case NETSTAT_IF_IFADDR: + ifap->iat_refcount = in->ia_ifa.ifa_refcnt; + break; + case NETSTAT_IF_IFMULTIADDR: + ifap->iat_refcount = ifma->ifma_refcount; + break; + } + ifap->iat_opackets = in6->ia_ifa.if_opackets; + ifap->iat_ipackets = in6->ia_ifa.if_ipackets; + ifap->iat_obytes = in6->ia_ifa.if_obytes; + ifap->iat_ibytes = in6->ia_ifa.if_ibytes; break; #endif /* INET6 */ case PF_IPX: @@ -231,74 +310,26 @@ case PF_APPLETALK: break; case PF_LINK: - ifap->iat_address_len = sizeof(struct sockaddr_dl); - ifap->iat_address = malloc(ifap->iat_address_len); - if (ifap->iat_address != NULL) - memcpy(ifap->iat_address, sa_dl, ifap->iat_address_len); - ifap->iat_network = NULL; - sprintf(ifap->iat_subnet, "", sa_dl->sdl_index); + ifap->iat_sockaddr_len = sizeof(struct sockaddr_dl); + ifap->iat_sockaddr = malloc(ifap->iat_sockaddr_len); + if (ifap->iat_sockaddr != NULL) + memcpy(ifap->iat_sockaddr, sa_dl, + ifap->iat_sockaddr_len); + sprintf(ifap->iat_ni_network, "", sa_dl->sdl_index); + ifap->iat_network = strdup(ifap->iat_ni_network); cp = (char *)LLADDR(sa_dl); n = sa_dl->sdl_alen; - p = ifap->iat_name; + p = ifap->iat_ni_address; while (--n >= 0) { sprintf(p, "%02x%s", *cp++ & 0xff, n > 0 ? ":" : ""); p += 3; } + ifap->iat_address = strdup(ifap->iat_ni_address); ifap->iat_layer = layer_Link; break; default: break; } - itp->it_addrcnt += 1; -} - -void -extract_if_maddress(struct ifmultiaddr *ifma, struct interface_type *itp) -{ - struct sockaddr *sa; - struct sockaddr_dl *sa_dl; - struct intfaddr_type *ifap; - - char *cp, *p; - int n; - - sa = ifma->ifma_addr; - sa_dl = (struct sockaddr_dl *)sa; - - /* Cannot store more addresses. */ - if (itp->it_maddrcnt == IFTYPE_MAXADDRCNT) - return; - - ifap = itp->it_maddress[itp->it_maddrcnt] = - _netstat_iat_allocate(sa->sa_family, NETSTAT_IF_IFMULTIADDR); - if (ifap == NULL) - return; - - switch (sa->sa_family) { - case PF_INET: - break; -#ifdef INET6 - case PF_INET6: - break; -#endif /* INET6 */ - case PF_LINK: - ifap->iat_address_len = sizeof(struct sockaddr_dl); - ifap->iat_address = malloc(ifap->iat_address_len); - if (ifap->iat_address != NULL) - memcpy(ifap->iat_address, sa_dl, ifap->iat_address_len); - ifap->iat_network = NULL; - sprintf(ifap->iat_subnet, "", sa_dl->sdl_index); - cp = (char *)LLADDR(sa_dl); - n = sa_dl->sdl_alen; - p = ifap->iat_name; - while (--n >= 0) { - sprintf(p, "%02x%s", *cp++ & 0xff, n > 0 ? ":" : ""); - p += 3; - } - ifap->iat_layer = layer_Link; - break; - } - - itp->it_maddrcnt += 1; + return (ifap); } ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#28 (text+ko) ==== @@ -186,13 +186,15 @@ int iat_family; /* protocol family */ enum intfaddr_layer iat_layer; int iat_type; /* ifa, ifma */ - char iat_name[20]; - char iat_subnet[16]; - void *iat_address; /* raw address */ - void *iat_network; /* raw network */ - int iat_address_len; - u_int64_t iat_network_mask; - u_int32_t iat_refcount; /* ifma */ + char *iat_address; + char iat_ni_address[20]; /* numeric */ + char *iat_network; + char iat_ni_network[16]; /* numeric */ + void *iat_sockaddr; + void *iat_ifaddr; + int iat_sockaddr_len; + int iat_ifaddr_len; + u_int32_t iat_refcount; /* for network-layer addresses: */ u_int64_t iat_opackets; u_int64_t iat_ipackets; @@ -261,8 +263,8 @@ /* XXX: merge these into a common address resolution routine. */ -const char *routename(in_addr_t *in, int numeric); -const char *netname(in_addr_t *in, u_long mask, int numeric); +const char *routename(in_addr_t in, int numeric); +const char *netname(in_addr_t in, u_long mask, int numeric); #ifdef INET6 const char *routename6(struct sockaddr_in6 *in6, int numeric); const char *netname6(struct sockaddr_in6 *in6, struct in6_addr *mask, ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#34 (text+ko) ==== @@ -863,6 +863,8 @@ { free(iatp->iat_address); free(iatp->iat_network); + free(iatp->iat_sockaddr); + free(iatp->iat_ifaddr); free(iatp); } @@ -973,15 +975,19 @@ } const char * -netstat_iat_get_name(const struct intfaddr_type *iatp) +netstat_iat_get_address(const struct intfaddr_type *iatp, int numeric) { - return (iatp->iat_name); + if (numeric) + return (iatp->iat_ni_address); + return (iatp->iat_address); } const char * -netstat_iat_get_subnet(const struct intfaddr_type *iatp) +netstat_iat_get_network(const struct intfaddr_type *iatp, int numeric) { - return (iatp->iat_subnet); + if (numeric) + return (iatp->iat_ni_network); + return (iatp->iat_network); } enum intfaddr_layer @@ -990,17 +996,46 @@ return (iatp->iat_layer); } +u_int64_t +netstat_iat_get_ipackets(const struct intfaddr_type *iatp) +{ + return (iatp->iat_ipackets); +} + +u_int64_t +netstat_iat_get_ibytes(const struct intfaddr_type *iatp) +{ + return (iatp->iat_ibytes); +} + +u_int64_t +netstat_iat_get_opackets(const struct intfaddr_type *iatp) +{ + return (iatp->iat_opackets); +} + +u_int64_t +netstat_iat_get_obytes(const struct intfaddr_type *iatp) +{ + return (iatp->iat_obytes); +} + +u_int32_t +netstat_iat_get_refcount(const struct intfaddr_type *iatp) +{ + return (iatp->iat_refcount); +} + const char * -routename(in_addr_t *in, int numeric) +routename(in_addr_t in, int numeric) { char *cp; static char line[MAXHOSTNAMELEN]; struct hostent *hp; - in_addr_t tin; cp = NULL; if (!numeric) { - hp = gethostbyaddr(in, sizeof(struct in_addr), PF_INET); + hp = gethostbyaddr(&in, sizeof(struct in_addr), PF_INET); if (hp != NULL) { cp = hp->h_name; trimdomain(cp, strlen(cp)); @@ -1010,9 +1045,9 @@ strlcpy(line, cp, sizeof(line)); } else { #define C(x) ((x) & 0xff) - tin = ntohl(*in); + in = ntohl(in); sprintf(line, "%u.%u.%u.%u", - C(tin >> 24), C(tin >> 16), C(tin >> 8), C(tin)); + C(in >> 24), C(in >> 16), C(in >> 8), C(in)); } return (line); } @@ -1039,8 +1074,9 @@ i = b; for (bb = b + 1; bb < 32; bb++) - if (!(mask & (1 << b))) { + if (!(mask & (1 << bb))) { i = -1; /* noncontig */ + break; } break; } @@ -1051,15 +1087,15 @@ } const char * -netname(in_addr_t *in, u_long mask, int numeric) +netname(in_addr_t in, u_long mask, int numeric) { char *cp = NULL; static char line[MAXHOSTNAMELEN]; struct netent *np = NULL; in_addr_t i; - i = ntohl(*in); - if (!numeric && i != 0) { + i = ntohl(in); + if (!numeric && i) { np = getnetbyaddr(i >> NSHIFT(mask), PF_INET); if (np != NULL) { cp = np->n_name;