📄 ax_mast.c
字号:
/* * Copyright 2000-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//* ax_mast.c - default IO routines for the SNMP AgentX master agent */#include <copyright_wrs.h>/*modification history-------------------------01h,13oct05,job proper handling of COMP_UN socket names01g,28jun05,job need some locking controls around socket creation01f,19apr05,job update copyright notices01e,19oct04,job add include line for selectLib.h01d,01dec03,job update copyright information01c,15aug03,job fix a prototyping issue01b,05dec00,ten Added routines for Agentx mib support01a,29Sep00,josh Created for AgentX master agent*//* * $Log: ax_mast.c,v $ * Revision 1.17 2002/12/02 21:02:10 josh * make sure allocated resources are freed if an error occurs in * envoyAxConnEntry * * Revision 1.16 2002/08/26 20:31:06 josh * modifications to the code to eliminate warnings from Diab compiler * * Revision 1.15 2002/06/20 15:21:04 meister * Fixed some function storage class compiler warnings * (static/non-static inconsistencies) * * Revision 1.14 2002/05/23 19:42:43 josh * updates to support the entity MIB * * Revision 1.13 2002/05/21 19:51:10 andre * Fix deadlock problem. Move agentxConnTableLastChange assignment location. * * Revision 1.12 2002/05/20 19:13:08 andre * Fixes envoyAxConnEntry() * * Revision 1.11 2002/05/17 19:53:26 tneale * Fixed building of OID in envoyAxConnEntry() * * Revision 1.10 2002/05/16 21:01:24 tneale * Changed location of "connection table last changed" update * * Revision 1.9 2002/04/05 13:55:12 andre * Remove envoyAxConnEntryType(); add envoyAxGetConnID(). * * Revision 1.8 2002/04/04 15:28:56 andre * Add locking in removeConn; change enum to int type * * Revision 1.6 2002/04/02 19:49:42 andre * Init connListLock; add locking in findPrevConn() * * Revision 1.5 2002/04/02 14:51:59 andre * Connection table work * * Revision 1.4 2002/03/14 20:02:17 josh * envoyGetSysUpTime() should be returning a value in centiseconds, not * milliseconds. * * Revision 1.3 2002/02/22 20:04:53 andre * Initial checkin for AgentX MIB changes * * Revision 1.2 2001/11/08 22:18:33 meister * rework pathnames * * Revision 1.1.1.1 2001/11/05 17:47:49 tneale * Tornado shuffle * * Revision 1.3 2001/06/24 19:49:15 josh * Let's free the bad part of the tree and not the good part * * Revision 1.2 2001/04/16 19:38:42 josh * merging the kingfisher branch onto the trunk * * Revision 1.1.2.5 2001/03/12 22:11:30 tneale * Updated copyright * * Revision 1.1.2.4 2000/12/05 22:07:07 tneale * Moved routines for old-style AgentX mib support to this file * * Revision 1.1.2.3 2000/10/26 21:36:00 josh * fixing a few bugs in the vxWorks AgentX master agent * * Revision 1.1.2.2 2000/10/13 21:34:09 josh * AgentX support, second round check-in * * Revision 1.1.2.1 2000/10/13 21:26:58 josh * Adding AgentX master agent support to vxWorks agent * * *//* This module implements the I/O routines used by the SNMP AgentX masteragent. All incoming messages from AgentX subagents will be processedin an auxiliary task, 'tAgentX'. When 'tSnmpd' spawns 'tAgentX', it assigns snmpAgentXMonitor() tomanage the process. This function waits on the socket that AgentXsubagents will use to open connections with the master agent. ThesnmpAgentXMonitor() function will open additional sockets to managesessions with newly registered subagents.For each new socket opened in this fashion, snmpAgentXMonitor() willcreate a structure (AX_CONN_T) to store important information aboutthis session.All messages subsequently received on open sockets will result in acall to envoy_ax_chunk_handler() to allow for processing of chunkeddata (since we're using TCP, there's no guarantee that a request willbe sent in a single packet).If the message submitted to envoy_ax_chunk_handler() is a registrationrequest, it includes information on a set of leaves representing theobjects that the subagent wants to add to the master agent's MIB tree.If the message passes all checks, the objects are added to the masteragent's MIB tree and a success message is sent back to the subagent. The snmpAgentXMonitor() function takes responsibility for sendingresponses to packets received from the subagent. */#include <wrn/wm/snmp/vxagent/snmpdLib.h>#include <selectLib.h>#include <msgQLib.h>#include <inetLib.h>#include <semLib.h>#include <wrn/wm/snmp/engine/buffer.h>#include <wrn/wm/snmp/vxagent/axCfg.h>#include <taskLib.h>#include <wrn/wm/snmp/engine/asn1conf.h>#include <wrn/wm/snmp/engine/snmp.h>#include <wrn/wm/snmp/engine/objectid.h>#include <wrn/wm/snmp/engine/axapi.h>#include <wrn/wm/snmp/vxagent/vxprotos.h>#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS#include <sys/un.h>#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS *//* defines */#define TIME 20 /* Timeout for masterIpcSend */#define MASTER_PRIO 151 /* tMonQue priority */#define MASTER_STACK_SIZE 5000 /* tMonQue stacksize */#define MASTER_OPTS 0 /* tMonQue options *//* Externals */extern bits32_t axConnTblLastChg;extern SEM_ID snmpdSocketControlSem;/* Locals */SEM_ID connListLock = 0;AX_CONN_T *pAxConnRoot = 0;AX_CONN_T *pAxConnTail = 0;static int axSocket;static int axLocalSocket = 0;static int axMasterTaskID;unsigned char rcvBuf[2048];static bits32_t AxConnectionID = 1;/* forward declarations */LOCAL void agentXAdmin (ptr_t cookie, ptr_t axPkt);LOCAL void agentXAdd (ptr_t cookie);LOCAL void agentXFree (ptr_t cookie, int errorStat);LOCAL int agentXSend (ptr_t cookie, ptr_t pAxPkt, ptr_t pVbList, ALENGTH_T need);LOCAL void addConn (AX_CONN_T *pAxConn);LOCAL void removeConn (AX_CONN_T *pAxConn);LOCAL AX_CONN_T *findPrevConn (AX_CONN_T *pAxConn);LOCAL void snmpAgentXMonitor (void);/********************************************************************************* axMasterIoInit - create the IPC mechanism at the SNMP master agent** This routine, called from snmpIoInit(), creates the SNMP master agent side* of the inter-process communication (IPC) mechanism used to carry messages* between AgentX subagents and the master agent. In this implementation,* axMasterIoInit() opens a TCP socket and listens on it. Subagents must open* a connection to this socket prior to sending any control messages or* otherwise passing AgentX traffic to this master agent.** The socket created by axMasterIoInit() is monitored by 'tAgentX'. The* 'tAgentX' task is one of the three tasks used to implement the SNMP AgentX* master agent. The purpose of 'tAgentX' is to process incoming messages from* the AgentX subagent and open new connections or pass the packet off to the* handler as necessary.** RETURNS: OK or ERROR.**/STATUS axMasterIoInit ( void ) { struct sockaddr_in axSock;#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS struct sockaddr_un axLocalSock; char axLocalPath[] = "/comp/socket/0x705";#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS */ /* create the AgentX socket */ if ((axSocket = socket (AF_INET, SOCK_STREAM, 0)) == -1) { snmpdLog (SNMP_ERROR, "Unable to create AgentX socket\n"); return (ERROR); } axSock.sin_family = AF_INET; axSock.sin_port = htons (ENVOY_AX_MASTER_PORT); axSock.sin_addr.s_addr = INADDR_ANY; if (bind (axSocket, (struct sockaddr *)&axSock, sizeof (axSock)) == -1) { snmpdLog (SNMP_ERROR, "Can't bind AgentX socket\n"); return (ERROR); } if (listen(axSocket, 5) == -1) { snmpdLog (SNMP_ERROR, "Can't listen on AgentX socket\n"); return (ERROR); }#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS /* create the AgentX local socket */ if ((axLocalSocket = socket (AF_LOCAL, SOCK_SEQPACKET, 0)) == -1) { snmpdLog (SNMP_ERROR, "Unable to create AgentX local socket\n"); return (ERROR); } axLocalSock.sun_family = AF_LOCAL; axLocalSock.sun_len = sizeof (axLocalSock); strcpy(axLocalSock.sun_path, axLocalPath); if (bind (axLocalSocket, (struct sockaddr *)&axLocalSock, sizeof (axLocalSock)) == -1) { snmpdLog (SNMP_ERROR, "Can't bind AgentX local socket\n"); return (ERROR); } if (listen(axLocalSocket, 5) == -1) { snmpdLog (SNMP_ERROR, "Can't listen on AgentX local socket\n"); return (ERROR); }#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS */ return (OK); }/********************************************************************************* snmpAxMonitorSpawn - spawn 'tAgentX' to run snmpAgentXMonitor()** This function spawns the 'tAgentX' task to run snmpAgentXMonitor() a* function that waits on the AgentX socket. The snmpAgentXMonitor() accepts* incoming connections and manages them. When a request comes in, it is* processed by calling envoy_ax_chunk_handler().** When a new connection is requested, the task will accept it and store* relevant information in the AX_CONN_T structure.**/void snmpAxMonitorSpawn (void) { if ((axMasterTaskID = taskSpawn ("tAgentX", MASTER_PRIO, MASTER_OPTS, MASTER_STACK_SIZE, (FUNCPTR) snmpAgentXMonitor, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) == ERROR) snmpdLog (SNMP_ERROR, "Error in spawning AgentX monitor task\n"); return; }/********************************************************************************* snmpAgentXMonitor - wait for connections and messages from the subagents** This routine sits in a select() loop on the listening AgentX socket and* waits for AgentX subagents to connect and send messages. When a subagent* opens the connection initially, this task will accept() the connection and* put information about it into an AX_CONN_T structure.** Messages received on opened connections will be passed through to* envoy_ax_chunk_handler().** RETURNS: N/A**/LOCAL void snmpAgentXMonitor (void) { struct sockaddr_in axAddr; int axAddrLen;#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS struct sockaddr_un axLocalAddr; int axLocalAddrLen;#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS */ int axTrue; int maxSocket; int got; fd_set ready; AX_CONN_T *pAxConn; AX_CONN_T *pNewAxConn = 0; AX_CONN_T *pAxConnNext; semTake(snmpdSocketControlSem, WAIT_FOREVER); semGive(snmpdSocketControlSem); while (1) { maxSocket = (axSocket > axLocalSocket) ? (axSocket + 1) : (axLocalSocket + 1); FD_ZERO (&ready); FD_SET (axSocket, &ready);#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS FD_SET (axLocalSocket, &ready);#endif /* #if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS */ for (pAxConn = pAxConnRoot; pAxConn; pAxConn = pAxConn->next) { FD_SET (pAxConn->sockNum, &ready); if (pAxConn->sockNum >= maxSocket) maxSocket = pAxConn->sockNum + 1; } if (select (maxSocket, &ready, 0, 0, 0) < 0) { snmpdLog (SNMP_ERROR, "Unable to select() on open sockets.\n"); return; } if (FD_ISSET (axSocket, &ready)) { pNewAxConn = SNMP_memory_alloc (sizeof (AX_CONN_T)); if (pNewAxConn == 0) { snmpdLog (SNMP_ERROR, "Unable to allocate new connection struct\n"); return; } axAddrLen = sizeof (axAddr); axTrue = 1; pNewAxConn->sockNum = accept (axSocket, (struct sockaddr *) &axAddr, &axAddrLen); if (ioctl (pNewAxConn->sockNum, FIONBIO, (int) &axTrue) != -1) { /* 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); } }#if INSTALL_SNMP_VXWORKS_MESSAGE_CHANNELS if (FD_ISSET (axLocalSocket, &ready)) { pNewAxConn = SNMP_memory_alloc (sizeof (AX_CONN_T)); if (pNewAxConn == 0) { snmpdLog (SNMP_ERROR, "Unable to allocate new connection struct\n"); return; } axLocalAddrLen = sizeof (axLocalAddr); axTrue = 1; pNewAxConn->sockNum = accept (axLocalSocket, (struct sockaddr *) &axLocalAddr, &axLocalAddrLen); if (ioctl (pNewAxConn->sockNum, FIONBIO, (int) &axTrue) != -1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -