]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
SNMP: tmp -- fix byte order handling
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Fri, 9 Aug 2024 22:07:49 +0000 (00:07 +0200)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Fri, 9 Aug 2024 22:07:49 +0000 (00:07 +0200)
proto/snmp/bgp4_mib.c
proto/snmp/mib_tree.c
proto/snmp/snmp.c
proto/snmp/snmp_test.c
proto/snmp/snmp_utils.c
proto/snmp/snmp_utils.h
proto/snmp/subagent.c
proto/snmp/subagent.h

index 9a0418fd5f913fbfe6e230b7c1dcecbb32ef56fc..d81d0432a4995d6d475c55e6a6b67a21b5e4351f 100644 (file)
@@ -245,6 +245,7 @@ snmp_bgp4_register(struct snmp_proto *p)
 
     struct oid *oid = mb_allocz(p->pool,
       snmp_oid_size_from_len(ARRAY_SIZE(bgp_mib_prefix)));
+    print(;
     STORE_U8(oid->n_subid, ARRAY_SIZE(bgp_mib_prefix));
     STORE_U8(oid->prefix, SNMP_MGMT);
 
@@ -284,10 +285,10 @@ ip4_to_oid(struct oid *o, ip4_addr addr)
 {
   u32 tmp = ip4_to_u32(addr);
   ASSUME(o->n_subid >= 9);
-  STORE_U32(o->ids[5], (tmp & 0xFF000000) >> 24);
-  STORE_U32(o->ids[6], (tmp & 0x00FF0000) >> 16);
-  STORE_U32(o->ids[7], (tmp & 0x0000FF00) >>  8);
-  STORE_U32(o->ids[8], (tmp & 0x000000FF) >>  0);
+  o->ids[5] = (tmp & 0xFF000000) >> 24;
+  o->ids[6] = (tmp & 0x00FF0000) >> 16;
+  o->ids[7] = (tmp & 0x0000FF00) >>  8;
+  o->ids[8] = (tmp & 0x000000FF) >>  0;
 }
 
 static void UNUSED
@@ -337,7 +338,7 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
 **conn, const struct bgp_stats **stats, const struct bgp_config **config)
 {
   const struct oid * const oid = &c->sr_vb_start->name;
-  if (snmp_bgp_valid_ip4(oid) && LOAD_U8(oid->n_subid) == 9)
+  if (snmp_bgp_valid_ip4(oid) && oid->n_subid == 9)
     *addr = ip4_from_oid(oid);
   else
     return SNMP_SEARCH_NO_INSTANCE;
@@ -378,7 +379,7 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto
 static enum snmp_search_res
 fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
+  if (c->sr_vb_start->name.n_subid != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   c->size -= snmp_str_size_from_len(1);
   snmp_varbind_nstr(c, BGP4_VERSIONS, 1);
@@ -388,7 +389,7 @@ fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 static enum snmp_search_res
 fill_local_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
+  if (c->sr_vb_start->name.n_subid != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   snmp_varbind_int(c, c->p->bgp_local_as);
   return SNMP_SEARCH_OK;
@@ -743,7 +744,7 @@ fill_in_update_elapsed_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu
 static enum snmp_search_res
 fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c)
 {
-  if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3)
+  if (c->sr_vb_start->name.n_subid != 3)
     return SNMP_SEARCH_NO_INSTANCE;
   snmp_varbind_ip4(c, c->p->bgp_local_id);
   return SNMP_SEARCH_OK;
@@ -771,10 +772,10 @@ bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c)
   const struct oid *peer_oid = (const struct oid *) &bgp4_peer_id;
 
   int precise = 1;
-  if (LOAD_U8(oid->n_subid) > 9)
+  if (oid->n_subid > 9)
     precise = 0;
 
-  if (LOAD_U8(oid->n_subid) != 9 || snmp_oid_compare(oid, peer_oid) < 0)
+  if (oid->n_subid != 9 || snmp_oid_compare(oid, peer_oid) < 0)
   {
     int old = snmp_oid_size(oid);
     int new = snmp_oid_size(peer_oid);
@@ -785,7 +786,7 @@ bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c)
     c->buffer += (new - old);
 
     snmp_oid_copy(oid, peer_oid);
-    STORE_U8(oid->include, 1);
+    oid->include = 1;
   }
 
   ASSUME(oid->n_subid == 9);
@@ -799,9 +800,9 @@ bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c)
 
   int match = trie_walk_init(&ws, c->p->bgp_trie, &net, 1);
 
-  if (match && LOAD_U8(oid->include) && precise)
+  if (match && oid->include && precise)
   {
-    STORE_U8(oid->include, 0);
+    oid->include = 0;
     ip4_to_oid(oid, ip4);
     return 0;
   }
index af0b7c094478f13a5800ca9b36d7b05143154554..23fcdfc540798e78e0378dff1468384e7fb8cf41 100644 (file)
@@ -46,13 +46,13 @@ mib_tree_init(pool *p, struct mib_tree *t)
 
   struct oid *oid = tmp_alloc(
     snmp_oid_size_from_len((uint) ARRAY_SIZE(snmp_internet)));
-  STORE_U8(oid->n_subid, ARRAY_SIZE(snmp_internet));
-  STORE_U8(oid->prefix, 0);
-  STORE_U8(oid->include, 0);
-  STORE_U8(oid->reserved, 0);
+  oid->n_subid =  ARRAY_SIZE(snmp_internet);
+  oid->prefix = 0;
+  oid->include =  0;
+  oid->reserved = 0;
 
   for (size_t i = 0; i < ARRAY_SIZE(snmp_internet); i++)
-    STORE_U32(oid->ids[i], snmp_internet[i]);
+    oid->ids[i] = snmp_internet[i];
 
   (void) mib_tree_add(p, t, oid, 0);
 }
@@ -110,7 +110,7 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
 
   mib_tree_walk_init(&walk, t);
   node = mib_tree_find(t, &walk, oid);
-  ASSERT(walk.id_pos <= LOAD_U8(oid->n_subid) + 1);
+  ASSERT(walk.id_pos <= oid->n_subid + 1);
 
   if (node)
   {
@@ -122,7 +122,7 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
     return NULL;
   }
 
-  ASSERT(walk.id_pos < LOAD_U8(oid->n_subid) + 1);
+  ASSERT(walk.id_pos < oid->n_subid + 1);
 
   node = walk.stack[walk.stack_pos - 1];
   /* we encounter leaf node before end of OID's id path */
@@ -161,14 +161,14 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
     if (walk.stack_pos == ARRAY_SIZE(snmp_internet) + 1)
     {
       u32 old_len = node_inner->child_len;
-      node_inner->child_len = MAX(old_len, (u32) LOAD_U8(oid->prefix) + 1);
+      node_inner->child_len = MAX(old_len, (u32) oid->prefix + 1);
       node_inner->children = realloc(node_inner->children,
        node_inner->child_len * sizeof(mib_node_u *));
 
       for (u32 i = old_len; i < node_inner->child_len; i++)
        node_inner->children[i] = NULL;
 
-      if (is_leaf && !LOAD_U8(oid->n_subid))
+      if (is_leaf && !oid->n_subid)
       {
        node = allocz(sizeof(struct mib_leaf));
        node->empty.flags = MIB_TREE_LEAF;
@@ -179,9 +179,9 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
        node->empty.flags = 0;
       }
 
-      node->empty.id = LOAD_U8(oid->prefix);
+      node->empty.id = oid->prefix;
       /* add node into the parent's children array */
-      node_inner->children[LOAD_U8(oid->prefix)] = node;
+      node_inner->children[oid->prefix] = node;
       node_inner = &node->inner;
       walk.stack[walk.stack_pos++] = node;
     }
@@ -190,17 +190,17 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
   /* snmp_internet + 2 = empty + snmp_internet + prefix */
   if (snmp_oid_is_prefixed(oid) &&
       walk.stack_pos == ARRAY_SIZE(snmp_internet) + 2 &&
-      LOAD_U8(oid->n_subid) == 0 &&
+      oid->n_subid == 0 &&
       mib_node_is_leaf(node) == is_leaf)
     return node;
 
   if (mib_node_is_leaf(node))
     return node;
 
-  u8 subids = LOAD_U8(oid->n_subid);
+  u8 subids = oid->n_subid;
   u32 old_len = node_inner->child_len;
   u32 child_id = oid->ids[walk.id_pos];
