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)
{
static void
snmp_startup_timeout(timer *t)
{
+ log(L_INFO "startup timer triggered");
snmp_startup(t->data);
}
/* 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;
rfree(p->sock);
p->sock = NULL;
+ rfree(p->lock);
+ p->lock = NULL;
+
p->state = SNMP_ERR;
tm_start(p->startup_timer, 15 S);
}
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)
#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" );
-
- for (int i = 0; i < oid->n_subid; i++)
- bt_debug(" %u: %u\n", i + 1, oid->ids[i]);
+#define OID_ALLOCATE(size) mb_alloc(&root_pool, sizeof(struct oid) + (size) * sizeof (u32))
- 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)
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);
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 );
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)
{
bt_test_suite(t_s_prefixize, "Function snmp_prefixize()");
+ bt_test_suite(t_oid_compare, "Function snmp_oid_compare()");
+
return bt_exit_value();
}
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;
+}
*
*/
+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);
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",
.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;
}
{
const u32 prefix[] = {1, 3, 6, 1};
+ if (oid == NULL)
+ return NULL;
+
if (snmp_is_oid_empty(oid))
{
/* allocate new zeroed oid */