PERFORCE change 166340 for review
Gabor Pali
pgj at FreeBSD.org
Tue Jul 21 01:02:09 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166340
Change 166340 by pgj at petymeg-current on 2009/07/21 01:01:29
Some netstat_interface() improvements:
- Eliminate the need for extract_if_maddress()
- Add support for PF_INET, PF_INET6
- Fix the problem of sockaddr types of different sizes
- Fix & improve address resolution
- Add further accessor functions
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#31 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#3 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#28 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#34 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#31 (text+ko) ====
@@ -245,9 +245,14 @@
u_int64_t netstat_ft_get_errors(const struct face_type *);
int netstat_iat_get_family(const struct intfaddr_type *);
-const char *netstat_iat_get_name(const struct intfaddr_type *);
-const char *netstat_iat_get_subnet(const struct intfaddr_type *);
+const char *netstat_iat_get_address(const struct intfaddr_type *, int numeric);
+const char *netstat_iat_get_network(const struct intfaddr_type *, int numeric);
enum intfaddr_layer netstat_iat_get_layer(const struct intfaddr_type *);
+u_int64_t netstat_iat_get_ipackets(const struct intfaddr_type *);
+u_int64_t netstat_iat_get_ibytes(const struct intfaddr_type *);
+u_int64_t netstat_iat_get_opackets(const struct intfaddr_type *);
+u_int64_t netstat_iat_get_obytes(const struct intfaddr_type *);
+u_int32_t netstat_iat_get_refcount(const struct intfaddr_type *);
/* Interface addresses: */
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_if.c#3 (text+ko) ====
@@ -37,6 +37,7 @@
#include <netinet/in_var.h>
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
+#include <arpa/inet.h>
#include <err.h>
#include <stdint.h>
@@ -56,9 +57,8 @@
static const char *const if_symbol[] = { "_ifnet" };
static void extract_if_data(struct ifnet *ifp, struct interface_type *itp);
-static void extract_if_address(struct ifaddr *ifa, struct interface_type *itp);
-static void extract_if_maddress(struct ifmultiaddr *ifma,
- struct interface_type *itp);
+static struct intfaddr_type *extract_if_address(int type, void *ifaddr,
+ void *saddr, struct interface_type *itp);
#define KREAD(off, dst) do { \
if ((list->itl_error = (kread_data(kvm, (uintptr_t)(off), &(dst), \
@@ -78,7 +78,14 @@
struct ifnethead ifnethead;
struct ifnet ifnet;
- struct ifaddr ifaddr;
+ union {
+ struct ifaddr ifa;
+ struct in_ifaddr in;
+#ifdef INET6
+ struct in6_ifaddr in6;
+#endif
+ struct ipx_ifaddr ipx;
+ } ifaddr;
union {
struct sockaddr sa;
struct sockaddr_dl dl;
@@ -126,15 +133,19 @@
/* Interface addresses. */
for (ifa_addr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead);
ifa_addr != 0;
- ifa_addr = (u_long)TAILQ_NEXT(&ifaddr, ifa_link)) {
+ ifa_addr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link)) {
KREAD(ifa_addr, ifaddr);
- KREAD(ifaddr.ifa_addr, sa);
- ifaddr.ifa_addr = &sa.sa;
+ KREAD(ifaddr.ifa.ifa_addr, sa);
+ ifaddr.ifa.ifa_addr = &sa.sa;
/* List addresses with the given protocol. */
if (domain != PF_UNSPEC &&
- domain != ifaddr.ifa_addr->sa_family)
+ domain != ifaddr.ifa.ifa_addr->sa_family)
continue;
- extract_if_address(&ifaddr, itp);
+ if (itp->it_addrcnt >= IFTYPE_MAXADDRCNT)
+ continue;
+ itp->it_address[itp->it_addrcnt++] =
+ extract_if_address(NETSTAT_IF_IFADDR,
+ &ifaddr.ifa, ifaddr.ifa.ifa_addr, itp);
}
/* Multicast addresses. */
@@ -147,7 +158,11 @@
if (domain != PF_UNSPEC &&
domain != ifmultiaddr.ifma_addr->sa_family)
continue;
- extract_if_maddress(&ifmultiaddr, itp);
+ if (itp->it_maddrcnt >= IFTYPE_MAXADDRCNT)
+ continue;
+ itp->it_maddress[itp->it_maddrcnt++] =
+ extract_if_address(NETSTAT_IF_IFMULTIADDR,
+ &ifmultiaddr, ifmultiaddr.ifma_addr, itp);
}
}
} else {
@@ -184,11 +199,15 @@
itp->it_flags |= NETSTAT_IF_UP;
}
-void
-extract_if_address(struct ifaddr *ifa, struct interface_type *itp)
+struct intfaddr_type *
+extract_if_address(int type, void *ifaddr, void *saddr,
+ struct interface_type *itp)
{
struct sockaddr *sa;
struct sockaddr_in *sa_in;
+#ifdef INET6
+ struct sockaddr_in6 *sa_in6;
+#endif
struct sockaddr_dl *sa_dl;
struct in_ifaddr *in;
#ifdef INET6
@@ -196,34 +215,94 @@
#endif
struct ipx_ifaddr *ipx;
+ struct ifmultiaddr *ifma;
struct intfaddr_type *ifap;
char *cp, *p;
int n;
- sa = (struct sockaddr *)ifa->ifa_addr;
+ sa = (struct sockaddr *)saddr;
sa_in = (struct sockaddr_in *)sa;
+ sa_in6 = (struct sockaddr_in6 *)sa;
sa_dl = (struct sockaddr_dl *)sa;
- in = (struct in_ifaddr *)sa;
- in6 = (struct in6_ifaddr *)sa;
- ipx = (struct ipx_ifaddr *)sa;
- /* Cannot store more addresses. */
- if (itp->it_addrcnt == IFTYPE_MAXADDRCNT)
- return;
+ in = (struct in_ifaddr *)ifaddr;
+ in6 = (struct in6_ifaddr *)in;
+ ipx = (struct ipx_ifaddr *)in;
+ ifma = (struct ifmultiaddr *)ifaddr;
- ifap = itp->it_address[itp->it_addrcnt] =
- _netstat_iat_allocate(sa->sa_family, NETSTAT_IF_IFADDR);
+ ifap = _netstat_iat_allocate(sa->sa_family, type);
if (ifap == NULL)
- return;
+ return (NULL);
switch (sa->sa_family) {
case PF_UNSPEC:
+ ifap->iat_address = strdup("none");
+ 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));
+ ifap->iat_network = strdup(netname(htonl(in->ia_subnet),
+ in->ia_subnetmask, 0));
+ inet_ntop(PF_INET, &sa_in->sin_addr, ifap->iat_ni_address,
+ sizeof(ifap->iat_ni_address));
+ ifap->iat_address = strdup(routename(sa_in->sin_addr.s_addr, 0));
+ ifap->iat_layer = layer_Network;
+ switch (type) {
+ case NETSTAT_IF_IFADDR:
+ ifap->iat_refcount = in->ia_ifa.ifa_refcnt;
+ break;
+ case NETSTAT_IF_IFMULTIADDR:
+ ifap->iat_refcount = ifma->ifma_refcount;
+ break;
+ }
+ ifap->iat_opackets = in->ia_ifa.if_opackets;
+ ifap->iat_ipackets = in->ia_ifa.if_ipackets;
+ ifap->iat_obytes = in->ia_ifa.if_obytes;
+ ifap->iat_ibytes = in->ia_ifa.if_ibytes;
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));
+ ifap->iat_network =
+ strdup(netname6(&in6->ia_addr,
+ &in6->ia_prefixmask.sin6_addr, 0));
+ inet_ntop(PF_INET6, &sa_in6->sin6_addr, ifap->iat_ni_address,
+ sizeof(ifap->iat_ni_address));
+ ifap->iat_address = strdup(routename6(sa_in6, 0));
+ ifap->iat_layer = layer_Network;
+ switch (type) {
+ case NETSTAT_IF_IFADDR:
+ ifap->iat_refcount = in->ia_ifa.ifa_refcnt;
+ break;
+ case NETSTAT_IF_IFMULTIADDR:
+ ifap->iat_refcount = ifma->ifma_refcount;
+ break;
+ }
+ ifap->iat_opackets = in6->ia_ifa.if_opackets;
+ ifap->iat_ipackets = in6->ia_ifa.if_ipackets;
+ ifap->iat_obytes = in6->ia_ifa.if_obytes;
+ ifap->iat_ibytes = in6->ia_ifa.if_ibytes;
break;
#endif /* INET6 */
case PF_IPX:
@@ -231,74 +310,26 @@
case PF_APPLETALK:
break;
case PF_LINK:
- ifap->iat_address_len = sizeof(struct sockaddr_dl);
- ifap->iat_address = malloc(ifap->iat_address_len);
- if (ifap->iat_address != NULL)
- memcpy(ifap->iat_address, sa_dl, ifap->iat_address_len);
- ifap->iat_network = NULL;
- sprintf(ifap->iat_subnet, "<Link#%d>", sa_dl->sdl_index);
+ 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);
n = sa_dl->sdl_alen;
- p = ifap->iat_name;
+ 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;
}
- itp->it_addrcnt += 1;
-}
-
-void
-extract_if_maddress(struct ifmultiaddr *ifma, struct interface_type *itp)
-{
- struct sockaddr *sa;
- struct sockaddr_dl *sa_dl;
- struct intfaddr_type *ifap;
-
- char *cp, *p;
- int n;
-
- sa = ifma->ifma_addr;
- sa_dl = (struct sockaddr_dl *)sa;
-
- /* Cannot store more addresses. */
- if (itp->it_maddrcnt == IFTYPE_MAXADDRCNT)
- return;
-
- ifap = itp->it_maddress[itp->it_maddrcnt] =
- _netstat_iat_allocate(sa->sa_family, NETSTAT_IF_IFMULTIADDR);
- if (ifap == NULL)
- return;
-
- switch (sa->sa_family) {
- case PF_INET:
- break;
-#ifdef INET6
- case PF_INET6:
- break;
-#endif /* INET6 */
- case PF_LINK:
- ifap->iat_address_len = sizeof(struct sockaddr_dl);
- ifap->iat_address = malloc(ifap->iat_address_len);
- if (ifap->iat_address != NULL)
- memcpy(ifap->iat_address, sa_dl, ifap->iat_address_len);
- ifap->iat_network = NULL;
- sprintf(ifap->iat_subnet, "<Link#%d>", sa_dl->sdl_index);
- cp = (char *)LLADDR(sa_dl);
- n = sa_dl->sdl_alen;
- p = ifap->iat_name;
- while (--n >= 0) {
- sprintf(p, "%02x%s", *cp++ & 0xff, n > 0 ? ":" : "");
- p += 3;
- }
- ifap->iat_layer = layer_Link;
- break;
- }
-
- itp->it_maddrcnt += 1;
+ return (ifap);
}
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#28 (text+ko) ====
@@ -186,13 +186,15 @@
int iat_family; /* protocol family */
enum intfaddr_layer iat_layer;
int iat_type; /* ifa, ifma */
- char iat_name[20];
- char iat_subnet[16];
- void *iat_address; /* raw address */
- void *iat_network; /* raw network */
- int iat_address_len;
- u_int64_t iat_network_mask;
- u_int32_t iat_refcount; /* ifma */
+ char *iat_address;
+ 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;
+ u_int32_t iat_refcount;
/* for network-layer addresses: */
u_int64_t iat_opackets;
u_int64_t iat_ipackets;
@@ -261,8 +263,8 @@
/* XXX: merge these into a common address resolution routine. */
-const char *routename(in_addr_t *in, int numeric);
-const char *netname(in_addr_t *in, u_long mask, int numeric);
+const char *routename(in_addr_t in, int numeric);
+const char *netname(in_addr_t in, u_long mask, int numeric);
#ifdef INET6
const char *routename6(struct sockaddr_in6 *in6, int numeric);
const char *netname6(struct sockaddr_in6 *in6, struct in6_addr *mask,
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#34 (text+ko) ====
@@ -863,6 +863,8 @@
{
free(iatp->iat_address);
free(iatp->iat_network);
+ free(iatp->iat_sockaddr);
+ free(iatp->iat_ifaddr);
free(iatp);
}
@@ -973,15 +975,19 @@
}
const char *
-netstat_iat_get_name(const struct intfaddr_type *iatp)
+netstat_iat_get_address(const struct intfaddr_type *iatp, int numeric)
{
- return (iatp->iat_name);
+ if (numeric)
+ return (iatp->iat_ni_address);
+ return (iatp->iat_address);
}
const char *
-netstat_iat_get_subnet(const struct intfaddr_type *iatp)
+netstat_iat_get_network(const struct intfaddr_type *iatp, int numeric)
{
- return (iatp->iat_subnet);
+ if (numeric)
+ return (iatp->iat_ni_network);
+ return (iatp->iat_network);
}
enum intfaddr_layer
@@ -990,17 +996,46 @@
return (iatp->iat_layer);
}
+u_int64_t
+netstat_iat_get_ipackets(const struct intfaddr_type *iatp)
+{
+ return (iatp->iat_ipackets);
+}
+
+u_int64_t
+netstat_iat_get_ibytes(const struct intfaddr_type *iatp)
+{
+ return (iatp->iat_ibytes);
+}
+
+u_int64_t
+netstat_iat_get_opackets(const struct intfaddr_type *iatp)
+{
+ return (iatp->iat_opackets);
+}
+
+u_int64_t
+netstat_iat_get_obytes(const struct intfaddr_type *iatp)
+{
+ return (iatp->iat_obytes);
+}
+
+u_int32_t
+netstat_iat_get_refcount(const struct intfaddr_type *iatp)
+{
+ return (iatp->iat_refcount);
+}
+
const char *
-routename(in_addr_t *in, int numeric)
+routename(in_addr_t in, int numeric)
{
char *cp;
static char line[MAXHOSTNAMELEN];
struct hostent *hp;
- in_addr_t tin;
cp = NULL;
if (!numeric) {
- hp = gethostbyaddr(in, sizeof(struct in_addr), PF_INET);
+ hp = gethostbyaddr(&in, sizeof(struct in_addr), PF_INET);
if (hp != NULL) {
cp = hp->h_name;
trimdomain(cp, strlen(cp));
@@ -1010,9 +1045,9 @@
strlcpy(line, cp, sizeof(line));
} else {
#define C(x) ((x) & 0xff)
- tin = ntohl(*in);
+ in = ntohl(in);
sprintf(line, "%u.%u.%u.%u",
- C(tin >> 24), C(tin >> 16), C(tin >> 8), C(tin));
+ C(in >> 24), C(in >> 16), C(in >> 8), C(in));
}
return (line);
}
@@ -1039,8 +1074,9 @@
i = b;
for (bb = b + 1; bb < 32; bb++)
- if (!(mask & (1 << b))) {
+ if (!(mask & (1 << bb))) {
i = -1; /* noncontig */
+ break;
}
break;
}
@@ -1051,15 +1087,15 @@
}
const char *
-netname(in_addr_t *in, u_long mask, int numeric)
+netname(in_addr_t in, u_long mask, int numeric)
{
char *cp = NULL;
static char line[MAXHOSTNAMELEN];
struct netent *np = NULL;
in_addr_t i;
- i = ntohl(*in);
- if (!numeric && i != 0) {
+ i = ntohl(in);
+ if (!numeric && i) {
np = getnetbyaddr(i >> NSHIFT(mask), PF_INET);
if (np != NULL) {
cp = np->n_name;
More information about the p4-projects
mailing list