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