xref: /original-bsd/usr.bin/systat/netcmds.c (revision e59fb703)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)netcmds.c	5.5 (Berkeley) 02/04/91";
9 #endif not lint
10 
11 /*
12  * Common network command support routines.
13  */
14 #include "systat.h"
15 #include <ctype.h>
16 
17 #include <sys/socket.h>
18 #include <sys/socketvar.h>
19 #include <sys/mbuf.h>
20 #include <sys/protosw.h>
21 
22 #include <net/route.h>
23 #include <netinet/in_systm.h>
24 #include <netinet/ip.h>
25 #include <netinet/in_pcb.h>
26 
27 #define	streq(a,b)	(strcmp(a,b)==0)
28 
29 static void changeitems(), showprotos(), showports(), showhosts();
30 static int selectproto(), selectport(), selecthost();
31 
32 netcmd(cmd, args)
33 	char *cmd, *args;
34 {
35 
36 	if (prefix(cmd, "tcp") || prefix(cmd, "udp")) {
37 		selectproto(cmd);
38 		return (1);
39 	}
40 	if (prefix(cmd, "ignore") || prefix(cmd, "display")) {
41 		changeitems(args, prefix(cmd, "display"));
42 		return (1);
43 	}
44 	if (prefix(cmd, "reset")) {
45 		selectproto(0);
46 		selecthost(0);
47 		selectport(-1);
48 		return (1);
49 	}
50 	if (prefix(cmd, "show")) {
51 		move(CMDLINE, 0); clrtoeol();
52 		if (*args == '\0') {
53 			showprotos();
54 			showhosts();
55 			showports();
56 			return (1);
57 		}
58 		if (prefix(args, "protos"))
59 			showprotos();
60 		else if (prefix(args, "hosts"))
61 			showhosts();
62 		else if (prefix(args, "ports"))
63 			showports();
64 		else
65 			addstr("show what?");
66 		return (1);
67 	}
68 	return (0);
69 }
70 
71 static void
72 changeitems(args, onoff)
73 	char *args;
74 	int onoff;
75 {
76 	register char *cp;
77 	struct servent *sp;
78 	struct hostent *hp;
79 	struct in_addr in;
80 	char *index();
81 
82 	cp = index(args, '\n');
83 	if (cp)
84 		*cp = '\0';
85 	for (;;args = cp) {
86 		for (cp = args; *cp && isspace(*cp); cp++)
87 			;
88 		args = cp;
89 		for (; *cp && !isspace(*cp); cp++)
90 			;
91 		if (*cp)
92 			*cp++ = '\0';
93 		if (cp - args == 0)
94 			break;
95 		sp = getservbyname(args,
96 		    protos == TCP ? "tcp" : protos == UDP ? "udp" : 0);
97 		if (sp) {
98 			selectport(sp->s_port, onoff);
99 			continue;
100 		}
101 		hp = gethostbyname(args);
102 		if (hp == 0) {
103 			in.s_addr = inet_addr(args);
104 			if (in.s_addr == -1) {
105 				error("%s: unknown host or port", args);
106 				continue;
107 			}
108 		} else
109 			in = *(struct in_addr *)hp->h_addr;
110 		selecthost(&in, onoff);
111 	}
112 }
113 
114 static int
115 selectproto(proto)
116 	char *proto;
117 {
118 	int new = protos;
119 
120 	if (proto == 0 || streq(proto, "all"))
121 		new = TCP|UDP;
122 	else if (streq(proto, "tcp"))
123 		new = TCP;
124 	else if (streq(proto, "udp"))
125 		new = UDP;
126 	return (new != protos, protos = new);
127 }
128 
129 static void
130 showprotos()
131 {
132 
133 	if ((protos&TCP) == 0)
134 		addch('!');
135 	addstr("tcp ");
136 	if ((protos&UDP) == 0)
137 		addch('!');
138 	addstr("udp ");
139 }
140 
141 static	struct pitem {
142 	long	port;
143 	int	onoff;
144 } *ports;
145 
146 static int
147 selectport(port, onoff)
148 	long port;
149 	int onoff;
150 {
151 	register struct pitem *p;
152 
153 	if (port == -1) {
154 		if (ports == 0)
155 			return (0);
156 		free((char *)ports), ports = 0;
157 		nports = 0;
158 		return (1);
159 	}
160 	for (p = ports; p < ports+nports; p++)
161 		if (p->port == port) {
162 			p->onoff = onoff;
163 			return (0);
164 		}
165 	if (nports == 0)
166 		ports = (struct pitem *)malloc(sizeof (*p));
167 	else
168 		ports = (struct pitem *)realloc(ports, (nports+1)*sizeof (*p));
169 	p = &ports[nports++];
170 	p->port = port;
171 	p->onoff = onoff;
172 	return (1);
173 }
174 
175 checkport(inp)
176 	register struct inpcb *inp;
177 {
178 	register struct pitem *p;
179 
180 	if (ports)
181 	for (p = ports; p < ports+nports; p++)
182 		if (p->port == inp->inp_lport || p->port == inp->inp_fport)
183 			return (p->onoff);
184 	return (1);
185 }
186 
187 static void
188 showports()
189 {
190 	register struct pitem *p;
191 	struct servent *sp;
192 
193 	for (p = ports; p < ports+nports; p++) {
194 		sp = getservbyport(p->port,
195 		    protos == TCP|UDP ? 0 : protos == TCP ? "tcp" : "udp");
196 		if (!p->onoff)
197 			addch('!');
198 		if (sp)
199 			printw("%s ", sp->s_name);
200 		else
201 			printw("%d ", p->port);
202 	}
203 }
204 
205 static	struct hitem {
206 	struct	in_addr addr;
207 	int	onoff;
208 } *hosts;
209 
210 static int
211 selecthost(in, onoff)
212 	struct in_addr *in;
213 	int onoff;
214 {
215 	register struct hitem *p;
216 
217 	if (in == 0) {
218 		if (hosts == 0)
219 			return (0);
220 		free((char *)hosts), hosts = 0;
221 		nhosts = 0;
222 		return (1);
223 	}
224 	for (p = hosts; p < hosts+nhosts; p++)
225 		if (p->addr.s_addr == in->s_addr) {
226 			p->onoff = onoff;
227 			return (0);
228 		}
229 	if (nhosts == 0)
230 		hosts = (struct hitem *)malloc(sizeof (*p));
231 	else
232 		hosts = (struct hitem *)realloc(hosts, (nhosts+1)*sizeof (*p));
233 	p = &hosts[nhosts++];
234 	p->addr = *in;
235 	p->onoff = onoff;
236 	return (1);
237 }
238 
239 checkhost(inp)
240 	register struct inpcb *inp;
241 {
242 	register struct hitem *p;
243 
244 	if (hosts)
245 	for (p = hosts; p < hosts+nhosts; p++)
246 		if (p->addr.s_addr == inp->inp_laddr.s_addr ||
247 		    p->addr.s_addr == inp->inp_faddr.s_addr)
248 			return (p->onoff);
249 	return (1);
250 }
251 
252 static void
253 showhosts()
254 {
255 	register struct hitem *p;
256 	struct hostent *hp;
257 
258 	for (p = hosts; p < hosts+nhosts; p++) {
259 		hp = gethostbyaddr(&p->addr, sizeof (p->addr), AF_INET);
260 		if (!p->onoff)
261 			addch('!');
262 		printw("%s ", hp ? hp->h_name : inet_ntoa(p->addr));
263 	}
264 }
265