-  node_inner->child_len = MAX(old_len, LOAD_U32(child_id) + 1);
+  node_inner->child_len = MAX(old_len, child_id + 1);
   node_inner->children = realloc(node_inner->children,
     node_inner->child_len * sizeof(mib_node_u *));
 
@@ -217,7 +217,7 @@ mib_tree_add(pool *p, struct mib_tree *t, const struct oid *oid, int is_leaf)
     parent->children[child_id] = (mib_node_u *) node_inner;
     node_inner->c.id = child_id;
 
-    child_id = LOAD_U32(oid->ids[++walk.id_pos]);
+    child_id = oid->ids[++walk.id_pos];
 
     node_inner->child_len = child_id + 1;
     node_inner->children = allocz(node_inner->child_len * sizeof(mib_node_u *));
@@ -430,14 +430,14 @@ mib_tree_find(const struct mib_tree *t, struct mib_walk_state *walk, const struc
     /* In any of cases below we did not move in the tree therefore the
      * walk->id_pos is left untouched. */
     if (snmp_oid_is_prefixed(oid) &&
-       LOAD_U8(oid->n_subid) + ARRAY_SIZE(snmp_internet) + 1 == walk->id_pos)
+       oid->n_subid + ARRAY_SIZE(snmp_internet) + 1 == walk->id_pos)
       return node;
 
     else if (snmp_oid_is_prefixed(oid) &&
-       LOAD_U8(oid->n_subid) + ARRAY_SIZE(snmp_internet) + 1 > walk->id_pos)
+       oid->n_subid + ARRAY_SIZE(snmp_internet) + 1 > walk->id_pos)
       return NULL;
 
-    else if (!snmp_oid_is_prefixed(oid) && LOAD_U8(oid->n_subid) + 1 == walk->id_pos)
+    else if (!snmp_oid_is_prefixed(oid) && oid->n_subid + 1 == walk->id_pos)
       return node;
   }
 
@@ -470,7 +470,7 @@ mib_tree_find(const struct mib_tree *t, struct mib_walk_state *walk, const struc
     }
 
     /* walking the prefix continuation (OID field oid->prefix) */
-    u8 prefix = LOAD_U8(oid->prefix);
+    u8 prefix = oid->prefix;
     if (node_inner->child_len <= prefix)
       return NULL;
 
@@ -483,18 +483,18 @@ mib_tree_find(const struct mib_tree *t, struct mib_walk_state *walk, const struc
     ASSERT(node->empty.id == prefix);
     walk->stack[walk->stack_pos++] = node;
 
-    if (mib_node_is_leaf(node) && LOAD_U8(oid->n_subid) > 0)
+    if (mib_node_is_leaf(node) && oid->n_subid > 0)
       return NULL;
   }
 
