PERFORCE change 164757 for review

Gabor Pali pgj at FreeBSD.org
Sat Jun 20 12:52:14 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=164757

Change 164757 by pgj at petymeg-current on 2009/06/20 12:51:54

	- Add preliminary support for "lazy" domain and port name resolution,
	  i.e. libnetstat should only resolve names when they are first
	  accessed -- this could save some effort when users need information
	  in numeric format only.
	- addr_type is refined according to this

Affected files ...

.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#31 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#19 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#17 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#19 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#18 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#14 edit
.. //depot/projects/soc2009/pgj_libstat/src/usr.bin/nettop/main.c#4 edit

Differences ...

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.c#31 (text+ko) ====

@@ -57,10 +57,10 @@
 static char ntop_buf[INET_ADDRSTRLEN];
 static char ntop_buf6[INET6_ADDRSTRLEN];
 
-static struct addr_type	*extract_inet_address(int type, const char *proto,
-    struct in_addr *in, u_short port, int anonport);
-static struct addr_type *extract_inet6_address(int type, const char *proto,
-    struct in6_addr *in, u_short port);
+static struct addr_type	*extract_inet_address(struct socket_type *parent,
+    int type, struct in_addr *in, u_short port, int anonport);
+static struct addr_type *extract_inet6_address(struct socket_type *parent,
+    int type, struct in6_addr *in, u_short port);
 
 static int  netstat_local_sockets(int, struct socket_type_list *, kvm_t *,
     struct nlist *, int);
@@ -608,7 +608,8 @@
 		    (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
 		    sa->sun_path);
 		stp->st_address[stp->st_addrcnt] =
-		    _netstat_at_allocate(NETSTAT_ADDRTYPE_LOCAL, address, NULL);
+		    _netstat_at_allocate(stp, NETSTAT_ADDRTYPE_LOCAL, address,
+			NULL, 0);
 		stp->st_address[stp->st_addrcnt]->at_port = 0;
 		strcpy(stp->st_address[stp->st_addrcnt]->at_portname, "*");
 		stp->st_address[stp->st_addrcnt]->at_numeric[0] = '\0';
