netcmds.c revision 14543
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
341590Srgrimes#ifndef lint
351590Srgrimesstatic char sccsid[] = "@(#)netcmds.c	8.1 (Berkeley) 6/6/93";
361590Srgrimes#endif /* not lint */
371590Srgrimes
381590Srgrimes/*
391590Srgrimes * Common network command support routines.
401590Srgrimes */
411590Srgrimes#include <sys/param.h>
4214543Sdg#include <sys/queue.h>
431590Srgrimes#include <sys/socket.h>
441590Srgrimes#include <sys/socketvar.h>
451590Srgrimes#include <sys/mbuf.h>
461590Srgrimes#include <sys/protosw.h>
471590Srgrimes
481590Srgrimes#include <net/route.h>
491590Srgrimes#include <netinet/in.h>
501590Srgrimes#include <netinet/in_systm.h>
511590Srgrimes#include <netinet/ip.h>
521590Srgrimes#include <netinet/in_pcb.h>
531590Srgrimes
541590Srgrimes#include <netdb.h>
551590Srgrimes#include <stdlib.h>
561590Srgrimes#include <string.h>
571590Srgrimes#include <ctype.h>
581590Srgrimes#include "systat.h"
591590Srgrimes#include "extern.h"
601590Srgrimes
611590Srgrimes#define	streq(a,b)	(strcmp(a,b)==0)
621590Srgrimes
631590Srgrimesstatic	struct hitem {
641590Srgrimes	struct	in_addr addr;
651590Srgrimes	int	onoff;
661590Srgrimes} *hosts;
671590Srgrimes
681590Srgrimesint nports, nhosts, protos;
691590Srgrimes
701590Srgrimesstatic void changeitems __P((char *, int));
711590Srgrimesstatic int selectproto __P((char *));
721590Srgrimesstatic void showprotos __P((void));
731590Srgrimesstatic int selectport __P((long, int));
741590Srgrimesstatic void showports __P((void));
751590Srgrimesstatic int selecthost __P((struct in_addr *, int));
761590Srgrimesstatic void showhosts __P((void));
771590Srgrimes
781590Srgrimesint
791590Srgrimesnetcmd(cmd, args)
801590Srgrimes	char *cmd, *args;
811590Srgrimes{
821590Srgrimes
831590Srgrimes	if (prefix(cmd, "tcp") || prefix(cmd, "udp")) {
841590Srgrimes		selectproto(cmd);
851590Srgrimes		return (1);
861590Srgrimes	}
871590Srgrimes	if (prefix(cmd, "ignore") || prefix(cmd, "display")) {
881590Srgrimes		changeitems(args, prefix(cmd, "display"));
891590Srgrimes		return (1);
901590Srgrimes	}
911590Srgrimes	if (prefix(cmd, "reset")) {
921590Srgrimes		selectproto(0);
931590Srgrimes		selecthost(0, 0);
941590Srgrimes		selectport(-1, 0);
951590Srgrimes		return (1);
961590Srgrimes	}
971590Srgrimes	if (prefix(cmd, "show")) {
981590Srgrimes		move(CMDLINE, 0); clrtoeol();
991590Srgrimes		if (*args == '\0') {
1001590Srgrimes			showprotos();
1011590Srgrimes			showhosts();
1021590Srgrimes			showports();
1031590Srgrimes			return (1);
1041590Srgrimes		}
1051590Srgrimes		if (prefix(args, "protos"))
1061590Srgrimes			showprotos();
1071590Srgrimes		else if (prefix(args, "hosts"))
1081590Srgrimes			showhosts();
1091590Srgrimes		else if (prefix(args, "ports"))
1101590Srgrimes			showports();
1111590Srgrimes		else
1121590Srgrimes			addstr("show what?");
1131590Srgrimes		return (1);
1141590Srgrimes	}
1151590Srgrimes	return (0);
1161590Srgrimes}
1171590Srgrimes
1181590Srgrimes
1191590Srgrimesstatic void
1201590Srgrimeschangeitems(args, onoff)
1211590Srgrimes	char *args;
1221590Srgrimes	int onoff;
1231590Srgrimes{
1241590Srgrimes	register char *cp;
1251590Srgrimes	struct servent *sp;
1261590Srgrimes	struct hostent *hp;
1271590Srgrimes	struct in_addr in;
1281590Srgrimes	char *index();
1291590Srgrimes
1301590Srgrimes	cp = index(args, '\n');
1311590Srgrimes	if (cp)
1321590Srgrimes		*cp = '\0';
1331590Srgrimes	for (;;args = cp) {
1341590Srgrimes		for (cp = args; *cp && isspace(*cp); cp++)
1351590Srgrimes			;
1361590Srgrimes		args = cp;
1371590Srgrimes		for (; *cp && !isspace(*cp); cp++)
1381590Srgrimes			;
1391590Srgrimes		if (*cp)
1401590Srgrimes			*cp++ = '\0';
1411590Srgrimes		if (cp - args == 0)
1421590Srgrimes			break;
1431590Srgrimes		sp = getservbyname(args,
1441590Srgrimes		    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
1451590Srgrimes		if (sp) {
1461590Srgrimes			selectport(sp->s_port, onoff);
1471590Srgrimes			continue;
1481590Srgrimes		}
1491590Srgrimes		hp = gethostbyname(args);
1501590Srgrimes		if (hp == 0) {
1511590Srgrimes			in.s_addr = inet_addr(args);
1521590Srgrimes			if (in.s_addr == -1) {
1531590Srgrimes				error("%s: unknown host or port", args);
1541590Srgrimes				continue;
1551590Srgrimes			}
1561590Srgrimes		} else
1571590Srgrimes			in = *(struct in_addr *)hp->h_addr;
1581590Srgrimes		selecthost(&in, onoff);
1591590Srgrimes	}
1601590Srgrimes}
1611590Srgrimes
1621590Srgrimesstatic int
1631590Srgrimesselectproto(proto)
1641590Srgrimes	char *proto;
1651590Srgrimes{
1661590Srgrimes	int new = protos;
1671590Srgrimes
1681590Srgrimes	if (proto == 0 || streq(proto, "all"))
1691590Srgrimes		new = TCP|UDP;
1701590Srgrimes	else if (streq(proto, "tcp"))
1711590Srgrimes		new = TCP;
1721590Srgrimes	else if (streq(proto, "udp"))
1731590Srgrimes		new = UDP;
1741590Srgrimes	return (new != protos, protos = new);
1751590Srgrimes}
1761590Srgrimes
1771590Srgrimesstatic void
1781590Srgrimesshowprotos()
1791590Srgrimes{
1801590Srgrimes
1811590Srgrimes	if ((protos&TCP) == 0)
1821590Srgrimes		addch('!');
1831590Srgrimes	addstr("tcp ");
1841590Srgrimes	if ((protos&UDP) == 0)
1851590Srgrimes		addch('!');
1861590Srgrimes	addstr("udp ");
1871590Srgrimes}
1881590Srgrimes
1891590Srgrimesstatic	struct pitem {
1901590Srgrimes	long	port;
1911590Srgrimes	int	onoff;
1921590Srgrimes} *ports;
1931590Srgrimes
1941590Srgrimesstatic int
1951590Srgrimesselectport(port, onoff)
1961590Srgrimes	long port;
1971590Srgrimes	int onoff;
1981590Srgrimes{
1991590Srgrimes	register struct pitem *p;
2001590Srgrimes
2011590Srgrimes	if (port == -1) {
2021590Srgrimes		if (ports == 0)
2031590Srgrimes			return (0);
2041590Srgrimes		free((char *)ports), ports = 0;
2051590Srgrimes		nports = 0;
2061590Srgrimes		return (1);
2071590Srgrimes	}
2081590Srgrimes	for (p = ports; p < ports+nports; p++)
2091590Srgrimes		if (p->port == port) {
2101590Srgrimes			p->onoff = onoff;
2111590Srgrimes			return (0);
2121590Srgrimes		}
2131590Srgrimes	if (nports == 0)
2141590Srgrimes		ports = (struct pitem *)malloc(sizeof (*p));
2151590Srgrimes	else
2161590Srgrimes		ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p));
2171590Srgrimes	p = &ports[nports++];
2181590Srgrimes	p->port = port;
2191590Srgrimes	p->onoff = onoff;
2201590Srgrimes	return (1);
2211590Srgrimes}
2221590Srgrimes
2231590Srgrimesint
2241590Srgrimescheckport(inp)
2251590Srgrimes	register struct inpcb *inp;
2261590Srgrimes{
2271590Srgrimes	register struct pitem *p;
2281590Srgrimes
2291590Srgrimes	if (ports)
2301590Srgrimes	for (p = ports; p < ports+nports; p++)
2311590Srgrimes		if (p->port == inp->inp_lport || p->port == inp->inp_fport)
2321590Srgrimes			return (p->onoff);
2331590Srgrimes	return (1);
2341590Srgrimes}
2351590Srgrimes
2361590Srgrimesstatic void
2371590Srgrimesshowports()
2381590Srgrimes{
2391590Srgrimes	register struct pitem *p;
2401590Srgrimes	struct servent *sp;
2411590Srgrimes
2421590Srgrimes	for (p = ports; p < ports+nports; p++) {
2431590Srgrimes		sp = getservbyport(p->port,
2441590Srgrimes		    protos == TCP|UDP ? 0 : protos == TCP ? "tcp" : "udp");
2451590Srgrimes		if (!p->onoff)
2461590Srgrimes			addch('!');
2471590Srgrimes		if (sp)
2481590Srgrimes			printw("%s ", sp->s_name);
2491590Srgrimes		else
2501590Srgrimes			printw("%d ", p->port);
2511590Srgrimes	}
2521590Srgrimes}
2531590Srgrimes
2541590Srgrimesstatic int
2551590Srgrimesselecthost(in, onoff)
2561590Srgrimes	struct in_addr *in;
2571590Srgrimes	int onoff;
2581590Srgrimes{
2591590Srgrimes	register struct hitem *p;
2601590Srgrimes
2611590Srgrimes	if (in == 0) {
2621590Srgrimes		if (hosts == 0)
2631590Srgrimes			return (0);
2641590Srgrimes		free((char *)hosts), hosts = 0;
2651590Srgrimes		nhosts = 0;
2661590Srgrimes		return (1);
2671590Srgrimes	}
2681590Srgrimes	for (p = hosts; p < hosts+nhosts; p++)
2691590Srgrimes		if (p->addr.s_addr == in->s_addr) {
2701590Srgrimes			p->onoff = onoff;
2711590Srgrimes			return (0);
2721590Srgrimes		}
2731590Srgrimes	if (nhosts == 0)
2741590Srgrimes		hosts = (struct hitem *)malloc(sizeof (*p));
2751590Srgrimes	else
2761590Srgrimes		hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
2771590Srgrimes	p = &hosts[nhosts++];
2781590Srgrimes	p->addr = *in;
2791590Srgrimes	p->onoff = onoff;
2801590Srgrimes	return (1);
2811590Srgrimes}
2821590Srgrimes
2831590Srgrimesint
2841590Srgrimescheckhost(inp)
2851590Srgrimes	register struct inpcb *inp;
2861590Srgrimes{
2871590Srgrimes	register struct hitem *p;
2881590Srgrimes
2891590Srgrimes	if (hosts)
2901590Srgrimes	for (p = hosts; p < hosts+nhosts; p++)
2911590Srgrimes		if (p->addr.s_addr == inp->inp_laddr.s_addr ||
2921590Srgrimes		    p->addr.s_addr == inp->inp_faddr.s_addr)
2931590Srgrimes			return (p->onoff);
2941590Srgrimes	return (1);
2951590Srgrimes}
2961590Srgrimes
2971590Srgrimesstatic void
2981590Srgrimesshowhosts()
2991590Srgrimes{
3001590Srgrimes	register struct hitem *p;
3011590Srgrimes	struct hostent *hp;
3021590Srgrimes
3031590Srgrimes	for (p = hosts; p < hosts+nhosts; p++) {
3041590Srgrimes		hp = gethostbyaddr((char *)&p->addr, sizeof (p->addr), AF_INET);
3051590Srgrimes		if (!p->onoff)
3061590Srgrimes			addch('!');
3071590Srgrimes		printw("%s ", hp ? hp->h_name : (char *)inet_ntoa(p->addr));
3081590Srgrimes	}
3091590Srgrimes}
310