diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index 72040aaa..0aa17dd3 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -194,7 +194,7 @@ static void snmp_tx_skip(sock *sk) { struct snmp_proto *p = sk->data; - proto_notify_state(&p->p, snmp_set_state(p, SNMP_STOP)); + snmp_set_state(p, SNMP_STOP); } /* @@ -219,6 +219,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) TRACE(D_EVENTS, "TODO"); ASSERT(last == SNMP_DOWN); + proto_notify_state(&p->p, PS_START); if (cf->trans_type == SNMP_TRANS_TCP) { /* We need to lock the IP address */ @@ -288,7 +289,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) p->startup_timer->hook = snmp_stop_timeout; tm_start(p->startup_timer, 1 S); - return PS_START; case SNMP_REGISTER: @@ -306,10 +306,11 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) case SNMP_CONN: TRACE(D_EVENTS, "MIBs registered"); ASSERT(last == SNMP_REGISTER); + proto_notify_state(&p->p, PS_UP); return PS_UP; case SNMP_STOP: - if (p->sock && p->state != SNMP_OPEN) + if (p->sock && p->state != SNMP_OPEN && !sk_tx_buffer_empty(p->sock)) { TRACE(D_EVENTS, "closing AgentX session"); if (p->state == SNMP_OPEN || p->state == SNMP_REGISTER || @@ -321,6 +322,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) p->startup_timer->hook = snmp_stop_timeout; tm_start(p->startup_timer, 150 MS); + proto_notify_state(&p->p, PS_STOP); return PS_STOP; } @@ -330,6 +332,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) case SNMP_DOWN: TRACE(D_EVENTS, "AgentX session closed"); snmp_cleanup(p); + proto_notify_state(&p->p, PS_DOWN); return PS_DOWN; default: @@ -426,11 +429,19 @@ snmp_connected(sock *sk) int snmp_reset(struct snmp_proto *p) { - int proto_state = snmp_set_state(p, SNMP_STOP); - proto_notify_state(&p->p, proto_state); - return proto_state; + return snmp_set_state(p, SNMP_STOP); } +/* + * snmp_up - AgentX session has registered all MIBs, protocols is up + * @p: SNMP protocol instance + */ +void +snmp_up(struct snmp_proto *p) +{ + if (p->state == SNMP_REGISTER) + snmp_set_state(p, SNMP_CONN); +} /* * snmp_sock_err - handle errors on socket by reopenning the socket @@ -498,7 +509,7 @@ static void snmp_stop_timeout(timer *tm) { struct snmp_proto *p = tm->data; - proto_notify_state(&p->p, snmp_set_state(p, SNMP_DOWN)); + snmp_set_state(p, SNMP_DOWN); } /* diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index 7e796841..26dcf2a5 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -170,6 +170,7 @@ void snmp_reconnect(timer *tm); int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state); int snmp_reset(struct snmp_proto *p); +void snmp_up(struct snmp_proto *p); extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)]; diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index f1a54a7b..7e5ebcf0 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -872,6 +872,7 @@ do_response(struct snmp_proto *p, byte *pkt) break; case SNMP_STOP: + case SNMP_DOWN: break; default: @@ -1014,7 +1015,7 @@ response_err_ind(struct agentx_response *res, enum agentx_response_errs err, u16 /* agentx-Get-PDU */ void -snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk) +snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk) { struct mib_leaf *leaf; leaf = snmp_walk_init(p->mib_tree, walk, &c->sr_vb_start->name, c); @@ -1022,13 +1023,14 @@ snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start enum snmp_search_res res; res = snmp_walk_fill(leaf, walk, c); + // TODO is this really necessary? if (res != SNMP_SEARCH_OK) c->sr_vb_start->type = snmp_search_res_to_type(res); } /* agentx-GetNext-PDU */ int -snmp_get_next_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk) +snmp_get_next_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk) { (void) snmp_walk_init(p->mib_tree, walk, &c->sr_vb_start->name, c); struct mib_leaf *leaf = snmp_walk_next(p->mib_tree, walk, c); @@ -1044,14 +1046,14 @@ snmp_get_next_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_ /* agentx-GetBulk-PDU */ void -snmp_get_bulk_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk, struct agentx_bulk_state *bulk) +snmp_get_bulk_pdu(struct snmp_proto *p, struct snmp_pdu *c, struct mib_walk_state *walk) { if (c->index >= bulk->getbulk.non_repeaters) bulk->repeaters++; // store the o_start and o_end - bulk->has_any |= snmp_get_next_pdu(p, c, o_start, walk); + bulk->has_any |= snmp_get_next_pdu(p, c, walk); } int @@ -1188,15 +1190,15 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) switch (h->type) { case AGENTX_GET_PDU: - snmp_get_pdu(p, &c, start_rx, &walk); + snmp_get_pdu(p, &c, &walk); break; case AGENTX_GET_NEXT_PDU: - snmp_get_next_pdu(p, &c, start_rx, &walk); + snmp_get_next_pdu(p, &c, &walk); break; case AGENTX_GET_BULK_PDU: - snmp_get_bulk_pdu(p, &c, start_rx, &walk, &bulk_state); + snmp_get_bulk_pdu(p, &c, &walk); break; default: