0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-03 15:41:54 +00:00

Register-PDU distinguish between instance/tree reg.

Other changes include simplification of large TX buffer when it's insufficient
and purge of additional_buffer.
This commit is contained in:
Vojtech Vilimek 2023-08-08 19:00:54 +02:00
parent bdf68b3240
commit 5f936b4442
5 changed files with 119 additions and 157 deletions

View File

@ -71,7 +71,7 @@ snmp_bgp_register(struct snmp_proto *p)
add_tail(&p->register_queue, &registering->n); add_tail(&p->register_queue, &registering->n);
p->register_to_ack++; p->register_to_ack++;
snmp_register(p, oid, 0, 1); snmp_register(p, oid, 0, 1, 0);
} }
/* /*

View File

@ -65,23 +65,15 @@ snmp_init(struct proto_config *CF)
static inline void static inline void
snmp_cleanup(struct snmp_proto *p) snmp_cleanup(struct snmp_proto *p)
{ {
struct additional_buffer *b;
WALK_LIST(b, p->additional_buffers)
{
mb_free(b->buf);
rem_node(&b->n);
mb_free(b);
}
init_list(&p->additional_buffers);
rfree(p->startup_timer); rfree(p->startup_timer);
rfree(p->ping_timer); p->startup_timer = NULL;
rfree(p->ping_timer);
p->ping_timer = NULL;
if (p->sock != NULL)
rfree(p->sock); rfree(p->sock);
p->sock = NULL; p->sock = NULL;
if (p->lock != NULL)
rfree(p->lock); rfree(p->lock);
p->lock = NULL; p->lock = NULL;
@ -172,14 +164,13 @@ snmp_start_locked(struct object_lock *lock)
s->tx_hook = snmp_connected; s->tx_hook = snmp_connected;
s->err_hook = snmp_sock_err; s->err_hook = snmp_sock_err;
//mb_free(p->sock);
p->sock = s; p->sock = s;
s->data = p; s->data = p;
p->to_send = 0; p->to_send = 0;
p->errs = 0; p->errs = 0;
// snmp_startup(p);
if (sk_open(s) < 0) if (sk_open(s) < 0)
{ {
log(L_ERR "Cannot open listening socket"); log(L_ERR "Cannot open listening socket");
@ -195,8 +186,6 @@ snmp_connected(sock *sk)
struct snmp_proto *p = sk->data; struct snmp_proto *p = sk->data;
snmp_log("snmp_connected() connection created"); snmp_log("snmp_connected() connection created");
byte *buf UNUSED = sk->rpos; byte *buf UNUSED = sk->rpos;
uint size = sk->rbuf + sk->rbsize - sk->rpos;
snmp_dump_packet(buf, size);
sk->rx_hook = snmp_rx; sk->rx_hook = snmp_rx;
sk->tx_hook = snmp_tx; sk->tx_hook = snmp_tx;
@ -223,13 +212,8 @@ snmp_sock_err(sock *sk, int err)
p->lock = NULL; p->lock = NULL;
snmp_log("changing proto_snmp state to ERR[OR]"); snmp_log("changing proto_snmp state to ERR[OR]");
if (err)
p->state = SNMP_ERR; p->state = SNMP_ERR;
else // snmp_shutdown((struct proto *) p);
{
snmp_shutdown((struct proto *) p);
return;
}
// TODO ping interval // TODO ping interval
tm_start(p->startup_timer, 4 S); tm_start(p->startup_timer, 4 S);
@ -252,29 +236,11 @@ snmp_start(struct proto *P)
init_list(&p->register_queue); init_list(&p->register_queue);
init_list(&p->bgp_registered); init_list(&p->bgp_registered);
p->partial_response = NULL;
p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0); p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0);
// tm_set(p->ping_timer, current_time() + 2 S); // tm_set(p->ping_timer, current_time() + 2 S);
/* remove duplicate lock acquiring code */
#if 0
/* starting agentX communicaiton channel */
snmp_log("preparing lock");
struct object_lock *lock;
lock = p->lock = olock_new(p->p.pool);
lock->type = OBJLOCK_TCP;
lock->hook = snmp_start_locked;
lock->data = p;
olock_acquire(lock);
snmp_log("lock acquired");
snmp_log("local ip: %I:%u, remote ip: %I:%u",
p->local_ip, p->local_port, p->remote_ip, p->remote_port);
#endif
/* create copy of bonds to bgp */ /* create copy of bonds to bgp */
HASH_INIT(p->bgp_hash, p->p.pool, 10); HASH_INIT(p->bgp_hash, p->p.pool, 10);
@ -298,8 +264,6 @@ snmp_start(struct proto *P)
} }
} }
init_list(&p->additional_buffers);
snmp_startup(p); snmp_startup(p);
return PS_START; return PS_START;
} }

