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

Merge branch 'vv-test' into proto-snmp

This commit is contained in:
Vojtech Vilimek 2023-10-19 16:32:38 +02:00
commit 3b87af96f3
6 changed files with 369 additions and 121 deletions

View File

@ -1302,3 +1302,12 @@ snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb)); ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb));
} }
#if 0
int
snmp_bgp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, void *tr, struct oid *oid, uint pkt_size)
{
// TODO: check the type of varbind vb and it's value correctness, don't overflow the pkt_size
return 0;
}
#endif

View File

@ -46,6 +46,7 @@ u8 snmp_bgp_getnext_valid(u8 state);
struct oid *snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid); struct oid *snmp_bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid);
enum snmp_search_res snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid); enum snmp_search_res snmp_bgp_search2(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint contid);
void snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, struct snmp_pdu *c); void snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb, struct snmp_pdu *c);
//int snmp_bgp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, void* tr, struct oid *oid, uint pkt_type);
void snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp); void snmp_bgp_notify_established(struct snmp_proto *p, struct bgp_proto *bgp);
void snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp); void snmp_bgp_notify_backward_trans(struct snmp_proto *p, struct bgp_proto *bgp);

View File

@ -134,8 +134,6 @@ snmp_cleanup(struct snmp_proto *p)
rfree(p->lock); rfree(p->lock);
p->lock = NULL; p->lock = NULL;
p->partial_response = NULL;
struct snmp_register *r, *r2; struct snmp_register *r, *r2;
WALK_LIST_DELSAFE(r, r2, p->register_queue) WALK_LIST_DELSAFE(r, r2, p->register_queue)
{ {
@ -254,13 +252,9 @@ snmp_start_locked(struct object_lock *lock)
} }
snmp_log("opening socket"); snmp_log("opening socket");
/* Try opening the socket, schedule a retry on fail */
if (sk_open(s) < 0) if (sk_open(s) < 0)
{ tm_set(p->startup_timer, current_time() + p->timeout S);
// TODO rather set the startup timer, then reset whole SNMP proto
log(L_ERR "Cannot open listening socket");
snmp_down(p);
// TODO go back to SNMP_INIT and try reconnecting after timeout
}
} }
/* this function is internal and shouldn't be used outside the snmp module */ /* this function is internal and shouldn't be used outside the snmp module */
@ -309,10 +303,7 @@ static void
snmp_stop_timeout(timer *t) snmp_stop_timeout(timer *t)
{ {
snmp_log("stop timer triggered"); snmp_log("stop timer triggered");
snmp_down(t->data);
struct snmp_proto *p = t->data;
snmp_down(p);
} }
static void static void
@ -338,7 +329,6 @@ snmp_start(struct proto *P)
p->to_send = 0; p->to_send = 0;
p->errs = 0; p->errs = 0;
p->partial_response = NULL;
p->startup_timer = tm_new_init(p->pool, snmp_startup_timeout, p, 0, 0); p->startup_timer = tm_new_init(p->pool, snmp_startup_timeout, p, 0, 0);
p->ping_timer = tm_new_init(p->pool, snmp_ping_timeout, p, 0, 0); p->ping_timer = tm_new_init(p->pool, snmp_ping_timeout, p, 0, 0);
@ -366,7 +356,6 @@ snmp_start(struct proto *P)
HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, defaultc); HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, defaultc);
p->context_id_map[0] = defaultc; p->context_id_map[0] = defaultc;
p->bgp_trie = NULL;
struct snmp_bond *b; struct snmp_bond *b;
WALK_LIST(b, cf->bgp_entries) WALK_LIST(b, cf->bgp_entries)

View File

