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