Hello coders,
It's nice that I implemented RowStatus Table by using mfd.conf,
on NET-SNMP v5.3.0.1 (v5.3.1 will ok).
Scenario:
A SNMP client will tell the sub-agent server_ip, server_port, game_ip and
game_port,
so the sub-agent could notify the correct server to deny that game's TCP
connection.
Who may read my info?:
Who know how to handl SNMP GET in a sub-agent, but do not know how to handle
SNMP SET/ RowStatus.
I should thank [EMAIL PROTECTED] I completed this example with your great helps.
Limitations:
The sub-agent can run.
Client's SET requests will be processed correctly.
snmpset ... Stat i 6
snmpset ... Stat i 5
snmpset ... SrvIp a <IP 1>
snmpset ... SrvPort i <port 1>
snmpset ... GsIp a <IP 2>
snmpset ... GsPort i <port 2>
snmpset ... Stat i 1
So the limitation is no any other things left.
I think it's enough as an example.
1. First of all you may find the patch (or you need to modify mfd-interface.m2i
which in snmp/mib2c-data)
to solve "undefined reference to `_mfd_${context}_rowreq_from_index' ".
(thanks rstory's help, see my previous posts).
2. Example (private MIBs, table-${context}.m2d, ${context}_data_access.c and
${context}_data_set.c that you may care about) posts below.
MIBs, take a look at MAX-ACCESS/STATUS/INDEX.
-----------------------
--
-- CCliCtr implementations
--
CCliCtrEntry ::= SEQUENCE{
Idx4CliCtr INTEGER,
Stat4CliCtr RowStatus,
SrvIp4CliCtr IpAddress,
SrvPort4CliCtr INTEGER,
GsIp4CliCtr IpAddress,
GsPort4CliCtr INTEGER
}
CCliCtrTable OBJECT-TYPE
SYNTAX SEQUENCE OF CCliCtrEntry
MAX-ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"xxx"
::= {cliCtr 1}
CCliCtrRow OBJECT-TYPE
SYNTAX CCliCtrEntry
MAX-ACCESS not-accessible
STATUS mandatory
INDEX{Idx4CliCtr}
::= {CCliCtrTable 1}
Idx4CliCtr OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS not-accessible
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 1}
Stat4CliCtr OBJECT-TYPE
SYNTAX RowStatus
MAX-ACCESS read-create
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 2}
SrvIp4CliCtr OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-write
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 3}
SrvPort4CliCtr OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-write
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 4}
GsIp4CliCtr OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-write
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 5}
GsPort4CliCtr OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-write
STATUS mandatory
DESCRIPTION
"xxx"
::= {CCliCtrRow 6}
------------------------------------------------
w/t *.c, you may note that I changed the code which I remarked /*rex ... */.
------------------------------------------------
data_access.c
int
CCliCtrTable_container_load(netsnmp_container * container)
{
CCliCtrTable_rowreq_ctx *rowreq_ctx;
size_t count = 0;
DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_container_load",
"called\n"));
/*
* TODO:351:M: |-> Load/update data in the CCliCtrTable container.
* loop over your CCliCtrTable data, allocate a rowreq context,
* set the index(es) [and data, optionally] and insert into
* the container.
*/
while (1) {
/*
* TODO:352:M: | |-> set indexes in new CCliCtrTable rowreq context.
*/
rowreq_ctx = CCliCtrTable_allocate_rowreq_ctx();
if (NULL == rowreq_ctx) {
snmp_log(LOG_ERR, "memory allocation failed\n");
return MFD_RESOURCE_UNAVAILABLE;
}
if (MFD_SUCCESS !=
/*rex CCliCtrTable_indexes_set(rowreq_ctx, Idx4CliCtr)) { */
CCliCtrTable_indexes_set(rowreq_ctx, rand()%10000)) {
snmp_log(LOG_ERR,
"error setting index while loading "
"CCliCtrTable data.\n");
CCliCtrTable_release_rowreq_ctx(rowreq_ctx);
continue;
}
/*
* TODO:352:r: | |-> populate CCliCtrTable data context.
* Populate data context here. (optionally, delay until row prep)
*/
/*
* non-TRANSIENT data: no need to copy. set pointer to data
*/
/*
* insert into table container
*/
CONTAINER_INSERT(container, rowreq_ctx);
++count;
}
DEBUGMSGT(("verbose:CCliCtrTable:CCliCtrTable_container_load",
"inserted %d records\n", count));
return MFD_SUCCESS;
} /* CCliCtrTable_container_load */
int
CCliCtrTable_validate_index(CCliCtrTable_registration * CCliCtrTable_reg,
CCliCtrTable_rowreq_ctx * rowreq_ctx)
{
int rc = MFD_SUCCESS;
DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_validate_index",
"called\n"));
/** we should have a non-NULL pointer */
netsnmp_assert(NULL != rowreq_ctx);
/*
* TODO:430:M: |-> Validate potential CCliCtrTable index.
*/
/* rex if (1) { */
if(0){
/*************/
snmp_log(LOG_WARNING, "invalid index for a new row in the "
"CCliCtrTable table.\n");
/*
* determine failure type.
*
* If the index could not ever be created, return MFD_NOT_EVER
* If the index can not be created under the present circumstances
* (even though it could be created under other circumstances),
* return MFD_NOT_NOW.
*/
if (0) {
return MFD_CANNOT_CREATE_EVER;
} else {
return MFD_CANNOT_CREATE_NOW;
}
}
return rc;
} /* CCliCtrTable_validate_index */
-------------------------------------------------------
data_set.c
int
CCliCtrTable_commit(CCliCtrTable_rowreq_ctx * rowreq_ctx)
{
int rc = MFD_SUCCESS;
int save_flags;
DEBUGMSGTL(("verbose:CCliCtrTable:CCliCtrTable_commit", "called\n"));
/** we should have a non-NULL pointer */
netsnmp_assert(NULL != rowreq_ctx);
/*
* save flags, then clear until we actually do something
*/
save_flags = rowreq_ctx->column_set_flags;
rowreq_ctx->column_set_flags = 0;
/*
* commit CCliCtrTable data
* 1) check the column's flag in save_flags to see if it was set.
* 2) clear the flag when you handle that column
* 3) set the column's flag in column_set_flags if it needs undo
* processing in case of a failure.
*/
if (save_flags & COLUMN_STAT4CLICTR_FLAG) {
save_flags &= ~COLUMN_STAT4CLICTR_FLAG; /* clear Stat4CliCtr */
/*
* TODO:482:o: |-> commit column Stat4CliCtr.
*/
/*rex rc = -1; */
if (-1 == rc) {
snmp_log(LOG_ERR,
"CCliCtrTable column Stat4CliCtr commit failed\n");
} else {
/*
* set flag, in case we need to undo Stat4CliCtr
*/
rowreq_ctx->column_set_flags |= COLUMN_STAT4CLICTR_FLAG;
}
}
if (save_flags & COLUMN_SRVIP4CLICTR_FLAG) {
save_flags &= ~COLUMN_SRVIP4CLICTR_FLAG; /* clear SrvIp4CliCtr */
/*
* TODO:482:o: |-> commit column SrvIp4CliCtr.
*/
/*rex rc = -1; */
if (-1 == rc) {
snmp_log(LOG_ERR,
"CCliCtrTable column SrvIp4CliCtr commit failed\n");
} else {
/*
* set flag, in case we need to undo SrvIp4CliCtr
*/
rowreq_ctx->column_set_flags |= COLUMN_SRVIP4CLICTR_FLAG;
}
}
if (save_flags & COLUMN_SRVPORT4CLICTR_FLAG) {
save_flags &= ~COLUMN_SRVPORT4CLICTR_FLAG; /* clear SrvPort4CliCtr
*/
/*
* TODO:482:o: |-> commit column SrvPort4CliCtr.
*/
/*rex rc = -1; */
if (-1 == rc) {
snmp_log(LOG_ERR,
"CCliCtrTable column SrvPort4CliCtr commit failed\n");
} else {
/*
* set flag, in case we need to undo SrvPort4CliCtr
*/
rowreq_ctx->column_set_flags |= COLUMN_SRVPORT4CLICTR_FLAG;
}
}
if (save_flags & COLUMN_GSIP4CLICTR_FLAG) {
save_flags &= ~COLUMN_GSIP4CLICTR_FLAG; /* clear GsIp4CliCtr */
/*
* TODO:482:o: |-> commit column GsIp4CliCtr.
*/
/*rex rc = -1; */
if (-1 == rc) {
snmp_log(LOG_ERR,
"CCliCtrTable column GsIp4CliCtr commit failed\n");
} else {
/*
* set flag, in case we need to undo GsIp4CliCtr
*/
rowreq_ctx->column_set_flags |= COLUMN_GSIP4CLICTR_FLAG;
}
}
if (save_flags & COLUMN_GSPORT4CLICTR_FLAG) {
save_flags &= ~COLUMN_GSPORT4CLICTR_FLAG; /* clear GsPort4CliCtr
*/
/*
* TODO:482:o: |-> commit column GsPort4CliCtr.
*/
/*rex rc = -1; */
if (-1 == rc) {
snmp_log(LOG_ERR,
"CCliCtrTable column GsPort4CliCtr commit failed\n");
} else {
/*
* set flag, in case we need to undo GsPort4CliCtr
*/
rowreq_ctx->column_set_flags |= COLUMN_GSPORT4CLICTR_FLAG;
}
}
/*
* if we successfully commited this row, set the dirty flag.
*/
if (MFD_SUCCESS == rc) {
rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
}
if (save_flags) {
snmp_log(LOG_ERR, "unhandled columns (0x%x) in commit\n",
save_flags);
return MFD_ERROR;
}
return rc;
} /* CCliCtrTable_commit */
-----------------------------------------------------------------
the table-*.m2d
-------------------------------------------
@eval $m2c_context_reg = "netsnmp_data_list"@
@eval $m2c_data_allocate = 0@
@eval $m2c_data_cache = 0@
@eval $m2c_data_context = "generated"@ [generated|NAME]
@eval $m2c_data_init = 0@
@eval $m2c_data_transient = 0@
@eval $m2c_include_examples = 1@
@eval $m2c_irreversible_commit = 0@
@eval $m2c_table_access = "container-cached"@
@eval $m2c_table_dependencies = 0@
@eval $m2c_table_persistent = 0@
@eval $m2c_table_row_creation = 1@
@eval $m2c_table_settable = 1@
@eval $m2c_table_skip_mapping = 1@
@eval $m2c_table_sparse = 1@
@eval $mfd_generate_makefile = 0@
@eval $mfd_generate_subagent = 0@
------------------------------------------------------------
Hope it is helpful to you.
Thanks & Regards,
Rex Huang
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders