1258945Sroberto/*****************************************************************************
2258945Sroberto *
3258945Sroberto *  ntpsnmpd.c
4258945Sroberto *
5258945Sroberto *  The NTP SNMP daemon is an Agent X subagent application that
6258945Sroberto *  registers itself with a running SNMP Agent X master process running
7258945Sroberto *  on the same machine on port TCP 705. It utilizes the libntqp library
8258945Sroberto *  which accesses status and general data of a running ntpd process on
9258945Sroberto *  the same machine and enables the user to monitor the status of a
10258945Sroberto *  ntp daemon process via SNMP.
11258945Sroberto *
12258945Sroberto *  This started as a Google Summer of Code 2008 project,
13258945Sroberto *  including the ntpsnmpd sub agent and the libntpq library.
14258945Sroberto *
15258945Sroberto *  For more information please visit
16258945Sroberto *	http://support.ntp.org/bin/view/Dev/GSoC2008snmp
17258945Sroberto *  Or contact:
18258945Sroberto *   Harlan Stenn   (Mentor) at stenn@ntp.org
19258945Sroberto *   Heiko Gerstung (Student) at gerstung@ntp.org
20258945Sroberto *
21258945Sroberto ****************************************************************************/
22258945Sroberto
23258945Sroberto#include <ntp_snmp.h>
24258945Sroberto#include <signal.h>
25258945Sroberto#include <sys/time.h>
26258945Sroberto
27258945Sroberto#ifdef SOLARIS /* needed with at least Solaris 8 */
28258945Sroberto#include <siginfo.h>
29258945Sroberto#endif
30258945Sroberto
31258945Sroberto#include <libntpq.h>
32258945Sroberto#include <ntpsnmpd-opts.h>
33258945Sroberto
34258945Srobertostatic int keep_running;
35258945SrobertoRETSIGTYPE stop_server(int);
36258945Sroberto
37258945SrobertoRETSIGTYPE
38258945Srobertostop_server(int a) {
39258945Sroberto    keep_running = 0;
40258945Sroberto}
41258945Sroberto
42258945Sroberto/* The main function just sets up a few things and then enters a loop in which it will
43258945Sroberto * wait for SNMP requests coming from the master agent
44258945Sroberto */
45258945Sroberto
46258945Srobertoint
47258945Srobertomain (int argc, char **argv) {
48258945Sroberto  int background = 0; /* start as background process */
49258945Sroberto  int use_syslog = 1; /* use syslog for logging */
50258945Sroberto
51258945Sroberto	{
52258945Sroberto		int optct = optionProcess(&ntpsnmpdOptions, argc, argv);
53258945Sroberto		argc -= optct;
54258945Sroberto		argv += optct;
55258945Sroberto	}
56258945Sroberto
57258945Sroberto	if (!HAVE_OPT(NOFORK))
58258945Sroberto		background = 1;
59258945Sroberto
60258945Sroberto	if (!HAVE_OPT(SYSLOG))
61258945Sroberto		use_syslog = 0;
62258945Sroberto
63258945Sroberto  /* using the net-snmp syslog facility */
64258945Sroberto  if (use_syslog)
65258945Sroberto    snmp_enable_calllog();
66258945Sroberto  else
67258945Sroberto    snmp_enable_stderrlog();
68258945Sroberto
69258945Sroberto  /* Become Subagent */
70258945Sroberto    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
71258945Sroberto
72258945Sroberto  /* go into background mode, if requested */
73258945Sroberto  if (background && netsnmp_daemonize(1, !use_syslog))
74258945Sroberto      exit(1);
75258945Sroberto
76258945Sroberto  /* Now register with the master Agent X process */
77258945Sroberto
78258945Sroberto  /* call Netsnmp socket startup macro, which will initialize the network stuff if required */
79258945Sroberto  SOCK_STARTUP;
80258945Sroberto
81258945Sroberto  /* Set AgentX socket interface */
82258945Sroberto  netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
83258945Sroberto                            NETSNMP_DS_AGENT_X_SOCKET, OPT_ARG( AGENTXSOCKET ));
84258945Sroberto
85258945Sroberto  init_agent("ntpsnmpd");
86258945Sroberto
87258945Sroberto  /* Try to connect to ntpd */
88280849Scy  if ( ntpq_openhost("localhost", 0) == 0 )
89258945Sroberto  {
90258945Sroberto	fprintf(stderr, "Error: Could not connect to ntpd. Aborting.\n");
91258945Sroberto	exit(1);
92258945Sroberto  }
93258945Sroberto
94258945Sroberto
95258945Sroberto  /* Register callback functions ...  */
96258945Sroberto  init_ntpSnmpSubagentObject();
97258945Sroberto  init_snmp("ntpsnmpd");
98258945Sroberto
99258945Sroberto  /* Signal handler */
100258945Sroberto  keep_running = 1;
101258945Sroberto  signal(SIGTERM, stop_server);
102258945Sroberto  signal(SIGINT, stop_server);
103258945Sroberto
104258945Sroberto  snmp_log(LOG_INFO,"ntpsnmpd started.\n");
105258945Sroberto
106258945Sroberto  /* main loop here... */
107258945Sroberto  while(keep_running) {
108258945Sroberto	agent_check_and_process(1); /* 0 == don't block */
109258945Sroberto  }
110258945Sroberto
111258945Sroberto  /* at shutdown time */
112258945Sroberto  ntpq_closehost();
113258945Sroberto  snmp_shutdown("ntpsnmpd");
114258945Sroberto  SOCK_CLEANUP;
115258945Sroberto
116258945Sroberto  return 0;
117258945Sroberto}
118258945Sroberto
119