@ -161,12 +161,6 @@ struct snmp_proto {
uint to_send; uint to_send;
uint errs; uint errs;
/*
* 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

@ -38,7 +38,7 @@ static struct oid *search_mib(struct snmp_proto *p, const struct oid *o_start, c
u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET }; u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET };
static const char * const snmp_errs[] = { static const char * const snmp_errs[] UNUSED = {
#define SNMP_ERR_SHIFT 256 #define SNMP_ERR_SHIFT 256
[AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed", [AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed",
[AGENTX_RES_NOT_OPEN - SNMP_ERR_SHIFT] = "Not open", [AGENTX_RES_NOT_OPEN - SNMP_ERR_SHIFT] = "Not open",
@ -55,7 +55,7 @@ static const char * const snmp_errs[] = {
[AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error", [AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
}; };
static const char * const snmp_pkt_type[] = { static const char * const snmp_pkt_type[] UNUSED = {
[AGENTX_OPEN_PDU] = "Open-PDU", [AGENTX_OPEN_PDU] = "Open-PDU",
[AGENTX_CLOSE_PDU] = "Close-PDU", [AGENTX_CLOSE_PDU] = "Close-PDU",
[AGENTX_REGISTER_PDU] = "Register-PDU", [AGENTX_REGISTER_PDU] = "Register-PDU",
@ -108,13 +108,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
c.buffer = snmp_put_str(c.buffer, cf->description); c.buffer = snmp_put_str(c.buffer, cf->description);
uint s = update_packet_size(p, buf, c.buffer); uint s = update_packet_size(p, buf, c.buffer);
int ret = sk_send(sk, s); 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");
#undef TIMEOUT_SIZE #undef TIMEOUT_SIZE
} }
@ -184,13 +178,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
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->tbuf, c.buffer);
int ret = sk_send(sk, s); 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");
#undef TRAP0_HEADER_SIZE #undef TRAP0_HEADER_SIZE
#undef UPTIME_SIZE #undef UPTIME_SIZE
@ -208,7 +196,7 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
if (size > AGENTX_HEADER_SIZE + ) if (size > AGENTX_HEADER_SIZE + )
{ {
snmp_log("de_allocate_pdu()"); //snmp_log("de_allocate_pdu()");
struct agentx_header *h; struct agentx_header *h;
SNMP_CREATE(pkt, struct agentx_header, h); SNMP_CREATE(pkt, struct agentx_header, h);
@ -221,7 +209,7 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
} }
else else
snmp_log("de_allocate_pdu(): insufficient size"); {}//snmp_log("de_allocate_pdu(): insufficient size");
} }
*/ */
@ -289,13 +277,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8
uint s = update_packet_size(p, buf, c.buffer); 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]);
int ret = sk_send(sk, s); 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 */
@ -343,15 +325,62 @@ close_pdu(struct snmp_proto *p, u8 reason)
uint s = update_packet_size(p, 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)");
int ret = sk_send(sk, s); 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");
} }
static uint UNUSED
parse_close_pdu(struct snmp_proto UNUSED *p, byte UNUSED *req, uint UNUSED size)
{
/*
snmp_log("parse_close_pdu()");
// byte *pkt = req;
// sock *sk = p->sock;
if (size < sizeof(struct agentx_header))
{
snmp_log("p_close early return");
return 0;
}
// struct agentx_header *h = (void *) req;
ADVANCE(req, size, AGENTX_HEADER_SIZE);
//snmp_log("after header %p", req);
p->state = SNMP_ERR;
// or snmp_cleanup(); // ??!
proto_notify_state(&p->p, PS_DOWN);
*/
return 0;
}
/* MUCH better signature would be
static int snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, uint pkt_size);
*/
/* return 1 if the value could be set */
static int
snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, struct oid *oid, uint pkt_size)
{
/* Hard-coded no support for writing */
(void)p;(void)vb;(void)oid;(void)pkt_size;
return 0;
#if 0
// TODO better logic
if (!oid)
return 0;
switch (oid->ids[1])
{
case SNMP_BGP4_MIB:
return snmp_bgp_testset(p, vb, oid, pkt_size);
default:
return 0;
}
#endif
}
#if 0 #if 0
static void UNUSED static void UNUSED
addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr, addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
@ -394,13 +423,7 @@ addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
// make a note in the snmp_proto structure // make a note in the snmp_proto structure
//int ret = sk_send(sk, buf - sk->tbuf); //int ret = sk_send(sk, buf - sk->tbuf);
int ret = sk_send(sk, buf - sk->tpos); sk_send(sk, buf - sk->tpos);
if (ret == 0)
snmp_log("sk_send sleep");
else if (ret < 0)
snmp_log("sk_send err");
else
log(L_INFO, "sk_send ok !!");
} }
static void UNUSED static void UNUSED
@ -438,14 +461,7 @@ removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap, struct agentx_context
// update state in snmp_proto structure // update state in snmp_proto structure
//int ret = sk_send(sk, buf - sk->tbuf); sk_send(sk, buf - sk->tpos);
int ret = sk_send(sk, buf - sk->tpos);
if (ret == 0)
snmp_log("sk_send sleep");
else if (ret < 0)
snmp_log("sk_send err");
else
log(L_INFO, "sk_send ok !!");
} }
#endif #endif
@ -457,6 +473,194 @@ refresh_ids(struct snmp_proto *p, struct agentx_header *h)
p->packet_id = LOAD_U32(h->packet_id, byte_ord); p->packet_id = LOAD_U32(h->packet_id, byte_ord);
} }
static uint
parse_test_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
//snmp_log("parse_test_set");
const byte *pkt_start = pkt; /* start of packet in RX-buffer */
uint ind = 0; /* index of the error */
uint s; /* final packat size */
struct agentx_response *res; /* pointer to reponse in TX-buffer */
struct agentx_header *h = (void *) pkt;
ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
sock *sk = p->sock;
struct snmp_pdu c = SNMP_PDU_CONTEXT(sk);
byte *buf = c.buffer; /* start of packet in TX-buffer */
c.byte_ord = 0; /* use little-endian */
if (c.size < AGENTX_HEADER_SIZE)
{
snmp_manage_tbuf(p, &c);
// TODO renew all pointers
}
res = prepare_response(p, &c);
uint clen;
const char *context;
SNMP_LOAD_CONTEXT(h, pkt, context, clen);
if (size < clen)
return 0;
if (pkt_size < clen)
{
c.error = AGENTX_RES_PARSE_ERROR;
goto error;
}
ADVANCE(pkt, pkt_size, clen);
size -= clen;
//snmp_log("test_set: parsed header and context");
/* 0 if there is piece, that we cannot set */
int all_possible = 0;
/* the all_possible is currently hard-coded with no support for writing to mib
* variables, when implementing the mentioned support, change the initializer
* to 1
*/
#if 0
// TODO think about future value setting data structure
//struct agentx_transaction *tr = mb_alloc(...);
void *tr = mb_alloc(p->pool, 16);
struct agentx_varbind *vb;
uint sz;
while (size > 0 && all_possible)
{
vb = (void *) pkt;
sz = snmp_varbind_size(vb, 0);
if (sz > size)
/* wait for more data to arive */
return 0;
if (sz > pkt_size)
{
c.error = AGENTX_RES_PARSE_ERROR;
goto error;
}
/* Unknown VarBind type check */
if (!snmp_test_varbind(vb))
{
c.error = AGENTX_RES_PARSE_ERROR;
goto error;
}
ADVANCE(pkt, size, snmp_varbind_size(vb, 0));
// TODO remove the mb_alloc() in prefixize()
struct oid *work = snmp_prefixize(p, &vb->name, c.byte_ord);
(void)work;
all_possible = snmp_testset(p, vb, tr, work, pkt_size);
mb_free(work);
}
//snmp_log("test_set parsed all varbinds");
mb_free(tr);
#endif
error:
s = update_packet_size(p, buf, c.buffer);
if (c.error != AGENTX_RES_NO_ERROR)
response_err_ind(res, c.error, ind + 1);
else if (all_possible)
response_err_ind(res, AGENTX_RES_NO_ERROR, 0);
else
//response_err_ind(res, AGENTX_RES_RESOURCE_UNAVAILABLE, ind + 1);
response_err_ind(res, AGENTX_RES_NOT_WRITABLE, ind + 1);
//snmp_log("test_set sending response");
sk_send(sk, s);
return pkt - pkt_start;
}
static uint
parse_set_pdu(struct snmp_proto *p, byte *pkt, uint size, uint err)
{
const byte *pkt_start = pkt;
if (size < AGENTX_HEADER_SIZE)
return 0;
struct agentx_header *h = (void *) pkt;
ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
struct snmp_pdu c = SNMP_PDU_CONTEXT(p->sock);
if (c.size < sizeof(struct agentx_response))
{
snmp_manage_tbuf(p, &c);
// TODO renew all pointers
}
struct agentx_response *r = prepare_response(p, &c);
uint clen;
const char *context;
SNMP_LOAD_CONTEXT(h, pkt, context, clen);
if (size < snmp_str_size_from_len(clen))
return 0;
if (size < pkt_size)
{
c.error = AGENTX_RES_PARSE_ERROR;
goto error;
}
ADVANCE(pkt, size, snmp_str_size_from_len(clen));
// TODO: work with context
// TODO: free resource allocated by parse_test_set_pdu()
// TODO: do something meaningful
//mb_free(tr);
c.error = err;
error:;
response_err_ind(r, c.error, 0);
sk_send(p->sock, AGENTX_HEADER_SIZE);
return pkt - pkt_start;
}
/* agentx-CommitSet-PDU */
static uint
parse_commit_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
// don't forget to free resoures allocated by parse_test_set_pdu()
//mb_free(tr);
return parse_set_pdu(p, pkt, size, AGENTX_RES_COMMIT_FAILED);
}
/* agentx-UndoSet-PDU */
static uint
parse_undo_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
// don't forget to free resources allocated by parse_test_set_pdu()
//mb_free(tr);
return parse_set_pdu(p, pkt, size, AGENTX_RES_UNDO_FAILED);
}
/* agentx-CleanupSet-PDU */
static uint
parse_cleanup_set_pdu(struct snmp_proto *p, byte *pkt, uint size)
{
// don't forget to free resources allocated by parse_test_set_pdu()
//mb_free(tr);
if (size < AGENTX_HEADER_SIZE)
return 0;
struct agentx_header *h = (void *) pkt;
return LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
/* No agentx-Response-PDU is sent in response to agentx-CleanupSet-PDU */
}
/** /**
* parse_pkt - parse recieved response packet * parse_pkt - parse recieved response packet
* @p: * @p:
@ -474,7 +678,6 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
if (size < AGENTX_HEADER_SIZE) if (size < AGENTX_HEADER_SIZE)
return 0; return 0;
uint parsed_len = 0;
struct agentx_header *h = (void *) pkt; struct agentx_header *h = (void *) pkt;
//snmp_log("parse_pkt got type %s (%d)", snmp_pkt_type[h->type], h->type); //snmp_log("parse_pkt got type %s (%d)", snmp_pkt_type[h->type], h->type);
@ -484,33 +687,58 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
{ {
case AGENTX_RESPONSE_PDU: case AGENTX_RESPONSE_PDU:
//snmp_log("parse_pkt returning parse_response"); //snmp_log("parse_pkt returning parse_response");
parsed_len = parse_response(p, pkt, size); return parse_response(p, pkt, size);
break;
case AGENTX_GET_PDU: case AGENTX_GET_PDU:
case AGENTX_GET_NEXT_PDU: case AGENTX_GET_NEXT_PDU:
case AGENTX_GET_BULK_PDU: case AGENTX_GET_BULK_PDU:
refresh_ids(p, h); refresh_ids(p, h);
parsed_len = parse_gets2_pdu(p, pkt, size, skip); return parse_gets2_pdu(p, pkt, size, skip);
break;
/* during testing the connection should stay opened (we die if we screw up
* and get CLOSE_PDU in response)
case AGENTX_CLOSE_PDU: case AGENTX_CLOSE_PDU:
refresh_ids(p, h); refresh_ids(p, h);
parsed_len = parse_close_pdu(p, pkt, size); return parse_close_pdu(p, pkt, size);
break;
*/ case AGENTX_TEST_SET_PDU:
refresh_ids(p, h);
return parse_test_set_pdu(p, pkt, size);
case AGENTX_COMMIT_SET_PDU:
refresh_ids(p, h);
return parse_commit_set_pdu(p, pkt, size);
case AGENTX_UNDO_SET_PDU:
refresh_ids(p, h);
return parse_undo_set_pdu(p, pkt, size);
case AGENTX_CLEANUP_SET_PDU:
refresh_ids(p, h);
return parse_cleanup_set_pdu(p, pkt, size);
default: default:
/* drop the packet with unknown type silently */ /* drop the packet with unknown type silently */
//snmp_log("unknown packet type %u", h->type); //snmp_log("unknown packet type %u", h->type);
return 0; return 0;
} }
}
//snmp_log("parse_pkt returning parsed length"); static void
return parsed_len; snmp_register_ok(struct snmp_proto *p, struct agentx_response *r, uint size, u8 type)
{
(void)p;(void)r;(void)size;(void)type;
}
static void
snmp_register_failed(struct snmp_proto *p, struct agentx_response *r, uint size, u8 type)
{
(void)p;(void)r;(void)size;(void)type;
}
static void
unsupported_context(struct snmp_proto *p, struct agentx_response *r, uint size)
{
(void)p;(void)r;(void)size;
// TODO unsupported_context
} }
static uint static uint
@ -543,13 +771,58 @@ parse_response(struct snmp_proto *p, byte *res, uint size)
*/ */
//snmp_log(" pkt size %u", h->payload); //snmp_log(" pkt size %u", h->payload);
//snmp_log(" pkt size %u", h->payload); switch (r->error)
{
case AGENTX_RES_NO_ERROR:
do_response(p, res, size);
break;
if (r->error == AGENTX_RES_NO_ERROR) case AGENTX_RES_NOT_OPEN:
do_response(p, res, size); if (p->state == SNMP_LOCKED || p->state == SNMP_INIT)
else snmp_startup(p);
/* erronous packet should be dropped quietly */ else
{}//snmp_log("an error occured '%s'", snmp_errs[get_u16(&r->error) - SNMP_ERR_SHIFT]); snmp_connected(p->sock);
break;
case AGENTX_RES_OPEN_FAILED:
if (p->state == SNMP_LOCKED || p->state == SNMP_INIT)
{
ASSUME(p->startup_timer);
p->startup_timer->hook = snmp_startup_timeout;
// TODO: better timeout
tm_set(p->startup_timer, current_time() + p->timeout S);
}
else
{
ASSUME(p->startup_timer);
p->startup_timer->hook = snmp_reconnect;
// TODO: better timeout
tm_set(p->startup_timer, current_time() + p->timeout S);
}
break;
/* Registration errors */
case AGENTX_RES_DUPLICATE_REGISTER:
case AGENTX_RES_REQUEST_DENIED:
snmp_register_failed(p, r, size, h->type);
break;
case AGENTX_RES_UNSUPPORTED_CONTEXT:
unsupported_context(p, r, size);
break;
/* We are trying to unregister a MIB, the unknownRegistration has same
* effect as success */
case AGENTX_RES_UNKNOWN_REGISTER:
case AGENTX_RES_UNKNOWN_AGENT_CAPS:
case AGENTX_RES_PARSE_ERROR:
case AGENTX_RES_PROCESSING_ERR:
default:
/* erronous packet should be dropped quietly */
// TODO correct error?
snmp_log("recieved response with error '%s'", snmp_errs[get_u16(&r->error) - SNMP_ERR_SHIFT]);
break;
}
return pkt_size + AGENTX_HEADER_SIZE; return pkt_size + AGENTX_HEADER_SIZE;
} }
@ -878,7 +1151,7 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
}; };
} }
if (!p->partial_response && c.size < sizeof(struct agentx_response)) if (c.size < sizeof(struct agentx_response))
{ {
snmp_manage_tbuf(p, &c); snmp_manage_tbuf(p, &c);
// TODO renew pkt, pkt_start pointers context clen // TODO renew pkt, pkt_start pointers context clen
@ -1024,17 +1297,9 @@ send:;
//snmp_log("sending response to Get-PDU, GetNext-PDU or GetBulk-PDU request (size %u)...", s); //snmp_log("sending response to Get-PDU, GetNext-PDU or GetBulk-PDU request (size %u)...", s);
/* We send the message in TX-buffer. */ /* We send the message in TX-buffer. */
int ret = sk_send(sk, s); 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");
// TODO think through the error state // TODO think through the error state
p->partial_response = NULL;
mb_free(o_start); mb_free(o_start);
mb_free(o_end); mb_free(o_end);
@ -1051,7 +1316,6 @@ partial:
(c.byte_ord) ? put_u32(&h->payload, pkt_size) : (h->payload = pkt_size); (c.byte_ord) ? put_u32(&h->payload, pkt_size) : (h->payload = pkt_size);
//snmp_log("new rx-buffer size %u", h->payload); //snmp_log("new rx-buffer size %u", h->payload);
*skip = AGENTX_HEADER_SIZE; *skip = AGENTX_HEADER_SIZE;
p->partial_response = response_header;
/* number of bytes parsed from RX-buffer */ /* number of bytes parsed from RX-buffer */
return pkt - pkt_start; return pkt - pkt_start;
@ -1176,13 +1440,7 @@ snmp_ping(struct snmp_proto *p)
/* sending only header -> pkt - buf */ /* sending only header -> pkt - buf */
uint s = update_packet_size(p, sk->tpos, c.buffer); uint s = update_packet_size(p, sk->tpos, c.buffer);
int ret = sk_send(sk, s); 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");
} }
static inline int static inline int
@ -1396,24 +1654,19 @@ prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
{ {
//snmp_log("prepare_response()"); //snmp_log("prepare_response()");
if (!p->partial_response) struct agentx_response *r = (void *) c->buffer;
{ struct agentx_header *h = &r->h;
struct agentx_response *r = (void *) c->buffer;
struct agentx_header *h = &r->h;
SNMP_BLANK_HEADER(h, AGENTX_RESPONSE_PDU); SNMP_BLANK_HEADER(h, AGENTX_RESPONSE_PDU);
SNMP_SESSION(h, p); SNMP_SESSION(h, p);
/* protocol doesn't care about subagent upTime */ /* protocol doesn't care about subagent upTime */
STORE_U32(r->uptime, 0); STORE_U32(r->uptime, 0);
STORE_U16(r->error, AGENTX_RES_NO_ERROR); STORE_U16(r->error, AGENTX_RES_NO_ERROR);
STORE_U16(r->index, 0); STORE_U16(r->index, 0);
ADVANCE(c->buffer, c->size, sizeof(struct agentx_response)); ADVANCE(c->buffer, c->size, sizeof(struct agentx_response));
return r; return r;
}
return p->partial_response;
} }