@@ -678,55 +679,102 @@
 	/* local address */
 	if (inp->inp_vflag & INP_IPV4) {
 		stp->st_address[stp->st_addrcnt] =
-		    extract_inet_address(NETSTAT_ADDRTYPE_INET_LOCAL,
-			stp->st_name, &inp->inp_laddr, inp->inp_lport,
+		    extract_inet_address(stp, NETSTAT_ADDRTYPE_INET_LOCAL,
+			&inp->inp_laddr, inp->inp_lport,
 			inp->inp_vflag & INP_ANONPORT);
 		stp->st_addrcnt += 1;
 	}
 #ifdef INET6
 	else if (inp->inp_vflag & INP_IPV6) {
 		stp->st_address[stp->st_addrcnt] =
-		    extract_inet6_address(NETSTAT_ADDRTYPE_INET6_LOCAL,
-			stp->st_name, &inp->in6p_laddr, inp->inp_lport);
+		    extract_inet6_address(stp, NETSTAT_ADDRTYPE_INET6_LOCAL,
+			&inp->in6p_laddr, inp->inp_lport);
 		stp->st_addrcnt += 1;
 	}
 #endif
 	/* foreign address */
 	if (inp->inp_vflag & INP_IPV4) {
 		stp->st_address[stp->st_addrcnt] =
-		    extract_inet_address(NETSTAT_ADDRTYPE_INET_FOREIGN,
-			stp->st_name, &inp->inp_faddr, inp->inp_fport,
+		    extract_inet_address(stp, NETSTAT_ADDRTYPE_INET_FOREIGN,
+			&inp->inp_faddr, inp->inp_fport,
 			inp->inp_vflag & INP_ANONPORT);
 		stp->st_addrcnt += 1;
 	}
 #ifdef INET6
 	else if (inp->inp_vflag & INP_IPV6) {
 		stp->st_address[stp->st_addrcnt] =
-		    extract_inet6_address(NETSTAT_ADDRTYPE_INET6_FOREIGN,
-			stp->st_name, &inp->in6p_faddr, inp->inp_fport);
+		    extract_inet6_address(stp, NETSTAT_ADDRTYPE_INET6_FOREIGN,
+			&inp->in6p_faddr, inp->inp_fport);
 		stp->st_addrcnt += 1;
 	}
 #endif
 }
 
-/* XXX: Add support for "lazy" domain and port name resolution. */
 struct addr_type *
-extract_inet_address(int type, const char *proto, struct in_addr *in,
+extract_inet_address(struct socket_type *parent, int type, struct in_addr *in,
     u_short port, int anonport)
 {
 	struct addr_type    *result;
-	char address[256], numeric[32];
+	char numeric[32];
+
+	result = _netstat_at_allocate(parent, type, "*", (char *)in,
+		    sizeof(*in));
+	if (result == NULL)
+		return (result);
+	if (in->s_addr == INADDR_ANY) {
+		strcpy(numeric, "*");
+		result->at_flags |= ADDRTYPE_NAME_RESOLVED;
+	} else {
+		sprintf(numeric, "%s", inet_ntop(AF_INET, (void *)in, ntop_buf,
+		    sizeof(ntop_buf)));
+	}
+	strlcpy(result->at_numeric, numeric, sizeof(result->at_numeric));
+	result->at_port = ntohs(port);
+	if (anonport)
+		result->at_flags |= ADDRTYPE_ANONPORT;
+
+	return (result);
+}
+
+struct addr_type *
+extract_inet6_address(struct socket_type *parent, int type,
+    struct in6_addr *in, u_short port)
+{
+	struct addr_type    *result;
+	char numeric[32];
+
+	result = _netstat_at_allocate(parent, type, "*", (char *)in,
+		    sizeof(*in));
+	if (result == NULL)
+		return (result);
+	if (IN6_IS_ADDR_UNSPECIFIED(in)) {
+		strcpy(numeric, "*");
+		result->at_flags |= ADDRTYPE_NAME_RESOLVED;
+	} else
+		sprintf(numeric, "%s", inet_ntop(AF_INET6, (void *)in,
+		    ntop_buf6, sizeof(ntop_buf6)));
+	strlcpy(result->at_numeric, numeric, sizeof(result->at_numeric));
+	result->at_port = ntohs(port);
+
+	return (result);
+}
+
+void
+_netstat_at_resolve_name(struct addr_type *addr)
+{
 	struct hostent *hp;
 	struct netent *np;
-	struct servent *sp = NULL;
 	int net, lna;
-	char *cp;
+	struct in_addr *in;
+	struct in6_addr *in6;
+	char *cp = NULL;
+	char domain[MAXHOSTNAMELEN];
 
-	cp = NULL;
-	if (in->s_addr != INADDR_ANY) {
+	switch (addr->at_parent->st_family) {
+	case PF_INET:
+		in = (struct in_addr *)addr->at_address;
 		net = inet_netof(*in);
 		lna = inet_lnaof(*in);
-
 		if (lna == INADDR_ANY) {
 			np = getnetbyaddr(net, AF_INET);
 			if (np != NULL)
@@ -739,80 +787,51 @@
 				trimdomain(cp, strlen(cp));
 			}
 		}
+		if (cp != NULL)
+			strlcpy(addr->at_name, cp, sizeof(addr->at_name));
+		else
+			strlcpy(addr->at_name, addr->at_numeric,
+			    sizeof(addr->at_name));
+		addr->at_flags |= ADDRTYPE_NAME_RESOLVED;
+		break;
+	case PF_INET6:
+		in6 = (struct in6_addr *)addr->at_address;
+		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
+		    (cp = index(domain, '.')))
+			strcpy(domain, cp + 1);
+		else
+			domain[0] = '\0';
+		cp = NULL;
+		if (!IN6_IS_ADDR_UNSPECIFIED(in6)) {
+			hp = gethostbyaddr((char *)in6, sizeof(*in6), AF_INET6);
+			if (hp != NULL) {
+				if ((cp = index(hp->h_name, '.')) &&
+				    !strcmp(cp + 1, domain))
+					*cp = '\0';
+				cp = hp->h_name;
+			}
+		}
+		if (cp != NULL)
+			strlcpy(addr->at_name, cp, sizeof(addr->at_name));
+		else
+			strlcpy(addr->at_name, addr->at_numeric,
+			    sizeof(addr->at_name));
+		addr->at_flags |= ADDRTYPE_NAME_RESOLVED;
+		break;
 	}
-	if (in->s_addr == INADDR_ANY)
-		strcpy(numeric, "*");
-	else
-		sprintf(numeric, "%s", inet_ntop(AF_INET, (void *)in, ntop_buf,
-		    sizeof(ntop_buf)));
-	if (in->s_addr == INADDR_ANY)
-		strcpy(address, "*");
-	else if (cp)
-		strlcpy(address, cp, sizeof(address));
-	else
-		strlcpy(address, numeric, sizeof(address));
-	result = _netstat_at_allocate(type, address, NULL);
-	if (result == NULL)
-		return (result);
-	strlcpy(result->at_numeric, numeric, sizeof(result->at_numeric));
-	result->at_port = ntohs(port);
-	sp = getservbyport((int)port, proto);
-	if ((sp != NULL || port == 0) && !anonport)
-		sprintf(result->at_portname, "%.15s", sp ? sp->s_name : "*");
-	else
-		sprintf(result->at_portname, "%d", result->at_port);
-
-	return (result);
 }
 
-/* XXX: Add support for "lazy" domain and port name resolution. */
-struct addr_type *
-extract_inet6_address(int type, const char *proto, struct in6_addr *in,
-    u_short port)
+void
+_netstat_at_resolve_portname(struct addr_type *addr)
 {
-	struct addr_type    *result;
-	char address[256], numeric[32], domain[MAXHOSTNAMELEN];
-	struct hostent *hp;
 	struct servent *sp = NULL;
-	char *cp;
 
-	if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
-	    (cp = index(domain, '.')))
-		strcpy(domain, cp + 1);
+	sp = getservbyport((int)htons(addr->at_port),
+	    addr->at_parent->st_name);
+	if ((sp != NULL || addr->at_port == 0) &&
+	    ((addr->at_flags & ADDRTYPE_ANONPORT) == 0))
+		sprintf(addr->at_portname, "%.15s", sp ? sp->s_name : "*");
 	else
-	    domain[0] = '\0';
-	cp = NULL;
-	if (!IN6_IS_ADDR_UNSPECIFIED(in)) {
-		hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET6);
-		if (hp != NULL) {
-			if ((cp = index(hp->h_name, '.')) &&
-			    !strcmp(cp + 1, domain))
-				*cp = '\0';
-			cp = hp->h_name;
-		}
-	}
-	if (IN6_IS_ADDR_UNSPECIFIED(in))
-		strcpy(numeric, "*");
-	else
-		sprintf(numeric, "%s", inet_ntop(AF_INET6, (void *)in,
-		    ntop_buf6, sizeof(ntop_buf6)));
-	if (IN6_IS_ADDR_UNSPECIFIED(in))
-		strcpy(address, "*");
-	else if (cp)
-		strcpy(address, cp);
-	else
-		strlcpy(address, numeric, sizeof(address));
-		
-	result = _netstat_at_allocate(type, address, NULL);
-	if (result == NULL)
-		return (result);
-	strlcpy(result->at_numeric, numeric, sizeof(result->at_numeric));
-	result->at_port = port;
-	sp = getservbyport((int)port, proto);
-	if (sp != NULL || port == 0)
-		sprintf(result->at_portname, "%.15s", sp ? sp->s_name : "*");
-	else
-		sprintf(result->at_portname, "%d", ntohs(port));
-
-	return (result);
+		sprintf(addr->at_portname, "%d", addr->at_port);
+	addr->at_flags |= ADDRTYPE_PORT_RESOLVED;
 }

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#19 (text+ko) ====

