-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Jonas Johansson <jonasj76@gmail.com>
- Loading branch information
Showing
4 changed files
with
370 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: | ||
*/ |