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

Annotation of src/usr.bin/systat/netcmds.c, Revision 1.18

1.18    ! ray         1: /*     $OpenBSD: netcmds.c,v 1.17 2007/03/20 03:56:13 tedu Exp $       */
1.1       deraadt     2: /*     $NetBSD: netcmds.c,v 1.4 1995/05/21 17:14:38 mycroft Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1980, 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
1.12      millert    16:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: #ifndef lint
                     34: #if 0
                     35: static char sccsid[] = "@(#)netcmds.c  8.1 (Berkeley) 6/6/93";
                     36: #endif
1.18    ! ray        37: static char rcsid[] = "$OpenBSD: netcmds.c,v 1.17 2007/03/20 03:56:13 tedu Exp $";
1.1       deraadt    38: #endif /* not lint */
                     39:
                     40: /*
                     41:  * Common network command support routines.
                     42:  */
                     43: #include <sys/param.h>
                     44: #include <sys/socket.h>
                     45: #include <sys/socketvar.h>
                     46: #include <sys/mbuf.h>
                     47: #include <sys/protosw.h>
                     48:
                     49: #include <net/route.h>
                     50: #include <netinet/in.h>
                     51: #include <netinet/in_systm.h>
                     52: #include <netinet/ip.h>
                     53: #include <netinet/in_pcb.h>
                     54:
                     55: #include <arpa/inet.h>
                     56:
1.18    ! ray        57: #include <errno.h>
1.1       deraadt    58: #include <netdb.h>
                     59: #include <stdlib.h>
                     60: #include <string.h>
                     61: #include <ctype.h>
                     62: #include "systat.h"
                     63: #include "extern.h"
                     64:
                     65: #define        streq(a,b)      (strcmp(a,b)==0)
                     66:
                     67: static struct hitem {
1.5       itojun     68:        struct sockaddr_storage addr;
1.1       deraadt    69:        int     onoff;
                     70: } *hosts;
                     71:
1.18    ! ray        72: size_t nports, nhosts;
        !            73: int protos;
1.1       deraadt    74:
1.10      millert    75: static void changeitems(char *, int);
                     76: static int selectproto(char *);
                     77: static void showprotos(void);
                     78: static int selectport(long, int);
                     79: static void showports(void);
                     80: static int addrcmp(struct sockaddr *, struct sockaddr *);
                     81: static int selecthost(struct sockaddr *, int);
                     82: static void showhosts(void);
1.1       deraadt    83:
                     84: int
1.11      deraadt    85: netcmd(char *cmd, char *args)
1.1       deraadt    86: {
                     87:
                     88:        if (prefix(cmd, "tcp") || prefix(cmd, "udp")) {
                     89:                selectproto(cmd);
                     90:                return (1);
                     91:        }
                     92:        if (prefix(cmd, "ignore") || prefix(cmd, "display")) {
                     93:                changeitems(args, prefix(cmd, "display"));
                     94:                return (1);
                     95:        }
                     96:        if (prefix(cmd, "reset")) {
                     97:                selectproto(0);
                     98:                selecthost(0, 0);
1.15      cloder     99:                selectport(htons(-1), 0);
1.1       deraadt   100:                return (1);
                    101:        }
                    102:        if (prefix(cmd, "show")) {
1.16      deraadt   103:                move(CMDLINE, 0);
                    104:                clrtoeol();
1.1       deraadt   105:                if (*args == '\0') {
                    106:                        showprotos();
                    107:                        showhosts();
                    108:                        showports();
                    109:                        return (1);
                    110:                }
                    111:                if (prefix(args, "protos"))
                    112:                        showprotos();
                    113:                else if (prefix(args, "hosts"))
                    114:                        showhosts();
                    115:                else if (prefix(args, "ports"))
                    116:                        showports();
                    117:                else
                    118:                        addstr("show what?");
                    119:                return (1);
                    120:        }
                    121:        return (0);
                    122: }
                    123:
                    124:
                    125: static void
