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