rfree(p->lp);
p->bgp_trie = NULL;
+ rfree(p->end_oids);
+ p->end_oids = NULL;
+
p->state = SNMP_DOWN;
}
p->lp = lp_new(p->pool);
p->mib_tree = mb_alloc(p->pool, sizeof(struct mib_tree));
p->bgp_trie = f_new_trie(p->lp, 0);
+ p->end_oids = lp_new(p->pool);
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, p->timeout, 0);
snmp_shutdown(struct proto *P)
{
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
- return snmp_set_state(p, SNMP_DOWN);
return snmp_reset(p);
}
struct object_lock *lock;
pool *pool; /* a shortcut to the procotol mem. pool */
linpool *lp; /* linpool for bgp_trie nodes */
+ linpool *end_oids;
enum snmp_proto_state state;
snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb)
{
ASSUME(vb != NULL && *vb != NULL);
- uint hdr_size = snmp_varbind_header_size(*vb->name);
+ uint hdr_size = snmp_varbind_header_size(&(*vb)->name);
(void) snmp_tbuf_reserve(c, hdr_size);
ASSERT(c->size >= hdr_size);
/*
* snmp_oid_from_buf - copy OID from RX buffer to dest in native byte order
- * @dst: destination to use
- * @src: OID to be copied from
+ * @dst: destination to use (native byte order)
+ * @src: OID to be copied from (packet byte order)
*/
void
snmp_oid_from_buf(struct oid *dst, const struct oid *src)
dst->ids[i] = LOAD_U32(src->ids[i]);
}
+/*
+ * snmp_oid_to_buf - copy OID to TX buffer with packet byte order
+ * @dst: destination to use (packet byte order)
+ * @src: OID to be copied from (native byte order)
+ */
+void
+snmp_oid_to_buf(struct oid *dst, const struct oid *src)
+{
+ STORE_U8(dst->n_subid, src->n_subid);
+ STORE_U8(dst->prefix, src->prefix);
+ STORE_U8(dst->include, (src->include) ? 1 : 0);
+ STORE_U8(dst->reserved, 0);
+
+ for (uint i = 0; i < src->n_subid; i++)
+ STORE_U32(dst->ids[i], src->ids[i]);
+}
+
/*
* snmp_oid_duplicate - duplicate an OID from memory pool
* @pool: pool to use
return sizeof(struct oid) + n_subid * sizeof(u32);
}
-/*
- * snmp_set_varbind_type - set VarBind's type field
- * @vb: Varbind inside TX buffer
- * @t: a valid type to be set
- *
- * This function assumes valid @t.
- */
-inline enum snmp_search_res
-snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t)
-{
- ASSUME(t != AGENTX_INVALID);
- STORE_U16(vb->type, t);
- STORE_U16(vb->reserved, 0);
-
- switch (t)
- {
- case AGENTX_END_OF_MIB_VIEW:
- return SNMP_SEARCH_END_OF_VIEW;
- case AGENTX_NO_SUCH_OBJECT:
- return SNMP_SEARCH_NO_OBJECT;
- case AGENTX_NO_SUCH_INSTANCE:
- return SNMP_SEARCH_NO_INSTANCE;
-
- /* valid varbind types */
- case AGENTX_INTEGER:
- case AGENTX_OCTET_STRING:
- case AGENTX_NULL:
- case AGENTX_OBJECT_ID:
- case AGENTX_IP_ADDRESS:
- case AGENTX_COUNTER_32:
- case AGENTX_GAUGE_32:
- case AGENTX_TIME_TICKS:
- case AGENTX_OPAQUE:
- case AGENTX_COUNTER_64:
- return SNMP_SEARCH_OK;
-
- default:
- die("invalid varbind type %d", (int) t);
- }
-}
-
static inline uint
snmp_get_octet_size(const struct agentx_octet_str *str)
{
*
*/
uint
-snmp_varbind_size_unsafe(const struct agentx_varbind *vb, int is_pkt_bo)
+snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
{
- ASSUME(snmp_test_varbind(vb));
-
- enum agentx_type type = (is_pkt_bo) ? LOAD_U16(vb->type) : vb->type;
- int value_size = agentx_type_size(type);
-
+ ASSUME(snmp_test_varbind_type(vb->type));
+ int value_size = agentx_type_size(vb->type);
uint vb_header = snmp_varbind_header_size(&vb->name);
if (value_size == 0)
if (value_size > 0)
return vb_header + value_size;
- switch (type)
+ switch (vb->type)
{
case AGENTX_OBJECT_ID:;
struct oid *oid = snmp_varbind_data(vb);
default:
/* Shouldn't happen */
- die("getting size of VarBind with unknown type (%u)", type);
+ die("getting size of VarBind with unknown type (%u)", vb->type);
return 0;
}
}
/**
* snmp_varbind_size - get size of in-buffer VarBind
- * @vb: VarBind to measure
+ * @vb: VarBind in cpu native byte order to measure
* @limit: upper limit of bytes that can be used
*
* This functions assumes valid VarBind type.
* Return 0 for Varbinds longer than limit, Varbind's size otherwise.
*/
-uint
+uint UNUSED
snmp_varbind_size(const struct agentx_varbind *vb, uint limit)
{
- //ASSUME(snmp_test_varbind(vb));
-
if (limit < sizeof(struct agentx_varbind))
return 0;
- enum agentx_type type = agentx_type_size(snmp_get_varbind_type(vb));
+ if (!snmp_test_varbind_type(vb->type))
+ return 0;
+
+ enum agentx_type type = vb->type;
int s = agentx_type_size(type);
- uint vb_header = snmp_varbind_header_size(vb);
+ uint vb_header = snmp_varbind_header_size(&vb->name);
if (limit < vb_header)
return 0;
else if (s > 0)
return 0;
+ uint sz;
switch (type)
{
case AGENTX_OBJECT_ID:;
struct oid *oid = snmp_varbind_data(vb);
- return vb_header + snmp_oid_size(oid);
+ /* snmp_oid_size works for both native and packet byte order */
+ sz = snmp_oid_size(oid);
+ if (limit < vb_header + sz)
+ return 0;
+ else
+ return vb_header + snmp_oid_size(oid);
case AGENTX_OCTET_STRING:
case AGENTX_IP_ADDRESS:
case AGENTX_OPAQUE:;
struct agentx_octet_str *os = snmp_varbind_data(vb);
- return vb_header + snmp_get_octet_size(os);
+ sz = snmp_get_octet_size(os);
+ if (limit < vb_header + sz)
+ return 0;
+ else
+ return vb_header + sz;
default:
/* This should not happen */
/*
* snmp_test_varbind - test validity of VarBind type
- * @type: Type of VarBind
+ * @type: Type of VarBind in cpu native byte order
*/
int
-snmp_test_varbind(u16 type)
+snmp_test_varbind_type(u16 type)
{
if (type == AGENTX_INTEGER ||
type == AGENTX_OCTET_STRING ||
return 0;
}
-/*
- * snmp_create_varbind - create a null-typed VarBind in buffer
- * @buf: buffer to use
- */
-struct agentx_varbind *
-snmp_create_varbind_null(byte *buf)
-{
- struct oid o = { 0 };
- struct agentx_varbind *vb = snmp_create_varbind(buf, &o);
- snmp_set_varbind_type(vb, AGENTX_NULL);
- return vb;
-}
-
-/*
- * snmp_create_varbind - initialize in-buffer non-typed VarBind
- * @buf: pointer to first unused buffer byte
- * @oid: OID to use as VarBind name
- */
-struct agentx_varbind *
-snmp_create_varbind(byte *buf, struct oid *oid)
-{
- struct agentx_varbind *vb = (void *) buf;
- snmp_oid_copy(&vb->name, oid);
- return vb;
-}
/**
* snmp_oid_ip4_index - check IPv4 address validity in oid
(int) right_subids);
for (int i = 0; i < limit; i++)
{
- u32 left_id = left->ids[i + ARRAY_SIZE(snmp_internet + 1)];
+ u32 left_id = left->ids[i + ARRAY_SIZE(snmp_internet) + 1];
u32 right_id = right->ids[i];
if (left_id < right_id)
return -1;
{
ASSUME(agentx_type_size(type) == 4); /* type as 4B representation */
- snmp_set_varbind_type(vb, type);
+ vb->type = type;
u32 *data = snmp_varbind_data(vb);
STORE_PTR(data, val);
data++;
inline void
snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr)
{
- snmp_set_varbind_type(c->sr_vb_start, AGENTX_IP_ADDRESS);
+ c->sr_vb_start->type = AGENTX_IP_ADDRESS;
c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr);
}
if (size < snmp_str_size_from_len(len))
return NULL;
- snmp_set_varbind_type(c->sr_vb_start, AGENTX_OCTET_STRING);
+ c->sr_vb_start = AGENTX_OCTET_STRING;
return snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
}
#endif
void
snmp_varbind_nstr(struct snmp_pdu *c, const char *str, uint len)
{
- snmp_set_varbind_type(c->sr_vb_start, AGENTX_OCTET_STRING);
+ c->sr_vb_start->type = AGENTX_OCTET_STRING;
c->buffer = snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
}
void
snmp_varbind_oid(struct snmp_pdu *c, const struct oid *oid_val)
{
- snmp_set_varbind_type(c->sr_vb_start, AGENTX_OBJECT_IDENTIFIER);
+ c->sr_vb_start->type = AGENTX_OBJECT_ID;
snmp_oid_to_buf(snmp_varbind_data(c->sr_vb_start), oid_val);
}
{
ASSERT(left && right && out);
- out->include, 0;
+ out->include = 0;
out->reserved = 0;
out->prefix = 0;
{
mib_tree_walk_init(walk, tree);
- snmp_vb_to_tx(c, oid);
-
mib_node_u *node = mib_tree_find(tree, walk, &c->sr_vb_start->name);
// TODO hide me in mib_tree code
{
struct agentx_varbind *vb = c->sr_vb_start;
+ enum agentx_search_res res;
+ if (snmp_oid_compare(&c->sr_vb_start->name, c->sr_o_end) >= 0)
+ {
+ res = AGENTX_END_OF_MIB_VIEW;
+ vb->type = snmp_search_res_to_type(res);
+ return res;
+ }
+
if (!leaf)
return SNMP_SEARCH_NO_OBJECT;
uint size = 0;
+ enum agentx_type type = AGENTX_NULL;
if (leaf->size >= 0)
{
if (leaf->type == AGENTX_OCTET_STRING || leaf->type == AGENTX_OPAQUE ||
leaf->type == AGENTX_OBJECT_ID)
{
- snmp_set_varbind_type(vb, leaf->type);
+ type = leaf->type;
size = leaf->size;
}
else if (leaf->type != AGENTX_INVALID)
{
- snmp_set_varbind_type(vb, leaf->type);
+ type = leaf->type;
size = agentx_type_size(leaf->type);
}
else
}
(void) snmp_tbuf_reserve(c, size);
+ vb->type = (u16) type;
- enum snmp_search_res res = leaf->filler(walk, c);
+ res = leaf->filler(walk, c);
vb = c->sr_vb_start;
if (res != SNMP_SEARCH_OK)
- snmp_set_varbind_type(vb, snmp_search_res_to_type(res));
+ vb->type = snmp_search_res_to_type(res);
- u16 type = vb->type;
- ASSUME(type == leaf->type || type == AGENTX_END_OF_MIB_VIEW || type == AGENTX_NO_SUCH_OBJECT ||
- type == AGENTX_NO_SUCH_INSTANCE);
+ ASSUME(vb->type == leaf->type || vb->type == AGENTX_END_OF_MIB_VIEW ||
+ vb->type == AGENTX_NO_SUCH_OBJECT || vb->type == AGENTX_NO_SUCH_INSTANCE);
return res;
}
/*
* AgentX - Variable Binding (VarBind) type utils
*/
-enum snmp_search_res snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t);
int agentx_type_size(enum agentx_type t);
/* type Octet String */
uint snmp_varbind_size(const struct agentx_varbind *vb, uint limit);
uint snmp_varbind_size_unsafe(const struct agentx_varbind *vb);
size_t snmp_varbind_size_from_len(uint n_subid, enum agentx_type t, uint len);
-int snmp_test_varbind(const struct agentx_varbind *vb);
+int snmp_test_varbind_type(u16 type);
void *snmp_varbind_data(const struct agentx_varbind *vb);
struct oid *snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len);
void snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb);
*/
/* Functions filling buffer a typed value */
-struct agentx_varbind *snmp_create_varbind(byte *buf, struct oid *oid);
-struct agentx_varbind *snmp_create_varbind_null(byte *buf);
void snmp_varbind_int(struct snmp_pdu *c, u32 val);
void snmp_varbind_counter32(struct snmp_pdu *c, u32 val);
void snmp_varbind_gauge32(struct snmp_pdu *c, s64 time);
static void do_response(struct snmp_proto *p, byte *buf);
static uint parse_gets_pdu(struct snmp_proto *p, byte *pkt);
static struct agentx_response *prepare_response(struct snmp_proto *p, struct snmp_pdu *c);
-static void response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_response_errs err, u16 ind);
+static void response_err_ind(struct agentx_response *res, enum agentx_response_errs err, u16 ind);
static uint update_packet_size(struct agentx_header *start, byte *end);
/* standard SNMP internet prefix (.1.3.6.1) */
{
STORE_U8(h->version, AGENTX_VERSION);
STORE_U8(h->type, type);
- STORE_U8(h->flags, flags | SNMP_ORDER);
+ STORE_U8(h->flags, flags | SNMP_BYTE_ORDER);
STORE_U8(h->reserved, 0);
STORE_U32(h->payload, 0);
}
ASSUME(c.size >= sizeof(struct agentx_response));
struct agentx_response *res = prepare_response(p, &c);
- response_err_ind(p, res, error, index);
+ response_err_ind(res, error, index);
sk_send(sk, sizeof(struct agentx_response));
}
struct agentx_varbind *trap_vb = (struct agentx_varbind *) c.buffer;
snmp_oid_to_buf(&trap_vb->name, trap_0);
/* snmp_oid_size() works for both byte orders same */
- snmp_varbind_oid(trap_vb, oid);
+ c.sr_vb_start = trap_vb;
+ snmp_varbind_oid(&c, oid);
ADVANCE(c.buffer, c.size, snmp_varbind_size_unsafe(trap_vb));
- STORE_U16(trap_vb, trap_vb);
+ STORE_U16(trap_vb->type, trap_vb->type);
/* We do not need to call the snmp_varbind_leave() because we used the packet
* byte order in the first place.
*/
if (c.error != AGENTX_RES_NO_ERROR)
{
- response_err_ind(p, res, c.error, c.index + 1);
+ response_err_ind(res, c.error, c.index + 1);
snmp_reset(p);
}
else if (all_possible)
{
/* All values in the agentx-TestSet-PDU are OK, realy to commit them */
- response_err_ind(p, res, AGENTX_RES_NO_ERROR, 0);
+ response_err_ind(res, AGENTX_RES_NO_ERROR, 0);
}
else
{
// Currently the only reachable branch
//TRACE(D_PACKETS, "SNMP SET action failed (not writable)");
/* This is a recoverable error, we do not need to reset the connection */
- response_err_ind(p, res, AGENTX_RES_NOT_WRITABLE, c.index + 1);
+ response_err_ind(res, AGENTX_RES_NOT_WRITABLE, c.index + 1);
}
sk_send(sk, s);
c.error = err;
TRACE(D_PACKETS, "SNMP received set PDU with error %u", c.error);
- response_err_ind(p, r, c.error, 0);
+ response_err_ind(r, c.error, 0);
sk_send(p->sock, AGENTX_HEADER_SIZE);
/* Reset the connection on unrecoverable error */
if (pkt_size != 0)
{
return AGENTX_HEADER_SIZE;
- TRACE(D_PACKET, "SNMP received malformed agentx-CleanupSet-PDU");
+ TRACE(D_PACKETS, "SNMP received malformed agentx-CleanupSet-PDU");
snmp_reset(p);
return 0;
}
return 0;
struct agentx_header *h = (struct agentx_header *) pkt;
- if (h->flags & AGENTX_NETWORK_BYTE_ORDER)
+ if (h->flags & AGENTX_NETWORK_BYTE_ORDER != SNMP_BYTE_ORDER)
{
TRACE(D_PACKETS, "SNMP received PDU with unexpected byte order");
- snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
+ if (h->type != AGENTX_RESPONSE_PDU)
+ snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
snmp_reset(p);
return 0;
}
if (pkt_size > SNMP_PKT_SIZE_MAX)
{
TRACE(D_PACKETS, "SNMP received PDU is too long");
- snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
+ if (h->type != AGENTX_RESPONSE_PDU)
+ snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0);
snmp_reset(p);
return 0;
}
case AGENTX_RES_PROCESSING_ERR:
default:
TRACE(D_PACKETS, "SNMP agentx-Response-PDU with unexepected error %u", r->error);
- //snmp_stop(p);
snmp_reset(p);
break;
}
dest->reserved = 0;
/* The LOAD_U32() and STORE_U32() cancel out */
- for (i = 0; i < dest->n_subid; i++)
+ for (u8 i = 0; i < dest->n_subid; i++)
dest->ids[i] = LOAD_U32(src->ids[i + 5]);
-
- return dest;
}
/*
* is @oid. Because we want to simplify code dealing with OIDs, the byte order
* of the name is optionally swapped to match cpu native byte order.
*/
-void
+struct agentx_varbind *
snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid)
{
uint vb_hdr_size = snmp_varbind_header_size(oid);
struct agentx_varbind *vb = (struct agentx_varbind *) c->buffer;
ADVANCE(c->buffer, c->size, sizeof(struct agentx_varbind) - sizeof(struct oid));
/* Move the c->buffer so that is points at &vb->name */
- snmp_set_varbind_type(vb, AGENTX_NULL);
+ vb->type = AGENTX_NULL;
if (snmp_oid_is_prefixable(oid) && !snmp_oid_is_prefixed(oid))
{
ADVANCE(c->buffer, c->size, snmp_oid_size_from_len(subids));
snmp_oid_prefixize_unsafe(&vb->name, oid);
- c->sr_vb_start = vb;
- return;
+ return vb;
}
ADVANCE(c->buffer, c->size, snmp_oid_size(oid));
snmp_oid_from_buf(&vb->name, oid);
- c->sr_vb_start = vb;
+ return vb;
}
/*
/*
* response_err_ind - update response error and index
- * @p: SNMP protocol instance
* @res: response PDU header
* @err: error status
* @ind: index of error, ignored for noAgentXError
* error is not noError, also set the corrent response PDU payload size.
*/
static inline void
-response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_response_errs err, u16 ind)
+response_err_ind(struct agentx_response *res, enum agentx_response_errs err, u16 ind)
{
STORE_U16(res->error, (u16) err);
// TODO deal with auto-incrementing of snmp_pdu context c.ind
snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk)
{
struct mib_leaf *leaf;
- leaf = snmp_walk_init(p->mib_tree, walk, o_start, c);
+ leaf = snmp_walk_init(p->mib_tree, walk, &c->sr_vb_start->name, c);
enum snmp_search_res res;
res = snmp_walk_fill(leaf, walk, c);
if (res != SNMP_SEARCH_OK)
- snmp_set_varbind_type(c->sr_vb_start, snmp_search_res_to_type(res));
+ c->sr_vb_start->type = snmp_search_res_to_type(res);
}
/* agentx-GetNext-PDU */
int
snmp_get_next_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk)
{
- (void) snmp_walk_init(p->mib_tree, walk, o_start, c);
+ (void) snmp_walk_init(p->mib_tree, walk, &c->sr_vb_start->name, c);
struct mib_leaf *leaf = snmp_walk_next(p->mib_tree, walk, c);
enum snmp_search_res res;
res = snmp_walk_fill(leaf, walk, c);
if (res != SNMP_SEARCH_OK)
- snmp_set_varbind_type(c->sr_vb_start, AGENTX_END_OF_MIB_VIEW);
+ c->sr_vb_start->type = AGENTX_END_OF_MIB_VIEW;
return res == SNMP_SEARCH_OK;
}
bulk->has_any |= snmp_get_next_pdu(p, c, o_start, walk);
}
-static inline const struct oid *
+int
snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c)
{
byte *pkt = *pkt_ptr;
uint pkt_size = *pkt_sz;
uint sz;
- const struct oid *start = (const struct oid *) pkt;
-
- if ((sz = snmp_oid_size(start)) > pkt_size)
+ /* in packet byte order */
+ const struct oid *start_buf = (const struct oid *) pkt;
+ if ((sz = snmp_oid_size(start_buf)) > pkt_size ||
+ LOAD_U8(start_buf->n_subid) >= OID_MAX_LEN)
{
c->error = AGENTX_RES_PARSE_ERROR;
*pkt_ptr = pkt;
*pkt_sz = pkt_size;
- return NULL;
+ return 0;
}
ADVANCE(pkt, pkt_size, sz);
- const struct oid *end = (const struct oid *) pkt;
- if ((sz = snmp_oid_size(end)) > pkt_size)
+ /* in packet byte order */
+ const struct oid *end_buf = (const struct oid *) pkt;
+ if ((sz = snmp_oid_size(end_buf)) > pkt_size ||
+ LOAD_U8(end_buf->n_subid) >= OID_MAX_LEN)
{
c->error = AGENTX_RES_PARSE_ERROR;
*pkt_ptr = pkt;
*pkt_sz = pkt_size;
- return NULL;
+ return 0;
}
+ /* in cpu native byte order */
+ struct agentx_varbind *start_vb = snmp_vb_to_tx(c, start_buf);
+
+ /* in cpu native byte order */
+ struct oid *end_oid = tmp_alloc(sz);
+ snmp_oid_from_buf(end_oid, end_buf);
+
ADVANCE(pkt, pkt_size, sz);
- // TODO: this does not work
- if (!snmp_is_oid_empty(end) &&
- snmp_oid_compare(start, end) > 0)
+ if (!snmp_is_oid_empty(end_oid) &&
+ snmp_oid_compare(&start_vb->name, end_oid) > 0)
{
c->error = AGENTX_RES_GEN_ERROR;
*pkt_ptr = pkt;
*pkt_sz = pkt_size;
- return NULL;
+ return 0;
}
- ASSERT(start != NULL);
- ASSERT(end != NULL);
+ ASSERT(start_vb != NULL);
+ ASSERT(end_oid != NULL);
- c->sr_o_end = end;
+ c->sr_vb_start = start_vb;
+ c->sr_o_end = end_oid;
*pkt_ptr = pkt;
*pkt_sz = pkt_size;
- return start;
+ return 1; /* ok */
}
/*
{
lp_restore(tmp_linpool, &tmps);
- const struct oid *start_rx;
- if (!(start_rx = snmp_load_oids(&pkt, &pkt_size, &c)))
+ if (!snmp_load_oids(&pkt, &pkt_size, &c))
{
snmp_simple_response(p, c.error,
(c.index > UINT16_MAX) ? UINT16_MAX : c.index);
snmp_reset(p);
- return pkt_size + AGENTX_HEADER_SIZE;
+ return 0;
}
switch (h->type)
die("implementation failure");
}
+ snmp_varbind_leave(c.sr_vb_start);
+
c.sr_vb_start = NULL;
c.sr_o_end = NULL;
#endif
/* We update the error, index pair on the beginning of the packet. */
- response_err_ind(p, response_header, c.error, c.index + 1);
+ response_err_ind(response_header, c.error, c.index + 1);
uint s = update_packet_size(&response_header->h, c.buffer);
/* We send the message in TX buffer. */
| AGENTX_NETWORK_BYTE_ORDER)
// TODO - make me compile time option
-#define SNMP_NATIVE
+#define SNMP_NETWORK_BYTE_ORDER
#if !(defined(SNMP_NATIVE) || defined(SNMP_NETWORK_BYTE_ORDER))
# error "SNMP: currently support only native byte order or network byte order."
#endif
#if (defined(SNMP_NATIVE) && defined(CPU_BIG_ENDIAN)) || defined(SNMP_NETWORK_BYTE_ORDER)
-#define SNMP_ORDER AGENTX_NETWORK_BYTE_ORDER
+#define SNMP_BYTE_ORDER AGENTX_NETWORK_BYTE_ORDER
#else
-#define SNMP_ORDER 0
+#define SNMP_BYTE_ORDER 0
#endif
/* We recommend using STORE_U32 over VALUE_U32 when possible */
p->state == SNMP_CONN;
}
-void snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid);
+struct agentx_varbind *snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid);
u8 snmp_get_mib_class(const struct oid *oid);
void snmp_register_mibs(struct snmp_proto *p);