📄 ospf_mib_envoy_api.c
字号:
/************************************************************************************* ospf_envoy_snmpdTreeAdd - dynamically add a subtree to the SNMP agent MIB tree** This routine adds the specified MIB subtree, located in memory at the address* <pTreeAddr>, to the agent's MIB data tree at the node with the object identifier* specified by <pTreeOidStr>.** RETURNS: OK or ERROR.** ERRNO: N/A*/STATUS ospf_envoy_snmpdTreeAdd( char *pTreeOidStr, MIBNODE_T *pTreeAddr, SEM_ID ospf_envoyBSem ){ int status = 0; MIBNODE_T *pReplacedNode; OBJ_ID_T treeOid; OIDC_T oidArray [MAX_OSPF_OID_LEN]; treeOid.num_components = ospf_envoy_oidStrToArray(pTreeOidStr, oidArray); if (treeOid.num_components > 0) { treeOid.component_list = oidArray; semTake( ospf_envoyBSem, WAIT_FOREVER ); status = Add_Node_From_Root (NULL, &treeOid, pTreeAddr, &pReplacedNode); semGive( ospf_envoyBSem ); if ( status == 0 ) { ospfEnvoyPrintf(("ospf_envoy_snmpdTreeAdd:%s successful\n", pTreeOidStr)); } else { ospfEnvoyPrintf(("ospf_envoy_snmpdTreeAdd:%s failed\n", pTreeOidStr)); } } return ((status == 0) ? OK : ERROR);}/**************************************************************************************** ospfEnvoy_undo - undo routine for ospf method routines.** This is the generic undo routine that will be invoked by Envoy SNMP if failure occured* within the testproc or setproc.** NOTE: The MIB API doesn't support undo. The undo capability will be provided in the* next release. For now, this generic undo routine is used to satisfy Envoy* SNMP.** RETURNS: N/A** NOMANUAL*/void ospfEnvoy_undo( OIDC_T lastmatch, int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp ){ /* tell envoy snmp that the undo process has just begun */ undoproc_started( pktp, vbp ); undoproc_error( pktp, vbp, UNDO_FAILED ); /* always failed for now... */ return;}/**************************************************************************************** ospf_envoy_setGenError - set varbinds with Envoy SNMP GEN_ERR error** This routine sets the varbind with the Envoy SNMP GEN_ERR.** RETURNS: N/A*/void ospf_envoy_setGenError( SNMP_PKT_T *pktp, VB_T *vbp, mApiReqType_t reqType ){ for ( ; vbp ; vbp = vbp->vb_link ) { if ( reqType == MAPI_GET_NEXT ) nextproc_error(pktp, vbp, GEN_ERR ); else if ( reqType == MAPI_GET ) getproc_error( pktp, vbp, GEN_ERR ); else if ( reqType == MAPI_TEST ) { vbp->vb_priv = NULL; testproc_error( pktp, vbp, GEN_ERR ); } else if ( reqType == MAPI_COMMIT ) { vbp->vb_priv = NULL; setproc_error( pktp, vbp, GEN_ERR ); } } return;}/**************************************************************************************** ospf_envoy_setNoSuchNameError - set varbinds with Envoy SNMP NO_SUCH_NAME error** This routine sets the varbinds with the Envoy SNMP NO_SUCH_NAME error** RETURNS: N/A*/void ospf_envoy_setNoSuchNameError( SNMP_PKT_T *pktp, VB_T *vbp, mApiReqType_t reqType ){ for ( ; vbp != NULL; vbp = vbp->vb_link ) { if ( reqType == MAPI_TEST ) { vbp->vb_priv = NULL; testproc_error( pktp, vbp, NO_SUCH_NAME ); } else if ( reqType == MAPI_COMMIT ) { vbp->vb_priv = NULL; setproc_error( pktp, vbp, NO_SUCH_NAME ); } } return;}/***************************************************************************************** ospf_envoy_processGetRespError - process MIB API response error** This routine process the MIB API response error and set the varbinds with the* appropriate Envoy SNMP error code.** RETURNS: N/A*/void ospf_envoy_processGetRespError( SNMP_PKT_T *pktp, VB_T *vbp, mApiReqType_t reqType, int mApiErr ){ for ( ; vbp ; vbp = vbp->vb_link ) { if ( mApiErr == MAPI_INVALID_INSTANCE ) { if ( reqType == MAPI_GET_NEXT ) nextproc_no_next( pktp, vbp ); else getproc_nosuchins( pktp, vbp ); } else { if ( reqType == MAPI_GET_NEXT ) nextproc_error( pktp, vbp, mApi2EnvoyErrorGet( (mApiError_t)mApiErr) ); else getproc_error( pktp, vbp, mApi2EnvoyErrorGet( (mApiError_t)mApiErr) ); } } return;}/************************************************************************************** ospf_envoy_buildSetReq - build MIB API TEST/COMMIT request** This routine build the MIB API request message for testproc, setproc and/or undoproc.* The routine copy the data from varbind to the pointer pointed to by the pValueBuf* array if the data type is VT_NUMBER, VT_COUNTER, VT_GAUGE or VT_IPADDRESS. For* VT_STRING and VT_OPAQUE, data is copied into memory that is dynamically allocated using* SNMP_memory_alloc() and the pOctetBuf pointer will be initialized to pointed to the* allocated memory. It is the caller responsibility to call ospf_envoy_clearBuffer()* to reinitialize the memory pointed to by the pValueBuf pointer and to free the* dynamically allocated memory if the <dynamic> boolean flag is set.** RETURNS: OK or ERROR** ERRNO: N/A*/STATUS ospf_envoy_buildSetReq( int tcount, OIDC_T *tlist, SNMP_PKT_T *pktp, VB_T *vbp, envoyRequest_t *pEnvoyReq, mApiRequest_t *pRequest, mApiReqType_t reqType, int mApiOidOffset ){ VB_T *group_vbp = vbp; mApiObject_t *pObject; unsigned char *envBuffer; int vbcount; int bufCnt; if ( pEnvoyReq == NULL || pRequest == NULL ) { ospfEnvoyPrintf(("ospf_envoy_getVbBuf:bogus pointer\n")); return ERROR; } /* find all the varbinds that share the same getproc and instance and group * them together. Although the varbinds don't change in any significant way between * the calling of the testproc, setproc and undoproc (the flag field may changed), * it is still necessary to call group_by_getproc_and_instance to group all * varbinds that share the same instance each time this routine is invoked. This * is because the pointer to the pValueBuf envoyReqest_t may have been reused * especially if there have been multiple testprocs before the setprocs. */ group_by_getproc_and_instance(pktp, vbp, tcount, tlist); /* retrive the cookie stash by the testproc if tcount is not 1 (scalar objects). * The varbinds don't change in any signification way between the calling of the * testproc, setproc and undoproc ( the flags field may change). The important * thing is the sequence of varbinds as arranged in the linked list remains the * same. Although the cookie is stashed in each varbinds during testproc, we * just need to retrieve the cookie that is is available in the first varbind * (don't need to go thru every varbind). MIB API only allow one cookie per * request anyhow... */ if ( (reqType == MAPI_COMMIT) && (tcount != 1 ) ) { if ( vbp->vb_priv == NULL ) { ospfEnvoyPrintf(("ospf_envoy_buildSetReq:No cookie found!\n")); return ERROR; } pRequest->pReqCookie = vbp->vb_priv; } /* get number of varbinds */ pRequest->numObjects = ospf_envoy_getVbCount( vbp ); /* if number of varbinds are more than what we can handle, return ERROR */ if ( pRequest->numObjects > pEnvoyReq->numValueBuf ) { ospfEnvoyPrintf(("ospf_build_mApiSetRequest: vbcount(%i) exceed max(%i)\n", pRequest->numObjects, pEnvoyReq->numValueBuf)); return ERROR; } /* build the mApiRequest_t structure */ pRequest->pInstance = (ulong_t *)tlist; pRequest->instanceLen = (ushort_t)tcount; pRequest->pObjectList = pEnvoyReq->pObjectList; /* get the data from varbinds. Ideally we want to be able to use the data * from varbinds directly without first copying to a local buffer. Because * of future compatibility concern, we discard that idea... */ for ( bufCnt = 0, vbcount = 0; group_vbp != NULL && vbcount < pRequest->numObjects && bufCnt < pEnvoyReq->numValueBuf; vbcount++, group_vbp = group_vbp->vb_link ) { pObject = &pRequest->pObjectList[vbcount]; pObject->oidPrefixEnum = group_vbp->vb_ml.ml_last_match + mApiOidOffset; pObject->pObjCookie = &pEnvoyReq->pObjCookie[vbcount]; /* set the object cookie in the envoyRequest_t to true if this is the last * object in the varbind list. This is needed so that the rowStatus library * used by the MIB API will know when to manipulate the rowStatus object for * the row instance. Since vbcount is zero-based, it is necessary to decrement * the numObjects by 1 in order to determine if this is the last object in * the varbind list. */ if ( vbcount == (pRequest->numObjects - 1) ) pEnvoyReq->pObjCookie[vbcount] = TRUE; else pEnvoyReq->pObjCookie[vbcount] = FALSE; switch( group_vbp->vb_ml.ml_leaf->expected_tag) { case VT_NUMBER: case VT_COUNTER: case VT_GAUGE: pEnvoyReq->pValueBuf[bufCnt] = VB_GET_INT32(group_vbp); pObject->pValueBuf = &pEnvoyReq->pValueBuf[bufCnt]; pObject->valueLen = sizeof(VB_GET_INT32(group_vbp)); bufCnt++; break; case VT_STRING: case VT_OPAQUE: envBuffer = EBufferStart(VB_GET_STRING(group_vbp)); pEnvoyReq->octetBufLen = EBufferUsed(VB_GET_STRING(group_vbp)); pEnvoyReq->pOctetBuf = SNMP_memory_alloc( pEnvoyReq->octetBufLen ); if ( pEnvoyReq->pOctetBuf == NULL ) { ospfEnvoyPrintf(("ospf_envoy_buildSetReq:octetBuf calloc failed\n")); return ERROR; } /* mark this buffer as dynamic so the caller knows to free it later */ pEnvoyReq->dynamic = TRUE; /* copy data from varbind */ memcpy( pEnvoyReq->pOctetBuf, envBuffer, pEnvoyReq->octetBufLen ); pObject->pValueBuf = pEnvoyReq->pOctetBuf; pObject->valueLen = pEnvoyReq->octetBufLen ; break; case VT_IPADDRESS: pObject->valueLen = 4; memcpy( (char *)&pEnvoyReq->pValueBuf[bufCnt], VB_GET_IP_ADDRESS(group_vbp), pObject->valueLen ); pObject->pValueBuf = &pEnvoyReq->pValueBuf[bufCnt]; bufCnt++; break; case VT_COUNTER64: case VT_OBJECT: case VT_EMPTY: default: return ERROR; } } return OK;}/**************************************************************************************** ospf_envoy_markVarbind - mark the varbind with the appropriate status** This routine mark the varbind as being done base on the request type. This routine* must be called before each testproc() and setproc() exit.** RETURNS: N/A** ERRNO: N/A*/void ospf_envoy_markVarbind( VB_T *vbp, SNMP_PKT_T *pktp, mApiRequest_t *pRequest, mApiReqType_t reqType ){ VB_T *group_vbp; mApiObject_t *pObj; int vbcount = 0; for ( group_vbp = vbp; group_vbp != NULL && vbcount < pRequest->numObjects; vbcount++, group_vbp = group_vbp->vb_link ) { pObj = &pRequest->pObjectList[vbcount]; if ( pObj->exception == MAPI_NO_EXCEPTION ) { /* tell 'em that this varbind has been processed */ if ( reqType == MAPI_TEST ) testproc_good( pktp, group_vbp ); if ( reqType == MAPI_COMMIT ) setproc_good( pktp, group_vbp ); if ( reqType == MAPI_UNDO ) undoproc_good( pktp, group_vbp ); } else { if ( pObj->exception == MAPI_NO_SUCH_OBJECT ) getproc_nosuchobj( pktp, group_vbp ); if ( pObj->exception == MAPI_NO_SUCH_INSTANCE ) getproc_nosuchins (pktp, group_vbp ); } }}/***************************************************************************************** ospf_envoy_processScalarGetResp - process MIB API GET/GET NEXT scalar objects response** This is a generic routine to process all the MIB API GET/GET_NEXT response for the* scalar objects. It is invoked by getproc or nextproc after retreiving the values of* requested objects from the MIB API. The value of the objects will be copied into the* appropriate varbind. If exceptions reported by MIB API, the appropriate envoy snmp* exception will be raised. This routine should not be used to process the GET/GET_NEXT* response for table rows. This is because the nextproc_next_instance() needs to be* treated differently for scalar objects.** RETURNS: N/A** ERRNO: N/A*/void ospf_envoy_processScalarGetResp( VB_T *vbp, SNMP_PKT_T *pktp, envoyRequest_t *pEnvoyReq, mApiRequest_t *pRequest, mApiReqType_t reqType, int mApiOidOffset ){ mApiObject_t *pObject; STATUS rc; int vbcount; OIDC_T instance; vbcount = 0; instance = 0; for ( ; vbp != NULL && vbcount < pRequest->numObjects; vbp = vbp->vb_link, vbcount++ ) { pObject = &pRequest->pObjectList[vbcount]; /* assumed the varbind is serailize with the request message */ if ( vbp->vb_ml.ml_last_match != pObject->oidPrefixEnum - mApiOidOffset )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -