mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
SNMP: Fix handling of partially received PDUs
This commit is contained in:
parent
bcbb56bef6
commit
fedaa0af5e
@ -257,7 +257,6 @@ snmp_sock_err(sock *sk, int UNUSED err)
|
||||
{
|
||||
snmp_log("socket error '%s' (errno: %d)", strerror(err), err);
|
||||
struct snmp_proto *p = sk->data;
|
||||
p->errs++;
|
||||
|
||||
snmp_sock_disconnect(p, 1);
|
||||
}
|
||||
@ -280,10 +279,6 @@ snmp_start_locked(struct object_lock *lock)
|
||||
p->state = SNMP_LOCKED;
|
||||
sock *s = p->sock;
|
||||
|
||||
p->to_send = 0;
|
||||
p->errs = 0;
|
||||
|
||||
|
||||
if (!p->bgp_trie)
|
||||
p->bgp_trie = f_new_trie(p->lp, 0); // TODO user-data attachment size
|
||||
|
||||
@ -303,9 +298,6 @@ snmp_start_locked(struct object_lock *lock)
|
||||
|
||||
p->sock = s;
|
||||
s->data = p;
|
||||
|
||||
p->to_send = 0;
|
||||
p->errs = 0;
|
||||
}
|
||||
|
||||
/* Try opening the socket, schedule a retry on fail */
|
||||
@ -478,6 +470,7 @@ snmp_start(struct proto *P)
|
||||
}
|
||||
}
|
||||
|
||||
p->last_header = NULL;
|
||||
snmp_startup(p);
|
||||
return PS_START;
|
||||
}
|
||||
@ -651,9 +644,9 @@ snmp_shutdown(struct proto *P)
|
||||
*/
|
||||
|
||||
struct protocol proto_snmp = {
|
||||
.name = "Snmp",
|
||||
.name = "SNMP",
|
||||
.template = "snmp%d",
|
||||
.channel_mask = NB_ANY,
|
||||
.channel_mask = 0,
|
||||
.proto_size = sizeof(struct snmp_proto),
|
||||
.config_size = sizeof(struct snmp_config),
|
||||
.postconfig = snmp_postconfig,
|
||||
|
@ -116,6 +116,7 @@ struct snmp_proto {
|
||||
u32 bgp_local_as;
|
||||
|
||||
sock *sock;
|
||||
void *last_header; /* points to partial PDU header */
|
||||
u8 timeout; /* timeout is part of MIB registration. It
|
||||
specifies how long should the master
|
||||
agent wait for request responses. */
|
||||
@ -139,9 +140,6 @@ struct snmp_proto {
|
||||
uint startup_delay;
|
||||
timer *startup_timer;
|
||||
u8 state;
|
||||
|
||||
uint to_send;
|
||||
uint errs;
|
||||
};
|
||||
|
||||
//void snmp_tx(sock *sk);
|
||||
|
@ -339,7 +339,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
|
||||
memcpy(c.buffer, data, size);
|
||||
ADVANCE(c.buffer, c.size, size);
|
||||
|
||||
uint s = update_packet_size(p, sk->tbuf, c.buffer);
|
||||
uint s = update_packet_size(p, sk->tpos, c.buffer);
|
||||
sk_send(sk, s);
|
||||
|
||||
#undef TRAP0_HEADER_SIZE
|
||||
@ -1522,15 +1522,23 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
|
||||
has_any = 0;
|
||||
for (bulk_state.index = 0; bulk_state.index < bulk_state.repeaters;
|
||||
bulk_state.repeaters++)
|
||||
has_any = has_any || snmp_get_bulk2(p, start, end, &bulk_state, &c);
|
||||
has_any = snmp_get_bulk2(p, start, end, &bulk_state, &c) || has_any;
|
||||
}
|
||||
}
|
||||
|
||||
/* send the constructed packet */
|
||||
struct agentx_response *res = (void *) sk->tbuf;
|
||||
struct agentx_response *res;
|
||||
if (p->last_header)
|
||||
{
|
||||
res = p->last_header;
|
||||
p->last_header = NULL;
|
||||
}
|
||||
else
|
||||
res = response_header;
|
||||
|
||||
/* We update the error, index pair on the beginning of the packet. */
|
||||
response_err_ind(res, c.error, c.index + 1);
|
||||
uint s = update_packet_size(p, (byte *) response_header, c.buffer);
|
||||
uint s = update_packet_size(p, (byte *) res, c.buffer);
|
||||
|
||||
/* We send the message in TX-buffer. */
|
||||
sk_send(sk, s);
|
||||
@ -1542,8 +1550,9 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
|
||||
|
||||
partial:
|
||||
/* need to tweak RX buffer packet size */
|
||||
(c.byte_ord) ? put_u32(&h->payload, pkt_size) : (h->payload = pkt_size);
|
||||
STORE_U32(h->payload, pkt_size);
|
||||
*skip = AGENTX_HEADER_SIZE;
|
||||
p->last_header = h;
|
||||
|
||||
/* number of bytes parsed from RX-buffer */
|
||||
ret = pkt - pkt_start;
|
||||
@ -1897,6 +1906,9 @@ snmp_manage_tbuf(struct snmp_proto UNUSED *p, struct snmp_pdu *c)
|
||||
static struct agentx_response *
|
||||
prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
|
||||
{
|
||||
if (p->last_header)
|
||||
return p->last_header;
|
||||
|
||||
struct agentx_response *r = (void *) c->buffer;
|
||||
struct agentx_header *h = &r->h;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user