-  u8 subids = LOAD_U8(oid->n_subid);
+  u8 subids = oid->n_subid;
   if (subids == 0)
     return (node == (mib_node_u *) &t->root) ? NULL : node;
 
   /* loop for all OID's ids except the last one */
   for (; oid_pos < subids - 1 && walk->stack_pos < MIB_WALK_STACK_SIZE + 1; oid_pos++)
   {
-    u32 id = LOAD_U32(oid->ids[oid_pos]);
+    u32 id = oid->ids[oid_pos];
     if (node_inner->child_len <= id)
     {
       /* The walk->id_pos points after the last accepted OID id.
@@ -527,7 +527,7 @@ mib_tree_find(const struct mib_tree *t, struct mib_walk_state *walk, const struc
   }
 
   walk->id_pos = oid_pos;
-  u32 last_id = LOAD_U32(oid->ids[oid_pos]);
+  u32 last_id = oid->ids[oid_pos];
   if (node_inner->child_len <= last_id ||
       walk->stack_pos >= MIB_WALK_STACK_SIZE + 1)
     return NULL;
@@ -598,9 +598,9 @@ mib_tree_walk_to_oid(const struct mib_walk_state *walk, struct oid *result, u32
 
     /* skip empty prefix, whole snmp_internet .1.3.6.1 and oid->prefix */
     index = 2 + ARRAY_SIZE(snmp_internet);
-    STORE_U8(result->n_subid, walk->stack_pos - (ARRAY_SIZE(snmp_internet) + 2));
-    STORE_U8(result->prefix,
-      walk->stack[ARRAY_SIZE(snmp_internet) + 1]->empty.id);
+    result->n_subid = walk->stack_pos - (ARRAY_SIZE(snmp_internet) + 2);
+    result->prefix = \
+      walk->stack[ARRAY_SIZE(snmp_internet) + 1]->empty.id;
   }
   else
   {
@@ -608,17 +608,17 @@ mib_tree_walk_to_oid(const struct mib_walk_state *walk, struct oid *result, u32
       return 1;
 
     index = 1; /* skip empty prefix */
-    STORE_U8(result->n_subid, walk->stack_pos - 1);
-    STORE_U8(result->prefix, 0);
+    result->n_subid = walk->stack_pos - 1;
+    result->prefix = 0;
   }
 
-  STORE_U8(result->include, 0);
-  STORE_U8(result->reserved, 0);
+  result->include = 0;
+  result->reserved = 0;
 
   u32 i = 0;
   /* the index could point after last stack array element */
   for (; index < walk->stack_pos && index < MIB_WALK_STACK_SIZE; index++)
-    STORE_U32(result->ids[i++], walk->stack[index]->empty.id);
+    result->ids[i++] = walk->stack[index]->empty.id;
 
   return 0;
 }
@@ -639,9 +639,9 @@ mib_tree_walk_oid_compare(const struct mib_walk_state *walk, const struct oid *o
 
   uint walk_idx = 1;
   u8 walk_subids = walk->stack_pos;      /* left_subids */
-  u8 oid_subids = LOAD_U8(oid->n_subid);  /* right_subids */
+  u8 oid_subids = oid->n_subid;  /* right_subids */
 
-  const u8 oid_prefix = LOAD_U8(oid->prefix);
+  const u8 oid_prefix = oid->prefix;
 
   if (oid_prefix != 0)
   {
@@ -668,7 +668,7 @@ mib_tree_walk_oid_compare(const struct mib_walk_state *walk, const struct oid *o
   for (; i < oid_subids && walk_idx < walk_subids; i++, walk_idx++)
   {
     u32 walk_id = walk->stack[walk_idx]->empty.id;
-    u32 oid_id = LOAD_U32(oid->ids[i]);
+    u32 oid_id = oid->ids[i];
     if (walk_id < oid_id)
       return -1;
     else if (walk_id > oid_id)
@@ -714,16 +714,16 @@ mib_tree_walk_is_oid_descendant(const struct mib_walk_state *walk, const struct
       return +1;
 
     if (i < walk->stack_pos &&
-       walk->stack[i]->empty.id != (u32)LOAD_U8(oid->prefix))
+       walk->stack[i]->empty.id != (u32) oid->prefix)
       return -1;
 
     i++;
   }
 
-  u32 ids = LOAD_U8(oid->n_subid);
+  u32 ids = oid->n_subid;
   for (; i < walk->stack_pos && j < ids; i++, j++)
   {
-    if (walk->stack[i]->empty.id != LOAD_U32(oid->ids[j]))
+    if (walk->stack[i]->empty.id != oid->ids[j])
       return -1;
   }
 
index 2200cca288e369cc51b5891de12d812e406bf948..c37f4394a3307c21bec41d5a811a929f823ab86e 100644 (file)
@@ -140,10 +140,10 @@ void agentx_get_mib_init(pool *p)
   struct oid *dest = mb_alloc(p, size);
 
   memcpy(dest, src, size);
-  u8 ids = LOAD_U8(src->n_subid);
+  u8 ids = src->n_subid;
 
   if (ids > 0)
-    STORE_U32(dest->ids[ids - 1], LOAD_U32(src->ids[ids - 1]) + 1);
+    dest->ids[ids - 1] = src->ids[ids - 1] + 1;
 
   agentx_available_mibs[AGENTX_MIB_COUNT] = dest;
 }
index 1223d13527b2727140218df41de83989a97228a4..e572d8860c271f868a13d040070dd2ed168f922a 100644 (file)
@@ -783,17 +783,17 @@ t_walk_oid_desc(void)
       case 1:
       {
        /* oid is longer than walk or has same length */
-       u8 ids = LOAD_U8(oid->n_subid);
+       u8 ids = oid->n_subid;
        u32 upto = MIN(OID_MAX_LEN - ids, 16);
 
        if (!upto)
          continue;
 
        u32 new = xrandom(upto) + 1;
-       STORE_U8(oid->n_subid, ids + new);
+       oid->n_subid = ids + new;
 
        for (u32 i = 0; i < new; i++)
-         STORE_U32(oid->ids[ids + i], xrandom(OID_MAX_ID));
+         oid->ids[ids + i] = xrandom(OID_MAX_ID);
 
        bt_assert(mib_tree_walk_is_oid_descendant(&walk, oid) > 0);
 
@@ -803,7 +803,7 @@ t_walk_oid_desc(void)
       case 3:
       {
        /* oid is shorter than walk */
-       u8 ids = LOAD_U8(oid->n_subid);
+       u8 ids = oid->n_subid;
 
        if (ids == 0 || ids == OID_MAX_LEN)
          continue;
@@ -811,14 +811,14 @@ t_walk_oid_desc(void)
        u32 split = (ids > 1) ? xrandom(ids - 1) + 1 : 0;
        u32 ext = (type == 3) ? xrandom(MIN(OID_MAX_LEN - ids, 16)) : 0;
 
-       STORE_U16(oid->n_subid, split + ext);
+       oid->n_subid = split + ext;
        for (u32 i = 0; i < ext; i++)
-         STORE_U32(oid->ids[split + i], xrandom(OID_MAX_ID));
+         oid->ids[split + i] = xrandom(OID_MAX_ID);
 
        int no_change = 1;
        for (u32 j = 0; j < MIN(ids - split, ext); j++)
        {
-         if (LOAD_U32(oid->ids[split + j]) != LOAD_U32(oids[i]->ids[split + j]))
+         if (oid->ids[split + j] != oids[i]->ids[split + j])
            no_change = 0;
        }
 
@@ -897,18 +897,18 @@ t_walk_oid_compare(void)
       case 1:
       {
        /* oid is longer than walk or has same length */
-       u8 ids = LOAD_U8(oid->n_subid);
+       u8 ids = oid->n_subid;
        u32 upto = MIN(OID_MAX_LEN - ids, 16);
 
        if (!upto)
          continue;
 
        u32 new = xrandom(upto) + 1;
-       STORE_U8(oid->n_subid, ids + new);
+       oid->n_subid = ids + new;
        ASSERT(snmp_oid_size(oid) < 1024);
 
        for (u32 i = 0; i < new; i++)
-         STORE_U32(oid->ids[ids + i], xrandom(OID_MAX_ID));
+         oid->ids[ids + i] = xrandom(OID_MAX_ID);
 
 
        bt_assert(mib_tree_walk_oid_compare(&walk, oid) < 0);
@@ -918,7 +918,7 @@ t_walk_oid_compare(void)
       case 3:
       {
        /* oid is shorter than walk */
-       u8 ids = LOAD_U8(oid->n_subid);
+       u8 ids = oid->n_subid;
 
        if (ids == 0 || ids == OID_MAX_LEN)
          continue;
@@ -926,13 +926,13 @@ t_walk_oid_compare(void)
        u32 split = (ids > 1) ? xrandom(ids - 1) + 1 : 0;
        u32 ext = (type == 3) ? xrandom(MIN(OID_MAX_LEN - ids, 16)) : 0;
 
-       STORE_U16(oid->n_subid, split + ext);
+       oid->n_subid = split + ext;
        for (u32 i = 0; i < ext; i++)
-         STORE_U32(oid->ids[split + i], xrandom(OID_MAX_ID));
+         oid->ids[split + i] = xrandom(OID_MAX_ID);
 
        int cmp_res = 0;
        for (u32 j = 0; j < MIN(ids - split, ext) && !cmp_res; j++)
-         cmp_res = LOAD_U32(oids[i]->ids[split + j]) - LOAD_U32(oid->ids[split + j]);
+         cmp_res = oids[i]->ids[split + j] - oid->ids[split + j];
 
        if (!cmp_res && split + ext == ids)
          continue;
@@ -1256,16 +1256,16 @@ gen_test_find(struct oid *(*generator)(void))
       }
       else
       {
-       for (uint j = 0; j < MIN(LOAD_U8(oids[i]->n_subid),
+       for (uint j = 0; j < MIN(oids[i]->n_subid,
            ARRAY_SIZE(snmp_internet)); j++)
        {
-         if (LOAD_U32(oids[i]->ids[j]) == snmp_internet[j] &&
+         if (oids[i]->ids[j] == snmp_internet[j] &&
              j >= longest_inet_pref_len)
          {
            longest_inet_pref->ids[j] = snmp_internet[j];
            longest_inet_pref_len = j + 1;
          }
-         else if (LOAD_U32(oids[i]->ids[j]) == snmp_internet[j])
+         else if (oids[i]->ids[j] == snmp_internet[j])
            ;
          else
            break;
@@ -1360,19 +1360,19 @@ gen_test_find(struct oid *(*generator)(void))
       last = found;
 
       /* test finding with walk state not pointing at the root of the tree */
-      u8 subids = LOAD_U8(oids[i]->n_subid);
+      u8 subids = oids[i]->n_subid;
       if (subids > 0)
       {
        found = NULL;
        u32 new_ids = xrandom(subids);
        mib_tree_walk_init(&walk, (xrandom(2)) ? tree : NULL);
 
-       STORE_U8(oids[i]->n_subid, new_ids);
+       oids[i]->n_subid = new_ids;
 
        mib_node_u *ignored UNUSED;
        ignored = mib_tree_find(tree, &walk, oids[i]);
 
-       STORE_U8(oids[i]->n_subid, subids);
+       oids[i]->n_subid = subids;
 
        found = mib_tree_find(tree, &walk, oids[i]);
 
@@ -1410,7 +1410,7 @@ gen_test_find(struct oid *(*generator)(void))
       if (!has_node && !snmp_oid_is_prefixed(oid))
       {
        for (uint i = 0; i < MIN(ARRAY_SIZE(snmp_internet),
-           LOAD_U8(oid->n_subid)); i++)
+           oid->n_subid); i++)
        {
          if (longest_inet_pref->ids[i] != 0 &&
              longest_inet_pref->ids[i] == oid->ids[i])
@@ -1422,7 +1422,7 @@ gen_test_find(struct oid *(*generator)(void))
          }
        }
 
-       if (has_node && LOAD_U8(oid->n_subid) > ARRAY_SIZE(snmp_internet))
+       if (has_node && oid->n_subid > ARRAY_SIZE(snmp_internet))
          has_node = 0;
       }
 
@@ -1437,19 +1437,19 @@ gen_test_find(struct oid *(*generator)(void))
 
       last = found;
 
-      u8 subids = LOAD_U8(searched[search]->n_subid);
+      u8 subids = searched[search]->n_subid;
       if (subids > 0)
       {
        found = NULL;
        u32 new_ids = xrandom(subids);
        mib_tree_walk_init(&walk, (xrandom(2)) ? tree : NULL);
 
-       STORE_U8(searched[search]->n_subid, new_ids);
+       searched[search]->n_subid = new_ids;
 
        mib_node_u *ignored UNUSED;
        ignored = mib_tree_find(tree, &walk, searched[search]);
 
-       STORE_U8(searched[search]->n_subid, subids);
+       searched[search]->n_subid = subids;
 
        found = mib_tree_find(tree, &walk, searched[search]);
 
@@ -1725,7 +1725,7 @@ gen_test_traverse(struct oid *(*generator)(void))
     {
       if (snmp_oid_is_prefixed(sorted[d]))
        bound += 5;
-      bound += (int)LOAD_U8(sorted[d]->n_subid);
+      bound += (int) sorted[d]->n_subid;
     }
 
     if (!no_inet_prefix)
index bb4bb811e2d88fa2bf6fbf59a9c879a48d60cbe5..a64b820e83ec253b764e4c648153ada98377264e 100644 (file)
@@ -46,7 +46,7 @@ inline void *
 snmp_varbind_data(const struct agentx_varbind *vb)
 {
   uint name_size = snmp_oid_size(&vb->name);
-  return (void *)&vb->name + name_size;
+  return (void *) &vb->name + name_size;
 }
 
 struct oid *
@@ -54,23 +54,23 @@ snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len
 {
   struct oid *oid = &(*vb)->name;
 
-  if (LOAD_U8(oid->n_subid) >= len)
+  if (oid->n_subid >= len)
   {
-    c->size += (LOAD_U8(oid->n_subid) - len) * sizeof(u32);
-    STORE_U8(oid->n_subid, len);
+    c->size += (oid->n_subid - len) * sizeof(u32);
+    oid->n_subid = len;
     return oid;
   }
 
   /* We need more space */
-  ASSUME(len >= LOAD_U8(oid->n_subid));
-  uint diff_size = (len - LOAD_U8(oid->n_subid)) * sizeof(u32);
+  ASSUME(len >= oid->n_subid);
+  uint diff_size = (len - oid->n_subid) * sizeof(u32);
 
   if (snmp_tbuf_reserve(c, diff_size))
     oid = &(*vb)->name;
 
   ASSERT(c->size >= diff_size);
   c->size -= diff_size;
-  STORE_U8(oid->n_subid, len);
+  oid->n_subid = len;
   return &(*vb)->name;
 }
 
@@ -78,7 +78,7 @@ void
 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);
+  uint hdr_size = snmp_varbind_header_size(*vb->name);
   (void) snmp_tbuf_reserve(c, hdr_size);
 
   ASSERT(c->size >= hdr_size);
@@ -100,7 +100,7 @@ snmp_is_oid_empty(const struct oid *oid)
 {
   /* We intentionaly ignore padding that should be zeroed */
   if (oid != NULL)
-    return LOAD_U8(oid->n_subid) == 0 && LOAD_U8(oid->prefix) == 0;
+    return oid->n_subid == 0 && oid->prefix == 0;
   else
     return 0;
 }
@@ -119,10 +119,10 @@ snmp_oid_is_prefixable(const struct oid *oid)
     return 0;
 
   for (int i = 0; i < 4; i++)
-    if (LOAD_U32(oid->ids[i]) != snmp_internet[i])
+    if (oid->ids[i] != snmp_internet[i])
       return 0;
 
-  if (LOAD_U32(oid->ids[4]) >= 256)
+  if (oid->ids[4] >= 256)
     return 0;
 
   return 1;
@@ -148,27 +148,12 @@ snmp_pkt_len(const byte *start, const byte *end)
 void
 snmp_oid_copy(struct oid *dest, const struct oid *src)
 {
-  STORE_U8(dest->n_subid, src->n_subid);
-  STORE_U8(dest->prefix, src->prefix);
-  STORE_U8(dest->include, src->include ? 1 : 0);
-  STORE_U8(dest->reserved, 0);
-
-  for (int i = 0; i < LOAD_U8(src->n_subid); i++)
-    STORE_U32(dest->ids[i], src->ids[i]);
-}
-
-/* this function assumes enougth space inside dest is allocated */
-void
-snmp_oid_copy2(struct oid *dest, const struct oid *src)
-{
-  /* The STORE_U8() and LOAD_U8() cancel out */
   dest->n_subid = src->n_subid;
   dest->prefix = src->prefix;
   dest->include = src->include ? 1 : 0;
   dest->reserved = 0;
 
-  /* The STORE_U32() and LOAD_U32 cancel out */
-  memcpy(dest->ids, src->ids, LOAD_U8(src->n_subid) * sizeof(u32));
+  memcpy(dest->ids, src->ids, src->n_subid * sizeof(u32));
 }
 
 /*
@@ -235,18 +220,21 @@ snmp_str_size(const char *str)
 }
 
 /**
- * snmp_oid_size - measure size of oid in bytes
+ * snmp_oid_size - measure size of OID in bytes
  * @o: object identifier to use
+ *
+ * Work for both packet and cpu native byte orders.
  */
 uint
 snmp_oid_size(const struct oid *o)
 {
+  /* LOAD_U8() is in both cases basic mem read */
   return 4 + (LOAD_U8(o->n_subid) * 4);
 }
 
-/**
- * snmp_get_size - calculate size for allocation
- * @n_subid: number of ids in oid
+/*
+ * snmp_oid_size_from_len - return size of OID with @n_subid subids in bytes
+ * @n_subid: number of subids in ids array
  */
 inline size_t
 snmp_oid_size_from_len(uint n_subid)
@@ -254,19 +242,6 @@ snmp_oid_size_from_len(uint n_subid)
   return sizeof(struct oid) + n_subid * sizeof(u32);
 }
 
-/*
- * snmp_varbind_hdr_size_from_oid - return in-buffer size of VarBind
- * @oid: OID used as VarBind's name
- *
- * This function assume @oid to be not NULL.
- */
-uint
-snmp_varbind_hdr_size_from_oid(const struct oid *oid)
-{
-  ASSUME(oid);
-  return snmp_oid_size(oid) + OFFSETOF(struct agentx_varbind, name);
-}
-
 /*
  * snmp_set_varbind_type - set VarBind's type field
  * @vb: Varbind inside TX buffer
@@ -308,54 +283,40 @@ snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t)
   }
 }
 
-/* Internal wrapper */
-static inline u16
-snmp_load_varbind_type(const struct agentx_varbind *vb)
-{
-  return LOAD_U16(vb->type);
-}
-
-/*
- * snmp_get_varbind_type - loads a VarBind type
- * @vb: VarBind pointer to TX buffer
- *
- * This function assumes VarBind with valid type, always call snmp_test_varbind
- * for in TX buffer VarBinds.
- */
-inline enum agentx_type
-snmp_get_varbind_type(const struct agentx_varbind *vb)
-{
-  ASSUME(snmp_test_varbind(vb));
-  return (enum agentx_type) snmp_load_varbind_type(vb);
-}
-
 static inline uint
 snmp_get_octet_size(const struct agentx_octet_str *str)
 {
-  return LOAD_U32(str->length);
+  return str->length;
 }
 
 /**
  * snmp_varbind_header_size - measure size of VarBind without data in bytes
- * @vb: VarBind to use
+ * @vb_name: VarBind OID name
  *
  * Return size including whole OID as well as the VarBind header.
  */
 uint
-snmp_varbind_header_size(const struct agentx_varbind *vb)
+snmp_varbind_header_size(const struct oid *vb_name)
 {
-  return snmp_varbind_hdr_size_from_oid(&vb->name);
+  ASSUME(vb_name);
+  return snmp_oid_size(vb_name) + OFFSETOF(struct agentx_varbind, name);
 }
 
+/*
+ * Beware that for octet string, using this function may be a bit tricky due to
+ * the different byte orders cpu native/packet
+ *
+ *
+ */
 uint
-snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
+snmp_varbind_size_unsafe(const struct agentx_varbind *vb, int is_pkt_bo)
 {
   ASSUME(snmp_test_varbind(vb));
 
-  enum agentx_type type = snmp_get_varbind_type(vb);
+  enum agentx_type type = (is_pkt_bo) ? LOAD_U16(vb->type) : vb->type;
   int value_size = agentx_type_size(type);
 
-  uint vb_header = snmp_varbind_header_size(vb);
+  uint vb_header = snmp_varbind_header_size(&vb->name);
 
   if (value_size == 0)
     return vb_header;
@@ -377,6 +338,7 @@ snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
 
     default:
       /* Shouldn't happen */
+      die("getting size of VarBind with unknown type (%u)", type);
       return 0;
   }
 }
@@ -392,7 +354,7 @@ snmp_varbind_size_unsafe(const struct agentx_varbind *vb)
 uint
 snmp_varbind_size(const struct agentx_varbind *vb, uint limit)
 {
-  ASSUME(snmp_test_varbind(vb));
+  //ASSUME(snmp_test_varbind(vb));
 
   if (limit < sizeof(struct agentx_varbind))
     return 0;
@@ -457,15 +419,12 @@ snmp_varbind_size_from_len(uint n_subid, enum agentx_type type, uint len)
 }
 
 /*
- * snmp_test_varbind - test validity of VarBind's type
- * @vb: VarBind to test
+ * snmp_test_varbind - test validity of VarBind type
+ * @type: Type of VarBind
  */
 int
-snmp_test_varbind(const struct agentx_varbind *vb)
+snmp_test_varbind(u16 type)
 {
-  ASSUME(vb);
-
-  u16 type = snmp_load_varbind_type(vb);
   if (type == AGENTX_INTEGER  ||
       type == AGENTX_OCTET_STRING  ||
       type == AGENTX_NULL  ||
@@ -506,7 +465,6 @@ struct agentx_varbind *
 snmp_create_varbind(byte *buf, struct oid *oid)
 {
   struct agentx_varbind *vb = (void *) buf;
-  STORE_U16(vb->reserved, 0);
   snmp_oid_copy(&vb->name, oid);
   return vb;
 }
@@ -519,7 +477,7 @@ snmp_create_varbind(byte *buf, struct oid *oid)
 int
 snmp_valid_ip4_index(const struct oid *o, uint start)
 {
-  if (start + 3 < LOAD_U8(o->n_subid))
+  if (start + 3 < o->n_subid)
     return snmp_valid_ip4_index_unsafe(o, start);
   else
     return 0;
@@ -537,7 +495,7 @@ int
 snmp_valid_ip4_index_unsafe(const struct oid *o, uint start)
 {
   for (int i = 0; i < 4; i++)
-    if (LOAD_U32(o->ids[start + i]) >= 256)
+    if (o->ids[start + i] >= 256)
       return 0;
 
   return 1;
@@ -561,7 +519,7 @@ snmp_put_nstr(byte *buf, const char *str, uint len)
 
   /* Insert zero padding in the gap at the end */
   for (uint i = 0; i < alen - len; i++)
-    STORE_U8(buf[i], '\0');
+    buf[i] = '\0';
 
   return buf + (alen - len);
 }
@@ -602,19 +560,6 @@ snmp_put_blank(byte *buf)
   return buf + 4;
 }
 
-/**
- * snmp_put_oid - put oid into SNMP PDU transcieve buffer
- * @buf: pointer to first free buffer byte
- * @oid: object identifier to use
- */
-byte *
-snmp_put_oid(byte *buf, struct oid *oid)
-{
-  struct oid *oid_buf = (void *) buf;
-  snmp_oid_copy(oid_buf, oid);
-  return buf + snmp_oid_size(oid);
-}
-
 /**
  * snmp_put_fbyte - put one padded byte to SNMP PDU transcieve buffer
  * @buf: pointer to free buffer byte
@@ -642,10 +587,10 @@ void
 snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr)
 {
   u32 temp = ip4_to_u32(addr);
-  STORE_U32(o->ids[start], temp >> 24);
-  STORE_U32(o->ids[start + 1], (temp >> 16) & 0xFF);
-  STORE_U32(o->ids[start + 2], (temp >>  8) & 0xFF);
-  STORE_U32(o->ids[start + 3], temp & 0xFF);
+  o->ids[start] = temp >> 24;
+  o->ids[start + 1] = (temp >> 16) & 0xFF;
+  o->ids[start + 2] = (temp >>  8) & 0xFF;
+  o->ids[start + 3] = temp & 0xFF;
 }
 
 
@@ -662,11 +607,11 @@ snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr)
 int
 snmp_oid_compare(const struct oid *left, const struct oid *right)
 {
-  const u8 left_subids = LOAD_U8(left->n_subid);
-  u8 right_subids = LOAD_U8(right->n_subid); /* see hack for more info */
+  const u8 left_subids = left->n_subid;
+  u8 right_subids = right->n_subid; /* see hack for more info */
 
-  const u8 left_prefix = LOAD_U8(left->prefix);
-  const u8 right_prefix = LOAD_U8(right->prefix);
+  const u8 left_prefix = left->prefix;
+  const u8 right_prefix = right->prefix;
 
   if (left_prefix == 0 && right_prefix == 0)
     goto test_ids;
@@ -679,7 +624,7 @@ snmp_oid_compare(const struct oid *left, const struct oid *right)
     uint bound = MIN((uint) left_subids, (uint) ARRAY_SIZE(snmp_internet));
     for (uint idx = 0; idx < bound; idx++)
     {
-      u32 id = LOAD_U32(left->ids[idx]);
+      u32 id = left->ids[idx];
       if (id < snmp_internet[idx])
        return -1;
       else if (id > snmp_internet[idx])
@@ -690,9 +635,9 @@ snmp_oid_compare(const struct oid *left, const struct oid *right)
       return -1;
 
     /* check prefix */
-    if (LOAD_U32(left->ids[4]) < (u32) right_prefix)
+    if (left->ids[4] < (u32) right_prefix)
       return -1;
-    else if (LOAD_U32(left->ids[4]) > (u32) right_prefix)
+    else if (left->ids[4] > (u32) right_prefix)
       return 1;
 
     /* the right prefix is already checked (+1) */
@@ -700,8 +645,8 @@ snmp_oid_compare(const struct oid *left, const struct oid *right)
       (int) right_subids);
     for (int i = 0; i < limit; i++)
     {
-      u32 left_id = LOAD_U32(left->ids[i + ARRAY_SIZE(snmp_internet) + 1]);
-      u32 right_id = LOAD_U32(right->ids[i]);
+      u32 left_id = left->ids[i + ARRAY_SIZE(snmp_internet + 1)];
+      u32 right_id = right->ids[i];
       if (left_id < right_id)
        return -1;
       else if (left_id > right_id)
@@ -723,8 +668,8 @@ snmp_oid_compare(const struct oid *left, const struct oid *right)
 test_ids:
   for (int i = 0; i < MIN(left->n_subid, right->n_subid); i++)
   {
-    u32 left_id = LOAD_U32(left->ids[i]);
-    u32 right_id = LOAD_U32(right->ids[i]);
+    u32 left_id = left->ids[i];
+    u32 right_id = right->ids[i];
     if (left_id < right_id)
       return -1;
     else if (left_id > right_id)
@@ -857,6 +802,7 @@ snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr)
   c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr);
 }
 
+#if 0
 inline byte *
 snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len)
 {
@@ -866,6 +812,7 @@ snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len)
   snmp_set_varbind_type(c->sr_vb_start, AGENTX_OCTET_STRING);
   return snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
 }
+#endif
 
 /*
  * snmp_varbind_nstr - fill varbind context with octet string
@@ -885,6 +832,19 @@ snmp_varbind_nstr(struct snmp_pdu *c, const char *str, uint len)
   c->buffer = snmp_put_nstr(snmp_varbind_data(c->sr_vb_start), str, len);
 }
 
+/*
+ * snmp_varbind_oid - fill VarBind data with OID @oid_val
+ * @oid_val - Object Identifier in cpu native byte order
+ *
+ * Function puts the @oid_val to the packet byte order.
+ */
+void
+snmp_varbind_oid(struct snmp_pdu *c, const struct oid *oid_val)
+{
+  snmp_set_varbind_type(c->sr_vb_start, AGENTX_OBJECT_IDENTIFIER);
+  snmp_oid_to_buf(snmp_varbind_data(c->sr_vb_start), oid_val);
+}
+
 inline enum agentx_type
 snmp_search_res_to_type(enum snmp_search_res r)
 {
@@ -983,65 +943,65 @@ snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct
 {
   ASSERT(left && right && out);
 
-  STORE_U8(out->include, 0);
-  STORE_U8(out->reserved, 0);
-  STORE_U8(out->prefix, 0);
+  out->include, 0;
+  out->reserved = 0;
+  out->prefix = 0;
 
   u32 offset = 0;
-  u8 left_ids = LOAD_U8(left->n_subid), right_ids = LOAD_U8(right->n_subid);
+  u8 left_ids = left->n_subid, right_ids = right->n_subid;
 
   int l = snmp_oid_is_prefixed(left), r = snmp_oid_is_prefixed(right);
   if (l && r)
   {
-    if (LOAD_U8(left->prefix) != LOAD_U8(right->prefix))
+    if (left->prefix != right->prefix)
     {
-      STORE_U8(out->n_subid, 4);
+      out->n_subid = 4;
 
       for (uint id = 0; id < ARRAY_SIZE(snmp_internet); id++)
-       STORE_U32(out->ids[id], snmp_internet[id]);
+       out->ids[id] = snmp_internet[id];
 
       return;
     }
 
-    STORE_U8(out->prefix, LOAD_U8(left->prefix));
+    out->prefix = left->prefix;
   }
   else if (!l && r)
   {
     if (left_ids == 0)
     {
       /* finish creating NULL OID */
-      STORE_U8(out->n_subid, 0);
+      out->n_subid = 0;
       return;
     }
 
     for (uint id = 0; id < MIN(ARRAY_SIZE(snmp_internet), left_ids); id++)
     {
-      if (LOAD_U32(left->ids[id]) != snmp_internet[id])
+      if (left->ids[id] != snmp_internet[id])
       {
-       STORE_U8(out->n_subid, id);
+       out->n_subid = id;
        return;
       }
 
-      STORE_U32(out->ids[id], snmp_internet[id]);
+      out->ids[id] = snmp_internet[id];
     }
 
     if (left_ids <= ARRAY_SIZE(snmp_internet))
     {
-      STORE_U8(out->n_subid, left_ids);
+      out->n_subid = left_ids;
       return;
     }
 
     /* index 4 is conresponding to the prefix in prefixed OID */
-    if (LOAD_U32(left->ids[4]) != (u32) LOAD_U8(right->prefix))
+    if (left->ids[4] != (u32) right->prefix)
     {
-      STORE_U8(out->n_subid, ARRAY_SIZE(snmp_internet));
+      out->n_subid = ARRAY_SIZE(snmp_internet);
       return;
     }
 
     /* delete snmp_internet from out->ids and store OID prefix */
     offset = ARRAY_SIZE(snmp_internet) + 1;
-    STORE_U8(out->n_subid, LOAD_U8(out->n_subid) - ARRAY_SIZE(snmp_internet));
-    STORE_U8(out->prefix, LOAD_U8(right->prefix));
+    out->n_subid = out->n_subid - ARRAY_SIZE(snmp_internet);
+    out->prefix = right->prefix;
   }
   else if (l && !r)
   {
@@ -1057,12 +1017,12 @@ snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct
     if (left->ids[offset + id] == right->ids[id])
     {
       subids++;
-      STORE_U32(out->ids[id], LOAD_U32(right->ids[id]));
+      out->ids[id] = right->ids[id];
     }
     else
       break;
   }
-  STORE_U8(out->n_subid, subids);
+  out->n_subid = subids;
 }
 
 /*
@@ -1115,15 +1075,15 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p
 
     found = !leaf->call_next(walk, c);
   }
-  else if (mib_node_is_leaf(node) && LOAD_U8(c->sr_vb_start->name.include))
+  else if (mib_node_is_leaf(node) && c->sr_vb_start->name.include)
   {
     found = 1;
-    STORE_U8(c->sr_vb_start->name.include, 0);
+    c->sr_vb_start->name.include = 0;
   }
 
   const struct oid *oid = &c->sr_vb_start->name;
-  u32 skip = (walk->id_pos < LOAD_U8(oid->n_subid)) ?
-    LOAD_U32(oid->ids[walk->id_pos]) : 0;
+  u32 skip = (walk->id_pos < oid->n_subid) ?
+    oid->ids[walk->id_pos] : 0;
   while (!found && (leaf = mib_tree_walk_next_leaf(tree, walk, skip)) != NULL)
   {
     /* mib_tree_walk_next() forces VarBind's name OID overwriting */
@@ -1141,8 +1101,8 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p
       found = 1;
 
     oid = &c->sr_vb_start->name;
-    skip = (walk->id_pos < LOAD_U8(oid->n_subid)) ?
-      LOAD_U32(oid->ids[walk->id_pos]) : 0;
+    skip = (walk->id_pos < oid->n_subid) ?
+      oid->ids[walk->id_pos] : 0;
   }
 
   if (!found)
@@ -1186,10 +1146,9 @@ snmp_walk_fill(struct mib_leaf *leaf, struct mib_walk_state *walk, struct snmp_p
   if (res != SNMP_SEARCH_OK)
     snmp_set_varbind_type(vb, snmp_search_res_to_type(res));
 
-  u16 type = snmp_load_varbind_type(vb);
+  u16 type = vb->type;
   ASSUME(type == leaf->type || type == AGENTX_END_OF_MIB_VIEW || type == AGENTX_NO_SUCH_OBJECT ||
     type == AGENTX_NO_SUCH_INSTANCE);
 
   return res;
 }
-
index 66fa1d37957d96b439ec19bad3f658e888c789bc..4ac86aa2ce72856d31c44426babf184854bc6b41 100644 (file)
@@ -16,7 +16,6 @@ uint snmp_pkt_len(const byte *start, const byte *end);
  *  AgentX - Variable Binding (VarBind) type utils
  */
 enum snmp_search_res snmp_set_varbind_type(struct agentx_varbind *vb, enum agentx_type t);
-enum agentx_type snmp_get_varbind_type(const struct agentx_varbind *vb);
 int agentx_type_size(enum agentx_type t);
 
 /* type Octet String */
@@ -32,6 +31,8 @@ void snmp_oid_copy(struct oid *dest, const struct oid *src);
 void snmp_oid_copy2(struct oid *dest, const struct oid *src);
 int snmp_oid_compare(const struct oid *first, const struct oid *second);
 void snmp_oid_common_ancestor(const struct oid *left, const struct oid *right, struct oid *result);
+void snmp_oid_from_buf(struct oid *dest, const struct oid *src);
+void snmp_oid_to_buf(struct oid *dest, const struct oid *src); 
 
 static inline int
 snmp_oid_is_prefixed(const struct oid *oid)
@@ -47,8 +48,7 @@ void snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr);
 /*
  *  AgentX - Variable Binding (VarBind) manupulation
  */
-uint snmp_varbind_hdr_size_from_oid(const struct oid *oid);
-uint snmp_varbind_header_size(const struct agentx_varbind *vb);
+uint snmp_varbind_header_size(const struct oid *vb_name);
 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);
@@ -81,6 +81,7 @@ void snmp_varbind_gauge32(struct snmp_pdu *c, s64 time);
 void snmp_varbind_ticks(struct snmp_pdu *c, u32 val);
 void snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr);
 void snmp_varbind_nstr(struct snmp_pdu *c, const char *str, uint len);
+void snmp_varbind_oid(struct snmp_pdu *c, const struct oid *oid_val);
 
 /* Raw */
 byte *snmp_no_such_object(byte *buf, struct agentx_varbind *vb, struct oid *oid);
@@ -88,7 +89,6 @@ byte *snmp_no_such_instance(byte *buf, struct agentx_varbind *vb, struct oid *oi
 byte *snmp_put_str(byte *buf, const char *str);
 byte *snmp_put_nstr(byte *buf, const char *str, uint len);
 byte *snmp_put_blank(byte *buf);
-byte *snmp_put_oid(byte *buf, struct oid *oid);
 byte *snmp_put_ip4(byte *buf, ip4_addr ip4);
 byte *snmp_put_fbyte(byte *buf, u8 data);
 
index af768a9d68a6d09c55edf33ae143980795f1f321..56f5420a90b11ecb9c3e696b71e9ec652967182c 100644 (file)
@@ -77,7 +77,7 @@ snmp_blank_header(struct agentx_header *h, enum agentx_pdu_types type)
  * snmp_register_ack - handle registration response
  * @p: SNMP protocol instance
  * @res: header of agentx-Response-PDU
- * @oid: MIB subtree Object Identifier
+ * @oid: MIB subtree Object Identifier in cpu native byte order
  */
 void
 snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struct oid *oid)
@@ -93,9 +93,9 @@ snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struc
       p->registrations_to_ack--;
 
       if (res->error == AGENTX_RES_NO_ERROR)
-       reg->reg_hook_ok(p, (const struct agentx_response *) res, reg);
+       reg->reg_hook_ok(p, res, reg);
       else
-       reg->reg_hook_fail(p, (const struct agentx_response *) res, reg);
+       reg->reg_hook_fail(p, res, reg);
 
       mb_free(reg->oid);
       mb_free(reg);
@@ -172,7 +172,8 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
   else /* p->timeout > 255 TO_US */
     c.buffer = snmp_put_fbyte(c.buffer, (u8) 255);
 
-  c.buffer = snmp_put_oid(c.buffer, oid);
+  snmp_oid_to_buf((struct oid *) c.buffer, oid);
+  c.buffer += snmp_oid_size(oid);
   c.buffer = snmp_put_str(c.buffer, cf->description);
 
   s = update_packet_size(h, c.buffer);
@@ -184,12 +185,12 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
  * send_notify_pdu - send an agentx-Notify-PDU
  * @p: SNMP protocol instance
  * @oid: PDU notification Varbind name (OID)
- * @data: PDU Varbind payload
- * @size: PDU Varbind payload size
- * @include_uptime: flag enabling inclusion of sysUpTime.0 OID
+ * @data: PDU VarBind payload in packet byte order
+ * @size: PDU VarBind payload size
+ * @include_up_time: flag enabling inclusion of sysUpTime.0 OID
  */
 void
-snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime)
+snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_up_time)
 {
   if (!snmp_is_active(p))
     return;
@@ -205,7 +206,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
   uint sz = AGENTX_HEADER_SIZE + TRAP0_HEADER_SIZE + snmp_oid_size(oid) \
     + size;
 
-  if (include_uptime)
+  if (include_up_time)
     sz += UPTIME_SIZE;
 
   /* Make sure that we have enough space in TX buffer */
@@ -217,7 +218,7 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
   p->packet_id++;   /* New packet id */
   snmp_session(p, h);
 
-  if (include_uptime)
+  if (include_up_time)
   {
     /* sysUpTime.0 oid */
     STATIC_OID(4) sys_up_time_0 = {
@@ -227,17 +228,19 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
       .reserved = 0,
       .ids = { SNMP_MIB_2, SNMP_SYSTEM, SNMP_SYS_UP_TIME, 0 },
     };
-    struct oid *uptime_0 = (struct oid *) &sys_up_time_0;
+    struct oid *up_time_0 = (struct oid *) &sys_up_time_0;
 
-    struct agentx_varbind *vb = snmp_create_varbind(c.buffer, uptime_0);
-    for (uint i = 0; i < uptime_0->n_subid; i++)
-      STORE_U32(vb->name.ids[i], uptime_0->ids[i]);
+    struct agentx_varbind *vb = (struct agentx_varbind *) c.buffer;
+    snmp_oid_to_buf(&vb->name, up_time_0);
 
     /* TODO use time from last reconfiguration instead? [config->load_time] */
     btime uptime = current_time() - boot_time;
     snmp_varbind_ticks(&c, (uptime TO_S) / 100);
-    ASSUME(snmp_test_varbind(vb));
     ADVANCE(c.buffer, c.size, snmp_varbind_size_unsafe(vb));
+    STORE_U16(vb->type, vb->type);
+    /* We do not need to call the snmp_varbind_leave() because we used
+     * the packet byte order in the first place.
+     */
   }
 
   /* snmpTrapOID.0 oid */
@@ -250,12 +253,15 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in
   };
   struct oid *trap_0 = (struct oid *) &snmp_trap_oid_0;
 
-  struct agentx_varbind *trap_vb = snmp_create_varbind(c.buffer, trap_0);
-  for (uint i = 0; i < trap_0->n_subid; i++)
-    STORE_U32(trap_vb->name.ids[i], trap_0->ids[i]);
-  trap_vb->type = AGENTX_OBJECT_ID;
-  snmp_put_oid(snmp_varbind_data(trap_vb), oid);
+  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);
   ADVANCE(c.buffer, c.size, snmp_varbind_size_unsafe(trap_vb));
