Exemple #1
0
void genControlInfo(int* oid,
                    size_t oid_size,
                    QueryData& results,
                    const std::map<std::string, std::string>& config) {
  // Get control size
  size_t response_size = CTL_MAX_VALUE;
  char response[CTL_MAX_VALUE + 1] = {0};
    if (sysctl(oid, oid_size, response, &response_size, 0, 0) != 0) {
      // Cannot request MIB data.
      return;
    }

    // Data is output, but no way to determine type (long, int, string, struct).
  Row r;
  r["oid"] = stringFromMIB(oid, oid_size);
  r["current_value"] = std::string(response);
  r["type"] = "string";
  results.push_back(r);
}
Exemple #2
0
void genControlInfo(int* oid,
                    size_t oid_size,
                    QueryData& results,
                    const std::map<std::string, std::string>& config) {
  Row r;
  if (oid_size == 0) {
    return;
  }

  r["oid"] = stringFromMIB(oid, oid_size);
  // Request the description (the canonical name) for the MIB.
  char response[CTL_MAX_VALUE] = {0};
  size_t response_size = CTL_MAX_VALUE;

  int request[CTL_MAXNAME + 2] = {0, CTL_DEBUG_DESCRIPTION};
  memcpy(request + 2, oid, oid_size * sizeof(int));
  if (sysctl(request, oid_size + 2, response, &response_size, 0, 0) != 0) {
    return;
  }

  r["name"] = std::string(response);
  if (oid[0] > 0 && oid[0] < static_cast<int>(kControlNames.size())) {
    r["subsystem"] = kControlNames[oid[0]];
  }

  // Now request structure type.
  request[1] = CTL_DEBUG_TYPE;
  if (sysctl(request, oid_size + 2, response, &response_size, 0, 0) != 0) {
    // Cannot request MIB type (int, string, struct, etc).
    return;
  }

  size_t oid_type = 0;
  if (response_size > 0) {
    oid_type = ((size_t)response[0] & CTLTYPE);
    if (oid_type < kControlTypes.size()) {
      r["type"] = kControlTypes[((int)response[0])];
    }
  }

  // Finally request MIB value.
  if (oid_type > CTLTYPE_NODE && oid_type < CTLTYPE_OPAQUE) {
    size_t value_size = 0;
    sysctl(oid, oid_size, 0, &value_size, 0, 0);

    if (value_size > CTL_MAX_VALUE) {
      // If the value size is larger than the max value, limit.
      value_size = CTL_MAX_VALUE;
    }

    sysctl(oid, oid_size, response, &value_size, 0, 0);
    if (oid_type == CTLTYPE_INT) {
      unsigned int value;
      memcpy(&value, response, sizeof(int));
      r["current_value"] = INTEGER(value);
    } else if (oid_type == CTLTYPE_STRING) {
      r["current_value"] = std::string(response);
    } else if (oid_type == CTLTYPE_QUAD) {
      unsigned long long value;
      memcpy(&value, response, value_size);
    }
  }

  // If this MIB was set using sysctl.conf add the value.
  if (config.count(r.at("name")) > 0) {
    r["config_value"] = config.at(r["name"]);
  }

  results.push_back(r);
}
Exemple #3
0
void genControlInfo(int* oid,
                    size_t oid_size,
                    QueryData& results,
                    const std::map<std::string, std::string>& config) {
  Row r;
  if (oid_size == 0) {
    return;
  }

  r["oid"] = stringFromMIB(oid, oid_size);
  // Request the description (the canonical name) for the MIB.
  char response[CTL_MAX_VALUE] = {0};
  size_t response_size = CTL_MAX_VALUE;

  int request[CTL_MAXNAME + 2] = {0, CTL_DEBUG_DESCRIPTION};
  memcpy(request + 2, oid, oid_size * sizeof(int));
  if (sysctl(request, oid_size + 2, response, &response_size, 0, 0) != 0) {
    return;
  }

  r["name"] = std::string(response);
  if (oid[0] > 0 && oid[0] < static_cast<int>(kControlNames.size())) {
    r["subsystem"] = kControlNames[oid[0]];
  }

  // Now request structure type.
  response_size = CTL_MAX_VALUE;
  request[1] = CTL_DEBUG_TYPE;
  if (sysctl(request, oid_size + 2, response, &response_size, 0, 0) != 0) {
    // Cannot request MIB type (int, string, struct, etc).
    return;
  }

  size_t oid_type = 0;
  if (response_size > 0) {
    oid_type = ((size_t)response[0] & CTLTYPE);
    if ((oid_type == 0 || oid_type == CTLTYPE_INT) && response_size > 4) {
      // For whatever reason, macOS defines fewer CTLTYPE's than BSD, and
      // sometimes uses the format character instead of (or in addition to)
      // the CTLTYPE to specify the type. Here we detect a few such cases and
      // map them to CTLTYPE's.
      // TODO: Both CTLTYPE_INT and CTLTYPE_QUAD can be specified as unsigned
      // using a similar method.
      char type_char = response[4];
      switch (type_char) {
      case 'I':
        oid_type = CTLTYPE_INT;
        break;
      case 'L':
        if (sizeof(long) == sizeof(long long)) {
          oid_type = CTLTYPE_QUAD;
        } else if (sizeof(long) == sizeof(int)) {
          oid_type = CTLTYPE_INT;
        }
        break;
      case 'S':
        oid_type = CTLTYPE_STRUCT;
        break;
      case 'Q':
        oid_type = CTLTYPE_QUAD;
        break;
        // Otherwise leave the type as it was; we have no additional knowledge
      }
    }
    if (oid_type < kControlTypes.size()) {
      r["type"] = kControlTypes[oid_type];
    }
  }

  // Finally request MIB value.
  if (oid_type > CTLTYPE_NODE && oid_type < CTLTYPE_OPAQUE) {
    size_t value_size = 0;
    sysctl(oid, oid_size, 0, &value_size, 0, 0);

    if (value_size > CTL_MAX_VALUE) {
      // If the value size is larger than the max value, limit.
      value_size = CTL_MAX_VALUE;
    }

    sysctl(oid, oid_size, response, &value_size, 0, 0);
    if (oid_type == CTLTYPE_INT) {
      unsigned int value;
      memcpy(&value, response, sizeof(int));
      r["current_value"] = INTEGER(value);
    } else if (oid_type == CTLTYPE_STRING) {
      r["current_value"] = std::string(response);
    } else if (oid_type == CTLTYPE_QUAD) {
      unsigned long long value;
      memcpy(&value, response, sizeof(unsigned long long));
      r["current_value"] = INTEGER(value);
    }
  }

  // If this MIB was set using sysctl.conf add the value.
  if (config.count(r.at("name")) > 0) {
    r["config_value"] = config.at(r["name"]);
  }

  results.push_back(r);
}