Skip to content

Commit

Permalink
Add table helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
  • Loading branch information
jonasj76 committed Mar 17, 2016
1 parent dafeaef commit 852e1a2
Show file tree
Hide file tree
Showing 4 changed files with 370 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ CPPFLAGS += -W -Wall
LDFLAGS +=
ARFLAGS +=

HEADERS = scalar.h priv.h
OBJS = scalar.o
HEADERS = scalar.h table.h priv.h
OBJS = scalar.o table.o
DEPS := $(OBJS:.o=.d)

LIBNAME = $(NAME)
Expand Down
3 changes: 3 additions & 0 deletions priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <net-snmp/agent/net-snmp-agent-includes.h>

#define FN_HANDLE(_n) ( nsh_handle_ ## _n )
#define FN_INDEX(_n) ( _n ## _index )

#define ENTRY_SIZE(s,e) sizeof(((s*)0)->e)

int __nsh_scalar_handler(u_char type,
int id,
Expand Down
148 changes: 148 additions & 0 deletions table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/* Table helpers
*
* Copyright (c) 2016 Jonas Johansson <jonasj76@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "table.h"

#define TIMEOUT 5

void nsh_register_table(const char* name,
const oid *table_oid,
size_t oid_len,
unsigned int min_column,
unsigned int max_column,
int* idx_list,
int num_idx,
Netsnmp_Node_Handler *table_handler,
Netsnmp_First_Data_Point *table_get_first,
Netsnmp_First_Data_Point *table_get_next,
NetsnmpCacheLoad *table_load_hook,
NetsnmpCacheFree *table_free_hook,
int access)
{
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
int i;

reg = netsnmp_create_handler_registration(name,
table_handler,
table_oid,
oid_len,
access);

table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
for (i = 0; i < num_idx; i++)
netsnmp_table_helper_add_index(table_info, idx_list[i]);
table_info->min_column = min_column;
table_info->max_column = max_column;

iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
iinfo->get_first_data_point = table_get_first;
iinfo->get_next_data_point = table_get_next;
iinfo->table_reginfo = table_info;

netsnmp_register_table_iterator(reg, iinfo);
netsnmp_inject_handler_before(reg,
netsnmp_get_cache_handler(TIMEOUT,
table_load_hook,
table_free_hook,
table_oid,
oid_len),
TABLE_ITERATOR_NAME);
}

static void __mode_get_req(netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *request,
nsh_table_entry_t *entry)
{
long *table_entry = netsnmp_extract_iterator_context(request);
uint8_t *ofs = (uint8_t*)(table_entry) + entry->ofs;
int len;

if (!table_entry || entry == NULL || !entry->len) {
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
return;
}

if (entry->isstring) {
len = strlen((const char*)ofs);
if (len > entry->len)
len = entry->len;
}
else
len = entry->len;

snmp_set_var_typed_value(request->requestvb,
entry->type,
ofs,
len);
}

static void __mode_get(netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests,
nsh_table_entry_t *table,
unsigned int table_sz)
{
netsnmp_request_info *request;
netsnmp_table_request_info *table_info;

for (request = requests; request; request = request->next) {
table_info = netsnmp_extract_table_info(request);

if (table_info->colnum <= table_sz)
__mode_get_req(reqinfo, request, &table[table_info->colnum-1]);
else
netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
}
}

int nsh_handle_table(netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests,
nsh_table_entry_t *table,
int table_sz)
{
switch (reqinfo->mode) {
case MODE_GET:
__mode_get(reqinfo, requests, table, table_sz);
break;
case MODE_SET_RESERVE1:
case MODE_SET_RESERVE2:
case MODE_SET_FREE:
case MODE_SET_ACTION:
case MODE_SET_UNDO:
case MODE_SET_COMMIT:
break;
}

return SNMP_ERR_NOERROR;
}

/**
* Local Variables:
* c-file-style: "linux"
* End:
*/
217 changes: 217 additions & 0 deletions table.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/* Table helpers
*
* Copyright (c) 2016 Jonas Johansson <jonasj76@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#ifndef NSH_TABLE_H_
#define NSH_TABLE_H_

#include "priv.h"

/**
* nsh_table_index_t - Table index struct
* @type : Index type:
* %ASN_COUNTER, %ASN_INTEGER, %ASN_TIMETICKS, %ASN_UNSIGNED,
* %ASN_IPADDRESS, %ASN_OCTET_STR or %ASN_OBJECT_ID
* @len : Length of index object.
* If @len = -1 and @type is %ASN_OCTET_STR, the length
* will be set by using strlen().
* @ofs : Offset in table data struct where object can be found.
*/
typedef struct nsh_table_index_t {
int type;
int len;
int ofs;
int isstring;
} nsh_table_index_t;

/**
* NSH_TABLE_INDEX - Macro to fill a @nsh_table_index_t entry
* @_type : Index type, see @nsh_table_index_t.
* @_table_data : Table data struct of type @nsh_table_index_t.
* @_obj : Element in @_table_data.
* @_isstring : Element is a string.
*/
#define NSH_TABLE_INDEX(_type, _struct, _obj, _isstring) \
{.type = _type, .len = ENTRY_SIZE(_struct, _obj), .ofs = offsetof (struct _struct, _obj), .isstring = _isstring}

/**
* nsh_table_entry_t - Table entry struct
* @type : Object type:
* %ASN_COUNTER, %ASN_INTEGER, %ASN_TIMETICKS, %ASN_UNSIGNED,
* %ASN_IPADDRESS, %ASN_OCTET_STR or %ASN_OBJECT_ID
* @len : Length of object.
* @ofs : Offset in table data struct where object can be found.
*/
typedef struct nsh_table_entry_t {
int type;
int len;
int ofs;
int isstring;
} nsh_table_entry_t;

/**
* NSH_TABLE_ENTRY - Macro to fill a @nsh_table_entry_t entry
* @_type : Index type, see @nsh_table_entry_t.
* @_table_data : Table data struct of type @nsh_table_entry_t.
* @_obj : Element in @_table_data.
* @_isstring : Element is a string.
*/
#define NSH_TABLE_ENTRY(_type, _struct, _obj, _isstring) \
{.type = _type, .len = ENTRY_SIZE(_struct, _obj), .ofs = offsetof(struct _struct, _obj), .isstring = _isstring}
#define NSH_TABLE_ENTRY_RO(_type, _struct, _obj, _isstring) \
NSH_TABLE_ENTRY(_type, _struct, _obj, _isstring)

/**
* nsh_register_table - Register a OID table handler
* @name : OID name of table. A string.
* @table_oid : OID to register.
* @oid_len : Length of OID. Use OID_LENGTH(@table_oid).
* @min_column : Fist column to be handled. Usually 1.
* @max_column : Last column to be handled.
* @idx_list : List if indexes. An int array.
* @num_idx : Number of indexes in @idx_list.
* @table_handler : Name of callback to table handler function.
* @table_get_first : Name of callback to table get first function.
* @table_get_next : Name of callback to table get next function.
* @table_load_hook : Name of callback to table load hook function.
* @table_free_hook : Name of callback to table free hook function.
* @access : HANDLER_CAN_RONLY | HANDLER_CAN_RWRITE
*
* This function will register a tabler handler callback for the OID @table_oid.
* The callbacks for @table_get_first, @table_get_next, @table_load_hook
* and @table_free_hook can be created by nsh_table_get_first(),
* nsh_table_get_next(), nsh_table_load_hook() and nsh_table_free_hook() macros.
*/
void nsh_register_table(const char* name,
const oid *table_oid,
size_t oid_len,
unsigned int min_column,
unsigned int max_column,
int* idx_list,
int num_idx,
Netsnmp_Node_Handler *table_handler,
Netsnmp_First_Data_Point *table_get_first,
Netsnmp_First_Data_Point *table_get_next,
NetsnmpCacheLoad *table_load_hook,
NetsnmpCacheFree *table_free_hook,
int access);

/**
* nsh_table_free - Empty table elements
* @_name : Name of the function to be created.
* @_table_data : Table data struct.
* @_head : Head of table data.
*
* This will run before an eventual table load to make sure that
* everything is empty.
*/
#define nsh_table_free(_name, _table_data, _head) \
static void _name(netsnmp_cache *cache, void* vmagic) \
{ \
_table_data *this, *that; \
\
for (this = _head; this; this = that) { \
that = this->next; \
SNMP_FREE (this); \
} \
_head = NULL; \
}

/**
* nsh_table_get_first - Get first table element
* @_name : Name of function to be created.
* @table_get_next : Name of callback to table get next function.
* @_head : Head of table data.
*/
#define nsh_table_get_first(_name, _table_get_next, _head) \
static netsnmp_variable_list* _name(void **loop_context, \
void **data_context, \
netsnmp_variable_list *put_index_data, \
netsnmp_iterator_info *data) \
{ \
*loop_context = _head; \
return _table_get_next(loop_context, data_context, \
put_index_data, data); \
}

/**
* nsh_table_get_next - Get next table element
* @_name : Name of function to be created.
* @_table_data : Table data struct.
* @_idx_list : Pointer to index list.
* @_num_idx : Number of indexes in table index list.
*/
#define nsh_table_get_next(_name, _table_data, _idx_list, _num_idx) \
typedef nsh_table_index_t* (*nsh_table_index_cb)(void); \
\
static nsh_table_index_t* FN_INDEX(_name)(void) \
{ \
return _idx_list; \
} \
\
static netsnmp_variable_list* _name (void **loop_context, \
void **data_context, \
netsnmp_variable_list *put_index_data, \
netsnmp_iterator_info *data) \
{ \
_table_data *entry = (_table_data*)*loop_context; \
netsnmp_variable_list *idx = put_index_data; \
nsh_table_index_cb idx_list_cb = FN_INDEX(_name); \
nsh_table_index_t *index = idx_list_cb(); \
int i, len; \
\
if (!entry) \
return NULL; \
\
for (i = 0; i < _num_idx; i++) { \
len = index[i].len; \
if (len < 0 && (index[i].type == ASN_OCTET_STR)) \
len = strlen(((char*)entry + index[i].ofs)); \
snmp_set_var_typed_value (idx, index[i].type, \
(char*)entry + index[i].ofs, len); \
idx = idx->next_variable; \
} \
*data_context = (void*) entry; \
*loop_context = (void*) entry->next; \
\
return put_index_data; \
}

/**
* nsh_handle_table - Handle table request
* @reqinfo : Net-Snmp parameter.
* @requests : Net-Snmp parameter.
* @table : Pointer to @nsh_table_entry_t list.
* @table_sz : Number of elements in @table.
*/
int nsh_handle_table(netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests,
nsh_table_entry_t *table,
int table_sz);

#endif /* NSH_TABLE_H_ */

/**
* Local Variables:
* c-file-style: "linux"
* End:
*/

0 comments on commit 852e1a2

Please sign in to comment.