+  STORE_U16(trap_vb, trap_vb);
+  /* We do not need to call the snmp_varbind_leave() because we used the packet
+   * byte order in the first place.
+   */
 
   memcpy(c.buffer, data, size);
   ADVANCE(c.buffer, c.size, size);
@@ -298,7 +304,6 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en
   snmp_pdu_context(&c, p, sk);
 
 #define BOUND_SIZE sizeof(u32)
-  /* conditional +4 for upper-bound (optinal field) */
   uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) +
       ((bound > 1) ? BOUND_SIZE : 0);
 
@@ -321,7 +326,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en
   STORE_U8(ur->reserved, 0);
   ADVANCE(c.buffer, c.size, sizeof(struct agentx_un_register_hdr));
 
-  (void) snmp_put_oid(c.buffer, oid);
+  snmp_oid_to_buf((struct oid *) c.buffer, oid);
   ADVANCE(c.buffer, c.size, snmp_oid_size(oid));
 
   /* place upper-bound if needed */
@@ -389,8 +394,8 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason)
   p->packet_id++;
   snmp_session(p, h);
 
-  snmp_put_fbyte(c.buffer, (u8) reason);
-  ADVANCE(c.buffer, c.size, 4);
+  (void) snmp_put_fbyte(c.buffer, (u8) reason);
+  ADVANCE(c.buffer, c.size, REASON_SIZE);
 
   uint s = update_packet_size(h, c.buffer);
   sk_send(sk, s);
