]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
SNMP: Use compile-time selected byte order
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Wed, 15 Nov 2023 11:37:10 +0000 (12:37 +0100)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Wed, 15 Nov 2023 12:00:24 +0000 (13:00 +0100)
In the AgentX communication the subagent chooses the byte order used. To reduce
code complexity, we decide to use compile-time selected byte order in PDU sent.
Supported options are:
  - SNMP_NATIVE: use native CPU byte order
  - SNMP_NETWORK_BYTE_ORDER: use big endian in PDUs, i.e. network byte order
It is recommended not to used both options at the same time (even it is possible
on big endian platforms).

proto/snmp/bgp_mib.c
proto/snmp/bgp_mib.h
proto/snmp/snmp_test.c
proto/snmp/snmp_utils.c
proto/snmp/snmp_utils.h
proto/snmp/subagent.c
proto/snmp/subagent.h

index 2ad89a51f22dd82613d00e83d171be81b96c6e54..c2c20bfdcd3f3132373d3c8ab0e2870661d2db67 100644 (file)
@@ -199,8 +199,7 @@ void
 snmp_bgp_reg_ok(struct snmp_proto *p, struct agentx_response *r, struct oid *oid)
 {
   const struct oid *in_buf = ((void *) r) + sizeof(r);
-  int byte_ord = r->h.flags & AGENTX_NETWORK_BYTE_ORDER;
-  struct oid *dup = snmp_prefixize(p, in_buf, byte_ord);
+  struct oid *dup = snmp_prefixize(p, in_buf);
 
   ASSUME(snmp_bgp_state(oid) == snmp_bgp_state(dup));
   mb_free(dup);
@@ -1151,7 +1150,7 @@ bgp_fill_dynamic(struct snmp_proto UNUSED *p, struct agentx_varbind *vb,
 
 static byte *
 bgp_fill_static(struct snmp_proto *p, struct agentx_varbind *vb, byte *pkt, uint size
-UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
+UNUSED, uint contid UNUSED, u8 state)
 {
   ASSUME((void *) pkt == (void *) vb);
 
@@ -1205,7 +1204,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, 0, c->byte_ord, state);
+    pkt = bgp_fill_static(p, vb, c->buffer, c->size, 0, state);
     ADVANCE(c->buffer, c->size, pkt - c->buffer);
     return;
   }
index 7e6d35ddf3776fa150d08d91ee6931e7ddc9a73a..52bf13f620d9a9196bd90b8c4c5c839c5e3ce43a 100644 (file)
@@ -36,8 +36,6 @@ enum BGP4_MIB_PEER_TABLE {
 #define SNMP_BGP_NEGOTIATED_VER_VALUE 4
 #define SNMP_BGP_NEGOTIATED_VER_NO_VALUE 0
 
-struct oid;
-
 void snmp_bgp_register(struct snmp_proto *p);
 void snmp_bgp_reg_ok(struct snmp_proto *p, struct agentx_response *r, struct oid *oid);
 void snmp_bgp_reg_failed(struct snmp_proto *p, struct agentx_response *r, struct oid *oid);
index 8737191b7a75d160fab2b160a7becb971210862a..08ea95ab9c9473c8a86cf0a32a37aa0775448c14 100644 (file)
   bt_debug("%s  expected: %3u   actual: %3u\n", \
     #expected, expected, actual);
 
-#ifdef CPU_BIG_ENDIAN
-  #define BYTE_ORD 1
-#else
-  #define BYTE_ORD 0
-#endif
-
 #define OID_ALLOCATE(size) mb_alloc(&root_pool, sizeof(struct oid) + (size) * sizeof (u32))
 
 #define OID_INIT(oid, n_subid_, prefix_, include_, arr_)      \
@@ -39,9 +33,10 @@ test_fill(struct snmp_proto *p)
   ((struct proto *) p)->pool = &root_pool;
 }
 
-static void
+static void UNUSED
 test_oid(struct oid *oid, uint base_size)
 {
+#if 0
   /* tests all states one by one */
 
   oid->n_subid = base_size + 2;
@@ -150,6 +145,7 @@ test_oid(struct oid *oid, uint base_size)
   bt_assert(snmp_bgp_state(oid) == BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME);
 
   bt_debug("testing BGP4-MIB::bgpPeerEntry end\n");
+#endif
 }
 
 static int
@@ -230,14 +226,14 @@ t_s_prefixize(void)
   struct snmp_proto snmp_proto;
   test_fill(&snmp_proto);
 
-  //struct oid *result = snmp_prefixize(&snmp_proto, nulled, BYTE_ORD);
+  //struct oid *result = snmp_prefixize(&snmp_proto, nulled);
   //bt_assert(NULL == result);
   //result != NULL ? mb_free(result) : NULL;
   struct oid *result;
 
   struct oid *blank = mb_allocz(&root_pool, sizeof(struct oid));
   /* here the byte order should not matter */
-  result = snmp_prefixize(&snmp_proto, blank, 1 - BYTE_ORD);
+  result = snmp_prefixize(&snmp_proto, blank);
   bt_assert(snmp_is_oid_empty(result) == 1);
 
   mb_free(result); result = NULL;
@@ -252,7 +248,7 @@ t_s_prefixize(void)
   u32 prefixed_arr[] = { ~((u32) 0), 0, 256 };
   memcpy(&prefixed->ids, prefixed_arr, sizeof(prefixed_arr));
 
-  /* struct oid */result = snmp_prefixize(&snmp_proto, prefixed, BYTE_ORD);
+  /* struct oid */result = snmp_prefixize(&snmp_proto, prefixed);
   bt_assert(memcmp(result, prefixed, snmp_oid_size(prefixed)) == 0);
 
   mb_free(result); result = NULL;
@@ -267,7 +263,7 @@ t_s_prefixize(void)
   u32 to_prefix_arr[] = {1, 3, 6, 1, 100, ~((u32) 0), 0, 256 };
   memcpy(to_prefix->ids, to_prefix_arr, sizeof(to_prefix_arr));
 
-  result = snmp_prefixize(&snmp_proto, to_prefix, BYTE_ORD);
+  result = snmp_prefixize(&snmp_proto, to_prefix);
 
   bt_assert(memcmp(result, prefixed, snmp_oid_size(prefixed)) == 0);
 
@@ -283,7 +279,7 @@ t_s_prefixize(void)
   u32 unpref[] = { 65535, 4 };
   memcpy(&unprefixable->ids, unpref, sizeof(unpref) / sizeof(unpref[0]));
 
-  result = snmp_prefixize(&snmp_proto, unprefixable, BYTE_ORD);
+  result = snmp_prefixize(&snmp_proto, unprefixable);
   bt_assert(result == NULL);
 
   result != NULL ? mb_free(result) : NULL;
@@ -296,7 +292,7 @@ t_s_prefixize(void)
   u32 unpref2[] = { 1, 3, 6, 2, 1, 2, 15, 6 };
   memcpy(&unprefixable2->ids, unpref2, sizeof(unpref2) / sizeof(unpref2[0]));
 
-  result = snmp_prefixize(&snmp_proto, unprefixable2, BYTE_ORD);
+  result = snmp_prefixize(&snmp_proto, unprefixable2);
   bt_assert(result == NULL);
 
   result != NULL ? mb_free(result) : NULL;
@@ -514,7 +510,7 @@ int main(int argc, char **argv)
 
   bt_bird_init();
 
-  bt_test_suite(t_s_bgp_state, "Function snmp_bgp_state()");
+  //bt_test_suite(t_s_bgp_state, "Function snmp_bgp_state()");
 
   bt_test_suite(t_s_is_oid_empty, "Function snmp_is_oid_empty()");
 
index 4016682398fc33ba201b0dd6b4b908f45f0411ab..9cd22baed12267b9f790bb31cd42f8f167848df8 100644 (file)
@@ -168,7 +168,7 @@ snmp_varbind_header_size(struct agentx_varbind *vb)
 }
 
 uint
-snmp_varbind_size(struct agentx_varbind *vb, int byte_ord)
+snmp_varbind_size(struct agentx_varbind *vb)
 {
   uint hdr_size = snmp_varbind_header_size(vb);
   int s = agentx_type_size(vb->type);
@@ -185,7 +185,7 @@ snmp_varbind_size(struct agentx_varbind *vb, int byte_ord)
    * Load length of octet string
    * (AGENTX_OCTET_STRING, AGENTX_IP_ADDRESS, AGENTX_OPAQUE)
    */
-  return hdr_size + snmp_str_size_from_len(LOAD_PTR(data, byte_ord));
+  return hdr_size + snmp_str_size_from_len(LOAD_PTR(data));
 }
 
 /* test if the varbind has valid type */
@@ -450,7 +450,7 @@ snmp_register_create(struct snmp_proto *p, u8 mib_class)
   r->n.prev = r->n.next = NULL;
 
   r->session_id = p->session_id;
-  /* will be incremented by SNMP_SESSION() macro during packet assembly */
+  /* will be incremented by snmp_session() macro during packet assembly */
   r->transaction_id = p->transaction_id;
   r->packet_id = p->packet_id + 1;
 
index bd2ceefadcae6c500d26fa75812f22e99a474209..b39a22e1df38b47d87108c87eee33c16f8240d80 100644 (file)
@@ -13,7 +13,7 @@ uint snmp_oid_size(const struct oid *o);
 size_t snmp_oid_sizeof(uint n_subid);
 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);
+uint snmp_varbind_size(struct agentx_varbind *vb);
 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);
@@ -46,7 +46,7 @@ void snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr);
 
 void snmp_oid_dump(const struct oid *oid);
 
-//struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
+//struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o);
 
 struct snmp_register *snmp_register_create(struct snmp_proto *p, u8 mib_class);
 int snmp_register_same(struct snmp_register *r, struct agentx_header *h, u8 class);
index 7baaf545bc6f8d235225770e8443f448739bfbac..d915bb5a28780cd5cc6669ae0f86bbe8fb8bf05d 100644 (file)
@@ -103,6 +103,21 @@ static const char * const snmp_pkt_type[] UNUSED = {
   [AGENTX_RESPONSE_PDU]                  =  "Response-PDU",
 };
 
+static inline void
+snmp_header(struct agentx_header *h, enum agentx_pdu_types type, u8 flags)
+{
+  STORE_U8(h->version, AGENTX_VERSION);
+  STORE_U8(h->type, (u8) type);
+  STORE_U8(h->flags, flags | SNMP_ORDER);
+  STORE_U8(h->pad, 0);
+  STORE_U32(h->payload, 0);
+}
+
+static inline void
+snmp_blank_header(struct agentx_header *h, enum agentx_pdu_types type)
+{
+  snmp_header(h, type, 0);
+}
 
 /*
  * snmp_register_ok - registration of OID was successful
@@ -251,8 +266,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
 
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
-  SNMP_BLANK_HEADER(h, AGENTX_OPEN_PDU);
-  c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
+  snmp_blank_header(h, AGENTX_OPEN_PDU);
 
   STORE_U32(h->session_id, 1);
   STORE_U32(h->transaction_id, 1);
@@ -300,10 +314,9 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
 
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
-  SNMP_BLANK_HEADER(h, AGENTX_NOTIFY_PDU);
+  snmp_blank_header(h, AGENTX_NOTIFY_PDU);
   p->packet_id++;
-  SNMP_SESSION(h, p);
-  c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
+  snmp_session(p, h);
 
   if (include_uptime)
   {
@@ -320,7 +333,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
     for (uint i = 0; i < uptime.n_subid; i++)
       STORE_U32(vb->name.ids[i], uptime_ids[i]);
     snmp_varbind_ticks(vb, c.size, (current_time() TO_S) / 100);
-    ADVANCE(c.buffer, c.size, snmp_varbind_size(vb, c.byte_ord));
+    ADVANCE(c.buffer, c.size, snmp_varbind_size(vb));
   }
 
   /* snmpTrapOID.0 oid */