@@ -91,12 +91,12 @@
 struct addr_type    *netstat_st_get_address(const struct socket_type *stp,
 			int index);
 
-const char	*netstat_at_get_name(const struct addr_type *atp);
+const char	*netstat_at_get_name(struct addr_type *atp);
 const char	*netstat_at_get_numeric(const struct addr_type *atp);
-void		netstat_at_get_address(const struct addr_type *atp,
-		    void *addr);
+int		netstat_at_get_address(const struct addr_type *atp,
+		    char *addr, int addr_len);
 u_short		netstat_at_get_port(const struct addr_type *atp);
-const char	*netstat_at_get_portname(const struct addr_type *atp);
+const char	*netstat_at_get_portname(struct addr_type *atp);
 __END_DECLS
 
 #endif /* !_NETSTAT_H_ */

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#17 (text+ko) ====

@@ -22,13 +22,21 @@
 	/* XXX: this should be an enum? */
 	int			    at_type;
 	char			    at_name[1024];
+	int			    at_flags;
+	struct socket_type *	    at_parent;
 	/* numeric representation */
 	char			    at_numeric[32];
-	void			    *at_address;
+	char			    *at_address;
+	int			    at_address_len;
 	u_short			    at_port;
 	char			    at_portname[32];
 };
 
+/* internal defines for addr_type: */
+#define ADDRTYPE_ANONPORT		    0x01
+#define ADDRTYPE_NAME_RESOLVED		    0x02
+#define ADDRTYPE_PORT_RESOLVED		    0x04
+
 #define NETSTAT_ADDRTYPE_LOCAL		    0
 #define NETSTAT_ADDRTYPE_INET_LOCAL	    1
 #define NETSTAT_ADDRTYPE_INET_FOREIGN	    2
