Date: Tue, 11 Aug 2009 23:36:21 GMT From: Gabor Pali <pgj@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 167229 for review Message-ID: <200908112336.n7BNaL5o080861@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167229 Change 167229 by pgj@petymeg-current on 2009/08/11 23:36:15 Modify netstat(1) to call libnetstat(3) instead of its original routines. Remove all moved code components as well. Affected files ... .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#36 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#46 edit .. //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/route.c#4 edit Differences ... ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/extern.h#36 (text+ko) ==== @@ -132,7 +132,7 @@ char *atalk_print2(struct sockaddr *, struct sockaddr *, int); char *ipx_print(struct sockaddr *); char *ns_print(struct sockaddr *); -void routepr(u_long); +void routepr(const struct session_type *, int); void ipxprotopr(u_long, const char *, int, int); void spx_stats(const struct stat_type *); ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/main.c#46 (text+ko) ==== @@ -77,23 +77,21 @@ static struct nlist nl[] = { -#define N_RTREE 0 - { .n_name = "_rt_tables"}, -#define N_MFCHASHTBL 1 +#define N_MFCHASHTBL 0 { .n_name = "_mfchashtbl" }, -#define N_VIFTABLE 2 +#define N_VIFTABLE 1 { .n_name = "_viftable" }, -#define N_IPX 3 +#define N_IPX 2 { .n_name = "_ipxpcb_list"}, -#define N_DDPCB 4 +#define N_DDPCB 3 { .n_name = "_ddpcb"}, -#define N_NGSOCKS 5 +#define N_NGSOCKS 4 { .n_name = "_ngsocklist"}, -#define N_MF6CTABLE 6 +#define N_MF6CTABLE 5 { .n_name = "_mf6ctable" }, -#define N_MIF6TABLE 7 +#define N_MIF6TABLE 6 { .n_name = "_mif6table" }, -#define N_MFCTABLESIZE 8 +#define N_MFCTABLESIZE 7 { .n_name = "_mfctablesize" }, { .n_name = NULL }, }; @@ -230,7 +228,7 @@ static struct protox *name2protox(const char *); static struct protox *knownname(const char *); -static kvm_t *kvmd; +/*static*/ kvm_t *kvmd; static char *nlistf = NULL, *memf = NULL; int Aflag; /* show addresses of protocol control block */ @@ -470,7 +468,9 @@ } else { kread(0, NULL, 0); - routepr(nl[N_RTREE].n_value); + session = netstat_session_new(kvmd); + routepr(session, af); + netstat_session_free(session); } exit(0); } ==== //depot/projects/soc2009/pgj_libstat/src/usr.bin/netstat/route.c#4 (text+ko) ==== @@ -1,6 +1,8 @@ /*- * Copyright (c) 1983, 1988, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * Copyright (c) 2009 Gabor Pali + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,41 +42,17 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD: src/usr.bin/netstat/route.c,v 1.93 2008/12/15 06:10:57 qingli Exp $"); -#include <sys/param.h> -#include <sys/protosw.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/time.h> - -#include <net/ethernet.h> -#include <net/if.h> -#include <net/if_var.h> -#include <net/if_dl.h> -#include <net/if_types.h> -#include <net/radix.h> -#include <net/route.h> - +#include <sys/types.h> +#include <netipx/ipx.h> #include <netinet/in.h> -#include <netipx/ipx.h> -#include <netatalk/at.h> -#include <netgraph/ng_socket.h> -#include <sys/sysctl.h> - -#include <arpa/inet.h> -#include <libutil.h> +#include <err.h> #include <netdb.h> -#include <stdint.h> +#include <string.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> -#include <err.h> +#include <netstat.h> #include "extern.h" -#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) - /* * Definitions for showing gateway flags. */ @@ -82,179 +60,137 @@ u_long b_mask; char b_val; } bits[] = { - { RTF_UP, 'U' }, - { RTF_GATEWAY, 'G' }, - { RTF_HOST, 'H' }, - { RTF_REJECT, 'R' }, - { RTF_DYNAMIC, 'D' }, - { RTF_MODIFIED, 'M' }, - { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ - { RTF_XRESOLVE, 'X' }, - { RTF_STATIC, 'S' }, - { RTF_PROTO1, '1' }, - { RTF_PROTO2, '2' }, - { RTF_PRCLONING,'c' }, - { RTF_PROTO3, '3' }, - { RTF_BLACKHOLE,'B' }, - { RTF_BROADCAST,'b' }, + { NETSTAT_RT_UP, 'U' }, + { NETSTAT_RT_GATEWAY, 'G' }, + { NETSTAT_RT_HOST, 'H' }, + { NETSTAT_RT_REJECT, 'R' }, + { NETSTAT_RT_DYNAMIC, 'D' }, + { NETSTAT_RT_MODIFIED, 'M' }, + { NETSTAT_RT_DONE, 'd' }, + { NETSTAT_RT_XRESOLVE, 'X' }, + { NETSTAT_RT_STATIC, 'S' }, + { NETSTAT_RT_PROTO1, '1' }, + { NETSTAT_RT_PROTO2, '2' }, + { NETSTAT_RT_PRCLONING, 'c' }, + { NETSTAT_RT_PROTO3, '3' }, + { NETSTAT_RT_BLACKHOLE, 'B' }, + { NETSTAT_RT_BROADCAST, 'b' }, #ifdef RTF_LLINFO - { RTF_LLINFO, 'L' }, + { NETSTAT_RT_LLINFO, 'L' }, #endif #ifdef RTF_WASCLONED - { RTF_WASCLONED,'W' }, + { NETSTAT_RT_WASCLONED, 'W' }, #endif #ifdef RTF_CLONING - { RTF_CLONING, 'C' }, + { NETSTAT_RT_CLONING, 'C' }, #endif { 0 , 0 } -}; -typedef union { - long dummy; /* Helps align structure. */ - struct sockaddr u_sa; - u_short u_data[128]; -} sa_u; - -static sa_u pt_u; - -int fibnum; -int do_rtent = 0; -struct rtentry rtentry; -struct radix_node rnode; -struct radix_mask rmask; -struct rtline { - struct radix_node_head *tables[AF_MAX+1]; /*xxx*/ }; -struct rtline *rt_tables; +static void size_cols(int ef, struct route_type_iterator *); +static const char *fmt_flags(int f); +static void p_rtnode(const struct routenode_type *); -struct radix_node_head *rt_tables_line[1][AF_MAX+1]; /*xxx*/ - -int NewTree = 0; - -struct timespec uptime; +static int wid_dst; +static int wid_gw; +static int wid_flags; +static int wid_refs; +static int wid_use; +static int wid_mtu; +static int wid_if; +static int wid_expire; -static struct sockaddr *kgetsa(struct sockaddr *); -static void size_cols(int ef, struct radix_node *rn); -static void size_cols_tree(struct radix_node *rn); -static void size_cols_rtentry(struct rtentry *rt); -static void p_tree(struct radix_node *); -static void p_rtnode(void); -static void ntreestuff(void); -static void np_rtentry(struct rt_msghdr *); -static void p_sockaddr(struct sockaddr *, struct sockaddr *, int, int); -static const char *fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, - int flags); -static void p_flags(int, const char *); -static const char *fmt_flags(int f); -static void p_rtentry(struct rtentry *); -static void domask(char *, in_addr_t, u_long); - /* * Print routing tables. */ void -routepr(u_long rtree) +routepr(const struct session_type *session, int domain) { - struct radix_node_head *rnh, head; - size_t intsize; - int i; - int numfibs; + struct route_type_list *rtlp; + struct route_type_iterator *rtip; + + const struct route_type *rtp; + const struct routeaddr_type *dst, *gw; + const struct routenode_type *rntp; + int error, last_domain, dom, flags; + int rt_flags; + + rtlp = netstat_rtl_alloc(); + if (rtlp == NULL) { + warn("netstat_rtl_alloc()"); + return; + } + + rt_flags = 0; + if (Aflag) + rt_flags |= NETSTAT_ROUTE_ALL; + if (netstat_route(session, 0, domain, rtlp, rt_flags)) { + error = netstat_rtl_geterror(rtlp); + if (error == NETSTAT_ERROR_KVM) + warnx("netstat_route: %s", netstat_kvmerror(session)); + else + warnx("netstat_route: %s", netstat_strerror(error)); + goto out; + } + + if (netstat_rti_alloc(rtlp, &rtip) < 0) { + warn("netstat_rti_alloc()"); + goto out; + } + + printf("Routing tables\n"); - intsize = sizeof(int); - if (sysctlbyname("net.my_fibnum", &fibnum, &intsize, NULL, 0) == -1) - fibnum = 0; - if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1) - numfibs = 1; - rt_tables = calloc(numfibs, sizeof(struct rtline)); - if (rt_tables == NULL) - err(EX_OSERR, "memory allocation failed"); /* - * Since kernel & userland use different timebase - * (time_uptime vs time_second) and we are reading kernel memory - * directly we should do rt_rmx.rmx_expire --> expire_time conversion. + * It should be guaranteed (somehow) by libnetstat that returned + * routes are not interleaved by protocol families. */ - if (clock_gettime(CLOCK_UPTIME, &uptime) < 0) - err(EX_OSERR, "clock_gettime() failed"); - printf("Routing tables\n"); - - if (Aflag == 0 && NewTree) - ntreestuff(); - else { - if (rtree == 0) { - printf("rt_tables: symbol not in namelist\n"); - return; + last_domain = -1; + for (rtp = netstat_rti_first(rtip); rtp != NULL; + rtp = netstat_rti_next(rtip)) { + dom = netstat_rt_get_family(rtp); + if (dom != last_domain) { + printf("\n%s:\n", netstat_family_name(dom)); + size_cols(dom, NULL); + pr_rthdr(dom); + last_domain = dom; + } + flags = netstat_rt_get_flags(rtp); + dst = netstat_rt_get_destination(rtp); + gw = netstat_rt_get_gateway(rtp); + rntp = netstat_rt_get_node(rtp); + if (Aflag) { + printf("%-8.8lx ", + (u_long)netstat_rnt_get_address(rntp)); } - - if (kread((u_long)(rtree), (char *)(rt_tables), - (numfibs * sizeof(struct rtline))) != 0) - return; - for (i = 0; i <= AF_MAX; i++) { - int tmpfib; - if (i != AF_INET) - tmpfib = 0; - else - tmpfib = fibnum; - if ((rnh = rt_tables[tmpfib].tables[i]) == 0) - continue; - if (kget(rnh, head) != 0) - continue; - if (i == AF_UNSPEC) { - if (Aflag && af == 0) { - printf("Netmasks:\n"); - p_tree(head.rnh_treetop); - } - } else if (af == AF_UNSPEC || af == i) { - size_cols(i, head.rnh_treetop); - pr_family(i); - do_rtent = 1; - pr_rthdr(i); - p_tree(head.rnh_treetop); + if (dst != NULL && gw != NULL) { + printf("%-*.*s %-*.*s %-*.*s", + wid_dst, wid_dst, + netstat_rat_get_name(dst, numeric_addr), + wid_gw, wid_gw, + netstat_rat_get_name(gw, numeric_addr), + wid_flags, wid_flags, fmt_flags(flags)); + if (dom == PF_INET) { + printf(" %*ju %*ju", + wid_refs, netstat_rt_get_refs(rtp), + wid_use, netstat_rt_get_used(rtp)); + if (Wflag) + printf(" %*d", + wid_mtu, netstat_rt_get_mtu(rtp)); } + printf(" %*s", + wid_if, netstat_rt_get_interface(rtp)); + if (flags & NETSTAT_RT_EXPIRES) + printf(" %*ju", wid_expire, + netstat_rt_get_expire(rtp)); } + if (Aflag) + p_rtnode(rntp); + putchar('\n'); } -} -/* - * Print address family header before a section of the routing table. - */ -void -pr_family(int af1) -{ - const char *afname; - - switch (af1) { - case AF_INET: - afname = "Internet"; - break; -#ifdef INET6 - case AF_INET6: - afname = "Internet6"; - break; -#endif /*INET6*/ - case AF_IPX: - afname = "IPX"; - break; - case AF_ISO: - afname = "ISO"; - break; - case AF_APPLETALK: - afname = "AppleTalk"; - break; - case AF_CCITT: - afname = "X.25"; - break; - case AF_NETGRAPH: - afname = "Netgraph"; - break; - default: - afname = NULL; - break; - } - if (afname) - printf("\n%s:\n", afname); - else - printf("\nProtocol Family %d:\n", af1); + netstat_rti_free(rtip); +out: netstat_rtl_free(rtlp); } /* column widths; each followed by one space */ @@ -270,17 +206,8 @@ #define WID_IF_DEFAULT(af) ((af) == AF_INET6 ? 8 : (Wflag ? 8 : 6)) #endif /*INET6*/ -static int wid_dst; -static int wid_gw; -static int wid_flags; -static int wid_refs; -static int wid_use; -static int wid_mtu; -static int wid_if; -static int wid_expire; - -static void -size_cols(int ef __unused, struct radix_node *rn) +void +size_cols(int ef, __unused struct route_type_iterator *rtip) { wid_dst = WID_DST_DEFAULT(ef); wid_gw = WID_GW_DEFAULT(ef); @@ -291,95 +218,71 @@ wid_if = WID_IF_DEFAULT(ef); wid_expire = 6; +/* if (Wflag) - size_cols_tree(rn); + size_cols_tree(rtip); +*/ } -static void -size_cols_tree(struct radix_node *rn) +static const char * +fmt_flags(int f) { -again: - if (kget(rn, rnode) != 0) - return; - if (!(rnode.rn_flags & RNF_ACTIVE)) - return; - if (rnode.rn_bit < 0) { - if ((rnode.rn_flags & RNF_ROOT) == 0) { - if (kget(rn, rtentry) != 0) - return; - size_cols_rtentry(&rtentry); - } - if ((rn = rnode.rn_dupedkey)) - goto again; - } else { - rn = rnode.rn_right; - size_cols_tree(rnode.rn_left); - size_cols_tree(rn); - } + static char name[33]; + char *flags; + struct bits *p = bits; + + for (flags = name; p->b_mask; p++) + if (p->b_mask & f) + *flags++ = p->b_val; + *flags = '\0'; + return (name); } -static void -size_cols_rtentry(struct rtentry *rt) +void p_rtnode(const struct routenode_type *rntp) { - static struct ifnet ifnet, *lastif; - static char buffer[100]; - const char *bp; - struct sockaddr *sa; - sa_u addr, mask; - int len; + const struct routemask_type *rmtp; + const struct routeaddr_type *mask; + char nbuf[20]; + int bit, i, flags; - bzero(&addr, sizeof(addr)); - if ((sa = kgetsa(rt_key(rt)))) - bcopy(sa, &addr, sa->sa_len); - bzero(&mask, sizeof(mask)); - if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) - bcopy(sa, &mask, sa->sa_len); - bp = fmt_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags); - len = strlen(bp); - wid_dst = MAX(len, wid_dst); - - bp = fmt_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST); - len = strlen(bp); - wid_gw = MAX(len, wid_gw); - - bp = fmt_flags(rt->rt_flags); - len = strlen(bp); - wid_flags = MAX(len, wid_flags); - - if (addr.u_sa.sa_family == AF_INET || Wflag) { - len = snprintf(buffer, sizeof(buffer), "%d", rt->rt_refcnt); - wid_refs = MAX(len, wid_refs); - len = snprintf(buffer, sizeof(buffer), "%lu", rt->rt_use); - wid_use = MAX(len, wid_use); - if (Wflag && rt->rt_rmx.rmx_mtu != 0) { - len = snprintf(buffer, sizeof(buffer), - "%lu", rt->rt_rmx.rmx_mtu); - wid_mtu = MAX(len, wid_mtu); + flags = netstat_rnt_get_flags(rntp); + if (flags & NETSTAT_RTN_ROOT) { + printf("(root node)%s", + flags & NETSTAT_RTN_DUPEDKEY ? " =>" : ""); + } else { + bit = netstat_rnt_get_bit(rntp); + if (bit < 0) { + mask = netstat_rnt_get_netmask(rntp); + if (mask != NULL) { + printf(" mask "); + printf("%s", + netstat_rat_get_name(mask, numeric_addr)); + } else if (netstat_rnt_get_mkcnt(rntp) == 0) + return; + } else { + sprintf(nbuf, "(%d)", bit); + printf("%6.6s %8.8lx : %8.8lx", nbuf, + (u_long)netstat_rnt_get_left(rntp), + (u_long)netstat_rnt_get_right(rntp)); } - } - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - if (kget(rt->rt_ifp, ifnet) == 0) - len = strlen(ifnet.if_xname); - else - len = strlen("---"); - lastif = rt->rt_ifp; - wid_if = MAX(len, wid_if); + for (i = 0; i < netstat_rnt_get_mkcnt(rntp); i++) { + if (i > 0) + printf(" ->"); + rmtp = netstat_rnt_get_mask(rntp, i); + sprintf(nbuf, " %ju refs, ", netstat_rmt_get_refs(rmtp)); + printf(" mk = %8.8lx { (%d),%s", + (u_long)netstat_rmt_get_address(rmtp), + -1 - netstat_rmt_get_bit(rmtp), + netstat_rmt_get_refs(rmtp) > 0 ? nbuf : " "); + if (netstat_rmt_get_flags(rmtp) & NETSTAT_RTM_NORMAL) + printf("<normal>, "); + mask = netstat_rmt_get_netmask(rmtp); + printf("%s ", netstat_rat_get_name(mask, numeric_addr)); + putchar('}'); } - if (rt->rt_rmx.rmx_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0) { - len = snprintf(buffer, sizeof(buffer), "%d", - (int)expire_time); - wid_expire = MAX(len, wid_expire); - } - } } } - /* * Print header for routing table columns. */ @@ -420,567 +323,6 @@ } } -static struct sockaddr * -kgetsa(struct sockaddr *dst) -{ - - if (kget(dst, pt_u.u_sa) != 0) - return (NULL); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) - kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len); - return (&pt_u.u_sa); -} - -static void -p_tree(struct radix_node *rn) -{ - -again: - if (kget(rn, rnode) != 0) - return; - if (!(rnode.rn_flags & RNF_ACTIVE)) - return; - if (rnode.rn_bit < 0) { - if (Aflag) - printf("%-8.8lx ", (u_long)rn); - if (rnode.rn_flags & RNF_ROOT) { - if (Aflag) - printf("(root node)%s", - rnode.rn_dupedkey ? " =>\n" : "\n"); - } else if (do_rtent) { - if (kget(rn, rtentry) == 0) { - p_rtentry(&rtentry); - if (Aflag) - p_rtnode(); - } - } else { - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - NULL, 0, 44); - putchar('\n'); - } - if ((rn = rnode.rn_dupedkey)) - goto again; - } else { - if (Aflag && do_rtent) { - printf("%-8.8lx ", (u_long)rn); - p_rtnode(); - } - rn = rnode.rn_right; - p_tree(rnode.rn_left); - p_tree(rn); - } -} - -char nbuf[20]; - -static void -p_rtnode(void) -{ - struct radix_mask *rm = rnode.rn_mklist; - - if (rnode.rn_bit < 0) { - if (rnode.rn_mask) { - printf("\t mask "); - p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_mask), - NULL, 0, -1); - } else if (rm == 0) - return; - } else { - sprintf(nbuf, "(%d)", rnode.rn_bit); - printf("%6.6s %8.8lx : %8.8lx", nbuf, (u_long)rnode.rn_left, (u_long)rnode.rn_right); - } - while (rm) { - if (kget(rm, rmask) != 0) - break; - sprintf(nbuf, " %d refs, ", rmask.rm_refs); - printf(" mk = %8.8lx {(%d),%s", - (u_long)rm, -1 - rmask.rm_bit, rmask.rm_refs ? nbuf : " "); - if (rmask.rm_flags & RNF_NORMAL) { - struct radix_node rnode_aux; - printf(" <normal>, "); - if (kget(rmask.rm_leaf, rnode_aux) == 0) - p_sockaddr(kgetsa((struct sockaddr *)rnode_aux.rn_mask), - NULL, 0, -1); - else - p_sockaddr(NULL, NULL, 0, -1); - } else - p_sockaddr(kgetsa((struct sockaddr *)rmask.rm_mask), - NULL, 0, -1); - putchar('}'); - if ((rm = rmask.rm_mklist)) - printf(" ->"); - } - putchar('\n'); -} - -static void -ntreestuff(void) -{ - size_t needed; - int mib[6]; - char *buf, *next, *lim; - struct rt_msghdr *rtm; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = 0; - mib[4] = NET_RT_DUMP; - mib[5] = 0; - if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { - err(1, "sysctl: net.route.0.0.dump estimate"); - } - - if ((buf = malloc(needed)) == 0) { - errx(2, "malloc(%lu)", (unsigned long)needed); - } - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { - err(1, "sysctl: net.route.0.0.dump"); - } - lim = buf + needed; - for (next = buf; next < lim; next += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)next; - np_rtentry(rtm); - } -} - -static void -np_rtentry(struct rt_msghdr *rtm) -{ - struct sockaddr *sa = (struct sockaddr *)(rtm + 1); -#ifdef notdef - static int masks_done, banner_printed; -#endif - static int old_af; - int af1 = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; - -#ifdef notdef - /* for the moment, netmasks are skipped over */ - if (!banner_printed) { - printf("Netmasks:\n"); - banner_printed = 1; - } - if (masks_done == 0) { - if (rtm->rtm_addrs != RTA_DST ) { - masks_done = 1; - af1 = sa->sa_family; - } - } else -#endif - af1 = sa->sa_family; - if (af1 != old_af) { - pr_family(af1); - old_af = af1; - } - if (rtm->rtm_addrs == RTA_DST) - p_sockaddr(sa, NULL, 0, 36); - else { - p_sockaddr(sa, NULL, rtm->rtm_flags, 16); - sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); - p_sockaddr(sa, NULL, 0, 18); - } - p_flags(rtm->rtm_flags & interesting, "%-6.6s "); - putchar('\n'); -} - -static void -p_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags, int width) -{ - const char *cp; - - cp = fmt_sockaddr(sa, mask, flags); - - if (width < 0 ) - printf("%s ", cp); - else { - if (numeric_addr) - printf("%-*s ", width, cp); - else - printf("%-*.*s ", width, width, cp); - } -} - -static const char * -fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags) -{ - static char workbuf[128]; - const char *cp; - - if (sa == NULL) - return ("null"); - - switch(sa->sa_family) { - case AF_INET: - { - struct sockaddr_in *sockin = (struct sockaddr_in *)sa; - - if ((sockin->sin_addr.s_addr == INADDR_ANY) && - mask && - ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr) - ==0L) - cp = "default" ; - else if (flags & RTF_HOST) - cp = routename(sockin->sin_addr.s_addr); - else if (mask) - cp = netname(sockin->sin_addr.s_addr, - ntohl(((struct sockaddr_in *)mask) - ->sin_addr.s_addr)); - else - cp = netname(sockin->sin_addr.s_addr, 0L); - break; - } - -#ifdef INET6 - case AF_INET6: - { - struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa; - struct in6_addr *in6 = &sa6->sin6_addr; - - /* - * XXX: This is a special workaround for KAME kernels. - * sin6_scope_id field of SA should be set in the future. - */ - if (IN6_IS_ADDR_LINKLOCAL(in6) || - IN6_IS_ADDR_MC_LINKLOCAL(in6)) { - /* XXX: override is ok? */ - sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)&in6->s6_addr[2]); - *(u_short *)&in6->s6_addr[2] = 0; - } - - if (flags & RTF_HOST) - cp = routename6(sa6); - else if (mask) - cp = netname6(sa6, - &((struct sockaddr_in6 *)mask)->sin6_addr); - else { - cp = netname6(sa6, NULL); - } - break; - } -#endif /*INET6*/ - - case AF_IPX: - { - struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr; - if (ipx_nullnet(satoipx_addr(work))) - cp = "default"; - else - cp = ipx_print(sa); - break; - } - case AF_APPLETALK: - { - if (!(flags & RTF_HOST) && mask) - cp = atalk_print2(sa,mask,9); - else - cp = atalk_print(sa,11); - break; - } - case AF_NETGRAPH: - { - strlcpy(workbuf, ((struct sockaddr_ng *)sa)->sg_data, - sizeof(workbuf)); - cp = workbuf; - break; - } - - case AF_LINK: - { - struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; - - if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && - sdl->sdl_slen == 0) { - (void) sprintf(workbuf, "link#%d", sdl->sdl_index); - cp = workbuf; - } else - switch (sdl->sdl_type) { - - case IFT_ETHER: - case IFT_L2VLAN: - case IFT_BRIDGE: - if (sdl->sdl_alen == ETHER_ADDR_LEN) { - cp = ether_ntoa((struct ether_addr *) - (sdl->sdl_data + sdl->sdl_nlen)); - break; - } - /* FALLTHROUGH */ - default: - cp = link_ntoa(sdl); - break; - } - break; - } - - default: - { - u_char *s = (u_char *)sa->sa_data, *slim; - char *cq, *cqlim; - - cq = workbuf; - slim = sa->sa_len + (u_char *) sa; - cqlim = cq + sizeof(workbuf) - 6; - cq += sprintf(cq, "(%d)", sa->sa_family); - while (s < slim && cq < cqlim) { - cq += sprintf(cq, " %02x", *s++); - if (s < slim) - cq += sprintf(cq, "%02x", *s++); - } - cp = workbuf; - } - } - - return (cp); -} - -static void -p_flags(int f, const char *format) -{ - printf(format, fmt_flags(f)); -} - -static const char * -fmt_flags(int f) -{ - static char name[33]; - char *flags; - struct bits *p = bits; - - for (flags = name; p->b_mask; p++) - if (p->b_mask & f) - *flags++ = p->b_val; - *flags = '\0'; - return (name); -} - -static void -p_rtentry(struct rtentry *rt) -{ - static struct ifnet ifnet, *lastif; - static char buffer[128]; - static char prettyname[128]; - struct sockaddr *sa; - sa_u addr, mask; - - bzero(&addr, sizeof(addr)); - if ((sa = kgetsa(rt_key(rt)))) - bcopy(sa, &addr, sa->sa_len); - bzero(&mask, sizeof(mask)); - if (rt_mask(rt) && (sa = kgetsa(rt_mask(rt)))) - bcopy(sa, &mask, sa->sa_len); - p_sockaddr(&addr.u_sa, &mask.u_sa, rt->rt_flags, wid_dst); - p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); - snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); - p_flags(rt->rt_flags, buffer); - if (addr.u_sa.sa_family == AF_INET || Wflag) { - printf("%*d %*lu ", wid_refs, rt->rt_refcnt, - wid_use, rt->rt_use); - if (Wflag) { - if (rt->rt_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu); - else - printf("%*s ", wid_mtu, ""); - } - } - if (rt->rt_ifp) { - if (rt->rt_ifp != lastif) { - if (kget(rt->rt_ifp, ifnet) == 0) - strlcpy(prettyname, ifnet.if_xname, - sizeof(prettyname)); - else - strlcpy(prettyname, "---", sizeof(prettyname)); - lastif = rt->rt_ifp; - } - printf("%*.*s", wid_if, wid_if, prettyname); - if (rt->rt_rmx.rmx_expire) { - time_t expire_time; - - if ((expire_time = - rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0) - printf(" %*d", wid_expire, (int)expire_time); - } - if (rt->rt_nodes[0].rn_dupedkey) - printf(" =>"); - } - putchar('\n'); -} - -char * -routename(in_addr_t in) -{ - char *cp; - static char line[MAXHOSTNAMELEN]; - struct hostent *hp; - - cp = 0; - if (!numeric_addr) { - hp = gethostbyaddr(&in, sizeof (struct in_addr), AF_INET); - if (hp) { - cp = hp->h_name; - trimdomain(cp, strlen(cp)); - } - } - if (cp) { - strlcpy(line, cp, sizeof(line)); - } else { -#define C(x) ((x) & 0xff) >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908112336.n7BNaL5o080861>