View File

@ -26,8 +26,8 @@
#define SNMP_PORT 705 #define SNMP_PORT 705
#define SNMP_RX_BUFFER_SIZE 2048 #define SNMP_RX_BUFFER_SIZE 8192
#define SNMP_TX_BUFFER_SIZE 2048 #define SNMP_TX_BUFFER_SIZE 8192
enum snmp_proto_state { enum snmp_proto_state {
SNMP_ERR = 0, SNMP_ERR = 0,
@ -129,8 +129,11 @@ struct snmp_proto {
uint to_send; uint to_send;
uint errs; uint errs;
list additional_buffers; /* buffers of data to send that does not fit /*
* into socket's TX buffer */ * if the packet hasn't been fully recieved, partial_reponse points
* into the TX buffer to the Response-PDU header (needed for packet payload)
*/
struct agentx_response *partial_response;
}; };
void snmp_tx(sock *sk); void snmp_tx(sock *sk);

View File

@ -43,13 +43,12 @@ static struct agentx_response *prepare_response(struct snmp_proto *p, struct snm
//static byte *prepare_response(struct snmp_proto *p, struct snmp_pdu_context *c); //static byte *prepare_response(struct snmp_proto *p, struct snmp_pdu_context *c);
//static struct agentx_response *prepare_response(struct snmp_proto *p, byte *buf, uint size); //static struct agentx_response *prepare_response(struct snmp_proto *p, byte *buf, uint size);
static void response_err_ind(struct agentx_response *res, uint err, uint ind); static void response_err_ind(struct agentx_response *res, uint err, uint ind);
static void update_packet_size(struct snmp_proto *p, struct agentx_header *h, byte *start, byte *end); static uint update_packet_size(struct snmp_proto *p, byte *start, byte *end);
//static void response_err_ind(byte *buf, uint err, uint ind); //static void response_err_ind(byte *buf, uint err, uint ind);
//static struct oid *search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class, struct snmp_pdu_context *c); //static struct oid *search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class, struct snmp_pdu_context *c);
static struct oid *search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end, struct oid *o_curr, struct snmp_pdu_context *c, enum snmp_search_res *result); static struct oid *search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end, struct oid *o_curr, struct snmp_pdu_context *c, enum snmp_search_res *result);
//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 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 inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord);
int snmp_send(struct snmp_proto *p, struct snmp_pdu_context *c);
static const char * const snmp_errs[] = { static const char * const snmp_errs[] = {
#define SNMP_ERR_SHIFT 256 #define SNMP_ERR_SHIFT 256
@ -109,24 +108,28 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
buf = c.buffer; buf = c.buffer;
} }
c.size -= (AGENTX_HEADER_SIZE + snmp_oid_size(oid) + snmp_str_size(str) + 4);
snmp_log("open_pdu()");
struct agentx_header *h = (struct agentx_header *) c.buffer; struct agentx_header *h = (struct agentx_header *) c.buffer;
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
SNMP_BLANK_HEADER(h, AGENTX_OPEN_PDU); SNMP_BLANK_HEADER(h, AGENTX_OPEN_PDU);
STORE_U32(h->session_id, 1); STORE_U32(h->session_id, 1);
STORE_U32(h->transaction_id, 1); STORE_U32(h->transaction_id, 1);
STORE_U32(h->packet_id, 1); STORE_U32(h->packet_id, 1);
c.size -= (4 + snmp_oid_size(oid) + snmp_str_size(str));
c.buffer = snmp_put_fbyte(c.buffer, p->timeout); c.buffer = snmp_put_fbyte(c.buffer, p->timeout);
c.buffer = snmp_put_oid(c.buffer, oid); c.buffer = snmp_put_oid(c.buffer, oid);
c.buffer = snmp_put_str(c.buffer, str); c.buffer = snmp_put_str(c.buffer, str);
update_packet_size(p, h, buf, c.buffer);
snmp_log("send PDU data (open) ..."); snmp_log("send PDU data (open) ...");
snmp_send(p, &c); uint s = update_packet_size(p, buf, c.buffer);
int ret = sk_send(sk, s);
if (ret > 0)
snmp_log("sk_send OK!");
else if (ret == 0)
snmp_log("sk_send sleep");
else
snmp_log("sk_send error");
} }
#if 0 #if 0
@ -241,9 +244,9 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
} }
*/ */
/* register / unregister pdu */ /* Register-PDU / Unregister-PDU */
static void static inline void
un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 type) un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 type, u8 is_instance)
{ {
sock *sk = p->sock; sock *sk = p->sock;
//buf = pkt = sk->tbuf; //buf = pkt = sk->tbuf;
@ -268,10 +271,9 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
struct agentx_header *h = &ur->h; struct agentx_header *h = &ur->h;
// FIXME correctly set INSTANCE REGISTRATION bit // FIXME correctly set INSTANCE REGISTRATION bit
SNMP_HEADER(h, type, AGENTX_FLAG_INSTANCE_REGISTRATION); SNMP_HEADER(h, type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
/* use new transactionID, reset packetID */ /* use new transactionID, reset packetID */
p->transaction_id++; p->packet_id++;
p->packet_id = 1;
SNMP_SESSION(h, p); SNMP_SESSION(h, p);
/* do not override timeout */ /* do not override timeout */
@ -292,22 +294,29 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
} }
/* buf - start, pkt - end */ /* buf - start, pkt - end */
update_packet_size(p, h, buf, c.buffer); update_packet_size(p, buf, c.buffer);
/* /*
for (uint i = 0; i < pkt - buf; i++) for (uint i = 0; i < pkt - buf; i++)
snmp_log("%p: %02X", buf+i, *(buf + i)); snmp_log("%p: %02X", buf+i, *(buf + i));
*/ */
uint s = update_packet_size(p, buf, c.buffer);
snmp_log("sending (un)register %s", snmp_pkt_type[type]); snmp_log("sending (un)register %s", snmp_pkt_type[type]);
snmp_send(p, &c); int ret = sk_send(sk, s);
if (ret > 0)
snmp_log("sk_send OK!");
else if (ret == 0)
snmp_log("sk_send sleep");
else
snmp_log("sk_send error");
} }
/* register pdu */ /* register pdu */
void void
snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len) snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance)
{ {
un_register_pdu(p, oid, index, len, AGENTX_REGISTER_PDU); un_register_pdu(p, oid, index, len, AGENTX_REGISTER_PDU, is_instance);
} }
@ -315,7 +324,7 @@ snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len)
void UNUSED void UNUSED
snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len) snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len)
{ {
un_register_pdu(p, oid, index, len, AGENTX_UNREGISTER_PDU); un_register_pdu(p, oid, index, len, AGENTX_UNREGISTER_PDU, 0);
} }
static void static void
@ -341,15 +350,22 @@ close_pdu(struct snmp_proto *p, u8 reason)
struct agentx_header *h = (struct agentx_header *) c.buffer; struct agentx_header *h = (struct agentx_header *) c.buffer;
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
SNMP_BLANK_HEADER(h, AGENTX_CLOSE_PDU); SNMP_BLANK_HEADER(h, AGENTX_CLOSE_PDU);
p->packet_id++;
SNMP_SESSION(h, p); SNMP_SESSION(h, p);
snmp_put_fbyte(c.buffer, reason); snmp_put_fbyte(c.buffer, reason);
ADVANCE(c.buffer, c.size, 4); ADVANCE(c.buffer, c.size, 4);
update_packet_size(p, h, buf, c.buffer); uint s = update_packet_size(p, buf, c.buffer);
snmp_log("preparing to sk_send() (close)"); snmp_log("preparing to sk_send() (close)");
snmp_send(p, &c); int ret = sk_send(sk, s);
if (ret > 0)
snmp_log("sk_send OK!");
else if (ret == 0)
snmp_log("sk_send sleep");
else
snmp_log("sk_send error");
} }
#if 0 #if 0
@ -481,8 +497,8 @@ static inline void
refresh_ids(struct snmp_proto *p, struct agentx_header *h) refresh_ids(struct snmp_proto *p, struct agentx_header *h)
{ {
int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER; int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
p->transaction_id = LOAD(h->transaction_id, byte_ord); p->transaction_id = LOAD_U32(h->transaction_id, byte_ord);
p->packet_id = LOAD(h->packet_id, byte_ord); p->packet_id = LOAD_U32(h->packet_id, byte_ord);
} }
/** /**
@ -576,7 +592,7 @@ parse_response(struct snmp_proto *p, byte *res, uint size)
int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER; int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
uint pkt_size = LOAD(h->payload, byte_ord); uint pkt_size = LOAD_U32(h->payload, byte_ord);
snmp_log("p_res pkt_size %u", pkt_size); snmp_log("p_res pkt_size %u", pkt_size);
if (size < pkt_size + AGENTX_HEADER_SIZE) { if (size < pkt_size + AGENTX_HEADER_SIZE) {
snmp_log("parse_response early return"); snmp_log("parse_response early return");
@ -630,7 +646,7 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
{ {
case SNMP_INIT: case SNMP_INIT:
/* copy session info from recieved packet */ /* copy session info from recieved packet */
p->session_id = LOAD(h->session_id, byte_ord); p->session_id = LOAD_U32(h->session_id, byte_ord);
refresh_ids(p, h); refresh_ids(p, h);
/* the state needs to be changed before sending registering PDUs to /* the state needs to be changed before sending registering PDUs to
@ -670,7 +686,7 @@ u8
snmp_get_mib_class(const struct oid *oid) snmp_get_mib_class(const struct oid *oid)
{ {
// TODO check code paths for oid->n_subid < 3 // TODO check code paths for oid->n_subid < 3
if (oid->prefix != 2 && oid->ids[0] != 1) if (oid->prefix != 2 && oid->ids[0] != SNMP_MIB_2)
return SNMP_CLASS_INVALID; return SNMP_CLASS_INVALID;
switch (oid->ids[1]) switch (oid->ids[1])
@ -865,32 +881,14 @@ parse_close_pdu(struct snmp_proto UNUSED *p, byte UNUSED *req, uint UNUSED size)
return 0; return 0;
} }
static inline void static inline uint
update_packet_size(struct snmp_proto *p, struct agentx_header *h, byte *start, byte *end) update_packet_size(struct snmp_proto *p, byte *start, byte *end)
{ {
uint size; struct agentx_header *h = (void *) p->sock->tpos;
if (EMPTY_LIST(p->additional_buffers)) size_t s = snmp_pkt_len(start, end);
size = snmp_pkt_len(start, end); STORE_U32(h->payload, s);
else return AGENTX_HEADER_SIZE + s;
size = p->to_send;
/* TODO add packet size limiting
* we couldn't overflow the size because we limit the maximum packet size
*/
struct additional_buffer *b;
WALK_LIST(b, p->additional_buffers)
{
size += b->pos - b->buf;
}
STORE_U32(h->payload, size);
// if (p->additional_buffers)
// STORE_U32(h->payload, p->to_send + (end - start));
// else {}
//// STORE_U32(h->payload, snmp_pkt_len(start, end));
} }
static inline void static inline void
@ -913,7 +911,7 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
struct agentx_header *h = (void *) pkt; struct agentx_header *h = (void *) pkt;
ADVANCE(pkt, size, AGENTX_HEADER_SIZE); ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
uint pkt_size = LOAD(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER); uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
sock *sk = p->sock; sock *sk = p->sock;
struct snmp_pdu_context c = { struct snmp_pdu_context c = {
@ -1074,9 +1072,9 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
send: send:
snmp_log("gets2: sending response ..."); snmp_log("gets2: sending response ...");
response_err_ind(response_header, c.error, ind); //response_err_ind(response_header, c.error, ind);
// update_packet_size(&response_header->h, sk->tbuf, c.buffer); // update_packet_size(&response_header->h, sk->tbuf, c.buffer);
update_packet_size(p, &response_header->h, (byte *) response_header, c.buffer); //update_packet_size(p, &response_header->h, (byte *) response_header, c.buffer);
//snmp_dump_packet((byte *) response_header, AGENTX_HEADER_SIZE + LOAD(response_header->h.payload, c.byte_ord)); //snmp_dump_packet((byte *) response_header, AGENTX_HEADER_SIZE + LOAD(response_header->h.payload, c.byte_ord));
//snmp_dump_packet((byte *) response_header, AGENTX_HEADER_SIZE + 16 + 8); //snmp_dump_packet((byte *) response_header, AGENTX_HEADER_SIZE + 16 + 8);
@ -1090,33 +1088,41 @@ send:
snmp_log("diff %d start byte %u end byte %u", c.buffer - ((byte *) snmp_log("diff %d start byte %u end byte %u", c.buffer - ((byte *)
response_header), b, d); response_header), b, d);
*/ */
response_err_ind(response_header, c.error, ind);
uint s = update_packet_size(p, (byte *) response_header, c.buffer);
/* number of bytes put into the tx-buffer */ /* number of bytes put into the tx-buffer */
//int ret = sk_send(sk, c.buffer - sk->tbuf); //int ret = sk_send(sk, c.buffer - sk->tbuf);
snmp_log("sending response to Get-PDU, GetNext-PDU or GetBulk-PDU request ..."); snmp_log("sending response to Get-PDU, GetNext-PDU or GetBulk-PDU request ...");
snmp_send(p, &c); int ret = sk_send(sk, s);
/*
int ret = sk_send(sk, c.buffer - sk->tpos);
if (ret == 0) if (ret == 0)
snmp_log("sk_send sleep (gets2"); snmp_log("sk_send sleep (gets2");
else if (ret < 0) else if (ret < 0)
snmp_log("sk_send err %d (gets2)", ret); snmp_log("sk_send err %d (gets2)", ret);
else else
snmp_log("sk_send was successful (gets2) !"); snmp_log("sk_send was successful (gets2) !");
*/
p->partial_response = NULL;
mb_free(context); mb_free(context);
mb_free(o_start); mb_free(o_start);
mb_free(o_end); mb_free(o_end);
/* number of bytes parsed form rx-buffer */ /* number of bytes parsed form rx-buffer */
return pkt - pkt_start; return pkt - pkt_start;
partial: partial:
snmp_log("partial packet"); snmp_log("partial packet");
/* The context octet is not added into response pdu */ /* The context octet is not added into response pdu */
/* need to tweak RX buffer packet size */
snmp_log("old rx-buffer size %u", h->payload);
(c.byte_ord) ? put_u32(&h->payload, pkt_size) : (h->payload = pkt_size);
snmp_log("new rx-buffer size %u", h->payload);
*skip = AGENTX_HEADER_SIZE; *skip = AGENTX_HEADER_SIZE;
goto send; p->partial_response = response_header;
return pkt - pkt_start;
wait: wait:
mb_free(context); mb_free(context);
@ -1321,7 +1327,7 @@ parse_gets_pdu(struct snmp_proto *p, byte *pkt_start, uint size, uint UNUSED *sk
snmp_log(" pasting size"); snmp_log(" pasting size");
response_err_ind(response_header, c.error, ind); response_err_ind(response_header, c.error, ind);
update_packet_size(p, &response_header->h, res, c.buffer); update_packet_size(p, res, c.buffer);
snmp_log("ttx %p c.buffer - res %lu", p->sock->ttx, c.buffer - res); snmp_log("ttx %p c.buffer - res %lu", p->sock->ttx, c.buffer - res);
snmp_log("c.buffer %p res %p", c.buffer, res); snmp_log("c.buffer %p res %p", c.buffer, res);
@ -1403,6 +1409,7 @@ snmp_rx(sock *sk, uint size)
struct snmp_proto *p = sk->data; struct snmp_proto *p = sk->data;
byte *pkt_start = sk->rbuf; byte *pkt_start = sk->rbuf;
byte *end = pkt_start + size; byte *end = pkt_start + size;
snmp_log("snmp_rx rbuf 0x%p rpos 0x%p", sk->rbuf, sk->rpos);
/* /*
* In some cases we want to save the header for future parsing, skip is number * In some cases we want to save the header for future parsing, skip is number
@ -1459,11 +1466,19 @@ snmp_ping(struct snmp_proto *p)
struct agentx_header *h = (struct agentx_header *) c.buffer; struct agentx_header *h = (struct agentx_header *) c.buffer;
ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
SNMP_BLANK_HEADER(h, AGENTX_PING_PDU); SNMP_BLANK_HEADER(h, AGENTX_PING_PDU);
p->packet_id++;
SNMP_SESSION(h, p); SNMP_SESSION(h, p);
/* sending only header => pkt - buf */ /* sending only header => pkt - buf */
snmp_log("sending ping packet ..."); snmp_log("sending ping packet ...");
snmp_send(p, &c); uint s = update_packet_size(p, sk->tpos, c.buffer);
int ret = sk_send(sk, s);
if (ret > 0)
snmp_log("sk_send OK!");
else if (ret == 0)
snmp_log("sk_send sleep");
else
snmp_log("sk_send error");
} }
/* /*
@ -1614,6 +1629,7 @@ search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_
/* fall through */ /* fall through */
default: default:
if (o_curr) mb_free(o_curr);
o_curr = snmp_oid_duplicate(p->p.pool, o_start); o_curr = snmp_oid_duplicate(p->p.pool, o_start);
*result = SNMP_SEARCH_END_OF_VIEW; *result = SNMP_SEARCH_END_OF_VIEW;
break; break;
@ -1667,7 +1683,7 @@ snmp_prefixize(struct snmp_proto *proto, const struct oid *oid, int byte_ord)
{ snmp_log("too small"); return NULL; } { snmp_log("too small"); return NULL; }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (LOAD(oid->ids[i], byte_ord) != prefix[i]) if (LOAD_U32(oid->ids[i], byte_ord) != prefix[i])
{ snmp_log("different prefix"); return NULL; } { snmp_log("different prefix"); return NULL; }
/* validity check here */ /* validity check here */
@ -1773,35 +1789,21 @@ void
snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c) snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c)
{ {
snmp_log("snmp_manage_tbuf()"); snmp_log("snmp_manage_tbuf()");
struct additional_buffer *t = TAIL(p->additional_buffers);
t->pos = c->buffer;
struct additional_buffer *b = mb_alloc(p->p.pool, sizeof(struct additional_buffer));
b->buf = b->pos = mb_alloc(p->p.pool, SNMP_TX_BUFFER_SIZE);
add_tail(&p->additional_buffers, &b->n);
c->buffer = b->buf;
c->size = SNMP_TX_BUFFER_SIZE;
}
int
snmp_send(struct snmp_proto *p, struct snmp_pdu_context *c)
{
sock *sk = p->sock; sock *sk = p->sock;
if (EMPTY_LIST(p->additional_buffers)) sk_set_tbsize(sk , sk->tbsize + 2048);
return sk_send(sk, c->buffer - sk->tpos); c->size += 2048;
return sk_send(sk, p->to_send);
} }
void void
snmp_tx(sock *sk) snmp_tx(sock *sk)
{ {
snmp_log("snmp_tx() hook"); snmp_log("snmp_tx() hook");
struct snmp_proto *p = sk->data; //struct snmp_proto *p = sk->data;
return;
#if 0
while (!EMPTY_LIST(p->additional_buffers)) while (!EMPTY_LIST(p->additional_buffers))
{ {
struct additional_buffer *b = HEAD(p->additional_buffers); struct additional_buffer *b = HEAD(p->additional_buffers);
@ -1816,6 +1818,7 @@ snmp_tx(sock *sk)
if (ret <= 0) if (ret <= 0)
return; return;
} }
#endif
} }

