📄 v_vxdemo.c
字号:
( OID * incoming, /* Ptr to the OID received in the SNMP PDU */ ObjectInfo * object, /* Ptr to MIB var in the SNMP MIB tree */ int searchType, /* EXACT = GetRequest,NEXT = Get[Next|Bulk] */ ContextInfo * contextInfo, /* Reserved for future used */ int serialNum /* Used for caching */ ) { static nfsEntry_t * pNfsEntry; /* Ptr to struct with MIB variables */ static OID inst; /* Table entry index to return to agent */ static unsigned long oidbuff; /* OID buffer for inst variable */ void * dp; /* Generic ptr used for returned variable */ long entryIndex; /* Table entry index */ int instLength; /* Length of the incoming OID */ static int lastSerialNum; static OID * last_incoming; int reqVar = -1; if ((lastSerialNum != serialNum) || (pNfsEntry == NULL) || (CmpOIDInst(incoming, last_incoming, object->oid.length) != 0)) { /* * instLength represents the length of the (incoming) requested OID * beyond the Object Identifier specified in the MIB tree. This value * is used to validate the request on an EXACT or NEXT search. Ex. * The MIB variable fakeMibVar = OID 1.3.6.1.4.1.731.1.1.2 and is * specified this way in the object variable. The incoming would * have fakeMibVar.0 = OID 1.3.6.1.4.1.731.1.1.2.0, the length would * be 1 and the last value 0. This information is used to valiate the * EXACT search. In the case of a NEXT search the length must be 0 * for leaf variables. For table entries with an integer index the * incoming OID would be 1.3.6.1.4.1.731.1.1.2.INDEX and the length * would represent the index. */ instLength = incoming->length - object->oid.length; switch (searchType) { case EXACT: if (instLength == 1) { reqVar = object->nominator; /* Field in the table req */ entryIndex = (long) incoming->oid_ptr [object->oid.length]; } break; case NEXT: reqVar = object->nominator; /* Field in the table req */ /* * If the Index was not specified in the request, pick zero as * the first entry. This lets the k_ logic start at the first * entry. Otherwise take the table index passed by the agent. */ entryIndex = (instLength < 1) ? 0 : (long) incoming->oid_ptr [object->oid.length]; break; default: DPRINTF((0, "snmpd: Internal error. (invalid search type in \ nfsEntry_get -- %d)\n", searchType)); } if (reqVar == -1 || (pNfsEntry = k_nfsEntry_get (serialNum, contextInfo, reqVar, searchType, entryIndex)) == NULL) { return ((VarBind *) NULL); /* Entry not Found or End of the Table */ } /* Return to SNMP NM the INDEX of the entry whose OID was requested * this INDEX will be used to request more OIDs of the same entry * entry or to request the NEXT entry in the table. */ inst.length = 1; inst.oid_ptr = &oidbuff; inst.oid_ptr [0] = pNfsEntry->nfsIndex; /* Get new catche information */ lastSerialNum = serialNum; if (last_incoming != NULL) FreeOID(last_incoming); last_incoming = CloneOID(incoming); } else { reqVar = object->nominator; /* Field in the table req */ } switch (reqVar) { case I_nfsIndex: dp = (void *) &pNfsEntry->nfsIndex; break; case I_nfsState: dp = (void *) &pNfsEntry->nfsState; break; case I_nfsHostName: dp = (void *) MakeOctetString (pNfsEntry->nfsHostName->octet_ptr, pNfsEntry->nfsHostName->length); break; case I_nfsHostIpAddr: dp = (void *) MakeOctetString ((unsigned char *) &pNfsEntry->nfsHostIpAddr, 4L); break; case I_nfsHostFileSysName: dp = (void *) MakeOctetString (pNfsEntry->nfsHostFileSysName->octet_ptr, pNfsEntry->nfsHostFileSysName->length); break; case I_nfsLocalFileSysName: dp = (void *) MakeOctetString (pNfsEntry->nfsLocalFileSysName->octet_ptr, pNfsEntry->nfsLocalFileSysName->length); break; default: return ((VarBind *) NULL); } /* * Construct the response for the SNMP agent. The structure returned * will be strung onto the response PDU. The inst parameter contains the * index in the table for the requested variable. */ return (MakeVarBind (object, &inst, dp)); }/********************************************************************************* nfsEntry_free - Free the nfsEntry data structure.** This routine is invoked indirectly by the SNMP agent to free the nfsEntry* structure that was allocated during the call to test, and after the call to* set, or after the test fails.** RETURNS: N/A** SEE ALSO:*/LOCAL void nfsEntry_free ( nfsEntry_t * pNfsEntry ) { if (pNfsEntry != NULL) { if (pNfsEntry->nfsHostName != NULL) FreeOctetString (pNfsEntry->nfsHostName); if (pNfsEntry->nfsHostFileSysName != NULL) FreeOctetString (pNfsEntry->nfsHostFileSysName); if (pNfsEntry->nfsLocalFileSysName != NULL) FreeOctetString (pNfsEntry->nfsLocalFileSysName); free( (char *) pNfsEntry); } }/********************************************************************************* nfsEntry_cleanup - Free all the resources allocated in nfsEntry_test.** This routine is invoked by the SNMP agent after the set operation has taken* placed or if the test routine failed.** RETURNS: NO_ERROR always successful.** SEE ALSO:*/LOCAL int nfsEntry_cleanup ( doList_t *trash ) { nfsEntry_free(trash->data); nfsEntry_free(trash->undodata); return NO_ERROR; }/********************************************************************************* nfsEntry_undo - provided for future use** RETURNS: ERROR** SEE ALSO:*/LOCAL int nfsEntry_undo ( ) { return UNDO_FAILED_ERROR; }/********************************************************************************* nfsEntry_test - Validate new values for the MIB variables.** This routine ensures that the value to which a MIB variable is to be set is* in accordance to its MIB definition in the file vxdemo.my. After all the* variables required to update the an entry or variable is collected, the state* of the doList structure is set to ADD_MODIFY or DELETE, based on the operaion* requested.** RETURNS: NO_ERROR for successful validation, otherwise an error is returned.** SEE ALSO:*/int nfsEntry_test ( OID * incoming, /* Ptr to the OID received in the SNMP PDU */ ObjectInfo * object, /* Ptr to MIB var in the SNMP MIB tree */ ObjectSyntax * value, /* Ptr the value to set the MIB variable */ doList_t * doHead, /* Ptr to the list of SNMP outstanding reqs */ doList_t * doCur, /* Ptr to free doList element */ ContextInfo * contextInfo /* Reserved for future used */ ) { long entryIndex; /* Table Index to be set */ int i; /* Generic index var */ doList_t * dp; nfsEntry_t * pNfsEntry; int instLength; /* * instLength represents the length of the (incoming) requested OID * beyond the Object Identifier specified in the MIB tree. This value * is used to validate the request on an EXACT or NEXT search. Ex. * The MIB variable fakeMibVar = OID 1.3.6.1.4.1.731.1.1.2 and is * specified this way in the object variable. The incoming would * have fakeMibVar.0 = OID 1.3.6.1.4.1.731.1.1.2.0, the length would * be 1 and the last value 0. This information is used to valiate the * EXACT search. In the case of a NEXT search the length must be 0 * for leaf variables. For table entries with an integer index the * incoming OID would be 1.3.6.1.4.1.731.1.1.2.INDEX and the length * would represent the index. In the case of a set operation the variable * needs to be specified exactly and therefore the length must be 1. */ instLength = incoming->length - object->oid.length; if (instLength != 1) { DPRINTF((APWARN, "snmpd: Invalid instance length (%d)\n", instLength)); return (NO_ACCESS_ERROR); } /* Get the index of the entry that is to be modified or created */ entryIndex = (long) incoming->oid_ptr [incoming->length - 1]; /* * There is a single list of SNMP outstanding requests. The list * is shared by all "v_" routines in the agent. Each time a variable * is SET the list must be search for the corresponding data structure. * if the structure does not exits it must be allocated. This space * is freed by the "*free" routine. */ for (dp = doHead; dp != NULL; dp = dp->next) { if ((dp->setMethod == nfsEntry_set) && ((void *) (dp->data) != (void *) NULL) && (((nfsEntry_t *) (dp->data))->nfsIndex == entryIndex)) { break; /* Structure found */ } } if (dp == NULL) { dp = doCur; if ((dp->data = (void *) calloc (1, sizeof(nfsEntry_t))) == NULL) { DPRINTF((0, "snmpd: Can't alloc memory in nfsEntry_test\n")); return (GEN_ERROR); } dp->setMethod = nfsEntry_set; dp->cleanupMethod = nfsEntry_cleanup; dp->undoMethod = nfsEntry_undo; dp->state = UNKNOWN; ((nfsEntry_t *) dp->data)->nfsIndex = entryIndex; SET_VALID(I_nfsIndex, ((nfsEntry_t *) dp->data)->valid); } pNfsEntry = (nfsEntry_t *) dp->data; switch (object->nominator) { case I_nfsIndex: /* * The index specified in the instance must match the index * value specified. The value was already saved above. */ if (value->sl_value != entryIndex) { return (WRONG_VALUE_ERROR); } SET_VALID(I_nfsIndex, pNfsEntry->valid); break; case I_nfsState: /* The entry state must be nfs-mounted(1) or nfs-unmount(2) */ if (value->sl_value != D_nfsState_nfs_mounted && value->sl_value != D_nfsState_nfs_unmount) { return (WRONG_VALUE_ERROR); } pNfsEntry->nfsState = value->sl_value; SET_VALID(I_nfsState, pNfsEntry->valid); break; case I_nfsHostName: pNfsEntry->nfsHostName = MakeOctetString (value->os_value->octet_ptr, value->os_value->length); SET_VALID(I_nfsHostName, pNfsEntry->valid); break; case I_nfsHostIpAddr: if (value->os_value->length != 4) return (WRONG_LENGTH_ERROR); for (i = 3; i >= 0; i--) { if (value->os_value->octet_ptr[i] > 255) return (WRONG_VALUE_ERROR); ((unsigned char *) (&pNfsEntry->nfsHostIpAddr))[i] = value->os_value->octet_ptr[i]; } SET_VALID(I_nfsHostIpAddr, pNfsEntry->valid); break; case I_nfsHostFileSysName: pNfsEntry->nfsHostFileSysName = MakeOctetString (value->os_value->octet_ptr, value->os_value->length); SET_VALID(I_nfsHostFileSysName, pNfsEntry->valid); break; case I_nfsLocalFileSysName: pNfsEntry->nfsLocalFileSysName = MakeOctetString (value->os_value->octet_ptr, value->os_value->length); SET_VALID(I_nfsLocalFileSysName, pNfsEntry->valid); break; default: DPRINTF((0, "snmpd: Internal error (invalid nominator \ in atEntry_test)\n")); return (GEN_ERROR); } /* * Two operations are allowed in NFS table entries. To delete an * entry the index and state must be specified. To add an entry * all the parameters must be specified. */ if (VALID(I_nfsIndex, pNfsEntry->valid) && VALID(I_nfsState, pNfsEntry->valid)) { if (pNfsEntry->nfsState == D_nfsState_nfs_unmount) { dp->state = DELETE; } else { if (VALID(I_nfsHostName, pNfsEntry->valid) && VALID(I_nfsHostIpAddr, pNfsEntry->valid) && VALID(I_nfsHostFileSysName, pNfsEntry->valid) && VALID(I_nfsLocalFileSysName, pNfsEntry->valid)) { dp->state = ADD_MODIFY; } } } return (NO_ERROR); }/********************************************************************************* nfsEntry_set - Invokes k_ logic to set the NFS Entry.** This set routine assumes that the variables to be set are correct. This* assumption is safe because the test routine has already validated the* variable(s) and set the state of the operation.** RETURNS: Success or Error to the SNMP agent.** SEE ALSO:*/int nfsEntry_set ( doList_t * doHead, /* Ptr to the list of SNMP outstanding reqs */ doList_t * doCur, /* Ptr to free doList element */ ContextInfo * contextInfo /* Reserved for future used */ ) { return (k_nfsEntry_set ((nfsEntry_t *) (doCur->data), contextInfo, doCur->state)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -