mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
SNMP: Slow integraion of MIB tree in SNMP code
This commit is contained in:
parent
2710221a4c
commit
af9a2d4cd7
@ -1,4 +1,4 @@
|
||||
S snmp.c
|
||||
S subagent.c
|
||||
S snmp_utils.c
|
||||
S bgp_mib.c
|
||||
S bgp4_mib.c
|
||||
|
@ -1,4 +1,4 @@
|
||||
src := snmp.c snmp_utils.c subagent.c bgp_mib.c mib_tree.c
|
||||
src := snmp.c snmp_utils.c subagent.c bgp4_mib.c mib_tree.c
|
||||
obj := $(src-o-files)
|
||||
$(all-daemon)
|
||||
$(cf-local)
|
||||
|
@ -8,10 +8,12 @@
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
/* need to be first header file included */
|
||||
#include "bgp4_mib.h"
|
||||
|
||||
#include "snmp.h"
|
||||
#include "snmp_utils.h"
|
||||
#include "subagent.h"
|
||||
#include "bgp_mib.h"
|
||||
|
||||
/* hash table macros */
|
||||
#define SNMP_HASH_KEY(n) n->peer_ip
|
||||
@ -25,13 +27,21 @@
|
||||
/* hash table only store ip4 addresses */
|
||||
#define SNMP_HASH_LESS(ip1, ip2) SNMP_HASH_LESS4(ip1,ip2)
|
||||
|
||||
// TODO delete me
|
||||
#define SNMP_MANAGE_TBUF(...) (void)0
|
||||
|
||||
#define DECLARE_BGP4(addr, proto, conn, stats, config) \
|
||||
ip4_addr addr; \
|
||||
const struct bgp_proto *proto; \
|
||||
const struct bgp_conn *conn; \
|
||||
const struct bgp_stats *stats; \
|
||||
const struct bgp_config *config
|
||||
|
||||
#define POPULATE_BGP4(addr, proto, conn, stats, config) populate_bgp4(p, c, &(addr), &(proto), &(conn), &(stats), &(config))
|
||||
|
||||
/* Simply discard type */
|
||||
#define SNMP_MANAGE_TBUF(p, vb, c) snmp_manage_tbuf(p, (void **) vb, c)
|
||||
|
||||
static inline void ip4_to_oid(struct oid *oid, ip4_addr addr);
|
||||
|
||||
|
||||
static inline void
|
||||
snmp_hash_add_peer(struct snmp_proto *p, struct snmp_bgp_peer *peer)
|
||||
{
|
||||
@ -83,7 +93,7 @@ bgp_get_candidate(u32 field)
|
||||
|
||||
/*
|
||||
* First value is in secord cell of array translation_table, as the
|
||||
* SNMP_BPG_IDENTIFIER == 1
|
||||
* SNMP_BGP_IDENTIFIER == 1
|
||||
*/
|
||||
if (field > 0 && field <= ARRAY_SIZE(translation_table)- 1)
|
||||
return translation_table[field];
|
||||
@ -193,25 +203,22 @@ snmp_bgp_state(const struct oid *oid)
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
snmp_bgp_reg_ok(struct snmp_proto *p, struct agentx_response *r, struct oid *oid)
|
||||
static void
|
||||
snmp_bgp_reg_ok(struct snmp_proto *p, const struct agentx_response *res, struct snmp_registration *reg)
|
||||
{
|
||||
(void)p;
|
||||
(void)r;
|
||||
const struct oid * const oid = reg->oid;
|
||||
(void)oid;
|
||||
/* TODO: EXPENSIVE_CHECK() that
|
||||
const struct oid *in_buf = ((void *) r) + sizeof(r);
|
||||
struct oid *dup = snmp_prefixize(p, in_buf);
|
||||
ASSUME(snmp_bgp_state(oid) == snmp_bgp_state(dup));
|
||||
mb_free(dup);
|
||||
*/
|
||||
(void)p;
|
||||
(void) res;
|
||||
}
|
||||
|
||||
void
|
||||
snmp_bgp_reg_failed(struct snmp_proto *p, struct agentx_response UNUSED *r, struct oid UNUSED *oid)
|
||||
static void
|
||||
snmp_bgp_reg_failed(struct snmp_proto *p, const struct agentx_response *res, struct snmp_registration *reg)
|
||||
{
|
||||
// TODO add more sensible action
|
||||
snmp_stop_subagent(p);
|
||||
const struct oid * const oid = reg->oid;
|
||||
(void) res;
|
||||
(void)oid;
|
||||
(void)p;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -280,8 +287,9 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_
|
||||
ip4_to_oid(addr, ip4);
|
||||
}
|
||||
/* We have enough space inside the TX-buffer prepared */
|
||||
struct snmp_pdu sink = { 0 };
|
||||
snmp_varbind_ip4(addr_vb, &sink, ip4);
|
||||
struct snmp_pdu dummy = { 0 };
|
||||
dummy.sr_vb_start = addr_vb;
|
||||
snmp_varbind_ip4(&dummy, ip4);
|
||||
|
||||
{ /* BGP4-MIB::bgpPeerLastError */
|
||||
struct oid *error = &error_vb->name;
|
||||
@ -294,7 +302,9 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_
|
||||
error->ids[ENTRY_TYPE] = BGP4_MIB_LAST_ERROR;
|
||||
ip4_to_oid(error, ip4);
|
||||
}
|
||||
snmp_varbind_nstr(error_vb, &sink, last_error, 2);
|
||||
|
||||
dummy.sr_vb_start = error_vb;
|
||||
snmp_varbind_nstr(&dummy, last_error, 2);
|
||||
|
||||
{ /* BGP4-MIB::bgpPeerState */
|
||||
struct oid *state = &state_vb->name;
|
||||
@ -307,7 +317,9 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_
|
||||
state->ids[ENTRY_TYPE] = BGP4_MIB_STATE;
|
||||
ip4_to_oid(state, ip4);
|
||||
}
|
||||
snmp_varbind_int(state_vb, &sink, state_val);
|
||||
|
||||
dummy.sr_vb_start = state_vb;
|
||||
snmp_varbind_int(&dummy, state_val);
|
||||
|
||||
/* We do not send the systemUpTime.0 */
|
||||
snmp_notify_pdu(p, head, data, sz, 0);
|
||||
@ -364,9 +376,10 @@ snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp)
|
||||
}
|
||||
|
||||
void
|
||||
snmp_bgp_register(struct snmp_proto *p)
|
||||
snmp_bgp4_register(struct snmp_proto *p)
|
||||
{
|
||||
u32 bgp_mib_prefix[] = { 1, 15 };
|
||||
// TODO
|
||||
|
||||
{
|
||||
/* Register the whole BGP4-MIB::bgp root tree node */
|
||||
@ -380,6 +393,8 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
|
||||
memcpy(oid->ids, bgp_mib_prefix, sizeof(bgp_mib_prefix));
|
||||
reg->oid = oid;
|
||||
reg->reg_hook_ok = snmp_bgp_reg_ok;
|
||||
reg->reg_hook_fail = snmp_bgp_reg_failed;
|
||||
|
||||
/*
|
||||
* We set both upper bound and index to zero, therefore only single OID
|
||||
@ -390,7 +405,7 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
}
|
||||
|
||||
static int
|
||||
snmp_bgp_valid_ip4(struct oid *o)
|
||||
snmp_bgp_valid_ip4(const struct oid *o)
|
||||
{
|
||||
return snmp_valid_ip4_index(o, 5);
|
||||
}
|
||||
@ -586,6 +601,565 @@ oid_state_compare(const struct oid *oid, u8 state)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline enum snmp_search_res
|
||||
populate_bgp4(struct snmp_proto *p, struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn
|
||||
**conn, const struct bgp_stats **stats, const struct bgp_config **config)
|
||||
{
|
||||
const struct oid * const oid = &c->sr_vb_start->name;
|
||||
if (snmp_bgp_valid_ip4(oid))
|
||||
*addr = ip4_from_oid(oid);
|
||||
else
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
|
||||
struct snmp_bgp_peer *pe = snmp_hash_find(p, *addr);
|
||||
if (!pe)
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
|
||||
const struct bgp_proto *bgp_proto;
|
||||
*proto = bgp_proto = pe->bgp_proto;
|
||||
if (ipa_is_ip4(bgp_proto->remote_ip))
|
||||
{
|
||||
log(L_ERR, "%s: Found BGP protocol instance with IPv6 address", bgp_proto->p.name);
|
||||
c->error = AGENTX_RES_GEN_ERROR;
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
}
|
||||
|
||||
ip4_addr proto_ip = ipa_to_ip4(bgp_proto->remote_ip);
|
||||
if (!ip4_equal(proto_ip, pe->peer_ip))
|
||||
{
|
||||
/* Here, we could be in problem as the bgp_proto IP address could be changed */
|
||||
log(L_ERR, "%s: Stored hash key IP address and peer remote address differ.",
|
||||
bgp_proto->p.name);
|
||||
c->error = AGENTX_RES_GEN_ERROR;
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
}
|
||||
|
||||
*conn = bgp_proto->conn;
|
||||
*stats = &bgp_proto->stats;
|
||||
*config = bgp_proto->cf;
|
||||
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_bgp_version(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
if (c->sr_vb_start->name.n_subid != 4)
|
||||
{
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_NO_SUCH_INSTANCE);
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
}
|
||||
|
||||
uint sz = snmp_str_size_from_len(1);
|
||||
if (c->size < sz)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
c->size -= sz;
|
||||
snmp_varbind_nstr(c, BGP4_VERSIONS, 1);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_local_as(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, p->bgp_local_as);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_peer_id(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint fsm_state = snmp_bgp_fsm_state(bgp_proto);
|
||||
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
if (fsm_state == BGP4_MIB_OPENCONFIRM || fsm_state == BGP4_MIB_ESTABLISHED)
|
||||
// TODO last
|
||||
snmp_varbind_ip4(c, ip4_from_u32(bgp_proto->remote_id));
|
||||
else
|
||||
snmp_varbind_ip4(c, IP4_NONE);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_peer_state(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint fsm_state = snmp_bgp_fsm_state(bgp_proto);
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, fsm_state);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_admin_status(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
if (bgp_proto->p.disabled)
|
||||
snmp_varbind_int(c, AGENTX_ADMIN_STOP);
|
||||
else
|
||||
snmp_varbind_int(c, AGENTX_ADMIN_START);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_neg_version(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
uint fsm_state = snmp_bgp_fsm_state(bgp_proto);
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
if (fsm_state == BGP4_MIB_ESTABLISHED || fsm_state == BGP4_MIB_ESTABLISHED)
|
||||
snmp_varbind_int(c, BGP4_MIB_NEGOTIATED_VER_VALUE);
|
||||
else
|
||||
snmp_varbind_int(c, BGP4_MIB_NEGOTIATED_VER_NO_VALUE);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_local_addr(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_ip4(c, ipa_to_ip4(bgp_proto->local_ip));
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_local_port(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, bgp_conf->local_port);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_remove_addr(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_ip4(c, ipa_to_ip4(bgp_proto->remote_ip));
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_remote_port(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, bgp_conf->remote_port);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_remote_as(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, bgp_proto->remote_as);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_in_updates(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_counter32(c, bgp_stats->rx_updates);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_out_update(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_counter32(c, bgp_stats->tx_updates);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_in_total_msg(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_counter32(c, bgp_stats->rx_messages);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_out_total_msg(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_counter32(c, bgp_stats->tx_messages);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_last_err(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < snmp_str_size_from_len(2))
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
char last_error[2];
|
||||
snmp_bgp_last_error(bgp_proto, last_error);
|
||||
|
||||
snmp_varbind_nstr(c, last_error, 2);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_established_trans(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_counter32(c,
|
||||
bgp_stats->fsm_established_transitions);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_established_time(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
|
||||
snmp_varbind_gauge32(c,
|
||||
(current_time() - bgp_proto->last_established) TO_S);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_retry_interval(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, bgp_conf->connect_retry_time);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_hold_time(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, (bgp_conn) ? bgp_conn->hold_time : 0);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_keep_alive(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
if (!bgp_conf->hold_time)
|
||||
snmp_varbind_int(c, 0);
|
||||
else
|
||||
snmp_varbind_int(c,
|
||||
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_hold_time_conf(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, bgp_conf->hold_time);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_keep_alive_conf(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
|
||||
if (!bgp_conf->keepalive_time)
|
||||
snmp_varbind_int(c, 0);
|
||||
else
|
||||
snmp_varbind_int(c,
|
||||
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_min_as_org_interval(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* value should be in 1..65535 but is not supported by bird */
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, 0);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_route_adv_interval(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* value should be in 1..65535 but is not supported by bird */
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(c, 0);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
fill_in_update_elapsed_time(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res res;
|
||||
DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf);
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
{
|
||||
(void) snmp_set_varbind_type(c->sr_vb_start, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_gauge32(c,
|
||||
(current_time() - bgp_proto->last_rx_update) TO_S
|
||||
);
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
static struct oid *
|
||||
update_bgp_vb(struct snmp_proto *p, struct agentx_varbind **vb, u8 state, struct snmp_pdu *c)
|
||||
{
|
||||
@ -892,19 +1466,26 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
if (oid_state_compare(oid, state) == 0 && snmp_bgp_valid_ip4(oid))
|
||||
addr = ip4_from_oid(oid);
|
||||
else
|
||||
return snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
{
|
||||
snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
struct snmp_bgp_peer *pe = snmp_hash_find(p, addr);
|
||||
|
||||
if (!pe)
|
||||
return snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
{
|
||||
snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
const struct bgp_proto *bgp_proto = pe->bgp_proto;
|
||||
if (!ipa_is_ip4(bgp_proto->remote_ip))
|
||||
{
|
||||
log(L_ERR, "%s: Found BGP protocol instance with IPv6 address", bgp_proto->p.name);
|
||||
c->error = AGENTX_RES_GEN_ERROR;
|
||||
return snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
ip4_addr proto_ip = ipa_to_ip4(bgp_proto->remote_ip);
|
||||
@ -914,7 +1495,8 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
log(L_ERR, "%s: Stored hash key IP address and peer remote address differ.",
|
||||
bgp_proto->p.name);
|
||||
c->error = AGENTX_RES_GEN_ERROR;
|
||||
return snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
const struct bgp_conn *bgp_conn = bgp_proto->conn;
|
||||
@ -931,20 +1513,20 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
{
|
||||
case BGP4_MIB_S_PEER_IDENTIFIER:
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
if (fsm_state == BGP4_MIB_OPENCONFIRM || fsm_state == BGP4_MIB_ESTABLISHED)
|
||||
// TODO last
|
||||
snmp_varbind_ip4(*vb, c, ip4_from_u32(bgp_proto->remote_id));
|
||||
; //snmp_varbind_ip4(*vb, c, ip4_from_u32(bgp_proto->remote_id));
|
||||
else
|
||||
snmp_varbind_ip4(*vb, c, IP4_NONE);
|
||||
; //snmp_varbind_ip4(*vb, c, IP4_NONE);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_STATE:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, fsm_state);
|
||||
//snmp_varbind_int(*vb, c, fsm_state);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_ADMIN_STATUS:
|
||||
@ -952,9 +1534,9 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
if (bgp_proto->p.disabled)
|
||||
snmp_varbind_int(*vb, c, AGENTX_ADMIN_STOP);
|
||||
; //snmp_varbind_int(*vb, c, AGENTX_ADMIN_STOP);
|
||||
else
|
||||
snmp_varbind_int(*vb, c, AGENTX_ADMIN_START);
|
||||
; //snmp_varbind_int(*vb, c, AGENTX_ADMIN_START);
|
||||
|
||||
break;
|
||||
|
||||
@ -962,10 +1544,12 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
uint fsm_state = snmp_bgp_fsm_state(bgp_proto);
|
||||
|
||||
if (fsm_state == BGP4_MIB_ESTABLISHED || fsm_state == BGP4_MIB_ESTABLISHED)
|
||||
snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_VALUE);
|
||||
; //snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_VALUE);
|
||||
else
|
||||
snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_NO_VALUE);
|
||||
; //snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_NO_VALUE);
|
||||
|
||||
break;
|
||||
|
||||
@ -973,78 +1557,78 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->local_ip));
|
||||
; //snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->local_ip));
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_LOCAL_PORT:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, bgp_conf->local_port);
|
||||
; //snmp_varbind_int(*vb, c, bgp_conf->local_port);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_REMOTE_ADDR:
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->remote_ip));
|
||||
; //snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->remote_ip));
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_REMOTE_PORT:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, bgp_conf->remote_port);
|
||||
; //snmp_varbind_int(*vb, c, bgp_conf->remote_port);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_REMOTE_AS:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, bgp_proto->remote_as);
|
||||
; //snmp_varbind_int(*vb, c, bgp_proto->remote_as);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_RX_UPDATES: /* bgpPeerInUpdates */
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_counter32(*vb, c, bgp_stats->rx_updates);
|
||||
; //snmp_varbind_counter32(*vb, c, bgp_stats->rx_updates);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_TX_UPDATES: /* bgpPeerOutUpdate */
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_counter32(*vb, c, bgp_stats->tx_updates);
|
||||
; //snmp_varbind_counter32(*vb, c, bgp_stats->tx_updates);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_RX_MESSAGES: /* bgpPeerInTotalMessages */
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_counter32(*vb, c, bgp_stats->rx_messages);
|
||||
; //snmp_varbind_counter32(*vb, c, bgp_stats->rx_messages);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_TX_MESSAGES: /* bgpPeerOutTotalMessages */
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_counter32(*vb, c, bgp_stats->tx_messages);
|
||||
; //snmp_varbind_counter32(*vb, c, bgp_stats->tx_messages);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_LAST_ERROR:
|
||||
if (c->size < snmp_str_size_from_len(2))
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_nstr(*vb, c, last_error, 2);
|
||||
; //snmp_varbind_nstr(*vb, c, last_error, 2);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_FSM_TRANSITIONS:
|
||||
if (c->size < AGENTX_TYPE_COUNTER32_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_counter32(*vb, c,
|
||||
bgp_stats->fsm_established_transitions);
|
||||
//snmp_varbind_counter32(*vb, c,
|
||||
// bgp_stats->fsm_established_transitions);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_FSM_ESTABLISHED_TIME:
|
||||
@ -1052,22 +1636,22 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
|
||||
snmp_varbind_gauge32(*vb, c,
|
||||
(current_time() - bgp_proto->last_established) TO_S);
|
||||
//snmp_varbind_gauge32(*vb, c,
|
||||
// (current_time() - bgp_proto->last_established) TO_S);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_RETRY_INTERVAL: /* retry inverval value should be != 0 */
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, bgp_conf->connect_retry_time);
|
||||
//snmp_varbind_int(*vb, c, bgp_conf->connect_retry_time);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_HOLD_TIME: /* hold time should be == 0 or in 3..65535 */
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, (bgp_conn) ? bgp_conn->hold_time : 0);
|
||||
//snmp_varbind_int(*vb, c, (bgp_conn) ? bgp_conn->hold_time : 0);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_KEEPALIVE:
|
||||
@ -1075,17 +1659,17 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
if (!bgp_conf->hold_time)
|
||||
snmp_varbind_int(*vb, c, 0);
|
||||
; //snmp_varbind_int(*vb, c, 0);
|
||||
else
|
||||
snmp_varbind_int(*vb, c,
|
||||
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
; //snmp_varbind_int(*vb, c,
|
||||
// (bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_HOLD_TIME_CONFIGURED:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, bgp_conf->hold_time);
|
||||
//snmp_varbind_int(*vb, c, bgp_conf->hold_time);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_KEEPALIVE_CONFIGURED:
|
||||
@ -1094,10 +1678,10 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
|
||||
|
||||
if (!bgp_conf->keepalive_time)
|
||||
snmp_varbind_int(*vb, c, 0);
|
||||
; //snmp_varbind_int(*vb, c, 0);
|
||||
else
|
||||
snmp_varbind_int(*vb, c,
|
||||
(bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
; //snmp_varbind_int(*vb, c,
|
||||
// (bgp_conn) ? bgp_conn->keepalive_time : 0);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_ORIGINATION_INTERVAL:
|
||||
@ -1105,7 +1689,7 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, 0);
|
||||
//snmp_varbind_int(*vb, c, 0);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_MIN_ROUTE_ADVERTISEMENT:
|
||||
@ -1113,16 +1697,16 @@ bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_p
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, 0);
|
||||
//snmp_varbind_int(*vb, c, 0);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_gauge32(*vb, c,
|
||||
(current_time() - bgp_proto->last_rx_update) TO_S
|
||||
);
|
||||
//snmp_varbind_gauge32(*vb, c,
|
||||
//(current_time() - bgp_proto->last_rx_update) TO_S
|
||||
//);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_END:
|
||||
@ -1167,21 +1751,21 @@ bgp_fill_static(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pd
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
c->size -= sz;
|
||||
snmp_varbind_nstr(*vb, c, BGP4_VERSIONS, 1);
|
||||
//snmp_varbind_nstr(*vb, c, BGP4_VERSIONS, 1);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_LOCAL_AS:
|
||||
if (c->size < AGENTX_TYPE_INT_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_int(*vb, c, p->bgp_local_as);
|
||||
//snmp_varbind_int(*vb, c, p->bgp_local_as);
|
||||
break;
|
||||
|
||||
case BGP4_MIB_S_IDENTIFIER:
|
||||
if (c->size < AGENTX_TYPE_IP4_SIZE)
|
||||
SNMP_MANAGE_TBUF(p, vb, c);
|
||||
|
||||
snmp_varbind_ip4(*vb, c, p->bgp_local_id);
|
||||
//snmp_varbind_ip4(*vb, c, p->bgp_local_id);
|
||||
break;
|
||||
|
||||
default:
|
@ -1,9 +1,29 @@
|
||||
#ifndef _BIRD_SNMP_BGP_MIB_H_
|
||||
#define _BIRD_SNMP_BGP_MIB_H_
|
||||
#ifndef _BIRD_SNMP_BGP4_MIB_H_
|
||||
#define _BIRD_SNMP_BGP4_MIB_H_
|
||||
|
||||
#ifdef _BIRD_SNMP_SUBAGENT_H_
|
||||
#define BIRD_SNMP_BGP4_SKIP
|
||||
#endif
|
||||
|
||||
#include "snmp.h"
|
||||
#include "proto/bgp/bgp.h"
|
||||
|
||||
void snmp_bgp4_register(struct snmp_proto *p);
|
||||
|
||||
struct bgp4_mib {
|
||||
enum snmp_tags tag; /* always BGP4_MIB, see subagent.h for more details */
|
||||
|
||||
ip4_addr addr;
|
||||
const struct bgp_proto *bgp_proto;
|
||||
const struct bgp_conn *bgp_conn;
|
||||
const struct bgp_stats *bgp_stats;
|
||||
const struct bgp_config *bgp_conf;
|
||||
};
|
||||
|
||||
#include "subagent.h"
|
||||
|
||||
#ifndef BIRD_SNMP_BGP4_SKIP
|
||||
|
||||
#define BGP4_MIB 15
|
||||
|
||||
/* peers attributes */
|
||||
@ -40,11 +60,6 @@ enum bgp4_mib_peer_entry_row {
|
||||
#define BGP4_MIB_NEGOTIATED_VER_VALUE 4
|
||||
#define BGP4_MIB_NEGOTIATED_VER_NO_VALUE 0
|
||||
|
||||
|
||||
void snmp_bgp_register(struct snmp_proto *p);
|
||||
void snmp_bgp_reg_ok(struct snmp_proto *p, struct agentx_response *r, struct oid *oid);
|
||||
void snmp_bgp_reg_failed(struct snmp_proto *p, struct agentx_response *r, struct oid *oid);
|
||||
|
||||
u8 snmp_bgp_get_valid(u8 state);
|
||||
u8 snmp_bgp_getnext_valid(u8 state);
|
||||
|
||||
@ -127,3 +142,5 @@ STATIC_ASSERT(BGP4_MIB_ESTABLISHED == BS_ESTABLISHED + 1);
|
||||
#define BGP4_MIB_BACKWARD_TRANS_NOTIFICATION 2
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -18,7 +18,7 @@ CF_DEFINES
|
||||
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(SNMP, PROTOCOL, BPG, LOCAL, AS, REMOTE, ADDRESS, PORT, DESCRIPTION,
|
||||
CF_KEYWORDS(SNMP, PROTOCOL, BGP, LOCAL, AS, REMOTE, ADDRESS, PORT, DESCRIPTION,
|
||||
TIMEOUT, PRIORITY, CONTEXT, DEFAULT, MESSAGE)
|
||||
|
||||
CF_GRAMMAR
|
||||
|
@ -24,10 +24,13 @@ struct mib_node {
|
||||
u32 child_len;
|
||||
};
|
||||
|
||||
struct mib_walk_state;
|
||||
|
||||
struct mib_leaf {
|
||||
struct mib_node_core c;
|
||||
enum snmp_search_res (*filler)(struct snmp_proto *p, struct snmp_pdu *c);
|
||||
//enum snmp_search_res (*filler)(struct snmp_proto_pdu *pc, struct agentx_varbind **vb);
|
||||
int (*call_next)(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *state);
|
||||
enum agentx_type type;
|
||||
int size;
|
||||
};
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
* The SNMP protocol is divided into several parts: |snmp.c| which implements
|
||||
* the BIRD intergration, |subagent.c| contains functions for creating and
|
||||
* parsing packets, |bgp_mib.c| takes care of the bgp MIB subtree of standard
|
||||
* parsing packets, |bgp4_mib.c| takes care of the bgp MIB subtree of standard
|
||||
* BGP4-MIB and |snmp_utils.c| which is collections of helper functions for
|
||||
* working with OIDs, VarBinds.
|
||||
*
|
||||
@ -334,14 +334,6 @@ snmp_cleanup(struct snmp_proto *p)
|
||||
r = NULL;
|
||||
}
|
||||
|
||||
struct snmp_registered_oid *ro, *ro2;
|
||||
WALK_LIST_DELSAFE(ro, ro2, p->bgp_registered)
|
||||
{
|
||||
rem_node(&r->n);
|
||||
mb_free(ro);
|
||||
ro = NULL;
|
||||
}
|
||||
|
||||
HASH_FREE(p->bgp_hash);
|
||||
|
||||
rfree(p->lp);
|
||||
@ -507,7 +499,6 @@ snmp_start(struct proto *P)
|
||||
p->ping_timer = tm_new_init(p->pool, snmp_ping_timeout, p, p->timeout, 0);
|
||||
|
||||
init_list(&p->registration_queue);
|
||||
init_list(&p->bgp_registered);
|
||||
|
||||
/* We create copy of bonds to BGP protocols. */
|
||||
HASH_INIT(p->bgp_hash, p->pool, 10);
|
||||
|
@ -17,8 +17,7 @@
|
||||
#include "nest/bird.h"
|
||||
#include "nest/protocol.h"
|
||||
#include "filter/data.h"
|
||||
#include "proto/bgp/bgp.h"
|
||||
|
||||
#include "proto/bgp/bgp.h" // TODO remove me
|
||||
|
||||
#define SNMP_UNDEFINED 0
|
||||
#define SNMP_BGP 1
|
||||
@ -42,6 +41,11 @@ enum snmp_proto_state {
|
||||
SNMP_RESET,
|
||||
};
|
||||
|
||||
enum snmp_tags {
|
||||
EMPTY_TAG = 0,
|
||||
BGP4_TAG,
|
||||
};
|
||||
|
||||
struct snmp_bond {
|
||||
node n;
|
||||
struct proto_config *config;
|
||||
@ -81,20 +85,13 @@ struct snmp_bgp_peer {
|
||||
struct snmp_bgp_peer *next;
|
||||
};
|
||||
|
||||
struct snmp_registration {
|
||||
node n;
|
||||
u8 mib_class;
|
||||
u32 session_id;
|
||||
u32 transaction_id;
|
||||
u32 packet_id;
|
||||
struct oid *oid;
|
||||
};
|
||||
|
||||
struct snmp_registered_oid {
|
||||
node n;
|
||||
struct oid *oid;
|
||||
};
|
||||
|
||||
struct mib_tree; /* see mib_tree.h */
|
||||
|
||||
struct snmp_proto {
|
||||
struct proto p;
|
||||
struct object_lock *lock;
|
||||
@ -125,8 +122,6 @@ struct snmp_proto {
|
||||
|
||||
uint registrations_to_ack; /* counter of pending responses to register-pdu */
|
||||
list registration_queue; /* list containing snmp_register records */
|
||||
list bgp_registered; /* list of currently registered bgp oids
|
||||
* (struct snmp_registered_oid) */
|
||||
|
||||
// map
|
||||
struct f_trie *bgp_trie;
|
||||
@ -138,6 +133,23 @@ struct snmp_proto {
|
||||
timer *ping_timer;
|
||||
btime startup_delay;
|
||||
timer *startup_timer;
|
||||
|
||||
struct mib_tree *mib_tree;
|
||||
};
|
||||
|
||||
struct snmp_registration;
|
||||
struct agentx_response; /* declared in subagent.h */
|
||||
typedef void (*snmp_reg_hook_t)(struct snmp_proto *p, const struct agentx_response *res, struct snmp_registration *reg);
|
||||
|
||||
struct snmp_registration {
|
||||
node n;
|
||||
u8 mib_class;
|
||||
u32 session_id;
|
||||
u32 transaction_id;
|
||||
u32 packet_id;
|
||||
struct oid *oid;
|
||||
snmp_reg_hook_t reg_hook_ok; /* hook called when successful response to OID registration is recieved */
|
||||
snmp_reg_hook_t reg_hook_fail; /* hook called when OID registration fail */
|
||||
};
|
||||
|
||||
//void snmp_tx(sock *sk);
|
||||
|
@ -65,7 +65,7 @@ snmp_varbind_set_name_len(struct snmp_proto *p, struct agentx_varbind **vb, u8 l
|
||||
uint diff_size = (len - LOAD_U8(oid->n_subid)) * sizeof(u32);
|
||||
if (c->size < diff_size)
|
||||
{
|
||||
snmp_manage_tbuf(p, (void **) vb, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
oid = &(*vb)->name;
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ snmp_varbind_duplicate_hdr(struct snmp_proto *p, struct agentx_varbind **vb, str
|
||||
ASSUME(vb != NULL && *vb != NULL);
|
||||
uint hdr_size = snmp_varbind_header_size(*vb);
|
||||
if (c->size < hdr_size)
|
||||
snmp_manage_tbuf(p, (void **) vb, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
ASSERT(c->size >= hdr_size);
|
||||
byte *buffer = c->buffer;
|
||||
@ -260,12 +260,38 @@ snmp_varbind_hdr_size_from_oid(const struct oid *oid)
|
||||
*
|
||||
* This function assumes valid @t.
|
||||
*/
|
||||
inline void
|
||||
inline enum snmp_search_res
|
||||
snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t)
|
||||
{
|
||||
ASSUME(t != AGENTX_INVALID);
|
||||
STORE_U16(vb->type, t);
|
||||
STORE_U16(vb->reserved, 0);
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case AGENTX_END_OF_MIB_VIEW:
|
||||
return SNMP_SEARCH_END_OF_VIEW;
|
||||
case AGENTX_NO_SUCH_OBJECT:
|
||||
return SNMP_SEARCH_NO_OBJECT;
|
||||
case AGENTX_NO_SUCH_INSTANCE:
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
|
||||
/* valid varbind types */
|
||||
case AGENTX_INTEGER:
|
||||
case AGENTX_OCTET_STRING:
|
||||
case AGENTX_NULL:
|
||||
case AGENTX_OBJECT_ID:
|
||||
case AGENTX_IP_ADDRESS:
|
||||
case AGENTX_COUNTER_32:
|
||||
case AGENTX_GAUGE_32:
|
||||
case AGENTX_TIME_TICKS:
|
||||
case AGENTX_OPAQUE:
|
||||
case AGENTX_COUNTER_64:
|
||||
return SNMP_SEARCH_OK;
|
||||
|
||||
default:
|
||||
die("invalid varbind type");
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal wrapper */
|
||||
@ -798,45 +824,46 @@ snmp_varbind_type32(struct agentx_varbind *vb, struct snmp_pdu *c, enum agentx_t
|
||||
}
|
||||
|
||||
inline void
|
||||
snmp_varbind_int(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val)
|
||||
snmp_varbind_int(struct snmp_pdu *c, u32 val)
|
||||
{
|
||||
snmp_varbind_type32(vb, c, AGENTX_INTEGER, val);
|
||||
snmp_varbind_type32(c->sr_vb_start, c, AGENTX_INTEGER, val);
|
||||
}
|
||||
|
||||
inline void
|
||||
snmp_varbind_counter32(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val)
|
||||
snmp_varbind_counter32(struct snmp_pdu *c, u32 val)
|
||||
{
|
||||
snmp_varbind_type32(vb, c, AGENTX_COUNTER_32, val);
|
||||
snmp_varbind_type32(c->sr_vb_start, c, AGENTX_COUNTER_32, val);
|
||||
}
|
||||
|
||||
inline void
|
||||
snmp_varbind_ticks(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val)
|
||||
snmp_varbind_ticks(struct snmp_pdu *c, u32 val)
|
||||
{
|
||||
snmp_varbind_type32(vb, c, AGENTX_TIME_TICKS, val);
|
||||
snmp_varbind_type32(c->sr_vb_start, c, AGENTX_TIME_TICKS, val);
|
||||
}
|
||||
|
||||
inline void
|
||||
snmp_varbind_gauge32(struct agentx_varbind *vb, struct snmp_pdu *c, s64 time)
|
||||
snmp_varbind_gauge32(struct snmp_pdu *c, s64 time)
|
||||
{
|
||||
snmp_varbind_type32(vb, c, AGENTX_GAUGE_32, MAX(0, MIN(time, UINT32_MAX)));
|
||||
snmp_varbind_type32(c->sr_vb_start, c,
|
||||
AGENTX_GAUGE_32, MAX(0, MIN(time, UINT32_MAX)));
|
||||
}
|
||||
|
||||
inline void
|
||||
snmp_varbind_ip4(struct agentx_varbind *vb, struct snmp_pdu *c, ip4_addr addr)
|
||||
snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr)
|
||||
{
|
||||
snmp_set_varbind_type(vb, AGENTX_IP_ADDRESS);
|
||||
c->buffer = snmp_put_ip4(snmp_varbind_data(vb), addr);
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_IP_ADDRESS);
|
||||
c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr);
|
||||
}
|
||||
|
||||
// TODO doc string, we have already the varbind prepared
|
||||
inline byte *
|
||||
snmp_varbind_nstr2(struct agentx_varbind *vb, uint size, const char *str, uint len)
|
||||
snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len)
|
||||
{
|
||||
if (size < snmp_str_size_from_len(len))
|
||||
return NULL;
|
||||
|
||||
snmp_set_varbind_type(vb, AGENTX_OCTET_STRING);
|
||||
return snmp_put_nstr(snmp_varbind_data(vb), str, len);
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_OCTET_STRING);
|
||||
return snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -851,10 +878,10 @@ snmp_varbind_nstr2(struct agentx_varbind *vb, uint size, const char *str, uint l
|
||||
* more info.
|
||||
*/
|
||||
void
|
||||
snmp_varbind_nstr(struct agentx_varbind *vb, struct snmp_pdu *c, const char *str, uint len)
|
||||
snmp_varbind_nstr(struct snmp_pdu *c, const char *str, uint len)
|
||||
{
|
||||
snmp_set_varbind_type(vb, AGENTX_OCTET_STRING);
|
||||
c->buffer = snmp_put_nstr(snmp_varbind_data(vb), str, len);
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_OCTET_STRING);
|
||||
c->buffer = snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
|
||||
}
|
||||
|
||||
inline enum agentx_type
|
||||
|
@ -14,7 +14,7 @@ uint snmp_pkt_len(const byte *start, const byte *end);
|
||||
/*
|
||||
* AgentX - Variable Binding (VarBind) type utils
|
||||
*/
|
||||
void snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t);
|
||||
enum snmp_search_res snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t);
|
||||
enum agentx_type snmp_get_varbind_type(const struct agentx_varbind *vb);
|
||||
int agentx_type_size(enum agentx_type t);
|
||||
|
||||
@ -74,12 +74,12 @@ int snmp_test_close_reason(byte value);
|
||||
/* Functions filling buffer a typed value */
|
||||
struct agentx_varbind *snmp_create_varbind(byte *buf, struct oid *oid);
|
||||
struct agentx_varbind *snmp_create_varbind_null(byte *buf);
|
||||
void snmp_varbind_int(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_counter32(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_gauge32(struct agentx_varbind *vb, struct snmp_pdu *c, s64 time);
|
||||
void snmp_varbind_ticks(struct agentx_varbind *vb, struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_ip4(struct agentx_varbind *vb, struct snmp_pdu *c, ip4_addr addr);
|
||||
void snmp_varbind_nstr(struct agentx_varbind *vb, struct snmp_pdu *c, const char *str, uint len);
|
||||
void snmp_varbind_int(struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_counter32(struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_gauge32(struct snmp_pdu *c, s64 time);
|
||||
void snmp_varbind_ticks(struct snmp_pdu *c, u32 val);
|
||||
void snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr);
|
||||
void snmp_varbind_nstr(struct snmp_pdu *c, const char *str, uint len);
|
||||
|
||||
/* Raw */
|
||||
byte *snmp_no_such_object(byte *buf, struct agentx_varbind *vb, struct oid *oid);
|
||||
|
@ -10,8 +10,9 @@
|
||||
|
||||
#include "lib/unaligned.h"
|
||||
#include "subagent.h"
|
||||
#include "mib_tree.h"
|
||||
#include "snmp_utils.h"
|
||||
#include "bgp_mib.h"
|
||||
#include "bgp4_mib.h"
|
||||
|
||||
/* =============================================================
|
||||
* Problems
|
||||
@ -115,40 +116,6 @@ snmp_blank_header(struct agentx_header *h, enum agentx_pdu_types type)
|
||||
snmp_header(h, type, (u8) 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
// todo switch based on oid type
|
||||
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 registration
|
||||
* failure.
|
||||
*/
|
||||
static void
|
||||
snmp_register_failed(struct snmp_proto *p, struct agentx_response *res, struct oid *oid, u8 UNUSED class)
|
||||
{
|
||||
// todo switch based on oid type
|
||||
snmp_bgp_reg_failed(p, res, oid);
|
||||
}
|
||||
|
||||
/*
|
||||
* snmp_register_ack - handle registration response
|
||||
* @p: SNMP protocol instance
|
||||
@ -161,26 +128,18 @@ snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, u8 class)
|
||||
struct snmp_registration *reg;
|
||||
WALK_LIST(reg, p->registration_queue)
|
||||
{
|
||||
// todo add support for more mib trees (other than BGP4-MIB)
|
||||
if (snmp_registration_match(reg, &res->h, class))
|
||||
{
|
||||
struct snmp_registered_oid *ro = \
|
||||
mb_alloc(p->p.pool, sizeof(struct snmp_registered_oid));
|
||||
|
||||
ro->n.prev = ro->n.next = NULL;
|
||||
|
||||
ro->oid = reg->oid;
|
||||
|
||||
rem_node(®->n);
|
||||
mb_free(reg);
|
||||
p->registrations_to_ack--;
|
||||
|
||||
add_tail(&p->bgp_registered, &ro->n);
|
||||
|
||||
if (res->error == AGENTX_RES_NO_ERROR)
|
||||
snmp_register_ok(p, res, ro->oid, class);
|
||||
reg->reg_hook_ok(p, (const struct agentx_response *) res, reg);
|
||||
else
|
||||
snmp_register_failed(p, res, ro->oid, class);
|
||||
reg->reg_hook_fail(p, (const struct agentx_response *) res, reg);
|
||||
|
||||
mb_free(reg->oid);
|
||||
mb_free(reg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -247,7 +206,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
/* Make sure that we have enough space in TX-buffer */
|
||||
if (c.size < AGENTX_HEADER_SIZE + TIMEOUT_SIZE + snmp_oid_size(oid) +
|
||||
+ snmp_str_size(cf->description))
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
struct agentx_header *h = (void *) c.buffer;
|
||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||
@ -293,6 +252,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
||||
struct snmp_pdu c;
|
||||
snmp_pdu_context(&c, sk);
|
||||
|
||||
// TODO use more readable anonymous structure decl.
|
||||
#define UPTIME_SIZE \
|
||||
(6 * sizeof(u32)) /* sizeof( { u32 vb_type, u32 oid_hdr, u32 ids[4] } ) */
|
||||
#define TRAP0_HEADER_SIZE \
|
||||
@ -306,7 +266,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
||||
|
||||
/* Make sure that we have enough space in TX-buffer */
|
||||
if (c.size < sz)
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
struct agentx_header *h = (void *) c.buffer;
|
||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||
@ -332,7 +292,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
||||
|
||||
/* TODO use time from last reconfiguration instead? [config->load_time] */
|
||||
btime uptime = current_time() - boot_time;
|
||||
snmp_varbind_ticks(vb, &c, (uptime TO_S) / 100);
|
||||
snmp_varbind_ticks(&c, (uptime TO_S) / 100);
|
||||
ASSUME(snmp_test_varbind(vb));
|
||||
ADVANCE(c.buffer, c.size, snmp_varbind_size_unsafe(vb));
|
||||
}
|
||||
@ -401,7 +361,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en
|
||||
((bound > 1) ? BOUND_SIZE : 0);
|
||||
|
||||
if (c.size < sz)
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
struct agentx_header *h = (void *) c.buffer;
|
||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||
@ -483,7 +443,7 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
|
||||
|
||||
#define REASON_SIZE sizeof(u32)
|
||||
if (c.size < AGENTX_HEADER_SIZE + REASON_SIZE)
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
struct agentx_header *h = (void *) c.buffer;
|
||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||
@ -614,7 +574,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
snmp_pdu_context(&c, sk);
|
||||
|
||||
if (c.size < AGENTX_HEADER_SIZE)
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
res = prepare_response(p, &c);
|
||||
|
||||
@ -675,7 +635,6 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
{
|
||||
TRACE(D_PACKETS, "SNMP SET action failed (not writable)");
|
||||
/* This is a recoverable error, we do not need to reset the connection */
|
||||
//response_err_ind(p, res, AGENTX_RES_RESOURCE_UNAVAILABLE, c.index + 1);
|
||||
response_err_ind(p, res, AGENTX_RES_NOT_WRITABLE, c.index + 1);
|
||||
}
|
||||
|
||||
@ -711,7 +670,7 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons
|
||||
struct snmp_pdu c;
|
||||
snmp_pdu_context(&c, p->sock);
|
||||
if (c.size < sizeof(struct agentx_response))
|
||||
snmp_manage_tbuf(p, NULL, &c);
|
||||
snmp_manage_tbuf(p, &c);
|
||||
|
||||
struct agentx_response *r = prepare_response(p, &c);
|
||||
|
||||
@ -786,6 +745,7 @@ parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
if (pkt_size != 0)
|
||||
{
|
||||
// TODO should we free even for malformed packets ??
|
||||
// TODO -> check that data is not freed
|
||||
return AGENTX_HEADER_SIZE;
|
||||
}
|
||||
|
||||
@ -981,8 +941,7 @@ parse_response(struct snmp_proto *p, byte *res)
|
||||
void
|
||||
snmp_register_mibs(struct snmp_proto *p)
|
||||
{
|
||||
snmp_bgp_register(p);
|
||||
/* snmp_ospf_regsiter(p); ... */
|
||||
snmp_bgp4_register(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1071,7 +1030,8 @@ snmp_get_mib_class(const struct oid *oid)
|
||||
*
|
||||
* Return 0 if the created VarBind type is endOfMibView, 1 otherwise.
|
||||
*/
|
||||
static int
|
||||
// TODO remove me
|
||||
static int UNUSED
|
||||
snmp_get_next2(struct snmp_proto *p, struct agentx_varbind **vb_search, struct oid *o_end, struct snmp_pdu *c)
|
||||
{
|
||||
enum snmp_search_res r;
|
||||
@ -1111,7 +1071,7 @@ snmp_get_next2(struct snmp_proto *p, struct agentx_varbind **vb_search, struct o
|
||||
|
||||
o_start = &(*vb_search)->name;
|
||||
if (c->size < snmp_varbind_hdr_size_from_oid(o_start))
|
||||
snmp_manage_tbuf(p, (void **) vb_search, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
snmp_set_varbind_type(*vb_search, AGENTX_END_OF_MIB_VIEW);
|
||||
return 0;
|
||||
@ -1186,7 +1146,7 @@ snmp_get_next3(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
||||
}
|
||||
|
||||
if (c->size < snmp_varbind_hdr_size_from_oid(o_start))
|
||||
snmp_manage_tbuf(p, (void **) vb, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
vb = snmp_create_varbind(c->buffer, o_start);
|
||||
vb->type = AGENTX_END_OF_MIB_VIEW;
|
||||
@ -1368,7 +1328,7 @@ snmp_oid_prefixize(struct snmp_proto *p, const struct oid *oid, struct snmp_pdu
|
||||
uint oid_size = snmp_oid_size(oid);
|
||||
|
||||
if (c->size < oid_size)
|
||||
snmp_manage_tbuf(p, NULL, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
// TODO check if the @oid is prefixable
|
||||
ASSERT(c->size >= oid_size);
|
||||
@ -1393,7 +1353,7 @@ snmp_vb_to_tx(struct snmp_proto *p, const struct oid *oid, struct snmp_pdu *c)
|
||||
{
|
||||
uint vb_hdr_size = snmp_varbind_hdr_size_from_oid(oid);
|
||||
if (c->size < vb_hdr_size)
|
||||
snmp_manage_tbuf(p, NULL, c);
|
||||
snmp_manage_tbuf(p, c);
|
||||
|
||||
ASSERT(c->size >= vb_hdr_size);
|
||||
struct agentx_varbind *vb = (void *) c->buffer;
|
||||
@ -1500,6 +1460,78 @@ parse_gets_error(struct snmp_proto *p, struct snmp_pdu *c, uint len)
|
||||
|
||||
return len + AGENTX_HEADER_SIZE;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
snmp_mib_fill2(struct snmp_proto *p, struct snmp_pdu *c, mib_node_u *mib_node)
|
||||
{
|
||||
if (!mib_node || !mib_node_is_leaf(mib_node))
|
||||
{
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_NO_SUCH_OBJECT);
|
||||
ADVANCE(c->buffer, c->size, snmp_varbind_header_size(c->sr_vb_start));
|
||||
return AGENTX_NO_SUCH_OBJECT;
|
||||
}
|
||||
|
||||
struct mib_leaf *leaf = &mib_node->leaf;
|
||||
|
||||
return leaf->filler(p, c);
|
||||
}
|
||||
|
||||
void
|
||||
snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk)
|
||||
{
|
||||
mib_node_u *node;
|
||||
node = mib_tree_find(p->mib_tree, walk, &c->sr_vb_start->name);
|
||||
|
||||
(void) snmp_mib_fill2(p, c, node);
|
||||
}
|
||||
|
||||
int
|
||||
snmp_get_next_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk)
|
||||
{
|
||||
mib_node_u *node;
|
||||
node = mib_tree_find(p->mib_tree, walk, &c->sr_vb_start->name);
|
||||
|
||||
int inclusive = c->sr_vb_start->name.include;
|
||||
|
||||
int move_next;
|
||||
if (!node && inclusive)
|
||||
move_next = 1;
|
||||
else if (!node && !inclusive)
|
||||
move_next = 1;
|
||||
else if (node && inclusive && mib_node_is_leaf(node))
|
||||
move_next = 0;
|
||||
else if (node && inclusive)
|
||||
move_next = 1;
|
||||
else if (node && !inclusive)
|
||||
move_next = 0;
|
||||
|
||||
struct mib_leaf *leaf = &node->leaf;
|
||||
if (move_next && node && mib_node_is_leaf(node))
|
||||
move_next = leaf->call_next(p, c, walk);
|
||||
|
||||
if (move_next)
|
||||
node = (mib_node_u *) mib_tree_walk_next_leaf(p->mib_tree, walk);
|
||||
|
||||
enum snmp_search_res res;
|
||||
res = snmp_mib_fill2(p, c, node);
|
||||
|
||||
if (res != SNMP_SEARCH_OK)
|
||||
snmp_set_varbind_type(c->sr_vb_start, AGENTX_END_OF_MIB_VIEW);
|
||||
|
||||
return res == SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
void
|
||||
snmp_get_bulk_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk, struct agentx_bulk_state *bulk)
|
||||
{
|
||||
if (c->index >= bulk->getbulk.non_repeaters)
|
||||
bulk->repeaters++;
|
||||
|
||||
// store the o_start and o_end
|
||||
|
||||
bulk->has_any |= snmp_get_next_pdu(p, c, walk);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse_gets_pdu - parse received gets PDUs
|
||||
* @p: SNMP protocol instance
|
||||
@ -1513,9 +1545,7 @@ static uint
|
||||
parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
{
|
||||
// TODO checks for c.size underflow
|
||||
//struct agentx_varbind *vb = NULL;
|
||||
struct agentx_varbind *vb_start = NULL;
|
||||
struct oid *o_end = NULL;
|
||||
struct mib_walk_state walk;
|
||||
byte *pkt = pkt_start;
|
||||
|
||||
struct agentx_header *h = (void *) pkt;
|
||||
@ -1530,7 +1560,6 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
* Get-Bulk processing stops if all the varbind have type END_OF_MIB_VIEW
|
||||
* has_any is true if some varbind has type other than END_OF_MIB_VIEW
|
||||
*/
|
||||
int has_any = 0;
|
||||
struct agentx_bulk_state bulk_state = { };
|
||||
if (h->type == AGENTX_GET_BULK_PDU)
|
||||
{
|
||||
@ -1544,6 +1573,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
struct agentx_getbulk *bulk_info = (void *) pkt;
|
||||
ADVANCE(pkt, pkt_size, sizeof(struct agentx_getbulk));
|
||||
|
||||
//TODO: bulk_state = AGENTX_BULK_STATE_INITIALIZER(bulk_info);
|
||||
bulk_state = (struct agentx_bulk_state) {
|
||||
.getbulk = {
|
||||
.non_repeaters = LOAD_U32(bulk_info->non_repeaters),
|
||||
@ -1552,6 +1582,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
/* In contrast to the RFC, we use 0-based indices. */
|
||||
.index = 0,
|
||||
.repetition = 0,
|
||||
.has_any = 0,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1592,30 +1623,34 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
/* We don't too to check for oversided OID because the PDU has 8k size limit */
|
||||
|
||||
/* We create copy of OIDs outside of rx-buffer and also prefixize them */
|
||||
vb_start = snmp_vb_to_tx(p, o_start_rx, &c);
|
||||
o_end = snmp_oid_to_scratch(o_end_rx);
|
||||
c.sr_vb_start = snmp_vb_to_tx(p, o_start_rx, &c);
|
||||
c.sr_o_end = snmp_oid_to_scratch(o_end_rx);
|
||||
|
||||
ASSERT(vb_start);
|
||||
ASSERT(o_end);
|
||||
ASSERT(c.sr_vb_start); // TODO implement failed parsing logic
|
||||
ASSERT(c.sr_o_end);
|
||||
|
||||
if (!snmp_is_oid_empty(o_end) && snmp_oid_compare(&vb_start->name, o_end) > 0)
|
||||
if (!snmp_is_oid_empty(c.sr_o_end) &&
|
||||
snmp_oid_compare(&c.sr_vb_start->name, c.sr_o_end) > 0)
|
||||
{
|
||||
c.error = AGENTX_RES_GEN_ERROR;
|
||||
return parse_gets_error(p, &c, pkt_size);
|
||||
}
|
||||
|
||||
/* TODO find mib_class, check if type is GET of GET_NEXT, act accordingly */
|
||||
switch (h->type)
|
||||
{
|
||||
case AGENTX_GET_PDU:
|
||||
snmp_mib_fill(p, &vb_start, &c);
|
||||
snmp_get_pdu(p, &c, &walk);
|
||||
//snmp_mib_fill(p, &vb_start, &c);
|
||||
break;
|
||||
|
||||
case AGENTX_GET_NEXT_PDU:
|
||||
snmp_get_next2(p, &vb_start, o_end, &c);
|
||||
snmp_get_next_pdu(p, &c, &walk);
|
||||
//snmp_get_next2(p, &vb_start, o_end, &c);
|
||||
break;
|
||||
|
||||
case AGENTX_GET_BULK_PDU:
|
||||
snmp_get_bulk_pdu(p, &c, &walk, &bulk_state);
|
||||
#if 0
|
||||
if (c.index >= bulk_state.getbulk.non_repeaters)
|
||||
bulk_state.repeaters++;
|
||||
|
||||
@ -1624,14 +1659,15 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
/* The behavior of GetBulk pdu in the first iteration is
|
||||
* identical to GetNext pdu. */
|
||||
has_any = snmp_get_next2(p, &vb_start, o_end, &c) || has_any;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
die("incorrect usage");
|
||||
}
|
||||
|
||||
vb_start = NULL;
|
||||
o_end = NULL;
|
||||
c.sr_vb_start = NULL;
|
||||
c.sr_o_end = NULL;
|
||||
|
||||
c.index++;
|
||||
} /* while (c.error == AGENTX_RES_NO_ERROR && size > 0) */
|
||||
@ -1641,6 +1677,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
if (h->type == AGENTX_GET_BULK_PDU)
|
||||
{
|
||||
#if 0
|
||||
// TODO
|
||||
for (bulk_state.repetition++;
|
||||
has_any && bulk_state.repetition < bulk_state.getbulk.max_repetitions;
|
||||
bulk_state.repetition++)
|
||||
@ -1660,6 +1697,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start)
|
||||
|
||||
/* We send the message in TX-buffer. */
|
||||
sk_send(sk, s);
|
||||
|
||||
// TODO think through the error state
|
||||
|
||||
/* number of bytes parsed from RX-buffer */
|
||||
@ -2022,6 +2060,7 @@ snmp_prefixize(struct snmp_proto *proto, const struct oid *oid)
|
||||
static void
|
||||
snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c)
|
||||
{
|
||||
(void) p;
|
||||
ASSUME(vb != NULL && *vb != NULL);
|
||||
|
||||
struct oid *oid = &((*vb)->name);
|
||||
@ -2037,7 +2076,7 @@ snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu
|
||||
switch (mib_class)
|
||||
{
|
||||
case SNMP_CLASS_BGP:
|
||||
snmp_bgp_fill(p, vb, c);
|
||||
//snmp_bgp_fill(p, vb, c);
|
||||
break;
|
||||
|
||||
case SNMP_CLASS_INVALID:
|
||||
@ -2050,7 +2089,26 @@ snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu
|
||||
}
|
||||
|
||||
/*
|
||||
* snmp_manage_tbuf - handle situation with too short transmit buffer
|
||||
* snmp_manage_tbuf - TODO
|
||||
*/
|
||||
void
|
||||
snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
sock *sk = p->sock;
|
||||
int diff;
|
||||
if (c->sr_vb_start != NULL)
|
||||
diff = (void *) c->sr_vb_start - (void *) sk->tbuf;
|
||||
|
||||
log(L_INFO "snmp_manage_tbuf2()");
|
||||
sk_set_tbsize(sk, sk->tbsize + 2048);
|
||||
c->size += 2048;
|
||||
|
||||
if (c->sr_vb_start != NULL)
|
||||
c->sr_vb_start = (struct agentx_varbind *) (sk->tbuf + diff);
|
||||
}
|
||||
|
||||
/*
|
||||
* snmp_manage_tbuf2 - handle situation with too short transmit buffer
|
||||
* @p: SNMP protocol instance
|
||||
* @c: transmit packet context to use
|
||||
*
|
||||
@ -2058,7 +2116,7 @@ snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu
|
||||
* are invalidated!
|
||||
*/
|
||||
void
|
||||
snmp_manage_tbuf(struct snmp_proto *p, void **ptr, struct snmp_pdu *c)
|
||||
snmp_manage_tbuf2(struct snmp_proto *p, void **ptr, struct snmp_pdu *c)
|
||||
{
|
||||
sock *sk = p->sock;
|
||||
int diff;
|
||||
@ -2069,7 +2127,6 @@ snmp_manage_tbuf(struct snmp_proto *p, void **ptr, struct snmp_pdu *c)
|
||||
sk_set_tbsize(sk, sk->tbsize + 2048);
|
||||
c->size += 2048;
|
||||
|
||||
|
||||
if (ptr)
|
||||
*ptr = sk->tbuf + diff;
|
||||
}
|
||||
|
@ -191,11 +191,6 @@ struct agentx_octet_str {
|
||||
byte data[0];
|
||||
};
|
||||
|
||||
struct agentx_getbulk {
|
||||
u16 non_repeaters;
|
||||
u16 max_repetitions;
|
||||
};
|
||||
|
||||
struct agentx_response {
|
||||
struct agentx_header h;
|
||||
u32 uptime;
|
||||
@ -219,11 +214,17 @@ struct agentx_un_register_hdr {
|
||||
u8 reserved; /* always zero filled */
|
||||
};
|
||||
|
||||
struct agentx_getbulk {
|
||||
u16 non_repeaters;
|
||||
u16 max_repetitions;
|
||||
};
|
||||
|
||||
struct agentx_bulk_state {
|
||||
struct agentx_getbulk getbulk;
|
||||
u16 index;
|
||||
u16 repetition;
|
||||
u32 repeaters;
|
||||
int has_any; /* flag is clear when all responses are EndOfMibView */
|
||||
};
|
||||
|
||||
enum agentx_pdu_types {
|
||||
@ -292,17 +293,29 @@ enum agentx_response_errs {
|
||||
AGENTX_RES_PROCESSING_ERR = 268, /* processingError */
|
||||
} PACKED;
|
||||
|
||||
/* SNMP PDU TX-buffer info */
|
||||
/* SNMP PDU info */
|
||||
struct snmp_pdu {
|
||||
/* TX buffer */
|
||||
byte *buffer; /* pointer to buffer */
|
||||
uint size; /* unused space in buffer */
|
||||
|
||||
/* Search Range */
|
||||
struct agentx_varbind *sr_vb_start; /* search range starting OID inside TX buffer (final storage) */
|
||||
struct oid *sr_o_end; /* search range ending OID */
|
||||
|
||||
/* Control */
|
||||
enum agentx_response_errs error; /* storage for result of current action */
|
||||
u32 index; /* index on which the error was found */
|
||||
|
||||
union snmp_mibs_data *mibs_data; /* data passed from MIB search phase to MIB fill phase */
|
||||
};
|
||||
|
||||
struct snmp_proto_pdu {
|
||||
struct snmp_proto *p;
|
||||
struct snmp_pdu *c;
|
||||
#include "bgp4_mib.h"
|
||||
|
||||
union snmp_mibs_data {
|
||||
enum snmp_tags empty;
|
||||
|
||||
struct bgp4_mib bgp4;
|
||||
};
|
||||
|
||||
struct snmp_packet_info {
|
||||
@ -331,7 +344,7 @@ void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len,
|
||||
void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len, uint contid);
|
||||
void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime);
|
||||
|
||||
void snmp_manage_tbuf(struct snmp_proto *p, void **ptr, struct snmp_pdu *c);
|
||||
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu *c);
|
||||
|
||||
struct agentx_varbind *snmp_vb_to_tx(struct snmp_proto *p, const struct oid *oid, struct snmp_pdu *c);
|
||||
u8 snmp_get_mib_class(const struct oid *oid);
|
||||
|
Loading…
Reference in New Issue
Block a user