/* ** File name: SNMP_SUBAGENT.C ** Product: TCPware for VMS ** Version: V5.6 ** Edit level: 2 ** ** Copyright (c) 2001, 2002 ** by ** Process Software LLC ** Framingham, Massachusetts ** ** Copyright (c) 1989-1999 ** by ** Process Software Corporation ** Framingham, Massachusetts ** ** This software is furnished under a license for use on a ** single computer system and may be copied only with the ** inclusion of the above copyright notice. This software, or ** any other copies thereof, may not be provided or otherwise ** made available to any other person except for use on such ** system and to one who agrees to these license terms. Title ** to and ownership of the software shall at all times remain ** in Process Software LLC's name. ** ** The information in this document is subject to change ** without notice and should not be construed as a commitment ** by Process Software LLC. Process Software LLC assumes no ** responsibility for any errors that may appear in this document. ** ** Abstract: ** SNMP_SUBAGENT - SNMP subagent for a microwave MIB. see ** below. ** */ /* ** This subagent implements the Microwave MIB. Definition follows: ** ** MICROWAVE-MIB DEFINITIONS ::= BEGIN ** ** IMPORTS ** enterprises ** FROM RFC1155-SMI ** OBJECT-TYPE ** FROM RFC-1212 ** DisplayString ** FROM RFC-1213; ** ** process OBJECT IDENTIFIER ::= { enterprises 105 } ** microwave OBJECT IDENTIFIER ::= { process 1 } ** ** -- microwave MIB ** ** microwaveMake OBJECT-TYPE ** SYNTAX DisplayString ** ACCESS read-only ** STATUS mandatory ** DESCRIPTION ** "The name of the microwave's manufacturer. for example, ** Micro-Blaster" ** ::= { microwave 1 } ** ** microwaveModel OBJECT-TYPE ** SYNTAX DisplayString ** ACCESS read-only ** STATUS mandatory ** DESCRIPTION ** "The name of the microwave's model. For example, ** Micro-Blaster 9000" ** ::= { microwave 2 } ** ** microwaveSetting OBJECT-TYPE ** SYNTAX INTEGER { ** low(1) ** medium(2) ** high(3) ** nuke(4) ** } ** ACCESS read-write ** STATUS mandatory ** DESCRIPTION ** "This variable controls the power setting on the ** microwave." ** ::= { microwave 3 } ** ** microwaveCook OBJECT-TYPE ** SYNTAX INTEGER (1..10) ** ACCESS read-write ** STATUS mandatory ** DESCRIPTION ** "This variable controls the on/off switch on the ** microwave" ** ::= { microwave 4 } ** ** microwaveTimer OBJECT-TYPE ** SYNTAX INTEGER ** ACCESS read-write ** STATUS mandatory ** DESCRIPTION ** "This variable controls the timer setting on the ** microwave. ** ::= { microwave 5 } ** ** END */ #include #include #include #include "snmp_common.h" #include "snmp_subagent.h" /* ** Define the MIB leaf nodes. The list of variables we are serving through ** this subagent. */ /* first the variable storage */ struct s_subagent_string { unsigned char stringP [256]; unsigned int str_len; }; char Make[] = "Micro-Blaster"; char Model[] = "Micro-Blaster-2000"; int Setting = 5; int Cook = 0; int Timer = 60; /* integrate information into a table */ static MIB_VAR MIB_TABLE[] = { {9, {MIB_PREFIX, 1}, ASN_OCTETSTRING, ACCESS_READ, &Make}, {9, {MIB_PREFIX, 2}, ASN_OCTETSTRING, ACCESS_READ, &Model}, {9, {MIB_PREFIX, 3}, ASN_INTEGER, ACCESS_READ_WRITE, &Setting}, {9, {MIB_PREFIX, 4}, ASN_INTEGER, ACCESS_READ_WRITE, &Cook}, {9, {MIB_PREFIX, 5}, ASN_INTEGER, ACCESS_READ_WRITE, &Timer} }; #define MIB_VAR_COUNT sizeof(MIB_TABLE) / sizeof (MIB_VAR) /* ** trap alert routine */ void (*trap_alert_rtn)(); /* SnmpExtensionInit: ** API routine to initialize and register this subagent with TCPware SNMP ** agent */ int SnmpExtensionInit (void (*trap_rtn)(), unsigned long tzero, unsigned long *reserved, AsnOBJID *supportedView) { OBJECT_ID mib_prefix[] = {MIB_PREFIX}; /* ** Tell the agent how deep the subtree is for this MIB */ supportedView->idLength = MIB_PREFIX_LENGTH; /* ** Send back the object ids for this subtree. */ memcpy (supportedView->ids, mib_prefix, MIB_PREFIX_LENGTH * sizeof (OBJECT_ID)); /* ** Save the trap alert routine. This will be called when this subagent ** needs to send a trap */ trap_alert_rtn = trap_rtn; return TRUE; } /* find_var: ** Return the mib entry in the mib table */ MIB_VAR * find_var (RFC1157VarBind *vb) { int i, j; for (i = 0; i < MIB_VAR_COUNT; i++) { for (j = 0; j < MIB_TABLE[i].idLength; j++) { if (MIB_TABLE[i].ids[j] != vb->name.ids[j]) break; } if (j == MIB_TABLE[i].idLength) break; } if (i < MIB_VAR_COUNT) return (&MIB_TABLE[i]); return NULL; } /* find_next_var ** Return the next mib entry in the mib table ** ** Compare the input parameter to each mib_entry in the table. When ** one is determined to be greater than the input parameter numericaly ** return that mib_entry. If none are return nosuch. */ MIB_VAR * find_next_var (RFC1157VarBind *vb) { int i, j; MIB_VAR *mib_var; int min; for (i = 0; i < MIB_VAR_COUNT; i++) { min = (vb->name.idLength < MIB_TABLE[i].idLength) ? vb->name.idLength : MIB_TABLE[i].idLength; j = 0; while (j < min) { if (MIB_TABLE[i].ids[j] > vb->name.ids[j]) { return &MIB_TABLE[i]; } j++; if (MIB_TABLE[i].ids[j-1] < vb->name.ids[j-1]) continue; } /* ** If we get here then either we didn't find a match and need to look at ** the next. Or the mib_entry is longer than the vb, if the latter return ** the current mib_entry. */ if ((j == min) && (min < MIB_TABLE[i].idLength)) return &MIB_TABLE[i]; } printf ("Not found\n"); return NULL; } void copy_vb (RFC1157VarBind *vb, MIB_VAR *mv) { int i; for (i = 0; i < mv->idLength; i++) vb->name.ids[i] = mv->ids[i]; vb->name.idLength = mv->idLength+ 1; vb->name.ids[i] = 0; return; } /* process_variable: ** Execute the request SET, GET, GET-NEXT and return the RFC1157VarBind record */ int process_variable (unsigned char request_type, RFC1157VarBind *vb) { int i; MIB_VAR *mib_var; switch (request_type) { case MIB_ACTION_SET: mib_var = find_var (vb); if (mib_var) { switch (mib_var->asnType) { case ASN_INTEGER: *(unsigned int *)mib_var->storage = vb->value.asnValue.value.positive; break; case ASN_OCTETSTRING: /* we don't allow write on strings */ return (SNMP_ERRORSTATUS_READONLY); break; default: break; } } break; case MIB_ACTION_GET: if (mib_var) { mib_var = find_var (vb); copy_vb (vb, mib_var); } break; case MIB_ACTION_GETNEXT: mib_var = find_next_var (vb); if (mib_var) { copy_vb (vb, mib_var); } break; default: break; } if (mib_var != NULL) { if ((request_type == MIB_ACTION_GET) || (request_type == MIB_ACTION_GETNEXT)) { switch (mib_var->asnType) { case ASN_INTEGER: vb->value.asnValue.value.positive = *(unsigned int *)mib_var->storage; break; case ASN_OCTETSTRING: vb->value.asnValue.value.stringP = (unsigned char *)mib_var->storage; vb->value.asnValue.str_len = strlen ((char *)mib_var->storage); break; default: break; } } } else return SNMP_ERRORSTATUS_NOSUCHNAME; vb->value.asnType = mib_var->asnType; return SNMP_ERRORSTATUS_NOERROR; } /* SnmpExtensionQuery: ** API routine to perform SET, GET, GET-NEXT operation on this subagents ** variables. */ int SnmpExtensionQuery (unsigned char request_type, RFC1157VarBindList *vbl, int *error_status, int *error_index) { int i; /* ** Process the variables in the list */ for (i = 0; i < vbl->len; i++) { *error_status = process_variable(request_type, &vbl->list[i]); if (*error_status != SNMP_ERRORSTATUS_NOERROR) break; } if (*error_status != SNMP_ERRORSTATUS_NOERROR) { *error_index = i; return FALSE; } return TRUE; } /* SnmpExtensionQuery: ** API routine to perform SET, GET, GET-NEXT operation on this subagents ** variables. */ int SnmpExtensionTrap (void) { return TRUE; }