Annotation of embedaddon/miniupnpd/bsd/getifstats.c, revision 1.1.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>