From 9a11ec8d839bdf4b0c32626780c6e66e66b5f658 Mon Sep 17 00:00:00 2001 From: Vojtech Vilimek Date: Tue, 29 Nov 2022 16:30:20 +0100 Subject: [PATCH] tmp: compiles --- proto/snmp/bgp_mib.h | 1 + proto/snmp/snmp.c | 21 +++++- proto/snmp/snmp_test.c | 157 +++++++++++++++++++++++++++++++++++++--- proto/snmp/snmp_utils.c | 60 +++++++++++++++ proto/snmp/snmp_utils.h | 2 + proto/snmp/subagent.c | 20 +++++ proto/snmp/subagent.h | 3 - 7 files changed, 248 insertions(+), 16 deletions(-) diff --git a/proto/snmp/bgp_mib.h b/proto/snmp/bgp_mib.h index 9e18158b..56080010 100644 --- a/proto/snmp/bgp_mib.h +++ b/proto/snmp/bgp_mib.h @@ -2,6 +2,7 @@ #define _BIRD_SNMP_BGP_MIB_H_ #include "snmp.h" +#include "subagent.h" /* peers attributes */ enum BGP4_MIB { diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index 0343168d..eb517243 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -23,6 +23,15 @@ static void snmp_startup(struct snmp_proto *p); static void snmp_startup_timeout(timer *t); static void snmp_start_locked(struct object_lock *lock); + +static const char * const snmp_state[] = { + [SNMP_ERR] = "SNMP ERROR", + [SNMP_DELAY] = "SNMP DELAY", + [SNMP_INIT] = "SNMP INIT", + [SNMP_REGISTR] = "SNMP REGISTERING", + [SNMP_CONN] = "SNMP CONNECTED", +}; + static struct proto * snmp_init(struct proto_config *CF) { @@ -50,6 +59,7 @@ snmp_init(struct proto_config *CF) static void snmp_startup_timeout(timer *t) { + log(L_INFO "startup timer triggered"); snmp_startup(t->data); } @@ -59,6 +69,9 @@ snmp_startup(struct snmp_proto *p) /* starting agentX communicaiton channel */ log(L_INFO "preparing lock"); struct object_lock *lock; + log(L_INFO "snmp_startup() object lock state %p", p->lock); + + /* we could have the lock already acquired but be in ERROR state */ lock = p->lock = olock_new(p->p.pool); lock->type = OBJLOCK_TCP; @@ -136,6 +149,9 @@ snmp_sock_err(sock *sk, int err) rfree(p->sock); p->sock = NULL; + rfree(p->lock); + p->lock = NULL; + p->state = SNMP_ERR; tm_start(p->startup_timer, 15 S); } @@ -222,9 +238,12 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF) static void snmp_show_proto_info(struct proto *P) { - //struct snmp_proto *sp = (void *) P; + struct snmp_proto *sp = (void *) P; struct snmp_config *c = (void *) P->cf; + cli_msg(-1006, ""); + cli_msg(-1006, " snmp status %s", snmp_state[sp->state]); + cli_msg(-1006, ""); cli_msg(-1006, " BGP peers"); struct snmp_bond *bond; WALK_LIST(bond, c->bgp_entries) diff --git a/proto/snmp/snmp_test.c b/proto/snmp/snmp_test.c index d4cb8300..d6acda34 100644 --- a/proto/snmp/snmp_test.c +++ b/proto/snmp/snmp_test.c @@ -25,18 +25,13 @@ #define BYTE_ORD 0 #endif -void -dump_oid(struct oid *oid) -{ - bt_debug(" OID DUMP: \n"); - bt_debug(" n_subid = %3u prefix = %3u include %s --- \n", - oid->n_subid, oid->prefix, (oid->include != 0) ? "yes" : "no" ); +#define OID_ALLOCATE(size) mb_alloc(&root_pool, sizeof(struct oid) + (size) * sizeof (u32)) - for (int i = 0; i < oid->n_subid; i++) - bt_debug(" %u: %u\n", i + 1, oid->ids[i]); - - bt_debug(" OID DUMP END\n"); -} +#define OID_INIT(oid, n_subid_, prefix_, include_, arr_) \ + (oid)->n_subid = (n_subid_); \ + (oid)->prefix = (prefix_); \ + (oid)->include = (include_); \ + memcpy((oid)->ids, (arr_), sizeof(arr_)); \ void test_fill(struct snmp_proto *p) @@ -68,7 +63,7 @@ test_oid(struct oid *oid, uint base_size) oid->n_subid = base_size + 4; oid->ids[2] = 3; oid->ids[3] = 1; // BGP4-MIB::bgpPeerEntry - dump_oid(oid); + snmp_oid_dump(oid); SNMP_EXPECTED(snmp_bgp_state(oid), BGP_INTERNAL_PEER_ENTRY); bt_assert(snmp_bgp_state(oid) == BGP_INTERNAL_PEER_ENTRY); @@ -215,6 +210,13 @@ t_s_prefixize(void) test_fill(&snmp_proto); bt_debug("before seg fault\n"); + + if (snmp_is_oid_empty(NULL)) + bt_debug("null oid is empty"); + else + bt_debug("null oid is not empty"); + + bt_debug("main cause\n"); struct oid *tmp = snmp_prefixize(&snmp_proto, nulled, BYTE_ORD); bt_debug("after snmp_prefixize() call\n"); bt_assert( NULL == tmp ); @@ -270,6 +272,135 @@ t_s_prefixize(void) return 1; } +static int +t_oid_compare(void) +{ + /* same length, no prefix */ + struct oid *l1 = OID_ALLOCATE(5); + { + u32 arr[] = { 1, 2, 3, 4, 5 }; + OID_INIT(l1, 5, 0, 1, arr); + } + + + struct oid *r1 = OID_ALLOCATE(5); + { + u32 arr[] = { 1, 2, 3, 4, 6 }; + OID_INIT(r1, 5, 0, 0, arr); + } + + bt_assert(snmp_oid_compare(l1, r1) == -1); + bt_assert(snmp_oid_compare(r1, l1) == 1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + /* same results for prefixed oids */ + l1->prefix = 1; + r1->prefix = 1; + + bt_assert(snmp_oid_compare(l1, r1) == -1); + bt_assert(snmp_oid_compare(r1, l1) == 1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + mb_free(l1); + mb_free(r1); + + + /* different length, no prefix */ + l1 = OID_ALLOCATE(4); + { + u32 arr[] = { 1, 2, 3, 4 }; + OID_INIT(l1, 4, 0, 0, arr); + } + + r1 = OID_ALLOCATE(5); + { + u32 arr[] = { 1, 2, 3, 4, 1 }; + OID_INIT(l1, 5, 0, 1, arr); + } + + bt_assert(snmp_oid_compare(l1, r1) == -1); + bt_assert(snmp_oid_compare(r1, l1) == 1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + /* same results for prefixed oids */ + l1->prefix = 3; + r1->prefix = 3; + + bt_assert(snmp_oid_compare(l1, r1) == -1); + bt_assert(snmp_oid_compare(r1, l1) == 1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + mb_free(l1); + mb_free(r1); + + + /* inverse order different length, no prefix */ + l1 = OID_ALLOCATE(4); + { + u32 arr[] = { 1, 2, 3, 5 }; + OID_INIT(l1, 4, 0, 0, arr); + } + + r1 = OID_ALLOCATE(5); + { + u32 arr[] = { 1, 2, 3, 4, 1 }; + OID_INIT(r1, 5, 0, 0, arr); + } + + bt_assert(snmp_oid_compare(l1, r1) == 1); + bt_assert(snmp_oid_compare(r1, l1) == -1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + /* same results for prefixed oids */ + l1->prefix = 254; + r1->prefix = 254; + + bt_assert(snmp_oid_compare(l1, r1) == 1); + bt_assert(snmp_oid_compare(r1, l1) == -1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + mb_free(l1); + mb_free(r1); + + +/* ==== MIXED PREFIXED / NON PREFIXED OID compare ==== */ + /* same length, mixed */ + l1 = OID_ALLOCATE(6); /* OID .1.2.17.3.21.4 */ + { + u32 arr[] = { 1, 2, 17, 3, 21, 4 }; + OID_INIT(l1, 6, 0, 1, arr); + } + + r1 = OID_ALLOCATE(1); /* OID .1.3.6.1.5.3 */ + { + u32 arr[] = { 3 }; + OID_INIT(l1, 1, 5, 1, arr); + } + + bt_assert(snmp_oid_compare(l1, r1) == -1); + bt_assert(snmp_oid_compare(r1, l1) == 1); + + bt_assert(snmp_oid_compare(l1, l1) == 0); + bt_assert(snmp_oid_compare(r1, r1) == 0); + + mb_free(l1); + mb_free(r1); + + return 1; +} + static int t_s_bgp_state(void) { @@ -323,5 +454,7 @@ int main(int argc, char **argv) bt_test_suite(t_s_prefixize, "Function snmp_prefixize()"); + bt_test_suite(t_oid_compare, "Function snmp_oid_compare()"); + return bt_exit_value(); } diff --git a/proto/snmp/snmp_utils.c b/proto/snmp/snmp_utils.c index 7bda1d74..ba351053 100644 --- a/proto/snmp/snmp_utils.c +++ b/proto/snmp/snmp_utils.c @@ -238,3 +238,63 @@ void snmp_oid_dump(struct oid *oid) log(L_WARN "OID DUMP END ===="); log(L_WARN); } + +/** snmp_oid_compare - find the lexicographical order relation between @left and @right + * @left: left object id relation operant + * @right: right object id relation operant + * + * function returns 0 if left == right -1 if left < right and 1 otherwise + */ +int +snmp_oid_compare(struct oid *left, struct oid *right) +{ + const u32 INTERNET_PREFIX[] = {1, 3, 6, 1}; + + if (left->prefix == 0 && right->prefix == 0) + goto test_ids; + + if (right->prefix == 0) + { + struct oid *temp = left; + left = right; + right = temp; + } + + if (left->prefix == 0) + { + for (int i = 0; i < 4; i++) + if (left->ids[i] < INTERNET_PREFIX[i]) + return -1; + else if (left->ids[i] > INTERNET_PREFIX[i]) + return 1; + + for (int i = 0; i < MIN(left->n_subid - 4, right->n_subid); i++) + if (left->ids[i + 4] < right->ids[i]) + return -1; + else if (left->ids[i + 4] > right->ids[i]) + return 1; + + goto all_same; + } + + if (left->prefix < right->prefix) + return -1; + else if (left->prefix > right->prefix) + return 1; + +test_ids: + for (int i = 0; i < MIN(left->n_subid, right->n_subid); i++) + if (left->ids[i] < right->ids[i]) + return -1; + else if (left->ids[i] > right->ids[i]) + return 1; + +all_same: + /* shorter sequence is before longer in lexicografical order */ + if (left->n_subid < right->n_subid) + return -1; + else if (left->n_subid > right->n_subid) + return 1; + else + return 0; +} diff --git a/proto/snmp/snmp_utils.h b/proto/snmp/snmp_utils.h index 6449f5d3..1d2136f3 100644 --- a/proto/snmp/snmp_utils.h +++ b/proto/snmp/snmp_utils.h @@ -29,4 +29,6 @@ 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); + #endif diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 68b489cd..e4742e1e 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -26,6 +26,9 @@ * */ +static byte *snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class, +byte *buf, uint size, struct snmp_error *error, uint contid, int byte_ord); + static int parse_response(struct snmp_proto *p, byte *buf, uint size); static int snmp_stop_ack(sock *sk, uint size); static void do_response(struct snmp_proto *p, byte *buf, uint size); @@ -36,6 +39,7 @@ 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, u8 mib_class, uint contid); static inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord); + static const char * const snmp_errs[] = { #define SNMP_ERR_SHIFT 256 [AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed", @@ -541,15 +545,28 @@ byte *pkt, uint rsize, uint contid, u8 mib_class, int byte_ord) .type = AGENTX_END_OF_MIB_VIEW, }; + /* pkt = snmp_mib_fill( p, o_copy, mib_class, pkt, rsize, &error, contid, byte_ord ); + */ if (o_copy) { + pkt = snmp_mib_fill( + p, o_copy, mib_class, pkt, rsize, &error, contid, byte_ord + ); + mb_free(o_copy); } + else + { + struct agentx_varbind *vb = snmp_create_varbind(pkt, o_start); + pkt += snmp_varbind_size(vb); + vb->type = AGENTX_NO_SUCH_OBJECT; + } + log(L_INFO "over HERE "); return pkt; } @@ -1317,6 +1334,9 @@ snmp_prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord) { const u32 prefix[] = {1, 3, 6, 1}; + if (oid == NULL) + return NULL; + if (snmp_is_oid_empty(oid)) { /* allocate new zeroed oid */ diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index 4042f189..a4217ebf 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -274,7 +274,4 @@ enum agentx_response_err { int snmp_rx(sock *sk, uint size); -static byte *snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class, -byte *buf, uint size, struct snmp_error *error, uint contid, int byte_ord); - #endif