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

1.16    ! deraadt     1: /*     $OpenBSD: netcmds.c,v 1.15 2005/03/13 19:00:45 cloder 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.16    ! deraadt    37: static char rcsid[] = "$OpenBSD: netcmds.c,v 1.15 2005/03/13 19:00:45 cloder 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:
                     57: #include <netdb.h>
                     58: #include <stdlib.h>
                     59: #include <string.h>
                     60: #include <ctype.h>
                     61: #include "systat.h"
                     62: #include "extern.h"
                     63:
                     64: #define        streq(a,b)      (strcmp(a,b)==0)
                     65:
                     66: static struct hitem {
1.5       itojun     67:        struct sockaddr_storage addr;
1.1       deraadt    68:        int     onoff;
                     69: } *hosts;
                     70:
                     71: int nports, nhosts, protos;
                     72:
1.10      millert    73: static void changeitems(char *, int);
                     74: static int selectproto(char *);
                     75: static void showprotos(void);
                     76: static int selectport(long, int);
                     77: static void showports(void);
                     78: static int addrcmp(struct sockaddr *, struct sockaddr *);
                     79: static int selecthost(struct sockaddr *, int);
                     80: static void showhosts(void);
1.1       deraadt    81:
                     82: int
1.11      deraadt    83: netcmd(char *cmd, char *args)
1.1       deraadt    84: {
                     85:
                     86:        if (prefix(cmd, "tcp") || prefix(cmd, "udp")) {
                     87:                selectproto(cmd);
                     88:                return (1);
                     89:        }
                     90:        if (prefix(cmd, "ignore") || prefix(cmd, "display")) {
                     91:                changeitems(args, prefix(cmd, "display"));
                     92:                return (1);
                     93:        }
                     94:        if (prefix(cmd, "reset")) {
                     95:                selectproto(0);
                     96:                selecthost(0, 0);
1.15      cloder     97:                selectport(htons(-1), 0);
1.1       deraadt    98:                return (1);
                     99:        }
                    100:        if (prefix(cmd, "show")) {
1.16    ! deraadt   101:                move(CMDLINE, 0);
        !           102:                clrtoeol();
1.1       deraadt   103:                if (*args == '\0') {
                    104:                        showprotos();
                    105:                        showhosts();
                    106:                        showports();
                    107:                        return (1);
                    108:                }
                    109:                if (prefix(args, "protos"))
                    110:                        showprotos();
                    111:                else if (prefix(args, "hosts"))
                    112:                        showhosts();
                    113:                else if (prefix(args, "ports"))
                    114:                        showports();
                    115:                else
                    116:                        addstr("show what?");
                    117:                return (1);
                    118:        }
                    119:        return (0);
                    120: }
                    121:
                    122:
                    123: static void
1.11      deraadt   124: changeitems(char *args, int onoff)
1.1       deraadt   125: {
1.6       mpech     126:        char *cp;
1.1       deraadt   127:        struct servent *sp;
1.5       itojun    128:        struct addrinfo hints, *res0, *res;
1.1       deraadt   129:
1.3       millert   130:        cp = strchr(args, '\n');
1.1       deraadt   131:        if (cp)
                    132:                *cp = '\0';
                    133:        for (;;args = cp) {
                    134:                for (cp = args; *cp && isspace(*cp); cp++)
                    135:                        ;
                    136:                args = cp;
                    137:                for (; *cp && !isspace(*cp); cp++)
                    138:                        ;
                    139:                if (*cp)
                    140:                        *cp++ = '\0';
                    141:                if (cp - args == 0)
                    142:                        break;
                    143:                sp = getservbyname(args,
                    144:                    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
                    145:                if (sp) {
                    146:                        selectport(sp->s_port, onoff);
                    147:                        continue;
                    148:                }
1.5       itojun    149:
                    150:                memset(&hints, 0, sizeof(hints));
                    151:                hints.ai_family = PF_UNSPEC;
                    152:                hints.ai_socktype = SOCK_DGRAM;
                    153:                if (getaddrinfo(args, "0", &hints, &res0) != 0) {
                    154:                        error("%s: unknown host or port", args);
                    155:                        continue;
1.1       deraadt   156:                }
1.5       itojun    157:                for (res = res0; res; res = res->ai_next)
                    158:                        selecthost(res->ai_addr, onoff);
                    159:                freeaddrinfo(res0);
1.1       deraadt   160:        }
                    161: }
                    162:
                    163: static int
1.11      deraadt   164: selectproto(char *proto)
1.1       deraadt   165: {
                    166:        int new = protos;
                    167:
                    168:        if (proto == 0 || streq(proto, "all"))
                    169:                new = TCP|UDP;
                    170:        else if (streq(proto, "tcp"))
                    171:                new = TCP;
                    172:        else if (streq(proto, "udp"))
                    173:                new = UDP;
1.4       millert   174:        return (protos = new);
1.1       deraadt   175: }
                    176:
                    177: static void
1.11      deraadt   178: showprotos(void)
1.1       deraadt   179: {
                    180:
                    181:        if ((protos&TCP) == 0)
                    182:                addch('!');
                    183:        addstr("tcp ");
                    184:        if ((protos&UDP) == 0)
                    185:                addch('!');
                    186:        addstr("udp ");
                    187: }
                    188:
                    189: static struct pitem {
                    190:        long    port;
                    191:        int     onoff;
                    192: } *ports;
                    193:
                    194: static int
1.11      deraadt   195: selectport(long port, int onoff)
1.1       deraadt   196: {
1.6       mpech     197:        struct pitem *p;
1.1       deraadt   198:
1.15      cloder    199:        if (ntohs(port) == -1) {
1.1       deraadt   200:                if (ports == 0)
                    201:                        return (0);
1.16    ! deraadt   202:                free(ports);
        !           203:                ports = NULL;
1.1       deraadt   204:                nports = 0;
                    205:                return (1);
                    206:        }
                    207:        for (p = ports; p < ports+nports; p++)
                    208:                if (p->port == port) {
                    209:                        p->onoff = onoff;
                    210:                        return (0);
                    211:                }
                    212:        if (nports == 0)
                    213:                ports = (struct pitem *)malloc(sizeof (*p));
                    214:        else
                    215:                ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p));
                    216:        p = &ports[nports++];
                    217:        p->port = port;
                    218:        p->onoff = onoff;
                    219:        return (1);
                    220: }
                    221:
                    222: int
1.11      deraadt   223: checkport(struct inpcb *inp)
1.1       deraadt   224: {
1.6       mpech     225:        struct pitem *p;
1.1       deraadt   226:
                    227:        if (ports)
                    228:        for (p = ports; p < ports+nports; p++)
                    229:                if (p->port == inp->inp_lport || p->port == inp->inp_fport)
                    230:                        return (p->onoff);
                    231:        return (1);
                    232: }
                    233:
                    234: static void
1.11      deraadt   235: showports(void)
1.1       deraadt   236: {
1.6       mpech     237:        struct pitem *p;
1.1       deraadt   238:        struct servent *sp;
                    239:
                    240:        for (p = ports; p < ports+nports; p++) {
                    241:                sp = getservbyport(p->port,
1.4       millert   242:                    protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp");
1.1       deraadt   243:                if (!p->onoff)
                    244:                        addch('!');
                    245:                if (sp)
                    246:                        printw("%s ", sp->s_name);
                    247:                else
1.15      cloder    248:                        printw("%d ", ntohs(p->port));
1.1       deraadt   249:        }
                    250: }
                    251:
                    252: static int
1.11      deraadt   253: addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
1.5       itojun    254: {
                    255:        if (sa1->sa_family != sa2->sa_family)
                    256:                return 0;
                    257:        if (sa1->sa_len != sa2->sa_len)
                    258:                return 0;
                    259:        switch (sa1->sa_family) {
                    260:        case AF_INET:
                    261:                if (((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
1.16    ! deraadt   262:                    ((struct sockaddr_in *)sa2)->sin_addr.s_addr)
1.5       itojun    263:                        return 1;
                    264:                break;
                    265:        case AF_INET6:
                    266:                if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)sa1)->sin6_addr,
1.16    ! deraadt   267:                    &((struct sockaddr_in6 *)sa2)->sin6_addr))
1.5       itojun    268:                        return 1;
                    269:                break;
                    270:        default:
                    271:                if (memcmp(sa1, sa2, sa1->sa_len) == 0)
                    272:                        return 1;
                    273:                break;
                    274:        }
                    275:        return 0;
                    276: }
                    277:
                    278: static int
1.11      deraadt   279: selecthost(struct sockaddr *sa, int onoff)
1.1       deraadt   280: {
1.6       mpech     281:        struct hitem *p;
1.1       deraadt   282:
1.5       itojun    283:        if (sa == 0) {
1.1       deraadt   284:                if (hosts == 0)
                    285:                        return (0);
1.16    ! deraadt   286:                free(hosts);
        !           287:                hosts = NULL;
1.1       deraadt   288:                nhosts = 0;
                    289:                return (1);
                    290:        }
                    291:        for (p = hosts; p < hosts+nhosts; p++)
1.5       itojun    292:                if (addrcmp((struct sockaddr *)&p->addr, sa)) {
1.1       deraadt   293:                        p->onoff = onoff;
                    294:                        return (0);
                    295:                }
1.5       itojun    296:        if (sa->sa_len > sizeof(struct sockaddr_storage))
                    297:                return (-1);    /*XXX*/