View File

@ -122,7 +122,7 @@ enum snmp_search_res {
buf += 4 + snmp_str_size_from_len(length); }) buf += 4 + snmp_str_size_from_len(length); })
#define SNMP_LOAD_CONTEXT(hdr, buf, cont, cont_len) ({ \ #define SNMP_LOAD_CONTEXT(hdr, buf, cont, cont_len) ({ \
if ((hdr)->flags & AGENTX_NON_DEFAULT_CONTEXT) \ if (cont = NULL, cont_len = 0, (hdr)->flags & AGENTX_NON_DEFAULT_CONTEXT) \
LOAD_STR((buf), (cont), (cont_len), \ LOAD_STR((buf), (cont), (cont_len), \
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER); }) (hdr)->flags & AGENTX_NETWORK_BYTE_ORDER); })
@ -289,7 +289,9 @@ enum agentx_response_err {
AGENTX_RES_NO_CREATION = 11, AGENTX_RES_NO_CREATION = 11,
AGENTX_RES_INCONSISTENT_VALUE = 12, AGENTX_RES_INCONSISTENT_VALUE = 12,
AGENTX_RES_RESOURCE_UNAVAILABLE = 13, AGENTX_RES_RESOURCE_UNAVAILABLE = 13,
AGENTX_RES_NOT_WRITEABLE = 17, AGENTX_RES_COMMIT_FAILED = 14,
AGENTX_RES_UNDO_FAILED = 15,
AGENTX_RES_NOT_WRITABLE = 17,
AGENTX_RES_INCONSISTENT_NAME = 18, AGENTX_RES_INCONSISTENT_NAME = 18,
/* end of TEST_SET_PDU resonse errs (master -> subagent) */ /* end of TEST_SET_PDU resonse errs (master -> subagent) */
AGENTX_RES_OPEN_FAILED = 256, AGENTX_RES_OPEN_FAILED = 256,