diff --git a/proto/snmp/snmp_utils.c b/proto/snmp/snmp_utils.c index 6fb4d3d4..40166823 100644 --- a/proto/snmp/snmp_utils.c +++ b/proto/snmp/snmp_utils.c @@ -10,6 +10,46 @@ #include "snmp_utils.h" +inline void +snmp_pdu_context(struct snmp_pdu *pdu, sock *sk) +{ + pdu->buffer = sk->tpos; + pdu->size = sk->tbuf + sk->tbsize - sk->tpos; + pdu->error = AGENTX_RES_NO_ERROR; + pdu->index = 0; +} + +inline void +snmp_session(const struct snmp_proto *p, struct agentx_header *h) +{ + h->session_id = p->session_id; + h->transaction_id = p->transaction_id; + h->packet_id = p->packet_id; +} + +inline int +snmp_has_context(const struct agentx_header *h) +{ + return h->flags & AGENTX_NON_DEFAULT_CONTEXT; +} + +inline byte * +snmp_add_context(struct snmp_proto *p, struct agentx_header *h, uint contid) +{ + h->flags = h->flags | AGENTX_NON_DEFAULT_CONTEXT; + // TODO append the context after the header + (void)p; + (void)contid; + return (void *)h + AGENTX_HEADER_SIZE; +} + +inline void * +snmp_varbind_data(const struct agentx_varbind *vb) +{ + uint name_size = snmp_oid_size(&vb->name); + return (void *)&vb->name + name_size; +} + /** * snmp_is_oid_empty - check if oid is null-valued * @oid: object identifier to check @@ -136,7 +176,7 @@ snmp_varbind_size(struct agentx_varbind *vb, int byte_ord) if (s >= 0) return hdr_size + (uint) s; - void *data = ((void *) vb) + hdr_size; + void *data = snmp_varbind_data(vb); if (vb->type == AGENTX_OBJECT_ID) return hdr_size + snmp_oid_size((struct oid *) data); @@ -478,7 +518,7 @@ snmp_varbind_type32(struct agentx_varbind *vb, uint size, enum agentx_type type, return NULL; vb->type = type; - u32 *data = SNMP_VB_DATA(vb); + u32 *data = snmp_varbind_data(vb); *data = val; return (byte *)(data + 1); } @@ -516,7 +556,7 @@ snmp_varbind_ip4(struct agentx_varbind *vb, uint size, ip4_addr addr) return NULL; vb->type = AGENTX_IP_ADDRESS; - return snmp_put_ip4(SNMP_VB_DATA(vb), addr); + return snmp_put_ip4(snmp_varbind_data(vb), addr); } inline byte * @@ -526,8 +566,7 @@ snmp_varbind_nstr(struct agentx_varbind *vb, uint size, const char *str, uint le return NULL; vb->type = AGENTX_OCTET_STRING; - //die("snmp_varbind_nstr() %p.data = %p", vb, SNMP_VB_DATA(vb)); - return snmp_put_nstr(SNMP_VB_DATA(vb), str, len); + return snmp_put_nstr(snmp_varbind_data(vb), str, len); } inline enum agentx_type diff --git a/proto/snmp/snmp_utils.h b/proto/snmp/snmp_utils.h index 0cad57e9..bd2ceefa 100644 --- a/proto/snmp/snmp_utils.h +++ b/proto/snmp/snmp_utils.h @@ -15,12 +15,16 @@ 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); +void snmp_session(const struct snmp_proto *p, struct agentx_header *h); +int snmp_has_context(const struct agentx_header *h); +void snmp_pdu_context(struct snmp_pdu *pdu, sock *sk); void snmp_oid_copy(struct oid *dest, const struct oid *src); struct oid *snmp_oid_duplicate(pool *pool, const struct oid *oid); struct oid *snmp_oid_blank(struct snmp_proto *p); +void *snmp_varbind_data(const struct agentx_varbind *vb); struct agentx_varbind *snmp_create_varbind(byte* buf, struct oid *oid); byte *snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new); diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 05585ec2..7baaf545 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -216,7 +216,8 @@ static void snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16 index) { sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); if (c.size < sizeof(struct agentx_response)) snmp_manage_tbuf(p, &c); @@ -240,7 +241,8 @@ open_pdu(struct snmp_proto *p, struct oid *oid) const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf); sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); #define TIMEOUT_SIZE 4 /* 1B timeout, 3B zero padding */ if (c.size < AGENTX_HEADER_SIZE + TIMEOUT_SIZE + snmp_oid_size(oid) + @@ -279,7 +281,8 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in { sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); #define UPTIME_SIZE \ (6 * sizeof(u32)) /* sizeof( { u32 vb_type, u32 oid_hdr, u32 ids[4] } )*/ @@ -333,7 +336,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in for (uint i = 0; i < trap0.n_subid; i++) STORE_U32(trap_vb->name.ids[i], trap0_ids[i]); trap_vb->type = AGENTX_OBJECT_ID; - snmp_put_oid(SNMP_VB_DATA(trap_vb), oid); + snmp_put_oid(snmp_varbind_data(trap_vb), oid); ADVANCE(c.buffer, c.size, snmp_varbind_size(trap_vb, c.byte_ord)); memcpy(c.buffer, data, size); @@ -363,7 +366,8 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, enum agentx_pdu_types typ byte *buf, *pkt; buf = pkt = sk->tbuf; uint size = sk->tbsize; - struct snmp_pdu = SNMP_PDU_CONTEXT(p->sock); + struct snmp_pdu c; + snmp_pdu_context(&c, p->sock); if (size > AGENTX_HEADER_SIZE + 0) // TODO additional size @@ -419,9 +423,11 @@ snmp_deallocate(struct snmp_proto *p, struct oid *oid, u8 flags) static void un_register_pdu(struct snmp_proto *p, struct oid *oid, uint bound, uint index, enum agentx_pdu_types type, u8 is_instance, uint UNUSED contid) { + /* used for agentx-Register-PDU and agentx-Unregister-PDU */ const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf); sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); /* conditional +4 for upper-bound (optinal field) */ uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((bound > 1) ? 4 : 0); @@ -504,7 +510,8 @@ static void close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason) { sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); #define REASON_SIZE 4 if (c.size < AGENTX_HEADER_SIZE + REASON_SIZE) @@ -700,20 +707,21 @@ refresh_ids(struct snmp_proto *p, struct agentx_header *h) static uint parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size) { + TRACE(D_PACKETS, "SNMP received agentx-TestSet-PDU"); byte *pkt = pkt_start; /* pointer to agentx-TestSet-PDU in RX-buffer */ 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); + uint pkt_size = LOAD_U32(h->payload); if (pkt_size < size) return 0; sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); - c.byte_ord = 0; /* use little-endian */ + struct snmp_pdu c; + snmp_pdu_context(&c, sk); if (c.size < AGENTX_HEADER_SIZE) snmp_manage_tbuf(p, &c); @@ -809,7 +817,8 @@ parse_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, enum agen // use varbind_list_size()?? } - struct snmp_pdu c = SNMP_PDU_CONTEXT(p->sock); + struct snmp_pdu c; + snmp_pdu_context(&c, p->sock); if (c.size < sizeof(struct agentx_response)) snmp_manage_tbuf(p, &c); @@ -1359,7 +1368,8 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s 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); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); // TODO better handling of endianness c.byte_ord = 0; /* use little-endian */ @@ -1671,7 +1681,8 @@ void snmp_ping(struct snmp_proto *p) { sock *sk = p->sock; - struct snmp_pdu c = SNMP_PDU_CONTEXT(sk); + struct snmp_pdu c; + snmp_pdu_context(&c, sk); if (c.size < AGENTX_HEADER_SIZE) snmp_manage_tbuf(p, &c); diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index 33fed169..70c0834e 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -121,9 +121,6 @@ enum snmp_search_res { str[length] = '\0'; /* set term. char */ \ buf += 4 + snmp_str_size_from_len(length); }) -#define SNMP_HAS_CONTEXT(hdr) \ - hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT - #define SNMP_PUT_OID(buf, size, oid, byte_ord) \ ({ \ struct agentx_varbind *vb = (void *) buf; \ @@ -133,16 +130,6 @@ enum snmp_search_res { #define SNMP_FILL_VARBIND(vb, oid, byte_ord) \ snmp_oid_copy(&(vb)->name, (oid), (byte_ord)), snmp_oid_size((oid)) -#define SNMP_VB_DATA(varbind) \ - (((void *)(varbind)) + snmp_varbind_header_size(varbind)) - -#define SNMP_PDU_CONTEXT(sk) { \ - .buffer = sk->tpos, \ - .size = sk->tbuf + sk->tbsize - sk->tpos, \ - .error = AGENTX_RES_NO_ERROR, \ - .index = 0, \ - } - struct agentx_header { u8 version; u8 type; @@ -169,7 +156,7 @@ struct agentx_varbind { u16 pad; /* oid part */ struct oid name; - byte data[]; + /* AgentX variable binding data optionaly here */ }; /* this does not work */