PageRenderTime 42ms CodeModel.GetById 30ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bsnmp/snmpd/snmpmod.3

https://bitbucket.org/freebsd/freebsd-head/
Unknown | 1184 lines | 1182 code | 2 blank | 0 comment | 0 complexity | 9813cb9d369a060b7534051beeb470d0 MD5 | raw file
   1.\"
   2.\" Copyright (c) 2004-2005
   3.\"	Hartmut Brandt.
   4.\"	All rights reserved.
   5.\" Copyright (c) 2001-2003
   6.\"	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
   7.\"	All rights reserved.
   8.\"
   9.\" Author: Harti Brandt <harti@FreeBSD.org>
  10.\" 
  11.\" Redistribution and use in source and binary forms, with or without
  12.\" modification, are permitted provided that the following conditions
  13.\" are met:
  14.\" 1. Redistributions of source code must retain the above copyright
  15.\"    notice, this list of conditions and the following disclaimer.
  16.\" 2. Redistributions in binary form must reproduce the above copyright
  17.\"    notice, this list of conditions and the following disclaimer in the
  18.\"    documentation and/or other materials provided with the distribution.
  19.\" 
  20.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.\" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
  24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30.\" SUCH DAMAGE.
  31.\"
  32.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
  33.\"
  34.Dd December 19, 2010
  35.Dt SNMPMOD 3
  36.Os
  37.Sh NAME
  38.Nm INSERT_OBJECT_OID_LINK_INDEX ,
  39.Nm INSERT_OBJECT_INT_LINK_INDEX ,
  40.Nm FIND_OBJECT_OID_LINK_INDEX ,
  41.Nm NEXT_OBJECT_OID_LINK_INDEX ,
  42.Nm FIND_OBJECT_INT_LINK_INDEX ,
  43.Nm NEXT_OBJECT_INT_LINK_INDEX ,
  44.Nm INSERT_OBJECT_OID_LINK ,
  45.Nm INSERT_OBJECT_INT_LINK ,
  46.Nm FIND_OBJECT_OID_LINK ,
  47.Nm NEXT_OBJECT_OID_LINK ,
  48.Nm FIND_OBJECT_INT_LINK ,
  49.Nm NEXT_OBJECT_INT_LINK ,
  50.Nm INSERT_OBJECT_OID ,
  51.Nm INSERT_OBJECT_INT ,
  52.Nm FIND_OBJECT_OID ,
  53.Nm FIND_OBJECT_INT ,
  54.Nm NEXT_OBJECT_OID ,
  55.Nm NEXT_OBJECT_INT ,
  56.Nm this_tick ,
  57.Nm start_tick ,
  58.Nm get_ticks ,
  59.Nm systemg ,
  60.Nm comm_define ,
  61.Nm community ,
  62.Nm oid_zeroDotZero ,
  63.Nm oid_usmUnknownEngineIDs ,
  64.Nm oid_usmNotInTimeWindows ,
  65.Nm reqid_allocate ,
  66.Nm reqid_next ,
  67.Nm reqid_base ,
  68.Nm reqid_istype ,
  69.Nm reqid_type ,
  70.Nm timer_start ,
  71.Nm timer_start_repeat ,
  72.Nm timer_stop ,
  73.Nm fd_select ,
  74.Nm fd_deselect ,
  75.Nm fd_suspend ,
  76.Nm fd_resume ,
  77.Nm or_register ,
  78.Nm or_unregister ,
  79.Nm buf_alloc ,
  80.Nm buf_size ,
  81.Nm snmp_input_start ,
  82.Nm snmp_input_finish ,
  83.Nm snmp_output ,
  84.Nm snmp_send_port ,
  85.Nm snmp_send_trap ,
  86.Nm snmp_pdu_auth_access
  87.Nm string_save ,
  88.Nm string_commit ,
  89.Nm string_rollback ,
  90.Nm string_get ,
  91.Nm string_get_max ,
  92.Nm string_free ,
  93.Nm ip_save ,
  94.Nm ip_rollback ,
  95.Nm ip_commit ,
  96.Nm ip_get ,
  97.Nm oid_save ,
  98.Nm oid_rollback ,
  99.Nm oid_commit ,
 100.Nm oid_get ,
 101.Nm index_decode ,
 102.Nm index_compare ,
 103.Nm index_compare_off ,
 104.Nm index_append ,
 105.Nm index_append_off,
 106.Nm snmpd_usmstats,
 107.Nm bsnmpd_get_usm_stats,
 108.Nm bsnmpd_reset_usm_stats,
 109.Nm usm_first_user,
 110.Nm usm_next_user,
 111.Nm usm_find_user,
 112.Nm usm_new_user,
 113.Nm usm_delete_user,
 114.Nm usm_flush_users,
 115.Nm usm_user
 116.Nm snmpd_target_stat
 117.Nm bsnmpd_get_target_stats
 118.Nm target_first_address
 119.Nm target_next_address
 120.Nm target_new_address
 121.Nm target_activate_address
 122.Nm target_delete_address
 123.Nm target_first_param
 124.Nm target_next_param
 125.Nm target_new_param
 126.Nm target_delete_param
 127.Nm target_first_notify
 128.Nm target_next_notify
 129.Nm target_new_notify
 130.Nm target_delete_notify
 131.Nm target_flush_all
 132.Nm target_address
 133.Nm target_param
 134.Nm target_notify
 135.Nd "SNMP daemon loadable module interface"
 136.Sh LIBRARY
 137Begemot SNMP library
 138.Pq libbsnmp, -lbsnmp
 139.Sh SYNOPSIS
 140.In bsnmp/snmpmod.h
 141.Fn INSERT_OBJECT_OID_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
 142.Fn INSERT_OBJECT_INT_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
 143.Fn FIND_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
 144.Fn FIND_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
 145.Fn NEXT_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
 146.Fn NEXT_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
 147.Fn INSERT_OBJECT_OID_LINK "PTR" "LIST" "LINK"
 148.Fn INSERT_OBJECT_INT_LINK "PTR" "LIST" "LINK"
 149.Fn FIND_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
 150.Fn FIND_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
 151.Fn NEXT_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
 152.Fn NEXT_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
 153.Fn INSERT_OBJECT_OID "PTR" "LIST"
 154.Fn INSERT_OBJECT_INT "PTR" "LIST"
 155.Fn FIND_OBJECT_OID "LIST" "OID" "SUB"
 156.Fn FIND_OBJECT_INT "LIST" "OID" "SUB"
 157.Fn NEXT_OBJECT_OID "LIST" "OID" "SUB"
 158.Fn NEXT_OBJECT_INT "LIST" "OID" "SUB"
 159.Vt extern uint64_t this_tick ;
 160.Vt extern uint64_t start_tick ;
 161.Ft uint64_t
 162.Fn get_ticks "void"
 163.Vt extern struct systemg systemg ;
 164.Ft u_int
 165.Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str"
 166.Ft const char *
 167.Fn comm_string "u_int comm"
 168.Vt extern u_int community ;
 169.Vt extern const struct asn_oid oid_zeroDotZero ;
 170.Ft u_int
 171.Fn reqid_allocate "int size" "struct lmodule *mod"
 172.Ft int32_t
 173.Fn reqid_next "u_int type"
 174.Ft int32_t
 175.Fn reqid_base "u_int type"
 176.Ft int
 177.Fn reqid_istype "int32_t reqid" "u_int type"
 178.Ft u_int
 179.Fn reqid_type "int32_t reqid"
 180.Ft void *
 181.Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
 182.Ft void *
 183.Fn timer_start_repeat "u_int ticks" "u_int repeat_ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
 184.Ft void
 185.Fn timer_stop "void *timer_id"
 186.Ft void *
 187.Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod"
 188.Ft void
 189.Fn fd_deselect "void *fd_id"
 190.Ft void
 191.Fn fd_suspend "void *fd_id"
 192.Ft int
 193.Fn fd_resume "void *fd_id"
 194.Ft u_int
 195.Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod"
 196.Ft void
 197.Fn or_unregister "u_int or_id"
 198.Ft void *
 199.Fn buf_alloc "int tx"
 200.Ft size_t
 201.Fn buf_size "int tx"
 202.Ft enum snmpd_input_err
 203.Fo snmp_input_start
 204.Fa "const u_char *buf" "size_t len" "const char *source"
 205.Fa "struct snmp_pdu *pdu" "int32_t *ip" "size_t *pdulen"
 206.Fc
 207.Ft enum snmpd_input_err
 208.Fo snmp_input_finish
 209.Fa "struct snmp_pdu *pdu" "const u_char *rcvbuf"
 210.Fa "size_t rcvlen" "u_char *sndbuf" "size_t *sndlen" "const char *source"
 211.Fa "enum snmpd_input_err ierr" "int32_t ip" "void *data"
 212.Fc
 213.Ft void
 214.Fo snmp_output
 215.Fa "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen"
 216.Fa "const char *dest"
 217.Fc
 218.Ft void
 219.Fo snmp_send_port
 220.Fa "void *trans" "const struct asn_oid *port"
 221.Fa "struct snmp_pdu *pdu" "const struct sockaddr *addr" "socklen_t addrlen"
 222.Fc
 223.Ft void
 224.Fn snmp_send_trap "const struct asn_oid *oid" "..."
 225.Ft enum snmp_code
 226.Fn snmp_pdu_auth_access "struct snmp_pdu *pdu" "int32_t *ip"
 227.Ft int
 228.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
 229.Ft void
 230.Fn string_commit "struct snmp_context *ctx"
 231.Ft void
 232.Fn string_rollback "struct snmp_context *ctx" "u_char **strp"
 233.Ft int
 234.Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len"
 235.Ft int
 236.Fn string_get_max "struct snmp_value *val" "const u_char *str" "ssize_t len" "size_t maxlen"
 237.Ft void
 238.Fn string_free "struct snmp_context *ctx"
 239.Ft int
 240.Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa"
 241.Ft void
 242.Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa"
 243.Ft void
 244.Fn ip_commit "struct snmp_context *ctx"
 245.Ft int
 246.Fn ip_get "struct snmp_value *val" "u_char *ipa"
 247.Ft int
 248.Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid"
 249.Ft void
 250.Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid"
 251.Ft void
 252.Fn oid_commit "struct snmp_context *ctx"
 253.Ft int
 254.Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid"
 255.Ft int
 256.Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..."
 257.Ft int
 258.Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2"
 259.Ft int
 260.Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off"
 261.Ft void
 262.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
 263.Ft void
 264.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
 265.Vt extern struct snmpd_usmstat snmpd_usmstats ;
 266.Ft struct snmpd_usmstat *
 267.Fn bsnmpd_get_usm_stats "void"
 268.Ft void
 269.Fn bsnmpd_reset_usm_stats "void"
 270.Ft struct usm_user *
 271.Fn usm_first_user "void"
 272.Ft struct usm_user *
 273.Fn usm_next_user "struct usm_user *uuser"
 274.Ft struct usm_user *
 275.Fn usm_find_user "uint8_t *engine" "uint32_t elen" "char *uname"
 276.Ft struct usm_user *
 277.Fn usm_new_user "uint8_t *engine" "uint32_t elen" "char *uname"
 278.Ft void
 279.Fn usm_delete_user "struct usm_user *"
 280.Ft void
 281.Fn usm_flush_users "void"
 282.Vt extern struct usm_user *usm_user;
 283.Ft struct snmpd_target_stats *
 284.Fn bsnmpd_get_target_stats "void"
 285.Ft struct target_address *
 286.Fn target_first_address "void"
 287.Ft struct target_address *
 288.Fn target_next_address "struct target_address *"
 289.Ft struct target_address *
 290.Fn target_new_address "char *"
 291.Ft int
 292.Fn target_activate_address "struct target_address *"
 293.Ft int
 294.Fn target_delete_address "struct target_address *"
 295.Ft struct target_param *
 296.Fn target_first_param "void"
 297.Ft struct target_param *
 298.Fn target_next_param "struct target_param *"
 299.Ft struct target_param *
 300.Fn target_new_param "char *"
 301.Ft int
 302.Fn target_delete_param "struct target_param *"
 303.Ft struct target_notify *
 304.Fn target_first_notify "void"
 305.Ft struct target_notify *
 306.Fn target_next_notify "struct target_notify *"
 307.Ft struct target_notify *
 308.Fn target_new_notify "char *"
 309.Ft int
 310.Fn target_delete_notify "struct target_notify *"
 311.Ft void
 312.Fn target_flush_all "void"
 313.Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
 314.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
 315.Sh DESCRIPTION
 316The
 317.Xr bsnmpd 1
 318SNMP daemon implements a minimal MIB which consists of the system group, part
 319of the SNMP MIB, a private configuration MIB, a trap destination table, a
 320UDP port table, a community table, a module table, a statistics group and
 321a debugging group.
 322All other MIBs are support through loadable modules.
 323This allows
 324.Xr bsnmpd 1
 325to use for task, that are not the classical SNMP task.
 326.Ss MODULE LOADING AND UNLOADING
 327Modules are loaded by writing to the module table.
 328This table is indexed by a string, that identifies the module to the daemon.
 329This identifier is used
 330to select the correct configuration section from the configuration files and
 331to identify resources allocated to this module.
 332A row in the module table is
 333created by writing a string of non-zero length to the
 334.Va begemotSnmpdModulePath
 335column.
 336This string must be the complete path to the file containing the module.
 337A module can be unloaded by writing a zero length string to the path column
 338of an existing row.
 339.Pp
 340Modules may depend on each other an hence must be loaded in the correct order.
 341The dependencies are listed in the corresponding manual pages.
 342.Pp
 343Upon loading a module the SNMP daemon expects the module file to a export
 344a global symbol
 345.Va config .
 346This symbol should be a variable of type
 347.Vt struct snmp_module :
 348.Bd -literal -offset indent
 349typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, void *,
 350    const struct asn_oid *, const struct sockaddr *, socklen_t,
 351    enum snmpd_input_err, int32_t);
 352
 353
 354struct snmp_module {
 355	const char *comment;
 356	int (*init)(struct lmodule *, int argc, char *argv[]);
 357	int (*fini)(void);
 358	void (*idle)(void);
 359	void (*dump)(void);
 360	void (*config)(void);
 361	void (*start)(void);
 362	proxy_err_f proxy;
 363	const struct snmp_node *tree;
 364	u_int tree_size;
 365	void (*loading)(const struct lmodule *, int);
 366};
 367.Ed
 368.Pp
 369This structure must be statically initialized and its fields have the
 370following functions:
 371.Bl -tag -width ".It Va tree_size"
 372.It Va comment
 373This is a string that will be visible in the module table.
 374It should give some hint about the function of this module.
 375.It Va init
 376This function is called upon loading the module.
 377The module pointer should
 378be stored by the module because it is needed in other calls and the
 379argument vector will contain the arguments to this module from the daemons
 380command line.
 381This function should return 0 if everything is ok or an UNIX error code (see
 382.Xr errno 3 ) .
 383Once the function returns 0, the
 384.Va fini
 385function is called when the module is unloaded.
 386.It Va fini
 387The module is unloaded.
 388This gives the module a chance to free resources that
 389are not automatically freed.
 390Be sure to free all memory, because daemons tend to run very long.
 391This function pointer may be
 392.Li NULL
 393if it is not needed.
 394.It Va idle
 395If this function pointer is not
 396.Li NULL ,
 397the function pointed to by it is called whenever the daemon is going
 398to wait for an event.
 399Try to avoid using this feature.
 400.It Va dump
 401Whenever the daemon receives a
 402.Li SIGUSR1
 403it dumps it internal state via
 404.Xr syslog 3 .
 405If the
 406.Va dump
 407field is not
 408.Li NULL
 409it is called by the daemon to dump the state of the module.
 410.It Va config
 411Whenever the daemon receives a
 412.Li SIGHUP
 413signal it re-reads its configuration file.
 414If the
 415.Va config
 416field is not
 417.Li NULL
 418it is called after reading the configuration file to give the module a chance
 419to adapt to the new configuration.
 420.It Va start
 421If not
 422.Li NULL
 423this function is called after successful loading and initializing the module
 424to start its actual operation.
 425.It Va proxy
 426If the daemon receives a PDU and that PDU has a community string whose
 427community was registered by this module and
 428.Va proxy
 429is not
 430.Li NULL
 431than this function is called to handle the PDU.
 432.It Va tree
 433This is a pointer to the node array for the MIB tree implemented by this module.
 434.It Va tree_size
 435This is the number of nodes in
 436.Va tree .
 437.It Va loading
 438If this pointer is not
 439.Li NULL
 440it is called whenever another module was loaded or unloaded.
 441It gets a
 442pointer to that module and a flag that is 0 for unloading and 1 for loading.
 443.El
 444.Pp
 445When everything is ok, the daemon merges the module's MIB tree into its current
 446global tree, calls the modules
 447.Fn init
 448function.
 449If this function returns an error, the modules MIB tree is removed from
 450the global one and the module is unloaded.
 451If initialization is successful, the modules
 452.Fn start
 453function is called.
 454After it returns the
 455.Fn loaded
 456functions of all modules (including the loaded one) are called.
 457.Pp
 458When the module is unloaded, its MIB tree is removed from the global one,
 459the communities, request id ranges, running timers and selected file
 460descriptors are released, the
 461.Fn fini
 462function is called, the module file is unloaded and the
 463.Fn loaded
 464functions of all other modules are called.
 465.Ss IMPLEMENTING TABLES
 466There are a number of macros designed to help implementing SNMP tables.
 467A problem while implementing a table is the support for the GETNEXT operator.
 468The GETNEXT operation has to find out whether, given an arbitrary OID, the
 469lessest table row, that has an OID higher than the given OID.
 470The easiest way
 471to do this is to keep the table as an ordered list of structures each one
 472of which contains an OID that is the index of the table row.
 473This allows easy removal, insertion and search.
 474.Pp
 475The helper macros assume, that the table is organized as a TAILQ (see
 476.Xr queue 3
 477and each structure contains a
 478.Vt struct asn_oid
 479that is used as index.
 480For simple tables with only a integer or unsigned index, an alternate form
 481of the macros is available, that presume the existence of an integer or
 482unsigned field as index field.
 483.Pp
 484The macros have name of the form
 485.Bd -literal -offset indent
 486{INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
 487.Ed
 488.Pp
 489The
 490.Fn INSERT_*
 491macros are used in the SET operation to insert a new table row into the table.
 492The
 493.Fn FIND_*
 494macros are used in the GET operation to find a specific row in the table.
 495The
 496.Fn NEXT_*
 497macros are used in the GETNEXT operation to find the next row in the table.
 498The last two macros return a pointer to the row structure if a row is found,
 499.Li NULL
 500otherwise.
 501The macros
 502.Fn *_OBJECT_OID_*
 503assume the existence of a
 504.Vt struct asn_oid
 505that is used as index, the macros
 506.Fn *_OBJECT_INT_*
 507assume the existence of an unsigned integer field that is used as index.
 508.Pp
 509The macros
 510.Fn *_INDEX
 511allow the explicit naming of the index field in the parameter
 512.Fa INDEX ,
 513whereas the other macros assume that this field is named
 514.Va index .
 515The macros
 516.Fn *_LINK_*
 517allow the explicit naming of the link field of the tail queues, the others
 518assume that the link field is named
 519.Va link .
 520Explicitly naming the link field may be necessary if the same structures
 521are held in two or more different tables.
 522.Pp
 523The arguments to the macros are as follows:
 524.Bl -tag -width "INDEX"
 525.It Fa PTR
 526A pointer to the new structure to be inserted into the table.
 527.It Fa LIST
 528A pointer to the tail queue head.
 529.It Fa LINK
 530The name of the link field in the row structure.
 531.It Fa INDEX
 532The name of the index field in the row structure.
 533.It Fa OID
 534Must point to the
 535.Va var
 536field of the
 537.Fa value
 538argument to the node operation callback.
 539This is the OID to search for.
 540.It Fa SUB
 541This is the index of the start of the table index in the OID pointed to
 542by
 543.Fa OID .
 544This is usually the same as the
 545.Fa sub
 546argument to the node operation callback.
 547.El
 548.Ss DAEMON TIMESTAMPS
 549The variable
 550.Va this_tick
 551contains the tick (there are 100 SNMP ticks in a second) when
 552the current PDU processing was started.
 553The variable
 554.Va start_tick
 555contains the tick when the daemon was started.
 556The function
 557.Fn get_ticks
 558returns the current tick.
 559The number of ticks since the daemon was started
 560is
 561.Bd -literal -offset indent
 562get_ticks() - start_tick
 563.Ed
 564.Ss THE SYSTEM GROUP
 565The scalar fields of the system group are held in the global variable
 566.Va systemg :
 567.Bd -literal -offset indent
 568struct systemg {
 569	u_char		*descr;
 570	struct asn_oid	object_id;
 571	u_char		*contact;
 572	u_char		*name;
 573	u_char		*location;
 574	uint32_t	services;
 575	uint32_t	or_last_change;
 576};
 577.Ed
 578.Ss COMMUNITIES
 579The SNMP daemon implements a community table.
 580On recipte of a request message
 581the community string in that message is compared to each of the community
 582strings in that table, if a match is found, the global variable
 583.Va community
 584is set to the community identifier for that community.
 585Community identifiers are unsigned integers.
 586For the three standard communities there are three constants defined:
 587.Bd -literal -offset indent
 588#define COMM_INITIALIZE	0
 589#define COMM_READ	1
 590#define COMM_WRITE	2
 591.Ed
 592.Pp
 593.Va community
 594is set to
 595.Li COMM_INITIALIZE
 596while the assignments in the configuration file are processed.
 597To
 598.Li COMM_READ
 599or
 600.Li COMM_WRITE
 601when the community strings for the read-write or read-only community are found
 602in the incoming PDU.
 603.Pp
 604Modules can define additional communities.
 605This may be necessary to provide
 606transport proxying (a PDU received on one communication link is proxied to
 607another link) or to implement non-UDP access points to SNMP.
 608A new community is defined with the function
 609.Fn comm_define .
 610It takes the following parameters:
 611.Bl -tag -width ".It Fa descr"
 612.It Fa priv
 613This is an integer identifying the community to the module.
 614Each module has its own namespace with regard to this parameter.
 615The community table is indexed with the module name and this identifier.
 616.It Fa descr
 617This is a string providing a human readable description of the community.
 618It is visible in the community table.
 619.It Fa mod
 620This is the module defining the community.
 621.It Fa str
 622This is the initial community string.
 623.El
 624.Pp
 625The function returns a globally unique community identifier.
 626If a SNMPv1 or SNMPv2 PDU is
 627received who's community string matches, this identifier is set into the global
 628.Va community .
 629.Pp
 630The function
 631.Fn comm_string
 632returns the current community string for the given community.
 633.Pp
 634All communities defined by a module are automatically released when the module
 635is unloaded.
 636.Ss THE USER-BASED SECURITY GROUP
 637The scalar statistics of the USM group are held in the global variable
 638.Va snmpd_usmstats :
 639.Bd -literal -offset indent
 640struct snmpd_usmstat {
 641	uint32_t	unsupported_seclevels;
 642	uint32_t	not_in_time_windows;
 643	uint32_t	unknown_users;
 644	uint32_t	unknown_engine_ids;
 645	uint32_t	wrong_digests;
 646	uint32_t	decrypt_errors;
 647};
 648.Ed
 649.Fn bsnmpd_get_usm_stats
 650returns a pointer to the global structure containing the statistics.
 651.Fn bsnmpd_reset_usm_stats
 652clears the statistics of the USM group.
 653.Pp
 654A global list of configured USM users is maintained by the daemon.
 655.Bd -literal -offset indent
 656struct usm_user {
 657	struct snmp_user		suser;
 658	uint8_t				user_engine_id[SNMP_ENGINE_ID_SIZ];
 659	uint32_t			user_engine_len;
 660	char				user_public[SNMP_ADM_STR32_SIZ];
 661	uint32_t			user_public_len;
 662	int32_t				status;
 663	int32_t				type;
 664	SLIST_ENTRY(usm_user)		up;
 665};
 666.Ed
 667This structure represents an USM user. The daemon only responds to SNMPv3 PDUs
 668with user credentials matching an USM user entry in its global list.
 669If a SNMPv3 PDU is received, whose security model is USM, the global
 670.Va usm_user
 671is set to point at the user entry that matches the credentials contained in
 672the PDU.
 673However, the daemon does not create or remove USM users, it gives an interface
 674to external loadable module(s) to manage the list.
 675.Fn usm_new_user
 676adds an user entry in the list, and
 677.Fn usm_delete_user
 678deletes an existing entry from the list.
 679.Fn usm_flush_users
 680is used to remove all configured USM users.
 681.Fn usm_first_user
 682will return the first user in the list, or
 683.Li NULL
 684if the list is empty.
 685.Fn usm_next_user
 686will return  the next user of a given entry if one exists, or
 687.Li NULL .
 688The list is sorted according to the USM user name and Engine ID.
 689.Fn usm_find_user
 690returns the USM user entry matching the given
 691.Fa engine
 692and
 693.Fa uname
 694or
 695.Li NULL
 696if an user with the specified name and engine id is not present in the list.
 697.Ss THE MANAGEMENT TARGET GROUP
 698The Management Target group holds target address information used when sending
 699SNMPv3 notifications.
 700.Pp
 701The scalar statistics of the Management Target group are held in the global
 702variable
 703.Va snmpd_target_stats :
 704.Bd -literal -offset indent
 705struct snmpd_target_stats {
 706	uint32_t			unavail_contexts;
 707	uint32_t			unknown_contexts;
 708};
 709.Ed
 710.Fn bsnmpd_get_target_stats
 711returns a pointer to the global structure containing the statistics.
 712.Pp
 713Three global lists of configured management target addresses, parameters and
 714notifications respectively are maintained by the daemon.
 715.Bd -literal -offset indent
 716struct target_address {
 717	char				name[SNMP_ADM_STR32_SIZ];
 718	uint8_t				address[SNMP_UDP_ADDR_SIZ];
 719	int32_t				timeout;
 720	int32_t				retry;
 721	char				taglist[SNMP_TAG_SIZ];
 722	char				paramname[SNMP_ADM_STR32_SIZ];
 723	int32_t				type;
 724	int32_t				socket;
 725	int32_t				status;
 726	SLIST_ENTRY(target_address)	ta;
 727};
 728.Ed
 729This structure represents a SNMPv3 Management Target address. Each time a SNMP
 730TRAP is send the daemon will send the Trap to all active Management Target
 731addresses in its global list.
 732.Bd -literal -offset indent
 733struct target_param {
 734	char				name[SNMP_ADM_STR32_SIZ];
 735	int32_t				mpmodel;
 736	int32_t				sec_model;
 737	char				secname[SNMP_ADM_STR32_SIZ];
 738	enum snmp_usm_level		sec_level;
 739	int32_t				type;
 740	int32_t				status;
 741	SLIST_ENTRY(target_param)	tp;
 742};
 743.Ed
 744This structure represents the information used to generate SNMP messages to the
 745associated SNMPv3 Management Target addresses.
 746.Bd -literal -offset indent
 747struct target_notify {
 748	char				name[SNMP_ADM_STR32_SIZ];
 749	char				taglist[SNMP_TAG_SIZ];
 750	int32_t				notify_type;
 751	int32_t				type;
 752	int32_t				status;
 753	SLIST_ENTRY(target_notify)	tn;
 754};
 755.Ed
 756This structure represents Notification Tag entries - SNMP notifications are sent
 757to the Target address for each entry in the Management Target Address list that
 758has a tag matching the specified tag in this structure.
 759.Pp
 760The daemon does not create or remove entries in the Management Target group
 761lists, it gives an interface to external loadable module(s) to manage the lists.
 762.Fn target_new_address
 763adds a target address entry, and
 764.Fn target_delete_address
 765deletes an existing entry from the target address list.
 766.Fn target_activate_address
 767creates a socket associated with the target address entry so that SNMP
 768notifications may actually be send to that target address.
 769.Fn target_first_address
 770will return a pointer to the first target address entry in the list, while
 771.Fn target_next_address
 772will return a pointer to the next target address of a given entry if one exists.
 773.Fn target_new_param
 774adds a target parameters' entry, and
 775.Fn target_delete_param
 776deletes an existing entry from the target parameters list.
 777.Fn target_first_param
 778will return a pointer to the first target parameters' entry in the list, while
 779.Fn target_next_param
 780will return a pointer to the next target parameters of a given entry if one
 781exists.
 782.Fn target_new_notify
 783adds a notification target entry, and
 784.Fn target_delete_notify
 785deletes an existing entry from the notification target list.
 786.Fn target_first_notify
 787will return a pointer to the first notification target entry in the list, while
 788.Fn target_next_notify
 789will return a pointer to the next notification target of a given entry if one
 790exists.
 791.Fn target_flush_all
 792is used to remove all configured data from the three global Management Target
 793Group lists.
 794.Ss WELL KNOWN OIDS
 795The global variable
 796.Va oid_zeroDotZero
 797contains the OID 0.0.
 798The global variables
 799.Va oid_usmUnknownEngineIDs
 800.Va oid_usmNotInTimeWindows
 801contains the OIDs 1.3.6.1.6.3.15.1.1.4.0 and  1.3.6.1.6.3.15.1.1.2.0 used
 802in the SNMPv3 USM Engine Discovery.
 803.Ss REQUEST ID RANGES
 804For modules that implement SNMP client functions besides SNMP agent functions
 805it may be necessary to identify SNMP requests by their identifier to allow
 806easier routing of responses to the correct sub-system.
 807Request id ranges
 808provide a way to acquire globally non-overlapping sub-ranges of the entire
 80931-bit id range.
 810.Pp
 811A request id range is allocated with
 812.Fn reqid_allocate .
 813The arguments are: the size of the range and the module allocating the range.
 814For example, the call
 815.Bd -literal -offset indent
 816id = reqid_allocate(1000, module);
 817.Ed
 818.Pp
 819allocates a range of 1000 request ids.
 820The function returns the request
 821id range identifier or 0 if there is not enough identifier space.
 822The function
 823.Fn reqid_base
 824returns the lowest request id in the given range.
 825.Pp
 826Request id are allocated starting at the lowest one linear throughout the range.
 827If the client application may have a lot of outstanding request the range
 828must be large enough so that an id is not reused until it is really expired.
 829.Fn reqid_next
 830returns the sequentially next id in the range.
 831.Pp
 832The function
 833.Fn reqid_istype
 834checks whether the request id
 835.Fa reqid
 836is within the range identified by
 837.Fa type .
 838The function
 839.Fn reqid_type
 840returns the range identifier for the given
 841.Fa reqid
 842or 0 if the request id is in none of the ranges.
 843.Ss TIMERS
 844The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
 845The function
 846.Fn timer_start
 847arranges for the callback
 848.Fa func
 849to be called with the argument
 850.Fa uarg
 851after
 852.Fa ticks
 853SNMP ticks have expired.
 854.Fa mod
 855is the module that starts the timer.
 856These timers are one-shot, they are not restarted.
 857Repeatable timers are started with
 858.Fn timer_start_repeat
 859which takes an additional argument
 860.Fa repeat_ticks .
 861The argument
 862.Fa ticks
 863gives the number of ticks until the first execution of the callback, while
 864.Fa repeat_ticks
 865is the number of ticks between invocations of the callback.
 866Note, that currently the number of initial ticks silently may be set identical
 867to the number of ticks between callback invocations.
 868The function returns a timer identifier that can be used to stop the timer via
 869.Fn timer_stop .
 870If a module is unloaded all timers started by the module that have not expired
 871yet are stopped.
 872.Ss FILE DESCRIPTOR SUPPORT
 873A module may need to get input from socket file descriptors without blocking
 874the daemon (for example to implement alternative SNMP transports).
 875.Pp
 876The function
 877.Fn fd_select
 878causes the callback function
 879.Fa func
 880to be called with the file descriptor
 881.Fa fd
 882and the user argument
 883.Fa uarg
 884whenever the file descriptor
 885.Fa fd
 886can be read or has a close condition.
 887If the file descriptor is not in
 888non-blocking mode, it is set to non-blocking mode.
 889If the callback is not needed anymore,
 890.Fn fd_deselect
 891may be called with the value returned from
 892.Fn fd_select .
 893All file descriptors selected by a module are automatically deselected when
 894the module is unloaded.
 895.Pp
 896To temporarily suspend the file descriptor registration
 897.Fn fd_suspend
 898can be called.
 899This also causes the file descriptor to be switched back to
 900blocking mode if it was blocking prior the call to
 901.Fn fd_select .
 902This is necessary to do synchronous input on a selected socket.
 903The effect of
 904.Fn fd_suspend
 905can be undone with
 906.Fn fd_resume .
 907.Ss OBJECT RESOURCES
 908The system group contains an object resource table.
 909A module may create an entry in this table by calling
 910.Fn or_register
 911with the
 912.Fa oid
 913to be registered, a textual description in
 914.Fa str
 915and a pointer to the module
 916.Fa mod .
 917The registration can be removed with
 918.Fn or_unregister .
 919All registrations of a module are automatically removed if the module is
 920unloaded.
 921.Ss TRANSMIT AND RECEIVE BUFFERS
 922A buffer is allocated via
 923.Fn buf_alloc .
 924The argument must be 1 for transmit and 0 for receive buffers.
 925The function may return
 926.Li NULL
 927if there is no memory available.
 928The current buffersize can be obtained with
 929.Fn buf_size .
 930.Sh PROCESSING PDUS
 931For modules that need to do their own PDU processing (for example for proxying)
 932the following functions are available:
 933.Pp
 934Function
 935.Fn snmp_input_start
 936decodes the PDU, searches the community, and sets the global
 937.Va this_tick .
 938It returns one of the following error codes:
 939.Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN"
 940.It Er SNMPD_INPUT_OK
 941Everything ok, continue with processing.
 942.It Er SNMPD_INPUT_FAILED
 943The PDU could not be decoded, has a wrong version or an unknown
 944community string.
 945.It Er SNMPD_INPUT_VALBADLEN
 946A SET PDU had a value field in a binding with a wrong length field in an
 947ASN.1 header.
 948.It Er SNMPD_INPUT_VALRANGE
 949A SET PDU had a value field in a binding with a value that is out of range
 950for the given ASN.1 type.
 951.It Er SNMPD_INPUT_VALBADENC
 952A SET PDU had a value field in a binding with wrong ASN.1 encoding.
 953.It Er SNMPD_INPUT_TRUNC
 954The buffer appears to contain a valid begin of a PDU, but is too short.
 955For streaming transports this means that the caller must save what he
 956already has and trying to obtain more input and reissue this input to
 957the function.
 958For datagram transports this means that part of the
 959datagram was lost and the input should be ignored.
 960.El
 961.Pp
 962The function
 963.Fn snmp_input_finish
 964does the other half of processing: if
 965.Fn snmp_input_start
 966did not return OK, tries to construct an error response.
 967If the start was OK, it calls the correct function from
 968.Xr bsnmpagent 3
 969to execute the request and depending on the outcome constructs a response or
 970error response PDU or ignores the request PDU.
 971It returns either
 972.Er SNMPD_INPUT_OK
 973or
 974.Er SNMPD_INPUT_FAILED .
 975In the first case a response PDU was constructed and should be sent.
 976.Pp
 977The function
 978.Fn snmp_output
 979takes a PDU and encodes it.
 980.Pp
 981The function
 982.Fn snmp_send_port
 983takes a PDU, encodes it and sends it through the given port (identified by
 984the transport and the index in the port table) to the given address.
 985.Pp
 986The function
 987.Fn snmp_send_trap
 988sends a trap to all trap destinations.
 989The arguments are the
 990.Fa oid
 991identifying the trap and a NULL-terminated list of
 992.Vt struct snmp_value
 993pointers that are to be inserted into the trap binding list.
 994.Fn snmp_pdu_auth_access
 995verifies whether access to the object IDs contained in the
 996.Fa pdu
 997 should be granted or denied, according to the configured View-Based Access
 998rules.
 999.Fa ip
1000contains the index of the first varbinding to which access was denied, or 0 if
1001access to all varbindings in the PDU is granted.
1002.Ss SIMPLE ACTION SUPPORT
1003For simple scalar variables that need no dependencies a number of support
1004functions is available to handle the set, commit, rollback and get.
1005.Pp
1006The following functions are used for OCTET STRING scalars, either NUL terminated
1007or not:
1008.Bl -tag -width "XXXXXXXXX"
1009.It Fn string_save
1010should be called for SNMP_OP_SET.
1011.Fa value
1012and
1013.Fa ctx
1014are the resp\&.\& arguments to the node callback.
1015.Fa valp
1016is a pointer to the pointer that holds the current value and
1017.Fa req_size
1018should be -1 if any size of the string is acceptable or a number larger or
1019equal zero if the string must have a specific size.
1020The function saves
1021the old value in the scratch area (note, that any initial value must have
1022been allocated by
1023.Xr malloc 3 ) ,
1024allocates a new string, copies over the new value, NUL-terminates it and
1025sets the new current value.
1026.It Fn string_commit
1027simply frees the saved old value in the scratch area.
1028.It Fn string_rollback
1029frees the new value, and puts back the old one.
1030.It Fn string_get
1031is used for GET or GETNEXT.
1032The function
1033.It Fn string_get_max
1034can be used instead of
1035.Fn string_get
1036to ensure that the returned string has a certain maximum length.
1037If
1038.Fa len
1039is -1, the length is computed via
1040.Xr strlen 3
1041from the current string value.
1042If the current value is NULL,
1043a OCTET STRING of zero length is returned.
1044.It Fn string_free
1045must be called if either rollback or commit fails to free the saved old value.
1046.El
1047.Pp
1048The following functions are used to process scalars of type IP-address:
1049.Bl -tag -width "XXXXXXXXX"
1050.It Fn ip_save
1051Saves the current value in the scratch area and sets the new value from
1052.Fa valp .
1053.It Fn ip_commit
1054Does nothing.
1055.It Fn ip_rollback
1056Restores the old IP address from the scratch area.
1057.It Fn ip_get
1058Retrieves the IP current address.
1059.El
1060.Pp
1061The following functions handle OID-typed variables:
1062.Bl -tag -width "XXXXXXXXX"
1063.It Fn oid_save
1064Saves the current value in the scratch area by allocating a
1065.Vt struct asn_oid
1066with
1067.Xr malloc 3
1068and sets the new value from
1069.Fa oid .
1070.It Fn oid_commit
1071Frees the old value in the scratch area.
1072.It Fn oid_rollback
1073Restores the old OID from the scratch area and frees the old OID.
1074.It Fn oid_get
1075Retrieves the OID
1076.El
1077.Ss TABLE INDEX HANDLING
1078The following functions help in handling table indexes:
1079.Bl -tag -width "XXXXXXXXX"
1080.It Fn index_decode
1081Decodes the index part of the OID.
1082The parameter
1083.Fa oid
1084must be a pointer to the
1085.Va var
1086field of the
1087.Fa value
1088argument of the node callback.
1089The
1090.Fa sub
1091argument must be the index of the start of the index in the OID (this is
1092the
1093.Fa sub
1094argument to the node callback).
1095.Fa code
1096is the index expression (parameter
1097.Fa idx
1098to the node callback).
1099These parameters are followed by parameters depending on the syntax of the index
1100elements as follows:
1101.Bl -tag -width ".It Li OCTET STRING"
1102.It Li INTEGER
1103.Vt int32_t *
1104expected as argument.
1105.It Li COUNTER64
1106.Vt uint64_t *
1107expected as argument.
1108Note, that this syntax is illegal for indexes.
1109.It Li OCTET STRING
1110A
1111.Vt u_char **
1112and a
1113.Vt size_t *
1114expected as arguments.
1115A buffer is allocated to hold the decoded string.
1116.It Li OID
1117A
1118.Vt struct asn_oid *
1119is expected as argument.
1120.It Li IP ADDRESS
1121A
1122.Vt u_int8_t *
1123expected as argument that points to a buffer of at least four byte.
1124.It Li COUNTER, GAUGE, TIMETICKS
1125A
1126.Vt u_int32_t
1127expected.
1128.It Li NULL
1129No argument expected.
1130.El
1131.It Fn index_compare
1132compares the current variable with an OID.
1133.Fa oid1
1134and
1135.Fa sub
1136come from the node callback arguments
1137.Fa value->var
1138and
1139.Fa sub
1140resp.
1141.Fa oid2
1142is the OID to compare to.
1143The function returns -1, 0, +1 when the
1144variable is lesser, equal, higher to the given OID.
1145.Fa oid2
1146must contain only the index part of the table column.
1147.It Fn index_compare_off
1148is equivalent to
1149.Fn index_compare
1150except that it takes an additional parameter
1151.Fa off
1152that causes it to ignore the first
1153.Fa off
1154components of both indexes.
1155.It Fn index_append
1156appends OID
1157.Fa src
1158beginning at position
1159.Fa sub
1160to
1161.Fa dst .
1162.It Fn index_append_off
1163appends OID
1164.Fa src
1165beginning at position
1166.Fa off
1167to
1168.Fa dst
1169beginning at position
1170.Fa sub
1171+
1172.Fa off .
1173.El
1174.Sh SEE ALSO
1175.Xr gensnmptree 1 ,
1176.Xr bsnmpd 1 ,
1177.Xr bsnmpagent 3 ,
1178.Xr bsnmpclient 3 ,
1179.Xr bsnmplib 3
1180.Sh STANDARDS
1181This implementation conforms to the applicable IETF RFCs and ITU-T
1182recommendations.
1183.Sh AUTHORS
1184.An Hartmut Brandt Aq harti@FreeBSD.org