mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-31 14:11:54 +00:00
fix the Get and GetNext
missing some functionality around GetBulk
This commit is contained in:
parent
9a75af4573
commit
508a420327
@ -1,4 +1,4 @@
|
||||
src := snmp.c subagent.c bgp_mib.c
|
||||
src := snmp.c snmp_utils.c subagent.c bgp_mib.c
|
||||
obj := $(src-o-files)
|
||||
$(all-daemon)
|
||||
$(cf-local)
|
||||
|
@ -11,6 +11,7 @@
|
||||
/* BGP_MIB states see enum BGP_INTERNAL_STATES */
|
||||
|
||||
#include "snmp.h"
|
||||
#include "snmp_utils.h"
|
||||
#include "subagent.h"
|
||||
#include "bgp_mib.h"
|
||||
|
||||
@ -56,7 +57,7 @@ snmp_bgp_register()
|
||||
int
|
||||
snmp_bgp_valid_ip4(struct oid *o)
|
||||
{
|
||||
return snmp_valid_ip4_index_safe(o, 6);
|
||||
return snmp_valid_ip4_index(o, 5);
|
||||
}
|
||||
|
||||
static u8
|
||||
@ -134,9 +135,9 @@ snmp_bgp_state(struct oid *oid)
|
||||
/* else oid->n_subid >= 2 */
|
||||
/* fall through */
|
||||
|
||||
/* between ids[6] and ids[9] should be IP address
|
||||
/* between ids[5] and ids[8] (n_subid == 9) should be IP address
|
||||
* validity is checked later in execution because
|
||||
* this field also could mean a boundry (upper or lower)
|
||||
* this field also could mean a query boundry (upper or lower)
|
||||
*/
|
||||
case 9:
|
||||
case 8:
|
||||
@ -198,7 +199,7 @@ snmp_bgp_state(struct oid *oid)
|
||||
return state;
|
||||
}
|
||||
|
||||
inline int
|
||||
static inline int
|
||||
is_dynamic(u8 state)
|
||||
{
|
||||
return (state >= BGP_INTERNAL_IDENTIFIER &&
|
||||
@ -208,15 +209,17 @@ is_dynamic(u8 state)
|
||||
static inline int
|
||||
snmp_bgp_has_value(u8 state)
|
||||
{
|
||||
/* bitmap would be faster */
|
||||
if (state <= BGP_INTERNAL_BGP ||
|
||||
state == BGP_INTERNAL_PEER_TABLE ||
|
||||
state == BGP_INTERNAL_PEER_ENTRY)
|
||||
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 */
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
return 1; /* has value */
|
||||
}
|
||||
|
||||
@ -423,7 +426,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, net4_prefix(net));
|
||||
snmp_oid_ip4_index(o, 5, net4_prefix(net));
|
||||
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
@ -440,13 +443,22 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
|
||||
return NULL;
|
||||
}
|
||||
|
||||
byte *
|
||||
snmp_bgp_fill(struct snmp_proto *p UNUSED, struct oid *oid, byte *buf UNUSED,
|
||||
uint size UNUSED, uint contid UNUSED, int byte_ord UNUSED)
|
||||
static struct oid *
|
||||
search_bgp_dynamic(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid
|
||||
UNUSED, u8 next_state)
|
||||
{
|
||||
u8 state = snmp_bgp_state(oid);
|
||||
(void)state;
|
||||
return NULL;
|
||||
/* TODO can be remove after implementing all BGP4-MIB::bgpPeerTable columns */
|
||||
struct oid *copy = o_start;
|
||||
do {
|
||||
o_start = copy = update_bgp_oid(copy, next_state);
|
||||
|
||||
o_start = bgp_find_dynamic_oid(p, o_start, o_end, next_state);
|
||||
|
||||
next_state = snmp_bgp_next_state(next_state);
|
||||
|
||||
} while (o_start == NULL && next_state < BGP_INTERNAL_END);
|
||||
|
||||
return o_start;
|
||||
}
|
||||
|
||||
/* o_start could be o_curr, but has basically same meaning for searching */
|
||||
@ -474,78 +486,266 @@ search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uin
|
||||
return o_start;
|
||||
|
||||
else
|
||||
{
|
||||
struct oid *copy = o_start;
|
||||
do {
|
||||
/* update_bgp_oid can reallocate the underlaying struct */
|
||||
o_start = copy = update_bgp_oid(copy, next_state);
|
||||
|
||||
o_start = bgp_find_dynamic_oid(p, o_start, o_end, next_state);
|
||||
|
||||
next_state = snmp_bgp_next_state(next_state);
|
||||
|
||||
} while (o_start != NULL && next_state < BGP_INTERNAL_END);
|
||||
|
||||
return o_start;
|
||||
}
|
||||
/* no need to check that retval < o_end -- done by bgp_find_dynamic_oid() */
|
||||
return search_bgp_dynamic(p, o_start, o_end, 0, next_state);
|
||||
}
|
||||
|
||||
/* else - is_dynamic(start_state) */
|
||||
/* ... (same as do ... while above) */
|
||||
/* no need to check that retval < o_end -- done by bgp_find_dynamic_oid() */
|
||||
return search_bgp_dynamic(p, o_start, o_end, 0, start_state);
|
||||
}
|
||||
|
||||
static byte *
|
||||
bgp_fill_dynamic(struct snmp_proto *p, struct oid *oid, byte *pkt, uint size
|
||||
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
{
|
||||
struct agentx_varbind *vb = (void *) pkt;
|
||||
*pkt += snmp_vb_size(vb);
|
||||
|
||||
return NULL;
|
||||
/* TODO not implemented yet */
|
||||
ip_addr addr;
|
||||
if (snmp_bgp_valid_ip4(oid))
|
||||
addr = ipa_from_ip4(ip4_from_oid(oid));
|
||||
else
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
|
||||
/* older implementation - untested */
|
||||
/* if o_curr is in invalid state, o_curr->include does't make any
|
||||
* difference; invalid state ~ no value to put in response packet
|
||||
*/
|
||||
/* indent \v/ */
|
||||
u8 state_curr = snmp_bgp_getnext_valid(state_curr);
|
||||
// TODO XXX deal with possible change of (remote) ip
|
||||
struct snmp_bgp_peer *pe = HASH_FIND(p->bgp_hash, SNMP_HASH, addr);
|
||||
|
||||
struct oid *o_curr = update_bgp_oid(o_curr, state_curr);
|
||||
|
||||
/* static part of BGP4-MIB tree, not depending on BGP connections */
|
||||
if (state_curr <= 5)
|
||||
struct bgp_proto *bgp_proto = NULL;
|
||||
struct proto *proto = NULL;
|
||||
if (pe)
|
||||
{
|
||||
return o_curr;
|
||||
}
|
||||
/* dynamic part of BGP4-MIB tree, depending on BGP connections */
|
||||
else /* state_curr > 5 */
|
||||
{
|
||||
ip4_addr ip4 = ip4_from_oid(o_curr);
|
||||
ip4_addr dest = ip4_from_oid(o_end);
|
||||
|
||||
net_addr *net = mb_allocz(p->p.pool, sizeof(struct net_addr));
|
||||
net_fill_ip4(net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
log(L_INFO "dynamic part of BGP mib");
|
||||
|
||||
struct f_trie_walk_state *ws = mb_allocz(p->p.pool,
|
||||
sizeof(struct f_trie_walk_state));
|
||||
|
||||
struct oid *o = mb_allocz(p->p.pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
o->n_subid = 9;
|
||||
trie_walk_init(ws, p->bgp_trie, NULL);
|
||||
|
||||
if (trie_walk_next(ws, net) && ip4_less(net4_prefix(net), dest))
|
||||
proto = ((struct proto_config *) pe->config)->proto;
|
||||
if (proto->proto == &proto_bgp &&
|
||||
ipa_equal(addr, ((struct bgp_proto *) proto)->remote_ip))
|
||||
{
|
||||
memcpy(o, o_curr, snmp_oid_size(o_curr));
|
||||
snmp_oid_ip4_index(o, net4_prefix(net));
|
||||
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
|
||||
return o;
|
||||
bgp_proto = (struct bgp_proto *) proto;
|
||||
}
|
||||
|
||||
/* binded bgp protocol not found */
|
||||
else
|
||||
{
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
|
||||
return NULL;
|
||||
die("Binded bgp protocol not found!");
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
}
|
||||
}
|
||||
|
||||
struct bgp_conn *bgp_conn = bgp_proto->conn;
|
||||
struct bgp_conn *bgp_in = &bgp_proto->incoming_conn;
|
||||
struct bgp_conn *bgp_out = &bgp_proto->outgoing_conn;
|
||||
|
||||
struct bgp_stats *bgp_stats = &bgp_proto->stats;
|
||||
const struct bgp_config *bgp_conf = bgp_proto->cf;
|
||||
|
||||
uint bgp_state;
|
||||
|
||||
if (bgp_conn)
|
||||
bgp_state = bgp_conn->state;
|
||||
else if (MAX(bgp_in->state, bgp_out->state) == BS_CLOSE &&
|
||||
MIN(bgp_in->state, bgp_out->state) != BS_CLOSE)
|
||||
bgp_state = MIN(bgp_in->state, bgp_out->state);
|
||||
else if (MIN(bgp_in->state, bgp_out->state) == BS_CLOSE)
|
||||
bgp_state = BS_IDLE;
|
||||
else
|
||||
bgp_state = MAX(bgp_in->state, bgp_out->state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
||||
case BGP_INTERNAL_IDENTIFIER:
|
||||
if (bgp_state == BS_OPENCONFIRM || bgp_state == BS_ESTABLISHED)
|
||||
{
|
||||
STORE_PTR(pkt, ipa_to_u32(bgp_proto->remote_ip));
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
snmp_put_blank(pkt); /* stores 4B of zeroes */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_STATE:
|
||||
STORE_PTR(pkt, bgp_state);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_ADMIN_STATUS:
|
||||
/* struct proto ~ (struct proto *) bgp_proto */
|
||||
if (proto->disabled)
|
||||
STORE_PTR(pkt, AGENTX_ADMIN_STOP);
|
||||
else
|
||||
STORE_PTR(pkt, 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
|
||||
else
|
||||
STORE_PTR(pkt, 0); /* zero dictated by rfc */
|
||||
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_ADDR:
|
||||
// TODO XXX bgp_proto->link_addr & zero local_ip
|
||||
STORE_PTR(pkt, ipa_to_u32(bgp_proto->local_ip));
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_PORT:
|
||||
STORE_PTR(pkt, bgp_conf->local_port);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_ADDR:
|
||||
STORE_PTR(pkt, ipa_to_u32(bgp_proto->remote_ip));
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_PORT:
|
||||
STORE_PTR(pkt, bgp_conf->remote_port);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_REMOTE_AS:
|
||||
STORE_PTR(pkt, bgp_proto->remote_as);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
|
||||
/* IN UPDATES */
|
||||
case BGP_INTERNAL_RX_UPDATES:
|
||||
STORE_PTR(pkt, bgp_stats->rx_updates);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
break;
|
||||
|
||||
/* OUT UPDATES */
|
||||
case BGP_INTERNAL_TX_UPDATES:
|
||||
STORE_PTR(pkt, bgp_stats->tx_updates);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
break;
|
||||
|
||||
/* IN MESSAGES */
|
||||
case BGP_INTERNAL_RX_MESSAGES:
|
||||
STORE_PTR(pkt, bgp_stats->rx_messages);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
break;
|
||||
|
||||
/* OUT MESSAGES */
|
||||
case BGP_INTERNAL_TX_MESSAGES:
|
||||
STORE_PTR(pkt, bgp_stats->tx_messages);
|
||||
BGP_DATA(vb, AGENTX_COUNTER_32, pkt);
|
||||
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);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_FSM_TRANSITIONS:
|
||||
break;
|
||||
case BGP_INTERNAL_FSM_ESTABLISHED_TIME:
|
||||
break;
|
||||
case BGP_INTERNAL_RETRY_INTERVAL:
|
||||
break;
|
||||
case BGP_INTERNAL_HOLD_TIME:
|
||||
break;
|
||||
case BGP_INTERNAL_KEEPALIVE:
|
||||
break;
|
||||
case BGP_INTERNAL_HOLD_TIME_CONFIGURED:
|
||||
break;
|
||||
case BGP_INTERNAL_KEEPALIVE_CONFIGURED:
|
||||
break;
|
||||
case BGP_INTERNAL_ORIGINATION_INTERVAL:
|
||||
break;
|
||||
case BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT:
|
||||
break;
|
||||
case BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME:
|
||||
break;
|
||||
case BGP_INTERNAL_END:
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_INVALID:
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_BGP:
|
||||
break;
|
||||
case BGP_INTERNAL_PEER_TABLE:
|
||||
break;
|
||||
case BGP_INTERNAL_PEER_ENTRY:
|
||||
break;
|
||||
case BGP_INTERNAL_NO_VALUE:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static byte *
|
||||
bgp_fill_static(struct snmp_proto *p, struct oid *oid, byte *buf, uint size
|
||||
UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
{
|
||||
log(L_INFO "snmp bgp_fill_static ()\n");
|
||||
|
||||
struct agentx_varbind *vb = (void *) buf;
|
||||
byte *pkt = buf + snmp_vb_size(vb);
|
||||
|
||||
/* 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)
|
||||
return snmp_no_such_object(buf, 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);
|
||||
break;
|
||||
|
||||
case BGP_INTERNAL_LOCAL_AS:
|
||||
// XXX local as to use
|
||||
|
||||
STORE_PTR(pkt, p->local_as);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
}
|
||||
|
||||
log(L_INFO "snmp ended with non empty pkt\n");
|
||||
return pkt;
|
||||
}
|
||||
|
||||
byte *
|
||||
snmp_bgp_fill(struct snmp_proto *p UNUSED, struct oid *oid, byte *buf UNUSED,
|
||||
uint size UNUSED, uint contid UNUSED, int byte_ord UNUSED)
|
||||
{
|
||||
u8 state = snmp_bgp_state(oid);
|
||||
|
||||
if (!is_dynamic(state))
|
||||
return bgp_fill_static(p, oid, buf, size, contid, byte_ord, state);
|
||||
|
||||
if (is_dynamic(state) && snmp_bgp_has_value(state))
|
||||
return bgp_fill_dynamic(p, oid, buf, size, contid, byte_ord, state);
|
||||
|
||||
else
|
||||
{
|
||||
// TODO XXX fix here
|
||||
return snmp_no_such_object(buf, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ enum BGP4_MIB {
|
||||
struct oid;
|
||||
|
||||
void snmp_bgp_register(void);
|
||||
int snmp_bgp_is_supported(struct oid *o);
|
||||
// - int snmp_bgp_is_supported(struct oid *o);
|
||||
|
||||
int snmp_bgp_valid_ip4(struct oid *o);
|
||||
u8 snmp_bgp_state(struct oid *o);
|
||||
|
@ -106,7 +106,4 @@ struct snmp_proto {
|
||||
uint errs;
|
||||
};
|
||||
|
||||
/* fixes bugs when making tests */
|
||||
//struct protocol proto_snmp;
|
||||
|
||||
#endif
|
||||
|
@ -12,11 +12,19 @@
|
||||
#include "bgp_mib.h"
|
||||
#include "subagent.h"
|
||||
#include "snmp.h"
|
||||
#include "snmp_utils.h"
|
||||
#include "snmp_internal.h"
|
||||
|
||||
#define SNMP_EXPECTED(actual, expected) \
|
||||
bt_debug("%s expected: %3u actual: %3u\n", \
|
||||
#expected, expected, actual);
|
||||
|
||||
#ifdef CPU_BIG_ENDIAN
|
||||
#define BYTE_ORD 1
|
||||
#else
|
||||
#define BYTE_ORD 0
|
||||
#endif
|
||||
|
||||
void
|
||||
dump_oid(struct oid *oid)
|
||||
{
|
||||
@ -31,12 +39,11 @@ dump_oid(struct oid *oid)
|
||||
}
|
||||
|
||||
void
|
||||
dump_bgp_state_values(void)
|
||||
test_fill(struct snmp_proto *p)
|
||||
{
|
||||
// TODO XXX here
|
||||
((struct proto *) p)->pool = &root_pool;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_oid(struct oid *oid, uint base_size)
|
||||
{
|
||||
@ -141,10 +148,132 @@ test_oid(struct oid *oid, uint base_size)
|
||||
bt_assert(snmp_bgp_state(oid) == BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME);
|
||||
}
|
||||
|
||||
static int
|
||||
t_s_is_oid_empty(void)
|
||||
{
|
||||
bt_assert(snmp_is_oid_empty(NULL) == 0);
|
||||
|
||||
struct oid *blank = mb_alloc(&root_pool, sizeof(struct oid));
|
||||
blank->n_subid = 0;
|
||||
blank->prefix = 0;
|
||||
blank->include = 0;
|
||||
|
||||
bt_assert(snmp_is_oid_empty(blank) == 1);
|
||||
|
||||
struct oid *prefixed = mb_alloc(&root_pool, sizeof(struct oid) + 3 * sizeof(u32));
|
||||
prefixed->n_subid = 3;
|
||||
prefixed->prefix = 100;
|
||||
prefixed->include = 1;
|
||||
|
||||
u32 prefixed_arr[] = { ~((u32) 0), 0, 256 };
|
||||
memcpy(&prefixed->ids, prefixed_arr, sizeof(prefixed_arr) /
|
||||
sizeof(prefixed_arr[0]));
|
||||
|
||||
bt_assert(snmp_is_oid_empty(prefixed) == 0);
|
||||
|
||||
struct oid *to_prefix = mb_alloc(&root_pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
to_prefix->n_subid = 8;
|
||||
to_prefix->prefix = 0;
|
||||
to_prefix->include = 1;
|
||||
|
||||
u32 to_prefix_arr[] = {1, 3, 6, 1, 100, ~((u32) 0), 0, 256 };
|
||||
memcpy(&to_prefix->n_subid, to_prefix_arr, sizeof(to_prefix_arr) /
|
||||
sizeof(to_prefix_arr[0]));
|
||||
|
||||
bt_assert(snmp_is_oid_empty(to_prefix) == 0);
|
||||
|
||||
struct oid *unprefixable = mb_alloc(&root_pool, sizeof(struct oid) + 2 * sizeof(u32));
|
||||
unprefixable->n_subid = 2;
|
||||
unprefixable->prefix = 0;
|
||||
unprefixable->include = 0;
|
||||
|
||||
u32 unpref[] = { 65535, 4 };
|
||||
memcpy(&unprefixable->ids, unpref, sizeof(unpref) / sizeof(unpref[0]));
|
||||
|
||||
bt_assert(snmp_is_oid_empty(unprefixable) == 0);
|
||||
|
||||
struct oid *unprefixable2 = mb_alloc(&root_pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
unprefixable2->n_subid = 8;
|
||||
unprefixable2->prefix = 0;
|
||||
unprefixable2->include = 1;
|
||||
|
||||
u32 unpref2[] = { 1, 3, 6, 2, 1, 2, 15, 6 };
|
||||
memcpy(&unprefixable2->ids, unpref2, sizeof(unpref2) / sizeof(unpref2[0]));
|
||||
|
||||
bt_assert(snmp_is_oid_empty(unprefixable2) == 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
t_s_prefixize(void)
|
||||
{
|
||||
struct oid *nulled = NULL;
|
||||
|
||||
struct snmp_proto snmp_proto;
|
||||
|
||||
test_fill(&snmp_proto);
|
||||
|
||||
bt_debug("before seg fault\n");
|
||||
struct oid *tmp = snmp_prefixize(&snmp_proto, nulled, BYTE_ORD);
|
||||
bt_debug("after snmp_prefixize() call\n");
|
||||
bt_assert( NULL == tmp );
|
||||
|
||||
bt_debug("after assert\n");
|
||||
struct oid *blank = mb_allocz(&root_pool, sizeof(struct oid));
|
||||
|
||||
/* here the byte order should not matter */
|
||||
bt_assert(snmp_is_oid_empty(snmp_prefixize(&snmp_proto, blank, 1 - BYTE_ORD)) == 1);
|
||||
|
||||
struct oid *prefixed = mb_alloc(&root_pool, sizeof(struct oid) + 3 * sizeof(u32));
|
||||
prefixed->n_subid = 3;
|
||||
prefixed->prefix = 100;
|
||||
prefixed->include = 1;
|
||||
|
||||
u32 prefixed_arr[] = { ~((u32) 0), 0, 256 };
|
||||
memcpy(&prefixed->ids, prefixed_arr, sizeof(prefixed_arr) /
|
||||
sizeof(prefixed_arr[0]));
|
||||
|
||||
bt_assert(memcmp(snmp_prefixize(&snmp_proto, prefixed, BYTE_ORD), prefixed, snmp_oid_size(prefixed)) == 0);
|
||||
|
||||
struct oid *to_prefix = mb_alloc(&root_pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
to_prefix->n_subid = 8;
|
||||
to_prefix->prefix = 0;
|
||||
to_prefix->include = 1;
|
||||
|
||||
u32 to_prefix_arr[] = {1, 3, 6, 1, 100, ~((u32) 0), 0, 256 };
|
||||
memcpy(&to_prefix->n_subid, to_prefix_arr, sizeof(to_prefix_arr) /
|
||||
sizeof(to_prefix_arr[0]));
|
||||
|
||||
bt_assert(memcmp(snmp_prefixize(&snmp_proto, to_prefix, BYTE_ORD), prefixed, snmp_oid_size(prefixed)) == 0);
|
||||
|
||||
struct oid *unprefixable = mb_alloc(&root_pool, sizeof(struct oid) + 2 * sizeof(u32));
|
||||
unprefixable->n_subid = 2;
|
||||
unprefixable->prefix = 0;
|
||||
unprefixable->include = 0;
|
||||
|
||||
u32 unpref[] = { 65535, 4 };
|
||||
memcpy(&unprefixable->ids, unpref, sizeof(unpref) / sizeof(unpref[0]));
|
||||
|
||||
bt_assert(snmp_prefixize(&snmp_proto, unprefixable, BYTE_ORD) == NULL);
|
||||
|
||||
struct oid *unprefixable2 = mb_alloc(&root_pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
unprefixable2->n_subid = 8;
|
||||
unprefixable2->prefix = 0;
|
||||
unprefixable2->include = 1;
|
||||
|
||||
u32 unpref2[] = { 1, 3, 6, 2, 1, 2, 15, 6 };
|
||||
memcpy(&unprefixable2->ids, unpref2, sizeof(unpref2) / sizeof(unpref2[0]));
|
||||
|
||||
bt_assert(snmp_prefixize(&snmp_proto, unprefixable2, BYTE_ORD) == NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
t_s_bgp_state(void)
|
||||
{
|
||||
struct oid *oid = alloca(sizeof(struct oid) + 10 * sizeof(32));
|
||||
struct oid *oid = mb_alloc(&root_pool, sizeof(struct oid) + 10 * sizeof(u32));
|
||||
|
||||
/* oid header */
|
||||
oid->n_subid = 0;
|
||||
@ -181,9 +310,6 @@ t_s_bgp_state(void)
|
||||
oid->ids[8] = 0xFFFF;
|
||||
test_oid(oid, 4);
|
||||
|
||||
bt_debug("testing too long oids\n");
|
||||
bt_debug("not implemented\n");
|
||||
bt_debug("exiting\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -193,5 +319,9 @@ int main(int argc, char **argv)
|
||||
|
||||
bt_test_suite(t_s_bgp_state, "Function snmp_bgp_state()");
|
||||
|
||||
bt_test_suite(t_s_is_oid_empty, "Function snmp_is_oid_empty()");
|
||||
|
||||
bt_test_suite(t_s_prefixize, "Function snmp_prefixize()");
|
||||
|
||||
return bt_exit_value();
|
||||
}
|
||||
|
@ -10,8 +10,11 @@
|
||||
|
||||
#include "lib/unaligned.h"
|
||||
#include "subagent.h"
|
||||
#include "snmp_utils.h"
|
||||
#include "bgp_mib.h"
|
||||
|
||||
#include "snmp_internal.h"
|
||||
|
||||
/* =============================================================
|
||||
* Problems
|
||||
* ------------------------------------------------------------
|
||||
@ -24,7 +27,6 @@
|
||||
*/
|
||||
|
||||
static int parse_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static inline uint vb_size(struct agentx_varbind *vb);
|
||||
static int snmp_stop_ack(sock *sk, uint size);
|
||||
static void do_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static uint parse_get_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
@ -32,9 +34,7 @@ static uint parse_gets_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
static byte *prepare_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static void response_err_ind(byte *buf, uint err, uint ind);
|
||||
static struct oid *search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, uint contid);
|
||||
static struct oid *prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
|
||||
static inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord);
|
||||
static byte *no_such_object(byte *buf, struct agentx_varbind *vb);
|
||||
|
||||
static const char * const snmp_errs[] = {
|
||||
#define SNMP_ERR_SHIFT 256
|
||||
@ -53,124 +53,6 @@ static const char * const snmp_errs[] = {
|
||||
[AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
|
||||
};
|
||||
|
||||
/* payload length in bytes */
|
||||
static inline size_t
|
||||
pkt_len(byte *buf, byte *pkt)
|
||||
{
|
||||
return (pkt - buf) - AGENTX_HEADER_SIZE;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
str_size(const char *str)
|
||||
{
|
||||
return 4 + BIRD_ALIGN(strlen(str), 4);
|
||||
}
|
||||
|
||||
int
|
||||
snmp_valid_ip4_index(struct oid *o, uint start)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (o->ids[start + i] >= 256)
|
||||
return 0; // false
|
||||
|
||||
return 1; // true
|
||||
}
|
||||
|
||||
int
|
||||
snmp_valid_ip4_index_safe(struct oid *o, uint start)
|
||||
{
|
||||
if (start + 3 < o->n_subid)
|
||||
return snmp_valid_ip4_index(o, start);
|
||||
else
|
||||
return 0; // false
|
||||
}
|
||||
|
||||
static byte *
|
||||
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 + str_size(str);
|
||||
}
|
||||
|
||||
static byte *
|
||||
put_blank(byte *buf)
|
||||
{
|
||||
STORE_PTR(buf, 0);
|
||||
return buf + 4;
|
||||
}
|
||||
|
||||
static byte *
|
||||
put_oid(byte *buf, struct oid *oid)
|
||||
{
|
||||
log(L_INFO "testing oid");
|
||||
for (uint i = 0; i < oid->n_subid; i++)
|
||||
log(L_INFO "oid id %d: %u", i, oid->ids[i]);
|
||||
log(L_INFO "put_oid()");
|
||||
put_u8(buf, oid->n_subid);
|
||||
log(L_INFO "data %p: %02X", buf, *buf);
|
||||
put_u8(++buf, oid->prefix);
|
||||
log(L_INFO "data %p: %02X", buf, *buf);
|
||||
put_u8(++buf, oid->include);
|
||||
log(L_INFO "data %p: %02X", buf, *buf);
|
||||
put_u8(++buf, 0); // PADDING
|
||||
/* last increment */
|
||||
++buf;
|
||||
log(L_INFO "oid head end %p", buf);
|
||||
|
||||
/* copy OID data */
|
||||
#ifdef SNMP_NATIVE
|
||||
for (uint i = 0; i < oid->n_subid; i++)
|
||||
*(((u32 *) buf) + i) = oid->ids[i];
|
||||
#else
|
||||
put_u32s(buf, oid->ids, oid->n_subid << 2);
|
||||
#endif
|
||||
/*
|
||||
for (uint i = 0; i <= (oid->n_subid << 2) +4 ; i += 4)
|
||||
log(L_INFO "OID % 3u: %02X %02X %02X %02X", i,
|
||||
*(buf - 4 + i),
|
||||
*(buf - 4 + i + 1),
|
||||
*(buf - 4 + i + 2),
|
||||
*(buf - 4 + i + 3)
|
||||
);
|
||||
*/
|
||||
|
||||
return buf + (oid->n_subid << 2);
|
||||
}
|
||||
|
||||
void
|
||||
snmp_oid_ip4_index(struct oid *o, ip4_addr addr)
|
||||
{
|
||||
u32 temp = ip4_to_u32(addr);
|
||||
STORE(o->ids[5], temp >> 24);
|
||||
STORE(o->ids[6], (temp & 0x00FF0000) >> 16);
|
||||
STORE(o->ids[7], (temp & 0x0000FF00) >> 8);
|
||||
STORE(o->ids[8], temp & 0x000000FF);
|
||||
}
|
||||
|
||||
/* paste data at first byte in message
|
||||
* with 3B of padding
|
||||
*/
|
||||
static byte *
|
||||
paste_fbyte(byte *buf, u8 data)
|
||||
{
|
||||
log(L_INFO "paste_fbyte()");
|
||||
put_u8(buf, data);
|
||||
put_u24(++buf, 0); // PADDING
|
||||
return buf + 3;
|
||||
}
|
||||
|
||||
static void
|
||||
open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
{
|
||||
@ -184,7 +66,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
|
||||
//uint pkt_size = 0;
|
||||
|
||||
if (size > AGENTX_HEADER_SIZE + snmp_oid_size(oid) + str_size(str))
|
||||
if (size > AGENTX_HEADER_SIZE + snmp_oid_size(oid) + snmp_str_size(str))
|
||||
{
|
||||
log(L_INFO "open_pdu()");
|
||||
|
||||
@ -196,11 +78,11 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
STORE(h->transaction_id, 1);
|
||||
STORE(h->packet_id, 1);
|
||||
|
||||
pkt = paste_fbyte(pkt, p->timeout);
|
||||
pkt = put_oid(pkt, oid);
|
||||
pkt = put_str(pkt, str);
|
||||
pkt = snmp_put_fbyte(pkt, p->timeout);
|
||||
pkt = snmp_put_oid(pkt, oid);
|
||||
pkt = snmp_put_str(pkt, str);
|
||||
|
||||
SNMP_UPDATE(h, pkt_len(buf, pkt));
|
||||
SNMP_UPDATE(h, snmp_pkt_len(buf, pkt));
|
||||
|
||||
int ret = sk_send(sk, pkt - buf);
|
||||
|
||||
@ -214,7 +96,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
|
||||
else
|
||||
log(L_INFO "open_pdu() insufficient size, %u <= %u ",
|
||||
size, AGENTX_HEADER_SIZE + snmp_oid_size(oid) + str_size(str));
|
||||
size, AGENTX_HEADER_SIZE + snmp_oid_size(oid) + snmp_str_size(str));
|
||||
}
|
||||
|
||||
/* index allocate / deallocate pdu * /
|
||||
@ -272,7 +154,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
|
||||
STORE(ur->priority, AGENTX_PRIORITY);
|
||||
STORE(ur->range_subid, (len > 1) ? index : 0);
|
||||
|
||||
pkt = put_oid(pkt, oid);
|
||||
pkt = snmp_put_oid(pkt, oid);
|
||||
log(L_INFO "pkt - buf : %lu sizeof %u", pkt -buf, AGENTX_HEADER_SIZE);
|
||||
|
||||
/* place upper-bound if needed */
|
||||
@ -282,8 +164,8 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
|
||||
pkt += 4;
|
||||
}
|
||||
|
||||
log("size of pkt: %u", pkt_len(buf,pkt));
|
||||
SNMP_UPDATE(h, pkt_len(buf, pkt));
|
||||
log("size of pkt: %u", snmp_pkt_len(buf,pkt));
|
||||
SNMP_UPDATE(h, snmp_pkt_len(buf, pkt));
|
||||
|
||||
for (uint i = 0; i < pkt - buf; i++)
|
||||
log(L_INFO "%p: %02X", buf+i, *(buf + i));
|
||||
@ -337,9 +219,9 @@ close_pdu(struct snmp_proto *p, u8 reason)
|
||||
|
||||
SNMP_SESSION(h, p)
|
||||
|
||||
pkt = paste_fbyte(pkt, reason);
|
||||
pkt = snmp_put_fbyte(pkt, reason);
|
||||
|
||||
SNMP_UPDATE(h, pkt_len(buf, pkt));
|
||||
SNMP_UPDATE(h, snmp_pkt_len(buf, pkt));
|
||||
|
||||
log(L_INFO "preparing to sk_send()");
|
||||
int ret = sk_send(sk, pkt - buf);
|
||||
@ -499,7 +381,7 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
log(L_INFO "before hash walk");
|
||||
HASH_WALK(p->bgp_hash, next, peer)
|
||||
{
|
||||
snmp_oid_ip4_index(o2, ipa_to_ip4(peer->peer_ip));
|
||||
snmp_oid_ip4_index(o2, 5, ipa_to_ip4(peer->peer_ip));
|
||||
|
||||
log(L_INFO "");
|
||||
log(L_INFO "o2 n_subid %u prefix %u include %u", o2->n_subid,
|
||||
@ -605,7 +487,7 @@ parse_get_pdu(struct snmp_proto *p, byte *buf, uint size)
|
||||
}
|
||||
|
||||
struct agentx_header *rh = (void *) res;
|
||||
SNMP_UPDATE(rh, pkt_len(res, res_pkt));
|
||||
SNMP_UPDATE(rh, snmp_pkt_len(res, res_pkt));
|
||||
|
||||
if (err)
|
||||
response_err_ind(res, err, ind);
|
||||
@ -670,10 +552,12 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
SNMP_LOAD_CONTEXT(p, h, req, context, clen);
|
||||
|
||||
res_pkt = prepare_response(p, res, rsize);
|
||||
|
||||
uint ind = 1;
|
||||
int err = 0;
|
||||
while (!err && pkt - req < pkt_size)
|
||||
{
|
||||
/* oids from message buffer */
|
||||
struct oid *o_start_b, *o_end_b;
|
||||
o_start_b = (struct oid *) pkt;
|
||||
pkt += snmp_oid_size(o_start_b);
|
||||
@ -688,11 +572,20 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
continue;
|
||||
}
|
||||
|
||||
snmp_oid_dump(o_start_b);
|
||||
snmp_oid_dump(o_end_b);
|
||||
/* object identifier (oid) normalization */
|
||||
struct oid *o_start = prefixize(p, o_start_b, byte_ord);
|
||||
struct oid *o_end = prefixize(p, o_end_b, byte_ord);
|
||||
|
||||
struct oid *o_start = snmp_prefixize(p, o_start_b, byte_ord);
|
||||
struct oid *o_end = snmp_prefixize(p, o_end_b, byte_ord);
|
||||
|
||||
snmp_oid_dump(o_start);
|
||||
snmp_oid_dump(o_end);
|
||||
|
||||
u8 mib_class = get_mib_class(o_start);
|
||||
|
||||
log(L_INFO "get mib_class () -> next pdu parsing ... ");
|
||||
|
||||
switch (h->type)
|
||||
{
|
||||
case AGENTX_GET_PDU:
|
||||
@ -765,7 +658,7 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
|
||||
log(L_INFO " pasting size");
|
||||
struct agentx_header *rh = (void *) res;
|
||||
SNMP_UPDATE(rh, pkt_len(res, res_pkt));
|
||||
SNMP_UPDATE(rh, snmp_pkt_len(res, res_pkt));
|
||||
|
||||
log(L_INFO "%p %lu", p->sock->ttx, res_pkt - res);
|
||||
log(L_INFO "%p %p", res_pkt, res);
|
||||
@ -801,14 +694,6 @@ snmp_stop_subagent(struct snmp_proto *p)
|
||||
}
|
||||
}
|
||||
|
||||
/* return number of bytes used by @o */
|
||||
uint
|
||||
snmp_oid_size(struct oid *o)
|
||||
{
|
||||
/* faster multipication by 4 */
|
||||
return 4 + (o->n_subid << 2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
oid_prefix(struct oid *o, u32 *prefix, uint len)
|
||||
{
|
||||
@ -819,14 +704,6 @@ oid_prefix(struct oid *o, u32 *prefix, uint len)
|
||||
return 1; // true
|
||||
}
|
||||
|
||||
/* return number of bytes used by @vb */
|
||||
static inline uint
|
||||
vb_size(struct agentx_varbind *vb)
|
||||
{
|
||||
/* +4B for type and pad */
|
||||
return snmp_oid_size(&vb->name) + 4;
|
||||
}
|
||||
|
||||
int
|
||||
snmp_rx(sock *sk, uint size)
|
||||
{
|
||||
@ -1038,7 +915,7 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, u
|
||||
b_state = MAX(b_in->state, b_out->state);
|
||||
|
||||
struct agentx_varbind *vb = (void *) pkt;
|
||||
pkt += vb_size(vb);
|
||||
pkt += snmp_vb_size(vb);
|
||||
|
||||
switch (o->ids[4])
|
||||
{
|
||||
@ -1050,7 +927,7 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, u
|
||||
}
|
||||
else
|
||||
{
|
||||
put_blank(pkt); /* store 4B of zeroes */
|
||||
snmp_put_blank(pkt); /* store 4B of zeroes */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
break;
|
||||
@ -1182,7 +1059,7 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, u
|
||||
|
||||
case SNMP_BGP_FSM_ESTABLISHED_TIME:
|
||||
case SNMP_BGP_IN_UPDATE_ELAPSED_TIME:
|
||||
return no_such_object(pkt, vb);
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
|
||||
/* no default */
|
||||
}
|
||||
@ -1195,7 +1072,7 @@ static byte *
|
||||
snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid)
|
||||
{
|
||||
struct agentx_varbind *vb = (void *) buf;
|
||||
byte *pkt = buf + vb_size(vb);
|
||||
byte *pkt = buf + snmp_vb_size(vb);
|
||||
|
||||
switch (o->ids[2])
|
||||
{
|
||||
@ -1217,7 +1094,7 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
/* end part of .1.3.6.1.2.1.15.3.1.x.a.b.c.d */
|
||||
if (o->n_subid < 9 || o->ids[3] != SNMP_BGP_PEER_ENTRY
|
||||
|| o->ids[4] == 0 || o->ids[4] > 24)
|
||||
return no_such_object(pkt, vb);
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
|
||||
// TODO enumerate range requests
|
||||
ip_addr addr = ipa_build4(o->ids[5], o->ids[6], o->ids[7], o->ids[8]);
|
||||
@ -1245,14 +1122,14 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
|
||||
if (!bp)
|
||||
/* pkt += 0; no data */
|
||||
return no_such_object(pkt, vb);
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
|
||||
return find_bgp_one(bp, o, buf, size, contid);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* pkt += 0; no data */
|
||||
return no_such_object(pkt, vb);
|
||||
return snmp_no_such_object(pkt, vb);
|
||||
}
|
||||
|
||||
return pkt;
|
||||
@ -1267,20 +1144,6 @@ find_ospf_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size)
|
||||
}
|
||||
*/
|
||||
|
||||
static byte *
|
||||
no_such_object(byte *buf, struct agentx_varbind *vb)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static UNUSED byte *
|
||||
no_such_instance(byte *buf, struct agentx_varbind *vb)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid)
|
||||
{
|
||||
@ -1290,7 +1153,7 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
|
||||
|
||||
/* SNMPv2 mgmt mib-2 */
|
||||
if (o->n_subid < 2 || (o->prefix != 2 && o->ids[0] != 1))
|
||||
no_such_object(buf + vb_size(vb), vb);
|
||||
snmp_no_such_object(buf + snmp_vb_size(vb), vb);
|
||||
|
||||
switch (o->ids[1])
|
||||
{
|
||||
@ -1299,16 +1162,16 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
|
||||
return snmp_bgp_record(p, o, buf, size, contid);
|
||||
|
||||
case SNMP_OSPFv3_MIB:
|
||||
return no_such_object(buf, vb);
|
||||
return snmp_no_such_object(buf, vb);
|
||||
//return find_ospf_record(p, o, buf, size);
|
||||
|
||||
default:
|
||||
return no_such_object(buf, vb);
|
||||
return snmp_no_such_object(buf, vb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prefixize - return prefixed oid copy if possible
|
||||
* snmp_prefixize - return prefixed oid copy if possible
|
||||
* @proto: allocation pool holder
|
||||
* @oid: from packet loaded object identifier
|
||||
* @byte_ord: byte order of @oid
|
||||
@ -1317,11 +1180,24 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
|
||||
* possible. NULL otherwise. Returned pointer is always allocated from @proto's
|
||||
* pool not a pointer to recieve buffer (from which is most likely @oid).
|
||||
*/
|
||||
static struct oid *
|
||||
prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord)
|
||||
struct oid *
|
||||
snmp_prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord)
|
||||
{
|
||||
const u32 prefix[] = {1, 3, 6, 1};
|
||||
|
||||
if (snmp_is_oid_empty(oid))
|
||||
{
|
||||
/* allocate new zeroed oid */
|
||||
struct oid *new = mb_allocz(proto->p.pool, sizeof(struct oid));
|
||||
return new;
|
||||
}
|
||||
else if (LOAD(oid->n_subid, byte_ord) != 0)
|
||||
{
|
||||
struct oid *new = mb_allocz(proto->p.pool, snmp_oid_size(oid));
|
||||
memcpy(new, oid, snmp_oid_size(oid));
|
||||
return new;
|
||||
}
|
||||
|
||||
if (oid->n_subid < 5)
|
||||
return NULL;
|
||||
|
||||
@ -1350,7 +1226,7 @@ static inline byte *
|
||||
find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord)
|
||||
{
|
||||
struct oid *new;
|
||||
if (!o->prefix && (new = prefixize(p, o, byte_ord)) != NULL)
|
||||
if (!o->prefix && (new = snmp_prefixize(p, o, byte_ord)) != NULL)
|
||||
return find_prefixed(p, new, buf, size, contid);
|
||||
else if (o->prefix)
|
||||
return find_prefixed(p, o, buf, size, contid);
|
||||
@ -1361,26 +1237,25 @@ find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint cont
|
||||
/**
|
||||
* snmp_mib_fill -
|
||||
*/
|
||||
static byte *
|
||||
snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class, byte *buf,
|
||||
uint size, uint contid, int byte_ord)
|
||||
static byte *snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class, byte *buf, uint size, uint contid, int byte_ord)
|
||||
{
|
||||
log(L_INFO "snmp_mib_fill()");
|
||||
struct agentx_varbind *vb = (void *) buf;
|
||||
|
||||
memcpy(&vb->name, oid, snmp_oid_size(oid));
|
||||
|
||||
/* SNMPv2 mgmt mib-2 */
|
||||
if (oid->n_subid < 2 || (oid->prefix != 2 && oid->ids[0] != 1))
|
||||
return no_such_object(buf + vb_size(vb), vb);
|
||||
return snmp_no_such_object(buf + snmp_vb_size(vb), vb);
|
||||
|
||||
switch (mib_class)
|
||||
{
|
||||
case SNMP_CLASS_BGP:
|
||||
buf = snmp_bgp_fill(p, oid, buf, size, contid, byte_ord);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static byte *
|
||||
|
@ -103,7 +103,7 @@ enum agentx_type {
|
||||
log(L_INFO "LOAD_STR(), %p %u", p->p.pool, l + 1); \
|
||||
s = mb_allocz(p->p.pool, l + 1); \
|
||||
memcpy(s, b, l); \
|
||||
b += str_size(s);
|
||||
b += snmp_str_size(s);
|
||||
|
||||
#define SNMP_LOAD_CONTEXT(p, h, b, s, l) \
|
||||
if (h->flags & AGENTX_NON_DEFAULT_CONTEXT) \
|
||||
@ -111,8 +111,8 @@ enum agentx_type {
|
||||
LOAD_STR(p, b, s, l, h->flags & AGENTX_NETWORK_BYTE_ORDER); }
|
||||
|
||||
#define SNMP_COPY_OID(b, o) \
|
||||
memcpy(b, o, oid_size(o)); \
|
||||
b += oid_size(o);
|
||||
memcpy(b, o, snmp_oid_size(o)); \
|
||||
b += snmp_oid_size(o);
|
||||
|
||||
#define SNMP_COPY_VB(b, s, e) \
|
||||
memcpy(b, s, 4); \
|
||||
@ -120,11 +120,11 @@ enum agentx_type {
|
||||
SNMP_COPY_OID(b, &s->name) \
|
||||
SNMP_COPY_OID(b, e)
|
||||
|
||||
#define BGP_DATA_(v, d, p, o) \
|
||||
(v)->type = d; \
|
||||
p += o;
|
||||
#define BGP_DATA_(varbind, type_, packet, offset) \
|
||||
(varbind)->type = type_; \
|
||||
packet += offset;
|
||||
|
||||
#define BGP_DATA(v, d, p) BGP_DATA_(v, d, p, 4)
|
||||
#define BGP_DATA(varbind, type_, packet) BGP_DATA_(varbind, type_, packet, 4)
|
||||
|
||||
struct agentx_header {
|
||||
u8 version;
|
||||
@ -160,6 +160,11 @@ struct agentx_search_range {
|
||||
struct oid end;
|
||||
};
|
||||
|
||||
struct agentx_getbulk {
|
||||
u16 non_repeaters;
|
||||
u16 max_repetitions;
|
||||
};
|
||||
|
||||
struct agentx_response {
|
||||
struct agentx_header h;
|
||||
u32 uptime;
|
||||
@ -255,11 +260,6 @@ enum agentx_response_err {
|
||||
} PACKED;
|
||||
|
||||
int snmp_rx(sock *sk, uint size);
|
||||
int snmp_valid_ip4_index_safe(struct oid *o, uint start);
|
||||
int snmp_valid_ip4_index(struct oid *o, uint start);
|
||||
void snmp_oid_ip4_index(struct oid *o, ip4_addr addr);
|
||||
|
||||
uint snmp_oid_size(struct oid *o);
|
||||
|
||||
static byte *snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class, byte *buf, uint size, uint contid, int byte_ord);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user