Example #1
0
static int
agentx_open(void)
{
  struct x_pdu_buf x_pdu;
  const char *descr = "SmartSNMP AgentX sub-agent";

  /* Send agentX open PDU */
  x_pdu = agentx_open_pdu(&agentx_datagram, NULL, 0, descr, strlen(descr));
  if (send(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0) == -1) {
    SMARTSNMP_LOG(L_ERROR, "Send agentX open PDU failure!\n");
    return -1;
  }

  /* Receive agentX open response PDU */
  x_pdu.len = TRANS_BUF_SIZ;
  x_pdu.buf = xrealloc(x_pdu.buf, x_pdu.len);
  x_pdu.len = recv(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0);
  if (x_pdu.len == -1) {
    SMARTSNMP_LOG(L_ERROR, "Receive agentX open response PDU failure!\n");
    return -1;
  }

  /* Verify open response PDU */
  if (agentx_recv(x_pdu.buf, x_pdu.len) != AGENTX_ERR_OK) {
    SMARTSNMP_LOG(L_ERROR, "Parse agentX open response PDU error!\n");
    return -1;
  }

  return 0;
}
Example #2
0
static int
agentx_close(void)
{
  struct x_pdu_buf x_pdu;

  /* Send agentX close PDU */
  x_pdu = agentx_close_pdu(&agentx_datagram, R_SHUTDOWN);
  if (send(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0) == -1) {
    SMARTSNMP_LOG(L_ERROR, "Send agentX close PDU failure!\n");
    return -1;
  }

  /* Receive agentX close response PDU */
  x_pdu.len = TRANS_BUF_SIZ;
  x_pdu.buf = xrealloc(x_pdu.buf, x_pdu.len);
  x_pdu.len = recv(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0);
  if (x_pdu.len == -1) {
    SMARTSNMP_LOG(L_ERROR, "Receive agentX close response PDU failure!\n");
    return -1;
  }

  /* Verify close response PDU */
  if (agentx_recv(x_pdu.buf, x_pdu.len) != AGENTX_ERR_OK) {
    SMARTSNMP_LOG(L_ERROR, "Parse agentX close response PDU error!\n");
    return -1;
  }
  
  return 0;
}
Example #3
0
/* Register one instance node in mib-tree according to given oid with lua callback. */
int
mib_node_reg(const oid_t *oid, uint32_t len, int callback)
{
  int i;
  struct mib_instance_node *in;

  assert(oid != NULL);

  mib_tree_init_check();

  /* Prefix must match root oid */
  if (len == 0) {
    SMARTSNMP_LOG(L_WARNING, "The register group node oid cannot be empty\n");
    return -1;
  }

  if (len > MIB_OID_MAX_LEN) {
    SMARTSNMP_LOG(L_WARNING, "The register group oid cannot be longer than %d\n", MIB_OID_MAX_LEN);
    return -1;
  }

  in = mib_tree_instance_insert(oid, len, callback);
  if (in == NULL) {
    SMARTSNMP_LOG(L_WARNING, "Register group node oid: ");
    for (i = 0; i < len; i++) {
      SMARTSNMP_LOG(L_WARNING, "%d ", oid[i]);
    }
    SMARTSNMP_LOG(L_WARNING, "fail, node already exists or oid overlaps.\n");
    return -1;
  }

  return 0;
}
Example #4
0
/* Decode agentx datagram */
static AGENTX_ERR_CODE_E
agentx_decode(struct agentx_datagram *xdg)
{
  AGENTX_ERR_CODE_E err;
  uint8_t *buf, dec_fail = 0;

  buf = xdg->recv_buf;

  /* PDU header */
  err = pdu_hdr_parse(xdg, &buf);
  if (err) {
    SMARTSNMP_LOG(L_ERROR, "ERR(%d): %s\n", err, error_message(agentx_err_msg, elem_num(agentx_err_msg), err));
    dec_fail = 1;
    goto DECODE_FINISH;
  }

  /* varbind or search range */
  switch (xdg->pdu_hdr.type) {
  case AGENTX_PDU_GET:
  case AGENTX_PDU_GETNEXT:
  case AGENTX_PDU_GETBULK:
    /* search range */
    err = search_range_parse(xdg, &buf);
    if (err) {
      SMARTSNMP_LOG(L_ERROR, "ERR(%d): %s\n", err, error_message(agentx_err_msg, elem_num(agentx_err_msg), err));
      dec_fail = 1;
    }
    break;
  case AGENTX_PDU_TESTSET:
  case AGENTX_PDU_RESPONSE:
    /* var bind */
    err = var_bind_parse(xdg, &buf);
    if (err) {
      SMARTSNMP_LOG(L_ERROR, "ERR(%d): %s\n", err, error_message(agentx_err_msg, elem_num(agentx_err_msg), err));
      dec_fail = 1;
    }
    break;
  default:
    break;
  }

DECODE_FINISH:
  /* If fail, do some clear things */
  if (dec_fail) {
    agentx_datagram_clear(xdg);
  }

  /* We should free received buf here */
  free(xdg->recv_buf);

  return err;
}
Example #5
0
/* Parse search range */
static AGENTX_ERR_CODE_E
search_range_parse(struct agentx_datagram *xdg, uint8_t **buffer)
{
  AGENTX_ERR_CODE_E err;
  uint8_t *buf;

  err = AGENTX_ERR_OK;
  buf = *buffer;

  while (xdg->pdu_hdr.payload_length > 0) {
    /* Alloc a new search range and add into search range list. */
    struct x_search_range *sr = search_range_alloc(&buf, xdg->pdu_hdr.flags, &err);
    if (sr == NULL) {
      SMARTSNMP_LOG(L_ERROR, "ERR(%d): %s\n", err, error_message(agentx_err_msg, elem_num(agentx_err_msg), err));
      *buffer = buf;
      break;
    }
    list_add_tail(&sr->link, &xdg->sr_in_list);
    xdg->sr_in_cnt++;
    xdg->pdu_hdr.payload_length -= buf - *buffer;
    *buffer = buf;
  }

  return err;
}
Example #6
0
/* Parse varbind */
static AGENTX_ERR_CODE_E
var_bind_parse(struct agentx_datagram *xdg, uint8_t **buffer)
{
  AGENTX_ERR_CODE_E err;
  uint8_t *buf;

  err = AGENTX_ERR_OK;
  buf = *buffer;

  while (xdg->pdu_hdr.payload_length > 0) {
    /* Alloc a new var_bind and add into var_bind list. */
    struct x_var_bind *vb = var_bind_alloc(&buf, xdg->pdu_hdr.flags, &err);
    if (vb == NULL) {
      SMARTSNMP_LOG(L_ERROR, "ERR(%d): %s\n", err, error_message(agentx_err_msg, elem_num(agentx_err_msg), err));
      *buffer = buf;
      break;
    }
    list_add_tail(&vb->link, &xdg->vb_in_list);
    xdg->vb_in_cnt++;
    xdg->pdu_hdr.payload_length -= buf - *buffer;
    *buffer = buf;
  }

  return err;
}
Example #7
0
/* Unregister mib group node */
static int
agentx_mib_node_unreg(const oid_t *grp_id, int id_len)
{
  struct x_pdu_buf x_pdu;

  /* Check oid prefix */
  if (id_len < 4 || grp_id[0] != 1 || grp_id[1] != 3 || grp_id[2] != 6 || grp_id[3] != 1) {
    SMARTSNMP_LOG(L_ERROR, "Oid prefix must be .1.3.6.1!");
    return -1;
  }

  /* Send angentX register PDU */
  x_pdu = agentx_unregister_pdu(&agentx_datagram, grp_id, id_len, NULL, 0, 0, 127, 0, 0);
  if (send(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0) == -1) {
    SMARTSNMP_LOG(L_ERROR, "Send agentX unregister PDU failure!");
    return -1;
  }

  /* Receive agentX response PDU */
  x_pdu.len = TRANS_BUF_SIZ;
  x_pdu.buf = xrealloc(x_pdu.buf, x_pdu.len);
  x_pdu.len = recv(agentx_datagram.sock, x_pdu.buf, x_pdu.len, 0);
  if (x_pdu.len == -1) {
    SMARTSNMP_LOG(L_ERROR, "Receive agentX unregister response PDU failure!\n");
    return -1;
  }

  /* Verify register response PDU */
  if (agentx_recv(x_pdu.buf, x_pdu.len) != AGENTX_ERR_OK) {
    SMARTSNMP_LOG(L_ERROR, "Unregister response error!");
    return -1;
  }

  /* Unregister node */
  mib_node_unreg(grp_id, id_len);
  return 0;
}
Example #8
0
/* Remove sub-node(s) in mib-tree. */
static void
__mib_tree_delete(struct node_pair *pair)
{
  struct node_backlog nbl, *p_nbl;
  struct node_backlog nbl_stk[MIB_OID_MAX_LEN];
  struct node_backlog *stk_top, *stk_buttom;

  struct mib_node *node = pair->child;
  struct mib_group_node *gn;
  struct mib_instance_node *in;

  if (node == (struct mib_node *)&mib_dummy_node) {
    SMARTSNMP_LOG(L_WARNING, "MIB dummy root node cannot be deleted!\n");
    return;
  }

  /* Init something */
  p_nbl = NULL;
  stk_top = stk_buttom = nbl_stk;

  for (; ;) {

    if (node != NULL)
    switch (node->type) {

      case MIB_OBJ_GROUP:
        gn = (struct mib_group_node *)node;

        int i;
        if (p_nbl != NULL) {
          /* Fetch the sub-id next to the pop-up backlogged one. */
          i = p_nbl->n_idx;
          p_nbl = NULL;
        } else {
          /* Fetch the first sub-id. */
          i = 0;
        }

        if (i == -1) {
          /* Sub-tree is empty, delete this node and go on backtracking */
          mib_group_node_delete(gn);
          break;
        }

        if (i + 1 >= gn->sub_id_cnt) {
          /* Last sub-id, mark n_idx = -1. */
          nbl.n_idx = -1;
        } else {
          nbl.n_idx = i + 1;
        }
        nbl.node = node;

        /* Backlog the current node and move down. */
        nbl_push(&nbl, &stk_top, &stk_buttom);
        node = gn->sub_ptr[i++];
        continue;

      case MIB_OBJ_INSTANCE:
        in = (struct mib_instance_node *)node;
        mib_instance_node_delete(in);
        break;

      default :
        assert(0);
    }

    /* Backtracking */
    p_nbl = nbl_pop(&stk_top, &stk_buttom);
    if (p_nbl == NULL) {
      /* End of traversal. */
      group_node_shrink((struct mib_group_node *)pair->parent, pair->sub_idx);
      return;
    }
    node = p_nbl->node;
  }
}
Example #9
0
/* Embedded code is not funny at all... */
int
mib_instance_search(struct oid_search_res *ret_oid)
{
  int i;
  Variable *var = &ret_oid->var;
  lua_State *L = mib_lua_state;

  /* Empty lua stack. */
  lua_pop(L, -1);
  /* Get function. */
  lua_rawgeti(L, LUA_ENVIRONINDEX, ret_oid->callback);
  /* op */
  lua_pushinteger(L, ret_oid->request);
  /* req_sub_oid */
  lua_newtable(L);
  for (i = 0; i < ret_oid->inst_id_len; i++) {
    lua_pushinteger(L, ret_oid->inst_id[i]);
    lua_rawseti(L, -2, i + 1);
  }

  if (ret_oid->request == MIB_REQ_SET) {
    /* req_val */
    switch (tag(var)) {
      case ASN1_TAG_INT:
        lua_pushinteger(L, integer(var));
        break;
      case ASN1_TAG_OCTSTR:
        lua_pushlstring(L, octstr(var), length(var));
        break;
      case ASN1_TAG_CNT:
        lua_pushnumber(L, count(var));
        break;
      case ASN1_TAG_IPADDR:
        lua_pushlstring(L, (char *)ipaddr(var), length(var));
        break;
      case ASN1_TAG_OBJID:
        lua_newtable(L);
        for (i = 0; i < length(var); i++) {
          lua_pushnumber(L, oid(var)[i]);
          lua_rawseti(L, -2, i + 1);
        }
        break;
      case ASN1_TAG_GAU:
        lua_pushnumber(L, gauge(var));
        break;
      case ASN1_TAG_TIMETICKS:
        lua_pushnumber(L, timeticks(var));
        break;
      default:
        lua_pushnil(L);
        break;
    }
    /* req_val_type */
    lua_pushinteger(L, tag(var));
  } else {
    /* req_val */
    lua_pushnil(L);
    /* req_val_type */
    lua_pushnil(L);
  }

  if (lua_pcall(L, 4, 4, 0) != 0) {
    SMARTSNMP_LOG(L_ERROR, "MIB search hander %d fail: %s\n", ret_oid->callback, lua_tostring(L, -1));
    tag(var) = ASN1_TAG_NO_SUCH_OBJ;
    return 0;
  }

  ret_oid->err_stat = lua_tointeger(L, -4);
  tag(var) = lua_tonumber(L, -1);

  if (!ret_oid->err_stat && MIB_TAG_VALID(tag(var))) {
    /* Return value */
    if (ret_oid->request != MIB_REQ_SET) {
      switch (tag(var)) {
        case ASN1_TAG_INT:
          length(var) = 1;
          integer(var) = lua_tointeger(L, -2);
          break;
        case ASN1_TAG_OCTSTR:
          length(var) = lua_objlen(L, -2);
          memcpy(octstr(var), lua_tostring(L, -2), length(var));
          break;
        case ASN1_TAG_CNT:
          length(var) = 1;
          count(var) = lua_tonumber(L, -2);
          break;
        case ASN1_TAG_IPADDR:
          length(var) = lua_objlen(L, -2);
          for (i = 0; i < length(var); i++) {
            lua_rawgeti(L, -2, i + 1);
            ipaddr(var)[i] = lua_tointeger(L, -1);
            lua_pop(L, 1);
          }
          break;
        case ASN1_TAG_OBJID:
          length(var) = lua_objlen(L, -2);
          for (i = 0; i < length(var); i++) {
            lua_rawgeti(L, -2, i + 1);
            oid(var)[i] = lua_tointeger(L, -1);
            lua_pop(L, 1);
          }
          break;
        case ASN1_TAG_GAU:
          length(var) = 1;
          gauge(var) = lua_tonumber(L, -2);
          break;
        case ASN1_TAG_TIMETICKS:
          length(var) = 1;
          timeticks(var) = lua_tonumber(L, -2);
          break;
        default:
          assert(0);
      }
    }

    /* For GETNEXT request, return the new oid */
    if (ret_oid->request == MIB_REQ_GETNEXT) {
      ret_oid->inst_id_len = lua_objlen(L, -3);
      for (i = 0; i < ret_oid->inst_id_len; i++) {
        lua_rawgeti(L, -3, i + 1);
        ret_oid->inst_id[i] = lua_tointeger(L, -1);
        lua_pop(L, 1);
      }
    }
  }

  return ret_oid->err_stat;
}
Example #10
0
/* Remove sub-node(s) in mib-tree. */
static void
__mib_tree_delete(struct node_pair *pair)
{
  struct node_backlog *p_nbl;
  struct node_backlog nbl_stack[ASN1_OID_MAX_LEN];
  struct node_backlog *top;

  struct mib_node *node = pair->child;
  struct mib_group_node *gn;
  struct mib_instance_node *in;

  if (node == (struct mib_node *)&mib_dummy_node) {
    SMARTSNMP_LOG(L_WARNING, "MIB dummy root node cannot be deleted!\n");
    return;
  }

  /* Init something */
  p_nbl = NULL;
  top = nbl_stack;

  for (; ;) {

    if (node != NULL)
    switch (node->type) {
    case MIB_OBJ_GROUP:
      gn = (struct mib_group_node *)node;

      /* Fetch the sub-id of the backlogged node. */
      int i = p_nbl != NULL ? p_nbl->n_idx : 0;
      /* n_idx is not reusable */
      p_nbl = NULL;

      if (i == -1) {
        /* Sub-tree is empty, delete this node and go on backtracking */
        mib_group_node_delete(gn);
        break;
      }

      /* If last sub-id, mark n_idx = -1. */
      top->n_idx = i + 1 >= gn->sub_id_cnt ? -1 : i + 1;
      top->node = node;
      top++;

      node = gn->sub_ptr[i++];
      continue;

    case MIB_OBJ_INSTANCE:
      in = (struct mib_instance_node *)node;
      mib_instance_node_delete(in);
      break;

    default :
      assert(0);
    }

    /* Backtracking */
    p_nbl = top == nbl_stack ? NULL : --top;
    if (p_nbl == NULL) {
      /* End of traversal. */
      group_node_shrink((struct mib_group_node *)pair->parent, pair->sub_idx);
      return;
    }
    node = p_nbl->node;
  }
}