ifconfig: add report of the string from SIOCGIFDOWNREASON.

Sample output:
# ifconfig mce0
mce0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3ed07bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,VLAN_HWFILTER,VLAN_HWTSO,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6,TXRTLMT,HWRXTSTMP>
        ether e4:1d:2d:e7:10:0a
        media: Ethernet autoselect <full-duplex,rxpause,txpause>
        status: no carrier (Negotiation failure)
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>

Reviewed by:	hselasky, rrs
Sponsored by:	Mellanox Technologies
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D21527
This commit is contained in:
Konstantin Belousov 2019-09-17 18:51:10 +00:00
parent 247cf5664e
commit 093aa3e311
1 changed files with 27 additions and 5 deletions

View File

@ -80,6 +80,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -110,18 +111,20 @@ static void
media_status(int s)
{
struct ifmediareq ifmr;
struct ifdownreason ifdr;
int *media_list, i;
int xmedia = 1;
bool no_carrier, xmedia;
(void) memset(&ifmr, 0, sizeof(ifmr));
(void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
xmedia = true;
/*
* Check if interface supports extended media types.
*/
if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
xmedia = 0;
if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
xmedia = false;
if (!xmedia && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
@ -158,6 +161,7 @@ media_status(int s)
putchar('\n');
if (ifmr.ifm_status & IFM_AVALID) {
no_carrier = false;
printf("\tstatus: ");
switch (IFM_TYPE(ifmr.ifm_active)) {
case IFM_ETHER:
@ -165,7 +169,7 @@ media_status(int s)
if (ifmr.ifm_status & IFM_ACTIVE)
printf("active");
else
printf("no carrier");
no_carrier = true;
break;
case IFM_IEEE80211:
@ -176,9 +180,27 @@ media_status(int s)
else
printf("running");
} else
printf("no carrier");
no_carrier = true;
break;
}
if (no_carrier) {
printf("no carrier");
memset(&ifdr, 0, sizeof(ifdr));
strlcpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
if (ioctl(s, SIOCGIFDOWNREASON, (caddr_t)&ifdr) == 0) {
switch (ifdr.ifdr_reason) {
case IFDR_REASON_MSG:
printf(" (%s)", ifdr.ifdr_msg);
break;
case IFDR_REASON_VENDOR:
printf(" (vendor code %d)",
ifdr.ifdr_vendor);
break;
default:
break;
}
}
}
putchar('\n');
}