PERFORCE change 167176 for review
Gabor Pali
pgj at FreeBSD.org
Mon Aug 10 14:46:30 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167176
Change 167176 by pgj at petymeg-current on 2009/08/10 14:45:40
- Add extract_address() for extracting destination and gateway
address information in routing table entries. Implement support
for PF_INET and PF_LINK families.
- Add functions for accessing routing addresses.
- Respect the "domain" argument in netstat_route().
Affected files ...
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#61 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#57 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_route.c#2 edit
.. //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#66 edit
Differences ...
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat.h#61 (text+ko) ====
@@ -1235,4 +1235,9 @@
u_int64_t netstat_rt_get_expire(const struct route_type *);
u_int32_t netstat_rt_get_mtu(const struct route_type *);
u_int64_t netstat_rt_get_address(const struct route_type *);
+
+/* Routing addresses: */
+const char *netstat_rat_get_name(const struct routeaddr_type *, int);
+size_t netstat_rat_get_address(const struct routeaddr_type *, void *, size_t);
+int netstat_rat_get_family(const struct routeaddr_type *);
#endif /* !_NETSTAT_H_ */
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_internal.h#57 (text+ko) ====
@@ -441,12 +441,13 @@
/* Route type. */
struct routeaddr_type {
+ int rat_family; /* protocol family */
/* for printing purposes: */
char *rat_address; /* resolved hostname */
char rat_ni_address[20]; /* numeric */
/* for other: */
void *rat_data; /* raw socket information */
- int rat_data_len;
+ size_t rat_data_len;
};
struct route_type {
@@ -507,7 +508,7 @@
void _netstat_rt_free(struct route_type *);
void _netstat_rat_free(struct routeaddr_type *);
struct route_type *_netstat_rt_allocate(struct route_type_list *);
-struct routeaddr_type *_netstat_rat_allocate(void *, size_t);
+struct routeaddr_type *_netstat_rat_allocate(int, void *, size_t);
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_route.c#2 (text+ko) ====
@@ -31,7 +31,10 @@
#include <sys/socket.h>
#include <net/if.h>
+#include <net/if_dl.h>
#include <net/if_var.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <err.h>
#include <kvm.h>
@@ -57,6 +60,8 @@
static int route_tree_sysctl(struct route_type_list *, int, int, int);
static void process_tree(kvm_t *, struct route_type_list *, struct radix_node *);
static void extract_rtentry_data(struct rtentry *, struct route_type *);
+static struct routeaddr_type *extract_address(struct sockaddr*,
+ struct sockaddr*, int);
int
netstat_route(const struct session_type *session, int fib, int domain,
@@ -129,19 +134,24 @@
goto out;
}
- for (i = 0; i <= PF_MAX; i++) {
- if (i != PF_INET)
- tmpfib = 0;
- else
- tmpfib = fibnum;
+ if (domain == PF_UNSPEC)
+ for (i = 0; i <= PF_MAX; i++) {
+ tmpfib = (i != PF_INET) ? 0 : fibnum;
+ rnh = rt_tables[tmpfib].tables[i];
- rnh = rt_tables[tmpfib].tables[i];
+ if (rnh == NULL)
+ continue;
- if (rnh == NULL)
- continue;
-
- KREAD(rnh, head);
- process_tree(kvm, list, head.rnh_treetop);
+ KREAD(rnh, head);
+ process_tree(kvm, list, head.rnh_treetop);
+ }
+ else {
+ tmpfib = (domain != PF_INET) ? 0 : fibnum;
+ rnh = rt_tables[tmpfib].tables[domain];
+ if (rnh != NULL) {
+ KREAD(rnh, head);
+ process_tree(kvm, list, head.rnh_treetop);
+ }
}
result = 0;
@@ -164,7 +174,7 @@
struct radix_node *rnode;
struct ifnet iface;
struct route_type *rtp;
- struct sockaddr sa, sagw;
+ struct sockaddr sa, mk, sagw;
again:
if (rn == NULL)
@@ -191,6 +201,11 @@
rtentry.rt_nodes->rn_key = (caddr_t)&sa;
}
+ if (rnode->rn_mask != NULL) {
+ KREAD(rnode->rn_mask, mk);
+ rtentry.rt_nodes->rn_mask = (caddr_t)&mk;
+ }
+
if (rtentry.rt_gateway != NULL) {
KREAD(rtentry.rt_gateway, sagw);
rtentry.rt_gateway = &sagw;
@@ -248,7 +263,7 @@
{
time_t expire_time;
struct timespec uptime;
- struct sockaddr *sa;
+ struct sockaddr *sa, *mask;
CNV_FLAG(RTF_UP, NETSTAT_RT_UP);
CNV_FLAG(RTF_GATEWAY, NETSTAT_RT_GATEWAY);
@@ -267,10 +282,10 @@
CNV_FLAG(RTF_BROADCAST, NETSTAT_RT_BROADCAST);
rtp->rt_fib = rte->rt_fibnum;
sa = (struct sockaddr *)rte->rt_nodes->rn_key;
+ mask = (struct sockaddr *)rte->rt_nodes->rn_mask;
rtp->rt_family = sa->sa_family;
- rtp->rt_destination = _netstat_rat_allocate(sa, sizeof(struct sockaddr));
- rtp->rt_gateway = _netstat_rat_allocate(rte->rt_gateway,
- sizeof(struct sockaddr));
+ rtp->rt_destination = extract_address(sa, mask, rte->rt_flags);
+ rtp->rt_gateway = extract_address(rte->rt_gateway, NULL, RTF_HOST);
rtp->rt_refs = rte->rt_refcnt;
rtp->rt_used = rte->rt_use;
if (rte->rt_ifp != NULL) {
@@ -291,3 +306,110 @@
rtp->rt_address = (int)rte;
}
#undef CNV_FLAG
+
+struct routeaddr_type *
+extract_address(struct sockaddr *sa, struct sockaddr *mask, int flags)
+{
+ struct routeaddr_type *rap;
+ struct sockaddr_in *sa_in, *mk_in;
+#ifdef INET6
+ struct sockaddr_in6 *sa_in6, *mk_in6;
+#endif
+ struct sockaddr_dl *sa_dl;
+ char *cp, *p;
+ int n;
+
+ sa_in = (struct sockaddr_in *)sa;
+ mk_in = (struct sockaddr_in *)mask;
+#ifdef INET6
+ sa_in6 = (struct sockaddr_in6 *)sa;
+ mk_in6 = (struct sockaddr_in6 *)mask;
+#endif
+ sa_dl = (struct sockaddr_dl *)sa;
+
+ rap = _netstat_rat_allocate(sa->sa_family, sa, sizeof(struct sockaddr));
+ if (rap == NULL)
+ return (NULL);
+
+ switch (sa->sa_family) {
+ case PF_UNSPEC:
+ rap->rat_address = strdup("none");
+ strlcpy(rap->rat_ni_address, "none",
+ sizeof(rap->rat_ni_address));
+ rap->rat_data = malloc(sizeof(struct sockaddr));
+ if (rap->rat_data != NULL) {
+ rap->rat_data_len = sizeof(struct sockaddr);
+ memcpy(rap->rat_data, sa, rap->rat_data_len);
+ }
+ break;
+ case PF_INET:
+ if ((sa_in->sin_addr.s_addr == INADDR_ANY) &&
+ (mask != NULL) &&
+ (ntohl(mk_in->sin_addr.s_addr) == 0L)) {
+ rap->rat_address = strdup("default");
+ strlcpy(rap->rat_ni_address, "default",
+ sizeof(rap->rat_ni_address));
+ } else if (flags & RTF_HOST) {
+ inet_ntop(PF_INET, &sa_in->sin_addr,
+ rap->rat_ni_address, sizeof(rap->rat_ni_address));
+ rap->rat_address =
+ strdup(routename(sa_in->sin_addr.s_addr, 0));
+ } else if (mask != NULL) {
+ strlcpy(rap->rat_ni_address,
+ netname(sa_in->sin_addr.s_addr,
+ ntohl(mk_in->sin_addr.s_addr), 1),
+ sizeof(rap->rat_ni_address));
+ rap->rat_address =
+ strdup(netname(sa_in->sin_addr.s_addr,
+ ntohl(mk_in->sin_addr.s_addr), 0));
+ } else {
+ rap->rat_address =
+ strdup(netname(sa_in->sin_addr.s_addr,
+ 0L, 0));
+ strlcpy(rap->rat_ni_address, rap->rat_address,
+ sizeof(rap->rat_ni_address));
+ }
+ rap->rat_data = malloc(sizeof(struct sockaddr_in));
+ if (rap->rat_data != NULL) {
+ rap->rat_data_len = sizeof(struct sockaddr_in);
+ memcpy(rap->rat_data, sa_in, rap->rat_data_len);
+ }
+ break;
+#ifdef INET6
+ case PF_INET6:
+ break;
+#endif
+ case PF_IPX:
+ break;
+ case PF_APPLETALK:
+ break;
+ case PF_NETGRAPH:
+ break;
+ case PF_LINK:
+ if (sa_dl->sdl_nlen == 0 && sa_dl->sdl_alen == 0 &&
+ sa_dl->sdl_slen == 0) {
+ sprintf(rap->rat_ni_address, "<Link#%d>",
+ sa_dl->sdl_index);
+ } else {
+ cp = (char *)LLADDR(sa_dl);
+ n = sa_dl->sdl_alen;
+ p = rap->rat_address;
+ while (--n >= 0) {
+ sprintf(p, "%02x%s", *cp++ & 0xff,
+ n > 0 ? ":" : "");
+ p += 3;
+ }
+ }
+ rap->rat_address = strdup(rap->rat_ni_address);
+ rap->rat_data = malloc(sizeof(struct sockaddr_dl));
+ if (rap->rat_data != NULL) {
+ rap->rat_data_len = sizeof(struct sockaddr_dl);
+ memcpy(rap->rat_data, sa_dl, rap->rat_data_len);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return (rap);
+}
==== //depot/projects/soc2009/pgj_libstat/src/lib/libnetstat/netstat_util.c#66 (text+ko) ====
@@ -2279,7 +2279,7 @@
}
struct routeaddr_type *
-_netstat_rat_allocate(void *address, size_t len)
+_netstat_rat_allocate(int family, void *address, size_t len)
{
struct routeaddr_type *ratp;
@@ -2298,6 +2298,7 @@
ratp->rat_data_len = len;
}
}
+ ratp->rat_family = family;
return (ratp);
}
@@ -2446,6 +2447,34 @@
return (rtp->rt_address);
}
+const char *
+netstat_rat_get_name(const struct routeaddr_type *ratp, int numeric)
+{
+ if (numeric)
+ return (ratp->rat_ni_address);
+ return (ratp->rat_address);
+}
+
+size_t
+netstat_rat_get_address(const struct routeaddr_type *ratp, void *addr,
+ size_t size)
+{
+ if ((ratp->rat_data != NULL) && (addr != NULL) &&
+ (ratp->rat_data_len <= size)) {
+ memcpy(addr, ratp->rat_data, ratp->rat_data_len);
+ return (ratp->rat_data_len);
+ }
+
+ return (0);
+}
+
+int
+netstat_rat_get_family(const struct routeaddr_type *ratp)
+{
+ return (ratp->rat_family);
+}
+
+
static const char *icmpnames[ICMP_MAXTYPE + 1] = {
"echo reply", /* RFC 792 */
"#1",
More information about the p4-projects
mailing list