Blame sysdeps/freebsd/netload.c

Packit Service 407539
/* Copyright (C) 1998-99 Martin Baulig
Packit Service 407539
   Copyright (C) 2014 Gleb Smirnoff
Packit Service 407539
   This file is part of LibGTop 1.0.
Packit Service 407539
Packit Service 407539
   Contributed by Martin Baulig <martin@home-of-linux.org>, October 1998.
Packit Service 407539
   Contributed by Gleb Smirnoff <glebius@FreeBSD.org>, September 2014
Packit Service 407539
Packit Service 407539
   LibGTop is free software; you can redistribute it and/or modify it
Packit Service 407539
   under the terms of the GNU General Public License as published by
Packit Service 407539
   the Free Software Foundation; either version 2 of the License,
Packit Service 407539
   or (at your option) any later version.
Packit Service 407539
Packit Service 407539
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit Service 407539
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service 407539
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service 407539
   for more details.
Packit Service 407539
Packit Service 407539
   You should have received a copy of the GNU General Public License
Packit Service 407539
   along with LibGTop; see the file COPYING. If not, write to the
Packit Service 407539
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit Service 407539
   Boston, MA 02110-1301, USA.
Packit Service 407539
*/
Packit Service 407539
Packit Service 407539
#include <config.h>
Packit Service 407539
#include <glibtop.h>
Packit Service 407539
#include <glibtop/error.h>
Packit Service 407539
#include <glibtop/netload.h>
Packit Service 407539
Packit Service 407539
#include <glibtop_suid.h>
Packit Service 407539
Packit Service 407539
#include <sys/ioctl.h>
Packit Service 407539
#include <sys/sockio.h>
Packit Service 407539
#include <netinet/in.h>
Packit Service 407539
#include <net/if.h>
Packit Service 407539
#include <net/if_dl.h>
Packit Service 407539
#include <net/if_media.h>
Packit Service 407539
#include <ifaddrs.h>
Packit Service 407539
Packit Service 407539
static const unsigned long _glibtop_sysdeps_netload =
Packit Service 407539
(1L << GLIBTOP_NETLOAD_IF_FLAGS) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_MTU) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_PACKETS_IN) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_PACKETS_OUT) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_BYTES_IN) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_BYTES_OUT) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_BYTES_TOTAL) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_ERRORS_IN) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_ERRORS_OUT) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_ERRORS_TOTAL) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_COLLISIONS) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_HWADDRESS);
Packit Service 407539
Packit Service 407539
static const unsigned long _glibtop_sysdeps_netload_data =
Packit Service 407539
(1L << GLIBTOP_NETLOAD_SUBNET) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_ADDRESS);
Packit Service 407539
Packit Service 407539
static const unsigned long _glibtop_sysdeps_netload6 =
Packit Service 407539
(1L << GLIBTOP_NETLOAD_ADDRESS6) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_PREFIX6) +
Packit Service 407539
(1L << GLIBTOP_NETLOAD_SCOPE6);
Packit Service 407539
Packit Service 407539
/* Init function. */
Packit Service 407539
Packit Service 407539
void
Packit Service 407539
_glibtop_init_netload_p (glibtop *server)
Packit Service 407539
{
Packit Service 407539
        server->sysdeps.netload = _glibtop_sysdeps_netload;
Packit Service 407539
}
Packit Service 407539
Packit Service 407539
/* Provides Network statistics. */
Packit Service 407539
Packit Service 407539
void
Packit Service 407539
glibtop_get_netload_p (glibtop *server, glibtop_netload *buf,
Packit Service 407539
                       const char *interface)
Packit Service 407539
{
Packit Service 407539
        struct ifaddrs *ifap, *ifa;
Packit Service 407539
Packit Service 407539
        memset (buf, 0, sizeof (glibtop_netload));
Packit Service 407539
Packit Service 407539
        if (server->sysdeps.netload == 0)
Packit Service 407539
                return;
Packit Service 407539
Packit Service 407539
        if (getifaddrs(&ifap) != 0) {
Packit Service 407539
                glibtop_warn_io_r (server, "getifaddrs");
Packit Service 407539
                return;
Packit Service 407539
        }
Packit Service 407539
Packit Service 407539
#define IFA_STAT(s)     (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
Packit Service 407539
Packit Service 407539
        for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
Packit Service 407539
                if (strcmp (ifa->ifa_name, interface) != 0)
Packit Service 407539
                        continue;
Packit Service 407539
Packit Service 407539
                switch (ifa->ifa_addr->sa_family) {
Packit Service 407539
                case AF_LINK: {
Packit Service 407539
                        struct sockaddr_dl *sdl;
Packit Service 407539
                        struct ifmediareq ifmr;
Packit Service 407539
                        struct ifreq ifr;
Packit Service 407539
                        int s, flags;
Packit Service 407539
Packit Service 407539
                        s = socket(AF_INET, SOCK_DGRAM, 0);
Packit Service 407539
                        if (s < 0) {
Packit Service 407539
                                glibtop_warn_io_r(server, "socket(AF_INET)");
Packit Service 407539
                                break;
Packit Service 407539
                        }
Packit Service 407539
Packit Service 407539
                        memset(&ifmr, 0, sizeof(ifmr));
Packit Service 407539
                        (void)strlcpy(ifmr.ifm_name, ifa->ifa_name,
Packit Service 407539
                                sizeof(ifmr.ifm_name));
Packit Service 407539
                        if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0 &&
Packit Service 407539
                            ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
Packit Service 407539
                                glibtop_warn_io_r(server, "ioctl(SIOCGIFMEDIA)");
Packit Service 407539
                        } else {
Packit Service 407539
                                if (IFM_TYPE (ifmr.ifm_current) & IFM_IEEE80211)
Packit Service 407539
                                    buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_WIRELESS);
Packit Service 407539
                                if (IFM_TYPE (ifmr.ifm_active) & IFM_IEEE80211)
Packit Service 407539
                                    buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_WIRELESS);
Packit Service 407539
                        }
