📄 ax_mast.c
字号:
/* Successfully created a new socket. Now we just need to complete the setup. */ pNewAxConn->refCount = 0; envoy_ax_chunk_init (&(pNewAxConn->chunk)); pNewAxConn->connectID = AxConnectionID++; pNewAxConn->createTime = ENVOY_GET_SYSUPTIME(0); pNewAxConn->next = 0; addConn (pNewAxConn); } }#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS */ /* Now we check the remaining sockets to see if we've received any additional data. */ for (pAxConn = pAxConnRoot; pAxConn; pAxConn = pAxConn->next) { pAxConnNext = pAxConn->next; if (FD_ISSET(pAxConn->sockNum, &ready)) { while (1) { /* We've received data on this socket... */ if ((got = recv (pAxConn->sockNum, (char *) rcvBuf, sizeof (rcvBuf), 0)) == -1) { if (errno != EWOULDBLOCK) { close (pAxConn->sockNum); envoy_ax_ma_cleanup_sessions (pAxConn, 0); envoy_ax_chunk_clean (&(pAxConn->chunk)); removeConn (pAxConn); SNMP_memory_free (pAxConn); } break; } if ((got == 0) || (envoy_ax_chunk_handler (rcvBuf, got, envoy_ax_ma_handler, &(pAxConn->chunk), 0, agentXAdmin, agentXSend, agentXFree, agentXAdd, pAxConn) != 0)) { close (pAxConn->sockNum); envoy_ax_ma_cleanup_sessions (pAxConn, 0); envoy_ax_chunk_clean (&(pAxConn->chunk)); removeConn (pAxConn); SNMP_memory_free (pAxConn); break; } } } } } }/********************************************************************************* linkAxConn - Add an AX_CONN_T structure to the end of the linked list.** Add a specific AX_CONN_T structure to the linked list.** RETURNS: N/A**/LOCAL void addConn (AX_CONN_T *pNewAxConn) { /* Create the semaphore/lock if it doesn't exist yet. Grab the lock. */ if (!connListLock) connListLock = semBCreate (SEM_Q_FIFO, SEM_FULL); semTake (connListLock, WAIT_FOREVER); if (pAxConnRoot && pAxConnTail) { /* Add the entry to the end of the list */ pNewAxConn->next = 0; pAxConnTail->next = pNewAxConn; pAxConnTail = pNewAxConn; } else { /* First entry on the list: Create the binary semaphore. Add the entry. */ pAxConnRoot = pNewAxConn; pAxConnTail = pNewAxConn; } /* Release the lock. Note the table change time. */ semGive (connListLock); setAxConnTblLastChg (ENVOY_GET_SYSUPTIME(0)); }/********************************************************************************* removeConn - Remove an AX_CONN_T from the connection table list** Remove a specific AX_CONN_T structure from the linked list.** RETURNS: N/A**/LOCAL void removeConn (AX_CONN_T *pAxConn) { AX_CONN_T *pAxConnPrev; /* Grab the lock. Find the previous entry. */ semTake (connListLock, WAIT_FOREVER); pAxConnPrev = findPrevConn (pAxConn); if (pAxConnPrev) { /* We found a previous entry. */ pAxConnPrev->next = pAxConn->next; if (!pAxConn->next) pAxConnTail = pAxConnPrev; } else { /* No previous entry in the list. */ if (pAxConn->next) { /* List has a non-zero number of elements */ pAxConnRoot = pAxConn->next; } else { /* List is now empty with the removal of the last element */ pAxConnRoot = 0; pAxConnTail = 0; } } /* Terminate the last entry. Release the lock. Set the table change time. */ pAxConn->next = 0; semGive (connListLock); setAxConnTblLastChg (ENVOY_GET_SYSUPTIME(0)); }/********************************************************************************* findPrevConn - Find the previous AX_CONN_T structure** Given a specific AX_CONN_T structure in the linked list, this routine returns* a pointer to the previous AX_CONN_T structure, or zero if there is none.** NOTE: It is assumed that the caller owns the connection entry list lock* prior to calling this routine!** RETURNS: A pointer to a specific AX_CONN_T structure in the linked list,* or zero if there isn't any prior entry on the list.**/LOCAL AX_CONN_T *findPrevConn (AX_CONN_T *pAxConn) { AX_CONN_T *curEntry = pAxConnRoot, *prevEntry = 0; while (curEntry) { if (curEntry->connectID == pAxConn->connectID) return prevEntry; prevEntry = curEntry; curEntry = curEntry->next; } return 0; }/***************************************************************************** agentXAdmin - used for passing an AgentX PDU to user code.** Currently this function does nothing. It can be used to process* traps sent by an AgentX subagent.** RETURNS: N/A**/LOCAL void agentXAdmin ( ptr_t cookie, ptr_t axPkt ) { return; }/***************************************************************************** agentXAdd - used for keeping track of references to important information. ** This function is called whenever a packet handler has been called. It* increments the refCount in the AX_CONN_T structure so we know how many* handlers are currently using the AX_CONN_T structure.** RETURNS: N/A**/LOCAL void agentXAdd ( ptr_t cookie ) { ((AX_CONN_T *)cookie)->refCount++; }/***************************************************************************** agentXFree - used for keeping track of references and processing errors.** This function is called to indicate that the handler is finished with* the AX_CONN_T structure and resources associated with it may be freed.* This function can also be expanded to handle error codes that are passed* in in the errorStat parameter.** RETURNS: N/A**/LOCAL void agentXFree ( ptr_t cookie, int errorStat ) { ((AX_CONN_T *)cookie)->refCount--; }/***************************************************************************** agentXSend - send a response message to the subagent** This routine is used to send a response message to the subagent, or to* send queries as part of an SNMP operation. It will allocate 'need'* bytes, place that space into an EBUFFER_T, encode the packet, and then* send it according to the information in the cookie.** RETURNS: 0 if successful* 1 if unsuccessful**/LOCAL int agentXSend ( ptr_t pCookie, ptr_t pAxPkt, ptr_t pVbList, ALENGTH_T need ) { bits8_t *pPkt; EBUFFER_T eBuff; ALENGTH_T pktLen = need; AX_CONN_T *pAxConn = (AX_CONN_T *) pCookie; EBufferInitialize (&eBuff); pPkt = SNMP_memory_alloc (need); if (pPkt == 0) return (1); EBufferSetup (BFL_IS_DYNAMIC, &eBuff, pPkt, pktLen); if (envoy_ax_pkt_encode (pAxPkt, pVbList, &eBuff, need)) { SNMP_memory_free (pPkt); return (1); } send (pAxConn->sockNum, (char *) pPkt, need, 0); SNMP_memory_free (pPkt); return (0); }/********************************************************************************* masterAxCleanup - free resources allocated for SNMP AgentX master agent** This routine is called from the cleanup routine in snmpIoLib if the agent* fails to allocate resources. This routine closes all sockets and all other* resources that have been allocated for the master agent.** RETURNS: N/A**/void masterAxCleanup (void) { /* we need to be careful here, since we do have a select loop * running on this set of sockets. For now, we'll do nothing. */ return; }/********************************************************************************* envoyAxConnEntry - Return the time, domain and address for a given connection** This function is provided to support the AgentX MIB.** Returns: 1 for success, 0 for failure.*/bits32_t envoyAxConnEntry ( bits32_t axConnID, int matchFlag, AX_CONNENT_T *pConnEntry ) { int addrSize = sizeof (struct sockaddr_in); OIDC_T domain[] = {0,0}; AX_CONN_T *curEntry = pAxConnRoot; struct sockaddr_in sockAddr; bits8_t tAddr[6]; /* Validate match type. Check the .0 case. */ if ((matchFlag != AX_MATCH_GET) && (matchFlag != AX_MATCH_NEXT)) return 0; while (curEntry) { if (((matchFlag == AX_MATCH_GET) && (curEntry->connectID == axConnID)) || /* Get */ ((matchFlag == AX_MATCH_NEXT) && (curEntry->connectID > axConnID)) || /* Next */ ((matchFlag == AX_MATCH_NEXT) && (axConnID == 0))) /* Next .0 */ { /* Copy the data to the output structure and declare victory */ if (getsockname (curEntry->sockNum, (struct sockaddr *) &sockAddr, &addrSize)) return 0; pConnEntry->agentxConnIndex = curEntry->connectID; pConnEntry->agentxConnTransportTime = curEntry->createTime; init_object_id (&pConnEntry->agentxConnTransportDomain); build_object_id (sizeof(domain)/sizeof(OIDC_T), domain, &pConnEntry->agentxConnTransportDomain); MEMCPY (tAddr, &sockAddr.sin_addr.s_addr, 4); MEMCPY (tAddr + 4, &sockAddr.sin_port, 2); EBufferInitialize (&pConnEntry->agentxConnTransportAddress); if (EBufferAllocateLoad (BFL_IS_ALLOC, &pConnEntry->agentxConnTransportAddress, tAddr, 6)) { Clean_Obj_ID (&pConnEntry->agentxConnTransportDomain); return 0; } return 1; } curEntry = curEntry->next; } return 0; }/********************************************************************************* envoyAxGetConnID - Return the connection ID for a given session ID** This function is provided to support the AgentX MIB.** Returns: Connection ID if successful; 0 for failure.*/bits32_t envoyAxGetConnID (AX_CONN_T *pCE){ return (pCE->connectID ? pCE->connectID : 0);}void axSockClose (void) { AX_CONN_T *pAxConn = 0; AX_CONN_T *nextAxConn = 0; (void) close (axSocket); for (pAxConn = pAxConnRoot; pAxConn; pAxConn = nextAxConn) { nextAxConn = pAxConn->next; (void) close (pAxConn->sockNum); envoy_ax_ma_cleanup_sessions (pAxConn, 0); envoy_ax_chunk_clean (&(pAxConn->chunk)); removeConn (pAxConn); SNMP_memory_free (pAxConn); } taskDelete(axMasterTaskID); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -