From owner-p4-projects@FreeBSD.ORG Sun Aug 22 18:25:47 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 32A0A10656A8; Sun, 22 Aug 2010 18:25:47 +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 D02D6106567A for ; Sun, 22 Aug 2010 18:25:46 +0000 (UTC) (envelope-from aman@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id BD2848FC15 for ; Sun, 22 Aug 2010 18:25:46 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7MIPk3I075234 for ; Sun, 22 Aug 2010 18:25:46 GMT (envelope-from aman@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7MIPkDr075231 for perforce@freebsd.org; Sun, 22 Aug 2010 18:25:46 GMT (envelope-from aman@freebsd.org) Date: Sun, 22 Aug 2010 18:25:46 GMT Message-Id: <201008221825.o7MIPkDr075231@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to aman@freebsd.org using -f From: Aman Jassal To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182768 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Aug 2010 18:25:47 -0000 http://p4web.freebsd.org/@@182768?ac=10 Change 182768 by aman@src on 2010/08/22 18:25:14 Several things here : introducing netisr abstractions and adding sysctl support to export interface information. netisr abstractions are fairly simple and are more like a porting of structures introduced by Robert Watson. Sysctl support for interface information was done via the addition of support in if_mib. Reviewed by: pgj Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#70 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#9 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#68 edit .. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#76 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/net/if_mib.c#3 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/net/if_mib.h#2 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/net/netisr.c#6 edit .. //depot/projects/soc2009/pgj_libstat/src/sys/net/netisr.h#5 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#70 (text+ko) ==== @@ -52,6 +52,8 @@ #define MIFTYPE_MAXNAME IFNAMSIZ #define MRTTYPE_MAXVIFS MAXVIFS +#define NETISR_NAMEMAXLEN 32 + #define NETSTAT_ERROR_UNDEFINED 0 #define NETSTAT_ERROR_NOMEMORY 1 #define NETSTAT_ERROR_VERSION 2 @@ -285,6 +287,18 @@ struct mroute_type_list; struct mroute_type_iterator; +struct netisr_protocol; +struct netisr_protocol_list; +struct netisr_protocol_iterator; + +struct netisr_workstream; +struct netisr_workstream_list; +struct netisr_workstream_iterator; + +struct netisr_work; +struct netisr_work_list; +struct netisr_work_iterator; + __BEGIN_DECLS const char *netstat_strerror(int); @@ -1339,6 +1353,68 @@ uint8_t netstat_mrt_get_ttl(const struct mroute_type *, int); int netstat_mrt_get_is_mif_set(const struct mroute_type *, uint32_t); + +/* Netisr Services: */ +void netstat_npp_free(struct netisr_protocol *); +struct netisr_protocol_list *netstat_npl_alloc(void); +void netstat_npl_free(struct netisr_protocol_list *); +int netstat_npl_geterror(const struct netisr_protocol_list *); +int netstat_npl_length(const struct netisr_protocol_list *); + +int netstat_npi_alloc(struct netisr_protocol_list *list, + struct netisr_protocol_iterator **iterator); +const struct netisr_protocol *netstat_npi_first(struct netisr_protocol_iterator *); +const struct netisr_protocol *netstat_npi_next(struct netisr_protocol_iterator *); +void netstat_npi_free(struct netisr_protocol_iterator *); + +uint32_t netstat_np_get_version(const struct netisr_protocol *); +const char* netstat_np_get_name(const struct netisr_protocol *); +uint32_t netstat_np_get_proto(const struct netisr_protocol *); +uint32_t netstat_np_get_qlimit(const struct netisr_protocol *); +uint32_t netstat_np_get_policy(const struct netisr_protocol *); +uint32_t netstat_np_get_flags(const struct netisr_protocol *); + +void netstat_nwsp_free(struct netisr_workstream *); +struct netisr_workstream_list *netstat_nwsl_alloc(void); +void netstat_nwsl_free(struct netisr_workstream_list *); +int netstat_nwsl_geterror(struct netisr_workstream_list *); +int netstat_nwsl_length(struct netisr_workstream_list *); + +int netstat_nwsi_alloc(struct netisr_workstream_list *list, + struct netisr_workstream_iterator **iterator); +const struct netisr_workstream *netstat_nwsi_first(struct netisr_workstream_iterator *); +const struct netisr_workstream *netstat_nwsi_next(struct netisr_workstream_iterator *); +void netstat_nwsi_free(struct netisr_workstream_iterator *); + +uint32_t netstat_nws_get_version(const struct netisr_workstream *); +uint32_t netstat_nws_get_flags(const struct netisr_workstream *); +uint32_t netstat_nws_get_wsid(const struct netisr_workstream *); +uint32_t netstat_nws_get_cpu(const struct netisr_workstream *); + +void netstat_nwp_free(struct netisr_work *); +struct netisr_work_list *netstat_nwl_alloc(void); +void netstat_nwl_free(struct netisr_work_list *); +int netstat_nwl_geterror(struct netisr_work_list *); +int netstat_nwl_length(struct netisr_work_list *); + +int netstat_nwi_alloc(struct netisr_work_list *list, + struct netisr_work_iterator **iterator); +const struct netisr_work *netstat_nwi_first(struct netisr_work_iterator *); +const struct netisr_work *netstat_nwi_next(struct netisr_work_iterator *); +void netstat_nwi_free(struct netisr_work_iterator *); + +uint32_t netstat_nw_get_version(const struct netisr_work *); +uint32_t netstat_nw_get_wsid(const struct netisr_work *); +uint32_t netstat_nw_get_proto(const struct netisr_work *); +uint32_t netstat_nw_get_len(const struct netisr_work *); +uint32_t netstat_nw_get_watermark(const struct netisr_work *); +uint64_t netstat_nw_get_dispatched(const struct netisr_work *); +uint64_t netstat_nw_get_hybrid_dispatched(const struct netisr_work *); +uint64_t netstat_nw_get_qdrops(const struct netisr_work *); +uint64_t netstat_nw_get_queued(const struct netisr_work *); +uint64_t netstat_nw_get_handled(const struct netisr_work *); + + __END_DECLS #endif /* !_NETSTAT_H_ */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#9 (text+ko) ==== @@ -29,9 +29,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -40,6 +42,7 @@ #include #include +#include #include #include #include @@ -57,8 +60,11 @@ static const char *const if_symbol[] = { "_ifnet" }; static void extract_if_data(struct ifnet *ifp, struct interface_type *itp); +static void extract_sif_data(struct ifmib_ifnet_data *iidp, struct interface_type *itp); static struct intfaddr_type *extract_if_address(int type, void *ifaddr, void *saddr, struct interface_type *itp); +static struct intfaddr_type *extract_sif_address(int type, int domain, + struct ifmib_ifaddress_data *iiadp, struct interface_type *itp); #define KREAD(off, dst) do { \ if ((list->itl_error = (kread_data(session->sst_kvm, \ @@ -100,6 +106,20 @@ u_long ifa_addr; u_long ifma_addr; + /* + * XXXAJ : Adding declarations for the sysctl part. + */ + struct ifmib_ifdata_stream *iisp; + struct ifmib_ifaddress_stream *iiasp; + //struct ifmib_ifmadress_stream *iimasp; + struct ifmib_ifnet_data *iidp; + struct ifmib_ifaddress_data *iiadp; + //struct ifmib_ifmaddress_data *iimadp; + size_t ifdata_len, ifaddress_len; + char *buffer_ifdata, *buffer_ifaddress, *p; + int interface_index, interface_to_look_for, ifmib_ifdata_sysctl[6], ifmib_ifaddress_sysctl[6]; + uint32_t interface_count, ifaddress_count; + result = -1; bzero(nls, sizeof(nls)); @@ -164,10 +184,146 @@ } } else { /* Using sysctl(8). */ - /* XXX: not implemented yet :) */ - goto end; + + /* + * XXXAJ : Adding support to export interface data and addresses for libnetstat + * using the pre-existing support offered by ifmib(4). + * + * The algorithm we follow to do so is not exactly straight-forward but + * it is the best compromise we could find when re-using ifmib(4). + * This is, basically, what we do : + * + * 1) Get the number of configured interfaces, which is given by the sysctl + * variable net.link.generic.system.if_count + * 2) Since interface indexes are <= to if_count, we make a loop from 1 + * (which is the lowest an index can be) to if_count, and + * then we call the ifmib sysctl to retrieve all the relevant + * data. + * 3) Once we have retrieved the complete list of configured interfaces, + * we select the one the user requested and print out all + * the information regarding this interface. + */ + const char *mibvar_ifcount = "net.link.generic.system.ifcount"; + int if_count; + + if (sysctlbyname(mibvar_ifcount, 0, &if_count, 0, 0) < 0) { + if (errno != ENOENT) + warn("sysctl: %s", mibvar_ifcount); + goto end; + } + + /* + * From here on in, we loop through the number of configured + * network interfaces, and we call the ifmib sysctls. + */ + + for (interface_index = 1; interface_index <= if_count; interface_index++) { + /* + * XXXAJ : All the sysctl nodes will be properly initialized + * in this for loop. + */ + ifmib_ifdata_sysctl[0] = CTL_NET; + ifmib_ifdata_sysctl[1] = PF_LINK; + ifmib_ifdata_sysctl[2] = NETLINK_GENERIC; + ifmib_ifdata_sysctl[3] = IFMIB_IFDATA; + ifmib_ifdata_sysctl[4] = interface_index; + ifmib_ifdata_sysctl[5] = IFDATA_MONITORING; + + if (sysctl(ifmib_ifdata_sysctl, 6, NULL, &ifdata_len, NULL, 0) < 0) { + if (errno != ENOENT) + warn("sysctl: ifmib_ifdata_sysctl estimate"); + goto end; + } + if ((buffer_ifdata = malloc(ifdata_len)) == 0) { + warnx("malloc %lu bytes", (u_long)ifdata_len); + goto end; + } + if (sysctl(ifmib_ifdata_sysctl, 6, buffer_ifdata, &ifdata_len, NULL, 0) < 0) { + warn("sysctl: ifmib_ifdata_sysctl retrieval"); + goto out_ifdata; + } + if (ifdata_len < sizeof(*iisp)) { + list->itl_error = NETSTAT_ERROR_VERSION; + goto out_ifdata; + } + + p = buffer_ifdata; + iisp = (struct ifmib_ifdata_stream *)p; + p += sizeof(*iisp); + + if (iisp->iis_version != IFMIB_IFDATA_STREAM_VERSION) { + list->itl_error = NETSTAT_ERROR_VERSION; + printf("Error in iis_version\n"); + goto out_ifdata; + } + + for (interface_count = 0; interface_count < iisp->iis_count; interface_count++) { + iidp = (struct ifmib_ifnet_data *)p; + p += sizeof(*iidp); + + if (strcmp(name, iidp->iid_ifi_name) != 0) + continue; + + interface_to_look_for = interface_index; + itp = _netstat_it_allocate(list, iidp->iid_ifi_type, + iidp->iid_ifi_physical, iidp->iid_ifi_name); + extract_sif_data(iidp, itp); + } + } + + /* + * XXXAJ : Now we have to retrieve interface addresses. + */ + ifmib_ifaddress_sysctl[0] = CTL_NET; + ifmib_ifaddress_sysctl[1] = PF_LINK; + ifmib_ifaddress_sysctl[2] = NETLINK_GENERIC; + ifmib_ifaddress_sysctl[3] = IFMIB_IFADDRESS; + ifmib_ifaddress_sysctl[4] = interface_to_look_for; + ifmib_ifaddress_sysctl[5] = domain; + + if (sysctl(ifmib_ifaddress_sysctl, 6, NULL, &ifaddress_len, NULL, 0) < 0) { + if (errno != ENOENT) + warn("sysctl: ifmib_ifaddress_sysctl estimate"); + goto end; + } + if ((buffer_ifaddress = malloc(ifaddress_len)) == 0) { + warnx("malloc %lu bytes", (u_long)ifaddress_len); + goto end; + } + if (sysctl(ifmib_ifaddress_sysctl, 6, buffer_ifaddress, &ifaddress_len, NULL, 0) < 0) { + warn("sysctl: ifmib_ifaddress_sysctl retrieval"); + goto out_ifaddress; + } + if (ifaddress_len < sizeof(*iiasp)) { + list->itl_error = NETSTAT_ERROR_VERSION; + goto out_ifaddress; + } + + p = buffer_ifaddress; + iiasp = (struct ifmib_ifaddress_stream *)p; + p += sizeof(*iiasp); + + if (iiasp->iias_version != IFMIB_IFADDRESS_STREAM_VERSION) { + printf("Error in iias_version\n"); + list->itl_error = NETSTAT_ERROR_VERSION; + goto out_ifaddress; + } + + for (ifaddress_count = 0; ifaddress_count < iiasp->iias_count; ifaddress_count++) { + iiadp = (struct ifmib_ifaddress_data *)p; + p += sizeof(*iiadp); + + if (itp->it_addrcnt >= IFTYPE_MAXADDRCNT) + continue; + itp->it_address[itp->it_addrcnt++] = extract_sif_address(NETSTAT_IF_IFADDR, + domain, iiadp, itp); + } } result = 0; +out_ifdata: + free(buffer_ifdata); +out_ifaddress: + free(buffer_ifaddress); end: return (result); } @@ -195,6 +351,27 @@ itp->it_flags |= NETSTAT_IF_UP; } +void +extract_sif_data(struct ifmib_ifnet_data *iidp, struct interface_type *itp) +{ + itp->it_mtu = iidp->iid_ifi_mtu; + itp->it_in.ft_packets = iidp->iid_ifi_ipackets; + itp->it_in.ft_bytes = iidp->iid_ifi_ibytes; + itp->it_in.ft_mcasts = iidp->iid_ifi_imcasts; + itp->it_in.ft_errors = iidp->iid_ifi_ierrors; + itp->it_in.ft_drops = iidp->iid_ifi_iqdrops; + itp->it_out.ft_packets = iidp->iid_ifi_opackets; + itp->it_out.ft_bytes = iidp->iid_ifi_obytes; + itp->it_out.ft_mcasts = iidp->iid_ifi_omcasts; + itp->it_out.ft_errors = iidp->iid_ifi_oerrors; + itp->it_out.ft_drops = 0; + itp->it_collisions = iidp->iid_ifi_collisions; + itp->it_drops = iidp->iid_ifi_ifq_drops; + itp->it_flags = 0; + if (iidp->iid_ifi_flags & IFF_UP) + itp->it_flags |= NETSTAT_IF_UP; +} + struct intfaddr_type * extract_if_address(int type, void *ifaddr, void *saddr, struct interface_type *itp) @@ -237,14 +414,6 @@ 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)); @@ -269,14 +438,6 @@ 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)); @@ -306,11 +467,6 @@ case PF_APPLETALK: break; case PF_LINK: - 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); @@ -329,3 +485,114 @@ return (ifap); } + +struct intfaddr_type * +extract_sif_address(int type, int domain, struct ifmib_ifaddress_data *iiadp, struct interface_type *itp) +{ + struct intfaddr_type *ifap; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6, *sin6_prefixmask; + char *p, *cp; + int n; + + ifap =_netstat_iat_allocate(domain, type); + if (ifap == NULL) + return (NULL); + + switch (domain) { + case PF_UNSPEC: + ifap->iat_address = strdup("none"); + ifap->iat_network = strdup("none"); + break; + + case PF_INET: + sin = malloc(sizeof(struct sockaddr_in)); + sin->sin_addr.s_addr = iiadp->iid_inet_address; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_family = PF_INET; + + strlcpy(ifap->iat_ni_network, + netname(htonl(iiadp->iid_inet_subnet), iiadp->iid_inet_subnetmask, 1), + sizeof(ifap->iat_ni_network)); + ifap->iat_network = strdup(netname(htonl(iiadp->iid_inet_subnet), + iiadp->iid_inet_subnetmask, 0)); + inet_ntop(PF_INET, &(iiadp->iid_inet_address), ifap->iat_ni_address, + sizeof(ifap->iat_ni_address)); + ifap->iat_address = strdup(routename(iiadp->iid_inet_address, 0)); + ifap->iat_layer = layer_Network; + + switch (type) { + case NETSTAT_IF_IFADDR: + ifap->iat_refcount = iiadp->iid_ifa_refcount; + break; + case NETSTAT_IF_IFMULTIADDR: + ifap->iat_refcount = iiadp->iid_ifa_refcount; + break; + } + ifap->iat_opackets = iiadp->iid_ifa_opackets; + ifap->iat_ipackets = iiadp->iid_ifa_ipackets; + ifap->iat_obytes = iiadp->iid_ifa_obytes; + ifap->iat_ibytes = iiadp->iid_ifa_ibytes; + break; + +#ifdef INET6 + case PF_INET6: + sin6 = malloc(sizeof(struct sockaddr_in6)); + sin6->sin6_len = sizeof(struct sockaddr_in6); + sin6->sin6_family = PF_INET6; + bcopy(&(sin6->sin6_addr), &(iiadp->iid_inet6_address), sizeof(iiadp->iid_inet6_address)); + sin6->sin6_scope_id = iiadp->iid_inet6_scope_id; + + sin6_prefixmask = malloc(sizeof(struct sockaddr_in6)); + sin6_prefixmask->sin6_len = sizeof(struct sockaddr_in6); + sin6_prefixmask->sin6_family = PF_INET6; + bcopy(&(sin6_prefixmask->sin6_addr), &(iiadp->iid_inet6_prefixmask), sizeof(iiadp->iid_inet6_prefixmask)); + strlcpy(ifap->iat_ni_network, netname6(sin6, &(sin6_prefixmask->sin6_addr), 1), + sizeof(ifap->iat_ni_network)); + ifap->iat_network = strdup(netname6(sin6, &(sin6_prefixmask->sin6_addr), 0)); + inet_ntop(PF_INET6, &(sin6->sin6_addr), ifap->iat_ni_address, sizeof(ifap->iat_ni_address)); + ifap->iat_address = strdup(routename6(sin6, 0)); + ifap->iat_layer = layer_Network; + + switch (type) { + case NETSTAT_IF_IFADDR: + ifap->iat_refcount = iiadp->iid_ifa_refcount; + break; + case NETSTAT_IF_IFMULTIADDR: + ifap->iat_refcount = iiadp->iid_ifa_refcount; + break; + } + ifap->iat_opackets = iiadp->iid_ifa_opackets; + ifap->iat_ipackets = iiadp->iid_ifa_ipackets; + ifap->iat_obytes = iiadp->iid_ifa_obytes; + ifap->iat_ibytes = iiadp->iid_ifa_ibytes; + break; +#endif /* INET6 */ + + case PF_IPX: + break; + + case PF_APPLETALK: + break; + + case PF_LINK: + sprintf(ifap->iat_ni_network, "", iiadp->iid_link_layer_index); + ifap->iat_network = strdup(ifap->iat_ni_network); + cp = iiadp->iid_link_layer_address; + n = iiadp->iid_link_layer_alen; + sprintf(ifap->iat_ni_address, iiadp->iid_link_layer_address); + 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; + } + + return (ifap); +} ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#68 (text+ko) ==== @@ -242,10 +242,6 @@ 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; uint32_t iat_refcount; /* for network-layer addresses: */ uint64_t iat_opackets; @@ -556,6 +552,84 @@ }; +/* Netisr protocol structures. */ +struct netisr_protocol { + uint32_t np_version; + char np_name[NETISR_NAMEMAXLEN]; + uint32_t np_proto; + uint32_t np_qlimit; + uint32_t np_policy; + uint32_t np_flags; + + LIST_ENTRY(netisr_protocol) np_list; +}; + +struct netisr_protocol_list { + LIST_HEAD(, netisr_protocol) npl_list; + int npl_length; + int npl_error; +}; + +struct netisr_protocol_iterator { + struct netisr_protocol_list *npi_list; + struct netisr_protocol *npi_first; + struct netisr_protocol *npi_next; +}; + + +/* Netisr workstream structure type. */ +struct netisr_workstream { + uint32_t nws_version; + uint32_t nws_flags; + uint32_t nws_wsid; + uint32_t nws_cpu; + + LIST_ENTRY(netisr_workstream) nws_list; +}; + +struct netisr_workstream_list { + LIST_HEAD(, netisr_workstream) nwsl_list; + int nwsl_length; + int nwsl_error; +}; + +struct netisr_workstream_iterator { + struct netisr_workstream_list *nwsi_list; + struct netisr_workstream *nwsi_first; + struct netisr_workstream *nwsi_next; +}; + + +/* Netisr work structure type. */ +struct netisr_work { + uint32_t nw_version; + uint32_t nw_wsid; + uint32_t nw_proto; + uint32_t nw_len; + uint32_t nw_watermark; + + uint64_t nw_dispatched; + uint64_t nw_hybrid_dispatched; + uint64_t nw_qdrops; + uint64_t nw_queued; + uint64_t nw_handled; + + LIST_ENTRY(netisr_work) nw_list; +}; + +struct netisr_work_list { + LIST_HEAD(, netisr_work) nwl_list; + int nwl_length; + int nwl_error; +}; + +struct netisr_work_iterator { + struct netisr_work_list *nwi_list; + struct netisr_work *nwi_first; + struct netisr_work *nwi_next; +}; + + int kread_data(kvm_t *kvm, u_long kvm_pointer, void *address, size_t size); int kread_string(kvm_t *kvm, u_long kvm_pointer, char *buffer, int buflen); @@ -598,6 +672,15 @@ int _mrt6_get_nstall_kvm(kvm_t *, struct mf6c *); #endif /* !INET6 */ +void _netstat_npl_empty(struct netisr_protocol_list *); +struct netisr_protocol *_netstat_np_allocate(struct netisr_protocol_list *); + +void _netstat_nwsl_empty(struct netisr_workstream_list *); +struct netisr_workstream *_netstat_nws_allocate(struct netisr_workstream_list *); + +void _netstat_nwl_empty(struct netisr_work_list *); +struct netisr_work *_netstat_nw_allocate(struct netisr_work_list *); + struct routeaddr_type *extract_address(void *, void *, int); const char *resolve_val2str_name(int, const struct val2str *); /* XXX: merge these into a common address resolution routine. */ ==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#76 (text+ko) ==== @@ -759,8 +759,6 @@ { free(iatp->iat_address); free(iatp->iat_network); - free(iatp->iat_sockaddr); - free(iatp->iat_ifaddr); free(iatp); } @@ -2450,6 +2448,463 @@ #undef MROUTE_ACC +void +_netstat_npl_empty(struct netisr_protocol_list *list) +{ + struct netisr_protocol *npp; + + while ((npp = LIST_FIRST(&list->npl_list))) { + LIST_REMOVE(npp, np_list); + netstat_npp_free(npp); + } + + list->npl_length = 0; +} + +void +netstat_npp_free(struct netisr_protocol *npp) +{ + free(npp); +} + +struct netisr_protocol * +_netstat_np_allocate(struct netisr_protocol_list *list) +{ + struct netisr_protocol *npp; + + MALLOC_PTR(npp); + + bzero(npp, sizeof(*npp)); + LIST_INSERT_HEAD(&list->npl_list, npp, np_list); + list->npl_length += 1; + + return (npp); +} + +struct netisr_protocol_list * +netstat_npl_alloc(void) +{ + struct netisr_protocol_list *nplp; + + MALLOC_PTR(nplp); + + LIST_INIT(&nplp->npl_list); + nplp->npl_error = NETSTAT_ERROR_UNDEFINED; + nplp->npl_length = 0; + + return (nplp); +} + +void +netstat_npl_free(struct netisr_protocol_list *list) +{ + _netstat_npl_empty(list); + free(list); +} + +int +netstat_npl_geterror(const struct netisr_protocol_list *list) +{ + return(list->npl_error); +} + +int +netstat_npl_length(const struct netisr_protocol_list *list) +{ + return(list->npl_length); +} + +int +netstat_npi_alloc(struct netisr_protocol_list *list, + struct netisr_protocol_iterator **iterator) +{ + struct netisr_protocol_iterator *npip; + + MALLOC_ITR(npip); + + bzero(npip, sizeof(*npip)); + npip->npi_list = list; + npip->npi_first = LIST_FIRST(&list->npl_list); + if (npip->npi_first != NULL) + npip->npi_next = LIST_NEXT(npip->npi_first, np_list); + *iterator = npip; + + return (0); +} + +const struct netisr_protocol * +netstat_npi_first(struct netisr_protocol_iterator *npip) +{ + if (npip->npi_first != NULL) + npip->npi_next = LIST_NEXT(npip->npi_first, np_list); + + return (npip->npi_first); +} + +const struct netisr_protocol * +netstat_npi_next(struct netisr_protocol_iterator *npip) +{ + const struct netisr_protocol *npp; + + npp = npip->npi_next; + if (npip->npi_next != NULL) + npip->npi_next = LIST_NEXT(npip->npi_next, np_list); + + return (npp); +} + +void +netstat_npi_free(struct netisr_protocol_iterator *npip) +{ + free(npip); +} + +uint32_t +netstat_np_get_version(const struct netisr_protocol *npp) +{ + return (npp->np_version); +} + +const char * +netstat_np_get_name(const struct netisr_protocol *npp) +{ + return (npp->np_name); +} + +uint32_t +netstat_np_get_proto(const struct netisr_protocol *npp) +{ + return (npp->np_proto); +} + +uint32_t +netstat_np_get_qlimit(const struct netisr_protocol *npp) +{ + return (npp->np_qlimit); +} + +uint32_t +netstat_np_get_policy(const struct netisr_protocol *npp) +{ + return (npp->np_policy); +} + +uint32_t +netstat_np_get_flags(const struct netisr_protocol *npp) +{ + return (npp->np_flags); +} + + +void +_netstat_nwsl_empty(struct netisr_workstream_list *list) +{ + struct netisr_workstream *nwsp; + + while ((nwsp = LIST_FIRST(&list->nwsl_list))) { + LIST_REMOVE(nwsp, nws_list); + netstat_nwsp_free(nwsp); + } + + list->nwsl_length = 0; +} + +void +netstat_nwsp_free(struct netisr_workstream *nwsp) +{ + free(nwsp); +} + +struct netisr_workstream * +_netstat_nws_allocate(struct netisr_workstream_list *list) +{ + struct netisr_workstream *nwsp; + + MALLOC_PTR(nwsp); + + bzero(nwsp, sizeof(*nwsp)); + LIST_INSERT_HEAD(&list->nwsl_list, nwsp, nws_list); + list->nwsl_length += 1; + + return (nwsp); +} + +struct netisr_workstream_list * +netstat_nwsl_alloc(void) +{ + struct netisr_workstream_list *nwslp; + + MALLOC_PTR(nwslp); + + LIST_INIT(&nwslp->nwsl_list); + nwslp->nwsl_error = NETSTAT_ERROR_UNDEFINED; + nwslp->nwsl_length = 0; + + return (nwslp); +} + +void +netstat_nwsl_free(struct netisr_workstream_list *list) +{ + _netstat_nwsl_empty(list); + free(list); +} + +int +netstat_nwsl_geterror(struct netisr_workstream_list *list) +{ + return(list->nwsl_error); +} + +int +netstat_nwsl_length(struct netisr_workstream_list *list) +{ + return(list->nwsl_length); +} + +int +netstat_nwsi_alloc(struct netisr_workstream_list *list, + struct netisr_workstream_iterator **iterator) +{ + struct netisr_workstream_iterator *nwsip; + + MALLOC_ITR(nwsip); + + bzero(nwsip, sizeof(*nwsip)); + nwsip->nwsi_list = list; + nwsip->nwsi_first = LIST_FIRST(&list->nwsl_list); + if (nwsip->nwsi_first != NULL) + nwsip->nwsi_next = LIST_NEXT(nwsip->nwsi_first, nws_list); + *iterator = nwsip; + + return (0); +} + +const struct netisr_workstream * +netstat_nwsi_first(struct netisr_workstream_iterator *nwsip) +{ + if (nwsip->nwsi_first != NULL) + nwsip->nwsi_next = LIST_NEXT(nwsip->nwsi_first, nws_list); + + return (nwsip->nwsi_first); +} + +const struct netisr_workstream * +netstat_nwsi_next(struct netisr_workstream_iterator *nwsip) +{ + const struct netisr_workstream *nwsp; + + nwsp = nwsip->nwsi_next; + if (nwsip->nwsi_next != NULL) + nwsip->nwsi_next = LIST_NEXT(nwsip->nwsi_next, nws_list); + + return (nwsp); +} + +void +netstat_nwsi_free(struct netisr_workstream_iterator *nwsip) +{ + free(nwsip); +} + +uint32_t +netstat_nws_get_version(const struct netisr_workstream *nwsp) +{ + return (nwsp->nws_version); +} + +uint32_t +netstat_nws_get_flags(const struct netisr_workstream *nwsp) +{ + return (nwsp->nws_flags); +} + +uint32_t +netstat_nws_get_wsid(const struct netisr_workstream *nwsp) +{ + return (nwsp->nws_wsid); +} + +uint32_t +netstat_nws_get_cpu(const struct netisr_workstream *nwsp) +{ + return (nwsp->nws_cpu); +} + + +void +_netstat_nwl_empty(struct netisr_work_list *list) +{ + struct netisr_work *nwp; + + while ((nwp = LIST_FIRST(&list->nwl_list))) { + LIST_REMOVE(nwp, nw_list); + netstat_nwp_free(nwp); + } + + list->nwl_length = 0; +} + +void +netstat_nwp_free(struct netisr_work *nwp) +{ + free(nwp); +} + +struct netisr_work * +_netstat_nw_allocate(struct netisr_work_list *list) +{ + struct netisr_work *nwp; + + MALLOC_PTR(nwp); + + bzero(nwp, sizeof(*nwp)); + LIST_INSERT_HEAD(&list->nwl_list, nwp, nw_list); + list->nwl_length += 1; + + return (nwp); +} + +struct netisr_work_list * +netstat_nwl_alloc(void) +{ + struct netisr_work_list *nwlp; + + MALLOC_PTR(nwlp); + + LIST_INIT(&nwlp->nwl_list); + nwlp->nwl_error = NETSTAT_ERROR_UNDEFINED; + nwlp->nwl_length = 0; + + return (nwlp); +} + +void +netstat_nwl_free(struct netisr_work_list *list) +{ + _netstat_nwl_empty(list); + free(list); +} + +int +netstat_nwl_geterror(struct netisr_work_list *list) +{ + return (list->nwl_error); +} + +int +netstat_nwl_length(struct netisr_work_list *list) +{ + return (list->nwl_length); +} + +int +netstat_nwi_alloc(struct netisr_work_list *list, + struct netisr_work_iterator **iterator) +{ + struct netisr_work_iterator *nwip; + + MALLOC_ITR(nwip); + + bzero(nwip, sizeof(*nwip)); + nwip->nwi_list = list; >>> TRUNCATED FOR MAIL (1000 lines) <<<