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

1.12    ! millert     1: /*     $OpenBSD: netcmds.c,v 1.11 2002/06/18 00:46:47 deraadt 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.12    ! millert    37: static char rcsid[] = "$OpenBSD: netcmds.c,v 1.11 2002/06/18 00:46:47 deraadt 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);
                     97:                selectport(-1, 0);
                     98:                return (1);
                     99:        }
                    100:        if (prefix(cmd, "show")) {
                    101:                move(CMDLINE, 0); clrtoeol();
                    102:                if (*args == '\0') {
                    103:                        showprotos();
                    104:                        showhosts();
                    105:                        showports();
                    106:                        return (1);
                    107:                }
                    108:                if (prefix(args, "protos"))
                    109:                        showprotos();
                    110:                else if (prefix(args, "hosts"))
                    111:                        showhosts();
                    112:                else if (prefix(args, "ports"))
                    113:                        showports();
                    114:                else
                    115:                        addstr("show what?");
                    116:                return (1);
                    117:        }
                    118:        return (0);
                    119: }
                    120:
                    121:
                    122: static void
1.11      deraadt   123: changeitems(char *args, int onoff)
1.1       deraadt   124: {
1.6       mpech     125:        char *cp;
1.1       deraadt   126:        struct servent *sp;
1.5       itojun    127:        struct addrinfo hints, *res0, *res;
1.1       deraadt   128:
1.3       millert   129:        cp = strchr(args, '\n');
1.1       deraadt   130:        if (cp)
                    131:                *cp = '\0';
                    132:        for (;;args = cp) {
                    133:                for (cp = args; *cp && isspace(*cp); cp++)
                    134:                        ;
                    135:                args = cp;
                    136:                for (; *cp && !isspace(*cp); cp++)
                    137:                        ;
                    138:                if (*cp)
                    139:                        *cp++ = '\0';
                    140:                if (cp - args == 0)
                    141:                        break;
                    142:                sp = getservbyname(args,
                    143:                    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
                    144:                if (sp) {
                    145:                        selectport(sp->s_port, onoff);
                    146:                        continue;
                    147:                }
1.5       itojun    148:
                    149:                memset(&hints, 0, sizeof(hints));
                    150:                hints.ai_family = PF_UNSPEC;
                    151:                hints.ai_socktype = SOCK_DGRAM;
                    152:                if (getaddrinfo(args, "0", &hints, &res0) != 0) {
                    153:                        error("%s: unknown host or port", args);
                    154:                        continue;
1.1       deraadt   155:                }
1.5       itojun    156:                for (res = res0; res; res = res->ai_next)
                    157:                        selecthost(res->ai_addr, onoff);
                    158:                freeaddrinfo(res0);
1.1       deraadt   159:        }
                    160: }
                    161:
                    162: static int
1.11      deraadt   163: selectproto(char *proto)
1.1       deraadt   164: {
                    165:        int new = protos;
                    166:
                    167:        if (proto == 0 || streq(proto, "all"))
                    168:                new = TCP|UDP;
                    169:        else if (streq(proto, "tcp"))
                    170:                new = TCP;
                    171:        else if (streq(proto, "udp"))
                    172:                new = UDP;
1.4       millert   173:        return (protos = new);
1.1       deraadt   174: }
                    175:
                    176: static void
1.11      deraadt   177: showprotos(void)
1.1       deraadt   178: {
                    179:
                    180:        if ((protos&TCP) == 0)
                    181:                addch('!');
                    182:        addstr("tcp ");
                    183:        if ((protos&UDP) == 0)
                    184:                addch('!');
                    185:        addstr("udp ");
                    186: }
                    187:
                    188: static struct pitem {
                    189:        long    port;
                    190:        int     onoff;
                    191: } *ports;
                    192:
                    193: static int
1.11      deraadt   194: selectport(long port, int onoff)
1.1       deraadt   195: {
1.6       mpech     196:        struct pitem *p;
1.1       deraadt   197:
                    198:        if (port == -1) {
                    199:                if (ports == 0)
                    200:                        return (0);
                    201:                free((char *)ports), ports = 0;
                    202:                nports = 0;
                    203:                return (1);
                    204:        }
                    205:        for (p = ports; p < ports+nports; p++)
                    206:                if (p->port == port) {
                    207:                        p->onoff = onoff;
                    208:                        return (0);
                    209:                }
                    210:        if (nports == 0)
                    211:                ports = (struct pitem *)malloc(sizeof (*p));
                    212:        else
                    213:                ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p));
                    214:        p = &ports[nports++];
                    215:        p->port = port;
                    216:        p->onoff = onoff;
                    217:        return (1);
                    218: }
                    219:
                    220: int
1.11      deraadt   221: checkport(struct inpcb *inp)
1.1       deraadt   222: {
1.6       mpech     223:        struct pitem *p;
1.1       deraadt   224:
                    225:        if (ports)
                    226:        for (p = ports; p < ports+nports; p++)
                    227:                if (p->port == inp->inp_lport || p->port == inp->inp_fport)
                    228:                        return (p->onoff);
                    229:        return (1);
                    230: }
                    231:
                    232: static void
1.11      deraadt   233: showports(void)
1.1       deraadt   234: {
1.6       mpech     235:        struct pitem *p;
1.1       deraadt   236:        struct servent *sp;
                    237:
                    238:        for (p = ports; p < ports+nports; p++) {
                    239:                sp = getservbyport(p->port,
1.4       millert   240:                    protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp");
1.1       deraadt   241:                if (!p->onoff)
                    242:                        addch('!');
                    243:                if (sp)
                    244:                        printw("%s ", sp->s_name);
                    245:                else
                    246:                        printw("%d ", p->port);
                    247:        }
                    248: }
                    249:
                    250: static int
1.11      deraadt   251: addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
1.5       itojun    252: {
                    253:        if (sa1->sa_family != sa2->sa_family)
                    254:                return 0;
                    255:        if (sa1->sa_len != sa2->sa_len)
                    256:                return 0;
                    257:        switch (sa1->sa_family) {
                    258:        case AF_INET:
                    259:                if (((struct sockaddr_in *)sa1)->sin_addr.s_addr ==
                    260:                                ((struct sockaddr_in *)sa2)->sin_addr.s_addr)
                    261:                        return 1;
                    262:                break;
                    263: #ifdef INET6
                    264:        case AF_INET6:
                    265:                if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)sa1)->sin6_addr,
                    266:                                &((struct sockaddr_in6 *)sa2)->sin6_addr))
                    267:                        return 1;
                    268:                break;
                    269: #endif
                    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);
                    286:                free((char *)hosts), hosts = 0;
                    287:                nhosts = 0;
                    288:                return (1);
                    289:        }
                    290:        for (p = hosts; p < hosts+nhosts; p++)
1.5       itojun    291:                if (addrcmp((struct sockaddr *)&p->addr, sa)) {
1.1       deraadt   292:                        p->onoff = onoff;
                    293:                        return (0);
                    294:                }
1.5       itojun    295:        if (sa->sa_len > sizeof(struct sockaddr_storage))
                    296:                return (-1);    /*XXX*/
