bsnmpagent snmp_depop_t snmp_op_t tree tree_size snmp_trace snmp_debug snmp_get snmp_getnext snmp_getbulk snmp_set snmp_make_errresp snmp_dep_lookup snmp_init_context snmp_dep_commit snmp_dep_rollback snmp_dep_finish - SNMP agent library
Begemot SNMP library (libbsnmp, -lbsnmp)
Most of the agent routines operate on a global array that the describes the complete MIB served by the agent. This array is held in the two variables:
extern struct snmp_node *tree; extern u_int tree_size;
The elements of the array are of type Vt struct snmp_node :
typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
u_int, u_int, enum snmp_op);
struct snmp_node {
struct asn_oid oid;
const char *name; /* name of the leaf */
enum snmp_node_type type; /* type of this node */
enum snmp_syntax syntax;
snmp_op_t op;
u_int flags;
u_int32_t index; /* index data */
void *data; /* application data */
void *tree_data; /* application data */
};
The fields of this structure are described below.
enum snmp_node_type {
SNMP_NODE_LEAF = 1,
SNMP_NODE_COLUMN
};
enum snmp_op {
SNMP_OP_GET = 1,
SNMP_OP_GETNEXT,
SNMP_OP_SET,
SNMP_OP_COMMIT,
SNMP_OP_ROLLBACK,
};
The user handler must return an appropriate SNMP v2 error code. If the original PDU was a version 1 PDU, the error code is mapped automatically.
#define SNMP_INDEXES_MAX 7
#define SNMP_INDEX_SHIFT 4
#define SNMP_INDEX_MASK 0xf
#define SNMP_INDEX_COUNT(V) ((V) & SNMP_INDEX_MASK)
#define SNMP_INDEX(V,I) \
(((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \
SNMP_INDEX_MASK)
The easiest way to construct the node table is gensnmptree(1). Note, that one must be careful when changing the tree while executing a SET operation. Consult the sources for bsnmpd(1).
The global variable snmp_trace together with the function pointed to by snmp_debug help in debugging the library and the agent. snmp_trace is a bit mask with the following bits:
enum {
SNMP_TRACE_GET,
SNMP_TRACE_GETNEXT,
SNMP_TRACE_SET,
SNMP_TRACE_DEPEND,
SNMP_TRACE_FIND,
};
Setting a bit to true causes the library to call
snmp_debug ();
in strategic places with a debug string.
The library contains a default
implementation for the debug function that prints a message to standard error.
Many of the functions use a so called context:
struct snmp_context {
u_int var_index;
struct snmp_scratch *scratch;
struct snmp_dependency *dep;
void *data; /* user data */
enum snmp_ret code; /* return code */
};
struct snmp_scratch {
void *ptr1;
void *ptr2;
uint32_t int1;
uint32_t int2;
};
The fields are used as follows:
The next three functions execute different kinds of GET requests.
The function
snmp_get ();
executes an SNMP GET operation, the function
snmp_getnext ();
executes an SNMP GETNEXT operation and the function
snmp_getbulk ();
executes an SNMP GETBULK operation.
For all three functions the response PDU is constructed and encoded
on the fly.
If everything is ok, the response PDU is returned in
Fa resp
and
Fa resp_b .
The caller must call
snmp_pdu_free ();
to free the response PDU in this case.
One of the following values may be returned:
The function
snmp_set ();
executes an SNMP SET operation.
The arguments are the same as for the previous
three functions.
The operation of this functions is, however, much more complex.
The SET operation occurs in several stages:
There are to mechanisms to help in complex SET operations: dependencies and
finalizers.
A dependency is used if several bindings depend on each other.
A typical example is the creation of a conceptual row, which requires
the setting of several columns to succeed.
A dependency is identified by
two OIDs.
In the table case, the first oid is typically the table's base OID
and the second one the index.
Both of these can easily be generated from the
variables OID with
asn_slice_oid (.);
The function
snmp_dep_lookup ();
tries to find a dependency based on these two OIDs and, if it cannot find one
creates a new one.
This means for the table example, that the function
returns the same dependency for each of the columns of the same table row.
This allows during the SNMP_OP_SET processing to collect all information
about the row into the dependency.
The arguments to
snmp_dep_lookup ();
are: the two OIDs to identify the dependency (they are copied into newly
created dependencies), the size of the structure to allocate and
the dependency callback.
When all SNMP_OP_SET operations have succeeded the dependencies are executed. At this stage the dependency callback has all information about the given table row that was available in this SET PDU and can operate accordingly.
It is guaranteed that each dependency callback is executed at minimum once - with an operation of SNMP_OP_ROLLBACK This ensures that all dynamically allocated resources in a callback can be freed correctly.
The function
snmp_make_errresp ();
makes an error response if an operation has failed.
It takes the original request PDU (it will look only on the error code and
index fields), the buffer containing the original PDU and a buffer for the
error PDU.
It copies the bindings field from the original PDUs buffer directly to
the response PDU and thus does not depend on the decodability of this field.
It may return the same values as the operation functions.
The next four functions allow some parts of the SET operation to be executed.
This is only used in
bsnmpd(1)
to implement the configuration as a single transaction.
The function
snmp_init_context ();
creates and initializes a context.
The function
snmp_dep_commit ();
executes SNMP_DEPOP_COMMIT for all dependencies in the context stopping at
the first error.
The function
snmp_dep_rollback ();
executes SNMP_DEPOP_ROLLBACK starting at the previous of the current
dependency in the context.
The function
snmp_dep_finish ();
executes SNMP_DEPOP_FINISH for all dependencies.
|
Закладки на сайте Проследить за страницей |
Created 1996-2025 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |