/* * Note: this file originally auto-generated by mib2c using * : mib2c.scalar.conf,v 1.9 2005/01/07 09:37:18 dts12 Exp $ */ #include #include #include #include #include "memory.h" #define DEFAULTMINIMUMSWAP 16000 /* kilobytes */ static int minimum_swap; /** Initializes the memory module */ void init_memory(void) { const oid memory_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 4 }; const oid memSwapError_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 4, 100 }; const oid memSwapErrMsg_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 4, 101 }; DEBUGMSGTL(("memory", "Initializing\n")); netsnmp_register_scalar_group( netsnmp_create_handler_registration("memory", handle_memory, memory_oid, OID_LENGTH(memory_oid), HANDLER_CAN_RONLY), 1, 27); netsnmp_register_scalar( netsnmp_create_handler_registration("memSwapError", handle_memory, memSwapError_oid, OID_LENGTH(memSwapError_oid), HANDLER_CAN_RONLY)); netsnmp_register_scalar( netsnmp_create_handler_registration("memSwapErrMsg", handle_memory, memSwapErrMsg_oid, OID_LENGTH(memSwapErrMsg_oid), HANDLER_CAN_RONLY)); snmpd_register_config_handler("swap", memory_parse_config, memory_free_config, "min-avail"); } void memory_parse_config(const char *token, char *cptr) { minimum_swap = atoi(cptr); } void memory_free_config(void) { minimum_swap = DEFAULTMINIMUMSWAP; } int handle_memory(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_memory_info *mem_info; unsigned long long val; struct counter64 c64; int type = ASN_INTEGER; char buf[1024]; /* * We just need to handle valid GET requests, as invalid instances * are rejected automatically, and (valid) GETNEXT requests are * converted into the appropriate GET request. * * We also only ever receive one request at a time. */ switch (reqinfo->mode) { case MODE_GET: netsnmp_memory_load(); switch (requests->requestvb->name[ reginfo->rootoid_len - 2 ]) { case MEMORY_INDEX: val = 0; break; case MEMORY_ERRNAME: sprintf(buf, "swap"); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *)buf, strlen(buf)); return SNMP_ERR_NOERROR; case MEMORY_SWAP_TOTAL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; /* swaptotal */ val *= (mem_info->units/1024); break; case MEMORY_SWAP_AVAIL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; /* swapfree */ val *= (mem_info->units/1024); break; case MEMORY_REAL_TOTAL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; /* memtotal */ val *= (mem_info->units/1024); break; case MEMORY_REAL_AVAIL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; /* memfree */ val *= (mem_info->units/1024); break; case MEMORY_STXT_TOTAL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_STEXT, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; val *= (mem_info->units/1024); break; case MEMORY_STXT_AVAIL: /* Deprecated */ case MEMORY_STXT_USED: /* * The original MIB description of memAvailSwapTXT * was inconsistent with that implied by the name. * Retain the actual behaviour for the (sole) * implementation of this object, but deprecate it in * favour of a more consistently named replacement object. */ mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_STEXT, 0 ); if (!mem_info) goto NOSUCH; val = (mem_info->size - mem_info->free); val *= (mem_info->units/1024); break; case MEMORY_RTXT_TOTAL: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_RTEXT, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; val *= (mem_info->units/1024); break; case MEMORY_RTXT_AVAIL: /* Deprecated */ case MEMORY_RTXT_USED: /* * The original MIB description of memAvailRealTXT * was inconsistent with that implied by the name. * Retain the actual behaviour for the (sole) * implementation of this object, but deprecate it in * favour of a more consistently named replacement object. */ mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_RTEXT, 0 ); if (!mem_info) goto NOSUCH; val = (mem_info->size - mem_info->free); val *= (mem_info->units/1024); break; case MEMORY_FREE: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; /* memfree + swapfree */ val *= (mem_info->units/1024); break; case MEMORY_SWAP_MIN: val = minimum_swap; break; case MEMORY_SHARED: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; /* memshared */ val *= (mem_info->units/1024); break; case MEMORY_BUFFER: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 0 ); if (!mem_info || mem_info->size == -1) goto NOSUCH; val = (mem_info->size - mem_info->free); /* buffers */ val *= (mem_info->units/1024); break; case MEMORY_CACHED: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 0 ); if (!mem_info || mem_info->size== -1) goto NOSUCH; val = (mem_info->size - mem_info->free); /* cached */ val *= (mem_info->units/1024); break; case MEMORY_SWAP_TOTAL_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_SWAP_AVAIL_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_REAL_TOTAL_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_REAL_AVAIL_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_SWAP_MIN_X: type = ASN_COUNTER64; val = minimum_swap; c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_FREE_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->free; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_SHARED_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_BUFFER_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size - mem_info->free; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_CACHED_X: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 0 ); if (!mem_info) goto NOSUCH; val = mem_info->size - mem_info->free; val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >>32; break; case MEMORY_SYS_AVAIL: type = ASN_COUNTER64; mem_info = netsnmp_memory_get_byIdx(NETSNMP_MEM_TYPE_AVAILMEM, 0); if (!mem_info) goto NOSUCH; val = mem_info->size; /* memavail */ val *= (mem_info->units/1024); c64.low = val & 0xFFFFFFFF; c64.high = val >> 32; break; case MEMORY_SWAP_ERROR: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; val = ((mem_info->units / 1024) * mem_info->free > minimum_swap) ? 0 : 1; break; case MEMORY_SWAP_ERRMSG: mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 0 ); if (!mem_info) goto NOSUCH; if ((mem_info->units / 1024) * mem_info->free > minimum_swap) buf[0] = 0; else sprintf(buf, "Running out of swap space (%ld)", mem_info->free); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *)buf, strlen(buf)); return SNMP_ERR_NOERROR; default: snmp_log(LOG_ERR, "unknown object (%" NETSNMP_PRIo "u) in handle_memory\n", requests->requestvb->name[ reginfo->rootoid_len - 2 ]); NOSUCH: netsnmp_set_request_error( reqinfo, requests, SNMP_NOSUCHOBJECT ); return SNMP_ERR_NOERROR; } /* * All non-integer objects (and errors) have already been * processed. So return the integer value. */ if (type == ASN_INTEGER) snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *)&val, sizeof(val)); else snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER64, (u_char *)&c64, sizeof(c64)); break; default: /* * we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, "unknown mode (%d) in handle_memory\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }