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

1.1     ! misho       1: /* MiniUPnP project
        !             2:  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
        !             3:  * author: Ryan Wagoner and Thomas Bernard
        !             4:  * (c) 2006 Ryan Wagoner
        !             5:  * This software is subject to the conditions detailed
        !             6:  * in the LICENCE file provided within the distribution */
        !             7: 
        !             8: #include <syslog.h>
        !             9: #include <sys/types.h>
        !            10: #include <sys/socket.h>
        !            11: #include <net/if.h>
        !            12: #include <arpa/inet.h>
        !            13: #include <netinet/in.h>
        !            14: #if defined(__FreeBSD__) || defined(__DragonFly__)
        !            15: #include <net/if_var.h>
        !            16: #endif
        !            17: #if defined(__DragonFly__)
        !            18: #include <net/pf/pfvar.h>
        !            19: #else
        !            20: #include <net/pfvar.h>
        !            21: #endif
        !            22: #include <kvm.h>
        !            23: #include <fcntl.h>
        !            24: #include <nlist.h>
        !            25: #include <sys/queue.h>
        !            26: #include <stdio.h>
        !            27: #include <string.h>
        !            28: #include <limits.h>
        !            29: 
        !            30: #include "../getifstats.h"
        !            31: #include "../config.h"
        !            32: 
        !            33: struct nlist list[] = {
        !            34:        {"_ifnet"},
        !            35:        {NULL}
        !            36: };
        !            37: 
        !            38: int 
        !            39: getifstats(const char * ifname, struct ifdata * data)
        !            40: {
        !            41: #if defined(__FreeBSD__) || defined(__DragonFly__)
        !            42:        struct ifnethead ifh;
        !            43: #elif defined(__OpenBSD__) || defined(__NetBSD__)
        !            44:        struct ifnet_head ifh;
        !            45: #else
        !            46:        #error "Dont know if I should use struct ifnethead or struct ifnet_head"
        !            47: #endif
        !            48:        struct ifnet ifc;
        !            49:        struct ifnet *ifp;
        !            50:        kvm_t *kd;
        !            51:        ssize_t n;
        !            52:        char errstr[_POSIX2_LINE_MAX];
        !            53: #ifdef ENABLE_GETIFSTATS_CACHING
        !            54:        static time_t cache_timestamp = 0;
        !            55:        static struct ifdata cache_data;
        !            56:        time_t current_time;
        !            57: #endif
        !            58:        if(!data)
        !            59:                return -1;
        !            60:        data->baudrate = 4200000;
        !            61:        data->opackets = 0;
        !            62:        data->ipackets = 0;
        !            63:        data->obytes = 0;
        !            64:        data->ibytes = 0;
        !            65:        if(!ifname || ifname[0]=='\0')
        !            66:                return -1;
        !            67: #ifdef ENABLE_GETIFSTATS_CACHING
        !            68:        current_time = time(NULL);
        !            69:        if(current_time == ((time_t)-1)) {
        !            70:                syslog(LOG_ERR, "getifstats() : time() error : %m");
        !            71:        } else {
        !            72:                if(current_time < cache_timestamp + GETIFSTATS_CACHING_DURATION) {
        !            73:                        memcpy(data, &cache_data, sizeof(struct ifdata));
        !            74:                        return 0;
        !            75:                }
        !            76:        }
        !            77: #endif
        !            78: 
        !            79:        /*kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);*/
        !            80:        kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errstr);
        !            81:        if(!kd)
        !            82:        {
        !            83:                syslog (LOG_ERR, "getifstats() : kvm_open(): %s", errstr);
        !            84:                return -1;
        !            85:        }
        !            86:        if(kvm_nlist(kd, list) < 0)
        !            87:        {
        !            88:                syslog(LOG_ERR, "getifstats() : kvm_nlist(): FAILED");
        !            89:                goto error;
        !            90:        }
        !            91:        if(!list[0].n_value)
        !            92:        {
        !            93:                syslog(LOG_ERR, "getifstats() : n_value(): FAILED");
        !            94:                goto error;
        !            95:        }
        !            96:        n = kvm_read(kd, list[0].n_value, &ifh, sizeof(ifh));
        !            97:        if(n<0)
        !            98:        {
        !            99:                syslog(LOG_ERR, "getifstats() : kvm_read(head): %s", kvm_geterr(kd));
        !           100:                goto error;
        !           101:        }
        !           102:        for(ifp = TAILQ_FIRST(&ifh); ifp; ifp = TAILQ_NEXT(&ifc, if_list))
        !           103:        {
        !           104:                n = kvm_read(kd, (u_long)ifp, &ifc, sizeof(ifc));
        !           105:                if(n<0)
        !           106:                {
        !           107:                        syslog(LOG_ERR, "getifstats() : kvm_read(element): %s", kvm_geterr(kd));
        !           108:                        goto error;
        !           109:                }
        !           110:                if(strcmp(ifname, ifc.if_xname) == 0)
        !           111:                {
        !           112:                        /* found the right interface */
        !           113:                        data->opackets = ifc.if_data.ifi_opackets;
        !           114:                        data->ipackets = ifc.if_data.ifi_ipackets;
        !           115:                        data->obytes = ifc.if_data.ifi_obytes;
        !           116:                        data->ibytes = ifc.if_data.ifi_ibytes;
        !           117:                        data->baudrate = ifc.if_data.ifi_baudrate;
        !           118:                        kvm_close(kd);
        !           119: 
        !           120: #ifdef ENABLE_GETIFSTATS_CACHING
        !           121:                        if(current_time!=((time_t)-1)) {
        !           122:                                cache_timestamp = current_time;
        !           123:                                memcpy(&cache_data, data, sizeof(struct ifdata));
        !           124:                        }
        !           125: #endif
        !           126:                        return 0;       /* ok */
        !           127:                }
        !           128:        }
        !           129: error:
        !           130:        kvm_close(kd);
        !           131:        return -1;      /* not found or error */
        !           132: }
        !           133: 

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