@@ -466,6 +471,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
   uint s; /* final packat size */
   struct agentx_response *res; /* pointer to reponse in TX buffer */
 
+  /* Presence of full header is guaranteed by parse_pkt() caller */
   struct agentx_header *h = (void *) pkt;
   pkt += AGENTX_HEADER_SIZE;
 
@@ -492,11 +498,13 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start)
   }
   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);
   }
   else
   {
-    TRACE(D_PACKETS, "SNMP SET action failed (not writable)");
+    // 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);
   }
@@ -517,6 +525,7 @@ static uint
 parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_response_errs err)
 {
   byte *pkt = pkt_start;
+  /* Presence of full header is guaranteed by parse_pkt() caller */
   struct agentx_header *h = (void *) pkt;
   pkt += AGENTX_HEADER_SIZE;
   uint pkt_size = LOAD_U32(h->payload);
@@ -525,8 +534,8 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons
   {
     TRACE(D_PACKETS, "SNMP received malformed set PDU (size)");
     snmp_simple_response(p, AGENTX_RES_PARSE_ERROR, 0);
-    // TODO best solution for possibly malicious pkt_size
-    return AGENTX_HEADER_SIZE;
+    snmp_reset(p);
+    return 0;
   }
 
   struct snmp_pdu c;
@@ -546,7 +555,10 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons
 
   /* Reset the connection on unrecoverable error */
   if (c.error != AGENTX_RES_NO_ERROR && c.error != err)
+  {
     snmp_reset(p);    /* error */
+    return 0;
+  }
 
   return pkt - pkt_start;
 }
