/contrib/bsnmp/lib/bsnmpagent.3

https://bitbucket.org/freebsd/freebsd-head/ · Unknown · 444 lines · 442 code · 2 blank · 0 comment · 0 complexity · fa45be81db759b23b41451af210cc081 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/lib/bsnmpagent.3,v 1.10 2005/10/04 08:46:49 brandt_h Exp $
  33. .\"
  34. .Dd October 4, 2005
  35. .Dt BSNMPAGENT 3
  36. .Os
  37. .Sh NAME
  38. .Nm bsnmpagent ,
  39. .Nm snmp_depop_t ,
  40. .Nm snmp_op_t ,
  41. .Nm tree ,
  42. .Nm tree_size ,
  43. .Nm snmp_trace ,
  44. .Nm snmp_debug ,
  45. .Nm snmp_get ,
  46. .Nm snmp_getnext ,
  47. .Nm snmp_getbulk ,
  48. .Nm snmp_set ,
  49. .Nm snmp_make_errresp ,
  50. .Nm snmp_dep_lookup ,
  51. .Nm snmp_init_context ,
  52. .Nm snmp_dep_commit ,
  53. .Nm snmp_dep_rollback ,
  54. .Nm snmp_dep_finish
  55. .Nd "SNMP agent library"
  56. .Sh LIBRARY
  57. Begemot SNMP library
  58. .Pq libbsnmp, -lbsnmp
  59. .Sh SYNOPSIS
  60. .In asn1.h
  61. .In snmp.h
  62. .In snmpagent.h
  63. .Ft typedef int
  64. .Fn (*snmp_depop_t) "struct snmp_context *ctx" "struct snmp_dependency *dep" "enum snmp_depop op"
  65. .Ft typedef int
  66. .Fn (*snmp_op_t) "struct snmp_context *ctx" "struct snmp_value *val" "u_int len" "u_int idx" "enum snmp_op op"
  67. .Vt extern struct snmp_node *tree ;
  68. .Vt extern u_int tree_size ;
  69. .Vt extern u_int snmp_trace ;
  70. .Vt extern void (*snmp_debug)(const char *fmt, ...) ;
  71. .Ft enum snmp_ret
  72. .Fn snmp_get "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
  73. .Ft enum snmp_ret
  74. .Fn snmp_getnext "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
  75. .Ft enum snmp_ret
  76. .Fn snmp_getbulk "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
  77. .Ft enum snmp_ret
  78. .Fn snmp_set "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
  79. .Ft enum snmp_ret
  80. .Fn snmp_make_errresp "const struct snmp_pdu *pdu" "struct asn_buf *req_b" "struct asn_buf *resp_b"
  81. .Ft struct snmp_dependency *
  82. .Fn snmp_dep_lookup "struct snmp_context *ctx" "const struct asn_oid *base" "const struct asn_oid *idx" "size_t alloc" "snmp_depop_t func"
  83. .Ft struct snmp_context *
  84. .Fn snmp_init_context "void"
  85. .Ft int
  86. .Fn snmp_dep_commit "struct snmp_context *ctx"
  87. .Ft int
  88. .Fn snmp_dep_rollback "struct snmp_context *ctx"
  89. .Ft void
  90. .Fn snmp_dep_finish "struct snmp_context *ctx"
  91. .Sh DESCRIPTION
  92. The SNMP library contains routines to easily build SNMP agent applications
  93. that use SNMP versions 1 or 2.
  94. Note, however, that it may be even easier to build an
  95. .Xr bsnmpd 1
  96. loadable module, that handles the new MIB (see
  97. .Xr snmpmod 3 ) .
  98. .Pp
  99. Most of the agent routines operate on a global array that the describes the
  100. complete MIB served by the agent.
  101. This array is held in the two variables:
  102. .Bd -literal -offset indent
  103. extern struct snmp_node *tree;
  104. extern u_int tree_size;
  105. .Ed
  106. .Pp
  107. The elements of the array are of type
  108. .Vt struct snmp_node :
  109. .Bd -literal -offset indent
  110. typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
  111. u_int, u_int, enum snmp_op);
  112. struct snmp_node {
  113. struct asn_oid oid;
  114. const char *name; /* name of the leaf */
  115. enum snmp_node_type type; /* type of this node */
  116. enum snmp_syntax syntax;
  117. snmp_op_t op;
  118. u_int flags;
  119. u_int32_t index; /* index data */
  120. void *data; /* application data */
  121. void *tree_data; /* application data */
  122. };
  123. .Ed
  124. .Pp
  125. The fields of this structure are described below.
  126. .Bl -tag -width "syntax"
  127. .It Va oid
  128. Base OID of the scalar or table column.
  129. .It Va name
  130. Name of this variable.
  131. .It Va type
  132. Type of this variable.
  133. One of:
  134. .Bd -literal -offset indent
  135. enum snmp_node_type {
  136. SNMP_NODE_LEAF = 1,
  137. SNMP_NODE_COLUMN
  138. };
  139. .Ed
  140. .It Va syntax
  141. The SNMP syntax of this variable.
  142. .It Va op
  143. The user supplied handler for this variable.
  144. The handler is called with the following arguments:
  145. .Bl -tag -width "ctx"
  146. .It Fa ctx
  147. A pointer to the context (see below).
  148. .Li NULL .
  149. .It Fa val
  150. The value to be set or retrieved.
  151. For GETNEXT and GETBULK operations the oid in
  152. this value is the current OID.
  153. The function (called in this case only for
  154. table rows) must find the lexically next existing OID within the same column and
  155. set the oid and value subfields accordingly.
  156. If the table column is exhausted the
  157. function must return
  158. .Li SNMP_ERR_NOSUCHNAME .
  159. For all other operations the oid in
  160. .Fa val
  161. is the oid to fetch or set.
  162. .It Fa len
  163. The length of the base oid without index.
  164. .It Fa idx
  165. For table columns this is the index expression from the node (see below).
  166. .It Fa op
  167. This is the operation to execute, one of:
  168. .Bd -literal -offset indent
  169. enum snmp_op {
  170. SNMP_OP_GET = 1,
  171. SNMP_OP_GETNEXT,
  172. SNMP_OP_SET,
  173. SNMP_OP_COMMIT,
  174. SNMP_OP_ROLLBACK,
  175. };
  176. .Ed
  177. .El
  178. .Pp
  179. The user handler must return an appropriate SNMP v2 error code.
  180. If the original
  181. PDU was a version 1 PDU, the error code is mapped automatically.
  182. .It Va flags
  183. Currently only the flag
  184. .Li SNMP_NODE_CANSET is defined and set for nodes, that can be written or
  185. created.
  186. .It Va index
  187. This word describes the index for table columns.
  188. Each part of the index takes 4 bits starting at bit 4.
  189. Bits 0 to 3 hold the number of index parts.
  190. This arrangement allows for tables with up to seven indexes.
  191. Each bit group contains the syntax for the index part.
  192. There are a number of macros to help in parsing this field:
  193. .Bd -literal -offset indent
  194. #define SNMP_INDEXES_MAX 7
  195. #define SNMP_INDEX_SHIFT 4
  196. #define SNMP_INDEX_MASK 0xf
  197. #define SNMP_INDEX_COUNT(V) ((V) & SNMP_INDEX_MASK)
  198. #define SNMP_INDEX(V,I) \e
  199. (((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \e
  200. SNMP_INDEX_MASK)
  201. .Ed
  202. .It Va data
  203. This field may contain arbitrary data and is not used by the library.
  204. .El
  205. .Pp
  206. The easiest way to construct the node table is
  207. .Xr gensnmptree 1 .
  208. Note, that one must be careful when changing the tree while executing a SET
  209. operation.
  210. Consult the sources for
  211. .Xr bsnmpd 1 .
  212. .Pp
  213. The global variable
  214. .Va snmp_trace
  215. together with the function pointed to by
  216. .Va snmp_debug
  217. help in debugging the library and the agent.
  218. .Va snmp_trace is a bit mask with the following bits:
  219. .Bd -literal -offset indent
  220. enum {
  221. SNMP_TRACE_GET,
  222. SNMP_TRACE_GETNEXT,
  223. SNMP_TRACE_SET,
  224. SNMP_TRACE_DEPEND,
  225. SNMP_TRACE_FIND,
  226. };
  227. .Ed
  228. .Pp
  229. Setting a bit to true causes the library to call
  230. .Fn snmp_debug
  231. in strategic places with a debug string.
  232. The library contains a default
  233. implementation for the debug function that prints a message to standard error.
  234. .Pp
  235. Many of the functions use a so called context:
  236. .Bd -literal -offset indent
  237. struct snmp_context {
  238. u_int var_index;
  239. struct snmp_scratch *scratch;
  240. struct snmp_dependency *dep;
  241. void *data; /* user data */
  242. enum snmp_ret code; /* return code */
  243. };
  244. struct snmp_scratch {
  245. void *ptr1;
  246. void *ptr2;
  247. uint32_t int1;
  248. uint32_t int2;
  249. };
  250. .Ed
  251. .Pp
  252. The fields are used as follows:
  253. .Bl -tag -width ".It Va var_index"
  254. .It Va va_index
  255. For the node operation callback this is the
  256. index of the variable binding that should be returned if an error occurs.
  257. Set by the library.
  258. In all other functions this is undefined.
  259. .It Va scratch
  260. For the node operation callback this is a pointer to a per variable binding
  261. scratch area that can be used to implement the commit and rollback.
  262. Set by the library.
  263. .It Va dep
  264. In the dependency callback function (see below) this is a pointer to the
  265. current dependency.
  266. Set by the library.
  267. .It Va data
  268. This is the
  269. .Fa data
  270. argument from the call to the library and is not used by the library.
  271. .El
  272. .Pp
  273. The next three functions execute different kinds of GET requests.
  274. The function
  275. .Fn snmp_get
  276. executes an SNMP GET operation, the function
  277. .Fn snmp_getnext
  278. executes an SNMP GETNEXT operation and the function
  279. .Fn snmp_getbulk
  280. executes an SNMP GETBULK operation.
  281. For all three functions the response PDU is constructed and encoded
  282. on the fly.
  283. If everything is ok, the response PDU is returned in
  284. .Fa resp
  285. and
  286. .Fa resp_b .
  287. The caller must call
  288. .Fn snmp_pdu_free
  289. to free the response PDU in this case.
  290. One of the following values may be returned:
  291. .Bl -tag -width ".It Li SNMP_RET_ERR"
  292. .It Li SNMP_RET_OK
  293. Operation successful, response PDU may be sent.
  294. .It Li SNMP_RET_IGN
  295. Operation failed, no response PDU constructed.
  296. Request is ignored.
  297. .It Li SNMP_RET_ERR
  298. Error in operation.
  299. The error code and index have been set in
  300. .Fa pdu .
  301. No response PDU has been constructed.
  302. The caller may construct an error response PDU via
  303. .Fn snmp_make_errresp .
  304. .El
  305. .Pp
  306. The function
  307. .Fn snmp_set
  308. executes an SNMP SET operation.
  309. The arguments are the same as for the previous
  310. three functions.
  311. The operation of this functions is, however, much more complex.
  312. .Pp
  313. The SET operation occurs in several stages:
  314. .Bl -enum -offset indent
  315. .It
  316. For each binding search the corresponding nodes, check that the
  317. variable is writeable and the syntax is ok.
  318. The writeable check can be done only for scalars.
  319. For columns it must be done in the node's operation callback function.
  320. .It
  321. For each binding call the node's operation callback with function SNMP_OP_SET.
  322. The callback may create dependencies or finalizers (see below).
  323. For simple
  324. scalars the scratch area may be enough to handle commit and rollback, for
  325. interdependent table columns dependencies may be necessary.
  326. .It
  327. If the previous step fails at any point, the node's operation callback
  328. functions are called for all bindings for which SNMP_OP_SET was executed
  329. with SNMP_OP_ROLLBACK, in the opposite order.
  330. This allows all variables to undo the effect of the SET operation.
  331. After this all the dependencies are freed
  332. and the finalizers are executed with a fail flag of 1.
  333. Then the function
  334. returns to the caller with an appropriate error indication.
  335. .It
  336. If the SET step was successful for all bindings, the dependency callbacks
  337. are executed in the order in which the dependencies were created with an
  338. operation of SNMP_DEPOP_COMMIT.
  339. If any of the dependencies fails, all the
  340. committed dependencies are called again in the opposite order
  341. with SNMP_DEPOP_ROLLBACK.
  342. Than for all bindings from the last to the first
  343. the node's operation callback is called with SNMP_OP_ROLLBACK to undo
  344. the effect of SNMP_OP_SET.
  345. At the end the dependencies are freed and the finalizers are called with
  346. a fail flag of 1 and the function returns to the caller with an appropriate
  347. error indication.
  348. .It
  349. If the dependency commits were successful, for each binding the node's
  350. operation callback is called with SNMP_OP_COMMIT.
  351. Any error returned from
  352. the callbacks is ignored (an error message is generated via
  353. .Fn snmp_error ).
  354. .It
  355. Now the dependencies are freed and the finalizers are called
  356. with a fail flag of 0.
  357. For each dependency just before freeing it
  358. its callback is called with
  359. .Li SNMP_DEPOP_FINISH.
  360. Then the function returns
  361. .Li SNMP_ERR_OK .
  362. .El
  363. .Pp
  364. There are to mechanisms to help in complex SET operations: dependencies and
  365. finalizers.
  366. A dependency is used if several bindings depend on each other.
  367. A typical example is the creation of a conceptual row, which requires
  368. the setting of several columns to succeed.
  369. A dependency is identified by
  370. two OIDs.
  371. In the table case, the first oid is typically the table's base OID
  372. and the second one the index.
  373. Both of these can easily be generated from the
  374. variables OID with
  375. .Fn asn_slice_oid .
  376. The function
  377. .Fn snmp_dep_lookup
  378. tries to find a dependency based on these two OIDs and, if it cannot find one
  379. creates a new one.
  380. This means for the table example, that the function
  381. returns the same dependency for each of the columns of the same table row.
  382. This allows during the SNMP_OP_SET processing to collect all information
  383. about the row into the dependency.
  384. The arguments to
  385. .Fn snmp_dep_lookup
  386. are: the two OIDs to identify the dependency (they are copied into newly
  387. created dependencies), the size of the structure to allocate and
  388. the dependency callback.
  389. .Pp
  390. When all SNMP_OP_SET operations have succeeded the dependencies are executed.
  391. At this stage the dependency callback has all information about the given
  392. table row that was available in this SET PDU and can operate accordingly.
  393. .Pp
  394. It is guaranteed that each dependency callback is executed at minimum once
  395. - with an operation of
  396. .Li SNMP_OP_ROLLBACK .
  397. This ensures that all dynamically allocated resources in a callback can be
  398. freed correctly.
  399. .Pp
  400. The function
  401. .Fn snmp_make_errresp
  402. makes an error response if an operation has failed.
  403. It takes the original request PDU (it will look only on the error code and
  404. index fields), the buffer containing the original PDU and a buffer for the
  405. error PDU.
  406. It copies the bindings field from the original PDUs buffer directly to
  407. the response PDU and thus does not depend on the decodability of this field.
  408. It may return the same values as the operation functions.
  409. .Pp
  410. The next four functions allow some parts of the SET operation to be executed.
  411. This is only used in
  412. .Xr bsnmpd 1
  413. to implement the configuration as a single transaction.
  414. The function
  415. .Fn snmp_init_context
  416. creates and initializes a context.
  417. The function
  418. .Fn snmp_dep_commit
  419. executes SNMP_DEPOP_COMMIT for all dependencies in the context stopping at
  420. the first error.
  421. The function
  422. .Fn snmp_dep_rollback
  423. executes SNMP_DEPOP_ROLLBACK starting at the previous of the current
  424. dependency in the context.
  425. The function
  426. .Fn snmp_dep_finish
  427. executes SNMP_DEPOP_FINISH for all dependencies.
  428. .Sh DIAGNOSTICS
  429. If an error occurs in any of the function an error indication as described
  430. above is returned.
  431. Additionally the functions may call snmp_error on unexpected errors.
  432. .Sh SEE ALSO
  433. .Xr gensnmptree 1 ,
  434. .Xr bsnmpd 1 ,
  435. .Xr bsnmpclient 3 ,
  436. .Xr bsnmplib 3 ,
  437. .Xr snmpmod 3
  438. .Sh STANDARDS
  439. This implementation conforms to the applicable IETF RFCs and ITU-T
  440. recommendations.
  441. .Sh AUTHORS
  442. .An Hartmut Brandt Aq harti@FreeBSD.org