diff options
author | harti <harti@FreeBSD.org> | 2006-07-14 09:07:56 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2006-07-14 09:07:56 +0000 |
commit | ec8dc009b10228a9b8b31cf0182a461f7477d800 (patch) | |
tree | d03c1bf4caba6a32c82c745b5521bd46029377df /usr.sbin | |
parent | fef54567b298952017d6a43f215042169168d037 (diff) | |
download | FreeBSD-src-ec8dc009b10228a9b8b31cf0182a461f7477d800.zip FreeBSD-src-ec8dc009b10228a9b8b31cf0182a461f7477d800.tar.gz |
Reduce the memory requirements for the tables by (1) using malloced strings
instead of maximum sized arrays embedded in the table structures and (2)
using pointers to constant oids instead of copying the oid into each
table structure. This also fixes indexing in the case when a string used
for indexing is longer than the maximum size allowed in the MIB.
Submitted by: Victor Cruceru <soc-victor@>
Diffstat (limited to 'usr.sbin')
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(); } |