@@ -593,11 +605,6 @@ parse_undo_set_pdu(struct snmp_proto *p, byte *pkt)
 static uint
 parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start)
 {
-  TRACE(D_PACKETS, "SNMP received agentx-CleanupSet-PDU");
-  (void)p;
-  // TODO don't forget to free resources allocated by parse_test_set_pdu()
-  //mb_free(p->tr);
-
   byte *pkt = pkt_start;
   struct agentx_header *h = (void *) pkt;
   uint pkt_size = LOAD_U32(h->payload);
@@ -605,11 +612,16 @@ parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start)
   /* errors are dropped silently, we must not send any agentx-Response-PDU */
   if (pkt_size != 0)
   {
-    // TODO should we free even for malformed packets ??
-    // TODO -> check that data is not freed
     return AGENTX_HEADER_SIZE;
+    TRACE(D_PACKET, "SNMP received malformed agentx-CleanupSet-PDU");
+    snmp_reset(p);
+    return 0;
   }
 
+  TRACE(D_PACKETS, "SNMP received agentx-CleanupSet-PDU");
+  (void)p;
+  // TODO don't forget to free resources allocated by parse_test_set_pdu()
+  //mb_free(p->tr);
   /* No agentx-Response-PDU is sent in response to agentx-CleanupSet-PDU */
   return pkt_size;
 }
