mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
SNMP: Context support and improved registering
This commit is contained in:
parent
14bcba7040
commit
2211644ed3
@ -13,6 +13,8 @@
|
|||||||
#include "subagent.h"
|
#include "subagent.h"
|
||||||
#include "bgp_mib.h"
|
#include "bgp_mib.h"
|
||||||
|
|
||||||
|
static inline void ip4_to_oid(struct oid *oid, ip4_addr addr);
|
||||||
|
|
||||||
/* BGP_MIB states see enum BGP_INTERNAL_STATES */
|
/* BGP_MIB states see enum BGP_INTERNAL_STATES */
|
||||||
static const char * const debug_bgp_states[] UNUSED = {
|
static const char * const debug_bgp_states[] UNUSED = {
|
||||||
[BGP_INTERNAL_INVALID] = "BGP_INTERNAL_INVALID",
|
[BGP_INTERNAL_INVALID] = "BGP_INTERNAL_INVALID",
|
||||||
@ -164,15 +166,16 @@ snmp_bgp_register(struct snmp_proto *p)
|
|||||||
{
|
{
|
||||||
snmp_log("snmp_bgp_register()");
|
snmp_log("snmp_bgp_register()");
|
||||||
|
|
||||||
u32 bgp_mib_prefix[] = {1, 15, 1};
|
//u32 bgp_mib_prefix[] = {1, 15, 1};
|
||||||
|
u32 bgp_mib_prefix[] = { 1, 15 };
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Register the whole BGP4-MIB::bgp root tree node */
|
/* Register the whole BGP4-MIB::bgp root tree node */
|
||||||
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
||||||
|
|
||||||
struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(2));
|
struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(2));
|
||||||
put_u8(&oid->n_subid, 2);
|
STORE_U8(oid->n_subid, 2);
|
||||||
put_u8(&oid->prefix, 2);
|
STORE_U8(oid->prefix, SNMP_MGMT);
|
||||||
|
|
||||||
memcpy(oid->ids, bgp_mib_prefix, 2 * sizeof(u32));
|
memcpy(oid->ids, bgp_mib_prefix, 2 * sizeof(u32));
|
||||||
|
|
||||||
@ -180,9 +183,37 @@ snmp_bgp_register(struct snmp_proto *p)
|
|||||||
add_tail(&p->register_queue, ®istering->n);
|
add_tail(&p->register_queue, ®istering->n);
|
||||||
p->register_to_ack++;
|
p->register_to_ack++;
|
||||||
|
|
||||||
/* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance) */
|
/* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid) */
|
||||||
snmp_register(p, oid, 0, 1, 0);
|
snmp_register(p, oid, 1, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 bgp_peer_entry[] = { 1, 15, 3, 1, 1 };
|
||||||
|
u32 bound = 24;
|
||||||
|
HASH_WALK(p->bgp_hash, next, peer)
|
||||||
|
{
|
||||||
|
if (peer->flags & SNMP_BGP_P_REGISTERED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct bgp_proto *bgp = (struct bgp_proto *) peer->config->c.proto;
|
||||||
|
|
||||||
|
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
||||||
|
|
||||||
|
struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(9));
|
||||||
|
STORE_U8(oid->n_subid, 9);
|
||||||
|
STORE_U8(oid->prefix, SNMP_MGMT);
|
||||||
|
|
||||||
|
for (uint i = 0; i < sizeof(bgp_peer_entry)/sizeof(bgp_peer_entry[0]); i++)
|
||||||
|
STORE_U32(oid->ids[i], bgp_peer_entry[i]);
|
||||||
|
ip4_to_oid(oid, ipa_to_ip4(bgp->remote_ip));
|
||||||
|
|
||||||
|
/* index is position of x in .1.3.6.1.2.15.3.1.x (1-based) */
|
||||||
|
snmp_register(p, oid, bound, 9, SNMP_REGISTER_INSTANCE, peer->context_id);
|
||||||
|
|
||||||
|
registering->oid = oid;
|
||||||
|
add_tail(&p->register_queue, ®istering->n);
|
||||||
|
p->register_to_ack++;
|
||||||
|
}
|
||||||
|
HASH_WALK_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -244,8 +275,19 @@ ip4_from_oid(const struct oid *o)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
ip4_to_oid(struct oid *o, ip4_addr addr)
|
||||||
|
{
|
||||||
|
u32 tmp = ip4_to_u32(addr);
|
||||||
|
ASSUME(o->n_subid >= 9);
|
||||||
|
STORE_U32(o->ids[5], (tmp & 0xFF000000) >> 24);
|
||||||
|
STORE_U32(o->ids[6], (tmp & 0x00FF0000) >> 16);
|
||||||
|
STORE_U32(o->ids[7], (tmp & 0x0000FF00) >> 8);
|
||||||
|
STORE_U32(o->ids[8], (tmp & 0x000000FF) >> 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_bgp_record(struct bgp_config *config)
|
print_bgp_record(const struct bgp_config *config)
|
||||||
{
|
{
|
||||||
struct proto_config *cf = (struct proto_config *) config;
|
struct proto_config *cf = (struct proto_config *) config;
|
||||||
struct bgp_proto *bgp_proto = (struct bgp_proto *) cf->proto;
|
struct bgp_proto *bgp_proto = (struct bgp_proto *) cf->proto;
|
||||||
@ -937,7 +979,7 @@ snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, ui
|
|||||||
|
|
||||||
static byte *
|
static byte *
|
||||||
bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
|
bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
|
||||||
struct snmp_pdu_context *c, u8 state)
|
struct snmp_pdu *c, u8 state)
|
||||||
{
|
{
|
||||||
struct oid *oid = &vb->name;
|
struct oid *oid = &vb->name;
|
||||||
uint size = c->size - snmp_varbind_header_size(vb);
|
uint size = c->size - snmp_varbind_header_size(vb);
|
||||||
@ -1202,7 +1244,7 @@ temp, temp, pkt);
|
|||||||
|
|
||||||
void
|
void
|
||||||
snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
|
snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
|
||||||
struct snmp_pdu_context *c)
|
struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
u8 state = snmp_bgp_state(&vb->name);
|
u8 state = snmp_bgp_state(&vb->name);
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ u8 snmp_bgp_getnext_valid(u8 state);
|
|||||||
|
|
||||||
struct oid *snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid);
|
struct oid *snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid);
|
||||||
enum snmp_search_res snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid);
|
enum snmp_search_res snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid);
|
||||||
void snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, struct snmp_pdu_context *c);
|
void snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, struct snmp_pdu *c);
|
||||||
|
|
||||||
void snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp);
|
void snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp);
|
||||||
void snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp);
|
void snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp);
|
||||||
|
@ -16,10 +16,12 @@ CF_DEFINES
|
|||||||
|
|
||||||
#define SNMP_CFG ((struct snmp_config *) this_proto)
|
#define SNMP_CFG ((struct snmp_config *) this_proto)
|
||||||
|
|
||||||
|
struct snmp_bond *this_bond = NULL;
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(SNMP, PROTOCOL, BPG, LOCAL, AS, REMOTE, ADDRESS, PORT, DESCRIPTION,
|
CF_KEYWORDS(SNMP, PROTOCOL, BPG, LOCAL, AS, REMOTE, ADDRESS, PORT, DESCRIPTION,
|
||||||
TIMEOUT, PRIORITY)
|
TIMEOUT, PRIORITY, CONTEXT, DEFAULT)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
@ -66,6 +68,8 @@ snmp_proto_start: proto_start SNMP
|
|||||||
|
|
||||||
init_list(&SNMP_CFG->bgp_entries);
|
init_list(&SNMP_CFG->bgp_entries);
|
||||||
SNMP_CFG->bonds = 0;
|
SNMP_CFG->bonds = 0;
|
||||||
|
/* We always have the default context */
|
||||||
|
SNMP_CFG->contexts = 1;
|
||||||
|
|
||||||
SNMP_CFG->local_ip = IPA_NONE;
|
SNMP_CFG->local_ip = IPA_NONE;
|
||||||
SNMP_CFG->remote_ip = ipa_build4(127,0,0,1);
|
SNMP_CFG->remote_ip = ipa_build4(127,0,0,1);
|
||||||
@ -80,18 +84,61 @@ snmp_proto_start: proto_start SNMP
|
|||||||
|
|
||||||
proto_name ;
|
proto_name ;
|
||||||
|
|
||||||
|
snmp_context:
|
||||||
|
/* empty */ {
|
||||||
|
if (!this_bond)
|
||||||
|
{
|
||||||
|
log(L_INFO "snmp_context no string alloc");
|
||||||
|
this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
||||||
|
}
|
||||||
|
|
||||||
snmp_bgp_bond: BGP symbol
|
this_bond->context = NULL;
|
||||||
|
}
|
||||||
|
| CONTEXT DEFAULT {
|
||||||
|
if (!this_bond)
|
||||||
|
{
|
||||||
|
log(L_INFO "snmp_context CONTEXT DEFAULT alloc");
|
||||||
|
this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
||||||
|
}
|
||||||
|
this_bond->context = NULL;
|
||||||
|
}
|
||||||
|
| CONTEXT text {
|
||||||
|
if(!this_bond)
|
||||||
|
{
|
||||||
|
log(L_INFO "snmp_context CONTEXT text alloc");
|
||||||
|
this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
||||||
|
}
|
||||||
|
this_bond->context = $2;
|
||||||
|
SNMP_CFG->contexts++;
|
||||||
|
log(L_INFO "storing context %s to bond at 0x%p", $2, this_bond);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
snmp_bgp_bond: BGP symbol snmp_context
|
||||||
{
|
{
|
||||||
struct snmp_bond *this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
/* the snmp_context rule sets the correct value of this_bond */
|
||||||
|
log(L_INFO "this_bond (at 0x%p) has value %s", this_bond,
|
||||||
|
(this_bond->context) ? this_bond->context : "<no_val>");
|
||||||
|
if (!this_bond)
|
||||||
|
{
|
||||||
|
log(L_INFO "snmp_bgp_bond BGP symbol ... alloc");
|
||||||
|
this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
||||||
|
log(L_INFO "Unexpedted alloc in snmp_bgp_bond rule");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log(L_INFO, "working with this_bond (at 0x%p)", this_bond);
|
||||||
|
}
|
||||||
this_bond->type = SNMP_BGP;
|
this_bond->type = SNMP_BGP;
|
||||||
|
|
||||||
cf_assert_symbol($2, SYM_PROTO);
|
cf_assert_symbol($2, SYM_PROTO);
|
||||||
this_bond->proto = $2->proto;
|
this_bond->proto = $2->proto;
|
||||||
|
|
||||||
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);
|
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);
|
||||||
add_tail(&SNMP_CFG->bgp_entries, NODE this_bond);
|
add_tail(&SNMP_CFG->bgp_entries, &this_bond->n);
|
||||||
SNMP_CFG->bonds++;
|
SNMP_CFG->bonds++;
|
||||||
|
|
||||||
|
this_bond = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CF_CODE
|
CF_CODE
|
||||||
|
@ -108,9 +108,13 @@ snmp_init(struct proto_config *CF)
|
|||||||
|
|
||||||
p->timeout = cf->timeout;
|
p->timeout = cf->timeout;
|
||||||
|
|
||||||
snmp_log("snmp_reconfigure() lip: %I:%u rip: %I:%u",
|
snmp_log("snmp_init() lip: %I:%u rip: %I:%u",
|
||||||
cf->local_ip, cf->local_port, cf->remote_ip, cf->remote_port);
|
cf->local_ip, cf->local_port, cf->remote_ip, cf->remote_port);
|
||||||
|
|
||||||
|
/* used when assigning the context ids in s_cont_create() */
|
||||||
|
p->context_max = 1;
|
||||||
|
p->context_id_map = NULL;
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +134,30 @@ snmp_cleanup(struct snmp_proto *p)
|
|||||||
rfree(p->lock);
|
rfree(p->lock);
|
||||||
p->lock = NULL;
|
p->lock = NULL;
|
||||||
|
|
||||||
// TODO cleanup lists, hash table, trie, ...
|
p->partial_response = NULL;
|
||||||
|
|
||||||
|
struct snmp_register *r, *r2;
|
||||||
|
WALK_LIST_DELSAFE(r, r2, p->register_queue)
|
||||||
|
{
|
||||||
|
rem_node(&r->n);
|
||||||
|
mb_free(r);
|
||||||
|
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);
|
||||||
|
HASH_FREE(p->context_hash);
|
||||||
|
mb_free(p->context_id_map);
|
||||||
|
p->context_id_map = NULL;
|
||||||
|
|
||||||
|
// TODO cleanup trie
|
||||||
|
|
||||||
return (p->state = SNMP_DOWN);
|
return (p->state = SNMP_DOWN);
|
||||||
}
|
}
|
||||||
@ -312,16 +339,29 @@ snmp_start(struct proto *P)
|
|||||||
|
|
||||||
/* We create copy of bonds to BGP protocols. */
|
/* We create copy of bonds to BGP protocols. */
|
||||||
HASH_INIT(p->bgp_hash, p->p.pool, 10);
|
HASH_INIT(p->bgp_hash, p->p.pool, 10);
|
||||||
|
HASH_INIT(p->context_hash, p->p.pool, 10);
|
||||||
|
|
||||||
|
/* We always have at least the default context */
|
||||||
|
p->context_id_map = mb_allocz(p->p.pool, cf->contexts * sizeof(struct snmp_context *));
|
||||||
|
log(L_INFO "number of context allocated %d", cf->contexts);
|
||||||
|
|
||||||
|
struct snmp_context *defaultc = mb_alloc(p->p.pool, sizeof(struct snmp_context));
|
||||||
|
defaultc->context = "";
|
||||||
|
defaultc->context_id = 0;
|
||||||
|
defaultc->flags = 0; /* TODO Default context fl. */
|
||||||
|
HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, defaultc);
|
||||||
|
|
||||||
|
p->context_id_map[0] = defaultc;
|
||||||
|
|
||||||
struct snmp_bond *b;
|
struct snmp_bond *b;
|
||||||
WALK_LIST(b, cf->bgp_entries)
|
WALK_LIST(b, cf->bgp_entries)
|
||||||
{
|
{
|
||||||
struct bgp_config *bc = (struct bgp_config *) b->proto;
|
const struct bgp_config *bc = (struct bgp_config *) b->proto;
|
||||||
if (bc && !ipa_zero(bc->remote_ip))
|
if (bc && !ipa_zero(bc->remote_ip))
|
||||||
{
|
{
|
||||||
struct snmp_bgp_peer *peer = \
|
struct snmp_bgp_peer *peer = \
|
||||||
mb_allocz(p->p.pool, sizeof(struct snmp_bgp_peer));
|
mb_allocz(p->p.pool, sizeof(struct snmp_bgp_peer));
|
||||||
peer->config = (struct bgp_config *) b->proto;
|
peer->config = bc;
|
||||||
peer->peer_ip = bc->remote_ip;
|
peer->peer_ip = bc->remote_ip;
|
||||||
|
|
||||||
struct net_addr net;
|
struct net_addr net;
|
||||||
@ -330,9 +370,30 @@ snmp_start(struct proto *P)
|
|||||||
trie_add_prefix(p->bgp_trie, &net, IP4_MAX_PREFIX_LENGTH, IP4_MAX_PREFIX_LENGTH);
|
trie_add_prefix(p->bgp_trie, &net, IP4_MAX_PREFIX_LENGTH, IP4_MAX_PREFIX_LENGTH);
|
||||||
|
|
||||||
HASH_INSERT(p->bgp_hash, SNMP_HASH, peer);
|
HASH_INSERT(p->bgp_hash, SNMP_HASH, peer);
|
||||||
|
|
||||||
|
/* Handle non-default context */
|
||||||
|
if (b->context)
|
||||||
|
{
|
||||||
|
const struct snmp_context *c = snmp_cont_create(p, b->context);
|
||||||
|
snmp_log("creating snmp context %s with id %u, writing", b->context, c->context_id);
|
||||||
|
p->context_id_map[c->context_id] = c;
|
||||||
|
peer->context_id = c->context_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
u32 *ptr = mb_alloc(p->p.pool, 4 * sizeof(u32));
|
||||||
|
*ptr = 1;
|
||||||
|
ptr[2] = 4;
|
||||||
|
(void)ptr[1]; (void)ptr[0]; (void)ptr[2];
|
||||||
|
mb_free(ptr);
|
||||||
|
log(L_INFO "testing alloc 3");
|
||||||
|
}
|
||||||
|
|
||||||
|
snmp_log("values of context cf %u proto %u", cf->contexts, p->context_max);
|
||||||
|
ASSUME(cf->contexts == p->context_max);
|
||||||
|
|
||||||
snmp_startup(p);
|
snmp_startup(p);
|
||||||
return PS_START;
|
return PS_START;
|
||||||
}
|
}
|
||||||
@ -344,6 +405,27 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
|
|||||||
const struct snmp_config *new = SKIP_BACK(struct snmp_config, cf, CF);
|
const struct snmp_config *new = SKIP_BACK(struct snmp_config, cf, CF);
|
||||||
const struct snmp_config *old = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
const struct snmp_config *old = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
||||||
|
|
||||||
|
struct snmp_bond *b1, *b2;
|
||||||
|
WALK_LIST(b1, new->bgp_entries)
|
||||||
|
{
|
||||||
|
WALK_LIST(b2, old->bgp_entries)
|
||||||
|
{
|
||||||
|
if (!strcmp(b1->proto->name, b2->proto->name))
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
/* Both bonds use default context */
|
||||||
|
if (!b1->context && !b2->context)
|
||||||
|
goto skip;
|
||||||
|
|
||||||
|
/* Both bonds use same non-default context */
|
||||||
|
if (b1->context && b2->context && !strcmp(b1->context, b2->context))
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
skip:;
|
||||||
|
}
|
||||||
|
|
||||||
return !memcmp(((byte *) old) + sizeof(struct proto_config),
|
return !memcmp(((byte *) old) + sizeof(struct proto_config),
|
||||||
((byte *) new) + sizeof(struct proto_config),
|
((byte *) new) + sizeof(struct proto_config),
|
||||||
OFFSETOF(struct snmp_config, description) - sizeof(struct proto_config))
|
OFFSETOF(struct snmp_config, description) - sizeof(struct proto_config))
|
||||||
@ -391,7 +473,7 @@ snmp_show_proto_info(struct proto *P)
|
|||||||
cli_msg(-1006, " in total: %u", bp->stats.rx_messages);
|
cli_msg(-1006, " in total: %u", bp->stats.rx_messages);
|
||||||
cli_msg(-1006, " out total: %u", bp->stats.tx_messages);
|
cli_msg(-1006, " out total: %u", bp->stats.tx_messages);
|
||||||
cli_msg(-1006, " fsm transitions: %u",
|
cli_msg(-1006, " fsm transitions: %u",
|
||||||
bp->stats.fsm_established_transitions);
|
bp->stats.fsm_established_transitions);
|
||||||
|
|
||||||
cli_msg(-1006, " fsm total time: -- (0)");
|
cli_msg(-1006, " fsm total time: -- (0)");
|
||||||
cli_msg(-1006, " retry interval: %u", bcf->connect_retry_time);
|
cli_msg(-1006, " retry interval: %u", bcf->connect_retry_time);
|
||||||
|
@ -51,10 +51,17 @@ enum snmp_proto_state {
|
|||||||
/* hash table only store ip4 addresses */
|
/* hash table only store ip4 addresses */
|
||||||
#define SNMP_HASH_LESS(ip1, ip2) SNMP_HASH_LESS4(ip1,ip2)
|
#define SNMP_HASH_LESS(ip1, ip2) SNMP_HASH_LESS4(ip1,ip2)
|
||||||
|
|
||||||
|
/* context hash table macros */
|
||||||
|
#define SNMP_H_CONTEXT_KEY(c) c->context
|
||||||
|
#define SNMP_H_CONTEXT_NEXT(c) c->next
|
||||||
|
#define SNMP_H_CONTEXT_EQ(s1,s2) strcmp(s1,s2)
|
||||||
|
#define SNMP_H_CONTEXT_FN(s) mem_hash(s, strlen(s))
|
||||||
|
|
||||||
struct snmp_bond {
|
struct snmp_bond {
|
||||||
node n;
|
node n;
|
||||||
struct proto_config *proto;
|
struct proto_config *proto;
|
||||||
u8 type;
|
u8 type;
|
||||||
|
const char *context;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snmp_config {
|
struct snmp_config {
|
||||||
@ -67,15 +74,21 @@ struct snmp_config {
|
|||||||
u8 timeout;
|
u8 timeout;
|
||||||
u8 priority;
|
u8 priority;
|
||||||
//struct iface *iface;
|
//struct iface *iface;
|
||||||
|
u32 bonds;
|
||||||
|
uint contexts; /* Number of all conetexts including the default */
|
||||||
const char *description;
|
const char *description;
|
||||||
list bgp_entries;
|
list bgp_entries;
|
||||||
u32 bonds;
|
|
||||||
// TODO add support for subagent oid identification
|
// TODO add support for subagent oid identification
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SNMP_BGP_P_REGISTERING 0x01
|
||||||
|
#define SNMP_BGP_P_REGISTERED 0x02
|
||||||
|
|
||||||
struct snmp_bgp_peer {
|
struct snmp_bgp_peer {
|
||||||
struct bgp_config *config;
|
const struct bgp_config *config;
|
||||||
ip_addr peer_ip;
|
ip_addr peer_ip;
|
||||||
|
uint context_id;
|
||||||
|
u8 flags;
|
||||||
struct snmp_bgp_peer *next;
|
struct snmp_bgp_peer *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +106,14 @@ struct snmp_registered_oid {
|
|||||||
struct oid *oid;
|
struct oid *oid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct snmp_context {
|
||||||
|
const char *context; /* string name */
|
||||||
|
//uint length; /* strlen() of name */
|
||||||
|
uint context_id;
|
||||||
|
u8 flags;
|
||||||
|
struct snmp_context *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct snmp_proto {
|
struct snmp_proto {
|
||||||
struct proto p;
|
struct proto p;
|
||||||
struct object_lock *lock;
|
struct object_lock *lock;
|
||||||
@ -121,6 +142,9 @@ struct snmp_proto {
|
|||||||
// map
|
// map
|
||||||
struct f_trie *bgp_trie;
|
struct f_trie *bgp_trie;
|
||||||
HASH(struct snmp_bgp_peer) bgp_hash;
|
HASH(struct snmp_bgp_peer) bgp_hash;
|
||||||
|
HASH(struct snmp_context) context_hash;
|
||||||
|
const struct snmp_context **context_id_map;
|
||||||
|
uint context_max;
|
||||||
struct tbf rl_gen;
|
struct tbf rl_gen;
|
||||||
|
|
||||||
timer *ping_timer;
|
timer *ping_timer;
|
||||||
|
@ -149,11 +149,13 @@ snmp_varbind_size(struct agentx_varbind *vb, int byte_ord)
|
|||||||
return hdr_size + snmp_str_size_from_len(LOAD_PTR(data, byte_ord));
|
return hdr_size + snmp_str_size_from_len(LOAD_PTR(data, byte_ord));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
inline uint
|
inline uint
|
||||||
snmp_context_size(struct agentx_context *c)
|
snmp_context_size(struct agentx_context *c)
|
||||||
{
|
{
|
||||||
return (c && c->length) ? snmp_str_size_from_len(c->length) : 0;
|
return (c && c->length) ? snmp_str_size_from_len(c->length) : 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
struct agentx_varbind *
|
struct agentx_varbind *
|
||||||
snmp_create_varbind(byte *buf, struct oid *oid)
|
snmp_create_varbind(byte *buf, struct oid *oid)
|
||||||
@ -208,14 +210,13 @@ snmp_put_nstr(byte *buf, const char *str, uint len)
|
|||||||
{
|
{
|
||||||
uint alen = BIRD_ALIGN(len, 4);
|
uint alen = BIRD_ALIGN(len, 4);
|
||||||
|
|
||||||
// TODO check for '\0' in the str bytes?
|
|
||||||
STORE_PTR(buf, len);
|
STORE_PTR(buf, len);
|
||||||
buf += 4;
|
buf += 4;
|
||||||
memcpy(buf, str, len);
|
memcpy(buf, str, len);
|
||||||
|
|
||||||
/* Insert zero padding in the gap at the end */
|
/* Insert zero padding in the gap at the end */
|
||||||
for (uint i = 0; i < alen - len; i++)
|
for (uint i = 0; i < alen - len; i++)
|
||||||
buf[len + i] = 0x00;
|
buf[len + i] = '\0';
|
||||||
|
|
||||||
return buf + alen;
|
return buf + alen;
|
||||||
}
|
}
|
||||||
@ -415,7 +416,7 @@ snmp_register_same(struct snmp_register *r, struct agentx_header *h, u8 class)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
snmp_register_ack(struct snmp_proto *p, struct agentx_header *h)
|
snmp_register_ack(struct snmp_proto *p, struct agentx_header *h, u8 class)
|
||||||
{
|
{
|
||||||
snmp_log("snmp_register_ack()");
|
snmp_log("snmp_register_ack()");
|
||||||
|
|
||||||
@ -428,7 +429,7 @@ h->packet_id);
|
|||||||
// TODO add support for more mib trees (other than BGP)
|
// TODO add support for more mib trees (other than BGP)
|
||||||
snmp_log("checking registration request sid: %u tid: %u pid: %u",
|
snmp_log("checking registration request sid: %u tid: %u pid: %u",
|
||||||
reg->session_id, reg->transaction_id, reg->packet_id);
|
reg->session_id, reg->transaction_id, reg->packet_id);
|
||||||
if (snmp_register_same(reg, h, SNMP_BGP4_MIB))
|
if (snmp_register_same(reg, h, class))
|
||||||
{
|
{
|
||||||
struct snmp_registered_oid *ro = \
|
struct snmp_registered_oid *ro = \
|
||||||
mb_alloc(p->p.pool, sizeof(struct snmp_registered_oid));
|
mb_alloc(p->p.pool, sizeof(struct snmp_registered_oid));
|
||||||
@ -575,3 +576,48 @@ snmp_search_res_to_type(enum snmp_search_res r)
|
|||||||
|
|
||||||
return type_arr[r];
|
return type_arr[r];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const struct snmp_context *
|
||||||
|
snmp_cont_find(struct snmp_proto *p, const char *name)
|
||||||
|
{
|
||||||
|
u32 *ptr = mb_alloc(p->p.pool, 4 * sizeof(u32));
|
||||||
|
*ptr = 1;
|
||||||
|
ptr[2] = 4;
|
||||||
|
(void)ptr[1]; (void)ptr[0]; (void)ptr[2];
|
||||||
|
mb_free(ptr);
|
||||||
|
return HASH_FIND(p->context_hash, SNMP_H_CONTEXT, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const struct snmp_context *
|
||||||
|
snmp_cont_get(struct snmp_proto *p, uint id)
|
||||||
|
{
|
||||||
|
if (id >= p->context_max)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return p->context_id_map[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const struct snmp_context *
|
||||||
|
snmp_cont_create(struct snmp_proto *p, const char *name)
|
||||||
|
{
|
||||||
|
const struct snmp_context *c = snmp_cont_find(p, name);
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
return c;
|
||||||
|
|
||||||
|
struct snmp_context *c2;
|
||||||
|
c2 = mb_alloc(p->p.pool, sizeof(struct snmp_context));
|
||||||
|
c2->context = name;
|
||||||
|
c2->context_id = p->context_max++;
|
||||||
|
c2->flags = 0;
|
||||||
|
|
||||||
|
u32 *ptr = mb_alloc(p->p.pool, 4 * sizeof(u32));
|
||||||
|
*ptr = 1;
|
||||||
|
ptr[2] = 4;
|
||||||
|
(void)ptr[1]; (void)ptr[0]; (void)ptr[2];
|
||||||
|
mb_free(ptr);
|
||||||
|
|
||||||
|
HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, c2);
|
||||||
|
|
||||||
|
return c2;
|
||||||
|
}
|
||||||
|
@ -14,7 +14,7 @@ size_t snmp_oid_sizeof(uint n_subid);
|
|||||||
uint snmp_varbind_hdr_size_from_oid(struct oid *oid);
|
uint snmp_varbind_hdr_size_from_oid(struct oid *oid);
|
||||||
uint snmp_varbind_header_size(struct agentx_varbind *vb);
|
uint snmp_varbind_header_size(struct agentx_varbind *vb);
|
||||||
uint snmp_varbind_size(struct agentx_varbind *vb, int byte_ord);
|
uint snmp_varbind_size(struct agentx_varbind *vb, int byte_ord);
|
||||||
uint snmp_context_size(struct agentx_context *c);
|
//uint snmp_context_size(struct agentx_context *c);
|
||||||
|
|
||||||
void snmp_oid_copy(struct oid *dest, const struct oid *src);
|
void snmp_oid_copy(struct oid *dest, const struct oid *src);
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ void snmp_oid_dump(struct oid *oid);
|
|||||||
|
|
||||||
struct snmp_register *snmp_register_create(struct snmp_proto *p, u8 mib_class);
|
struct snmp_register *snmp_register_create(struct snmp_proto *p, u8 mib_class);
|
||||||
|
|
||||||
void snmp_register_ack(struct snmp_proto *p, struct agentx_header *h);
|
void snmp_register_ack(struct snmp_proto *p, struct agentx_header *h, u8 class);
|
||||||
|
|
||||||
byte *snmp_varbind_int(struct agentx_varbind *vb, uint size, u32 val);
|
byte *snmp_varbind_int(struct agentx_varbind *vb, uint size, u32 val);
|
||||||
byte *snmp_varbind_counter32(struct agentx_varbind *vb, uint size, u32 val);
|
byte *snmp_varbind_counter32(struct agentx_varbind *vb, uint size, u32 val);
|
||||||
@ -57,7 +57,13 @@ byte *snmp_varbind_nstr(struct agentx_varbind *vb, uint size, const char *str, u
|
|||||||
|
|
||||||
void snmp_dump_packet(byte *pkt, uint size);
|
void snmp_dump_packet(byte *pkt, uint size);
|
||||||
|
|
||||||
|
const struct snmp_context *snmp_cont_find(struct snmp_proto *p, const char *name);
|
||||||
|
const struct snmp_context *snmp_cont_get(struct snmp_proto *p, uint context_id);
|
||||||
|
const struct snmp_context *snmp_cont_create(struct snmp_proto *p, const char *name);
|
||||||
|
|
||||||
enum agentx_type snmp_search_res_to_type(enum snmp_search_res res);
|
enum agentx_type snmp_search_res_to_type(enum snmp_search_res res);
|
||||||
|
|
||||||
int agentx_type_size(enum agentx_type t);
|
int agentx_type_size(enum agentx_type t);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,15 +27,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void snmp_mib_fill2(struct snmp_proto *p, struct oid *oid, struct snmp_pdu_context *c);
|
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 uint parse_response(struct snmp_proto *p, byte *buf, uint size);
|
||||||
static void do_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 uint parse_gets2_pdu(struct snmp_proto *p, byte *buf, uint size, uint *skip);
|
||||||
static uint parse_close_pdu(struct snmp_proto *p, byte *buf, uint size);
|
static uint parse_close_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||||
static struct agentx_response *prepare_response(struct snmp_proto *p, struct snmp_pdu_context *c);
|
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, uint err, uint ind);
|
||||||
static uint update_packet_size(struct snmp_proto *p, byte *start, byte *end);
|
static uint update_packet_size(struct snmp_proto *p, 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_context *c, enum snmp_search_res *result);
|
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);
|
||||||
|
|
||||||
u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET };
|
u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET };
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
|||||||
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
|
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
byte *buf = c.buffer;
|
byte *buf = c.buffer;
|
||||||
|
|
||||||
/* +4 for timeout (1B with 4B alignment) */
|
/* +4 for timeout (1B with 4B alignment) */
|
||||||
@ -94,6 +94,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
|||||||
buf = c.buffer;
|
buf = c.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Function open_pdu() does not generate agentx_pkt. */
|
||||||
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
||||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||||
SNMP_BLANK_HEADER(h, AGENTX_OPEN_PDU);
|
SNMP_BLANK_HEADER(h, AGENTX_OPEN_PDU);
|
||||||
@ -123,7 +124,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
|||||||
{
|
{
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
|
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
|
|
||||||
#define UPTIME_SIZE \
|
#define UPTIME_SIZE \
|
||||||
(6 * sizeof(u32)) /* sizeof( { u32 vb_type, u32 oid_hdr, u32 ids[4] } )*/
|
(6 * sizeof(u32)) /* sizeof( { u32 vb_type, u32 oid_hdr, u32 ids[4] } )*/
|
||||||
@ -142,6 +143,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
|||||||
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
||||||
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||||
SNMP_BLANK_HEADER(h, AGENTX_NOTIFY_PDU);
|
SNMP_BLANK_HEADER(h, AGENTX_NOTIFY_PDU);
|
||||||
|
p->packet_id++;
|
||||||
SNMP_SESSION(h, p);
|
SNMP_SESSION(h, p);
|
||||||
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
|
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
|
||||||
|
|
||||||
@ -183,7 +185,6 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
|||||||
ADVANCE(c.buffer, c.size, size);
|
ADVANCE(c.buffer, c.size, size);
|
||||||
|
|
||||||
uint s = update_packet_size(p, sk->tbuf, c.buffer);
|
uint s = update_packet_size(p, sk->tbuf, c.buffer);
|
||||||
|
|
||||||
int ret = sk_send(sk, s);
|
int ret = sk_send(sk, s);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
snmp_log("sk_send OK!");
|
snmp_log("sk_send OK!");
|
||||||
@ -227,15 +228,24 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
|
|||||||
|
|
||||||
/* Register-PDU / Unregister-PDU */
|
/* Register-PDU / Unregister-PDU */
|
||||||
static void
|
static void
|
||||||
un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 type, u8 is_instance)
|
un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 type, u8 is_instance, uint contid)
|
||||||
{
|
{
|
||||||
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
byte *buf = c.buffer;
|
byte *buf = c.buffer;
|
||||||
|
|
||||||
/* conditional +4 for upper-bound (optinal field) */
|
/* conditional +4 for upper-bound (optinal field) */
|
||||||
if (c.size < AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((len > 1) ? 4 : 0))
|
uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((len > 1) ? 4 : 0);
|
||||||
|
|
||||||
|
const struct snmp_context *sc = NULL;
|
||||||
|
if (contid)
|
||||||
|
{
|
||||||
|
sc = snmp_cont_get(p, contid);
|
||||||
|
sz += snmp_str_size(sc->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.size < sz)
|
||||||
{
|
{
|
||||||
snmp_log("un_register_pdu() insufficient size");
|
snmp_log("un_register_pdu() insufficient size");
|
||||||
snmp_manage_tbuf(p, &c);
|
snmp_manage_tbuf(p, &c);
|
||||||
@ -243,22 +253,28 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
|
|||||||
}
|
}
|
||||||
|
|
||||||
snmp_log("un_register_pdu()");
|
snmp_log("un_register_pdu()");
|
||||||
struct agentx_un_register_pdu *ur = (struct agentx_un_register_pdu *)c.buffer;
|
struct agentx_header *h = (struct agentx_header *) c.buffer;
|
||||||
ADVANCE(c.buffer, c.size, sizeof(struct agentx_un_register_pdu));
|
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
|
||||||
struct agentx_header *h = &ur->h;
|
|
||||||
|
|
||||||
SNMP_HEADER(h, type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
|
SNMP_HEADER(h, type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
|
||||||
/* use new transactionID, reset packetID */
|
|
||||||
p->packet_id++;
|
p->packet_id++;
|
||||||
SNMP_SESSION(h, p);
|
SNMP_SESSION(h, p);
|
||||||
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
|
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
|
||||||
|
|
||||||
|
log("un_register_pdu contid %u s_cont (at 0x%p) %s", contid, sc, (sc &&
|
||||||
|
sc->context) ? sc->context : "<not_avail>");
|
||||||
|
|
||||||
|
SNMP_NON_DEFAULT_CONTEXT(h, c, contid);
|
||||||
|
|
||||||
|
struct agentx_un_register_hdr *ur = (struct agentx_un_register_hdr *) c.buffer;
|
||||||
|
|
||||||
/* do not override timeout */
|
/* do not override timeout */
|
||||||
STORE_U8(ur->timeout, p->timeout);
|
STORE_U8(ur->timeout, p->timeout);
|
||||||
/* default priority */
|
/* default priority */
|
||||||
STORE_U8(ur->priority, cf->priority);
|
STORE_U8(ur->priority, cf->priority);
|
||||||
STORE_U8(ur->range_subid, (len > 1) ? index : 0);
|
STORE_U8(ur->range_subid, (len > 1) ? index : 0);
|
||||||
STORE_U8(ur->pad, 0);
|
STORE_U8(ur->pad, 0);
|
||||||
|
ADVANCE(c.buffer, c.size, sizeof(struct agentx_un_register_hdr));
|
||||||
|
|
||||||
snmp_put_oid(c.buffer, oid);
|
snmp_put_oid(c.buffer, oid);
|
||||||
ADVANCE(c.buffer, c.size, snmp_oid_size(oid));
|
ADVANCE(c.buffer, c.size, snmp_oid_size(oid));
|
||||||
@ -284,23 +300,23 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
|
|||||||
|
|
||||||
/* Register-PDU */
|
/* Register-PDU */
|
||||||
void
|
void
|
||||||
snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance)
|
snmp_register(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 is_instance, uint contid)
|
||||||
{
|
{
|
||||||
un_register_pdu(p, oid, index, len, AGENTX_REGISTER_PDU, is_instance);
|
un_register_pdu(p, oid, len, index, AGENTX_REGISTER_PDU, is_instance, contid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unregister-PDU */
|
/* Unregister-PDU */
|
||||||
void UNUSED
|
void UNUSED
|
||||||
snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len)
|
snmp_unregister(struct snmp_proto *p, struct oid *oid, uint len, uint index, uint contid)
|
||||||
{
|
{
|
||||||
un_register_pdu(p, oid, index, len, AGENTX_UNREGISTER_PDU, 0);
|
un_register_pdu(p, oid, len, index, AGENTX_UNREGISTER_PDU, 0, contid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_pdu(struct snmp_proto *p, u8 reason)
|
close_pdu(struct snmp_proto *p, u8 reason)
|
||||||
{
|
{
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
byte *buf = c.buffer;
|
byte *buf = c.buffer;
|
||||||
|
|
||||||
snmp_log("close_pdu() size: %u %c %u", c.size, (c.size > AGENTX_HEADER_SIZE + 4)
|
snmp_log("close_pdu() size: %u %c %u", c.size, (c.size > AGENTX_HEADER_SIZE + 4)
|
||||||
@ -475,13 +491,13 @@ refresh_ids(struct snmp_proto *p, struct agentx_header *h)
|
|||||||
* @size: number of packet bytes in buffer
|
* @size: number of packet bytes in buffer
|
||||||
* retval number of byte parsed
|
* retval number of byte parsed
|
||||||
*
|
*
|
||||||
* function parse_ptk() parses response-pdu and calls do_response().
|
* function parse_pkt() parses response-pdu and calls do_response().
|
||||||
* returns number of bytes parsed by function excluding size of header.
|
* returns number of bytes parsed by function excluding size of header.
|
||||||
*/
|
*/
|
||||||
static uint
|
static uint
|
||||||
parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
|
parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
|
||||||
{
|
{
|
||||||
snmp_log("parse_ptk() pkt start: %p", pkt);
|
snmp_log("parse_pkt() pkt start: %p", pkt);
|
||||||
|
|
||||||
if (size < AGENTX_HEADER_SIZE)
|
if (size < AGENTX_HEADER_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
@ -540,7 +556,8 @@ parse_response(struct snmp_proto *p, byte *res, uint size)
|
|||||||
|
|
||||||
uint pkt_size = LOAD_U32(h->payload, byte_ord);
|
uint pkt_size = LOAD_U32(h->payload, byte_ord);
|
||||||
snmp_log("p_res pkt_size %u", pkt_size);
|
snmp_log("p_res pkt_size %u", pkt_size);
|
||||||
if (size < pkt_size + AGENTX_HEADER_SIZE) {
|
if (size < pkt_size + AGENTX_HEADER_SIZE)
|
||||||
|
{
|
||||||
snmp_log("parse_response early return");
|
snmp_log("parse_response early return");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -562,13 +579,6 @@ parse_response(struct snmp_proto *p, byte *res, uint size)
|
|||||||
return pkt_size + AGENTX_HEADER_SIZE;
|
return pkt_size + AGENTX_HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
snmp_registered_all(struct snmp_proto *p)
|
|
||||||
{
|
|
||||||
snmp_log("snmp_registered_all() %u", list_length(&p->register_queue));
|
|
||||||
return p->register_to_ack == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
snmp_register_mibs(struct snmp_proto *p)
|
snmp_register_mibs(struct snmp_proto *p)
|
||||||
{
|
{
|
||||||
@ -580,7 +590,7 @@ snmp_register_mibs(struct snmp_proto *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
do_response(struct snmp_proto *p, byte *buf, uint size)
|
||||||
{
|
{
|
||||||
snmp_log("do_response()");
|
snmp_log("do_response()");
|
||||||
struct agentx_response *r = (void *) buf;
|
struct agentx_response *r = (void *) buf;
|
||||||
@ -607,14 +617,28 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
|||||||
p->state = SNMP_REGISTER;
|
p->state = SNMP_REGISTER;
|
||||||
snmp_register_mibs(p);
|
snmp_register_mibs(p);
|
||||||
snmp_log("do_response state SNMP_INIT register list %u", list_length(&p->register_queue));
|
snmp_log("do_response state SNMP_INIT register list %u", list_length(&p->register_queue));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNMP_REGISTER:
|
case SNMP_REGISTER:
|
||||||
snmp_log("do_response state SNMP_REGISTER register list %u", list_length(&p->register_queue));
|
snmp_log("do_response state SNMP_REGISTER register list %u", list_length(&p->register_queue));
|
||||||
snmp_register_ack(p ,h);
|
|
||||||
|
|
||||||
if (snmp_registered_all(p)) {
|
byte *pkt = buf;
|
||||||
|
ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
|
||||||
|
|
||||||
|
uint clen;
|
||||||
|
const char *context;
|
||||||
|
SNMP_LOAD_CONTEXT((struct agentx_header *) buf, pkt, context, clen);
|
||||||
|
|
||||||
|
if (size < snmp_str_size_from_len(clen))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ADVANCE(pkt, size, snmp_str_size_from_len(clen));
|
||||||
|
const struct oid *oid = (void *) pkt;
|
||||||
|
|
||||||
|
snmp_register_ack(p, h, snmp_get_mib_class(oid));
|
||||||
|
|
||||||
|
if (p->register_to_ack == 0)
|
||||||
|
{
|
||||||
snmp_log("changing proto_snmp state to CONNECTED");
|
snmp_log("changing proto_snmp state to CONNECTED");
|
||||||
p->state = SNMP_CONN;
|
p->state = SNMP_CONN;
|
||||||
proto_notify_state(&p->p, PS_UP);
|
proto_notify_state(&p->p, PS_UP);
|
||||||
@ -622,11 +646,9 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SNMP_CONN:
|
case SNMP_CONN:
|
||||||
// proto_notify_state(&p->p, PS_UP);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNMP_STOP:
|
case SNMP_STOP:
|
||||||
snmp_down(p);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -653,7 +675,7 @@ snmp_get_mib_class(const struct oid *oid)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
snmp_get_next2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
snmp_get_next2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
||||||
struct snmp_pdu_context *c)
|
struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
snmp_log("get_next2()");
|
snmp_log("get_next2()");
|
||||||
enum snmp_search_res r;
|
enum snmp_search_res r;
|
||||||
@ -721,7 +743,7 @@ snmp_get_next2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
snmp_get_bulk2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
snmp_get_bulk2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end,
|
||||||
struct agentx_bulk_state *state, struct snmp_pdu_context *c)
|
struct agentx_bulk_state *state, struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
if (state->index <= state->getbulk.non_repeaters)
|
if (state->index <= state->getbulk.non_repeaters)
|
||||||
{
|
{
|
||||||
@ -834,6 +856,7 @@ response_err_ind(struct agentx_response *res, uint err, uint ind)
|
|||||||
static uint
|
static uint
|
||||||
parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *skip)
|
parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *skip)
|
||||||
{
|
{
|
||||||
|
// TODO checks for c.size underflow
|
||||||
snmp_log("parse_gets2_pdu()");
|
snmp_log("parse_gets2_pdu()");
|
||||||
|
|
||||||
struct oid *o_start = NULL, *o_end = NULL;
|
struct oid *o_start = NULL, *o_end = NULL;
|
||||||
@ -844,15 +867,15 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
|
|||||||
uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
|
uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
|
||||||
|
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
// TODO better handling of endianness
|
// TODO better handling of endianness
|
||||||
c.byte_ord = 0; /* use little-endian */
|
c.byte_ord = 0; /* use little-endian */
|
||||||
|
|
||||||
uint clen; /* count of characters in context (without last '\0') */
|
uint clen; /* count of characters in context (without last '\0') */
|
||||||
char *context; /* newly allocated string of character */
|
const char *context; /* pointer to RX-buffer context */
|
||||||
|
|
||||||
/* alters pkt; assign context, clen */
|
/* alters pkt; assign context, clen */
|
||||||
SNMP_LOAD_CONTEXT(p, h, pkt, context, clen);
|
SNMP_LOAD_CONTEXT(h, pkt, context, clen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need more data; for valid response we need to know full
|
* We need more data; for valid response we need to know full
|
||||||
@ -1040,7 +1063,6 @@ send:
|
|||||||
|
|
||||||
p->partial_response = NULL;
|
p->partial_response = NULL;
|
||||||
|
|
||||||
mb_free(context);
|
|
||||||
mb_free(o_start);
|
mb_free(o_start);
|
||||||
mb_free(o_end);
|
mb_free(o_end);
|
||||||
|
|
||||||
@ -1064,9 +1086,9 @@ partial:
|
|||||||
|
|
||||||
|
|
||||||
wait:
|
wait:
|
||||||
mb_free(context);
|
|
||||||
mb_free(o_start);
|
mb_free(o_start);
|
||||||
mb_free(o_end);
|
mb_free(o_end);
|
||||||
|
p->packet_id--; /* we did not use the packetID */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1163,7 +1185,7 @@ snmp_ping(struct snmp_proto *p)
|
|||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
snmp_dump_packet(sk->tpos, AGENTX_HEADER_SIZE + 4);
|
snmp_dump_packet(sk->tpos, AGENTX_HEADER_SIZE + 4);
|
||||||
snmp_log("snmp_ping sk->tpos 0x%p", sk->tpos);
|
snmp_log("snmp_ping sk->tpos 0x%p", sk->tpos);
|
||||||
struct snmp_pdu_context c = SNMP_PDU_CONTEXT(sk);
|
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
|
||||||
|
|
||||||
if (c.size < AGENTX_HEADER_SIZE)
|
if (c.size < AGENTX_HEADER_SIZE)
|
||||||
snmp_manage_tbuf(p, &c);
|
snmp_manage_tbuf(p, &c);
|
||||||
@ -1180,6 +1202,7 @@ snmp_ping(struct snmp_proto *p)
|
|||||||
snmp_dump_packet(sk->tpos, AGENTX_HEADER_SIZE + 4);
|
snmp_dump_packet(sk->tpos, AGENTX_HEADER_SIZE + 4);
|
||||||
/* sending only header -> pkt - buf */
|
/* sending only header -> pkt - buf */
|
||||||
uint s = update_packet_size(p, sk->tpos, c.buffer);
|
uint s = update_packet_size(p, sk->tpos, c.buffer);
|
||||||
|
|
||||||
int ret = sk_send(sk, s);
|
int ret = sk_send(sk, s);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
snmp_log("sk_send OK!");
|
snmp_log("sk_send OK!");
|
||||||
@ -1231,7 +1254,7 @@ int snmp_search_check_end_oid(const struct oid *found, const struct oid *bound)
|
|||||||
working only with o_start, o_end allocated in heap (not from buffer)*/
|
working only with o_start, o_end allocated in heap (not from buffer)*/
|
||||||
static struct oid *
|
static struct oid *
|
||||||
search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end,
|
search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end,
|
||||||
struct oid *o_curr, struct snmp_pdu_context *c,
|
struct oid *o_curr, struct snmp_pdu *c,
|
||||||
enum snmp_search_res *result)
|
enum snmp_search_res *result)
|
||||||
{
|
{
|
||||||
snmp_log("search_mib()");
|
snmp_log("search_mib()");
|
||||||
@ -1344,16 +1367,13 @@ snmp_prefixize(struct snmp_proto *proto, const struct oid *oid, int byte_ord)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
snmp_mib_fill2(struct snmp_proto *p, struct oid *oid,
|
snmp_mib_fill2(struct snmp_proto *p, struct oid *oid,
|
||||||
struct snmp_pdu_context *c)
|
struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
ASSUME(oid != NULL);
|
ASSUME(oid != NULL);
|
||||||
|
|
||||||
snmp_log("critical part");
|
|
||||||
if (c->size < snmp_varbind_hdr_size_from_oid(oid))
|
if (c->size < snmp_varbind_hdr_size_from_oid(oid))
|
||||||
snmp_manage_tbuf(p, c);
|
snmp_manage_tbuf(p, c);
|
||||||
|
|
||||||
snmp_log("critical part done");
|
|
||||||
|
|
||||||
struct agentx_varbind *vb = snmp_create_varbind(c->buffer, oid);
|
struct agentx_varbind *vb = snmp_create_varbind(c->buffer, oid);
|
||||||
|
|
||||||
if (oid->n_subid < 2 || (oid->prefix != SNMP_MGMT && oid->ids[0] != SNMP_MIB_2))
|
if (oid->n_subid < 2 || (oid->prefix != SNMP_MGMT && oid->ids[0] != SNMP_MIB_2))
|
||||||
@ -1384,7 +1404,7 @@ snmp_mib_fill2(struct snmp_proto *p, struct oid *oid,
|
|||||||
* are invalidated!
|
* are invalidated!
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
snmp_manage_tbuf(struct snmp_proto UNUSED *p, struct snmp_pdu_context *c)
|
snmp_manage_tbuf(struct snmp_proto UNUSED *p, struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
snmp_log("snmp_manage_tbuf()");
|
snmp_log("snmp_manage_tbuf()");
|
||||||
sock *sk = p->sock;
|
sock *sk = p->sock;
|
||||||
@ -1403,7 +1423,7 @@ snmp_tx(sock UNUSED *sk)
|
|||||||
|
|
||||||
|
|
||||||
static struct agentx_response *
|
static struct agentx_response *
|
||||||
prepare_response(struct snmp_proto *p, struct snmp_pdu_context *c)
|
prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
|
||||||
{
|
{
|
||||||
snmp_log("prepare_response()");
|
snmp_log("prepare_response()");
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ void snmp_ping(struct snmp_proto *p);
|
|||||||
|
|
||||||
extern u32 snmp_internet[4];
|
extern u32 snmp_internet[4];
|
||||||
|
|
||||||
|
#define SNMP_DEFAULT_CONTEXT 0
|
||||||
|
|
||||||
enum SNMP_CLASSES {
|
enum SNMP_CLASSES {
|
||||||
SNMP_CLASS_INVALID = 0,
|
SNMP_CLASS_INVALID = 0,
|
||||||
SNMP_CLASS_BGP = 1,
|
SNMP_CLASS_BGP = 1,
|
||||||
@ -64,6 +66,9 @@ enum snmp_search_res {
|
|||||||
|
|
||||||
#define AGENTX_PRIORITY 127
|
#define AGENTX_PRIORITY 127
|
||||||
|
|
||||||
|
#define SNMP_REGISTER_TREE 0
|
||||||
|
#define SNMP_REGISTER_INSTANCE 1
|
||||||
|
|
||||||
#define SNMP_NATIVE
|
#define SNMP_NATIVE
|
||||||
|
|
||||||
#ifdef SNMP_NATIVE
|
#ifdef SNMP_NATIVE
|
||||||
@ -95,7 +100,7 @@ enum snmp_search_res {
|
|||||||
|
|
||||||
#define SNMP_BLANK_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
|
#define SNMP_BLANK_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
|
||||||
|
|
||||||
#define SNMP_SESSION(h, p) \
|
#define SNMP_SESSION(h, p) \
|
||||||
STORE_U32(h->session_id, p->session_id); \
|
STORE_U32(h->session_id, p->session_id); \
|
||||||
STORE_U32(h->transaction_id, p->transaction_id); \
|
STORE_U32(h->transaction_id, p->transaction_id); \
|
||||||
STORE_U32(h->packet_id, p->packet_id)
|
STORE_U32(h->packet_id, p->packet_id)
|
||||||
@ -104,23 +109,39 @@ enum snmp_search_res {
|
|||||||
#define LOAD_U16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
|
#define LOAD_U16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
|
||||||
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : *((u32 *) v))
|
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : *((u32 *) v))
|
||||||
|
|
||||||
#define LOAD_STR(proto, buf, str, length, byte_order) ({ \
|
#define LOAD_STR(/* byte * */buf, str, length, byte_ord) ({ \
|
||||||
|
length = LOAD_PTR(buf, byte_ord); \
|
||||||
|
length > 0 ? (str = buf + 4) : (str = NULL); })
|
||||||
|
|
||||||
|
#define COPY_STR(proto, buf, str, length, byte_order) ({ \
|
||||||
length = LOAD_PTR(buf, byte_order); \
|
length = LOAD_PTR(buf, byte_order); \
|
||||||
log(L_INFO "LOAD_STR(), %p %u", proto->p.pool, length + 1); \
|
log(L_INFO "LOAD_STR(), %p %u", proto->p.pool, length + 1); \
|
||||||
str = mb_alloc(proto->p.pool, length + 1); \
|
str = mb_alloc(proto->p.pool, length + 1); \
|
||||||
memcpy(str, buf, length); \
|
memcpy(str, buf+4, length); \
|
||||||
str[length] = '\0'; /* set term. char */ \
|
str[length] = '\0'; /* set term. char */ \
|
||||||
buf += snmp_str_size_from_len(length); })
|
buf += 4 + snmp_str_size_from_len(length); })
|
||||||
|
|
||||||
#define SNMP_LOAD_CONTEXT(proto, hdr, buf, cont, cont_len) \
|
#define SNMP_LOAD_CONTEXT(hdr, buf, cont, cont_len) ({ \
|
||||||
|
if ((hdr)->flags & AGENTX_NON_DEFAULT_CONTEXT) \
|
||||||
|
LOAD_STR((buf), (cont), (cont_len), \
|
||||||
|
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER); })
|
||||||
|
|
||||||
|
#define SNMP_COPY_CONTEXT(proto, hdr, buf, cont, cont_len) ({ \
|
||||||
cont = NULL; cont_len = 0; \
|
cont = NULL; cont_len = 0; \
|
||||||
if (hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) \
|
if (hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) \
|
||||||
LOAD_STR(proto, buf, cont, cont_len, \
|
COPY_STR(proto, buf, cont, cont_len, \
|
||||||
hdr->flags & AGENTX_NETWORK_BYTE_ORDER)
|
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER) })
|
||||||
|
|
||||||
#define SNMP_HAS_CONTEXT(hdr) \
|
#define SNMP_HAS_CONTEXT(hdr) \
|
||||||
hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT
|
hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT
|
||||||
|
|
||||||
|
#define SNMP_NON_DEFAULT_CONTEXT(hdr,pdu,contid) ({ \
|
||||||
|
if (contid) { \
|
||||||
|
SNMP_HAS_CONTEXT(hdr); \
|
||||||
|
snmp_put_str((c).buffer, (sc)->context); \
|
||||||
|
ADVANCE((c).buffer, (c).size, snmp_str_size((sc)->context)); \
|
||||||
|
} })
|
||||||
|
|
||||||
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \
|
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \
|
||||||
({ \
|
({ \
|
||||||
struct agentx_varbind *vb = (void *) buf; \
|
struct agentx_varbind *vb = (void *) buf; \
|
||||||
@ -191,8 +212,7 @@ struct agentx_close_pdu {
|
|||||||
u8 reason;
|
u8 reason;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct agentx_un_register_pdu {
|
struct agentx_un_register_hdr {
|
||||||
struct agentx_header h;
|
|
||||||
u8 timeout;
|
u8 timeout;
|
||||||
u8 priority;
|
u8 priority;
|
||||||
u8 range_subid;
|
u8 range_subid;
|
||||||
@ -280,13 +300,8 @@ enum agentx_response_err {
|
|||||||
AGENTX_RES_PROCESSING_ERR = 268,
|
AGENTX_RES_PROCESSING_ERR = 268,
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct agentx_context {
|
/* SNMP PDU buffer info */
|
||||||
char *context; /* string name of this context */
|
struct snmp_pdu {
|
||||||
uint length; /* normal strlen() size */
|
|
||||||
/* XXX add buffered context hash? */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct snmp_pdu_context {
|
|
||||||
byte *buffer; /* pointer to buffer */
|
byte *buffer; /* pointer to buffer */
|
||||||
uint size; /* unused space in buffer */
|
uint size; /* unused space in buffer */
|
||||||
uint context; /* context hash */
|
uint context; /* context hash */
|
||||||
@ -305,11 +320,11 @@ struct agentx_alloc_context {
|
|||||||
int snmp_rx(sock *sk, uint size);
|
int snmp_rx(sock *sk, uint size);
|
||||||
int snmp_rx_stop(sock *sk, uint size);
|
int snmp_rx_stop(sock *sk, uint size);
|
||||||
void snmp_down(struct snmp_proto *p);
|
void snmp_down(struct snmp_proto *p);
|
||||||
void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance);
|
void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid);
|
||||||
void snmp_unregister(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_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime);
|
||||||
|
|
||||||
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c);
|
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu *c);
|
||||||
|
|
||||||
struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o, int byte_ord);
|
struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o, int byte_ord);
|
||||||
u8 snmp_get_mib_class(const struct oid *oid);
|
u8 snmp_get_mib_class(const struct oid *oid);
|
||||||
|
Loading…
Reference in New Issue
Block a user