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 + -
显示快捷键?