1.11      deraadt   126: changeitems(char *args, int onoff)
1.1       deraadt   127: {
1.6       mpech     128:        char *cp;
1.1       deraadt   129:        struct servent *sp;
1.5       itojun    130:        struct addrinfo hints, *res0, *res;
1.1       deraadt   131:
1.3       millert   132:        cp = strchr(args, '\n');
1.1       deraadt   133:        if (cp)
                    134:                *cp = '\0';
                    135:        for (;;args = cp) {
1.17      tedu      136:                for (cp = args; isspace(*cp); cp++)
1.1       deraadt   137:                        ;
                    138:                args = cp;
                    139:                for (; *cp && !isspace(*cp); cp++)
                    140:                        ;
                    141:                if (*cp)
                    142:                        *cp++ = '\0';
                    143:                if (cp - args == 0)
                    144:                        break;
                    145:                sp = getservbyname(args,
                    146:                    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
                    147:                if (sp) {
                    148:                        selectport(sp->s_port, onoff);
                    149:                        continue;
                    150:                }
1.5       itojun    151:
                    152:                memset(&hints, 0, sizeof(hints));
                    153:                hints.ai_family = PF_UNSPEC;
                    154:                hints.ai_socktype = SOCK_DGRAM;
                    155:                if (getaddrinfo(args, "0", &hints, &res0) != 0) {
                    156:                        error("%s: unknown host or port", args);
                    157:                        continue;
1.1       deraadt   158:                }
1.5       itojun    159:                for (res = res0; res; res = res->ai_next)
                    160:                        selecthost(res->ai_addr, onoff);
                    161:                freeaddrinfo(res0);
1.1       deraadt   162:        }
                    163: }
                    164:
                    165: static int
1.11      deraadt   166: selectproto(char *proto)
1.1       deraadt   167: {
                    168:        int new = protos;
                    169:
                    170:        if (proto == 0 || streq(proto, "all"))
                    171:                new = TCP|UDP;
                    172:        else if (streq(proto, "tcp"))
                    173:                new = TCP;
                    174:        else if (streq(proto, "udp"))
                    175:                new = UDP;
1.4       millert   176:        return (protos = new);
1.1       deraadt   177: }
                    178:
                    179: static void
1.11      deraadt   180: showprotos(void)
1.1       deraadt   181: {
                    182:
                    183:        if ((protos&TCP) == 0)
                    184:                addch('!');
                    185:        addstr("tcp ");
                    186:        if ((protos&UDP) == 0)
                    187:                addch('!');
                    188:        addstr("udp ");
                    189: }
                    190:
                    191: static struct pitem {
                    192:        long    port;
                    193:        int     onoff;
                    194: } *ports;
                    195:
                    196: static int
1.11      deraadt   197: selectport(long port, int onoff)
1.1       deraadt   198: {
1.6       mpech     199:        struct pitem *p;
1.1       deraadt   200:
1.15      cloder    201:        if (ntohs(port) == -1) {
1.1       deraadt   202:                if (ports == 0)
                    203:                        return (0);
1.16      deraadt   204:                free(ports);
                    205:                ports = NULL;
1.1       deraadt   206:                nports = 0;
                    207:                return (1);
                    208:        }
                    209:        for (p = ports; p < ports+nports; p++)
                    210:                if (p->port == port) {
                    211:                        p->onoff = onoff;
                    212:                        return (0);
                    213:                }
1.18    ! ray       214:        if (nports + 1 > SIZE_MAX / sizeof(*p) ||
        !           215:            (p = realloc(ports, (nports + 1) * sizeof(*p))) == NULL) {
        !           216:                error("selectport: %s", strerror(ENOMEM));
        !           217:                die();
        !           218:        }
        !           219:        ports = p;
        !           220:
1.1       deraadt   221:        p = &ports[nports++];
                    222:        p->port = port;
                    223:        p->onoff = onoff;
                    224:        return (1);
                    225: }
                    226:
                    227: int
1.11      deraadt   228: checkport(struct inpcb *inp)
1.1       deraadt   229: {
1.6       mpech     230:        struct pitem *p;
1.1       deraadt   231:
                    232:        if (ports)
                    233:        for (p = ports; p < ports+nports; p++)
                    234:                if (p->port == inp->inp_lport || p->port == inp->inp_fport)
                    235:                        return (p->onoff);
                    236:        return (1);
                    237: }
                    238:
                    239: static void
1.11      deraadt   240: showports(void)
1.1       deraadt   241: {
1.6       mpech     242:        struct pitem *p;
1.1       deraadt   243:        struct servent *sp;
                    244:
                    245:        for (p = ports; p < ports+nports; p++) {
                    246:                sp = getservbyport(p->port,
1.4       millert   247:                    protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp");
1.1       deraadt   248:                if (!p->onoff)
                    249:                        addch('!');
                    250:                if (sp)
                    251:                        printw("%s ", sp->s_name);
                    252:                else
1.15      cloder    253:                        printw("%d ", ntohs(p->port));
1.1       deraadt   254:        }
                    255: }
                    256:
                    257: static int
1.11      deraadt   258: addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
1.5       itojun    259: {
                    260:        if (sa1->sa_family != sa2->sa_family)
                    261:                return 0;
                    262:        if (sa1->sa_len != sa2->sa_len)
                    263:                return 0;
                    264:        switch (sa1->sa_family) {
                    265:        case AF_INET:
                    266:                if (((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
1.16      deraadt   267:                    ((struct sockaddr_in *)sa2)->sin_addr.s_addr)
1.5       itojun    268:                        return 1;
                    269:                break;
                    270:        case AF_INET6:
                    271:                if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)sa1)->sin6_addr,
1.16      deraadt   272:                    &((struct sockaddr_in6 *)sa2)->sin6_addr))
1.5       itojun    273:                        return 1;
                    274:                break;
                    275:        default:
                    276:                if (memcmp(sa1, sa2, sa1->sa_len) == 0)
                    277:                        return 1;
                    278:                break;
                    279:        }
                    280:        return 0;
                    281: }
                    282:
                    283: static int
1.11      deraadt   284: selecthost(struct sockaddr *sa, int onoff)
1.1       deraadt   285: {
1.6       mpech     286:        struct hitem *p;
1.1       deraadt   287:
1.5       itojun    288:        if (sa == 0) {
1.1       deraadt   289:                if (hosts == 0)
                    290:                        return (0);
1.16      deraadt   291:                free(hosts);
                    292:                hosts = NULL;
1.1       deraadt   293:                nhosts = 0;
                    294:                return (1);
                    295:        }
                    296:        for (p = hosts; p < hosts+nhosts; p++)
1.5       itojun    297:                if (addrcmp((struct sockaddr *)&p->addr, sa)) {
1.1       deraadt   298:                        p->onoff = onoff;
                    299:                        return (0);
                    300:                }
1.5       itojun    301:        if (sa->sa_len > sizeof(struct sockaddr_storage))
                    302:                return (-1);    /*XXX*/
1.18    ! ray       303:        if (nhosts + 1 > SIZE_MAX / sizeof(*p) ||
        !           304:            (p = realloc(hosts, (nhosts + 1) * sizeof(*p))) == NULL) {
        !           305:                error("selecthost: %s", strerror(ENOMEM));
        !           306:                die();
        !           307:        }
        !           308:        hosts = p;
        !           309:
1.1       deraadt   310:        p = &hosts[nhosts++];
1.5       itojun    311:        memcpy(&p->addr, sa, sa->sa_len);
1.1       deraadt   312:        p->onoff = onoff;
                    313:        return (1);
                    314: }
                    315:
                    316: int
1.11      deraadt   317: checkhost(struct inpcb *inp)
1.1       deraadt   318: {
1.6       mpech     319:        struct hitem *p;
1.1       deraadt   320:
                    321:        if (hosts)
1.5       itojun    322:        for (p = hosts; p < hosts+nhosts; p++) {
1.9       deraadt   323:                if (((struct sockaddr *)&p->addr)->sa_family == AF_INET &&
                    324:                    !(inp->inp_flags & INP_IPV6)) {
1.5       itojun    325:                        struct sockaddr_in *sin;
                    326:                        sin = (struct sockaddr_in *)&p->addr;
                    327:                        if (sin->sin_addr.s_addr == inp->inp_laddr.s_addr ||
                    328:                            sin->sin_addr.s_addr == inp->inp_faddr.s_addr)
                    329:                                return (p->onoff);
                    330:                }
1.9       deraadt   331:                if (((struct sockaddr *)&p->addr)->sa_family == AF_INET6 &&
                    332:                    (inp->inp_flags & INP_IPV6)) {
1.5       itojun    333:                        struct sockaddr_in6 *sin6;
                    334:                        sin6 = (struct sockaddr_in6 *)&p->addr;
                    335:                        if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_laddr6) ||
                    336:                            IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_faddr6))
                    337:                                return (p->onoff);
                    338:                }
                    339:        }
1.1       deraadt   340:        return (1);
                    341: }
                    342:
                    343: static void
1.11      deraadt   344: showhosts(void)
1.1       deraadt   345: {
1.6       mpech     346:        struct hitem *p;
1.5       itojun    347:        char hbuf[NI_MAXHOST];
                    348:        struct sockaddr *sa;
                    349:        int flags;
1.1       deraadt   350:
1.5       itojun    351:        flags = nflag ? NI_NUMERICHOST : 0;
1.1       deraadt   352:        for (p = hosts; p < hosts+nhosts; p++) {
1.5       itojun    353:                sa = (struct sockaddr *)&p->addr;
                    354:                if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
1.16      deraadt   355:                    flags) != 0)
1.9       deraadt   356:                        strlcpy(hbuf, "(invalid)", sizeof hbuf);
1.1       deraadt   357:                if (!p->onoff)
                    358:                        addch('!');
1.5       itojun    359:                printw("%s ", hbuf);
1.1       deraadt   360:        }
                    361: }