Date: Sat, 20 Jun 2009 12:52:12 GMT From: Gabor Pali <pgj@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 164757 for review Message-ID: <200906201252.n5KCqCWc006533@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=164757 Change 164757 by pgj@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906201252.n5KCqCWc006533>