snmp_api.c

来自「eCos操作系统源码」· C语言 代码 · 共 2,082 行 · 第 1/5 页

C
2,082
字号
    session->contextEngineID = NULL;    session->contextName = NULL;    session->securityEngineID = NULL;    session->securityName = NULL;    session->securityAuthProto = NULL;    session->securityPrivProto = NULL;    /*     * session now points to the new structure that still contains pointers to     * data allocated elsewhere.  Some of this data is copied to space malloc'd     * here, and the pointer replaced with the new one.     */    if (in_session->peername != NULL){	session->peername = (char *)malloc(strlen(in_session->peername) + 1);	if (session->peername == NULL) {          snmp_sess_close(slp);	  in_session->s_snmp_errno = SNMPERR_MALLOC;          return(NULL);        }	strcpy(session->peername, in_session->peername);    }    /* Fill in defaults if necessary */    if (in_session->community_len != SNMP_DEFAULT_COMMUNITY_LEN){	ucp = (u_char *)malloc(in_session->community_len);	if (ucp != NULL)	    memmove(ucp, in_session->community, in_session->community_len);    } else {	if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_COMMUNITY)) != NULL) {	    session->community_len = strlen(cp);	    ucp = (u_char *)malloc(session->community_len);	    if (ucp)		memmove(ucp, cp, session->community_len);	}	else {#ifdef NO_ZEROLENGTH_COMMUNITY	    session->community_len = strlen(DEFAULT_COMMUNITY);	    ucp = (u_char *)malloc(session->community_len);	    if (ucp)		memmove(ucp, DEFAULT_COMMUNITY, session->community_len);#else	    ucp = (u_char *)strdup("");#endif	}    }    if (ucp == NULL) {      snmp_sess_close(slp);      in_session->s_snmp_errno = SNMPERR_MALLOC;      return(NULL);    }    session->community = ucp;	/* replace pointer with pointer to new data */#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT    if (session->securityLevel <= 0)      session->securityLevel = ds_get_int(DS_LIBRARY_ID, DS_LIB_SECLEVEL);    if (session->securityLevel == 0)      session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;    if (in_session->securityAuthProtoLen > 0) {      session->securityAuthProto = 	(oid*)malloc(in_session->securityAuthProtoLen * sizeof(oid));      if (session->securityAuthProto == NULL) {	snmp_sess_close(slp);	in_session->s_snmp_errno = SNMPERR_MALLOC;	return(NULL);      }      memmove(session->securityAuthProto, in_session->securityAuthProto,	      in_session->securityAuthProtoLen * sizeof(oid));    } else if (get_default_authtype(&i) != NULL) {        session->securityAuthProto =          snmp_duplicate_objid(get_default_authtype(NULL), i);        session->securityAuthProtoLen = i;    }    if (in_session->securityPrivProtoLen > 0) {      session->securityPrivProto = 	(oid*)malloc((unsigned)in_session->securityPrivProtoLen * sizeof(oid));      if (session->securityPrivProto == NULL) {	snmp_sess_close(slp);	in_session->s_snmp_errno = SNMPERR_MALLOC;	return(NULL);      }      memmove(session->securityPrivProto, in_session->securityPrivProto,	      in_session->securityPrivProtoLen * sizeof(oid));    } else if (get_default_privtype(&i) != NULL) {        session->securityPrivProto =          snmp_duplicate_objid(get_default_privtype(NULL), i);        session->securityPrivProtoLen = i;    }    if (in_session->securityEngineIDLen > 0) {      ucp = (u_char*)malloc((unsigned)in_session->securityEngineIDLen *			   sizeof(u_char));      if (ucp == NULL) {	snmp_sess_close(slp);	in_session->s_snmp_errno = SNMPERR_MALLOC;	return(NULL);      }      memmove(ucp, in_session->securityEngineID,	      in_session->securityEngineIDLen * sizeof(u_char));      session->securityEngineID = ucp;    }    if (in_session->contextEngineIDLen > 0) {      ucp = (u_char*)malloc((unsigned)in_session->contextEngineIDLen *			   sizeof(u_char));      if (ucp == NULL) {	snmp_sess_close(slp);	in_session->s_snmp_errno = SNMPERR_MALLOC;	return(NULL);      }      memmove(ucp, in_session->contextEngineID,	      in_session->contextEngineIDLen * sizeof(u_char));      session->contextEngineID = ucp;    } else if (in_session->securityEngineIDLen > 0) {      /* default contextEngineID to securityEngineIDLen if defined */      ucp = (u_char*)malloc((unsigned)in_session->securityEngineIDLen *			   sizeof(u_char));      if (ucp == NULL) {	snmp_sess_close(slp);	in_session->s_snmp_errno = SNMPERR_MALLOC;	return(NULL);      }      memmove(ucp, in_session->securityEngineID,	      in_session->securityEngineIDLen * sizeof(u_char));      session->contextEngineID = ucp;      session->contextEngineIDLen = in_session->securityEngineIDLen;    }    if (in_session->contextName) {      session->contextName = strdup(in_session->contextName);      if (session->contextName == NULL) {	snmp_sess_close(slp);	return(NULL);      }    } else if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_CONTEXT)) != NULL) {      cp = strdup(cp);      if (cp == NULL) {	snmp_sess_close(slp);	return(NULL);      }      session->contextName = cp;      session->contextNameLen = strlen(cp);    } else {      cp = strdup(SNMP_DEFAULT_CONTEXT);      session->contextName = cp;      session->contextNameLen = strlen(cp);    }    if (in_session->securityName) {      session->securityName = strdup(in_session->securityName);      if (session->securityName == NULL) {	snmp_sess_close(slp);	return(NULL);      }    } else if ((cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_SECNAME)) != NULL) {      cp = strdup(cp);      if (cp == NULL) {	snmp_sess_close(slp);	return(NULL);      }      session->securityName = cp;      session->securityNameLen = strlen(cp);    }    if ((in_session->securityAuthKeyLen <= 0) &&	(cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_AUTHPASSPHRASE))) {      session->securityAuthKeyLen = USM_AUTH_KU_LEN;      if (generate_Ku(session->securityAuthProto,                      session->securityAuthProtoLen,                      (u_char*)cp, strlen(cp),                      session->securityAuthKey,                      &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {        snmp_set_detail("Error generating Ku from authentication pass phrase.");	snmp_sess_close(slp);        return NULL;      }    }    if ((in_session->securityPrivKeyLen <= 0) && 	       (cp = ds_get_string(DS_LIBRARY_ID, DS_LIB_PRIVPASSPHRASE))) {      session->securityPrivKeyLen = USM_PRIV_KU_LEN;      if (generate_Ku(session->securityAuthProto,                      session->securityAuthProtoLen,                      (u_char *)cp, strlen(cp),                      session->securityPrivKey,                      &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {        snmp_set_detail("Error generating Ku from privacy pass phrase.");	snmp_sess_close(slp);        return NULL;      }    }#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */    if (session->retries == SNMP_DEFAULT_RETRIES)	session->retries = DEFAULT_RETRIES;    if (session->timeout == SNMP_DEFAULT_TIMEOUT)	session->timeout = DEFAULT_TIMEOUT;    session->sessid = snmp_get_next_sessid();    return( slp );}struct session_list *snmp_sess_copy( struct snmp_session *pss){    struct session_list * psl;    psl = _sess_copy(pss);    if ( !psl) {        if ( !pss->s_snmp_errno)	        pss->s_snmp_errno = SNMPERR_GENERR;	    SET_SNMP_ERROR(pss->s_snmp_errno);    }    return psl;}/*******************************************************************-o-****** * snmp_sess_open * * Parameters: *	*in_session * * Returns: *      Pointer to a session in the session list   -OR-		FIX -- right? *	NULL on failure. * * The "spin-free" version of snmp_open. */static void *_sess_open(struct snmp_session *in_session){    struct session_list *slp;    struct snmp_internal_session *isp;    struct snmp_session *session;    int sd;    in_addr_t addr;    struct sockaddr_in *isp_addr, *meIp;#ifdef HAVE_GETHOSTBYNAME    struct hostent *hp;#endif#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT    struct snmp_pdu *pdu, *response;    int status;#endif    size_t i, addr_size;    char *cp = NULL;    in_session->s_snmp_errno = 0;    in_session->s_errno = 0;    if (Reqid == 0)      _init_snmp();    if ((slp = snmp_sess_copy( in_session )) == NULL )        return( NULL );    isp     = slp->internal;    session = slp->session;    if ( isp->addr.sa_family == AF_UNSPEC ) {        if ( session->peername && session->peername[0] == '/' ) {#ifdef AF_UNIX            isp->addr.sa_family = AF_UNIX;            strcpy( isp->addr.sa_data, session->peername);#else /* AF_UNIX */            snmp_log(LOG_ERR,"%s:%d: _sess_open invalid session name %s- unix sockets not supported  \n",                    __FILE__,__LINE__,                    session->peername);            return(NULL);#endif /* AF_UNIX */                    } else {            isp->addr.sa_family = AF_INET;            isp_addr = (struct sockaddr_in *)&(isp->addr);            if (session->peername != SNMP_DEFAULT_PEERNAME) {			/* Try and extract an appended port number */		cp = strchr( session->peername, ':' );		if ( cp ) {		    *cp = '\0';		    cp++;		    session->remote_port = atoi( cp );		    if ( session->local_port )	/* i.e. server */			session->local_port = session->remote_port;		}			/* Interpret the peername as an IP port ... */		cp = strchr( session->peername, '.' );		if ( !cp && (( i = atoi( session->peername )) != 0 )) {		    session->remote_port = i;		    if ( session->local_port )	/* i.e. server */			session->local_port = session->remote_port;		}			/* ... failing that, as an IP address ... */                else if ((int)(addr = inet_addr(session->peername)) != -1){                    memmove(&isp_addr->sin_addr, &addr, sizeof(isp_addr->sin_addr));                } else {			/* .... failing that, as a hostname */#ifdef HAVE_GETHOSTBYNAME                    hp = gethostbyname(session->peername);                    if (hp == NULL){                        in_session->s_snmp_errno = SNMPERR_BAD_ADDRESS;                        in_session->s_errno = errno;                        snmp_set_detail(session->peername);                        snmp_sess_close(slp);                        return 0;                    } else {                        memmove(&isp_addr->sin_addr, hp->h_addr, hp->h_length);                    }#else /* HAVE_GETHOSTBYNAME */                    snmp_log(LOG_ERR,"%s:%d: _sess_open do not have get host by name - cannot resolve %s \n",                            __FILE__,__LINE__,                            session->peername);                    return(0);#endif /* HAVE_GETHOSTBYNAME */                }                if (session->remote_port == SNMP_DEFAULT_REMPORT){                    short iport = ds_get_int(DS_LIBRARY_ID, DS_LIB_DEFAULT_PORT);                    isp_addr->sin_port = htons(iport);                } else {                    isp_addr->sin_port = htons(session->remote_port);                }            } else {                isp_addr->sin_addr.s_addr = SNMP_DEFAULT_ADDRESS;            }        }    }    if ( session->local_port ) {	/*	 *  If the session structure includes a non-null value for	 *    local_port, then this session is intended as a server.	 *    This means that the isp->addr structure will not be 	 *    needed to contact a remote entity.	 *	 *  By using this address as the local address to bind to,	 *    we can provide a facility for listening on selected	 *    (rather than all) interfaces.	 */	memcpy( &isp->me, &isp->addr, sizeof(isp->me));	if ( isp->addr.sa_family == AF_INET ) {			/*			 * Remember to use the specified local port,			 *   rather than the (default?) remote one.			 * If no local interface address is specified,			 *   default to listening on all interfaces,			 *   rather than the default connection host			 *   (SNMP_DEFAULT_ADDRESS)			 */	    meIp = (struct sockaddr_in*)&(isp->me);	    meIp->sin_port = htons(session->local_port);            if (session->peername == SNMP_DEFAULT_PEERNAME)                meIp->sin_addr.s_addr = INADDR_ANY;	}    }    else {        memset(&isp->me, '\0', sizeof(isp->me));        isp->me.sa_family = isp->addr.sa_family;        if ( isp->me.sa_family == AF_INET ) {	    meIp = (struct sockaddr_in*)&(isp->me);            meIp->sin_addr.s_addr = INADDR_ANY;            meIp->sin_port = htons(session->local_port);        }#ifdef AF_UNIX        else if ( isp->me.sa_family == AF_UNIX ) {    		/* Need a unique socket name */#ifndef UNIX_SOCKET_BASE_NAME#define UNIX_SOCKET_BASE_NAME  "/tmp/s."#endif    #ifndef WIN32                strcpy( isp->me.sa_data, UNIX_SOCKET_BASE_NAME );                strcat( isp->me.sa_data, "XXXXXX" );                mktemp( isp->me.sa_data );#endif        }#endif /* AF_UNIX */    }    addr_size = snmp_socket_length(isp->me.sa_family);    /* Set up connections */    if ( session->flags & SNMP_FLAGS_STREAM_SOCKET ) {        if ( session->local_port != 0 )            session->flags |= SNMP_FLAGS_LISTENING;        sd = socket(isp->me.sa_family, SOCK_STREAM, 0);    }    else        sd = socket(isp->me.sa_family, SOCK_DGRAM, 0);    if (sd < 0){	in_session->s_snmp_errno = SNMPERR_NO_SOCKET;	in_session->s_errno = errno;	snmp_set_detail(strerror(errno));	snmp_sess_close(slp);	return 0;    }    isp->sd = sd;#ifdef SO_BSDCOMPAT    /* Patch for Linux.  Without this, UDP packets that fail get an ICMP     * response.  Linux turns the failed ICMP response into an error message     * and return value, unlike all other OS's.     */    {	int one=1;	setsockopt(sd, SOL_SOCKET, SO_BSDCOMPAT, &one, sizeof(one));    }#endif /* SO_BSDCOMPAT *///#ifndef __ECOS#ifndef SERVER_REQUIRES_CLIENT_SOCKET

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?