/**
 * @file
 * MIB tree access/construction functions.
 */

/*
 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * Author: Christiaan Simons <christiaan.simons@axon.tv>
 */

#include "lwip/opt.h"

#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */

#include "lwip/snmp_structs.h"
#include "lwip/mem.h"

/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */
const s32_t prefix[4] = {1, 3, 6, 1};

#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN)
/** node stack entry (old news?) */
struct nse
{
  /** right child */
  struct mib_node* r_ptr;
  /** right child identifier */
  s32_t r_id;
  /** right child next level */
  u8_t r_nl;
};
static u8_t node_stack_cnt;
static struct nse node_stack[NODE_STACK_SIZE];

/**
 * Pushes nse struct onto stack.
 */
static void
push_node(struct nse* node)
{
  LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE);
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id));
  if (node_stack_cnt < NODE_STACK_SIZE)
  {
    node_stack[node_stack_cnt] = *node;
    node_stack_cnt++;
  }
}

/**
 * Pops nse struct from stack.
 */
static void
pop_node(struct nse* node)
{
  if (node_stack_cnt > 0)
  {
    node_stack_cnt--;
    *node = node_stack[node_stack_cnt];
  }
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id));
}

/**
 * Conversion from ifIndex to lwIP netif
 * @param ifindex is a s32_t object sub-identifier
 * @param netif points to returned netif struct pointer
 */
void
snmp_ifindextonetif(s32_t ifindex, struct netif **netif)
{
  struct netif *nif = netif_list;
  u16_t i, ifidx;

  ifidx = ifindex - 1;
  i = 0;
  while ((nif != NULL) && (i < ifidx))
  {
    nif = nif->next;
    i++;
  }
  *netif = nif;
}

/**
 * Conversion from lwIP netif to ifIndex
 * @param netif points to a netif struct
 * @param ifidx points to s32_t object sub-identifier
 */
void
snmp_netiftoifindex(struct netif *netif, s32_t *ifidx)
{
  struct netif *nif = netif_list;
  u16_t i;

  i = 0;
  while ((nif != NULL) && (nif != netif))
  {
    nif = nif->next;
    i++;
  }
  *ifidx = i+1;
}

/**
 * Conversion from oid to lwIP ip_addr
 * @param ident points to s32_t ident[4] input
 * @param ip points to output struct
 */
void
snmp_oidtoip(s32_t *ident, struct ip_addr *ip)
{
  u32_t ipa;

  ipa = ident[0];
  ipa <<= 8;
  ipa |= ident[1];
  ipa <<= 8;
  ipa |= ident[2];
  ipa <<= 8;
  ipa |= ident[3];
  ip->addr = ipa;
}

/**
 * Conversion from lwIP ip_addr to oid
 * @param ip points to input struct
 * @param ident points to s32_t ident[4] output
 */
void
snmp_iptooid(struct ip_addr *ip, s32_t *ident)
{
  u32_t ipa;

  ipa = ip->addr;
  ident[0] = (ipa >> 24) & 0xff;
  ident[1] = (ipa >> 16) & 0xff;
  ident[2] = (ipa >> 8) & 0xff;
  ident[3] = ipa & 0xff;
}

struct mib_list_node *
snmp_mib_ln_alloc(s32_t id)
{
  struct mib_list_node *ln;

  ln = (struct mib_list_node *)mem_malloc(sizeof(struct mib_list_node));
  if (ln != NULL)
  {
    ln->prev = NULL;
    ln->next = NULL;
    ln->objid = id;
    ln->nptr = NULL;
  }
  return ln;
}

void
snmp_mib_ln_free(struct mib_list_node *ln)
{
  mem_free(ln);
}

struct mib_list_rootnode *
snmp_mib_lrn_alloc(void)
{
  struct mib_list_rootnode *lrn;

  lrn = (struct mib_list_rootnode*)mem_malloc(sizeof(struct mib_list_rootnode));
  if (lrn != NULL)
  {
    lrn->get_object_def = noleafs_get_object_def;
    lrn->get_value = noleafs_get_value;
    lrn->set_test = noleafs_set_test;
    lrn->set_value = noleafs_set_value;
    lrn->node_type = MIB_NODE_LR;
    lrn->maxlength = 0;
    lrn->head = NULL;
    lrn->tail = NULL;
    lrn->count = 0;
  }
  return lrn;
}

