xref: /original-bsd/usr.bin/netstat/if.c (revision e2944021)
1 /*
2  * Copyright (c) 1983 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[] = "@(#)if.c	5.3 (Berkeley) 04/23/86";
9 #endif not lint
10 
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 
14 #include <net/if.h>
15 #include <netinet/in.h>
16 #include <netinet/in_var.h>
17 #include <netns/ns.h>
18 
19 #include <stdio.h>
20 
21 extern	int kmem;
22 extern	int tflag;
23 extern	int nflag;
24 extern	char *interface;
25 extern	int unit;
26 extern	char *routename(), *netname();
27 
28 /*
29  * Print a description of the network interfaces.
30  */
31 intpr(interval, ifnetaddr)
32 	int interval;
33 	off_t ifnetaddr;
34 {
35 	struct ifnet ifnet;
36 	union {
37 		struct ifaddr ifa;
38 		struct in_ifaddr in;
39 	} ifaddr;
40 	off_t ifaddraddr;
41 	char name[16];
42 
43 	if (ifnetaddr == 0) {
44 		printf("ifnet: symbol not defined\n");
45 		return;
46 	}
47 	if (interval) {
48 		sidewaysintpr(interval, ifnetaddr);
49 		return;
50 	}
51 	klseek(kmem, ifnetaddr, 0);
52 	read(kmem, &ifnetaddr, sizeof ifnetaddr);
53 	printf("%-5.5s %-5.5s %-10.10s  %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s",
54 		"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
55 		"Opkts", "Oerrs");
56 	printf(" %-6.6s", "Collis");
57 	if (tflag)
58 		printf(" %-6.6s", "Timer");
59 	putchar('\n');
60 	ifaddraddr = 0;
61 	while (ifnetaddr || ifaddraddr) {
62 		struct sockaddr_in *sin;
63 		register char *cp;
64 		int n;
65 		char *index();
66 		struct in_addr in, inet_makeaddr();
67 
68 		if (ifaddraddr == 0) {
69 			klseek(kmem, ifnetaddr, 0);
70 			read(kmem, &ifnet, sizeof ifnet);
71 			klseek(kmem, (off_t)ifnet.if_name, 0);
72 			read(kmem, name, 16);
73 			name[15] = '\0';
74 			ifnetaddr = (off_t) ifnet.if_next;
75 			if (interface != 0 &&
76 			    (strcmp(name, interface) != 0 || unit != ifnet.if_unit))
77 				continue;
78 			cp = index(name, '\0');
79 			*cp++ = ifnet.if_unit + '0';
80 			if ((ifnet.if_flags&IFF_UP) == 0)
81 				*cp++ = '*';
82 			*cp = '\0';
83 			ifaddraddr = (off_t)ifnet.if_addrlist;
84 		}
85 		printf("%-5.5s %-5d ", name, ifnet.if_mtu);
86 		if (ifaddraddr == 0) {
87 			printf("%-10.10s  ", "none");
88 			printf("%-12.12s ", "none");
89 		} else {
90 			klseek(kmem, ifaddraddr, 0);
91 			read(kmem, &ifaddr, sizeof ifaddr);
92 			ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
93 			switch (ifaddr.ifa.ifa_addr.sa_family) {
94 			case AF_UNSPEC:
95 				printf("%-10.10s  ", "none");
96 				printf("%-12.12s ", "none");
97 				break;
98 			case AF_INET:
99 				sin = (struct sockaddr_in *)&ifaddr.in.ia_addr;
100 #ifdef notdef
101 				/* can't use inet_makeaddr because kernel
102 				 * keeps nets unshifted.
103 				 */
104 				in = inet_makeaddr(ifaddr.in.ia_subnet,
105 					INADDR_ANY);
106 				printf("%-10.10s  ", netname(in));
107 #else
108 				printf("%-10.10s  ",
109 					netname(htonl(ifaddr.in.ia_subnet),
110 						ifaddr.in.ia_subnetmask));
111 #endif
112 				printf("%-12.12s ", routename(sin->sin_addr));
113 				break;
114 			case AF_NS:
115 				{
116 				struct sockaddr_ns *sns =
117 				(struct sockaddr_ns *)&ifaddr.in.ia_addr;
118 				long net;
119 				char host[8];
120 				*(union ns_net *) &net = sns->sns_addr.x_net;
121 				sprintf(host, "%lxH", ntohl(net));
122 				upHex(host);
123 				printf("ns:%-8s ", host);
124 
125 				printf("%-12s ",ns_phost(sns));
126 				}
127 				break;
128 			default:
129 				printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family);
130 				for (cp = (char *)&ifaddr.ifa.ifa_addr +
131 				    sizeof(struct sockaddr) - 1;
132 				    cp >= ifaddr.ifa.ifa_addr.sa_data; --cp)
133 					if (*cp != 0)
134 						break;
135 				n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1;
136 				cp = (char *)ifaddr.ifa.ifa_addr.sa_data;
137 				if (n <= 6)
138 					while (--n)
139 						printf("%02d.", *cp++ & 0xff);
140 				else
141 					while (--n)
142 						printf("%02d", *cp++ & 0xff);
143 				printf("%02d ", *cp & 0xff);
144 				break;
145 			}
146 		}
147 		printf("%-7d %-5d %-7d %-5d %-6d",
148 		    ifnet.if_ipackets, ifnet.if_ierrors,
149 		    ifnet.if_opackets, ifnet.if_oerrors,
150 		    ifnet.if_collisions);
151 		if (tflag)
152 			printf(" %-6d", ifnet.if_timer);
153 		putchar('\n');
154 	}
155 }
156 
157 #define	MAXIF	10
158 struct	iftot {
159 	char	ift_name[16];		/* interface name */
160 	int	ift_ip;			/* input packets */
161 	int	ift_ie;			/* input errors */
162 	int	ift_op;			/* output packets */
163 	int	ift_oe;			/* output errors */
164 	int	ift_co;			/* collisions */
165 } iftot[MAXIF];
166 
167 /*
168  * Print a running summary of interface statistics.
169  * Repeat display every interval seconds, showing
170  * statistics collected over that interval.  First
171  * line printed at top of screen is always cumulative.
172  */
173 sidewaysintpr(interval, off)
174 	int interval;
175 	off_t off;
176 {
177 	struct ifnet ifnet;
178 	off_t firstifnet;
179 	register struct iftot *ip, *total;
180 	register int line;
181 	struct iftot *lastif, *sum, *interesting;
182 	int maxtraffic;
183 
184 	klseek(kmem, off, 0);
185 	read(kmem, &firstifnet, sizeof (off_t));
186 	lastif = iftot;
187 	sum = iftot + MAXIF - 1;
188 	total = sum - 1;
189 	interesting = iftot;
190 	for (off = firstifnet, ip = iftot; off;) {
191 		char *cp;
192 
193 		klseek(kmem, off, 0);
194 		read(kmem, &ifnet, sizeof ifnet);
195 		klseek(kmem, (int)ifnet.if_name, 0);
196 		ip->ift_name[0] = '(';
197 		read(kmem, ip->ift_name + 1, 15);
198 		if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
199 		    unit == ifnet.if_unit)
200 			interesting = ip;
201 		ip->ift_name[15] = '\0';
202 		cp = index(ip->ift_name, '\0');
203 		sprintf(cp, "%d)", ifnet.if_unit);
204 		ip++;
205 		if (ip >= iftot + MAXIF - 2)
206 			break;
207 		off = (off_t) ifnet.if_next;
208 	}
209 	lastif = ip;
210 banner:
211 	printf("    input   %-6.6s    output       ", interesting->ift_name);
212 	if (lastif - iftot > 0)
213 		printf("   input  (Total)    output       ");
214 	for (ip = iftot; ip < iftot + MAXIF; ip++) {
215 		ip->ift_ip = 0;
216 		ip->ift_ie = 0;
217 		ip->ift_op = 0;
218 		ip->ift_oe = 0;
219 		ip->ift_co = 0;
220 	}
221 	putchar('\n');
222 	printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ",
223 		"packets", "errs", "packets", "errs", "colls");
224 	if (lastif - iftot > 0)
225 		printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ",
226 			"packets", "errs", "packets", "errs", "colls");
227 	putchar('\n');
228 	fflush(stdout);
229 	line = 0;
230 loop:
231 	sum->ift_ip = 0;
232 	sum->ift_ie = 0;
233 	sum->ift_op = 0;
234 	sum->ift_oe = 0;
235 	sum->ift_co = 0;
236 	for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
237 		klseek(kmem, off, 0);
238 		read(kmem, &ifnet, sizeof ifnet);
239 		if (ip == interesting)
240 			printf("%-7d %-5d %-7d %-5d %-5d ",
241 				ifnet.if_ipackets - ip->ift_ip,
242 				ifnet.if_ierrors - ip->ift_ie,
243 				ifnet.if_opackets - ip->ift_op,
244 				ifnet.if_oerrors - ip->ift_oe,
245 				ifnet.if_collisions - ip->ift_co);
246 		ip->ift_ip = ifnet.if_ipackets;
247 		ip->ift_ie = ifnet.if_ierrors;
248 		ip->ift_op = ifnet.if_opackets;
249 		ip->ift_oe = ifnet.if_oerrors;
250 		ip->ift_co = ifnet.if_collisions;
251 		sum->ift_ip += ip->ift_ip;
252 		sum->ift_ie += ip->ift_ie;
253 		sum->ift_op += ip->ift_op;
254 		sum->ift_oe += ip->ift_oe;
255 		sum->ift_co += ip->ift_co;
256 		off = (off_t) ifnet.if_next;
257 	}
258 	if (lastif - iftot > 0)
259 		printf("%-7d %-5d %-7d %-5d %-5d\n",
260 			sum->ift_ip - total->ift_ip,
261 			sum->ift_ie - total->ift_ie,
262 			sum->ift_op - total->ift_op,
263 			sum->ift_oe - total->ift_oe,
264 			sum->ift_co - total->ift_co);
265 	*total = *sum;
266 	fflush(stdout);
267 	line++;
268 	if (interval)
269 		sleep(interval);
270 	if (line == 21)
271 		goto banner;
272 	goto loop;
273 	/*NOTREACHED*/
274 }
275