@@ -734,7 +746,7 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size)
 
     default:
       /* We reset the connection for malformed packet (Unknown packet type) */
-      TRACE(D_PACKETS, "SNMP received unknown packet with type %u", LOAD_U8(h->type));
+      TRACE(D_PACKETS, "SNMP received unknown packet type (%u)", LOAD_U8(h->type));
       snmp_reset(p);
       return 0;
   }
@@ -770,7 +782,10 @@ parse_response(struct snmp_proto *p, byte *res)
       // TODO more direct path to mib-specific code
       TRACE(D_PACKETS, "SNMP received agentx-Response-PDU with error %u", r->error);
       byte *pkt = res + sizeof(struct agentx_response);
-      struct oid *failed = (struct oid *) pkt;
+      const struct oid *failed_buf = (struct oid *) pkt;
+      uint failed_size = snmp_oid_size(failed_buf);
+      struct oid *failed = tmp_alloc(failed_size);
+      snmp_oid_from_buf(failed, failed_buf);
       snmp_register_ack(p, r, failed);
       break;
 
@@ -841,7 +856,10 @@ do_response(struct snmp_proto *p, byte *pkt)
     case SNMP_REGISTER:;
       pkt += AGENTX_HEADER_SIZE;
 
-      const struct oid *oid = (struct oid *) pkt;
+      const struct oid *oid_buf = (struct oid *) pkt;
+      uint oid_size = snmp_oid_size(oid_buf);
+      struct oid *oid = tmp_alloc(oid_size);
+      snmp_oid_from_buf(oid, oid_buf);
       snmp_register_ack(p, r, oid);
 
       if (p->registrations_to_ack == 0)
