Annotation of embedaddon/miniupnpd/mac/getifstats.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * MiniUPnP project
        !             3:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
        !             4:  * (c) 2009 Jarder Weyrich
        !             5:  * This software is subject to the conditions detailed
        !             6:  * in the LICENCE file provided within the distribution
        !             7:  */
        !             8: 
        !             9: #include <syslog.h>
        !            10: #include <sys/sysctl.h>
        !            11: #include <sys/types.h>
        !            12: #include <netinet/in.h>
        !            13: #include <net/if.h>
        !            14: #include <net/if_types.h>
        !            15: #include <net/route.h>
        !            16: #include <nlist.h>
        !            17: #include <stdio.h>
        !            18: #include <stdlib.h>
        !            19: #include <string.h>
        !            20: 
        !            21: #include "../getifstats.h"
        !            22: #include "../config.h"
        !            23: 
        !            24: int getifstats(const char * ifname, struct ifdata * data) {
        !            25:        int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(ifname) };
        !            26:        const size_t mib_len = sizeof(mib) / sizeof(mib[0]);
        !            27:        size_t needed;
        !            28:        char *buf, *end;
        !            29:        struct if_msghdr *ifm;
        !            30:        struct if_data ifdata;  
        !            31: #ifdef ENABLE_GETIFSTATS_CACHING
        !            32:        static time_t cache_timestamp = 0;
        !            33:        static struct ifdata cache_data;
        !            34:        time_t current_time;
        !            35: #endif
        !            36: 
        !            37:        if (data == NULL || ifname == NULL || ifname[0] == '\0')
        !            38:                return -1; // error
        !            39: 
        !            40:        data->baudrate = 4200000;
        !            41:        data->opackets = 0;
        !            42:        data->ipackets = 0;
        !            43:        data->obytes = 0;
        !            44:        data->ibytes = 0;
        !            45: 
        !            46: #ifdef ENABLE_GETIFSTATS_CACHING
        !            47:        current_time = time(NULL);
        !            48:        if (current_time == ((time_t)-1)) {
        !            49:                syslog(LOG_ERR, "getifstats() : time() error : %m");
        !            50:        } else {
        !            51:                if (current_time < cache_timestamp + GETIFSTATS_CACHING_DURATION) {
        !            52:                        memcpy(data, &cache_data, sizeof(struct ifdata));
        !            53:                        return 0;
        !            54:                }
        !            55:        }
        !            56: #endif
        !            57: 
        !            58:        if (sysctl(mib, mib_len, NULL, &needed, NULL, 0) == -1) {
        !            59:                syslog(LOG_ERR, "sysctl(): %m");
        !            60:                return -1;
        !            61:        }
        !            62:        buf = (char *) malloc(needed);
        !            63:        if (buf == NULL)
        !            64:                return -1; // error
        !            65:        if (sysctl(mib, mib_len, buf, &needed, NULL, 0) == -1) {
        !            66:                syslog(LOG_ERR, "sysctl(): %m");
        !            67:                free(buf);
        !            68:                return -1; // error
        !            69:        } else {
        !            70:                for (end = buf + needed; buf < end; buf += ifm->ifm_msglen) {
        !            71:                        ifm = (struct if_msghdr *) buf;
        !            72:                        if (ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) {
        !            73:                                ifdata = ifm->ifm_data;
        !            74:                                data->opackets = ifdata.ifi_opackets;
        !            75:                                data->ipackets = ifdata.ifi_ipackets;
        !            76:                                data->obytes = ifdata.ifi_obytes;
        !            77:                                data->ibytes = ifdata.ifi_ibytes;
        !            78:                                data->baudrate = ifdata.ifi_baudrate;
        !            79:                                free(buf);
        !            80: #ifdef ENABLE_GETIFSTATS_CACHING
        !            81:                                if (current_time!=((time_t)-1)) {
        !            82:                                        cache_timestamp = current_time;
        !            83:                                        memcpy(&cache_data, data, sizeof(struct ifdata));
        !            84:                                }
        !            85: #endif
        !            86:                                return 0; // found, ok
        !            87:                        }
        !            88:                }               
        !            89:        }
        !            90:        free(buf);
        !            91:        return -1; // not found or error
        !            92: }
        !            93: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>