2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Author: Hartmut Brandt <harti@freebsd.org>
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/types.h>
33 #include <sys/sysctl.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <sys/queue.h>
38 #include <net/if_mib.h>
39 #include <net/if_var.h>
40 #include <net/if_types.h>
41 #include <net/if_atm.h>
42 #include <net/if_media.h>
43 #include <netnatm/natm.h>
44 #include <dev/utopia/utopia.h>
45 #include <dev/utopia/suni.h>
46 #include <dev/utopia/idtphy.h>
48 #include "atmconfig.h"
52 static void diag_list(int, char *[]);
53 static void diag_config(int, char *[]);
54 static void diag_vcc(int, char *[]);
55 static void diag_phy_show(int, char *[]);
56 static void diag_phy_set(int, char *[]);
57 static void diag_phy_print(int, char *[]);
58 static void diag_phy_stats(int, char *[]);
59 static void diag_stats(int, char *[]);
61 const struct cmdtab diag_phy_tab[] = {
62 { "show", NULL, diag_phy_show },
63 { "set", NULL, diag_phy_set },
64 { "stats", NULL, diag_phy_stats },
65 { "print", NULL, diag_phy_print },
69 const struct cmdtab diag_tab[] = {
70 { "list", NULL, diag_list },
71 { "config", NULL, diag_config },
72 { "phy", diag_phy_tab, NULL },
73 { "stats", NULL, diag_stats },
74 { "vcc", NULL, diag_vcc },
78 static const struct utopia_print suni_lite[] = { SUNI_PRINT_LITE };
79 static const struct utopia_print suni_ultra[] = { SUNI_PRINT_ULTRA };
80 static const struct utopia_print suni_622[] = { SUNI_PRINT_622 };
81 static const struct utopia_print idt77105[] = { IDTPHY_PRINT_77105 };
82 static const struct utopia_print idt77155[] = { IDTPHY_PRINT_77155 };
85 const struct utopia_print *tab;
89 { suni_lite, sizeof(suni_lite) / sizeof(suni_lite[0]),
91 { suni_ultra, sizeof(suni_ultra) / sizeof(suni_ultra[0]),
92 UTP_TYPE_SUNI_ULTRA },
93 { suni_622, sizeof(suni_622) / sizeof(suni_622[0]),
95 { idt77105, sizeof(idt77105) / sizeof(idt77105[0]),
97 { idt77155, sizeof(idt77155) / sizeof(idt77155[0]),
101 static const u_int utopia_addreg[] = { UTP_REG_ADD };
104 * Driver statistics printing
106 static const char *const print_stats_pca200e[] = {
113 "tx_queue_almost_full:",
128 static const char *const print_stats_he[] = {
159 static const char *const print_stats_eni[] = {
181 static const char *const print_stats_idt77211[] = {
190 static const char *const print_stats_idt77252[] = {
200 static const char *const print_stats_virtual[] = {
204 static const char *const *const print_stats[] = {
205 [ATM_DEVICE_UNKNOWN] = NULL,
206 [ATM_DEVICE_PCA200E] = print_stats_pca200e,
207 [ATM_DEVICE_HE155] = print_stats_he,
208 [ATM_DEVICE_HE622] = print_stats_he,
209 [ATM_DEVICE_ENI155P] = print_stats_eni,
210 [ATM_DEVICE_ADP155P] = print_stats_eni,
211 [ATM_DEVICE_FORELE25] = print_stats_idt77211,
212 [ATM_DEVICE_FORELE155] = print_stats_idt77211,
213 [ATM_DEVICE_NICSTAR25] = print_stats_idt77211,
214 [ATM_DEVICE_NICSTAR155] = print_stats_idt77211,
215 [ATM_DEVICE_IDTABR25] = print_stats_idt77252,
216 [ATM_DEVICE_IDTABR155] = print_stats_idt77252,
217 [ATM_DEVICE_PROATM25] = print_stats_idt77252,
218 [ATM_DEVICE_PROATM155] = print_stats_idt77252,
219 [ATM_DEVICE_VIRTUAL] = print_stats_virtual,
222 struct diagif_list diagif_list = TAILQ_HEAD_INITIALIZER(diagif_list);
228 phy_fetch(const char *ifname, const char *var, void *val, size_t len,
233 if (asprintf(&str, "hw.atm.%s.phy_%s", ifname, var) == -1)
235 if (sysctlbyname(str, val, &len, NULL, NULL) == -1) {
236 if (err_fatal || errno != ENOENT)
246 * Fetch the list of all ATM network interfaces and their MIBs.
254 struct ifmibdata mib;
255 struct ifatm_mib atm;
259 while ((d = TAILQ_FIRST(&diagif_list)) != NULL) {
262 TAILQ_REMOVE(&diagif_list, d, link);
267 if (sysctlbyname("net.link.generic.system.ifcount", &count, &len,
273 name[2] = NETLINK_GENERIC;
274 name[3] = IFMIB_IFDATA;
276 for (idx = 1; idx <= count; idx++) {
278 name[5] = IFDATA_GENERAL;
280 if (sysctl(name, 6, &mib, &len, NULL, 0) == -1)
281 err(1, "interface %d: general mib", idx);
282 if (mib.ifmd_data.ifi_type == IFT_ATM) {
283 name[5] = IFDATA_LINKSPECIFIC;
285 if (sysctl(name, 6, &atm, &len, NULL, 0) == -1)
286 err(1, "interface %d: ATM mib", idx);
288 d = malloc(sizeof(*d));
291 bzero(d, sizeof(*d));
294 strcpy(d->ifname, mib.ifmd_name);
295 TAILQ_INSERT_TAIL(&diagif_list, d, link);
297 if (phy_fetch(d->ifname, "type", &d->phy_type,
298 sizeof(d->phy_type), 0) == 0) {
300 phy_fetch(d->ifname, "loopback",
302 sizeof(d->phy_loopback), 1);
303 phy_fetch(d->ifname, "name", &d->phy_name,
304 sizeof(d->phy_name), 1);
305 phy_fetch(d->ifname, "state", &d->phy_state,
306 sizeof(d->phy_state), 1);
307 phy_fetch(d->ifname, "carrier", &d->phy_carrier,
308 sizeof(d->phy_carrier), 1);
315 * "<radix><bit>STRING\011<mask><pattern>STRING\012<mask><radix>STRING"
318 printb8(uint32_t val, const char *descr)
320 static char buffer[1000];
323 u_char mask, pattern;
325 if (*descr++ == '\010')
326 sprintf(buffer, "%#o", val);
328 sprintf(buffer, "%#x", val);
329 ptr = buffer + strlen(buffer);
333 if (*descr == '\11') {
337 if ((val & mask) == pattern) {
340 while (*descr >= ' ')
343 while (*descr >= ' ')
346 } else if (*descr == '\12') {
352 while (*descr >= ' ')
357 (val & mask) >> (ffs(mask)-1));
358 else if (pattern == 10)
360 (val & mask) >> (ffs(mask)-1));
363 (val & mask) >> (ffs(mask)-1));
366 if (val & (1 << (*descr++ - 1))) {
369 while (*descr >= ' ')
372 while (*descr >= ' ')
384 * "<radix><bit>STRING<bit>STRING"
387 printb(uint32_t val, const char *descr)
389 static char buffer[1000];
393 if (*descr++ == '\010')
394 sprintf(buffer, "%#o", val);
396 sprintf(buffer, "%#x", val);
397 ptr = buffer + strlen(buffer);
401 if (val & (1 << (*descr++ - 1))) {
419 diag_loop(int argc, char *argv[], const char *text,
420 void (*func)(const struct diagif *))
427 for (i = 0; i < argc; i++) {
428 TAILQ_FOREACH(aif, &diagif_list, link) {
429 if (strcmp(argv[i], aif->ifname) == 0) {
436 warnx("%s: no such ATM interface", argv[i]);
439 TAILQ_FOREACH(aif, &diagif_list, link) {
447 * Print the config line for the given interface
450 config_line1(const struct diagif *aif)
452 printf("%-6u%-9s%-8u%-5u%-6u%-5u%-6u%02x:%02x:%02x:%02x:%02x:%02x\n",
453 aif->index, aif->ifname, aif->mib.pcr, (1 << aif->mib.vpi_bits) - 1,
454 (1 << aif->mib.vci_bits) - 1, aif->mib.max_vpcs, aif->mib.max_vccs,
455 aif->mib.esi[0], aif->mib.esi[1], aif->mib.esi[2],
456 aif->mib.esi[3], aif->mib.esi[4], aif->mib.esi[5]);
460 config_line2(const struct diagif *aif)
464 static const struct {
470 static const struct {
472 const char *const name;
473 } medias[] = IFM_SUBTYPE_ATM_DESCRIPTIONS;
475 for (i = 0; medias[i].name; i++)
476 if (aif->mib.media == medias[i].media)
479 if ((d = aif->mib.device) >= sizeof(devs) / sizeof(devs[0]))
482 printf("%-6u%-9s%-12.11s%-13.12s%-8u%-6x%-6x %s\n", aif->index,
483 aif->ifname, devs[d].vendor, devs[d].dev, aif->mib.serial,
484 aif->mib.hw_version, aif->mib.sw_version,
485 medias[i].name ? medias[i].name : "unknown");
489 diag_config(int argc, char *argv[])
496 static const struct option opts[] = {
497 { "hardware", OPT_SIMPLE, &hardware },
498 { "atm", OPT_SIMPLE, &atm },
502 static const char config_text1[] =
503 "Interface Max Max\n"
504 "Index Name PCR VPI VCI VPCs VCCs ESI Media\n";
505 static const char config_text2[] =
506 "Interface Version\n"
507 "Index Name Vendor Card "
508 "Serial HW SW Media\n";
510 while ((opt = parse_options(&argc, &argv, opts)) != -1)
515 if (TAILQ_EMPTY(&diagif_list))
516 errx(1, "no ATM interfaces found");
518 if (!atm && !hardware)
522 diag_loop(argc, argv, config_text1, config_line1);
524 diag_loop(argc, argv, config_text2, config_line2);
529 diag_list(int argc, char *argv[])
534 static const struct option opts[] = {
538 while ((opt = parse_options(&argc, &argv, opts)) != -1)
543 errx(1, "no arguments required for 'diag list'");
546 if (TAILQ_EMPTY(&diagif_list))
547 errx(1, "no ATM interfaces found");
549 TAILQ_FOREACH(aif, &diagif_list, link)
550 printf("%s ", aif->ifname);
555 * Print the config line for the given interface
558 phy_show_line(const struct diagif *aif)
560 printf("%-6u%-9s", aif->index, aif->ifname);
561 if (aif->phy_present)
562 printf("%-5u%-25s0x%-9x", aif->phy_type,
563 aif->phy_name, aif->phy_loopback);
568 diag_phy_show(int argc, char *argv[])
572 static const struct option opts[] = {
576 static const char phy_show_text[] =
578 "Index Name Type Name Loopback State\n";
580 while ((opt = parse_options(&argc, &argv, opts)) != -1)
585 if (TAILQ_EMPTY(&diagif_list))
586 errx(1, "no ATM interfaces found");
588 diag_loop(argc, argv, phy_show_text, phy_show_line);
592 * Make sure the interface exists and has a phy
594 static struct diagif *
595 diagif_get_phy(const char *arg)
600 TAILQ_FOREACH(aif, &diagif_list, link)
601 if (strcmp(aif->ifname, arg) == 0)
604 errx(1, "no such interface: %s", arg);
605 if (!aif->phy_present)
606 errx(1, "interface %s has no phy", arg);
612 diag_phy_set(int argc, char *argv[])
620 static const struct option opts[] = {
624 while ((opt = parse_options(&argc, &argv, opts)) != -1)
629 errx(1, "missing arguments for 'diag phy set'");
632 res = strtoul(argv[1], &end, 0);
634 err(1, "register number");
636 errx(1, "malformed register number '%s'", argv[1]);
638 errx(1, "register number too large");
642 res = strtoul(argv[2], &end, 0);
646 errx(1, "malformed mask '%s'", argv[1]);
648 errx(1, "mask too large");
652 res = strtoul(argv[3], &end, 0);
656 errx(1, "malformed value '%s'", argv[1]);
658 errx(1, "value too large");
661 (void)diagif_get_phy(argv[0]);
663 if (asprintf(&str, "hw.atm.%s.phy_regs", argv[0]) == -1)
666 if (sysctlbyname(str, NULL, NULL, reg, 3 * sizeof(uint8_t)))
673 diag_phy_print(int argc, char *argv[])
680 const struct utopia_print *p;
684 static const struct option opts[] = {
685 { "numeric", OPT_SIMPLE, &numeric },
689 while ((opt = parse_options(&argc, &argv, opts)) != -1)
694 errx(1, "need device name for 'diag phy print'");
696 (void)diagif_get_phy(argv[0]);
698 if (asprintf(&str, "hw.atm.%s.phy_regs", argv[0]) == -1)
701 if (sysctlbyname(str, NULL, &len, NULL, 0))
702 err(1, "'%s' not found", str);
708 if (sysctlbyname(str, regs, &len, NULL, 0))
709 err(1, "'%s' not found", str);
713 for (i = 0; i < len; i++) {
718 printf(" %02x", regs[i]);
725 if (asprintf(&str, "hw.atm.%s.phy_type", argv[0]) == -1)
728 if (sysctlbyname(str, &type, &len1, NULL, 0))
729 err(1, "'%s' not found", str);
732 for (i = 0; i < sizeof(phy_print) / sizeof(phy_print[0]); i++)
733 if (type == phy_print[i].type)
735 if (i == sizeof(phy_print) / sizeof(phy_print[0]))
736 errx(1, "unknown PHY chip type %u\n", type);
738 for (p = phy_print[i].tab;
739 p < phy_print[i].tab + phy_print[i].len;
741 if (p->reg + utopia_addreg[p->type] > len)
742 /* don't have this register */
745 printf("%s:%*s", p->name, 40 - (int)strlen(p->name),"");
750 printf("%s\n", printb8(regs[p->reg], p->fmt));
754 printf("%#x\n", regs[p->reg]);
757 case UTP_REGT_INT10BITS:
758 printf("%#x %s\n", regs[p->reg] |
759 ((regs[p->reg + 1] & 0x3) << 8),
760 printb8(regs[p->reg + 1], p->fmt));
764 printf("%#x\n", regs[p->reg] |
765 ((regs[p->reg + 1] & 0xf) << 8));
769 printf("%#x\n", regs[p->reg] |
770 (regs[p->reg + 1] << 8));
774 printf("%#x\n", regs[p->reg] |
775 (regs[p->reg + 1] << 8) |
776 ((regs[p->reg + 2] & 0x7) << 16));
780 printf("%#x\n", regs[p->reg] |
781 (regs[p->reg + 1] << 8) |
782 ((regs[p->reg + 2] & 0xf) << 16));
786 printf("%#x\n", regs[p->reg] |
787 (regs[p->reg + 1] << 8) |
788 ((regs[p->reg + 2] & 0x1f) << 16));
800 diag_phy_stats(int argc, char *argv[])
805 struct utopia_stats1 stats1;
810 static const struct option opts[] = {
811 { "clear", OPT_SIMPLE, &clear },
815 while ((opt = parse_options(&argc, &argv, opts)) != -1)
820 errx(1, "need device name for 'diag phy stats'");
822 (void)diagif_get_phy(argv[0]);
824 if (asprintf(&str, "hw.atm.%s.phy_stats", argv[0]) == -1)
827 len = sizeof(stats1);
828 if (sysctlbyname(str, &stats1, &len,
829 clear ? &foo : NULL, clear ? sizeof(foo) : 0))
830 err(1, "'%s' not found", str);
831 if (len < sizeof(stats1.version))
832 errx(1, "phy statistics too short %zu", len);
834 switch (stats1.version) {
837 if (len != sizeof(stats1))
838 errx(1, "bad phy stats length %zu (expecting %zu)",
839 len, sizeof(stats1));
843 errx(1, "unknown phy stats version %u", stats1.version);
848 printf("rx_sbip: %llu\n", (unsigned long long)stats1.rx_sbip);
849 printf("rx_lbip: %llu\n", (unsigned long long)stats1.rx_lbip);
850 printf("rx_lfebe: %llu\n", (unsigned long long)stats1.rx_lfebe);
851 printf("rx_pbip: %llu\n", (unsigned long long)stats1.rx_pbip);
852 printf("rx_pfebe: %llu\n", (unsigned long long)stats1.rx_pfebe);
853 printf("rx_cells: %llu\n", (unsigned long long)stats1.rx_cells);
854 printf("rx_corr: %llu\n", (unsigned long long)stats1.rx_corr);
855 printf("rx_uncorr: %llu\n", (unsigned long long)stats1.rx_uncorr);
856 printf("rx_symerr: %llu\n", (unsigned long long)stats1.rx_symerr);
857 printf("tx_cells: %llu\n", (unsigned long long)stats1.tx_cells);
861 * Fetch the table of open vccs
864 diagif_fetch_vcc(struct diagif *aif, int fd)
868 if (aif->vtab != NULL)
871 strncpy(ifr.ifr_name, aif->ifname, IFNAMSIZ);
872 ifr.ifr_name[IFNAMSIZ] = '\0';
874 aif->vtab = malloc(sizeof(*aif->vtab) + sizeof(aif->vtab->vccs[0]) *
876 if (aif->vtab == NULL)
878 ifr.ifr_data = (caddr_t)aif->vtab;
880 if (ioctl(fd, SIOCATMGVCCS, &ifr) == -1)
881 err(1, "SIOCATMGVCCS");
885 * Print the VCC table for this interface.
888 print_channel(const struct diagif *aif)
890 const struct atmio_vcc *v;
892 static const char *const aal_tab[] = {
894 [ATMIO_AAL_34] "3/4",
896 [ATMIO_AAL_RAW] "raw",
898 static const char *const traffic_tab[] = {
899 [ATMIO_TRAFFIC_UBR] "ubr",
900 [ATMIO_TRAFFIC_CBR] "cbr",
901 [ATMIO_TRAFFIC_ABR] "abr",
902 [ATMIO_TRAFFIC_VBR] "vbr",
905 for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) {
906 printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname,
909 if (v->aal >= sizeof(aal_tab)/sizeof(aal_tab[0]) ||
910 aal_tab[v->aal] == NULL)
913 printf("%-4s", aal_tab[v->aal]);
915 if (v->traffic >= sizeof(traffic_tab)/sizeof(traffic_tab[0]) ||
916 traffic_tab[v->traffic] == NULL)
919 printf("%-8s", traffic_tab[v->traffic]);
921 printf("%-6u%-6u%s\n", v->rmtu, v->tmtu,
922 printb(v->flags, ATMIO_FLAGS));
927 * Print the VCC table for this interface, traffic parameters.
930 print_traffic(const struct diagif *aif)
932 const struct atmio_vcc *v;
934 for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) {
935 printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname,
938 switch (v->traffic) {
940 case ATMIO_TRAFFIC_CBR:
941 printf("%u", v->tparam.pcr);
944 case ATMIO_TRAFFIC_UBR:
945 printf("%-8u %u", v->tparam.pcr,
949 case ATMIO_TRAFFIC_VBR:
950 printf("%-8u%-8u%-8u", v->tparam.pcr, v->tparam.scr,
954 case ATMIO_TRAFFIC_ABR:
956 v->tparam.pcr, v->tparam.mcr);
964 * Print the VCC table for this interface, ABR traffic parameters.
967 print_abr(const struct diagif *aif)
969 const struct atmio_vcc *v;
971 for (v = aif->vtab->vccs; v < &aif->vtab->vccs[aif->vtab->count]; v++) {
972 printf("%-6u%-9s%-4u%-6u", aif->index, aif->ifname,
975 if (v->traffic == ATMIO_TRAFFIC_ABR) {
976 printf("%-8u%-8u%-4u%-4u%-5u%-5u%-5u%u",
977 v->tparam.icr, v->tparam.tbe, v->tparam.nrm,
978 v->tparam.trm, v->tparam.adtf, v->tparam.rif,
979 v->tparam.rdf, v->tparam.cdf);
986 diag_vcc_loop(void (*func)(const struct diagif *), const char *text,
987 int argc, char *argv[], int fd)
993 TAILQ_FOREACH(aif, &diagif_list, link) {
994 diagif_fetch_vcc(aif, fd);
995 if (aif->vtab->count != 0) {
1002 for (optind = 0; optind < argc; optind++) {
1003 TAILQ_FOREACH(aif, &diagif_list, link)
1004 if (strcmp(aif->ifname, argv[optind]) == 0) {
1005 diagif_fetch_vcc(aif, fd);
1006 if (aif->vtab->count != 0) {
1013 warnx("no such interface '%s'", argv[optind]);
1019 diag_vcc(int argc, char *argv[])
1023 static int channel, traffic, abr;
1024 static const struct option opts[] = {
1025 { "abr", OPT_SIMPLE, &abr },
1026 { "channel", OPT_SIMPLE, &channel },
1027 { "traffic", OPT_SIMPLE, &traffic },
1030 static const char head_channel[] =
1032 "Index Name VPI VCI AAL Traffic RxMTU TxMTU Flags\n";
1033 static const char head_traffic[] =
1034 "Interface Traffic parameters\n"
1035 "Index Name VPI VCI PCR SCR MBS MCR\n";
1036 static const char head_abr[] =
1037 "Interface ABR traffic parameters\n"
1038 "Index Name VPI VCI ICR TBE NRM TRM ADTF RIF RDF "
1041 while ((opt = parse_options(&argc, &argv, opts)) != -1)
1045 fd = socket(PF_NATM, SOCK_STREAM, PROTO_NATMAAL5);
1050 if (TAILQ_EMPTY(&diagif_list))
1051 errx(1, "no ATM interfaces found");
1053 if (!channel && !traffic && !abr)
1057 diag_vcc_loop(print_channel, head_channel, argc, argv, fd);
1059 diag_vcc_loop(print_traffic, head_traffic, argc, argv, fd);
1061 diag_vcc_loop(print_abr, head_abr, argc, argv, fd);
1065 * Print driver-internal statistics
1068 diag_stats(int argc, char *argv[])
1077 static const struct option opts[] = {
1081 while ((opt = parse_options(&argc, &argv, opts)) != -1)
1086 errx(1, "need one arg for 'diag stats'");
1089 TAILQ_FOREACH(aif, &diagif_list, link)
1090 if (strcmp(aif->ifname, argv[0]) == 0)
1094 errx(1, "interface '%s' not found", argv[0]);
1096 if (asprintf(&str, "hw.atm.%s.istats", argv[0]) == -1)
1099 if (sysctlbyname(str, NULL, &len, NULL, 0))
1100 err(1, "'%s' not found", str);
1102 stats = malloc(len);
1106 if (sysctlbyname(str, stats, &len, NULL, 0))
1107 err(1, "'%s' not found", str);
1110 if (aif->mib.device >= sizeof(print_stats) / sizeof(print_stats[0]) ||
1111 print_stats[aif->mib.device] == NULL)
1112 errx(1, "unknown stats format (%u)", aif->mib.device);
1114 for (i = 0; print_stats[aif->mib.device][i] != NULL; i++) {
1115 if (i * sizeof(uint32_t) >= len)
1116 errx(1, "debug info too short (version mismatch?)");
1117 printf("%-22s%u\n", print_stats[aif->mib.device][i], stats[i]);
1121 if (i != len / sizeof(uint32_t))
1122 errx(1, "debug info too long (version mismatch?)");