diff options
| author | Michael Stapelberg | 2009-07-22 18:36:01 +0200 | 
|---|---|---|
| committer | Michael Stapelberg | 2009-07-22 18:36:01 +0200 | 
| commit | c9ab465cbba2dc38c5564582531e1b44c8d63ce8 (patch) | |
| tree | 21a5d64bab4db13e192142e4e3ac72a084b8503c | |
| parent | Free the addresses correctly (diff) | |
Implement getting the interface speed on FreeBSD, patch by Baptiste Daroussin
| -rw-r--r-- | src/get_eth_info.c | 74 | 
1 files changed, 63 insertions, 11 deletions
| diff --git a/src/get_eth_info.c b/src/get_eth_info.c index 5e9ab54..9172abb 100644 --- a/src/get_eth_info.c +++ b/src/get_eth_info.c @@ -4,14 +4,41 @@  #include <stdio.h>  #include <sys/ioctl.h>  #include <sys/types.h> +#include <sys/socket.h>  #include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> -#ifdef LINUX +#include "i3status.h" + +#if defined(LINUX)  #include <linux/ethtool.h>  #include <linux/sockios.h> +#define PART_ETHSPEED  "E: %s (%d Mbit/s)"  #endif -#include "i3status.h" +#if defined(__FreeBSD__) +#include <net/if_media.h> +#define IFM_TYPE_MATCH(dt, t)                       \ +        (IFM_TYPE((dt)) == 0 || IFM_TYPE((dt)) == IFM_TYPE((t))) + +#define PART_ETHSPEED  "E: %s (%s)" + +struct ifmedia_type_to_subtype { +    struct { +        struct ifmedia_description *desc; +        int alias; +    } subtypes[5]; +    struct { +        struct ifmedia_description *desc; +        int alias; +    } options[3]; +    struct { +        struct ifmedia_description *desc; +        int alias; +    } modes[3]; +}; +#endif  /*   * Combines ethernet IP addresses and speed (if requested) for displaying @@ -19,11 +46,20 @@   */  const char *get_eth_info() {          static char part[512]; +#if defined(LINUX) +        int ethspeed=0; +#elif defined(__FreeBSD__) +        char *ethspeed; +#endif          const char *ip_address = get_ip_addr(eth_interface); -        int ethspeed = 0; + +        if (ip_address == NULL) { +                (void)snprintf(part, sizeof(part), "E: down"); +                return part; +        }          if (get_ethspeed) { -#ifdef LINUX +#if defined(LINUX)                  /* This code path requires root privileges */                  struct ifreq ifr;                  struct ethtool_cmd ecmd; @@ -35,16 +71,32 @@ const char *get_eth_info() {                  if (ioctl(general_socket, SIOCETHTOOL, &ifr) == 0)                          ethspeed = (ecmd.speed == USHRT_MAX ? 0 : ecmd.speed);                  else get_ethspeed = false; +#elif defined(__FreeBSD__) +                struct ifmediareq ifm; +                (void)memset(&ifm, 0, sizeof(ifm)); +                (void)strncpy(ifm.ifm_name, ifaddr->ifa_name, 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 : "?");  #endif          } -        if (ip_address == NULL) -                (void)snprintf(part, sizeof(part), "E: down"); -        else { -                if (get_ethspeed) -                        (void)snprintf(part, sizeof(part), "E: %s (%d Mbit/s)", ip_address, ethspeed); -                else (void)snprintf(part, sizeof(part), "E: %s", ip_address); -        } +        if (get_ethspeed) +                (void)snprintf(part, sizeof(part), PART_ETHSPEED, ip_address, ethspeed); +        else (void)snprintf(part, sizeof(part), "E: %s", ip_address);          return part;  } | 