void
snmp_mib_lrn_free(struct mib_list_rootnode *lrn)
{
  mem_free(lrn);
}

/**
 * Inserts node in idx list in a sorted
 * (ascending order) fashion and
 * allocates the node if needed.
 *
 * @param rn points to the root node
 * @param objid is the object sub identifier
 * @param insn points to a pointer to the inserted node
 *   used for constructing the tree.
 * @return -1 if failed, 1 if inserted, 2 if present.
 */
s8_t
snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn)
{
  struct mib_list_node *nn;
  s8_t insert;

  LWIP_ASSERT("rn != NULL",rn != NULL);

  /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */
  insert = 0;
  if (rn->head == NULL)
  {
    /* empty list, add first node */
    LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid));
    nn = snmp_mib_ln_alloc(objid);
    if (nn != NULL)
    {
      rn->head = nn;
      rn->tail = nn;
      *insn = nn;
      insert = 1;
    }
    else
    {
      insert = -1;
    }
  }
  else
  {
    struct mib_list_node *n;
    /* at least one node is present */
    n = rn->head;
    while ((n != NULL) && (insert == 0))
    {
      if (n->objid == objid)
      {
        /* node is already there */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid));
        *insn = n;
        insert = 2;
      }
      else if (n->objid < objid)
      {
        if (n->next == NULL)
        {
          /* alloc and insert at the tail */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid));
          nn = snmp_mib_ln_alloc(objid);
          if (nn != NULL)
          {
            nn->next = NULL;
            nn->prev = n;
            n->next = nn;
            rn->tail = nn;
            *insn = nn;
            insert = 1;
          }
          else
          {
            /* insertion failure */
            insert = -1;
          }
        }
        else
        {
          /* there's more to explore: traverse list */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n"));
          n = n->next;
        }
      }
      else
      {
        /* n->objid > objid */
        /* alloc and insert between n->prev and n */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid));
        nn = snmp_mib_ln_alloc(objid);
        if (nn != NULL)
        {
          if (n->prev == NULL)
          {
            /* insert at the head */
            nn->next = n;
            nn->prev = NULL;
            rn->head = nn;
            n->prev = nn;
          }
          else
          {
            /* insert in the middle */
            nn->next = n;
            nn->prev = n->prev;
            n->prev->next = nn;
            n->prev = nn;
          }
          *insn = nn;
          insert = 1;
        }
        else
        {
          /* insertion failure */
          insert = -1;
        }
      }
    }
  }
  if (insert == 1)
  {
    rn->count += 1;
  }
  LWIP_ASSERT("insert != 0",insert != 0);
  return insert;
}

/**
 * Finds node in idx list and returns deletion mark.
 *
 * @param rn points to the root node
 * @param objid  is the object sub identifier
 * @param fn returns pointer to found node
 * @return 0 if not found, 1 if deletable,
 *   2 can't delete (2 or more children), 3 not a list_node
 */
s8_t
snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn)
{
  s8_t fc;
  struct mib_list_node *n;

  LWIP_ASSERT("rn != NULL",rn != NULL);
  n = rn->head;
  while ((n != NULL) && (n->objid != objid))
  {
    n = n->next;
  }
  if (n == NULL)
  {
    fc = 0;
  }
  else if (n->nptr == NULL)
  {
    /* leaf, can delete node */
    fc = 1;
  }
  else
  {
    struct mib_list_rootnode *r;

    if (n->nptr->node_type == MIB_NODE_LR)
    {
      r = (struct mib_list_rootnode *)n->nptr;
      if (r->count > 1)
      {
        /* can't delete node */
        fc = 2;
      }
      else
      {
        /* count <= 1, can delete node */
        fc = 1;
      }
    }
    else
    {
      /* other node type */
      fc = 3;
    }
  }
  *fn = n;
  return fc;
}

