main.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:12k
- /* $OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $ */
- /* $NetBSD: main.c,v 1.9 1996/05/07 02:55:02 thorpej Exp $ */
- /*
- * Copyright (c) 1983, 1988, 1993
- * Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #ifndef lint
- char copyright[] =
- "@(#) Copyright (c) 1983, 1988, 1993n
- Regents of the University of California. All rights reserved.n";
- #endif /* not lint */
- #ifdef INHERITED_CODE
- #ifndef lint
- #if 0
- static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";
- #else
- static char *rcsid = "$OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $";
- #endif
- #endif /* not lint */
- #endif
- #include <net-snmp/net-snmp-config.h>
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/utilities.h>
- #if HAVE_NETDB_H
- #include <netdb.h>
- #endif
- #include "main.h"
- #include "netstat.h"
- int Aflag; /* show addresses of protocol control block */
- int aflag; /* show all sockets (including servers) */
- int bflag; /* show bytes instead of packets */
- int dflag; /* show i/f dropped packets */
- int gflag; /* show group (multicast) routing or stats */
- int iflag; /* show interfaces */
- int lflag; /* show routing table with use and ref */
- int mflag; /* show memory stats */
- int nflag; /* show addresses numerically */
- int oflag; /* Open/Net-BSD style octet output */
- int pflag; /* show given protocol */
- int qflag; /* only display non-zero values for output */
- int rflag; /* show routing tables (or routing stats) */
- int Sflag; /* show source address in routing table */
- int sflag; /* show protocol statistics */
- int tflag; /* show i/f watchdog timers */
- int vflag; /* be verbose */
- int interval; /* repeat interval for i/f stats */
- char *intrface; /* desired i/f for stats, or NULL for all i/fs */
- int af; /* address family */
- char *progname = NULL;
- /*
- * struct nlist nl[] - Omitted
- */
- struct protox {
- /* pr_index/pr_sindex - Omitted */
- int pr_wanted; /* 1 if wanted, 0 otherwise */
- void (*pr_cblocks)(const char *); /* control blocks printing routine */
- void (*pr_stats)(const char *); /* statistics printing routine */
- const char *pr_name; /* well-known name */
- } protox[] = {
- { 1, tcpprotopr, tcp_stats, "tcp" },
- { 1, udpprotopr, udp_stats, "udp" },
- { 1, 0, ip_stats, "ip" }, /* protopr Omitted */
- { 1, 0, icmp_stats, "icmp" },
- /* igmp/ah/esp/ipencap/etherip/ipcomp/carp/pfsync/pim - Omitted */
- { 0, 0, 0, 0 }
- };
- struct protox ip6protox[] = {
- { 1, tcp6protopr, 0, "tcp6" },
- { 1, udp6protopr, 0, "udp6" },
- { 1, 0, ip6_stats, "ip6" }, /* ip6protopr Omitted */
- { 1, 0, icmp6_stats, "icmp6" },
- /* pim6/rip6 - Omitted */
- { 0, 0, 0, 0 }
- };
- /* {ipx,ns,atalk}protox Omitted */
- struct protox *protoprotox[] = {
- protox, ip6protox, NULL
- };
- static void printproto(struct protox *, const char *);
- static void usage(void);
- static struct protox *name2protox(const char *);
- static struct protox *knownname(const char *);
- netsnmp_session *ss;
- struct protox *tp = NULL; /* for printing cblocks & stats */
- static void
- optProc( int argc, char *const *argv, int opt )
- {
- switch (opt) {
- case 'C':
- while (*optarg) {
- switch (*optarg++) {
- /* case 'A': *BSD: display PCB addresses
- Linux: protocol family
- Aflag = 1;
- break;
- */
- case 'a':
- aflag = 1;
- break;
- case 'b':
- bflag = 1;
- break;
- case 'd':
- dflag = 1;
- break;
- case 'f':
- if (!*optarg)
- optarg = argv[optind++];
- if (strcmp(optarg, "inet") == 0)
- af = AF_INET;
- else if (strcmp(optarg, "inet6") == 0)
- af = AF_INET6;
- /*
- else if (strcmp(optarg, "local") == 0)
- af = AF_LOCAL;
- else if (strcmp(optarg, "unix") == 0)
- af = AF_UNIX;
- else if (strcmp(optarg, "ipx") == 0)
- af = AF_IPX;
- else if (strcmp(optarg, "ns") == 0)
- af = AF_NS;
- else if (strcmp(optarg, "encap") == 0)
- af = PF_KEY;
- else if (strcmp(optarg, "atalk") == 0)
- af = AF_APPLETALK;
- */
- else {
- (void)fprintf(stderr,
- "%s: %s: unknown address familyn",
- progname, optarg);
- exit(1);
- }
- return;
- case 'g':
- gflag = 1;
- break;
- case 'I':
- iflag = 1;
- if (!*optarg)
- optarg = argv[optind++];
- intrface = optarg;
- return;
- case 'i':
- iflag = 1;
- break;
- /* case 'L': FreeBSD: Display listen queue lengths
- NetBSD: Suppress link-level routes */
- /* case 'l': OpenBSD: Wider IPv6 display
- Linux: Listening sockets only
- lflag = 1;
- break;
- case 'M': *BSD: Memory image
- Linux: Masqueraded connections
- memf = optarg;
- break;
- */
- case 'm':
- mflag = 1;
- break;
- /* case 'N': *BSD: Kernel image
- nlistf = optarg;
- break;
- */
- case 'n':
- nflag = 1;
- break;
- case 'o':
- oflag = 1;
- break;
- /* case 'P': NetBSD:
- OpenBSD: dump PCB block */
- case 'p':
- if (!*optarg)
- optarg = argv[optind++];
- if ((tp = name2protox(optarg)) == NULL) {
- (void)fprintf(stderr,
- "%s: %s: unknown protocoln",
- progname, optarg);
- exit(1);
- }
- pflag = 1;
- return;
- /* case 'q': NetBSD: IRQ information
- OpenBSD: Suppress inactive I/Fs
- qflag = 1;
- break;
- */
- case 'r':
- rflag = 1;
- break;
- case 'S': /* FreeBSD:
- NetBSD: Semi-numeric display
- OpenBSD: Show route source selector */
- Sflag = 1;
- break;
- case 's':
- ++sflag;
- break;
- /* case 't': FreeBSD:
- OpenBSD: Display watchdog timers
- tflag = 1;
- break;
- case 'u': OpenBSD: unix sockets only
- af = AF_UNIX;
- break;
- */
- case 'v':
- vflag = 1;
- break;
- case 'w':
- if (!*optarg)
- optarg = argv[optind++];
- interval = atoi(optarg);
- iflag = 1;
- return;
- case '?':
- default:
- usage();
- }
- }
- break; /* End of '-Cx' switch */
- /*
- * Backward compatability for the main display modes
- * (where this doesn't clash with standard SNMP flags)
- */
- case 'i':
- iflag = 1;
- break;
- case 'R':
- rflag = 1; /* -r sets the retry count */
- break;
- case 's':
- ++sflag;
- break;
- }
- }
- int
- main(int argc, char *argv[])
- {
- netsnmp_session session;
- struct protoent *p;
- char *cp;
- af = AF_UNSPEC;
- cp = strrchr( argv[0], '/' );
- if (cp)
- progname = cp+1;
- else
- progname = argv[0];
- switch (snmp_parse_args( argc, argv, &session, "C:iRs", optProc)) {
- case -2:
- exit(0);
- case -1:
- usage();
- exit(0);
- default:
- break;
- }
- /*
- * Check argc vs optind ??
- */
- argv += optind;
- argc -= optind;
- /*
- * Open an SNMP session.
- */
- SOCK_STARTUP;
- ss = snmp_open(&session);
- if (ss == NULL) {
- /*
- * diagnose snmp_open errors with the input netsnmp_session pointer
- */
- snmp_sess_perror("snmpnetstat", &session);
- SOCK_CLEANUP;
- exit(1);
- }
- /*
- * Omitted:
- * Privilege handling
- * "Backward Compatibility"
- * Kernel namelis handling
- */
- if (mflag) {
- /*
- mbpr(nl[N_MBSTAT].n_value, nl[N_MBPOOL].n_value,
- nl[N_MCLPOOL].n_value);
- */
- exit(0);
- }
- if (pflag) {
- printproto(tp, tp->pr_name);
- exit(0);
- }
- /*
- * Keep file descriptors open to avoid overhead
- * of open/close on each call to get* routines.
- */
- sethostent(1);
- setnetent(1);
- if (iflag) {
- intpr(interval);
- exit(0);
- }
- if (rflag) {
- /*
- if (sflag)
- rt_stats();
- else
- */
- routepr();
- exit(0);
- }
- /*
- if (gflag) {
- if (sflag) {
- if (af == AF_INET || af == AF_UNSPEC)
- mrt_stats(nl[N_MRTPROTO].n_value,
- nl[N_MRTSTAT].n_value);
- #ifdef INET6
- if (af == AF_INET6 || af == AF_UNSPEC)
- mrt6_stats(nl[N_MRT6PROTO].n_value,
- nl[N_MRT6STAT].n_value);
- #endif
- }
- else {
- if (af == AF_INET || af == AF_UNSPEC)
- mroutepr(nl[N_MRTPROTO].n_value,
- nl[N_MFCHASHTBL].n_value,
- nl[N_MFCHASH].n_value,
- nl[N_VIFTABLE].n_value);
- #ifdef INET6
- if (af == AF_INET6 || af == AF_UNSPEC)
- mroute6pr(nl[N_MRT6PROTO].n_value,
- nl[N_MF6CTABLE].n_value,
- nl[N_MIF6TABLE].n_value);
- #endif
- }
- exit(0);
- }
- */
- if (af == AF_INET || af == AF_UNSPEC) {
- setprotoent(1);
- setservent(1);
- /* ugh, this is O(MN) ... why do we do this? */
- while ((p = getprotoent())) {
- for (tp = protox; tp->pr_name; tp++)
- if (strcmp(tp->pr_name, p->p_name) == 0)
- break;
- if (tp->pr_name == 0 || tp->pr_wanted == 0)
- continue;
- printproto(tp, p->p_name);
- }
- endprotoent();
- }
- if (af == AF_INET6 || af == AF_UNSPEC)
- for (tp = ip6protox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
- /*
- if (af == AF_IPX || af == AF_UNSPEC)
- for (tp = ipxprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
- if (af == AF_NS || af == AF_UNSPEC)
- for (tp = nsprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
- if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
- unixpr(nl[N_UNIXSW].n_value);
- if (af == AF_APPLETALK || af == AF_UNSPEC)
- for (tp = atalkprotox; tp->pr_name; tp++)
- printproto(tp, tp->pr_name);
- */
- exit(0);
- }
- /*
- * Print out protocol statistics or control blocks (per sflag).
- * Namelist checks - Omitted
- */
- static void
- printproto(struct protox *tp, const char *name)
- {
- void (*pr)(const char *);
- if (sflag) {
- pr = tp->pr_stats;
- } else {
- pr = tp->pr_cblocks;
- }
- if (pr != NULL)
- (*pr)(name);
- }
- /*
- * Read kernel memory - Omitted
- */
- const char *
- plural(int n)
- {
- return (n != 1 ? "s" : "");
- }
- const char *
- plurales(int n)
- {
- return (n != 1 ? "es" : "");
- }
- /*
- * Find the protox for the given "well-known" name.
- */
- static struct protox *
- knownname(const char *name)
- {
- struct protox **tpp, *tp;
- for (tpp = protoprotox; *tpp; tpp++)
- for (tp = *tpp; tp->pr_name; tp++)
- if (strcmp(tp->pr_name, name) == 0)
- return (tp);
- return (NULL);
- }
- /*
- * Find the protox corresponding to name.
- */
- static struct protox *
- name2protox(const char *name)
- {
- struct protox *tp;
- char **alias; /* alias from p->aliases */
- struct protoent *p;
- /*
- * Try to find the name in the list of "well-known" names. If that
- * fails, check if name is an alias for an Internet protocol.
- */
- if ((tp = knownname(name)))
- return (tp);
- setprotoent(1); /* make protocol lookup cheaper */
- while ((p = getprotoent())) {
- /* assert: name not same as p->name */
- for (alias = p->p_aliases; *alias; alias++)
- if (strcmp(name, *alias) == 0) {
- endprotoent();
- return (knownname(p->p_name));
- }
- }
- endprotoent();
- return (NULL);
- }
- static void
- usage(void)
- {
- (void)fprintf(stderr,
- "usage: %s [snmp_opts] [-Can] [-Cf address_family]n", progname);
- (void)fprintf(stderr,
- " %s [snmp_opts] [-CbdgimnrSs] [-Cf address_family]n", progname);
- (void)fprintf(stderr,
- " %s [snmp_opts] [-Cbdn] [-CI interface] [-Cw wait]n", progname);
- (void)fprintf(stderr,
- " %s [snmp_opts] [-Cs] [-Cp protocol]n", progname);
- (void)fprintf(stderr,
- " %s [snmp_opts] [-Ca] [-Cf address_family] [-Ci | -CI interface]n", progname);
- exit(1);
- }