@@ -337,7 +350,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
     STORE_U32(trap_vb->name.ids[i], trap0_ids[i]);
   trap_vb->type = AGENTX_OBJECT_ID;
   snmp_put_oid(snmp_varbind_data(trap_vb), oid);
-  ADVANCE(c.buffer, c.size, snmp_varbind_size(trap_vb, c.byte_ord));
+  ADVANCE(c.buffer, c.size, snmp_varbind_size(trap_vb));
 
   memcpy(c.buffer, data, size);
   ADVANCE(c.buffer, c.size, size);
@@ -374,8 +387,8 @@ de_allocate_pdu(struct snmp_proto *p, struct oid *oid, enum agentx_pdu_types typ
   {
     struct agentx_header *h;
     SNMP_CREATE(pkt, struct agentx_header, h);
-    SNMP_BLANK_HEADER(h, type);
-    SNMP_SESSION(h,p);
+    snmp_blank_header(h, type);
+    snmp_session(p, h);
 
     struct agentx_varbind *vb = (struct agentx_varbind *) pkt;
 
@@ -438,10 +451,9 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint bound, uint index, e
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE);
 
-  SNMP_HEADER(h, (u8) type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
+  snmp_header(h, type, is_instance ? AGENTX_FLAG_INSTANCE_REGISTRATION : 0);
   p->packet_id++;
-  SNMP_SESSION(h, p);
-  c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
+  snmp_session(p, h);
 
   struct agentx_un_register_hdr *ur = (struct agentx_un_register_hdr *) c.buffer;
 
@@ -519,10 +531,9 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
 
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   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);
-  c.byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
+  snmp_session(p, h);
 
   snmp_put_fbyte(c.buffer, (u8) reason);
   ADVANCE(c.buffer, c.size, 4);
@@ -546,8 +557,7 @@ parse_close_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
   byte *pkt = pkt_start;
   struct agentx_header *h = (void *) pkt;
   ADVANCE(pkt, size, AGENTX_HEADER_SIZE);
-  int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
-  uint pkt_size = LOAD_U32(h->payload, byte_ord);
+  uint pkt_size = LOAD_U32(h->payload);
 
   if (pkt_size != 0)
   {
@@ -622,8 +632,8 @@ addagentcaps_pdu(struct snmp_proto *p, struct oid *cap, char *descr,
 
   struct agentx_header *h;
   SNMP_CREATE(buf, struct agentx_header, h);
-  SNMP_BLANK_HEADER(h, AGENTX_ADD_AGENT_CAPS_PDU);
-  SNMP_SESSION(h, p);
+  snmp_blank_header(h, AGENTX_ADD_AGENT_CAPS_PDU);
+  snmp_session(p, h);
   ADVANCE(buf, size, AGENTX_HEADER_SIZE);
 
   uint in_pkt;
@@ -664,7 +674,7 @@ removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap)
 
   struct agentx_header *h;
   SNMP_CREATE(buf, struct agentx_header, h);
-  SNMP_SESSION(h, p);
+  snmp_session(p, h);
   ADVANCE(buf, size, AGENTX_HEADER_SIZE);
 
   uint in_pkt;
@@ -691,9 +701,8 @@ removeagentcaps_pdu(struct snmp_proto *p, struct oid *cap)
 static inline void
 refresh_ids(struct snmp_proto *p, struct agentx_header *h)
 {
-  int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
-  p->transaction_id = LOAD_U32(h->transaction_id, byte_ord);
-  p->packet_id = LOAD_U32(h->packet_id, byte_ord);
+  p->transaction_id = LOAD_U32(h->transaction_id);
+  p->packet_id = LOAD_U32(h->packet_id);
 }
 
 /*
@@ -767,7 +776,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
     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);
+    struct oid *work = snmp_prefixize(p, &vb->name);
     (void)work;
     all_possible = snmp_testset(p, vb, tr, work, pkt_size);
     mb_free(work);
@@ -807,7 +816,7 @@ parse_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, enum agen
   byte *pkt = pkt_start;
   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 != 0)
   {
@@ -896,7 +905,7 @@ parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start, uint size)
 
   byte *pkt = pkt_start;
   struct agentx_header *h = (void *) pkt;
-  uint pkt_size = LOAD_U32(h->payload, h->flags & AGENTX_NETWORK_BYTE_ORDER);
+  uint pkt_size = LOAD_U32(h->payload);
 
   /* errors are dropped silently, we must not send any agentx-Response-PDU */
   if (pkt_size != 0)
@@ -925,8 +934,7 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
     return 0;
 
   struct agentx_header *h = (void *) pkt;
-  int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
-  uint pkt_size = LOAD_U32(h->payload, byte_ord);
+  uint pkt_size = LOAD_U32(h->payload);
 
   /* We need to see the responses for PDU such as
    * agentx-Open-PDU, agentx-Register-PDU, ...
@@ -936,7 +944,7 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size, uint *skip)
     return parse_response(p, pkt, size);
 
   if (p->state != SNMP_CONN ||
-      p->session_id != LOAD_U32(h->session_id, byte_ord))
+      p->session_id != LOAD_U32(h->session_id))
   {
     struct agentx_header copy = {
       .session_id = p->session_id,
@@ -1014,9 +1022,8 @@ parse_response(struct snmp_proto *p, byte *res, uint size)
   struct agentx_response *r = (void *) res;
   struct agentx_header *h = &r->h;
 
-  int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
-
-  uint pkt_size = LOAD_U32(h->payload, byte_ord);
+  // todo reject not compiled byte order
+  uint pkt_size = LOAD_U32(h->payload);
   if (size < pkt_size + AGENTX_HEADER_SIZE)
     return 0;
 
@@ -1098,7 +1105,6 @@ do_response(struct snmp_proto *p, byte *buf, uint size)
 {
   struct agentx_response *r = (void *) buf;
   struct agentx_header *h = &r->h;
-  int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
 
   /* TODO make it asynchronous for better speed */
   switch (p->state)
@@ -1110,7 +1116,7 @@ do_response(struct snmp_proto *p, byte *buf, uint size)
 
     case SNMP_OPEN:
       /* copy session info from received packet */
-      p->session_id = LOAD_U32(h->session_id, byte_ord);
+      p->session_id = LOAD_U32(h->session_id);
       refresh_ids(p, h);
 
       /* the state needs to be changed before sending registering PDUs to
@@ -1365,13 +1371,12 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
 
   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);
 
   sock *sk = p->sock;
   struct snmp_pdu c;
   snmp_pdu_context(&c, sk);
   // TODO better handling of endianness
-  c.byte_ord = 0; /* use little-endian */
 
   /*
    * Get-Bulk processing stops if all the varbind have type END_OF_MIB_VIEW
@@ -1397,8 +1402,8 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
 
     bulk_state = (struct agentx_bulk_state) {
       .getbulk = {
-       .non_repeaters = LOAD_U32(bulk_info->non_repeaters, c.byte_ord),
-       .max_repetitions = LOAD_U32(bulk_info->max_repetitions, c.byte_ord),
+       .non_repeaters = LOAD_U32(bulk_info->non_repeaters),
+       .max_repetitions = LOAD_U32(bulk_info->max_repetitions),
       },
       /* In contrast to the RFC, we use 0-based indices. */
       .index = 0,
@@ -1476,8 +1481,8 @@ parse_gets2_pdu(struct snmp_proto *p, byte * const pkt_start, uint size, uint *s
     // TODO check for oversized OIDs before any allocation (in prefixize())
 
     /* We create copy of OIDs outside of rx-buffer and also prefixize them */
-    o_start = snmp_prefixize(p, o_start_b, c.byte_ord);
-    o_end = snmp_prefixize(p, o_end_b, c.byte_ord);
+    o_start = snmp_prefixize(p, o_start_b);
+    o_end = snmp_prefixize(p, o_end_b);
 
     if (!snmp_is_oid_empty(o_end) && snmp_oid_compare(o_start, o_end) > 0)
     {
@@ -1689,10 +1694,9 @@ snmp_ping(struct snmp_proto *p)
 
   struct agentx_header *h = (struct agentx_header *) c.buffer;
   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);
-  c.byte_ord = AGENTX_NETWORK_BYTE_ORDER;
+  snmp_session(p, h);
 
   /* sending only header -> pkt - buf */
   uint s = update_packet_size(p, sk->tpos, c.buffer);
@@ -1799,14 +1803,13 @@ search_mib(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_
  * snmp_prefixize - return prefixed OID copy if possible
  * @proto: allocation pool holder
  * @oid: from packet loaded object identifier
- * @byte_ord: byte order of @oid
  *
  * Return prefixed (meaning with nonzero prefix field) oid copy of @oid if
  * possible, NULL otherwise. Returned pointer is always allocated from @proto's
  * pool not a pointer to RX-buffer (from which is most likely @oid).
  */
 struct oid *
-snmp_prefixize(struct snmp_proto *proto, const struct oid *oid, int byte_ord)
+snmp_prefixize(struct snmp_proto *proto, const struct oid *oid)
 {
   ASSERT(oid != NULL);
 
@@ -1826,7 +1829,7 @@ snmp_prefixize(struct snmp_proto *proto, const struct oid *oid, int byte_ord)
     return NULL;
 
   for (int i = 0; i < 4; i++)
-    if (LOAD_U32(oid->ids[i], byte_ord) != snmp_internet[i])
+    if (LOAD_U32(oid->ids[i]) != snmp_internet[i])
       return NULL;
 
   /* validity check here */
@@ -1923,8 +1926,8 @@ prepare_response(struct snmp_proto *p, struct snmp_pdu *c)
   struct agentx_response *r = (void *) c->buffer;
   struct agentx_header *h = &r->h;
 
-  SNMP_BLANK_HEADER(h, AGENTX_RESPONSE_PDU);
-  SNMP_SESSION(h, p);
+  snmp_blank_header(h, AGENTX_RESPONSE_PDU);
+  snmp_session(p, h);
 
   /* protocol doesn't care about subagent upTime */
   STORE_U32(r->uptime, 0);
index 70c0834ecc7affada99ca2721f8e80ddb5501bdf..f4af725bde0cf26b248329012282eecd34ecef85 100644 (file)
@@ -69,66 +69,83 @@ enum snmp_search_res {
 #define SNMP_REGISTER_TREE 0
 #define SNMP_REGISTER_INSTANCE 1
 
+enum agentx_flags {
+  AGENTX_FLAG_BLANK                = 0x00,
+  AGENTX_FLAG_INSTANCE_REGISTRATION = 0x01,
+  AGENTX_FLAG_NEW_INDEX                    = 0x02,
+  AGENTX_FLAG_ANY_INDEX                    = 0x04,
+  AGENTX_NON_DEFAULT_CONTEXT       = 0x08,
+  AGENTX_NETWORK_BYTE_ORDER        = 0x10,
+} PACKED;
+
+#define AGENTX_FLAGS_MASK (AGENTX_FLAG_INSTANCE_REGISTRATION                 \
+  | AGENTX_FLAG_NEW_INDEX                                                    \
+  | AGENTX_FLAG_ANY_INDEX                                                    \
+  | AGENTX_NON_DEFAULT_CONTEXT                                               \
+  | AGENTX_NETWORK_BYTE_ORDER)
+
+// TODO - make me compile time option
 #define SNMP_NATIVE
 
+#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(SNMP_NETWORK_BYTE_ORDER) && !defined(CPU_BIG_ENDIAN)
+# error "SNMP: couldn't use both native byte order and network byte order " \
+  "(big endian) on little endian machine."
+#endif
+
+#if (defined(SNMP_NATIVE) && defined(CPU_BIG_ENDIAN)) || defined(SNMP_NETWORK_BYTE_ORDER)
+#define SNMP_ORDER AGENTX_NETWORK_BYTE_ORDER
+#else
+#define SNMP_ORDER 0
+#endif
+
 #ifdef SNMP_NATIVE
 #define STORE_U32(dest, val)  ((dest) = (u32) (val))
 #define STORE_U16(dest, val)  ((dest) = (u16) (val))
 #define STORE_U8(dest, val)   ((dest) = (u8) (val))
 #define STORE_PTR(ptr, val)   (*((u32 *) (ptr)) = (u32) (val))
-#else
+
+#define LOAD_U32(src)        *((u32 *) &(src))
+#define LOAD_U16(src)        *((u16 *) &(src))
+#define LOAD_U8(src)         *((u8 *) &(src))
+#define LOAD_PTR(ptr)        *((u32 *) (ptr))
+#endif
+
+#if  defined(SNMP_NETWORK_BYTE_ORDER) && (!defined(SNMP_NATIVE) || defined(CPU_BIG_ENDIAN))
 #define STORE_U32(dest, val)  put_u32(&(dest), (val))
 #define STORE_U16(dest, val)  put_u16(&(dest), (val))
 #define STORE_U8(dest, val)   put_u8(&(dest), (val))
 #define STORE_PTR(ptr, val)   put_u32(ptr, val)
-#endif
 
-/* storing byte (u8) is always the same */
-#define SNMP_HEADER_(h, v, t, f)  \
-  put_u8(&h->version, v);        \
-  put_u8(&h->type, t);           \
-  put_u8(&h->flags, f);                  \
-  put_u8(&h->pad, 0);            \
-  STORE_U32(h->payload, 0)
-
-#ifdef SNMP_NATIVE
-#define SNMP_HEADER(h,t,f)    SNMP_HEADER_(h, AGENTX_VERSION, t, f)
-#else
-#define SNMP_HEADER(h,t,f) \
-  SNMP_HEADER_(h, AGENTX_VERSION, t, f | SNMP_NETWORK_BYTE_ORDER)
+#define LOAD_U32(src)        get_u32(&(src))
+#define LOAD_U16(src)        get_u16(&(src))
+#define LOAD_U8(src)         get_u8(&(src))
+#define LOAD_PTR(src)        get_u32(ptr)
 #endif
 
-#define SNMP_BLANK_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
-
-#define SNMP_SESSION(h, p)                                                   \
-  STORE_U32(h->session_id, p->session_id);                                   \
-  STORE_U32(h->transaction_id, p->transaction_id);                           \
-  STORE_U32(h->packet_id, p->packet_id)
-
-#define LOAD_U32(v, bo) ((bo) ? get_u32(&v) : (u32) (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_STR(/* byte * */buf, str, length, byte_ord)  ({                 \
-  length = LOAD_PTR(buf, byte_ord);                                          \
+#define LOAD_STR(/* byte * */buf, str, length)  ({                           \
+  length = LOAD_PTR(buf);                                                    \
   length > 0 ? (str = buf + 4) : (str = NULL); })
 
-#define COPY_STR(proto, buf, str, length, byte_order) ({                     \
-  length = LOAD_PTR(buf, byte_order);                                        \
+#define COPY_STR(proto, buf, str, length) ({                                 \
+  length = LOAD_PTR(buf);                                                    \
   /*log(L_INFO "LOAD_STR(), %p %u", proto->pool, length + 1); */             \
   str = mb_alloc(proto->pool, length + 1);                                   \
   memcpy(str, buf+4, length);                                                \
   str[length] = '\0'; /* set term. char */                                   \
   buf += 4 + snmp_str_size_from_len(length); })
 
-#define SNMP_PUT_OID(buf, size, oid, byte_ord)                               \
+#define SNMP_PUT_OID(buf, size, oid)                                         \
   ({                                                                         \
     struct agentx_varbind *vb = (void *) buf;                                \
-    SNMP_FILL_VARBIND(vb, oid, byte_ord);                                    \
+    SNMP_FILL_VARBIND(vb, oid);                                                      \
   })
 
-#define SNMP_FILL_VARBIND(vb, oid, byte_ord)                                 \
-  snmp_oid_copy(&(vb)->name, (oid), (byte_ord)), snmp_oid_size((oid))
+#define SNMP_FILL_VARBIND(vb, oid)                                           \
+  snmp_oid_copy(&(vb)->name, (oid)), snmp_oid_size((oid))
 
 struct agentx_header {
   u8 version;
@@ -217,21 +234,6 @@ enum agentx_pdu_types {
   AGENTX_RESPONSE_PDU          = 18,     /* agentx-Response-PDU */
 } PACKED;
 
-enum agentx_flags {
-  AGENTX_FLAG_BLANK                = 0x00,
-  AGENTX_FLAG_INSTANCE_REGISTRATION = 0x01,
-  AGENTX_FLAG_NEW_INDEX                    = 0x02,
-  AGENTX_FLAG_ANY_INDEX                    = 0x04,
-  AGENTX_NON_DEFAULT_CONTEXT       = 0x08,
-  AGENTX_NETWORK_BYTE_ORDER        = 0x10,
-} PACKED;
-
-#define AGENTX_FLAGS_MASK (AGENTX_FLAG_INSTANCE_REGISTRATION                 \
-  | AGENTX_FLAG_NEW_INDEX                                                    \
-  | AGENTX_FLAG_ANY_INDEX                                                    \
-  | AGENTX_NON_DEFAULT_CONTEXT                                               \
-  | AGENTX_NETWORK_BYTE_ORDER)
-
 /* agentx-Close-PDU close reasons */
 enum agentx_close_reasons {
   AGENTX_CLOSE_OTHER         = 1,
@@ -281,7 +283,6 @@ enum agentx_response_errs {
 struct snmp_pdu {
   byte *buffer;                            /* pointer to buffer */
   uint size;                       /* unused space in buffer */
-  int byte_ord;                            /* flag signaling NETWORK_BYTE_ORDER */
   enum agentx_response_errs error;  /* storage for result of current action */
   u32 index;                       /* index on which the error was found */
 };
@@ -305,7 +306,7 @@ void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint siz
 
 void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu *c);
 
-struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o, int byte_ord);
+struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o);
 u8 snmp_get_mib_class(const struct oid *oid);