* | SNMP_OPEN | socket created, starting subagent
* +-----------------+
* |
- * | BIRD recieve response for Open-PDU
+ * | BIRD receive response for Open-PDU
* V
* +-----------------+
* | SNMP_REGISTER | session was established, subagent registers MIBs
* +-----------------+
* |
- * | subagent recieved responses for all registration requests
+ * | subagent received responses for all registration requests
* V
* +-----------------+
* | SNMP_CONN | everything is set
* session is establised and the GetNext request should be responsed
* without regard to MIB registration.
*
- * When the session has been closed for some reason (socket error, reciept of
+ * When the session has been closed for some reason (socket error, receipt of
* Close-PDU) SNMP cleans the session information and message queue and goes
* back to the SNMP_LOCKED state.
*
[SNMP_DOWN] = "SNMP DOWN",
};
+/*
+ * snmp_init - preinitialize SNMP instance
+ * @CF - SNMP configuration generic handle
+ *
+ * Return value is generic handle pointing to preinitialized SNMP procotol
+ * instance.
+ */
static struct proto *
snmp_init(struct proto_config *CF)
{
return P;
}
+/*
+ * snmp_cleanup - free all resources allocated by SNMP protocol
+ * @p - SNMP protocol instance
+ *
+ * This function forcefully stops and cleans all resources and memory acqiured
+ * by given SNMP protocol instance, such as timers, lists, hash tables etc.
+ * Function snmp_cleanup() does not change the protocol state to PS_DOWN for
+ * practical reasons, it should be done by the caller.
+ */
static inline void
snmp_cleanup(struct snmp_proto *p)
{
p->state = SNMP_DOWN;
}
+/*
+ * snmp_down - stop the SNMP protocol and free resources
+ * @p - SNMP protocol instance
+ *
+ * AgentX session is destroyed by closing underlying socket and all resources
+ * are freed. Afterwards, the PS_DOWN protocol state is announced.
+ */
void
snmp_down(struct snmp_proto *p)
{
proto_notify_state(&p->p, PS_DOWN);
}
-/* this function is internal and shouldn't be used outside the snmp module */
+/*
+ * snmp_connected - start AgentX session on established channel
+ * @sk - socket owned by SNMP protocol instance
+ *
+ * Starts the AgentX communication by sending an agentx-Open-PDU.
+ * This function is internal and shouldn't be used outside the SNMP module.
+ */
void
snmp_connected(sock *sk)
{
struct snmp_proto *p = sk->data;
- snmp_log("connection created");
p->state = SNMP_OPEN;
tm_set(p->ping_timer, current_time() + p->timeout S);
}
-/* this function is internal and shouldn't be used outside the snmp module */
+/*
+ * snmp_sock_disconnect - end or reset socket connection
+ * @p - SNMP protocol instance
+ *
+ * If the @reconnect flags is set, we close the socket and then reestablish
+ * the AgentX session by reentering the start procedure as from the
+ * snmp_start_locked() function.
+ * Otherwise we simply shutdown the SNMP protocol if the flag is clear.
+ * This function is internal and shouldn't be used outside the SNMP module.
+ */
void
snmp_sock_disconnect(struct snmp_proto *p, int reconnect)
{
tm_start(p->startup_timer, 4 S); // TODO make me configurable
}
+/*
+ * snmp_sock_err - handle errors on socket by reopenning the socket
+ * @sk - socket owned by SNMP protocol instance
+ * @err - socket error errno
+ */
static void
snmp_sock_err(sock *sk, int UNUSED err)
{
snmp_sock_disconnect(p, 1);
}
+/*
+ * snmp_start_locked - open the socket on locked address
+ * @lock - object lock guarding the communication mean (address, ...)
+ *
+ * This function is called when the object lock is acquired. Main goal is to set
+ * socket parameters and try to open configured socket. Function
+ * snmp_connected() handles next stage of SNMP protocol start. When the socket
+ * coundn't be opened, a new try is scheduled after a small delay.
+ */
static void
snmp_start_locked(struct object_lock *lock)
{
p->errs = 0;
}
- snmp_log("opening socket");
/* Try opening the socket, schedule a retry on fail */
if (sk_open(s) < 0)
tm_set(p->startup_timer, current_time() + p->timeout S);
}
-/* this function is internal and shouldn't be used outside the snmp module */
+/*
+ * snmp_reconnect - helper restarting the AgentX session on packet errors
+ * @tm - the startup_timer holding the SNMP protocol instance
+ *
+ * Rerun the SNMP module start procedure. Used in situations when the master
+ * agent returns an agentx-Response-PDU with 'Not Opened' error. We do not close
+ * the socket if have one.
+ */
void
snmp_reconnect(timer *tm)
{
snmp_connected(p->sock);
}
-
-/* this function is internal and shouldn't be used outside the snmp module */
+/*
+ * snmp_startup - start initialized SNMP protocol
+ * @p - SNMP protocol to start
+ *
+ * Starting of SNMP protocols begins with address acqusition through object
+ * lock. Next step is handled by snmp_start_locked() function.
+ * This function is internal and shouldn't be used outside the SNMP
+ * module.
+ */
void
snmp_startup(struct snmp_proto *p)
{
return;
}
- snmp_log("preparing object lock");
p->state = SNMP_INIT;
struct object_lock *lock;
olock_acquire(lock);
}
-/* this function is internal and shouldn't be used outside the snmp module */
+/*
+ * snmp_startup_timeout - start the initiliazed SNMP protocol
+ * @tm - the startup_timer holding the SNMP protocol instance.
+ *
+ * When the timer rings, the function snmp_startup() is invoked.
+ * This function is internal and shoudln't be used outside the SNMP module.
+ * Used when we delaying the start procedure, or we want to resend
+ * an agentx-Open-PDU for non-responding master agent.
+ */
void
-snmp_startup_timeout(timer *t)
+snmp_startup_timeout(timer *tm)
{
- snmp_log("startup timer triggered");
- snmp_startup(t->data);
+ snmp_startup(tm->data);
}
+/*
+ * snmp_stop_timeout - a timeout for nonresponding master agent
+ * @tm - the startup_timer holding the SNMP protocol instance.
+ *
+ * We are shutting down the SNMP protocol instance and we sent the
+ * agentx-Close-PDU. This function forcefully closes the AgentX session and
+ * stops the SNMP protocol instance. Used only when we did not receive any
+ * agentx-Response-PDU for the sent closed packet (before timeout).
+ */
static void
-snmp_stop_timeout(timer *t)
+snmp_stop_timeout(timer *tm)
{
- snmp_log("stop timer triggered");
- snmp_down(t->data);
+ snmp_down(tm->data);
}
+/*
+ * snmp_ping_timeout - send a agentx-Ping-PDU
+ * @tm - the ping_timer holding the SNMP protocol instance.
+ *
+ * Send an agentx-Ping-PDU and reset the timer for next ping.
+ */
static void
snmp_ping_timeout(timer *tm)
{
p->state == SNMP_CONN)
{
snmp_ping(p);
+ tm_set(tm, current_time() + p->timeout S);
}
-
- tm_set(tm, current_time() + p->timeout S);
}
+/*
+ * snmp_start - Initialize the SNMP protocol instance
+ * @P - SNMP protocol generic handle
+ *
+ * The first step in AgentX subagent startup is protocol initialition.
+ * We must prepare lists, find BGP peers and finally asynchornously open
+ * a AgentX subagent session through snmp_startup() function call.
+ */
static int
snmp_start(struct proto *P)
{
return PS_START;
}
+/*
+ * snmp_reconfigure - Test if SNMP instance is reconfigurable
+ * @P - SNMP protocol generic handle, current state
+ * @CF - SNMP protocol configuration generic handle carring new values
+ *
+ * We accept the reconfiguration if the new configuration @CF is identical with
+ * the currently deployed. Otherwise we deny reconfiguration because
+ * the implementation would be cumbersome.
+ */
static int
snmp_reconfigure(struct proto *P, struct proto_config *CF)
{
&& ! strncmp(old->description, new->description, UINT32_MAX);
}
+/*
+ * snmp_show_proto_info - Print basic information about SNMP protocol instance
+ * @P - SNMP protocol generic handle
+ */
static void
snmp_show_proto_info(struct proto *P)
{
}
}
+/*
+ * snmp_postconfig - Check configuration correctness
+ * @CF - SNMP procotol configuration generic handle
+ */
static void
snmp_postconfig(struct proto_config *CF)
{
cf_error("local as not specified");
}
+/*
+ * snmp_shutdown - Forcefully stop the SNMP protocol instance
+ * @P - SNMP protocol generic handle
+ *
+ * If we have established connection, we firstly stop the subagent and then
+ * later cleanup the protocol. The subagent stopping consist of sending the
+ * agentx-Close-PDU and changing the current protocol state to PS_STOP.
+ * If we have no connection created, we simple do the cleanup.
+ * The cleanup is transition straight to PS_DOWN state with snmp_cleanup() call.
+ */
static int
snmp_shutdown(struct proto *P)
{
}
}
+
+/*
+ * Protocol infrastructure
+ */
+
struct protocol proto_snmp = {
.name = "Snmp",
.template = "snmp%d",
*
*/
+/**
+ * Handling of malformed packet:
+ * When we find an error in PDU data, we create and send a response with error
+ * defined by the RFC. We await until the packet is send and then we close the
+ * communication socket. This also closes the established session. We chose
+ * this approach because we cannot easily mark the boundary between packets.
+ * When we are reseting the connection, we change the snmp_state to SNMP_RESET.
+ * In SNMP_RESET state we skip all received bytes and wait for snmp_tx()
+ * to be called. The socket's tx_hook is called when the TX-buffer is empty,
+ * meaning our response (agentx-Response-PDU) was send.
+ *
+ */
+
static void snmp_mib_fill2(struct snmp_proto *p, struct oid *oid, struct snmp_pdu *c);
static uint parse_response(struct snmp_proto *p, byte *buf, uint size);
static void do_response(struct snmp_proto *p, byte *buf, uint size);
static uint parse_gets2_pdu(struct snmp_proto *p, byte *buf, uint size, uint *skip);
static struct agentx_response *prepare_response(struct snmp_proto *p, struct snmp_pdu *c);
-static void response_err_ind(struct agentx_response *res, uint err, uint ind);
+static void response_err_ind(struct agentx_response *res, enum agentx_response_errs err, u16 ind);
static uint update_packet_size(struct snmp_proto *p, const byte *start, byte *end);
static struct oid *search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end, struct oid *o_curr, struct snmp_pdu *c, enum snmp_search_res *result);
static void snmp_tx(sock *sk);
u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET };
static const char * const snmp_errs[] UNUSED = {
- #define SNMP_ERR_SHIFT 256
- [AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed",
- [AGENTX_RES_NOT_OPEN - SNMP_ERR_SHIFT] = "Not open",
- [AGENTX_RES_INDEX_WRONG_TYPE - SNMP_ERR_SHIFT] = "Index wrong type",
- [AGENTX_RES_INDEX_ALREADY_ALLOC - SNMP_ERR_SHIFT] = "Index already allocated",
- [AGENTX_RES_INDEX_NONE_AVAIL - SNMP_ERR_SHIFT] = "Index none availlable",
- [AGENTX_RES_NOT_ALLOCATED - SNMP_ERR_SHIFT] = "Not allocated",
- [AGENTX_RES_UNSUPPORTED_CONTEXT - SNMP_ERR_SHIFT] = "Unsupported contex",
- [AGENTX_RES_DUPLICATE_REGISTER - SNMP_ERR_SHIFT] = "Duplicate registration",
- [AGENTX_RES_UNKNOWN_REGISTER - SNMP_ERR_SHIFT] = "Unknown registration",
- [AGENTX_RES_UNKNOWN_AGENT_CAPS - SNMP_ERR_SHIFT] = "Unknown agent caps",
- [AGENTX_RES_PARSE_ERROR - SNMP_ERR_SHIFT] = "Parse error",
- [AGENTX_RES_REQUEST_DENIED - SNMP_ERR_SHIFT] = "Request denied",
- [AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
+ [AGENTX_RES_NO_ERROR ] = "No error",
+ [AGENTX_RES_GEN_ERROR ] = "General error",
+ [AGENTX_RES_NO_ACCESS ] = "No access",
+ [AGENTX_RES_WRONG_TYPE ] = "Wrong type",
+ [AGENTX_RES_WRONG_LENGTH ] = "Wrong length",
+ [AGENTX_RES_WRONG_ENCODING ] = "Wrong encoding",
+ [AGENTX_RES_WRONG_VALUE ] = "Wrong value",
+ [AGENTX_RES_NO_CREATION ] = "No creation",
+ [AGENTX_RES_INCONSISTENT_VALUE ] = "Inconsistent value",
+ [AGENTX_RES_RESOURCE_UNAVAILABLE ] = "Resource unavailable",
+ [AGENTX_RES_COMMIT_FAILED ] = "Commit failed",
+ [AGENTX_RES_UNDO_FAILED ] = "Undo failed",
+ [AGENTX_RES_NOT_WRITABLE ] = "Not writable",
+ [AGENTX_RES_INCONSISTENT_NAME ] = "Inconsistent name",
+ [AGENTX_RES_OPEN_FAILED ] = "Open failed",
+ [AGENTX_RES_NOT_OPEN ] = "Not open",
+ [AGENTX_RES_INDEX_WRONG_TYPE ] = "Index wrong type",
+ [AGENTX_RES_INDEX_ALREADY_ALLOC ] = "Index already allocated",
+ [AGENTX_RES_INDEX_NONE_AVAIL ] = "Index none availlable",
+ [AGENTX_RES_NOT_ALLOCATED ] = "Not allocated",
+ [AGENTX_RES_UNSUPPORTED_CONTEXT ] = "Unsupported contex",
+ [AGENTX_RES_DUPLICATE_REGISTER ] = "Duplicate registration",
+ [AGENTX_RES_UNKNOWN_REGISTER ] = "Unknown registration",
+ [AGENTX_RES_UNKNOWN_AGENT_CAPS ] = "Unknown agent caps",
+ [AGENTX_RES_PARSE_ERROR ] = "Parse error",
+ [AGENTX_RES_REQUEST_DENIED ] = "Request denied",
+ [AGENTX_RES_PROCESSING_ERR ] = "Processing error",
};
static const char * const snmp_pkt_type[] UNUSED = {
};
+/*
+ * snmp_register_ok - registration of OID was successful
+ * @p: SNMP protocol instance
+ * @res: header of agentx-Response-PDU
+ * @oid: OID that was successfully registered
+ * @class: MIB subtree of @oid
+ *
+ * Send a notification to MIB (selected by @class) about successful registration
+ * of @oid.
+ */
static void
snmp_register_ok(struct snmp_proto *p, struct agentx_response *res, struct oid *oid, u8 UNUSED class)
{
snmp_bgp_reg_ok(p, res, oid);
}
+/*
+ * snmp_regsiter_failed - registration of OID failed
+ * @p: SNMP protocol instance
+ * @res: header of agentx-Response-PDU
+ * @oid: OID whose registration failed
+ * @class: MIB subtree of @oid
+ *
+ * Send a notification to MIB (selected by @class) about @oid registraion
+ * failure.
+ */
static void
snmp_register_failed(struct snmp_proto *p, struct agentx_response *res, struct oid *oid, u8 UNUSED class)
{
snmp_bgp_reg_failed(p, res, oid);
}
+/*
+ * snmp_register_ack - handle response to agentx-Register-PDU
+ * @p: SNMP protocol instance
+ * @res: header of agentx-Response-PDU
+ * @class: MIB subtree associated with agentx-Register-PDU
+ */
void
snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, u8 class)
{
}
}
+/*
+ * snmp_rx_skip - skip all received data
+ * @sk: communication socket
+ * @size: size of received PDUs
+ *
+ * Socket rx_hook used when we are reseting the connection due to malformed PDU.
+ */
static int
snmp_rx_skip(sock UNUSED *sk, uint UNUSED size)
{
return 1;
}
+/*
+ * snmp_error - handle a malformed packet
+ * @p: SNMP protocol instance
+ *
+ * We wait until all packets are send. Then we close the socket which also
+ * closes the established session on given socket. Finally we try to start a new
+ * session.
+ */
static inline void
snmp_error(struct snmp_proto *p)
{
p->sock->tx_hook = snmp_tx;
}
+/*
+ * snmp_simple_response - send an agentx-Response-PDU with no data payload
+ * @p: SNMP protocol instance
+ * @error: PDU error fields value
+ * @index: PDU error index field value
+ */
static void
-snmp_simple_response(struct snmp_proto *p, enum agentx_response_err error, u16 index)
+snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16 index)
{
sock *sk = p->sock;
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
sk_send(sk, sizeof(struct agentx_response));
}
+/*
+ * open_pdu - send an agentx-Open-PDU
+ * @p: SNMP protocol instance
+ * @oid: PDU OID description field value
+ *
+ * Other fields are filled based on @p configuratin (timeout, subagent string
+ * description)
+ */
static void
open_pdu(struct snmp_proto *p, struct oid *oid)
{
#undef TIMEOUT_SIZE
}
+/*
+ * send_notify_pdu - send an agentx-Notify-PDU
+ * @p: SNMP protocol instance
+ * @oid: PDU notification Varbind name (OID)
+ * @data: PDU Varbind payload
+ * @size - PDU Varbind payload size
+ * @include_uptime: flag enabling inclusion of sysUpTime.0 OID
+ */
void
snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime)
{
#undef UPTIME_SIZE
}
-/* index allocate / deallocate pdu * /
+#if 0
+/*
+ * de_allocate_pdu - common functionality for allocation PDUs
+ * @p: SNMP protocol instance
+ * @oid: OID to allocate/deallocate
+ * @type: allocate/deacollcate PDU type
+ * @flags: type of allocation (NEW_INDEX, ANY_INDEX)
+ *
+ * This function is internal and shouldn't be used outside the SNMP module.
+ */
static void
-de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
+de_allocate_pdu(struct snmp_proto *p, struct oid *oid, enum agentx_pdu_types type, u8 flags)
{
sock *sk = p->sock;
byte *buf, *pkt;
buf = pkt = sk->tbuf;
uint size = sk->tbsize;
+ struct snmp_pdu = SNMP_PDU_CONTEXT(p->sock);
- if (size > AGENTX_HEADER_SIZE + )
+ if (size > AGENTX_HEADER_SIZE + 0) // TODO additional size
{
struct agentx_header *h;
SNMP_CREATE(pkt, struct agentx_header, h);
SNMP_SESSION(h,p);
struct agentx_varbind *vb = (struct agentx_varbind *) pkt;
+
+ // TODO
STORE_16(vb->type, AGENTX_OBJECT_ID);
- STORE(vb->oid,
+ STORE(vb->oid, 0);
}
}
-*/
-/* Register-PDU / Unregister-PDU */
+void
+snmp_allocate(struct snmp_proto *p, struct oid *oid, u8 flags)
+{
+ /* TODO - call the de_allocate_pdu() */
+}
+
+void
+snmp_deallocate(struct snmp_proto *p, struct oid *oid, u8 flags)
+{
+ /* TODO - call the de_allocate_pdu() */
+}
+#endif
+
+/*
+ * un_register_pdu - common functionality for registration PDUs
+ * @p: SNMP protocol instance
+ * @oid: OID to register/unregister
+ * @bound: OIDs registration upper bound
+ * @index: OIDs registration n_subid index
+ * @type: register/unregister PDU type
+ * @is_instance: flag enabling instance registration (used only for register)
+ * @contid: context ID to register in (currently unsupported)
+ *
+ * Both register and unregister PDUs are capable of specifing a number of OIDs
+ * by using pair of index and upper bound. The index (r.range_subid) points into
+ * the OID's n_subid array to ID being threated as variable. The upper bound
+ * (r.upper_bound) determins maximal value for n_subid selected by index.
+ * The index and upper bound are passed as @index, and @bound respectively.
+ *
+ * Zero value for @is_instance means we want to register/unregister OID as a MIB
+ * subtree, for nonzero value we are registering MIB tree an instance (leaf).
+ *
+ * This function in internal and shoulnd't be used outside the SNMP module,
+ * see snmp_register() and snmp_unregister() functions.
+ */
static void
-un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 type, u8 is_instance, uint UNUSED contid)
+un_register_pdu(struct snmp_proto *p, struct oid *oid, uint bound, uint index, enum agentx_pdu_types type, u8 is_instance, uint UNUSED contid)
{
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
sock *sk = p->sock;
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
/* conditional +4 for upper-bound (optinal field) */
- uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((len > 1) ? 4 : 0);
+ uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((bound > 1) ? 4 : 0);
if (c.size < sz)
snmp_manage_tbuf(p, &c);
struct agentx_header *h = (struct agentx_header *) c.buffer;
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
- SNMP_HEADER(h, type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
+ SNMP_HEADER(h, (u8) type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
p->packet_id++;
SNMP_SESSION(h, p);
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
STORE_U8(ur->timeout, p->timeout);
/* default priority */
STORE_U8(ur->priority, cf->priority);
- STORE_U8(ur->range_subid, (len > 1) ? index : 0);
+ STORE_U8(ur->range_subid, (bound > 1) ? index : 0);
STORE_U8(ur->pad, 0);
ADVANCE(c.buffer, c.size, sizeof(struct agentx_un_register_hdr));
ADVANCE(c.buffer, c.size, snmp_oid_size(oid));
/* place upper-bound if needed */
- if (len > 1)
+ if (bound > 1)
{
- STORE_PTR(c.buffer, len);
+ STORE_PTR(c.buffer, bound);
ADVANCE(c.buffer, c.size, 4);
}
sk_send(sk, s);
}
-/* Register-PDU */
+/*
+ * snmp_register - send an agentx-Register-PDU
+ * @p: SNMP protocol instance
+ * @oid: OID to register
+ * @bound: OIDs registration upper bound
+ * @index: OIDs registration n_subid index
+ * @is_instance: flag enabling instance registration
+ * @contid: context ID to register in (currently unsupported)
+ *
+ * For more detailed description see un_register_pdu() function.
+ */
void
-snmp_register(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 is_instance, uint contid)
+snmp_register(struct snmp_proto *p, struct oid *oid, uint bound, uint index, u8 is_instance, uint contid)
{
- un_register_pdu(p, oid, len, index, AGENTX_REGISTER_PDU, is_instance, contid);
+ un_register_pdu(p, oid, bound, index, AGENTX_REGISTER_PDU, is_instance, contid);
}
-/* Unregister-PDU */
+/*
+ * snmp_unregister - send an agentx-Unregister-PDU
+ * @p: SNMP protocol instance
+ * @oid: OID to uregister
+ * @bound: OIDs unregistration upper bound
+ * @index: OIDs unregistration n_subid index
+ * @contid: context ID to unregister from (currently unsupported)
+ *
+ * For more detailed description see un_register_pdu() function.
+ */
void UNUSED
snmp_unregister(struct snmp_proto *p, struct oid *oid, uint len, uint index, uint contid)
{
un_register_pdu(p, oid, len, index, AGENTX_UNREGISTER_PDU, 0, contid);
}
+/*
+ * close_pdu - send an agentx-Close-PDU
+ * @p: SNMP protocol instance
+ * @reason: reason for closure
+ */
static void
-close_pdu(struct snmp_proto *p, u8 reason)
+close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
{
sock *sk = p->sock;
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
SNMP_SESSION(h, p);
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
- snmp_put_fbyte(c.buffer, reason);
+ snmp_put_fbyte(c.buffer, (u8) reason);
ADVANCE(c.buffer, c.size, 4);
uint s = update_packet_size(p, sk->tpos, c.buffer);
#undef REASON_SIZE
}
+/*
+ * parse_close_pdu - parse an agentx-Close-PDU
+ * @p: SNMP protocol instance
+ * @pkt_start: pointer to first byte of PDU
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static uint
parse_close_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
{
return AGENTX_HEADER_SIZE;
}
+
+/*
+ * snmp_testset - check possibility of VarBind name and data setting
+ * @p: SNMP protocol instance
+ * @vb: checked VarBind
+ * @oid: pool-allocated prefixed copy of VarBind name
+ * @pkt_size: number of not parsed bytes in processed PDU
+ *
+ * Check done by specialized function for specific MIB subtree whether
+ * the VarBind is valid for set action (changing to current value to value
+ * in VarBind).
+ *
+ * Return 1 if the VarBind setting is possible, 0 otherwise.
+ */
/* MUCH better signature would be
static int snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, uint pkt_size);
*/
-/* return 1 if the value could be set */
static int UNUSED
snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, struct oid *oid, uint pkt_size)
{
}
#endif
+/*
+ * refresh_ids - Copy current ids from packet to protocol
+ * @p: SNMP protocol instance
+ * @h: PDU header with new transaction_id and packet_id ids.
+ */
static inline void
refresh_ids(struct snmp_proto *p, struct agentx_header *h)
{
p->packet_id = LOAD_U32(h->packet_id, byte_ord);
}
+/*
+ * parse_test_set_pdu - parse an agentx-TestSet-PDU in buffer
+ * @p: SNMP protocol instance
+ * @pkt_start: first byte of test set PDU
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static uint
parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
{
if (sz > pkt_size)
{
c.error = AGENTX_RES_PARSE_ERROR;
- goto error;
+ all_possible = 0;
+ break;
}
/* Unknown VarBind type check */
if (!snmp_test_varbind(vb))
{
c.error = AGENTX_RES_PARSE_ERROR;
- goto error;
+ all_possible = 0;
+ break;
}
ADVANCE(pkt, size, snmp_varbind_size(vb, 0));
}
mb_free(tr);
#endif
- goto error;
-error:
s = update_packet_size(p, sk->tpos, c.buffer);
if (c.error != AGENTX_RES_NO_ERROR)
}
/*
- * Common code for packets:
- * agentx-CommitSet-PDU
- * agentx-UndoSet-PDU
+ * parse_set_pdu - common functionality for commit set and undo set PDUs
+ * @p: SNMP protocol instance
+ * @pkt_start: pointer to first byte of on of set related PDU
+ * @size: number of bytes received from a socket
+ * @error: error status to use
+ *
+ * Return number of bytes parsed from RX-buffer.
*/
static uint
-parse_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint err)
+parse_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, enum agentx_response_errs err)
{
byte *pkt = pkt_start;
struct agentx_header *h = (void *) pkt;
if (size < pkt_size)
{
c.error = AGENTX_RES_PARSE_ERROR;
- goto error;
+ }
+ else
+ {
+ // TODO: free resource allocated by parse_test_set_pdu()
+ // TODO: do something meaningful
+ //mb_free(tr);
+ c.error = err;
}
- // TODO: free resource allocated by parse_test_set_pdu()
- // TODO: do something meaningful
- //mb_free(tr);
- c.error = err;
-
-error:;
response_err_ind(r, c.error, 0);
sk_send(p->sock, AGENTX_HEADER_SIZE);
return pkt - pkt_start;
}
-/* agentx-CommitSet-PDU */
+/*
+ * parse_commit_set_pdu - parse an agentx-CommitSet-PDU
+ * @p: SNMP protocol instance
+ * @pkt: pointer to first byte of PDU inside RX-buffer
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static uint
parse_commit_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
return parse_set_pdu(p, pkt, size, AGENTX_RES_COMMIT_FAILED);
}
-/* agentx-UndoSet-PDU */
+/*
+ * parse_undo_set_pdu - parse an agentx-UndoSet-PDU
+ * @p: SNMP protocol instance
+ * @pkt: pointer to first byte of PDU inside RX-buffer
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from buffer.
+ */
static uint
parse_undo_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
return parse_set_pdu(p, pkt, size, AGENTX_RES_UNDO_FAILED);
}
-/* agentx-CleanupSet-PDU */
+/*
+ * parse_cleanup_set_pdu - parse an agentx-CleanupSet-PDU
+ * @p: SNMP protocol instance
+ * @pkt_start: pointer to first byte of PDU inside RX-buffer
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static uint
parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
{
}
/**
- * parse_pkt - parse recieved AgentX packet
- * @p:
- * @pkt: packet buffer
- * @size: number of packet bytes in buffer
- * retval number of byte parsed
+ * parse_pkt - parse received AgentX packet
+ * @p: SNMP protocol instance
+ * @pkt: first byte of PDU inside RX-buffer
+ * @size: number of bytes received from a socket
+ * @skip: length of header that stays still in partial processing
*
- * Returns number of bytes parsed from RX-buffer.
+ * Return number of bytes parsed from RX-buffer.
*/
static uint
parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
}
+/*
+ * parse_response - parse an agentx-Response-PDU
+ * @p: SNMP protocol instance
+ * @res: pointer of agentx-Response-PDU header in RX-buffer
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static uint
parse_response(struct snmp_proto *p, byte *res, uint size)
{
default:
/* erronous packet should be dropped quietly */
// TODO correct error?
- snmp_log("recieved response with error '%s'", snmp_errs[get_u16(&r->error) - SNMP_ERR_SHIFT]);
+ snmp_log("received response with error '%s'", snmp_errs[get_u16(&r->error)]);
break;
}
return pkt_size + AGENTX_HEADER_SIZE;
}
+/*
+ * snmp_register_mibs - register all MIB subtrees
+ * @p: SNMP protocol instance
+ */
static void
snmp_register_mibs(struct snmp_proto *p)
{
/* snmp_ospf_regsiter(p); ... */
}
+/*
+ * do_response - act on agentx-Response-PDU and protocol state
+ * @p: SNMP protocol instance
+ * @buf: RX-buffer with PDU bytes
+ * @size: number of bytes received from a socket
+ *
+ * Return number of bytes parsed from RX-buffer.
+ */
static void
do_response(struct snmp_proto *p, byte *buf, uint size)
{
{
case SNMP_INIT:
case SNMP_LOCKED:
- /* silent drop of recieved packet */
+ /* silent drop of received packet */
break;
case SNMP_OPEN:
- /* copy session info from recieved packet */
+ /* copy session info from received packet */
p->session_id = LOAD_U32(h->session_id, byte_ord);
refresh_ids(p, h);
}
}
+/*
+ * snmp_get_mib_class - classify MIB tree belongings of OID
+ * @oid: OID to be classified based on prefix
+ */
u8
snmp_get_mib_class(const struct oid *oid)
{
}
}
-/* return 0 if the created varbind type is END_OF_MIB_VIEW, 1 otherwise */
+/*
+ * snmp_get_next - process single agentx-GetNext-PDU search range
+ * @p: SNMP protocol instance
+ * @o_start: SearchRange start OID
+ * @o_end: SearchRange end OID
+ * @c: transmit PDU context to use
+ *
+ * Return 0 if the created VarBind type is endOfMibView, 1 otherwise.
+ */
static int
snmp_get_next2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
struct snmp_pdu *c)
return 0;
}
-/* returns 0 if the created varbind has type EndOfMibView, 1 otherwise */
+/*
+ * snmp_get_bulk - process one iteration of get bulk PDU
+ * @p: SNMP protocol instance
+ * @o_start: SearchRange start OID
+ * @o_end: SearchRange end OID
+ * @state: state of get bulk PDU processing
+ * @c: transmit PDU context to use
+ *
+ * Return 0 if the created VarBind has type endOfMibView, 1 otherwise.
+ */
static int
snmp_get_bulk2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
struct agentx_bulk_state *state, struct snmp_pdu *c)
} while (o_curr && i < state->repetition);
// TODO check if the approach below works
- // it need to generate varbinds that will be only of type EndOfMibView
+ // it need to generate varbinds that will be only of type endOfMibView
/* Object Identifier fall-backs */
if (!o_curr)
o_curr = o_predecessor;
}
}
+/*
+ * update_packet_size - set PDU size
+ * @p - SNMP protocol instance
+ * @start - pointer to PDU data start (excluding header size)
+ * @end - pointer after the last PDU byte
+ *
+ * Return number of bytes in TX-buffer (including header size).
+ */
static inline uint
update_packet_size(struct snmp_proto *p, const byte *start, byte *end)
{
return AGENTX_HEADER_SIZE + s;
}
+/*
+ * response_err_ind - update response error and index
+ * @res: response PDU header
+ * @err: error status
+ * @ind: index of error, ignored for noAgentXError
+ *
+ * Update agentx-Response-PDU header fields res.error and it's res.index.
+ */
static inline void
-response_err_ind(struct agentx_response *res, uint err, uint ind)
+response_err_ind(struct agentx_response *res, enum agentx_response_errs err, u16 ind)
{
- STORE_U32(res->error, err);
+ STORE_U32(res->error, (u16) err);
if (err != AGENTX_RES_NO_ERROR && err != AGENTX_RES_PARSE_ERROR)
STORE_U32(res->index, ind);
else
STORE_U32(res->index, 0);
}
+/*
+ * parse_gets_pdu - parse received gets PDUs
+ * @p: SNMP protocol instance
+ * @pkt_start: pointer to first byte of received PDU
+ * @size: number of bytes received from a socket
+ * @skip: length of header that stays still in partial processing
+ *
+ * Gets PDUs are agentx-Get-PDU, agentx-GetNext-PDU, agentx-GetBulk-PDU.
+ *
+ * Return number of bytes parsed from RX-buffer
+ */
static uint
parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *skip)
{
/*
* If we already have written same relevant data to the TX buffer, then
* we send processed part, otherwise we don't have anything to send and
- * need to wait for more data to be recieved.
+ * need to wait for more data to be received.
*/
if (sz > size && c.index > 0)
{
return ret;
}
+/*
+ * snmp_start_subagent - send session open request
+ * @p: SNMP protocol instance
+ *
+ * Send agentx-Open-PDU with configured OID and string description.
+ */
void
snmp_start_subagent(struct snmp_proto *p)
{
mb_free(blank);
}
+/*
+ * snmp_stop_subagent - close established session
+ * @p: SNMP protocol instance
+ *
+ * Send agentx-Close-PDU on established session.
+ */
void
snmp_stop_subagent(struct snmp_proto *p)
{
- if (p->state == SNMP_STOP)
+ if (p->state == SNMP_OPEN ||
+ p->state == SNMP_REGISTER ||
+ p->state == SNMP_CONN)
close_pdu(p, AGENTX_CLOSE_SHUTDOWN);
}
-static inline int
-oid_prefix(struct oid *o, u32 *prefix, uint len)
-{
- for (uint i = 0; i < len; i++)
- if (o->ids[i] != prefix[i])
- return 0;
-
- return 1;
-}
-
+/*
+ * snmp_rx - handle received PDUs in RX-buffer in normal operation
+ * @sk: communication socket
+ * @size: number of bytes received
+ */
int
snmp_rx(sock *sk, uint size)
{
return 1;
}
-/* snmp_tx - used to reset the connection when the
- * agentx-Response-PDU was sent
+/*
+ * snmp_tx - handle empty TX-buffer during session reset
+ * @sk: communication socket
+ *
+ * The socket tx_hook is called when the TX-buffer is empty, i.e. all data was
+ * send. This function is used only when we found malformed PDU and we are
+ * resetting the established session. If called we direcly reset the session.
*/
static void
snmp_tx(sock *sk)
snmp_sock_disconnect(p, 1);
}
-/* Ping-PDU */
+/*
+ * snmp_ping - send an agentx-Ping-PDU
+ * @p: SNMP protocol instance
+ */
void
snmp_ping(struct snmp_proto *p)
{
sk_send(sk, s);
}
-static inline int
-is_bgp4_mib_prefix(struct oid *o)
-{
- if (o->prefix == SNMP_MGMT && o->ids[0] == SNMP_MIB_2 &&
- o->ids[1] == SNMP_BGP4_MIB)
- return 1;
- else
- return 0;
-}
-
-static inline int
-has_inet_prefix(struct oid *o)
-{
- return (o->n_subid > 4 && o->ids[0] == 1 &&
- o->ids[1] == 3 && o->ids[2] == 6 &&
- o->ids[3] == 1);
-}
-
/**
* snmp_search_check_end_oid - check if oid is before SearchRange end
*
* check if found oid meet the SearchRange upper bound condition in
* lexicographical order, returns boolean value
*/
-int snmp_search_check_end_oid(const struct oid *found, const struct oid *bound)
+int
+snmp_search_check_end_oid(const struct oid *found, const struct oid *bound)
{
if (snmp_is_oid_empty(bound))
return 1;
return (snmp_oid_compare(found, bound) < 0);
}
+/*
+ * search_mib - search for successor of given OID
+ * @p: SNMP protocol instance
+ * @o_start: search starting OID
+ * @o_end: search ending OID
+ * @o_curr: current OID inside @o_start, @o_end interval
+ * @c: transmit PDU context to use
+ * @result: search result state
+ *
+ * Perform a search in MIB tree in SearchRange from @o_start to @o_end.
+ * If the @o_start has set include the search is inclusive, the @o_end has
+ * always the include flag cleared. For agentx-GetNext-PDU, the o_curr is always
+ * NULL, for agentx-GetBulk-PDU it could have non-NULL value. In such case the
+ * @o_curr effectively replaces the role of @o_start. It is mandatory to pass
+ * @o_start and @o_end only allocated from @p protocol's memory pool.
+ *
+ * Return found OID or NULL.
+ */
/* tree is tree with "internet" prefix .1.3.6.1
working only with o_start, o_end allocated in heap (not from buffer)*/
static struct oid *
}
if (o_end == blank)
- mb_free((void *) blank);
+ /* cast drops const qualifier */
+ mb_free((struct oid *)blank);
return o_curr;
}
/**
- * snmp_prefixize - return prefixed oid copy if possible
+ * snmp_prefixize - return prefixed OID copy if possible
* @proto: allocation pool holder
* @oid: from packet loaded object identifier
* @byte_ord: byte order of @oid
*
- * Returns prefixed (meaning with nonzero prefix field) oid copy of @oid if
+ * Return prefixed (meaning with nonzero prefix field) oid copy of @oid if
* possible, NULL otherwise. Returned pointer is always allocated from @proto's
- * pool not a pointer to recieve buffer (from which is most likely @oid).
+ * pool not a pointer to RX-buffer (from which is most likely @oid).
*/
struct oid *
snmp_prefixize(struct snmp_proto *proto, const struct oid *oid, int byte_ord)
return new;
}
+/*
+ * snmp_mib_fill - append a AgentX VarBind to PDU
+ * @p: SNMP protocol instance
+ * @oid: OID to use as VarBind v.name
+ * @c: transmit PDU context to use
+ *
+ * Append new AgentX VarBind at the end of created PDU. The content (v.data)
+ * is handled in function specialized for given MIB subtree. The binding is
+ * created only if the v.name matches some variable name precisely.
+ */
static void
-snmp_mib_fill2(struct snmp_proto *p, struct oid *oid,
- struct snmp_pdu *c)
+snmp_mib_fill2(struct snmp_proto *p, struct oid *oid, struct snmp_pdu *c)
{
ASSUME(oid != NULL);
}
}
-/**
+/*
+ * snmp_manage_tbuf - handle situation with too short transmit buffer
+ * @p: SNMP protocol instance
+ * @c: transmit packet context to use
*
* Important note: After managing insufficient buffer size all in buffer pointers
* are invalidated!
c->size += 2048;
}
+/*
+ * prepare_response - fill buffer with AgentX PDU header
+ * @p: SNMP protocol instance
+ * @c: transmit PDU context to use
+ *
+ * Prepare known parts of AgentX packet header into the TX-buffer held by @c.
+ */
static struct agentx_response *
prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
{
ADVANCE(c->buffer, c->size, sizeof(struct agentx_response));
return r;
}
-
-
-#undef SNMP_ERR_SHIFT
u16 pad;
/* oid part */
struct oid name;
+ byte data[];
};
/* this does not work */
u32 repeaters;
};
-enum agentx_pdu {
- AGENTX_OPEN_PDU = 1,
- AGENTX_CLOSE_PDU = 2,
- AGENTX_REGISTER_PDU = 3,
- AGENTX_UNREGISTER_PDU = 4,
- AGENTX_GET_PDU = 5,
- AGENTX_GET_NEXT_PDU = 6,
- AGENTX_GET_BULK_PDU = 7,
- AGENTX_TEST_SET_PDU = 8,
- AGENTX_COMMIT_SET_PDU = 9,
- AGENTX_UNDO_SET_PDU = 10,
- AGENTX_CLEANUP_SET_PDU = 11,
- AGENTX_NOTIFY_PDU = 12,
- AGENTX_PING_PDU = 13,
- AGENTX_INDEX_ALLOCATE_PDU = 14,
- AGENTX_INDEX_DEALLOCATE_PDU = 15,
- AGENTX_ADD_AGENT_CAPS_PDU = 16,
- AGENTX_REMOVE_AGENT_CAPS_PDU = 17,
- AGENTX_RESPONSE_PDU = 18,
+enum agentx_pdu_types {
+ AGENTX_OPEN_PDU = 1, /* agentx-Open-PDU */
+ AGENTX_CLOSE_PDU = 2, /* agentx-Close-PDU */
+ AGENTX_REGISTER_PDU = 3, /* agentx-Regiter-PDU */
+ AGENTX_UNREGISTER_PDU = 4, /* agentx-Unregister-PDU */
+ AGENTX_GET_PDU = 5, /* agentx-Get-PDU */
+ AGENTX_GET_NEXT_PDU = 6, /* agentx-GetNext-PDU */
+ AGENTX_GET_BULK_PDU = 7, /* agentx-GetBulk-PDU */
+ AGENTX_TEST_SET_PDU = 8, /* agentx-TestSet-PDU */
+ AGENTX_COMMIT_SET_PDU = 9, /* agentx-CommitSet-PDU */
+ AGENTX_UNDO_SET_PDU = 10, /* agentx-UndoSet-PDU */
+ AGENTX_CLEANUP_SET_PDU = 11, /* agentx-CleanupSet-PDU */
+ AGENTX_NOTIFY_PDU = 12, /* agentx-Notify-PDU */
+ AGENTX_PING_PDU = 13, /* agentx-Ping-PDU */
+ AGENTX_INDEX_ALLOCATE_PDU = 14, /* agentx-IndexAllocate-PDU */
+ AGENTX_INDEX_DEALLOCATE_PDU = 15, /* agentx-IndexDeallocate-PDU */
+ AGENTX_ADD_AGENT_CAPS_PDU = 16, /* agentx-AddAgentCaps-PDU */
+ AGENTX_REMOVE_AGENT_CAPS_PDU = 17, /* agentx-RemoveAgentCaps-PDU */
+ AGENTX_RESPONSE_PDU = 18, /* agentx-Response-PDU */
} PACKED;
-#define AGENTX_FLAGS_MASK 0x1F
-
enum agentx_flags {
AGENTX_FLAG_BLANK = 0x00,
AGENTX_FLAG_INSTANCE_REGISTRATION = 0x01,
AGENTX_NETWORK_BYTE_ORDER = 0x10,
} PACKED;
-#define AGENTX_FLAGS (AGENTX_FLAG_INSTANCE_REGISTRATION \
+#define AGENTX_FLAGS_MASK (AGENTX_FLAG_INSTANCE_REGISTRATION \
| AGENTX_FLAG_NEW_INDEX \
| AGENTX_FLAG_ANY_INDEX \
| AGENTX_NON_DEFAULT_CONTEXT \
| AGENTX_NETWORK_BYTE_ORDER)
-/* CLOSE_PDU close reasons */
+/* agentx-Close-PDU close reasons */
enum agentx_close_reasons {
AGENTX_CLOSE_OTHER = 1,
AGENTX_CLOSE_PARSE_ERROR = 2,
} PACKED;
-/* RESPONSE_PDU - result error */
-enum agentx_response_err {
- /* response OK master <-> subagent */
- AGENTX_RES_NO_ERROR = 0,
- /* TEST_SET_PDU response errors (subagent -> master) */
- AGENTX_RES_GEN_ERROR = 5,
- AGENTX_RES_NO_ACCESS = 6,
- AGENTX_RES_WRONG_TYPE = 7,
- AGENTX_RES_WRONG_LENGTH = 8,
- AGENTX_RES_WRONG_ENCODING = 9,
- AGENTX_RES_WRONG_VALUE = 10,
- AGENTX_RES_NO_CREATION = 11,
- AGENTX_RES_INCONSISTENT_VALUE = 12,
- AGENTX_RES_RESOURCE_UNAVAILABLE = 13,
- AGENTX_RES_COMMIT_FAILED = 14,
- AGENTX_RES_UNDO_FAILED = 15,
- AGENTX_RES_NOT_WRITABLE = 17,
- AGENTX_RES_INCONSISTENT_NAME = 18,
- /* end of TEST_SET_PDU resonse errs (master -> subagent) */
- AGENTX_RES_OPEN_FAILED = 256,
- AGENTX_RES_NOT_OPEN = 257,
- AGENTX_RES_INDEX_WRONG_TYPE = 258,
- AGENTX_RES_INDEX_ALREADY_ALLOC = 259,
- AGENTX_RES_INDEX_NONE_AVAIL = 260,
- AGENTX_RES_NOT_ALLOCATED = 261,
- AGENTX_RES_UNSUPPORTED_CONTEXT = 262,
- AGENTX_RES_DUPLICATE_REGISTER = 263,
- AGENTX_RES_UNKNOWN_REGISTER = 264,
- AGENTX_RES_UNKNOWN_AGENT_CAPS = 265,
- AGENTX_RES_PARSE_ERROR = 266,
- AGENTX_RES_REQUEST_DENIED = 267,
- AGENTX_RES_PROCESSING_ERR = 268,
+/* agentx-Response-PDU - result errors */
+enum agentx_response_errs {
+ /* response error to both Administrative and SNMP messages */
+ AGENTX_RES_NO_ERROR = 0, /* noAgentXError */
+ /* response errors to SNMP messages */
+ AGENTX_RES_GEN_ERROR = 5, /* genError */
+ AGENTX_RES_NO_ACCESS = 6, /* noAccess */
+ AGENTX_RES_WRONG_TYPE = 7, /* wrongType */
+ AGENTX_RES_WRONG_LENGTH = 8, /* wrongLength */
+ AGENTX_RES_WRONG_ENCODING = 9, /* wrongEncoding */
+ AGENTX_RES_WRONG_VALUE = 10, /* wrongValue*/
+ AGENTX_RES_NO_CREATION = 11, /* noCreation */
+ AGENTX_RES_INCONSISTENT_VALUE = 12, /* inconsistentValue */
+ AGENTX_RES_RESOURCE_UNAVAILABLE = 13, /* resourceUnavailable */
+ AGENTX_RES_COMMIT_FAILED = 14, /* commitFailed */
+ AGENTX_RES_UNDO_FAILED = 15, /* undoFailed */
+ AGENTX_RES_NOT_WRITABLE = 17, /* notWritable */
+ AGENTX_RES_INCONSISTENT_NAME = 18, /* inconsistentName */
+ /* response error to Administrative messages */
+ AGENTX_RES_OPEN_FAILED = 256, /* openFailed */
+ AGENTX_RES_NOT_OPEN = 257, /* notOpen */
+ AGENTX_RES_INDEX_WRONG_TYPE = 258, /* indexWrongType */
+ AGENTX_RES_INDEX_ALREADY_ALLOC = 259, /* indexAlreadyAlloc */
+ AGENTX_RES_INDEX_NONE_AVAIL = 260, /* indexNoneAvail */
+ AGENTX_RES_NOT_ALLOCATED = 261, /* notAllocated */
+ AGENTX_RES_UNSUPPORTED_CONTEXT = 262, /* unsupportedContext */
+ AGENTX_RES_DUPLICATE_REGISTER = 263, /* duplicateRegister */
+ AGENTX_RES_UNKNOWN_REGISTER = 264, /* unknownRegister */
+ AGENTX_RES_UNKNOWN_AGENT_CAPS = 265, /* unknownAgentCaps */
+ AGENTX_RES_PARSE_ERROR = 266, /* parseError */
+ AGENTX_RES_REQUEST_DENIED = 267, /* requestDenied */
+ AGENTX_RES_PROCESSING_ERR = 268, /* processingError */
} PACKED;
/* SNMP PDU buffer info */
byte *buffer; /* pointer to buffer */
uint size; /* unused space in buffer */
int byte_ord; /* flag signaling NETWORK_BYTE_ORDER */
- enum agentx_response_err error; /* storage for result of current action */
- uint index; /* index on which the error was found */
+ enum agentx_response_errs error; /* storage for result of current action */
+ u32 index; /* index on which the error was found */
};
+#if 0
struct agentx_alloc_context {
u8 is_instance; /* flag INSTANCE_REGISTRATION */
u8 new_index; /* flag NEW_INDEX */
char *context; /* context to allocate in */
uint clen; /* length of context string */
};
+#endif
int snmp_rx(sock *sk, uint size);
int snmp_rx_stop(sock *sk, uint size);