reorganize window management to allow display routines to set
[unix-history] / usr / src / usr.bin / netstat / main.c
CommitLineData
ed85a06f 1#ifndef lint
bbd2d21e 2static char sccsid[] = "@(#)main.c 4.9 83/05/30";
ed85a06f
SL
3#endif
4
5#include <sys/param.h>
d96df0d1 6#include <sys/vmmac.h>
7cd60ad6 7#include <machine/pte.h>
ed85a06f
SL
8#include <ctype.h>
9#include <errno.h>
10#include <netdb.h>
11#include <nlist.h>
12#include <stdio.h>
13
14struct nlist nl[] = {
15#define N_MBSTAT 0
16 { "_mbstat" },
17#define N_IPSTAT 1
18 { "_ipstat" },
19#define N_TCB 2
20 { "_tcb" },
21#define N_TCPSTAT 3
22 { "_tcpstat" },
23#define N_UDB 4
24 { "_udb" },
25#define N_UDPSTAT 5
26 { "_udpstat" },
27#define N_RAWCB 6
28 { "_rawcb" },
29#define N_SYSMAP 7
30 { "_Sysmap" },
31#define N_SYSSIZE 8
32 { "_Syssize" },
33#define N_IFNET 9
34 { "_ifnet" },
35#define N_HOSTS 10
36 { "_hosts" },
37#define N_RTHOST 11
38 { "_rthost" },
39#define N_RTNET 12
40 { "_rtnet" },
7333c75b
SL
41#define N_ICMPSTAT 13
42 { "_icmpstat" },
bbd2d21e
SL
43#define N_RTSTAT 14
44 { "_rtstat" },
7333c75b 45 "",
ed85a06f
SL
46};
47
6df0a927 48extern int protopr();
7333c75b 49extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
6df0a927 50
ed85a06f 51struct protox {
6df0a927
SL
52 u_char pr_index; /* index into nlist of cb head */
53 u_char pr_sindex; /* index into nlist of stat block */
54 u_char pr_wanted; /* 1 if wanted, 0 otherwise */
55 int (*pr_cblocks)(); /* control blocks printing routine */
56 int (*pr_stats)(); /* statistics printing routine */
57 char *pr_name; /* well-known name */
ed85a06f 58} protox[] = {
6df0a927
SL
59 { N_TCB, N_TCPSTAT, 1, protopr,
60 tcp_stats, "tcp" },
61 { N_UDB, N_UDPSTAT, 1, protopr,
62 udp_stats, "udp" },
63 { -1, N_IPSTAT, 1, 0,
64 ip_stats, "ip" },
7333c75b
SL
65 { -1, N_ICMPSTAT, 1, 0,
66 icmp_stats, "icmp" },
6df0a927
SL
67 { -1, -1, 0, 0,
68 0, 0 }
ed85a06f
SL
69};
70
71struct pte *Sysmap;
72
73char *system = "/vmunix";
74char *kmemf = "/dev/kmem";
75int kmem;
76int kflag;
77int Aflag;
78int aflag;
79int hflag;
80int iflag;
81int mflag;
82int nflag;
83int rflag;
84int sflag;
85int tflag;
86int interval;
87char usage[] = "[ -Aaihmnrst ] [ interval ] [ system ] [ core ]";
88
89main(argc, argv)
90 int argc;
91 char *argv[];
92{
93 int i;
94 char *cp, *name;
95 register struct protoent *p;
96
97 name = argv[0];
98 argc--, argv++;
99 while (argc > 0 && **argv == '-') {
100 for (cp = &argv[0][1]; *cp; cp++)
101 switch(argv[0][1]) {
102
103 case 'A':
104 Aflag++;
105 break;
106
107 case 'a':
108 aflag++;
109 break;
110
111 case 'h':
112 hflag++;
113 break;
114
115 case 'i':
116 iflag++;
117 break;
118
119 case 'm':
120 mflag++;
121 break;
122
123 case 'n':
124 nflag++;
125 break;
126
127 case 'r':
128 rflag++;
129 break;
130
131 case 's':
132 sflag++;
133 break;
134
135 case 't':
136 tflag++;
137 break;
138
139 default:
140use:
141 printf("usage: %s %s\n", name, usage);
142 exit(1);
143 }
144 argv++, argc--;
145 }
146 if (argc > 0 && isdigit(argv[0][0])) {
147 interval = atoi(argv[0]);
148 if (interval <= 0)
149 goto use;
150 argv++, argc--;
90cb8200 151 iflag++;
ed85a06f
SL
152 }
153 if (argc > 0) {
154 system = *argv;
155 argv++, argc--;
156 }
157 nlist(system, nl);
158 if (nl[0].n_type == 0) {
159 fprintf(stderr, "%s: no namelist\n", system);
160 exit(1);
161 }
162 if (argc > 0) {
163 kmemf = *argv;
164 kflag++;
165 }
166 kmem = open(kmemf, 0);
167 if (kmem < 0) {
168 fprintf(stderr, "cannot open ");
169 perror(kmemf);
170 exit(1);
171 }
172 if (kflag) {
173 off_t off;
174
175 off = nl[N_SYSMAP].n_value & 0x7fffffff;
176 lseek(kmem, off, 0);
177 nl[N_SYSSIZE].n_value *= 4;
178 Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value);
179 if (Sysmap == 0) {
180 perror("Sysmap");
181 exit(1);
182 }
183 read(kmem, Sysmap, nl[N_SYSSIZE].n_value);
184 }
185 if (mflag) {
186 mbpr(nl[N_MBSTAT].n_value);
187 exit(0);
188 }
ed85a06f
SL
189 /*
190 * Keep file descriptors open to avoid overhead
191 * of open/close on each call to get* routines.
192 */
ed85a06f
SL
193 sethostent(1);
194 setnetent(1);
90cb8200
SL
195 if (iflag) {
196 intpr(interval, nl[N_IFNET].n_value);
197 exit(0);
198 }
ed85a06f
SL
199 if (hflag) {
200 hostpr(nl[N_HOSTS].n_value);
201 exit(0);
202 }
203 if (rflag) {
bbd2d21e
SL
204 if (sflag)
205 rt_stats(nl[N_RTSTAT].n_value);
206 else
207 routepr(nl[N_RTHOST].n_value, nl[N_RTNET].n_value);
ed85a06f
SL
208 exit(0);
209 }
90cb8200
SL
210 setprotoent(1);
211 setservent(1);
ed85a06f
SL
212 while (p = getprotoent()) {
213 register struct protox *tp;
214
6df0a927 215 for (tp = protox; tp->pr_name; tp++)
ed85a06f
SL
216 if (strcmp(tp->pr_name, p->p_name) == 0)
217 break;
6df0a927
SL
218 if (tp->pr_name == 0 || tp->pr_wanted == 0)
219 continue;
220 if (sflag && tp->pr_stats) {
221 (*tp->pr_stats)(nl[tp->pr_sindex].n_value, p->p_name);
ed85a06f 222 continue;
6df0a927
SL
223 }
224 if (tp->pr_cblocks)
225 (*tp->pr_cblocks)(nl[tp->pr_index].n_value, p->p_name);
ed85a06f
SL
226 }
227 endprotoent();
228}
229
230/*
231 * Seek into the kernel for a value.
232 */
233klseek(fd, base, off)
234 int fd, base, off;
235{
236
237 if (kflag) {
238 /* get kernel pte */
4659bf8e 239#ifdef vax
ed85a06f 240 base &= 0x7fffffff;
4659bf8e 241#endif
d96df0d1 242 base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
ed85a06f
SL
243 }
244 lseek(fd, base, off);
245}
bbd2d21e
SL
246
247char *
248plural(n)
249 int n;
250{
251
252 return (n != 1 ? "s" : "");
253}