/**
 * Removes node from idx list
 * if it has a single child left.
 *
 * @param rn points to the root node
 * @param n points to the node to delete
 * @return the nptr to be freed by caller
 */
struct mib_list_rootnode *
snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n)
{
  struct mib_list_rootnode *next;

  LWIP_ASSERT("rn != NULL",rn != NULL);
  LWIP_ASSERT("n != NULL",n != NULL);

  /* caller must remove this sub-tree */
  next = (struct mib_list_rootnode*)(n->nptr);
  rn->count -= 1;

  if (n == rn->head)
  {
    rn->head = n->next;
    if (n->next != NULL)
    {
      /* not last node, new list begin */
      n->next->prev = NULL;
    }
  }
  else if (n == rn->tail)
  {
    rn->tail = n->prev;
    if (n->prev != NULL)
    {
      /* not last node, new list end */
      n->prev->next = NULL;
    }
  }
  else
  {
    /* node must be in the middle */
    n->prev->next = n->next;
    n->next->prev = n->prev;
  }
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid));
  snmp_mib_ln_free(n);
  if (rn->count == 0)
  {
    rn->head = NULL;
    rn->tail = NULL;
  }
  return next;
}



/**
 * Searches tree for the supplied (scalar?) object identifier.
 *
 * @param node points to the root of the tree ('.internet')
 * @param ident_len the length of the supplied object identifier
 * @param ident points to the array of sub identifiers
 * @param np points to the found object instance (rerurn)
 * @return pointer to the requested parent (!) node if success, NULL otherwise
 */
struct mib_node *
snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np)
{
  u8_t node_type, ext_level;

  ext_level = 0;
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident));
  while (node != NULL)
  {
    node_type = node->node_type;
    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      u16_t i;

      if (ident_len > 0)
      {
        /* array node (internal ROM or RAM, fixed length) */
        an = (struct mib_array_node *)node;
        i = 0;
        while ((i < an->maxlength) && (an->objid[i] != *ident))
        {
          i++;
        }
        if (i < an->maxlength)
        {
          /* found it, if available proceed to child, otherwise inspect leaf */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
          if (an->nptr[i] == NULL)
          {
            /* a scalar leaf OR table,
               inspect remaining instance number / table index */
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)an;
          }
          else
          {
            /* follow next child pointer */
            ident++;
            ident_len--;
            node = an->nptr[i];
          }
        }
        else
        {
          /* search failed, identifier mismatch (nosuchname) */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if(node_type == MIB_NODE_LR)
    {
      struct mib_list_rootnode *lrn;
      struct mib_list_node *ln;

      if (ident_len > 0)
      {
        /* list root node (internal 'RAM', variable length) */
        lrn = (struct mib_list_rootnode *)node;
        ln = lrn->head;
        /* iterate over list, head to tail */
        while ((ln != NULL) && (ln->objid != *ident))
        {
          ln = ln->next;
        }
        if (ln != NULL)
        {
          /* found it, proceed to child */;
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
          if (ln->nptr == NULL)
          {
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)lrn;
          }
          else
          {
            /* follow next child pointer */
            ident_len--;
            ident++;
            node = ln->nptr;
          }
        }
        else
        {
          /* search failed */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if(node_type == MIB_NODE_EX)
    {
      struct mib_external_node *en;
      u16_t i, len;

      if (ident_len > 0)
      {
        /* external node (addressing and access via functions) */
        en = (struct mib_external_node *)node;

        i = 0;
        len = en->level_length(en->addr_inf,ext_level);
        while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0))
        {
          i++;
        }
        if (i < len)
        {
          s32_t debug_id;

          en->get_objid(en->addr_inf,ext_level,i,&debug_id);
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident));
          if ((ext_level + 1) == en->tree_levels)
          {
            np->ident_len = ident_len;
            np->ident = ident;
            return (struct mib_node*)en;
          }
          else
          {
            /* found it, proceed to child */
            ident_len--;
            ident++;
            ext_level++;
          }
        }
        else
        {
          /* search failed */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident));
          return NULL;
        }
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n"));
        return NULL;
      }
    }
    else if (node_type == MIB_NODE_SC)
    {
      mib_scalar_node *sn;

      sn = (mib_scalar_node *)node;
      if ((ident_len == 1) && (*ident == 0))
      {
        np->ident_len = ident_len;
        np->ident = ident;
        return (struct mib_node*)sn;
      }
      else
      {
        /* search failed, short object identifier (nosuchname) */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n"));
        return NULL;
      }
    }
    else
    {
      /* unknown node_type */
      LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type));
      return NULL;
    }
  }
  /* done, found nothing */
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node));
  return NULL;
}