1.1       deraadt   297:        if (nhosts == 0)
                    298:                hosts = (struct hitem *)malloc(sizeof (*p));
                    299:        else
                    300:                hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
                    301:        p = &hosts[nhosts++];
1.5       itojun    302:        memcpy(&p->addr, sa, sa->sa_len);
1.1       deraadt   303:        p->onoff = onoff;
                    304:        return (1);
                    305: }
                    306:
                    307: int
1.11      deraadt   308: checkhost(struct inpcb *inp)
1.1       deraadt   309: {
1.6       mpech     310:        struct hitem *p;
1.1       deraadt   311:
                    312:        if (hosts)
1.5       itojun    313:        for (p = hosts; p < hosts+nhosts; p++) {
1.9       deraadt   314:                if (((struct sockaddr *)&p->addr)->sa_family == AF_INET &&
                    315:                    !(inp->inp_flags & INP_IPV6)) {
1.5       itojun    316:                        struct sockaddr_in *sin;
                    317:                        sin = (struct sockaddr_in *)&p->addr;
                    318:                        if (sin->sin_addr.s_addr == inp->inp_laddr.s_addr ||
                    319:                            sin->sin_addr.s_addr == inp->inp_faddr.s_addr)
                    320:                                return (p->onoff);
                    321:                }
                    322: #ifdef INET6
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: #endif
                    332:        }
1.1       deraadt   333:        return (1);
                    334: }
                    335:
                    336: static void
1.11      deraadt   337: showhosts(void)
1.1       deraadt   338: {
1.6       mpech     339:        struct hitem *p;
1.5       itojun    340:        char hbuf[NI_MAXHOST];
                    341:        struct sockaddr *sa;
                    342:        int flags;
1.1       deraadt   343:
1.5       itojun    344: #if 0
                    345:        flags = nflag ? NI_NUMERICHOST : 0;
                    346: #else
                    347:        flags = 0;
                    348: #endif
1.1       deraadt   349:        for (p = hosts; p < hosts+nhosts; p++) {
1.5       itojun    350:                sa = (struct sockaddr *)&p->addr;
                    351:                if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
                    352:                                flags) != 0)
1.9       deraadt   353:                        strlcpy(hbuf, "(invalid)", sizeof hbuf);
1.1       deraadt   354:                if (!p->onoff)
                    355:                        addch('!');
1.5       itojun    356:                printw("%s ", hbuf);
1.1       deraadt   357:        }
                    358: }