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