0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

SNMP: Remove support for context

This commit is contained in:
Vojtech Vilimek 2023-10-25 16:23:39 +02:00
parent aef20fe1a7
commit fd243b6e9e
8 changed files with 34 additions and 312 deletions

View File

@ -186,36 +186,6 @@ snmp_bgp_register(struct snmp_proto *p)
/* snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid) */
snmp_register(p, oid, 1, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT);
}
#if 0
u32 bgp_peer_entry[] = { 1, 15, 3, 1, 1 };
u32 bound = 24;
HASH_WALK(p->bgp_hash, next, peer)
{
if (peer->flags & SNMP_BGP_P_REGISTERED)
continue;
struct bgp_proto *bgp = (struct bgp_proto *) peer->config->c.proto;
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
struct oid *oid = mb_alloc(p->pool, snmp_oid_sizeof(9));
STORE_U8(oid->n_subid, 9);
STORE_U8(oid->prefix, SNMP_MGMT);
for (uint i = 0; i < ARRAY_SIZE(bgp_peer_entry); i++)
STORE_U32(oid->ids[i], bgp_peer_entry[i]);
ip4_to_oid(oid, ipa_to_ip4(bgp->remote_ip));
/* index is position of x in .1.3.6.1.2.15.3.1.x (1-based) */
snmp_register(p, oid, bound, 9, SNMP_REGISTER_INSTANCE, peer->context_id);
registering->oid = oid;
add_tail(&p->register_queue, &registering->n);
p->register_to_ack++;
}
HASH_WALK_END;
#endif
}
static int
@ -959,7 +929,6 @@ bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
{
struct oid *oid = &vb->name;
uint size = c->size - snmp_varbind_header_size(vb);
uint UNUSED contid = c->context;
byte *pkt;
ip_addr addr;
@ -1219,7 +1188,7 @@ snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind *vb,
byte *pkt;
if (is_static(state))
{
pkt = bgp_fill_static(p, vb, c->buffer, c->size, c->context, c->byte_ord, state);
pkt = bgp_fill_static(p, vb, c->buffer, c->size, 0, c->byte_ord, state);
ADVANCE(c->buffer, c->size, pkt - c->buffer);
return;
}

View File

@ -16,8 +16,6 @@ CF_DEFINES
#define SNMP_CFG ((struct snmp_config *) this_proto)
struct snmp_bond *this_bond = NULL;
CF_DECLS
CF_KEYWORDS(SNMP, PROTOCOL, BPG, LOCAL, AS, REMOTE, ADDRESS, PORT, DESCRIPTION,
@ -69,8 +67,6 @@ snmp_proto_start: proto_start SNMP
init_list(&SNMP_CFG->bgp_entries);
SNMP_CFG->bonds = 0;
/* We always have the default context */
SNMP_CFG->contexts = 1;
SNMP_CFG->local_ip = IPA_NONE;
SNMP_CFG->remote_ip = ipa_build4(127,0,0,1);
@ -86,34 +82,10 @@ snmp_proto_start: proto_start SNMP
proto_name ;
snmp_context:
/* empty */ {
if (!this_bond)
this_bond = cfg_alloc(sizeof(struct snmp_bond));
this_bond->context = NULL;
}
| CONTEXT DEFAULT {
if (!this_bond)
this_bond = cfg_alloc(sizeof(struct snmp_bond));
this_bond->context = NULL;
}
| CONTEXT text {
if(!this_bond)
this_bond = cfg_alloc(sizeof(struct snmp_bond));
this_bond->context = $2;
SNMP_CFG->contexts++;
}
;
snmp_bgp_bond: BGP symbol snmp_context
snmp_bgp_bond: BGP symbol
{
/* the snmp_context rule sets the correct value of this_bond */
if (!this_bond)
this_bond = cfg_alloc(sizeof(struct snmp_bond));
struct snmp_bond *this_bond = cfg_alloc(sizeof(struct snmp_bond));
this_bond->type = SNMP_BGP;
cf_assert_symbol($2, SYM_PROTO);
@ -122,8 +94,6 @@ snmp_bgp_bond: BGP symbol snmp_context
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);
add_tail(&SNMP_CFG->bgp_entries, &this_bond->n);
SNMP_CFG->bonds++;
this_bond = NULL;
}
CF_CODE

View File

@ -120,10 +120,6 @@ snmp_init(struct proto_config *CF)
p->timeout = cf->timeout;
/* used when assigning the context ids in s_cont_create() */
p->context_max = 1;
p->context_id_map = NULL;
return P;
}
@ -160,9 +156,6 @@ snmp_cleanup(struct snmp_proto *p)
}
HASH_FREE(p->bgp_hash);
HASH_FREE(p->context_hash);
mb_free(p->context_id_map);
p->context_id_map = NULL;
rfree(p->lp);
p->bgp_trie = NULL;
@ -196,15 +189,6 @@ snmp_connected(sock *sk)
tm_set(p->ping_timer, current_time() + p->timeout S);
}
/* this function is internal and shouldn't be used outside the snmp module */
void
snmp_reconnect(timer *tm)
{
struct snmp_proto *p = tm->data;
ASSUME(p->sock);
snmp_connected(p->sock);
}
/* this function is internal and shouldn't be used outside the snmp module */
void
snmp_sock_disconnect(struct snmp_proto *p, int reconnect)
@ -274,6 +258,27 @@ snmp_start_locked(struct object_lock *lock)
tm_set(p->startup_timer, current_time() + p->timeout S);
}
/* this function is internal and shouldn't be used outside the snmp module */
void
snmp_reconnect(timer *tm)
{
struct snmp_proto *p = tm->data;
if (p->state == SNMP_STOP ||
p->state == SNMP_DOWN)
return;
// TODO is SNMP_RESET really needed ?
if (p->state == SNMP_INIT ||
p->state == SNMP_RESET)
snmp_startup(p);
if (!p->sock)
snmp_start_locked(p->lock);
else
snmp_connected(p->sock);
}
/* this function is internal and shouldn't be used outside the snmp module */
void
snmp_startup(struct snmp_proto *p)
@ -359,20 +364,6 @@ snmp_start(struct proto *P)
/* We create copy of bonds to BGP protocols. */
HASH_INIT(p->bgp_hash, p->pool, 10);
HASH_INIT(p->context_hash, p->pool, 10);
/* We always have at least the default context */
p->context_id_map_size = cf->contexts;
p->context_id_map = mb_allocz(p->pool, cf->contexts * sizeof(struct snmp_context *));
//log(L_INFO "number of context allocated %d", cf->contexts);
struct snmp_context *defaultc = mb_alloc(p->pool, sizeof(struct snmp_context));
defaultc->context = "";
defaultc->context_id = 0;
defaultc->flags = 0; /* TODO Default context fl. */
HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, defaultc);
p->context_id_map[0] = defaultc;
struct snmp_bond *b;
WALK_LIST(b, cf->bgp_entries)
@ -391,18 +382,9 @@ snmp_start(struct proto *P)
trie_add_prefix(p->bgp_trie, &net, IP4_MAX_PREFIX_LENGTH, IP4_MAX_PREFIX_LENGTH);
HASH_INSERT(p->bgp_hash, SNMP_HASH, peer);
/* Handle non-default context */
if (b->context)
{
const struct snmp_context *c = snmp_cont_create(p, b->context);
peer->context_id = c->context_id;
}
}
}
ASSUME(cf->contexts == p->context_max);
snmp_startup(p);
return PS_START;
}
@ -421,14 +403,6 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
{
if (!strcmp(b1->proto->name, b2->proto->name))
goto skip;
/* Both bonds use default context */
if (!b1->context && !b2->context)
goto skip;
/* Both bonds use same non-default context */
if (b1->context && b2->context && !strcmp(b1->context, b2->context))
goto skip;
}
return 0;