Packit Service 407539
Packit Service 407539
                        memset(&ifr, 0, sizeof(ifr));
Packit Service 407539
                        (void)strlcpy(ifr.ifr_name, ifa->ifa_name,
Packit Service 407539
                                sizeof(ifr.ifr_name));
Packit Service 407539
                        if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
Packit Service 407539
                                glibtop_warn_io_r(server, "ioctl(SIOCGIFFLAGS)");
Packit Service 407539
                                close(s);
Packit Service 407539
                                break;
Packit Service 407539
                        }
Packit Service 407539
Packit Service 407539
                        close(s);
Packit Service 407539
Packit Service 407539
                        flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
Packit Service 407539
Packit Service 407539
                        if (flags & IFF_UP)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP);
Packit Service 407539
                        if (flags & IFF_BROADCAST)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST);
Packit Service 407539
                        if (flags & IFF_DEBUG)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG);
Packit Service 407539
                        if (flags & IFF_LOOPBACK)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK);
Packit Service 407539
                        if (flags & IFF_POINTOPOINT)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT);
Packit Service 407539
                        if (flags & IFF_RUNNING)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING);
Packit Service 407539
                        if (flags & IFF_NOARP)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP);
Packit Service 407539
                        if (flags & IFF_PROMISC)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC);
Packit Service 407539
                        if (flags & IFF_ALLMULTI)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI);
Packit Service 407539
                        if (flags & IFF_OACTIVE)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE);
Packit Service 407539
                        if (flags & IFF_SIMPLEX)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX);
Packit Service 407539
                        if (flags & IFF_LINK0)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0);
Packit Service 407539
                        if (flags & IFF_LINK1)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1);
Packit Service 407539
                        if (flags & IFF_LINK2)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2);
Packit Service 407539
                        if (flags & IFF_ALTPHYS)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS);
Packit Service 407539
                        if (flags & IFF_MULTICAST)
Packit Service 407539
                                buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST);
Packit Service 407539
Packit Service 407539
                        buf->packets_in = IFA_STAT(ipackets);
Packit Service 407539
                        buf->packets_out = IFA_STAT(opackets);
Packit Service 407539
                        buf->packets_total = buf->packets_in + buf->packets_out;
Packit Service 407539
Packit Service 407539
                        buf->bytes_in = IFA_STAT(ibytes);
Packit Service 407539
                        buf->bytes_out = IFA_STAT(obytes);
Packit Service 407539
                        buf->bytes_total = buf->bytes_in + buf->bytes_out;
Packit Service 407539
Packit Service 407539
                        buf->errors_in = IFA_STAT(ierrors);
Packit Service 407539
                        buf->errors_out = IFA_STAT(oerrors);
Packit Service 407539
                        buf->errors_total = buf->errors_in + buf->errors_out;
Packit Service 407539
Packit Service 407539
                        buf->collisions = IFA_STAT(collisions);
Packit Service 407539
Packit Service 407539
                        sdl = (struct sockaddr_dl *)(void *)ifa->ifa_addr;
Packit Service 407539
                        memcpy(buf->hwaddress, LLADDR(sdl),
Packit Service 407539
                                sizeof(buf->hwaddress));
Packit Service 407539
                        buf->mtu = IFA_STAT(mtu);
Packit Service 407539
                        buf->flags |= _glibtop_sysdeps_netload;
Packit Service 407539
                        break;
Packit Service 407539
                }
Packit Service 407539
                case AF_INET: {
Packit Service 407539
                        struct sockaddr_in *sin;
Packit Service 407539
Packit Service 407539
                        sin = (struct sockaddr_in *)(void *)ifa->ifa_addr;
Packit Service 407539
                        buf->address = sin->sin_addr.s_addr;
Packit Service 407539
                        sin = (struct sockaddr_in *)(void *)ifa->ifa_netmask;
Packit Service 407539
                        buf->subnet = sin->sin_addr.s_addr & buf->address;
Packit Service 407539
                        buf->flags |= _glibtop_sysdeps_netload_data;
Packit Service 407539
                        break;
Packit Service 407539
                }
Packit Service 407539
                case AF_INET6: {
Packit Service 407539
                        struct sockaddr_in6 *sin6;
Packit Service 407539
Packit Service 407539
                        sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr;
Packit Service 407539
                        memcpy(buf->address6, &sin6->sin6_addr,
Packit Service 407539
                                sizeof(buf->address6));
Packit Service 407539
                        buf->scope6 = (guint8 )sin6->sin6_scope_id;
Packit Service 407539
                        sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_netmask;
Packit Service 407539
                        memcpy(buf->prefix6, &sin6->sin6_addr,
Packit Service 407539
                                sizeof(buf->prefix6));
Packit Service 407539
                        buf->flags |= _glibtop_sysdeps_netload6;
Packit Service 407539
                        break;
Packit Service 407539
                }
Packit Service 407539
                } // switch() end
Packit Service 407539
        }
Packit Service 407539
        freeifaddrs(ifap);
Packit Service 407539
}