/**
 * Test table for presence of at least one table entry.
 */
static u8_t
empty_table(struct mib_node *node)
{
  u8_t node_type;
  u8_t empty = 0;

  if (node != NULL)
  {
    node_type = node->node_type;
    if (node_type == MIB_NODE_LR)
    {
      struct mib_list_rootnode *lrn;
      lrn = (struct mib_list_rootnode *)node;
      if ((lrn->count == 0) || (lrn->head == NULL))
      {
        empty = 1;
      }
    }
    else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      an = (struct mib_array_node *)node;
      if ((an->maxlength == 0) || (an->nptr == NULL))
      {
        empty = 1;
      }
    }
    else if (node_type == MIB_NODE_EX)
    {
      struct mib_external_node *en;
      en = (struct mib_external_node *)node;
      if (en->tree_levels == 0)
      {
        empty = 1;
      }
    }
  }
  return empty;
}

/**
 * Tree expansion.
 */
struct mib_node *
snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
{
  u8_t node_type, ext_level, climb_tree;

  ext_level = 0;
  /* reset node stack */
  node_stack_cnt = 0;
  while (node != NULL)
  {
    climb_tree = 0;
    node_type = node->node_type;
    if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA))
    {
      struct mib_array_node *an;
      u16_t i;

      /* array node (internal ROM or RAM, fixed length) */
      an = (struct mib_array_node *)node;
      if (ident_len > 0)
      {
        i = 0;
        while ((i < an->maxlength) && (an->objid[i] < *ident))
        {
          i++;
        }
        if (i < an->maxlength)
        {
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident));
          /* add identifier to oidret */
          oidret->id[oidret->len] = an->objid[i];
          (oidret->len)++;

          if (an->nptr[i] == NULL)
          {
            LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
            /* leaf node (e.g. in a fixed size table) */
            if (an->objid[i] > *ident)
            {
              return (struct mib_node*)an;
            }
            else if ((i + 1) < an->maxlength)
            {
              /* an->objid[i] == *ident */
              (oidret->len)--;
              oidret->id[oidret->len] = an->objid[i + 1];
              (oidret->len)++;
              return (struct mib_node*)an;
            }
            else
            {
              /* (i + 1) == an->maxlength */
              (oidret->len)--;
              climb_tree = 1;
            }
          }
          else
          {
            u8_t j;
            struct nse cur_node;

            LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
            /* non-leaf, store right child ptr and id */
            j = i + 1;
            while ((j < an->maxlength) && (empty_table(an->nptr[j])))
            {
              j++;
            }
            if (j < an->maxlength)
            {
              cur_node.r_ptr = an->nptr[j];
              cur_node.r_id = an->objid[j];
              cur_node.r_nl = 0;
            }
            else
            {
              cur_node.r_ptr = NULL;
            }
            push_node(&cur_node);
            if (an->objid[i] == *ident)
            {
              ident_len--;
              ident++;
            }
            else
            {
              /* an->objid[i] < *ident */
              ident_len = 0;
            }
            /* follow next child pointer */
            node = an->nptr[i];
          }
        }
        else
        {
          /* i == an->maxlength */
          climb_tree = 1;
        }
      }
      else
      {
        u8_t j;
        /* ident_len == 0, complete with leftmost '.thing' */
        j = 0;
        while ((j < an->maxlength) && empty_table(an->nptr[j]))
        {
          j++;
        }
        if (j < an->maxlength)
        {
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j]));
          oidret->id[oidret->len] = an->objid[j];
          (oidret->len)++;
          if (an->nptr[j] == NULL)
          {
            /* leaf node */
            return (struct mib_node*)an;
          }
          else
          {
            /* no leaf, continue */
            node = an->nptr[j];
          }
        }
        else
        {
          /* j == an->maxlength */
          climb_tree = 1;
        }
      }
    }
    else if(node_type == MIB_NODE_LR)
    {
      struct mib_list_rootnode *lrn;
      struct mib_list_node *ln;

      /* list root node (internal 'RAM', variable length) */
      lrn = (struct mib_list_rootnode *)node;
      if (ident_len > 0)
      {
        ln = lrn->head;
        /* iterate over list, head to tail */
        while ((ln != NULL) && (ln->objid < *ident))
        {
          ln = ln->next;
        }
        if (ln != NULL)
        {
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident));
          oidret->id[oidret->len] = ln->objid;
          (oidret->len)++;
          if (ln->nptr == NULL)
          {
            /* leaf node */
            if (ln->objid > *ident)
            {
              return (struct mib_node*)lrn;
            }
            else if (ln->next != NULL)
            {
              /* ln->objid == *ident */
              (oidret->len)--;
              oidret->id[oidret->len] = ln->next->objid;
              (oidret->len)++;
              return (struct mib_node*)lrn;
            }
            else
            {
              /* ln->next == NULL */
              (oidret->len)--;
              climb_tree = 1;
            }
          }
          else
          {
            struct mib_list_node *jn;
            struct nse cur_node;

            /* non-leaf, store right child ptr and id */
            jn = ln->next;
            while ((jn != NULL) && empty_table(jn->nptr))
            {
              jn = jn->next;
            }
            if (jn != NULL)
            {
              cur_node.r_ptr = jn->nptr;
              cur_node.r_id = jn->objid;
              cur_node.r_nl = 0;
            }
            else
            {
              cur_node.r_ptr = NULL;
            }
            push_node(&cur_node);
            if (ln->objid == *ident)
            {
              ident_len--;
              ident++;
            }
            else
            {
              /* ln->objid < *ident */
              ident_len = 0;
            }
            /* follow next child pointer */
            node = ln->nptr;
          }

        }
        else
        {
          /* ln == NULL */
          climb_tree = 1;
        }
      }
      else
      {
        struct mib_list_node *jn;
        /* ident_len == 0, complete with leftmost '.thing' */
        jn = lrn->head;
        while ((jn != NULL) && empty_table(jn->nptr))
        {
          jn = jn->next;
        }
        if (jn != NULL)
        {
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid));
          oidret->id[oidret->len] = jn->objid;
          (oidret->len)++;
          if (jn->nptr == NULL)
          {
            /* leaf node */
            LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n"));
            return (struct mib_node*)lrn;
          }
          else
          {
            /* no leaf, continue */
            node = jn->nptr;
          }
        }
        else
        {
          /* jn == NULL */
          climb_tree = 1;
        }
      }
    }
    else if(node_type == MIB_NODE_EX)
    {
      struct mib_external_node *en;
      s32_t ex_id;

      /* external node (addressing and access via functions) */
      en = (struct mib_external_node *)node;
      if (ident_len > 0)
      {
        u16_t i, len;

        i = 0;
        len = en->level_length(en->addr_inf,ext_level);
        while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0))
        {
          i++;
        }
        if (i < len)
        {
          /* add identifier to oidret */
          en->get_objid(en->addr_inf,ext_level,i,&ex_id);
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident));
          oidret->id[oidret->len] = ex_id;
          (oidret->len)++;

          if ((ext_level + 1) == en->tree_levels)
          {
            LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n"));
            /* leaf node */
            if (ex_id > *ident)
            {
              return (struct mib_node*)en;
            }
            else if ((i + 1) < len)
            {
              /* ex_id == *ident */
              en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id);
              (oidret->len)--;
              oidret->id[oidret->len] = ex_id;
              (oidret->len)++;
              return (struct mib_node*)en;
            }
            else
            {
              /* (i + 1) == len */
              (oidret->len)--;
              climb_tree = 1;
            }
          }
          else
          {
            u8_t j;
            struct nse cur_node;

            LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n"));
            /* non-leaf, store right child ptr and id */
            j = i + 1;
            if (j < len)
            {
              /* right node is the current external node */
              cur_node.r_ptr = node;
              en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id);
              cur_node.r_nl = ext_level + 1;
            }
            else
            {
              cur_node.r_ptr = NULL;
            }
            push_node(&cur_node);
            if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0)
            {
              ident_len--;
              ident++;
            }
            else
            {
              /* external id < *ident */
              ident_len = 0;
            }
            /* proceed to child */
            ext_level++;
          }
        }
        else
        {
          /* i == len (en->level_len()) */
          climb_tree = 1;
        }
      }
      else
      {
        /* ident_len == 0, complete with leftmost '.thing' */
        en->get_objid(en->addr_inf,ext_level,0,&ex_id);
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id));
        oidret->id[oidret->len] = ex_id;
        (oidret->len)++;
        if ((ext_level + 1) == en->tree_levels)
        {
          /* leaf node */
          LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n"));
          return (struct mib_node*)en;
        }
        else
        {
          /* no leaf, proceed to child */
          ext_level++;
        }
      }
    }
    else if(node_type == MIB_NODE_SC)
    {
      mib_scalar_node *sn;

      /* scalar node  */
      sn = (mib_scalar_node *)node;
      if (ident_len > 0)
      {
        /* at .0 */
        climb_tree = 1;
      }
      else
      {
        /* ident_len == 0, complete object identifier */
        oidret->id[oidret->len] = 0;
        (oidret->len)++;
        /* leaf node */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n"));
        return (struct mib_node*)sn;
      }
    }
    else
    {
      /* unknown/unhandled node_type */
      LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type));
      return NULL;
    }

    if (climb_tree)
    {
      struct nse child;

      /* find right child ptr */
      child.r_ptr = NULL;
      child.r_id = 0;
      child.r_nl = 0;
      while ((node_stack_cnt > 0) && (child.r_ptr == NULL))
      {
        pop_node(&child);
        /* trim returned oid */
        (oidret->len)--;
      }
      if (child.r_ptr != NULL)
      {
        /* incoming ident is useless beyond this point */
        ident_len = 0;
        oidret->id[oidret->len] = child.r_id;
        oidret->len++;
        node = child.r_ptr;
        ext_level = child.r_nl;
      }
      else
      {
        /* tree ends here ... */
        LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n"));
        return NULL;
      }
    }
  }
  /* done, found nothing */
  LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node));
  return NULL;
}