1.1       deraadt   298:        if (nhosts == 0)
                    299:                hosts = (struct hitem *)malloc(sizeof (*p));
                    300:        else
                    301:                hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
                    302:        p = &hosts[nhosts++];
1.5       itojun    303:        memcpy(&p->addr, sa, sa->sa_len);
1.1       deraadt   304:        p->onoff = onoff;
                    305:        return (1);
                    306: }
                    307:
                    308: int
1.11      deraadt   309: checkhost(struct inpcb *inp)
1.1       deraadt   310: {
1.6       mpech     311:        struct hitem *p;
1.1       deraadt   312:
                    313:        if (hosts)
1.5       itojun    314:        for (p = hosts; p < hosts+nhosts; p++) {
1.9       deraadt   315:                if (((struct sockaddr *)&p->addr)->sa_family == AF_INET &&
                    316:                    !(inp->inp_flags & INP_IPV6)) {
1.5       itojun    317:                        struct sockaddr_in *sin;
                    318:                        sin = (struct sockaddr_in *)&p->addr;
                    319:                        if (sin->sin_addr.s_addr == inp->inp_laddr.s_addr ||
                    320:                            sin->sin_addr.s_addr == inp->inp_faddr.s_addr)
                    321:                                return (p->onoff);
                    322:                }
1.9       deraadt   323:                if (((struct sockaddr *)&p->addr)->sa_family == AF_INET6 &&
                    324:                    (inp->inp_flags & INP_IPV6)) {
1.5       itojun    325:                        struct sockaddr_in6 *sin6;
                    326:                        sin6 = (struct sockaddr_in6 *)&p->addr;
                    327:                        if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_laddr6) ||
                    328:                            IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &inp->inp_faddr6))
                    329:                                return (p->onoff);
                    330:                }
                    331:        }
1.1       deraadt   332:        return (1);
                    333: }
                    334:
                    335: static void
1.11      deraadt   336: showhosts(void)
1.1       deraadt   337: {
1.6       mpech     338:        struct hitem *p;
1.5       itojun    339:        char hbuf[NI_MAXHOST];
                    340:        struct sockaddr *sa;
                    341:        int flags;
1.1       deraadt   342:
1.5       itojun    343:        flags = nflag ? NI_NUMERICHOST : 0;
1.1       deraadt   344:        for (p = hosts; p < hosts+nhosts; p++) {
1.5       itojun    345:                sa = (struct sockaddr *)&p->addr;
                    346:                if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
1.16    ! deraadt   347:                    flags) != 0)
1.9       deraadt   348:                        strlcpy(hbuf, "(invalid)", sizeof hbuf);
1.1       deraadt   349:                if (!p->onoff)
                    350:                        addch('!');
1.5       itojun    351:                printw("%s ", hbuf);
1.1       deraadt   352:        }
                    353: }