/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/if_mib.h>
+#include <net/if_llreach.h>
#include <net/ethernet.h>
#include <net/route.h>
#include <unistd.h>
#include <stdlib.h>
#include <err.h>
+#include <errno.h>
#include "netstat.h"
static void sidewaysintpr ();
static void catchalarm (int);
+static char *sec2str(time_t);
+static void llreach_sysctl(uint32_t);
#ifdef INET6
char *netname6 (struct sockaddr_in6 *, struct sockaddr *);
/* Construct the format string */
if (showvalue) {
- sprintf(newfmt, "%%%d%s", width, fmt);
+ snprintf(newfmt, sizeof(newfmt), "%%%d%s", width, fmt);
printf(newfmt, value);
} else {
- sprintf(newfmt, "%%%ds", width);
+ snprintf(newfmt, sizeof(newfmt), "%%%ds", width);
printf(newfmt, "-");
}
}
memcpy(&sin6, sa, sizeof(struct sockaddr_in6));
if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr) ||
+ IN6_IS_ADDR_MC_NODELOCAL(&sin6.sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) {
sin6.sin6_scope_id = ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]);
sin6.sin6_addr.s6_addr[2] = 0;
free(buf);
return;
}
+
if (!pfunc) {
printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
- if (bflag)
+ if (prioflag >= 0)
+ printf(" %8.8s", "Itcpkts");
+ if (bflag) {
printf(" %10.10s","Ibytes");
+ if (prioflag >= 0)
+ printf(" %10.10s", "Itcbytes");
+ }
printf(" %8.8s %5.5s", "Opkts", "Oerrs");
- if (bflag)
+ if (prioflag >= 0)
+ printf(" %8.8s", "Otcpkts");
+ if (bflag) {
printf(" %10.10s","Obytes");
+ if (prioflag >= 0)
+ printf(" %10.10s", "Otcbytes");
+ }
printf(" %5s", "Coll");
if (tflag)
printf(" %s", "Time");
for (next = buf; next < lim; ) {
char *cp;
int n, m;
+ struct ifmibdata_supplemental ifmsupp;
+ u_int64_t ift_itcp = 0; /* input tc packets */
+ u_int64_t ift_itcb = 0; /* input tc bytes */
+ u_int64_t ift_otcp = 0; /* output tc packets */
+ u_int64_t ift_otcb = 0; /* output tc bytes */
+
+ bzero(&ifmsupp, sizeof(struct ifmibdata_supplemental));
network_layer = 0;
link_layer = 0;
drops = if2m->ifm_snd_drops;
mtu = if2m->ifm_data.ifi_mtu;
+ if (prioflag >= 0) {
+ int name[6];
+ size_t miblen = sizeof(struct ifmibdata_supplemental);
+
+ /* Common OID prefix */
+ name[0] = CTL_NET;
+ name[1] = PF_LINK;
+ name[2] = NETLINK_GENERIC;
+ name[3] = IFMIB_IFDATA;
+ name[4] = if2m->ifm_index;
+ name[5] = IFDATA_SUPPLEMENTAL;
+ if (sysctl(name, 6, &ifmsupp, &miblen, (void *)0, 0) == -1)
+ err(1, "sysctl IFDATA_SUPPLEMENTAL");
+
+ switch (prioflag) {
+ case SO_TC_BK:
+ ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibkpackets;
+ ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibkbytes;
+ ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obkpackets;
+ ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obkbytes;
+ break;
+ case SO_TC_VI:
+ ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivipackets;
+ ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivibytes;
+ ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovipackets;
+ ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovibytes;
+ break;
+ case SO_TC_VO:
+ ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivopackets;
+ ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivobytes;
+ ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovopackets;
+ ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovobytes;
+ break;
+ default:
+ ift_itcp = 0;
+ ift_itcb = 0;
+ ift_otcp = 0;
+ ift_otcb = 0;
+ break;
+ }
+ }
+
get_rti_info(if2m->ifm_addrs, (struct sockaddr*)(if2m + 1), rti_info);
sa = rti_info[RTAX_IFP];
} else if (ifm->ifm_type == RTM_NEWADDR) {
char linknum[10];
cp = (char *)LLADDR(sdl);
n = sdl->sdl_alen;
- sprintf(linknum, "<Link#%d>", sdl->sdl_index);
+ snprintf(linknum, sizeof(linknum), "<Link#%d>", sdl->sdl_index);
m = printf("%-11.11s ", linknum);
goto hexprint;
}
printf(" ");
show_stat("llu", 5, ierrors, link_layer);
printf(" ");
+ if (prioflag >= 0) {
+ show_stat("llu", 8, ift_itcp, link_layer|network_layer);
+ printf(" ");
+ }
if (bflag) {
show_stat("llu", 10, ibytes, link_layer|network_layer);
printf(" ");
+ if (prioflag >= 0) {
+ show_stat("llu", 8, ift_itcb, link_layer|network_layer);
+ printf(" ");
+ }
}
show_stat("llu", 8, opackets, link_layer|network_layer);
printf(" ");
show_stat("llu", 5, oerrors, link_layer);
printf(" ");
+ if (prioflag >= 0) {
+ show_stat("llu", 8, ift_otcp, link_layer|network_layer);
+ printf(" ");
+ }
if (bflag) {
show_stat("llu", 10, obytes, link_layer|network_layer);
printf(" ");
+ if (prioflag >= 0) {
+ show_stat("llu", 8, ift_otcb, link_layer|network_layer);
+ printf(" ");
+ }
}
show_stat("llu", 5, collisions, link_layer);
if (tflag) {
if (aflag)
multipr(sa->sa_family, next, lim);
}
+ free(buf);
}
struct iftot {
u_int64_t ift_dr; /* drops */
u_int64_t ift_ib; /* input bytes */
u_int64_t ift_ob; /* output bytes */
- u_int64_t ift_obgp; /* output bg packets */
- u_int64_t ift_obgb; /* output bg bytes */
+ u_int64_t ift_itcp; /* input tc packets */
+ u_int64_t ift_itcb; /* input tc bytes */
+ u_int64_t ift_otcp; /* output tc packets */
+ u_int64_t ift_otcb; /* output tc bytes */
};
u_char signalled; /* set if alarm goes off "early" */
sigset_t sigset, oldsigset;
struct itimerval timer_interval;
-
/* Common OID prefix */
name[0] = CTL_NET;
name[1] = PF_LINK;
if (interface && strcmp(ifmd->ifmd_name, interface) == 0) {
if ((interesting = calloc(ifcount, sizeof(struct iftot))) == NULL)
err(1, "malloc failed");
- interesting_row = i + 1;
+ interesting_row = if_nametoindex(interface);
snprintf(interesting->ift_name, 16, "(%s)", ifmd->ifmd_name);;
}
}
(void)setitimer(ITIMER_REAL, &timer_interval, NULL);
first = 1;
banner:
- printf("%17s %14s %16s", "input",
- interesting ? interesting->ift_name : "(Total)", "output");
+ if (prioflag >= 0)
+ printf("%37s %14s %16s", "input",
+ interesting ? interesting->ift_name : "(Total)", "output");
+ else
+ printf("%17s %14s %16s", "input",
+ interesting ? interesting->ift_name : "(Total)", "output");
putchar('\n');
- printf("%10s %5s %10s %10s %5s %10s %5s",
- "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
+ printf("%10s %5s %10s ",
+ "packets", "errs", "bytes");
+ if (prioflag >= 0)
+ printf(" %10s %10s", "tcpkts", "tcbytes");
+ printf("%10s %5s %10s %5s",
+ "packets", "errs", "bytes", "colls");
if (dflag)
printf(" %5.5s", "drops");
- if (prioflag)
- printf(" %10s %10s", "obgpkts", "obgbytes");
+ if (prioflag >= 0)
+ printf(" %10s %10s", "tcpkts", "tcbytes");
putchar('\n');
fflush(stdout);
line = 0;
loop:
if (interesting != NULL) {
struct ifmibdata ifmd;
+ struct ifmibdata_supplemental ifmsupp;
len = sizeof(struct ifmibdata);
name[3] = IFMIB_IFDATA;
if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1)
err(1, "sysctl IFDATA_GENERAL %d", interesting_row);
+ if (prioflag >= 0) {
+ len = sizeof(struct ifmibdata_supplemental);
+ name[3] = IFMIB_IFDATA;
+ name[4] = interesting_row;
+ name[5] = IFDATA_SUPPLEMENTAL;
+ if (sysctl(name, 6, &ifmsupp, &len, (void *)0, 0) == -1)
+ err(1, "sysctl IFDATA_SUPPLEMENTAL %d", interesting_row);
+ }
if (!first) {
- printf("%10llu %5llu %10llu %10llu %5llu %10llu %5llu",
+ printf("%10llu %5llu %10llu ",
ifmd.ifmd_data.ifi_ipackets - interesting->ift_ip,
ifmd.ifmd_data.ifi_ierrors - interesting->ift_ie,
- ifmd.ifmd_data.ifi_ibytes - interesting->ift_ib,
+ ifmd.ifmd_data.ifi_ibytes - interesting->ift_ib);
+ switch (prioflag) {
+ case SO_TC_BK:
+ printf("%10llu %10llu ",
+ ifmsupp.ifmd_traffic_class.ifi_ibkpackets - interesting->ift_itcp,
+ ifmsupp.ifmd_traffic_class.ifi_ibkbytes - interesting->ift_itcb);
+ break;
+ case SO_TC_VI:
+ printf("%10llu %10llu ",
+ ifmsupp.ifmd_traffic_class.ifi_ivipackets - interesting->ift_itcp,
+ ifmsupp.ifmd_traffic_class.ifi_ivibytes - interesting->ift_itcb);
+ break;
+ case SO_TC_VO:
+ printf("%10llu %10llu ",
+ ifmsupp.ifmd_traffic_class.ifi_ivopackets - interesting->ift_itcp,
+ ifmsupp.ifmd_traffic_class.ifi_ivobytes - interesting->ift_itcb);
+ break;
+ default:
+ break;
+ }
+ printf("%10llu %5llu %10llu %5llu",
ifmd.ifmd_data.ifi_opackets - interesting->ift_op,
ifmd.ifmd_data.ifi_oerrors - interesting->ift_oe,
ifmd.ifmd_data.ifi_obytes - interesting->ift_ob,
ifmd.ifmd_data.ifi_collisions - interesting->ift_co);
if (dflag)
printf(" %5llu", ifmd.ifmd_snd_drops - interesting->ift_dr);
- if (prioflag)
- printf(" %10llu %10llu",
- ifmd.ifmd_filler[0] - interesting->ift_obgp,
- ifmd.ifmd_filler[1] - interesting->ift_obgb);
+ switch (prioflag) {
+ case SO_TC_BK:
+ printf(" %10llu %10llu",
+ ifmsupp.ifmd_traffic_class.ifi_obkpackets - interesting->ift_otcp,
+ ifmsupp.ifmd_traffic_class.ifi_obkbytes - interesting->ift_otcb);
+ break;
+ case SO_TC_VI:
+ printf(" %10llu %10llu",
+ ifmsupp.ifmd_traffic_class.ifi_ovipackets - interesting->ift_otcp,
+ ifmsupp.ifmd_traffic_class.ifi_ovibytes - interesting->ift_otcb);
+ break;
+ case SO_TC_VO:
+ printf(" %10llu %10llu",
+ ifmsupp.ifmd_traffic_class.ifi_ovopackets - interesting->ift_otcp,
+ ifmsupp.ifmd_traffic_class.ifi_ovobytes - interesting->ift_otcb);
+ break;
+ default:
+ break;
+ }
}
interesting->ift_ip = ifmd.ifmd_data.ifi_ipackets;
interesting->ift_ie = ifmd.ifmd_data.ifi_ierrors;
interesting->ift_co = ifmd.ifmd_data.ifi_collisions;
interesting->ift_dr = ifmd.ifmd_snd_drops;
/* private counters */
- interesting->ift_obgp = ifmd.ifmd_filler[0];
- interesting->ift_obgb = ifmd.ifmd_filler[1];
+ switch (prioflag) {
+ case SO_TC_BK:
+ interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ibkpackets;
+ interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ibkbytes;
+ interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_obkpackets;
+ interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_obkbytes;
+ break;
+ case SO_TC_VI:
+ interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivipackets;
+ interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivibytes;
+ interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovipackets;
+ interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovibytes;
+ break;
+ case SO_TC_VO:
+ interesting->ift_itcp = ifmsupp.ifmd_traffic_class.ifi_ivopackets;
+ interesting->ift_itcb = ifmsupp.ifmd_traffic_class.ifi_ivobytes;
+ interesting->ift_otcp = ifmsupp.ifmd_traffic_class.ifi_ovopackets;
+ interesting->ift_otcb = ifmsupp.ifmd_traffic_class.ifi_ovobytes;
+ break;
+ default:
+ break;
+ }
} else {
unsigned int latest_ifcount;
+ struct ifmibdata_supplemental *ifmsuppall = NULL;
len = sizeof(int);
name[3] = IFMIB_SYSTEM;
free(ifmdall);
ifmdall = malloc(len);
if (ifmdall == 0)
- err(1, "malloc failed");
+ err(1, "malloc ifmdall failed");
} else if (latest_ifcount > ifcount) {
ifcount = latest_ifcount;
len = ifcount * sizeof(struct ifmibdata);
name[5] = IFDATA_GENERAL;
if (sysctl(name, 6, ifmdall, &len, (void *)0, 0) == -1)
err(1, "sysctl IFMIB_IFALLDATA");
-
+ if (prioflag >= 0) {
+ len = ifcount * sizeof(struct ifmibdata_supplemental);
+ ifmsuppall = malloc(len);
+ if (ifmsuppall == NULL)
+ err(1, "malloc ifmsuppall failed");
+ name[3] = IFMIB_IFALLDATA;
+ name[4] = 0;
+ name[5] = IFDATA_SUPPLEMENTAL;
+ if (sysctl(name, 6, ifmsuppall, &len, (void *)0, 0) == -1)
+ err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL");
+ }
sum->ift_ip = 0;
sum->ift_ie = 0;
sum->ift_ib = 0;
sum->ift_ob = 0;
sum->ift_co = 0;
sum->ift_dr = 0;
- sum->ift_obgp = 0;
- sum->ift_obgb = 0;
+ sum->ift_itcp = 0;
+ sum->ift_itcb = 0;
+ sum->ift_otcp = 0;
+ sum->ift_otcb = 0;
for (i = 0; i < ifcount; i++) {
struct ifmibdata *ifmd = ifmdall + i;
sum->ift_co += ifmd->ifmd_data.ifi_collisions;
sum->ift_dr += ifmd->ifmd_snd_drops;
/* private counters */
- sum->ift_obgp += ifmd->ifmd_filler[0];
- sum->ift_obgb += ifmd->ifmd_filler[1];
+ if (prioflag >= 0) {
+ struct ifmibdata_supplemental *ifmsupp = ifmsuppall + i;
+ switch (prioflag) {
+ case SO_TC_BK:
+ sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ibkpackets;
+ sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ibkbytes;
+ sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_obkpackets;
+ sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_obkbytes;
+ break;
+ case SO_TC_VI:
+ sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivipackets;
+ sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivibytes;
+ sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovipackets;
+ sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovibytes;
+ break;
+ case SO_TC_VO:
+ sum->ift_itcp += ifmsupp->ifmd_traffic_class.ifi_ivopackets;
+ sum->ift_itcb += ifmsupp->ifmd_traffic_class.ifi_ivobytes;
+ sum->ift_otcp += ifmsupp->ifmd_traffic_class.ifi_ovopackets;
+ sum->ift_otcb += ifmsupp->ifmd_traffic_class.ifi_ovobytes;
+ break;
+ default:
+ break;
+ }
+ }
}
if (!first) {
- printf("%10llu %5llu %10llu %10llu %5llu %10llu %5llu",
+ printf("%10llu %5llu %10llu ",
sum->ift_ip - total->ift_ip,
sum->ift_ie - total->ift_ie,
- sum->ift_ib - total->ift_ib,
+ sum->ift_ib - total->ift_ib);
+ if (prioflag >= 0)
+ printf(" %10llu %10llu",
+ sum->ift_itcp - total->ift_itcp,
+ sum->ift_itcb - total->ift_itcb);
+ printf("%10llu %5llu %10llu %5llu",
sum->ift_op - total->ift_op,
sum->ift_oe - total->ift_oe,
sum->ift_ob - total->ift_ob,
sum->ift_co - total->ift_co);
if (dflag)
printf(" %5llu", sum->ift_dr - total->ift_dr);
- if (prioflag)
+ if (prioflag >= 0)
printf(" %10llu %10llu",
- sum->ift_obgp - total->ift_obgp,
- sum->ift_obgb - total->ift_obgb);
+ sum->ift_otcp - total->ift_otcp,
+ sum->ift_otcb - total->ift_otcb);
}
*total = *sum;
}
{
signalled = YES;
}
+
+static char *
+sec2str(total)
+ time_t total;
+{
+ static char result[256];
+ int days, hours, mins, secs;
+ int first = 1;
+ char *p = result;
+
+ days = total / 3600 / 24;
+ hours = (total / 3600) % 24;
+ mins = (total / 60) % 60;
+ secs = total % 60;
+
+ if (days) {
+ first = 0;
+ p += snprintf(p, sizeof(result) - (p - result), "%dd", days);
+ }
+ if (!first || hours) {
+ first = 0;
+ p += snprintf(p, sizeof(result) - (p - result), "%dh", hours);
+ }
+ if (!first || mins) {
+ first = 0;
+ p += snprintf(p, sizeof(result) - (p - result), "%dm", mins);
+ }
+ snprintf(p, sizeof(result) - (p - result), "%ds", secs);
+
+ return(result);
+}
+
+void
+intpr_ri(void (*pfunc)(char *))
+{
+ int mib[6];
+ char *buf = NULL, *lim, *next;
+ size_t len;
+ unsigned int ifindex = 0;
+ struct if_msghdr2 *if2m;
+
+ if (interface != 0) {
+ ifindex = if_nametoindex(interface);
+ if (ifindex == 0) {
+ printf("interface name is not valid: %s\n", interface);
+ exit(1);
+ }
+ }
+
+ mib[0] = CTL_NET; /* networking subsystem */
+ mib[1] = PF_ROUTE; /* type of information */
+ mib[2] = 0; /* protocol (IPPROTO_xxx) */
+ mib[3] = 0; /* address family */
+ mib[4] = NET_RT_IFLIST2; /* operation */
+ mib[5] = 0;
+ if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
+ return;
+ if ((buf = malloc(len)) == NULL) {
+ printf("malloc failed\n");
+ exit(1);
+ }
+ if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+ free(buf);
+ return;
+ }
+
+ printf("%-6s %-17s %8.8s %-9.9s %4s %4s\n",
+ "Proto", "Linklayer Address", "Netif", "Expire", "Refs", "Prbs");
+
+ lim = buf + len;
+ if2m = (struct if_msghdr2 *)buf;
+
+ for (next = buf; next < lim; ) {
+ if2m = (struct if_msghdr2 *)next;
+ next += if2m->ifm_msglen;
+
+ if (if2m->ifm_type != RTM_IFINFO2)
+ continue;
+ else if (interface != 0 && if2m->ifm_index != ifindex)
+ continue;
+
+ llreach_sysctl(if2m->ifm_index);
+ }
+ free(buf);
+}
+
+static void
+llreach_sysctl(uint32_t ifindex)
+{
+#define MAX_SYSCTL_TRY 5
+ int mib[6], i, ntry = 0;
+ size_t mibsize, len, needed, cnt;
+ struct if_llreach_info *lri;
+ struct timeval time;
+ char *buf;
+ char ifname[IF_NAMESIZE];
+
+ bzero(&mib, sizeof (mib));
+ mibsize = sizeof (mib) / sizeof (mib[0]);
+ if (sysctlnametomib("net.link.generic.system.llreach_info", mib,
+ &mibsize) == -1) {
+ perror("sysctlnametomib");
+ return;
+ }
+
+ needed = 0;
+ mib[5] = ifindex;
+
+ mibsize = sizeof (mib) / sizeof (mib[0]);
+ do {
+ if (sysctl(mib, mibsize, NULL, &needed, NULL, 0) == -1) {
+ perror("sysctl net.link.generic.system.llreach_info");
+ return;
+ }
+ if ((buf = malloc(needed)) == NULL) {
+ perror("malloc");
+ return;
+ }
+ if (sysctl(mib, mibsize, buf, &needed, NULL, 0) == -1) {
+ if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) {
+ perror("sysctl");
+ goto out_free;
+ }
+ free(buf);
+ buf = NULL;
+ }
+ } while (buf == NULL);
+
+ len = needed;
+ cnt = len / sizeof (*lri);
+ lri = (struct if_llreach_info *)buf;
+
+ gettimeofday(&time, 0);
+ if (if_indextoname(ifindex, ifname) == NULL)
+ snprintf(ifname, sizeof (ifname), "%s", "?");
+
+ for (i = 0; i < cnt; i++, lri++) {
+ printf("0x%-4x %-17s %8.8s ", lri->lri_proto,
+ ether_ntoa((struct ether_addr *)lri->lri_addr), ifname);
+
+ if (lri->lri_expire > time.tv_sec)
+ printf("%-9.9s", sec2str(lri->lri_expire - time.tv_sec));
+ else if (lri->lri_expire == 0)
+ printf("%-9.9s", "permanent");
+ else
+ printf("%-9.9s", "expired");
+
+ printf(" %4d", lri->lri_refcnt);
+ if (lri->lri_probes)
+ printf(" %4d", lri->lri_probes);
+ printf("\n");
+ len -= sizeof (*lri);
+ }
+ if (len > 0) {
+ fprintf(stderr, "warning: %u trailing bytes from %s\n",
+ (unsigned int)len, "net.link.generic.system.llreach_info");
+ }
+
+out_free:
+ free(buf);
+#undef MAX_SYSCTL_TRY
+}