// vim:ts=8:expandtab #include #include #include #include #include #include #include #include #include #include #include #include "i3status.h" #if defined(LINUX) #include #include #define PART_ETHSPEED "E: %s (%d Mbit/s)" #endif #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #include #define IFM_TYPE_MATCH(dt, t) \ (IFM_TYPE((dt)) == 0 || IFM_TYPE((dt)) == IFM_TYPE((t))) #define PART_ETHSPEED "E: %s (%s)" #endif static int print_eth_speed(char *outwalk, const char *interface) { #if defined(LINUX) int ethspeed = 0; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) char *ethspeed; #endif #if defined(LINUX) /* This code path requires root privileges */ struct ifreq ifr; struct ethtool_cmd ecmd; ecmd.cmd = ETHTOOL_GSET; (void)memset(&ifr, 0, sizeof(ifr)); ifr.ifr_data = (caddr_t)&ecmd; (void)strcpy(ifr.ifr_name, interface); if (ioctl(general_socket, SIOCETHTOOL, &ifr) == 0) { ethspeed = (ecmd.speed == USHRT_MAX ? 0 : ecmd.speed); return sprintf(outwalk, "%d Mbit/s", ethspeed); } else return sprintf(outwalk, "?"); #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) struct ifmediareq ifm; (void)memset(&ifm, 0, sizeof(ifm)); (void)strncpy(ifm.ifm_name, interface, sizeof(ifm.ifm_name)); int ret = ioctl(general_socket, SIOCGIFMEDIA, (caddr_t)&ifm); /* Get the description of the media type, partially taken from * FreeBSD's ifconfig */ const struct ifmedia_description *desc; struct ifmedia_description ifm_subtype_descriptions[] = IFM_SUBTYPE_ETHERNET_DESCRIPTIONS; for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL; desc++) { if (IFM_TYPE_MATCH(desc->ifmt_word, ifm.ifm_active) && IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(ifm.ifm_active)) break; } ethspeed = (desc->ifmt_string != NULL ? desc->ifmt_string : "?"); return sprintf(outwalk, "%s", ethspeed); #endif } /* * Combines ethernet IP addresses and speed (if requested) for displaying * */ void print_eth_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down) { const char *walk; const char *ip_address = get_ip_addr(interface); char *outwalk = buffer; INSTANCE(interface); if (ip_address == NULL) { START_COLOR("color_bad"); outwalk += sprintf(outwalk, "%s", format_down); goto out; } START_COLOR("color_good"); for (walk = format_up; *walk != '\0'; walk++) { if (*walk != '%') { *(outwalk++) = *walk; continue; } if (strncmp(walk+1, "ip", strlen("ip")) == 0) { outwalk += sprintf(outwalk, "%s", ip_address); walk += strlen("ip"); } else if (strncmp(walk+1, "speed", strlen("speed")) == 0) { outwalk += print_eth_speed(outwalk, interface); walk += strlen("speed"); } } out: END_COLOR; OUTPUT_FULL_TEXT(buffer); }