View File

@ -52,17 +52,10 @@ enum snmp_proto_state {
/* hash table only store ip4 addresses */
#define SNMP_HASH_LESS(ip1, ip2) SNMP_HASH_LESS4(ip1,ip2)
/* context hash table macros */
#define SNMP_H_CONTEXT_KEY(c) c->context
#define SNMP_H_CONTEXT_NEXT(c) c->next
#define SNMP_H_CONTEXT_EQ(s1,s2) strcmp(s1,s2)
#define SNMP_H_CONTEXT_FN(s) mem_hash(s, strlen(s))
struct snmp_bond {
node n;
struct proto_config *proto;
u8 type;
const char *context;
};
struct snmp_config {
@ -79,7 +72,6 @@ struct snmp_config {
u8 priority;
//struct iface *iface;
u32 bonds;
uint contexts; /* Number of all conetexts including the default */
const char *description;
list bgp_entries;
// TODO add support for subagent oid identification
@ -91,7 +83,6 @@ struct snmp_config {
struct snmp_bgp_peer {
const struct bgp_config *config;
ip_addr peer_ip;
uint context_id;
u8 flags;
struct snmp_bgp_peer *next;
};
@ -110,14 +101,6 @@ struct snmp_registered_oid {
struct oid *oid;
};
struct snmp_context {
const char *context; /* string name */
//uint length; /* strlen() of name */
uint context_id;
u8 flags;
struct snmp_context *next;
};
struct snmp_proto {
struct proto p;
struct object_lock *lock;
@ -149,10 +132,6 @@ struct snmp_proto {
// map
struct f_trie *bgp_trie;
HASH(struct snmp_bgp_peer) bgp_hash;
HASH(struct snmp_context) context_hash;
struct snmp_context **context_id_map;
uint context_id_map_size;
uint context_max;
struct tbf rl_gen;
timer *ping_timer;

View File

@ -170,14 +170,6 @@ snmp_test_varbind(const struct agentx_varbind *vb)
return 0;
}
/*
inline uint
snmp_context_size(struct agentx_context *c)
{
return (c && c->length) ? snmp_str_size_from_len(c->length) : 0;
}
*/
struct agentx_varbind *
snmp_create_varbind(byte *buf, struct oid *oid)
{
@ -575,56 +567,3 @@ snmp_search_res_to_type(enum snmp_search_res r)
return type_arr[r];
}
inline const struct snmp_context *
snmp_cont_find(struct snmp_proto *p, const char *name)
{
u32 *ptr = mb_alloc(p->p.pool, 4 * sizeof(u32));
*ptr = 1;
ptr[2] = 4;
(void)ptr[1]; (void)ptr[0]; (void)ptr[2];
mb_free(ptr);
return HASH_FIND(p->context_hash, SNMP_H_CONTEXT, name);
}
inline const struct snmp_context *
snmp_cont_get(struct snmp_proto *p, uint cont_id)
{
if (cont_id >= p->context_max)
return NULL;
return p->context_id_map[cont_id];
}
inline const struct snmp_context *
snmp_cont_create(struct snmp_proto *p, const char *name)
{
const struct snmp_context *c = snmp_cont_find(p, name);
if (c)
return c;
struct snmp_context *c2;
c2 = mb_alloc(p->p.pool, sizeof(struct snmp_context));
c2->context = name;
c2->context_id = p->context_max++;
c2->flags = 0;
u32 *ptr = mb_alloc(p->p.pool, 4 * sizeof(u32));
*ptr = 1;
ptr[2] = 4;
(void)ptr[1]; (void)ptr[0]; (void)ptr[2];
mb_free(ptr);
HASH_INSERT(p->context_hash, SNMP_H_CONTEXT, c2);
if (c2->context_id >= p->context_id_map_size)
{
// TODO: allocate more than needed for better speed
p->context_id_map_size = c2->context_id + 1;
p->context_id_map = mb_realloc(p->context_id_map, p->context_id_map_size * sizeof(struct snmp_context *));
}
p->context_id_map[c2->context_id] = c2;
return c2;
}

View File

@ -15,7 +15,6 @@ uint snmp_varbind_hdr_size_from_oid(struct oid *oid);
uint snmp_varbind_header_size(struct agentx_varbind *vb);
uint snmp_varbind_size(struct agentx_varbind *vb, int byte_ord);
int snmp_test_varbind(const struct agentx_varbind *vb);
//uint snmp_context_size(struct agentx_context *c);
void snmp_oid_copy(struct oid *dest, const struct oid *src);
@ -58,10 +57,6 @@ byte *snmp_varbind_nstr(struct agentx_varbind *vb, uint size, const char *str, u
void snmp_dump_packet(byte *pkt, uint size);
const struct snmp_context *snmp_cont_find(struct snmp_proto *p, const char *name);
const struct snmp_context *snmp_cont_get(struct snmp_proto *p, uint context_id);
const struct snmp_context *snmp_cont_create(struct snmp_proto *p, const char *name);
enum agentx_type snmp_search_res_to_type(enum snmp_search_res res);
int agentx_type_size(enum agentx_type t);

View File

@ -237,7 +237,7 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, u8 type)
/* Register-PDU / Unregister-PDU */
static void
un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 type, u8 is_instance, uint contid)
un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8 type, u8 is_instance, uint UNUSED contid)
{
const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf);
sock *sk = p->sock;
@ -246,13 +246,6 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8
/* conditional +4 for upper-bound (optinal field) */
uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((len > 1) ? 4 : 0);
const struct snmp_context *sc = NULL;
if (contid)
{
sc = snmp_cont_get(p, contid);
sz += snmp_str_size(sc->context);
}
if (c.size < sz)
snmp_manage_tbuf(p, &c);
@ -264,8 +257,6 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint len, uint index, u8
SNMP_SESSION(h, p);
c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
SNMP_NON_DEFAULT_CONTEXT(h, c, contid);
struct agentx_un_register_hdr *ur = (struct agentx_un_register_hdr *) c.buffer;
/* do not override timeout */
@ -347,8 +338,6 @@ parse_close_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
return AGENTX_HEADER_SIZE;
}
/* The agentx-Close-PDU must not have non-default context */
snmp_simple_response(p, AGENTX_RES_NO_ERROR, 0);
snmp_sock_disconnect(p, 1); // TODO: should we try to reconnect (2nd arg) ??
return AGENTX_HEADER_SIZE;
@ -383,7 +372,7 @@ snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, struct oid *
#if 0
static void UNUSED
addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
uint descr_len, struct agentx_context *c)
uint descr_len)
{
ASSUME(descr != NULL && descr_len > 0);
sock *sk = p->sock;
@ -393,7 +382,7 @@ addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
byte *buf = sk->tpos;
uint size = sk->tbuf + sk->tbsize - sk->tpos;
if (size < AGENTX_HEADER_SIZE + snmp_context_size(c) + snmp_oid_size(cap) + snmp_str_size_from_len(descr_len))
if (size < AGENTX_HEADER_SIZE + snmp_oid_size(cap) + snmp_str_size_from_len(descr_len))
{
/* TO-DO need more mem */
return;
@ -409,7 +398,6 @@ addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
if (c && c->length)
{
SNMP_HAS_CONTEXT(h);
in_pkt = snmp_put_nstr(buf, c->context, c->length) - buf;
ADVANCE(buf, size, in_pkt);
}
@ -426,7 +414,7 @@ addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
}
static void UNUSED
removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap, struct agentx_context *c)
removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap)
{
sock *sk = p->sock;
@ -436,7 +424,7 @@ removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap, struct agentx_context
byte *buf = sk->tpos;
uint size = sk->tbuf + sk->tbsize - sk->tpos;
if (size < AGENTX_HEADER_SIZE + snmp_context_size(c) + snmp_oid_size(cap))
if (size < AGENTX_HEADER_SIZE + snmp_oid_size(cap))
{
/* TO-DO need more mem */
return;
@ -451,7 +439,6 @@ removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap, struct agentx_context
if (c && c->length)
{
SNMP_HAS_CONTEXT(h);
in_pkt = snmp_put_nstr(buf, c->context, c->length) - buf;
ADVANCE(buf, size, in_pkt);
}
@ -492,30 +479,12 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
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;
/* 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(...);
@ -554,7 +523,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
}
mb_free(tr);
#endif
goto error;
error:
s = update_packet_size(p, sk->tpos, c.buffer);
@ -601,22 +570,12 @@ parse_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint err)
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);
@ -891,14 +850,6 @@ do_response(struct snmp_proto *p, byte *buf, uint size)
byte *pkt = buf;
ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
uint clen;
const char *context;
SNMP_LOAD_CONTEXT((struct agentx_header *) buf, pkt, context, clen);
if (size < snmp_str_size_from_len(clen))
return;
ADVANCE(pkt, size, snmp_str_size_from_len(clen));
const struct oid *oid = (void *) pkt;
snmp_register_ack(p, h, snmp_get_mib_class(oid));
@ -1098,39 +1049,6 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
// TODO better handling of endianness
c.byte_ord = 0; /* use little-endian */
uint clen; /* count of characters in context (without last '\0') */
const char *context; /* pointer to RX-buffer context */
/* moves with pkt; assign context, clen */
SNMP_LOAD_CONTEXT(h, pkt, context, clen);
/*
* We need more data; for valid response we need to know full
* header picture, including the context octet string
*/
if (size < clen)
goto wait;
/*
* It is a malformed packet if the context octet string should be longer than
* whole packet.
*/
if (pkt_size < clen)
{
c.error = AGENTX_RES_PARSE_ERROR;
c.index = 0;
ret = MIN(size, pkt_size + AGENTX_HEADER_SIZE);
goto error;
}
/* The RFC does not consider the context octet string as a part of a header */
ADVANCE(pkt, pkt_size, clen);
size -= clen;
/* FIXME add support for c.context hashing
c.context = ...
*/
/*
* Get-Bulk processing stops if all the varbind have type END_OF_MIB_VIEW
* has_any is true if some varbind has type other than END_OF_MIB_VIEW
@ -1167,7 +1085,7 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
if (c.size < sizeof(struct agentx_response))
{
snmp_manage_tbuf(p, &c);
// TODO renew pkt, pkt_start pointers context clen
// TODO renew pkt, pkt_start pointers
}
struct agentx_response *response_header = prepare_response(p, &c);
@ -1309,11 +1227,9 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
goto free;
partial:
/* The context octet is not added into response pdu. */
/* need to tweak RX buffer packet size */
(c.byte_ord) ? put_u32(&h->payload, pkt_size) : (h->payload = pkt_size);
*skip = AGENTX_HEADER_SIZE + snmp_str_size_from_len(clen);
*skip = AGENTX_HEADER_SIZE;
/* number of bytes parsed from RX-buffer */
ret = pkt - pkt_start;
@ -1472,7 +1388,7 @@ int snmp_search_check_end_oid(const struct oid *found, const struct oid *bound)
working only with o_start, o_end allocated in heap (not from buffer)*/
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 *c,
struct oid *o_curr, struct snmp_pdu UNUSED *c,
enum snmp_search_res *result)
{
ASSUME(o_start != NULL);
@ -1500,7 +1416,7 @@ search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_
switch (o_curr->ids[1])
{
case SNMP_BGP4_MIB:
r = snmp_bgp_search2(p, &o_curr, o_end, c->context);
r = snmp_bgp_search2(p, &o_curr, o_end, 0);
if (r == SNMP_SEARCH_OK)
{

View File

@ -121,27 +121,9 @@ enum snmp_search_res {
str[length] = '\0'; /* set term. char */ \
buf += 4 + snmp_str_size_from_len(length); })
#define SNMP_LOAD_CONTEXT(hdr, buf, cont, cont_len) ({ \
if (cont = NULL, cont_len = 0, (hdr)->flags & AGENTX_NON_DEFAULT_CONTEXT) \
LOAD_STR((buf), (cont), (cont_len), \
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER); })
#define SNMP_COPY_CONTEXT(proto, hdr, buf, cont, cont_len) ({ \
cont = NULL; cont_len = 0; \
if (hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) \
COPY_STR(proto, buf, cont, cont_len, \
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER) })
#define SNMP_HAS_CONTEXT(hdr) \
hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT
#define SNMP_NON_DEFAULT_CONTEXT(hdr,pdu,contid) ({ \
if (contid) { \
SNMP_HAS_CONTEXT(hdr); \
snmp_put_str((c).buffer, (sc)->context); \
ADVANCE((c).buffer, (c).size, snmp_str_size((sc)->context)); \
} })
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \
({ \
struct agentx_varbind *vb = (void *) buf; \
@ -158,7 +140,6 @@ enum snmp_search_res {
.buffer = sk->tpos, \
.size = sk->tbuf + sk->tbsize - sk->tpos, \
.error = AGENTX_RES_NO_ERROR, \
.context = 0, \
.index = 0, \
}
@ -314,7 +295,6 @@ enum agentx_response_err {
struct snmp_pdu {
byte *buffer; /* pointer to buffer */
uint size; /* unused space in buffer */
uint context; /* context hash */
int byte_ord; /* flag signaling NETWORK_BYTE_ORDER */
enum agentx_response_err error; /* storage for result of current action */
uint index; /* index on which the error was found */