|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)main.c 5.19 (Berkeley) 6/18/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <sys/vmmac.h>
32: #include <sys/socket.h>
33: #include <sys/file.h>
34: #include <machine/pte.h>
35: #include <ctype.h>
36: #include <errno.h>
37: #include <netdb.h>
38: #include <nlist.h>
39: #include <stdio.h>
40: #include <paths.h>
41:
42: #define nl netstatnl
43: struct nlist nl[] = {
44: #define N_MBSTAT 0
45: { "_mbstat" },
46: #define N_IPSTAT 1
47: { "_ipstat" },
48: #define N_TCB 2
49: { "_tcb" },
50: #define N_TCPSTAT 3
51: { "_tcpstat" },
52: #define N_UDB 4
53: { "_udb" },
54: #define N_UDPSTAT 5
55: { "_udpstat" },
56: #define N_RAWCB 6
57: { "_rawcb" },
58: #define N_SYSMAP 7
59: { "_Sysmap" },
60: #define N_SYSSIZE 8
61: { "_Syssize" },
62: #define N_IFNET 9
63: { "_ifnet" },
64: #define N_IMP 10
65: { "_imp_softc" },
66: #define N_RTHOST 11
67: { "_rthost" },
68: #define N_RTNET 12
69: { "_rtnet" },
70: #define N_ICMPSTAT 13
71: { "_icmpstat" },
72: #define N_RTSTAT 14
73: { "_rtstat" },
74: #define N_NFILE 15
75: { "_nfile" },
76: #define N_FILE 16
77: { "_file" },
78: #define N_UNIXSW 17
79: { "_unixsw" },
80: #define N_RTHASHSIZE 18
81: { "_rthashsize" },
82: #define N_IDP 19
83: { "_nspcb"},
84: #define N_IDPSTAT 20
85: { "_idpstat"},
86: #define N_SPPSTAT 21
87: { "_spp_istat"},
88: #define N_NSERR 22
89: { "_ns_errstat"},
90: #define N_CLNPSTAT 23
91: { "_clnp_stat"},
92: #define IN_TP 24
93: { "_tp_inpcb" },
94: #define ISO_TP 25
95: { "_tp_isopcb" },
96: #define ISO_X25 26
97: { /*"_x25_isopcb"*/ "_file"}, /* fast gross hack to speed up */
98: #define N_TPSTAT 27
99: { "_tp_stat" },
100: #define N_X25STAT 28
101: { /*"_x25_stat"*/ "_file"},
102: #define N_ESISSTAT 29
103: { "_esis_stat"},
104: #define N_NIMP 30
105: { "_nimp"},
106: #define N_RTREE 31
107: { "_radix_node_head"},
108: #define N_CLTP 32
109: { "_cltb"},
110: #define N_CLTPSTAT 33
111: { "_cltpstat"},
112:
113: "",
114: };
115:
116: /* internet protocols */
117: extern int protopr();
118: extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
119: /* ns protocols */
120: extern int nsprotopr();
121: extern int spp_stats(), idp_stats(), nserr_stats();
122: /* iso protocols */
123: extern int iso_protopr();
124: extern int tp_stats(), esis_stats(), clnp_stats(), cltp_stats();
125:
126: #define NULLPROTOX ((struct protox *) 0)
127: struct protox {
128: u_char pr_index; /* index into nlist of cb head */
129: u_char pr_sindex; /* index into nlist of stat block */
130: u_char pr_wanted; /* 1 if wanted, 0 otherwise */
131: int (*pr_cblocks)(); /* control blocks printing routine */
132: int (*pr_stats)(); /* statistics printing routine */
133: char *pr_name; /* well-known name */
134: } protox[] = {
135: { N_TCB, N_TCPSTAT, 1, protopr,
136: tcp_stats, "tcp" },
137: { N_UDB, N_UDPSTAT, 1, protopr,
138: udp_stats, "udp" },
139: { IN_TP, N_TPSTAT, 1, protopr,
140: tp_stats, "tpip" },
141: { -1, N_IPSTAT, 1, 0,
142: ip_stats, "ip" },
143: { -1, N_ICMPSTAT, 1, 0,
144: icmp_stats, "icmp" },
145: { -1, -1, 0, 0,
146: 0, 0 }
147: };
148:
149: struct protox nsprotox[] = {
150: { N_IDP, N_IDPSTAT, 1, nsprotopr,
151: idp_stats, "idp" },
152: { N_IDP, N_SPPSTAT, 1, nsprotopr,
153: spp_stats, "spp" },
154: { -1, N_NSERR, 1, 0,
155: nserr_stats, "ns_err" },
156: { -1, -1, 0, 0,
157: 0, 0 }
158: };
159:
160: struct protox isoprotox[] = {
161: { ISO_TP, N_TPSTAT, 1, iso_protopr,
162: tp_stats, "tp" },
163: { N_CLTP, N_CLTPSTAT, 1, iso_protopr,
164: cltp_stats, "cltp" },
165: #ifdef notdef
166: { ISO_X25, N_X25STAT, 1, x25_protopr,
167: x25_stats, "x25" },
168: #endif
169: { -1, N_CLNPSTAT, 1, 0,
170: clnp_stats, "clnp"},
171: { -1, N_ESISSTAT, 1, 0,
172: esis_stats, "esis"},
173: { -1, -1, 0, 0,
174: 0, 0 }
175: };
176:
177: struct protox *protoprotox[] = { protox, nsprotox, isoprotox, NULLPROTOX };
178:
179: struct pte *Sysmap;
180:
181: char *system = _PATH_UNIX;
182: char *kmemf;
183: int kmem;
184: int kflag;
185: int Aflag;
186: int aflag;
187: int hflag;
188: int iflag;
189: int mflag;
190: int nflag;
191: int pflag;
192: int rflag;
193: int sflag;
194: int tflag;
195: int dflag;
196: int interval;
197: char *interface;
198: int unit;
199:
200: int af = AF_UNSPEC;
201:
202: extern char *malloc();
203: extern off_t lseek();
204:
205: main(argc, argv)
206: int argc;
207: char *argv[];
208: {
209: extern char *optarg;
210: extern int optind;
211: register struct protoent *p;
212: register struct protox *tp; /* for printing cblocks & stats */
213: struct protox *name2protox(); /* for -p */
214: int ch;
215:
216: while ((ch = getopt(argc, argv, "AI:af:himnp:drstu")) != EOF)
217: switch((char)ch) {
218: case 'A':
219: Aflag++;
220: break;
221: case 'I': {
222: char *cp;
223:
224: iflag++;
225: for (cp = interface = optarg; isalpha(*cp); cp++);
226: unit = atoi(cp);
227: *cp = '\0';
228: break;
229: }
230: case 'a':
231: aflag++;
232: break;
233: case 'd':
234: dflag++;
235: break;
236: case 'f':
237: if (strcmp(optarg, "ns") == 0)
238: af = AF_NS;
239: else if (strcmp(optarg, "inet") == 0)
240: af = AF_INET;
241: else if (strcmp(optarg, "unix") == 0)
242: af = AF_UNIX;
243: else if (strcmp(optarg, "iso") == 0)
244: af = AF_ISO;
245: else {
246: fprintf(stderr, "%s: unknown address family\n", optarg);
247: exit(10);
248: }
249: break;
250: case 'h':
251: hflag++;
252: break;
253: case 'i':
254: iflag++;
255: break;
256: case 'm':
257: mflag++;
258: break;
259: case 'n':
260: nflag++;
261: break;
262: case 'p':
263: if ((tp = name2protox(optarg)) == NULLPROTOX) {
264: fprintf(stderr, "%s: unknown or uninstrumented protocol\n", optarg);
265: exit(10);
266: }
267: pflag++;
268: break;
269: case 'r':
270: rflag++;
271: break;
272: case 's':
273: sflag++;
274: break;
275: case 't':
276: tflag++;
277: break;
278: case 'u':
279: af = AF_UNIX;
280: break;
281: case '?':
282: default:
283: usage();
284: }
285: argv += optind;
286: argc -= optind;
287:
288: if (argc > 0) {
289: if (isdigit(argv[0][0])) {
290: interval = atoi(argv[0]);
291: if (interval <= 0)
292: usage();
293: argv++, argc--;
294: iflag++;
295: }
296: if (argc > 0) {
297: system = *argv;
298: argv++, argc--;
299: if (argc > 0) {
300: kmemf = *argv;
301: kflag++;
302: }
303: }
304: }
305: if (kvm_openfiles(system, kmemf, (char *)0) == -1) {
306: fprintf("netstat(kvm_openfiles): %s\n", kvm_geterr());
307: exit(1);
308: }
309: if (kvm_nlist(nl) < 0 || nl[0].n_type == 0) {
310: fprintf(stderr, "%s: no namelist\n", system);
311: exit(1);
312: }
313: if (mflag) {
314: mbpr((off_t)nl[N_MBSTAT].n_value);
315: exit(0);
316: }
317: if (pflag) {
318: if (tp->pr_stats)
319: (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
320: tp->pr_name);
321: else
322: printf("%s: no stats routine\n", tp->pr_name);
323: exit(0);
324: }
325: if (hflag) {
326: hostpr(nl[N_IMP].n_value, nl[N_NIMP].n_value);
327: exit(0);
328: }
329: /*
330: * Keep file descriptors open to avoid overhead
331: * of open/close on each call to get* routines.
332: */
333: sethostent(1);
334: setnetent(1);
335: if (iflag) {
336: intpr(interval, nl[N_IFNET].n_value);
337: exit(0);
338: }
339: if (rflag) {
340: if (sflag)
341: rt_stats((off_t)nl[N_RTSTAT].n_value);
342: else
343: routepr((off_t)nl[N_RTHOST].n_value,
344: (off_t)nl[N_RTNET].n_value,
345: (off_t)nl[N_RTHASHSIZE].n_value,
346: (off_t)nl[N_RTREE].n_value);
347: exit(0);
348: }
349: if (af == AF_INET || af == AF_UNSPEC) {
350: setprotoent(1);
351: setservent(1);
352: while (p = getprotoent()) {
353:
354: for (tp = protox; tp->pr_name; tp++)
355: if (strcmp(tp->pr_name, p->p_name) == 0)
356: break;
357: if (tp->pr_name == 0 || tp->pr_wanted == 0)
358: continue;
359: if (sflag) {
360: if (tp->pr_stats)
361: (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
362: p->p_name);
363: } else
364: if (tp->pr_cblocks)
365: (*tp->pr_cblocks)(nl[tp->pr_index].n_value,
366: p->p_name);
367: }
368: endprotoent();
369: }
370: if (af == AF_NS || af == AF_UNSPEC) {
371: for (tp = nsprotox; tp->pr_name; tp++) {
372: if (sflag) {
373: if (tp->pr_stats)
374: (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
375: tp->pr_name);
376: } else
377: if (tp->pr_cblocks)
378: (*tp->pr_cblocks)(nl[tp->pr_index].n_value,
379: tp->pr_name);
380: }
381: }
382: if (af == AF_ISO || af == AF_UNSPEC) {
383: for (tp = isoprotox; tp->pr_name; tp++) {
384: if (sflag) {
385: if (tp->pr_stats)
386: (*tp->pr_stats)(nl[tp->pr_sindex].n_value,
387: tp->pr_name);
388: } else
389: if (tp->pr_cblocks)
390: (*tp->pr_cblocks)(nl[tp->pr_index].n_value,
391: tp->pr_name);
392: }
393: }
394: if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
395: unixpr((off_t)nl[N_NFILE].n_value, (off_t)nl[N_FILE].n_value,
396: (struct protosw *)nl[N_UNIXSW].n_value);
397: if (af == AF_UNSPEC && sflag)
398: impstats(nl[N_IMP].n_value, nl[N_NIMP].n_value);
399: exit(0);
400: }
401:
402:
403: char *
404: plural(n)
405: int n;
406: {
407:
408: return (n != 1 ? "s" : "");
409: }
410:
411: /*
412: * Find the protox for the given "well-known" name.
413: */
414: struct protox *
415: knownname(name)
416: char *name;
417: {
418: struct protox **tpp, *tp;
419:
420: for (tpp = protoprotox; *tpp; tpp++)
421: for (tp = *tpp; tp->pr_name; tp++)
422: if (strcmp(tp->pr_name, name) == 0)
423: return(tp);
424: return(NULLPROTOX);
425: }
426:
427: /*
428: * Find the protox corresponding to name.
429: */
430: struct protox *
431: name2protox(name)
432: char *name;
433: {
434: struct protox *tp;
435: char **alias; /* alias from p->aliases */
436: struct protoent *p;
437:
438: /*
439: * Try to find the name in the list of "well-known" names. If that
440: * fails, check if name is an alias for an Internet protocol.
441: */
442: if (tp = knownname(name))
443: return(tp);
444:
445: setprotoent(1); /* make protocol lookup cheaper */
446: while (p = getprotoent()) {
447: /* assert: name not same as p->name */
448: for (alias = p->p_aliases; *alias; alias++)
449: if (strcmp(name, *alias) == 0) {
450: endprotoent();
451: return(knownname(p->p_name));
452: }
453: }
454: endprotoent();
455: return(NULLPROTOX);
456: }
457:
458: usage()
459: {
460: fputs("usage: netstat [-Aan] [-f address_family] [system] [core]\n [-himnrs] [-f address_family] [system] [core]\n [-n] [-I interface] interval [system] [core]\n", stderr);
461: exit(1);
462: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.