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