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

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