mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-11 17:08:46 +00:00
changes in bgp_mib.c API (mainly)
This commit is contained in:
parent
ec7d4fd52c
commit
9f8950d4d7
@ -194,17 +194,23 @@ bgp_get_candidate(u32 field)
|
||||
/* first value is in secord cell of array translation_table (as the
|
||||
* SNMP_BPG_IDENTIFIER == 1
|
||||
*/
|
||||
if (field > 0 && field < sizeof(translation_table) / sizeof(translation_table[0]))
|
||||
if (field > 0 && field <= sizeof(translation_table) / sizeof(translation_table[0]))
|
||||
return translation_table[field];
|
||||
if (field == 0)
|
||||
return BGP_INTERNAL_INVALID;
|
||||
else
|
||||
return BGP_INTERNAL_NO_VALUE;
|
||||
return BGP_INTERNAL_END;
|
||||
}
|
||||
|
||||
static inline struct ip4_addr
|
||||
ip4_from_oid(const struct oid *o)
|
||||
{
|
||||
return (o->n_subid == 9) ? ip4_build(o->ids[5], o->ids[6], o->ids[7],
|
||||
o->ids[8]) : ip4_from_u32(0xFFFFFFFF);
|
||||
return ip4_build(
|
||||
o->n_subid > 5 ? (o->ids[5] & 0xff) : 0,
|
||||
o->n_subid > 6 ? (o->ids[6] & 0xff) : 0,
|
||||
o->n_subid > 7 ? (o->ids[7] & 0xff) : 0,
|
||||
o->n_subid > 8 ? (o->ids[8] & 0xff) : 0
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -283,6 +289,9 @@ snmp_bgp_state(struct oid *oid)
|
||||
* -> BGP4-MIB::bgp (root)
|
||||
*/
|
||||
|
||||
if (snmp_is_oid_empty(oid))
|
||||
return BGP_INTERNAL_END;
|
||||
|
||||
u8 state = BGP_INTERNAL_NO_VALUE;
|
||||
|
||||
u8 candidate;
|
||||
@ -374,15 +383,10 @@ snmp_bgp_has_value(u8 state)
|
||||
if (state <= BGP_INTERNAL_BGP ||
|
||||
state == BGP_INTERNAL_PEER_TABLE ||
|
||||
state == BGP_INTERNAL_PEER_ENTRY ||
|
||||
|
||||
/* unsupported fields */
|
||||
state == BGP_INTERNAL_FSM_ESTABLISHED_TIME ||
|
||||
state == BGP_INTERNAL_ORIGINATION_INTERVAL ||
|
||||
state == BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT ||
|
||||
state == BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME)
|
||||
return 0; /* hasn't value */
|
||||
state >= BGP_INTERNAL_END)
|
||||
return 0;
|
||||
else
|
||||
return 1; /* has value */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,15 +427,8 @@ snmp_bgp_next_state(u8 state)
|
||||
case BGP_INTERNAL_PEER_ENTRY:
|
||||
return BGP_INTERNAL_IDENTIFIER;
|
||||
|
||||
case BGP_INTERNAL_FSM_TRANSITIONS:
|
||||
case BGP_INTERNAL_FSM_ESTABLISHED_TIME:
|
||||
return BGP_INTERNAL_RETRY_INTERVAL;
|
||||
|
||||
|
||||
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
|
||||
|
||||
case BGP_INTERNAL_END:
|
||||
|
||||
return BGP_INTERNAL_END;
|
||||
|
||||
default:
|
||||
@ -445,20 +442,19 @@ snmp_bgp_is_supported(struct oid *o)
|
||||
/* most likely not functioning */
|
||||
if (o->prefix == 2 && o->n_subid > 0 && o->ids[0] == 1)
|
||||
{
|
||||
if (o->n_subid == 2 && o->ids[1] == BGP4_MIB_VERSION ||
|
||||
o->ids[1] == BGP4_MIB_LOCAL_AS)
|
||||
if (o->n_subid == 2 && (o->ids[1] == BGP4_MIB_VERSION ||
|
||||
o->ids[1] == BGP4_MIB_LOCAL_AS))
|
||||
return 1;
|
||||
else if (o->n_subid > 2 && o->ids[1] == BGP4_PEER_TABLE &&
|
||||
o->ids[2] == BGP4_PEER_ENTRY)
|
||||
{
|
||||
if (o->n_subid == 3)
|
||||
return 1;
|
||||
if (o->n_subid == 8 &&
|
||||
o->ids[3] > 0 &&
|
||||
if (o->n_subid == 8 && o->ids[3] > 0)
|
||||
/* do not include bgpPeerInUpdatesElapsedTime
|
||||
and bgpPeerFsmEstablishedTime */
|
||||
o->ids[3] < SNMP_BGP_IN_UPDATE_ELAPSED_TIME &&
|
||||
o->ids[3] != SNMP_BGP_FSM_ESTABLISHED_TIME)
|
||||
//&& o->ids[3] < SNMP_BGP_IN_UPDATE_ELAPSED_TIME
|
||||
//&& o->ids[3] != SNMP_BGP_FSM_ESTABLISHED_TIME)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -468,50 +464,127 @@ snmp_bgp_is_supported(struct oid *o)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
oid_state_compare(const struct oid *oid, u8 state)
|
||||
{
|
||||
ASSUME(oid != NULL);
|
||||
if (state >= BGP_INTERNAL_IDENTIFIER &&
|
||||
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME)
|
||||
return (oid->n_subid > 9) - (oid->n_subid < 9);
|
||||
if (state >= BGP_INTERNAL_VERSION && state <= BGP_INTERNAL_PEER_TABLE)
|
||||
return (oid->n_subid > 3) - (oid->n_subid < 3);
|
||||
if (state == BGP_INTERNAL_PEER_ENTRY)
|
||||
return (oid->n_subid > 4) - (oid->n_subid < 4);
|
||||
if (state == BGP_INTERNAL_BGP)
|
||||
return (oid->n_subid > 2) - (oid->n_subid < 2);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct oid *
|
||||
update_bgp_oid(struct oid *oid, u8 state)
|
||||
{
|
||||
ASSERT (state != BGP_INTERNAL_INVALID);
|
||||
ASSERT (state != BGP_INTERNAL_NO_VALUE);
|
||||
ASSERT (state != BGP_INTERNAL_END);
|
||||
snmp_log("update_bgp_oid()");
|
||||
if (state == BGP_INTERNAL_END || state == BGP_INTERNAL_INVALID ||
|
||||
state == BGP_INTERNAL_NO_VALUE)
|
||||
return oid;
|
||||
|
||||
/* if same state, no need to realloc anything */
|
||||
if (snmp_bgp_state(oid) == state)
|
||||
return oid;
|
||||
{
|
||||
if (state >= BGP_INTERNAL_IDENTIFIER &&
|
||||
state <= BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME &&
|
||||
oid->n_subid == 9)
|
||||
return oid;
|
||||
if (state >= BGP_INTERNAL_VERSION &&
|
||||
state <= BGP_INTERNAL_PEER_TABLE && oid->n_subid == 3)
|
||||
return oid;
|
||||
if (state == BGP_INTERNAL_PEER_ENTRY && oid->n_subid == 4)
|
||||
return oid;
|
||||
if (state == BGP_INTERNAL_BGP && oid->n_subid == 2)
|
||||
return oid;
|
||||
}
|
||||
|
||||
snmp_log("update work");
|
||||
switch (state)
|
||||
{
|
||||
case BGP_INTERNAL_BGP:
|
||||
/* could destroy same old data */
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(2));
|
||||
if (oid->n_subid != 2)
|
||||
{
|
||||
snmp_log("realloc");
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(2));
|
||||
snmp_log("/realloc");
|
||||
}
|
||||
|
||||
oid->n_subid = 2;
|
||||
oid->ids[0] = 1;
|
||||
oid->ids[1] = SNMP_BGP4_MIB;
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_VERSION:
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
||||
if (oid->n_subid != 3)
|
||||
{ snmp_log("realloc");
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
||||
snmp_log("/realloc"); }
|
||||
|
||||
oid->n_subid = 3;
|
||||
oid->ids[2] = SNMP_BGP_VERSION;
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_AS:
|
||||
if (oid->n_subid != 3)
|
||||
{ snmp_log("realloc");
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(3));
|
||||
snmp_log("/realloc"); }
|
||||
|
||||
oid->n_subid = 3;
|
||||
oid->ids[2] = 2;
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_IDENTIFIER:
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(9));
|
||||
oid->n_subid = 9;
|
||||
if (oid->n_subid != 9)
|
||||
{
|
||||
snmp_log("realloc");
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(9));
|
||||
snmp_log("/realloc");
|
||||
|
||||
if (oid->n_subid < 6)
|
||||
oid->ids[5] = 0;
|
||||
if (oid->n_subid < 7)
|
||||
oid->ids[6] = 0;
|
||||
if (oid->n_subid < 8)
|
||||
oid->ids[7] = 0;
|
||||
if (oid->n_subid < 9)
|
||||
oid->ids[8] = 0;
|
||||
}
|
||||
|
||||
oid->ids[2] = SNMP_BGP_PEER_TABLE;
|
||||
oid->ids[3] = SNMP_BGP_PEER_ENTRY;
|
||||
|
||||
oid->ids[4] = SNMP_BGP_IDENTIFIER;
|
||||
/* zero the ip */
|
||||
oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0;
|
||||
oid->n_subid = 9;
|
||||
break;
|
||||
|
||||
#define SNMP_UPDATE_CASE(num, update) \
|
||||
case num: \
|
||||
oid->ids[4] = update; \
|
||||
#define SNMP_UPDATE_CASE(num, update) \
|
||||
case num: \
|
||||
if (oid->n_subid != 9) \
|
||||
{ \
|
||||
snmp_log("realloc"); \
|
||||
oid = mb_realloc(oid, snmp_oid_sizeof(9)); \
|
||||
snmp_log("/realloc"); \
|
||||
\
|
||||
if (oid->n_subid < 6) \
|
||||
oid->ids[5] = 0; \
|
||||
if (oid->n_subid < 7) \
|
||||
oid->ids[6] = 0; \
|
||||
if (oid->n_subid < 8) \
|
||||
oid->ids[7] = 0; \
|
||||
if (oid->n_subid < 9) \
|
||||
oid->ids[8] = 0; \
|
||||
} \
|
||||
oid->n_subid = 9; \
|
||||
oid->ids[4] = update; \
|
||||
break;
|
||||
|
||||
SNMP_UPDATE_CASE(BGP_INTERNAL_STATE, SNMP_BGP_STATE)
|
||||
@ -559,6 +632,9 @@ update_bgp_oid(struct oid *oid, u8 state)
|
||||
SNMP_UPDATE_CASE(BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT, SNMP_BGP_MIN_ROUTE_ADVERTISEMENT)
|
||||
|
||||
SNMP_UPDATE_CASE(BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME, SNMP_BGP_IN_UPDATE_ELAPSED_TIME)
|
||||
|
||||
default:
|
||||
die("update unavailable");
|
||||
}
|
||||
|
||||
return oid;
|
||||
@ -567,37 +643,50 @@ update_bgp_oid(struct oid *oid, u8 state)
|
||||
|
||||
// TODO test bgp_find_dynamic_oid
|
||||
static struct oid *
|
||||
bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, u8 state UNUSED)
|
||||
bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, const struct oid *o_end, u8 start_state)
|
||||
{
|
||||
ASSUME(o_start != NULL);
|
||||
ASSUME(o_end != NULL);
|
||||
|
||||
snmp_log("bgp_find_dynamic_oid()");
|
||||
ip4_addr ip4 = ip4_from_oid(o_start);
|
||||
/* dest is 255.255.255.255 if o_end is empty */
|
||||
ip4_addr dest = ip4_from_oid(o_end);
|
||||
ip4_addr dest;
|
||||
|
||||
if (o_start->n_subid < 9)
|
||||
o_start->include = 1;
|
||||
|
||||
int check_dest = snmp_is_oid_empty(o_end);
|
||||
if (check_dest)
|
||||
{
|
||||
u8 end_state = snmp_bgp_state(o_end);
|
||||
dest = (start_state == end_state && o_end->n_subid > 5) ?
|
||||
ip4_from_oid(o_end) :
|
||||
ip4_from_u32(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
snmp_log("ip addresses build (ip4) %I (dest) %I", ipa_from_ip4(ip4), ipa_from_ip4(dest));
|
||||
|
||||
// why am I allocated dynamically ?!
|
||||
net_addr *net = mb_allocz(p->p.pool, sizeof(struct net_addr));
|
||||
net_fill_ip4(net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
net_addr net;
|
||||
net_fill_ip4(&net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
snmp_log("dynamic part of BGP mib");
|
||||
|
||||
// why am I allocated dynamically ?!
|
||||
struct f_trie_walk_state *ws = mb_allocz(p->p.pool,
|
||||
sizeof(struct f_trie_walk_state));
|
||||
struct f_trie_walk_state ws;
|
||||
|
||||
trie_walk_init(ws, p->bgp_trie, NULL);
|
||||
// TODO move to newer API
|
||||
trie_walk_init(&ws, p->bgp_trie, NULL, 0);
|
||||
|
||||
snmp_log("walk init");
|
||||
|
||||
if (trie_walk_next(ws, net)) // && ip4_less(net4_prefix(net), dest))
|
||||
if (trie_walk_next(&ws, &net)) // && ip4_less(net4_prefix(net), dest))
|
||||
{
|
||||
snmp_log("trie_walk_next() returned true");
|
||||
|
||||
/*
|
||||
* if the o_end is empty then there are no conditions on the ip4 addr
|
||||
*/
|
||||
int cmp = ip4_compare(net4_prefix(net), dest);
|
||||
//int cmp = (check_dest) ? ip4_compare(net4_prefix(&net), dest) : ;
|
||||
int cmp = ip4_compare(net4_prefix(&net), dest);
|
||||
if (cmp < 0 || (cmp == 0 && snmp_is_oid_empty(o_end)))
|
||||
{
|
||||
snmp_log("ip4_less() returned true");
|
||||
@ -605,10 +694,7 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
|
||||
o->n_subid = 9;
|
||||
|
||||
memcpy(o, o_start, snmp_oid_size(o_start));
|
||||
snmp_oid_ip4_index(o, 5, net4_prefix(net));
|
||||
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
snmp_oid_ip4_index(o, 5, net4_prefix(&net));
|
||||
|
||||
return o;
|
||||
}
|
||||
@ -616,9 +702,7 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
|
||||
// delete me
|
||||
else
|
||||
{
|
||||
snmp_log("ip4_less() returned false for %I >= %I", net4_prefix(net), dest);
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
snmp_log("ip4_less() returned false for %I >= %I", net4_prefix(&net), dest);
|
||||
}
|
||||
// delete me end
|
||||
}
|
||||
@ -626,8 +710,6 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
|
||||
else
|
||||
{
|
||||
snmp_log("trie_walk_next() returned false, cleaning");
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -652,6 +734,9 @@ UNUSED, u8 current_state)
|
||||
snmp_oid_dump(o_start);
|
||||
|
||||
next_state = snmp_bgp_next_state(next_state);
|
||||
/* search in next state is done from beginning */
|
||||
o_start->ids[5] = o_start->ids[6] = o_start->ids[7] = o_start->ids[8] = 0;
|
||||
o_start->include = 1;
|
||||
|
||||
snmp_log("looping");
|
||||
} while (o_start == NULL && next_state < BGP_INTERNAL_END);
|
||||
@ -659,9 +744,208 @@ UNUSED, u8 current_state)
|
||||
return o_start;
|
||||
}
|
||||
|
||||
/**
|
||||
* snmp_bgp_find_next_oid - walk bgp peer addresses and update @o_start oid
|
||||
*
|
||||
* @p:
|
||||
* @oid:
|
||||
* @contid:
|
||||
*/
|
||||
static int
|
||||
snmp_bgp_find_next_oid(struct snmp_proto *p, struct oid *oid, uint UNUSED contid)
|
||||
{
|
||||
// TODO add o_end paramenter for faster searches
|
||||
ip4_addr ip4 = ip4_from_oid(oid);
|
||||
//ip_add4 dest = ip4_from_u32(0xFFFFFFFF);
|
||||
|
||||
net_addr net;
|
||||
net_fill_ip4(&net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
struct f_trie_walk_state ws;
|
||||
|
||||
int match = trie_walk_init(&ws, p->bgp_trie, &net, 1);
|
||||
|
||||
snmp_log("match %d include %u", match, oid->include);
|
||||
if (match && oid->include)
|
||||
{
|
||||
oid->include = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We skip the first match as we should not include ip address in oid */
|
||||
if (match)
|
||||
{
|
||||
snmp_log("continue");
|
||||
trie_walk_next(&ws, &net);
|
||||
}
|
||||
|
||||
if (trie_walk_next(&ws, &net))
|
||||
{
|
||||
snmp_oid_dump(oid);
|
||||
snmp_log("setting up");
|
||||
u32 res = ipa_to_u32(net_prefix(&net));
|
||||
|
||||
ASSUME(oid->n_subid == 9);
|
||||
oid->ids[5] = (res & 0xFF000000) >> 24;
|
||||
oid->ids[6] = (res & 0x00FF0000) >> 16;
|
||||
oid->ids[7] = (res & 0x0000FF00) >> 8;
|
||||
oid->ids[8] = (res & 0x000000FF) >> 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
snmp_log("bad");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum snmp_search_res
|
||||
snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint UNUSED contid, u8 next_state)
|
||||
{
|
||||
struct oid *oid = *searched;
|
||||
snmp_log(" **searched = 0x%p *oid = 0x%p", searched, oid);
|
||||
snmp_oid_dump(*searched);
|
||||
snmp_oid_dump(oid);
|
||||
u8 end_state = snmp_bgp_state(o_end);
|
||||
|
||||
snmp_log("before assumption %s [%u] < %u INTERNAL_END", debug_bgp_states[end_state], end_state, BGP_INTERNAL_END);
|
||||
// failed
|
||||
ASSUME(end_state <= BGP_INTERNAL_END);
|
||||
snmp_log("before assupmtion oid 0x%p != NULL (0x0)", oid);
|
||||
ASSUME(oid != NULL);
|
||||
|
||||
oid = update_bgp_oid(oid, next_state);
|
||||
|
||||
snmp_log("update bgp oid to state %s [%d]", debug_bgp_states[next_state], next_state);
|
||||
snmp_oid_dump(*searched);
|
||||
snmp_oid_dump(oid);
|
||||
|
||||
int found;
|
||||
while (!(found = snmp_bgp_find_next_oid(p, oid, contid)) && next_state <= end_state)
|
||||
{
|
||||
snmp_log("loop");
|
||||
|
||||
next_state = snmp_bgp_next_state(next_state);
|
||||
if (next_state == BGP_INTERNAL_END)
|
||||
break;
|
||||
oid = update_bgp_oid(oid, next_state);
|
||||
/* in search for next bgp state, we want to start from beginning */
|
||||
oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0;
|
||||
}
|
||||
|
||||
if (next_state <= end_state)
|
||||
{
|
||||
*searched = oid;
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
// free in the caller ?!
|
||||
mb_free(oid);
|
||||
*searched = NULL;
|
||||
return SNMP_SEARCH_END_OF_VIEW;
|
||||
}
|
||||
|
||||
enum snmp_search_res
|
||||
snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid)
|
||||
{
|
||||
u8 bgp_state = snmp_bgp_state(*searched);
|
||||
struct oid *oid = *searched;
|
||||
snmp_log("snmp_bgp_search2() with state %s [%d]", debug_bgp_states[bgp_state], bgp_state);
|
||||
|
||||
/* TODO remove todo below, then remove this code */
|
||||
if (is_dynamic(bgp_state))
|
||||
{
|
||||
snmp_log("returning oid with dynamic state");
|
||||
return snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
|
||||
//return snmp_bgp_search_dynamic(p, searched, contid, result, bgp_state);
|
||||
}
|
||||
|
||||
/* TODO snmp_bgp_has_value is false only for state which are not dynamic */
|
||||
if (!snmp_bgp_has_value(bgp_state) || !oid->include)
|
||||
{
|
||||
bgp_state = snmp_bgp_next_state(bgp_state);
|
||||
snmp_log("altering searched oid with next state %s [%d]", debug_bgp_states[bgp_state], bgp_state);
|
||||
snmp_oid_dump(*searched);
|
||||
snmp_log("after oid update:");
|
||||
snmp_oid_dump(*searched);
|
||||
|
||||
/* zero the ip address section for previously non-dynamic oid (search all peers) */
|
||||
for (int i = 5; i < MIN(9, oid->n_subid); i++)
|
||||
oid->ids[i] = 0;
|
||||
}
|
||||
|
||||
if (is_dynamic(bgp_state))
|
||||
{
|
||||
snmp_log("returning oid with dynamic state 2");
|
||||
return snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state);
|
||||
//return snmp_bgp_search_dynamic(p, o_start, contid, result, bgp_state);
|
||||
}
|
||||
|
||||
oid = *searched = update_bgp_oid(*searched, bgp_state);
|
||||
if (oid->n_subid == 3 && oid->ids[2] >= SNMP_BGP_VERSION &&
|
||||
oid->ids[2] <= SNMP_BGP_LOCAL_AS)
|
||||
{
|
||||
snmp_log("oid matches static state");
|
||||
oid->include = 0;
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
snmp_log("reached unguarded code, returning END_OF_VIEW");
|
||||
/* TODO */
|
||||
//if (
|
||||
|
||||
|
||||
return SNMP_SEARCH_END_OF_VIEW;
|
||||
// return SNMP_NO_SUCH_OBJECT;
|
||||
|
||||
#if 0
|
||||
if (is_dynamic(bgp_state))
|
||||
return snmp_bgp_search_dynamic(p, o_start, contid, res);
|
||||
|
||||
if (!snmp_bgp_has_value(bgp_state))
|
||||
{
|
||||
bgp_state = x;
|
||||
}
|
||||
print_bgp_record_all(p);
|
||||
|
||||
if (o_start->include)
|
||||
return snmp_bgp_search_included(p, o_start, contid, result, bgp_state);
|
||||
|
||||
u8 next_state = snmp_bgp_next_state(bgp_state);
|
||||
if (!is_dynamic(next_state))
|
||||
{
|
||||
o_start = update_bgp_oid(o_start, next_state);
|
||||
snmp_log("next state is also not dynamic");
|
||||
*res = o_start;
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
|
||||
return search_bgp_dynamic(p, o_start, o_end, contid, bgp_state);
|
||||
|
||||
|
||||
if (o_start->include && snmp_bgp_has_value(bgp_state))
|
||||
&& !is_dynamic(bgp_state))
|
||||
{
|
||||
if (o_start->n_subid == 3)
|
||||
{
|
||||
o_start->include = 0;
|
||||
*result = o_start;
|
||||
return SNMP_SEARCH_OK;
|
||||
}
|
||||
else if (o_start->n_subid > 3)
|
||||
return SNMP_SEARCH_NO_INSTANCE;
|
||||
else
|
||||
return SNMP_SEARCH_NO_OBJECT;
|
||||
}
|
||||
else if (o_start->include && snmp_bgp_has_value(bgp_state))
|
||||
&& is_dynamic(bgp_state))
|
||||
return search_bgp_dynamic1(p, o_start, contid, result);
|
||||
else if (o_start
|
||||
|
||||
/ * o_start is not inclusive * /
|
||||
#endif
|
||||
}
|
||||
|
||||
/* o_start could be o_curr, but has basically same meaning for searching */
|
||||
struct oid *
|
||||
search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid UNUSED)
|
||||
snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid UNUSED)
|
||||
{
|
||||
u8 start_state = snmp_bgp_state(o_start);
|
||||
//u8 state_curr = snmp_bgp_state(o_start);
|
||||
@ -674,14 +958,14 @@ search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uin
|
||||
if (o_start->include && snmp_bgp_has_value(start_state) &&
|
||||
!is_dynamic(start_state) && o_start->n_subid == 3)
|
||||
{
|
||||
snmp_log("search_bgp_mib() first search element (due to include field) returned");
|
||||
snmp_log("snmp_bgp_search() first search element (due to include field) returned");
|
||||
o_start->include = 0; /* disable including for next time */
|
||||
return o_start;
|
||||
}
|
||||
else if (o_start->include && snmp_bgp_has_value(start_state) &&
|
||||
is_dynamic(start_state))
|
||||
is_dynamic(start_state))
|
||||
{
|
||||
snmp_log("search_bgp_mib() first search element matched dynamic entry!");
|
||||
snmp_log("snmp_bgp_search() first search element matched dynamic entry!");
|
||||
return search_bgp_dynamic(p, o_start, o_end, contid, start_state);
|
||||
}
|
||||
|
||||
@ -728,19 +1012,21 @@ search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uin
|
||||
}
|
||||
|
||||
static byte *
|
||||
bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind *vb, byte *pkt, uint size
|
||||
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
|
||||
struct snmp_pdu_context *c, u8 state)
|
||||
{
|
||||
//snmp_log("bgp_fill_dynamic() valid ip %s", snmp_bgp_valid_ip4(oid) ? "true" : "false");
|
||||
|
||||
struct oid *oid = &vb->name;
|
||||
uint size = c->size - snmp_varbind_header_size(vb);
|
||||
uint UNUSED contid = c->context;
|
||||
byte *pkt;
|
||||
|
||||
ip_addr addr;
|
||||
if (snmp_bgp_valid_ip4(oid))
|
||||
if (oid_state_compare(oid, state) == 0 && snmp_bgp_valid_ip4(oid))
|
||||
addr = ipa_from_ip4(ip4_from_oid(oid));
|
||||
else
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
pkt = ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
return pkt;
|
||||
}
|
||||
|
||||
@ -754,25 +1040,23 @@ UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
{
|
||||
proto = ((struct proto_config *) pe->config)->proto;
|
||||
if (proto->proto == &proto_bgp &&
|
||||
ipa_equal(addr, ((struct bgp_proto *) proto)->remote_ip))
|
||||
ipa_equal(addr, ((struct bgp_proto *) proto)->remote_ip))
|
||||
{
|
||||
bgp_proto = (struct bgp_proto *) proto;
|
||||
snmp_log("bgp_dynamic_fill() using bgp_proto %p", bgp_proto);
|
||||
}
|
||||
|
||||
/* binded bgp protocol not found */
|
||||
else
|
||||
{
|
||||
die("Binded bgp protocol not found!");
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return pkt;
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return pkt;
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
}
|
||||
|
||||
struct bgp_conn *bgp_conn = bgp_proto->conn;
|
||||
@ -794,164 +1078,129 @@ UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
else
|
||||
bgp_state = MAX(bgp_in->state, bgp_out->state);
|
||||
|
||||
btime now;
|
||||
char last_error[2] = { bgp_proto->last_error_code & 0x00FF0000 >> 16,
|
||||
bgp_proto->last_error_code & 0x000000FF };
|
||||
switch (state)
|
||||
{
|
||||
|
||||
case BGP_INTERNAL_IDENTIFIER:
|
||||
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
|
||||
{
|
||||
snmp_put_ip4(pkt, bgp_proto->remote_ip);
|
||||
pkt += 4;
|
||||
/* the inserted ip has size 8 bytes, the BGP_DATA will increment by 4B */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(bgp_proto->remote_ip));
|
||||
else
|
||||
{
|
||||
snmp_put_blank(pkt); /* stores 4B of zeroes */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
pkt = snmp_varbind_ip4(vb, size, IP4_NONE);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_STATE:
|
||||
STORE_PTR(pkt, bgp_state);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_state);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_ADMIN_STATUS:
|
||||
/* struct proto ~ (struct proto *) bgp_proto */
|
||||
if (proto->disabled)
|
||||
STORE_PTR(pkt, AGENTX_ADMIN_STOP);
|
||||
pkt = snmp_varbind_int(vb, size, AGENTX_ADMIN_STOP);
|
||||
else
|
||||
STORE_PTR(pkt, AGENTX_ADMIN_START);
|
||||
pkt = snmp_varbind_int(vb, size, AGENTX_ADMIN_START);
|
||||
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_NEGOTIATED_VERSION:
|
||||
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
|
||||
STORE_PTR(pkt, 4); // TODO replace with MACRO
|
||||
pkt = snmp_varbind_int(vb, size, SNMP_BGP_NEGOTIATED_VER_VALUE);
|
||||
else
|
||||
STORE_PTR(pkt, 0); /* zero dictated by rfc */
|
||||
pkt = snmp_varbind_int(vb, size, SNMP_BGP_NEGOTIATED_VER_NO_VALUE);
|
||||
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_ADDR:
|
||||
// TODO XXX bgp_proto->link_addr & zero local_ip
|
||||
snmp_put_ip4(pkt, bgp_proto->local_ip);
|
||||
pkt += 4;
|
||||
/* the inserted ip has size 8 bytes, the BGP_DATA will increment by 4B */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(bgp_proto->local_ip));
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_PORT:
|
||||
STORE_PTR(pkt, bgp_conf->local_port);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conf->local_port);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_ADDR:
|
||||
snmp_put_ip4(pkt, bgp_proto->remote_ip);
|
||||
pkt += 4;
|
||||
/* the inserted ip has size 8 bytes, the BGP_DATA will increment by 4B */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
pkt = snmp_varbind_ip4(vb, size, ipa_to_ip4(bgp_proto->remote_ip));
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_PORT:
|
||||
STORE_PTR(pkt, bgp_conf->remote_port);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conf->remote_port);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_AS:
|
||||
STORE_PTR(pkt, bgp_proto->remote_as);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_proto->remote_as);
|
||||
break;
|
||||
|
||||
/* IN UPDATES */
|
||||
case BGP_INTERNAL_RX_UPDATES:
|
||||
STORE_PTR(pkt, bgp_stats->rx_updates);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
pkt = snmp_varbind_counter32(vb, size, bgp_stats->rx_updates);
|
||||
break;
|
||||
|
||||
/* OUT UPDATES */
|
||||
case BGP_INTERNAL_TX_UPDATES:
|
||||
STORE_PTR(pkt, bgp_stats->tx_updates);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
pkt = snmp_varbind_counter32(vb, size, bgp_stats->tx_updates);
|
||||
break;
|
||||
|
||||
/* IN MESSAGES */
|
||||
case BGP_INTERNAL_RX_MESSAGES:
|
||||
STORE_PTR(pkt, bgp_stats->rx_messages);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
pkt = snmp_varbind_counter32(vb, size, bgp_stats->rx_messages);
|
||||
break;
|
||||
|
||||
/* OUT MESSAGES */
|
||||
case BGP_INTERNAL_TX_MESSAGES:
|
||||
STORE_PTR(pkt, bgp_stats->tx_messages);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
pkt = snmp_varbind_counter32(vb, size, bgp_stats->tx_messages);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LAST_ERROR:
|
||||
STORE_PTR(pkt, 2);
|
||||
pkt += 4;
|
||||
|
||||
if (bgp_proto->last_error_code)
|
||||
{
|
||||
/* force network order */
|
||||
put_u32(pkt, bgp_proto->last_error_code & 0x00FF0000 << 8 |
|
||||
bgp_proto->last_error_code & 0x000000FF << 24);
|
||||
}
|
||||
else
|
||||
snmp_put_blank(pkt);
|
||||
|
||||
BGP_DATA(vb, AGENTX_OCTET_STRING, pkt);
|
||||
pkt = snmp_varbind_nstr(vb, size, last_error, 2);
|
||||
break;
|
||||
|
||||
// TODO finish me here
|
||||
case BGP_INTERNAL_FSM_TRANSITIONS:
|
||||
STORE_PTR(pkt, bgp_stats->fsm_established_transitions);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
pkt = snmp_varbind_counter32(vb, size,
|
||||
bgp_stats->fsm_established_transitions);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_FSM_ESTABLISHED_TIME:
|
||||
pkt = snmp_varbind_gauge32(vb, size,
|
||||
(current_time() - bgp_proto->last_established) TO_S);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_RETRY_INTERVAL:
|
||||
// retry interval != 0
|
||||
STORE_PTR(pkt, bgp_conf->connect_retry_time);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conf->connect_retry_time);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_HOLD_TIME:
|
||||
// (0, 3..65535)
|
||||
STORE_PTR(pkt, bgp_conn->hold_time);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conn->hold_time);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_KEEPALIVE:
|
||||
STORE_PTR(pkt, bgp_conn->keepalive_time);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conn->keepalive_time);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_HOLD_TIME_CONFIGURED:
|
||||
STORE_PTR(pkt, bgp_conf->hold_time);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
case BGP_INTERNAL_KEEPALIVE_CONFIGURED:
|
||||
STORE_PTR(pkt, bgp_conf->keepalive_time);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conf->hold_time);
|
||||
break;
|
||||
|
||||
// finish me here
|
||||
case BGP_INTERNAL_ORIGINATION_INTERVAL:
|
||||
case BGP_INTERNAL_KEEPALIVE_CONFIGURED:
|
||||
pkt = snmp_varbind_int(vb, size, bgp_conf->keepalive_time);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_ORIGINATION_INTERVAL:
|
||||
// (1..65535) but is not supported
|
||||
pkt = snmp_varbind_int(vb, size, 0);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT:
|
||||
// (1..65535) but is not supported
|
||||
pkt = snmp_varbind_int(vb, size, 0);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
|
||||
now = current_time();
|
||||
STORE_PTR(pkt, (now - bgp_proto->last_rx_update) TO_S );
|
||||
BGP_DATA(vb, AGENTX_GAUGE_32, pkt);
|
||||
pkt = snmp_varbind_gauge32(vb, size, (current_time()
|
||||
- bgp_proto->last_rx_update) TO_S);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_END:
|
||||
@ -970,78 +1219,96 @@ UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pkt)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
}
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
|
||||
static byte *
|
||||
bgp_fill_static(struct snmp_proto *p, struct agentx_varbind *vb, byte *pkt, uint size
|
||||
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
{
|
||||
snmp_log("snmp bgp_fill_static ()\n");
|
||||
byte *temp = pkt;
|
||||
snmp_log("bgp_fill_static: vb->type %u, ptk %02x", vb->type, *((u32 *) pkt));
|
||||
|
||||
struct oid *oid = &vb->name;
|
||||
snmp_oid_dump(oid);
|
||||
snmp_log("bgp_fill_static");
|
||||
|
||||
/* snmp_bgp_state() check only prefix. To be sure on oid equivalence we need to
|
||||
* compare the oid->n_subid length. All BGP static fields have same n_subid.
|
||||
*/
|
||||
if (oid->n_subid != 3)
|
||||
if (oid_state_compare(oid, state) < 0 || state == BGP_INTERNAL_END)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return pkt;
|
||||
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
}
|
||||
else if (oid_state_compare(oid, state) > 0)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case BGP_INTERNAL_VERSION:
|
||||
STORE_PTR(pkt, 1); /* store string len */
|
||||
pkt += 4;
|
||||
STORE_PTR(pkt, BGP4_VERSIONS);
|
||||
|
||||
/* real size is 8 but we already shifted the pkt by 4 */
|
||||
BGP_DATA(vb, AGENTX_OCTET_STRING, pkt);
|
||||
pkt = snmp_varbind_nstr(vb, size, BGP4_VERSIONS, 1);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_AS:
|
||||
// XXX local as to use
|
||||
|
||||
STORE_PTR(pkt, p->local_as);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
pkt = snmp_varbind_int(vb, size, p->local_as);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_BGP:
|
||||
default:
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
pkt = ((byte *) vb) + snmp_varbind_header_size(vb);
|
||||
break;
|
||||
}
|
||||
|
||||
snmp_log("bgp_fill_static: type %u packet %p", vb->type, pkt);
|
||||
snmp_oid_dump(oid);
|
||||
|
||||
snmp_log("snmp ended with non empty pkt %u starting from %p to %p\n", pkt -
|
||||
temp, temp, pkt);
|
||||
snmp_dump_packet(temp, pkt - temp);
|
||||
return pkt;
|
||||
}
|
||||
|
||||
byte *
|
||||
snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, byte *buf UNUSED,
|
||||
uint size UNUSED, uint contid UNUSED, int byte_ord UNUSED)
|
||||
void
|
||||
snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
|
||||
struct snmp_pdu_context *c)
|
||||
{
|
||||
u8 state = snmp_bgp_state(&vb->name);
|
||||
//snmp_log("snmp_bgp_fill() state %u is dynamic %s has value %s", state, is_dynamic(state) ? "true" : "false", snmp_bgp_has_value(state) ? "true" : "false");
|
||||
//byte *tmp;
|
||||
|
||||
byte *pkt;
|
||||
if (!is_dynamic(state))
|
||||
return bgp_fill_static(p, vb, buf, size, contid, byte_ord, state);
|
||||
{
|
||||
//return bgp_fill_static(p, vb, c->buffer, c->size, c->context, c->byte_ord, state);
|
||||
pkt = bgp_fill_static(p, vb, c->buffer, c->size, c->context, c->byte_ord, state);
|
||||
ADVANCE(c->buffer, c->size, pkt - c->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_dynamic(state) && snmp_bgp_has_value(state))
|
||||
return bgp_fill_dynamic(p, vb, buf, size, contid, byte_ord, state);
|
||||
|
||||
{
|
||||
pkt = bgp_fill_dynamic(p, vb, c, state);
|
||||
ADVANCE(c->buffer, c->size, pkt - c->buffer);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return buf;
|
||||
die("snmp_bgp_fill unreachable");
|
||||
// AGENTX_NO_SUCH_OBJECT
|
||||
((void) c->buffer);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
{
|
||||
snmp_log("has no value");
|
||||
struct agentx_varbind *vb = snmp_create_varbind(buf, oid);
|
||||
buf += snmp_varbind_size(vb);
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return buf;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,10 @@ enum BGP4_MIB {
|
||||
SNMP_BGP_IN_UPDATE_ELAPSED_TIME = 24, /* UNSUPPORTED */
|
||||
} PACKED;
|
||||
|
||||
/* version of BGP, here BGP-4 */
|
||||
#define SNMP_BGP_NEGOTIATED_VER_VALUE 4
|
||||
#define SNMP_BGP_NEGOTIATED_VER_NO_VALUE 0
|
||||
|
||||
//void snmp_init_bgp_table(void);
|
||||
//void snmp_del_bgp_table(void);
|
||||
|
||||
@ -45,8 +49,10 @@ u8 snmp_bgp_state(struct oid *o);
|
||||
u8 snmp_bgp_get_valid(u8 state);
|
||||
u8 snmp_bgp_getnext_valid(u8 state);
|
||||
|
||||
struct oid *search_bgp_mib(struct snmp_proto *p , struct oid *o_start, struct oid *o_end, uint contid);
|
||||
byte * snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, byte *buf, uint size, uint contid UNUSED, int byte_ord);
|
||||
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);
|
||||
//byte * snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, byte *buf, uint size, uint contid UNUSED, int byte_ord);
|
||||
void snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, struct snmp_pdu_context *c);
|
||||
|
||||
#define BGP4_MIB_VERSION 1
|
||||
#define BGP4_MIB_LOCAL_AS 2
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "snmp_utils.h"
|
||||
|
||||
int agentx_type_size(enum agentx_type t);
|
||||
|
||||
/**
|
||||
* snmp_is_oid_empty - check if oid is null-valued
|
||||
* @oid: object identifier to check
|
||||
@ -17,7 +19,7 @@
|
||||
* Test if the oid header is full of zeroes. For @oid NULL returns 0.
|
||||
*/
|
||||
int
|
||||
snmp_is_oid_empty(struct oid *oid)
|
||||
snmp_is_oid_empty(const struct oid *oid)
|
||||
{
|
||||
if (oid != NULL)
|
||||
return oid->n_subid == 0 && oid->prefix == 0 && oid->include == 0;
|
||||
@ -30,10 +32,38 @@ snmp_is_oid_empty(struct oid *oid)
|
||||
* @buf: packet first byte
|
||||
* @pkt: first byte past packet end
|
||||
*/
|
||||
size_t
|
||||
snmp_pkt_len(byte *buf, byte *pkt)
|
||||
uint
|
||||
snmp_pkt_len(byte *start, byte *end)
|
||||
{
|
||||
return (pkt - buf) - AGENTX_HEADER_SIZE;
|
||||
snmp_log("snmp_pkt_len start 0x%p end 0x%p res %u", start, end, (end - start)
|
||||
- AGENTX_HEADER_SIZE);
|
||||
return (end - start) - AGENTX_HEADER_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* used for copying oid to in buffer oid @dest
|
||||
*/
|
||||
void snmp_oid_copy(struct oid *dest, const struct oid *src)
|
||||
{
|
||||
STORE_U8(dest->n_subid, src->n_subid);
|
||||
STORE_U8(dest->prefix, src->prefix);
|
||||
STORE_U8(dest->include, src->include);
|
||||
STORE_U8(dest->pad, 0);
|
||||
|
||||
for (int i = 0; i < src->n_subid; i++)
|
||||
STORE_U32(dest->ids[i], src->ids[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
struct oid *
|
||||
snmp_oid_duplicate(pool *pool, const struct oid *oid)
|
||||
{
|
||||
struct oid *res = mb_alloc(pool, snmp_oid_size(oid));
|
||||
memcpy(res, oid, snmp_oid_size(oid));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,6 +76,12 @@ snmp_oid_blank(struct snmp_proto *p)
|
||||
return mb_allocz(p->p.pool, sizeof(struct oid));
|
||||
}
|
||||
|
||||
size_t
|
||||
snmp_str_size_from_len(uint len)
|
||||
{
|
||||
return 4 + BIRD_ALIGN(len, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* snmp_str_size - return in packet size of supplied string
|
||||
* @str: measured string
|
||||
@ -53,10 +89,10 @@ snmp_oid_blank(struct snmp_proto *p)
|
||||
* Returned value is string length aligned to 4 byte with 32bit length
|
||||
* annotation included.
|
||||
*/
|
||||
size_t
|
||||
inline size_t
|
||||
snmp_str_size(const char *str)
|
||||
{
|
||||
return 4 + BIRD_ALIGN(strlen(str), 4);
|
||||
return snmp_str_size_from_len(strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +100,7 @@ snmp_str_size(const char *str)
|
||||
* @o: object identifier to use
|
||||
*/
|
||||
uint
|
||||
snmp_oid_size(struct oid *o)
|
||||
snmp_oid_size(const struct oid *o)
|
||||
{
|
||||
return 4 + (o->n_subid * 4);
|
||||
}
|
||||
@ -79,28 +115,62 @@ snmp_oid_sizeof(uint n_subid)
|
||||
return sizeof(struct oid) + n_subid * sizeof(u32);
|
||||
}
|
||||
|
||||
uint snmp_varbind_hdr_size_from_oid(struct oid *oid)
|
||||
{
|
||||
return snmp_oid_size(oid) + 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* snmp_vb_size - measure size of varbind in bytes
|
||||
* @vb: variable binding to use
|
||||
*/
|
||||
uint
|
||||
snmp_varbind_size(struct agentx_varbind *vb)
|
||||
snmp_varbind_header_size(struct agentx_varbind *vb)
|
||||
{
|
||||
return snmp_oid_size(&vb->name) + 4;
|
||||
return snmp_varbind_hdr_size_from_oid(&vb->name);
|
||||
}
|
||||
|
||||
uint
|
||||
snmp_varbind_size(struct agentx_varbind *vb, int byte_ord)
|
||||
{
|
||||
uint hdr_size = snmp_varbind_header_size(vb);
|
||||
int s = agentx_type_size(vb->type);
|
||||
|
||||
if (s >= 0)
|
||||
return hdr_size + (uint) s;
|
||||
|
||||
void *data = ((void *) vb) + hdr_size;
|
||||
|
||||
if (vb->type == AGENTX_OBJECT_ID)
|
||||
return hdr_size + snmp_oid_size((struct oid *) data);
|
||||
|
||||
/*
|
||||
* Load length of octet string
|
||||
* (AGENTX_OCTET_STRING, AGENTX_IP_ADDRESS, AGENTX_OPAQUE)
|
||||
*/
|
||||
return hdr_size + snmp_str_size_from_len(LOAD_PTR(data, byte_ord));
|
||||
}
|
||||
|
||||
inline uint
|
||||
snmp_context_size(struct agentx_context *c)
|
||||
{
|
||||
return (c && c->length) ? snmp_str_size_from_len(c->length) : 0;
|
||||
}
|
||||
|
||||
struct agentx_varbind *
|
||||
snmp_create_varbind(byte *buf, struct oid *oid)
|
||||
{
|
||||
struct agentx_varbind *vb = (void*) buf;
|
||||
vb->pad = 0;
|
||||
memcpy(&vb->name, oid, snmp_oid_size(oid));
|
||||
return vb;
|
||||
}
|
||||
|
||||
byte *snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new)
|
||||
byte *
|
||||
snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new)
|
||||
{
|
||||
memcpy(&vb->name, new, snmp_oid_size(new));
|
||||
return (void *) vb + snmp_varbind_size(vb);
|
||||
return (void *) vb + snmp_varbind_header_size(vb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +179,7 @@ byte *snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new)
|
||||
* @start: index of first address id
|
||||
*/
|
||||
int
|
||||
snmp_valid_ip4_index(struct oid *o, uint start)
|
||||
snmp_valid_ip4_index(const struct oid *o, uint start)
|
||||
{
|
||||
if (start + 3 < o->n_subid)
|
||||
return snmp_valid_ip4_index_unsafe(o, start);
|
||||
@ -126,7 +196,7 @@ snmp_valid_ip4_index(struct oid *o, uint start)
|
||||
* length sufficiency is done.
|
||||
*/
|
||||
int
|
||||
snmp_valid_ip4_index_unsafe(struct oid *o, uint start)
|
||||
snmp_valid_ip4_index_unsafe(const struct oid *o, uint start)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (o->ids[start + i] >= 256)
|
||||
@ -135,6 +205,23 @@ snmp_valid_ip4_index_unsafe(struct oid *o, uint start)
|
||||
return 1; // true
|
||||
}
|
||||
|
||||
byte *
|
||||
snmp_put_nstr(byte *buf, const char *str, uint len)
|
||||
{
|
||||
uint alen = BIRD_ALIGN(len, 4);
|
||||
|
||||
// TODO check for '\0' in the str bytes?
|
||||
STORE_PTR(buf, len);
|
||||
buf += 4;
|
||||
memcpy(buf, str, len);
|
||||
|
||||
/* Insert zero padding in the gap at the end */
|
||||
for (uint i = 0; i < alen - len; i++)
|
||||
buf[len + i] = 0x00;
|
||||
|
||||
return buf + alen;
|
||||
}
|
||||
|
||||
/**
|
||||
* snmp_put_str - put string into SNMP PDU transcieve buffer
|
||||
* @buf: pointer to first unoccupied buffer byte
|
||||
@ -148,28 +235,16 @@ byte *
|
||||
snmp_put_str(byte *buf, const char *str)
|
||||
{
|
||||
uint len = strlen(str);
|
||||
uint slen = BIRD_ALIGN(len, 4);
|
||||
|
||||
if (len > MAX_STR)
|
||||
return NULL;
|
||||
|
||||
STORE_PTR(buf, len);
|
||||
|
||||
memcpy(buf + 4, str, len);
|
||||
|
||||
for (uint i = 0; i < slen - len; i++)
|
||||
buf[len + i] = 0x00; // PADDING
|
||||
|
||||
return buf + snmp_str_size(str);
|
||||
return snmp_put_nstr(buf, str, len);
|
||||
}
|
||||
|
||||
byte *
|
||||
snmp_put_ip4(byte *buf, ip_addr addr)
|
||||
snmp_put_ip4(byte *buf, ip4_addr addr)
|
||||
{
|
||||
/* octet string has size 4 bytes */
|
||||
STORE_PTR(buf, 4);
|
||||
|
||||
put_u32(buf+4, ipa_to_u32(addr));
|
||||
put_u32(buf+4, ip4_to_u32(addr));
|
||||
|
||||
return buf + 8;
|
||||
}
|
||||
@ -231,10 +306,10 @@ void
|
||||
snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr)
|
||||
{
|
||||
u32 temp = ip4_to_u32(addr);
|
||||
STORE(o->ids[start], temp >> 24);
|
||||
STORE(o->ids[start + 1], (temp >> 16) & 0xFF);
|
||||
STORE(o->ids[start + 2], (temp >> 8) & 0xFF);
|
||||
STORE(o->ids[start + 3], temp & 0xFF);
|
||||
STORE_U32(o->ids[start], temp >> 24);
|
||||
STORE_U32(o->ids[start + 1], (temp >> 16) & 0xFF);
|
||||
STORE_U32(o->ids[start + 2], (temp >> 8) & 0xFF);
|
||||
STORE_U32(o->ids[start + 3], temp & 0xFF);
|
||||
}
|
||||
|
||||
void snmp_oid_dump(struct oid *oid)
|
||||
@ -278,7 +353,7 @@ void snmp_oid_dump(struct oid *oid)
|
||||
* and 1 otherwise
|
||||
*/
|
||||
int
|
||||
snmp_oid_compare(struct oid *left, struct oid *right)
|
||||
snmp_oid_compare(const struct oid *left, const struct oid *right)
|
||||
{
|
||||
const u32 INTERNET_PREFIX[] = {1, 3, 6, 1};
|
||||
|
||||
@ -404,3 +479,113 @@ snmp_dump_packet(byte *pkt, uint size)
|
||||
snmp_log("pkt [%d] 0x%02x%02x%02x%02x", i, pkt[i],pkt[i+1],pkt[i+2],pkt[i+3]);
|
||||
snmp_log("end dump");
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns length of agentx_type @type in bytes.
|
||||
* Variable length types result in -1.
|
||||
*/
|
||||
int
|
||||
agentx_type_size(enum agentx_type type)
|
||||
{
|
||||
/*
|
||||
* AGENTX_NULL, AGENTX_NO_SUCH_OBJECT, AGENTX_NO_SUCH_INSTANCE,
|
||||
* AGENTX_END_OF_MIB_VIEW
|
||||
*/
|
||||
if (type >= AGENTX_NO_SUCH_OBJECT || type == AGENTX_NULL)
|
||||
return 0;
|
||||
|
||||
/* AGENTX_INTEGER, AGENTX_COUNTER_32, AGENTX_GAUGE_32, AGENTX_TIME_TICKS */
|
||||
if (type >= AGENTX_COUNTER_32 && type <= AGENTX_TIME_TICKS ||
|
||||
type == AGENTX_INTEGER)
|
||||
return 4;
|
||||
|
||||
/* AGENTX_COUNTER_64 */
|
||||
if (type == AGENTX_COUNTER_64)
|
||||
return 8;
|
||||
|
||||
/* AGENTX_OBJECT_ID, AGENTX_OCTET_STRING, AGENTX_IP_ADDRESS, AGENTX_OPAQUE */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
snmp_varbind_type32(struct agentx_varbind *vb, uint size, enum agentx_type type, u32 val)
|
||||
{
|
||||
ASSUME(agentx_type_size(type) == 4); /* type has 4B representation */
|
||||
|
||||
if (size < (uint) agentx_type_size(type))
|
||||
{
|
||||
snmp_log("varbind type32 returned NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vb->type = type;
|
||||
u32 *data = SNMP_VB_DATA(vb);
|
||||
snmp_log("varbind type32 vb data 0x%p (from vb 0x%p)", data, (void *) vb);
|
||||
*data = val;
|
||||
return (byte *)(data + 1);
|
||||
}
|
||||
|
||||
inline byte *
|
||||
snmp_varbind_int(struct agentx_varbind *vb, uint size, u32 val)
|
||||
{
|
||||
return snmp_varbind_type32(vb, size, AGENTX_INTEGER, val);
|
||||
}
|
||||
|
||||
|
||||
inline byte *
|
||||
snmp_varbind_counter32(struct agentx_varbind *vb, uint size, u32 val)
|
||||
{
|
||||
return snmp_varbind_type32(vb, size, AGENTX_COUNTER_32, val);
|
||||
}
|
||||
|
||||
inline byte *
|
||||
snmp_varbind_gauge32(struct agentx_varbind *vb, uint size, s64 val)
|
||||
{
|
||||
return snmp_varbind_type32(vb, size, AGENTX_GAUGE_32,
|
||||
MAX(0, MIN(val, UINT32_MAX)));
|
||||
}
|
||||
|
||||
inline byte *
|
||||
snmp_varbind_ip4(struct agentx_varbind *vb, uint size, ip4_addr addr)
|
||||
{
|
||||
if (size < snmp_str_size_from_len(4))
|
||||
{
|
||||
snmp_log("varbind ip4 NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vb->type = AGENTX_IP_ADDRESS;
|
||||
snmp_log("snmp_varbind_ip4 vb data 0x%p (from vb 0x%p)", SNMP_VB_DATA(vb), (void
|
||||
*) vb);
|
||||
return snmp_put_ip4(SNMP_VB_DATA(vb), addr);
|
||||
}
|
||||
|
||||
inline byte *
|
||||
snmp_varbind_nstr(struct agentx_varbind *vb, uint size, const char *str, uint len)
|
||||
{
|
||||
if (size < snmp_str_size_from_len(len))
|
||||
{
|
||||
snmp_log("varbind nstr NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vb->type = AGENTX_OCTET_STRING;
|
||||
//die("snmp_varbind_nstr() %p.data = %p", vb, SNMP_VB_DATA(vb));
|
||||
snmp_log("snmp_varbind_nstr vb data 0x%p (from vb 0x%p)", SNMP_VB_DATA(vb), (void *) vb);
|
||||
//snmp_log("snmp_varbind_nstr() %p.data = %p", vb, SNMP_VB_DATA(vb));
|
||||
return snmp_put_nstr(SNMP_VB_DATA(vb), str, len);
|
||||
}
|
||||
|
||||
inline enum agentx_type
|
||||
snmp_search_res_to_type(enum snmp_search_res r)
|
||||
{
|
||||
ASSUME(r != SNMP_SEARCH_OK);
|
||||
static enum agentx_type type_arr[] = {
|
||||
[SNMP_SEARCH_NO_OBJECT] = AGENTX_NO_SUCH_OBJECT,
|
||||
[SNMP_SEARCH_NO_INSTANCE] = AGENTX_NO_SUCH_INSTANCE,
|
||||
[SNMP_SEARCH_END_OF_VIEW] = AGENTX_END_OF_MIB_VIEW,
|
||||
};
|
||||
|
||||
return type_arr[r];
|
||||
}
|
||||
|
@ -3,30 +3,38 @@
|
||||
|
||||
#include "subagent.h"
|
||||
|
||||
size_t snmp_pkt_len(byte *buf, byte *pkt);
|
||||
uint snmp_pkt_len(byte *start, byte *end);
|
||||
size_t snmp_str_size_from_len(uint len);
|
||||
size_t snmp_str_size(const char *str);
|
||||
int snmp_is_oid_empty(struct oid *oid);
|
||||
int snmp_valid_ip4_index(struct oid *o, uint start);
|
||||
int snmp_valid_ip4_index_unsafe(struct oid *o, uint start);
|
||||
uint snmp_oid_size(struct oid *o);
|
||||
int snmp_is_oid_empty(const struct oid *oid);
|
||||
int snmp_valid_ip4_index(const struct oid *o, uint start);
|
||||
int snmp_valid_ip4_index_unsafe(const struct oid *o, uint start);
|
||||
uint snmp_oid_size(const struct oid *o);
|
||||
size_t snmp_oid_sizeof(uint n_subid);
|
||||
uint snmp_varbind_size(struct agentx_varbind *vb);
|
||||
uint snmp_varbind_hdr_size_from_oid(struct oid *oid);
|
||||
uint snmp_varbind_header_size(struct agentx_varbind *vb);
|
||||
uint snmp_varbind_size(struct agentx_varbind *vb, int byte_ord);
|
||||
uint snmp_context_size(struct agentx_context *c);
|
||||
|
||||
void snmp_oid_copy(struct oid *dest, const struct oid *src);
|
||||
|
||||
struct oid *snmp_oid_duplicate(pool *pool, const struct oid *oid);
|
||||
struct oid *snmp_oid_blank(struct snmp_proto *p);
|
||||
|
||||
struct agentx_varbind *snmp_create_varbind(byte* buf, struct oid *oid);
|
||||
byte *snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new);
|
||||
|
||||
int snmp_oid_compare(struct oid *first, struct oid *second);
|
||||
int snmp_oid_compare(const struct oid *first, const struct oid *second);
|
||||
|
||||
byte *snmp_no_such_object(byte *buf, struct agentx_varbind *vb, struct oid *oid);
|
||||
byte *snmp_no_such_instance(byte *buf, struct agentx_varbind *vb, struct oid *oid);
|
||||
|
||||
byte *snmp_put_str(byte *buf, const char *str);
|
||||
byte *snmp_put_nstr(byte *buf, const char *str, uint len);
|
||||
byte *snmp_put_blank(byte *buf);
|
||||
byte *snmp_put_oid(byte *buf, struct oid *oid);
|
||||
|
||||
byte *snmp_put_ip4(byte *buf, ip_addr ip4);
|
||||
byte *snmp_put_ip4(byte *buf, ip4_addr ip4);
|
||||
|
||||
byte *snmp_put_fbyte(byte *buf, u8 data);
|
||||
|
||||
@ -34,13 +42,19 @@ void snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr);
|
||||
|
||||
void snmp_oid_dump(struct oid *oid);
|
||||
|
||||
int snmp_oid_compare(struct oid *left, struct oid *right);
|
||||
|
||||
struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
|
||||
//struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
|
||||
|
||||
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);
|
||||
|
||||
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_gauge32(struct agentx_varbind *vb, uint size, s64 val);
|
||||
byte *snmp_varbind_ip4(struct agentx_varbind *vb, uint size, ip4_addr addr);
|
||||
byte *snmp_varbind_nstr(struct agentx_varbind *vb, uint size, const char *str, uint len);
|
||||
|
||||
void snmp_dump_packet(byte *pkt, uint size);
|
||||
|
||||
enum agentx_type snmp_search_res_to_type(enum snmp_search_res res);
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@ enum SNMP_CLASSES {
|
||||
SNMP_CLASS_END,
|
||||
};
|
||||
|
||||
#define BGP4_VERSIONS 0x10
|
||||
#define BGP4_VERSIONS ((char[]) { 0x10 })
|
||||
|
||||
enum agentx_type {
|
||||
AGENTX_INTEGER = 2,
|
||||
@ -44,6 +44,13 @@ enum agentx_type {
|
||||
AGENTX_END_OF_MIB_VIEW = 130,
|
||||
} PACKED;
|
||||
|
||||
enum snmp_search_res {
|
||||
SNMP_SEARCH_OK = 0,
|
||||
SNMP_SEARCH_NO_OBJECT = 1,
|
||||
SNMP_SEARCH_NO_INSTANCE = 2,
|
||||
SNMP_SEARCH_END_OF_VIEW = 3,
|
||||
};
|
||||
|
||||
#define AGENTX_ADMIN_STOP 1
|
||||
#define AGENTX_ADMIN_START 2
|
||||
|
||||
@ -53,18 +60,15 @@ enum agentx_type {
|
||||
#define SNMP_NATIVE
|
||||
|
||||
#ifdef SNMP_NATIVE
|
||||
#define STORE(v,c) (v) = (u32) (c)
|
||||
#define STORE_16(v,c) (v) = (u16) (c)
|
||||
#define STORE_PTR(v,c) *((u32 *) (v)) = (u32) (c)
|
||||
#define SNMP_UPDATE(h,l) \
|
||||
STORE((h)->payload, l)
|
||||
|
||||
#define STORE_U32(dest, val) ((dest) = (u32) (val))
|
||||
#define STORE_U16(dest, val) ((dest) = (u16) (val))
|
||||
#define STORE_U8(dest, val) ((dest) = (u8) (val))
|
||||
#define STORE_PTR(ptr, val) (*((u32 *) (ptr)) = (u32) (val))
|
||||
#else
|
||||
#define STORE(v, c) put_u32(&v, c)
|
||||
#define STORE_16(v,c) put_u32(&v, c)
|
||||
#define STORE_PTR(v,c) put_u32(v, c)
|
||||
#define SNMP_UPDATE(h,l) \
|
||||
STORE(h->payload, l)
|
||||
#define STORE_U32(dest, val) put_u32(&(dest), (val))
|
||||
#define STORE_U16(dest, val) put_u16(&(dest), (val))
|
||||
#define STORE_U8(dest, val) put_u8(&(dest), (val))
|
||||
#define STORE_PTR(ptr, val) put_u32(ptr, val)
|
||||
#endif
|
||||
|
||||
/* storing byte (u8) is always the same */
|
||||
@ -82,18 +86,18 @@ enum agentx_type {
|
||||
#endif
|
||||
|
||||
#define SNMP_B_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
|
||||
|
||||
#define SNMP_SESSION(h, p) \
|
||||
STORE(h->session_id, p->session_id); \
|
||||
STORE(h->transaction_id, p->transaction_id); \
|
||||
p->transaction_id++; \
|
||||
STORE(h->packet_id, p->packet_id);
|
||||
#define SNMP_BLANK_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
|
||||
|
||||
#define SNMP_CREATE(b, t, n) \
|
||||
n = (void *) (b); \
|
||||
memset(n, 0, sizeof(t)); \
|
||||
(b) += sizeof(t);
|
||||
|
||||
#define SNMP_SESSION(h, p) \
|
||||
STORE_U32(h->session_id, p->session_id); \
|
||||
STORE_U32(h->transaction_id, p->transaction_id); \
|
||||
STORE_U32(h->packet_id, p->packet_id)
|
||||
|
||||
#define LOAD(v, bo) ((bo) ? get_u32(&v) : (u32) (v))
|
||||
#define LOAD_16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
|
||||
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : (u32) *(v))
|
||||
@ -125,7 +129,17 @@ enum agentx_type {
|
||||
(varbind)->type = type_; \
|
||||
packet += offset;
|
||||
|
||||
#define BGP_DATA(varbind, type_, packet) BGP_DATA_(varbind, type_, packet, 4)
|
||||
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \
|
||||
({ \
|
||||
struct agentx_varbind *vb = (void *) buf; \
|
||||
SNMP_FILL_VARBIND(vb, oid, byte_ord); \
|
||||
})
|
||||
|
||||
#define SNMP_FILL_VARBIND(vb, oid, byte_ord) \
|
||||
snmp_oid_copy(&(vb)->name, (oid), (byte_ord)), snmp_oid_size((oid))
|
||||
|
||||
#define SNMP_VB_DATA(varbind) \
|
||||
(((void *)(varbind)) + snmp_varbind_header_size(varbind))
|
||||
|
||||
struct agentx_header {
|
||||
u8 version;
|
||||
@ -273,12 +287,45 @@ enum agentx_response_err {
|
||||
AGENTX_RES_PROCESSING_ERR = 268,
|
||||
} PACKED;
|
||||
|
||||
struct agentx_context {
|
||||
char *context; /* string name of this context */
|
||||
uint length; /* normal strlen() size */
|
||||
/* add buffered context hash? */
|
||||
};
|
||||
|
||||
struct snmp_pdu_context {
|
||||
byte *buffer; /* pointer to buffer */
|
||||
uint size; /* unused space in buffer */
|
||||
uint context; /* context hash */
|
||||
int byte_ord; /* flag signaling NETWORK_BYTE_ORDER */
|
||||
enum agentx_response_err error; /* storage for result of current action */
|
||||
};
|
||||
|
||||
struct agentx_alloc_context {
|
||||
u8 is_instance; /* flag INSTANCE_REGISTRATION */
|
||||
u8 new_index; /* flag NEW_INDEX */
|
||||
u8 any_index; /* flag ANY_INDEX */
|
||||
char *context; /* context to allocate in */
|
||||
uint clen; /* length of context string */
|
||||
};
|
||||
|
||||
struct additional_buffer {
|
||||
node n;
|
||||
byte *buf; /* pointer to buffer data */
|
||||
byte *pos; /* position of first unused byte */
|
||||
};
|
||||
|
||||
int snmp_rx(sock *sk, uint size);
|
||||
int snmp_rx_stop(sock *sk, uint size);
|
||||
void snmp_down(struct snmp_proto *p);
|
||||
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);
|
||||
|
||||
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c);
|
||||
|
||||
struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o, int byte_ord);
|
||||
u8 snmp_get_mib_class(const struct oid *oid);
|
||||
|
||||
// debug wrapper
|
||||
#define snmp_log(...) log(L_INFO "snmp " __VA_ARGS__)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user