Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Aug 2010 18:25:46 GMT
From:      Aman Jassal <aman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 182768 for review
Message-ID:  <201008221825.o7MIPkDr075231@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/types.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <sys/sysctl.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
+#include <net/if_mib.h>
 #include <net/if_var.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -40,6 +42,7 @@
 #include <arpa/inet.h>
 
 #include <err.h>
+#include <errno.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -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, "<Link#%d>", 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, "<Link#%d>", 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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008221825.o7MIPkDr075231>