xref: /openbsd/lib/libagentx/agentx.3 (revision 73471bf0)
1.\" $OpenBSD: agentx.3,v 1.7 2021/03/12 05:18:00 jsg Exp $
2.\"
3.\" Copyright (c) 2020 Martijn van Duren <martijn@openbsd.org>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: March 12 2021 $
18.Dt AGENTX 3
19.Os
20.Sh NAME
21.Nm agentx_log_fatal ,
22.Nm agentx_log_warn ,
23.Nm agentx_log_info ,
24.Nm agentx_log_debug ,
25.Nm agentx ,
26.Nm agentx_connect ,
27.Nm agentx_read ,
28.Nm agentx_write ,
29.Nm agentx_wantwrite ,
30.Nm agentx_free ,
31.Nm agentx_session ,
32.Nm agentx_session_free ,
33.Nm agentx_context ,
34.Nm agentx_context_object_find ,
35.Nm agentx_context_object_nfind ,
36.Nm agentx_context_uptime ,
37.Nm agentx_context_free ,
38.Nm agentx_region ,
39.Nm agentx_region_free ,
40.Nm agentx_agentcaps ,
41.Nm agentx_agentcaps_free ,
42.Nm agentx_index_integer_new ,
43.Nm agentx_index_integer_any ,
44.Nm agentx_index_integer_value ,
45.Nm agentx_index_integer_dynamic ,
46.Nm agentx_index_string_dynamic ,
47.Nm agentx_index_nstring_dynamic ,
48.Nm agentx_index_oid_dynamic ,
49.Nm agentx_index_noid_dynamic ,
50.Nm agentx_index_ipaddress_dynamic ,
51.Nm agentx_index_free ,
52.Nm agentx_object ,
53.Nm agentx_object_free ,
54.Nm agentx_varbind_integer ,
55.Nm agentx_varbind_string ,
56.Nm agentx_varbind_nstring ,
57.Nm agentx_varbind_printf ,
58.Nm agentx_varbind_null ,
59.Nm agentx_varbind_oid ,
60.Nm agentx_varbind_object ,
61.Nm agentx_varbind_index ,
62.Nm agentx_varbind_ipaddress ,
63.Nm agentx_varbind_counter32 ,
64.Nm agentx_varbind_gauge32 ,
65.Nm agentx_varbind_unsigned32 ,
66.Nm agentx_varbind_timeticks ,
67.Nm agentx_varbind_opaque ,
68.Nm agentx_varbind_counter64 ,
69.Nm agentx_varbind_notfound ,
70.Nm agentx_varbind_error ,
71.Nm agentx_varbind_request ,
72.Nm agentx_varbind_get_index_integer ,
73.Nm agentx_varbind_get_index_string ,
74.Nm agentx_varbind_get_index_oid ,
75.Nm agentx_varbind_get_index_ipaddress ,
76.Nm agentx_varbind_set_index_integer ,
77.Nm agentx_varbind_set_index_string ,
78.Nm agentx_varbind_set_index_nstring ,
79.Nm agentx_varbind_set_index_oid ,
80.Nm agentx_varbind_set_index_object ,
81.Nm agentx_varbind_set_index_ipaddress
82.Nd manage an interface to an agentx master
83.Sh SYNOPSIS
84.In agentx.h
85.Ft extern void
86.Fn (*agentx_log_fatal) "const char *fmt" ...
87.Ft extern void
88.Fn (*agentx_log_warn) "const char *fmt" ...
89.Ft extern void
90.Fn (*agentx_log_info) "const char *fmt" ...
91.Ft extern void
92.Fn (*agentx_log_debug) "const char *fmt" ...
93.Ft struct agentx *
94.Fn agentx "void (*nofd)(struct agentx *, void *, int)" "void *cookie"
95.Ft void
96.Fn agentx_connect "struct agentx *sa" "int fd"
97.Ft void
98.Fn agentx_read "struct agentx *sa"
99.Ft void
100.Fn agentx_write "struct agentx *sa"
101.Ft extern void
102.Fn (*agentx_wantwrite) "struct agentx *sa" "int fd"
103.Ft void
104.Fn agentx_free "struct agentx *sa"
105.Ft struct agentx_session *
106.Fo agentx_session
107.Fa "struct agentx *sa" "uint32_t oid[]" "size_t oidlen"
108.Fa "const char *descr" "uint8_t timeout"
109.Fc
110.Ft void
111.Fn agentx_session_free "struct agentx_session *sas"
112.Ft struct agentx_context *
113.Fn agentx_context "struct agentx_session *sas" "const char *name"
114.Ft struct agentx_object *
115.Fo agentx_context_object_find
116.Fa "struct agentx_context *sac" "const uint32_t oid[]" "size_t oidlen"
117.Fa "int active" "int instance"
118.Fc
119.Ft struct agentx_object *
120.Fo agentx_context_object_nfind
121.Fa "struct agentx_context *" "const uint32_t oid[]" "size_t oidlen"
122.Fa "int active" "int inclusive"
123.Fc
124.Ft uint32_t
125.Fn agentx_context_uptime "struct agentx_context *sac"
126.Ft void
127.Fn agentx_context_free "struct agentx_context *sac"
128.Ft struct agentx_agentcaps *
129.Fo agentx_agentcaps
130.Fa "struct agentx_context *sac" "uint32_t oid[]" "size_t oidlen"
131.Fa "const char *descr"
132.Fc
133.Ft void
134.Fn agentx_agentcaps_free "struct agentx_agentcaps *saa"
135.Ft struct agentx_region *
136.Fo agentx_region
137.Fa "struct agentx_context *sac" "uint32_t oid[]"
138.Fa "size_t oidlen" "uint8_t timeout"
139.Fc
140.Ft void
141.Fn agentx_region_free "struct agentx_region *sar"
142.Ft struct agentx_index *
143.Fo agentx_index_integer_new
144.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
145.Fc
146.Ft struct agentx_index *
147.Fo agentx_index_integer_any
148.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
149.Fc
150.Ft struct agentx_index *
151.Fo agentx_index_integer_value
152.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
153.Fa "int32_t value"
154.Fc
155.Ft struct agentx_index *
156.Fo agentx_index_integer_dynamic
157.Fa "struct agentx_region *sar" "uint32_t oid[] "size_t oidlen"
158.Fc
159.Ft struct agentx_index *
160.Fo agentx_index_string_dynamic
161.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
162.Fc
163.Ft struct agentx_index *
164.Fo agentx_index_nstring_dynamic
165.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
166.Fa "size_t slen"
167.Fc
168.Ft struct agentx_index *
169.Fo agentx_index_oid_dynamic
170.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
171.Fc
172.Ft struct agentx_index *
173.Fo agentx_index_noid_dynamic
174.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
175.Fa "size_t vlen"
176.Fc
177.Ft struct agentx_index *
178.Fo agentx_index_ipaddress_dynamic
179.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
180.Fc
181.Ft void
182.Fn agentx_index_free "struct agentx_index *sai"
183.Ft struct agentx_object *
184.Fo agentx_object
185.Fa "struct agentx_region *sar" "uint32_t oid[]" "size_t oidlen"
186.Fa "struct agentx_index *index[]" "size_t indexlen" "int implied"
187.Fa "void (*getcb)(struct agentx_varbind *)"
188.Fc
189.Ft void
190.Fn agentx_object_free "struct agentx_object *sao"
191.Ft void
192.Fn agentx_varbind_integer "struct agentx_varbind *sav" "int32_t value"
193.Ft void
194.Fn agentx_varbind_string "struct agentx_varbind *sav" "const char *value"
195.Ft void
196.Fo agentx_varbind_nstring
197.Fa "struct agentx_varbind *sav" "const char *value" "size_t slen"
198.Fc
199.Ft void
200.Fo agentx_varbind_printf
201.Fa "struct agentx_varbind *sav" "const char *fmt" ...
202.Fc
203.Ft void
204.Fn agentx_varbind_null "struct agentx_varbind *sav"
205.Ft void
206.Fo agentx_varbind_oid
207.Fa "struct agentx_varbind *sav" "const uint32_t oid[]" "size_t oidlen"
208.Fc
209.Ft void
210.Fo agentx_varbind_object
211.Fa "struct agentx_varbind *sav" "struct agentx_object *sao"
212.Fc
213.Ft void
214.Fo agentx_varbind_index
215.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
216.Fc
217.Ft void
218.Fo agentx_varbind_ipaddress
219.Fa "struct agentx_varbind *sav" "const struct in_addr *addr"
220.Fc
221.Ft void
222.Fn agentx_varbind_counter32 "struct agentx_varbind *sav" "uint32_t value"
223.Ft void
224.Fn agentx_varbind_gauge32 "struct agentx_varbind *sav" "uint32_t value"
225.Ft void
226.Fn agentx_varbind_unsigned32 "struct agentx_varbind *sav" "uint32_t value"
227.Ft void
228.Fo agentx_varbind_timeticks
229.Fa "struct agentx_varbind *sav"  "uint32_t value"
230.Fc
231.Ft void
232.Fo agentx_varbind_opaque
233.Fa "struct agentx_varbind *sav" "const char *value" "size_t slen"
234.Fc
235.Ft void
236.Fn agentx_varbind_counter64 "struct agentx_varbind *sav" "uint64_t value"
237.Ft void
238.Fn agentx_varbind_notfound "struct agentx_varbind *sav"
239.Ft void
240.Fn agentx_varbind_error "struct agentx_varbind *sav"
241.Ft enum agentx_request_type
242.Fn agentx_varbind_request "struct agentx_varbind *sav"
243.Ft int32_t
244.Fo agentx_varbind_get_index_integer
245.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
246.Fc
247.Ft const unsigned char *
248.Fo agentx_varbind_get_index_string
249.Fa "struct agentx_varbind *sav" "struct agentx_index *sai" "size_t *slen"
250.Fa "int *implied"
251.Fc
252.Ft const uint32_t *
253.Fo agentx_varbind_get_index_oid
254.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
255.Fa "size_t *oidlen" "int *implied"
256.Fc
257.Ft const struct in_addr *
258.Fo agentx_varbind_get_index_ipaddress
259.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
260.Fc
261.Ft void
262.Fo agentx_varbind_set_index_integer
263.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
264.Fa "int32_t value"
265.Fc
266.Ft void
267.Fo agentx_varbind_set_index_string
268.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
269.Fa "const unsigned char *value"
270.Fc
271.Ft void
272.Fo agentx_varbind_set_index_nstring
273.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
274.Fa "const unsigned char *value" "size_t slen"
275.Fc
276.Ft void
277.Fo agentx_varbind_set_index_oid
278.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
279.Fa "const uint32_t *oid" "size_t oidlen"
280.Fc
281.Ft void
282.Fo agentx_varbind_set_index_object
283.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
284.Fa "struct agentx_object *sao"
285.Fc
286.Ft void
287.Fo agentx_varbind_set_index_ipaddress
288.Fa "struct agentx_varbind *sav" "struct agentx_index *sai"
289.Fa "const struct in_addr *addr"
290.Fc
291.Bd -literal
292enum agentx_request_type {
293        AGENTX_REQUEST_TYPE_GET,
294        AGENTX_REQUEST_TYPE_GETNEXT,
295        AGENTX_REQUEST_TYPE_GETNEXTINCLUSIVE
296};
297.Ed
298.Fd #define AGENTX_MASTER_PATH \(dq/var/agentx/master\(dq
299.Fd #define AGENTX_OID_MAX_LEN 128
300.Fd #define AGENTX_OID_INDEX_MAX_LEN 10
301.Fd #define AGENTX_OID(...)
302.Fd #define AGENTX_MIB2 1, 3, 6, 1, 2, 1
303.Fd #define AGENTX_ENTERPRISES 1, 3, 6, 1, 4, 1
304.Sh DESCRIPTION
305The
306.Nm agentx
307functions allow an application to describe their MIB layout and provide an
308.Fa fd
309based interface to control the internal agentx state.
310.Nm agentx
311is not thread safe.
312.Ss DESCRIBING THE MIB
313.Nm agentx
314is a framework to abstract away the agentx protocol from the application.
315For the framework to report information to the administrator, the
316.Fn agentx_log_fatal ,
317.Fn agentx_log_warn ,
318.Fn agentx_log_info
319and
320.Fn agentx_log_debug
321functions must be set.
322.Pp
323When
324.Fa sa
325is created by
326.Fn agentx
327or when
328.Fa sa
329detects that there is no connection to the agentx master it calls out to
330.Fa nofd
331with itself,
332.Fa cookie
333and an integer
334.Fa close
335as arguments.
336If
337.Fa close
338is not set
339.Fn nofd
340is expected to set up a new
341.Fa fd
342to the agentx master.
343This one can usually be found at
344.Dv AGENTX_MASTER_PATH .
345This
346.Fa fd
347can be returned to
348.Fa sa
349at any moment via
350.Fn agentx_connect ,
351but must always be done as a result of a call to
352.Fn nofd .
353Once
354.Fn agentx_connect
355has been called the application is responsible for retrieving data when available
356on
357.Fa fd
358by calling
359.Fn agentx_read .
360If nonblocking writes are desirable the
361.Fn agentx_wantwrite
362pointer can be set to an application function and will be called as soon as
363there's data available to be written out.
364Once
365.Fa fd
366is ready for write the function
367.Fn agentx_write
368should be called.
369.Pp
370.Fa sa
371can be freed via
372.Fn agentx_free .
373It will close all active sessions and free all derived objects.
374Once freed no new objects can be derived from the freed objects.
375Once all sessions are closed it will call out to
376.Fn nofd
377with
378.Fa close
379set, indicating that the application can clean up any context related to
380.Fa sa .
381.Pp
382On top of the
383.Fa sa
384connection a
385.Vt agentx_session
386must be set up.
387Normally there's only a single session per
388.Fa sa .
389The
390.Fa timeout
391argument specifies the maximum time in seconds the master should wait for a
392reply before determining we're gone.
393If set to 0 the agentx master determines the timeout.
394The
395.Fa oid
396and
397.Fa oidlen
398combination identifies the subagent and will be visible through the
399agentxSessionObjectID object on the agentx master.
400The
401.Fa descr
402is a short displaystring description of the agent and will be visible through
403the agentxSessionDescr object on the agentx master.
404.Pp
405The
406.Vt agentx_context
407is the SNMPv3 context in which the objects operate and is built on top of
408agentx_session
409.Fa sas .
410If the default context is requested
411.Fa name
412must be NULL.
413.Pp
414.Fn agentx_agentcaps
415registers an entry in the agentx master's sysORTable.
416The
417.Fa oid ,
418.Fa oidlen
419combination should point to an AGENT-CAPABILITIES object which describes the
420capabilities of the subagent.
421.Fa descr
422should be a textual description of the capabilities.
423If no AGENT-CAPABILITIES object is defined this function can be omitted.
424.Pp
425A
426.Vt agentx_region
427indicates a region inside the object-tree for which get- and set-requests will
428be queried.
429If the OID has already been claimed by another subagent it will try to claim it
430on a lower priority.
431The
432.Fa timeout
433parameter overrules its
434.Vt agentx_session
435counterpart.
436.Pp
437For objects in a table one or more
438.Ft agentx_index
439elements must be supplied.
440.Fn agentx_index_integer_new ,
441.Fn agentx_index_integer_any
442and
443.Fn agentx_index_integer_value
444register an integer index at the agentx master.
445Of these
446.Fn agentx_index_integer_new
447registers a new, previously unused, index;
448.Fn agentx_index_integer_any
449registers the first available index;
450and
451.Fn agentx_index_integer_value
452tries to register a specific value.
453If the registration of an index fails an error will be logged and all objects
454using it will remain disabled.
455The OID where the index should be registered is documented by the MIB.
456These registered indices are usually used for tables where multiple subagents
457are registered.
458.Pp
459For dynamic indices the agentx_index_*_dynamic functions can be used, based
460on the data type of the object.
461The data type should match the data type in the MIB at the
462.Fa oid
463object.
464Indices of data type string or oid with a fixed length should be created via
465.Fn agentx_index_nstring_dynamic
466and
467.Fn agentx_index_noid_dynamic
468respectively.
469.Pp
470.Vt agentx_object
471is an object as described in the MIB.
472For scalar objects
473.Pq without indices
474the final zero must be omitted.
475For table entries a list of 1 or more indices must be added via
476.Fa index
477and
478.Fa indexlen .
479The list of indices must match the INDEX list on the ENTRY object in the MIB.
480The total length of the OID, including indices, can't be more than
481.Dv AGENTX_OID_MAX_LEN
482and indexlen can't be more than
483.Dv AGENTX_OID_INDEX_MAX_LEN .
484If
485.Fa implied
486is set the final index must be of type OID or string and will omit the leading
487length indicator.
488This value must only be set if specified in the MIB.
489.Fn getcb
490will be called for each varbind in a GET, GETNEXT or GETBULK request that
491matches the object.
492.Ss HANDLING GET REQUESTS
493A call to
494.Fn getcb
495must eventually result in a call to one of the following functions:
496.Bl -tag -width agentx_varbind_counter32()
497.It Fn agentx_varbind_integer
498Set the return value to an int32_t value.
499.It Fn agentx_varbind_string
500A C string wrapper around
501.Fn agentx_varbind_nstring .
502.It Fn agentx_varbind_nstring
503Set the return value to an octetstring.
504.It Fn agentx_varbind_printf
505A printf wrapper around
506.Fn agentx_varbind_nstring .
507.It Fn agentx_varbind_null
508Set the return value to null.
509.It Fn agentx_varbind_oid
510Set the return value to an OID value.
511.It Fn agentx_varbind_object
512An agentx_object wrapper around
513.Fn agentx_varbind_oid .
514.It Fn agentx_varbind_index
515An agentx_index wrapper around
516.Fn agentx_varbind_oid .
517.It Fn agentx_varbind_ipaddress
518Set the return value to ipaddress.
519.It Fn agentx_varbind_counter32
520Set the return value to an uint32_t of type counter32.
521.It Fn agentx_varbind_gauge32
522Set the return value to an uint32_t of type gauge32.
523.It Fn agentx_varbind_unsigned32
524A wrapper around agentx_varbind_gauge32.
525.It Fn agentx_varbind_timeticks
526Set the return value to an uint32_t of type timeticks.
527.It Fn agentx_varbind_opaque
528Set the return value to an opaque value.
529.It Fn agentx_varbind_counter64
530Set the return value to an uint64_t of type counter64.
531.It Fn agentx_varbind_notfound
532When the request is of type GET return a nosuchinstance error.
533When the request is of type GETNEXT or GETBULK return an endofmibview error.
534On endofmibview the next object is queried.
535This function can only be called on objects that contain one or more *_dynamic
536indices.
537.It Fn agentx_varbind_error
538Returns a GENERR error to the client.
539.El
540.Pp
541For objects containing *_dynamic indices the following support functions are to
542be used:
543.Bl -tag -width Ds
544.It Fn agentx_varbind_request
545Returns whether the request is of type GET, GETNEXT or GETNEXTINCLUSIVE.
546.It Fn agentx_varbind_get_index_integer
547Retrieve a single int32_t index value.
548.It Fn agentx_varbind_get_index_string
549Retrieve an octetstring index value.
550.Fa slen
551is the length of the string and
552.Fa implied
553indicates if the next value for this index should be length sorted before
554alphabetically sorted.
555.It Fn agentx_varbind_get_index_oid
556Retrieve an oid index value.
557.Fa oidlen
558is the length of the oid and
559.Fa implied
560indicates if the next value for this index should be length sorted before
561alphabetically sorted.
562.It Fn agentx_varbind_get_index_ipaddress
563Retrieve an ipaddress index value.
564.It Fn agentx_varbind_set_index_integer
565Sets a single int32_t index value.
566.It Fn agentx_varbind_set_index_string
567A C string wrapper around
568.Fn agentx_varbind_set_index_nstring .
569.It Fn agentx_varbind_set_index_nstring
570Set an octetstring index value.
571.It Fn agentx_varbind_set_index_oid
572Set an oid index value.
573.It Fn agentx_varbind_set_index_object
574A agentx_object wrapper around
575.Fn agentx_varbind_set_index_oid .
576.It Fn agentx_varbind_set_index_ipaddress
577Set an ipaddress index value.
578.El
579.Pp
580For these functions
581.Fa sai
582must be part of the object the request is performed on.
583The function type must also match the data type of
584.Fa sai .
585.Pp
586Other functions that can retrieve information from the agentx context are:
587.Bl -tag -width Ds
588.It Fn agentx_context_object_find
589Find an agentx_object created inside agentx_context
590.Fa sac
591based on
592.Fa oid
593and
594.Fa oidlen .
595If
596.Fa active
597is set the object must be reachable from the agentx master, else NULL is
598returned.
599If
600.Fa oid
601can be an instance, find its parent object.
602.It Fn agentx_context_object_nfind
603Find the next agentx_object created inside agentx_context
604.Fa sac
605based on
606.Fa oid
607and
608.Fa oidlen .
609If
610.Fa active
611is set the object must be reachable from the agentx master, else NULL is
612returned.
613If
614.Fa inclusive
615is set the object returned may also exactly match
616.Fa oid .
617.It Fn agentx_context_uptime
618Returns the sysuptime in seconds for
619.Fa sac
620in timeticks.
621.El
622.Sh SEE ALSO
623.Xr snmp 1 ,
624.Xr snmpd 8
625.Sh STANDARDS
626.Rs
627.%A M. Daniele
628.%A B. Wijnen
629.%A M. Ellison, Ed.
630.%A D. Francisco, Ed.
631.%D January 2000
632.%R RFC 2741
633.%T Agent Extensibility (AgentX) Protocol Version 1
634.Re
635.Pp
636.Rs
637.%A L. Heintz
638.%A S. Gudur
639.%A M. Ellison, Ed.
640.%D January 2000
641.%R RFC 2742
642.%T Definitions of Managed Objects for Extensible SNMP Agents
643.Re
644.Sh HISTORY
645The
646.Nm agentx
647API first appeared in
648.Ox 6.9 .
649.Sh AUTHORS
650.An Martijn van Duren Aq Mt martijn@openbsd.org
651