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

1.7     ! claudio     1: /*     $OpenBSD: if.c,v 1.6 2006/03/31 18:19:44 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>
1.5       deraadt    26: #include <string.h>
1.1       markus     27:
                     28: #include "systat.h"
                     29: #include "extern.h"
                     30:
                     31: static  enum state { BOOT, TIME, RUN } state = TIME;
                     32:
                     33: struct ifcount {
                     34:        u_long          ifc_ib;                 /* input bytes */
                     35:        u_long          ifc_ip;                 /* input packets */
                     36:        u_long          ifc_ie;                 /* input errors */
                     37:        u_long          ifc_ob;                 /* output bytes */
                     38:        u_long          ifc_op;                 /* output packets */
                     39:        u_long          ifc_oe;                 /* output errors */
                     40:        u_long          ifc_co;                 /* collisions */
1.7     ! claudio    41:        int             ifc_flags;              /* up / down */
        !            42:        int             ifc_state;              /* link state */
1.1       markus     43: } sum;
                     44:
                     45: struct ifstat {
                     46:        char            ifs_name[IFNAMSIZ];     /* interface name */
                     47:        struct ifcount  ifs_cur;
                     48:        struct ifcount  ifs_old;
                     49:        struct ifcount  ifs_now;
                     50: } *ifstats;
                     51:
                     52: static int nifs = 0;
1.5       deraadt    53: extern u_int naptime;
1.1       markus     54:
1.7     ! claudio    55: const char     *showlinkstate(int);
        !            56:
1.1       markus     57: WINDOW *
                     58: openifstat(void)
                     59: {
                     60:
                     61:        return (subwin(stdscr, LINES-5-1, 0, 5, 0));
                     62: }
                     63:
                     64: void
                     65: closeifstat(WINDOW *w)
                     66: {
                     67:
                     68:        if (w == NULL)
                     69:                return;
                     70:        wclear(w);
                     71:        wrefresh(w);
                     72:        delwin(w);
                     73: }
                     74:
                     75: int
                     76: initifstat(void)
                     77: {
                     78:
                     79:        fetchifstat();
                     80:        return(1);
                     81: }
                     82:
                     83: #define UPDATE(x, y) do { \
1.2       deraadt    84:                ifs->ifs_now.x = ifm.y; \
1.1       markus     85:                ifs->ifs_cur.x = ifs->ifs_now.x - ifs->ifs_old.x; \
1.4       dlg        86:                if (state == TIME) {\
                     87:                        ifs->ifs_old.x = ifs->ifs_now.x; \
                     88:                        ifs->ifs_cur.x /= naptime; \
                     89:                } \
1.1       markus     90:                sum.x += ifs->ifs_cur.x; \
                     91:        } while(0)
                     92:
                     93:
                     94: void
                     95: rt_getaddrinfo(struct sockaddr *sa, int addrs, struct sockaddr **info)
                     96: {
                     97:        int i;
                     98:
                     99:        for (i = 0; i < RTAX_MAX; i++) {
                    100:                if (addrs & (1 << i)) {
                    101:                        info[i] = sa;
                    102:                        sa = (struct sockaddr *) ((char *)(sa) +
                    103:                            roundup(sa->sa_len, sizeof(long)));
                    104:                } else
                    105:                        info[i] = NULL;
                    106:        }
                    107: }
                    108:
                    109: void
                    110: fetchifstat(void)
                    111: {
                    112:        struct ifstat *newstats, *ifs;
1.2       deraadt   113:        struct if_msghdr ifm;
1.1       markus    114:        struct sockaddr *info[RTAX_MAX];
                    115:        struct sockaddr_dl *sdl;
                    116:        char *buf, *next, *lim;
1.5       deraadt   117:        int mib[6];
1.1       markus    118:        size_t need;
                    119:
                    120:        mib[0] = CTL_NET;
                    121:        mib[1] = AF_ROUTE;
                    122:        mib[2] = 0;
                    123:        mib[3] = 0;
                    124:        mib[4] = NET_RT_IFLIST;
                    125:        mib[5] = 0;
                    126:
                    127:        if (sysctl(mib, 6, NULL, &need, NULL, 0) == -1)
                    128:                return;
                    129:        if ((buf = malloc(need)) == NULL)
                    130:                return;
                    131:        if (sysctl(mib, 6, buf, &need, NULL, 0) == -1) {
                    132:                free(buf);
                    133:                return;
                    134:        }
                    135:
                    136:        bzero(&sum, sizeof(sum));
                    137:
                    138:        lim = buf + need;
1.2       deraadt   139:        for (next = buf; next < lim; next += ifm.ifm_msglen) {
                    140:                bcopy(next, &ifm, sizeof ifm);
                    141:                if (ifm.ifm_type != RTM_IFINFO ||
                    142:                   !(ifm.ifm_addrs & RTA_IFP))
1.1       markus    143:                        continue;
1.2       deraadt   144:                if (ifm.ifm_index >= nifs) {
                    145:                        if ((newstats = realloc(ifstats, (ifm.ifm_index + 4) *
1.1       markus    146:                            sizeof(struct ifstat))) == NULL)
                    147:                                continue;
                    148:                        ifstats = newstats;
1.2       deraadt   149:                        for (; nifs < ifm.ifm_index + 4; nifs++)
1.1       markus    150:                                ifstats[nifs].ifs_name[0] = '\0';
                    151:                }
1.2       deraadt   152:                ifs = &ifstats[ifm.ifm_index];
1.1       markus    153:                if (ifs->ifs_name[0] == '\0') {
                    154:                        bzero(&info, sizeof(info));
1.2       deraadt   155:                        rt_getaddrinfo(
                    156:                            (struct sockaddr *)((struct if_msghdr *)next + 1),
                    157:                            ifm.ifm_addrs, info);
1.1       markus    158:                        if ((sdl = (struct sockaddr_dl *)info[RTAX_IFP])) {
                    159:                                if (sdl->sdl_family == AF_LINK &&
1.3       dlg       160:                                    sdl->sdl_nlen > 0) {
                    161:                                        bcopy(sdl->sdl_data, ifs->ifs_name,
                    162:                                            sdl->sdl_nlen);
                    163:                                        ifs->ifs_name[sdl->sdl_nlen] = '\0';
                    164:                                }
1.1       markus    165:                        }
                    166:                        if (ifs->ifs_name[0] == '\0')
                    167:                                continue;
                    168:                }
                    169:                UPDATE(ifc_ip, ifm_data.ifi_ipackets);
                    170:                UPDATE(ifc_ib, ifm_data.ifi_ibytes);
                    171:                UPDATE(ifc_ie, ifm_data.ifi_ierrors);
                    172:                UPDATE(ifc_op, ifm_data.ifi_opackets);
                    173:                UPDATE(ifc_ob, ifm_data.ifi_obytes);
                    174:                UPDATE(ifc_oe, ifm_data.ifi_oerrors);
                    175:                UPDATE(ifc_co, ifm_data.ifi_collisions);
1.7     ! claudio   176:                ifs->ifs_cur.ifc_flags = ifm.ifm_flags;
        !           177:                ifs->ifs_cur.ifc_state = ifm.ifm_data.ifi_link_state;
1.1       markus    178:        }
                    179:        free(buf);
                    180: }
                    181:
                    182: #define INSET 0
                    183:
                    184: void
                    185: labelifstat(void)
                    186: {
                    187:
1.5       deraadt   188:        wmove(wnd, 0, 0);
                    189:        wclrtobot(wnd);
1.1       markus    190:
1.7     ! claudio   191:        mvwaddstr(wnd, 1, INSET, "Iface");
        !           192:        mvwaddstr(wnd, 1, INSET+9, "State");
        !           193:        mvwaddstr(wnd, 1, INSET+19, "Ibytes");
        !           194:        mvwaddstr(wnd, 1, INSET+29, "Ipkts");
        !           195:        mvwaddstr(wnd, 1, INSET+36, "Ierrs");
        !           196:        mvwaddstr(wnd, 1, INSET+48, "Obytes");
1.1       markus    197:        mvwaddstr(wnd, 1, INSET+58, "Opkts");
                    198:        mvwaddstr(wnd, 1, INSET+65, "Oerrs");
                    199:        mvwaddstr(wnd, 1, INSET+74, "Colls");
                    200: }
                    201:
1.7     ! claudio   202: #define FMT "%-8.8s %2s%2s  %10lu %8lu %6lu   %10lu %8lu %6lu   %6lu "
        !           203:
        !           204: const char *
        !           205: showlinkstate(int state)
        !           206: {
        !           207:        switch (state) {
        !           208:        case LINK_STATE_UP:
        !           209:                return (":U");
        !           210:        case LINK_STATE_DOWN:
        !           211:                return (":D");
        !           212:        case LINK_STATE_UNKNOWN:
        !           213:                return ("");
        !           214:        }
        !           215: }
1.6       deraadt   216:
1.1       markus    217: void
                    218: showifstat(void)
                    219: {
                    220:        int row;
                    221:        struct ifstat *ifs;
                    222:
                    223:        row = 2;
1.5       deraadt   224:        wmove(wnd, 0, 0);
                    225:        wclrtoeol(wnd);
1.1       markus    226:        for (ifs = ifstats; ifs < ifstats + nifs; ifs++) {
                    227:                if (ifs->ifs_name[0] == '\0')
                    228:                        continue;
                    229:                mvwprintw(wnd, row++, INSET, FMT,
                    230:                    ifs->ifs_name,
1.7     ! claudio   231:                    ifs->ifs_cur.ifc_flags & IFF_UP ? "up" : "dn",
        !           232:                    showlinkstate(ifs->ifs_cur.ifc_state),
1.1       markus    233:                    ifs->ifs_cur.ifc_ib,
                    234:                    ifs->ifs_cur.ifc_ip,
                    235:                    ifs->ifs_cur.ifc_ie,
                    236:                    ifs->ifs_cur.ifc_ob,
                    237:                    ifs->ifs_cur.ifc_op,
                    238:                    ifs->ifs_cur.ifc_oe,
                    239:                    ifs->ifs_cur.ifc_co);
                    240:        }
                    241:        mvwprintw(wnd, row++, INSET, FMT,
                    242:            "Totals",
1.7     ! claudio   243:            "", "",
1.1       markus    244:            sum.ifc_ib,
                    245:            sum.ifc_ip,
                    246:            sum.ifc_ie,
                    247:            sum.ifc_ob,
                    248:            sum.ifc_op,
                    249:            sum.ifc_oe,
                    250:            sum.ifc_co);
                    251: }
                    252:
                    253: int
                    254: cmdifstat(char *cmd, char *args)
                    255: {
                    256:        struct ifstat *ifs;
                    257:
                    258:        if (prefix(cmd, "run")) {
                    259:                if (state != RUN)
                    260:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    261:                                ifs->ifs_old = ifs->ifs_now;
                    262:                state = RUN;
                    263:                return (1);
                    264:        }
                    265:        if (prefix(cmd, "boot")) {
                    266:                state = BOOT;
                    267:                for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    268:                        bzero(&ifs->ifs_old, sizeof(ifs->ifs_old));
                    269:                return (1);
                    270:        }
                    271:        if (prefix(cmd, "time")) {
                    272:                state = TIME;
                    273:                return (1);
                    274:        }
                    275:        if (prefix(cmd, "zero")) {
                    276:                if (state == RUN)
                    277:                        for (ifs = ifstats; ifs < ifstats + nifs; ifs++)
                    278:                                ifs->ifs_old = ifs->ifs_now;
                    279:                return (1);
                    280:        }
                    281:        return (1);
                    282: }