@@ -859,33 +877,44 @@ do_response(struct snmp_proto *p, byte *pkt)
   }
 }
 
-static inline struct oid *
+/*
+ * snmp_oid_prefixize_unsafe - normalize OID to prefixed form
+ * @dest: destination for normalized OID in native byte order
+ * @src: source OID in packet byte order
+ *
+ * Note that again, snmp_oid_prefixize_unsafe is intended to copy Object
+ * Identifier from RX buffer to TX buffer but also optionally swap the byte
+ * order from packet b.o. to cpu native b.o. This is done to simplify the code
+ * dealing with OIDs.
+ */
+static inline void
 snmp_oid_prefixize_unsafe(struct oid *dest, const struct oid *src)
 {
-  u8 subids = LOAD_U8(src->n_subid) - 5;
-  dest->n_subid = subids;
-  STORE_U8(dest->prefix, (u8) LOAD_U32(src->ids[ARRAY_SIZE(snmp_internet)]));
-  STORE_U8(dest->include, (LOAD_U8(src->include)) ? 1 : 0);
-  STORE_U8(dest->reserved, 0);
+  dest->n_subid = LOAD_U8(src->n_subid) - 5;
+  dest->prefix = (u8) LOAD_U32(src->ids[ARRAY_SIZE(snmp_internet)]);
+  dest->include = (LOAD_U8(src->include)) ? 1 : 0;
+  dest->reserved = 0;
 
   /* The LOAD_U32() and STORE_U32() cancel out */
-  memcpy(&dest->ids[0], &src->ids[5], subids * sizeof(u32));
+  for (i = 0; i < dest->n_subid; i++)
+    dest->ids[i] = LOAD_U32(src->ids[i + 5]);
 
   return dest;
 }
 
 /*
- * snmp_vb_to_tx - create varbind from RX buffer OID
+ * snmp_vb_to_tx - create VarBind in TX buffer from RX buffer OID
  * @c: PDU context
- * @oid: object identifier located in RX buffer
+ * @oid: Object Identifier located in RX buffer with packet byte order
  *
- * Create NULL initialized VarBind inside TX buffer (from @c) whose vb->name is
- * @oid. The @oid prefixed if possible. The result is stored in @c->sr_vb_start.
+ * Create a NULL initialized VarBind inside TX buffer (from @c) whose name
+ * 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
 snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid)
 {
-  uint vb_hdr_size = snmp_varbind_hdr_size_from_oid(oid);
+  uint vb_hdr_size = snmp_varbind_header_size(oid);
   (void) snmp_tbuf_reserve(c, vb_hdr_size);
 
   ASSERT(c->size >= vb_hdr_size);
@@ -898,32 +927,43 @@ snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid)
   {
     u8 subids = LOAD_U8(oid->n_subid) - 5;
     ADVANCE(c->buffer, c->size, snmp_oid_size_from_len(subids));
-    (void) snmp_oid_prefixize_unsafe(&vb->name, oid);
+    snmp_oid_prefixize_unsafe(&vb->name, oid);
 
     c->sr_vb_start = vb;
     return;
   }
 
   ADVANCE(c->buffer, c->size, snmp_oid_size(oid));
-  snmp_oid_copy2(&vb->name, oid);
+  snmp_oid_from_buf(&vb->name, oid);
 
   c->sr_vb_start = vb;
 }
 
 /*
- * snmp_fix_vb - fix VarBind's name OID byte order
- * @vb: VarBind to use
+ * snmp_varbind_leave - transform VarBind to packet byte order
+ * @vb: prepared VarBind in cpu native byte order
  */
 void
-snmp_fix_vb(struct agentx_varbind *vb)
+snmp_varbind_leave(struct agentx_varbind *vb)
 {
-  snmp_oid_copy(&vb->name, &vb->name);
+  STORE_U16(vb->type, vb->type);
+
+  /* Does nothing */
+  STORE_U16(vb->reserved, 0);
+  struct oid *oid = &vb->name;
+  STORE_U8(oid->n_subid, oid->n_subid);
+  STORE_U8(oid->prefix, oid->prefix);
+  STORE_U8(oid->include, oid->include);
+  STORE_U8(oid->reserved, 0);
+
+  for (u8 i = 0; i < oid->n_subid; i++)
+    STORE_U32(oid->ids[i], oid->ids[i]);
 }
 
 /*
  * update_packet_size - set PDU size
- * @start - pointer to PDU data start (excluding header size)
- * @end - pointer after the last PDU byte
+ * @start: pointer to PDU data start (excluding header size)
+ * @end: pointer after the last PDU byte
  *
  * Return number of bytes in TX buffer (including header size).
  */
@@ -952,17 +992,17 @@ response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_
   // TODO deal with auto-incrementing of snmp_pdu context c.ind
   if (err != AGENTX_RES_NO_ERROR && err != AGENTX_RES_GEN_ERROR)
   {
-    TRACE(D_PACKETS, "Last PDU resulted in error %u", err);
+    //TRACE(D_PACKETS, "Last PDU resulted in error %u", err);
     STORE_U16(res->index, ind);
-    TRACE(D_PACKETS, "Storing packet size %u (was %u)", sizeof(struct agentx_response) - AGENTX_HEADER_SIZE, LOAD_U32(res->h.payload));
+    /* Reset VarBindList to null */
     STORE_U32(res->h.payload,
       sizeof(struct agentx_response) - AGENTX_HEADER_SIZE);
   }
   else if (err == AGENTX_RES_GEN_ERROR)
   {
-    TRACE(D_PACKETS, "Last PDU resulted in error %u genErr", err);
+    //TRACE(D_PACKETS, "Last PDU resulted in error %u genErr", err);
     STORE_U16(res->index, 0);
-    TRACE(D_PACKETS, "Storing packet size %u (was %u)", sizeof(struct agentx_response) - AGENTX_HEADER_SIZE, LOAD_U32(res->h.payload));
+    /* Reset VarBindList to null */
     STORE_U32(res->h.payload,
       sizeof(struct agentx_response) - AGENTX_HEADER_SIZE);
   }
index 3c90da14029bbe4c5feb9aca9450434147ffb268..a2c0807a441bc619d225600c1685ada43f6a8c97 100644 (file)
@@ -138,26 +138,6 @@ enum agentx_flags {
 #define LOAD_PTR(src)        get_u32(ptr)
 #endif
 
-#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) ({                                 \
-  length = LOAD_PTR(buf);                                                    \
-  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)                                         \
-  ({                                                                         \
-    struct agentx_varbind *vb = (void *) buf;                                \
-    SNMP_FILL_VARBIND(vb, oid);                                                      \
-  })
-
-#define SNMP_FILL_VARBIND(vb, oid)                                           \
-  snmp_oid_copy(&(vb)->name, (oid)), snmp_oid_size((oid))
-
 struct agentx_header {
   u8 version;
   u8 type;
@@ -189,25 +169,31 @@ struct oid {
     u32 ids[sbids];                                                          \
   }
 
-#define VALUE_U32_HELPER(x) VALUE_U32(x),
 #define STATIC_OID_INITIALIZER(sbids, pref, ...)                             \
   {                                                                          \
-    .n_subid = VALUE_U8(sbids),                                                      \
-    .prefix = VALUE_U8(pref),                                                \
-    .include = VALUE_U8(0),                                                  \
-    .reserved = VALUE_U8(0),                                                 \
-    .ids = { MACRO_FOREACH(VALUE_U32_HELPER, __VA_ARGS__) },                 \
+    .n_subid = sbids,                                                        \
+    .prefix = pref,                                                          \
+    .include = 0,                                                            \
+    .reserved = 0,                                                           \
+    .ids = { __VA_ARGS__ },                                                  \
   }
 
 /* enforced by MIB tree, see mib_tree.h for more info */
 #define OID_MAX_LEN 32
 
+/*
+ * AgentX VarBind -- Variable Binding
+ * During the processing of the VarBind, the fields @type and @name are in cpu
+ * native byte order. This should be fixed by running snmp_varbind_leave()
+ * before VarBind control pointer abondonment or before packet transmission.
+ * The data following the structure should always follow the packet byte order.
+ */
 struct agentx_varbind {
   u16 type;
   u16 reserved; /* always zero filled */
   /* oid part */
   struct oid name;
-  /* AgentX variable binding data optionaly here */
+  /* AgentX variable binding data optionally here */
 };
 
 struct agentx_search_range {