main.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:12k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /* $OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $ */
  2. /* $NetBSD: main.c,v 1.9 1996/05/07 02:55:02 thorpej Exp $ */
  3. /*
  4.  * Copyright (c) 1983, 1988, 1993
  5.  * Regents of the University of California.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. Neither the name of the University nor the names of its contributors
  16.  *    may be used to endorse or promote products derived from this software
  17.  *    without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29.  * SUCH DAMAGE.
  30.  */
  31. #ifndef lint
  32. char copyright[] =
  33. "@(#) Copyright (c) 1983, 1988, 1993n
  34. Regents of the University of California.  All rights reserved.n";
  35. #endif /* not lint */
  36. #ifdef  INHERITED_CODE
  37. #ifndef lint
  38. #if 0
  39. static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";
  40. #else
  41. static char *rcsid = "$OpenBSD: main.c,v 1.52 2005/02/10 14:25:08 itojun Exp $";
  42. #endif
  43. #endif /* not lint */
  44. #endif
  45. #include <net-snmp/net-snmp-config.h>
  46. #include <net-snmp/net-snmp-includes.h>
  47. #include <net-snmp/utilities.h>
  48. #if HAVE_NETDB_H
  49. #include <netdb.h>
  50. #endif
  51. #include "main.h"
  52. #include "netstat.h"
  53. int Aflag; /* show addresses of protocol control block */
  54. int aflag; /* show all sockets (including servers) */
  55. int bflag; /* show bytes instead of packets */
  56. int dflag; /* show i/f dropped packets */
  57. int gflag; /* show group (multicast) routing or stats */
  58. int iflag; /* show interfaces */
  59. int lflag; /* show routing table with use and ref */
  60. int mflag; /* show memory stats */
  61. int nflag; /* show addresses numerically */
  62. int oflag; /* Open/Net-BSD style octet output */
  63. int pflag; /* show given protocol */
  64. int qflag; /* only display non-zero values for output */
  65. int rflag; /* show routing tables (or routing stats) */
  66. int Sflag; /* show source address in routing table */
  67. int sflag; /* show protocol statistics */
  68. int tflag; /* show i/f watchdog timers */
  69. int vflag; /* be verbose */
  70. int interval; /* repeat interval for i/f stats */
  71. char *intrface; /* desired i/f for stats, or NULL for all i/fs */
  72. int af; /* address family */
  73. char    *progname = NULL;
  74.     /*
  75.      * struct nlist nl[] - Omitted
  76.      */
  77. struct protox {
  78.         /* pr_index/pr_sindex - Omitted */ 
  79. int pr_wanted; /* 1 if wanted, 0 otherwise */
  80. void (*pr_cblocks)(const char *); /* control blocks printing routine */
  81. void (*pr_stats)(const char *); /* statistics printing routine */
  82.   const char *pr_name; /* well-known name */
  83. } protox[] = {
  84. { 1, tcpprotopr, tcp_stats, "tcp" },
  85. { 1, udpprotopr, udp_stats, "udp" },
  86. { 1, 0, ip_stats, "ip" }, /* protopr Omitted */
  87. { 1, 0, icmp_stats, "icmp" },
  88. /* igmp/ah/esp/ipencap/etherip/ipcomp/carp/pfsync/pim - Omitted */
  89. { 0, 0, 0, 0 }
  90. };
  91. struct protox ip6protox[] = {
  92. { 1, tcp6protopr, 0, "tcp6" },
  93. { 1, udp6protopr, 0, "udp6" },
  94. { 1, 0, ip6_stats, "ip6" }, /* ip6protopr Omitted */
  95. { 1, 0, icmp6_stats, "icmp6" },
  96. /* pim6/rip6 - Omitted */
  97. { 0, 0, 0, 0 }
  98. };
  99. /* {ipx,ns,atalk}protox Omitted */
  100. struct protox *protoprotox[] = {
  101. protox, ip6protox, NULL
  102. };
  103. static void printproto(struct protox *, const char *);
  104. static void usage(void);
  105. static struct protox *name2protox(const char *);
  106. static struct protox *knownname(const char *);
  107. netsnmp_session *ss;
  108. struct protox *tp = NULL; /* for printing cblocks & stats */
  109. static void
  110. optProc( int argc, char *const *argv, int opt )
  111. {
  112.     switch (opt) {
  113.     case 'C':
  114.         while (*optarg) {
  115.             switch (*optarg++) {
  116.     /* case 'A': *BSD:  display PCB addresses
  117. Linux: protocol family
  118. Aflag = 1;
  119. break;
  120.      */
  121. case 'a':
  122. aflag = 1;
  123. break;
  124. case 'b':
  125. bflag = 1;
  126. break;
  127. case 'd':
  128. dflag = 1;
  129. break;
  130. case 'f':
  131.                         if (!*optarg)
  132.                             optarg = argv[optind++];
  133. if (strcmp(optarg, "inet") == 0)
  134. af = AF_INET;
  135. else if (strcmp(optarg, "inet6") == 0)
  136. af = AF_INET6;
  137. /*
  138. else if (strcmp(optarg, "local") == 0)
  139. af = AF_LOCAL;
  140. else if (strcmp(optarg, "unix") == 0)
  141. af = AF_UNIX;
  142. else if (strcmp(optarg, "ipx") == 0)
  143. af = AF_IPX;
  144. else if (strcmp(optarg, "ns") == 0)
  145. af = AF_NS;
  146. else if (strcmp(optarg, "encap") == 0)
  147. af = PF_KEY;
  148. else if (strcmp(optarg, "atalk") == 0)
  149. af = AF_APPLETALK;
  150. */
  151. else {
  152. (void)fprintf(stderr,
  153.     "%s: %s: unknown address familyn",
  154.     progname, optarg);
  155. exit(1);
  156. }
  157. return;
  158. case 'g':
  159. gflag = 1;
  160. break;
  161. case 'I':
  162. iflag = 1;
  163.                         if (!*optarg)
  164.                             optarg = argv[optind++];
  165. intrface = optarg;
  166. return;
  167. case 'i':
  168. iflag = 1;
  169. break;
  170.     /*  case 'L': FreeBSD: Display listen queue lengths
  171. NetBSD:  Suppress link-level routes */
  172.     /* case 'l': OpenBSD: Wider IPv6 display
  173. Linux:   Listening sockets only
  174. lflag = 1;
  175. break;
  176. case 'M': *BSD:    Memory image
  177. Linux:   Masqueraded connections
  178. memf = optarg;
  179. break;
  180.      */
  181. case 'm':
  182. mflag = 1;
  183. break;
  184.     /* case 'N': *BSD:    Kernel image
  185. nlistf = optarg;
  186. break;
  187.      */
  188. case 'n':
  189. nflag = 1;
  190. break;
  191. case 'o':
  192. oflag = 1;
  193. break;
  194.     /*  case 'P': NetBSD:
  195. OpenBSD: dump PCB block */
  196. case 'p':
  197.                         if (!*optarg)
  198.                             optarg = argv[optind++];
  199. if ((tp = name2protox(optarg)) == NULL) {
  200. (void)fprintf(stderr,
  201.     "%s: %s: unknown protocoln",
  202.     progname, optarg);
  203. exit(1);
  204. }
  205. pflag = 1;
  206. return;
  207.     /* case 'q': NetBSD:  IRQ information
  208. OpenBSD: Suppress inactive I/Fs
  209. qflag = 1;
  210. break;
  211.      */
  212. case 'r':
  213. rflag = 1;
  214. break;
  215. case 'S':      /* FreeBSD:
  216. NetBSD:  Semi-numeric display
  217. OpenBSD: Show route source selector */
  218. Sflag = 1;
  219. break;
  220. case 's':
  221. ++sflag;
  222. break;
  223.      /* case 't': FreeBSD:
  224. OpenBSD: Display watchdog timers
  225. tflag = 1;
  226. break;
  227. case 'u': OpenBSD: unix sockets only
  228. af = AF_UNIX;
  229. break;
  230.       */
  231. case 'v':
  232. vflag = 1;
  233. break;
  234. case 'w':
  235.                         if (!*optarg)
  236.                             optarg = argv[optind++];
  237. interval = atoi(optarg);
  238. iflag = 1;
  239. return;
  240. case '?':
  241. default:
  242. usage();
  243.             }
  244.         }
  245.         break;   /* End of '-Cx' switch */
  246.     /*
  247.      *  Backward compatability for the main display modes
  248.      *    (where this doesn't clash with standard SNMP flags)
  249.      */
  250.     case 'i':
  251. iflag = 1;
  252. break;
  253.     case 'R':
  254. rflag = 1;    /* -r sets the retry count */
  255. break;
  256.     case 's':
  257. ++sflag;
  258. break;
  259.     }
  260. }
  261. int
  262. main(int argc, char *argv[])
  263. {
  264. netsnmp_session session;
  265. struct protoent *p;
  266.         char *cp;
  267. af = AF_UNSPEC;
  268.         cp = strrchr( argv[0], '/' );
  269.         if (cp)
  270.             progname = cp+1;
  271.         else
  272.             progname = argv[0];
  273. switch (snmp_parse_args( argc, argv, &session, "C:iRs", optProc)) {
  274. case -2:
  275.     exit(0);
  276. case -1:
  277.     usage();
  278.     exit(0);
  279. default:
  280.     break;
  281. }
  282.     /*
  283.      * Check argc vs optind ??
  284.      */
  285. argv += optind;
  286. argc -= optind;
  287.     /*
  288.      * Open an SNMP session.
  289.      */
  290.     SOCK_STARTUP;
  291.     ss = snmp_open(&session);
  292.     if (ss == NULL) {
  293.         /*
  294.          * diagnose snmp_open errors with the input netsnmp_session pointer 
  295.          */
  296.         snmp_sess_perror("snmpnetstat", &session);
  297.         SOCK_CLEANUP;
  298.         exit(1);
  299.     }
  300. /*
  301.  * Omitted:
  302.  *     Privilege handling
  303.  *    "Backward Compatibility"
  304.  *     Kernel namelis handling
  305.  */
  306. if (mflag) {
  307.             /*
  308. mbpr(nl[N_MBSTAT].n_value, nl[N_MBPOOL].n_value,
  309.     nl[N_MCLPOOL].n_value);
  310.              */
  311. exit(0);
  312. }
  313. if (pflag) {
  314. printproto(tp, tp->pr_name);
  315. exit(0);
  316. }
  317. /*
  318.  * Keep file descriptors open to avoid overhead
  319.  * of open/close on each call to get* routines.
  320.  */
  321. sethostent(1);
  322. setnetent(1);
  323. if (iflag) {
  324. intpr(interval);
  325. exit(0);
  326. }
  327. if (rflag) {
  328.              /*
  329. if (sflag)
  330. rt_stats();
  331. else
  332.               */
  333. routepr();
  334. exit(0);
  335. }
  336.      /*
  337. if (gflag) {
  338. if (sflag) {
  339. if (af == AF_INET || af == AF_UNSPEC)
  340. mrt_stats(nl[N_MRTPROTO].n_value,
  341.     nl[N_MRTSTAT].n_value);
  342. #ifdef INET6
  343. if (af == AF_INET6 || af == AF_UNSPEC)
  344. mrt6_stats(nl[N_MRT6PROTO].n_value,
  345.     nl[N_MRT6STAT].n_value);
  346. #endif
  347. }
  348. else {
  349. if (af == AF_INET || af == AF_UNSPEC)
  350. mroutepr(nl[N_MRTPROTO].n_value,
  351.     nl[N_MFCHASHTBL].n_value,
  352.     nl[N_MFCHASH].n_value,
  353.     nl[N_VIFTABLE].n_value);
  354. #ifdef INET6
  355. if (af == AF_INET6 || af == AF_UNSPEC)
  356. mroute6pr(nl[N_MRT6PROTO].n_value,
  357.     nl[N_MF6CTABLE].n_value,
  358.     nl[N_MIF6TABLE].n_value);
  359. #endif
  360. }
  361. exit(0);
  362. }
  363.      */
  364. if (af == AF_INET || af == AF_UNSPEC) {
  365. setprotoent(1);
  366. setservent(1);
  367. /* ugh, this is O(MN) ... why do we do this? */
  368. while ((p = getprotoent())) {
  369. for (tp = protox; tp->pr_name; tp++)
  370. if (strcmp(tp->pr_name, p->p_name) == 0)
  371. break;
  372. if (tp->pr_name == 0 || tp->pr_wanted == 0)
  373. continue;
  374. printproto(tp, p->p_name);
  375. }
  376. endprotoent();
  377. }
  378. if (af == AF_INET6 || af == AF_UNSPEC)
  379. for (tp = ip6protox; tp->pr_name; tp++)
  380. printproto(tp, tp->pr_name);
  381.     /*
  382. if (af == AF_IPX || af == AF_UNSPEC)
  383. for (tp = ipxprotox; tp->pr_name; tp++)
  384. printproto(tp, tp->pr_name);
  385. if (af == AF_NS || af == AF_UNSPEC)
  386. for (tp = nsprotox; tp->pr_name; tp++)
  387. printproto(tp, tp->pr_name);
  388. if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
  389. unixpr(nl[N_UNIXSW].n_value);
  390. if (af == AF_APPLETALK || af == AF_UNSPEC)
  391. for (tp = atalkprotox; tp->pr_name; tp++)
  392. printproto(tp, tp->pr_name);
  393.      */
  394. exit(0);
  395. }
  396. /*
  397.  * Print out protocol statistics or control blocks (per sflag).
  398.  * Namelist checks - Omitted
  399.  */
  400. static void
  401. printproto(struct protox *tp, const char *name)
  402. {
  403. void (*pr)(const char *);
  404. if (sflag) {
  405. pr = tp->pr_stats;
  406. } else {
  407. pr = tp->pr_cblocks;
  408. }
  409. if (pr != NULL)
  410. (*pr)(name);
  411. }
  412. /*
  413.  * Read kernel memory - Omitted
  414.  */
  415. const char *
  416. plural(int n)
  417. {
  418. return (n != 1 ? "s" : "");
  419. }
  420. const char *
  421. plurales(int n)
  422. {
  423. return (n != 1 ? "es" : "");
  424. }
  425. /*
  426.  * Find the protox for the given "well-known" name.
  427.  */
  428. static struct protox *
  429. knownname(const char *name)
  430. {
  431. struct protox **tpp, *tp;
  432. for (tpp = protoprotox; *tpp; tpp++)
  433. for (tp = *tpp; tp->pr_name; tp++)
  434. if (strcmp(tp->pr_name, name) == 0)
  435. return (tp);
  436. return (NULL);
  437. }
  438. /*
  439.  * Find the protox corresponding to name.
  440.  */
  441. static struct protox *
  442. name2protox(const char *name)
  443. {
  444. struct protox *tp;
  445. char **alias; /* alias from p->aliases */
  446. struct protoent *p;
  447. /*
  448.  * Try to find the name in the list of "well-known" names. If that
  449.  * fails, check if name is an alias for an Internet protocol.
  450.  */
  451. if ((tp = knownname(name)))
  452. return (tp);
  453. setprotoent(1); /* make protocol lookup cheaper */
  454. while ((p = getprotoent())) {
  455. /* assert: name not same as p->name */
  456. for (alias = p->p_aliases; *alias; alias++)
  457. if (strcmp(name, *alias) == 0) {
  458. endprotoent();
  459. return (knownname(p->p_name));
  460. }
  461. }
  462. endprotoent();
  463. return (NULL);
  464. }
  465. static void
  466. usage(void)
  467. {
  468. (void)fprintf(stderr,
  469. "usage: %s [snmp_opts] [-Can] [-Cf address_family]n", progname);
  470. (void)fprintf(stderr,
  471. "       %s [snmp_opts] [-CbdgimnrSs] [-Cf address_family]n", progname);
  472. (void)fprintf(stderr,
  473. "       %s [snmp_opts] [-Cbdn] [-CI interface] [-Cw wait]n", progname);
  474. (void)fprintf(stderr,
  475. "       %s [snmp_opts] [-Cs] [-Cp protocol]n", progname);
  476. (void)fprintf(stderr,
  477. "       %s [snmp_opts] [-Ca] [-Cf address_family] [-Ci | -CI interface]n", progname);
  478. exit(1);
  479. }