@@ -104,9 +112,10 @@
 			unsigned short family, unsigned short protocol,
 			const char *name);
 void		    _netstat_st_reset_stats(struct socket_type *list);
-
-struct addr_type    *_netstat_at_allocate(int type, const char *name,
-			void *address);
+struct addr_type    *_netstat_at_allocate(struct socket_type *parent, int type,
+			const char *name, char *address, int addr_len);
+void		    _netstat_at_resolve_name(struct addr_type *addr);
+void		    _netstat_at_resolve_portname(struct addr_type *addr);
 
 int	sotoxsocket(kvm_t * kvm, struct socket *so, struct xsocket *xso);
 #endif /* !_NETSTAT_INTERNAL_H_ */

==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#19 (text+ko) ====

@@ -291,7 +291,8 @@
 
 /* Address type */
 struct addr_type *
-_netstat_at_allocate(int type, const char *name, void __unused *address)
+_netstat_at_allocate(struct socket_type *parent, int type, const char *name,
+    char *address, int addr_len)
 {
 	struct addr_type *atp;
 
@@ -301,13 +302,26 @@
 
 	bzero(atp, sizeof(*atp));
 	atp->at_type = type;
+	atp->at_parent = parent;
 	strlcpy(atp->at_name, name, 1024);
+	if (address != NULL && addr_len > 0) {
+		atp->at_address = (char *)malloc(addr_len);
+		if (atp->at_address == NULL) {
+			free(atp);
+			atp = NULL;
+		} else {
+			memcpy(atp->at_address, address, addr_len);
+			atp->at_address_len = addr_len;
+		}
+	}
 	return (atp);
 }
 
 void
 netstat_at_free(struct addr_type *atp)
 {
+	if (atp->at_address != NULL)
+		free(atp->at_address);
 	free(atp);
 }
 
