Date: Mon, 10 Aug 2009 14:46:29 GMT From: Gabor Pali <pgj@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167176 for review Message-ID: <200908101446.n7AEkTPA041592@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167176 Change 167176 by pgj@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",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908101446.n7AEkTPA041592>