components/net-snmp/sun/sdk/demo/demo_module_7/demo_module_7.c
changeset 252 ee0fb1eabcbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/net-snmp/sun/sdk/demo/demo_module_7/demo_module_7.c	Fri May 20 12:17:45 2011 +0530
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ *
+ * U.S. Government Rights - Commercial software. Government users are subject
+ * to the Sun Microsystems, Inc. standard license agreement and applicable
+ * provisions of the FAR and its supplements.
+ *
+ *
+ * This distribution may include materials developed by third parties. Sun,
+ * Sun Microsystems, the Sun logo and Solaris are trademarks or registered
+ * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
+ *
+ */
+
+/*
+ * Note: this file originally auto-generated by mib2c using
+ *        : mib2c.scalar.conf,v 1.5 2002/07/18 14:18:52 dts12 Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "demo_module_7.h"
+
+static long fileX_data = 111; // Hardcoded size of fileX context name string
+static long fileY_data = 999; // Hardcoded size of fileY context name string
+
+static long PRIORITY = 0;
+static long SUB_ID = 0;
+static long RANGE_UBOUND = 0;
+
+// Gets size of file
+static oid me1filesize_oid[] =      { 1,3,6,1,4,1,42,2,2,4,4,6,1,1,0 };
+
+// Registers a context
+static oid me1createContext_oid[] = { 1,3,6,1,4,1,42,2,2,4,4,6,1,2,0 };
+
+// Unregisters a context
+static oid me1removeContext_oid[] = { 1,3,6,1,4,1,42,2,2,4,4,6,1,3,0 };
+
+// Name of file whose size should be returned
+char *filename;
+
+/*
+  This example module registers context name strings that represent files.
+  Get requests to these contexts will retrieve the size of the file.
+
+  The module can be dynamically updated to register new file names, by
+  issuing an snmpset command.  You do not need to edit the module in
+  application passes the file name to the module by issuing an snmpset
+  command, such as the following:
+
+	snmpset -v 3 -u < user_name > -n "< file_name >"
+	-l authNoPriv -A " <password >" < agent_host_name >
+	< createContext OID > .
+
+  The module registers the set_createContext handler to handle incoming
+  snmp set requests for this OID. The set_createContext handler registers
+  the new filename as a context string in the contextName member of the
+  netsnmp_registration_handler struct for the filesize_oid.
+
+  Subsequent snmpget requests for the size of the file will
+  return its size in blocks:  For example:
+
+	snmpget -v 3 -u < user_name > -n "< file_name >"
+	-l authNoPriv -A "< password  >" < agent_host_name >
+	< filesize_oid >  */
+
+
+/* Initializes the filesize module */
+
+void
+init_demo_module_7(void)
+{
+
+	char *filexcon = "fileX";
+	char *fileycon = "fileY";
+
+
+	netsnmp_handler_registration *myreg1;
+	int status;
+
+	/*
+	Create a read-only registration handler named filesize,
+	which calls the get_filesize function to service snmp requests
+	for the me1filesize_oid object.  The OID_LENGTH argument
+	calculates the length of the me1filesize_oid. */
+	DEBUGMSGTL(("demo_module_7", "Initializing\n"));
+	myreg1 = netsnmp_create_handler_registration
+					("filesize",
+					get_filesize,
+					me1filesize_oid,
+					OID_LENGTH(me1filesize_oid),
+					HANDLER_CAN_RONLY);
+
+	myreg1->contextName = filexcon;
+	status = netsnmp_register_read_only_instance(myreg1);
+	DEBUGMSGTL(("demo_module_7", "init reg1 status %d:\n",  status));
+
+
+	myreg1 = netsnmp_create_handler_registration
+					("filesize",
+					get_filesize,
+					me1filesize_oid,
+					OID_LENGTH(me1filesize_oid),
+					HANDLER_CAN_RONLY);
+
+	myreg1->contextName = fileycon;
+	status = netsnmp_register_read_only_instance(myreg1);
+	DEBUGMSGTL(("demo_module_7", "init reg2 status %d:\n",  status));
+
+
+	/*
+	Create a read-write registration handler named filesize,
+	which calls the set_createContext function to service snmp requests
+	for the me1createContext_oid object.  The OID_LENGTH argument
+	calculates the length of the me1createContext_oid. */
+	myreg1 = netsnmp_create_handler_registration
+					("filesize",
+					set_createContext,
+					me1createContext_oid,
+					OID_LENGTH(me1createContext_oid),
+					HANDLER_CAN_RWRITE);
+
+	status = netsnmp_register_instance(myreg1);
+	DEBUGMSGTL(("filesize", "init reg3 status %d:\n",  status));
+
+	/*
+	Create a read-write registration handler named filesize,
+	which calls the set_removeContext function to service snmp requests
+	for the me1removeContext_oid object.  The OID_LENGTH argument
+	calculates the length of the me1removeContext_oid. */
+	myreg1 = netsnmp_create_handler_registration
+					("filesize",
+					set_removeContext,
+					me1removeContext_oid,
+					OID_LENGTH(me1removeContext_oid),
+					HANDLER_CAN_RWRITE);
+
+	status = netsnmp_register_instance(myreg1);
+	DEBUGMSGTL(("demo_module_7", "init reg4 status %d:\n", status));
+}
+
+	/*
+	This handler handles set requests on the m1createContext_oid
+	by registering a context. The handler extracts the string from
+	the snmp set request and uses it to register a new context for
+	the mefilesize_oid.
+
+	This handler handles get requests by returning the last context
+	name that was registered.
+
+	For detailed info. on net-snmp set processing,
+	see "http://www.net-snmp.org/tutorial-5/toolkit/mib_module/index.html"
+	net-snmp call each SNMP mode in sequence. The case statement
+	transfers control to the default: case when no other condition
+	is satisfied. */
+
+int
+set_createContext(netsnmp_mib_handler *handler,
+	netsnmp_handler_registration *reginfo,
+	netsnmp_agent_request_info *reqinfo,
+	netsnmp_request_info *requests)
+{
+
+	netsnmp_handler_registration *myreg;
+	char *context_names[256];
+	int status;
+	DEBUGMSGTL(("demo_module_7", "set_createContext CALLED\n"));
+	DEBUGMSGTL(("demo_module_7", "reqinfo->mode = %d\n", reqinfo->mode));
+	switch (reqinfo -> mode) {
+
+	case MODE_SET_RESERVE1:
+		break;
+
+	case MODE_SET_RESERVE2:
+		break;
+
+	case MODE_SET_FREE:
+		break;
+
+	case MODE_SET_ACTION:
+
+		DEBUGMSGTL(("demo_module_7", "MODE_SET_ACTION CALLED\n"));
+		DEBUGMSGTL(("demo_module_7", "requests->requestvb->val = %s\n",
+			(u_char *) requests->requestvb->val.string));
+
+                // You must allocate memory for this variable because
+		// the unregister_mib function frees it.
+		filename = malloc(requests->requestvb->val_len + 1);
+		snprintf(filename, requests->requestvb->val_len + 1, "%s",
+		    (u_char *) requests->requestvb->val.string);
+	        filename[requests->requestvb->val_len + 1] = '\0';
+	
+		DEBUGMSGTL(("demo_module_7", "filename = %s\n", filename));
+
+		/*
+		Create a registration handler for the me1filesize_oid
+		object in the new context name specified by
+		the snmp set on the me1createContext OID. */
+		myreg = netsnmp_create_handler_registration
+			("test", get_test, me1filesize_oid,
+			OID_LENGTH(me1filesize_oid),
+			HANDLER_CAN_RONLY);
+		myreg->contextName = filename;
+		status = netsnmp_register_read_only_instance(myreg);
+		DEBUGMSGTL(("demo_module_7", "status %d:\n",  status));
+		break;
+
+	case MODE_SET_COMMIT:
+		break;
+
+	case MODE_SET_UNDO:
+		/*
+		Not handling the undo case because we don't care about
+		multi-phase sets for this example. */
+		break;
+
+	case MODE_GET:
+		snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
+			(u_char *)filename, sizeof (filename));
+
+	default:
+		/* we should never get here, so this is a really bad error */
+	DEBUGMSGTL(("demo_module_7", "default CALLED\n"));
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
+
+	/*
+	This handler handles set requests on the m1removeContext_oid
+	for detailed info. on net-snmp set processing,
+	see "http://www.net-snmp.org/tutorial-5/toolkit/mib_module/index.html"
+	net-snmp call each SNMP mode in sequence. The case statement
+	transfers control to the default: case when no other condition
+	is satisfied. */
+
+int
+set_removeContext(netsnmp_mib_handler *handler,
+	netsnmp_handler_registration *reginfo,
+	netsnmp_agent_request_info *reqinfo,
+	netsnmp_request_info *requests)
+{
+	DEBUGMSGTL(("demo_module_7", "remove_filesize CALLED\n"));
+	switch (reqinfo->mode) {
+		case MODE_SET_RESERVE1:
+			break;
+		case MODE_SET_RESERVE2:
+			break;
+		case MODE_SET_ACTION:
+			DEBUGMSGTL(("demo_module_7",
+				"remove_filesize MODE_SET_ACTION CALLED\n"));
+			DEBUGMSGTL(("demo_module_7",
+			    "remove_filesize MODE_SET_ACTION CALLED\n"));
+			snprintf(filename, requests->requestvb->val_len + 1,
+			    "%s",  (u_char *) requests->requestvb->val.string);
+			filename[requests->requestvb->val_len + 1] = '\0';
+			DEBUGMSGTL(("demo_module_7",
+				"filename after snmpset = %s:\n",
+				filename));
+			unregister_mib_context(me1filesize_oid,
+				OID_LENGTH(me1filesize_oid),
+				PRIORITY, SUB_ID, RANGE_UBOUND,
+				filename);
+			break;
+
+		case MODE_SET_COMMIT:
+			break;
+
+		case MODE_SET_FREE:
+			break;
+
+		case MODE_SET_UNDO:
+			/*
+			Not handling the undo case because we don't care about
+			multi-phase sets for this example. */
+			break;
+
+		default:
+			/*
+			we should never get here, so this
+			is a really bad error */
+			DEBUGMSGTL(("demo_module_7", "set_removeContext CALLED\n"));
+	}
+	return (SNMP_ERR_NOERROR);
+}
+
+
+
+int
+get_filesize(netsnmp_mib_handler *handler,
+	netsnmp_handler_registration *reginfo,
+	netsnmp_agent_request_info *reqinfo,
+	netsnmp_request_info *requests)
+{
+	/*
+	This handler is never called for a getnext
+	if it is registered as an instance. An instance
+	handler only delivers one request at a time, so
+	we do not need to loop over a list of requests. */
+
+	DEBUGMSGTL(("demo_module_7", "get_filesize CALLED\n"));
+	DEBUGMSGTL(("demo_module_7", "INCOMING CONTEXT NAME = %s:\n",
+		reginfo->contextName));
+
+	switch (reqinfo->mode) {
+
+		case MODE_GET:
+
+		if (strcmp(reginfo->contextName, "fileX") == 0)
+			snmp_set_var_typed_value(requests->requestvb,
+				ASN_INTEGER, (u_char *) &fileX_data
+					/* pointer to the scalar's data */,
+				sizeof (fileX_data)
+					/* the length of the data in bytes */);
+
+		else if (strcmp(reginfo->contextName, "fileY") == 0)
+			snmp_set_var_typed_value(requests->requestvb,
+				ASN_INTEGER, (u_char *)	&fileY_data
+					/* Pointer to the scalar's data */,
+				sizeof (fileY_data)
+					/* Length of the data in bytes */);
+	break;
+
+	default:
+	/*
+	We should never get here, so this is a really bad error */
+		return (SNMP_ERR_GENERR);
+}
+
+    return (SNMP_ERR_NOERROR);
+}
+
+int
+get_test(netsnmp_mib_handler *handler,
+	netsnmp_handler_registration *reginfo,
+	netsnmp_agent_request_info *reqinfo,
+	netsnmp_request_info *requests)
+{
+	/*
+	This handler is called to handle snmpset requests for a new
+	context name in the me1filesize_oid. If it is called to
+	handle snmp get requests, the handler does not need to
+	handle a GETNEXT if it is registered as an
+	instance handler. Instance handlers only deliver one request
+	at a time, so we do not need to loop over a list of requests. */
+
+	struct stat buf;
+	static int fd = 0;
+	DEBUGMSGTL(("demo_module_7", "get_test CALLED\n"));
+	DEBUGMSGTL(("demo_module_7", "INCOMING CONTEXT NAME = %s:\n",
+		reginfo->contextName));
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		if (strcmp(reginfo->contextName, filename) == 0)
+		// An open() for reading only returns without delay.
+			if ((fd = open(filename, O_NONBLOCK |
+				O_RDONLY)) == -1)
+				DEBUGMSGTL(("demo_module_7", "ERROR\n"));
+
+			if (fstat(fd, &buf) == -1)
+				DEBUGMSGTL(("demo_module_7", "ERROR\n"));
+			else
+				DEBUGMSGTL(("demo_module_7",
+				"FILE SIZE IN BYTES = %d:\n",
+					buf.st_size));
+
+				snmp_set_var_typed_value(requests->requestvb,
+					ASN_INTEGER, (u_char *) &buf.st_size
+					/* Pointer to the scalar's data */,
+					sizeof (buf.st_size)
+					/* The length of the data in bytes*/);
+		break;
+
+	default:
+		/*
+		we should never get here, so this is a really bad error */
+		return (SNMP_ERR_GENERR);
+	}
+	return (SNMP_ERR_NOERROR);
+}