1 | /*- |
---|
2 | * Copyright (c) 1983, 1988, 1993 |
---|
3 | * Regents of the University of California. All rights reserved. |
---|
4 | * |
---|
5 | * Redistribution and use in source and binary forms, with or without |
---|
6 | * modification, are permitted provided that the following conditions |
---|
7 | * are met: |
---|
8 | * 1. Redistributions of source code must retain the above copyright |
---|
9 | * notice, this list of conditions and the following disclaimer. |
---|
10 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer in the |
---|
12 | * documentation and/or other materials provided with the distribution. |
---|
13 | * 3. All advertising materials mentioning features or use of this software |
---|
14 | * must display the following acknowledgement: |
---|
15 | * This product includes software developed by the University of |
---|
16 | * California, Berkeley and its contributors. |
---|
17 | * 4. Neither the name of the University nor the names of its contributors |
---|
18 | * may be used to endorse or promote products derived from this software |
---|
19 | * without specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
31 | * SUCH DAMAGE. |
---|
32 | */ |
---|
33 | |
---|
34 | #ifndef lint |
---|
35 | char const copyright[] = |
---|
36 | "@(#) Copyright (c) 1983, 1988, 1993\n\ |
---|
37 | Regents of the University of California. All rights reserved.\n"; |
---|
38 | #endif /* not lint */ |
---|
39 | |
---|
40 | #if 0 |
---|
41 | #ifndef lint |
---|
42 | static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94"; |
---|
43 | #endif /* not lint */ |
---|
44 | #endif |
---|
45 | |
---|
46 | #ifdef __rtems__ |
---|
47 | #define __need_getopt_newlib |
---|
48 | #include <getopt.h> |
---|
49 | #endif /* __rtems__ */ |
---|
50 | #include <sys/cdefs.h> |
---|
51 | __FBSDID("$FreeBSD$"); |
---|
52 | |
---|
53 | #include <rtems/bsd/sys/param.h> |
---|
54 | #include <sys/file.h> |
---|
55 | #include <sys/protosw.h> |
---|
56 | #include <sys/socket.h> |
---|
57 | #include <sys/socketvar.h> |
---|
58 | |
---|
59 | #include <netinet/in.h> |
---|
60 | |
---|
61 | #ifdef NETGRAPH |
---|
62 | #include <netgraph/ng_socket.h> |
---|
63 | #endif |
---|
64 | |
---|
65 | #include <ctype.h> |
---|
66 | #include <err.h> |
---|
67 | #include <errno.h> |
---|
68 | #include <kvm.h> |
---|
69 | #include <limits.h> |
---|
70 | #include <netdb.h> |
---|
71 | #include <nlist.h> |
---|
72 | #include <paths.h> |
---|
73 | #include <stdint.h> |
---|
74 | #include <stdio.h> |
---|
75 | #include <stdlib.h> |
---|
76 | #include <string.h> |
---|
77 | #include <unistd.h> |
---|
78 | #include "netstat.h" |
---|
79 | |
---|
80 | static struct nlist nl[] = { |
---|
81 | #define N_IFNET 0 |
---|
82 | { .n_name = "_ifnet" }, |
---|
83 | #define N_RTSTAT 1 |
---|
84 | { .n_name = "_rtstat" }, |
---|
85 | #define N_RTREE 2 |
---|
86 | { .n_name = "_rt_tables"}, |
---|
87 | #define N_MRTSTAT 3 |
---|
88 | { .n_name = "_mrtstat" }, |
---|
89 | #define N_MFCHASHTBL 4 |
---|
90 | { .n_name = "_mfchashtbl" }, |
---|
91 | #define N_VIFTABLE 5 |
---|
92 | { .n_name = "_viftable" }, |
---|
93 | #define N_IPX 6 |
---|
94 | { .n_name = "_ipxpcb_list"}, |
---|
95 | #define N_IPXSTAT 7 |
---|
96 | { .n_name = "_ipxstat"}, |
---|
97 | #define N_SPXSTAT 8 |
---|
98 | { .n_name = "_spx_istat"}, |
---|
99 | #define N_DDPSTAT 9 |
---|
100 | { .n_name = "_ddpstat"}, |
---|
101 | #define N_DDPCB 10 |
---|
102 | { .n_name = "_ddpcb"}, |
---|
103 | #define N_NGSOCKS 11 |
---|
104 | { .n_name = "_ngsocklist"}, |
---|
105 | #define N_IP6STAT 12 |
---|
106 | { .n_name = "_ip6stat" }, |
---|
107 | #define N_ICMP6STAT 13 |
---|
108 | { .n_name = "_icmp6stat" }, |
---|
109 | #define N_IPSECSTAT 14 |
---|
110 | { .n_name = "_ipsec4stat" }, |
---|
111 | #define N_IPSEC6STAT 15 |
---|
112 | { .n_name = "_ipsec6stat" }, |
---|
113 | #define N_PIM6STAT 16 |
---|
114 | { .n_name = "_pim6stat" }, |
---|
115 | #define N_MRT6STAT 17 |
---|
116 | { .n_name = "_mrt6stat" }, |
---|
117 | #define N_MF6CTABLE 18 |
---|
118 | { .n_name = "_mf6ctable" }, |
---|
119 | #define N_MIF6TABLE 19 |
---|
120 | { .n_name = "_mif6table" }, |
---|
121 | #define N_PFKEYSTAT 20 |
---|
122 | { .n_name = "_pfkeystat" }, |
---|
123 | #define N_MBSTAT 21 |
---|
124 | { .n_name = "_mbstat" }, |
---|
125 | #define N_MBTYPES 22 |
---|
126 | { .n_name = "_mbtypes" }, |
---|
127 | #define N_NMBCLUSTERS 23 |
---|
128 | { .n_name = "_nmbclusters" }, |
---|
129 | #define N_NMBUFS 24 |
---|
130 | { .n_name = "_nmbufs" }, |
---|
131 | #define N_MBHI 25 |
---|
132 | { .n_name = "_mbuf_hiwm" }, |
---|
133 | #define N_CLHI 26 |
---|
134 | { .n_name = "_clust_hiwm" }, |
---|
135 | #define N_NCPUS 27 |
---|
136 | { .n_name = "_smp_cpus" }, |
---|
137 | #define N_PAGESZ 28 |
---|
138 | { .n_name = "_pagesize" }, |
---|
139 | #define N_MBPSTAT 29 |
---|
140 | { .n_name = "_mb_statpcpu" }, |
---|
141 | #define N_RTTRASH 30 |
---|
142 | { .n_name = "_rttrash" }, |
---|
143 | #define N_MBLO 31 |
---|
144 | { .n_name = "_mbuf_lowm" }, |
---|
145 | #define N_CLLO 32 |
---|
146 | { .n_name = "_clust_lowm" }, |
---|
147 | #define N_CARPSTAT 33 |
---|
148 | { .n_name = "_carpstats" }, |
---|
149 | #define N_PFSYNCSTAT 34 |
---|
150 | { .n_name = "_pfsyncstats" }, |
---|
151 | #define N_AHSTAT 35 |
---|
152 | { .n_name = "_ahstat" }, |
---|
153 | #define N_ESPSTAT 36 |
---|
154 | { .n_name = "_espstat" }, |
---|
155 | #define N_IPCOMPSTAT 37 |
---|
156 | { .n_name = "_ipcompstat" }, |
---|
157 | #define N_TCPSTAT 38 |
---|
158 | { .n_name = "_tcpstat" }, |
---|
159 | #define N_UDPSTAT 39 |
---|
160 | { .n_name = "_udpstat" }, |
---|
161 | #define N_IPSTAT 40 |
---|
162 | { .n_name = "_ipstat" }, |
---|
163 | #define N_ICMPSTAT 41 |
---|
164 | { .n_name = "_icmpstat" }, |
---|
165 | #define N_IGMPSTAT 42 |
---|
166 | { .n_name = "_igmpstat" }, |
---|
167 | #define N_PIMSTAT 43 |
---|
168 | { .n_name = "_pimstat" }, |
---|
169 | #define N_TCBINFO 44 |
---|
170 | { .n_name = "_tcbinfo" }, |
---|
171 | #define N_UDBINFO 45 |
---|
172 | { .n_name = "_udbinfo" }, |
---|
173 | #define N_DIVCBINFO 46 |
---|
174 | { .n_name = "_divcbinfo" }, |
---|
175 | #define N_RIPCBINFO 47 |
---|
176 | { .n_name = "_ripcbinfo" }, |
---|
177 | #define N_UNP_COUNT 48 |
---|
178 | { .n_name = "_unp_count" }, |
---|
179 | #define N_UNP_GENCNT 49 |
---|
180 | { .n_name = "_unp_gencnt" }, |
---|
181 | #define N_UNP_DHEAD 50 |
---|
182 | { .n_name = "_unp_dhead" }, |
---|
183 | #define N_UNP_SHEAD 51 |
---|
184 | { .n_name = "_unp_shead" }, |
---|
185 | #define N_RIP6STAT 52 |
---|
186 | { .n_name = "_rip6stat" }, |
---|
187 | #define N_SCTPSTAT 53 |
---|
188 | { .n_name = "_sctpstat" }, |
---|
189 | #define N_MFCTABLESIZE 54 |
---|
190 | { .n_name = "_mfctablesize" }, |
---|
191 | #define N_ARPSTAT 55 |
---|
192 | { .n_name = "_arpstat" }, |
---|
193 | { .n_name = NULL }, |
---|
194 | }; |
---|
195 | |
---|
196 | struct protox { |
---|
197 | int pr_index; /* index into nlist of cb head */ |
---|
198 | int pr_sindex; /* index into nlist of stat block */ |
---|
199 | u_char pr_wanted; /* 1 if wanted, 0 otherwise */ |
---|
200 | void (*pr_cblocks)(u_long, const char *, int, int); |
---|
201 | /* control blocks printing routine */ |
---|
202 | void (*pr_stats)(u_long, const char *, int, int); |
---|
203 | /* statistics printing routine */ |
---|
204 | void (*pr_istats)(char *); /* per/if statistics printing routine */ |
---|
205 | const char *pr_name; /* well-known name */ |
---|
206 | int pr_usesysctl; /* non-zero if we use sysctl, not kvm */ |
---|
207 | int pr_protocol; |
---|
208 | } protox[] = { |
---|
209 | { N_TCBINFO, N_TCPSTAT, 1, protopr, |
---|
210 | tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, |
---|
211 | { N_UDBINFO, N_UDPSTAT, 1, protopr, |
---|
212 | udp_stats, NULL, "udp", 1, IPPROTO_UDP }, |
---|
213 | #ifdef SCTP |
---|
214 | { -1, N_SCTPSTAT, 1, sctp_protopr, |
---|
215 | sctp_stats, NULL, "sctp", 1, IPPROTO_SCTP }, |
---|
216 | #endif |
---|
217 | { N_DIVCBINFO, -1, 1, protopr, |
---|
218 | NULL, NULL, "divert", 1, IPPROTO_DIVERT }, |
---|
219 | { N_RIPCBINFO, N_IPSTAT, 1, protopr, |
---|
220 | ip_stats, NULL, "ip", 1, IPPROTO_RAW }, |
---|
221 | { N_RIPCBINFO, N_ICMPSTAT, 1, protopr, |
---|
222 | icmp_stats, NULL, "icmp", 1, IPPROTO_ICMP }, |
---|
223 | { N_RIPCBINFO, N_IGMPSTAT, 1, protopr, |
---|
224 | igmp_stats, NULL, "igmp", 1, IPPROTO_IGMP }, |
---|
225 | #ifdef IPSEC |
---|
226 | { -1, N_IPSECSTAT, 1, NULL, /* keep as compat */ |
---|
227 | ipsec_stats, NULL, "ipsec", 0, 0}, |
---|
228 | { -1, N_AHSTAT, 1, NULL, |
---|
229 | ah_stats, NULL, "ah", 0, 0}, |
---|
230 | { -1, N_ESPSTAT, 1, NULL, |
---|
231 | esp_stats, NULL, "esp", 0, 0}, |
---|
232 | { -1, N_IPCOMPSTAT, 1, NULL, |
---|
233 | ipcomp_stats, NULL, "ipcomp", 0, 0}, |
---|
234 | #endif |
---|
235 | { N_RIPCBINFO, N_PIMSTAT, 1, protopr, |
---|
236 | pim_stats, NULL, "pim", 1, IPPROTO_PIM }, |
---|
237 | { -1, N_CARPSTAT, 1, NULL, |
---|
238 | carp_stats, NULL, "carp", 1, 0 }, |
---|
239 | { -1, N_PFSYNCSTAT, 1, NULL, |
---|
240 | pfsync_stats, NULL, "pfsync", 1, 0 }, |
---|
241 | { -1, N_ARPSTAT, 1, NULL, |
---|
242 | arp_stats, NULL, "arp", 1, 0 }, |
---|
243 | { -1, -1, 0, NULL, |
---|
244 | NULL, NULL, NULL, 0, 0 } |
---|
245 | }; |
---|
246 | |
---|
247 | #ifdef INET6 |
---|
248 | struct protox ip6protox[] = { |
---|
249 | { N_TCBINFO, N_TCPSTAT, 1, protopr, |
---|
250 | tcp_stats, NULL, "tcp", 1, IPPROTO_TCP }, |
---|
251 | { N_UDBINFO, N_UDPSTAT, 1, protopr, |
---|
252 | udp_stats, NULL, "udp", 1, IPPROTO_UDP }, |
---|
253 | { N_RIPCBINFO, N_IP6STAT, 1, protopr, |
---|
254 | ip6_stats, ip6_ifstats, "ip6", 1, IPPROTO_RAW }, |
---|
255 | { N_RIPCBINFO, N_ICMP6STAT, 1, protopr, |
---|
256 | icmp6_stats, icmp6_ifstats, "icmp6", 1, IPPROTO_ICMPV6 }, |
---|
257 | #ifdef IPSEC |
---|
258 | { -1, N_IPSEC6STAT, 1, NULL, |
---|
259 | ipsec_stats, NULL, "ipsec6", 0, 0 }, |
---|
260 | #endif |
---|
261 | #ifdef notyet |
---|
262 | { -1, N_PIM6STAT, 1, NULL, |
---|
263 | pim6_stats, NULL, "pim6", 1, 0 }, |
---|
264 | #endif |
---|
265 | { -1, N_RIP6STAT, 1, NULL, |
---|
266 | rip6_stats, NULL, "rip6", 1, 0 }, |
---|
267 | { -1, -1, 0, NULL, |
---|
268 | NULL, NULL, NULL, 0, 0 } |
---|
269 | }; |
---|
270 | #endif /*INET6*/ |
---|
271 | |
---|
272 | #ifdef IPSEC |
---|
273 | struct protox pfkeyprotox[] = { |
---|
274 | { -1, N_PFKEYSTAT, 1, NULL, |
---|
275 | pfkey_stats, NULL, "pfkey", 0, 0 }, |
---|
276 | { -1, -1, 0, NULL, |
---|
277 | NULL, NULL, NULL, 0, 0 } |
---|
278 | }; |
---|
279 | #endif |
---|
280 | |
---|
281 | #ifndef __rtems__ |
---|
282 | struct protox atalkprotox[] = { |
---|
283 | { N_DDPCB, N_DDPSTAT, 1, atalkprotopr, |
---|
284 | ddp_stats, NULL, "ddp", 0, 0 }, |
---|
285 | { -1, -1, 0, NULL, |
---|
286 | NULL, NULL, NULL, 0, 0 } |
---|
287 | }; |
---|
288 | #endif |
---|
289 | #ifdef NETGRAPH |
---|
290 | struct protox netgraphprotox[] = { |
---|
291 | { N_NGSOCKS, -1, 1, netgraphprotopr, |
---|
292 | NULL, NULL, "ctrl", 0, 0 }, |
---|
293 | { N_NGSOCKS, -1, 1, netgraphprotopr, |
---|
294 | NULL, NULL, "data", 0, 0 }, |
---|
295 | { -1, -1, 0, NULL, |
---|
296 | NULL, NULL, NULL, 0, 0 } |
---|
297 | }; |
---|
298 | #endif |
---|
299 | #ifdef IPX |
---|
300 | struct protox ipxprotox[] = { |
---|
301 | { N_IPX, N_IPXSTAT, 1, ipxprotopr, |
---|
302 | ipx_stats, NULL, "ipx", 0, 0 }, |
---|
303 | { N_IPX, N_SPXSTAT, 1, ipxprotopr, |
---|
304 | spx_stats, NULL, "spx", 0, 0 }, |
---|
305 | { -1, -1, 0, NULL, |
---|
306 | NULL, NULL, 0, 0, 0 } |
---|
307 | }; |
---|
308 | #endif |
---|
309 | |
---|
310 | struct protox *protoprotox[] = { |
---|
311 | protox, |
---|
312 | #ifdef INET6 |
---|
313 | ip6protox, |
---|
314 | #endif |
---|
315 | #ifdef IPSEC |
---|
316 | pfkeyprotox, |
---|
317 | #endif |
---|
318 | #ifdef IPX |
---|
319 | ipxprotox, |
---|
320 | #endif |
---|
321 | #ifndef __rtems__ |
---|
322 | atalkprotox, NULL }; |
---|
323 | #else |
---|
324 | NULL }; |
---|
325 | #endif |
---|
326 | |
---|
327 | static void printproto(struct protox *, const char *); |
---|
328 | static void usage(void); |
---|
329 | static struct protox *name2protox(const char *); |
---|
330 | static struct protox *knownname(const char *); |
---|
331 | |
---|
332 | static kvm_t *kvmd; |
---|
333 | static char *nlistf = NULL, *memf = NULL; |
---|
334 | |
---|
335 | int Aflag; /* show addresses of protocol control block */ |
---|
336 | int aflag; /* show all sockets (including servers) */ |
---|
337 | int Bflag; /* show information about bpf consumers */ |
---|
338 | int bflag; /* show i/f total bytes in/out */ |
---|
339 | int dflag; /* show i/f dropped packets */ |
---|
340 | int gflag; /* show group (multicast) routing or stats */ |
---|
341 | int hflag; /* show counters in human readable format */ |
---|
342 | int iflag; /* show interfaces */ |
---|
343 | int Lflag; /* show size of listen queues */ |
---|
344 | int mflag; /* show memory stats */ |
---|
345 | int noutputs = 0; /* how much outputs before we exit */ |
---|
346 | int numeric_addr; /* show addresses numerically */ |
---|
347 | int numeric_port; /* show ports numerically */ |
---|
348 | static int pflag; /* show given protocol */ |
---|
349 | int rflag; /* show routing tables (or routing stats) */ |
---|
350 | int sflag; /* show protocol statistics */ |
---|
351 | int tflag; /* show i/f watchdog timers */ |
---|
352 | int Wflag; /* wide display */ |
---|
353 | int xflag; /* extra information, includes all socket buffer info */ |
---|
354 | int zflag; /* zero stats */ |
---|
355 | |
---|
356 | int interval; /* repeat interval for i/f stats */ |
---|
357 | |
---|
358 | char *interface; /* desired i/f for stats, or NULL for all i/fs */ |
---|
359 | int unit; /* unit number for above */ |
---|
360 | |
---|
361 | int af; /* address family */ |
---|
362 | int live; /* true if we are examining a live system */ |
---|
363 | |
---|
364 | |
---|
365 | #ifdef __rtems__ |
---|
366 | static int main_netstat(int argc, char *argv[]); |
---|
367 | static int rtems_shell_main_netstat(int argc, char *argv[]) |
---|
368 | { |
---|
369 | int i; |
---|
370 | rtems_shell_globals_t netstat_globals; |
---|
371 | rtems_shell_globals = &netstat_globals; |
---|
372 | memset (rtems_shell_globals, 0, sizeof (netstat_globals)); |
---|
373 | |
---|
374 | i = 0; |
---|
375 | protox[i].pr_index = N_TCBINFO; |
---|
376 | protox[i].pr_sindex = N_TCPSTAT; |
---|
377 | protox[i].pr_wanted = 1; |
---|
378 | protox[i].pr_cblocks = protopr; |
---|
379 | protox[i].pr_stats = tcp_stats; |
---|
380 | protox[i].pr_istats = NULL; |
---|
381 | protox[i].pr_name = "tcp"; |
---|
382 | protox[i].pr_usesysctl = 1; |
---|
383 | protox[i].pr_protocol = IPPROTO_TCP; |
---|
384 | i++; |
---|
385 | protox[i].pr_index = N_UDBINFO; |
---|
386 | protox[i].pr_sindex = N_UDPSTAT; |
---|
387 | protox[i].pr_wanted = 1; |
---|
388 | protox[i].pr_cblocks = protopr; |
---|
389 | protox[i].pr_stats = udp_stats; |
---|
390 | protox[i].pr_istats = NULL; |
---|
391 | protox[i].pr_name = "udp"; |
---|
392 | protox[i].pr_usesysctl = 1; |
---|
393 | protox[i].pr_protocol = IPPROTO_UDP; |
---|
394 | i++; |
---|
395 | #ifdef SCTP |
---|
396 | protox[i].pr_index = -1; |
---|
397 | protox[i].pr_sindex = N_SCTPSTAT; |
---|
398 | protox[i].pr_wanted = 1; |
---|
399 | protox[i].pr_cblocks = sctp_protopr; |
---|
400 | protox[i].pr_stats = sctp_stats; |
---|
401 | protox[i].pr_istats = NULL; |
---|
402 | protox[i].pr_name = "sctp"; |
---|
403 | protox[i].pr_usesysctl = 1; |
---|
404 | protox[i].pr_protocol = IPPROTO_SCTP; |
---|
405 | i++; |
---|
406 | #endif |
---|
407 | protox[i].pr_index = N_DIVCBINFO; |
---|
408 | protox[i].pr_sindex = -1; |
---|
409 | protox[i].pr_wanted = 1; |
---|
410 | protox[i].pr_cblocks = protopr; |
---|
411 | protox[i].pr_stats = NULL; |
---|
412 | protox[i].pr_istats = NULL; |
---|
413 | protox[i].pr_name = "divert"; |
---|
414 | protox[i].pr_usesysctl = 1; |
---|
415 | protox[i].pr_protocol = IPPROTO_DIVERT; |
---|
416 | i++; |
---|
417 | protox[i].pr_index = N_RIPCBINFO; |
---|
418 | protox[i].pr_sindex = N_IPSTAT; |
---|
419 | protox[i].pr_wanted = 1; |
---|
420 | protox[i].pr_cblocks = protopr; |
---|
421 | protox[i].pr_stats = ip_stats; |
---|
422 | protox[i].pr_istats = NULL; |
---|
423 | protox[i].pr_name = "ip"; |
---|
424 | protox[i].pr_usesysctl = 1; |
---|
425 | protox[i].pr_protocol = IPPROTO_RAW; |
---|
426 | i++; |
---|
427 | protox[i].pr_index = N_RIPCBINFO; |
---|
428 | protox[i].pr_sindex = N_ICMPSTAT; |
---|
429 | protox[i].pr_wanted = 1; |
---|
430 | protox[i].pr_cblocks = protopr; |
---|
431 | protox[i].pr_stats = icmp_stats; |
---|
432 | protox[i].pr_istats = NULL; |
---|
433 | protox[i].pr_name = "icmp"; |
---|
434 | protox[i].pr_usesysctl = 1; |
---|
435 | protox[i].pr_protocol = IPPROTO_ICMP; |
---|
436 | i++; |
---|
437 | protox[i].pr_index = N_RIPCBINFO; |
---|
438 | protox[i].pr_sindex = N_IGMPSTAT; |
---|
439 | protox[i].pr_wanted = 1; |
---|
440 | protox[i].pr_cblocks = protopr; |
---|
441 | protox[i].pr_stats = igmp_stats; |
---|
442 | protox[i].pr_istats = NULL; |
---|
443 | protox[i].pr_name = "igmp"; |
---|
444 | protox[i].pr_usesysctl = 1; |
---|
445 | protox[i].pr_protocol = IPPROTO_IGMP; |
---|
446 | i++; |
---|
447 | #ifdef IPSEC |
---|
448 | protox[i].pr_index = -1; |
---|
449 | protox[i].pr_sindex = N_IPSECSTAT; |
---|
450 | protox[i].pr_wanted = 1; |
---|
451 | protox[i].pr_cblocks = NULL; |
---|
452 | protox[i].pr_stats = ipsec_stats; |
---|
453 | protox[i].pr_istats = NULL; |
---|
454 | protox[i].pr_name = "ipsec"; |
---|
455 | protox[i].pr_usesysctl = 0; |
---|
456 | protox[i].pr_protocol = 0; |
---|
457 | i++; |
---|
458 | protox[i].pr_index = -1; |
---|
459 | protox[i].pr_sindex = N_AHSTAT; |
---|
460 | protox[i].pr_wanted = 1; |
---|
461 | protox[i].pr_cblocks = NULL; |
---|
462 | protox[i].pr_stats = ah_stats; |
---|
463 | protox[i].pr_istats = NULL; |
---|
464 | protox[i].pr_name = "ah"; |
---|
465 | protox[i].pr_usesysctl = 0; |
---|
466 | protox[i].pr_protocol = 0; |
---|
467 | i++; |
---|
468 | protox[i].pr_index = -1; |
---|
469 | protox[i].pr_sindex = N_ESPSTAT; |
---|
470 | protox[i].pr_wanted = 1; |
---|
471 | protox[i].pr_cblocks = NULL; |
---|
472 | protox[i].pr_stats = esp_stats; |
---|
473 | protox[i].pr_istats = NULL; |
---|
474 | protox[i].pr_name = "esp"; |
---|
475 | protox[i].pr_usesysctl = 0; |
---|
476 | protox[i].pr_protocol = 0; |
---|
477 | i++; |
---|
478 | protox[i].pr_index = -1; |
---|
479 | protox[i].pr_sindex = N_IPCOMPSTAT; |
---|
480 | protox[i].pr_wanted = 1; |
---|
481 | protox[i].pr_cblocks = NULL; |
---|
482 | protox[i].pr_stats = ipcomp_stats; |
---|
483 | protox[i].pr_istats = NULL; |
---|
484 | protox[i].pr_name = "ipcomp"; |
---|
485 | protox[i].pr_usesysctl = 0; |
---|
486 | protox[i].pr_protocol = 0; |
---|
487 | i++; |
---|
488 | #endif |
---|
489 | protox[i].pr_index = N_RIPCBINFO; |
---|
490 | protox[i].pr_sindex = N_PIMSTAT; |
---|
491 | protox[i].pr_wanted = 1; |
---|
492 | protox[i].pr_cblocks = protopr; |
---|
493 | protox[i].pr_stats = pim_stats; |
---|
494 | protox[i].pr_istats = NULL; |
---|
495 | protox[i].pr_name = "pim"; |
---|
496 | protox[i].pr_usesysctl = 1; |
---|
497 | protox[i].pr_protocol = IPPROTO_PIM; |
---|
498 | i++; |
---|
499 | protox[i].pr_index = -1; |
---|
500 | protox[i].pr_sindex = N_CARPSTAT; |
---|
501 | protox[i].pr_wanted = 1; |
---|
502 | protox[i].pr_cblocks = NULL; |
---|
503 | protox[i].pr_stats = carp_stats; |
---|
504 | protox[i].pr_istats = NULL; |
---|
505 | protox[i].pr_name = "carp"; |
---|
506 | protox[i].pr_usesysctl = 1; |
---|
507 | protox[i].pr_protocol = 0; |
---|
508 | i++; |
---|
509 | protox[i].pr_index = -1; |
---|
510 | protox[i].pr_sindex = N_PFSYNCSTAT; |
---|
511 | protox[i].pr_wanted = 1; |
---|
512 | protox[i].pr_cblocks = NULL; |
---|
513 | protox[i].pr_stats = pfsync_stats; |
---|
514 | protox[i].pr_istats = NULL; |
---|
515 | protox[i].pr_name = "pfsync"; |
---|
516 | protox[i].pr_usesysctl = 1; |
---|
517 | protox[i].pr_protocol = 0; |
---|
518 | i++; |
---|
519 | protox[i].pr_index = -1; |
---|
520 | protox[i].pr_sindex = N_ARPSTAT; |
---|
521 | protox[i].pr_wanted = 1; |
---|
522 | protox[i].pr_cblocks = NULL; |
---|
523 | protox[i].pr_stats = arp_stats; |
---|
524 | protox[i].pr_istats = NULL; |
---|
525 | protox[i].pr_name = "arp"; |
---|
526 | protox[i].pr_usesysctl = 1; |
---|
527 | protox[i].pr_protocol = 0; |
---|
528 | i++; |
---|
529 | protox[i].pr_index = -1; |
---|
530 | protox[i].pr_sindex = -1; |
---|
531 | protox[i].pr_wanted = 0; |
---|
532 | protox[i].pr_cblocks = NULL; |
---|
533 | protox[i].pr_stats = NULL; |
---|
534 | protox[i].pr_istats = NULL; |
---|
535 | protox[i].pr_name = NULL; |
---|
536 | protox[i].pr_usesysctl = 0; |
---|
537 | protox[i].pr_protocol = 0; |
---|
538 | |
---|
539 | #ifdef INET6 |
---|
540 | i=0; |
---|
541 | ip6protox[i].pr_index = N_TCBINFO; |
---|
542 | ip6protox[i].pr_sindex = N_TCPSTAT; |
---|
543 | ip6protox[i].pr_wanted = 1; |
---|
544 | ip6protox[i].pr_cblocks = protopr; |
---|
545 | ip6protox[i].pr_stats = tcp_stats; |
---|
546 | ip6protox[i].pr_istats = NULL; |
---|
547 | ip6protox[i].pr_name = "tcp"; |
---|
548 | ip6protox[i].pr_usesysctl = 1; |
---|
549 | ip6protox[i].pr_protocol = IPPROTO_TCP; |
---|
550 | i++; |
---|
551 | ip6protox[i].pr_index = N_UDBINFO; |
---|
552 | ip6protox[i].pr_sindex = N_UDPSTAT; |
---|
553 | ip6protox[i].pr_wanted = 1; |
---|
554 | ip6protox[i].pr_cblocks = protopr; |
---|
555 | ip6protox[i].pr_stats = udp_stats; |
---|
556 | ip6protox[i].pr_istats = NULL; |
---|
557 | ip6protox[i].pr_name = "udp"; |
---|
558 | ip6protox[i].pr_usesysctl = 1; |
---|
559 | ip6protox[i].pr_protocol = IPPROTO_UDP; |
---|
560 | i++; |
---|
561 | ip6protox[i].pr_index = N_RIPCBINFO; |
---|
562 | ip6protox[i].pr_sindex = N_IP6STAT; |
---|
563 | ip6protox[i].pr_wanted = 1; |
---|
564 | ip6protox[i].pr_cblocks = protopr; |
---|
565 | ip6protox[i].pr_stats = ip6_stats; |
---|
566 | ip6protox[i].pr_istats = ip6_ifstats; |
---|
567 | ip6protox[i].pr_name = "ip6"; |
---|
568 | ip6protox[i].pr_usesysctl = 1; |
---|
569 | ip6protox[i].pr_protocol = IPPROTO_RAW; |
---|
570 | i++; |
---|
571 | ip6protox[i].pr_index = N_RIPCBINFO; |
---|
572 | ip6protox[i].pr_sindex = N_ICMP6STAT; |
---|
573 | ip6protox[i].pr_wanted = 1; |
---|
574 | ip6protox[i].pr_cblocks = protopr; |
---|
575 | ip6protox[i].pr_stats = icmp6_stats; |
---|
576 | ip6protox[i].pr_istats = icmp6_ifstats; |
---|
577 | ip6protox[i].pr_name = "icmp6"; |
---|
578 | ip6protox[i].pr_usesysctl = 1; |
---|
579 | ip6protox[i].pr_protocol = IPPROTO_ICMPV6; |
---|
580 | i++; |
---|
581 | #ifdef IPSEC |
---|
582 | ip6protox[i].pr_index = -1; |
---|
583 | ip6protox[i].pr_sindex = N_IPSEC6STAT; |
---|
584 | ip6protox[i].pr_wanted = 1; |
---|
585 | ip6protox[i].pr_cblocks = NULL; |
---|
586 | ip6protox[i].pr_stats = ipsec_stats; |
---|
587 | ip6protox[i].pr_istats = NULL; |
---|
588 | ip6protox[i].pr_name = "ipsec6"; |
---|
589 | ip6protox[i].pr_usesysctl = 0; |
---|
590 | ip6protox[i].pr_protocol = 0; |
---|
591 | i++; |
---|
592 | #endif |
---|
593 | #ifdef notyet |
---|
594 | ip6protox[i].pr_index = -1; |
---|
595 | ip6protox[i].pr_sindex = N_PIM6STAT; |
---|
596 | ip6protox[i].pr_wanted = 1; |
---|
597 | ip6protox[i].pr_cblocks = NULL; |
---|
598 | ip6protox[i].pr_stats = pim6_stats; |
---|
599 | ip6protox[i].pr_istats = NULL; |
---|
600 | ip6protox[i].pr_name = "pim6"; |
---|
601 | ip6protox[i].pr_usesysctl = 1; |
---|
602 | ip6protox[i].pr_protocol = 0; |
---|
603 | i++; |
---|
604 | #endif |
---|
605 | ip6protox[i].pr_index = -1; |
---|
606 | ip6protox[i].pr_sindex = N_RIP6STAT; |
---|
607 | ip6protox[i].pr_wanted = 1; |
---|
608 | ip6protox[i].pr_cblocks = NULL; |
---|
609 | ip6protox[i].pr_stats = rip6_stats; |
---|
610 | ip6protox[i].pr_istats = NULL; |
---|
611 | ip6protox[i].pr_name = "rip6"; |
---|
612 | ip6protox[i].pr_usesysctl = 1; |
---|
613 | ip6protox[i].pr_protocol = 0; |
---|
614 | i++; |
---|
615 | ip6protox[i].pr_index = -1; |
---|
616 | ip6protox[i].pr_sindex = -1; |
---|
617 | ip6protox[i].pr_wanted = 0; |
---|
618 | ip6protox[i].pr_cblocks = NULL; |
---|
619 | ip6protox[i].pr_stats = NULL; |
---|
620 | ip6protox[i].pr_istats = NULL; |
---|
621 | ip6protox[i].pr_name = NULL; |
---|
622 | ip6protox[i].pr_usesysctl = 0; |
---|
623 | ip6protox[i].pr_protocol = 0; |
---|
624 | i++; |
---|
625 | #endif /*INET6*/ |
---|
626 | |
---|
627 | #ifdef IPSEC |
---|
628 | i=0; |
---|
629 | pfkeyprotox[i].pr_index = -1; |
---|
630 | pfkeyprotox[i].pr_sindex = N_PFKEYSTAT; |
---|
631 | pfkeyprotox[i].pr_wanted = 1; |
---|
632 | pfkeyprotox[i].pr_cblocks = NULL; |
---|
633 | pfkeyprotox[i].pr_stats = pfkey_stats; |
---|
634 | pfkeyprotox[i].pr_istats = NULL; |
---|
635 | pfkeyprotox[i].pr_name = "pfkey"; |
---|
636 | pfkeyprotox[i].pr_usesysctl = 0; |
---|
637 | pfkeyprotox[i].pr_protocol = 0; |
---|
638 | i++; |
---|
639 | pfkeyprotox[i].pr_index = -1; |
---|
640 | pfkeyprotox[i].pr_sindex = -1; |
---|
641 | pfkeyprotox[i].pr_wanted = 0; |
---|
642 | pfkeyprotox[i].pr_cblocks = NULL; |
---|
643 | pfkeyprotox[i].pr_stats = NULL; |
---|
644 | pfkeyprotox[i].pr_istats = NULL; |
---|
645 | pfkeyprotox[i].pr_name = NULL; |
---|
646 | pfkeyprotox[i].pr_usesysctl = 0; |
---|
647 | pfkeyprotox[i].pr_protocol = 0; |
---|
648 | #endif |
---|
649 | |
---|
650 | #ifdef NETGRAPH |
---|
651 | netgraphprotox[i].pr_index = N_NGSOCKS; |
---|
652 | netgraphprotox[i].pr_sindex = -1; |
---|
653 | netgraphprotox[i].pr_wanted = 1; |
---|
654 | netgraphprotox[i].pr_cblocks = netgraphprotopr; |
---|
655 | netgraphprotox[i].pr_stats = NULL; |
---|
656 | netgraphprotox[i].pr_istats = NULL; |
---|
657 | netgraphprotox[i].pr_name = "ctrl"; |
---|
658 | netgraphprotox[i].pr_usesysctl = 0; |
---|
659 | netgraphprotox[i].pr_protocol = 0; |
---|
660 | i++; |
---|
661 | netgraphprotox[i].pr_index = N_NGSOCKS; |
---|
662 | netgraphprotox[i].pr_sindex = -1; |
---|
663 | netgraphprotox[i].pr_wanted = 1; |
---|
664 | netgraphprotox[i].pr_cblocks = netgraphprotopr; |
---|
665 | netgraphprotox[i].pr_stats = NULL; |
---|
666 | netgraphprotox[i].pr_istats = NULL; |
---|
667 | netgraphprotox[i].pr_name = "data"; |
---|
668 | netgraphprotox[i].pr_usesysctl = 0; |
---|
669 | netgraphprotox[i].pr_protocol = 0; |
---|
670 | i++; |
---|
671 | netgraphprotox[i].pr_index = -1; |
---|
672 | netgraphprotox[i].pr_sindex = -1; |
---|
673 | netgraphprotox[i].pr_wanted = 0; |
---|
674 | netgraphprotox[i].pr_cblocks = NULL; |
---|
675 | netgraphprotox[i].pr_stats = NULL; |
---|
676 | netgraphprotox[i].pr_istats = NULL; |
---|
677 | netgraphprotox[i].pr_name = NULL; |
---|
678 | netgraphprotox[i].pr_usesysctl = 0; |
---|
679 | netgraphprotox[i].pr_protocol = 0; |
---|
680 | #endif |
---|
681 | #ifdef IPX |
---|
682 | i=0; |
---|
683 | ipxprotox[i].pr_index = N_IPX; |
---|
684 | ipxprotox[i].pr_sindex = N_IPXSTAT; |
---|
685 | ipxprotox[i].pr_wanted = 1; |
---|
686 | ipxprotox[i].pr_cblocks = ipxprotopr; |
---|
687 | ipxprotox[i].pr_stats = ipx_stats; |
---|
688 | ipxprotox[i].pr_istats = NULL; |
---|
689 | ipxprotox[i].pr_name = "ipx"; |
---|
690 | ipxprotox[i].pr_usesysctl = 0; |
---|
691 | ipxprotox[i].pr_protocol = 0; |
---|
692 | i++; |
---|
693 | ipxprotox[i].pr_index = N_IPX; |
---|
694 | ipxprotox[i].pr_sindex = N_SPXSTAT; |
---|
695 | ipxprotox[i].pr_wanted = 1; |
---|
696 | ipxprotox[i].pr_cblocks = ipxprotopr; |
---|
697 | ipxprotox[i].pr_stats = spx_stats; |
---|
698 | ipxprotox[i].pr_istats = NULL; |
---|
699 | ipxprotox[i].pr_name = "spx"; |
---|
700 | ipxprotox[i].pr_usesysctl = 0; |
---|
701 | ipxprotox[i].pr_protocol = 0; |
---|
702 | i++; |
---|
703 | ipxprotox[i].pr_index = -1; |
---|
704 | ipxprotox[i].pr_sindex = -1; |
---|
705 | ipxprotox[i].pr_wanted = 0; |
---|
706 | ipxprotox[i].pr_cblocks = NULL; |
---|
707 | ipxprotox[i].pr_stats = NULL; |
---|
708 | ipxprotox[i].pr_istats = NULL; |
---|
709 | ipxprotox[i].pr_name = 0; |
---|
710 | ipxprotox[i].pr_usesysctl = 0; |
---|
711 | ipxprotox[i].pr_protocol = 0; |
---|
712 | i++; |
---|
713 | #endif |
---|
714 | |
---|
715 | i=0; |
---|
716 | protoprotox[i] = protox; |
---|
717 | i++; |
---|
718 | #ifdef INET6 |
---|
719 | protoprotox[i] = ip6protox, |
---|
720 | i++; |
---|
721 | #endif |
---|
722 | #ifdef IPSEC |
---|
723 | protoprotox[i] = pfkeyprotox, |
---|
724 | i++; |
---|
725 | #endif |
---|
726 | #ifdef IPX |
---|
727 | protoprotox[i] = ipxprotox, |
---|
728 | #endif |
---|
729 | noutputs = 0; |
---|
730 | |
---|
731 | netstat_globals.exit_code = 1; |
---|
732 | if (setjmp (netstat_globals.exit_jmp) == 0) |
---|
733 | return main_netstat (argc, argv); |
---|
734 | return netstat_globals.exit_code; |
---|
735 | } |
---|
736 | #endif |
---|
737 | |
---|
738 | int |
---|
739 | #ifdef __rtems__ |
---|
740 | main_netstat(int argc, char *argv[]) |
---|
741 | #else |
---|
742 | main(int argc, char *argv[]) |
---|
743 | #endif |
---|
744 | { |
---|
745 | struct protox *tp = NULL; /* for printing cblocks & stats */ |
---|
746 | int ch; |
---|
747 | #ifdef __rtems__ |
---|
748 | struct getopt_data getopt_data; |
---|
749 | memset(&getopt_data, 0, sizeof(getopt_data)); |
---|
750 | #define optind getopt_data.optind |
---|
751 | #define optarg getopt_data.optarg |
---|
752 | #define opterr getopt_data.opterr |
---|
753 | #define optopt getopt_data.optopt |
---|
754 | #define getopt(argc, argv, opt) getopt_r(argc, argv, opt, &getopt_data) |
---|
755 | #endif /* __rtems__ */ |
---|
756 | |
---|
757 | af = AF_UNSPEC; |
---|
758 | |
---|
759 | while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1) |
---|
760 | switch(ch) { |
---|
761 | case 'A': |
---|
762 | Aflag = 1; |
---|
763 | break; |
---|
764 | case 'a': |
---|
765 | aflag = 1; |
---|
766 | break; |
---|
767 | case 'B': |
---|
768 | Bflag = 1; |
---|
769 | break; |
---|
770 | case 'b': |
---|
771 | bflag = 1; |
---|
772 | break; |
---|
773 | case 'd': |
---|
774 | dflag = 1; |
---|
775 | break; |
---|
776 | case 'f': |
---|
777 | if (strcmp(optarg, "ipx") == 0) |
---|
778 | af = AF_IPX; |
---|
779 | else if (strcmp(optarg, "inet") == 0) |
---|
780 | af = AF_INET; |
---|
781 | #ifdef INET6 |
---|
782 | else if (strcmp(optarg, "inet6") == 0) |
---|
783 | af = AF_INET6; |
---|
784 | #endif |
---|
785 | #ifdef IPSEC |
---|
786 | else if (strcmp(optarg, "pfkey") == 0) |
---|
787 | af = PF_KEY; |
---|
788 | #endif |
---|
789 | else if (strcmp(optarg, "unix") == 0) |
---|
790 | af = AF_UNIX; |
---|
791 | else if (strcmp(optarg, "atalk") == 0) |
---|
792 | af = AF_APPLETALK; |
---|
793 | #ifdef NETGRAPH |
---|
794 | else if (strcmp(optarg, "ng") == 0 |
---|
795 | || strcmp(optarg, "netgraph") == 0) |
---|
796 | af = AF_NETGRAPH; |
---|
797 | #endif |
---|
798 | else if (strcmp(optarg, "link") == 0) |
---|
799 | af = AF_LINK; |
---|
800 | else { |
---|
801 | errx(1, "%s: unknown address family", optarg); |
---|
802 | } |
---|
803 | break; |
---|
804 | case 'g': |
---|
805 | gflag = 1; |
---|
806 | break; |
---|
807 | case 'h': |
---|
808 | hflag = 1; |
---|
809 | break; |
---|
810 | case 'I': { |
---|
811 | char *cp; |
---|
812 | |
---|
813 | iflag = 1; |
---|
814 | for (cp = interface = optarg; isalpha(*cp); cp++) |
---|
815 | continue; |
---|
816 | unit = atoi(cp); |
---|
817 | break; |
---|
818 | } |
---|
819 | case 'i': |
---|
820 | iflag = 1; |
---|
821 | break; |
---|
822 | case 'L': |
---|
823 | Lflag = 1; |
---|
824 | break; |
---|
825 | case 'M': |
---|
826 | memf = optarg; |
---|
827 | break; |
---|
828 | case 'm': |
---|
829 | mflag = 1; |
---|
830 | break; |
---|
831 | case 'N': |
---|
832 | nlistf = optarg; |
---|
833 | break; |
---|
834 | case 'n': |
---|
835 | numeric_addr = numeric_port = 1; |
---|
836 | break; |
---|
837 | case 'p': |
---|
838 | if ((tp = name2protox(optarg)) == NULL) { |
---|
839 | errx(1, |
---|
840 | "%s: unknown or uninstrumented protocol", |
---|
841 | optarg); |
---|
842 | } |
---|
843 | pflag = 1; |
---|
844 | break; |
---|
845 | case 'q': |
---|
846 | noutputs = atoi(optarg); |
---|
847 | if (noutputs != 0) |
---|
848 | noutputs++; |
---|
849 | break; |
---|
850 | case 'r': |
---|
851 | rflag = 1; |
---|
852 | break; |
---|
853 | case 's': |
---|
854 | ++sflag; |
---|
855 | break; |
---|
856 | case 'S': |
---|
857 | numeric_addr = 1; |
---|
858 | break; |
---|
859 | case 't': |
---|
860 | tflag = 1; |
---|
861 | break; |
---|
862 | case 'u': |
---|
863 | af = AF_UNIX; |
---|
864 | break; |
---|
865 | case 'W': |
---|
866 | case 'l': |
---|
867 | Wflag = 1; |
---|
868 | break; |
---|
869 | case 'w': |
---|
870 | interval = atoi(optarg); |
---|
871 | iflag = 1; |
---|
872 | break; |
---|
873 | case 'x': |
---|
874 | xflag = 1; |
---|
875 | break; |
---|
876 | case 'z': |
---|
877 | zflag = 1; |
---|
878 | break; |
---|
879 | case '?': |
---|
880 | default: |
---|
881 | usage(); |
---|
882 | } |
---|
883 | argv += optind; |
---|
884 | argc -= optind; |
---|
885 | |
---|
886 | #define BACKWARD_COMPATIBILITY |
---|
887 | #ifdef BACKWARD_COMPATIBILITY |
---|
888 | if (*argv) { |
---|
889 | if (isdigit(**argv)) { |
---|
890 | interval = atoi(*argv); |
---|
891 | if (interval <= 0) |
---|
892 | usage(); |
---|
893 | ++argv; |
---|
894 | iflag = 1; |
---|
895 | } |
---|
896 | if (*argv) { |
---|
897 | nlistf = *argv; |
---|
898 | if (*++argv) |
---|
899 | memf = *argv; |
---|
900 | } |
---|
901 | } |
---|
902 | #endif |
---|
903 | |
---|
904 | /* |
---|
905 | * Discard setgid privileges if not the running kernel so that bad |
---|
906 | * guys can't print interesting stuff from kernel memory. |
---|
907 | */ |
---|
908 | live = (nlistf == NULL && memf == NULL); |
---|
909 | if (!live) |
---|
910 | setgid(getgid()); |
---|
911 | |
---|
912 | if (Bflag) { |
---|
913 | if (!live) |
---|
914 | usage(); |
---|
915 | bpf_stats(interface); |
---|
916 | exit(0); |
---|
917 | } |
---|
918 | if (mflag) { |
---|
919 | if (!live) { |
---|
920 | if (kread(0, NULL, 0) == 0) |
---|
921 | mbpr(kvmd, nl[N_MBSTAT].n_value); |
---|
922 | } else |
---|
923 | mbpr(NULL, 0); |
---|
924 | exit(0); |
---|
925 | } |
---|
926 | #if 0 |
---|
927 | /* |
---|
928 | * Keep file descriptors open to avoid overhead |
---|
929 | * of open/close on each call to get* routines. |
---|
930 | */ |
---|
931 | sethostent(1); |
---|
932 | setnetent(1); |
---|
933 | #else |
---|
934 | /* |
---|
935 | * This does not make sense any more with DNS being default over |
---|
936 | * the files. Doing a setXXXXent(1) causes a tcp connection to be |
---|
937 | * used for the queries, which is slower. |
---|
938 | */ |
---|
939 | #endif |
---|
940 | kread(0, NULL, 0); |
---|
941 | if (iflag && !sflag) { |
---|
942 | intpr(interval, nl[N_IFNET].n_value, NULL); |
---|
943 | exit(0); |
---|
944 | } |
---|
945 | if (rflag) { |
---|
946 | if (sflag) |
---|
947 | rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value); |
---|
948 | else |
---|
949 | routepr(nl[N_RTREE].n_value); |
---|
950 | exit(0); |
---|
951 | } |
---|
952 | if (gflag) { |
---|
953 | if (sflag) { |
---|
954 | if (af == AF_INET || af == AF_UNSPEC) |
---|
955 | mrt_stats(nl[N_MRTSTAT].n_value); |
---|
956 | #ifdef INET6 |
---|
957 | if (af == AF_INET6 || af == AF_UNSPEC) |
---|
958 | mrt6_stats(nl[N_MRT6STAT].n_value); |
---|
959 | #endif |
---|
960 | } else { |
---|
961 | if (af == AF_INET || af == AF_UNSPEC) |
---|
962 | mroutepr(nl[N_MFCHASHTBL].n_value, |
---|
963 | nl[N_MFCTABLESIZE].n_value, |
---|
964 | nl[N_VIFTABLE].n_value); |
---|
965 | #ifdef INET6 |
---|
966 | if (af == AF_INET6 || af == AF_UNSPEC) |
---|
967 | mroute6pr(nl[N_MF6CTABLE].n_value, |
---|
968 | nl[N_MIF6TABLE].n_value); |
---|
969 | #endif |
---|
970 | } |
---|
971 | exit(0); |
---|
972 | } |
---|
973 | |
---|
974 | if (tp) { |
---|
975 | printproto(tp, tp->pr_name); |
---|
976 | exit(0); |
---|
977 | } |
---|
978 | if (af == AF_INET || af == AF_UNSPEC) |
---|
979 | for (tp = protox; tp->pr_name; tp++) |
---|
980 | printproto(tp, tp->pr_name); |
---|
981 | #ifdef INET6 |
---|
982 | if (af == AF_INET6 || af == AF_UNSPEC) |
---|
983 | for (tp = ip6protox; tp->pr_name; tp++) |
---|
984 | printproto(tp, tp->pr_name); |
---|
985 | #endif /*INET6*/ |
---|
986 | #ifdef IPSEC |
---|
987 | if (af == PF_KEY || af == AF_UNSPEC) |
---|
988 | for (tp = pfkeyprotox; tp->pr_name; tp++) |
---|
989 | printproto(tp, tp->pr_name); |
---|
990 | #endif /*IPSEC*/ |
---|
991 | #ifdef IPX |
---|
992 | if (af == AF_IPX || af == AF_UNSPEC) { |
---|
993 | for (tp = ipxprotox; tp->pr_name; tp++) |
---|
994 | printproto(tp, tp->pr_name); |
---|
995 | } |
---|
996 | #endif /* IPX */ |
---|
997 | #ifndef __rtems__ |
---|
998 | if (af == AF_APPLETALK || af == AF_UNSPEC) |
---|
999 | for (tp = atalkprotox; tp->pr_name; tp++) |
---|
1000 | printproto(tp, tp->pr_name); |
---|
1001 | #endif |
---|
1002 | #ifdef NETGRAPH |
---|
1003 | if (af == AF_NETGRAPH || af == AF_UNSPEC) |
---|
1004 | for (tp = netgraphprotox; tp->pr_name; tp++) |
---|
1005 | printproto(tp, tp->pr_name); |
---|
1006 | #endif /* NETGRAPH */ |
---|
1007 | #ifndef __rtems__ |
---|
1008 | if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) |
---|
1009 | unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value, |
---|
1010 | nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value); |
---|
1011 | #endif |
---|
1012 | exit(0); |
---|
1013 | } |
---|
1014 | |
---|
1015 | /* |
---|
1016 | * Print out protocol statistics or control blocks (per sflag). |
---|
1017 | * If the interface was not specifically requested, and the symbol |
---|
1018 | * is not in the namelist, ignore this one. |
---|
1019 | */ |
---|
1020 | static void |
---|
1021 | printproto(tp, name) |
---|
1022 | struct protox *tp; |
---|
1023 | const char *name; |
---|
1024 | { |
---|
1025 | void (*pr)(u_long, const char *, int, int); |
---|
1026 | u_long off; |
---|
1027 | |
---|
1028 | if (sflag) { |
---|
1029 | if (iflag) { |
---|
1030 | if (tp->pr_istats) |
---|
1031 | intpr(interval, nl[N_IFNET].n_value, |
---|
1032 | tp->pr_istats); |
---|
1033 | else if (pflag) |
---|
1034 | printf("%s: no per-interface stats routine\n", |
---|
1035 | tp->pr_name); |
---|
1036 | return; |
---|
1037 | } else { |
---|
1038 | pr = tp->pr_stats; |
---|
1039 | if (!pr) { |
---|
1040 | if (pflag) |
---|
1041 | printf("%s: no stats routine\n", |
---|
1042 | tp->pr_name); |
---|
1043 | return; |
---|
1044 | } |
---|
1045 | if (tp->pr_usesysctl && live) |
---|
1046 | off = 0; |
---|
1047 | else if (tp->pr_sindex < 0) { |
---|
1048 | if (pflag) |
---|
1049 | printf( |
---|
1050 | "%s: stats routine doesn't work on cores\n", |
---|
1051 | tp->pr_name); |
---|
1052 | return; |
---|
1053 | } else |
---|
1054 | off = nl[tp->pr_sindex].n_value; |
---|
1055 | } |
---|
1056 | } else { |
---|
1057 | pr = tp->pr_cblocks; |
---|
1058 | if (!pr) { |
---|
1059 | if (pflag) |
---|
1060 | printf("%s: no PCB routine\n", tp->pr_name); |
---|
1061 | return; |
---|
1062 | } |
---|
1063 | if (tp->pr_usesysctl && live) |
---|
1064 | off = 0; |
---|
1065 | else if (tp->pr_index < 0) { |
---|
1066 | if (pflag) |
---|
1067 | printf( |
---|
1068 | "%s: PCB routine doesn't work on cores\n", |
---|
1069 | tp->pr_name); |
---|
1070 | return; |
---|
1071 | } else |
---|
1072 | off = nl[tp->pr_index].n_value; |
---|
1073 | } |
---|
1074 | if (pr != NULL && (off || (live && tp->pr_usesysctl) || |
---|
1075 | af != AF_UNSPEC)) |
---|
1076 | (*pr)(off, name, af, tp->pr_protocol); |
---|
1077 | } |
---|
1078 | |
---|
1079 | #ifdef __rtems__ |
---|
1080 | #define _POSIX2_LINE_MAX 128 |
---|
1081 | #endif |
---|
1082 | |
---|
1083 | /* |
---|
1084 | * Read kernel memory, return 0 on success. |
---|
1085 | */ |
---|
1086 | int |
---|
1087 | kread(u_long addr, void *buf, size_t size) |
---|
1088 | { |
---|
1089 | char errbuf[_POSIX2_LINE_MAX]; |
---|
1090 | #ifdef __rtems__ |
---|
1091 | /* printf( "kread( %p to %p for %d)\n", (void *)addr, buf, size ); */ |
---|
1092 | #endif |
---|
1093 | |
---|
1094 | if (kvmd == NULL) { |
---|
1095 | kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
---|
1096 | setgid(getgid()); |
---|
1097 | if (kvmd != NULL) { |
---|
1098 | if (kvm_nlist(kvmd, nl) < 0) { |
---|
1099 | if (nlistf) |
---|
1100 | errx(1, "%s: kvm_nlist: %s", nlistf, |
---|
1101 | kvm_geterr(kvmd)); |
---|
1102 | else |
---|
1103 | errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); |
---|
1104 | } |
---|
1105 | |
---|
1106 | if (nl[0].n_type == 0) { |
---|
1107 | if (nlistf) |
---|
1108 | errx(1, "%s: no namelist", nlistf); |
---|
1109 | else |
---|
1110 | errx(1, "no namelist"); |
---|
1111 | } |
---|
1112 | } else { |
---|
1113 | warnx("kvm not available: %s", errbuf); |
---|
1114 | return(-1); |
---|
1115 | } |
---|
1116 | } |
---|
1117 | if (!buf) |
---|
1118 | return (0); |
---|
1119 | if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) { |
---|
1120 | warnx("%s", kvm_geterr(kvmd)); |
---|
1121 | return (-1); |
---|
1122 | } |
---|
1123 | return (0); |
---|
1124 | } |
---|
1125 | |
---|
1126 | const char * |
---|
1127 | plural(uintmax_t n) |
---|
1128 | { |
---|
1129 | return (n != 1 ? "s" : ""); |
---|
1130 | } |
---|
1131 | |
---|
1132 | const char * |
---|
1133 | plurales(uintmax_t n) |
---|
1134 | { |
---|
1135 | return (n != 1 ? "es" : ""); |
---|
1136 | } |
---|
1137 | |
---|
1138 | const char * |
---|
1139 | pluralies(uintmax_t n) |
---|
1140 | { |
---|
1141 | return (n != 1 ? "ies" : "y"); |
---|
1142 | } |
---|
1143 | |
---|
1144 | /* |
---|
1145 | * Find the protox for the given "well-known" name. |
---|
1146 | */ |
---|
1147 | static struct protox * |
---|
1148 | knownname(const char *name) |
---|
1149 | { |
---|
1150 | struct protox **tpp, *tp; |
---|
1151 | |
---|
1152 | for (tpp = protoprotox; *tpp; tpp++) |
---|
1153 | for (tp = *tpp; tp->pr_name; tp++) |
---|
1154 | if (strcmp(tp->pr_name, name) == 0) |
---|
1155 | return (tp); |
---|
1156 | return (NULL); |
---|
1157 | } |
---|
1158 | |
---|
1159 | /* |
---|
1160 | * Find the protox corresponding to name. |
---|
1161 | */ |
---|
1162 | static struct protox * |
---|
1163 | name2protox(const char *name) |
---|
1164 | { |
---|
1165 | struct protox *tp; |
---|
1166 | char **alias; /* alias from p->aliases */ |
---|
1167 | struct protoent *p; |
---|
1168 | |
---|
1169 | /* |
---|
1170 | * Try to find the name in the list of "well-known" names. If that |
---|
1171 | * fails, check if name is an alias for an Internet protocol. |
---|
1172 | */ |
---|
1173 | if ((tp = knownname(name)) != NULL) |
---|
1174 | return (tp); |
---|
1175 | |
---|
1176 | setprotoent(1); /* make protocol lookup cheaper */ |
---|
1177 | while ((p = getprotoent()) != NULL) { |
---|
1178 | /* assert: name not same as p->name */ |
---|
1179 | for (alias = p->p_aliases; *alias; alias++) |
---|
1180 | if (strcmp(name, *alias) == 0) { |
---|
1181 | endprotoent(); |
---|
1182 | return (knownname(p->p_name)); |
---|
1183 | } |
---|
1184 | } |
---|
1185 | endprotoent(); |
---|
1186 | return (NULL); |
---|
1187 | } |
---|
1188 | |
---|
1189 | static void |
---|
1190 | usage(void) |
---|
1191 | { |
---|
1192 | (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", |
---|
1193 | "usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n" |
---|
1194 | " [-M core] [-N system]", |
---|
1195 | " netstat -i | -I interface [-abdhntW] [-f address_family]\n" |
---|
1196 | " [-M core] [-N system]", |
---|
1197 | " netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]", |
---|
1198 | " netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n" |
---|
1199 | " [-M core] [-N system]", |
---|
1200 | " netstat -i | -I interface -s [-f protocol_family | -p protocol]\n" |
---|
1201 | " [-M core] [-N system]", |
---|
1202 | " netstat -m [-M core] [-N system]", |
---|
1203 | " netstat -B [-I interface]", |
---|
1204 | " netstat -r [-AanW] [-f address_family] [-M core] [-N system]", |
---|
1205 | " netstat -rs [-s] [-M core] [-N system]", |
---|
1206 | " netstat -g [-W] [-f address_family] [-M core] [-N system]", |
---|
1207 | " netstat -gs [-s] [-f address_family] [-M core] [-N system]"); |
---|
1208 | exit(1); |
---|
1209 | } |
---|
1210 | |
---|
1211 | #ifdef __rtems__ |
---|
1212 | #include <rtems/shell.h> |
---|
1213 | |
---|
1214 | rtems_shell_cmd_t rtems_shell_NETSTAT_Command = { |
---|
1215 | "netstat", /* name */ |
---|
1216 | "netstat [args]", /* usage */ |
---|
1217 | "net", /* topic */ |
---|
1218 | rtems_shell_main_netstat, /* command */ |
---|
1219 | NULL, /* alias */ |
---|
1220 | NULL /* next */ |
---|
1221 | }; |
---|
1222 | #endif |
---|