@@ -485,22 +499,19 @@
 netstat_st_get_address(const struct socket_type *stp,
     int index)
 {
-	struct addr_type    *result = NULL;
-
 	if (0 <= index && index < stp->st_addrcnt) {
-		result = (struct addr_type *)malloc(sizeof(struct addr_type));
-		if (result != NULL) {
-			memcpy(result, stp->st_address[index],
-			    sizeof(struct addr_type));
-		}
+		return (stp->st_address[index]);
 	}
 
-	return (result);
+	return (NULL);
 }
 
 const char *
-netstat_at_get_name(const struct addr_type *atp)
+netstat_at_get_name(struct addr_type *atp)
 {
+	if ((atp->at_flags & ADDRTYPE_NAME_RESOLVED) == 0) {
+		_netstat_at_resolve_name(atp);
+	}
 	return (atp->at_name);
 }
 
@@ -510,10 +521,16 @@
 	return (atp->at_numeric);
 }
 
-void
-netstat_at_get_address(const struct addr_type *atp, void *addr)
+int
+netstat_at_get_address(const struct addr_type *atp, char *addr, int size)
 {
-	/* XXX: stub */
+	if ((atp->at_address != NULL) && (addr != NULL) &&
+	    (atp->at_address_len < size)) {
+		memcpy(addr, atp->at_address, atp->at_address_len);
+		return (atp->at_address_len);
+	}
+
+	return (0);
 }
 
 u_short
@@ -523,7 +540,10 @@
 }
 
 const char *
-netstat_at_get_portname(const struct addr_type *atp)
+netstat_at_get_portname(struct addr_type *atp)
 {
+	if ((atp->at_flags & ADDRTYPE_PORT_RESOLVED) == 0) {
+		_netstat_at_resolve_portname(atp);
+	}
 	return (atp->at_portname);
 }

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/inet.c#18 (text+ko) ====

@@ -95,8 +95,7 @@
 #ifdef INET6
 static int udp_done, tcp_done;
 #endif /* INET6 */
-void	addr_print(const struct addr_type *atp, const char *proto,
-	    int numeric);
+void	addr_print(struct addr_type *atp, const char *proto, int numeric);
 
 /*
  * Print a summary of connections related to an Internet
@@ -215,8 +214,6 @@
 		    numeric_port ||
 		    netstat_at_get_port(laddr) != netstat_at_get_port(faddr));
 	}
-	netstat_at_free(laddr);
-	netstat_at_free(faddr);
 	if (xflag) {
 		if (Lflag)
 			printf("%21s", " ");
@@ -924,7 +921,7 @@
 }
 
 void
-addr_print(const struct addr_type *atp, const char *proto, int numeric)
+addr_print(struct addr_type *atp, const char *proto, int numeric)
 {
 	int width;
 	char line[80], *cp;

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/unix.c#14 (text+ko) ====

@@ -143,7 +143,6 @@
 	if (netstat_st_get_addrcnt(stp) > 0) {
 		addr = netstat_st_get_address(stp, 0);
 		printf(" %s", netstat_at_get_name(addr));
-		netstat_at_free(addr);
 	}
 	putchar('\n');
 }

==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/nettop/main.c#4 (text+ko) ====

@@ -84,7 +84,6 @@
 		if (netstat_st_get_addrcnt(stp) > 0) {
 			atp = netstat_st_get_address(stp, 0);
 			printw(" %s", netstat_at_get_name(atp));
-			netstat_at_free(atp);
 		}
 		netstat_st_free(stp);
 	}
@@ -110,8 +109,6 @@
 		    netstat_at_get_name(faddr),
 		    netstat_at_get_portname(faddr),
 		    netstat_st_get_tcpstate(stp));
-		netstat_at_free(laddr);
-		netstat_at_free(faddr);
 		netstat_st_free(stp);
 	}
 	netstat_sti_free(stip);


More information about the p4-projects mailing list