| 61 | extern char *f_ether; |
| 62 | |
| 63 | static void |
| 64 | link_status(int s __unused, const struct ifaddrs *ifa) |
| 65 | { |
| 66 | /* XXX no const 'cuz LLADDR is defined wrong */ |
| 67 | struct sockaddr_dl *sdl; |
| 68 | char *ether_format, *format_char; |
| 69 | struct ifreq ifr; |
| 70 | int n, rc, sock_hw; |
| 71 | static const u_char laggaddr[6] = {0}; |
| 72 | |
| 73 | sdl = (struct sockaddr_dl *) ifa->ifa_addr; |
| 74 | if (sdl == NULL || sdl->sdl_alen == 0) |
| 75 | return; |
| 76 | |
| 77 | if ((sdl->sdl_type == IFT_ETHER || sdl->sdl_type == IFT_L2VLAN || |
| 78 | sdl->sdl_type == IFT_BRIDGE) && sdl->sdl_alen == ETHER_ADDR_LEN) { |
| 79 | ether_format = ether_ntoa((struct ether_addr *)LLADDR(sdl)); |
| 80 | if (f_ether != NULL && strcmp(f_ether, "dash") == 0) { |
| 81 | while ((format_char = strchr(ether_format, ':')) != |
| 82 | NULL) { |
| 83 | *format_char = '-'; |
| 84 | } |
| 85 | } |
| 86 | printf("\tether %s\n", ether_format); |
| 87 | } else { |
| 88 | n = sdl->sdl_nlen > 0 ? sdl->sdl_nlen + 1 : 0; |
| 89 | printf("\tlladdr %s\n", link_ntoa(sdl) + n); |
| 90 | } |
| 91 | |
| 92 | /* |
| 93 | * Best-effort (i.e. failures are silent) to get original |
| 94 | * hardware address, as read by NIC driver at attach time. Only |
| 95 | * applies to Ethernet NICs (IFT_ETHER). However, laggX |
| 96 | * interfaces claim to be IFT_ETHER, and re-type their component |
| 97 | * Ethernet NICs as IFT_IEEE8023ADLAG. So, check for both. If |
| 98 | * the MAC is zeroed, then it's actually a lagg. |
| 99 | */ |
| 100 | if ((sdl->sdl_type != IFT_ETHER && |
| 101 | sdl->sdl_type != IFT_IEEE8023ADLAG) || |
| 102 | sdl->sdl_alen != ETHER_ADDR_LEN) |
| 103 | return; |
| 104 | |
| 105 | strncpy(ifr.ifr_name, ifa->ifa_name, sizeof(ifr.ifr_name)); |
| 106 | memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(ifa->ifa_addr->sa_len)); |
| 107 | ifr.ifr_addr.sa_family = AF_LOCAL; |
| 108 | if ((sock_hw = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) { |
| 109 | warn("socket(AF_LOCAL,SOCK_DGRAM)"); |
| 110 | return; |
| 111 | } |
| 112 | rc = ioctl(sock_hw, SIOCGHWADDR, &ifr); |
| 113 | close(sock_hw); |
| 114 | if (rc != 0) |
| 115 | return; |
| 116 | |
| 117 | /* |
| 118 | * If this is definitely a lagg device or the hwaddr |
| 119 | * matches the link addr, don't bother. |
| 120 | */ |