209 lines
8.2 KiB
C
209 lines
8.2 KiB
C
#include <net-snmp/net-snmp-config.h>
|
|
#include <net-snmp/net-snmp-includes.h>
|
|
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
#include <net-snmp/agent/hardware/sensors.h>
|
|
#include "hardware/sensors/hw_sensors.h"
|
|
#include "ucd-snmp/lmsensorsMib.h"
|
|
|
|
netsnmp_container *sensorContainer = NULL;
|
|
|
|
static void initialize_lmSensorsTable(const char *tableName,
|
|
const oid *tableOID,
|
|
netsnmp_container_op *filter,
|
|
int mult);
|
|
|
|
static int _sensor_filter_temp( netsnmp_container *c, const void *v );
|
|
static int _sensor_filter_fan( netsnmp_container *c, const void *v );
|
|
static int _sensor_filter_volt( netsnmp_container *c, const void *v );
|
|
static int _sensor_filter_misc( netsnmp_container *c, const void *v );
|
|
|
|
static const oid lmTempSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,2};
|
|
static const oid lmFanSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,3};
|
|
static const oid lmVoltSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,4};
|
|
static const oid lmMiscSensorsTable_oid[] = {1,3,6,1,4,1,2021,13,16,5};
|
|
/* All the tables have the same length root OID */
|
|
const size_t lmSensorsTables_oid_len = OID_LENGTH(lmMiscSensorsTable_oid);
|
|
|
|
|
|
/* Initialise the LM Sensors MIB module */
|
|
void
|
|
init_lmsensorsMib(void)
|
|
{
|
|
DEBUGMSGTL(("ucd-snmp/lmsensorsMib","Initializing LM-SENSORS-MIB tables\n"));
|
|
|
|
/*
|
|
* Initialise the four LM-SENSORS-MIB tables
|
|
*
|
|
* They are almost identical, so we can use the same registration code.
|
|
*/
|
|
initialize_lmSensorsTable( "lmTempSensorsTable", lmTempSensorsTable_oid,
|
|
_sensor_filter_temp, 1000 ); /* MIB asks for mC */
|
|
initialize_lmSensorsTable( "lmFanSensorsTable", lmFanSensorsTable_oid,
|
|
_sensor_filter_fan, 1);
|
|
initialize_lmSensorsTable( "lmVoltSensorsTable", lmVoltSensorsTable_oid,
|
|
_sensor_filter_volt, 1000 ); /* MIB asks for mV */
|
|
initialize_lmSensorsTable( "lmMiscSensorsTable", lmMiscSensorsTable_oid,
|
|
_sensor_filter_misc, 1 );
|
|
}
|
|
|
|
/*
|
|
* Common initialisation code, used for setting up all four tables
|
|
*/
|
|
void
|
|
initialize_lmSensorsTable(const char *tableName, const oid *tableOID,
|
|
netsnmp_container_op *filter, int mult )
|
|
{
|
|
netsnmp_handler_registration *reg;
|
|
netsnmp_table_registration_info *table_info;
|
|
netsnmp_cache *cache;
|
|
netsnmp_container *container;
|
|
|
|
/*
|
|
* Ensure the HAL sensors module has been initialised,
|
|
* and retrieve the main sensors container.
|
|
* This table will then be registered using a filter on this container.
|
|
*/
|
|
sensorContainer = get_sensor_container();
|
|
if ( !sensorContainer ) {
|
|
init_hw_sensors( );
|
|
sensorContainer = get_sensor_container();
|
|
}
|
|
container = netsnmp_container_find("sensorTable:table_container");
|
|
container->insert_filter = filter;
|
|
netsnmp_container_add_index( sensorContainer, container );
|
|
|
|
|
|
/*
|
|
* Create a basic registration structure for the table
|
|
*/
|
|
reg = netsnmp_create_handler_registration(
|
|
tableName, lmSensorsTables_handler,
|
|
tableOID, lmSensorsTables_oid_len, HANDLER_CAN_RONLY
|
|
);
|
|
|
|
/*
|
|
* Register the table using the filtered container
|
|
* Include an indicator of any scaling to be applied to the sensor value
|
|
*/
|
|
reg->my_reg_void = (void *)(uintptr_t)mult;
|
|
table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
|
|
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
|
|
table_info->min_column = COLUMN_LMSENSORS_INDEX;
|
|
table_info->max_column = COLUMN_LMSENSORS_VALUE;
|
|
netsnmp_container_table_register( reg, table_info, container, 0 );
|
|
|
|
/*
|
|
* If the HAL sensors module was configured as an on-demand caching
|
|
* module (rather than being automatically loaded regularly),
|
|
* then ensure this table makes use of that cache.
|
|
*/
|
|
cache = get_sensor_cache();
|
|
if ( cache ) {
|
|
netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get( cache ),
|
|
"table_container");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Container filters for the four tables
|
|
*
|
|
* Used to ensure that sensor entries appear in the appropriate table.
|
|
*/
|
|
int _sensor_filter_temp( netsnmp_container *c, const void *v ) {
|
|
const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
|
|
/* Only matches temperature sensors */
|
|
return (( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) ? 0 : 1 );
|
|
}
|
|
|
|
int _sensor_filter_fan( netsnmp_container *c, const void *v ) {
|
|
const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
|
|
/* Only matches fan sensors */
|
|
return (( sp->type == NETSNMP_SENSOR_TYPE_RPM ) ? 0 : 1 );
|
|
}
|
|
|
|
int _sensor_filter_volt( netsnmp_container *c, const void *v ) {
|
|
const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
|
|
/* Only matches voltage sensors (AC or DC) */
|
|
return ((( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC ) ||
|
|
( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC )) ? 0 : 1 );
|
|
}
|
|
|
|
int _sensor_filter_misc( netsnmp_container *c, const void *v ) {
|
|
const netsnmp_sensor_info *sp = (const netsnmp_sensor_info *)v;
|
|
/* Matches everything except temperature, fan or voltage sensors */
|
|
return ((( sp->type == NETSNMP_SENSOR_TYPE_TEMPERATURE ) ||
|
|
( sp->type == NETSNMP_SENSOR_TYPE_RPM ) ||
|
|
( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_DC ) ||
|
|
( sp->type == NETSNMP_SENSOR_TYPE_VOLTAGE_AC )) ? 1 : 0 );
|
|
}
|
|
|
|
|
|
/*
|
|
* Handle requests for any of the four lmXxxxSensorsTables
|
|
*
|
|
* This is possible because all the table share the
|
|
* same structure and behaviour.
|
|
*/
|
|
int
|
|
lmSensorsTables_handler(
|
|
netsnmp_mib_handler *handler,
|
|
netsnmp_handler_registration *reginfo,
|
|
netsnmp_agent_request_info *reqinfo,
|
|
netsnmp_request_info *requests) {
|
|
|
|
netsnmp_request_info *request;
|
|
netsnmp_table_request_info *table_info;
|
|
netsnmp_sensor_info *sensor_info;
|
|
int mult = (uintptr_t)reginfo->my_reg_void;
|
|
|
|
DEBUGMSGTL(( "ucd-snmp/lmsensorsMib","lmSensorsTables_handler - root: "));
|
|
DEBUGMSGOID(("ucd-snmp/lmsensorsMib", reginfo->rootoid, reginfo->rootoid_len));
|
|
DEBUGMSG(( "ucd-snmp/lmsensorsMib",", mode %d\n", reqinfo->mode ));
|
|
/*
|
|
* This is a read-only table, so we only need to handle GET requests.
|
|
* (The container helper converts GETNEXT->GET requests automatically).
|
|
*/
|
|
switch (reqinfo->mode) {
|
|
case MODE_GET:
|
|
for (request=requests; request; request=request->next) {
|
|
sensor_info = (netsnmp_sensor_info *)
|
|
netsnmp_container_table_extract_context(request);
|
|
if ( !sensor_info ) {
|
|
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
|
|
continue;
|
|
}
|
|
|
|
table_info = netsnmp_extract_table_info(request);
|
|
switch (table_info->colnum) {
|
|
case COLUMN_LMSENSORS_INDEX:
|
|
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
|
|
sensor_info->idx.oids[0]);
|
|
break;
|
|
case COLUMN_LMSENSORS_DEVICE:
|
|
if ( sensor_info->descr[0] != '\0' ) {
|
|
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
|
|
sensor_info->descr, strlen(sensor_info->descr));
|
|
} else {
|
|
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
|
|
sensor_info->name, strlen(sensor_info->name));
|
|
}
|
|
break;
|
|
case COLUMN_LMSENSORS_VALUE:
|
|
/* Multiply the value by the appropriate scaling factor for this table */
|
|
snmp_set_var_typed_integer( request->requestvb, ASN_GAUGE,
|
|
(int)(mult*sensor_info->value));
|
|
break;
|
|
default:
|
|
netsnmp_set_request_error(reqinfo, request,
|
|
SNMP_NOSUCHOBJECT);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
return SNMP_ERR_NOERROR;
|
|
}
|