[BACK]Return to if.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Annotation of src/usr.bin/systat/if.c, Revision 1.4

1.4     ! dlg         1: /*     $OpenBSD: if.c,v 1.3 2005/12/13 09:52:20 dlg Exp $ */
1.1       markus      2: /*
                      3:  * Copyright (c) 2004 Markus Friedl <markus@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: #include <sys/param.h>
                     18: #include <sys/types.h>
                     19: #include <sys/socket.h>
                     20: #include <sys/sysctl.h>
                     21: #include <net/if.h>
                     22: #include <net/if_dl.h>
                     23: #include <net/route.h>
                     24:
                     25: #include <stdlib.h>
                     26:
                     27: #include "systat.h"
                     28: #include "extern.h"
                     29:
                     30: static  enum state { BOOT, TIME, RUN } state = TIME;
                     31:
                     32: struct ifcount {
                     33:        u_long          ifc_ib;                 /* input bytes */
                     34:        u_long          ifc_ip;                 /* input packets */
                     35:        u_long          ifc_ie;                 /* input errors */
                     36:        u_long          ifc_ob;                 /* output bytes */
                     37:        u_long          ifc_op;                 /* output packets */
                     38:        u_long          ifc_oe;                 /* output errors */
                     39:        u_long          ifc_co;                 /* collisions */
                     40: } sum;
                     41:
                     42: struct ifstat {
                     43:        char            ifs_name[IFNAMSIZ];     /* interface name */
                     44:        struct ifcount  ifs_cur;
                     45:        struct ifcount  ifs_old;
                     46:        struct ifcount  ifs_now;
                     47: } *ifstats;
                     48:
                     49: static int nifs = 0;
1.4     ! dlg        50: extern int naptime;
1.1       markus     51:
                     52: WINDOW *
                     53: openifstat(void)
                     54: {
                     55:
                     56:        return (subwin(stdscr, LINES-5-1, 0, 5, 0));
                     57: }
                     58:
                     59: void
                     60: closeifstat(WINDOW *w)
                     61: {
                     62:
                     63:        if (w == NULL)
                     64:                return;
                     65:        wclear(w);
                     66:        wrefresh(w);
                     67:        delwin(w);
                     68: }
                     69:
                     70: int
                     71: initifstat(void)
                     72: {
                     73:
                     74:        fetchifstat();
                     75:        return(1);
                     76: }
                     77:
                     78: #define UPDATE(x, y) do { \
1.2       deraadt    79:                ifs->ifs_now.x = ifm.y; \
1.1       markus     80:                ifs->ifs_cur.x = ifs->ifs_now.x - ifs->ifs_old.x; \
1.4     ! dlg        81:                if (state == TIME) {\
        !            82:                        ifs->ifs_old.x = ifs->ifs_now.x; \
        !            83:                        ifs->ifs_cur.x /= naptime; \
        !            84:                } \
