1258945Sroberto/*****************************************************************************
2258945Sroberto *
3258945Sroberto *  ntpSnmpSubAgentObject.c
4258945Sroberto *
5258945Sroberto *  This file provides the callback functions for net-snmp and registers the
6258945Sroberto *  serviced MIB objects with the master agent.
7258945Sroberto *
8258945Sroberto *  Each object has its own callback function that is called by the
9258945Sroberto *  master agent process whenever someone queries the corresponding MIB
10258945Sroberto *  object.
11258945Sroberto *
12258945Sroberto *  At the moment this triggers a full send/receive procedure for each
13258945Sroberto *  queried MIB object, one of the things that are still on my todo list:
14258945Sroberto *  a caching mechanism that reduces the number of requests sent to the
15258945Sroberto *  ntpd process.
16258945Sroberto *
17258945Sroberto ****************************************************************************/
18258945Sroberto#include <ntp_snmp.h>
19258945Sroberto#include <ctype.h>
20258945Sroberto#include <ntp.h>
21258945Sroberto#include <libntpq.h>
22258945Sroberto
23258945Sroberto/* general purpose buffer length definition */
24258945Sroberto#define NTPQ_BUFLEN 2048
25258945Sroberto
26258945Srobertochar ntpvalue[NTPQ_BUFLEN];
27258945Sroberto
28258945Sroberto
29258945Sroberto/*****************************************************************************
30258945Sroberto *
31258945Sroberto * ntpsnmpd_parse_string
32258945Sroberto *
33258945Sroberto *  This function will parse a given NULL terminated string and cut it
34258945Sroberto *  into a fieldname and a value part (using the '=' as the delimiter.
35258945Sroberto *  The fieldname will be converted to uppercase and all whitespace
36258945Sroberto *  characters are removed from it.
37258945Sroberto *  The value part is stripped, e.g. all whitespace characters are removed
38258945Sroberto *  from the beginning and end of the string.
39258945Sroberto *  If the value is started and ended with quotes ("), they will be removed
40258945Sroberto *  and everything between the quotes is left untouched (including
41258945Sroberto *  whitespace)
42258945Sroberto *  Example:
43258945Sroberto *     server host name =   hello world!
44258945Sroberto *  will result in a field string "SERVERHOSTNAME" and a value
45258945Sroberto *  of "hello world!".
46258945Sroberto *     My first Parameter		=		"  is this!    "
47258945Sroberto  * results in a field string "MYFIRSTPARAMETER" and a value " is this!    "
48258945Sroberto ****************************************************************************
49258945Sroberto * Parameters:
50258945Sroberto *	string		const char *	The source string to parse.
51258945Sroberto *					NOTE: must be NULL terminated!
52258945Sroberto *	field		char *		The buffer for the field name.
53258945Sroberto *	fieldsize	size_t		The size of the field buffer.
54258945Sroberto *	value		char *		The buffer for the value.
55258945Sroberto *	valuesize	size_t		The size of the value buffer.
56258945Sroberto *
57258945Sroberto * Returns:
58258945Sroberto *	size_t			length of value string
59258945Sroberto ****************************************************************************/
60258945Sroberto
61258945Srobertosize_t
62258945Srobertontpsnmpd_parse_string(
63258945Sroberto	const char *	string,
64258945Sroberto	char *		field,
65258945Sroberto	size_t		fieldsize,
66258945Sroberto	char *		value,
67258945Sroberto	size_t		valuesize
68258945Sroberto	)
69258945Sroberto{
70258945Sroberto	int i;
71258945Sroberto	int j;
72258945Sroberto	int loop;
73258945Sroberto	size_t str_cnt;
74258945Sroberto	size_t val_cnt;
75258945Sroberto
76258945Sroberto	/* we need at least one byte to work with to simplify */
77258945Sroberto	if (fieldsize < 1 || valuesize < 1)
78258945Sroberto		return 0;
79258945Sroberto
80258945Sroberto	str_cnt = strlen(string);
81258945Sroberto
82258945Sroberto	/* Parsing the field name */
83258945Sroberto	j = 0;
84258945Sroberto	loop = TRUE;
85258945Sroberto	for (i = 0; loop && i <= str_cnt; i++) {
86258945Sroberto		switch (string[i]) {
87258945Sroberto
88258945Sroberto		case '\t': 	/* Tab */
89258945Sroberto		case '\n':	/* LF */
90258945Sroberto		case '\r':	/* CR */
91258945Sroberto		case ' ':  	/* Space */
92258945Sroberto			break;
93258945Sroberto
94258945Sroberto		case '=':
95258945Sroberto			loop = FALSE;
96258945Sroberto			break;
97258945Sroberto
98258945Sroberto		default:
99258945Sroberto			if (j < fieldsize)
100258945Sroberto				field[j++] = toupper(string[i]);
101258945Sroberto		}
102258945Sroberto	}
103258945Sroberto
104258945Sroberto	j = min(j, fieldsize - 1);
105258945Sroberto	field[j] = '\0';
106258945Sroberto
107258945Sroberto	/* Now parsing the value */
108258945Sroberto	value[0] = '\0';
109258945Sroberto	j = 0;
110258945Sroberto	for (val_cnt = 0; i < str_cnt; i++) {
111258945Sroberto		if (string[i] > 0x0D && string[i] != ' ')
112258945Sroberto			val_cnt = min(j + 1, valuesize - 1);
113258945Sroberto
114258945Sroberto		if (value[0] != '\0' ||
115258945Sroberto		    (string[i] > 0x0D && string[i] != ' ')) {
116258945Sroberto			if (j < valuesize)
117258945Sroberto				value[j++] = string[i];
118258945Sroberto		}
119258945Sroberto	}
120258945Sroberto	value[val_cnt] = '\0';
121258945Sroberto
122258945Sroberto	if (value[0] == '"') {
123258945Sroberto		val_cnt--;
124280849Scy		strlcpy(value, &value[1], valuesize);
125258945Sroberto		if (val_cnt > 0 && value[val_cnt - 1] == '"') {
126258945Sroberto			val_cnt--;
127258945Sroberto			value[val_cnt] = '\0';
128258945Sroberto		}
129258945Sroberto	}
130258945Sroberto
131258945Sroberto	return val_cnt;
132258945Sroberto}
133258945Sroberto
134258945Sroberto
135258945Sroberto/*****************************************************************************
136258945Sroberto *
137258945Sroberto * ntpsnmpd_cut_string
138258945Sroberto *
139258945Sroberto *  This function will parse a given NULL terminated string and cut it
140258945Sroberto *  into fields using the specified delimiter character.
141258945Sroberto *  It will then copy the requested field into a destination buffer
142258945Sroberto *  Example:
143258945Sroberto *     ntpsnmpd_cut_string(read:my:lips:fool, RESULT, ':', 2, sizeof(RESULT))
144258945Sroberto *  will copy "lips" to RESULT.
145258945Sroberto ****************************************************************************
146258945Sroberto * Parameters:
147258945Sroberto *	src		const char *	The name of the source string variable
148258945Sroberto *					NOTE: must be NULL terminated!
149258945Sroberto *	dest		char *		The name of the string which takes the
150258945Sroberto *					requested field content
151258945Sroberto * 	delim		char		The delimiter character
152258945Sroberto *	fieldnumber	int		The number of the required field
153258945Sroberto *					(start counting with 0)
154258945Sroberto *	maxsize		size_t		The maximum size of dest
155258945Sroberto *
156258945Sroberto * Returns:
157258945Sroberto *	size_t		length of resulting dest string
158258945Sroberto ****************************************************************************/
159258945Sroberto
160258945Srobertosize_t
161258945Srobertontpsnmpd_cut_string(
162258945Sroberto	const char *	string,
163258945Sroberto	char *		dest,
164258945Sroberto	char		delim,
165258945Sroberto	int		fieldnumber,
166258945Sroberto	size_t		maxsize
167258945Sroberto	)
168258945Sroberto{
169258945Sroberto	size_t i;
170258945Sroberto	size_t j;
171258945Sroberto	int l;
172258945Sroberto	size_t str_cnt;
173258945Sroberto
174258945Sroberto	if (maxsize < 1)
175258945Sroberto		return 0;
176258945Sroberto
177258945Sroberto	str_cnt = strlen(string);
178258945Sroberto	j = 0;
179258945Sroberto	memset(dest, 0, maxsize);
180258945Sroberto
181258945Sroberto	/* Parsing the field name */
182258945Sroberto	for (i = 0, l = 0; i < str_cnt && l <= fieldnumber; i++) {
183258945Sroberto		if (string[i] == delim)
184258945Sroberto			l++;	/* next field */
185258945Sroberto		else if (l == fieldnumber && j < maxsize)
186258945Sroberto			dest[j++] = string[i];
187258945Sroberto	}
188258945Sroberto	j = min(j, maxsize - 1);
189258945Sroberto	dest[j] = '\0';
190258945Sroberto
191258945Sroberto	return j;
192258945Sroberto}
193258945Sroberto
194258945Sroberto
195258945Sroberto/*****************************************************************************
196258945Sroberto *
197258945Sroberto *  read_ntp_value
198258945Sroberto *
199258945Sroberto *  This function retrieves the value for a given variable, currently
200258945Sroberto *  this only supports sysvars. It starts a full mode 6 send/receive/parse
201258945Sroberto *  iteration and needs to be optimized, e.g. by using a caching mechanism
202258945Sroberto *
203258945Sroberto ****************************************************************************
204258945Sroberto * Parameters:
205258945Sroberto *	variable	char*	The name of the required variable
206258945Sroberto *	rbuffer		char*	The buffer where the value goes
207258945Sroberto *	maxlength	int	Max. number of bytes for resultbuf
208258945Sroberto *
209258945Sroberto * Returns:
210258945Sroberto *	u_int		number of chars that have been copied to
211258945Sroberto *			rbuffer
212258945Sroberto ****************************************************************************/
213258945Sroberto
214258945Srobertosize_t
215258945Srobertoread_ntp_value(
216258945Sroberto	const char *	variable,
217258945Sroberto	char *		value,
218258945Sroberto	size_t		valuesize
219258945Sroberto	)
220258945Sroberto{
221258945Sroberto	size_t	sv_len;
222258945Sroberto	char	sv_data[NTPQ_BUFLEN];
223258945Sroberto
224258945Sroberto	memset(sv_data, 0, sizeof(sv_data));
225258945Sroberto	sv_len = ntpq_read_sysvars(sv_data, sizeof(sv_data));
226258945Sroberto
227258945Sroberto	if (0 == sv_len)
228258945Sroberto		return 0;
229258945Sroberto	else
230258945Sroberto		return ntpq_getvar(sv_data, sv_len, variable, value,
231258945Sroberto				   valuesize);
232258945Sroberto}
233258945Sroberto
234258945Sroberto
235258945Sroberto/*****************************************************************************
236258945Sroberto *
237258945Sroberto *  The get_xxx functions
238258945Sroberto *
239258945Sroberto *  The following function calls are callback functions that will be
240258945Sroberto *  used by the master agent process to retrieve a value for a requested
241258945Sroberto *  MIB object.
242258945Sroberto *
243258945Sroberto ****************************************************************************/
244258945Sroberto
245258945Sroberto
246258945Srobertoint get_ntpEntSoftwareName (netsnmp_mib_handler *handler,
247258945Sroberto                               netsnmp_handler_registration *reginfo,
248258945Sroberto                               netsnmp_agent_request_info *reqinfo,
249258945Sroberto                               netsnmp_request_info *requests)
250258945Sroberto{
251258945Sroberto char ntp_softwarename[NTPQ_BUFLEN];
252258945Sroberto
253258945Sroberto   memset (ntp_softwarename, 0, NTPQ_BUFLEN);
254258945Sroberto
255258945Sroberto   switch (reqinfo->mode) {
256258945Sroberto   case MODE_GET:
257258945Sroberto   {
258258945Sroberto	if ( read_ntp_value("product", ntpvalue, NTPQ_BUFLEN) )
259258945Sroberto       {
260258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
261258945Sroberto                             (u_char *)ntpvalue,
262258945Sroberto                             strlen(ntpvalue)
263258945Sroberto                            );
264258945Sroberto       }
265258945Sroberto    else  if ( read_ntp_value("version", ntpvalue, NTPQ_BUFLEN) )
266258945Sroberto    {
267258945Sroberto	ntpsnmpd_cut_string(ntpvalue, ntp_softwarename, ' ', 0, sizeof(ntp_softwarename)-1);
268258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
269258945Sroberto                             (u_char *)ntp_softwarename,
270258945Sroberto                             strlen(ntp_softwarename)
271258945Sroberto                            );
272258945Sroberto    } else {
273258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
274258945Sroberto                             (u_char *)"N/A",
275258945Sroberto                             3
276258945Sroberto                            );
277258945Sroberto    }
278258945Sroberto    break;
279258945Sroberto
280258945Sroberto  }
281258945Sroberto
282258945Sroberto
283258945Sroberto  default:
284258945Sroberto	  /* If we cannot get the information we need, we will return a generic error to the SNMP client */
285258945Sroberto        return SNMP_ERR_GENERR;
286258945Sroberto  }
287258945Sroberto
288258945Sroberto  return SNMP_ERR_NOERROR;
289258945Sroberto}
290258945Sroberto
291258945Sroberto
292258945Srobertoint get_ntpEntSoftwareVersion (netsnmp_mib_handler *handler,
293258945Sroberto                               netsnmp_handler_registration *reginfo,
294258945Sroberto                               netsnmp_agent_request_info *reqinfo,
295258945Sroberto                               netsnmp_request_info *requests)
296258945Sroberto{
297258945Sroberto
298258945Sroberto   switch (reqinfo->mode) {
299258945Sroberto   case MODE_GET:
300258945Sroberto   {
301258945Sroberto
302258945Sroberto    if ( read_ntp_value("version", ntpvalue, NTPQ_BUFLEN) )
303258945Sroberto    {
304258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
305258945Sroberto                             (u_char *)ntpvalue,
306258945Sroberto                             strlen(ntpvalue)
307258945Sroberto                            );
308258945Sroberto    } else {
309258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
310258945Sroberto                             (u_char *)"N/A",
311258945Sroberto                             3
312258945Sroberto                            );
313258945Sroberto    }
314258945Sroberto    break;
315258945Sroberto
316258945Sroberto  }
317258945Sroberto
318258945Sroberto
319258945Sroberto  default:
320258945Sroberto	  /* If we cannot get the information we need, we will return a generic error to the SNMP client */
321258945Sroberto        return SNMP_ERR_GENERR;
322258945Sroberto  }
323258945Sroberto
324258945Sroberto  return SNMP_ERR_NOERROR;
325258945Sroberto}
326258945Sroberto
327258945Sroberto
328258945Srobertoint get_ntpEntSoftwareVendor (netsnmp_mib_handler *handler,
329258945Sroberto                               netsnmp_handler_registration *reginfo,
330258945Sroberto                               netsnmp_agent_request_info *reqinfo,
331258945Sroberto                               netsnmp_request_info *requests)
332258945Sroberto{
333258945Sroberto
334258945Sroberto   switch (reqinfo->mode) {
335258945Sroberto   case MODE_GET:
336258945Sroberto   {
337258945Sroberto
338258945Sroberto    if ( read_ntp_value("vendor", ntpvalue, NTPQ_BUFLEN) )
339258945Sroberto    {
340258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
341258945Sroberto                             (u_char *)ntpvalue,
342258945Sroberto                             strlen(ntpvalue)
343258945Sroberto                            );
344258945Sroberto    } else {
345258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
346258945Sroberto                             (u_char *)"N/A",
347258945Sroberto                             3
348258945Sroberto                            );
349258945Sroberto    }
350258945Sroberto    break;
351258945Sroberto
352258945Sroberto  default:
353258945Sroberto	  /* If we cannot get the information we need, we will return a generic error to the SNMP client */
354258945Sroberto        return SNMP_ERR_GENERR;
355258945Sroberto   }
356258945Sroberto  }
357258945Sroberto  return SNMP_ERR_NOERROR;
358258945Sroberto}
359258945Sroberto
360258945Sroberto
361258945Srobertoint get_ntpEntSystemType (netsnmp_mib_handler *handler,
362258945Sroberto                               netsnmp_handler_registration *reginfo,
363258945Sroberto                               netsnmp_agent_request_info *reqinfo,
364258945Sroberto                               netsnmp_request_info *requests)
365258945Sroberto{
366258945Sroberto
367258945Sroberto   switch (reqinfo->mode) {
368258945Sroberto   case MODE_GET:
369258945Sroberto   {
370258945Sroberto
371258945Sroberto    if ( read_ntp_value("systemtype", ntpvalue, NTPQ_BUFLEN) )
372258945Sroberto    {
373258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
374258945Sroberto                             (u_char *)ntpvalue,
375258945Sroberto                             strlen(ntpvalue)
376258945Sroberto                            );
377258945Sroberto    }
378258945Sroberto
379258945Sroberto    if ( read_ntp_value("system", ntpvalue, NTPQ_BUFLEN) )
380258945Sroberto    {
381258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
382258945Sroberto                             (u_char *)ntpvalue,
383258945Sroberto                             strlen(ntpvalue)
384258945Sroberto                            );
385258945Sroberto    } else {
386258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
387258945Sroberto                             (u_char *)"N/A",
388258945Sroberto                             3
389258945Sroberto                            );
390258945Sroberto    }
391258945Sroberto    break;
392258945Sroberto
393258945Sroberto  }
394258945Sroberto
395258945Sroberto
396258945Sroberto  default:
397258945Sroberto	  /* If we cannot get the information we need, we will return a generic error to the SNMP client */
398258945Sroberto        return SNMP_ERR_GENERR;
399258945Sroberto  }
400258945Sroberto
401258945Sroberto  return SNMP_ERR_NOERROR;
402258945Sroberto}
403258945Sroberto
404258945Sroberto
405258945Sroberto/*
406258945Sroberto * ntpEntTimeResolution
407258945Sroberto *	"The time resolution in integer format, where the resolution
408258945Sroberto *	 is represented as divisions of a second, e.g., a value of 1000
409258945Sroberto *	 translates to 1.0 ms."
410258945Sroberto *
411258945Sroberto * ntpEntTimeResolution is a challenge for ntpd, as the resolution is
412258945Sroberto * not known nor exposed by ntpd, only the measured precision (time to
413258945Sroberto * read the clock).
414258945Sroberto *
415258945Sroberto * Logically the resolution must be at least the precision, so report
416258945Sroberto * it as our best approximation of resolution until/unless ntpd provides
417258945Sroberto * better.
418258945Sroberto */
419258945Srobertoint
420258945Srobertoget_ntpEntTimeResolution(
421258945Sroberto	netsnmp_mib_handler *		handler,
422258945Sroberto	netsnmp_handler_registration *	reginfo,
423258945Sroberto	netsnmp_agent_request_info *	reqinfo,
424258945Sroberto	netsnmp_request_info *		requests
425258945Sroberto	)
426258945Sroberto{
427258945Sroberto	int	precision;
428258945Sroberto	u_int32 resolution;
429258945Sroberto
430258945Sroberto	switch (reqinfo->mode) {
431258945Sroberto
432258945Sroberto	case MODE_GET:
433258945Sroberto		if (!read_ntp_value("precision", ntpvalue,
434258945Sroberto				    sizeof(ntpvalue)))
435258945Sroberto			return SNMP_ERR_GENERR;
436258945Sroberto		if (1 != sscanf(ntpvalue, "%d", &precision))
437258945Sroberto			return SNMP_ERR_GENERR;
438258945Sroberto		if (precision >= 0)
439258945Sroberto			return SNMP_ERR_GENERR;
440258945Sroberto		precision = max(precision, -31);
441258945Sroberto		resolution = 1 << -precision;
442258945Sroberto		snmp_set_var_typed_value(
443258945Sroberto			requests->requestvb,
444258945Sroberto			ASN_UNSIGNED,
445258945Sroberto			(void *)&resolution,
446258945Sroberto			sizeof(resolution));
447258945Sroberto		break;
448258945Sroberto
449258945Sroberto	default:
450258945Sroberto		return SNMP_ERR_GENERR;
451258945Sroberto	}
452258945Sroberto
453258945Sroberto	return SNMP_ERR_NOERROR;
454258945Sroberto}
455258945Sroberto
456258945Sroberto
457258945Sroberto/*
458258945Sroberto * ntpEntTimePrecision
459258945Sroberto *	"The entity's precision in integer format, shows the precision.
460258945Sroberto *	 A value of -5 would mean 2^-5 = 31.25 ms."
461258945Sroberto */
462258945Srobertoint
463258945Srobertoget_ntpEntTimePrecision(
464258945Sroberto	netsnmp_mib_handler *		handler,
465258945Sroberto	netsnmp_handler_registration *	reginfo,
466258945Sroberto	netsnmp_agent_request_info *	reqinfo,
467258945Sroberto	netsnmp_request_info *		requests
468258945Sroberto	)
469258945Sroberto{
470258945Sroberto	int	precision;
471258945Sroberto	int32	precision32;
472258945Sroberto
473258945Sroberto	switch (reqinfo->mode) {
474258945Sroberto
475258945Sroberto	case MODE_GET:
476258945Sroberto		if (!read_ntp_value("precision", ntpvalue,
477258945Sroberto				    sizeof(ntpvalue)))
478258945Sroberto			return SNMP_ERR_GENERR;
479258945Sroberto		if (1 != sscanf(ntpvalue, "%d", &precision))
480258945Sroberto			return SNMP_ERR_GENERR;
481258945Sroberto		precision32 = (int32)precision;
482258945Sroberto		snmp_set_var_typed_value(
483258945Sroberto			requests->requestvb,
484258945Sroberto			ASN_INTEGER,
485258945Sroberto			(void *)&precision32,
486258945Sroberto			sizeof(precision32));
487258945Sroberto		break;
488258945Sroberto
489258945Sroberto	default:
490258945Sroberto		return SNMP_ERR_GENERR;
491258945Sroberto	}
492258945Sroberto
493258945Sroberto	return SNMP_ERR_NOERROR;
494258945Sroberto}
495258945Sroberto
496258945Sroberto
497258945Srobertoint get_ntpEntTimeDistance (netsnmp_mib_handler *handler,
498258945Sroberto                               netsnmp_handler_registration *reginfo,
499258945Sroberto                               netsnmp_agent_request_info *reqinfo,
500258945Sroberto                               netsnmp_request_info *requests)
501258945Sroberto{
502258945Sroberto   switch (reqinfo->mode) {
503258945Sroberto   case MODE_GET:
504258945Sroberto   {
505258945Sroberto
506258945Sroberto    if ( read_ntp_value("rootdelay", ntpvalue, NTPQ_BUFLEN) )
507258945Sroberto    {
508258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
509258945Sroberto                             (u_char *)ntpvalue,
510258945Sroberto                             strlen(ntpvalue)
511258945Sroberto                            );
512258945Sroberto    } else {
513258945Sroberto	snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
514258945Sroberto                             (u_char *)"N/A",
515258945Sroberto                             3
516258945Sroberto                            );
517258945Sroberto    }
518258945Sroberto    break;
519258945Sroberto
520258945Sroberto  }
521258945Sroberto
522258945Sroberto
523258945Sroberto  default:
524258945Sroberto	  /* If we cannot get the information we need, we will return a generic error to the SNMP client */
525258945Sroberto        return SNMP_ERR_GENERR;
526258945Sroberto  }
527258945Sroberto
528258945Sroberto  return SNMP_ERR_NOERROR;
529258945Sroberto}
530258945Sroberto
531258945Sroberto
532258945Sroberto/*
533258945Sroberto *
534258945Sroberto * Initialize sub agent
535258945Sroberto */
536258945Sroberto
537258945Srobertovoid
538258945Srobertoinit_ntpSnmpSubagentObject(void)
539258945Sroberto{
540258945Sroberto	/* Register all MIB objects with the agentx master */
541258945Sroberto	NTP_OID_RO( ntpEntSoftwareName,		1, 1, 1, 0);
542258945Sroberto	NTP_OID_RO( ntpEntSoftwareVersion,	1, 1, 2, 0);
543258945Sroberto	NTP_OID_RO( ntpEntSoftwareVendor,	1, 1, 3, 0);
544258945Sroberto	NTP_OID_RO( ntpEntSystemType,		1, 1, 4, 0);
545258945Sroberto	NTP_OID_RO( ntpEntTimeResolution,	1, 1, 5, 0);
546258945Sroberto	NTP_OID_RO( ntpEntTimePrecision,	1, 1, 6, 0);
547258945Sroberto	NTP_OID_RO( ntpEntTimeDistance,		1, 1, 7, 0);
548258945Sroberto}
549258945Sroberto
550