View File

@ -55,7 +55,6 @@ enum snmp_search_res {
#define AGENTX_ADMIN_START 2 #define AGENTX_ADMIN_START 2
#define AGENTX_PRIORITY 127 #define AGENTX_PRIORITY 127
#define MAX_STR 0xFFFFFFFF
#define SNMP_NATIVE #define SNMP_NATIVE
@ -76,7 +75,8 @@ enum snmp_search_res {
put_u8(&h->version, v); \ put_u8(&h->version, v); \
put_u8(&h->type, t); \ put_u8(&h->type, t); \
put_u8(&h->flags, f); \ put_u8(&h->flags, f); \
put_u8(&h->pad, 0) put_u8(&h->pad, 0); \
STORE_U32(h->payload, 0)
#ifdef SNMP_NATIVE #ifdef SNMP_NATIVE
#define SNMP_HEADER(h,t,f) SNMP_HEADER_(h, AGENTX_VERSION, t, f) #define SNMP_HEADER(h,t,f) SNMP_HEADER_(h, AGENTX_VERSION, t, f)
@ -92,8 +92,8 @@ enum snmp_search_res {
STORE_U32(h->transaction_id, p->transaction_id); \ STORE_U32(h->transaction_id, p->transaction_id); \
STORE_U32(h->packet_id, p->packet_id) STORE_U32(h->packet_id, p->packet_id)
#define LOAD(v, bo) ((bo) ? get_u32(&v) : (u32) (v)) #define LOAD_U32(v, bo) ((bo) ? get_u32(&v) : (u32) (v))
#define LOAD_16(v, bo) ((bo) ? get_u16(&v) : (u16) (v)) #define LOAD_U16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : *((u32 *) v)) #define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : *((u32 *) v))
#define LOAD_STR(proto, buf, str, length, byte_order) ({ \ #define LOAD_STR(proto, buf, str, length, byte_order) ({ \
@ -113,12 +113,6 @@ enum snmp_search_res {
#define SNMP_HAS_CONTEXT(hdr) \ #define SNMP_HAS_CONTEXT(hdr) \
hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT
#if 0
if (h->flags & AGENTX_NON_DEFAULT_CONTEXT) \
{ log(L_INFO "encountered non-default context"); \
LOAD_STR(p, b, s, l, h->flags & AGENTX_NETWORK_BYTE_ORDER); }
#endif
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \ #define SNMP_PUT_OID(buf, size, oid, byte_ord) \
({ \ ({ \
struct agentx_varbind *vb = (void *) buf; \ struct agentx_varbind *vb = (void *) buf; \
@ -196,11 +190,6 @@ struct agentx_bulk_state {
u16 repetition; u16 repetition;
}; };
//struct snmp_error {
// struct oid *oid;
// uint type;
//};
enum agentx_pdu { enum agentx_pdu {
AGENTX_OPEN_PDU = 1, AGENTX_OPEN_PDU = 1,
AGENTX_CLOSE_PDU = 2, AGENTX_CLOSE_PDU = 2,
@ -279,7 +268,7 @@ enum agentx_response_err {
struct agentx_context { struct agentx_context {
char *context; /* string name of this context */ char *context; /* string name of this context */
uint length; /* normal strlen() size */ uint length; /* normal strlen() size */
/* add buffered context hash? */ /* XXX add buffered context hash? */
}; };
struct snmp_pdu_context { struct snmp_pdu_context {
@ -298,16 +287,19 @@ struct agentx_alloc_context {
uint clen; /* length of context string */ uint clen; /* length of context string */
}; };
#if 0
struct additional_buffer { struct additional_buffer {
node n; node n;
byte *buf; /* pointer to buffer data */ byte *buf; /* pointer to buffer data */
byte *pos; /* position of first unused byte */ byte *pos; /* position of first unused byte */
}; };
#endif
int snmp_rx(sock *sk, uint size); int snmp_rx(sock *sk, uint size);
int snmp_rx_stop(sock *sk, uint size); int snmp_rx_stop(sock *sk, uint size);
//int snmp_is_active(int snmp_state);
void snmp_down(struct snmp_proto *p); void snmp_down(struct snmp_proto *p);
void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len); void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance);
void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len); void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len);
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c); void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu_context *c);