[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.3

1.3     ! dlg         1: /*     $OpenBSD: if.c,v 1.2 2004/11/25 23:08:13 deraadt 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;
                     50:
                     51: WINDOW *
                     52: openifstat(void)
                     53: {
                     54:
                     55:        return (subwin(stdscr, LINES-5-1, 0, 5, 0));
                     56: }
                     57:
                     58: void
                     59: closeifstat(WINDOW *w)
                     60: {
                     61:
                     62:        if (w == NULL)
                     63:                return;
                     64:        wclear(w);
                     65:        wrefresh(w);
                     66:        delwin(w);
                     67: }
                     68:
                     69: int
                     70: initifstat(void)
                     71: {
                     72:
                     73:        fetchifstat();
                     74:        return(1);
                     75: }
                     76:
                     77: #define UPDATE(x, y) do { \
1.2       deraadt    78:                ifs->ifs_now.x = ifm.y; \
1.1       markus     79:                ifs->ifs_cur.x = ifs->ifs_now.x - ifs->ifs_old.x; \
                     80:                sum.x += ifs->ifs_cur.x; \
                     81:                if (state == TIME) \
                     82:                        ifs->ifs_old.x = ifs->ifs_now.x; \
                     83:        } while(0)
                     84:
                     85:
                     86: void
                     87: rt_getaddrinfo(struct sockaddr *sa, int addrs, struct sockaddr **info)
                     88: {
                     89:        int i;
                     90:
                     91:        for (i = 0; i < RTAX_MAX; i++) {
                     92:                if (addrs & (1 << i)) {
                     93:                        info[i] = sa;
                     94:                        sa = (struct sockaddr *) ((char *)(sa) +
                     95:                            roundup(sa->sa_len, sizeof(long)));
                     96:                } else
                     97:                        info[i] = NULL;
                     98:        }
                     99: }
                    100:
                    101: void
                    102: fetchifstat(void)
                    103: {
                    104:        struct ifstat *newstats, *ifs;
1.2       deraadt   105:        struct if_msghdr ifm;
1.1       markus    106:        struct sockaddr *info[RTAX_MAX];
                    107:        struct sockaddr_dl *sdl;
                    108:        char *buf, *next, *lim;
                    109:        int mib[6], i;
                    110:        size_t need;
                    111:
                    112:        mib[0] = CTL_NET;
                    113:        mib[1] = AF_ROUTE;
                    114:        mib[2] = 0;
                    115:        mib[3] = 0;
                    116:        mib[4] = NET_RT_IFLIST;
                    117:        mib[5] = 0;
                    118:
                    119:        if (sysctl(mib, 6, NULL, &need, NULL, 0) == -1)
                    120:                return;
                    121:        if ((buf = malloc(need)) == NULL)
                    122:                return;
                    123:        if (sysctl(mib, 6, buf, &need, NULL, 0) == -1) {
                    124:                free(buf);
                    125:                return;
                    126:        }
                    127:
                    128:        bzero(&sum, sizeof(sum));
                    129:
                    130:        lim = buf + need;
1.2       deraadt   131:        for (next = buf; next < lim; next += ifm.ifm_msglen) {
                    132:                bcopy(next, &ifm, sizeof ifm);
                    133:                if (ifm.ifm_type != RTM_IFINFO ||
                    134:                   !(ifm.ifm_addrs & RTA_IFP))
1.1       markus    135:                        continue;
1.2       deraadt   136:                if (ifm.ifm_index >= nifs) {
                    137:                        if ((newstats = realloc(ifstats, (ifm.ifm_index + 4) *
1.1       markus    138:                            sizeof(struct ifstat))) == NULL)
                    139:                                continue;
                    140:                        ifstats = newstats;
1.2       deraadt   141:                        for (; nifs < ifm.ifm_index + 4; nifs++)
1.1       markus    142:                                ifstats[nifs].ifs_name[0] = '\0';
                    143:                }
1.2       deraadt   144:                ifs = &ifstats[ifm.ifm_index];
1.1       markus    145:                if (ifs->ifs_name[0] == '\0') {
                    146:                        bzero(&info, sizeof(info));
1.2       deraadt   147:                        rt_getaddrinfo(
                    148:                            (struct sockaddr *)((struct if_msghdr *)next + 1),
                    149:                            ifm.ifm_addrs, info);
1.1       markus    150:                        if ((sdl = (struct sockaddr_dl *)info[RTAX_IFP])) {
                    151:                                if (sdl->sdl_family == AF_LINK &&
1.3     ! dlg       152:                                    sdl->sdl_nlen > 0) {
        !           153:                                        bcopy(sdl->sdl_data, ifs->ifs_name,
        !           154:                                            sdl->sdl_nlen);
        !           155:                                        ifs->ifs_name[sdl->sdl_nlen] = '\0';
        !           156:                                }
1.1       markus    157:                        }
                    158:                        if (ifs->ifs_name[0] == '\0')
                    159:                                continue;
                    160:                }
                    161:                UPDATE(ifc_ip, ifm_data.ifi_ipackets);
                    162:                UPDATE(ifc_ib, ifm_data.ifi_ibytes);
                    163:                UPDATE(ifc_ie, ifm_data.ifi_ierrors);
                    164:                UPDATE(ifc_op, ifm_data.ifi_opackets);
                    165:                UPDATE(ifc_ob, ifm_data.ifi_obytes);
                    166:                UPDATE(ifc_oe, ifm_data.ifi_oerrors);
                    167:                UPDATE(ifc_co, ifm_data.ifi_collisions);
                    168:        }
                    169:        free(buf);
                    170: }
                    171:
                    172: #define INSET 0
                    173:
                    174: void
                    175: labelifstat(void)
                    176: {
                    177:
                    178:        wmove(wnd, 0, 0); wclrtobot(wnd);
                    179:
                    180:        mvwaddstr(wnd, 1, INSET, "Interfaces");
                    181:        mvwaddstr(wnd, 1, INSET+15, "Ibytes");
                    182:        mvwaddstr(wnd, 1, INSET+27, "Ipkts");
                    183:        mvwaddstr(wnd, 1, INSET+34, "Ierrs");
                    184:        mvwaddstr(wnd, 1, INSET+46, "Obytes");
                    185:        mvwaddstr(wnd, 1, INSET+58, "Opkts");
                    186:        mvwaddstr(wnd, 1, INSET+65, "Oerrs");
                    187:        mvwaddstr(wnd, 1, INSET+74, "Colls");
                    188: }
                    189:
                    190: #define FMT "%-10.10s %10lu %10lu %6lu   %10lu %10lu %6lu   %6lu "
                    191:
                    192: void
                    193: showifstat(void)
                    194: {
                    195:        int row;
                    196:        struct ifstat *ifs;
                    197:
                    198:        row = 2;
                    199:        wmove(wnd, 0, 0); wclrtoeol(wnd);
                    200:        for (ifs = ifstats; ifs < ifstats + nifs; ifs++) {
                    201:                if (ifs->ifs_name[0] == '\0')
                    202:                        continue;
                    203:                mvwprintw(wnd, row++, INSET, FMT,
                    204:                    ifs->ifs_name,
                    205:                    ifs->ifs_cur.ifc_ib,
                    206:                    ifs->ifs_cur.ifc_ip,
                    207:                    ifs->ifs_cur.ifc_ie,
                    208:                    ifs->ifs_cur.ifc_ob,
                    209:                    ifs->ifs_cur.ifc_op,
                    210:                    ifs->ifs_cur.ifc_oe,
                    211:                    ifs->ifs_cur.ifc_co);
                    212:        }
                    213:        mvwprintw(wnd, row++, INSET, FMT,
                    214:            "Totals",
                    215:            sum.ifc_ib,
                    216:            sum.ifc_ip,
                    217:            sum.ifc_ie,
                    218:            sum.ifc_ob,
                    219:            sum.ifc_op,
                    220:            sum.ifc_oe,
                    221:            sum.ifc_co);
                    222: }
                    223:
                    224: int
                    225: cmdifstat(char *cmd, char *args)
                    226: {
                    227:        struct ifstat *ifs;
                    228:
                    229:        if (prefix(cmd, "run")) {
                    230:                if (state != RUN)
                    231:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    232:                                ifs->ifs_old = ifs->ifs_now;
                    233:                state = RUN;
                    234:                return (1);
                    235:        }
                    236:        if (prefix(cmd, "boot")) {
                    237:                state = BOOT;
                    238:                for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    239:                        bzero(&ifs->ifs_old, sizeof(ifs->ifs_old));
                    240:                return (1);
                    241:        }
                    242:        if (prefix(cmd, "time")) {
                    243:                state = TIME;
                    244:                return (1);
                    245:        }
                    246:        if (prefix(cmd, "zero")) {
                    247:                if (state == RUN)
                    248:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    249:                                ifs->ifs_old = ifs->ifs_now;
                    250:                return (1);
                    251:        }
                    252:        return (1);
                    253: }