diff options
11 files changed, 604 insertions, 282 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c index eb1ad91..f258682 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c @@ -43,11 +43,19 @@ #include <string.h> #include <syslog.h> #include <unistd.h> +#include <sysexits.h> #include "hostres_snmp.h" #include "hostres_oid.h" #include "hostres_tree.h" +#define FREE_DEV_STRUCT(entry_p) do { \ + free(entry_p->name); \ + free(entry_p->location); \ + free(entry_p->descr); \ + free(entry_p); \ +} while (0) + /* * Status of a device */ @@ -92,49 +100,73 @@ static const struct asn_oid OIDX_hrDeviceOther_c = OIDX_hrDeviceOther; struct device_entry * device_entry_create(const char *name, const char *location, const char *descr) { - struct device_entry *entry; - struct device_map_entry *map; + struct device_entry *entry = NULL; + struct device_map_entry *map = NULL; + size_t name_len; + size_t location_len; assert((name[0] != 0) || (location[0] != 0)); if (name[0] == 0 && location[0] == 0) return (NULL); - if ((entry = malloc(sizeof(*entry))) == NULL) { - syslog(LOG_WARNING, "hrDeviceTable: %s: %m", __func__); - return (NULL); - } - memset(entry, 0, sizeof(*entry)); + STAILQ_FOREACH(map, &device_map, link) { + assert(map->name_key != NULL); + assert(map->location_key != NULL); - STAILQ_FOREACH(map, &device_map, link) if (strcmp(map->name_key, name) == 0 && strcmp(map->location_key, location) == 0) { - entry->index = map->hrIndex; - map->entry_p = entry; break; } + } if (map == NULL) { /* new object - get a new index */ if (next_device_index > INT_MAX) { syslog(LOG_ERR, "%s: hrDeviceTable index wrap", __func__); - free(entry); - return (NULL); + /* There isn't much we can do here. + * If the next_swins_index is consumed + * then we can't add entries to this table + * So it is better to exit - if the table is sparsed + * at the next agent run we can fill it fully. + */ + errx(EX_SOFTWARE, "hrDeviceTable index wrap"); + /* not reachable */ } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); - free(entry); return (NULL); } - map->hrIndex = next_device_index++; + map->entry_p = NULL; - strlcpy(map->name_key, name, sizeof(map->name_key)); - strlcpy(map->location_key, location, sizeof(map->location_key)); + name_len = strlen(name) + 1; + if (name_len > DEV_NAME_MLEN) + name_len = DEV_NAME_MLEN; - map->entry_p = entry; + if ((map->name_key = malloc(name_len)) == NULL) { + syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); + free(map); + return (NULL); + } + + location_len = strlen(location) + 1; + if (location_len > DEV_LOC_MLEN) + location_len = DEV_LOC_MLEN; + + if ((map->location_key = malloc(location_len )) == NULL) { + syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); + free(map->name_key); + free(map); + return (NULL); + } + + map->hrIndex = next_device_index++; + + strlcpy(map->name_key, name, name_len); + strlcpy(map->location_key, location, location_len); STAILQ_INSERT_TAIL(&device_map, map, link); HRDBG("%s at %s added into hrDeviceMap at index=%d", @@ -144,22 +176,63 @@ device_entry_create(const char *name, const char *location, const char *descr) name, location, map->hrIndex); } + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "hrDeviceTable: %s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + entry->index = map->hrIndex; + map->entry_p = entry; + + if ((entry->name = strdup(map->name_key)) == NULL) { + syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); + free(entry); + return (NULL); + } + + if ((entry->location = strdup(map->location_key)) == NULL) { + syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); + free(entry->name); + free(entry); + return (NULL); + } + + /* + * From here till the end of this function we reuse name_len + * for a diferrent purpose - for device_entry::descr + */ + if (name[0] != '\0') + name_len = strlen(name) + strlen(descr) + + strlen(": ") + 1; + else + name_len = strlen(location) + strlen(descr) + + strlen("unknown at : ") + 1; + + if (name_len > DEV_DESCR_MLEN) + name_len = DEV_DESCR_MLEN; + + if ((entry->descr = malloc(name_len )) == NULL) { + syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); + free(entry->name); + free(entry->location); + free(entry); + return (NULL); + } - strlcpy(entry->name, name, sizeof(entry->name)); - strlcpy(entry->location, location, sizeof(entry->location)); + memset(&entry->descr[0], '\0', name_len); if (name[0] != '\0') - snprintf(entry->descr, sizeof(entry->descr), "%s: %s", - name, descr); + snprintf(entry->descr, name_len, + "%s: %s", name, descr); else - snprintf(entry->descr, sizeof(entry->descr), + snprintf(entry->descr, name_len, "unknown at %s: %s", location, descr); - entry->id = oid_zeroDotZero; /* unknown id - FIXME */ - entry->status = (u_int)DIS_ATTACHED; + entry->id = &oid_zeroDotZero; /* unknown id - FIXME */ + entry->status = (u_int)DS_UNKNOWN; entry->errors = 0; - entry->type = OIDX_hrDeviceOther_c; + entry->type = &OIDX_hrDeviceOther_c; INSERT_OBJECT_INT(entry, &device_tbl); @@ -183,7 +256,7 @@ device_entry_create_devinfo(const struct devinfo_dev *dev_p) /** * Delete an entry from the device table. */ -static void +void device_entry_delete(struct device_entry *entry) { struct device_map_entry *map; @@ -197,7 +270,8 @@ device_entry_delete(struct device_entry *entry) map->entry_p = NULL; break; } - free(entry); + + FREE_DEV_STRUCT(entry); } /** @@ -252,7 +326,7 @@ device_find_by_name(const char *dev_name) * Find out the type of device. CPU only currently. */ static void -device_get_type(struct devinfo_dev *dev_p, struct asn_oid *out_type_p) +device_get_type(struct devinfo_dev *dev_p, const struct asn_oid **out_type_p) { assert(dev_p != NULL); @@ -263,7 +337,7 @@ device_get_type(struct devinfo_dev *dev_p, struct asn_oid *out_type_p) if (strncmp(dev_p->dd_name, "cpu", strlen("cpu")) == 0 && strstr(dev_p->dd_location, ".CPU") != NULL) { - *out_type_p = OIDX_hrDeviceProcessor_c; + *out_type_p = &OIDX_hrDeviceProcessor_c; return; } } @@ -361,7 +435,7 @@ create_devd_socket(void) /* * Event on the devd socket. - ** + * * We should probably directly process entries here. For simplicity just * call the refresh routine with the force flag for now. */ @@ -463,8 +537,10 @@ fini_device_tbl(void) STAILQ_REMOVE_HEAD(&device_map, link); if (n1->entry_p != NULL) { TAILQ_REMOVE(&device_tbl, n1->entry_p, link); - free(n1->entry_p); + FREE_DEV_STRUCT(n1->entry_p); } + free(n1->name_key); + free(n1->location_key); free(n1); } assert(TAILQ_EMPTY(&device_tbl)); @@ -590,14 +666,15 @@ op_hrDeviceTable(struct snmp_context *ctx __unused, struct snmp_value *value, return (SNMP_ERR_NOERROR); case LEAF_hrDeviceType: - value->v.oid = entry->type; + assert(entry->type != NULL); + value->v.oid = *(entry->type); return (SNMP_ERR_NOERROR); case LEAF_hrDeviceDescr: return (string_get(value, entry->descr, -1)); case LEAF_hrDeviceID: - value->v.oid = entry->id; + value->v.oid = *(entry->id); return (SNMP_ERR_NOERROR); case LEAF_hrDeviceStatus: diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c index 10cce50..200f1ec 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c @@ -172,11 +172,23 @@ disk_entry_create(const struct device_entry *devEntry) static void disk_entry_delete(struct disk_entry *entry) { + struct device_entry *devEntry; assert(entry != NULL); - TAILQ_REMOVE(&disk_tbl, entry, link); + + devEntry = device_find_by_index(entry->index); + free(entry); + + /* + * Also delete the respective device entry - + * this is needed for disk devices that are not + * detected by libdevinfo + */ + if (devEntry != NULL && + (devEntry->flags & HR_DEVICE_IMMUTABLE) == HR_DEVICE_IMMUTABLE) + device_entry_delete(devEntry); } /** @@ -290,7 +302,7 @@ disk_OS_get_ATA_disks(void) /* First get the entry from the hrDeviceTbl */ entry = map->entry_p; - entry->type = OIDX_hrDeviceDiskStorage_c; + entry->type = &OIDX_hrDeviceDiskStorage_c; /* Then check hrDiskStorage table for this device */ disk_entry = disk_find_by_index(entry->index); @@ -335,7 +347,7 @@ disk_OS_get_MD_disks(void) /* First get the entry from the hrDeviceTbl */ entry = device_find_by_index(map->hrIndex); - entry->type = OIDX_hrDeviceDiskStorage_c; + entry->type = &OIDX_hrDeviceDiskStorage_c; /* Then check hrDiskStorage table for this device */ disk_entry = disk_find_by_index(entry->index); @@ -426,7 +438,6 @@ disk_OS_get_disks(void) if ((entry = device_find_by_name(disk)) == NULL) { /* * not found there - insert it as immutable - * XXX somehow we should remove it if it disappears */ syslog(LOG_WARNING, "%s: device '%s' not in " "device list", __func__, disk); @@ -437,7 +448,7 @@ disk_OS_get_disks(void) entry->flags |= HR_DEVICE_IMMUTABLE; } - entry->type = OIDX_hrDeviceDiskStorage_c; + entry->type = &OIDX_hrDeviceDiskStorage_c; /* Then check hrDiskStorage table for this device */ disk_entry = disk_find_by_index(entry->index); diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c index 51e7181..a35743b 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c @@ -43,6 +43,7 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <sysexits.h> #include "hostres_snmp.h" #include "hostres_oid.h" @@ -56,21 +57,27 @@ enum hrFSAccess { FS_READ_ONLY = 2 }; +/* maximum length (according to MIB) for fs_entry::mountPoint */ +#define FS_MP_MLEN (128 + 1) + +/* maximum length (according to MIB) for fs_entry::remoteMountPoint */ +#define FS_RMP_MLEN (128 + 1) + /* * This structure is used to hold a SNMP table entry * for HOST-RESOURCES-MIB's hrFSTable */ struct fs_entry { int32_t index; - u_char mountPoint[128 + 1]; - u_char remoteMountPoint[128 + 1]; + u_char *mountPoint; + u_char *remoteMountPoint; const struct asn_oid *type; int32_t access; /* enum hrFSAccess, see above */ int32_t bootable; /* TruthValue */ int32_t storageIndex; /* hrStorageTblEntry::index */ u_char lastFullBackupDate[11]; u_char lastPartialBackupDate[11]; -#define HR_FS_FOUND 0x001 +#define HR_FS_FOUND 0x001 uint32_t flags; /* not in mib table, for internal use */ TAILQ_ENTRY(fs_entry) link; }; @@ -82,8 +89,8 @@ TAILQ_HEAD(fs_tbl, fs_entry); * index for a specific name at least for the duration of one SNMP agent run. */ struct fs_map_entry { - int32_t hrIndex; /* used for hrFSTblEntry::index */ - u_char a_name[128 + 1];/* map key */ + int32_t hrIndex; /* used for fs_entry::index */ + u_char *a_name; /* map key same as fs_entry::mountPoint */ /* may be NULL if the respective hrFSTblEntry is (temporally) gone */ struct fs_entry *entry; @@ -146,39 +153,42 @@ fs_entry_create(const char *name) struct fs_entry *entry; struct fs_map_entry *map; - if ((entry = malloc(sizeof(*entry))) == NULL) { - syslog(LOG_WARNING, "%s: %m", __func__); - return (NULL); - } - - strlcpy(entry->mountPoint, name, sizeof(entry->mountPoint)); + assert(name != NULL); + assert(strlen(name) > 0); STAILQ_FOREACH(map, &fs_map, link) - if (strncmp(map->a_name, entry->mountPoint, - sizeof(map->a_name) - 1) == 0) { - entry->index = map->hrIndex; - map->entry = entry; + if (strcmp(map->a_name, name) == 0) break; - } if (map == NULL) { + size_t mount_point_len; + /* new object - get a new index */ if (next_fs_index > INT_MAX) { - /* XXX no other sensible reaction? */ + /* Unrecoverable error - die clean and quicly*/ syslog(LOG_ERR, "%s: hrFSTable index wrap", __func__); - return (NULL); + errx(EX_SOFTWARE, "hrFSTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); - free(entry); return (NULL); } - map->hrIndex = next_fs_index++; - strlcpy(map->a_name, entry->mountPoint, sizeof(map->a_name)); - map->entry = entry; + mount_point_len = strlen(name) + 1; + if (mount_point_len > FS_MP_MLEN) + mount_point_len = FS_MP_MLEN; + + if ((map->a_name = malloc(mount_point_len)) == NULL) { + syslog(LOG_ERR, "%s: %m", __func__); + free(map); + return (NULL); + } + strlcpy(map->a_name, name, mount_point_len); + + map->hrIndex = next_fs_index++; + map->entry = NULL; STAILQ_INSERT_TAIL(&fs_map, map, link); HRDBG("%s added into hrFSMap at index=%d", name, map->hrIndex); @@ -186,10 +196,21 @@ fs_entry_create(const char *name) HRDBG("%s exists in hrFSMap index=%d", name, map->hrIndex); } + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "%s: %m", __func__); + return (NULL); + } + + if ((entry->mountPoint = strdup(name)) == NULL) { + syslog(LOG_ERR, "%s: %m", __func__); + free(entry); + return (NULL); + } + entry->index = map->hrIndex; + map->entry = entry; INSERT_OBJECT_INT(entry, &fs_tbl); - return (entry); } @@ -201,13 +222,16 @@ fs_entry_delete(struct fs_entry* entry) { struct fs_map_entry *map; + assert(entry != NULL); + TAILQ_REMOVE(&fs_tbl, entry, link); STAILQ_FOREACH(map, &fs_map, link) if (map->entry == entry) { map->entry = NULL; break; } - + free(entry->mountPoint); + free(entry->remoteMountPoint); free(entry); } @@ -220,8 +244,7 @@ fs_find_by_name(const char *name) struct fs_entry *entry; TAILQ_FOREACH(entry, &fs_tbl, link) - if (strncmp(entry->mountPoint, name, - sizeof(entry->mountPoint) - 1) == 0) + if (strcmp(entry->mountPoint, name) == 0) return (entry); return (NULL); @@ -239,8 +262,11 @@ fini_fs_tbl(void) STAILQ_REMOVE_HEAD(&fs_map, link); if (n1->entry != NULL) { TAILQ_REMOVE(&fs_tbl, n1->entry, link); + free(n1->entry->mountPoint); + free(n1->entry->remoteMountPoint); free(n1->entry); } + free(n1->a_name); free(n1); } assert(TAILQ_EMPTY(&fs_tbl)); @@ -327,13 +353,15 @@ fs_tbl_process_statfs_entry(const struct statfs *fs_p, int32_t storage_idx) (entry = fs_entry_create(fs_p->f_mntonname)) != NULL) { entry->flags |= HR_FS_FOUND; - strcpy(entry->mountPoint, fs_p->f_mntonname); - - if (!(fs_p->f_flags & MNT_LOCAL)) + if (!(fs_p->f_flags & MNT_LOCAL)) { /* this is a remote mount */ - strcpy(entry->remoteMountPoint, fs_p->f_mntfromname); - else - entry->remoteMountPoint[0] = '\0'; + entry->remoteMountPoint = strdup(fs_p->f_mntfromname); + /* if strdup failed, let it be NULL */ + + } else { + entry->remoteMountPoint = strdup(""); + /* if strdup failed, let it be NULL */ + } entry->type = fs_get_type(fs_p); @@ -411,11 +439,15 @@ op_hrFSTable(struct snmp_context *ctx __unused, struct snmp_value *value, return (string_get(value, entry->mountPoint, -1)); case LEAF_hrFSRemoteMountPoint: - return (string_get(value, entry->remoteMountPoint, -1)); + if (entry->remoteMountPoint == NULL) + return (string_get(value, "", -1)); + else + return (string_get(value, entry->remoteMountPoint, -1)); break; case LEAF_hrFSType: - value->v.oid = *entry->type; + assert(entry->type != NULL); + value->v.oid = *(entry->type); return (SNMP_ERR_NOERROR); case LEAF_hrFSAccess: diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c index a98241c..4329a1c 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c @@ -67,7 +67,7 @@ struct network_entry { int32_t index; int32_t ifIndex; TAILQ_ENTRY(network_entry) link; -#define HR_NETWORK_FOUND 0x001 +#define HR_NETWORK_FOUND 0x001 uint32_t flags; }; @@ -172,7 +172,7 @@ network_get_interfaces(void) } HRDBG("%s found in hrDeviceTable", dname); - dev->type = OIDX_hrDeviceNetwork_c; + dev->type = &OIDX_hrDeviceNetwork_c; dev->flags |= HR_DEVICE_IMMUTABLE; free(dname); diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c index f56513b..65c0012 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c @@ -44,28 +44,32 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <sysexits.h> #include "hostres_snmp.h" #include "hostres_oid.h" #include "hostres_tree.h" #ifdef PC98 -#define HR_FREEBSD_PART_TYPE 0xc494 +#define HR_FREEBSD_PART_TYPE 0xc494 #else #define HR_FREEBSD_PART_TYPE 165 #endif +/* Maximum length for label and id including \0 */ +#define PART_STR_MLEN (128 + 1) + /* * One row in the hrPartitionTable */ struct partition_entry { - struct asn_oid index; - u_char label[128 + 1]; - u_char id[128 + 1]; + asn_subid_t index[2]; + u_char *label; /* max allocated len will be PART_STR_MLEN */ + u_char *id; /* max allocated len will be PART_STR_MLEN */ int32_t size; int32_t fs_Index; TAILQ_ENTRY(partition_entry) link; -#define HR_PARTITION_FOUND 0x001 +#define HR_PARTITION_FOUND 0x001 uint32_t flags; }; TAILQ_HEAD(partition_tbl, partition_entry); @@ -75,8 +79,8 @@ TAILQ_HEAD(partition_tbl, partition_entry); * mapping while we rebuild the partition table. */ struct partition_map_entry { - int32_t index; /* hrPartitionTblEntry::index */ - u_char id[128 + 1]; + int32_t index; /* partition_entry::index */ + u_char *id; /* max allocated len will be PART_STR_MLEN */ /* * next may be NULL if the respective partition_entry @@ -98,6 +102,56 @@ static struct partition_tbl partition_tbl = /* next int available for indexing the hrPartitionTable */ static uint32_t next_partition_index = 1; +/* + * Partition_entry_cmp is used for INSERT_OBJECT_FUNC_LINK + * macro. + */ +static int +partition_entry_cmp(const struct partition_entry *a, + const struct partition_entry *b) +{ + assert(a != NULL); + assert(b != NULL); + + if (a->index[0] < b->index[0]) + return (-1); + + if (a->index[0] > b->index[0]) + return (+1); + + if (a->index[1] < b->index[1]) + return (-1); + + if (a->index[1] > b->index[1]) + return (+1); + + return (0); +} + +/* + * Partition_idx_cmp is used for NEXT_OBJECT_FUNC and FIND_OBJECT_FUNC + * macros + */ +static int +partition_idx_cmp(const struct asn_oid *oid, u_int sub, + const struct partition_entry *entry) +{ + u_int i; + + for (i = 0; i < 2 && i < oid->len - sub; i++) { + if (oid->subs[sub + i] < entry->index[i]) + return (-1); + if (oid->subs[sub + i] > entry->index[i]) + return (+1); + } + if (oid->len - sub < 2) + return (-1); + if (oid->len - sub > 2) + return (+1); + + return (0); +} + /** * Create a new partition table entry */ @@ -105,45 +159,49 @@ static struct partition_entry * partition_entry_create(int32_t ds_index, const char *chunk_name) { struct partition_entry *entry; - struct partition_map_entry *map = NULL; + struct partition_map_entry *map; + size_t id_len; /* sanity checks */ assert(chunk_name != NULL); if (chunk_name == NULL || chunk_name[0] == '\0') return (NULL); - if ((entry = malloc(sizeof(*entry))) == NULL) { - syslog(LOG_WARNING, "hrPartitionTable: %s: %m", __func__); - return (NULL); - } - memset(entry, 0, sizeof(*entry)); - /* check whether we already have seen this partition */ STAILQ_FOREACH(map, &partition_map, link) - if (strcmp(map->id, chunk_name) == 0 ) { - map->entry = entry; + if (strcmp(map->id, chunk_name) == 0) break; - } if (map == NULL) { /* new object - get a new index and create a map */ + if (next_partition_index > INT_MAX) { + /* Unrecoverable error - die clean and quicly*/ syslog(LOG_ERR, "%s: hrPartitionTable index wrap", __func__); - errx(1, "hrPartitionTable index wrap"); + errx(EX_SOFTWARE, "hrPartitionTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "hrPartitionTable: %s: %m", __func__); - free(entry); + return (NULL); + } + + id_len = strlen(chunk_name) + 1; + if (id_len > PART_STR_MLEN) + id_len = PART_STR_MLEN; + + if ((map->id = malloc(id_len)) == NULL) { + free(map); return (NULL); } map->index = next_partition_index++; - strlcpy(map->id, chunk_name, sizeof(map->id)); + strlcpy(map->id, chunk_name, id_len); + + map->entry = NULL; - map->entry = entry; STAILQ_INSERT_TAIL(&partition_map, map, link); HRDBG("%s added into hrPartitionMap at index=%d", @@ -154,17 +212,42 @@ partition_entry_create(int32_t ds_index, const char *chunk_name) chunk_name, map->index); } + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "hrPartitionTable: %s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + /* create the index */ - entry->index.len = 2; - entry->index.subs[0] = ds_index; - entry->index.subs[1] = map->index; + entry->index[0] = ds_index; + entry->index[1] = map->index; - strlcpy(entry->id, chunk_name, sizeof(entry->id)); + map->entry = entry; - snprintf(entry->label, sizeof(entry->label) - 1, - "%s%s", _PATH_DEV, chunk_name); + if ((entry->id = strdup(map->id)) == NULL) { + free(entry); + return (NULL); + } - INSERT_OBJECT_OID(entry, &partition_tbl); + /* + * reuse id_len from here till the end of this function + * for partition_entry::label + */ + id_len = strlen(_PATH_DEV) + strlen(chunk_name) + 1; + + if (id_len > PART_STR_MLEN) + id_len = PART_STR_MLEN; + + if ((entry->label = malloc(id_len )) == NULL) { + free(entry->id); + free(entry); + return (NULL); + } + + snprintf(entry->label, id_len, "%s%s", _PATH_DEV, chunk_name); + + INSERT_OBJECT_FUNC_LINK(entry, &partition_tbl, link, + partition_entry_cmp); return (entry); } @@ -185,7 +268,8 @@ partition_entry_delete(struct partition_entry *entry) map->entry = NULL; break; } - + free(entry->id); + free(entry->label); free(entry); } @@ -227,7 +311,7 @@ partition_entry_find_by_label(const char *name) static void handle_chunk(int32_t ds_index, const char *chunk_name, off_t chunk_size) { - struct partition_entry *entry = NULL; + struct partition_entry *entry; daddr_t k_size; assert(chunk_name != NULL); @@ -257,7 +341,7 @@ handle_chunk(int32_t ds_index, const char *chunk_name, off_t chunk_size) void partition_tbl_pre_refresh(void) { - struct partition_entry *entry = NULL; + struct partition_entry *entry; /* mark each entry as missing */ TAILQ_FOREACH(entry, &partition_tbl, link) @@ -372,7 +456,7 @@ partition_tbl_handle_disk(int32_t ds_index, const char *disk_dev_name) assert(disk_dev_name != NULL); assert(ds_index > 0); - HRDBG("===> getting partitions for %s <===", disk_dev_name); + HRDBG("===> getting partitions for %s <===", disk_dev_name); /* try to construct the GEOM tree */ if ((error = geom_gettree(&mesh)) != 0) { @@ -441,14 +525,17 @@ fini_partition_tbl(void) { struct partition_map_entry *m; - while ((m = STAILQ_FIRST(&partition_map)) != NULL) { + while ((m = STAILQ_FIRST(&partition_map)) != NULL) { STAILQ_REMOVE_HEAD(&partition_map, link); if(m->entry != NULL) { TAILQ_REMOVE(&partition_tbl, m->entry, link); + free(m->entry->id); + free(m->entry->label); free(m->entry); } + free(m->id); free(m); - } + } assert(TAILQ_EMPTY(&partition_tbl)); } @@ -490,22 +577,25 @@ op_hrPartitionTable(struct snmp_context *ctx __unused, struct snmp_value *value, switch (op) { case SNMP_OP_GETNEXT: - if ((entry = NEXT_OBJECT_OID(&partition_tbl, - &value->var, sub)) == NULL) + if ((entry = NEXT_OBJECT_FUNC(&partition_tbl, + &value->var, sub, partition_idx_cmp)) == NULL) return (SNMP_ERR_NOSUCHNAME); - index_append(&value->var, sub, &entry->index); + value->var.len = sub + 2; + value->var.subs[sub] = entry->index[0]; + value->var.subs[sub + 1] = entry->index[1]; + goto get; case SNMP_OP_GET: - if ((entry = FIND_OBJECT_OID(&partition_tbl, - &value->var, sub)) == NULL) + if ((entry = FIND_OBJECT_FUNC(&partition_tbl, + &value->var, sub, partition_idx_cmp)) == NULL) return (SNMP_ERR_NOSUCHNAME); goto get; case SNMP_OP_SET: - if ((entry = FIND_OBJECT_OID(&partition_tbl, - &value->var, sub)) == NULL) + if ((entry = FIND_OBJECT_FUNC(&partition_tbl, + &value->var, sub, partition_idx_cmp)) == NULL) return (SNMP_ERR_NOT_WRITEABLE); return (SNMP_ERR_NO_CREATION); @@ -519,7 +609,7 @@ op_hrPartitionTable(struct snmp_context *ctx __unused, struct snmp_value *value, switch (value->var.subs[sub - 1]) { case LEAF_hrPartitionIndex: - value->v.integer = entry->index.subs[1]; + value->v.integer = entry->index[1]; return (SNMP_ERR_NOERROR); case LEAF_hrPartitionLabel: diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c index c29b29b..883d67a 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c @@ -73,7 +73,7 @@ struct printer_entry { int32_t status; /* values from PrinterStatus enum above */ u_char detectedErrorState[2]; TAILQ_ENTRY(printer_entry) link; -#define HR_PRINTER_FOUND 0x001 +#define HR_PRINTER_FOUND 0x001 uint32_t flags; }; @@ -240,8 +240,8 @@ handle_printer(struct printer *pp) return; } HRDBG("%s found in hrDeviceTable", pp->lp); + dev_entry->type = &OIDX_hrDevicePrinter_c; - dev_entry->type = OIDX_hrDevicePrinter_c; dev_entry->flags |= HR_DEVICE_IMMUTABLE; /* Then check hrPrinterTable for this device */ diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c index 1c8273f..33f7b2d 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c @@ -55,10 +55,10 @@ */ struct processor_entry { int32_t index; - struct asn_oid frwId; + const struct asn_oid *frwId; int32_t load; TAILQ_ENTRY(processor_entry) link; - u_char cpu_no; /* which cpu, counted from 0 */ + u_char cpu_no; /* which cpu, counted from 0 */ pid_t idle_pid; /* PID of idle process for this CPU */ /* the samples from the last minute, as required by MIB */ @@ -168,7 +168,7 @@ proc_create_entry(u_int cpu_no, struct device_map_entry *map) if (map == NULL) abort(); } - + if ((entry = malloc(sizeof(*entry))) == NULL) { syslog(LOG_ERR, "hrProcessorTable: %s malloc " "failed: %m", __func__); @@ -180,7 +180,7 @@ proc_create_entry(u_int cpu_no, struct device_map_entry *map) entry->load = 0; entry->cpu_no = (u_char)cpu_no; entry->idle_pid = 0; - entry->frwId = oid_zeroDotZero; /* unknown id FIXME */ + entry->frwId = &oid_zeroDotZero; /* unknown id FIXME */ INSERT_OBJECT_INT(entry, &processor_tbl); @@ -232,7 +232,7 @@ processor_get_pids(void) if (entry == NULL) { /* create entry on non-ACPI systems */ - if ((entry = proc_create_entry(cpu, NULL)) == NULL) + if ((entry = proc_create_entry(cpu, NULL)) == NULL) continue; detected_processor_count++; @@ -495,7 +495,8 @@ op_hrProcessorTable(struct snmp_context *ctx __unused, switch (value->var.subs[sub - 1]) { case LEAF_hrProcessorFrwID: - value->v.oid = entry->frwId; + assert(entry->frwId != NULL); + value->v.oid = *entry->frwId; return (SNMP_ERR_NOERROR); case LEAF_hrProcessorLoad: diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h index acac238..567368a 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h @@ -32,7 +32,7 @@ */ #ifndef HOSTRES_SNMP_H_1132245017 -#define HOSTRES_SNMP_H_1132245017 +#define HOSTRES_SNMP_H_1132245017 #include <sys/types.h> #include <sys/queue.h> @@ -51,18 +51,18 @@ * Default package directory for hrSWInstalledTable. Can be overridden * via SNMP or configuration file. */ -#define PATH_PKGDIR "/var/db/pkg" +#define PATH_PKGDIR "/var/db/pkg" /* * These are the default maximum caching intervals for the various tables * in seconds. They can be overridden from the configuration file. */ -#define HR_STORAGE_TBL_REFRESH 7 -#define HR_FS_TBL_REFRESH 7 -#define HR_DISK_TBL_REFRESH 7 -#define HR_NETWORK_TBL_REFRESH 7 -#define HR_SWINS_TBL_REFRESH 120 -#define HR_SWRUN_TBL_REFRESH 3 +#define HR_STORAGE_TBL_REFRESH 7 +#define HR_FS_TBL_REFRESH 7 +#define HR_DISK_TBL_REFRESH 7 +#define HR_NETWORK_TBL_REFRESH 7 +#define HR_SWINS_TBL_REFRESH 120 +#define HR_SWRUN_TBL_REFRESH 3 struct tm; struct statfs; @@ -93,7 +93,26 @@ enum snmpTCTruthValue { }; /* The number of CPU load samples per one minute, per each CPU */ -#define MAX_CPU_SAMPLES 4 +#define MAX_CPU_SAMPLES 4 + + +/* + * max len (including '\0'), for device_entry::descr field below, + * according to MIB + */ +#define DEV_DESCR_MLEN (64 + 1) + +/* + * max len (including '\0'), for device_entry::name and + * device_map_entry::name_key fields below, according to MIB + */ +#define DEV_NAME_MLEN (32 + 1) + +/* + * max len (including '\0'), for device_entry::location and + * device_map_entry::location_key fields below, according to MIB + */ +#define DEV_LOC_MLEN (128 + 1) /* * This structure is used to hold a SNMP table entry @@ -101,20 +120,21 @@ enum snmpTCTruthValue { */ struct device_entry { int32_t index; - struct asn_oid type; - u_char descr[64 + 1]; - struct asn_oid id; - int32_t status; /* enum DeviceStatus */ + const struct asn_oid *type; + u_char *descr; + const struct asn_oid *id; /* only oid_zeroDotZero as (*id) value*/ + int32_t status; /* enum DeviceStatus */ uint32_t errors; -#define HR_DEVICE_FOUND 0x001 +#define HR_DEVICE_FOUND 0x001 /* not dectected by libdevice, so don't try to refresh it*/ -#define HR_DEVICE_IMMUTABLE 0x002 +#define HR_DEVICE_IMMUTABLE 0x002 /* next 3 are not from the SNMP mib table, only to be used internally */ uint32_t flags; - u_char name[32 + 1]; - u_char location[128 + 1]; + + u_char *name; + u_char *location; TAILQ_ENTRY(device_entry) link; }; @@ -128,8 +148,8 @@ struct device_map_entry { int32_t hrIndex; /* used for hrDeviceTblEntry::index */ /* map key is the pair (name_key, location_key) */ - u_char name_key[32 + 1]; /* copy of device name */ - u_char location_key[128 + 1]; + u_char *name_key; /* copy of device name */ + u_char *location_key; /* * Next may be NULL if the respective hrDeviceTblEntry @@ -232,6 +252,9 @@ struct device_entry *device_find_by_name(const char *); struct device_entry *device_entry_create(const char *, const char *, const char *); +/* Delete an entry from hrDeviceTbl */ +void device_entry_delete(struct device_entry *entry); + /* Init the things for hrProcessorTable. */ void init_processor_tbl(void); diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c index 851d0f7..488d9f5 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c @@ -49,25 +49,29 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> -#include <unistd.h> /*for getpagesize()*/ +#include <unistd.h> /* for getpagesize() */ +#include <sysexits.h> #include "hostres_snmp.h" #include "hostres_oid.h" #include "hostres_tree.h" +/* maximum length for descritpion string according to MIB */ +#define SE_DESC_MLEN (255 + 1) + /* * This structure is used to hold a SNMP table entry * for HOST-RESOURCES-MIB's hrStorageTable */ struct storage_entry { int32_t index; - struct asn_oid type; - u_char descr[255 + 1]; + const struct asn_oid *type; + u_char *descr; int32_t allocationUnits; int32_t size; int32_t used; uint32_t allocationFailures; -#define HR_STORAGE_FOUND 0x001 +#define HR_STORAGE_FOUND 0x001 uint32_t flags; /* to be used internally*/ TAILQ_ENTRY(storage_entry) link; }; @@ -80,13 +84,13 @@ TAILQ_HEAD(storage_tbl, storage_entry); * run. */ struct storage_map_entry { - int32_t hrIndex; /* used for hrStorageTblEntry::index */ + int32_t hrIndex; /* used for storage_entry::index */ - /* map key, also used for hrStorageTblEntry::descr */ - u_char a_name[255 + 1]; + /* map key, also used for storage_entry::descr */ + u_char *a_name; /* - * next may be NULL if the respective hrStorageTblEntry + * next may be NULL if the respective storage_entry * is (temporally) gone */ struct storage_entry *entry; @@ -137,39 +141,39 @@ storage_entry_create(const char *name) { struct storage_entry *entry; struct storage_map_entry *map; + size_t name_len; - if ((entry = malloc(sizeof(*entry))) == NULL) { - syslog(LOG_WARNING, "%s: %m", __func__); - return (NULL); - } - - strlcpy(entry->descr, name, sizeof(entry->descr)); + assert(name != NULL); + assert(strlen(name) > 0); STAILQ_FOREACH(map, &storage_map, link) - if (strcmp(map->a_name, entry->descr) == 0) { - entry->index = map->hrIndex; - map->entry = entry; + if (strcmp(map->a_name, name) == 0) break; - } if (map == NULL) { /* new object - get a new index */ if (next_storage_index > INT_MAX) { syslog(LOG_ERR, "%s: hrStorageTable index wrap", __func__); - free(entry); - return (NULL); + errx(EX_SOFTWARE, "hrStorageTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "hrStorageTable: %s: %m", __func__ ); - free(entry); return (NULL); } - map->hrIndex = next_storage_index ++; - strlcpy(map->a_name, entry->descr, sizeof(map->a_name)); - map->entry = entry; + name_len = strlen(name) + 1; + if (name_len > SE_DESC_MLEN) + name_len = SE_DESC_MLEN; + + if ((map->a_name = malloc(name_len)) == NULL) { + free(map); + return (NULL); + } + + strlcpy(map->a_name, name, name_len); + map->hrIndex = next_storage_index++; STAILQ_INSERT_TAIL(&storage_map, map, link); @@ -180,8 +184,21 @@ storage_entry_create(const char *name) name, map->hrIndex); } + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "%s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + entry->index = map->hrIndex; + if ((entry->descr = strdup(map->a_name)) == NULL) { + free(entry); + return (NULL); + } + + map->entry = entry; + INSERT_OBJECT_INT(entry, &storage_tbl); return (entry); @@ -203,7 +220,7 @@ storage_entry_delete(struct storage_entry *entry) map->entry = NULL; break; } - + free(entry->descr); free(entry); } @@ -216,8 +233,7 @@ storage_find_by_name(const char *name) struct storage_entry *entry; TAILQ_FOREACH(entry, &storage_tbl, link) - if (strncmp(entry->descr, name, - sizeof(entry->descr) - 1) == 0) + if (strcmp(entry->descr, name) == 0) return (entry); return (NULL); @@ -250,7 +266,7 @@ storage_OS_get_vm(void) return; /* I'm out of luck now, maybe next time */ entry->flags |= HR_STORAGE_FOUND; - entry->type = OIDX_hrStorageRam_c; + entry->type = &OIDX_hrStorageRam_c; entry->allocationUnits = page_size_bytes; entry->size = mem_stats.t_rm; entry->used = mem_stats.t_arm; /* ACTIVE is not USED - FIXME */ @@ -264,7 +280,7 @@ storage_OS_get_vm(void) return; entry->flags |= HR_STORAGE_FOUND; - entry->type = OIDX_hrStorageRam_c; + entry->type = &OIDX_hrStorageRam_c; entry->allocationUnits = page_size_bytes; entry->size = mem_stats.t_rmshr; /* ACTIVE is not USED - FIXME */ @@ -281,38 +297,38 @@ storage_OS_get_memstat(void) if (mt_list == NULL) { if ((mt_list = memstat_mtl_alloc()) == NULL) /* again? we have a serious problem */ - return; + return; } if (memstat_sysctl_all(mt_list, 0) < 0) { syslog(LOG_ERR, "memstat_sysctl_all failed: %s", memstat_strerror(memstat_mtl_geterror(mt_list)) ); - return; - } + return; + } if ((mt_item = memstat_mtl_first(mt_list)) == NULL) { /* usually this is not an error, no errno for this failure*/ HRDBG("memstat_mtl_first failed"); - return; + return; } do { const char *memstat_name; uint64_t tmp_size; int allocator; - char alloc_descr[255 + 1]; + char alloc_descr[SE_DESC_MLEN]; memstat_name = memstat_get_name(mt_item); - if (memstat_name == NULL || strlen(memstat_name) == 0) + if (memstat_name == NULL || strlen(memstat_name) == 0) continue; switch (allocator = memstat_get_allocator(mt_item)) { - case ALLOCATOR_MALLOC: + case ALLOCATOR_MALLOC: snprintf(alloc_descr, sizeof(alloc_descr), "MALLOC: %s", memstat_name); - break; + break; case ALLOCATOR_UMA: snprintf(alloc_descr, sizeof(alloc_descr), @@ -330,23 +346,23 @@ storage_OS_get_memstat(void) return; entry->flags |= HR_STORAGE_FOUND; - entry->type = OIDX_hrStorageRam_c; + entry->type = &OIDX_hrStorageRam_c; if ((tmp_size = memstat_get_size(mt_item)) == 0) tmp_size = memstat_get_sizemask(mt_item); - entry->allocationUnits = + entry->allocationUnits = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); tmp_size = memstat_get_countlimit(mt_item); - entry->size = + entry->size = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); - tmp_size = memstat_get_count(mt_item); - entry->used = + tmp_size = memstat_get_count(mt_item); + entry->used = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); tmp_size = memstat_get_failures(mt_item); - entry->allocationFailures = + entry->allocationFailures = (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size); } while((mt_item = memstat_mtl_next(mt_item)) != NULL); @@ -361,7 +377,7 @@ storage_OS_get_swap(void) int nswapdev = 0; size_t len = sizeof(nswapdev); struct storage_entry *entry; - char swap_w_prefix[255 + 1]; + char swap_w_prefix[SE_DESC_MLEN]; if (sysctlbyname("vm.nswapdev", &nswapdev, &len, NULL,0 ) < 0) { syslog(LOG_ERR, @@ -410,7 +426,7 @@ storage_OS_get_swap(void) return; /* Out of luck */ entry->flags |= HR_STORAGE_FOUND; - entry->type = OIDX_hrStorageVirtualMemory_c; + entry->type = &OIDX_hrStorageVirtualMemory_c; entry->allocationUnits = getpagesize(); entry->size = swap_devs[len].ksw_total; entry->used = swap_devs[len].ksw_used; @@ -427,7 +443,7 @@ storage_OS_get_fs(void) { struct storage_entry *entry; uint64_t used_blocks_count = 0; - char fs_string[255+1]; + char fs_string[SE_DESC_MLEN]; int mounted_fs_count; int i = 0; @@ -470,7 +486,7 @@ storage_OS_get_fs(void) return; /* Out of luck */ entry->flags |= HR_STORAGE_FOUND; - entry->type = *fs_get_type(&fs_buf[i]); + entry->type = fs_get_type(&fs_buf[i]); /*XXX - This is wrong*/ if (fs_buf[i].f_bsize > INT_MAX) entry->allocationUnits = INT_MAX; @@ -532,8 +548,10 @@ fini_storage_tbl(void) STAILQ_REMOVE_HEAD(&storage_map, link); if (n1->entry != NULL) { TAILQ_REMOVE(&storage_tbl, n1->entry, link); + free(n1->entry->descr); free(n1->entry); } + free(n1->a_name); free(n1); } assert(TAILQ_EMPTY(&storage_tbl)); @@ -621,10 +639,12 @@ op_hrStorageTable(struct snmp_context *ctx __unused, struct snmp_value *value, return (SNMP_ERR_NOERROR); case LEAF_hrStorageType: - value->v.oid = entry->type; + assert(entry->type != NULL); + value->v.oid = *entry->type; return (SNMP_ERR_NOERROR); case LEAF_hrStorageDescr: + assert(entry->descr != NULL); return (string_get(value, entry->descr, -1)); break; diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c index 1c21a9f..5fa5b4c 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c @@ -44,12 +44,13 @@ #include <stdlib.h> #include <string.h> #include <syslog.h> +#include <sysexits.h> #include "hostres_snmp.h" #include "hostres_oid.h" #include "hostres_tree.h" -#define CONTENTS_FNAME "+CONTENTS" +#define CONTENTS_FNAME "+CONTENTS" enum SWInstalledType { SWI_UNKNOWN = 1, @@ -58,7 +59,7 @@ enum SWInstalledType { SWI_APPLICATION = 4 }; -#define NAMELEN 64 /* w/o \0 */ +#define SW_NAME_MLEN (64 + 1) /* * This structure is used to hold a SNMP table entry @@ -66,14 +67,14 @@ enum SWInstalledType { */ struct swins_entry { int32_t index; - u_char name[NAMELEN + 1]; - struct asn_oid id; - int32_t type; /* from enum SWInstalledType */ + u_char *name; /* max len for this is SW_NAME_MLEN */ + const struct asn_oid *id; + int32_t type; /* from enum SWInstalledType */ u_char date[11]; u_int date_len; -#define HR_SWINSTALLED_FOUND 0x001 -#define HR_SWINSTALLED_IMMUTABLE 0x002 +#define HR_SWINSTALLED_FOUND 0x001 +#define HR_SWINSTALLED_IMMUTABLE 0x002 uint32_t flags; TAILQ_ENTRY(swins_entry) link; @@ -84,8 +85,8 @@ TAILQ_HEAD(swins_tbl, swins_entry); * Table to keep a conistent mapping between software and indexes. */ struct swins_map_entry { - int32_t index; /* hrSWInstalledTblEntry::index */ - u_char name[NAMELEN + 1]; /* map key */ + int32_t index; /* swins_entry::index */ + u_char *name; /* map key,a copy of swins_entry::name*/ /* * next may be NULL if the respective hrSWInstalledTblEntry @@ -93,7 +94,7 @@ struct swins_map_entry { */ struct swins_entry *entry; - STAILQ_ENTRY(swins_map_entry) link; + STAILQ_ENTRY(swins_map_entry) link; }; STAILQ_HEAD(swins_map, swins_map_entry); @@ -127,39 +128,60 @@ swins_entry_create(const char *name) struct swins_entry *entry; struct swins_map_entry *map; - if ((entry = malloc(sizeof(*entry))) == NULL) { - syslog(LOG_WARNING, "%s: %m", __func__); - return (NULL); - } - memset(entry, 0, sizeof(*entry)); - strlcpy((char*)entry->name, name, sizeof(entry->name)); - STAILQ_FOREACH(map, &swins_map, link) - if (strcmp((const char *)map->name, - (const char *)entry->name) == 0) + if (strcmp((const char *)map->name, name) == 0) break; if (map == NULL) { + size_t name_len; /* new object - get a new index */ if (next_swins_index > INT_MAX) { syslog(LOG_ERR, "%s: hrSWInstalledTable index wrap", __func__ ); - free(entry); - return (NULL); + /* There isn't much we can do here. + * If the next_swins_index is consumed + * then we can't add entries to this table + * So it is better to exit - if the table is sparsed + * at the next agent run we can fill it fully. + */ + errx(EX_SOFTWARE, "hrSWInstalledTable index wrap"); } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__ ); - free(entry); return (NULL); } + + name_len = strlen(name) + 1; + if (name_len > SW_NAME_MLEN) + name_len = SW_NAME_MLEN; + + if ((map->name = malloc(name_len)) == NULL) { + syslog(LOG_WARNING, "%s: %m", __func__); + free(map); + return (NULL); + } + map->index = next_swins_index++; - strcpy((char *)map->name, (const char *)entry->name); + strlcpy((char *)map->name, name, name_len); STAILQ_INSERT_TAIL(&swins_map, map, link); HRDBG("%s added into hrSWInstalled at %d", name, map->index); } + + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "%s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + + if ((entry->name = strdup(map->name)) == NULL) { + syslog(LOG_WARNING, "%s: %m", __func__); + free(entry); + return (NULL); + } + entry->index = map->index; map->entry = entry; @@ -186,6 +208,7 @@ swins_entry_delete(struct swins_entry *entry) break; } + free(entry->name); free(entry); } @@ -198,8 +221,7 @@ swins_find_by_name(const char *name) struct swins_entry *entry; TAILQ_FOREACH(entry, &swins_tbl, link) - if (strncmp((const char*)entry->name, name, - sizeof(entry->name) - 1) == 0) + if (strcmp((const char*)entry->name, name) == 0) return (entry); return (NULL); } @@ -216,10 +238,12 @@ fini_swins_tbl(void) STAILQ_REMOVE_HEAD(&swins_map, link); if (n1->entry != NULL) { TAILQ_REMOVE(&swins_tbl, n1->entry, link); + free(n1->entry->name); free(n1->entry); } + free(n1->name); free(n1); - } + } assert(TAILQ_EMPTY(&swins_tbl)); } @@ -230,14 +254,16 @@ static void swins_get_OS_ident(void) { struct utsname os_id; - char os_string[NAMELEN + 1]; + char os_string[SW_NAME_MLEN] = ""; struct swins_entry *entry; u_char *boot; struct stat sb; struct tm k_ts; - if (uname(&os_id) == -1) + if (uname(&os_id) == -1) { + syslog(LOG_WARNING, "%s: %m", __func__); return; + } snprintf(os_string, sizeof(os_string), "%s: %s", os_id.sysname, os_id.version); @@ -247,7 +273,7 @@ swins_get_OS_ident(void) return; entry->flags |= (HR_SWINSTALLED_FOUND | HR_SWINSTALLED_IMMUTABLE); - entry->id = oid_zeroDotZero; + entry->id = &oid_zeroDotZero; entry->type = (int32_t)SWI_OPERATING_SYSTEM; memset(entry->date, 0, sizeof(entry->date)); @@ -267,7 +293,7 @@ swins_get_packages(void) DIR *p_dir; struct dirent *ent; struct tm k_ts; - char *pkg_file; + char *pkg_file; struct swins_entry *entry; int ret = 0; @@ -295,23 +321,23 @@ swins_get_packages(void) return (0); } - if ((p_dir = opendir(pkg_dir)) == NULL) { - syslog(LOG_ERR, "hrSWInstalledTable: opendir(\"%s\") failed: " + if ((p_dir = opendir(pkg_dir)) == NULL) { + syslog(LOG_ERR, "hrSWInstalledTable: opendir(\"%s\") failed: " "%m", pkg_dir); return (-1); - } + } while (errno = 0, (ent = readdir(p_dir)) != NULL) { - HRDBG(" pkg file: %s", ent->d_name); + HRDBG(" pkg file: %s", ent->d_name); /* check that the contents file is a regular file */ - if (asprintf(&pkg_file, "%s/%s/%s", pkg_dir, ent->d_name, + if (asprintf(&pkg_file, "%s/%s/%s", pkg_dir, ent->d_name, CONTENTS_FNAME) == -1) continue; - if (stat(pkg_file, &sb) != 0 ) { + if (stat(pkg_file, &sb) != 0 ) { free(pkg_file); - continue; + continue; } if (!S_ISREG(sb.st_mode)) { @@ -334,14 +360,14 @@ swins_get_packages(void) free(pkg_file); /* update or create entry */ - if ((entry = swins_find_by_name(ent->d_name)) == NULL && - (entry = swins_entry_create(ent->d_name)) == NULL) { + if ((entry = swins_find_by_name(ent->d_name)) == NULL && + (entry = swins_entry_create(ent->d_name)) == NULL) { ret = -1; - goto PKG_LOOP_END; + goto PKG_LOOP_END; } entry->flags |= HR_SWINSTALLED_FOUND; - entry->id = oid_zeroDotZero; + entry->id = &oid_zeroDotZero; entry->type = (int32_t)SWI_APPLICATION; entry->date_len = make_date_time(entry->date, &k_ts, 0); @@ -354,7 +380,7 @@ swins_get_packages(void) } else { /* * save the timestamp of directory - * to avoid any further scanning + * to avoid any further scanning */ os_pkg_last_change = sb.st_ctime; } @@ -399,9 +425,9 @@ void init_swins_tbl(void) { - if ((pkg_dir = malloc(sizeof(PATH_PKGDIR))) == NULL) { + if ((pkg_dir = malloc(sizeof(PATH_PKGDIR))) == NULL) syslog(LOG_ERR, "%s: %m", __func__); - } else + else strcpy(pkg_dir, PATH_PKGDIR); swins_get_OS_ident(); @@ -446,7 +472,7 @@ op_hrSWInstalledTable(struct snmp_context *ctx __unused, case SNMP_OP_ROLLBACK: case SNMP_OP_COMMIT: - abort(); + abort(); } abort(); @@ -458,16 +484,17 @@ op_hrSWInstalledTable(struct snmp_context *ctx __unused, return (SNMP_ERR_NOERROR); case LEAF_hrSWInstalledName: - return (string_get(value, entry->name, -1)); - break; + return (string_get(value, entry->name, -1)); + break; - case LEAF_hrSWInstalledID: - value->v.oid = entry->id; - return (SNMP_ERR_NOERROR); + case LEAF_hrSWInstalledID: + assert(entry->id != NULL); + value->v.oid = *entry->id; + return (SNMP_ERR_NOERROR); case LEAF_hrSWInstalledType: - value->v.integer = entry->type; - return (SNMP_ERR_NOERROR); + value->v.integer = entry->type; + return (SNMP_ERR_NOERROR); case LEAF_hrSWInstalledDate: return (string_get(value, entry->date, entry->date_len)); diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c index 7c05311..1f82648 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c @@ -47,7 +47,6 @@ #include "hostres_oid.h" #include "hostres_tree.h" - /* * Ugly thing: PID_MAX, NO_PID defined only in kernel */ @@ -68,6 +67,11 @@ enum SWRunStatus { SRS_INVALID = 4 }; +/* Maximum lengths for the strings according to the MIB */ +#define SWR_NAME_MLEN (64 + 1) +#define SWR_PATH_MLEN (128 + 1) +#define SWR_PARAM_MLEN (128 + 1) + /* * This structure is used to hold a SNMP table entry * for both hrSWRunTable and hrSWRunPerfTable because @@ -75,15 +79,15 @@ enum SWRunStatus { */ struct swrun_entry { int32_t index; - u_char name[64 + 1]; - struct asn_oid id; - u_char path[128 + 1]; - u_char parameters[128 + 1]; + u_char *name; /* it may be NULL */ + const struct asn_oid *id; + u_char *path; /* it may be NULL */ + u_char *parameters; /* it may be NULL */ int32_t type; /* enum SWRunType */ int32_t status; /* enum SWRunStatus */ int32_t perfCPU; int32_t perfMemory; -#define HR_SWRUN_FOUND 0x001 +#define HR_SWRUN_FOUND 0x001 uint32_t flags; uint64_t r_tick; /* tick when entry refreshed */ TAILQ_ENTRY(swrun_entry) link; @@ -134,6 +138,9 @@ swrun_entry_delete(struct swrun_entry *entry) TAILQ_REMOVE(&swrun_tbl, entry, link); + free(entry->name); + free(entry->path); + free(entry->parameters); free(entry); } @@ -152,7 +159,7 @@ swrun_entry_find_by_index(int32_t idx) } /** - * Translate the kernel's process status to the SNMP one. + * Translate the kernel's process status to SNMP. */ static enum SWRunStatus swrun_OS_get_proc_status(const struct kinfo_proc *kp) @@ -199,19 +206,22 @@ kinfo_proc_to_swrun_entry(const struct kinfo_proc *kp, { char **argv = NULL; uint64_t cpu_time = 0; + size_t pname_len; - strlcpy((char*)entry->name, kp->ki_comm, sizeof(entry->name)); + pname_len = strlen(kp->ki_comm) + 1; + entry->name = reallocf(entry->name, pname_len); + if (entry->name != NULL) + strlcpy(entry->name, kp->ki_comm, pname_len); - entry->id = oid_zeroDotZero; /* unknown id - FIXME */ - - entry->path[0] = '\0'; - entry->parameters[0] = '\0'; + entry->id = &oid_zeroDotZero; /* unknown id - FIXME */ assert(hr_kd != NULL); - argv = kvm_getargv(hr_kd, kp, sizeof(entry->parameters) - 1); + argv = kvm_getargv(hr_kd, kp, SWR_PARAM_MLEN - 1); if(argv != NULL){ - memset(entry->parameters, '\0', sizeof(entry->parameters)); + u_char param[SWR_PARAM_MLEN]; + + memset(param, '\0', sizeof(param)); /* * FIXME @@ -221,25 +231,39 @@ kinfo_proc_to_swrun_entry(const struct kinfo_proc *kp, * is not realiable */ if(*argv != NULL && (*argv)[0] == '/') { - memset(entry->path, '\0', sizeof(entry->path)); - strlcpy((char*)entry->path, *argv, sizeof(entry->path)); + size_t path_len; + + path_len = strlen(*argv) + 1; + if (path_len > SWR_PATH_MLEN) + path_len = SWR_PATH_MLEN; + + entry->path = reallocf(entry->path, path_len); + if (entry->path != NULL) { + memset(entry->path, '\0', path_len); + strlcpy((char*)entry->path, *argv, path_len); + } } argv++; /* skip the first one which was used for path */ while (argv != NULL && *argv != NULL ) { - if (entry->parameters[0] != 0) { + if (param[0] != 0) { /* * add a space between parameters, * except before the first one */ - strlcat((char *)entry->parameters, - " ", sizeof(entry->parameters)); + strlcat((char *)param, " ", sizeof(param)); } - strlcat((char *)entry->parameters, *argv, - sizeof(entry->parameters)); + strlcat((char *)param, *argv, sizeof(param)); argv++; } + /* reuse pname_len */ + pname_len = strlen(param) + 1; + if (pname_len > SWR_PARAM_MLEN) + pname_len = SWR_PARAM_MLEN; + + entry->parameters = reallocf(entry->parameters, pname_len); + strlcpy(entry->parameters, param, pname_len); } entry->type = (int32_t)(IS_KERNPROC(kp) ? SRT_OPERATING_SYSTEM : @@ -261,19 +285,26 @@ static void kld_file_stat_to_swrun(const struct kld_file_stat *kfs, struct swrun_entry *entry) { + size_t name_len; assert(kfs != NULL); assert(entry != NULL); - strlcpy((char *)entry->name, kfs->name, sizeof(entry->name)); + name_len = strlen(kfs->name) + 1; + if (name_len > SWR_NAME_MLEN) + name_len = SWR_NAME_MLEN; + + entry->name = reallocf(entry->name, name_len); + if (entry->name != NULL) + strlcpy((char *)entry->name, kfs->name, name_len); /* FIXME: can we find the location where the module was loaded from? */ - entry->path[0] = '\0'; + entry->path = NULL; /* no parameters for kernel files (.ko) of for the kernel */ - entry->parameters[0] = '\0'; + entry->parameters = NULL; - entry->id = oid_zeroDotZero; /* unknown id - FIXME */ + entry->id = &oid_zeroDotZero; /* unknown id - FIXME */ if (strcmp(kfs->name, "kernel") == 0) { entry->type = (int32_t)SRT_OPERATING_SYSTEM; @@ -629,31 +660,41 @@ op_hrSWRunTable(struct snmp_context *ctx __unused, struct snmp_value *value, break; case LEAF_hrSWRunName: - ret = string_get(value, entry->name, -1); - break; + if (entry->name != NULL) + ret = string_get(value, entry->name, -1); + else + ret = string_get(value, "", -1); + break; case LEAF_hrSWRunID: - value->v.oid = entry->id; - break; + assert(entry->id != NULL); + value->v.oid = *entry->id; + break; - case LEAF_hrSWRunPath: - ret = string_get(value, entry->path, -1); - break; + case LEAF_hrSWRunPath: + if (entry->path != NULL) + ret = string_get(value, entry->path, -1); + else + ret = string_get(value, "", -1); + break; case LEAF_hrSWRunParameters: - ret = string_get(value, entry->parameters, -1); - break; + if (entry->parameters != NULL) + ret = string_get(value, entry->parameters, -1); + else + ret = string_get(value, "", -1); + break; case LEAF_hrSWRunType: - value->v.integer = entry->type; + value->v.integer = entry->type; break; case LEAF_hrSWRunStatus: - value->v.integer = entry->status; + value->v.integer = entry->status; break; default: - abort(); + abort(); } return (ret); } @@ -732,7 +773,7 @@ op_hrSWRunPerfTable(struct snmp_context *ctx __unused, case SNMP_OP_ROLLBACK: case SNMP_OP_COMMIT: - abort(); + abort(); } abort(); @@ -745,7 +786,7 @@ op_hrSWRunPerfTable(struct snmp_context *ctx __unused, case LEAF_hrSWRunPerfMem: value->v.integer = entry->perfMemory; - return (SNMP_ERR_NOERROR); + return (SNMP_ERR_NOERROR); } abort(); } |