1.1       markus     85:                sum.x += ifs->ifs_cur.x; \
                     86:        } while(0)
                     87:
                     88:
                     89: void
                     90: rt_getaddrinfo(struct sockaddr *sa, int addrs, struct sockaddr **info)
                     91: {
                     92:        int i;
                     93:
                     94:        for (i = 0; i < RTAX_MAX; i++) {
                     95:                if (addrs & (1 << i)) {
                     96:                        info[i] = sa;
                     97:                        sa = (struct sockaddr *) ((char *)(sa) +
                     98:                            roundup(sa->sa_len, sizeof(long)));
                     99:                } else
                    100:                        info[i] = NULL;
                    101:        }
                    102: }
                    103:
                    104: void
                    105: fetchifstat(void)
                    106: {
                    107:        struct ifstat *newstats, *ifs;
1.2       deraadt   108:        struct if_msghdr ifm;
1.1       markus    109:        struct sockaddr *info[RTAX_MAX];
                    110:        struct sockaddr_dl *sdl;
                    111:        char *buf, *next, *lim;
                    112:        int mib[6], i;
                    113:        size_t need;
                    114:
                    115:        mib[0] = CTL_NET;
                    116:        mib[1] = AF_ROUTE;
                    117:        mib[2] = 0;
                    118:        mib[3] = 0;
                    119:        mib[4] = NET_RT_IFLIST;
                    120:        mib[5] = 0;
                    121:
                    122:        if (sysctl(mib, 6, NULL, &need, NULL, 0) == -1)
                    123:                return;
                    124:        if ((buf = malloc(need)) == NULL)
                    125:                return;
                    126:        if (sysctl(mib, 6, buf, &need, NULL, 0) == -1) {
                    127:                free(buf);
                    128:                return;
                    129:        }
                    130:
                    131:        bzero(&sum, sizeof(sum));
                    132:
                    133:        lim = buf + need;
1.2       deraadt   134:        for (next = buf; next < lim; next += ifm.ifm_msglen) {
                    135:                bcopy(next, &ifm, sizeof ifm);
                    136:                if (ifm.ifm_type != RTM_IFINFO ||
                    137:                   !(ifm.ifm_addrs & RTA_IFP))
1.1       markus    138:                        continue;
1.2       deraadt   139:                if (ifm.ifm_index >= nifs) {
                    140:                        if ((newstats = realloc(ifstats, (ifm.ifm_index + 4) *
1.1       markus    141:                            sizeof(struct ifstat))) == NULL)
                    142:                                continue;
                    143:                        ifstats = newstats;
1.2       deraadt   144:                        for (; nifs < ifm.ifm_index + 4; nifs++)
1.1       markus    145:                                ifstats[nifs].ifs_name[0] = '\0';
                    146:                }
1.2       deraadt   147:                ifs = &ifstats[ifm.ifm_index];
1.1       markus    148:                if (ifs->ifs_name[0] == '\0') {
                    149:                        bzero(&info, sizeof(info));
1.2       deraadt   150:                        rt_getaddrinfo(
                    151:                            (struct sockaddr *)((struct if_msghdr *)next + 1),
                    152:                            ifm.ifm_addrs, info);
1.1       markus    153:                        if ((sdl = (struct sockaddr_dl *)info[RTAX_IFP])) {
                    154:                                if (sdl->sdl_family == AF_LINK &&
1.3       dlg       155:                                    sdl->sdl_nlen > 0) {
                    156:                                        bcopy(sdl->sdl_data, ifs->ifs_name,
                    157:                                            sdl->sdl_nlen);
                    158:                                        ifs->ifs_name[sdl->sdl_nlen] = '\0';
                    159:                                }
1.1       markus    160:                        }
                    161:                        if (ifs->ifs_name[0] == '\0')
                    162:                                continue;
                    163:                }
                    164:                UPDATE(ifc_ip, ifm_data.ifi_ipackets);
                    165:                UPDATE(ifc_ib, ifm_data.ifi_ibytes);
                    166:                UPDATE(ifc_ie, ifm_data.ifi_ierrors);
                    167:                UPDATE(ifc_op, ifm_data.ifi_opackets);
                    168:                UPDATE(ifc_ob, ifm_data.ifi_obytes);
                    169:                UPDATE(ifc_oe, ifm_data.ifi_oerrors);
                    170:                UPDATE(ifc_co, ifm_data.ifi_collisions);
                    171:        }
                    172:        free(buf);
                    173: }
                    174:
                    175: #define INSET 0
                    176:
                    177: void
                    178: labelifstat(void)
                    179: {
                    180:
                    181:        wmove(wnd, 0, 0); wclrtobot(wnd);
                    182:
                    183:        mvwaddstr(wnd, 1, INSET, "Interfaces");
                    184:        mvwaddstr(wnd, 1, INSET+15, "Ibytes");
                    185:        mvwaddstr(wnd, 1, INSET+27, "Ipkts");
                    186:        mvwaddstr(wnd, 1, INSET+34, "Ierrs");
                    187:        mvwaddstr(wnd, 1, INSET+46, "Obytes");
                    188:        mvwaddstr(wnd, 1, INSET+58, "Opkts");
                    189:        mvwaddstr(wnd, 1, INSET+65, "Oerrs");
                    190:        mvwaddstr(wnd, 1, INSET+74, "Colls");
                    191: }
                    192:
                    193: #define FMT "%-10.10s %10lu %10lu %6lu   %10lu %10lu %6lu   %6lu "
                    194:
                    195: void
                    196: showifstat(void)
                    197: {
                    198:        int row;
                    199:        struct ifstat *ifs;
                    200:
                    201:        row = 2;
                    202:        wmove(wnd, 0, 0); wclrtoeol(wnd);
                    203:        for (ifs = ifstats; ifs < ifstats + nifs; ifs++) {
                    204:                if (ifs->ifs_name[0] == '\0')
                    205:                        continue;
                    206:                mvwprintw(wnd, row++, INSET, FMT,
                    207:                    ifs->ifs_name,
                    208:                    ifs->ifs_cur.ifc_ib,
                    209:                    ifs->ifs_cur.ifc_ip,
                    210:                    ifs->ifs_cur.ifc_ie,
                    211:                    ifs->ifs_cur.ifc_ob,
                    212:                    ifs->ifs_cur.ifc_op,
                    213:                    ifs->ifs_cur.ifc_oe,
                    214:                    ifs->ifs_cur.ifc_co);
                    215:        }
                    216:        mvwprintw(wnd, row++, INSET, FMT,
                    217:            "Totals",
                    218:            sum.ifc_ib,
                    219:            sum.ifc_ip,
                    220:            sum.ifc_ie,
                    221:            sum.ifc_ob,
                    222:            sum.ifc_op,
                    223:            sum.ifc_oe,
                    224:            sum.ifc_co);
                    225: }
                    226:
                    227: int
                    228: cmdifstat(char *cmd, char *args)
                    229: {
                    230:        struct ifstat *ifs;
                    231:
                    232:        if (prefix(cmd, "run")) {
                    233:                if (state != RUN)
                    234:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    235:                                ifs->ifs_old = ifs->ifs_now;
                    236:                state = RUN;
                    237:                return (1);
                    238:        }
                    239:        if (prefix(cmd, "boot")) {
                    240:                state = BOOT;
                    241:                for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    242:                        bzero(&ifs->ifs_old, sizeof(ifs->ifs_old));
                    243:                return (1);
                    244:        }
                    245:        if (prefix(cmd, "time")) {
                    246:                state = TIME;
                    247:                return (1);
                    248:        }
                    249:        if (prefix(cmd, "zero")) {
                    250:                if (state == RUN)
                    251:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    252:                                ifs->ifs_old = ifs->ifs_now;
                    253:                return (1);
                    254:        }
                    255:        return (1);
                    256: }