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