/**
 * Test object identifier for the iso.org.dod.internet prefix.
 *
 * @param ident_len the length of the supplied object identifier
 * @param ident points to the array of sub identifiers
 * @return 1 if it matches, 0 otherwise
 */
u8_t
snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
{
  if ((ident_len > 3) &&
      (ident[0] == 1) && (ident[1] == 3) &&
      (ident[2] == 6) && (ident[3] == 1))
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

/**
 * Expands object identifier to the iso.org.dod.internet
 * prefix for use in getnext operation.
 *
 * @param ident_len the length of the supplied object identifier
 * @param ident points to the array of sub identifiers
 * @param oidret points to returned expanded object identifier
 * @return 1 if it matches, 0 otherwise
 *
 * @note ident_len 0 is allowed, expanding to the first known object id!!
 */
u8_t
snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret)
{
  const s32_t *prefix_ptr;
  s32_t *ret_ptr;
  u8_t i;

  i = 0;
  prefix_ptr = &prefix[0];
  ret_ptr = &oidret->id[0];
  ident_len = ((ident_len < 4)?ident_len:4);
  while ((i < ident_len) && ((*ident) <= (*prefix_ptr)))
  {
    *ret_ptr++ = *prefix_ptr++;
    ident++;
    i++;
  }
  if (i == ident_len)
  {
    /* match, complete missing bits */
    while (i < 4)
    {
      *ret_ptr++ = *prefix_ptr++;
      i++;
    }
    oidret->len = i;
    return 1;
  }
  else
  {
    /* i != ident_len */
    return 0;
  }
}

#endif /* LWIP_SNMP */
