netcmds.c revision 92922
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1980, 1992, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
3487715Smarkm#include <sys/cdefs.h>
351590Srgrimes
3687715Smarkm__FBSDID("$FreeBSD: head/usr.bin/systat/netcmds.c 92922 2002-03-22 01:42:45Z imp $");
3787715Smarkm
3887715Smarkm#ifdef lint
3987715Smarkmstatic const char sccsid[] = "@(#)netcmds.c	8.1 (Berkeley) 6/6/93";
4087715Smarkm#endif
4187715Smarkm
421590Srgrimes/*
431590Srgrimes * Common network command support routines.
441590Srgrimes */
451590Srgrimes#include <sys/param.h>
4614543Sdg#include <sys/queue.h>
471590Srgrimes#include <sys/socket.h>
481590Srgrimes#include <sys/socketvar.h>
491590Srgrimes#include <sys/protosw.h>
501590Srgrimes
511590Srgrimes#include <net/route.h>
521590Srgrimes#include <netinet/in.h>
531590Srgrimes#include <netinet/in_systm.h>
541590Srgrimes#include <netinet/ip.h>
551590Srgrimes#include <netinet/in_pcb.h>
5636916Speter#include <arpa/inet.h>
571590Srgrimes
5887715Smarkm#include <ctype.h>
591590Srgrimes#include <netdb.h>
601590Srgrimes#include <stdlib.h>
611590Srgrimes#include <string.h>
6287715Smarkm
631590Srgrimes#include "systat.h"
641590Srgrimes#include "extern.h"
651590Srgrimes
661590Srgrimes#define	streq(a,b)	(strcmp(a,b)==0)
671590Srgrimes
681590Srgrimesstatic	struct hitem {
691590Srgrimes	struct	in_addr addr;
701590Srgrimes	int	onoff;
711590Srgrimes} *hosts;
721590Srgrimes
731590Srgrimesint nports, nhosts, protos;
741590Srgrimes
7592922Simpstatic void changeitems(const char *, int);
7692922Simpstatic int selectproto(const char *);
7792922Simpstatic void showprotos(void);
7892922Simpstatic int selectport(long, int);
7992922Simpstatic void showports(void);
8092922Simpstatic int selecthost(struct in_addr *, int);
8192922Simpstatic void showhosts(void);
821590Srgrimes
831590Srgrimesint
841590Srgrimesnetcmd(cmd, args)
8587715Smarkm	const char *cmd, *args;
861590Srgrimes{
871590Srgrimes
8831522Ssteve	if (prefix(cmd, "proto")) {
8931522Ssteve		if (*args == '\0') {
9031522Ssteve			move(CMDLINE, 0);
9131522Ssteve			clrtoeol();
9231522Ssteve			addstr("which proto?");
9331522Ssteve		} else if (!selectproto(args)) {
9431522Ssteve			error("%s: Unknown protocol.", args);
9531522Ssteve		}
961590Srgrimes		return (1);
971590Srgrimes	}
981590Srgrimes	if (prefix(cmd, "ignore") || prefix(cmd, "display")) {
991590Srgrimes		changeitems(args, prefix(cmd, "display"));
1001590Srgrimes		return (1);
1011590Srgrimes	}
1021590Srgrimes	if (prefix(cmd, "reset")) {
1031590Srgrimes		selectproto(0);
1041590Srgrimes		selecthost(0, 0);
1051590Srgrimes		selectport(-1, 0);
1061590Srgrimes		return (1);
1071590Srgrimes	}
1081590Srgrimes	if (prefix(cmd, "show")) {
1091590Srgrimes		move(CMDLINE, 0); clrtoeol();
1101590Srgrimes		if (*args == '\0') {
1111590Srgrimes			showprotos();
1121590Srgrimes			showhosts();
1131590Srgrimes			showports();
1141590Srgrimes			return (1);
1151590Srgrimes		}
1161590Srgrimes		if (prefix(args, "protos"))
1171590Srgrimes			showprotos();
1181590Srgrimes		else if (prefix(args, "hosts"))
1191590Srgrimes			showhosts();
1201590Srgrimes		else if (prefix(args, "ports"))
1211590Srgrimes			showports();
1221590Srgrimes		else
1231590Srgrimes			addstr("show what?");
1241590Srgrimes		return (1);
1251590Srgrimes	}
1261590Srgrimes	return (0);
1271590Srgrimes}
1281590Srgrimes
1291590Srgrimes
1301590Srgrimesstatic void
1311590Srgrimeschangeitems(args, onoff)
13287715Smarkm	const char *args;
1331590Srgrimes	int onoff;
1341590Srgrimes{
13587715Smarkm	char *cp, *tmpstr, *tmpstr1;
1361590Srgrimes	struct servent *sp;
1371590Srgrimes	struct hostent *hp;
1381590Srgrimes	struct in_addr in;
1391590Srgrimes
14087715Smarkm	tmpstr = tmpstr1 = strdup(args);
14187715Smarkm	cp = index(tmpstr1, '\n');
1421590Srgrimes	if (cp)
1431590Srgrimes		*cp = '\0';
14487715Smarkm	for (;;tmpstr1 = cp) {
14587715Smarkm		for (cp = tmpstr1; *cp && isspace(*cp); cp++)
1461590Srgrimes			;
14787715Smarkm		tmpstr1 = cp;
1481590Srgrimes		for (; *cp && !isspace(*cp); cp++)
1491590Srgrimes			;
1501590Srgrimes		if (*cp)
1511590Srgrimes			*cp++ = '\0';
15287715Smarkm		if (cp - tmpstr1 == 0)
1531590Srgrimes			break;
15487715Smarkm		sp = getservbyname(tmpstr1,
1551590Srgrimes		    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
1561590Srgrimes		if (sp) {
1571590Srgrimes			selectport(sp->s_port, onoff);
1581590Srgrimes			continue;
1591590Srgrimes		}
16087715Smarkm		hp = gethostbyname(tmpstr1);
1611590Srgrimes		if (hp == 0) {
16287715Smarkm			in.s_addr = inet_addr(tmpstr1);
16387715Smarkm			if ((int)in.s_addr == -1) {
16487715Smarkm				error("%s: unknown host or port", tmpstr1);
1651590Srgrimes				continue;
1661590Srgrimes			}
1671590Srgrimes		} else
1681590Srgrimes			in = *(struct in_addr *)hp->h_addr;
1691590Srgrimes		selecthost(&in, onoff);
1701590Srgrimes	}
17187715Smarkm	free(tmpstr);
1721590Srgrimes}
1731590Srgrimes
1741590Srgrimesstatic int
1751590Srgrimesselectproto(proto)
17687715Smarkm	const char *proto;
1771590Srgrimes{
1781590Srgrimes
1791590Srgrimes	if (proto == 0 || streq(proto, "all"))
18031522Ssteve		protos = TCP | UDP;
1811590Srgrimes	else if (streq(proto, "tcp"))
18231522Ssteve		protos = TCP;
1831590Srgrimes	else if (streq(proto, "udp"))
18431522Ssteve		protos = UDP;
18531522Ssteve	else
18631522Ssteve		return (0);
18731522Ssteve
18831522Ssteve	return (protos);
1891590Srgrimes}
1901590Srgrimes
1911590Srgrimesstatic void
1921590Srgrimesshowprotos()
1931590Srgrimes{
1941590Srgrimes
1951590Srgrimes	if ((protos&TCP) == 0)
1961590Srgrimes		addch('!');
1971590Srgrimes	addstr("tcp ");
1981590Srgrimes	if ((protos&UDP) == 0)
1991590Srgrimes		addch('!');
2001590Srgrimes	addstr("udp ");
2011590Srgrimes}
2021590Srgrimes
2031590Srgrimesstatic	struct pitem {
2041590Srgrimes	long	port;
2051590Srgrimes	int	onoff;
2061590Srgrimes} *ports;
2071590Srgrimes
2081590Srgrimesstatic int
2091590Srgrimesselectport(port, onoff)
2101590Srgrimes	long port;
2111590Srgrimes	int onoff;
2121590Srgrimes{
2131590Srgrimes	register struct pitem *p;
2141590Srgrimes
2151590Srgrimes	if (port == -1) {
2161590Srgrimes		if (ports == 0)
2171590Srgrimes			return (0);
2181590Srgrimes		free((char *)ports), ports = 0;
2191590Srgrimes		nports = 0;
2201590Srgrimes		return (1);
2211590Srgrimes	}
2221590Srgrimes	for (p = ports; p < ports+nports; p++)
2231590Srgrimes		if (p->port == port) {
2241590Srgrimes			p->onoff = onoff;
2251590Srgrimes			return (0);
2261590Srgrimes		}
2271590Srgrimes	if (nports == 0)
2281590Srgrimes		ports = (struct pitem *)malloc(sizeof (*p));
2291590Srgrimes	else
2301590Srgrimes		ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p));
2311590Srgrimes	p = &ports[nports++];
2321590Srgrimes	p->port = port;
2331590Srgrimes	p->onoff = onoff;
2341590Srgrimes	return (1);
2351590Srgrimes}
2361590Srgrimes
2371590Srgrimesint
2381590Srgrimescheckport(inp)
2391590Srgrimes	register struct inpcb *inp;
2401590Srgrimes{
2411590Srgrimes	register struct pitem *p;
2421590Srgrimes
2431590Srgrimes	if (ports)
2441590Srgrimes	for (p = ports; p < ports+nports; p++)
2451590Srgrimes		if (p->port == inp->inp_lport || p->port == inp->inp_fport)
2461590Srgrimes			return (p->onoff);
2471590Srgrimes	return (1);
2481590Srgrimes}
2491590Srgrimes
2501590Srgrimesstatic void
2511590Srgrimesshowports()
2521590Srgrimes{
2531590Srgrimes	register struct pitem *p;
2541590Srgrimes	struct servent *sp;
2551590Srgrimes
2561590Srgrimes	for (p = ports; p < ports+nports; p++) {
2571590Srgrimes		sp = getservbyport(p->port,
25874671Stmm		    protos == (TCP|UDP) ? 0 : protos == TCP ? "tcp" : "udp");
2591590Srgrimes		if (!p->onoff)
2601590Srgrimes			addch('!');
2611590Srgrimes		if (sp)
2621590Srgrimes			printw("%s ", sp->s_name);
2631590Srgrimes		else
2641590Srgrimes			printw("%d ", p->port);
2651590Srgrimes	}
2661590Srgrimes}
2671590Srgrimes
2681590Srgrimesstatic int
2691590Srgrimesselecthost(in, onoff)
2701590Srgrimes	struct in_addr *in;
2711590Srgrimes	int onoff;
2721590Srgrimes{
2731590Srgrimes	register struct hitem *p;
2741590Srgrimes
2751590Srgrimes	if (in == 0) {
2761590Srgrimes		if (hosts == 0)
2771590Srgrimes			return (0);
2781590Srgrimes		free((char *)hosts), hosts = 0;
2791590Srgrimes		nhosts = 0;
2801590Srgrimes		return (1);
2811590Srgrimes	}
2821590Srgrimes	for (p = hosts; p < hosts+nhosts; p++)
2831590Srgrimes		if (p->addr.s_addr == in->s_addr) {
2841590Srgrimes			p->onoff = onoff;
2851590Srgrimes			return (0);
2861590Srgrimes		}
2871590Srgrimes	if (nhosts == 0)
2881590Srgrimes		hosts = (struct hitem *)malloc(sizeof (*p));
2891590Srgrimes	else
2901590Srgrimes		hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
2911590Srgrimes	p = &hosts[nhosts++];
2921590Srgrimes	p->addr = *in;
2931590Srgrimes	p->onoff = onoff;
2941590Srgrimes	return (1);
2951590Srgrimes}
2961590Srgrimes
2971590Srgrimesint
2981590Srgrimescheckhost(inp)
2991590Srgrimes	register struct inpcb *inp;
3001590Srgrimes{
3011590Srgrimes	register struct hitem *p;
3021590Srgrimes
3031590Srgrimes	if (hosts)
3041590Srgrimes	for (p = hosts; p < hosts+nhosts; p++)
3051590Srgrimes		if (p->addr.s_addr == inp->inp_laddr.s_addr ||
3061590Srgrimes		    p->addr.s_addr == inp->inp_faddr.s_addr)
3071590Srgrimes			return (p->onoff);
3081590Srgrimes	return (1);
3091590Srgrimes}
3101590Srgrimes
3111590Srgrimesstatic void
3121590Srgrimesshowhosts()
3131590Srgrimes{
3141590Srgrimes	register struct hitem *p;
3151590Srgrimes	struct hostent *hp;
3161590Srgrimes
3171590Srgrimes	for (p = hosts; p < hosts+nhosts; p++) {
3181590Srgrimes		hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET);
3191590Srgrimes		if (!p->onoff)
3201590Srgrimes			addch('!');
3211590Srgrimes		printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr));
3221590Srgrimes	}
3231590Srgrimes}
324