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