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);
|
snmp_log("socket error '%s' (errno: %d)", strerror(err), err);
|
||||||
struct snmp_proto *p = sk->data;
|
struct snmp_proto *p = sk->data;
|
||||||
p->errs++;
|
|
||||||
|
|
||||||
snmp_sock_disconnect(p, 1);
|
snmp_sock_disconnect(p, 1);
|
||||||
}
|
}
|
||||||
@ -280,10 +279,6 @@ snmp_start_locked(struct object_lock *lock)
|
|||||||
p->state = SNMP_LOCKED;
|
p->state = SNMP_LOCKED;
|
||||||
sock *s = p->sock;
|
sock *s = p->sock;
|
||||||
|
|
||||||
p->to_send = 0;
|
|
||||||
p->errs = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (!p->bgp_trie)
|
if (!p->bgp_trie)
|
||||||
p->bgp_trie = f_new_trie(p->lp, 0); // TODO user-data attachment size
|
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;
|
p->sock = s;
|
||||||
s->data = p;
|
s->data = p;
|
||||||
|
|
||||||
p->to_send = 0;
|
|
||||||
p->errs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try opening the socket, schedule a retry on fail */
|
/* 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);
|
snmp_startup(p);
|
||||||
return PS_START;
|
return PS_START;
|
||||||
}
|
}
|
||||||
@ -651,9 +644,9 @@ snmp_shutdown(struct proto *P)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct protocol proto_snmp = {
|
struct protocol proto_snmp = {
|
||||||
.name = "Snmp",
|
.name = "SNMP",
|
||||||
.template = "snmp%d",
|
.template = "snmp%d",
|
||||||
.channel_mask = NB_ANY,
|
.channel_mask = 0,
|
||||||
.proto_size = sizeof(struct snmp_proto),
|
.proto_size = sizeof(struct snmp_proto),
|
||||||
.config_size = sizeof(struct snmp_config),
|
.config_size = sizeof(struct snmp_config),
|
||||||
.postconfig = snmp_postconfig,
|
.postconfig = snmp_postconfig,
|
||||||
|
@ -116,6 +116,7 @@ struct snmp_proto {
|
|||||||
u32 bgp_local_as;
|
u32 bgp_local_as;
|
||||||
|
|
||||||
sock *sock;
|
sock *sock;
|
||||||
|
void *last_header; /* points to partial PDU header */
|
||||||
u8 timeout; /* timeout is part of MIB registration. It
|
u8 timeout; /* timeout is part of MIB registration. It
|
||||||
specifies how long should the master
|
specifies how long should the master
|
||||||
agent wait for request responses. */
|
agent wait for request responses. */
|
||||||
@ -139,9 +140,6 @@ struct snmp_proto {
|
|||||||
uint startup_delay;
|
uint startup_delay;
|
||||||
timer *startup_timer;
|
timer *startup_timer;
|
||||||
u8 state;
|
u8 state;
|
||||||
|
|
||||||
uint to_send;
|
|
||||||
uint errs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//void snmp_tx(sock *sk);
|
//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);
|
memcpy(c.buffer, data, size);
|
||||||
ADVANCE(c.buffer, c.size, 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);
|
sk_send(sk, s);
|
||||||
|
|
||||||
#undef TRAP0_HEADER_SIZE
|
#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;
|
has_any = 0;
|
||||||
for (bulk_state.index = 0; bulk_state.index < bulk_state.repeaters;
|
for (bulk_state.index = 0; bulk_state.index < bulk_state.repeaters;
|
||||||
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 */
|
/* 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. */
|
/* We update the error, index pair on the beginning of the packet. */
|
||||||
response_err_ind(res, c.error, c.index + 1);
|
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. */
|
/* We send the message in TX-buffer. */
|
||||||
sk_send(sk, s);
|
sk_send(sk, s);
|
||||||
@ -1542,8 +1550,9 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
|
|||||||
|
|
||||||
partial:
|
partial:
|
||||||
/* need to tweak RX buffer packet size */
|
/* 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;
|
*skip = AGENTX_HEADER_SIZE;
|
||||||
|
p->last_header = h;
|
||||||
|
|
||||||
/* number of bytes parsed from RX-buffer */
|
/* number of bytes parsed from RX-buffer */
|
||||||
ret = pkt - pkt_start;
|
ret = pkt - pkt_start;
|
||||||
@ -1897,6 +1906,9 @@ snmp_manage_tbuf(struct snmp_proto UNUSED *p, struct snmp_pdu *c)
|
|||||||
static struct agentx_response *
|
static struct agentx_response *
|
||||||
prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
|
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_response *r = (void *) c->buffer;
|
||||||
struct agentx_header *h = &r->h;
|
struct agentx_header *h = &r->h;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user