📄 snmp_api.c
字号:
}
isp = (struct snmp_internal_session *)calloc(1,sizeof(struct snmp_internal_session));
if (isp == NULL) {
snmp_sess_close(slp);
in_session->s_snmp_errno = SNMPERR_MALLOC;
return(NULL);
}
slp->internal = isp;
slp->internal->sd = -1; /* mark it not set */
slp->session = (struct snmp_session *)malloc(sizeof(struct snmp_session));
if (slp->session == NULL) {
snmp_sess_close(slp);
in_session->s_snmp_errno = SNMPERR_MALLOC;
return(NULL);
}
memmove(slp->session, in_session, sizeof(struct snmp_session));
session = slp->session;
/* zero out pointers so if we have to free the session we wont free mem
owned by in_session */
session->peername = NULL;
session->community = NULL;
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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -