From c41a9e044b7d5c8ab7385f0d412e12b293cdba94 Mon Sep 17 00:00:00 2001 From: Vojtech Vilimek Date: Thu, 15 Aug 2024 11:52:38 +0200 Subject: [PATCH] SNMP: Handle unresponsive master agent --- proto/snmp/snmp.c | 5 +++-- proto/snmp/snmp.h | 1 + proto/snmp/subagent.c | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index 1f0127d1..fbc2cf0b 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -207,7 +207,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) if (cf->trans_type == SNMP_TRANS_TCP) { s->type = SK_TCP_ACTIVE; - //s->saddr = ipa_from_ip4(p->local_ip); s->daddr = p->remote_ip; s->dport = p->remote_port; s->rbsize = SNMP_RX_BUFFER_SIZE; @@ -221,7 +220,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) s->tbsize = SNMP_TX_BUFFER_SIZE; } - /* s->tos = IP_PREC_INTERNET_CONTROL */ s->tx_hook = snmp_connected; s->err_hook = snmp_sock_err; @@ -262,6 +260,9 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) p->sock->tx_hook = snmp_tx; snmp_register_mibs(p); + + // TODO timer for CONN + return PS_START; case SNMP_CONN: diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index d52484eb..9a787c6e 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -136,6 +136,7 @@ struct snmp_proto { struct mib_tree *mib_tree; int verbose; + uint pings; u32 ignore_ping_id; }; diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 083ae998..4e432458 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -781,13 +781,21 @@ parse_response(struct snmp_proto *p, byte *res) uint pkt_size = LOAD_U32(h->payload); + if (p->ignore_ping_id && LOAD_U32(h->packet_id) == p->ignore_ping_id) + { + p->pings--; + p->ignore_ping_id = 0; + } + + /* Number of agentx-Ping-PDU without response */ + if (p->pings > 5) + snmp_reset(p); + switch (r->error) { case AGENTX_RES_NO_ERROR: if (p->verbose || LOAD_U32(h->packet_id) != p->ignore_ping_id) TRACE(D_PACKETS, "SNMP received agentx-Response-PDU"); - if (LOAD_U32(h->packet_id) == p->ignore_ping_id) - p->ignore_ping_id = 0; do_response(p, res); break; @@ -796,8 +804,6 @@ parse_response(struct snmp_proto *p, byte *res) case AGENTX_RES_REQUEST_DENIED: case AGENTX_RES_UNKNOWN_REGISTER: TRACE(D_PACKETS, "SNMP received agentx-Response-PDU with error %u", r->error); - if (LOAD_U32(h->packet_id) == p->ignore_ping_id) - p->ignore_ping_id = 0; snmp_register_ack(p, r); break; @@ -1361,6 +1367,8 @@ snmp_ping(struct snmp_proto *p) /* sending only header */ uint s = update_packet_size(h, (byte *) h + AGENTX_HEADER_SIZE); + if (p->packet_id) + p->pings++; sk_send(sk, s); }