112f961f4SSam Leffler /*- 212f961f4SSam Leffler * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 312f961f4SSam Leffler * All rights reserved. 412f961f4SSam Leffler * 512f961f4SSam Leffler * Redistribution and use in source and binary forms, with or without 612f961f4SSam Leffler * modification, are permitted provided that the following conditions 712f961f4SSam Leffler * are met: 812f961f4SSam Leffler * 1. Redistributions of source code must retain the above copyright 912f961f4SSam Leffler * notice, this list of conditions and the following disclaimer, 1012f961f4SSam Leffler * without modification. 1112f961f4SSam Leffler * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1212f961f4SSam Leffler * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 1312f961f4SSam Leffler * redistribution must be conditioned upon including a substantially 1412f961f4SSam Leffler * similar Disclaimer requirement for further binary redistribution. 1512f961f4SSam Leffler * 3. Neither the names of the above-listed copyright holders nor the names 1612f961f4SSam Leffler * of any contributors may be used to endorse or promote products derived 1712f961f4SSam Leffler * from this software without specific prior written permission. 1812f961f4SSam Leffler * 1912f961f4SSam Leffler * Alternatively, this software may be distributed under the terms of the 2012f961f4SSam Leffler * GNU General Public License ("GPL") version 2 as published by the Free 2112f961f4SSam Leffler * Software Foundation. 2212f961f4SSam Leffler * 2312f961f4SSam Leffler * NO WARRANTY 2412f961f4SSam Leffler * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2512f961f4SSam Leffler * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2612f961f4SSam Leffler * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 2712f961f4SSam Leffler * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 2812f961f4SSam Leffler * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 2912f961f4SSam Leffler * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3012f961f4SSam Leffler * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3112f961f4SSam Leffler * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 3212f961f4SSam Leffler * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3312f961f4SSam Leffler * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3412f961f4SSam Leffler * THE POSSIBILITY OF SUCH DAMAGES. 3512f961f4SSam Leffler * 3612f961f4SSam Leffler * $FreeBSD$ 3712f961f4SSam Leffler */ 3812f961f4SSam Leffler 3912f961f4SSam Leffler /* 4012f961f4SSam Leffler * Simple Atheros-specific tool to inspect and monitor network traffic 4112f961f4SSam Leffler * statistics. 4212f961f4SSam Leffler * athstats [-i interface] [interval] 4312f961f4SSam Leffler * (default interface is ath0). If interval is specified a rolling output 4412f961f4SSam Leffler * a la netstat -i is displayed every interval seconds. 4512f961f4SSam Leffler * 4612f961f4SSam Leffler * To build: cc -o athstats athstats.c -lkvm 4712f961f4SSam Leffler */ 4812f961f4SSam Leffler #include <sys/types.h> 4912f961f4SSam Leffler #include <sys/file.h> 5012f961f4SSam Leffler #include <sys/sockio.h> 5112f961f4SSam Leffler #include <sys/socket.h> 5212f961f4SSam Leffler #include <net/if.h> 5312f961f4SSam Leffler #include <net/if_media.h> 5412f961f4SSam Leffler #include <net/if_var.h> 5512f961f4SSam Leffler 5612f961f4SSam Leffler #include <stdio.h> 5712f961f4SSam Leffler #include <signal.h> 5812f961f4SSam Leffler 5944301bc9SSam Leffler #include "../../../../sys/contrib/dev/ath/ah_desc.h" 6044301bc9SSam Leffler #include "../../../../sys/net80211/ieee80211_ioctl.h" 6144301bc9SSam Leffler #include "../../../../sys/net80211/ieee80211_radiotap.h" 6244301bc9SSam Leffler #include "../../../../sys/dev/ath/if_athioctl.h" 6312f961f4SSam Leffler 6412f961f4SSam Leffler static const struct { 6512f961f4SSam Leffler u_int phyerr; 6612f961f4SSam Leffler const char* desc; 6712f961f4SSam Leffler } phyerrdescriptions[] = { 6812f961f4SSam Leffler { HAL_PHYERR_UNDERRUN, "transmit underrun" }, 6912f961f4SSam Leffler { HAL_PHYERR_TIMING, "timing error" }, 7012f961f4SSam Leffler { HAL_PHYERR_PARITY, "illegal parity" }, 7112f961f4SSam Leffler { HAL_PHYERR_RATE, "illegal rate" }, 7212f961f4SSam Leffler { HAL_PHYERR_LENGTH, "illegal length" }, 7312f961f4SSam Leffler { HAL_PHYERR_RADAR, "radar detect" }, 7412f961f4SSam Leffler { HAL_PHYERR_SERVICE, "illegal service" }, 7512f961f4SSam Leffler { HAL_PHYERR_TOR, "transmit override receive" }, 7612f961f4SSam Leffler { HAL_PHYERR_OFDM_TIMING, "OFDM timing" }, 7712f961f4SSam Leffler { HAL_PHYERR_OFDM_SIGNAL_PARITY,"OFDM illegal parity" }, 7812f961f4SSam Leffler { HAL_PHYERR_OFDM_RATE_ILLEGAL, "OFDM illegal rate" }, 7912f961f4SSam Leffler { HAL_PHYERR_OFDM_POWER_DROP, "OFDM power drop" }, 8012f961f4SSam Leffler { HAL_PHYERR_OFDM_SERVICE, "OFDM illegal service" }, 8112f961f4SSam Leffler { HAL_PHYERR_OFDM_RESTART, "OFDM restart" }, 8212f961f4SSam Leffler { HAL_PHYERR_CCK_TIMING, "CCK timing" }, 8312f961f4SSam Leffler { HAL_PHYERR_CCK_HEADER_CRC, "CCK header crc" }, 8412f961f4SSam Leffler { HAL_PHYERR_CCK_RATE_ILLEGAL, "CCK illegal rate" }, 8512f961f4SSam Leffler { HAL_PHYERR_CCK_SERVICE, "CCK illegal service" }, 8612f961f4SSam Leffler { HAL_PHYERR_CCK_RESTART, "CCK restart" }, 8712f961f4SSam Leffler }; 8812f961f4SSam Leffler 8912f961f4SSam Leffler static void 9012f961f4SSam Leffler printstats(FILE *fd, const struct ath_stats *stats) 9112f961f4SSam Leffler { 9212f961f4SSam Leffler #define N(a) (sizeof(a) / sizeof(a[0])) 9312f961f4SSam Leffler #define STAT(x,fmt) \ 9412f961f4SSam Leffler if (stats->ast_##x) fprintf(fd, "%u " fmt "\n", stats->ast_##x) 9512f961f4SSam Leffler int i, j; 9612f961f4SSam Leffler 9712f961f4SSam Leffler STAT(watchdog, "watchdog timeouts"); 9812f961f4SSam Leffler STAT(hardware, "hardware error interrupts"); 9912f961f4SSam Leffler STAT(bmiss, "beacon miss interrupts"); 10012f961f4SSam Leffler STAT(bstuck, "stuck beacon conditions"); 10112f961f4SSam Leffler STAT(rxorn, "recv overrun interrupts"); 10212f961f4SSam Leffler STAT(rxeol, "recv eol interrupts"); 10312f961f4SSam Leffler STAT(txurn, "txmit underrun interrupts"); 10412f961f4SSam Leffler STAT(mib, "mib overflow interrupts"); 10512f961f4SSam Leffler STAT(intrcoal, "interrupts coalesced"); 10612f961f4SSam Leffler STAT(tx_mgmt, "tx management frames"); 10712f961f4SSam Leffler STAT(tx_discard, "tx frames discarded prior to association"); 10812f961f4SSam Leffler STAT(tx_qstop, "tx stopped 'cuz no xmit buffer"); 10912f961f4SSam Leffler STAT(tx_encap, "tx encapsulation failed"); 11012f961f4SSam Leffler STAT(tx_nonode, "tx failed 'cuz no node"); 11112f961f4SSam Leffler STAT(tx_nombuf, "tx failed 'cuz no mbuf"); 11212f961f4SSam Leffler STAT(tx_nomcl, "tx failed 'cuz no cluster"); 11312f961f4SSam Leffler STAT(tx_linear, "tx linearized to cluster"); 11412f961f4SSam Leffler STAT(tx_nodata, "tx discarded empty frame"); 11512f961f4SSam Leffler STAT(tx_busdma, "tx failed for dma resrcs"); 11612f961f4SSam Leffler STAT(tx_xretries, "tx failed 'cuz too many retries"); 11712f961f4SSam Leffler STAT(tx_fifoerr, "tx failed 'cuz FIFO underrun"); 11812f961f4SSam Leffler STAT(tx_filtered, "tx failed 'cuz xmit filtered"); 11912f961f4SSam Leffler STAT(tx_shortretry, "short on-chip tx retries"); 12012f961f4SSam Leffler STAT(tx_longretry, "long on-chip tx retries"); 12112f961f4SSam Leffler STAT(tx_badrate, "tx failed 'cuz bogus xmit rate"); 12212f961f4SSam Leffler STAT(tx_noack, "tx frames with no ack marked"); 12312f961f4SSam Leffler STAT(tx_rts, "tx frames with rts enabled"); 12412f961f4SSam Leffler STAT(tx_cts, "tx frames with cts enabled"); 12512f961f4SSam Leffler STAT(tx_shortpre, "tx frames with short preamble"); 12612f961f4SSam Leffler STAT(tx_altrate, "tx frames with an alternate rate"); 12712f961f4SSam Leffler STAT(tx_protect, "tx frames with 11g protection"); 12812f961f4SSam Leffler STAT(rx_nombuf, "rx setup failed 'cuz no mbuf"); 12912f961f4SSam Leffler STAT(rx_busdma, "rx setup failed for dma resrcs"); 13012f961f4SSam Leffler STAT(rx_orn, "rx failed 'cuz of desc overrun"); 13112f961f4SSam Leffler STAT(rx_crcerr, "rx failed 'cuz of bad CRC"); 13212f961f4SSam Leffler STAT(rx_fifoerr, "rx failed 'cuz of FIFO overrun"); 13312f961f4SSam Leffler STAT(rx_badcrypt, "rx failed 'cuz decryption"); 13412f961f4SSam Leffler STAT(rx_badmic, "rx failed 'cuz MIC failure"); 13512f961f4SSam Leffler STAT(rx_tooshort, "rx failed 'cuz frame too short"); 13612f961f4SSam Leffler STAT(rx_toobig, "rx failed 'cuz frame too large"); 13712f961f4SSam Leffler STAT(rx_mgt, "rx management frames"); 13812f961f4SSam Leffler STAT(rx_ctl, "rx control frames"); 13912f961f4SSam Leffler STAT(rx_phyerr, "rx failed 'cuz of PHY err"); 14012f961f4SSam Leffler if (stats->ast_rx_phyerr != 0) { 14112f961f4SSam Leffler for (i = 0; i < 32; i++) { 14212f961f4SSam Leffler if (stats->ast_rx_phy[i] == 0) 14312f961f4SSam Leffler continue; 14412f961f4SSam Leffler for (j = 0; j < N(phyerrdescriptions); j++) 14512f961f4SSam Leffler if (phyerrdescriptions[j].phyerr == i) 14612f961f4SSam Leffler break; 14712f961f4SSam Leffler if (j == N(phyerrdescriptions)) 14812f961f4SSam Leffler fprintf(fd, 14912f961f4SSam Leffler " %u (unknown phy error code %u)\n", 15012f961f4SSam Leffler stats->ast_rx_phy[i], i); 15112f961f4SSam Leffler else 15212f961f4SSam Leffler fprintf(fd, " %u %s\n", 15312f961f4SSam Leffler stats->ast_rx_phy[i], 15412f961f4SSam Leffler phyerrdescriptions[j].desc); 15512f961f4SSam Leffler } 15612f961f4SSam Leffler } 15712f961f4SSam Leffler STAT(be_nombuf, "beacon setup failed 'cuz no mbuf"); 15812f961f4SSam Leffler STAT(be_xmit, "beacons transmitted"); 15912f961f4SSam Leffler STAT(per_cal, "periodic calibrations"); 16012f961f4SSam Leffler STAT(per_calfail, "periodic calibration failures"); 16112f961f4SSam Leffler STAT(per_rfgain, "rfgain value change"); 16212f961f4SSam Leffler STAT(rate_calls, "rate control checks"); 16312f961f4SSam Leffler STAT(rate_raise, "rate control raised xmit rate"); 16412f961f4SSam Leffler STAT(rate_drop, "rate control dropped xmit rate"); 16512f961f4SSam Leffler if (stats->ast_tx_rssi) 16612f961f4SSam Leffler fprintf(fd, "rssi of last ack: %u\n", stats->ast_tx_rssi); 16712f961f4SSam Leffler if (stats->ast_rx_rssi) 16812f961f4SSam Leffler fprintf(fd, "avg recv rssi: %u\n", stats->ast_rx_rssi); 16912f961f4SSam Leffler STAT(ant_defswitch, "switched default/rx antenna"); 17012f961f4SSam Leffler STAT(ant_txswitch, "tx used alternate antenna"); 17112f961f4SSam Leffler fprintf(fd, "Antenna profile:\n"); 17212f961f4SSam Leffler for (i = 0; i < 8; i++) 17312f961f4SSam Leffler if (stats->ast_ant_rx[i] || stats->ast_ant_tx[i]) 17412f961f4SSam Leffler fprintf(fd, "[%u] tx %8u rx %8u\n", i, 17512f961f4SSam Leffler stats->ast_ant_tx[i], stats->ast_ant_rx[i]); 17612f961f4SSam Leffler #undef STAT 17712f961f4SSam Leffler #undef N 17812f961f4SSam Leffler } 17912f961f4SSam Leffler 18012f961f4SSam Leffler static u_int 18112f961f4SSam Leffler getifrate(int s, const char* ifname) 18212f961f4SSam Leffler { 18312f961f4SSam Leffler #define N(a) (sizeof(a) / sizeof(a[0])) 18412f961f4SSam Leffler static const int rates[] = { 18512f961f4SSam Leffler 0, /* IFM_AUTO */ 18612f961f4SSam Leffler 0, /* IFM_MANUAL */ 18712f961f4SSam Leffler 0, /* IFM_NONE */ 18812f961f4SSam Leffler 1, /* IFM_IEEE80211_FH1 */ 18912f961f4SSam Leffler 2, /* IFM_IEEE80211_FH2 */ 19012f961f4SSam Leffler 1, /* IFM_IEEE80211_DS1 */ 19112f961f4SSam Leffler 2, /* IFM_IEEE80211_DS2 */ 19212f961f4SSam Leffler 5, /* IFM_IEEE80211_DS5 */ 19312f961f4SSam Leffler 11, /* IFM_IEEE80211_DS11 */ 19412f961f4SSam Leffler 22, /* IFM_IEEE80211_DS22 */ 19512f961f4SSam Leffler 6, /* IFM_IEEE80211_OFDM6 */ 19612f961f4SSam Leffler 9, /* IFM_IEEE80211_OFDM9 */ 19712f961f4SSam Leffler 12, /* IFM_IEEE80211_OFDM12 */ 19812f961f4SSam Leffler 18, /* IFM_IEEE80211_OFDM18 */ 19912f961f4SSam Leffler 24, /* IFM_IEEE80211_OFDM24 */ 20012f961f4SSam Leffler 36, /* IFM_IEEE80211_OFDM36 */ 20112f961f4SSam Leffler 48, /* IFM_IEEE80211_OFDM48 */ 20212f961f4SSam Leffler 54, /* IFM_IEEE80211_OFDM54 */ 20312f961f4SSam Leffler 72, /* IFM_IEEE80211_OFDM72 */ 20412f961f4SSam Leffler }; 20512f961f4SSam Leffler struct ifmediareq ifmr; 20612f961f4SSam Leffler int *media_list, i; 20712f961f4SSam Leffler 20812f961f4SSam Leffler (void) memset(&ifmr, 0, sizeof(ifmr)); 20912f961f4SSam Leffler (void) strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); 21012f961f4SSam Leffler 21112f961f4SSam Leffler if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) 21212f961f4SSam Leffler return 0; 21312f961f4SSam Leffler return IFM_SUBTYPE(ifmr.ifm_active) < N(rates) ? 21412f961f4SSam Leffler rates[IFM_SUBTYPE(ifmr.ifm_active)] : 0; 21512f961f4SSam Leffler #undef N 21612f961f4SSam Leffler } 21712f961f4SSam Leffler 21812f961f4SSam Leffler static int signalled; 21912f961f4SSam Leffler 22012f961f4SSam Leffler static void 22112f961f4SSam Leffler catchalarm(int signo __unused) 22212f961f4SSam Leffler { 22312f961f4SSam Leffler signalled = 1; 22412f961f4SSam Leffler } 22512f961f4SSam Leffler 22612f961f4SSam Leffler int 22712f961f4SSam Leffler main(int argc, char *argv[]) 22812f961f4SSam Leffler { 22912f961f4SSam Leffler int s; 23012f961f4SSam Leffler struct ifreq ifr; 23112f961f4SSam Leffler 23212f961f4SSam Leffler s = socket(AF_INET, SOCK_DGRAM, 0); 23312f961f4SSam Leffler if (s < 0) 23412f961f4SSam Leffler err(1, "socket"); 23512f961f4SSam Leffler if (argc > 1 && strcmp(argv[1], "-i") == 0) { 23612f961f4SSam Leffler if (argc < 2) { 23712f961f4SSam Leffler fprintf(stderr, "%s: missing interface name for -i\n", 23812f961f4SSam Leffler argv[0]); 23912f961f4SSam Leffler exit(-1); 24012f961f4SSam Leffler } 24112f961f4SSam Leffler strncpy(ifr.ifr_name, argv[2], sizeof (ifr.ifr_name)); 24212f961f4SSam Leffler argc -= 2, argv += 2; 24312f961f4SSam Leffler } else 24412f961f4SSam Leffler strncpy(ifr.ifr_name, "ath0", sizeof (ifr.ifr_name)); 24512f961f4SSam Leffler if (argc > 1) { 24612f961f4SSam Leffler u_long interval = strtoul(argv[1], NULL, 0); 24712f961f4SSam Leffler int line, omask; 24812f961f4SSam Leffler u_int rate = getifrate(s, ifr.ifr_name); 24912f961f4SSam Leffler struct ath_stats cur, total; 25012f961f4SSam Leffler 25112f961f4SSam Leffler if (interval < 1) 25212f961f4SSam Leffler interval = 1; 25312f961f4SSam Leffler signal(SIGALRM, catchalarm); 25412f961f4SSam Leffler signalled = 0; 25512f961f4SSam Leffler alarm(interval); 25612f961f4SSam Leffler banner: 25712f961f4SSam Leffler printf("%8s %8s %7s %7s %7s %6s %6s %5s %7s %4s %4s" 25812f961f4SSam Leffler , "input" 25912f961f4SSam Leffler , "output" 26012f961f4SSam Leffler , "altrate" 26112f961f4SSam Leffler , "short" 26212f961f4SSam Leffler , "long" 26312f961f4SSam Leffler , "xretry" 26412f961f4SSam Leffler , "crcerr" 26512f961f4SSam Leffler , "crypt" 26612f961f4SSam Leffler , "phyerr" 26712f961f4SSam Leffler , "rssi" 26812f961f4SSam Leffler , "rate" 26912f961f4SSam Leffler ); 27012f961f4SSam Leffler putchar('\n'); 27112f961f4SSam Leffler fflush(stdout); 27212f961f4SSam Leffler line = 0; 27312f961f4SSam Leffler loop: 27412f961f4SSam Leffler if (line != 0) { 27512f961f4SSam Leffler ifr.ifr_data = (caddr_t) &cur; 27612f961f4SSam Leffler if (ioctl(s, SIOCGATHSTATS, &ifr) < 0) 27712f961f4SSam Leffler err(1, ifr.ifr_name); 27812f961f4SSam Leffler rate = getifrate(s, ifr.ifr_name); 27912f961f4SSam Leffler printf("%8u %8u %7u %7u %7u %6u %6u %5u %7u %4u %3uM\n" 28012f961f4SSam Leffler , cur.ast_rx_packets - total.ast_rx_packets 28112f961f4SSam Leffler , cur.ast_tx_packets - total.ast_tx_packets 28212f961f4SSam Leffler , cur.ast_tx_altrate - total.ast_tx_altrate 28312f961f4SSam Leffler , cur.ast_tx_shortretry - total.ast_tx_shortretry 28412f961f4SSam Leffler , cur.ast_tx_longretry - total.ast_tx_longretry 28512f961f4SSam Leffler , cur.ast_tx_xretries - total.ast_tx_xretries 28612f961f4SSam Leffler , cur.ast_rx_crcerr - total.ast_rx_crcerr 28712f961f4SSam Leffler , cur.ast_rx_badcrypt - total.ast_rx_badcrypt 28812f961f4SSam Leffler , cur.ast_rx_phyerr - total.ast_rx_phyerr 28912f961f4SSam Leffler , cur.ast_rx_rssi 29012f961f4SSam Leffler , rate 29112f961f4SSam Leffler ); 29212f961f4SSam Leffler total = cur; 29312f961f4SSam Leffler } else { 29412f961f4SSam Leffler ifr.ifr_data = (caddr_t) &total; 29512f961f4SSam Leffler if (ioctl(s, SIOCGATHSTATS, &ifr) < 0) 29612f961f4SSam Leffler err(1, ifr.ifr_name); 29712f961f4SSam Leffler rate = getifrate(s, ifr.ifr_name); 29812f961f4SSam Leffler printf("%8u %8u %7u %7u %7u %6u %6u %5u %7u %4u %3uM\n" 29912f961f4SSam Leffler , total.ast_rx_packets 30012f961f4SSam Leffler , total.ast_tx_packets 30112f961f4SSam Leffler , total.ast_tx_altrate 30212f961f4SSam Leffler , total.ast_tx_shortretry 30312f961f4SSam Leffler , total.ast_tx_longretry 30412f961f4SSam Leffler , total.ast_tx_xretries 30512f961f4SSam Leffler , total.ast_rx_crcerr 30612f961f4SSam Leffler , total.ast_rx_badcrypt 30712f961f4SSam Leffler , total.ast_rx_phyerr 30812f961f4SSam Leffler , total.ast_rx_rssi 30912f961f4SSam Leffler , rate 31012f961f4SSam Leffler ); 31112f961f4SSam Leffler } 31212f961f4SSam Leffler fflush(stdout); 31312f961f4SSam Leffler omask = sigblock(sigmask(SIGALRM)); 31412f961f4SSam Leffler if (!signalled) 31512f961f4SSam Leffler sigpause(0); 31612f961f4SSam Leffler sigsetmask(omask); 31712f961f4SSam Leffler signalled = 0; 31812f961f4SSam Leffler alarm(interval); 31912f961f4SSam Leffler line++; 32012f961f4SSam Leffler if (line == 21) /* XXX tty line count */ 32112f961f4SSam Leffler goto banner; 32212f961f4SSam Leffler else 32312f961f4SSam Leffler goto loop; 32412f961f4SSam Leffler /*NOTREACHED*/ 32512f961f4SSam Leffler } else { 32612f961f4SSam Leffler struct ath_stats stats; 32712f961f4SSam Leffler 32812f961f4SSam Leffler ifr.ifr_data = (caddr_t) &stats; 32912f961f4SSam Leffler if (ioctl(s, SIOCGATHSTATS, &ifr) < 0) 33012f961f4SSam Leffler err(1, ifr.ifr_name); 33112f961f4SSam Leffler printstats(stdout, &stats); 33212f961f4SSam Leffler } 33312f961f4SSam Leffler return 0; 33412f961f4SSam Leffler } 335